socket: allow applications to set seq numbers
refs: #4032
Change-Id: I4ed379baaebc1643abf5864f7b674724f901e0e6
diff --git a/src/socket.cpp b/src/socket.cpp
index dad1125..4a947d7 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -107,6 +107,13 @@
}
void
+Socket::publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
+ const uint64_t& seqNo, const Name& prefix)
+{
+ publishData(ndn::encoding::makeBinaryBlock(ndn::tlv::Content, buf, len), freshness, seqNo, prefix);
+}
+
+void
Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness,
const Name& prefix)
{
@@ -130,6 +137,29 @@
}
void
+Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness,
+ const uint64_t& seqNo, const Name& prefix)
+{
+ shared_ptr<Data> data = make_shared<Data>();
+ data->setContent(content);
+ data->setFreshnessPeriod(freshness);
+
+ SeqNo newSeq = seqNo;
+ Name dataName;
+ dataName.append(m_logic.getSessionName(prefix)).appendNumber(newSeq);
+ data->setName(dataName);
+
+ if (m_signingId.empty())
+ m_keyChain.sign(*data);
+ else
+ m_keyChain.signByIdentity(*data, m_signingId);
+
+ m_ims.insert(*data);
+
+ m_logic.updateSeqNo(newSeq, prefix);
+}
+
+void
Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
const ndn::OnDataValidated& dataCallback,
int nRetries)
diff --git a/src/socket.hpp b/src/socket.hpp
index 807e173..09fee72 100644
--- a/src/socket.hpp
+++ b/src/socket.hpp
@@ -115,6 +115,24 @@
*
* This method will create a data packet with the supplied content.
* The packet name is the local session + seqNo.
+ * The seqNo is set by the application.
+ *
+ * @throws It will throw error, if the prefix does not exist in m_logic
+ *
+ * @param buf Pointer to the bytes in content
+ * @param len size of the bytes in content
+ * @param freshness FreshnessPeriod of the data packet.
+ * @param seqNo Sequence number of the data
+ */
+ void
+ publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
+ const uint64_t& seqNo, const Name& prefix = DEFAULT_PREFIX);
+
+ /**
+ * @brief Publish a data packet in the session and trigger synchronization updates
+ *
+ * This method will create a data packet with the supplied content.
+ * The packet name is the local session + seqNo.
* The seqNo is automatically maintained by internal Logic.
*
* @throws It will throw error, if the prefix does not exist in m_logic
@@ -127,6 +145,23 @@
const Name& prefix = DEFAULT_PREFIX);
/**
+ * @brief Publish a data packet in the session and trigger synchronization updates
+ *
+ * This method will create a data packet with the supplied content.
+ * The packet name is the local session + seqNo.
+ * The seqNo is set by the application.
+ *
+ * @throws It will throw error, if the prefix does not exist in m_logic
+ *
+ * @param content Block that will be set as the content of the data packet.
+ * @param freshness FreshnessPeriod of the data packet.
+ * @param seqNo Sequence number of the data
+ */
+ void
+ publishData(const Block& content, const ndn::time::milliseconds& freshness,
+ const uint64_t& seqNo, const Name& prefix = DEFAULT_PREFIX);
+
+ /**
* @brief Retrive a data packet with a particular seqNo from a session
*
* @param sessionName The name of the target session.
diff --git a/tests/unit-tests/test-socket.cpp b/tests/unit-tests/test-socket.cpp
index 9ba1294..0c478ec 100644
--- a/tests/unit-tests/test-socket.cpp
+++ b/tests/unit-tests/test-socket.cpp
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
- * Copyright (c) 2012-2016 University of California, Los Angeles
+ * Copyright (c) 2012-2017 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -107,7 +107,7 @@
}
void
- fetchNumbers(const vector<MissingDataInfo> &v)
+ fetchNumbers(const vector<MissingDataInfo>& v)
{
// std::cerr << "fetchNumbers" << std::endl;
for (size_t i = 0; i < v.size(); i++) {
@@ -203,6 +203,13 @@
}
void
+ publishAppData(size_t idx, const string& data, SeqNo seqNo)
+ {
+ app[idx]->socket.publishData(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(),
+ ndn::time::milliseconds(1000), seqNo);
+ }
+
+ void
setAppData(size_t idx, SeqNo seqNo, const string& data)
{
Name dataName = sessionName[idx];
@@ -354,6 +361,85 @@
BOOST_CHECK_EQUAL(app[1]->sum, 30);
}
+BOOST_AUTO_TEST_CASE(BasicDataWithAppSeq)
+{
+ createSocket(0, false);
+ advanceClocks(ndn::time::milliseconds(10), 5);
+ createSocket(1, false);
+ advanceClocks(ndn::time::milliseconds(10), 5);
+ createSocket(2, false);
+ advanceClocks(ndn::time::milliseconds(10), 5);
+
+ string data0 = "Very funny Scotty, now beam down my clothes";
+ publishAppData(0, data0, 100);
+
+ for (int i = 0; i < 50; i++) {
+ advanceClocks(ndn::time::milliseconds(2), 10);
+ passPacket();
+ }
+ setAppData(0, 100, data0);
+
+ advanceClocks(ndn::time::milliseconds(10), 1);
+ BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
+ BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
+
+ string data1 = "Yes, give me that ketchup";
+ string data2 = "Don't look conspicuous, it draws fire";
+ publishAppData(0, data1, 200);
+ advanceClocks(ndn::time::milliseconds(10), 1);
+ publishAppData(0, data2, 300);
+
+ for (int i = 0; i < 50; i++) {
+ advanceClocks(ndn::time::milliseconds(2), 10);
+ passPacket();
+ }
+ setAppData(0, 200, data1);
+ advanceClocks(ndn::time::milliseconds(10), 1);
+ setAppData(0, 300, data2);
+
+ advanceClocks(ndn::time::milliseconds(10), 1);
+ BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
+ BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
+
+ string data3 = "You surf the Internet, I surf the real world";
+ string data4 = "I got a fortune cookie once that said 'You like Chinese food'";
+ string data5 = "Real men wear pink. Why? Because their wives make them";
+ publishAppData(2, data3, 100);
+ advanceClocks(ndn::time::milliseconds(10), 2);
+ publishAppData(1, data4, 100);
+ advanceClocks(ndn::time::milliseconds(10), 1);
+ publishAppData(1, data5, 200);
+
+ for (int i = 0; i < 100; i++) {
+ advanceClocks(ndn::time::milliseconds(2), 10);
+ passPacket();
+ }
+ setAppData(2, 100, data3);
+ advanceClocks(ndn::time::milliseconds(10), 1);
+ setAppData(1, 100, data4);
+ advanceClocks(ndn::time::milliseconds(10), 1);
+ setAppData(1, 200, data5);
+
+ advanceClocks(ndn::time::milliseconds(10), 7);
+ BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
+ BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
+
+ string data6 = "Shakespeare says: 'Prose before hos.'";
+ string data7 = "Pick good people, talent never wears out";
+ publishAppData(0, data6, 500);
+ publishAppData(1, data7, 300);
+
+ for (int i = 0; i < 100; i++) {
+ advanceClocks(ndn::time::milliseconds(2), 10);
+ passPacket();
+ }
+ setAppData(0, 500, data6);
+ setAppData(1, 300, data7);
+
+ BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
+ BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace test