blob: afb030775e7fa4d66a0f35ddd604e68d71ef3aa0 [file] [log] [blame]
Zhenkai Zhue4dc4d82013-01-23 13:17:08 -08001#include "ccnx-discovery.h"
2#include "simple-interval-generator.h"
3#include "task.h"
4#include "periodic-task.h"
5#include <sstream>
6#include <boost/make_shared.hpp>
7#include <boost/bind.hpp>
8
9using namespace Ccnx;
10using namespace std;
11
12const string
13TaggedFunction::CHAR_SET = string("abcdefghijklmnopqtrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
14
15TaggedFunction::TaggedFunction(const Callback &callback, const string &tag)
16 : m_callback(callback)
17 , m_tag(tag)
18{
19}
20
21string
22TaggedFunction::GetRandomTag()
23{
24 //boost::random::random_device rng;
25 boost::random::uniform_int_distribution<> dist(0, CHAR_SET.size() - 1);
26 ostringstream oss;
27 for (int i = 0; i < DEFAULT_TAG_SIZE; i++)
28 {
29 //oss << CHAR_SET[dist(rng)];
30 }
31 return oss.str();
32}
33
34void
35TaggedFunction::operator()(const Name &name)
36{
37 if (!m_callback.empty())
38 {
39 m_callback(name);
40 }
41}
42
43const double
44CcnxDiscovery::INTERVAL = 15.0;
45
46CcnxDiscovery *
47CcnxDiscovery::instance = NULL;
48
49boost::mutex
50CcnxDiscovery::mutex;
51
52CcnxDiscovery::CcnxDiscovery()
53 : m_scheduler(new Scheduler())
54 , m_localPrefix("/")
55{
56 m_scheduler->start();
Alexander Afanasyevfcf81dc2013-01-25 20:36:58 -080057
58 Scheduler::scheduleOneTimeTask (m_scheduler, 0,
59 boost::bind(&CcnxDiscovery::poll, this), "Initial-Local-Prefix-Check");
60 Scheduler::schedulePeriodicTask (m_scheduler,
61 boost::make_shared<SimpleIntervalGenerator>(INTERVAL),
62 boost::bind(&CcnxDiscovery::poll, this), "Local-Prefix-Check");
Zhenkai Zhue4dc4d82013-01-23 13:17:08 -080063}
64
65CcnxDiscovery::~CcnxDiscovery()
66{
67 m_scheduler->shutdown();
68}
69
70void
71CcnxDiscovery::addCallback(const TaggedFunction &callback)
72{
73 m_callbacks.push_back(callback);
74}
75
76int
77CcnxDiscovery::deleteCallback(const TaggedFunction &callback)
78{
79 List::iterator it = m_callbacks.begin();
80 while (it != m_callbacks.end())
81 {
82 if ((*it) == callback)
83 {
84 it = m_callbacks.erase(it);
85 }
86 else
87 {
88 ++it;
89 }
90 }
91 return m_callbacks.size();
92}
93
94void
95CcnxDiscovery::poll()
96{
97 Name localPrefix = CcnxWrapper::getLocalPrefix();
98 if (localPrefix != m_localPrefix)
99 {
100 Lock lock(mutex);
101 for (List::iterator it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
102 {
103 (*it)(localPrefix);
104 }
105 m_localPrefix = localPrefix;
106 }
107}
108
109void
110CcnxDiscovery::registerCallback(const TaggedFunction &callback)
111{
112 Lock lock(mutex);
113 if (instance == NULL)
114 {
115 instance = new CcnxDiscovery();
116 }
117
118 instance->addCallback(callback);
119}
120
121void
122CcnxDiscovery::deregisterCallback(const TaggedFunction &callback)
123{
124 Lock lock(mutex);
125 if (instance == NULL)
126 {
127 cerr << "CcnxDiscovery::deregisterCallback called without instance" << endl;
128 }
129 else
130 {
131 int size = instance->deleteCallback(callback);
132 if (size == 0)
133 {
134 delete instance;
135 instance = NULL;
136 }
137 }
138}
139