int MSFDSearchProvider::flag = 0;
long MSFDSearchProvider::ttl = 0;
+int MSFDSearchProvider::fd = 0;
+
class ResultMSFDServiceCallback : public Result_Base
{
public:
struct ip_mreq mreq;
char msgbuf[MSGBUFSIZE];
fd = 0;
- u_int yes = 1; /*** MODIFICATION TO ORIGINAL */
+ u_int yes = 1, no = 0; /*** MODIFICATION TO ORIGINAL */
/* create what looks like an ordinary UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- perror("socket");
MSF_DBG("MSFD socket faile");
return;
}
/**** MODIFICATION TO ORIGINAL */
/* allow multiple sockets to use the same PORT number */
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
- perror("Reusing ADDR failed");
MSF_DBG("MSFD reusing ADDR failed");
}
/*** END OF MODIFICATION TO ORIGINAL */
//dlog_print(DLOG_INFO, "MSF", "MSFD try bind socket");
/* bind to receive address */
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror("bind");
MSF_DBG("MSFD bind failed");
}
//dlog_print(DLOG_INFO, "MSF", "MSFD try bind socket success");
mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
- perror("setsockopt");
MSF_DBG("MSFD setsockopt failed");
}
- struct timeval tv = {2, 0};
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &no, sizeof(no)) < 0) {
+ MSF_DBG("MSFD setsockopt failed");
+ }
- if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
- perror("setsockopt");
- MSF_DBG("MSFD setsockopt(SOL_SOCKET) failed");
- }
+ int timerId = miscStartTimer(sendDiscovery, 2, NULL);
+ sendDiscovery(NULL);
while (1) {
addrlen = sizeof(msf_server_addr);
- if ((nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *) &msf_server_addr, &addrlen)) < 0) {
- if (fd < 1)
- return;
- } else {
+ nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *) &msf_server_addr, &addrlen);
+ if (fd < 1) {
+ miscStopTimer(timerId);
+ return;
+ }
+ if (nbytes > 0) {
msgbuf[nbytes] = '\0';
processReceivedMsg(msgbuf, nbytes);
}
}
}
+gboolean MSFDSearchProvider::__misc_timer_worker(gpointer ud)
+{
+ MSF_DBG("timer_work..");
+ gpointer *tdata = (gpointer*)ud;
+ if (tdata[0]) {
+ ((timer_function)tdata[0])(tdata[1]);
+ }
+ return true;
+}
+
+int MSFDSearchProvider::miscStartTimer(timer_function function, unsigned int interval, void *data)
+{
+ guint id = 0;
+ GSource *src = NULL;
+ gpointer *tdata = NULL;
+
+ MSF_DBG("misc_start_timer with interval[%d]", interval);
+ src = g_timeout_source_new(interval*1000);
+
+ tdata = g_new0(gpointer, 2);
+
+ tdata[0] = (void*)function;
+ tdata[1] = data;
+
+ g_source_set_callback(src, __misc_timer_worker, tdata, g_free);
+ id = g_source_attach(src, NULL);
+ g_source_unref(src);
+
+ MSF_DBG("Done with id[%d] in misc_start_timer", id);
+ return id;
+}
+
+void MSFDSearchProvider::miscStopTimer(int timer)
+{
+ guint id = (guint) timer;
+ MSF_DBG("Requested Stop Timer[%d]", id);
+ if (id) {
+ if (!g_source_remove(id)) {
+ MSF_ERR("g_source_remove is fail (timer)");
+ }
+ }
+}
+
+void MSFDSearchProvider::sendDiscovery(void* data)
+{
+ struct sockaddr_in dest;
+ socklen_t len = sizeof(dest);
+
+ /* set up destination address */
+ memset(&dest,0,sizeof(dest));
+ dest.sin_family=AF_INET;
+ dest.sin_addr.s_addr=inet_addr(MULTICAST_GROUP);
+ dest.sin_port=htons(MULTICAST_PORT);
+
+ string discovery = "{\"type\":\"discover\"}";
+
+ int ret = sendto(fd, discovery.c_str(), discovery.length(), 0, (struct sockaddr*)&dest, len);
+ if (ret != (int)discovery.length()) {
+ MSF_ERR("error : MSFD Failed(request size:%d, written size:%d)", discovery.length(), ret);
+ }
+}
+
void MSFDSearchProvider::processReceivedMsg(char *buf, int buflen)
{
if (buf == NULL)
string ip;
int port = 0;
+ if (url.empty()) {
+ MSF_DBG("url is empty");
+ return;
+ }
+
Channel::get_ip_port_from_uri(url, &ip, &port);
map<string,ttl_info>::iterator itr = aliveMap.find(ip);