uint8_t dm_handleRequest(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_server_t * serverP, coap_packet_t * message, coap_packet_t * response) { uint8_t result; lwm2m_media_type_t format; LOG_ARG("Code: %02X, server status: %s", message->code, STR_STATUS(serverP->status)); LOG_URI(uriP); if (IS_OPTION(message, COAP_OPTION_CONTENT_TYPE)) { format = utils_convertMediaType(message->content_type); } else { format = LWM2M_CONTENT_TLV; } if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID) { return COAP_404_NOT_FOUND; } if (serverP->status != STATE_REGISTERED && serverP->status != STATE_REG_UPDATE_NEEDED && serverP->status != STATE_REG_FULL_UPDATE_NEEDED && serverP->status != STATE_REG_UPDATE_PENDING) { return COAP_IGNORE; } // TODO: check ACL switch (message->code) { case COAP_GET: { uint8_t * buffer = NULL; size_t length = 0; int res; if (IS_OPTION(message, COAP_OPTION_OBSERVE)) { lwm2m_data_t * dataP = NULL; int size = 0; result = object_readData(contextP, uriP, &size, &dataP); if (COAP_205_CONTENT == result) { result = observe_handleRequest(contextP, uriP, serverP, size, dataP, message, response); if (COAP_205_CONTENT == result) { if (IS_OPTION(message, COAP_OPTION_ACCEPT)) { format = utils_convertMediaType(message->accept[0]); } else { format = LWM2M_CONTENT_TLV; } res = lwm2m_data_serialize(uriP, size, dataP, &format, &buffer); if (res < 0) { result = COAP_500_INTERNAL_SERVER_ERROR; } else { length = (size_t)res; LOG_ARG("Observe Request[/%d/%d/%d]: %.*s\n", uriP->objectId, uriP->instanceId, uriP->resourceId, length, buffer); } } lwm2m_data_free(size, dataP); } } else if (IS_OPTION(message, COAP_OPTION_ACCEPT) && message->accept_num == 1 && message->accept[0] == APPLICATION_LINK_FORMAT) { format = LWM2M_CONTENT_LINK; result = object_discover(contextP, uriP, serverP, &buffer, &length); } else { if (IS_OPTION(message, COAP_OPTION_ACCEPT)) { format = utils_convertMediaType(message->accept[0]); } result = object_read(contextP, uriP, &format, &buffer, &length); } 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: { if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) { 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); lwm2m_update_registration(contextP, 0, true); } } else if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) { 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 (IS_OPTION(message, COAP_OPTION_URI_QUERY)) { lwm2m_attributes_t attr; if (0 != prv_readAttributes(message->uri_query, &attr)) { result = COAP_400_BAD_REQUEST; } else { result = observe_setParameters(contextP, uriP, serverP, &attr); } } else if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { result = object_write(contextP, uriP, format, message->payload, message->payload_len); } else { result = COAP_400_BAD_REQUEST; } } break; case COAP_DELETE: { if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = COAP_400_BAD_REQUEST; } else { result = object_delete(contextP, uriP); if (result == COAP_202_DELETED) { lwm2m_update_registration(contextP, 0, true); } } } break; default: result = COAP_400_BAD_REQUEST; break; } 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; }