void coap_SendNotify(AddressType * addr, const char * path, const char * token, int tokenSize, ContentType contentType, const char * payload, int payloadLen, int sequence) { // TODO - FIXME: if path is not full uri then map addr to Network address + append path(?) coap_packet_t notify; coap_transaction_t *transaction; NetworkAddress * remoteAddress = NetworkAddress_New(path, strlen(path)); Lwm2m_Debug("Coap notify: %s\n", path); //Lwm2m_Debug("Coap IPv6 request address: " PRINT6ADDR(&addr->Addr)); //Lwm2m_Debug("Coap request port: %d\n", addr->Port); coap_init_message(¬ify, COAP_TYPE_NON, CONTENT_2_05, coap_get_mid()); if (contentType != ContentType_None) { coap_set_header_content_format(¬ify, contentType); coap_set_payload(¬ify, payload, payloadLen); } coap_set_token(¬ify, token, tokenSize); coap_set_header_observe(¬ify, sequence); if ((transaction = coap_new_transaction(networkSocket, notify.mid, remoteAddress))) { transaction->packet_len = coap_serialize_message(¬ify, transaction->packet); coap_send_transaction(transaction); // for NON confirmable messages this will call coap_clear_transaction(); } }
/*-----------------------------------------------------------------------------------*/ void coap_observe_handler(resource_t *resource, void *request, void *response) { static char content[26]; if (response && ((coap_packet_t *)response)->code<128) /* response without error code */ { if (IS_OPTION((coap_packet_t *)request, COAP_OPTION_OBSERVE)) { if (IS_OPTION((coap_packet_t *)request, COAP_OPTION_TOKEN)) { if (coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, ((coap_packet_t *)request)->token, ((coap_packet_t *)request)->token_len, resource->url)) { coap_set_header_observe(response, 0); coap_set_payload(response, (uint8_t *)content, snprintf(content, sizeof(content), "Added as observer %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS)); } else { ((coap_packet_t *)response)->code = SERVICE_UNAVAILABLE_503; coap_set_payload(response, (uint8_t *)"Too many observers", 18); } /* if (added observer) */ } else /* if (token) */ { ((coap_packet_t *)response)->code = TOKEN_OPTION_REQUIRED; coap_set_payload(response, (uint8_t *)"Observing requires token", 24); } /* if (token) */ } else /* if (observe) */ { /* Remove client if it is currently observing. */ coap_remove_observer_by_client(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport); } /* if (observe) */ } }
void coap_SendNotify(AddressType * addr, const char * path, const char * token, int tokenSize, ContentType contentType, const char * payload, int payloadLen, int sequence) { coap_packet_t notify; coap_transaction_t *transaction; Lwm2m_Debug("Coap notify: %s\n", path); Lwm2m_Debug("Coap IPv6 request address: " PRINT6ADDR(&addr->Addr)); Lwm2m_Debug("Coap request port: %d\n", addr->Port); coap_init_message(¬ify, COAP_TYPE_NON, CONTENT_2_05, coap_get_mid()); if (contentType != ContentType_None) { coap_set_header_content_format(¬ify, contentType); coap_set_payload(¬ify, payload, payloadLen); } coap_set_token(¬ify, token, tokenSize); coap_set_header_observe(¬ify, sequence); if ((transaction = coap_new_transaction(notify.mid, &addr->Addr, uip_htons(addr->Port)))) { transaction->packet_len = coap_serialize_message(¬ify, transaction->packet); coap_send_transaction(transaction); // for NON confirmable messages this will call coap_clear_transaction(); } }
/*-----------------------------------------------------------------------------------*/ void coap_observe_handler(resource_t *resource, void *request, void *response) { coap_packet_t *const coap_req = (coap_packet_t *) request; coap_packet_t *const coap_res = (coap_packet_t *) response; static char content[16]; if (coap_req->code==COAP_GET && coap_res->code<128) /* GET request and response without error code */ { if (IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) { if (coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, coap_req->token, coap_req->token_len, resource->url)) { coap_set_header_observe(coap_res, 0); /* * For demonstration purposes only. A subscription should return the same representation as a normal GET. * TODO: Comment the following line for any real application. */ coap_set_payload(coap_res, content, snprintf(content, sizeof(content), "Added %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS)); } else { coap_res->code = SERVICE_UNAVAILABLE_5_03; coap_set_payload(coap_res, "TooManyObservers", 16); } /* if (added observer) */ } else /* if (observe) */ { /* Remove client if it is currently observing. */ coap_remove_observer_by_url(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, resource->url); } /* if (observe) */ } }
int lwm2m_observe_cancel(lwm2m_context_t * contextP, uint16_t clientID, lwm2m_uri_t * uriP, lwm2m_result_callback_t callback, void * userData) { lwm2m_client_t * clientP; lwm2m_observation_t * observationP; clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); if (clientP == NULL) return COAP_404_NOT_FOUND; observationP = prv_findObservationByURI(clientP, uriP); if (observationP == NULL) return COAP_404_NOT_FOUND; switch (observationP->status) { case STATE_REGISTERED: { lwm2m_transaction_t * transactionP; cancellation_data_t * cancelP; transactionP = transaction_new(COAP_TYPE_CON, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 0, NULL, ENDPOINT_CLIENT, (void *)clientP); if (transactionP == NULL) { return COAP_500_INTERNAL_SERVER_ERROR; } cancelP = (cancellation_data_t *)lwm2m_malloc(sizeof(cancellation_data_t)); if (cancelP == NULL) { lwm2m_free(transactionP); return COAP_500_INTERNAL_SERVER_ERROR; } coap_set_header_observe(transactionP->message, 1); cancelP->observationP = observationP; cancelP->callbackP = callback; cancelP->userDataP = userData; transactionP->callback = prv_obsCancelRequestCallback; transactionP->userData = (void *)cancelP; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transactionP); return transaction_send(contextP, transactionP); } case STATE_REG_PENDING: observationP->status = STATE_DEREG_PENDING; break; default: // Should not happen break; } return COAP_NO_ERROR; }
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; } }
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); }
/*---------------------------------------------------------------------------*/ void coap_notify_observers(resource_t *resource) { /* build notification */ coap_packet_t notification[1]; /* this way the packet can be treated as pointer as usual */ coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0); coap_observer_t *obs = NULL; PRINTF("Observe: Notification from %s\n", resource->url); /* iterate over observers */ for(obs = (coap_observer_t *)list_head(observers_list); obs; obs = obs->next) { if(obs->url == resource->url) { /* using RESOURCE url pointer as handle */ coap_transaction_t *transaction = NULL; /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers */ if((transaction = coap_new_transaction(coap_get_mid(), &obs->addr, obs->port))) { if(obs->obs_counter % COAP_OBSERVE_REFRESH_INTERVAL == 0) { PRINTF(" Force Confirmable for\n"); notification->type = COAP_TYPE_CON; } PRINTF(" Observer "); PRINT6ADDR(&obs->addr); PRINTF(":%u\n", obs->port); /* update last MID for RST matching */ obs->last_mid = transaction->mid; /* prepare response */ notification->mid = transaction->mid; resource->get_handler(NULL, notification, transaction->packet + COAP_MAX_HEADER_SIZE, REST_MAX_CHUNK_SIZE, NULL); if(notification->code < BAD_REQUEST_4_00) { coap_set_header_observe(notification, (obs->obs_counter)++); } coap_set_token(notification, obs->token, obs->token_len); transaction->packet_len = coap_serialize_message(notification, transaction->packet); coap_send_transaction(transaction); } } } }
/*-----------------------------------------------------------------------------------*/ void coap_notify_observers(resource_t *resource, int32_t obs_counter, void *notification) { coap_packet_t *const coap_res = (coap_packet_t *) notification; coap_observer_t* obs = NULL; uint8_t preferred_type = coap_res->type; PRINTF("Observing: Notification from %s\n", resource->url); /* Iterate over observers. */ for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) { if (obs->url==resource->url) /* using RESOURCE url pointer as handle */ { coap_transaction_t *transaction = NULL; /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers. */ if ( (transaction = coap_new_transaction(coap_get_mid(), &obs->addr, obs->port)) ) { PRINTF(" Observer "); PRINT6ADDR(&obs->addr); PRINTF(":%u\n", obs->port); /* Update last MID for RST matching. */ obs->last_mid = transaction->mid; /* Prepare response */ coap_res->mid = transaction->mid; coap_set_header_observe(coap_res, obs_counter); coap_set_header_token(coap_res, obs->token, obs->token_len); /* Use CON to check whether client is still there/interested after COAP_OBSERVING_REFRESH_INTERVAL. */ if (stimer_expired(&obs->refresh_timer)) { PRINTF(" Refreshing with CON\n"); coap_res->type = COAP_TYPE_CON; stimer_restart(&obs->refresh_timer); } else { coap_res->type = preferred_type; } transaction->packet_len = coap_serialize_message(coap_res, transaction->packet); coap_send_transaction(transaction); } } } }
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; }
void oc_send_separate_response(oc_separate_response_t *handle, oc_status_t response_code) { oc_response_buffer_t response_buffer; response_buffer.buffer = handle->buffer; response_buffer.response_length = response_length(); response_buffer.code = oc_status_code(response_code); coap_separate_t *cur = oc_list_head(handle->requests), *next = NULL; coap_packet_t response[1]; while (cur != NULL) { next = cur->next; if (cur->observe > 0) { coap_transaction_t *t = coap_new_transaction(coap_get_mid(), &cur->endpoint); if (t) { coap_separate_resume(response, cur, oc_status_code(response_code), t->mid); coap_set_header_content_format(response, APPLICATION_CBOR); if (cur->observe == 1) { coap_set_header_observe(response, 1); } if (response_buffer.response_length > 0) { coap_set_payload(response, handle->buffer, response_buffer.response_length); } t->message->length = coap_serialize_message(response, t->message->data); coap_send_transaction(t); } coap_separate_clear(handle, cur); } else { if (coap_notify_observers(NULL, &response_buffer, &cur->endpoint) == 0) { coap_separate_clear(handle, cur); } } cur = next; } if (oc_list_length(handle->requests) == 0) { handle->active = 0; } }
/*---------------------------------------------------------------------------*/ void coap_observe_handler(resource_t *resource, void *request, void *response) { coap_packet_t *const coap_req = (coap_packet_t *)request; coap_packet_t *const coap_res = (coap_packet_t *)response; coap_observer_t * obs; if(coap_req->code == COAP_GET && coap_res->code < 128) { /* GET request and response without error code */ if(IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) { if(coap_req->observe == 0) { obs = coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, coap_req->token, coap_req->token_len, resource->url); if(obs) { coap_set_header_observe(coap_res, (obs->obs_counter)++); /* * Following payload is for demonstration purposes only. * A subscription should return the same representation as a normal GET. * Uncomment if you want an information about the avaiable observers. */ #if 0 static char content[16]; coap_set_payload(coap_res, content, snprintf(content, sizeof(content), "Added %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS)); #endif } else { coap_res->code = SERVICE_UNAVAILABLE_5_03; coap_set_payload(coap_res, "TooManyObservers", 16); } } else if(coap_req->observe == 1) { /* remove client if it is currently observe */ coap_remove_observer_by_token(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, coap_req->token, coap_req->token_len); } } } }
void ICACHE_FLASH_ATTR lwm2m_resource_value_changed(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { int result; obs_list_t * listP; lwm2m_watcher_t * watcherP; listP = prv_getObservedList(contextP, uriP); while (listP != NULL) { obs_list_t * targetP; uint8_t * buffer = NULL; size_t length = 0; lwm2m_media_type_t format; format = LWM2M_CONTENT_TEXT; result = object_read(contextP, &listP->item->uri, &format, &buffer, &length); if (result == COAP_205_CONTENT) { coap_packet_t message[1]; coap_init_message(message, COAP_TYPE_NON, COAP_205_CONTENT, 0); coap_set_header_content_type(message, format); coap_set_payload(message, buffer, length); for (watcherP = listP->item->watcherList ; watcherP != NULL ; watcherP = watcherP->next) { watcherP->lastMid = contextP->nextMID++; message->mid = watcherP->lastMid; coap_set_header_token(message, watcherP->token, watcherP->tokenLen); coap_set_header_observe(message, watcherP->counter++); (void)message_send(contextP, message, watcherP->server->sessionH); } } targetP = listP; listP = listP->next; lwm2m_free(targetP); } }
/*-----------------------------------------------------------------------------------*/ void coap_notify_observers(const char *url, int type, uint32_t observe, uint8_t *payload, size_t payload_len) { coap_observer_t* obs = NULL; for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next) { if (obs->url==url) /* using RESOURCE url string as handle */ { coap_transaction_t *transaction = NULL; /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers */ if ( (transaction = coap_new_transaction(coap_get_tid(), &obs->addr, obs->port)) ) { /* Use CON to check whether client is still there/interested after COAP_OBSERVING_REFRESH_INTERVAL. */ if (stimer_expired(&obs->refresh_timer)) { PRINTF("Observing: Refresh client with CON\n"); type = COAP_TYPE_CON; stimer_restart(&obs->refresh_timer); } /* prepare response */ coap_packet_t push[1]; /* This way the packet can be treated as pointer as usual. */ coap_init_message(push, (coap_message_type_t)type, OK_200, transaction->tid ); coap_set_header_observe(push, observe); coap_set_header_token(push, obs->token, obs->token_len); coap_set_payload(push, payload, payload_len); transaction->packet_len = coap_serialize_message(push, transaction->packet); PRINTF("Observing: Notify from /%s for ", url); PRINT6ADDR(&obs->addr); PRINTF(":%u\n", obs->port); PRINTF(" %.*s\n", payload_len, payload); coap_send_transaction(transaction); } } } }
void lwm2m_resource_value_changed(lwm2m_context_t * contextP, lwm2m_uri_t * uriP) { int result; obs_list_t * listP; lwm2m_watcher_t * watcherP; listP = prv_getObservedList(contextP, uriP); while (listP != NULL) { obs_list_t * targetP; char * buffer = NULL; int length = 0; result = object_read(contextP, &listP->item->uri, &buffer, &length); if (result == COAP_205_CONTENT) { coap_packet_t message[1]; coap_init_message(message, COAP_TYPE_ACK, COAP_204_CHANGED, 0); coap_set_payload(message, buffer, length); for (watcherP = listP->item->watcherList ; watcherP != NULL ; watcherP = watcherP->next) { watcherP->lastMid = contextP->nextMID++; message->mid = watcherP->lastMid; coap_set_header_token(message, watcherP->token, watcherP->tokenLen); coap_set_header_observe(message, watcherP->counter++); (void)message_send(contextP, message, watcherP->server->addr, watcherP->server->addrLen); } } targetP = listP; listP = listP->next; lwm2m_free(targetP); } }
int 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]; 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; clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); if (clientP == NULL) return COAP_404_NOT_FOUND; for (observationP = clientP->observationList; observationP != NULL; observationP = observationP->next) { if (uriP->objectId == observationP->uri.objectId && (LWM2M_URI_IS_SET_INSTANCE(uriP) == false || observationP->uri.instanceId == uriP->instanceId) && (LWM2M_URI_IS_SET_INSTANCE(uriP) == false || observationP->uri.instanceId == uriP->instanceId)) { break; } } if (observationP == NULL) { observationP = (lwm2m_observation_t *)lwm2m_malloc(sizeof(lwm2m_observation_t)); if (observationP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; memset(observationP, 0, sizeof(lwm2m_observation_t)); observationP->id = lwm2m_list_newId((lwm2m_list_t *)clientP->observationList); memcpy(&observationP->uri, uriP, sizeof(lwm2m_uri_t)); observationP->clientP = clientP; observationP->clientP->observationList = (lwm2m_observation_t *)LWM2M_LIST_ADD(observationP->clientP->observationList, observationP); } 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(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, token); if (transactionP == NULL) { observationP->clientP->observationList = (lwm2m_observation_t *)LWM2M_LIST_RM(observationP->clientP->observationList, observationP->id, NULL); lwm2m_free(observationP); return COAP_500_INTERNAL_SERVER_ERROR; } coap_set_header_observe(transactionP->message, 0); if (clientP->supportJSON == true) { coap_set_header_accept(transactionP->message, LWM2M_CONTENT_JSON); } else { coap_set_header_accept(transactionP->message, LWM2M_CONTENT_TLV); } transactionP->callback = prv_obsRequestCallback; transactionP->userData = (void *)observationP; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transactionP); return transaction_send(contextP, transactionP); }
void coap_createCoapRequest(coap_method_t method, const char * uri, ContentType contentType, ObserveState observeState, const char * payload, int payloadLen, TransactionCallback callback, void * context) { coap_packet_t request; char path[MAX_COAP_PATH] = { 0 }; char query[128] = { 0 }; coap_transaction_t *transaction; NetworkAddress * remoteAddress = NetworkAddress_New(uri, strlen(uri)); coap_getPathQueryFromURI(uri, path, query); Lwm2m_Info("Coap request: %s\n", uri); //Lwm2m_Debug("Coap request path: %s\n", path); //Lwm2m_Debug("Coap request query: %s\n", query); coap_init_message(&request, COAP_TYPE_CON, method, coap_get_mid()); coap_set_header_uri_path(&request, path); if (strlen(query) > 0) coap_set_header_uri_query(&request, query); // TODO - REVIEW: Erbium must copy path/query from request - else mem out of scope if (contentType != ContentType_None) { if ((method == COAP_POST) || (method == COAP_PUT)) { coap_set_header_content_format(&request, contentType); coap_set_payload(&request, payload, payloadLen); } else { coap_set_header_accept(&request, contentType); } } if (method == COAP_GET) { if (observeState == ObserveState_Establish) { coap_set_header_observe(&request, 0); int token = addObserve(remoteAddress, path, callback, context); if (token != 0) coap_set_token(&request, (const uint8_t *) &token, sizeof(token)); } else if (observeState == ObserveState_Cancel) { coap_set_header_observe(&request, 1); int token = removeObserve(remoteAddress, path); if (token != 0) coap_set_token(&request, (const uint8_t *) &token, sizeof(token)); } } if (CurrentTransaction[CurrentTransactionIndex].TransactionUsed && CurrentTransaction[CurrentTransactionIndex].TransactionPtr) { Lwm2m_Warning("Canceled previous transaction [%d]: %p\n", CurrentTransactionIndex, CurrentTransaction[CurrentTransactionIndex].TransactionPtr); coap_clear_transaction(&CurrentTransaction[CurrentTransactionIndex].TransactionPtr); } //if ((transaction = coap_new_transaction(request.mid, remote_ipaddr, uip_htons(remote_port)))) if ((transaction = coap_new_transaction(networkSocket, request.mid, remoteAddress))) { transaction->callback = coap_CoapRequestCallback; memcpy(CurrentTransaction[CurrentTransactionIndex].Path, path, MAX_COAP_PATH); CurrentTransaction[CurrentTransactionIndex].Callback = callback; CurrentTransaction[CurrentTransactionIndex].Context = context; CurrentTransaction[CurrentTransactionIndex].TransactionUsed = true; CurrentTransaction[CurrentTransactionIndex].TransactionPtr = transaction; NetworkAddress_SetAddressType(remoteAddress, &CurrentTransaction[CurrentTransactionIndex].Address); transaction->callback_data = &CurrentTransaction[CurrentTransactionIndex]; transaction->packet_len = coap_serialize_message(&request, transaction->packet); Lwm2m_Debug("Sending transaction [%d]: %p\n", CurrentTransactionIndex, CurrentTransaction[CurrentTransactionIndex].TransactionPtr); coap_send_transaction(transaction); CurrentTransactionIndex++; if (CurrentTransactionIndex >= MAX_COAP_TRANSACTIONS) { CurrentTransactionIndex = 0; } } }
void observe_step(lwm2m_context_t * contextP, time_t currentTime, time_t * timeoutP) { lwm2m_observed_t * targetP; for (targetP = contextP->observedList ; targetP != NULL ; targetP = targetP->next) { lwm2m_watcher_t * watcherP; uint8_t * buffer = NULL; size_t length = 0; lwm2m_data_t * dataP = NULL; int size = 0; double floatValue = 0; int64_t integerValue = 0; bool storeValue = false; lwm2m_media_type_t format = LWM2M_CONTENT_TEXT; coap_packet_t message[1]; time_t interval; if (LWM2M_URI_IS_SET_RESOURCE(&targetP->uri)) { if (COAP_205_CONTENT != object_readData(contextP, &targetP->uri, &size, &dataP)) continue; switch (dataP->type) { case LWM2M_TYPE_INTEGER: if (1 != lwm2m_data_decode_int(dataP, &integerValue)) continue; storeValue = true; break; case LWM2M_TYPE_FLOAT: if (1 != lwm2m_data_decode_float(dataP, &floatValue)) continue; storeValue = true; break; default: break; } } for (watcherP = targetP->watcherList ; watcherP != NULL ; watcherP = watcherP->next) { if (watcherP->active == true) { bool notify = false; if (watcherP->update == true) { // value changed, should we notify the server ? if (watcherP->parameters == NULL || watcherP->parameters->toSet == 0) { // no conditions notify = true; LOG("observation_step(/%d/%d/%d) notify[1] = TRUE\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId); } if (notify == false && watcherP->parameters != NULL && (watcherP->parameters->toSet & ATTR_FLAG_NUMERIC) != 0) { if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_LESS_THAN) != 0) { // Did we cross the lower treshold ? switch (dataP->type) { case LWM2M_TYPE_INTEGER: if ((integerValue <= watcherP->parameters->lessThan && watcherP->lastValue.asInteger > watcherP->parameters->lessThan) || (integerValue >= watcherP->parameters->lessThan && watcherP->lastValue.asInteger < watcherP->parameters->lessThan)) { notify = true; } break; case LWM2M_TYPE_FLOAT: if ((floatValue <= watcherP->parameters->lessThan && watcherP->lastValue.asFloat > watcherP->parameters->lessThan) || (floatValue >= watcherP->parameters->lessThan && watcherP->lastValue.asFloat < watcherP->parameters->lessThan)) { notify = true; } break; default: break; } LOG("observation_step(/%d/%d/%d) notify[2] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE"); } if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_GREATER_THAN) != 0) { // Did we cross the upper treshold ? switch (dataP->type) { case LWM2M_TYPE_INTEGER: if ((integerValue <= watcherP->parameters->greaterThan && watcherP->lastValue.asInteger > watcherP->parameters->greaterThan) || (integerValue >= watcherP->parameters->greaterThan && watcherP->lastValue.asInteger < watcherP->parameters->greaterThan)) { notify = true; } break; case LWM2M_TYPE_FLOAT: if ((floatValue <= watcherP->parameters->greaterThan && watcherP->lastValue.asFloat > watcherP->parameters->greaterThan) || (floatValue >= watcherP->parameters->greaterThan && watcherP->lastValue.asFloat < watcherP->parameters->greaterThan)) { notify = true; } break; default: break; } LOG("observation_step(/%d/%d/%d) notify[3] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE"); } if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_STEP) != 0) { switch (dataP->type) { case LWM2M_TYPE_INTEGER: { int64_t diff; diff = integerValue - watcherP->lastValue.asInteger; if ((diff < 0 && (0 - diff) >= watcherP->parameters->step) || (diff >= 0 && diff >= watcherP->parameters->step)) { notify = true; } } break; case LWM2M_TYPE_FLOAT: { double diff; diff = floatValue - watcherP->lastValue.asFloat; if ((diff < 0 && (0 - diff) >= watcherP->parameters->step) || (diff >= 0 && diff >= watcherP->parameters->step)) { notify = true; } } break; default: break; } LOG("observation_step(/%d/%d/%d) notify[4] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify? "TRUE" : "FALSE"); } } if (watcherP->parameters != NULL && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) != 0) { if (watcherP->lastTime + watcherP->parameters->minPeriod > currentTime) { // Minimum Period did not elapse yet interval = watcherP->lastTime + watcherP->parameters->minPeriod - currentTime; if (*timeoutP > interval) *timeoutP = interval; notify = false; } else { notify = true; } LOG("observation_step(/%d/%d/%d) notify[5] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE"); } } // Is the Maximum Period reached ? if (notify == false && watcherP->parameters != NULL && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0) { if (watcherP->lastTime + watcherP->parameters->maxPeriod <= currentTime) { notify = true; } LOG("observation_step(/%d/%d/%d) notify[6] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE"); } if (notify == true) { if (buffer == NULL) { if (dataP != NULL) { length = lwm2m_data_serialize(&targetP->uri, size, dataP, &format, &buffer); if (length == 0) break; } else { if (COAP_205_CONTENT != object_read(contextP, &targetP->uri, &format, &buffer, &length)) { buffer = NULL; break; } } coap_init_message(message, COAP_TYPE_NON, COAP_205_CONTENT, 0); coap_set_header_content_type(message, format); coap_set_payload(message, buffer, length); LOG("Observe Update[/%d/%d/%d]: %.*s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, length, buffer); } watcherP->lastTime = currentTime; watcherP->lastMid = contextP->nextMID++; message->mid = watcherP->lastMid; coap_set_header_token(message, watcherP->token, watcherP->tokenLen); coap_set_header_observe(message, watcherP->counter++); (void)message_send(contextP, message, watcherP->server->sessionH); watcherP->update = false; } // Store this value if (notify == true && storeValue == true) { switch (dataP->type) { case LWM2M_TYPE_INTEGER: watcherP->lastValue.asInteger = integerValue; break; case LWM2M_TYPE_FLOAT: watcherP->lastValue.asFloat = floatValue; break; default: break; } } if (watcherP->parameters != NULL && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0) { // update timers interval = watcherP->lastTime + watcherP->parameters->maxPeriod - currentTime; if (*timeoutP > interval) *timeoutP = interval; } } } if (dataP != NULL) lwm2m_data_free(size, dataP); if (buffer != NULL) lwm2m_free(buffer); } }
void mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { /* The ETag and Token is copied to the header. */ uint8_t opaque[] = {0x0A, 0xBC, 0xDE}; /* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */ static char location[] = {'/','f','/','a','?','k','&','e', 0}; /* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */ unsigned int content_type = REST.get_header_content_type(request); /* The other getters copy the value (or string/array pointer) to the given pointers and return 1 for success or the length of strings/arrays. */ uint32_t max_age_and_size = 0; const char *str = NULL; uint32_t observe = 0; const uint8_t *bytes = NULL; uint32_t block_num = 0; uint8_t block_more = 0; uint16_t block_size = 0; const char *query = ""; int len = 0; /* Mirror the received header options in the response payload. Unsupported getters (e.g., rest_get_header_observe() with HTTP) will return 0. */ int strpos = 0; /* snprintf() counts the terminating '\0' to the size parameter. * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. * Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */ if (content_type!=-1) { strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE+1, "CT %u\n", content_type); } /* Some getters such as for ETag or Location are omitted, as these options should not appear in a request. * Max-Age might appear in HTTP requests or used for special purposes in CoAP. */ if (strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &max_age_and_size)) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "MA %lu\n", max_age_and_size); } /* For HTTP this is the Length option, for CoAP it is the Size option. */ if (strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &max_age_and_size)) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "SZ %lu\n", max_age_and_size); } if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UH %.*s\n", len, str); } /* CoAP-specific example: actions not required for normal RESTful Web service. */ #if WITH_COAP > 1 if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_observe(request, &observe)) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Ob %lu\n", observe); } if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_token(request, &bytes))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "To 0x"); int index = 0; for (index = 0; index<len; ++index) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%02X", bytes[index]); } strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "\n"); } if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_etag(request, &bytes))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "ET 0x"); int index = 0; for (index = 0; index<len; ++index) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%02X", bytes[index]); } strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "\n"); } if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_uri_path(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UP "); strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%.*s\n", len, str); } #if WITH_COAP == 3 if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_location(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Lo %.*s\n", len, str); } if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_block(request, &block_num, &block_more, &block_size, NULL)) /* This getter allows NULL pointers to get only a subset of the block parameters. */ { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Bl %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); } #else if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_path(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "LP %.*s\n", len, str); } if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_query(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "LQ %.*s\n", len, str); } if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_block2(request, &block_num, &block_more, &block_size, NULL)) /* This getter allows NULL pointers to get only a subset of the block parameters. */ { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "B2 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); } /* * Critical Block1 option is currently rejected by engine. * if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "B1 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); } */ #endif /* CoAP > 03 */ #endif /* CoAP-specific example */ if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &query))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Qu %.*s\n", len, query); } if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%.*s", len, bytes); } if (strpos >= REST_MAX_CHUNK_SIZE) { buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* '»' to indicate truncation */ } REST.set_response_payload(response, buffer, strpos); PRINTF("/mirror options received: %s\n", buffer); /* Set dummy header options for response. Like getters, some setters are not implemented for HTTP and have no effect. */ REST.set_header_content_type(response, REST.type.TEXT_PLAIN); REST.set_header_max_age(response, 17); /* For HTTP, browsers will not re-request the page for 17 seconds. */ REST.set_header_etag(response, opaque, 2); REST.set_header_location(response, location); /* Initial slash is omitted by framework */ REST.set_header_length(response, strpos); /* For HTTP, browsers will not re-request the page for 10 seconds. CoAP action depends on the client. */ /* CoAP-specific example: actions not required for normal RESTful Web service. */ #if WITH_COAP > 1 coap_set_header_uri_host(response, "tiki"); coap_set_header_observe(response, 10); #if WITH_COAP == 3 coap_set_header_block(response, 42, 0, 64); /* The block option might be overwritten by the framework when blockwise transfer is requested. */ #else coap_set_header_proxy_uri(response, "ftp://x"); coap_set_header_block2(response, 42, 0, 64); /* The block option might be overwritten by the framework when blockwise transfer is requested. */ coap_set_header_block1(response, 23, 0, 16); coap_set_header_accept(response, TEXT_PLAIN); coap_set_header_if_none_match(response); #endif /* CoAP > 03 */ #endif /* CoAP-specific example */ }
static void coap_HandleResource(/*CoapRequestHandlerCallbacks * RequestCB,*/ void *packet, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { const char *url = NULL; int urlLen = 0; const uint8_t * payload = NULL; int payloadLen = 0; int content = -1; coap_packet_t *const request = (coap_packet_t *)packet; CoapResponse coapResponse = { .responseContent = buffer, .responseContentLen = preferred_size, .responseCode = 400, }; payloadLen = REST.get_request_payload(request, &payload); if ((urlLen = REST.get_url(request, &url))) { char uriBuf[64] = {0}; rest_resource_flags_t method = REST.get_method_type(request); uriBuf[0] = '/'; memcpy(&uriBuf[1], url, urlLen); const char * query = NULL; REST.get_query(request, &query); CoapRequest coapRequest = { .ctxt = context, .addr = { 0 }, .path = uriBuf, .query = query, .token = request->token, .tokenLength = request->token_len, .requestContent = payload, .requestContentLen = payloadLen, }; memcpy(&coapRequest.addr.Addr, &UIP_IP_BUF->srcipaddr, sizeof(uip_ipaddr_t)); coapRequest.addr.Port = uip_ntohs(UIP_UDP_BUF->srcport); switch(method) { case METHOD_GET: REST.get_header_accept(request, &content); coapRequest.contentType = content; int32_t observe; if (!coap_get_header_observe(request, &observe)) observe = -1; switch(observe) { case -1: Lwm2m_Debug("Coap GET for %s\n", uriBuf); coapRequest.type = COAP_GET_REQUEST; requestHandler(&coapRequest, &coapResponse); break; case 0: Lwm2m_Debug("Coap OBSERVE for %s\n", uriBuf); coapRequest.type = COAP_OBSERVE_REQUEST; requestHandler(&coapRequest, &coapResponse); coap_set_header_observe(response, 1); break; case 1: Lwm2m_Debug("Coap CANCEL OBSERVE for %s\n", uriBuf); coapRequest.type = COAP_CANCEL_OBSERVE_REQUEST; requestHandler(&coapRequest, &coapResponse); break; default: break; } REST.set_header_content_type(response, coapResponse.responseContentType); /* text/plain is the default, hence this option could be omitted. */ break; case METHOD_POST: REST.get_header_content_type(request, &content); coapRequest.contentType = content; coapRequest.type = COAP_POST_REQUEST; Lwm2m_Debug("Coap POST for %s\n", uriBuf); requestHandler(&coapRequest, &coapResponse); break; case METHOD_PUT: REST.get_header_content_type(request, &content); coapRequest.contentType = content; coapRequest.type = COAP_PUT_REQUEST; Lwm2m_Debug("Coap PUT for %s\n", uriBuf); requestHandler(&coapRequest, &coapResponse); break; case METHOD_DELETE: coapRequest.contentType = ContentType_None; coapRequest.type = COAP_DELETE_REQUEST; Lwm2m_Debug("Coap DELETE for %s\n", uriBuf); requestHandler(&coapRequest, &coapResponse); break; default: break; } if (coapResponse.responseContentLen > 0 && coapResponse.responseCode == 205 ) { REST.set_response_payload(response, coapResponse.responseContent, coapResponse.responseContentLen); } } REST.set_response_status(response, COAP_RESPONSE_CODE(coapResponse.responseCode)); }
static int coap_HandleRequest(void *packet, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { int result = 1; const char *url = NULL; int urlLen = 0; const uint8_t * payload = NULL; int payloadLen = 0; int content = -1; coap_packet_t * const request = (coap_packet_t *) packet; CoapResponse coapResponse = { .responseContent = buffer, .responseContentLen = preferred_size, .responseCode = 400, }; payloadLen = coap_get_payload(request, &payload); if ((urlLen = coap_get_header_uri_path(request, &url))) { char uriBuf[MAX_COAP_PATH] = { 0 }; rest_resource_flags_t method = (rest_resource_flags_t) (1 << (((coap_packet_t *) packet)->code - 1)); //coap_get_rest_method(request); uriBuf[0] = '/'; memcpy(&uriBuf[1], url, urlLen); char queryBuf[128] = "?"; const char * query = NULL; int queryLength = coap_get_header_uri_query(request, &query); if (queryLength > 0) memcpy(&queryBuf[1], query, queryLength); queryBuf[queryLength+1] = '\0'; CoapRequest coapRequest = { .ctxt = context, .addr = { 0 }, .path = uriBuf, .query = queryBuf, .token = request->token, .tokenLength = request->token_len, .requestContent = payload, .requestContentLen = payloadLen, }; NetworkAddress_SetAddressType(sourceAddress, &coapRequest.addr); switch (method) { case METHOD_GET: coap_get_header_accept(request, &content); coapRequest.contentType = content; int32_t observe; if (!coap_get_header_observe(request, &observe)) observe = -1; switch (observe) { case -1: Lwm2m_Debug("Coap GET for %s\n", uriBuf); coapRequest.type = COAP_GET_REQUEST; requestHandler(&coapRequest, &coapResponse); break; case 0: Lwm2m_Debug("Coap OBSERVE for %s\n", uriBuf); coapRequest.type = COAP_OBSERVE_REQUEST; requestHandler(&coapRequest, &coapResponse); coap_set_header_observe(response, 1); break; case 1: Lwm2m_Debug("Coap CANCEL OBSERVE for %s\n", uriBuf); coapRequest.type = COAP_CANCEL_OBSERVE_REQUEST; requestHandler(&coapRequest, &coapResponse); break; default: break; } coap_set_header_content_format(response, coapResponse.responseContentType); /* text/plain is the default, hence this option could be omitted. */ break; case METHOD_POST: coap_get_header_content_format(request, &content); coapRequest.contentType = content; coapRequest.type = COAP_POST_REQUEST; Lwm2m_Debug("Coap POST for %s\n", uriBuf); requestHandler(&coapRequest, &coapResponse); if (coapResponse.responseContentLen > 0 && coapResponse.responseCode == 201) { coap_set_header_location_path(response, coapResponse.responseContent); } break; case METHOD_PUT: coap_get_header_content_format(request, &content); coapRequest.contentType = content; coapRequest.type = COAP_PUT_REQUEST; Lwm2m_Debug("Coap PUT for %s\n", uriBuf); requestHandler(&coapRequest, &coapResponse); break; case METHOD_DELETE: coapRequest.contentType = ContentType_None; coapRequest.type = COAP_DELETE_REQUEST; Lwm2m_Debug("Coap DELETE for %s\n", uriBuf); requestHandler(&coapRequest, &coapResponse); break; default: break; } if (coapResponse.responseContentLen > 0 && coapResponse.responseCode == 205) { coap_set_payload(response, coapResponse.responseContent, coapResponse.responseContentLen); } } coap_set_status_code(response, COAP_RESPONSE_CODE(coapResponse.responseCode)); return result; }