static void dm_result_callback(lwm2m_transaction_t * transacP, void * message) { dm_data_t * dataP = (dm_data_t *)transacP->userData; if (message == NULL) { dataP->callback(((lwm2m_client_t*)transacP->peerP)->internalID, &dataP->uri, COAP_503_SERVICE_UNAVAILABLE, LWM2M_CONTENT_TEXT, NULL, 0, dataP->userData); } else { coap_packet_t * packet = (coap_packet_t *)message; //if packet is a CREATE response and the instanceId was assigned by the client if (packet->code == COAP_201_CREATED && packet->location_path != NULL) { char * locationString = NULL; int result = 0; lwm2m_uri_t locationUri; locationString = coap_get_multi_option_as_string(packet->location_path); if (locationString == NULL) { LOG("Error: coap_get_multi_option_as_string() failed for Location_path option in dm_result_callback()\n"); return; } result = lwm2m_stringToUri(locationString, strlen(locationString), &locationUri); if (result == 0) { LOG("Error: lwm2m_stringToUri() failed for Location_path option in dm_result_callback()\n"); lwm2m_free(locationString); return; } ((dm_data_t*)transacP->userData)->uri.instanceId = locationUri.instanceId; ((dm_data_t*)transacP->userData)->uri.flag = locationUri.flag; lwm2m_free(locationString); } dataP->callback(((lwm2m_client_t*)transacP->peerP)->internalID, &dataP->uri, packet->code, prv_convertMediaType(packet->content_type), packet->payload, packet->payload_len, dataP->userData); } lwm2m_free(dataP); }
coap_status_t handle_bootstrap_command(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_server_t * serverP, coap_packet_t * message, coap_packet_t * response) { coap_status_t result; lwm2m_media_type_t format; format = prv_convertMediaType(message->content_type); result = prv_check_server_status(serverP); if (result != COAP_NO_ERROR) return result; switch (message->code) { case COAP_PUT: { if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { if (object_isInstanceNew(contextP, uriP->objectId, uriP->instanceId)) { result = object_create(contextP, uriP, format, message->payload, message->payload_len); if (COAP_201_CREATED == result) { result = COAP_204_CHANGED; } } else { result = object_write(contextP, uriP, format, message->payload, message->payload_len); if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID && result == COAP_204_CHANGED) { prv_tag_server(contextP, uriP->instanceId); } } } else { result = BAD_REQUEST_4_00; } } break; case COAP_DELETE: { if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = BAD_REQUEST_4_00; } else { result = object_delete(contextP, uriP); if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID && result == COAP_202_DELETED) { if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { prv_tag_server(contextP, uriP->instanceId); } else { prv_tag_all_servers(contextP, NULL); } } } } break; case COAP_GET: case COAP_POST: default: result = BAD_REQUEST_4_00; break; } if (result == COAP_202_DELETED || result == COAP_204_CHANGED) { if (serverP->status != STATE_BS_PENDING) { serverP->status = STATE_BS_PENDING; contextP->state = STATE_BOOTSTRAPPING; } } return result; }
coap_status_t handle_dm_request(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, void * fromSessionH, coap_packet_t * message, coap_packet_t * response) { coap_status_t result; lwm2m_server_t * serverP = NULL; lwm2m_media_type_t format; #ifdef LWM2M_BOOTSTRAP lwm2m_server_t * bsServerP = NULL; #endif format = prv_convertMediaType(message->content_type); serverP = prv_findServer(contextP, fromSessionH); if (NULL == serverP) { #ifdef LWM2M_BOOTSTRAP bsServerP = utils_findBootstrapServer(contextP, fromSessionH); if (NULL == bsServerP) { // No server found return COAP_IGNORE; } #else return COAP_IGNORE; #endif } #ifdef LWM2M_BOOTSTRAP if (contextP->bsState != BOOTSTRAP_PENDING) { if (NULL != bsServerP) { // server initiated bootstrap? // currently not implemented. return NOT_IMPLEMENTED_5_01; } if ( serverP->status != STATE_REGISTERED && serverP->status != STATE_REG_UPDATE_PENDING) { return COAP_IGNORE; } } else { if (NULL != serverP) { // Request form management server during bootstrap. return UNAUTHORIZED_4_01; } } #endif switch (message->code) { case COAP_GET: { uint8_t * buffer = NULL; size_t length = 0; result = object_read(contextP, uriP, &format, &buffer, &length); if (COAP_205_CONTENT == result) { if (IS_OPTION(message, COAP_OPTION_OBSERVE)) { result = handle_observe_request(contextP, uriP, serverP, message, response); } if (COAP_205_CONTENT == result) { coap_set_header_content_type(response, format); coap_set_payload(response, buffer, length); // lwm2m_handle_packet will free buffer } else { lwm2m_free(buffer); } } } break; case COAP_POST: { #ifdef LWM2M_BOOTSTRAP /* no POST during bootstrap */ if (contextP->bsState == BOOTSTRAP_PENDING) return METHOD_NOT_ALLOWED_4_05; #endif if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) { lwm2m_media_type_t format; format = prv_convertMediaType(message->content_type); result = object_create(contextP, uriP, format, message->payload, message->payload_len); if (result == COAP_201_CREATED) { //longest uri is /65535/65535 = 12 + 1 (null) chars char location_path[13] = ""; //instanceId expected if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0) { result = COAP_500_INTERNAL_SERVER_ERROR; break; } if (sprintf(location_path, "/%d/%d", uriP->objectId, uriP->instanceId) < 0) { result = COAP_500_INTERNAL_SERVER_ERROR; break; } coap_set_header_location_path(response, location_path); } } else if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) { if (object_isInstanceNew(contextP, uriP->objectId, uriP->instanceId)) { result = object_create(contextP, uriP, format, message->payload, message->payload_len); } else { result = object_write(contextP, uriP, format, message->payload, message->payload_len); } } else { result = object_execute(contextP, uriP, message->payload, message->payload_len); } } break; case COAP_PUT: { if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { #ifdef LWM2M_BOOTSTRAP if (contextP->bsState == BOOTSTRAP_PENDING && object_isInstanceNew(contextP, uriP->objectId, uriP->instanceId)) { result = object_create(contextP, uriP, format, message->payload, message->payload_len); if (COAP_201_CREATED == result) { result = COAP_204_CHANGED; } } else #endif { result = object_write(contextP, uriP, format, message->payload, message->payload_len); } } else { result = BAD_REQUEST_4_00; } } break; case COAP_DELETE: { if (LWM2M_URI_IS_SET_INSTANCE(uriP) && !LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = object_delete(contextP, uriP); } else { result = BAD_REQUEST_4_00; } } break; default: result = BAD_REQUEST_4_00; break; } return result; }