41 #define DISCOVERY_NEIGHBOUR_CACHE 3
42 #define DISCOVERY_CYCLE 5
43 #define DISCOVERY_NEIGHBOUR_TIMEOUT (5*DISCOVERY_CYCLE)
44 #define DISCOVERY_IPND_SERVICE "lowpancl"
45 #define DISCOVERY_IPND_BUFFER_LEN 60
46 #define DISCOVERY_IPND_WHITELIST 0
49 #define IPND_FLAGS_SOURCE_EID (1<<0)
50 #define IPND_FLAGS_SERVICE_BLOCK (1<<1)
51 #define IPND_FLAGS_BLOOMFILTER (1<<2)
57 struct discovery_basic_neighbour_list_entry {
58 struct discovery_basic_neighbour_list_entry *
next;
60 unsigned long timestamp_last;
61 unsigned long timestamp_discovered;
65 PROCESS(discovery_process,
"DISCOVERY process");
71 MEMB(neighbour_mem,
struct discovery_basic_neighbour_list_entry, DISCOVERY_NEIGHBOUR_CACHE);
73 uint8_t discovery_status = 0;
74 static struct etimer discovery_timeout_timer;
75 static struct etimer discovery_cycle_timer;
76 uint16_t discovery_sequencenumber = 0;
78 rimeaddr_t discovery_whitelist[DISCOVERY_IPND_WHITELIST];
94 #if DISCOVERY_IPND_WHITELIST > 0
96 memset(&discovery_whitelist, 0,
sizeof(rimeaddr_t) * DISCOVERY_IPND_WHITELIST);
100 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_WRN,
"Whitelist enabled");
114 struct discovery_basic_neighbour_list_entry *
entry;
116 if( discovery_status == 0 ) {
123 entry = entry->next) {
138 discovery_status = 1;
147 discovery_status = 0;
199 if( discovery_status == 0 ) {
213 if( payload[offset++] != 0x02 ) {
214 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_WRN,
"IPND version mismatch");
219 uint8_t
flags = payload[offset++];
222 uint16_t sequenceNumber = ((payload[offset] & 0xFF) << 8) + (payload[offset+1] & 0xFF);
226 if( flags & IPND_FLAGS_SOURCE_EID ) {
230 if( flags & IPND_FLAGS_SERVICE_BLOCK ) {
234 if( flags & IPND_FLAGS_BLOOMFILTER ) {
238 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_DBG,
"Discovery from %lu with flags %02X and seqNo %u", eid, flags, sequenceNumber);
245 uint8_t ipnd_buffer[DISCOVERY_IPND_BUFFER_LEN];
246 char string_buffer[20];
251 memset(ipnd_buffer, 0, DISCOVERY_IPND_BUFFER_LEN);
254 ipnd_buffer[offset++] = 0x02;
257 ipnd_buffer[offset++] = IPND_FLAGS_SOURCE_EID | IPND_FLAGS_SERVICE_BLOCK;
260 ipnd_buffer[offset++] = (discovery_sequencenumber & 0xFF00) << 8;
261 ipnd_buffer[offset++] = (discovery_sequencenumber & 0x00FF) << 0;
262 discovery_sequencenumber ++;
273 ipnd_buffer[offset++] = 1;
276 len = sprintf(string_buffer, DISCOVERY_IPND_SERVICE);
277 offset +=
sdnv_encode(len, &ipnd_buffer[offset], DISCOVERY_IPND_BUFFER_LEN - offset);
278 memcpy(&ipnd_buffer[offset], string_buffer, len);
282 len = sprintf(string_buffer,
"ip=%lu;port=%u;", dtn_node_id, IEEE802154_PANID);
283 offset +=
sdnv_encode(len, &ipnd_buffer[offset], DISCOVERY_IPND_BUFFER_LEN - offset);
284 memcpy(&ipnd_buffer[offset], string_buffer, len);
288 rimeaddr_t destination = {{0, 0}};
289 convergence_layer_send_discovery(ipnd_buffer, offset, &destination);
301 #if DISCOVERY_IPND_WHITELIST > 0
304 for(i=0; i<DISCOVERY_IPND_WHITELIST; i++) {
305 if(
rimeaddr_cmp(&discovery_whitelist[i], neighbour) ) {
312 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_WRN,
"Ignoring peer %u.%u, not on whitelist", neighbour->u8[0], neighbour->u8[1]);
317 struct discovery_basic_neighbour_list_entry *
entry;
319 if( discovery_status == 0 ) {
326 entry = entry->next) {
329 entry->timestamp_last = clock_seconds();
343 struct discovery_basic_neighbour_list_entry *
entry;
345 if( discovery_status == 0 ) {
350 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_INF,
"Neighbour %u.%u disappeared", neighbour->u8[0], neighbour->u8[1]);
353 convergence_layer_neighbour_down(neighbour);
357 entry = entry->next) {
378 if( discovery_status == 0 ) {
388 struct discovery_basic_neighbour_list_entry *
entry;
391 if( entry ==
NULL ) {
392 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_WRN,
"no more space for neighbours");
396 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_INF,
"Found new neighbour %u.%u", neighbour->u8[0], neighbour->u8[1]);
399 memset(entry, 0,
sizeof(
struct discovery_basic_neighbour_list_entry));
403 entry->timestamp_last = clock_seconds();
404 entry->timestamp_discovered = clock_seconds();
412 process_post(&agent_process, dtn_beacon_event, &entry->neighbour);
440 etimer_set(&discovery_cycle_timer, DISCOVERY_CYCLE * CLOCK_SECOND);
441 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_INF,
"Discovery process running");
447 struct discovery_basic_neighbour_list_entry *
entry;
451 entry = entry->next) {
452 if( entry->active && (clock_seconds() - entry->timestamp_last) > DISCOVERY_NEIGHBOUR_TIMEOUT ) {
453 LOG(LOGD_DTN, LOG_DISCOVERY, LOGL_DBG,
"Neighbour %u.%u timed out: %lu vs. %lu = %lu", entry->neighbour.u8[0], entry->neighbour.u8[1],
clock_time(), entry->timestamp_last,
clock_time() - entry->timestamp_last);