static uint8_t prv_device_write(uint16_t instanceId, int numData, lwm2m_tlv_t * dataArray, lwm2m_object_t * objectP) { int i; uint8_t result; // this is a single instance object if (instanceId != 0) { return COAP_404_NOT_FOUND; } i = 0; do { switch (dataArray[i].id) { case 13: if (1 == lwm2m_tlv_decode_int(dataArray + i, &((device_data_t*)(objectP->userData))->time)) { result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case 14: if (1 == prv_check_time_offset(dataArray[i].value, dataArray[i].length)) { strncpy(((device_data_t*)(objectP->userData))->time_offset, dataArray[i].value, dataArray[i].length); ((device_data_t*)(objectP->userData))->time_offset[dataArray[i].length] = 0; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; default: result = COAP_405_METHOD_NOT_ALLOWED; } i++; } while (i < numData && result == COAP_204_CHANGED); return result; }
static int prv_getMandatoryInfo(lwm2m_object_t * objectP, uint16_t instanceID, lwm2m_server_t * targetP) { lwm2m_tlv_t * tlvP; int size; int64_t value; size = 2; tlvP = lwm2m_tlv_new(size); if (tlvP == NULL) return -1; tlvP[0].id = LWM2M_SERVER_LIFETIME_ID; tlvP[1].id = LWM2M_SERVER_BINDING_ID; if (objectP->readFunc(instanceID, &size, &tlvP, objectP) != COAP_205_CONTENT) { lwm2m_free(tlvP); return -1; } if (0 == lwm2m_tlv_decode_int(tlvP, &value) || value < 0 || value >0xFFFFFFFF) // This is an implementation limit { lwm2m_free(tlvP); return -1; } targetP->lifetime = value; targetP->binding = lwm2m_stringToBinding(tlvP[1].value, tlvP[1].length); lwm2m_free(tlvP); if (targetP->binding == BINDING_UNKNOWN) { return -1; } return 0; }
static lwm2m_list_t * prv_findServerInstance(lwm2m_object_t * objectP, uint16_t shortID) { lwm2m_list_t * instanceP; lwm2m_tlv_t * tlvP; int size; size = 1; tlvP = lwm2m_tlv_new(size); if (tlvP == NULL) return NULL; tlvP->id = LWM2M_SERVER_SHORT_ID_ID; instanceP = objectP->instanceList; while (instanceP != NULL) { int64_t value; if (objectP->readFunc(instanceP->id, &size, &tlvP, objectP) != COAP_205_CONTENT) { lwm2m_free(tlvP); return NULL; } if (1 == lwm2m_tlv_decode_int(tlvP, &value)) { if (value == shortID) { break; } } instanceP = instanceP->next; } lwm2m_free(tlvP); return instanceP; }
static uint8_t prv_set_int_value(lwm2m_tlv_t * dataArray, uint32_t * data) { uint8_t result; int64_t value; if (1 == lwm2m_tlv_decode_int(dataArray, &value)) { if (value >= 0 && value <= 0xFFFFFFFF) { *data = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } return result; }
static uint8_t prv_security_write(uint16_t instanceId, int numData, lwm2m_tlv_t * dataArray, lwm2m_object_t * objectP) { security_instance_t * targetP; int i; uint8_t result = COAP_204_CHANGED; if ((dataArray->flags & LWM2M_TLV_FLAG_BOOTSTRAPPING) == 0) return COAP_401_UNAUTHORIZED; targetP = (security_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (NULL == targetP) { return COAP_404_NOT_FOUND; } i = 0; do { switch (dataArray[i].id) { case LWM2M_SECURITY_URI_ID: if (targetP->uri != NULL) lwm2m_free(targetP->uri); targetP->uri = (char *)lwm2m_malloc(dataArray[i].length + 1); memset(targetP->uri, 0, dataArray[i].length + 1); if (targetP->uri != NULL) { strncpy(targetP->uri, (char*)dataArray[i].value, dataArray[i].length); result = COAP_204_CHANGED; } else { result = COAP_500_INTERNAL_SERVER_ERROR; } break; case LWM2M_SECURITY_BOOTSTRAP_ID: if (1 == lwm2m_tlv_decode_bool(dataArray + i, &(targetP->isBootstrap))) { result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case LWM2M_SECURITY_SECURITY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_PUBLIC_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SECRET_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_SECURITY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_KEY_PARAM_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_SECRET_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_SERVER_NUMBER_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SHORT_SERVER_ID: { int64_t value; if (1 == lwm2m_tlv_decode_int(dataArray + i, &value)) { if (value >= 0 && value <= 0xFFFF) { targetP->shortID = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } } break; case LWM2M_SECURITY_HOLD_OFF_ID: { int64_t value; if (1 == lwm2m_tlv_decode_int(dataArray + i, &value)) { if (value >= 0 && value <= 0xFFFF) { targetP->clientHoldOffTime = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } default: return COAP_404_NOT_FOUND; } i++; } while (i < numData && result == COAP_204_CHANGED); return result; }
static uint8_t prv_security_write(uint16_t instanceId, int numData, lwm2m_tlv_t * dataArray, lwm2m_object_t * objectP, bool bootstrapPending) { security_instance_t * targetP; int i; uint8_t result = COAP_204_CHANGED; targetP = (security_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (NULL == targetP) { LOG(" >>>> Object with instanceID: %u not found\r\n", instanceId); if (bootstrapPending == true) { targetP = (security_instance_t *)lwm2m_malloc(sizeof(security_instance_t)); if (NULL == targetP) { return COAP_500_INTERNAL_SERVER_ERROR; } memset(targetP, 0, sizeof(security_instance_t)); targetP->instanceId = instanceId; objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, targetP); LOG(" >>>> new instance created: /%u/%u\r\n", objectP->objID, targetP->instanceId); } else { return COAP_404_NOT_FOUND; } } i = 0; do { switch (dataArray[i].id) { case LWM2M_SECURITY_URI_ID: if (targetP->uri != NULL) lwm2m_free(targetP->uri); targetP->uri = (char *)lwm2m_malloc(dataArray[i].length + 1); memset(targetP->uri, 0, dataArray[i].length + 1); if (targetP->uri != NULL) { strncpy(targetP->uri, dataArray[i].value, dataArray[i].length); result = COAP_204_CHANGED; } else { result = COAP_500_INTERNAL_SERVER_ERROR; } break; case LWM2M_SECURITY_BOOTSTRAP_ID: if (1 == lwm2m_tlv_decode_bool(dataArray + i, &(targetP->isBootstrap))) { result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case LWM2M_SECURITY_SECURITY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_PUBLIC_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SECRET_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_SECURITY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_KEY_PARAM_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_SECRET_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_SERVER_NUMBER_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SHORT_SERVER_ID: { int64_t value; if (1 == lwm2m_tlv_decode_int(dataArray + i, &value)) { if (value >= 0 && value <= 0xFFFF) { targetP->shortID = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } } break; case LWM2M_SECURITY_HOLD_OFF_ID: { int64_t value; if (1 == lwm2m_tlv_decode_int(dataArray + i, &value)) { if (value >= 0 && value <= 0xFFFF) { targetP->clientHoldOffTime = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } default: return COAP_404_NOT_FOUND; } i++; } while (i < numData && result == COAP_204_CHANGED); return result; }
void dump_tlv(FILE * stream, int size, lwm2m_tlv_t * tlvP, int indent) { int i; for(i= 0 ; i < size ; i++) { print_indent(stream, indent); fprintf(stream, "{\r\n"); print_indent(stream, indent+1); fprintf(stream, "id: %d\r\n", tlvP[i].id); print_indent(stream, indent+1); fprintf(stream, "type: "); switch (tlvP[i].type) { case LWM2M_TYPE_OBJECT_INSTANCE: fprintf(stream, "LWM2M_TYPE_OBJECT_INSTANCE\r\n"); break; case LWM2M_TYPE_RESOURCE_INSTANCE: fprintf(stream, "LWM2M_TYPE_RESOURCE_INSTANCE\r\n"); break; case LWM2M_TYPE_MULTIPLE_RESOURCE: fprintf(stream, "LWM2M_TYPE_MULTIPLE_RESOURCE\r\n"); break; case LWM2M_TYPE_RESOURCE: fprintf(stream, "LWM2M_TYPE_RESOURCE\r\n"); break; default: fprintf(stream, "unknown (%d)\r\n", (int)tlvP[i].type); break; } print_indent(stream, indent+1); fprintf(stream, "flags: "); if (tlvP[i].flags & LWM2M_TLV_FLAG_STATIC_DATA) { fprintf(stream, "STATIC_DATA"); if (tlvP[i].flags & LWM2M_TLV_FLAG_TEXT_FORMAT) { fprintf(stream, " | TEXT_FORMAT"); } } else if (tlvP[i].flags & LWM2M_TLV_FLAG_TEXT_FORMAT) { fprintf(stream, "TEXT_FORMAT"); } fprintf(stream, "\r\n"); print_indent(stream, indent+1); fprintf(stream, "data length: %d\r\n", (int) tlvP[i].length); if (tlvP[i].type == LWM2M_TYPE_OBJECT_INSTANCE || tlvP[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) { dump_tlv(stream, tlvP[i].length, (lwm2m_tlv_t *)(tlvP[i].value), indent+1); } else { print_indent(stream, indent+1); fprintf(stream, "data type: "); switch (tlvP[i].dataType) { case LWM2M_TYPE_INTEGER: fprintf(stream, "Integer"); if ((tlvP[i].flags & LWM2M_TLV_FLAG_TEXT_FORMAT) == 0) { int64_t value; if (1 == lwm2m_tlv_decode_int(tlvP + i, &value)) { fprintf(stream, " (%" PRId64 ")", value); } } break; case LWM2M_TYPE_STRING: fprintf(stream, "String"); break; case LWM2M_TYPE_FLOAT: fprintf(stream, "Float"); break; case LWM2M_TYPE_BOOLEAN: fprintf(stream, "Boolean"); if ((tlvP[i].flags & LWM2M_TLV_FLAG_TEXT_FORMAT) == 0) { bool value; if (1 == lwm2m_tlv_decode_bool(tlvP + i, &value)) { fprintf(stream, " (%s)", value?"true":"false"); } } break; case LWM2M_TYPE_TIME: fprintf(stream, "Time"); break; case LWM2M_TYPE_OBJECT_LINK: fprintf(stream, "Object Link"); break; case LWM2M_TYPE_OPAQUE: fprintf(stream, "Opaque"); break; case LWM2M_TYPE_UNDEFINED: fprintf(stream, "Undefined"); break; } fprintf(stream, "\r\n"); output_buffer(stream, tlvP[i].value, tlvP[i].length, indent+1); } print_indent(stream, indent); fprintf(stream, "}\r\n"); } }
int object_getServers(lwm2m_context_t * contextP) { lwm2m_object_t * securityObjP; lwm2m_object_t * serverObjP; lwm2m_list_t * securityInstP; // instanceID of the server in the LWM2M Security Object int i; for (i = 0 ; i < contextP->numObject ; i++) { if (contextP->objectList[i]->objID == LWM2M_SECURITY_OBJECT_ID) { securityObjP = contextP->objectList[i]; } else if (contextP->objectList[i]->objID == LWM2M_SERVER_OBJECT_ID) { serverObjP = contextP->objectList[i]; } } securityInstP = securityObjP->instanceList; while (securityInstP != NULL) { lwm2m_tlv_t * tlvP; int size; lwm2m_server_t * targetP; bool isBootstrap; int64_t value = 0; size = 3; tlvP = lwm2m_tlv_new(size); if (tlvP == NULL) return -1; tlvP[0].id = LWM2M_SECURITY_BOOTSTRAP_ID; tlvP[1].id = LWM2M_SECURITY_SHORT_SERVER_ID; tlvP[2].id = LWM2M_SECURITY_HOLD_OFF_ID; if (securityObjP->readFunc(securityInstP->id, &size, &tlvP, securityObjP) != COAP_205_CONTENT) { lwm2m_free(tlvP); return -1; } targetP = (lwm2m_server_t *)lwm2m_malloc(sizeof(lwm2m_server_t)); if (targetP == NULL) return -1; memset(targetP, 0, sizeof(lwm2m_server_t)); if (0 == lwm2m_tlv_decode_bool(tlvP + 0, &isBootstrap)) { lwm2m_free(targetP); lwm2m_free(tlvP); return -1; } if (0 == lwm2m_tlv_decode_int(tlvP + 1, &value) || value <= 0 || value >0xFFFF) // 0 is forbidden as a Short Server ID { lwm2m_free(targetP); lwm2m_free(tlvP); return -1; } targetP->shortID = value; if (isBootstrap == true) { if (0 == lwm2m_tlv_decode_int(tlvP + 1, &value) || value < 0 || value >0xFFFFFFFF) // This is an implementation limit { lwm2m_free(targetP); lwm2m_free(tlvP); return -1; } 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_free(tlvP); return -1; } if (0 != prv_getMandatoryInfo(serverObjP, serverInstP->id, targetP)) { lwm2m_free(targetP); lwm2m_free(tlvP); return -1; } contextP->serverList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->serverList, targetP); } lwm2m_free(tlvP); securityInstP = securityInstP->next; } return 0; }
uint8_t connectivity_moni_change(lwm2m_tlv_t * dataArray, lwm2m_object_t * objectP) { int64_t value; uint8_t result; conn_m_data_t * data; data = (conn_m_data_t*) (objectP->userData); switch (dataArray->id) { case RES_M_RADIO_SIGNAL_STRENGTH: if (1 == lwm2m_tlv_decode_int(dataArray, &value)) { data->signalStrength = value; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case RES_O_LINK_QUALITY: if (1 == lwm2m_tlv_decode_int(dataArray, &value)) { data->linkQuality = value; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case RES_M_IP_ADDRESSES: if (sizeof(data->ipAddresses[0]) <= dataArray->length) { result = COAP_400_BAD_REQUEST; } else { memset(data->ipAddresses[0], 0, sizeof(data->ipAddresses[0])); memcpy(data->ipAddresses[0], dataArray->value, dataArray->length); data->ipAddresses[0][dataArray->length] = 0; result = COAP_204_CHANGED; } break; case RES_O_ROUTER_IP_ADDRESS: if (sizeof(data->routerIpAddresses[0]) <= dataArray->length) { result = COAP_400_BAD_REQUEST; } else { memset(data->routerIpAddresses[0], 0, sizeof(data->routerIpAddresses[0])); memcpy(data->routerIpAddresses[0], dataArray->value, dataArray->length); data->routerIpAddresses[0][dataArray->length] = 0; result = COAP_204_CHANGED; } break; case RES_O_CELL_ID: if (1 == lwm2m_tlv_decode_int(dataArray, &value)) { data->cellId = value; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; default: result = COAP_405_METHOD_NOT_ALLOWED; } return result; }