/*---------------------------------------------------------------------------*/ PROCESS_THREAD(rd_client_process, ev, data) { static struct etimer et; static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ static char query_buffer[200]; static char rd_client_name[64]; PROCESS_BEGIN(); PROCESS_PAUSE(); PRINTF("RD client started\n"); sprintf(rd_client_name, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", uip_lladdr.addr[0], uip_lladdr.addr[1], uip_lladdr.addr[2], uip_lladdr.addr[3], uip_lladdr.addr[4], uip_lladdr.addr[5], uip_lladdr.addr[6], uip_lladdr.addr[7]); while(1) { new_address = 0; while(!registered) { while(uip_is_addr_unspecified(&rd_server_ipaddr)) { status = RD_CLIENT_UNCONFIGURED; PROCESS_YIELD(); } status = RD_CLIENT_REGISTERING; etimer_set(&et, CLOCK_SECOND); PROCESS_YIELD_UNTIL(etimer_expired(&et)); PRINTF("Registering to "); PRINT6ADDR(&rd_server_ipaddr); PRINTF(" %d with %s\n", rd_server_port, resources_list); coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); coap_set_header_uri_path(request, "rd"); sprintf(query_buffer, "ep=%s&b=U<=%d", rd_client_name, RD_CLIENT_LIFETIME); coap_set_header_uri_query(request, query_buffer); coap_set_payload(request, (uint8_t *) resources_list, resources_list_size); COAP_BLOCKING_REQUEST_BLOCK_RESPONSE(coap_default_context, &rd_server_ipaddr, UIP_HTONS(rd_server_port), request, client_registration_request_handler, client_registration_response_handler); } status = RD_CLIENT_REGISTERED; etimer_set(&et, RD_CLIENT_LIFETIME * CLOCK_SECOND / 10 * 9); PROCESS_YIELD_UNTIL(etimer_expired(&et) || new_address); registered = 0; if(!new_address) { PRINTF("Update endpoint %s\n", registration_name); coap_init_message(request, COAP_TYPE_CON, COAP_PUT, 0); coap_set_header_uri_path(request, registration_name); sprintf(query_buffer, "b=U<=%d", RD_CLIENT_LIFETIME); coap_set_header_uri_query(request, query_buffer); COAP_BLOCKING_REQUEST(coap_default_context, &rd_server_ipaddr, UIP_HTONS(rd_server_port), request, client_update_response_handler); } } PROCESS_END(); }
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_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_createCoapRequest(void * context, coap_method_t method, const char * uri, ContentType contentType, const char * payload, int payloadLen, TransactionCallback callback) { coap_packet_t request; uip_ipaddr_t * remote_ipaddr = coap_getIpFromURI(uri); int remote_port = coap_getPortFromURI(uri); coap_transaction_t *transaction; char path[128] = {0}; char query[128] = {0}; coap_getPathQueryFromURI(uri, path, query); Lwm2m_Debug("Coap request: %s\n", uri); Lwm2m_Debug("Coap IPv6 request address: " PRINT6ADDR(remote_ipaddr)); Lwm2m_Debug("Coap request port: %d\n", remote_port); 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); coap_set_header_uri_query(&request, query); if (contentType != ContentType_None) { coap_set_header_content_format(&request, contentType); coap_set_payload(&request, payload, payloadLen); } 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)))) { transaction->callback = coap_CoapRequestCallback; CurrentTransaction[CurrentTransactionIndex].Callback = callback; CurrentTransaction[CurrentTransactionIndex].Context = context; CurrentTransaction[CurrentTransactionIndex].TransactionUsed = true; CurrentTransaction[CurrentTransactionIndex].TransactionPtr = transaction; memcpy(&CurrentTransaction[CurrentTransactionIndex].Address.Addr, remote_ipaddr, sizeof(uip_ipaddr_t)); CurrentTransaction[CurrentTransactionIndex].Address.Port = uip_htons(remote_port); 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; } } }
bool ICACHE_FLASH_ATTR handle_observe_notify(lwm2m_context_t * contextP, void * fromSessionH, coap_packet_t * message, coap_packet_t * response) { uint8_t * tokenP; int token_len; uint16_t clientID; uint16_t obsID; lwm2m_client_t * clientP; lwm2m_observation_t * observationP; uint32_t count; token_len = coap_get_header_token(message, (const uint8_t **)&tokenP); if (token_len != sizeof(uint32_t)) return false; if (1 != coap_get_header_observe(message, &count)) return false; clientID = (tokenP[0] << 8) | tokenP[1]; obsID = (tokenP[2] << 8) | tokenP[3]; clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); if (clientP == NULL) return false; observationP = (lwm2m_observation_t *)lwm2m_list_find((lwm2m_list_t *)clientP->observationList, obsID); if (observationP == NULL) { coap_init_message(response, COAP_TYPE_RST, 0, message->mid); message_send(contextP, response, fromSessionH); } else { if (message->type == COAP_TYPE_CON ) { coap_init_message(response, COAP_TYPE_ACK, 0, message->mid); message_send(contextP, response, fromSessionH); } observationP->callback(clientID, &observationP->uri, (int)count, message->content_type, message->payload, message->payload_len, observationP->userData); } return true; }
/*----------------------------------------------------------------------------*/ void coap_separate_resume(void *response, coap_separate_t *separate_store, uint8_t code) { coap_init_message(response, separate_store->type, code, separate_store->mid); if (separate_store->token_len) { coap_set_header_token(response, separate_store->token, separate_store->token_len); } }
/*---------------------------------------------------------------------------*/ void co2_resource_periodic_handler(resource_t *r) { static int event_counter; char buffer[16]; read_co2(buffer); coap_packet_t notification[1]; coap_init_message(notification, COAP_TYPE_NON, REST.status.OK, 0); coap_set_payload(notification, buffer, strlen(buffer)+1); REST.notify_subscribers(r, event_counter++, notification); }
lwm2m_transaction_t * transaction_new(coap_method_t method, lwm2m_uri_t * uriP, uint16_t mID, lwm2m_endpoint_type_t peerType, void * peerP) { lwm2m_transaction_t * transacP; int result; transacP = (lwm2m_transaction_t *)lwm2m_malloc(sizeof(lwm2m_transaction_t)); if (transacP == NULL) return NULL; memset(transacP, 0, sizeof(lwm2m_transaction_t)); transacP->message = lwm2m_malloc(sizeof(coap_packet_t)); if (transacP->message == NULL) goto error; coap_init_message(transacP->message, COAP_TYPE_CON, method, mID); transacP->mID = mID; transacP->peerType = peerType; transacP->peerP = peerP; if (uriP != NULL) { result = snprintf(transacP->objStringID, LWM2M_STRING_ID_MAX_LEN, "%hu", uriP->objectId); if (result < 0 || result > LWM2M_STRING_ID_MAX_LEN) goto error; coap_set_header_uri_path_segment(transacP->message, transacP->objStringID); if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { result = snprintf(transacP->instanceStringID, LWM2M_STRING_ID_MAX_LEN, "%hu", uriP->instanceId); if (result < 0 || result > LWM2M_STRING_ID_MAX_LEN) goto error; coap_set_header_uri_path_segment(transacP->message, transacP->instanceStringID); } else { if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { coap_set_header_uri_path_segment(transacP->message, NULL); } } if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = snprintf(transacP->resourceStringID, LWM2M_STRING_ID_MAX_LEN, "%hu", uriP->resourceId); if (result < 0 || result > LWM2M_STRING_ID_MAX_LEN) goto error; coap_set_header_uri_path_segment(transacP->message, transacP->resourceStringID); } } return transacP; error: lwm2m_free(transacP); return NULL; }
/*----------------------------------------------------------------------------*/ PROCESS_THREAD(tres_process, ev, data) { PROCESS_BEGIN(); srand(node_id); rest_init_engine(); tres_init(); SENSORS_ACTIVATE(light_sensor); rest_activate_periodic_resource(&periodic_resource_light); rplinfo_activate_resources(); static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ SERVER_NODE(&server_ipaddr); /* receives all CoAP messages */ coap_receiver_init(); int wait_time = getRandUint(MAX_WAITING); int base_wait = BASE_WAITING; static int g_time=0; static char content[12]; etimer_set(&et, (wait_time + base_wait) * CLOCK_SECOND); while(1) { PROCESS_YIELD(); if (etimer_expired(&et)) break; } etimer_reset(&et); etimer_set(&et, TOGGLE_INTERVAL * CLOCK_SECOND); while(1) { PROCESS_YIELD(); if (etimer_expired(&et)) { coap_init_message(request, COAP_TYPE_NON, COAP_POST, 0 ); coap_set_header_uri_path(request, service_urls[1]); coap_set_payload(request, content, snprintf(content, sizeof(content), "%d", g_time++)); coap_transaction_t *transaction; request->mid = coap_get_mid(); if ((transaction = coap_new_transaction(request->mid, &server_ipaddr, REMOTE_PORT))) { transaction->packet_len = coap_serialize_message(request, transaction->packet); coap_send_transaction(transaction); } etimer_reset(&et); } } /* while (1) */ PROCESS_END(); }
/*----------------------------------------------------------------------------*/ PROCESS_THREAD(tres_process, ev, data) { PROCESS_BEGIN(); srand(node_id); rest_init_engine(); tres_init(); rest_activate_resource(&actuator, "actuator"); rplinfo_activate_resources(); sprintf(setpoint, "0"); #if PYOT_KEEPALIVE static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ SERVER_NODE(&server_ipaddr); int wait_time = (unsigned int)(rand() % MAX_WAITING); int base_wait = BASE_WAITING; static int g_time=0; static char content[12]; etimer_set(&et, (wait_time + base_wait) * CLOCK_SECOND); while(1) { PROCESS_YIELD(); //PROCESS_WAIT_EVENT(); if (etimer_expired(&et)) break; } etimer_reset(&et); etimer_set(&et, TOGGLE_INTERVAL * CLOCK_SECOND); while(1) { PROCESS_YIELD(); if (etimer_expired(&et)) { coap_init_message(request, COAP_TYPE_NON, COAP_POST, 0 ); coap_set_header_uri_path(request, "/rd"); coap_set_payload(request, content, snprintf(content, sizeof(content), "%d", g_time++)); //PRINT6ADDR(&server_ipaddr); //PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); coap_transaction_t *transaction; request->mid = coap_get_mid(); if ((transaction = coap_new_transaction(request->mid, &server_ipaddr, REMOTE_PORT))) { transaction->packet_len = coap_serialize_message(request, transaction->packet); coap_send_transaction(transaction); } etimer_reset(&et); } } /* while (1) */ #endif PROCESS_END(); }
/*---------------------------------------------------------------------------*/ void motion_resource_periodic_handler(resource_t *r) { static int event_counter; char buffer[16]; PRINTF("*** motion_resource_periodic_handler(): called!\n"); int value = 4095-sensor_value(0); PRINTF("%d", value); sprintf(buffer, "%d", value); coap_packet_t notification[1]; coap_init_message(notification, COAP_TYPE_NON, REST.status.OK, 0); coap_set_payload(notification, buffer, strlen(buffer)+1); REST.notify_subscribers(r, event_counter++, notification); PRINTF("*** motion_resource_periodic_handler(): done\n"); }
/*---------------------------------------------------------------------------*/ 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 light_periodic_handler(resource_t *r) { uint16_t light_photosynthetic = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); static uint16_t obs_counter = 0; static char content[11]; ++obs_counter; /* 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, REST.status.OK, 0 ); coap_set_payload(notification, content, snprintf(content, sizeof(content), "%u", light_photosynthetic)); /* Notify the registered observers with the given message type, observe option, and payload. */ REST.notify_subscribers(r, obs_counter, notification); }
int lwm2m_ping(lwm2m_context_t * contextP) { lwm2m_server_t *srv = contextP->serverList; while (NULL != srv) { if (srv->status == STATE_REGISTERED) { coap_packet_t message[1]; coap_init_message(message, COAP_TYPE_CON, COAP_204_CHANGED, 0); coap_set_payload(message, NULL, 0); (void)message_send(contextP, message, srv->addr, srv->addrLen); break; } srv = srv->next; } return NO_ERROR; }
static void AI1_periodic_handler(resource_t *r) { static uint16_t obs_counter = 0; ++obs_counter; char msg[4]; snprintf((char *)msg, sizeof(msg), "%u", ai1_in()); /* 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, TEXT_PLAIN ); coap_set_payload(notification, msg, strlen(msg)); /* Notify the registered observers with the given message type, observe option, and payload. */ REST.notify_subscribers(r, obs_counter, notification); }
/** * \brief Initiate a separate response with an empty ACK * \param request The request to accept * \param separate_store A pointer to the data structure that will store the * relevant information for the response * * When the server does not have enough resources left to store the information * for a separate response or otherwise cannot execute the resource handler, * this function will respond with 5.03 Service Unavailable. The client can * then retry later. */ void coap_separate_accept(void *request, coap_separate_t *separate_store) { coap_packet_t *const coap_req = (coap_packet_t *)request; coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid); PRINTF("Separate ACCEPT: /%.*s MID %u\n", coap_req->uri_path_len, coap_req->uri_path, coap_req->mid); if(t) { /* send separate ACK for CON */ if(coap_req->type == COAP_TYPE_CON) { coap_packet_t ack[1]; /* ACK with empty code (0) */ coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid); /* serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct */ coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, (uip_appdata), coap_serialize_message(ack, uip_appdata)); } /* store remote address */ uip_ipaddr_copy(&separate_store->addr, &t->addr); separate_store->port = t->port; /* store correct response type */ separate_store->type = coap_req->type == COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON; separate_store->mid = coap_get_mid(); /* if it was a NON, we burned one MID in the engine... */ memcpy(separate_store->token, coap_req->token, coap_req->token_len); separate_store->token_len = coap_req->token_len; separate_store->block1_num = coap_req->block1_num; separate_store->block1_size = coap_req->block1_size; separate_store->block2_num = coap_req->block2_num; separate_store->block2_size = coap_req->block2_size > 0 ? MIN(COAP_MAX_BLOCK_SIZE, coap_req->block2_size) : COAP_MAX_BLOCK_SIZE; /* signal the engine to skip automatic response and clear transaction by engine */ erbium_status_code = MANUAL_RESPONSE; } else { PRINTF("ERROR: Response transaction for separate request not found!\n"); erbium_status_code = INTERNAL_SERVER_ERROR_5_00; } }
/*----------------------------------------------------------------------------*/ void lo_event_handler(tres_res_t *task) { coap_packet_t notification[1]; resource_t r; int len; // Build notification coap_init_message(notification, COAP_TYPE_CON, REST.status.OK, 0); len = strlen((char *)task->last_output); coap_set_payload(notification, task->last_output, len); // Notify the registered observers with the given message type, observe // option, and payload r.url = task->lo_url; task->obs_count++; REST.notify_subscribers(&r, task->obs_count, notification); }
/* * Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE. * It will be called by the REST manager process with the defined period. */ void obs_periodic_handler(resource_t *r) { ++obs_counter; PRINTF("TICK %u for /%s\n", obs_counter, r->url); /* Build notification. */ /*TODO: REST.new_response() */ 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 ); /* Better use a generator function for both handlers that only takes *resonse. */ obs_handler(NULL, notification, NULL, 0, NULL); /* Notify the registered observers with the given message type, observe option, and payload. */ REST.notify_subscribers(r, obs_counter, notification); }
void co2_periodic_handler(resource_t *r) { static uint32_t obs_counter = 0; char content[32]; obs_counter++; uint16_t co2 = co2_get(); /* 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_set_payload(notification, content, snprintf(content, sizeof(content), "%u", co2)); /* Notify the registered observers with the given message type, observe option, and payload. */ REST.notify_subscribers(r, obs_counter, notification); }
/* Additionally, a handler function named [resource name]_event_handler must be implemented for each PERIODIC_RESOURCE defined. * It will be called by the REST manager process with the defined period. */ void event_event_handler(resource_t *r) { static uint16_t event_counter = 0; static char content[12]; ++event_counter; PRINTF("TICK %u for /%s\n", event_counter, r->url); /* Build notification. */ coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ coap_init_message(notification, COAP_TYPE_CON, REST.status.OK, 0 ); coap_set_payload(notification, content, snprintf(content, sizeof(content), "EVENT %u", event_counter)); /* Notify the registered observers with the given message type, observe option, and payload. */ REST.notify_subscribers(r, event_counter, notification); }
/* Additionally, a handler function named [resource name]_event_handler must be implemented for each PERIODIC_RESOURCE defined. * It will be called by the REST manager process with the defined period. */ void DI1_event_handler(resource_t *r) { static uint16_t event_counter = 0; ++event_counter; PRINTF("TICK %u for /%s\n", event_counter, r->url); char msg[4]; snprintf(msg, sizeof(msg), "%u", di1_in()); /* 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); REST.set_header_content_type(notification, REST.type.APPLICATION_JSON); coap_set_payload(notification, msg, strlen(msg)); /* Notify the registered observers with the given message type, observe option, and payload. */ REST.notify_subscribers(r, event_counter, notification); }
void handle_observe_notify(lwm2m_context_t * contextP, uint8_t * fromAddr, size_t fromAddrLen, coap_packet_t * message) { uint8_t * tokenP; int token_len; uint16_t clientID; uint16_t obsID; lwm2m_client_t * clientP; lwm2m_observation_t * observationP; uint32_t count; token_len = coap_get_header_token(message, (const uint8_t **)&tokenP); if (token_len != sizeof(uint32_t)) return; if (1 != coap_get_header_observe(message, &count)) return; clientID = (tokenP[0] << 8) | tokenP[1]; obsID = (tokenP[2] << 8) | tokenP[3]; clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); if (clientP == NULL) return; observationP = (lwm2m_observation_t *)lwm2m_list_find((lwm2m_list_t *)clientP->observationList, obsID); if (observationP == NULL) { coap_packet_t resetMsg; coap_init_message(&resetMsg, COAP_TYPE_RST, 0, message->mid); message_send(contextP, &resetMsg, fromAddr, fromAddrLen); } else { observationP->callback(clientID, &observationP->uri, (int)count, message->payload, message->payload_len, observationP->userData); } }
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 registration_deregister(lwm2m_context_t * contextP, lwm2m_server_t * serverP) { coap_packet_t message[1]; uint8_t pktBuffer[COAP_MAX_PACKET_SIZE+1]; size_t pktBufferLen = 0; if (serverP->status != STATE_REGISTERED) return; coap_init_message(message, COAP_TYPE_NON, COAP_DELETE, contextP->nextMID++); coap_set_header_uri_path(message, serverP->location); pktBufferLen = coap_serialize_message(message, pktBuffer); if (0 != pktBufferLen) { coap_send_message(contextP->socket, serverP->addr, serverP->addrLen, pktBuffer, pktBufferLen); } serverP->status = STATE_UNKNOWN; }
void temperature_periodic_handler(resource_t *r) { static uint32_t event_i = 0; char content[6]; temperature = -3960+sht11_sensor.value(SHT11_SENSOR_TEMP); // temperature = temperature_sensor.value(0)*10-15848; if (temperature < temperature_last - TEMP_THRESHOLD || temperature > temperature_last + TEMP_THRESHOLD) { temperature_last = temperature; ++event_i; coap_packet_t notification[1]; /* This way the packet can be treated as pointer as usual. */ coap_init_message(notification, COAP_TYPE_CON, CONTENT_2_05, 0 ); coap_set_payload(notification, content, snprintf(content, 6, "%d.%02d\n",temperature/100, temperature>0 ? temperature%100 : (-1*temperature)%100)); REST.notify_subscribers(r, event_i, notification); } }
/*-----------------------------------------------------------------------------------*/ 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); } }
/* * Additionally, a handler function named [resource name]_handler must * be implemented for each PERIODIC_RESOURCE. It will be called by * the REST manager process with the defined period. */ void pushing_periodic_handler(resource_t * r) { static uint16_t obs_counter = 0; static char content[11]; ++obs_counter; PRINTF("TICK %u for /%s\n", obs_counter, r->url); /* Build notification. */ /* This way the packet can be treated as pointer as usual. */ coap_packet_t notification[1]; coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0); coap_set_payload(notification, content, snprintf(content, sizeof(content), "TICK %u", obs_counter)); /* Notify the registered observers with the given message type, observe option, and payload. */ REST.notify_subscribers(r, obs_counter, notification); }
void light_periodic_handler(resource_t *r) { static uint16_t obs_counter = 0; static char content[REST_MAX_CHUNK_SIZE]; ++obs_counter; PRINTF("TICK %u for /%s\n", obs_counter, r->url); uint16_t light_photosynthetic = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); uint16_t light_solar = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR); /* 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, REST.status.OK, 0 ); //coap_set_payload(notification, content, snprintf(content, sizeof(content), "TICK %u", obs_counter)); coap_set_header_content_type(notification, REST.type.APPLICATION_JSON); snprintf((char *)content, REST_MAX_CHUNK_SIZE, "{'light':{'photosynthetic':%u,'solar':%u}}", light_photosynthetic, light_solar); coap_set_payload(notification, content, strlen((char *)content)); /* Notify the registered observers with the given message type, observe option, and payload. */ REST.notify_subscribers(r, obs_counter, notification); }
PROCESS_THREAD(poti, ev, data) { static struct etimer loop_timer; PROCESS_BEGIN(); /* Initialize the REST engine. */ rest_init_engine (); SERVER_NODE (&server_ipaddr); adc_init (); /* Activate the application-specific resources. */ #if PLATFORM_HAS_BATTERY SENSORS_ACTIVATE(battery_sensor); rest_activate_resource (&res_battery, "s/battery"); #endif rest_activate_resource (&res_server_ip, "poti/ip"); rest_activate_resource (&res_server_resource, "poti/resource"); rest_activate_resource (&res_interval, "poti/interval"); etimer_set (&loop_timer, LOOP_INTERVAL); /* Define application-specific events here. */ while(1) { static int count = 0; static int lastval = -1; static coap_packet_t request [1]; /* Array: treat as pointer */ uint8_t val = 127; PROCESS_WAIT_EVENT(); if (etimer_expired (&loop_timer)) { uint16_t sum = 0; int i; count++; adc_setup (ADC_DEFAULT, A5); for (i=0; i<5; i++) { sum += adc_read (); clock_delay_usec (50); } adc_fin (); val = (sum / 5) >> 2; if ((interval > 0 && count > interval) || (val != lastval)) { char buf [4]; coap_transaction_t *transaction; sprintf (buf, "%d", val); lastval = val; printf ("Sending Value: %s\n", buf); coap_init_message (request, COAP_TYPE_NON, COAP_PUT, 0); coap_set_header_uri_path (request, server_resource); coap_set_header_content_format (request, REST.type.TEXT_PLAIN); coap_set_payload (request, buf, strlen (buf)); request->mid = coap_get_mid (); transaction = coap_new_transaction (request->mid, &server_ipaddr, REMOTE_PORT); transaction->packet_len = coap_serialize_message (request, transaction->packet); coap_send_transaction (transaction); count = 0; } etimer_reset (&loop_timer); } } /* while (1) */