coap-example
Dependencies: NetworkServices W5500Interface easy-connect
Fork of coap-example by
main.cpp
00001 /* 00002 * PackageLicenseDeclared: Apache-2.0 00003 * Copyright (c) 2017 ARM Limited 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include <string> 00019 #include "mbed.h" 00020 #include "easy-connect.h" 00021 #include "sn_coap_protocol.h" 00022 #include "sn_coap_header.h" 00023 00024 UDPSocket socket; // Socket to talk CoAP over 00025 Thread recvfromThread; // Thread to receive messages over CoAP 00026 00027 struct coap_s* coapHandle; 00028 coap_version_e coapVersion = COAP_VERSION_1; 00029 00030 // CoAP HAL 00031 void* coap_malloc(uint16_t size) { 00032 return malloc(size); 00033 } 00034 00035 void coap_free(void* addr) { 00036 free(addr); 00037 } 00038 00039 // tx_cb and rx_cb are not used in this program 00040 uint8_t coap_tx_cb(uint8_t *a, uint16_t b, sn_nsdl_addr_s *c, void *d) { 00041 printf("coap tx cb\n"); 00042 return 0; 00043 } 00044 00045 int8_t coap_rx_cb(sn_coap_hdr_s *a, sn_nsdl_addr_s *b, void *c) { 00046 printf("coap rx cb\n"); 00047 return 0; 00048 } 00049 00050 // Main function for the recvfrom thread 00051 void recvfromMain() { 00052 SocketAddress addr; 00053 uint8_t* recv_buffer = (uint8_t*)malloc(1280); // Suggested is to keep packet size under 1280 bytes 00054 00055 nsapi_size_or_error_t ret; 00056 00057 while ((ret = socket.recvfrom(&addr, recv_buffer, 1280)) >= 0) { 00058 // to see where the message came from, inspect addr.get_addr() and addr.get_port() 00059 00060 printf("Received a message of length '%d'\n", ret); 00061 00062 sn_coap_hdr_s* parsed = sn_coap_parser(coapHandle, ret, recv_buffer, &coapVersion); 00063 00064 // We know the payload is going to be a string 00065 std::string payload((const char*)parsed->payload_ptr, parsed->payload_len); 00066 00067 printf("\tmsg_id: %d\n", parsed->msg_id); 00068 printf("\tmsg_code: %d\n", parsed->msg_code); 00069 printf("\tcontent_format: %d\n", parsed->content_format); 00070 printf("\tpayload_len: %d\n", parsed->payload_len); 00071 printf("\tpayload: %s\n", payload.c_str()); 00072 printf("\toptions_list_ptr: %p\n", parsed->options_list_ptr); 00073 } 00074 00075 free(recv_buffer); 00076 00077 printf("UDPSocket::recvfrom failed, error code %d. Shutting down receive thread.\n", ret); 00078 } 00079 00080 int main() { 00081 printf("Easy connect...\n"); 00082 NetworkInterface *network = easy_connect(true); 00083 if (!network) { 00084 printf("Cannot connect to the network, see serial output"); 00085 return 1; 00086 } 00087 00088 printf("Connected to the network. Opening a socket...\n"); 00089 00090 // Open a socket on the network interface 00091 socket.open(network); 00092 00093 // Initialize the CoAP protocol handle, pointing to local implementations on malloc/free/tx/rx functions 00094 coapHandle = sn_coap_protocol_init(&coap_malloc, &coap_free, &coap_tx_cb, &coap_rx_cb); 00095 00096 // UDPSocket::recvfrom is blocking, so run it in a separate RTOS thread 00097 recvfromThread.start(&recvfromMain); 00098 00099 // Path to the resource we want to retrieve 00100 const char* coap_uri_path = "/test"; 00101 00102 // See ns_coap_header.h 00103 sn_coap_hdr_s *coap_res_ptr = (sn_coap_hdr_s*)calloc(sizeof(sn_coap_hdr_s), 1); 00104 coap_res_ptr->uri_path_ptr = (uint8_t*)coap_uri_path; // Path 00105 coap_res_ptr->uri_path_len = strlen(coap_uri_path); 00106 coap_res_ptr->msg_code = COAP_MSG_CODE_REQUEST_GET; // CoAP method 00107 coap_res_ptr->content_format = COAP_CT_TEXT_PLAIN; // CoAP content type 00108 coap_res_ptr->payload_len = 0; // Body length 00109 coap_res_ptr->payload_ptr = 0; // Body pointer 00110 coap_res_ptr->options_list_ptr = 0; // Optional: options list 00111 // Message ID is used to track request->response patterns, because we're using UDP (so everything is unconfirmed). 00112 // See the receive code to verify that we get the same message ID back 00113 coap_res_ptr->msg_id = 7; 00114 00115 // Calculate the CoAP message size, allocate the memory and build the message 00116 uint16_t message_len = sn_coap_builder_calc_needed_packet_data_size(coap_res_ptr); 00117 printf("Calculated message length: %d bytes\n", message_len); 00118 00119 uint8_t* message_ptr = (uint8_t*)malloc(message_len); 00120 sn_coap_builder(message_ptr, coap_res_ptr); 00121 00122 // Uncomment to see the raw buffer that will be sent... 00123 // printf("Message is: "); 00124 // for (size_t ix = 0; ix < message_len; ix++) { 00125 // printf("%02x ", message_ptr[ix]); 00126 // } 00127 // printf("\n"); 00128 00129 int scount = socket.sendto("i-ce.itron.cloud", 5683, message_ptr, message_len); 00130 printf("Sent %d bytes to coap://i-ce.itron.cloud:5683\n", scount); 00131 00132 free(coap_res_ptr); 00133 free(message_ptr); 00134 00135 Thread::wait(osWaitForever); 00136 }
Generated on Sat Jul 16 2022 00:11:42 by 1.7.2