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 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; } }
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; }
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"); } }
static int prv_dataStrip(int size, lwm2m_data_t * dataP, lwm2m_data_t ** resultP) { int i; int j; int realSize; realSize = 0; for (i = 0 ; i < size ; i++) { if (dataP[i].type != LWM2M_TYPE_UNDEFINED) { realSize++; } } *resultP = lwm2m_data_new(realSize); if (*resultP == NULL) return -1; j = 0; for (i = 0 ; i < size ; i++) { if (dataP[i].type != LWM2M_TYPE_UNDEFINED) { memcpy((*resultP) + j, dataP + i, sizeof(lwm2m_data_t)); if (dataP[i].type == LWM2M_TYPE_OBJECT || dataP[i].type == LWM2M_TYPE_OBJECT_INSTANCE || dataP[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) { int childLen; childLen = prv_dataStrip(dataP[i].value.asChildren.count, dataP[i].value.asChildren.array, &((*resultP)[j].value.asChildren.array)); if (childLen <= 0) { // skip this one j--; } else { (*resultP)[j].value.asChildren.count = childLen; } } else { dataP[i].value.asBuffer.buffer = NULL; } j++; } } return realSize; }
static uint8_t prv_read(uint16_t instanceId, int * numDataP, lwm2m_data_t** dataArrayP, lwm2m_data_cfg_t * dataCfg,lwm2m_object_t * objectP) { uint8_t result; int ri, ni; // multi-instance object: search instance acc_ctrl_oi_t* accCtrlOiP = (acc_ctrl_oi_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (accCtrlOiP == NULL) { return COAP_404_NOT_FOUND ; } // is the server asking for the full object ? if (*numDataP == 0) { uint16_t resList[] = { RES_M_OBJECT_ID, RES_M_OBJECT_INSTANCE_ID, RES_O_ACL, // prv_set_tlv will return COAP_404_NOT_FOUND w/o values! RES_M_ACCESS_CONTROL_OWNER }; int nbRes = sizeof(resList) / sizeof(uint16_t); *dataArrayP = lwm2m_data_new(nbRes); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR ; *numDataP = nbRes; for (ri = 0; ri < nbRes; ri++) { (*dataArrayP)[ri].id = resList[ri]; } } ni = ri = 0; do { result = prv_set_tlv((*dataArrayP) + ni, accCtrlOiP); if (result==COAP_404_NOT_FOUND) { ri++; if (*numDataP>1) result = COAP_205_CONTENT; } else if (ri > 0) // copy new one by ri skipped ones in front { (*dataArrayP)[ni-ri] = (*dataArrayP)[ni]; } ni++; } while (ni < *numDataP && result == COAP_205_CONTENT); *numDataP = ni-ri; 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 = 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; }
static uint8_t prv_read(uint16_t instanceId, int * numDataP, lwm2m_data_t ** dataArrayP, lwm2m_object_t * objectP) { uint8_t result; int i; // this is a single instance object if (instanceId != 0) { return COAP_404_NOT_FOUND ; } // is the server asking for the full object ? if (*numDataP == 0) { uint16_t resList[] = { RES_M_NETWORK_BEARER, RES_M_AVL_NETWORK_BEARER, RES_M_RADIO_SIGNAL_STRENGTH, RES_O_LINK_QUALITY, RES_M_IP_ADDRESSES, RES_O_ROUTER_IP_ADDRESS, RES_O_LINK_UTILIZATION, RES_O_APN, RES_O_CELL_ID, RES_O_SMNC, RES_O_SMCC }; int nbRes = sizeof(resList) / sizeof(uint16_t); *dataArrayP = lwm2m_data_new(nbRes); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR ; *numDataP = nbRes; for (i = 0; i < nbRes; i++) { (*dataArrayP)[i].id = resList[i]; } } i = 0; do { result = prv_set_value((*dataArrayP) + i, (conn_m_data_t*) (objectP->userData)); i++; } while (i < *numDataP && result == COAP_205_CONTENT ); return result; }
char * security_get_secret_key(lwm2m_object_t * obj, int instanceId, int * length){ int size = 1; lwm2m_data_t * dataP = lwm2m_data_new(size); dataP->id = 5; // secret key obj->readFunc(instanceId, &size, &dataP, obj); if (dataP != NULL && dataP->type == LWM2M_TYPE_OPAQUE) { *length = dataP->value.asBuffer.length; return dataP->value.asBuffer.buffer; }else{ return NULL; } }
static lwm2m_data_t * prv_extendData(lwm2m_data_t * parentP) { lwm2m_data_t * newP; newP = lwm2m_data_new(parentP->value.asChildren.count + 1); if (newP == NULL) return NULL; if (parentP->value.asChildren.array != NULL) { memcpy(newP, parentP->value.asChildren.array, parentP->value.asChildren.count * sizeof(lwm2m_data_t)); lwm2m_free(parentP->value.asChildren.array); // do not use lwm2m_data_free() to keep pointed values } parentP->value.asChildren.array = newP; parentP->value.asChildren.count += 1; return newP + parentP->value.asChildren.count - 1; }
static uint8_t prv_read(uint16_t instanceId, int * numDataP, lwm2m_data_t ** dataArrayP, lwm2m_object_t * objectP) { prv_instance_t * targetP; int i; targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (*numDataP == 0) { *dataArrayP = lwm2m_data_new(3); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; *numDataP = 3; (*dataArrayP)[0].id = 1; (*dataArrayP)[1].id = 3; (*dataArrayP)[2].id = 4; } for (i = 0 ; i < *numDataP ; i++) { switch ((*dataArrayP)[i].id) { case 1: (*dataArrayP)[i].type = LWM2M_TYPE_RESOURCE; lwm2m_data_encode_int(targetP->test, *dataArrayP + i); break; case 2: return COAP_405_METHOD_NOT_ALLOWED; case 3: (*dataArrayP)[i].type = LWM2M_TYPE_RESOURCE; lwm2m_data_encode_float(targetP->dec, *dataArrayP + i); break; case 4: (*dataArrayP)[i].type = LWM2M_TYPE_RESOURCE; lwm2m_data_encode_int(targetP->sig, *dataArrayP + i); break; default: return COAP_404_NOT_FOUND; } if ((*dataArrayP)[i].length == 0) return COAP_500_INTERNAL_SERVER_ERROR; } return COAP_205_CONTENT; }
static uint8_t prv_security_read(uint16_t instanceId, int * numDataP, lwm2m_data_t ** dataArrayP, lwm2m_object_t * objectP) { security_instance_t * targetP; uint8_t result; int i; targetP = (security_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (NULL == targetP) return COAP_404_NOT_FOUND; // is the server asking for the full instance ? if (*numDataP == 0) { uint16_t resList[] = {LWM2M_SECURITY_URI_ID, LWM2M_SECURITY_BOOTSTRAP_ID, LWM2M_SECURITY_SECURITY_ID, LWM2M_SECURITY_PUBLIC_KEY_ID, LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID, LWM2M_SECURITY_SECRET_KEY_ID, LWM2M_SECURITY_SMS_SECURITY_ID, LWM2M_SECURITY_SMS_KEY_PARAM_ID, LWM2M_SECURITY_SMS_SECRET_KEY_ID, LWM2M_SECURITY_SMS_SERVER_NUMBER_ID, LWM2M_SECURITY_SHORT_SERVER_ID, LWM2M_SECURITY_HOLD_OFF_ID}; int nbRes = sizeof(resList)/sizeof(uint16_t); *dataArrayP = lwm2m_data_new(nbRes); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; *numDataP = nbRes; for (i = 0 ; i < nbRes ; i++) { (*dataArrayP)[i].id = resList[i]; } } i = 0; do { result = prv_get_value((*dataArrayP) + i, targetP); i++; } while (i < *numDataP && result == COAP_205_CONTENT); return result; }
char * security_get_secret_key(lwm2m_object_t * obj, int instanceId, int * length){ int size = 1; lwm2m_data_t * dataP = lwm2m_data_new(size); dataP->id = 5; // secret key obj->readFunc(instanceId, &size, &dataP, obj); if (dataP != NULL && dataP->dataType == LWM2M_TYPE_OPAQUE && dataP->type == LWM2M_TYPE_RESOURCE && dataP->flags == LWM2M_TLV_FLAG_STATIC_DATA) { *length = dataP->length; return dataP->value; }else{ return NULL; } }
int64_t security_get_mode(lwm2m_object_t * obj, int instanceId){ int64_t mode; int size = 1; lwm2m_data_t * dataP = lwm2m_data_new(size); dataP->id = 2; // security mode obj->readFunc(instanceId, &size, &dataP, obj); if (0 != lwm2m_data_decode_int(dataP,&mode)) { lwm2m_data_free(size, dataP); return mode; } lwm2m_data_free(size, dataP); fprintf(stderr, "Unable to get security mode : use not secure mode"); return LWM2M_SECURITY_MODE_NONE; }
/** * Implementation (callback-) function of reading object resources. For whole * object, single resources or a sequence of resources * see 3GPP TS 23.032 V11.0.0(2012-09) page 23,24. * implemented for: HORIZONTAL_VELOCITY_WITH_UNCERTAINT * @param objInstId in, instances ID of the location object to read * @param numDataP in/out, pointer to the number of resource to read. 0 is the * exception for all readable resource of object instance * @param tlvArrayP in/out, TLV data sequence with initialized resource ID to read * @param objectP in, private location data structure */ static uint8_t prv_location_read(uint16_t objInstId, int* numDataP, lwm2m_data_t** tlvArrayP, lwm2m_object_t* objectP) { //-------------------------------------------------------------------- JH -- int i; uint8_t result = COAP_500_INTERNAL_SERVER_ERROR; location_data_t* locDataP = (location_data_t*)(objectP->userData); // defined as single instance object! if (objInstId != 0) return COAP_404_NOT_FOUND; if (*numDataP == 0) // full object, readable resources! { uint16_t readResIds[] = { RES_M_LATITUDE, RES_M_LONGITUDE, RES_O_ALTITUDE, RES_O_RADIUS, RES_O_VELOCITY, RES_M_TIMESTAMP, RES_O_SPEED }; // readable resources! *numDataP = sizeof(readResIds)/sizeof(uint16_t); *tlvArrayP = lwm2m_data_new(*numDataP); if (*tlvArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; // init readable resource id's for (i = 0 ; i < *numDataP ; i++) { (*tlvArrayP)[i].id = readResIds[i]; } } for (i = 0 ; i < *numDataP ; i++) { result = prv_res2tlv ((*tlvArrayP)+i, locDataP); if (result!=COAP_205_CONTENT) break; } return result; }
static uint8_t prv_set_tlv(lwm2m_data_t* dataP, acc_ctrl_oi_t* accCtrlOiP) { switch (dataP->id) { case RES_M_OBJECT_ID: lwm2m_data_encode_int(accCtrlOiP->objectId, dataP); return COAP_205_CONTENT; case RES_M_OBJECT_INSTANCE_ID: lwm2m_data_encode_int(accCtrlOiP->objectInstId, dataP); return COAP_205_CONTENT; case RES_O_ACL: { int ri; acc_ctrl_ri_t* accCtrlRiP; for (accCtrlRiP =accCtrlOiP->accCtrlValList, ri=0; accCtrlRiP!=NULL; accCtrlRiP = accCtrlRiP->next, ri++); if (ri==0) // no values! { return COAP_404_NOT_FOUND; } else { lwm2m_data_t* subTlvP = lwm2m_data_new(ri); if (subTlvP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; for (accCtrlRiP = accCtrlOiP->accCtrlValList, ri = 0; accCtrlRiP!= NULL; accCtrlRiP = accCtrlRiP->next, ri++) { subTlvP[ri].id = accCtrlRiP->resInstId; lwm2m_data_encode_int(accCtrlRiP->accCtrlValue, &subTlvP[ri]); } lwm2m_data_encode_instances(subTlvP, 2, dataP); return COAP_205_CONTENT; } } case RES_M_ACCESS_CONTROL_OWNER: lwm2m_data_encode_int(accCtrlOiP->accCtrlOwner, dataP); return COAP_205_CONTENT; default: return COAP_404_NOT_FOUND ; } }
static uint8_t prv_read(uint16_t instanceId, int * numDataP, lwm2m_data_t** dataArrayP, lwm2m_object_t * objectP) { uint8_t result; int i; // this is a single instance object if (instanceId != 0) { return COAP_404_NOT_FOUND ; } // is the server asking for the full object ? if (*numDataP == 0) { uint16_t resList[] = { RES_O_SMS_TX_COUNTER, RES_O_SMS_RX_COUNTER, RES_O_TX_DATA, RES_O_RX_DATA, RES_O_MAX_MESSAGE_SIZE, RES_O_AVERAGE_MESSAGE_SIZE }; int nbRes = sizeof(resList) / sizeof(uint16_t); *dataArrayP = lwm2m_data_new(nbRes); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR ; *numDataP = nbRes; for (i = 0; i < nbRes; i++) { (*dataArrayP)[i].id = resList[i]; } } i = 0; do { result = prv_set_tlv((*dataArrayP) + i, (conn_s_data_t*) (objectP->userData)); i++; } while (i < *numDataP && result == COAP_205_CONTENT ); return result; }
static uint8_t prv_device_read(uint16_t instanceId, int * numDataP, lwm2m_data_t ** dataArrayP, lwm2m_object_t * objectP) { uint8_t result; int i; // this is a single instance object if (instanceId != 0) { return COAP_404_NOT_FOUND; } // is the server asking for the full object ? if (*numDataP == 0) { uint16_t resList[] = { RES_O_MANUFACTURER, RES_O_MODEL_NUMBER, RES_M_BINDING_MODES }; int nbRes = sizeof(resList)/sizeof(uint16_t); *dataArrayP = lwm2m_data_new(nbRes); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; *numDataP = nbRes; for (i = 0 ; i < nbRes ; i++) { (*dataArrayP)[i].id = resList[i]; } } i = 0; do { result = prv_set_value((*dataArrayP) + i); i++; } while (i < *numDataP && result == COAP_205_CONTENT); return result; }
/********************* Security Obj Helpers **********************/ char * security_get_uri(lwm2m_object_t * obj, int instanceId, char * uriBuffer, int bufferSize){ int size = 1; lwm2m_data_t * dataP = lwm2m_data_new(size); dataP->id = 0; // security server uri obj->readFunc(instanceId, &size, &dataP, obj); if (dataP != NULL && dataP->type == LWM2M_TYPE_STRING && dataP->value.asBuffer.length > 0) { if (bufferSize > dataP->value.asBuffer.length){ memset(uriBuffer,0,dataP->value.asBuffer.length+1); strncpy(uriBuffer,dataP->value.asBuffer.buffer,dataP->value.asBuffer.length); lwm2m_data_free(size, dataP); return uriBuffer; } } lwm2m_data_free(size, dataP); return NULL; }
static uint8_t prv_server_read(uint16_t instanceId, int * numDataP, lwm2m_data_t ** dataArrayP, lwm2m_object_t * objectP) { server_instance_t * targetP; uint8_t result; int i; targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (NULL == targetP) return COAP_404_NOT_FOUND; // is the server asking for the full instance ? if (*numDataP == 0) { uint16_t resList[] = { LWM2M_SERVER_SHORT_ID_ID, LWM2M_SERVER_LIFETIME_ID, LWM2M_SERVER_STORING_ID, LWM2M_SERVER_BINDING_ID }; int nbRes = sizeof(resList)/sizeof(uint16_t); *dataArrayP = lwm2m_data_new(nbRes); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; *numDataP = nbRes; for (i = 0 ; i < nbRes ; i++) { (*dataArrayP)[i].id = resList[i]; } } i = 0; do { result = prv_get_value((*dataArrayP) + i, targetP); i++; } while (i < *numDataP && result == COAP_205_CONTENT); return result; }
static int ICACHE_FLASH_ATTR prv_getMandatoryInfo(lwm2m_object_t * objectP, uint16_t instanceID, lwm2m_server_t * targetP) { lwm2m_data_t * dataP; int size; int64_t value; size = 2; dataP = lwm2m_data_new(size); if (dataP == NULL) return -1; dataP[0].id = LWM2M_SERVER_LIFETIME_ID; dataP[1].id = LWM2M_SERVER_BINDING_ID; if (objectP->readFunc(instanceID, &size, &dataP, objectP) != COAP_205_CONTENT) { lwm2m_data_free(size, dataP); return -1; } if (0 == lwm2m_data_decode_int(dataP, &value) || value < 0 || value >0xFFFFFFFF) // This is an implementation limit { lwm2m_data_free(size, dataP); return -1; } targetP->lifetime = value; targetP->binding = lwm2m_stringToBinding(dataP[1].value, dataP[1].length); lwm2m_data_free(size, dataP); if (targetP->binding == BINDING_UNKNOWN) { return -1; } return 0; }
static lwm2m_list_t * ICACHE_FLASH_ATTR prv_findServerInstance(lwm2m_object_t * objectP, uint16_t shortID) { lwm2m_list_t * instanceP; instanceP = objectP->instanceList; while (NULL != instanceP) { int64_t value; lwm2m_data_t * dataP; int size; size = 1; dataP = lwm2m_data_new(size); if (dataP == NULL) return NULL; dataP->id = LWM2M_SERVER_SHORT_ID_ID; if (objectP->readFunc(instanceP->id, &size, &dataP, objectP) != COAP_205_CONTENT) { lwm2m_data_free(size, dataP); return NULL; } if (1 == lwm2m_data_decode_int(dataP, &value)) { if (value == shortID) { lwm2m_data_free(size, dataP); break; } } lwm2m_data_free(size, dataP); instanceP = instanceP->next; } return instanceP; }
int64_t security_get_mode(lwm2m_object_t * obj, int instanceId){ int size = 1; lwm2m_data_t * dataP = lwm2m_data_new(size); dataP->id = 2; // security mode obj->readFunc(instanceId, &size, &dataP, obj); if (dataP != NULL && dataP->dataType == LWM2M_TYPE_INTEGER && dataP->type == LWM2M_TYPE_RESOURCE && dataP->length > 0) { int64_t mode; if (0 != lwm2m_data_decode_int(dataP,&mode)) { lwm2m_data_free(size, dataP); return mode; } } lwm2m_data_free(size, dataP); printf("Unable to get security mode : use not secure mode"); return LWM2M_SECURITY_MODE_NONE; }
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; }
char * security_get_secret_key(lwm2m_object_t * obj, int instanceId, int * length){ int size = 1; lwm2m_data_t * dataP = lwm2m_data_new(size); dataP->id = 5; // secret key obj->readFunc(instanceId, &size, &dataP, obj); if (dataP != NULL && dataP->type == LWM2M_TYPE_OPAQUE) { char * buff; buff = (char*)lwm2m_malloc(dataP->value.asBuffer.length); if (buff != 0) { memcpy(buff, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length); *length = dataP->value.asBuffer.length; } lwm2m_data_free(size, dataP); return buff; } else { return NULL; } }
static int prv_add_server(bs_info_t * infoP, read_server_t * dataP) { lwm2m_data_t * tlvP; int size; bs_server_tlv_t * serverP; lwm2m_media_type_t format; switch (dataP->securityMode) { case LWM2M_SECURITY_MODE_NONE: size = 4; break; case LWM2M_SECURITY_MODE_PRE_SHARED_KEY: size = 6; break; case LWM2M_SECURITY_MODE_RAW_PUBLIC_KEY: case LWM2M_SECURITY_MODE_CERTIFICATE: size = 7; break; default: return -1; } serverP = (bs_server_tlv_t *)lwm2m_malloc(sizeof(bs_server_tlv_t)); if (serverP == NULL) return -1; memset(serverP, 0, sizeof(bs_server_tlv_t)); serverP->id = dataP->id; tlvP = lwm2m_data_new(size); if (tlvP == NULL) goto error; // LWM2M Server URI tlvP[0].id = LWM2M_SECURITY_URI_ID; lwm2m_data_encode_string(dataP->uri, tlvP); // Bootstrap Server tlvP[1].id = LWM2M_SECURITY_BOOTSTRAP_ID; lwm2m_data_encode_bool(dataP->isBootstrap, tlvP + 1); // Short Server ID tlvP[2].id = LWM2M_SECURITY_SHORT_SERVER_ID; lwm2m_data_encode_int(dataP->id, tlvP + 2); // Security Mode tlvP[3].id = LWM2M_SECURITY_SECURITY_ID; lwm2m_data_encode_int(dataP->securityMode, tlvP + 3); if (size > 4) { tlvP[4].id = LWM2M_SECURITY_PUBLIC_KEY_ID; lwm2m_data_encode_opaque(dataP->publicKey, dataP->publicKeyLen, tlvP + 4); tlvP[5].id = LWM2M_SECURITY_SECRET_KEY_ID; lwm2m_data_encode_opaque(dataP->secretKey, dataP->secretKeyLen, tlvP + 5); if (size == 7) { tlvP[6].id = LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID; lwm2m_data_encode_opaque(dataP->serverKey, dataP->serverKeyLen, tlvP + 5); } } format = LWM2M_CONTENT_TLV; serverP->securityLen = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->securityData)); if (serverP->securityLen <= 0) goto error; lwm2m_data_free(size, tlvP); if (dataP->isBootstrap == false) { size = 4; tlvP = lwm2m_data_new(size); if (tlvP == NULL) goto error; // Short Server ID tlvP[0].id = LWM2M_SERVER_SHORT_ID_ID; lwm2m_data_encode_int(dataP->id, tlvP); // Lifetime tlvP[1].id = LWM2M_SERVER_LIFETIME_ID; lwm2m_data_encode_int(dataP->lifetime, tlvP + 1); // Notification Storing tlvP[2].id = LWM2M_SERVER_STORING_ID; lwm2m_data_encode_bool(false, tlvP + 2); // Binding tlvP[3].id = LWM2M_SERVER_BINDING_ID; lwm2m_data_encode_string("U", tlvP + 3); serverP->serverLen = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->serverData)); if (serverP->serverLen <= 0) goto error; lwm2m_data_free(size, tlvP); } infoP->serverList = (bs_server_tlv_t *)LWM2M_LIST_ADD(infoP->serverList, serverP); return 0; error: if (tlvP != NULL) lwm2m_data_free(size, tlvP); if (serverP->securityData != NULL) lwm2m_free(serverP->securityData); if (serverP->serverData != NULL) lwm2m_free(serverP->serverData); lwm2m_free(serverP); return -1; }
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; }
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; }
static void prv_create_client(char * buffer, void * user_data) { lwm2m_context_t * lwm2mH = (lwm2m_context_t *) user_data; uint16_t clientId; lwm2m_uri_t uri; char * end = NULL; int result; int64_t value; uint8_t * temp_buffer = NULL; int temp_length = 0; lwm2m_media_type_t format = LWM2M_CONTENT_TEXT; //Get Client ID result = prv_read_id(buffer, &clientId); if (result != 1) goto syntax_error; //Get Uri buffer = get_next_arg(buffer, &end); if (buffer[0] == 0) goto syntax_error; result = lwm2m_stringToUri(buffer, end - buffer, &uri); if (result == 0) goto syntax_error; //Get Data to Post buffer = get_next_arg(end, &end); if (buffer[0] == 0) goto syntax_error; if (!check_end_of_args(end)) goto syntax_error; // TLV /* Client dependent part */ if (uri.objectId == 1024) { lwm2m_data_t * dataP; dataP = lwm2m_data_new(1); if (dataP == NULL) { fprintf(stdout, "Allocation error !"); return; } lwm2m_data_encode_int(value, dataP); dataP->id = 1; format = LWM2M_CONTENT_TLV; temp_length = lwm2m_data_serialize(NULL, 1, dataP, &format, &temp_buffer); } /* End Client dependent part*/ //Create result = lwm2m_dm_create(lwm2mH, clientId, &uri, format, temp_buffer, temp_length, prv_result_callback, NULL); if (result == 0) { fprintf(stdout, "OK"); } else { prv_print_error(result); } return; syntax_error: fprintf(stdout, "Syntax error !"); }
static int prv_convertRecord(_record_t * recordArray, int count, lwm2m_data_t ** dataP) { int index; int tlvIndex; lwm2m_data_t * tlvP; // may be overkill tlvP = lwm2m_data_new(count); if (NULL == tlvP) return -1; tlvIndex = 0; for (index = 0 ; index < count ; index++) { lwm2m_data_t * targetP; if (recordArray[index].resInstId == LWM2M_MAX_ID) { targetP = tlvP + tlvIndex; targetP->type = LWM2M_TYPE_RESOURCE; targetP->id = recordArray[index].resId; tlvIndex++; } else { int resIndex; resIndex = 0; while (resIndex < tlvIndex && tlvP[resIndex].id != recordArray[index].resId) { resIndex++; } if (resIndex == tlvIndex) { targetP = lwm2m_data_new(1); if (NULL == targetP) goto error; tlvP[resIndex].type = LWM2M_TYPE_MULTIPLE_RESOURCE; tlvP[resIndex].id = recordArray[index].resId; tlvP[resIndex].length = 1; tlvP[resIndex].value = (uint8_t *)targetP; tlvIndex++; } else { targetP = lwm2m_data_new(tlvP[resIndex].length + 1); if (NULL == targetP) goto error; memcpy(targetP + 1, tlvP[resIndex].value, tlvP[resIndex].length * sizeof(lwm2m_data_t)); lwm2m_free(tlvP[resIndex].value); // do not use lwm2m_data_free() to preserve value pointers tlvP[resIndex].value = (uint8_t *)targetP; tlvP[resIndex].length++; } targetP->type = LWM2M_TYPE_RESOURCE_INSTANCE; targetP->id = recordArray[index].resInstId; } switch (recordArray[index].type) { case _TYPE_FALSE: lwm2m_data_encode_bool(false, targetP); break; case _TYPE_TRUE: lwm2m_data_encode_bool(true, targetP); break; case _TYPE_FLOAT: { size_t i; i = 0; while (i < recordArray[index].valueLen && recordArray[index].value[i] != '.') { i++; } if (i == recordArray[index].valueLen) { int64_t value; if ( 1 != lwm2m_PlainTextToInt64(recordArray[index].value, recordArray[index].valueLen, &value)) { goto error; } lwm2m_data_encode_int(value, targetP); } else { double value; if ( 1 != lwm2m_PlainTextToFloat64(recordArray[index].value, recordArray[index].valueLen, &value)) { goto error; } lwm2m_data_encode_float(value, targetP); } } break; // TODO: Copy string instead of pointing to it case _TYPE_STRING: targetP->flags = LWM2M_TLV_FLAG_STATIC_DATA | LWM2M_TLV_FLAG_TEXT_FORMAT; targetP->dataType = LWM2M_TYPE_STRING; // or opaque ? targetP->length = recordArray[index].valueLen; targetP->value = recordArray[index].value; break; case _TYPE_UNSET: default: goto error; } } *dataP = tlvP; return tlvIndex; error: lwm2m_data_free(count, tlvP); return -1; }