コード例 #1
0
ファイル: gnrc_rpl.c プロジェクト: aabadie/RIOT
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;
}
コード例 #2
0
ファイル: trickle.c プロジェクト: centurysys/RIOT
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);
}
コード例 #3
0
ファイル: gnrc_rpl.c プロジェクト: ntrtrung/RIOT
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;
}
コード例 #4
0
ファイル: rpl.c プロジェクト: mm3/RIOT
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
        }
    }
}