research application on sending data to headend

Dependencies:   DataStore JobScheduler NetworkServices W5500Interface nanopb protocol

See "main.cpp" documentation on "API Documentation" tab for details about application.

Committer:
sgnezdov
Date:
Fri Aug 11 19:07:20 2017 +0000
Revision:
28:7214f7806526
Parent:
19:40f5bcec121e
fixed compilation bug

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgnezdov 4:b360d4f0bf34 1 #include "lceProxy.h"
sgnezdov 4:b360d4f0bf34 2
sgnezdov 4:b360d4f0bf34 3 #include "mbed.h"
sgnezdov 4:b360d4f0bf34 4 #include "sn_coap_protocol.h"
sgnezdov 4:b360d4f0bf34 5 #include "sn_coap_header.h"
sgnezdov 4:b360d4f0bf34 6
sgnezdov 4:b360d4f0bf34 7 #include "mbed-trace/mbed_trace.h"
sgnezdov 4:b360d4f0bf34 8 #define TRACE_GROUP "lce"
sgnezdov 4:b360d4f0bf34 9
sgnezdov 4:b360d4f0bf34 10 // CoAP HAL
sgnezdov 4:b360d4f0bf34 11 void* coap_malloc(uint16_t size) {
sgnezdov 4:b360d4f0bf34 12 return malloc(size);
sgnezdov 4:b360d4f0bf34 13 }
sgnezdov 4:b360d4f0bf34 14
sgnezdov 4:b360d4f0bf34 15 void coap_free(void* addr) {
sgnezdov 4:b360d4f0bf34 16 free(addr);
sgnezdov 4:b360d4f0bf34 17 }
sgnezdov 4:b360d4f0bf34 18
sgnezdov 4:b360d4f0bf34 19 // tx_cb and rx_cb are not used in this program
sgnezdov 4:b360d4f0bf34 20 uint8_t coap_tx_cb(uint8_t *a, uint16_t b, sn_nsdl_addr_s *c, void *d) {
sgnezdov 4:b360d4f0bf34 21 tr_warn("coap tx cb");
sgnezdov 4:b360d4f0bf34 22 return 0;
sgnezdov 4:b360d4f0bf34 23 }
sgnezdov 4:b360d4f0bf34 24
sgnezdov 4:b360d4f0bf34 25 int8_t coap_rx_cb(sn_coap_hdr_s *a, sn_nsdl_addr_s *b, void *c) {
sgnezdov 4:b360d4f0bf34 26 tr_warn("coap rx cb");
sgnezdov 4:b360d4f0bf34 27 return 0;
sgnezdov 4:b360d4f0bf34 28 }
sgnezdov 4:b360d4f0bf34 29
sgnezdov 4:b360d4f0bf34 30 Thread receiver; // Thread to receive messages over CoAP
sgnezdov 4:b360d4f0bf34 31 UDPSocket socket;
sgnezdov 4:b360d4f0bf34 32 struct coap_s* coapHandle;
sgnezdov 4:b360d4f0bf34 33 coap_version_e coapVersion = COAP_VERSION_1;
sgnezdov 4:b360d4f0bf34 34
sgnezdov 4:b360d4f0bf34 35
sgnezdov 4:b360d4f0bf34 36 // Main function for the recvfrom thread
sgnezdov 4:b360d4f0bf34 37 void receive() {
sgnezdov 4:b360d4f0bf34 38 SocketAddress addr;
sgnezdov 4:b360d4f0bf34 39 uint8_t* recv_buffer = (uint8_t*)malloc(1280); // Suggested is to keep packet size under 1280 bytes
sgnezdov 4:b360d4f0bf34 40
sgnezdov 4:b360d4f0bf34 41 nsapi_size_or_error_t ret;
sgnezdov 4:b360d4f0bf34 42
sgnezdov 4:b360d4f0bf34 43 while ((ret = socket.recvfrom(&addr, recv_buffer, 1280)) >= 0) {
sgnezdov 4:b360d4f0bf34 44 // to see where the message came from, inspect addr.get_addr() and addr.get_port()
sgnezdov 4:b360d4f0bf34 45
sgnezdov 4:b360d4f0bf34 46 tr_debug("Received a message of length '%d'", ret);
sgnezdov 4:b360d4f0bf34 47
sgnezdov 4:b360d4f0bf34 48 sn_coap_hdr_s* parsed = sn_coap_parser(coapHandle, ret, recv_buffer, &coapVersion);
sgnezdov 4:b360d4f0bf34 49
sgnezdov 4:b360d4f0bf34 50 tr_debug("\tmsg_id: %d", parsed->msg_id);
sgnezdov 4:b360d4f0bf34 51 tr_debug("\tmsg_code: %d", parsed->msg_code);
sgnezdov 4:b360d4f0bf34 52 tr_debug("\tcontent_format: %d", parsed->content_format);
sgnezdov 4:b360d4f0bf34 53 tr_debug("\tpayload_len: %d", parsed->payload_len);
sgnezdov 4:b360d4f0bf34 54 tr_debug("\tpayload: ");
sgnezdov 4:b360d4f0bf34 55 tr_array(parsed->payload_ptr, parsed->payload_len);
sgnezdov 4:b360d4f0bf34 56 tr_debug("\toptions_list_ptr: %p", parsed->options_list_ptr);
sgnezdov 4:b360d4f0bf34 57 }
sgnezdov 4:b360d4f0bf34 58
sgnezdov 4:b360d4f0bf34 59 free(recv_buffer);
sgnezdov 4:b360d4f0bf34 60
sgnezdov 7:c4123a87abe2 61 tr_error("UDPSocket::recvfrom failed, error code %d. Shutting down receive thread.", ret);
sgnezdov 4:b360d4f0bf34 62 }
sgnezdov 4:b360d4f0bf34 63
sgnezdov 7:c4123a87abe2 64 void LceProxy::SendV1(const char* path, uint8_t *data, size_t dataLen, bool isAlarm, time_t taken)
sgnezdov 4:b360d4f0bf34 65 {
sgnezdov 4:b360d4f0bf34 66
sgnezdov 4:b360d4f0bf34 67 // Open a socket on the network interface
sgnezdov 4:b360d4f0bf34 68 socket.open(&_ni);
sgnezdov 4:b360d4f0bf34 69
sgnezdov 4:b360d4f0bf34 70 // Initialize the CoAP protocol handle, pointing to local implementations on malloc/free/tx/rx functions
sgnezdov 4:b360d4f0bf34 71 coapHandle = sn_coap_protocol_init(&coap_malloc, &coap_free, &coap_tx_cb, &coap_rx_cb);
sgnezdov 4:b360d4f0bf34 72
sgnezdov 4:b360d4f0bf34 73 // UDPSocket::recvfrom is blocking, so run it in a separate RTOS thread
sgnezdov 16:bef1673b199e 74 //receiver.start(&receive);
sgnezdov 4:b360d4f0bf34 75
sgnezdov 7:c4123a87abe2 76 // URIPath option id is 11.
sgnezdov 7:c4123a87abe2 77 // URIQuery option id is 15. Option delta is 15-11=4.
sgnezdov 7:c4123a87abe2 78
sgnezdov 7:c4123a87abe2 79 sn_coap_options_list_s options;
sgnezdov 7:c4123a87abe2 80 memset(&options, 0, sizeof(sn_coap_options_list_s));
sgnezdov 7:c4123a87abe2 81 options.uri_port = -1; // -1 if not used
sgnezdov 7:c4123a87abe2 82 options.observe = -1; // -1 if not used
sgnezdov 7:c4123a87abe2 83 options.block1 = -1; // -1 if not used
sgnezdov 7:c4123a87abe2 84 options.block2 = -1; // -1 if not used
sgnezdov 7:c4123a87abe2 85 options.max_age = 60; // restore default 60
sgnezdov 7:c4123a87abe2 86 options.accept = COAP_CT_NONE; // COAP_CT_NONE is not used
sgnezdov 7:c4123a87abe2 87 char* query = "S=Nucleo1&TH=14d14764c9a7a2fb";
sgnezdov 7:c4123a87abe2 88 options.uri_query_ptr = (uint8_t*)query;
sgnezdov 7:c4123a87abe2 89 options.uri_query_len = strlen(query);
sgnezdov 7:c4123a87abe2 90
sgnezdov 7:c4123a87abe2 91
sgnezdov 7:c4123a87abe2 92 // * HEX build is not a way to go! * the following is a bad way
sgnezdov 7:c4123a87abe2 93 // HEX: 53 4e 3d 4e 75 63 6c 65 6f 31 is "SN=Nucleo1"
sgnezdov 7:c4123a87abe2 94 // uint8_t query[] = { 0x3, 0xA, 0x53, 0x4e, 0x3d, 0x4e, 0x75, 0x63, 0x6c, 0x65, 0x6f, 0x31 };
sgnezdov 7:c4123a87abe2 95 // options.uri_query_ptr = query;
sgnezdov 7:c4123a87abe2 96 // options.uri_query_len = 12; // strlen(query)
sgnezdov 7:c4123a87abe2 97
sgnezdov 4:b360d4f0bf34 98 // See ns_coap_header.h
sgnezdov 4:b360d4f0bf34 99 sn_coap_hdr_s *coap_res_ptr = (sn_coap_hdr_s*)calloc(sizeof(sn_coap_hdr_s), 1);
sgnezdov 4:b360d4f0bf34 100 coap_res_ptr->uri_path_ptr = (uint8_t*)path; // Path
sgnezdov 4:b360d4f0bf34 101 coap_res_ptr->uri_path_len = strlen(path);
sgnezdov 4:b360d4f0bf34 102 coap_res_ptr->msg_code = COAP_MSG_CODE_REQUEST_GET; // CoAP method
sgnezdov 4:b360d4f0bf34 103 coap_res_ptr->content_format = COAP_CT_TEXT_PLAIN; // CoAP content type
sgnezdov 4:b360d4f0bf34 104 coap_res_ptr->payload_len = dataLen; // Body length
sgnezdov 4:b360d4f0bf34 105 coap_res_ptr->payload_ptr = data; // Body pointer
sgnezdov 7:c4123a87abe2 106 coap_res_ptr->options_list_ptr = &options; // Optional: options list
sgnezdov 4:b360d4f0bf34 107 // Message ID is used to track request->response patterns, because we're using UDP (so everything is unconfirmed).
sgnezdov 4:b360d4f0bf34 108 // See the receive code to verify that we get the same message ID back
sgnezdov 4:b360d4f0bf34 109 coap_res_ptr->msg_id = 7;
sgnezdov 7:c4123a87abe2 110
sgnezdov 16:bef1673b199e 111 // print payload content as hex string
sgnezdov 16:bef1673b199e 112 {
sgnezdov 16:bef1673b199e 113 int hexOutSize = 3*dataLen+1;
sgnezdov 16:bef1673b199e 114 char* hexOut = new char[hexOutSize];
sgnezdov 19:40f5bcec121e 115 hexOut[0] = 0;
sgnezdov 16:bef1673b199e 116 for (int i = 0; i < dataLen; i++) {
sgnezdov 16:bef1673b199e 117 snprintf(hexOut, hexOutSize, "%s %02x", hexOut, data[i]);
sgnezdov 16:bef1673b199e 118 }
sgnezdov 16:bef1673b199e 119 tr_debug("CoAP Payload: %s", hexOut);
sgnezdov 16:bef1673b199e 120 delete hexOut;
sgnezdov 16:bef1673b199e 121 }
sgnezdov 7:c4123a87abe2 122
sgnezdov 4:b360d4f0bf34 123 // Calculate the CoAP message size, allocate the memory and build the message
sgnezdov 4:b360d4f0bf34 124 uint16_t message_len = sn_coap_builder_calc_needed_packet_data_size(coap_res_ptr);
sgnezdov 4:b360d4f0bf34 125 tr_debug("Calculated message length: %d bytes", message_len);
sgnezdov 4:b360d4f0bf34 126
sgnezdov 4:b360d4f0bf34 127 uint8_t* message_ptr = (uint8_t*)malloc(message_len);
sgnezdov 4:b360d4f0bf34 128 sn_coap_builder(message_ptr, coap_res_ptr);
sgnezdov 4:b360d4f0bf34 129
sgnezdov 4:b360d4f0bf34 130 // Uncomment to see the raw buffer that will be sent...
sgnezdov 4:b360d4f0bf34 131 // tr_debug("Message is: ");
sgnezdov 4:b360d4f0bf34 132 // for (size_t ix = 0; ix < message_len; ix++) {
sgnezdov 4:b360d4f0bf34 133 // tr_debug("%02x ", message_ptr[ix]);
sgnezdov 4:b360d4f0bf34 134 // }
sgnezdov 4:b360d4f0bf34 135 // tr_debug("");
sgnezdov 4:b360d4f0bf34 136
sgnezdov 16:bef1673b199e 137 const char host[] = "kama.blackhawk-lab.itron.com";
sgnezdov 16:bef1673b199e 138 int scount = 0;
sgnezdov 16:bef1673b199e 139 scount = socket.sendto(host, 5683, message_ptr, message_len);
sgnezdov 16:bef1673b199e 140 //Thread::wait(3);
sgnezdov 16:bef1673b199e 141 tr_debug("Sent %d bytes to coap://%s:5683", scount, host);
sgnezdov 16:bef1673b199e 142
sgnezdov 16:bef1673b199e 143 socket.close();
sgnezdov 4:b360d4f0bf34 144
sgnezdov 4:b360d4f0bf34 145 free(coap_res_ptr);
sgnezdov 16:bef1673b199e 146 free(message_ptr);
sgnezdov 16:bef1673b199e 147
sgnezdov 4:b360d4f0bf34 148 }