00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <dlfcn.h>
00038 #include <errno.h>
00039 #include <sys/time.h>
00040
00041 #include "mesh_protocol.h"
00042 #include "sensor_self.h"
00043 #include "mesh_discovery.h"
00044 #include "mesh_link.h"
00045 #include "mesh_net.h"
00046
00047
00048 u_int64_t get_current_time(void)
00049 {
00050 struct timeval tv;
00051 gettimeofday(&tv, NULL);
00052
00053 return ((u_int64_t)tv.tv_sec) * 1000 + ((u_int64_t)tv.tv_usec) / 1000;
00054 }
00055
00056
00057
00058 int add_protocol(self_t *self, char *name, int id, char *path,
00059 unsigned int tmo, unsigned char pro, unsigned char re,
00060 char *discovery_fctn, char *route_send_fctn,
00061 char *route_recv_fctn, char *socket_mod_fctn)
00062 {
00063 int rc;
00064 char *errstr;
00065 protocol_t *proto = malloc(sizeof(protocol_t));
00066
00067 proto->sensor = self;
00068 strncpy(proto->name, name, PROTO_NAMELEN);
00069 proto->unique_id = id;
00070 proto->timeout = tmo;
00071 proto->proactive = pro;
00072 proto->reactive = re;
00073
00074 if ((proto->lib_handle = dlopen(path, RTLD_LAZY)) == NULL) {
00075 syslog(LOG_ERR, "add_protocol: %s", dlerror());
00076 free(proto);
00077 return -1;
00078 }
00079
00080 proto->mesh_init_discovery = dlsym(proto->lib_handle, discovery_fctn);
00081 if ((errstr = dlerror()) != NULL) {
00082 syslog(LOG_ERR, "add_protocol (discovery fctn): %s", errstr);
00083 dlclose(proto->lib_handle);
00084 free(proto);
00085 return -1;
00086 }
00087
00088 proto->mesh_route_send = dlsym(proto->lib_handle, route_send_fctn);
00089 if ((errstr = dlerror()) != NULL) {
00090 syslog(LOG_ERR, "add_protocol (send fctn): %s", errstr);
00091 dlclose(proto->lib_handle);
00092 free(proto);
00093 return -1;
00094 }
00095
00096 proto->mesh_route_recv = dlsym(proto->lib_handle, route_recv_fctn);
00097 if ((errstr = dlerror()) != NULL) {
00098 syslog(LOG_ERR, "add_protocol (recv fctn): %s", errstr);
00099 dlclose(proto->lib_handle);
00100 free(proto);
00101 return -1;
00102 }
00103
00104 if (self->last_p != NULL)
00105 self->last_p->next = proto;
00106
00107 if (self->protocols == NULL) {
00108 self->protocols = proto;
00109 self->last_p = proto;
00110 }
00111 self->last_p = proto;
00112
00113 if ((rc = pthread_create(&proto->discover_thread, NULL,
00114 discover_network, self)) < 0) {
00115 syslog(LOG_ERR, "discover network: %m");
00116 return -1;
00117 }
00118
00119 return 0;
00120 }
00121
00122
00123 int delete_protocol(self_t *self, char *string)
00124 {
00125 protocol_t *prev = NULL, *iter = self->protocols;
00126 while (iter != NULL) {
00127 if (strcasecmp(string, iter->name) == 0) {
00128 if (prev == NULL)
00129 self->protocols = iter->next;
00130 else
00131 prev->next = iter->next;
00132 dlclose(iter->lib_handle);
00133 free(iter);
00134 return 0;
00135 }
00136 prev = iter;
00137 iter = iter->next;
00138 }
00139 return -1;
00140 }
00141
00142
00143 protocol_t *protocol_by_string(self_t *self, char *string)
00144 {
00145 protocol_t *iter = self->protocols;
00146 while (iter != NULL) {
00147 if (strcasecmp(string, iter->name) == 0)
00148 return iter;
00149 iter = iter->next;
00150 }
00151 return NULL;
00152 }
00153
00154
00155 protocol_t *protocol_by_id(self_t *self, int id)
00156 {
00157 int i = 0;
00158 protocol_t *iter = self->protocols;
00159 while (iter != NULL) {
00160 if (iter->unique_id == id)
00161 return iter;
00162 iter = iter->next;
00163 i++;
00164 }
00165 return NULL;
00166 }
00167
00168
00169 int recv_mesh_discovery(protocol_t *proto, int sd, int reply_size)
00170 {
00171 if (proto == NULL || proto->sensor == NULL) {
00172 errno = EINVAL;
00173 return -1;
00174 }
00175
00176 return proto->mesh_route_recv(proto, sd, reply_size);
00177 }
00178
00179
00180 ssize_t send_routes(self_t *self, int sd, database_t *db,
00181 unsigned int num_links, struct sockaddr_in *to)
00182 {
00183 int db_size = database_size(num_links);
00184
00185 pack_database(db);
00186
00187 return mesh_sendmsg(self->interface, self->mac_addr, sd, db, db_size, to);
00188 }
00189
00190
00191 ssize_t receive_routes(int sd, database_t *db, unsigned int num_links,
00192 struct sockaddr_in *from, struct msghdr *msg_header,
00193 size_t ctl_msg_size)
00194 {
00195 int nbytes, db_size = database_size(num_links);
00196
00197 if ((nbytes = mesh_recvmsg(sd, db, db_size, from,
00198 msg_header, ctl_msg_size)) < 0)
00199 return nbytes;
00200
00201 unpack_database(db);
00202 return nbytes;
00203 }