sandbox
/
coap-example
CoAP example application for mbed OS 5
Embed:
(wiki syntax)
Show/hide line numbers
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_nsdl.h" 00022 #include "sn_coap_protocol.h" 00023 #include "sn_coap_header.h" 00024 00025 UDPSocket socket; // Socket to talk CoAP over 00026 Thread recvfromThread; // Thread to receive messages over CoAP 00027 00028 struct coap_s* coapHandle; 00029 coap_version_e coapVersion = COAP_VERSION_1; 00030 00031 // CoAP HAL 00032 void* coap_malloc(uint16_t size) { 00033 return malloc(size); 00034 } 00035 00036 void coap_free(void* addr) { 00037 free(addr); 00038 } 00039 00040 // tx_cb and rx_cb are not used in this program 00041 uint8_t coap_tx_cb(uint8_t *a, uint16_t b, sn_nsdl_addr_s *c, void *d) { 00042 printf("coap tx cb\n"); 00043 return 0; 00044 } 00045 00046 int8_t coap_rx_cb(sn_coap_hdr_s *a, sn_nsdl_addr_s *b, void *c) { 00047 printf("coap rx cb\n"); 00048 return 0; 00049 } 00050 00051 // Main function for the recvfrom thread 00052 void recvfromMain() { 00053 SocketAddress addr; 00054 uint8_t* recv_buffer = (uint8_t*)malloc(1280); // Suggested is to keep packet size under 1280 bytes 00055 00056 nsapi_size_or_error_t ret; 00057 00058 while ((ret = socket.recvfrom(&addr, recv_buffer, 1280)) >= 0) { 00059 // to see where the message came from, inspect addr.get_addr() and addr.get_port() 00060 00061 printf("Received a message of length '%d'\n", ret); 00062 00063 sn_coap_hdr_s* parsed = sn_coap_parser(coapHandle, ret, recv_buffer, &coapVersion); 00064 00065 // We know the payload is going to be a string 00066 std::string payload((const char*)parsed->payload_ptr, parsed->payload_len); 00067 00068 printf("\tmsg_id: %d\n", parsed->msg_id); 00069 printf("\tmsg_code: %d\n", parsed->msg_code); 00070 printf("\tcontent_format: %d\n", parsed->content_format); 00071 printf("\tpayload_len: %d\n", parsed->payload_len); 00072 printf("\tpayload: %s\n", payload.c_str()); 00073 printf("\toptions_list_ptr: %p\n", parsed->options_list_ptr); 00074 } 00075 00076 free(recv_buffer); 00077 00078 printf("UDPSocket::recvfrom failed, error code %d. Shutting down receive thread.\n", ret); 00079 } 00080 00081 int main() { 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 = "/hello"; 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("coap.me", 5683, message_ptr, message_len); 00130 printf("Sent %d bytes to coap://coap.me:5683\n", scount); 00131 00132 free(coap_res_ptr); 00133 free(message_ptr); 00134 00135 Thread::wait(osWaitForever); 00136 }
Generated on Tue Jul 12 2022 22:01:29 by 1.7.2