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; }
int lwm2m_data_serialize(lwm2m_uri_t * uriP, int size, lwm2m_data_t * dataP, lwm2m_media_type_t * formatP, uint8_t ** bufferP) { LOG_URI(uriP); LOG_ARG("size: %d, formatP: %s", size, STR_MEDIA_TYPE(*formatP)); // Check format if (*formatP == LWM2M_CONTENT_TEXT || *formatP == LWM2M_CONTENT_OPAQUE) { if (size != 1 || (uriP != NULL && !LWM2M_URI_IS_SET_RESOURCE(uriP)) || dataP->type == LWM2M_TYPE_OBJECT || dataP->type == LWM2M_TYPE_OBJECT_INSTANCE || dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) { #ifdef LWM2M_SUPPORT_JSON *formatP = LWM2M_CONTENT_JSON; #else *formatP = LWM2M_CONTENT_TLV; #endif } } if (*formatP == LWM2M_CONTENT_OPAQUE && dataP->type != LWM2M_TYPE_OPAQUE) { LOG("Opaque format is reserved to opaque resources."); return -1; } LOG_ARG("Final format: %s", STR_MEDIA_TYPE(*formatP)); switch (*formatP) { case LWM2M_CONTENT_TEXT: return prv_textSerialize(dataP, bufferP); case LWM2M_CONTENT_OPAQUE: *bufferP = (uint8_t *)lwm2m_malloc(dataP->value.asBuffer.length); if (*bufferP == NULL) return -1; memcpy(*bufferP, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length); return (int)dataP->value.asBuffer.length; case LWM2M_CONTENT_TLV: case LWM2M_CONTENT_TLV_OLD: { bool isResourceInstance; if (uriP != NULL && LWM2M_URI_IS_SET_RESOURCE(uriP) && (size != 1 || dataP->id != uriP->resourceId)) { isResourceInstance = true; } else { isResourceInstance = false; } return tlv_serialize(isResourceInstance, size, dataP, bufferP); } #ifdef LWM2M_CLIENT_MODE case LWM2M_CONTENT_LINK: return discover_serialize(NULL, uriP, NULL, size, dataP, bufferP); #endif #ifdef LWM2M_SUPPORT_JSON case LWM2M_CONTENT_JSON: case LWM2M_CONTENT_JSON_OLD: return json_serialize(uriP, size, dataP, bufferP); #endif default: return -1; } }