void coap_handle_notification(NetworkAddress * sourceAddress, coap_packet_t * message) { if (message->token_len == sizeof(int)) { int token; memcpy(&token, message->token, sizeof(int)); Observation * observation = NULL; int index; for (index = 0; index < MAX_COAP_OBSERVATIONS; index++) { if ((Observations[index].Token == token) && (NetworkAddress_Compare(Observations[index].Address, sourceAddress) == 0)) { observation = &Observations[index]; break; } } if (observation && observation->Callback) { AddressType address; int ContentType = 0; char * payload = NULL; NetworkAddress_SetAddressType(sourceAddress, &address); coap_get_header_content_format(message, &ContentType); int payloadLen = coap_get_payload(message, (const uint8_t **) &payload); observation->Callback(observation->Context, &address, observation->Path, COAP_OPTION_TO_RESPONSE_CODE(message->code), ContentType, payload, payloadLen); } } }
/* * Handle the response to the observe request and the following notifications */ static void notification_callback(coap_observee_t *obs, void *notification, coap_notification_flag_t flag) { int len = 0; const uint8_t *payload = NULL; /* printf("Notification handler\n"); */ /* printf("Observee URI: %s\n", obs->url); */ if(notification) { len = coap_get_payload(notification, &payload); } switch(flag) { case NOTIFICATION_OK: count_notify++; printf("NOTIFICATION OK: %d\n%*s\n", count_notify, len, (char *)payload); break; case OBSERVE_OK: /* server accepeted observation request */ printf("OBSERVE_OK: \n%*s\n", len, (char *)payload); break; case OBSERVE_NOT_SUPPORTED: printf("OBSERVE_NOT_SUPPORTED: \n%*s\n", len, (char *)payload); obs = NULL; break; case ERROR_RESPONSE_CODE: printf("ERROR_RESPONSE_CODE: \n%*s\n", len, (char *)payload); obs = NULL; break; case NO_REPLY_FROM_SERVER: printf("NO_REPLY_FROM_SERVER: " "removing observe registration with token %x%x\n", obs->token[0], obs->token[1]); obs = NULL; break; } }
void coap_CoapRequestCallback(void *callback_data, void *response) { TransactionType * transaction = (TransactionType *)callback_data; coap_packet_t * coap_response = (coap_packet_t *)response; int ContentType = 0; const char *url = NULL; char * payload = NULL; char uriBuf[64] = {0}; if(callback_data != NULL) { if(response != NULL) { int urlLen = 0; if ((urlLen = coap_get_header_location_path(response, &url))) { uriBuf[0] = '/'; memcpy(&uriBuf[1], url, urlLen); } coap_get_header_content_format(response, &ContentType); int payloadLen = coap_get_payload(response, (const uint8_t **)&payload); transaction->Callback(transaction->Context, &transaction->Address, uriBuf, COAP_OPTION_TO_RESPONSE_CODE(coap_response->code), ContentType, payload, payloadLen); } else { transaction->Callback(transaction->Context, NULL, NULL, 0, 0, NULL, 0); } transaction->TransactionUsed = false; } }
/* This function is will be passed to COAP_BLOCKING_REQUEST() to handle responses. */ void client_chunk_handler(void *response) { const uint8_t *chunk; int len = coap_get_payload(response, &chunk); printf("|%.*s", len, (char *)chunk); }
static void response_handler(coap_packet_t* response) { uint16_t payload_len = 0; uint8_t* payload = NULL; payload_len = coap_get_payload(response, &payload); PRINTF("Response transaction id: %u", response->tid); if (payload) { memcpy(temp, payload, payload_len); temp[payload_len] = 0; PRINTF(" payload: %s\n", temp); } }
/* This function is will be passed to COAP_BLOCKING_REQUEST() to handle responses. */ void client_chunk_handler(void *response) { const uint8_t *chunk; int len = coap_get_payload(response, &chunk); #if PLATFORM_HAS_LEDS /* set red led when receiving a packet */ leds_on(LEDS_RED); #endif /* printf("|%.*s", len, (char *)chunk); */ printf("RX: %d\n%s\n", len, (char *)chunk); }
oc_discovery_flags_t oc_ri_process_discovery_payload(struct coap_packet_rx *rsp, oc_discovery_cb_t *handler, oc_endpoint_t *endpoint) { oc_discovery_flags_t ret = OC_CONTINUE_DISCOVERY; oc_string_t uri = { .os_sz = 0, .os_str = NULL }; oc_string_t di = { .os_sz = 0, .os_str = NULL }; bool secure = false; uint16_t dtls_port = 0, default_port = endpoint->oe_ip.v6.port; oc_string_array_t types = {}; oc_interface_mask_t interfaces = 0; oc_server_handle_t handle; uint16_t data_off; struct os_mbuf *m; int len; memcpy(&handle.endpoint, endpoint, sizeof(oc_endpoint_t)); oc_rep_t *array = 0, *rep; len = coap_get_payload(rsp, &m, &data_off); int s = oc_parse_rep(m, data_off, len, &rep); if (s == 0) array = rep; while (array != NULL) { oc_rep_t *device_map = array->value_object; while (device_map != NULL) { switch (device_map->type) { case STRING: if (oc_string_len(device_map->name) == 2 && strncmp(oc_string(device_map->name), "di", 2) == 0) di = device_map->value_string; break; default: break; } device_map = device_map->next; } device_map = array->value_object; while (device_map != NULL) { switch (device_map->type) { case OBJECT_ARRAY: { oc_rep_t *links = device_map->value_object_array; while (links != NULL) { switch (links->type) { case OBJECT: { oc_rep_t *resource_info = links->value_object; while (resource_info != NULL) { switch (resource_info->type) { case STRING: uri = resource_info->value_string; break; case STRING_ARRAY: if (oc_string_len(resource_info->name) == 2 && strncmp(oc_string(resource_info->name), "rt", 2) == 0) types = resource_info->value_array; else { interfaces = 0; int i; for (i = 0; i < oc_string_array_get_allocated_size( resource_info->value_array); i++) { interfaces |= oc_ri_get_interface_mask( oc_string_array_get_item(resource_info->value_array, i), oc_string_array_get_item_size(resource_info->value_array, i)); } } break; case OBJECT: { oc_rep_t *policy_info = resource_info->value_object; while (policy_info != NULL) { if (policy_info->type == INT && oc_string_len(policy_info->name) == 4 && strncmp(oc_string(policy_info->name), "port", 4) == 0) { dtls_port = policy_info->value_int; } if (policy_info->type == BOOL && oc_string_len(policy_info->name) == 3 && strncmp(oc_string(policy_info->name), "sec", 3) == 0 && policy_info->value_boolean == true) { secure = true; } policy_info = policy_info->next; } } break; default: break; } resource_info = resource_info->next; } if (secure) { handle.endpoint.oe_ip.v6.port = dtls_port; handle.endpoint.oe_ip.flags |= SECURED; } else { handle.endpoint.oe_ip.v6.port = default_port; handle.endpoint.oe_ip.flags &= ~SECURED; } if (handler(oc_string(di), oc_string(uri), types, interfaces, &handle) == OC_STOP_DISCOVERY) { ret = OC_STOP_DISCOVERY; goto done; } dtls_port = 0; secure = false; } break; default: break; } links = links->next; } } break; default: break; } device_map = device_map->next; } array = array->next; } done: oc_free_rep(rep); return ret; }
/*----------------------------------------------------------------------------*/ void pf_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset, tres_res_t *task) { rest_resource_flags_t method; uint32_t num = 0; uint8_t more = 0; uint16_t size = 0; uint32_t b1_offset = 0; uint16_t plen; const uint8_t *payload; method = REST.get_method_type(request); PRINTF("Method %d\n", method); switch (method) { case METHOD_GET: //TODO: retrieve python bytecode REST.set_response_status(response, REST.status.NOT_IMPLEMENTED); break; case METHOD_PUT: if(coap_get_header_block1(request, &num, &more, &size, &b1_offset)) { coap_set_header_block1(response, num, more, size); } PRINTF("Request on /pf: num = %"PRIu32", more = %"PRIu8", size = %"PRIu16 ", offset = %"PRIu32"\n", num, more, size, b1_offset); // if it's the first packet, stop input resource monitoring if(b1_offset == 0) { tres_stop_monitoring(task); // if the user is actually updating the PF, clear it first if(task->pf_img) { tres_mem_pf_clear(task->pf_img); task_reset_state(task); } } plen = coap_get_payload(request, &payload); PRINTF("Payload len: %d\n", plen); #if TRES_COPPER_WORKAROUND // if no block-wise transfer and payload len equal to maximum size, then // we probably need block wise transfer. FIXME: that may be not true if(size == 0 && plen == REST_MAX_CHUNK_SIZE) { more = 1; size = REST_MAX_CHUNK_SIZE; coap_set_header_block1(response, num, more, size); } #endif // if it's the first packet, allocate a memory slot if(b1_offset == 0) { // ... but, if the first byte is not 0x0a than it is not python bytecode if(payload[0] != 0x0a) { REST.set_response_status(response, REST.status.BAD_REQUEST); return; } task->sid = tres_mem_pf_store_start(); if(task->sid < 0) { PRINTF("No memory slot available\n"); // TODO: we should return a server error code return; } } // store the current block if(tres_mem_pf_store_step(task->sid, payload, plen) < 0) { PRINTF("PF too big\n"); return; } // if it's the final block, finalize the memory slot if(more == 0) { task->pf_img = tres_mem_pf_store_done(task->sid); PRINTF("task->pf_img: %p\n", task->pf_img); REST.set_response_status(response, REST.status.CHANGED); } break; case METHOD_POST: REST.set_response_status(response, REST.status.METHOD_NOT_ALLOWED); break; case METHOD_DELETE: if(task->pf_img) { tres_stop_monitoring(task); tres_mem_pf_clear(task->pf_img); task_reset_state(task); task->pf_img = NULL; } REST.set_response_status(response, REST.status.DELETED); break; default: break; } }
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; }