Esempio n. 1
0
/* Only GET method allowed */
static uint8_t door_trip_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;
    snprintf(door_trip_val,2,"%d" ,current_door_trip_value);
    pc.printf("door_trip callback\r\n");
    pc.printf("door_trip: %s\r\n", door_trip_val);
 
    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 = strlen(door_trip_val);
        coap_res_ptr->payload_ptr = (uint8_t*)door_trip_val;
        
        coap_res_ptr->content_type_ptr = &content_type;
        coap_res_ptr->content_type_len = sizeof(content_type);
        

        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++;
        }
        pc.printf("   Send observation %d... \r\n", obs_number);
 
        sn_nsdl_send_coap_message(address, coap_res_ptr);
        nsdl_free(coap_res_ptr->options_list_ptr);
        coap_res_ptr->options_list_ptr = NULL;
        coap_res_ptr->content_type_ptr = NULL;// parser_release below tries to free this memory
 
    }
 
    sn_coap_parser_release_allocated_coap_msg_mem(coap_res_ptr);
 
    return 0;
}
/* 
Callback for LWM2M (CoAP REST) operations allowed on the resosurce
GET and PUT methods allowed 
*/
static uint8_t LWM2M_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;

    if(COAP_MSG_CODE_REQUEST_GET == received_coap_ptr->msg_code){
        coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT);
   
        current_sample = LWM2M_Sensor.read() * (float) 100;
        sprintf(LWM2M_value_string,"%3.1f", current_sample);
        pc.printf("LWM2M resource callback\r\n");
        pc.printf("LWM2M resource state %s\r\n", LWM2M_value_string);
   
        coap_res_ptr->payload_len = strlen(LWM2M_value_string);
        coap_res_ptr->payload_ptr = (uint8_t*)LWM2M_value_string;
        
        coap_res_ptr->content_type_ptr = &LWM2M_content_type;
        coap_res_ptr->content_type_len = sizeof(LWM2M_content_type);
        
        coap_res_ptr->options_list_ptr = (sn_coap_options_list_s*)nsdl_alloc(sizeof(sn_coap_options_list_s));
        if(!coap_res_ptr->options_list_ptr){
            pc.printf("cant alloc option list\r\n");
            coap_res_ptr->options_list_ptr = NULL; //FIXME report error and recover
        }
        else{
            memset(coap_res_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
            coap_res_ptr->options_list_ptr->max_age_ptr = &LWM2M_max_age;
            coap_res_ptr->options_list_ptr->max_age_len = sizeof(LWM2M_max_age);
        }
        
        if(received_coap_ptr->token_ptr){
            pc.printf("Token included\r\n");
            // replace any existing token
            if(LWM2M_obs_token_ptr){   
                free(LWM2M_obs_token_ptr);
                LWM2M_obs_token_ptr = 0;
            }
            //with new token
            LWM2M_obs_token_ptr = (uint8_t*)malloc(received_coap_ptr->token_len);
            if(LWM2M_obs_token_ptr){
                memcpy(LWM2M_obs_token_ptr, received_coap_ptr->token_ptr, received_coap_ptr->token_len);
                LWM2M_obs_token_len = received_coap_ptr->token_len;
            }
        }

        if(received_coap_ptr->options_list_ptr->observe) {
            // get observe start/stop value from received GET
            LWM2M_obs_option = * received_coap_ptr->options_list_ptr->observe_ptr;   
            // start or stop based on option value 
            // ref. draft-ietf-core-observe-16          
            if (START_OBS == LWM2M_obs_option){
                coap_res_ptr->options_list_ptr->observe_ptr = &LWM2M_obs_number;
                coap_res_ptr->options_list_ptr->observe_len = sizeof(LWM2M_obs_number);
                LWM2M_start_notification(); 
            }
            else if (STOP_OBS == LWM2M_obs_option){
                LWM2M_stop_notification();
            }
        }
 
        sn_nsdl_send_coap_message(address, coap_res_ptr);
        nsdl_free(coap_res_ptr->options_list_ptr);
        coap_res_ptr->options_list_ptr = NULL;
        coap_res_ptr->content_type_ptr = NULL;// parser_release below tries to free this memory
    }
    
    /* 
    PUT needs to be enabled for the write attributes operation which is empty payload + query options
    */
    else if(COAP_MSG_CODE_REQUEST_PUT == received_coap_ptr->msg_code){
        //pc.printf("PUT: %d bytes\r\n", received_coap_ptr->payload_len);
        if((received_coap_ptr->payload_len > 0) && (received_coap_ptr->payload_len <= 5)){
            memcpy(LWM2M_update_string, (char *)received_coap_ptr->payload_ptr, received_coap_ptr->payload_len);
            LWM2M_update_string[received_coap_ptr->payload_len] = '\0';
            pc.printf("PUT: %s\r\n", LWM2M_update_string);

            sscanf( LWM2M_update_string, "%f3.1", &current_sample); //update for read-back test, observe will clobber

            coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CHANGED);
            sn_nsdl_send_coap_message(address, coap_res_ptr);
        }
        // see if there are query options and scan for write attributes, allow payload and query options
        // PUT without query ffrom web client reads some query string, wireshark it...
        if(received_coap_ptr->options_list_ptr->uri_query_ptr != NULL){
            LWM2M_query_string_ptr = (char*)nsdl_alloc(received_coap_ptr->options_list_ptr->uri_query_len+1);
            if (LWM2M_query_string_ptr){
                memcpy(LWM2M_query_string_ptr, 
                    received_coap_ptr->options_list_ptr->uri_query_ptr, 
                    received_coap_ptr->options_list_ptr->uri_query_len);
                memset(LWM2M_query_string_ptr + received_coap_ptr->options_list_ptr->uri_query_len,'\0',1);//string terminator
                // diagnostic
                // pc.printf("query string received: %s\r\n", LWM2M_query_string_ptr);
                attribute_update = false;
                // extract query options from string
                query_option = strtok(LWM2M_query_string_ptr, "&");// split the string
                num_options = 0;
                while (query_option != NULL){
                    strcpy(query_options[num_options++], query_option);
                    // pc.printf("query part: %s\r\n", query_option);
                    query_option = strtok(NULL, "&");// next query option
                }
                // pc.printf("setting attributes\r\n");
                for (int option = 0; option < num_options; option++)
                    set_notification_attribute(query_options[option]);

                nsdl_free(LWM2M_query_string_ptr);
                // if anything was updated, re-initialize the stored notification attributes
                if (attribute_update){
                    // initializes and sends an update if observing is on, don't change observing state
                    // allows cancel to turn off observing and updte state without sending a notification
                    LWM2M_notification_init(); 
                    coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CHANGED); // 2.04
                }
                else
                    // if query options are sent but no notification attribute names were found, it's an error
                    coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_BAD_REQUEST);// 4.00
                    
                sn_nsdl_send_coap_message(address, coap_res_ptr);

            }
            else
                pc.printf("cant alloc query string\r\n"); 
        }
    }

    sn_coap_parser_release_allocated_coap_msg_mem(coap_res_ptr);

    return 0;
}