00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <unistd.h>
00038 #include <string.h>
00039 #include <sys/types.h>
00040 #include <sys/socket.h>
00041 #include <sys/time.h>
00042 #include <sys/select.h>
00043 #include <sys/ioctl.h>
00044 #include <netinet/in.h>
00045 #include <arpa/inet.h>
00046 #include <net/route.h>
00047 #include <errno.h>
00048 #include <syslog.h>
00049 #include <netdb.h>
00050 #include <pthread.h>
00051 #include <sched.h>
00052
00053 #include "sensor_self.h"
00054 #include "mesh_link.h"
00055 #include "mesh_discovery.h"
00056
00057
00058 pthread_mutex_t mesh_send_mutex = PTHREAD_MUTEX_INITIALIZER;
00059
00060
00061
00062 int propagate_routes(protocol_t *proto, int flags)
00063 {
00064 int sd, error = 0;
00065
00066 if (proto == NULL) {
00067 errno = EINVAL;
00068 return -1;
00069 }
00070
00071 if (!proto->proactive)
00072 return 0;
00073
00074 pthread_mutex_lock(&mesh_send_mutex);
00075 if ((sd = mesh_socket(proto->sensor->interface, MESH_DISCOVERY_PORT)) < 0) {
00076 pthread_mutex_unlock(&mesh_send_mutex);
00077 return sd;
00078 }
00079 pthread_mutex_unlock(&mesh_send_mutex);
00080
00081 if ((error = proto->mesh_route_send(proto, sd, flags)) < 0)
00082 return error;
00083
00084 close(sd);
00085 return error;
00086 }
00087
00088
00089
00090 static int run_discovery(protocol_t *proto)
00091 {
00092 int sd, error;
00093
00094 if (proto == NULL) {
00095 errno = EINVAL;
00096 return -1;
00097 }
00098
00099 if ((sd = mesh_socket(proto->sensor->interface, MESH_DISCOVERY_PORT)) < 0)
00100 return sd;
00101
00102 while (1) {
00103 header_t header;
00104 struct sockaddr_in their_addr;
00105 memset(&their_addr, 0, sizeof(their_addr));
00106 memset(&header, 0, header_size());
00107
00108 if ((error = timed_recv_peek(sd, &header, header_size(),
00109 &their_addr, proto->timeout)) <= 0) {
00110 if (error == -1)
00111 syslog(LOG_ERR, "timed_recv: %m");
00112 if (error == -2)
00113 propagate_routes(proto, MESH_DISCOVER);
00114 continue;
00115 }
00116 unpack_header(&header);
00117
00118 if (header.protocol != proto->unique_id) {
00119 int found = 0;
00120 protocol_t *cur = proto->sensor->protocols;
00121 while (cur != NULL) {
00122 if (cur->unique_id == header.protocol) {
00123 found++;
00124 break;
00125 }
00126 }
00127 if (!found)
00128 recv(sd, &header, header_size(), 0);
00129 else
00130 sched_yield();
00131 continue;
00132 }
00133 if (strcmp(proto->sensor->ip_addr, inet_ntoa(their_addr.sin_addr)) == 0) {
00134 recv(sd, &header, header_size(), 0);
00135 continue;
00136 }
00137 #if DEBUG
00138 syslog(LOG_INFO, "size %u", header.size);
00139 syslog(LOG_INFO, "protocol %u, %s (%u)",
00140 header.protocol, proto->name, proto->unique_id);
00141 #endif
00142
00143 pthread_mutex_lock(&mesh_send_mutex);
00144 if (recv_mesh_discovery(proto, sd, header.size) < 0)
00145 syslog(LOG_ERR, "recv_mesh_discovery: %m");
00146 pthread_mutex_unlock(&mesh_send_mutex);
00147 }
00148 close(sd);
00149 return 0;
00150 }
00151
00152
00153 void *discover_network(void *arg)
00154 {
00155 protocol_t *proto = (protocol_t*)arg;
00156 if (proto == NULL)
00157 return NULL;
00158 run_discovery(proto);
00159 return NULL;
00160 }