Sensinode NSDL demo with WiFi interface

Dependencies:   Beep C12832_lcd LM75B MMA7660 WiflyInterface mbed-rtos mbed nsdl_lib

Fork of NSDL_HelloWorld by Sensinode

main.cpp

Committer:
terohoo
Date:
2013-10-09
Revision:
0:2edbfea18d23
Child:
1:e35d7f10999a

File content as of revision 0:2edbfea18d23:

/* Define DEBUG for USB serial communication */
#define DEBUG

#include "mbed.h"
#include "EthernetInterface.h"
#include "C12832_lcd.h"
#include "LM75B.h"
#include "MMA7660.h"
#include "Beep.h"
/* Sensinode includes */
#include "sn_nsdl.h"
#include "sn_coap_header.h"
#include "sn_coap_protocol.h"
#include "sn_nsdl_lib.h"

#include "resource_generation_help.h"

/* Define this to enable DHCP, otherwise manual address configuration is used */
#define DHCP

/* Manual IP configurations, if DHCP not defined */
#define IP      "10.45.0.206"
#define MASK    "255.255.255.0"
#define GW      "10.45.0.1"

/* Change this IP address to that of your NanoService Platform installation */
const char* NSP_ADDRESS = "10.45.3.42"; /* internal NSP*/
const int NSP_PORT = 5683;

uint8_t nsp_addr[4];

/* The number of seconds between NSP registration messages */
#define RD_UPDATE_PERIOD  60

/* Resource paths and registration parameters */
static uint8_t res_mgf[] = {"dev/mfg"};
static uint8_t res_mgf_val[] = {"Sensinode"};
static uint8_t res_mdl[] = {"dev/mdl"};
static uint8_t res_mdl_val[] = {"NSDL-C power node"};
static uint8_t res_temp[] = {"sen/temp"};
static uint8_t res_light[] = {"lt/0/dim"};
static uint8_t res_gps[] = {"gps/loc"};
static uint8_t res_gps_val[] = {"52.182382,0.178849"};
static uint8_t res_rel[] = {"lt/0/on"};

static uint8_t ep_type[] = {"PowerNode"};
static uint8_t lifetime_ptr[] = {"1200"};

/* stored data for observable resource */
uint8_t obs_number = 0;
uint8_t *obs_token_ptr = 0;
uint8_t obs_token_len = 0;
char temp_val[5];

/* App board related stuff */
Beep buzzer(p26);
//PwmOut led1(LED1);
PwmOut led2(LED2);
PwmOut led3(LED3);
//PwmOut led4(LED4);
#ifdef DEBUG
Serial pc(USBTX, USBRX); // tx, rx
#endif
C12832_LCD lcd;
LM75B tmp(p28,p27);
MMA7660 MMA(p28, p27);

EthernetInterface eth;
UDPSocket server;
Endpoint nsp;
Endpoint from;

/* For creating uniq name for board.. */
char mbed_uid[33];
char endpoint_name[15] = "MyMbedexam";

extern "C"
{
uint8_t tx_cb(sn_nsdl_capab_e protocol, uint8_t *data_ptr, uint16_t data_len, sn_nsdl_addr_s *address_ptr);
uint8_t rx_cb(sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr);
void *own_alloc(uint16_t size);
void own_free(void* ptr_to_free);
static uint8_t temp_resource_cb(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s * proto);
static uint8_t light_resource_cb(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s * proto);
static uint8_t gps_resource_cb(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s * proto);
static uint8_t relay_resource_cb(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s * proto);
}

/* Thread for handling registration updates */
void registration_update_thread(void const *args)
{
    sn_nsdl_ep_parameters_s *endpoint_ptr = 0;
    while(true)
    {
        wait(RD_UPDATE_PERIOD);
        INIT_REGISTER_NSDL_ENDPOINT(endpoint_ptr, (uint8_t*)endpoint_name, ep_type, lifetime_ptr);
        if(sn_nsdl_register_endpoint(endpoint_ptr) != 0)
            pc.printf("NSP re-registering failed\r\n");
        else
            pc.printf("NSP re-registering OK\r\n");
        CLEAN_REGISTER_NSDL_ENDPOINT(endpoint_ptr);

    }
}

/* Thread for calling libNsdl exec function (cleanup, resendings etc..) */
/* Node updates temperature every 10 seconds. Notification sending is done here. */
void exec_call_thread(void const *args)
{
    int32_t time = 0;
    while (true)
    {
        wait(1);
        time++;
        sn_nsdl_exec(time);
        if((!(time % 10)) && obs_number != 0)
        {
            obs_number++;
            sprintf(temp_val,"%2.2f" ,tmp.read());
            if(sn_nsdl_send_observation_notification(obs_token_ptr, obs_token_len, (uint8_t*)temp_val, 5, &obs_number, 1, COAP_MSG_TYPE_NON_CONFIRMABLE, 0) == 0)
                pc.printf("Observation sending failed\r\n");
            else
                pc.printf("Observation\r\n");
        }
    }
}

int main()
{

    Thread registration_thread(registration_update_thread);
    Thread exec_thread(exec_call_thread);

    sn_nsdl_mem_s memory_cbs;
    sn_nsdl_resource_info_s *resource_ptr = 0;
    sn_nsdl_ep_parameters_s *endpoint_ptr = 0;
    sn_nsdl_addr_s received_packet_address;
    uint8_t received_address[4];

    memset(&received_packet_address, 0, sizeof(sn_nsdl_addr_s));
    received_packet_address.addr_ptr = received_address;

    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("mbed NanoService demo");
#ifdef DEBUG
    pc.printf("mbed NanoService Example App 0.1\n\n\r");
#endif

    /* Initialize network */
#ifdef DHCP
#ifdef DEBUG
    pc.printf("DHCP in use\r\n");
#endif
    eth.init();
#else
    eth.init(IP, MASK, GW);
#endif
    if(eth.connect(30000) == 0)
        pc.printf("Connect OK\n\r");

    mbed_interface_uid(mbed_uid);
    mbed_uid[32] = '\0';
    memcpy(&endpoint_name[10], &mbed_uid[27], 5);

    lcd.locate(0,11);
    lcd.printf("IP:%s", eth.getIPAddress());

#ifdef DEBUG
    pc.printf("IP Address:%s \n\r", eth.getIPAddress());
#endif
    server.init();
    server.bind(NSP_PORT);

    nsp.set_address(NSP_ADDRESS,NSP_PORT);

#ifdef DEBUG
    pc.printf("name: %s\n\r", endpoint_name);
    pc.printf("NSP=%s - port %d\r\n\n",NSP_ADDRESS, NSP_PORT);
#endif

    lcd.locate(0,22);
    lcd.printf("EP name:%s", endpoint_name);

    memory_cbs.sn_nsdl_alloc = &own_alloc;
    memory_cbs.sn_nsdl_free = &own_free;

    /* Initialize libNsdl */
    if(sn_nsdl_init(&tx_cb, &rx_cb, &memory_cbs) == -1)
        pc.printf("libNsdl init failed\r\n");
    else
        pc.printf("libNsdl init done\r\n");

    /* Set nsp address for library */
    set_NSP_address(nsp_addr, 5683, SN_NSDL_ADDRESS_TYPE_IPV4);

#ifdef DEBUG
    pc.printf("Creating resources\r\n");
#endif
    /* Create resources */
    resource_ptr = (sn_nsdl_resource_info_s*)own_alloc(sizeof(sn_nsdl_resource_info_s));
    if(!resource_ptr)
        return 0;
    memset(resource_ptr, 0, sizeof(sn_nsdl_resource_info_s));

    resource_ptr->resource_parameters_ptr = (sn_nsdl_resource_parameters_s*)own_alloc(sizeof(sn_nsdl_resource_parameters_s));
    if(!resource_ptr->resource_parameters_ptr)
    {
        own_free(resource_ptr);
        return 0;
    }
    memset(resource_ptr->resource_parameters_ptr, 0, sizeof(sn_nsdl_resource_parameters_s));

    /* Static resurces */
    CREATE_STATIC_RESOURCE(resource_ptr, sizeof(res_mgf)-1, (uint8_t*) res_mgf, 0, 0,  (uint8_t*) res_mgf_val, sizeof(res_mgf_val)-1);
    CREATE_STATIC_RESOURCE(resource_ptr, sizeof(res_mdl)-1, (uint8_t*) res_mdl, 0, 0,  (uint8_t*) res_mdl_val, sizeof(res_mdl_val)-1);

    CREATE_DYNAMIC_RESOURCE(resource_ptr, sizeof(res_temp)-1, (uint8_t*) res_temp, 0, 0, 1, &temp_resource_cb, SN_GRS_GET_ALLOWED);
    CREATE_DYNAMIC_RESOURCE(resource_ptr, sizeof(res_light)-1, (uint8_t*) res_light, 0, 0, 0, &light_resource_cb, (SN_GRS_GET_ALLOWED | SN_GRS_PUT_ALLOWED));
    CREATE_DYNAMIC_RESOURCE(resource_ptr, sizeof(res_gps)-1, (uint8_t*) res_gps, 0, 0, 0, &gps_resource_cb, SN_GRS_GET_ALLOWED);
    CREATE_DYNAMIC_RESOURCE(resource_ptr, sizeof(res_rel)-1, (uint8_t*) res_rel, 0, 0, 0, &relay_resource_cb, (SN_GRS_GET_ALLOWED | SN_GRS_PUT_ALLOWED));


        /* Register with NSP */
    INIT_REGISTER_NSDL_ENDPOINT(endpoint_ptr, (uint8_t*)endpoint_name, ep_type, lifetime_ptr);

    if(sn_nsdl_register_endpoint(endpoint_ptr) != 0)
        pc.printf("NSP registering failed\r\n");
    else
        pc.printf("NSP registering OK\r\n");

    CLEAN_REGISTER_NSDL_ENDPOINT(endpoint_ptr);

    own_free(resource_ptr->resource_parameters_ptr);
    own_free(resource_ptr);

    char buffer[1024];
    while(1)
    {
        int n = server.receiveFrom(from, buffer, sizeof(buffer));
        if (n < 0)
        {
            pc.printf("Socket error\n\r");
        }
        else
        {   
            pc.printf("Received %d bytes\r\n", n);
            sn_nsdl_process_coap((uint8_t*)buffer, n, &received_packet_address);
        }
    }
}
uint8_t tx_cb(sn_nsdl_capab_e protocol, uint8_t *data_ptr, uint16_t data_len, sn_nsdl_addr_s *address_ptr)
{
    pc.printf("TX callback!\n\rSending %d bytes:\r\n", data_len);

    if(server.sendTo(nsp, (char*)data_ptr, data_len) != data_len)
        pc.printf("sending failed\n\r");

    return 1;
}


uint8_t rx_cb(sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr)
{
    pc.printf("RX callback!\r\n");

    return 0;
}

void *own_alloc(uint16_t size)
{
    return malloc(size);
}

void own_free(void* ptr_to_free)
{
    free(ptr_to_free);
}

/* Only GET method allowed */
/* Observable resource */
static uint8_t temp_resource_cb(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s * proto)
{
    sprintf(temp_val,"%2.2f" ,tmp.read());
    sn_coap_hdr_s *coap_res_ptr = 0;

    pc.printf("temp callback\r\n");
    coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT);

    coap_res_ptr->payload_len = 5;
    coap_res_ptr->payload_ptr = (uint8_t*)temp_val;

    if(received_coap_ptr->token_ptr)
    {
        pc.printf("Token included\r\n");
        if(obs_token_ptr)
        {
            free(obs_token_ptr);
            obs_token_ptr = 0;
        }
        obs_token_ptr = (uint8_t*)malloc(received_coap_ptr->token_len);
        if(obs_token_ptr)
        {
            memcpy(obs_token_ptr, received_coap_ptr->token_ptr, received_coap_ptr->token_len);
            obs_token_len = received_coap_ptr->token_len;
        }
    }

    if(received_coap_ptr->options_list_ptr->observe)
    {
        coap_res_ptr->options_list_ptr = (sn_coap_options_list_s*)malloc(sizeof(sn_coap_options_list_s));
        memset(coap_res_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
        coap_res_ptr->options_list_ptr->observe_ptr = &obs_number;
        coap_res_ptr->options_list_ptr->observe_len = 1;
        obs_number++;
    }

    sn_nsdl_send_coap_message(address, coap_res_ptr);

    /* sn_coap_release.... */
    if(coap_res_ptr->options_list_ptr)
        free(coap_res_ptr->options_list_ptr);
    if(coap_res_ptr->token_ptr)
    {
        own_free(coap_res_ptr->token_ptr);
    }
    own_free(coap_res_ptr);
    return 0;
}

/* Only GET and PUT method allowed */
static uint8_t light_resource_cb(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s * proto)
{
    sn_coap_hdr_s *coap_res_ptr = 0;
    static float led_dimm = 0;
    int led_state = 0;
    char led_dimm_temp[4];

    pc.printf("light callback\r\n");

    if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET)
    {
        coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT);

        led_state = led_dimm * 100;
        sprintf(led_dimm_temp, "%d", led_state);

        coap_res_ptr->payload_len = strlen(led_dimm_temp);
        coap_res_ptr->payload_ptr = (uint8_t*)led_dimm_temp;
    }
    if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT)
    {
        memcpy(led_dimm_temp, (char *)received_coap_ptr->payload_ptr, received_coap_ptr->payload_len);

        led_dimm_temp[received_coap_ptr->payload_len] = '\0';

        led_dimm = atof(led_dimm_temp);
        led_dimm = led_dimm/100;

        //led1.write(led_dimm);
        led2.write(led_dimm);
        led3.write(led_dimm);
        //led4.write(led_dimm);

        coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CHANGED);
    }

    sn_nsdl_send_coap_message(address, coap_res_ptr);

    /* sn_coap_release.... */
    if(coap_res_ptr->token_ptr)
    {
        own_free(coap_res_ptr->token_ptr);
    }
    own_free(coap_res_ptr);
    return 0;
}

/* Only GET method allowed */
static uint8_t gps_resource_cb(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s * proto)
{
    sn_coap_hdr_s *coap_res_ptr = 0;
    static float led_dimm = 0;
    int led_state = 0;
    char led_dimm_temp[4];

    pc.printf("gps callback\r\n");

    coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT);

    led_state = led_dimm * 100;
    sprintf(led_dimm_temp, "%d", led_state);

    coap_res_ptr->payload_len = sizeof(res_gps_val)-1;
    coap_res_ptr->payload_ptr = (uint8_t*)res_gps_val;

    sn_nsdl_send_coap_message(address, coap_res_ptr);

    /* sn_coap_release.... */
    if(coap_res_ptr->token_ptr)
    {
        own_free(coap_res_ptr->token_ptr);
    }
    own_free(coap_res_ptr);
    return 0;
}

/* Only GET and PUT method allowed */
static uint8_t relay_resource_cb(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s * proto)
{
    sn_coap_hdr_s *coap_res_ptr = 0;
    static uint8_t relay_state = '0';

    pc.printf("relay callback\r\n");

    if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET)
    {
        coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT);

        coap_res_ptr->payload_len = 1;
        coap_res_ptr->payload_ptr = &relay_state;
    }
    if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT)
    {
        if(received_coap_ptr->payload_len)
        {
            if(*(received_coap_ptr->payload_ptr) == '1')
            {
                buzzer.beep(1000,0);
                relay_state = '1';
                
            }
            else if(*(received_coap_ptr->payload_ptr) == '0')
            {
                buzzer.nobeep();
                relay_state = '0';
            }
            
            coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CHANGED);
            
        }
    }

    sn_nsdl_send_coap_message(address, coap_res_ptr);

    /* sn_coap_release.... */
    if(coap_res_ptr->token_ptr)
    {
        own_free(coap_res_ptr->token_ptr);
    }
    own_free(coap_res_ptr);
    return 0;
}