int vfs_node_write(struct vfs_inode *node) { if (node->is_root) return 0; if (object_write(node->ptr.object, node->ptr.offt, (const char*) &node->data, sizeof(node->data)) != SUCCESS) { warning("Write error on inode %016" PRIx64, node->ptr.object.index); return -EFAULT; } return 0; }
coap_status_t handle_dm_request(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, uint8_t * fromAddr, size_t fromAddrLen, coap_packet_t * message, coap_packet_t * response) { coap_status_t result; switch (message->code) { case COAP_GET: { char * buffer = NULL; int length = 0; result = object_read(contextP, uriP, &buffer, &length); if (result == COAP_205_CONTENT) { if (IS_OPTION(message, COAP_OPTION_OBSERVE)) { result = handle_observe_request(contextP, uriP, fromAddr, fromAddrLen, message, response); } if (result == COAP_205_CONTENT) { coap_set_payload(response, buffer, length); // lwm2m_handle_packet will free buffer } } } break; case COAP_POST: { result = object_create_execute(contextP, uriP, (char *)message->payload, message->payload_len); } break; case COAP_PUT: { result = object_write(contextP, uriP, (char *)message->payload, message->payload_len); } break; case COAP_DELETE: { result = object_delete(contextP, uriP); } break; default: result = BAD_REQUEST_4_00; break; } return result; }
int vfs_io_perform(struct vfs_inode *node, enum vfs_io_type type, char *buf, uint64_t size, off_t offset) { struct volume_object object; uint64_t chunk; uint32_t nlen, offt; int ret; object.index = node->data.ino; while (size) { chunk = offset >> OBJECT_MAX_SIZE_LOG2; offt = offset & ((1 << OBJECT_MAX_SIZE_LOG2) - 1); nlen = min(OBJECT_MAX_SIZE - offt, size); object.chunk = chunk; switch (type) { case VFS_IO_READ: if ((ret = object_read(object, offt, buf, nlen, NULL)) != SUCCESS) { if (ret == NOT_FOUND) { memset(buf, 0, nlen); } else { warning("Object read error on %016" PRIx64 ":%u: %d", node->data.ino, offt, ret); return -EFAULT; } } break; case VFS_IO_WRITE: if ((ret = object_write(object, offt, buf, nlen)) != SUCCESS) { warning("Object write error on %016" PRIx64 ":%u: %d", node->data.ino, offt, ret); return -EFAULT; } break; } size -= nlen; offset += nlen; buf += nlen; } return 0; }
uint8_t bootstrap_handleCommand(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", message->code); LOG_URI(uriP); format = utils_convertMediaType(message->content_type); result = prv_checkServerStatus(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_tagServer(contextP, uriP->instanceId); } } } else { lwm2m_data_t * dataP = NULL; int size = 0; int i; if (message->payload_len == 0 || message->payload == 0) { result = COAP_400_BAD_REQUEST; } else { size = lwm2m_data_parse(uriP, message->payload, message->payload_len, format, &dataP); if (size == 0) { result = COAP_500_INTERNAL_SERVER_ERROR; break; } for (i = 0 ; i < size ; i++) { if(dataP[i].type == LWM2M_TYPE_OBJECT_INSTANCE) { if (object_isInstanceNew(contextP, uriP->objectId, dataP[i].id)) { result = object_createInstance(contextP, uriP, &dataP[i]); if (COAP_201_CREATED == result) { result = COAP_204_CHANGED; } } else { result = object_writeInstance(contextP, uriP, &dataP[i]); if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID && result == COAP_204_CHANGED) { prv_tagServer(contextP, dataP[i].id); } } if(result != COAP_204_CHANGED) // Stop object create or write when result is error { break; } } else { result = COAP_400_BAD_REQUEST; } } lwm2m_data_free(size, dataP); } } } break; case COAP_DELETE: { if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = COAP_400_BAD_REQUEST; } 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_tagServer(contextP, uriP->instanceId); } else { prv_tagAllServer(contextP, NULL); } } } } break; case COAP_GET: case COAP_POST: default: result = COAP_400_BAD_REQUEST; 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; } } LOG_ARG("Server status: %s", STR_STATUS(serverP->status)); return result; }
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; }
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; }