static uint8_t prv_firmware_write(uint16_t instanceId, int numData, lwm2m_tlv_t * dataArray, lwm2m_object_t * objectP, bool bootstrapPending) { int i; bool bvalue; uint8_t result; firmware_data_t * data = (firmware_data_t*)(objectP->userData); // this is a single instance object if (instanceId != 0) { return COAP_404_NOT_FOUND; } i = 0; do { switch (dataArray[i].id) { case 0: // inline firmware binary result = COAP_204_CHANGED; break; case 1: // URL for download the firmware result = COAP_204_CHANGED; break; case 4: if (lwm2m_tlv_decode_bool(&dataArray[i], &bvalue) == 1) { data->supported = bvalue ? 1 : 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 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; }
static uint8_t prv_server_write(uint16_t instanceId, int numData, lwm2m_tlv_t * dataArray, lwm2m_object_t * objectP) { server_instance_t * targetP; int i; uint8_t result; targetP = (server_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_SERVER_SHORT_ID_ID: { uint32_t value; result = prv_set_int_value(dataArray + i, &value); if (COAP_204_CHANGED == result) { if (0 < value && value <= 0xFFFF) { targetP->shortServerId = value; } else { result = COAP_406_NOT_ACCEPTABLE; } } } break; case LWM2M_SERVER_LIFETIME_ID: result = prv_set_int_value(dataArray + i, (uint32_t *)&(targetP->lifetime)); break; case LWM2M_SERVER_DISABLE_ID: result = COAP_405_METHOD_NOT_ALLOWED; break; case LWM2M_SERVER_STORING_ID: { bool value; if (1 == lwm2m_tlv_decode_bool(dataArray + i, &value)) { targetP->storing = value; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } } break; case LWM2M_SERVER_BINDING_ID: if ((dataArray[i].length > 0 && dataArray[i].length <= 3) && (strncmp((char*)dataArray[i].value, "U", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "UQ", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "S", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "SQ", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "US", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "UQS", dataArray[i].length) == 0)) { strncpy(targetP->binding, (char*)dataArray[i].value, dataArray[i].length); result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case LWM2M_SERVER_UPDATE_ID: result = COAP_405_METHOD_NOT_ALLOWED; break; default: return COAP_404_NOT_FOUND; } i++; } while (i < numData && result == COAP_204_CHANGED); return result; }
static uint8_t prv_firmware_write(uint16_t instanceId, int numData, lwm2m_tlv_t * dataArray, lwm2m_object_t * objectP) { int i; bool bvalue; uint8_t result; firmware_data_t * data = (firmware_data_t*)(objectP->userData); UINT cnt; FRESULT err; // this is a single instance object if (instanceId != 0) { return COAP_404_NOT_FOUND; } i = 0; do { switch (dataArray[i].id) { case RES_M_PACKAGE: // inline firmware binary if (data->state == 1 || data->state == 3) { if ((err = f_open(&fp, "boot.hex", FA_WRITE | FA_CREATE_ALWAYS))) { xprintf("err is : %d\n",err); break; } f_write(&fp, dataArray->value, dataArray->length, &cnt); data->state = 2; } else { f_write(&fp, dataArray->value, dataArray->length, &cnt); } if (cnt != 256) { data->state = 3; f_close(&fp); } result = COAP_204_CHANGED; break; case RES_M_PACKAGE_URI: // URL for download the firmware result = COAP_204_CHANGED; break; case RES_O_UPDATE_SUPPORTED_OPJECTS: if (lwm2m_tlv_decode_bool(&dataArray[i], &bvalue)) { data->supported = bvalue ? 1 : 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; }