Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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