static void prv_result_callback(uint16_t clientID, lwm2m_uri_t * uriP, int status, uint8_t * data, int dataLength, void * userData) { fprintf(stdout, "\r\nClient #%d %d", clientID, uriP->objectId); if (LWM2M_URI_IS_SET_INSTANCE(uriP)) fprintf(stdout, "/%d", uriP->instanceId); else if (LWM2M_URI_IS_SET_RESOURCE(uriP)) fprintf(stdout, "/"); if (LWM2M_URI_IS_SET_RESOURCE(uriP)) fprintf(stdout, "/%d", uriP->resourceId); fprintf(stdout, " returned status %d.%2d\r\n", (status&0xE0)>>5, status&0x1F); if (data != NULL) { fprintf(stdout, "%d bytes received:\r\n", dataLength); prv_output_buffer(stdout, data, dataLength); } fprintf(stdout, "\r\n> "); fflush(stdout); }
lwm2m_observed_t * observe_findByUri(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { lwm2m_observed_t * targetP; targetP = contextP->observedList; while (targetP != NULL) { if (targetP->uri.objectId == uriP->objectId) { if ((!LWM2M_URI_IS_SET_INSTANCE(uriP) && !LWM2M_URI_IS_SET_INSTANCE(&(targetP->uri))) || (LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_INSTANCE(&(targetP->uri)) && (uriP->instanceId == targetP->uri.instanceId))) { if ((!LWM2M_URI_IS_SET_RESOURCE(uriP) && !LWM2M_URI_IS_SET_RESOURCE(&(targetP->uri))) || (LWM2M_URI_IS_SET_RESOURCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(&(targetP->uri)) && (uriP->resourceId == targetP->uri.resourceId))) { return targetP; } } } targetP = targetP->next; } return NULL; }
lwm2m_observed_t * observe_findByUri(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { lwm2m_observed_t * targetP; LOG_URI(uriP); targetP = contextP->observedList; while (targetP != NULL) { if (targetP->uri.objectId == uriP->objectId) { if ((!LWM2M_URI_IS_SET_INSTANCE(uriP) && !LWM2M_URI_IS_SET_INSTANCE(&(targetP->uri))) || (LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_INSTANCE(&(targetP->uri)) && (uriP->instanceId == targetP->uri.instanceId))) { if ((!LWM2M_URI_IS_SET_RESOURCE(uriP) && !LWM2M_URI_IS_SET_RESOURCE(&(targetP->uri))) || (LWM2M_URI_IS_SET_RESOURCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(&(targetP->uri)) && (uriP->resourceId == targetP->uri.resourceId))) { LOG_ARG("Found one with%s observers.", targetP->watcherList ? "" : " no"); LOG_URI(&(targetP->uri)); return targetP; } } } targetP = targetP->next; } LOG("Found nothing"); return NULL; }
int lwm2m_data_parse(lwm2m_uri_t * uriP, uint8_t * buffer, size_t bufferLen, lwm2m_media_type_t format, lwm2m_data_t ** dataP) { int res; LOG_ARG("format: %s, bufferLen: %d", STR_MEDIA_TYPE(format), bufferLen); LOG_URI(uriP); switch (format) { case LWM2M_CONTENT_TEXT: if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return 0; *dataP = lwm2m_data_new(1); if (*dataP == NULL) return 0; (*dataP)->id = uriP->resourceId; (*dataP)->type = LWM2M_TYPE_STRING; res = prv_setBuffer(*dataP, buffer, bufferLen); if (res == 0) { lwm2m_data_free(1, *dataP); *dataP = NULL; } return res; case LWM2M_CONTENT_OPAQUE: if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return 0; *dataP = lwm2m_data_new(1); if (*dataP == NULL) return 0; (*dataP)->id = uriP->resourceId; (*dataP)->type = LWM2M_TYPE_OPAQUE; res = prv_setBuffer(*dataP, buffer, bufferLen); if (res == 0) { lwm2m_data_free(1, *dataP); *dataP = NULL; } return res; #ifdef LWM2M_OLD_CONTENT_FORMAT_SUPPORT case LWM2M_CONTENT_TLV_OLD: #endif case LWM2M_CONTENT_TLV: return tlv_parse(buffer, bufferLen, dataP); #ifdef LWM2M_SUPPORT_JSON #ifdef LWM2M_OLD_CONTENT_FORMAT_SUPPORT case LWM2M_CONTENT_JSON_OLD: #endif case LWM2M_CONTENT_JSON: return json_parse(uriP, buffer, bufferLen, dataP); #endif default: return 0; } }
coap_status_t observe_handleRequest(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_server_t * serverP, int size, lwm2m_data_t * dataP, coap_packet_t * message, coap_packet_t * response) { lwm2m_watcher_t * watcherP; uint32_t count; LOG("observe_handleRequest()\r\n"); coap_get_header_observe(message, &count); switch (count) { case 0: if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST; if (message->token_len == 0) return COAP_400_BAD_REQUEST; watcherP = prv_getWatcher(contextP, uriP, serverP); if (watcherP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; watcherP->tokenLen = message->token_len; memcpy(watcherP->token, message->token, message->token_len); watcherP->active = true; watcherP->lastTime = lwm2m_gettime(); if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { switch (dataP->type) { case LWM2M_TYPE_INTEGER: if (1 != lwm2m_data_decode_int(dataP, &(watcherP->lastValue.asInteger))) return COAP_500_INTERNAL_SERVER_ERROR; break; case LWM2M_TYPE_FLOAT: if (1 != lwm2m_data_decode_float(dataP, &(watcherP->lastValue.asFloat))) return COAP_500_INTERNAL_SERVER_ERROR; break; default: break; } } coap_set_header_observe(response, watcherP->counter++); return COAP_205_CONTENT; case 1: // cancellation observe_cancel(contextP, LWM2M_MAX_ID, serverP->sessionH); return COAP_205_CONTENT; default: return COAP_400_BAD_REQUEST; } }
lwm2m_transaction_t * transaction_new(coap_method_t method, lwm2m_uri_t * uriP, uint16_t mID, lwm2m_endpoint_type_t peerType, void * peerP) { lwm2m_transaction_t * transacP; int result; transacP = (lwm2m_transaction_t *)lwm2m_malloc(sizeof(lwm2m_transaction_t)); if (transacP == NULL) return NULL; memset(transacP, 0, sizeof(lwm2m_transaction_t)); transacP->message = lwm2m_malloc(sizeof(coap_packet_t)); if (transacP->message == NULL) goto error; coap_init_message(transacP->message, COAP_TYPE_CON, method, mID); transacP->mID = mID; transacP->peerType = peerType; transacP->peerP = peerP; if (uriP != NULL) { result = snprintf(transacP->objStringID, LWM2M_STRING_ID_MAX_LEN, "%hu", uriP->objectId); if (result < 0 || result > LWM2M_STRING_ID_MAX_LEN) goto error; coap_set_header_uri_path_segment(transacP->message, transacP->objStringID); if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { result = snprintf(transacP->instanceStringID, LWM2M_STRING_ID_MAX_LEN, "%hu", uriP->instanceId); if (result < 0 || result > LWM2M_STRING_ID_MAX_LEN) goto error; coap_set_header_uri_path_segment(transacP->message, transacP->instanceStringID); } else { if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { coap_set_header_uri_path_segment(transacP->message, NULL); } } if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = snprintf(transacP->resourceStringID, LWM2M_STRING_ID_MAX_LEN, "%hu", uriP->resourceId); if (result < 0 || result > LWM2M_STRING_ID_MAX_LEN) goto error; coap_set_header_uri_path_segment(transacP->message, transacP->resourceStringID); } } return transacP; error: lwm2m_free(transacP); return NULL; }
int lwm2m_dm_write(lwm2m_context_t * contextP, uint16_t clientID, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, int length, lwm2m_result_callback_t callback, void * userData) { LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length); LOG_URI(uriP); if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || length == 0) { return COAP_400_BAD_REQUEST; } if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { return prv_makeOperation(contextP, clientID, uriP, COAP_PUT, format, buffer, length, callback, userData); } else { return prv_makeOperation(contextP, clientID, uriP, COAP_POST, format, buffer, length, callback, userData); } }
void lwm2m_resource_value_changed(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { lwm2m_observed_t * targetP; LOG("lwm2m_resource_value_changed(/%d/%d/%d)\n", uriP->objectId, uriP->instanceId, uriP->resourceId); targetP = contextP->observedList; while (targetP != NULL) { if (targetP->uri.objectId == uriP->objectId) { if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || (targetP->uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0 || uriP->instanceId == targetP->uri.instanceId) { if (!LWM2M_URI_IS_SET_RESOURCE(uriP) || (targetP->uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) == 0 || uriP->resourceId == targetP->uri.resourceId) { lwm2m_watcher_t * watcherP; for (watcherP = targetP->watcherList ; watcherP != NULL ; watcherP = watcherP->next) { if ( watcherP->active == true) watcherP->update = true; } } } } targetP = targetP->next; } }
int lwm2m_dm_write(lwm2m_context_t * contextP, uint16_t clientID, lwm2m_uri_t * uriP, uint8_t * buffer, int length, lwm2m_result_callback_t callback, void * userData) { if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || length == 0) { return COAP_400_BAD_REQUEST; } if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { return prv_make_operation(contextP, clientID, uriP, COAP_PUT, LWM2M_CONTENT_TEXT, buffer, length, callback, userData); } else { return prv_make_operation(contextP, clientID, uriP, COAP_POST, LWM2M_CONTENT_TLV, buffer, length, callback, userData); } }
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_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; }
int uri_toString(lwm2m_uri_t * uriP, uint8_t * buffer, size_t bufferLen, uri_depth_t * depthP) { size_t head; int res; LOG_ARG("bufferLen: %u", bufferLen); LOG_URI(uriP); buffer[0] = '/'; if (uriP == NULL) { if (depthP) *depthP = URI_DEPTH_OBJECT; return 1; } head = 1; res = utils_intToText(uriP->objectId, buffer + head, bufferLen - head); if (res <= 0) return -1; head += res; if (head >= bufferLen - 1) return -1; if (depthP) *depthP = URI_DEPTH_OBJECT_INSTANCE; if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { buffer[head] = '/'; head++; res = utils_intToText(uriP->instanceId, buffer + head, bufferLen - head); if (res <= 0) return -1; head += res; if (head >= bufferLen - 1) return -1; if (depthP) *depthP = URI_DEPTH_RESOURCE; if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { buffer[head] = '/'; head++; res = utils_intToText(uriP->resourceId, buffer + head, bufferLen - head); if (res <= 0) return -1; head += res; if (head >= bufferLen - 1) return -1; if (depthP) *depthP = URI_DEPTH_RESOURCE_INSTANCE; } } buffer[head] = '/'; head++; LOG_ARG("length: %u, buffer: \"%.*s\"", head, head, buffer); return head; }
coap_status_t object_server_read(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, char ** bufferP, int * lengthP) { if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) { return COAP_501_NOT_IMPLEMENTED; } else { lwm2m_server_t * serverP; serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId); if (serverP == NULL) return COAP_404_NOT_FOUND; if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) { return COAP_501_NOT_IMPLEMENTED; } else { switch (uriP->resourceId) { case RESOURCE_SHORTID_ID: *lengthP = lwm2m_int32ToPlainText(serverP->shortID, bufferP); if (0 != *lengthP) { return COAP_205_CONTENT; } else { return COAP_500_INTERNAL_SERVER_ERROR; } break; case RESOURCE_LIFETIME_ID: return COAP_501_NOT_IMPLEMENTED; case RESOURCE_MINPERIOD_ID: return COAP_404_NOT_FOUND; case RESOURCE_MAXPERIOD_ID: return COAP_404_NOT_FOUND; case RESOURCE_TIMEOUT_ID: return COAP_404_NOT_FOUND; case RESOURCE_STORING_ID: return COAP_501_NOT_IMPLEMENTED; case RESOURCE_BINDING_ID: return COAP_501_NOT_IMPLEMENTED; default: return COAP_405_METHOD_NOT_ALLOWED; } } } }
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 = prv_find_object(contextP, uriP->objectId); if (NULL == targetP) { result = NOT_FOUND_4_04; } else if (NULL == targetP->writeFunc) { result = METHOD_NOT_ALLOWED_4_05; } else { if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { size = 1; dataP = lwm2m_data_new(size); if (dataP == NULL) { return COAP_500_INTERNAL_SERVER_ERROR; } dataP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT | LWM2M_TLV_FLAG_STATIC_DATA; dataP->type = LWM2M_TYPE_RESOURCE; dataP->id = uriP->resourceId; dataP->length = length; dataP->value = (uint8_t *)buffer; } else { size = lwm2m_data_parse(buffer, length, format, &dataP); if (size == 0) { result = COAP_500_INTERNAL_SERVER_ERROR; } } } if (result == NO_ERROR) { result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP); lwm2m_data_free(size, dataP); } return result; }
int ICACHE_FLASH_ATTR lwm2m_observe(lwm2m_context_t * contextP, uint16_t clientID, lwm2m_uri_t * uriP, lwm2m_result_callback_t callback, void * userData) { lwm2m_client_t * clientP; lwm2m_transaction_t * transactionP; lwm2m_observation_t * observationP; uint8_t token[4]; if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST; clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); if (clientP == NULL) return COAP_404_NOT_FOUND; observationP = (lwm2m_observation_t *)lwm2m_malloc(sizeof(lwm2m_observation_t)); if (observationP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; c_memset(observationP, 0, sizeof(lwm2m_observation_t)); observationP->id = lwm2m_list_newId((lwm2m_list_t *)clientP->observationList); c_memcpy(&observationP->uri, uriP, sizeof(lwm2m_uri_t)); observationP->clientP = clientP; observationP->status = STATE_REG_PENDING; observationP->callback = callback; observationP->userData = userData; token[0] = clientP->internalID >> 8; token[1] = clientP->internalID & 0xFF; token[2] = observationP->id >> 8; token[3] = observationP->id & 0xFF; transactionP = transaction_new(COAP_TYPE_CON, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, token, ENDPOINT_CLIENT, (void *)clientP); if (transactionP == NULL) { lwm2m_free(observationP); return COAP_500_INTERNAL_SERVER_ERROR; } observationP->clientP->observationList = (lwm2m_observation_t *)LWM2M_LIST_ADD(observationP->clientP->observationList, observationP); coap_set_header_observe(transactionP->message, 0); coap_set_header_token(transactionP->message, token, sizeof(token)); transactionP->callback = prv_obsRequestCallback; transactionP->userData = (void *)observationP; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transactionP); return transaction_send(contextP, transactionP); }
static void prv_notify_callback(uint16_t clientID, lwm2m_uri_t * uriP, int count, lwm2m_media_type_t format, uint8_t * data, int dataLength, void * userData) { fprintf(stdout, "\r\nNotify from client #%d /%d", clientID, uriP->objectId); if (LWM2M_URI_IS_SET_INSTANCE(uriP)) fprintf(stdout, "/%d", uriP->instanceId); else if (LWM2M_URI_IS_SET_RESOURCE(uriP)) fprintf(stdout, "/"); if (LWM2M_URI_IS_SET_RESOURCE(uriP)) fprintf(stdout, "/%d", uriP->resourceId); fprintf(stdout, " number %d\r\n", count); output_data(stdout, format, data, dataLength, 1); fprintf(stdout, "\r\n> "); fflush(stdout); }
static void prv_result_callback(uint16_t clientID, lwm2m_uri_t * uriP, int status, lwm2m_media_type_t format, uint8_t * data, int dataLength, void * userData) { fprintf(stdout, "\r\nClient #%d /%d", clientID, uriP->objectId); if (LWM2M_URI_IS_SET_INSTANCE(uriP)) fprintf(stdout, "/%d", uriP->instanceId); else if (LWM2M_URI_IS_SET_RESOURCE(uriP)) fprintf(stdout, "/"); if (LWM2M_URI_IS_SET_RESOURCE(uriP)) fprintf(stdout, "/%d", uriP->resourceId); fprintf(stdout, " : "); print_status(stdout, status); fprintf(stdout, "\r\n"); output_data(stdout, format, data, dataLength, 1); fprintf(stdout, "\r\n> "); fflush(stdout); }
static void prv_print_uri(FILE * fd, lwm2m_uri_t * uriP) { fprintf(fd, "/"); if (uriP != NULL) { fprintf(fd, "%hu", uriP->objectId); if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { fprintf(fd, "/%d", uriP->instanceId); if (LWM2M_URI_IS_SET_RESOURCE(uriP)) fprintf(fd, "/%d", uriP->resourceId); } } }
int lwm2m_dm_delete(lwm2m_context_t * contextP, uint16_t clientID, lwm2m_uri_t * uriP, lwm2m_result_callback_t callback, void * userData) { if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || LWM2M_URI_IS_SET_RESOURCE(uriP)) { return COAP_400_BAD_REQUEST; } return prv_make_operation(contextP, clientID, uriP, COAP_DELETE, NULL, 0, callback, userData); }
coap_status_t handle_observe_request(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, uint8_t * fromAddr, size_t fromAddrLen, coap_packet_t * message, coap_packet_t * response) { lwm2m_observed_t * observedP; lwm2m_watcher_t * watcherP; lwm2m_server_t * serverP; LOG("handle_observe_request()\r\n"); if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST; if (message->token_len == 0) return COAP_400_BAD_REQUEST; serverP = prv_findServer(contextP, fromAddr, fromAddrLen); if (serverP == NULL || serverP->status != STATE_REGISTERED) return COAP_401_UNAUTHORIZED; observedP = prv_findObserved(contextP, uriP); if (observedP == NULL) { observedP = (lwm2m_observed_t *)lwm2m_malloc(sizeof(lwm2m_observed_t)); if (observedP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; memset(observedP, 0, sizeof(lwm2m_observed_t)); memcpy(&(observedP->uri), uriP, sizeof(lwm2m_uri_t)); observedP->next = contextP->observedList; contextP->observedList = observedP; } watcherP = prv_findWatcher(observedP, serverP); if (watcherP == NULL) { watcherP = (lwm2m_watcher_t *)lwm2m_malloc(sizeof(lwm2m_watcher_t)); if (watcherP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; memset(watcherP, 0, sizeof(lwm2m_watcher_t)); watcherP->server = serverP; watcherP->tokenLen = message->token_len; memcpy(watcherP->token, message->token, message->token_len); watcherP->next = observedP->watcherList; observedP->watcherList = watcherP; } coap_set_header_observe(response, watcherP->counter++); return COAP_205_CONTENT; }
static lwm2m_observed_t * prv_findObserved(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { lwm2m_observed_t * targetP; targetP = contextP->observedList; while (targetP != NULL && (targetP->uri.objectId != uriP->objectId || targetP->uri.flag != uriP->flag || (LWM2M_URI_IS_SET_INSTANCE(uriP) && targetP->uri.instanceId != uriP->instanceId) || (LWM2M_URI_IS_SET_RESOURCE(uriP) && targetP->uri.resourceId != uriP->resourceId))) { targetP = targetP->next; } return targetP; }
int lwm2m_dm_execute(lwm2m_context_t * contextP, uint16_t clientID, lwm2m_uri_t * uriP, char * buffer, int length, lwm2m_result_callback_t callback, void * userData) { if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) { return COAP_400_BAD_REQUEST; } return prv_make_operation(contextP, clientID, uriP, COAP_POST, buffer, length, callback, userData); }
static uint8_t prv_firmware_write(lwm2m_uri_t * uriP, char * buffer, int length, lwm2m_object_t * objectP) { // this is a single instance object if (LWM2M_URI_IS_SET_INSTANCE(uriP) && uriP->instanceId != 0) { return COAP_404_NOT_FOUND; } if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_501_NOT_IMPLEMENTED; firmware_data_t * data = (firmware_data_t*)(objectP->userData); switch (uriP->resourceId) { case 0: // inline firmware binary return COAP_204_CHANGED; case 1: // URL for download the firmware return COAP_204_CHANGED; case 4: if (1 == length && buffer[0] == '0') { data->supported = 0; return COAP_204_CHANGED; } else if (1 == length && buffer[0] == '1') { data->supported = 1; return COAP_204_CHANGED; } else { return COAP_400_BAD_REQUEST; } default: return COAP_405_METHOD_NOT_ALLOWED; } }
int lwm2m_dm_delete(lwm2m_context_t * contextP, uint16_t clientID, lwm2m_uri_t * uriP, lwm2m_result_callback_t callback, void * userData) { LOG_ARG("clientID: %d", clientID); LOG_URI(uriP); if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || LWM2M_URI_IS_SET_RESOURCE(uriP)) { return COAP_400_BAD_REQUEST; } return prv_makeOperation(contextP, clientID, uriP, COAP_DELETE, LWM2M_CONTENT_TEXT, NULL, 0, callback, userData); }
coap_status_t object_server_write(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, char * buffer, int length) { if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) { return COAP_501_NOT_IMPLEMENTED; } else { lwm2m_server_t * serverP; serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId); if (serverP == NULL) return COAP_404_NOT_FOUND; if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) { return COAP_501_NOT_IMPLEMENTED; } else { switch (uriP->resourceId) { case RESOURCE_LIFETIME_ID: return COAP_501_NOT_IMPLEMENTED; case RESOURCE_MINPERIOD_ID: return COAP_404_NOT_FOUND; case RESOURCE_MAXPERIOD_ID: return COAP_404_NOT_FOUND; case RESOURCE_TIMEOUT_ID: return COAP_404_NOT_FOUND; case RESOURCE_STORING_ID: return COAP_501_NOT_IMPLEMENTED; case RESOURCE_BINDING_ID: return COAP_501_NOT_IMPLEMENTED; default: return COAP_405_METHOD_NOT_ALLOWED; } } } }
static obs_list_t * ICACHE_FLASH_ATTR prv_getObservedList(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { obs_list_t * resultP; lwm2m_observed_t * targetP; resultP = NULL; targetP = contextP->observedList; while (targetP != NULL) { if (targetP->uri.objectId == uriP->objectId) { if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || (targetP->uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0 || uriP->instanceId == targetP->uri.instanceId) { if (!LWM2M_URI_IS_SET_RESOURCE(uriP) || (targetP->uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) == 0 || uriP->resourceId == targetP->uri.resourceId) { obs_list_t * newP; newP = (obs_list_t *)lwm2m_malloc(sizeof(obs_list_t)); if (newP != NULL) { newP->item = targetP; newP->next = resultP; resultP = newP; } } } } targetP = targetP->next; } return resultP; }
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; }
coap_status_t object_write(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, char * buffer, int length) { coap_status_t result; lwm2m_object_t * targetP; lwm2m_tlv_t * tlvP = NULL; int size = 0; targetP = prv_find_object(contextP, uriP->objectId); if (NULL == targetP) return NOT_FOUND_4_04; if (NULL == targetP->writeFunc) return METHOD_NOT_ALLOWED_4_05; if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { size = 1; tlvP = lwm2m_tlv_new(size); if (tlvP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; tlvP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT | LWM2M_TLV_FLAG_STATIC_DATA; tlvP->type = LWM2M_TYPE_RESSOURCE; tlvP->id = uriP->resourceId; tlvP->length = length; tlvP->value = buffer; } else { size = lwm2m_tlv_parse(buffer, length, &tlvP); if (size == 0) return COAP_500_INTERNAL_SERVER_ERROR; } result = targetP->writeFunc(uriP->instanceId, size, tlvP, targetP); lwm2m_tlv_free(size, tlvP); return result; }
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; }