/* 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", ¤t_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; }