main.c 9.6 KB
/*
 * Copyright (C) 2015 Freie Universität Berlin
 *
 * This file is subject to the terms and conditions of the GNU Lesser
 * General Public License v2.1. See the file LICENSE in the top level
 * directory for more details.
 */

/**
 * @ingroup     examples
 * @{
 *
 * @file
 * @brief       Example application for demonstrating the RIOT network stack
 *
 * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
 *
 * @}
 */

#include <stdio.h>
#include <inttypes.h>
#include <errno.h>
#include "kernel_types.h"
#include "byteorder.h"
#include "thread.h"
#include "net/gnrc/ipv6.h"
#include "net/gnrc/udp.h"
#include "net/gnrc.h"
#include "net/ipv6/addr.h"
#include "net/ipv6/hdr.h"
#include "net/udp.h"
#include "net/sixlowpan.h"
#include "od.h"
#include "periph/timer.h"
#include "../../boards/stm32f4discovery/include/board.h"
#include "../../boards/stm32f4discovery/include/periph_conf.h"
#include "periph/pwm.h"
#include "shell.h"
#include "msg.h"

#ifndef GNRC_PKTDUMP_MSG_QUEUE_SIZE
#define GNRC_PKTDUMP_MSG_QUEUE_SIZE     (8U)
#endif

/**
 * @brief   Priority of the pktdump thread
 */
#ifndef GNRC_PKTDUMP_PRIO
#define GNRC_PKTDUMP_PRIO               (THREAD_PRIORITY_MAIN - 1)
#endif

/**
 * @brief   Stack size used for the pktdump thread
 */
#ifndef GNRC_PKTDUMP_STACKSIZE
#define GNRC_PKTDUMP_STACKSIZE          (THREAD_STACKSIZE_MAIN)
#endif
//#define DST
#define MAIN_QUEUE_SIZE     (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];

extern int udp_cmd(int argc, char **argv);
static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL,
                                                               KERNEL_PID_UNDEF);
unsigned rssi_dest, lqi_dest;
typedef struct mon_attribute {
    uint8_t rssi;      
    uint8_t lqi;     
} Data_quality;

#ifdef DST
    ipv6_hdr_t* ipv6_HDR;
    Data_quality data_quality;
#endif
    
//uint8_t node[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x34,0x51,0x0b,0x33,0x0b,0x34,0x0a};
#ifdef DST
static void reply_quality(ipv6_addr_t addr, char *port_str, Data_quality* data)

{
    uint16_t port;
    port = (uint16_t)atoi(port_str);
    if (port == 0) {
        puts("Error: unable to parse destination port");
        return;
    }

    
        gnrc_pktsnip_t *payload, *udp, *ip;
       // unsigned payload_size;
        payload=gnrc_pktbuf_add(NULL, data, sizeof(data), GNRC_NETTYPE_UNDEF);
        if (payload == NULL) {
            puts("Error: unable to copy data to packet buffer");
            return;
        }
        // store size for output
        //payload_size = (unsigned)payload->size;
        // allocate UDP header, set source port := destination port 
        udp = gnrc_udp_hdr_build(payload, port, port);
        if (udp == NULL) {
            puts("Error: unable to allocate UDP header");
            gnrc_pktbuf_release(payload);
            return;
        }
        // allocate IPv6 header
        ip = gnrc_ipv6_hdr_build(udp, NULL, &addr);
        if (ip == NULL) {
            puts("Error: unable to allocate IPv6 header");
            gnrc_pktbuf_release(udp);
            return;
        }
        // send packet
        printf("RSSI %u LQI %u \n",data->rssi,data->lqi);
        printf("%d\n",port);
        if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip)) {
            puts("Error: unable to locate UDP thread");
            gnrc_pktbuf_release(ip);
            return;
        }
      
        //printf("Success: send %u byte to [%s]:%u\n", payload_size, addr_str,port);
    
}
#endif
/***************************************************************************************/
//copy pktdump


/**
 * @brief   PID of the pktdump thread
 */
static kernel_pid_t copy_pktd_pid = KERNEL_PID_UNDEF;



/**
 * @brief   Stack for the pktdump thread
 */
static char _stack[GNRC_PKTDUMP_STACKSIZE];

static void _dump_snip(gnrc_pktsnip_t *pkt)
{

    switch (pkt->type) {
        case GNRC_NETTYPE_UNDEF:
            printf("NETTYPE_UNDEF (%i)\n", pkt->type);
            //od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT);
            Data_quality* pkt_rcv=pkt->data;
            printf("MON_RSSI %d MON_LQI %d \n",pkt_rcv->rssi,pkt_rcv->lqi); 
	    /*if(strcmp((char *)pkt->data,"go")==0)
	    {
		//pwm_set(PWM_DEV(0),1,25);
		ordre = 1;
		timer_set(XTIMER_DEV,0,8400);
		timer_clear(TIMER_DEV(1),0);
	    }
	    else 
	    {
		//pwm_set(PWM_DEV(0),1,0);
		ordre = 0;
	    }*/
           
            break;
#ifdef MODULE_GNRC_NETIF
        case GNRC_NETTYPE_NETIF:
            printf("NETTYPE_NETIF (%i)\n", pkt->type);
            gnrc_netif_hdr_print(pkt->data);
#ifdef DST
            gnrc_netif_hdr_t* header=(gnrc_netif_hdr_t*)pkt->data;
            data_quality.rssi=(uint8_t)header->rssi;
            data_quality.lqi=(uint8_t)header->lqi;
            printf("MES DATA:%u ---- %u\n",data_quality.rssi,data_quality.lqi);
#endif
            break;
#endif
#ifdef MODULE_GNRC_SIXLOWPAN
        case GNRC_NETTYPE_SIXLOWPAN:
            printf("NETTYPE_SIXLOWPAN (%i)\n", pkt->type);
            //sixlowpan_print(pkt->data, pkt->size);
            break;
#endif
#ifdef MODULE_GNRC_IPV6
        case GNRC_NETTYPE_IPV6:
            printf("NETTYPE_IPV6 (%i)\n", pkt->type);
#ifdef DST
            ipv6_hdr_print(pkt->data);
            //ipv6_HDR= (ipv6_hdr_t*)pkt->data;
            //char addr_str[IPV6_ADDR_MAX_STR_LEN];
            ipv6_HDR = (ipv6_hdr_t*)pkt->data;
           // ipv6_addr_to_str(addr_str, &ipv6_HDR->src,sizeof(addr_str));
            //printf("mon-test : %s\n",addr_str);
            //ipv6_HDR =(ipv6_addr_t)pkt->data;
#endif
            break;
#endif
#ifdef MODULE_GNRC_ICMPV6
        case GNRC_NETTYPE_ICMPV6:
            printf("NETTYPE_ICMPV6 (%i)\n", pkt->type);
            break;
#endif
#ifdef MODULE_GNRC_TCP
        case GNRC_NETTYPE_TCP:
            printf("NETTYPE_TCP (%i)\n", pkt->type);
            break;
#endif
#ifdef MODULE_GNRC_UDP
        case GNRC_NETTYPE_UDP:
            printf("NETTYPE_UDP (%i)\n", pkt->type);
            udp_hdr_print(pkt->data);
            
            break;
#endif
#ifdef TEST_SUITES
        case GNRC_NETTYPE_TEST:
            printf("NETTYPE_TEST (%i)\n", pkt->type);
            //od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT);
            break;
#endif
        default:
            printf("NETTYPE_UNKNOWN (%i)\n", pkt->type);
            //od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT);
            break;
    }
}

static void _dump(gnrc_pktsnip_t *pkt)
{
    int snips = 0;
    int size = 0;
    gnrc_pktsnip_t *snip = pkt;

    while (snip != NULL) {
        printf("~~ SNIP %2i - size: %3u byte, type: ", snips,
               (unsigned int)snip->size);
        _dump_snip(snip);
        ++snips;
        size += snip->size;
        snip = snip->next;
    }

    printf("~~ PKT    - %2i snips, total size: %3i byte\n", snips, size);
    gnrc_pktbuf_release(pkt);
    #ifdef DST
    reply_quality(ipv6_HDR->src,"8888",&data_quality);
#endif
}

static void *_eventloop(void *arg)
{
    (void)arg;
    msg_t msg, reply;
    msg_t msg_queue[GNRC_PKTDUMP_MSG_QUEUE_SIZE];

    /* setup the message queue */
    msg_init_queue(msg_queue, GNRC_PKTDUMP_MSG_QUEUE_SIZE);

    reply.content.value = (uint32_t)(-ENOTSUP);
    reply.type = GNRC_NETAPI_MSG_TYPE_ACK;

    while (1) {
        msg_receive(&msg);

        switch (msg.type) {
            case GNRC_NETAPI_MSG_TYPE_RCV:
                puts("PKTDUMP: data received:");
                _dump(msg.content.ptr);
                break;
            case GNRC_NETAPI_MSG_TYPE_SND:
                puts("PKTDUMP: data to send:");
                _dump(msg.content.ptr);
                break;
            case GNRC_NETAPI_MSG_TYPE_GET:
            case GNRC_NETAPI_MSG_TYPE_SET:
                msg_reply(&msg, &reply);
                break;
            default:
                puts("PKTDUMP: received something unexpected");
                break;
        }
    }

    /* never reached */
    return NULL;
}

kernel_pid_t gnrc_pktdump_init(void)
{
    if (copy_pktd_pid == KERNEL_PID_UNDEF) {
        copy_pktd_pid = thread_create(_stack, sizeof(_stack), GNRC_PKTDUMP_PRIO,
                             THREAD_CREATE_STACKTEST,
                             _eventloop, NULL, "pktdump_copy");
    }
    return copy_pktd_pid;
}
//end copy pktdump
/***************************************************************************************/


static void start_server(char *port_str)
{
    uint16_t port;

    /* check if server is already running */
    if (server.target.pid != KERNEL_PID_UNDEF) {
        printf("Error: server already running on port %" PRIu32 "\n",
               server.demux_ctx);
        return;
    }
    /* parse port */
    port = (uint16_t)atoi(port_str);
    if (port == 0) {
        puts("Error: invalid port specified");
        return;
    }
    /* start server (which means registering pktdump for the chosen port) */
    server.target.pid = copy_pktd_pid;
    server.demux_ctx = (uint32_t)port;
    gnrc_netreg_register(GNRC_NETTYPE_UDP, &server);
    printf("Success: started UDP server on port %" PRIu16 "\n", port);
}

static const shell_command_t shell_commands[] = {
    { "udp", "send data over UDP and listen on UDP ports", udp_cmd },
    { NULL, NULL, NULL }
};


int main(void)
{
    /* we need a message queue for the thread running the shell in order to
     * receive potentially fast incoming networking packets */
    msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
    puts("RIOT network stack example application");
    gnrc_pktdump_init();
    start_server("8888");
    /* start shell */
    puts("All up, running the shell now");
    char line_buf[SHELL_DEFAULT_BUFSIZE];
    shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);

    /* should be never reached */
    return 0;
}