void *rpl_process(void *arg) { (void) arg; msg_t m_recv; msg_init_queue(rpl_msg_queue, RPL_PKT_RECV_BUF_SIZE); while (1) { msg_receive(&m_recv); /* differentiate packet types */ ipv6_buf = ((ipv6_hdr_t *)m_recv.content.ptr); memcpy(&rpl_buffer, ipv6_buf, NTOHS(ipv6_buf->length) + IPV6_HDR_LEN); /* This is an RPL-related message. */ if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) { icmp_buf = ((icmpv6_hdr_t *)(m_recv.content.ptr + IPV6_HDR_LEN)); /* get code for message-interpretation and process message */ DEBUGF("Received RPL information of type %04X and length %u\n", icmp_buf->code, NTOHS(ipv6_buf->length)); switch (icmp_buf->code) { 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_NON_STORING_MODE /* If the message is not RPL-type, it relates to non-storing mode */ else if (RPL_DEFAULT_MOP == RPL_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); } } } 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 } }
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 } } }