static void *_event_loop(void *args) { msg_t msg, reply; (void)args; msg_init_queue(_msg_q, GNRC_RPL_MSG_QUEUE_SIZE); /* preinitialize ACK */ reply.type = GNRC_NETAPI_MSG_TYPE_ACK; trickle_t *trickle; /* start event loop */ while (1) { DEBUG("RPL: waiting for incoming message.\n"); msg_receive(&msg); switch (msg.type) { case GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE: DEBUG("RPL: GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE received\n"); _update_lifetime(); break; case GNRC_RPL_MSG_TYPE_TRICKLE_INTERVAL: DEBUG("RPL: GNRC_RPL_MSG_TYPE_TRICKLE_INTERVAL received\n"); trickle = msg.content.ptr; if (trickle && (trickle->callback.func != NULL)) { trickle_interval(trickle); } break; case GNRC_RPL_MSG_TYPE_TRICKLE_CALLBACK: DEBUG("RPL: GNRC_RPL_MSG_TYPE_TRICKLE_CALLBACK received\n"); trickle = msg.content.ptr; if (trickle && (trickle->callback.func != NULL)) { trickle_callback(trickle); } break; case GNRC_NETAPI_MSG_TYPE_RCV: DEBUG("RPL: GNRC_NETAPI_MSG_TYPE_RCV received\n"); _receive(msg.content.ptr); break; case GNRC_NETAPI_MSG_TYPE_SND: break; case GNRC_NETAPI_MSG_TYPE_GET: case GNRC_NETAPI_MSG_TYPE_SET: DEBUG("RPL: reply to unsupported get/set\n"); reply.content.value = -ENOTSUP; msg_reply(&msg, &reply); break; default: break; } } return NULL; }
void trickle_start(kernel_pid_t pid, trickle_t *trickle, uint16_t interval_msg_type, uint16_t callback_msg_type, uint32_t Imin, uint8_t Imax, uint8_t k) { trickle->pid = pid; trickle->c = 0; trickle->k = k; trickle->Imin = Imin; trickle->Imax = Imax; trickle->I = trickle->Imin + (rand() % (4 * trickle->Imin)); trickle->pid = pid; trickle->interval_msg_type = interval_msg_type; trickle->callback_msg_type = callback_msg_type; trickle_interval(trickle); }
static void *_event_loop(void *args) { msg_t msg, reply; (void)args; msg_init_queue(_msg_q, GNRC_RPL_MSG_QUEUE_SIZE); /* preinitialize ACK */ reply.type = GNRC_NETAPI_MSG_TYPE_ACK; trickle_t *trickle; gnrc_rpl_dodag_t *dodag; /* start event loop */ while (1) { DEBUG("RPL: waiting for incoming message.\n"); msg_receive(&msg); switch (msg.type) { case GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE: DEBUG("RPL: GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE received\n"); _update_lifetime(); break; case GNRC_RPL_MSG_TYPE_TRICKLE_INTERVAL: DEBUG("RPL: GNRC_RPL_MSG_TYPE_TRICKLE_INTERVAL received\n"); trickle = (trickle_t *) msg.content.ptr; if (trickle && (trickle->callback.func != NULL)) { trickle_interval(trickle); } break; case GNRC_RPL_MSG_TYPE_TRICKLE_CALLBACK: DEBUG("RPL: GNRC_RPL_MSG_TYPE_TRICKLE_CALLBACK received\n"); trickle = (trickle_t *) msg.content.ptr; if (trickle && (trickle->callback.func != NULL)) { trickle_callback(trickle); } break; case GNRC_RPL_MSG_TYPE_DAO_HANDLE: DEBUG("RPL: GNRC_RPL_MSG_TYPE_DAO_HANDLE received\n"); dodag = (gnrc_rpl_dodag_t *) msg.content.ptr; if (dodag && (dodag->state != 0)) { _dao_handle_send(dodag); } break; case GNRC_RPL_MSG_TYPE_CLEANUP_HANDLE: DEBUG("RPL: GNRC_RPL_MSG_TYPE_CLEANUP received\n"); dodag = (gnrc_rpl_dodag_t *) msg.content.ptr; if (dodag && (dodag->state != 0) && (dodag->parents == NULL)) { /* no parents - delete this DODAG */ gnrc_rpl_dodag_remove(dodag); } break; case GNRC_NETAPI_MSG_TYPE_RCV: DEBUG("RPL: GNRC_NETAPI_MSG_TYPE_RCV received\n"); _receive((gnrc_pktsnip_t *)msg.content.ptr); break; case GNRC_NETAPI_MSG_TYPE_SND: case GNRC_NETAPI_MSG_TYPE_GET: case GNRC_NETAPI_MSG_TYPE_SET: DEBUG("RPL: reply to unsupported recv/get/set\n"); reply.content.value = -ENOTSUP; msg_reply(&msg, &reply); break; default: break; } } return NULL; }
void *rpl_process(void *arg) { (void) arg; msg_t m_recv; msg_init_queue(rpl_msg_queue, RPL_PKT_RECV_BUF_SIZE); rpl_dodag_t *dodag; trickle_t *trickle; while (1) { msg_receive(&m_recv); if (m_recv.type > ICMP_CODE_END) { switch (m_recv.type) { case RPL_MSG_TYPE_DAO_HANDLE: dodag = (rpl_dodag_t *) m_recv.content.ptr; if (dodag->joined) { _dao_handle_send(dodag); } break; case RPL_MSG_TYPE_ROUTING_ENTRY_UPDATE: _rpl_update_routing_table(); break; case RPL_MSG_TYPE_TRICKLE_INTERVAL: trickle = (trickle_t *) m_recv.content.ptr; if (trickle->callback.func != NULL) { trickle_interval(trickle); } break; case RPL_MSG_TYPE_TRICKLE_CALLBACK: trickle = (trickle_t *) m_recv.content.ptr; if (trickle->callback.func != NULL) { trickle_callback(trickle); } break; default: break; } } /* This is an RPL-related message. */ else { /* differentiate packet types */ ipv6_buf = (ipv6_hdr_t *) m_recv.content.ptr; memcpy(&rpl_buffer, ipv6_buf, NTOHS(ipv6_buf->length) + IPV6_HDR_LEN); if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) { /* get code for message-interpretation and process message */ DEBUGF("Received RPL information of type %04X and length %u\n", m_recv.type, NTOHS(ipv6_buf->length)); switch (m_recv.type) { case (ICMP_CODE_DIS): { rpl_recv_DIS(); break; } case (ICMP_CODE_DIO): { rpl_recv_DIO(); break; } case (ICMP_CODE_DAO): { rpl_recv_DAO(); break; } case (ICMP_CODE_DAO_ACK): { rpl_recv_DAO_ACK(); break; } default: break; } } #if RPL_DEFAULT_MOP == RPL_MOP_NON_STORING_MODE /* If the message is not RPL-type, it relates to non-storing mode */ else if (RPL_DEFAULT_MOP == RPL_MOP_NON_STORING_MODE) { if (ipv6_buf->nextheader == IPV6_PROTO_NUM_SRH) { srh_header = ((ipv6_srh_t *)(m_recv.content.ptr + IPV6_HDR_LEN)); /* if there are no segments left, the routing is finished */ if (srh_header->segments_left == 0) { DEBUGF("Source routing finished with next header: %02X.\n", srh_header->nextheader); DEBUGF("Size of srh: %d\n", srh_header->hdrextlen); uint8_t *payload = ((uint8_t *)(m_recv.content.ptr + IPV6_HDR_LEN + sizeof(ipv6_srh_t) + srh_header->hdrextlen)); rpl_remove_srh_header(ipv6_buf, payload, srh_header->nextheader); } else { internal_srh_process(srh_header); if (down_next_hop != NULL) { uint8_t *payload = ((uint8_t *)(m_recv.content.ptr + IPV6_HDR_LEN)); rpl_srh_sendto(payload, NTOHS(ipv6_buf->length), &ipv6_buf->srcaddr, down_next_hop, srh_header, 0); } } } #if RPL_MAX_ROUTING_ENTRIES != 0 else { srh_header = rpl_get_srh_header(ipv6_buf); if (srh_header != NULL) { uint8_t *payload = ((uint8_t *)(m_recv.content.ptr + IPV6_HDR_LEN)); rpl_srh_sendto(payload, NTOHS(ipv6_buf->length), &ipv6_buf->srcaddr, &ipv6_buf->destaddr, srh_header, srh_header->hdrextlen + sizeof(ipv6_srh_t)); } } #endif } #endif } } }