static void prv_backup_objects(lwm2m_context_t * context) { uint16_t i; for (i = 0; i < BACKUP_OBJECT_COUNT; i++) { if (NULL != backupObjectArray[i]) { switch (backupObjectArray[i]->objID) { case LWM2M_SECURITY_OBJECT_ID: clean_security_object(backupObjectArray[i]); lwm2m_free(backupObjectArray[i]); break; case LWM2M_SERVER_OBJECT_ID: clean_server_object(backupObjectArray[i]); lwm2m_free(backupObjectArray[i]); break; default: break; } } backupObjectArray[i] = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); if(backupObjectArray[i] != NULL) memset(backupObjectArray[i], 0, sizeof(lwm2m_object_t)); } /* * Backup content of objects 0 (security) and 1 (server) */ copy_security_object(backupObjectArray[0], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID)); copy_server_object(backupObjectArray[1], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID)); }
static void prv_tagServer(lwm2m_context_t * contextP, uint16_t id) { lwm2m_server_t * targetP; targetP = (lwm2m_server_t *)LWM2M_LIST_FIND(contextP->bootstrapServerList, id); if (targetP == NULL) { targetP = (lwm2m_server_t *)LWM2M_LIST_FIND(contextP->serverList, id); } if (targetP != NULL) { targetP->dirty = true; } }
uint8_t object_checkReadable(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { coap_status_t result; lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) return COAP_205_CONTENT; if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_205_CONTENT; size = 1; dataP = lwm2m_data_new(1); if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; dataP->id = uriP->resourceId; result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); lwm2m_data_free(1, dataP); return result; }
coap_status_t object_delete(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { lwm2m_object_t * objectP; coap_status_t result; objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == objectP) return COAP_404_NOT_FOUND; if (NULL == objectP->deleteFunc) return COAP_405_METHOD_NOT_ALLOWED; LOG(" Call to object_delete\r\n"); if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = objectP->deleteFunc(uriP->instanceId, objectP); } else { lwm2m_list_t * instanceP; result = COAP_202_DELETED; instanceP = objectP->instanceList; while (NULL != instanceP && result == COAP_202_DELETED) { result = objectP->deleteFunc(instanceP->id, objectP); instanceP = objectP->instanceList; } } return result; }
coap_status_t object_write(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { coap_status_t result = NO_ERROR; lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) { result = COAP_404_NOT_FOUND; } else if (NULL == targetP->writeFunc) { result = COAP_405_METHOD_NOT_ALLOWED; } else { size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); if (size == 0) { result = COAP_406_NOT_ACCEPTABLE; } } if (result == NO_ERROR) { result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP); lwm2m_data_free(size, dataP); } return result; }
TEST_F(AddRemoveServerTests, AddServer) { uint8_t s = lwm2m_add_server(123, LWM2M_SERVER_ADDR, 100, false, NULL, NULL, 0); ASSERT_EQ(s, COAP_205_CONTENT); ASSERT_EQ(client_context->state, STATE_INITIAL); security_instance_t* secInstance = (security_instance_t*)securityObj->instanceList; server_instance_t* serverInstance = (server_instance_t*)serverObj->instanceList; ASSERT_EQ(123, secInstance->shortID); ASSERT_EQ(123, serverInstance->shortServerId); char uriBuffer[100]; ASSERT_TRUE(lwm2m_get_server_uri(secInstance->instanceId,uriBuffer, sizeof(uriBuffer))); ASSERT_STREQ(uriBuffer, LWM2M_SERVER_ADDR); time_t timeout; uint8_t result = lwm2m_step(client_context, &timeout); ASSERT_EQ(COAP_NO_ERROR, result); ASSERT_EQ(STATE_REGISTERING, client_context->state); lwm2m_server_t * serverListEntry; serverListEntry = (lwm2m_server_t *)LWM2M_LIST_FIND(client_context->serverList, secInstance->instanceId); ASSERT_TRUE(serverListEntry); }
coap_status_t object_readData(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, int * sizeP, lwm2m_data_t ** dataP) { coap_status_t result; lwm2m_object_t * targetP; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; if (targetP->instanceList == NULL) return COAP_404_NOT_FOUND; if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; // single instance read if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { *sizeP = 1; *dataP = lwm2m_data_new(*sizeP); if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; (*dataP)->id = uriP->resourceId; } result = targetP->readFunc(uriP->instanceId, sizeP, dataP, targetP); } else { // multiple object instances read lwm2m_list_t * instanceP; int i; *sizeP = 0; for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) { (*sizeP)++; } *dataP = lwm2m_data_new(*sizeP); if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; result = COAP_205_CONTENT; instanceP = targetP->instanceList; i = 0; while (instanceP != NULL && result == COAP_205_CONTENT) { result = targetP->readFunc(instanceP->id, (int*)&((*dataP)[i].value.asChildren.count), &((*dataP)[i].value.asChildren.array), targetP); (*dataP)[i].type = LWM2M_TYPE_OBJECT_INSTANCE; (*dataP)[i].id = instanceP->id; i++; instanceP = instanceP->next; } } return result; }
void handle_value_changed(lwm2m_context_t * lwm2mH, lwm2m_uri_t * uri, const char * value, size_t valueLength) { lwm2m_object_t * object = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri->objectId); if (NULL != object) { if (object->writeFunc != NULL) { lwm2m_data_t * dataP; int result; dataP = lwm2m_data_new(1); if (dataP == NULL) { fprintf(stderr, "Internal allocation failure !\n"); return; } dataP->id = uri->resourceId; lwm2m_data_encode_nstring(value, valueLength, dataP); result = object->writeFunc(uri->instanceId, 1, dataP, object); if (COAP_405_METHOD_NOT_ALLOWED == result) { switch (uri->objectId) { case LWM2M_DEVICE_OBJECT_ID: result = device_change(dataP, object); break; default: break; } } if (COAP_204_CHANGED != result) { fprintf(stderr, "Failed to change value!\n"); } else { fprintf(stderr, "value changed!\n"); lwm2m_resource_value_changed(lwm2mH, uri); } lwm2m_data_free(1, dataP); return; } else { fprintf(stderr, "write not supported for specified resource!\n"); } return; } else { fprintf(stderr, "Object not found !\n"); } }
coap_status_t object_create(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; uint8_t result; if (length == 0 || buffer == 0) { return COAP_400_BAD_REQUEST; } targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED; size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); if (size <= 0) return COAP_400_BAD_REQUEST; switch (dataP[0].type) { case LWM2M_TYPE_OBJECT: result = COAP_400_BAD_REQUEST; goto exit; case LWM2M_TYPE_OBJECT_INSTANCE: if (size != 1) { result = COAP_400_BAD_REQUEST; goto exit; } if (NULL != lwm2m_list_find(targetP->instanceList, dataP[0].id)) { // Instance already exists result = COAP_406_NOT_ACCEPTABLE; goto exit; } result = targetP->createFunc(dataP[0].id, dataP[0].value.asChildren.count, dataP[0].value.asChildren.array, targetP); uriP->instanceId = dataP[0].id; uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; break; default: uriP->instanceId = lwm2m_list_newId(targetP->instanceList); uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; result = targetP->createFunc(uriP->instanceId, size, dataP, targetP); break; } exit: lwm2m_data_free(size, dataP); return result; }
char * get_server_uri(lwm2m_object_t * objectP, uint16_t secObjInstID) { security_instance_t * targetP = (security_instance_t *)LWM2M_LIST_FIND(objectP->instanceList, secObjInstID); if (NULL != targetP) { return lwm2m_strdup(targetP->uri); } return NULL; }
coap_status_t object_execute(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, uint8_t * buffer, size_t length) { lwm2m_object_t * targetP; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->executeFunc) return COAP_405_METHOD_NOT_ALLOWED; return targetP->executeFunc(uriP->instanceId, uriP->resourceId, buffer, length, targetP); }
static void prv_restore_objects(lwm2m_context_t * context) { lwm2m_object_t * targetP; /* * Restore content of objects 0 (security) and 1 (server) */ targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID); // first delete internal content clean_security_object(targetP); // then restore previous object copy_security_object(targetP, backupObjectArray[0]); targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID); // first delete internal content clean_server_object(targetP); // then restore previous object copy_server_object(targetP, backupObjectArray[1]); // restart the old servers fprintf(stdout, "[BOOTSTRAP] ObjectList restored\r\n"); }
coap_status_t object_writeInstance(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_data_t * dataP) { lwm2m_object_t * targetP; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->writeFunc) { return COAP_405_METHOD_NOT_ALLOWED; } return targetP->writeFunc(dataP->id, dataP->value.asChildren.count, dataP->value.asChildren.array, targetP); }
bool object_isInstanceNew(lwm2m_context_t * contextP, uint16_t objectId, uint16_t instanceId) { lwm2m_object_t * targetP; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, objectId); if (targetP != NULL) { if (NULL != lwm2m_list_find(targetP->instanceList, instanceId)) { return false; } } return true; }
static void prv_object_dump(char *buffer, void *user_data) { lwm2mH = (lwm2m_context_t *) user_data; lwm2m_uri_t uri; char *end = NULL; int result; lwm2m_object_t *objectP; end = get_end_of_arg(buffer); if (end[0] == 0) { goto syntax_error; } result = lwm2m_stringToUri(buffer, end - buffer, &uri); if (result == 0) { goto syntax_error; } if (uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) { goto syntax_error; } objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri.objectId); if (objectP == NULL) { fprintf(stdout, "Object not found.\n"); return; } if (uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) { prv_instance_dump(objectP, uri.instanceId); } else { lwm2m_list_t *instanceP; for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next) { fprintf(stdout, "Instance %d:\r\n", instanceP->id); prv_instance_dump(objectP, instanceP->id); fprintf(stdout, "\r\n"); } } return; syntax_error: fprintf(stdout, "Syntax error !\n"); }
int lwm2m_add_object(lwm2m_context_t * contextP, lwm2m_object_t * objectP) { lwm2m_object_t * targetP; LOG_ARG("ID: %d", objectP->objID); targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, objectP->objID); if (targetP != NULL) return COAP_406_NOT_ACCEPTABLE; objectP->next = NULL; contextP->objectList = (lwm2m_object_t *)LWM2M_LIST_ADD(contextP->objectList, objectP); if (contextP->state == STATE_READY) { return lwm2m_update_registration(contextP, 0, true); } return COAP_NO_ERROR; }
static void prv_remove(char *buffer, void *user_data) { lwm2mH = (lwm2m_context_t *)user_data; int res; lwm2m_object_t * objectP; objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, 1024); res = lwm2m_remove_object(lwm2mH, 1024); if (res != 0) { fprintf(stdout, "Removing object 1024 failed: "); print_status(stdout, res); fprintf(stdout, "\r\n"); } else { fprintf(stdout, "Object 1024 removed.\r\n"); free_test_object(objectP); objArray[5] = NULL; } return; }
coap_status_t object_create(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; uint8_t result; if (length == 0 || buffer == 0) { return COAP_400_BAD_REQUEST; } targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED; if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { if (NULL != lwm2m_list_find(targetP->instanceList, uriP->instanceId)) { // Instance already exists return COAP_406_NOT_ACCEPTABLE; } } else { uriP->instanceId = lwm2m_list_newId(targetP->instanceList); uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; } size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); if (size == 0) return COAP_500_INTERNAL_SERVER_ERROR; result = targetP->createFunc(uriP->instanceId, size, dataP, targetP); lwm2m_data_free(size, dataP); return result; }
void * lwm2m_connect_server(uint16_t secObjInstID, void * userData) { client_data_t * dataP; lwm2m_list_t * instance; dtls_connection_t * newConnP = NULL; dataP = (client_data_t *)userData; lwm2m_object_t * securityObj = dataP->securityObjP; instance = LWM2M_LIST_FIND(dataP->securityObjP->instanceList, secObjInstID); if (instance == NULL) return NULL; newConnP = connection_create(dataP->connList, dataP->sock, securityObj, instance->id, dataP->lwm2mH, dataP->addressFamily); if (newConnP == NULL) { fprintf(stderr, "Connection creation failed.\n"); return NULL; } dataP->connList = newConnP; return (void *)newConnP; }
TEST_F(AddRemoveServerTests, RemoveServer) { uint8_t result; time_t timeout; uint8_t s = lwm2m_add_server(123, LWM2M_SERVER_ADDR, 100, false, NULL, NULL, 0); ASSERT_EQ(s, COAP_205_CONTENT); security_instance_t* secInstance = (security_instance_t*)securityObj->instanceList; // Add server to serverlist result = lwm2m_step(client_context, &timeout); lwm2m_server_t * serverListEntry; serverListEntry = (lwm2m_server_t *)LWM2M_LIST_FIND(client_context->serverList, secInstance->instanceId); ASSERT_TRUE(serverListEntry); // Now assume registering worked serverListEntry->status = STATE_REGISTERED; serverListEntry->location = (char*)lwm2m_malloc(1); // Unregister now lwm2m_unregister_server(secInstance->instanceId); ASSERT_EQ(serverListEntry->status, STATE_DEREG_PENDING); serverListEntry->status = STATE_DEREGISTERED; lwm2m_remove_unregistered_servers(); ASSERT_FALSE(securityObj->instanceList); ASSERT_FALSE(serverObj->instanceList); ASSERT_TRUE(client_context->serverList); ASSERT_EQ(client_context->state, STATE_INITIAL); result = lwm2m_step(client_context, &timeout); ASSERT_EQ(client_context->state, STATE_BOOTSTRAP_REQUIRED); ASSERT_FALSE(client_context->serverList); }
uint8_t object_checkNumeric(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { coap_status_t result; lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size; if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_405_METHOD_NOT_ALLOWED; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; size = 1; dataP = lwm2m_data_new(1); if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; dataP->id = uriP->resourceId; result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); if (result == COAP_205_CONTENT) { switch (dataP->type) { case LWM2M_TYPE_INTEGER: case LWM2M_TYPE_FLOAT: break; default: result = COAP_405_METHOD_NOT_ALLOWED; } } lwm2m_data_free(1, dataP); return result; }
static void prv_send_command(internal_data_t * dataP, endpoint_t * endP) { int res; if (endP->cmdList == NULL) return; switch (endP->cmdList->operation) { case BS_DELETE: fprintf(stdout, "Sending DELETE "); prv_print_uri(stdout, endP->cmdList->uri); fprintf(stdout, " to \"%s\"", endP->name); res = lwm2m_bootstrap_delete(dataP->lwm2mH, endP->handle, endP->cmdList->uri); break; case BS_WRITE_SECURITY: { lwm2m_uri_t uri; bs_server_tlv_t * serverP; serverP = (bs_server_tlv_t *)LWM2M_LIST_FIND(dataP->bsInfo->serverList, endP->cmdList->serverId); if (serverP == NULL || serverP->securityData == NULL) { endP->status = CMD_STATUS_FAIL; return; } uri.flag = LWM2M_URI_FLAG_OBJECT_ID | LWM2M_URI_FLAG_INSTANCE_ID; uri.objectId = LWM2M_SECURITY_OBJECT_ID; uri.instanceId = endP->cmdList->serverId; fprintf(stdout, "Sending WRITE "); prv_print_uri(stdout, &uri); fprintf(stdout, " to \"%s\"", endP->name); res = lwm2m_bootstrap_write(dataP->lwm2mH, endP->handle, &uri, LWM2M_CONTENT_TLV, serverP->securityData, serverP->securityLen); } break; case BS_WRITE_SERVER: { lwm2m_uri_t uri; bs_server_tlv_t * serverP; serverP = (bs_server_tlv_t *)LWM2M_LIST_FIND(dataP->bsInfo->serverList, endP->cmdList->serverId); if (serverP == NULL || serverP->serverData == NULL) { endP->status = CMD_STATUS_FAIL; return; } uri.flag = LWM2M_URI_FLAG_OBJECT_ID | LWM2M_URI_FLAG_INSTANCE_ID; uri.objectId = LWM2M_SERVER_OBJECT_ID; uri.instanceId = endP->cmdList->serverId; fprintf(stdout, "Sending WRITE "); prv_print_uri(stdout, &uri); fprintf(stdout, " to \"%s\"", endP->name); res = lwm2m_bootstrap_write(dataP->lwm2mH, endP->handle, &uri, LWM2M_CONTENT_TLV, serverP->serverData, serverP->serverLen); } break; case BS_FINISH: fprintf(stdout, "Sending BOOTSTRAP FINISH "); fprintf(stdout, " to \"%s\"", endP->name); res = lwm2m_bootstrap_finish(dataP->lwm2mH, endP->handle); break; default: return; } if (res == COAP_NO_ERROR) { fprintf(stdout, " OK.\r\n"); endP->status = CMD_STATUS_SENT; } else { fprintf(stdout, " failed!\r\n"); endP->status = CMD_STATUS_FAIL; } }
int object_getServers(lwm2m_context_t * contextP) { lwm2m_object_t * objectP; lwm2m_object_t * securityObjP = NULL; lwm2m_object_t * serverObjP = NULL; lwm2m_list_t * securityInstP; // instanceID of the server in the LWM2M Security Object for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next) { if (objectP->objID == LWM2M_SECURITY_OBJECT_ID) { securityObjP = objectP; } else if (objectP->objID == LWM2M_SERVER_OBJECT_ID) { serverObjP = objectP; } } if (NULL == securityObjP) return -1; securityInstP = securityObjP->instanceList; while (securityInstP != NULL) { if (LWM2M_LIST_FIND(contextP->bootstrapServerList, securityInstP->id) == NULL && LWM2M_LIST_FIND(contextP->serverList, securityInstP->id) == NULL) { // This server is new. eg created by last bootstrap lwm2m_data_t * dataP; int size; lwm2m_server_t * targetP; bool isBootstrap; int64_t value = 0; size = 3; dataP = lwm2m_data_new(size); if (dataP == NULL) return -1; dataP[0].id = LWM2M_SECURITY_BOOTSTRAP_ID; dataP[1].id = LWM2M_SECURITY_SHORT_SERVER_ID; dataP[2].id = LWM2M_SECURITY_HOLD_OFF_ID; if (securityObjP->readFunc(securityInstP->id, &size, &dataP, securityObjP) != COAP_205_CONTENT) { lwm2m_data_free(size, dataP); return -1; } targetP = (lwm2m_server_t *)lwm2m_malloc(sizeof(lwm2m_server_t)); if (targetP == NULL) { lwm2m_data_free(size, dataP); return -1; } memset(targetP, 0, sizeof(lwm2m_server_t)); targetP->secObjInstID = securityInstP->id; if (0 == lwm2m_data_decode_bool(dataP + 0, &isBootstrap)) { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } if (0 == lwm2m_data_decode_int(dataP + 1, &value) || value < (isBootstrap ? 0 : 1) || value > 0xFFFF) // 0 is forbidden as a Short Server ID { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } targetP->shortID = value; if (isBootstrap == true) { if (0 == lwm2m_data_decode_int(dataP + 2, &value) || value < 0 || value > 0xFFFFFFFF) // This is an implementation limit { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } // lifetime of a bootstrap server is set to ClientHoldOffTime targetP->lifetime = value; contextP->bootstrapServerList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->bootstrapServerList, targetP); } else { lwm2m_list_t * serverInstP; // instanceID of the server in the LWM2M Server Object serverInstP = prv_findServerInstance(serverObjP, targetP->shortID); if (serverInstP == NULL) { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } if (0 != prv_getMandatoryInfo(serverObjP, serverInstP->id, targetP)) { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } targetP->status = STATE_DEREGISTERED; contextP->serverList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->serverList, targetP); } lwm2m_data_free(size, dataP); } securityInstP = securityInstP->next; } return 0; }
bs_info_t * bs_get_info(FILE * fd) { bs_info_t * infoP; read_server_t * readSrvP; bs_endpoint_info_t * cltInfoP; bs_command_t * cmdP; infoP = (bs_info_t *)lwm2m_malloc(sizeof(bs_info_t)); if (infoP == NULL) return NULL; memset(infoP, 0, sizeof(bs_info_t)); do { readSrvP = prv_read_next_server(fd); if (readSrvP != NULL) { if (prv_add_server(infoP, readSrvP) != 0) goto error; } } while (readSrvP != NULL); rewind(fd); do { cltInfoP = prv_read_next_endpoint(fd); if (cltInfoP != NULL) { cltInfoP->next = infoP->endpointList; infoP->endpointList = cltInfoP; } } while (cltInfoP != NULL); // check validity if (infoP->endpointList == NULL) goto error; cltInfoP = infoP->endpointList; while (cltInfoP != NULL) { bs_endpoint_info_t * otherP; bs_command_t * cmdP; bs_command_t * parentP; // check names are unique otherP = cltInfoP->next; while (otherP != NULL) { if (cltInfoP->name == NULL) { if (otherP->name == NULL) goto error; } else { if (otherP->name != NULL && strcmp(cltInfoP->name, otherP->name) == 0) { goto error; } } otherP = otherP->next; } // check servers exist cmdP = cltInfoP->commandList; parentP = NULL; // be careful: iterator changes are inside the switch/case while (cmdP != NULL) { switch (cmdP->operation) { case BS_WRITE_SECURITY: if (LWM2M_LIST_FIND(infoP->serverList, cmdP->serverId) == NULL) goto error; parentP = cmdP; cmdP = cmdP->next; break; case BS_WRITE_SERVER: { bs_server_tlv_t * serverP; serverP = (bs_server_tlv_t *)LWM2M_LIST_FIND(infoP->serverList, cmdP->serverId); if (serverP == NULL) goto error; if (serverP->serverData == NULL) { // this is a Bootstrap server, remove this command if (parentP == NULL) { cltInfoP->commandList = cmdP->next; lwm2m_free(cmdP); cmdP = cltInfoP->commandList; } else { parentP->next = cmdP->next; lwm2m_free(cmdP); cmdP = parentP->next; } } else { cmdP = cmdP->next; } } break; case BS_DELETE: default: parentP = cmdP; cmdP = cmdP->next; break; } } cltInfoP = cltInfoP->next; } return infoP; error: bs_free_info(infoP); return NULL; }
coap_status_t object_discover(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, uint8_t ** bufferP, size_t * lengthP) { coap_status_t result; lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->discoverFunc) return COAP_501_NOT_IMPLEMENTED; if (targetP->instanceList == NULL) return COAP_404_NOT_FOUND; if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; // single instance read if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { size = 1; dataP = lwm2m_data_new(size); if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; dataP->id = uriP->resourceId; uriP->flag &= ~LWM2M_URI_FLAG_RESOURCE_ID; } result = targetP->discoverFunc(uriP->instanceId, &size, &dataP, targetP); } else { // multiple object instances read lwm2m_list_t * instanceP; int i; size = 0; for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) { size++; } dataP = lwm2m_data_new(size); if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; result = COAP_205_CONTENT; instanceP = targetP->instanceList; i = 0; while (instanceP != NULL && result == COAP_205_CONTENT) { result = targetP->discoverFunc(instanceP->id, (int*)&(dataP[i].value.asChildren.count), &(dataP[i].value.asChildren.array), targetP); dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE; dataP[i].id = instanceP->id; i++; instanceP = instanceP->next; } } if (result == COAP_205_CONTENT) { int len; len = discover_serialize(contextP, uriP, size, dataP, bufferP); if (len <= 0) result = COAP_500_INTERNAL_SERVER_ERROR; else *lengthP = len; } lwm2m_data_free(size, dataP); return result; }