/*---------------------------------------------------------------------------*/ 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 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_UNKNOWN || serverP->status == STATE_REG_PENDING || serverP->status == STATE_DEREG_PENDING) { return; } lwm2m_transaction_t * transaction; transaction = transaction_new(COAP_DELETE, NULL, contextP->nextMID++, ENDPOINT_SERVER, (void *)serverP); if (transaction == NULL) return; coap_set_header_uri_path(transaction->message, serverP->location); transaction->callback = prv_handleDeregistrationReply; transaction->userData = (void *) contextP; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); if (transaction_send(contextP, transaction) == 0) { serverP->status = STATE_REG_PENDING; serverP->mid = transaction->mID; } }
int lwm2m_bootstrap_finish(lwm2m_context_t * contextP, void * sessionH) { lwm2m_transaction_t * transaction; bs_data_t * dataP; LOG("Entering"); transaction = transaction_new(sessionH, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL); if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; coap_set_header_uri_path(transaction->message, "/"URI_BOOTSTRAP_SEGMENT); dataP = (bs_data_t *)lwm2m_malloc(sizeof(bs_data_t)); if (dataP == NULL) { transaction_free(transaction); return COAP_500_INTERNAL_SERVER_ERROR; } dataP->isUri = false; dataP->callback = contextP->bootstrapCallback; dataP->userData = contextP->bootstrapUserData; transaction->callback = prv_resultCallback; transaction->userData = (void *)dataP; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); return transaction_send(contextP, transaction); }
void registration_deregister(lwm2m_context_t * contextP, lwm2m_server_t * serverP) { if (serverP->status == STATE_DEREGISTERED || serverP->status == STATE_REG_PENDING || serverP->status == STATE_DEREG_PENDING || serverP->status == STATE_REG_FAILED || serverP->location == NULL) { return; } lwm2m_transaction_t * transaction; transaction = transaction_new(COAP_TYPE_CON, COAP_DELETE, NULL, NULL, contextP->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)serverP); if (transaction == NULL) return; coap_set_header_uri_path(transaction->message, serverP->location); transaction->callback = prv_handleDeregistrationReply; transaction->userData = (void *) contextP; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); if (transaction_send(contextP, transaction) == 0) { serverP->status = STATE_DEREG_PENDING; } }
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; } } }
// start a device initiated bootstrap static void prv_requestBootstrap(lwm2m_context_t * context, lwm2m_server_t * bootstrapServer) { char query[PRV_QUERY_BUFFER_LENGTH]; int query_length = 0; int res; LOG("Entering"); query_length = utils_stringCopy(query, PRV_QUERY_BUFFER_LENGTH, QUERY_STARTER QUERY_NAME); if (query_length < 0) { bootstrapServer->status = STATE_BS_FAILING; return; } res = utils_stringCopy(query + query_length, PRV_QUERY_BUFFER_LENGTH - query_length, context->endpointName); if (res < 0) { bootstrapServer->status = STATE_BS_FAILING; return; } query_length += res; if (bootstrapServer->sessionH == NULL) { bootstrapServer->sessionH = lwm2m_connect_server(bootstrapServer->secObjInstID, context->userData); } if (bootstrapServer->sessionH != NULL) { lwm2m_transaction_t * transaction = NULL; LOG("Bootstrap server connection opened"); transaction = transaction_new(bootstrapServer->sessionH, COAP_POST, NULL, NULL, context->nextMID++, 4, NULL); if (transaction == NULL) { bootstrapServer->status = STATE_BS_FAILING; return; } coap_set_header_uri_path(transaction->message, "/"URI_BOOTSTRAP_SEGMENT); coap_set_header_uri_query(transaction->message, query); transaction->callback = prv_handleBootstrapReply; transaction->userData = (void *)bootstrapServer; context->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(context->transactionList, transaction); if (transaction_send(context, transaction) == 0) { LOG("CI bootstrap requested to BS server"); bootstrapServer->status = STATE_BS_INITIATED; } } else { LOG("Connecting bootstrap server failed"); bootstrapServer->status = STATE_BS_FAILED; } }
// start a device initiated bootstrap static void bootstrap_initiating_request(lwm2m_context_t * context, lwm2m_server_t * bootstrapServer) { char query[PRV_QUERY_BUFFER_LENGTH]; int query_length = 0; int res; query_length = utils_stringCopy(query, PRV_QUERY_BUFFER_LENGTH, "?ep="); if (query_length < 0) { bootstrapServer->status = STATE_BS_FAILED; return; } res = utils_stringCopy(query + query_length, PRV_QUERY_BUFFER_LENGTH - query_length, context->endpointName); if (res < 0) { bootstrapServer->status = STATE_BS_FAILED; return; } query_length += res; if (bootstrapServer->sessionH == NULL) { bootstrapServer->sessionH = context->connectCallback(bootstrapServer->secObjInstID, context->userData); } if (bootstrapServer->sessionH != NULL) { lwm2m_transaction_t * transaction = NULL; LOG("[BOOTSTRAP] Bootstrap session starting...\r\n"); transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, context->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)bootstrapServer); if (transaction == NULL) { bootstrapServer->status = STATE_BS_FAILED; return; } coap_set_header_uri_path(transaction->message, "/"URI_BOOTSTRAP_SEGMENT); coap_set_header_uri_query(transaction->message, query); transaction->callback = prv_handleBootstrapReply; transaction->userData = (void *)bootstrapServer; context->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(context->transactionList, transaction); if (transaction_send(context, transaction) == 0) { LOG("[BOOTSTRAP] CI bootstrap requested to BS server\r\n"); bootstrapServer->status = STATE_BS_INITIATED; } } else { LOG("No bootstrap session handler found\r\n"); bootstrapServer->status = STATE_BS_FAILED; } }
// send the registration for a single server static uint8_t prv_register(lwm2m_context_t * contextP, lwm2m_server_t * server) { char query[200]; int query_length; uint8_t payload[512]; int payload_length; lwm2m_transaction_t * transaction; payload_length = object_getRegisterPayload(contextP, payload, sizeof(payload)); if (payload_length == 0) return COAP_500_INTERNAL_SERVER_ERROR; query_length = prv_getRegistrationQuery(contextP, server, query, sizeof(query)); if (query_length == 0) return COAP_500_INTERNAL_SERVER_ERROR; #if !defined(COAP_TCP) if (0 != server->lifetime) { int res; res = utils_stringCopy(query + query_length, PRV_QUERY_BUFFER_LENGTH - query_length, QUERY_DELIMITER QUERY_LIFETIME); if (res < 0) return COAP_500_INTERNAL_SERVER_ERROR; query_length += res; res = utils_intCopy(query + query_length, PRV_QUERY_BUFFER_LENGTH - query_length, server->lifetime); if (res < 0) return COAP_500_INTERNAL_SERVER_ERROR; query_length += res; } #endif if (server->sessionH == NULL) { server->sessionH = lwm2m_connect_server(server->secObjInstID, contextP->userData); } if (NULL == server->sessionH) return COAP_503_SERVICE_UNAVAILABLE; transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)server); if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; coap_set_header_uri_path(transaction->message, "/"URI_REGISTRATION_SEGMENT); coap_set_header_uri_query(transaction->message, query); coap_set_header_content_type(transaction->message, LWM2M_CONTENT_LINK); coap_set_payload(transaction->message, payload, payload_length); transaction->callback = prv_handleRegistrationReply; transaction->userData = (void *) server; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); if (transaction_send(contextP, transaction) != 0) return COAP_500_INTERNAL_SERVER_ERROR; server->status = STATE_REG_PENDING; return COAP_NO_ERROR; }
/*----------------------------------------------------------------------------*/ 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(); }
/*----------------------------------------------------------------------------*/ 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(); }
// send the registration for a single server static void prv_register(lwm2m_context_t * contextP, lwm2m_server_t * server) { char query[200]; int query_length; uint8_t payload[512]; int payload_length; lwm2m_transaction_t * transaction; payload_length = prv_getRegisterPayload(contextP, payload, sizeof(payload)); if (payload_length == 0) return; query_length = prv_getRegistrationQuery(contextP, server, query, sizeof(query)); if (query_length == 0) return; if (0 != server->lifetime) { if (snprintf(query + query_length, PRV_QUERY_BUFFER_LENGTH - query_length, QUERY_DELIMITER QUERY_LIFETIME "%d", (int)server->lifetime) <= 0) { return; } } if (server->sessionH == NULL) { server->sessionH = contextP->connectCallback(server->secObjInstID, contextP->userData); } if (NULL != server->sessionH) { transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)server); if (transaction == NULL) return; coap_set_header_uri_path(transaction->message, "/"URI_REGISTRATION_SEGMENT); coap_set_header_uri_query(transaction->message, query); coap_set_payload(transaction->message, payload, payload_length); transaction->callback = prv_handleRegistrationReply; transaction->userData = (void *) server; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); if (transaction_send(contextP, transaction) == 0) { server->status = STATE_REG_PENDING; } } }
// start a device initiated bootstrap int bootstrap_initiating_request(lwm2m_context_t * context) { char query[PRV_QUERY_BUFFER_LENGTH]; int query_length = 0; lwm2m_transaction_t * transaction = NULL; query_length = snprintf(query, sizeof(query), "?ep=%s", context->endpointName); if (query_length <= 1) { return INTERNAL_SERVER_ERROR_5_00; } // find the first bootstrap server lwm2m_server_t * bootstrapServer = context->bootstrapServerList; while (bootstrapServer != NULL) { if (bootstrapServer->sessionH == NULL) { bootstrapServer->sessionH = context->connectCallback(bootstrapServer->secObjInstID, context->userData); } if (bootstrapServer->sessionH != NULL) { LOG("[BOOTSTRAP] Bootstrap session starting...\r\n"); transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, context->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)bootstrapServer); if (transaction == NULL) { return INTERNAL_SERVER_ERROR_5_00; } coap_set_header_uri_path(transaction->message, "/"URI_BOOTSTRAP_SEGMENT); coap_set_header_uri_query(transaction->message, query); transaction->callback = prv_handleBootstrapReply; transaction->userData = (void *)context; context->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(context->transactionList, transaction); if (transaction_send(context, transaction) == 0) { LOG("[BOOTSTRAP] DI bootstrap requested to BS server\r\n"); context->bsState = BOOTSTRAP_INITIATED; reset_bootstrap_timer(context); } } else { LOG("No bootstrap session handler found\r\n"); } bootstrapServer = bootstrapServer->next; } return NO_ERROR; }
int lwm2m_register(lwm2m_context_t * contextP) { char * query; char payload[512]; int payload_length; lwm2m_server_t * targetP; payload_length = prv_getRegisterPayload(contextP, payload, sizeof(payload)); if (payload_length == 0) return INTERNAL_SERVER_ERROR_5_00; query = (char*)lwm2m_malloc(QUERY_LENGTH + strlen(contextP->endpointName) + 1); if (query == NULL) return INTERNAL_SERVER_ERROR_5_00; strcpy(query, QUERY_TEMPLATE); strcpy(query + QUERY_LENGTH, contextP->endpointName); targetP = contextP->serverList; while (targetP != NULL) { lwm2m_transaction_t * transaction; transaction = transaction_new(COAP_POST, NULL, contextP->nextMID++, ENDPOINT_SERVER, (void *)targetP); if (transaction == NULL) return INTERNAL_SERVER_ERROR_5_00; coap_set_header_uri_path(transaction->message, "/"URI_REGISTRATION_SEGMENT); coap_set_header_uri_query(transaction->message, query); coap_set_payload(transaction->message, payload, payload_length); transaction->callback = prv_handleRegistrationReply; transaction->userData = (void *) contextP; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); if (transaction_send(contextP, transaction) == 0) { targetP->status = STATE_REG_PENDING; targetP->mid = transaction->mID; } targetP = targetP->next; } lwm2m_free(query); return 0; }
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; }
static int prv_update_registration(lwm2m_context_t * contextP, lwm2m_server_t * server) { lwm2m_transaction_t * transaction; transaction = transaction_new(COAP_PUT, NULL, contextP->nextMID++, ENDPOINT_SERVER, (void *)server); if (transaction == NULL) return INTERNAL_SERVER_ERROR_5_00; coap_set_header_uri_path(transaction->message, server->location); transaction->callback = prv_handleRegistrationUpdateReply; transaction->userData = (void *) server; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); if (transaction_send(contextP, transaction) == 0) { server->status = STATE_REG_UPDATE_PENDING; server->mid = transaction->mID; } return 0; }
static int prv_updateRegistration(lwm2m_context_t * contextP, lwm2m_server_t * server, bool withObjects) { lwm2m_transaction_t * transaction; uint8_t payload[512]; int payload_length; transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)server); if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; coap_set_header_uri_path(transaction->message, server->location); if (withObjects == true) { payload_length = object_getRegisterPayload(contextP, payload, sizeof(payload)); if (payload_length == 0) { transaction_free(transaction); return COAP_500_INTERNAL_SERVER_ERROR; } coap_set_payload(transaction->message, payload, payload_length); } transaction->callback = prv_handleRegistrationUpdateReply; transaction->userData = (void *) server; contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); if (transaction_send(contextP, transaction) == 0) { server->status = STATE_REG_UPDATE_PENDING; } return COAP_NO_ERROR; }
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) */
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 transmitTask(void *pvParameters) { struct userdata *user = (struct userdata *)pvParameters; coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ int a; char payload[128]; int failures = 0; // Get host/port from request URL // should call free(uri) somewhere coap_uri_t *uri = coap_new_uri(SERVER_URI, strlen(SERVER_URI)); if (uri == NULL) { COAP_PRINTF("coap_new_uri(): URI failed\n"); vTaskDelete(NULL); } COAP_PRINTF("URI Path: %s\n", uri->path.s); COAP_PRINTF("URI Host: %s\n", uri->host.s); // init a HTTP POST message and set message header coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); coap_set_header_uri_path(request, (char *)uri->path.s); coap_set_header_uri_host(request, (char *)uri->host.s); // create network socket struct addrinfo hints; struct addrinfo *res; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; // 2. DNS lookup int err; char port[6]; sprintf(port, "%d", uri->port); printf("Running DNS lookup for %s...\r\n", uri->host.s); while (1) { err = getaddrinfo((char*)uri->host.s, (char*)port, &hints, &res); if (err == 0) break; freeaddrinfo(res); printf("DNS lookup failed err=%d res=%p\r\n", err, res); vTaskDelay(3000 / portTICK_RATE_MS); } /* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */ struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(*addr)); // 3. Create a local socket int s = socket(res->ai_family, res->ai_socktype, 0); if(s < 0) { printf("... Failed to allocate socket.\r\n"); freeaddrinfo(res); vTaskDelete(NULL); } printf("... allocated socket\r\n"); int ret; while(1) { // connect to server if (connect(s, res->ai_addr, res->ai_addrlen) != 0) { close(s); freeaddrinfo(res); failures++; printf("... socket connect failed. tries = %d.\r\n", failures); vTaskDelay(4000 / portTICK_RATE_MS); continue; } printf("... connected\r\n"); freeaddrinfo(res); repeat: xQueueReceive(user->xQueue, &a, portMAX_DELAY); sprintf(payload, "{ \"quality\": %d }\n", a); COAP_PRINTF("Payload: %s\n", payload); // CoAP payload coap_set_payload(request, payload, strlen(payload)); ret = write(s, payload, strlen(payload)); if (ret >= 0) goto repeat; } }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(coap_client_process, ev, data) { /* #if WITH_COMPOWER static int print = 0; #endif */ PROCESS_BEGIN(); PROCESS_PAUSE(); set_global_address(); PRINTF("CoAP client process started\n"); print_local_addresses(); /**************************************************************************/ static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ /* receives all CoAP messages */ coap_init_engine(); etimer_set(&et, GET_INTERVAL * CLOCK_SECOND); while(1) { PROCESS_YIELD(); if(ev == tcpip_event) { printf("TCPIP_HANDLER\n"); tcpip_handler(); } if(etimer_expired(&et)) { count_get++; /*---------------------------------------------------------------------------*/ if(count_get < 10) { /* we do normal GET 3 times for each resource */ /* TEST GET: looping through the 3 resources: status, vdc, hwcfg */ /* Also CoAP GET doesn't need to have a payload */ coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); if(count_get % 3 == 1) { coap_set_header_uri_path(request, service_urls[1]); PRINTF("GET %d: %s\n", count_get, service_urls[1]); } else if(count_get % 3 == 2) { coap_set_header_uri_path(request, service_urls[2]); PRINTF("GET %d: %s\n", count_get, service_urls[2]); } else { coap_set_header_uri_path(request, service_urls[3]); PRINTF("GET %d: %s\n", count_get, service_urls[3]); } #if PLATFORM_HAS_LEDS /* set yellow led when sending packet */ leds_on(LEDS_YELLOW); #endif COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); } /* if (count_get < 10) */ /*---------------------------------------------------------------------------*/ /* test PUT: vdc and hwcfg on odd and even packet */ /* every 10th timer we PUT a resource: vdc and hwcfg alternately */ if(count_get % 10 == 0) { /* static char msg[64] = ""; */ char msg[64] = ""; /*---------------------------------------------------------------------------*/ /* We read CO2 sensor if it is enable */ #ifdef CO2 coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); coap_set_header_uri_path(request, "/dcdc/co2"); PRINTF("GET %d: %s\n", count_get, "/dcdc/co2"); #if PLATFORM_HAS_LEDS leds_on(LEDS_YELLOW); #endif COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); #endif /*---------------------------------------------------------------------------*/ count_put++; coap_init_message(request, COAP_TYPE_CON, COAP_PUT, 0); if(count_put % 2 == 0) { coap_set_header_uri_path(request, service_urls[3]); generate_random_payload(3, msg); coap_set_payload(request, (uint8_t *)msg, sizeof(msg) - 1); PRINTF("PUT %d: %s PAYLOAD: %s\n", count_get, service_urls[3], msg); } else { coap_set_header_uri_path(request, service_urls[2]); generate_random_payload(2, msg); coap_set_payload(request, (uint8_t *)msg, sizeof(msg) - 1); PRINTF("PUT %d: %s PAYLOAD: %s\n", count_get, service_urls[2], msg); } #if PLATFORM_HAS_LEDS /* set yellow led when sending packet */ leds_on(LEDS_YELLOW); #endif COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); } /* after 2 more timeout we do GET to check the resource new value */ if((count_get > 10) && ((count_get - 2) % 10 == 0)) { coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); if(count_put % 2 == 0) { coap_set_header_uri_path(request, service_urls[3]); PRINTF("GET %d: %s\n", count_get, service_urls[3]); } else { coap_set_header_uri_path(request, service_urls[2]); PRINTF("GET %d: %s\n", count_get, service_urls[2]); } #if PLATFORM_HAS_LEDS /* set yellow led when sending packet */ leds_on(LEDS_YELLOW); #endif COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); } /*---------------------------------------------------------------------------*/ /* test GET with observe option when timer expires the 15th time */ if(count_get == 15) { /* PRINTF("GET %d: OBSERVE: %s\n", count_get, service_urls[2]); */ toggle_observation(); } etimer_reset(&et); } } /* END_WHILE(1) */ PROCESS_END(); }
void http_get_task(void *pvParameters) { coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ int failures = 0; // create network socket struct addrinfo hints; struct addrinfo *res; // Use an UDP socket hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; // Get host/port from request URL // should call free(uri) somewhere coap_uri_t *uri = coap_new_uri((unsigned char*)URI, strlen(URI)); if (uri == NULL) { COAP_PRINTF("coap_new_uri(): URI failed\n"); vTaskDelete(NULL); } // DNS lookup int err; char port[6]; char host[32]; char path[64]; sprintf(port, "%d", uri->port); sprintf(path, "%s", uri->path.s); memcpy(host, uri->host.s, uri->host.length); host[uri->host.length] = '\0'; COAP_PRINTF("URI Path: %s\n", path); COAP_PRINTF("URI Host: %s\n", host); COAP_PRINTF("URI Port: %s\n", port); printf("Running DNS lookup for %s...\r\n", host); while (1) { err = getaddrinfo(host, port, &hints, &res); if (err == 0) break; freeaddrinfo(res); printf("DNS lookup failed err=%d res=%p\r\n", err, res); vTaskDelay(3000 / portTICK_RATE_MS); } /* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */ struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; char *ip = inet_ntoa(*addr); printf("DNS lookup succeeded. HOST=%s, IP=%s\r\n", host, ip); // init a HTTP POST message and set message header coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); coap_set_header_uri_path(request, path); coap_set_header_uri_host(request, host); // Create a local socket int s = socket(res->ai_family, res->ai_socktype, 0); if(s < 0) { printf("... Failed to allocate socket.\r\n"); freeaddrinfo(res); vTaskDelete(NULL); } printf("... allocated socket\r\n"); int a; int ret; char payload[128]; struct request_state_t state[1]; ip_addr_t ipaddr; ipaddr.addr = ipaddr_addr(ip); while(1) { if(connect(s, res->ai_addr, res->ai_addrlen) != 0) { close(s); freeaddrinfo(res); printf("... socket connect failed.\r\n"); vTaskDelay(3000 / portTICK_RATE_MS); failures++; continue; } printf("... connected\r\n"); freeaddrinfo(res); repeat: vTaskDelay(5000 / portTICK_RATE_MS); // read sensor data from ESP8266 A0 a = sdk_system_adc_read(); sprintf(payload, "{ \"quality\": %d }\n", a); COAP_PRINTF("Payload: %s\n", payload); // CoAP payload coap_set_payload(request, payload, strlen(payload)); // Make CoAP transaction request->mid = coap_get_mid(); if ((state->transaction = coap_new_transaction(request->mid, &ipaddr, uri->port))) { state->transaction->callback = coap_blocking_request_callback; state->transaction->callback_data = state; if (state->block_num > 0) { coap_set_header_block2(request, state->block_num, 0, REST_MAX_CHUNK_SIZE); } // Build CoAP header and Options state->transaction->packet_len = coap_serialize_message(request, state->transaction->packet); COAP_PRINTF("Header dump: [0x%02X %02X %02X %02X]. Size: %d\n", request->buffer[0], request->buffer[1], request->buffer[2], request->buffer[3], state->transaction->packet_len ); COAP_PRINTF("Requested #%u (MID %u)\n", state->block_num, request->mid); // Transmit ret = write(s, state->transaction->packet, state->transaction->packet_len); //ret = sendto(s, state->transaction->packet, state->transaction->packet_len); if (ret < 0) { printf("[RET: %d] CoAP packet send failed.\n", ret); continue; } } else { COAP_PRINTF("Could not allocate transaction buffer"); } goto repeat; } }
PROCESS_THREAD(coap_client_example, ev, data) { PROCESS_BEGIN(); 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(); etimer_set(&et, TOGGLE_INTERVAL * CLOCK_SECOND); #if PLATFORM_HAS_BUTTON SENSORS_ACTIVATE(button_sensor); printf("Press a button to request %s\n", service_urls[uri_switch]); #endif while(1) { PROCESS_YIELD(); if (etimer_expired(&et)) { printf("--Toggle timer--\n"); /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0 ); coap_set_header_uri_path(request, service_urls[1]); const char msg[] = "Toggle!"; coap_set_payload(request, (uint8_t *)msg, sizeof(msg)-1); PRINT6ADDR(&server_ipaddr); PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); printf("\n--Done--\n"); etimer_reset(&et); #if PLATFORM_HAS_BUTTON } else if (ev == sensors_event && data == &button_sensor) { /* send a request to notify the end of the process */ coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); coap_set_header_uri_path(request, service_urls[uri_switch]); printf("--Requesting %s--\n", service_urls[uri_switch]); PRINT6ADDR(&server_ipaddr); PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT)); COAP_BLOCKING_REQUEST(&server_ipaddr, REMOTE_PORT, request, client_chunk_handler); printf("\n--Done--\n"); uri_switch = (uri_switch+1) % NUMBER_OF_URLS; #endif } } PROCESS_END(); }