Hi there!
After having worked with the nRF5 SDK and nRF SDK for Mesh, I'm off to a start for a project with LTE; CoAP to be precise. I'm using the nRF Connect SDK with Visual Studio Code extension and I'm absolutely loving it with my nRF9160 DK.
So, I went ahead and took the CoAP Client Example and have setup an instance of ThingsBoard on my server. I know everyone suggests to use Leshan, but you can be assured that everythings is working correctly; I've written a counter that increments on the dashboard. Hence, I changed the main of the example to this.
static int client_post_send(const char* payload){ int err; struct coap_packet request; next_token++; err = coap_packet_init(&request, coap_buf, sizeof(coap_buf), APP_COAP_VERSION, COAP_TYPE_NON_CON, sizeof(next_token), (uint8_t *)&next_token, COAP_METHOD_POST, coap_next_id()); if (err < 0) { printk("Failed to create CoAP request, %d\n", err); return err; } const char* path = "api/v1/T2_TEST_TOKEN/telemetry"; err = coap_packet_append_option(&request, COAP_OPTION_URI_PATH, (uint8_t *)path, strlen(path)); if (err < 0) { printk("Failed to encode CoAP option, %d\n", err); return err; } coap_packet_append_payload_marker(&request); err = coap_packet_append_payload(&request, (uint8_t *)payload, strlen(payload)); if (err < 0) { printk("Failed to encode CoAP option, %d\n", err); return err; } err = send(sock, request.data, request.offset, 0); if (err < 0) { printk("Failed to send CoAP request, %d\n", errno); return -errno; } printk("CoAP request sent: token 0x%04x\n", next_token); return 0; } void main(void){ int64_t next_msg_time = APP_COAP_SEND_INTERVAL_MS; int err, received; printk("The nRF CoAP client sample started\n"); modem_configure(); if (server_resolve() != 0) { printk("Failed to resolve server name\n"); return; } if (client_init() != 0) { printk("Failed to initialize CoAP client\n"); return; } next_msg_time = k_uptime_get(); uint8_t i = 0; while (1) { if (k_uptime_get() >= next_msg_time) { char payload[30]; snprintf(payload, sizeof(payload), "{\"temperature\": %i}", i++); if (client_post_send(payload) != 0) { printk("Failed to send POST request, exit...\n"); break; } next_msg_time += APP_COAP_SEND_INTERVAL_MS; } int64_t remaining = next_msg_time - k_uptime_get(); if (remaining < 0) { remaining = 0; } if(wait(remaining) == 0){ received = recv(sock, coap_buf, sizeof(coap_buf), MSG_DONTWAIT); if(received > 0){ client_handle_get_response(coap_buf, received); } } } (void)close(sock); }
Now that this is working, I'd like to also be able to receive messages. As can be seen in the code snippet above. This, however, crashes the nRF... Now I'm wondering if this is even the best approach; polling seems like an indesirable method. Isn't there a way to register a callback that's triggered whenever a POST, GET or PUT request is received?
I could of course be overlooking something since I'm quite new to all this, but I couldn't realy manage to plough through the Zephyr documentation. I'm hoping some of you could help me out.
Kind regards,
A learning Jochem