Morse Micro IoT SDK  2.11.2
socket.c
Go to the documentation of this file.
1/*
2 * Copyright 2025 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
19#include "mmconfig.h"
20#include "mmosal.h"
21#include "mmhal_app.h"
22#include "mmipal.h"
23
24#if !defined(MBEDTLS_CONFIG_FILE)
25#include "mbedtls/mbedtls_config.h"
26#else
27#include MBEDTLS_CONFIG_FILE
28#endif
29#include "mbedtls/net.h"
30
31#include "mm_app_common.h"
32#include "mmwlan.h"
33
35#define DEFAULT_TARGET_ADDR "192.168.1.1"
37#define DEFAULT_PORT "1337"
39#define DEFAULT_IP_PROTOCOL MBEDTLS_NET_PROTO_TCP
42#define DEFAULT_IP_PROTOCOL_STR "tcp"
43
45#define DEFAULT_PACKET_COUNT 5
47#define DEFAULT_PACKET_INTERVAL_MS 10000
50#define MAX_DATA_SIZE_BYTES (uint32_t)1500
52#define DEFAULT_DATA_SIZE_BYTES 500
55#define PACKET_DATA_FORMAT "Packet index %ld, len=%ld: "
58#define PACKET_SEND_DURATION_MS 200
60#define CONNECT_MAX_ATTEMPTS 5
61
62#if defined(ENABLE_PWR_MEAS) && ENABLE_PWR_MEAS
64#define PWR_MEAS_DELAY_MS(delay_ms) mmosal_task_sleep(delay_ms)
66#define SET_DEBUG_STATE(state) mmhal_set_debug_pins(MMHAL_ALL_DEBUG_PINS, state);
67#else
68#include "mmutils.h"
70#define PWR_MEAS_DELAY_MS(delay_ms) MM_UNUSED(delay_ms)
72#define SET_DEBUG_STATE(state) MM_UNUSED(state)
73#endif
74
77
84{
107};
108
116int parse_protocol_str(const char *protocol, uint8_t len)
117{
118 if (strncmp("tcp", protocol, len) == 0)
119 {
120 return MBEDTLS_NET_PROTO_TCP;
121 }
122 else if (strncmp("udp", protocol, len) == 0)
123 {
124#if defined(ipconfigUSE_IPv4) || defined(ipconfigUSE_IPv6)
125 printf("WARNING: The FreeRTOS+TCP socket implementation for Mbed TLS dos not currently "
126 "support UDP\n");
127 return -1;
128#endif
129 return MBEDTLS_NET_PROTO_UDP;
130 }
131 return -1;
132}
133
141void generate_packet_data(uint32_t packet_idx, uint32_t len, unsigned char *buf)
142{
143 snprintf(((char *)buf), sizeof(PACKET_DATA_FORMAT), PACKET_DATA_FORMAT, packet_idx, len);
144 for (uint32_t i = sizeof(PACKET_DATA_FORMAT); i < len; i++)
145 {
146 buf[i] = '0' + (i % 10);
147 }
148}
149
154void app_init(void)
155{
157
158 printf("\n\nSockets Example (Built " __DATE__ " " __TIME__ ")\n\n");
159
160 /* Initialize and connect to Wi-Fi, blocks till connected */
162
164
166
168
170
171 /* Delay to allow communications to settle so we measure only idle current */
173
175
176 PWR_MEAS_DELAY_MS(1000);
177
179
180 mbedtls_net_context server_fd;
181 mbedtls_net_init(&server_fd);
182
184
185 uint32_t data_size_bytes = DEFAULT_DATA_SIZE_BYTES;
186 (void)mmconfig_read_uint32("socket.data_size_bytes", &data_size_bytes);
187 if (data_size_bytes > MAX_DATA_SIZE_BYTES)
188 {
189 data_size_bytes = MAX_DATA_SIZE_BYTES;
190 printf("Selected data size (socket.data_size_bytes) too large. Using the maximum of %ld "
191 "instead",
193 }
194
196 enum mmipal_status status = mmipal_get_ip_config(&ip_config);
197 char target_ip[48] = DEFAULT_TARGET_ADDR;
198 if (status == MMIPAL_SUCCESS && ip_config.mode != MMIPAL_DISABLED)
199 {
200 memcpy(target_ip, ip_config.gateway_addr, sizeof(ip_config.gateway_addr));
201 }
202 else
203 {
204 printf("Failed to retrieve IP config\n");
205 }
206 /* If socket.target is set, we use it as an override */
207 (void)mmconfig_read_string("socket.target", target_ip, sizeof(target_ip));
208
209 char target_port[6] = DEFAULT_PORT;
210 (void)mmconfig_read_string("socket.port", target_port, sizeof(target_port));
211
212 int ip_protocol;
213 char protocol_str[4];
214 (void)mmconfig_read_string("socket.protocol", protocol_str, sizeof(protocol_str));
215 if ((ip_protocol = parse_protocol_str(protocol_str, sizeof(protocol_str))) < 0)
216 {
217 ip_protocol = DEFAULT_IP_PROTOCOL;
218 snprintf(protocol_str, sizeof(protocol_str), DEFAULT_IP_PROTOCOL_STR);
219 printf("Failed to parse socket.protocol config. Defaulting to %s\n", protocol_str);
220 }
221
223
224 printf("Connecting to %s server at %s:%s...\n", protocol_str, target_ip, target_port);
225
226 int ret;
227 uint32_t retries = CONNECT_MAX_ATTEMPTS;
228 while ((ret = mbedtls_net_connect(&server_fd, target_ip, target_port, ip_protocol)) &&
229 retries--)
230 {
231 printf("Failed to connect to server. Status: %d\n", ret);
232 }
233 if (ret == 0)
234 {
235 printf("Successfully connected to server.\n");
236 }
237
238 /* Send an empty packet to ensure all ARP activity completes. This prevents the first
239 * packet from taking longer and consuming more power. Wait 2 seconds for network
240 * activity to finish. */
241 mbedtls_net_send(&server_fd, NULL, 0);
242 PWR_MEAS_DELAY_MS(2000);
243
244 uint32_t packet_interval_ms = DEFAULT_PACKET_INTERVAL_MS;
245 uint32_t packet_count = DEFAULT_PACKET_COUNT;
246 mmconfig_read_uint32("socket.packet_interval_ms", &packet_interval_ms);
247 mmconfig_read_uint32("socket.count", &packet_count);
248 MMOSAL_ASSERT(packet_interval_ms >= PACKET_SEND_DURATION_MS);
249 for (uint32_t packet_idx = 0; packet_idx < packet_count; packet_idx++)
250 {
252 generate_packet_data(packet_idx, data_size_bytes, buf);
253 printf("Sending packet number %ld... ", packet_idx);
254 if ((ret = mbedtls_net_send(&server_fd, buf, data_size_bytes)) < 0)
255 {
256 printf("Packet failed to send. Return code: %d\n", ret);
257 }
258 else if ((uint32_t)ret < data_size_bytes)
259 {
260 printf("Packet not fully sent: %d of %ld\n", ret, data_size_bytes);
261 }
262 else
263 {
264 printf("Packet successfully sent\n");
265 }
266#if defined(ENABLE_PWR_MEAS) && ENABLE_PWR_MEAS
268
270
271 PWR_MEAS_DELAY_MS(packet_interval_ms - PACKET_SEND_DURATION_MS);
272#else
273 mmosal_task_sleep(packet_interval_ms);
274#endif
275 }
276
278
279 /* Disconnect from Wi-Fi */
281}
int mmconfig_read_string(const char *key, char *buffer, int bufsize)
Returns the persistent store string value identified by the key.
int mmconfig_read_uint32(const char *key, uint32_t *value)
Returns the unsigned integer stored in persistent store identified by the key.
#define MMIPAL_IP_CONFIG_DEFAULT
Initializer for mmipal_ip_config.
Definition: mmipal.h:107
mmipal_status
Enumeration of status codes returned by MMIPAL functions.
Definition: mmipal.h:43
enum mmipal_status mmipal_get_ip_config(struct mmipal_ip_config *config)
Get the IP configurations.
@ MMIPAL_SUCCESS
Completed successfully.
Definition: mmipal.h:45
@ MMIPAL_DISABLED
Disabled.
Definition: mmipal.h:69
#define MMOSAL_ASSERT(expr)
Assert that the given expression evaluates to true and abort execution if not.
Definition: mmosal.h:1006
void mmosal_task_sleep(uint32_t duration_ms)
Sleep for a period of time, yielding during that time.
Morse Micro application helper routines for initializing/de-initializing the Wireless LAN interface a...
void app_wlan_stop(void)
Disconnects from Wi-Fi and de-initializes the WLAN interface.
void app_wlan_init(void)
Initializes the WLAN interface (and dependencies) using settings specified in the config store.
void app_wlan_start(void)
Starts the WLAN interface and connects to Wi-Fi using settings specified in the config store.
debug_state
Enumeration of debug states that will be reflected on debug pins.
Definition: ping.c:75
#define DEFAULT_DATA_SIZE_BYTES
Default data size for TCP/UDP packets.
Definition: socket.c:52
#define DEFAULT_PACKET_COUNT
Default number of packets to send.
Definition: socket.c:45
#define SET_DEBUG_STATE(state)
Disable GPIO writing if not measuring power consumption.
Definition: socket.c:72
#define DEFAULT_PORT
Default port to use for contacting server.
Definition: socket.c:37
#define MAX_DATA_SIZE_BYTES
Arbitrary maximum data size for TCP/UDP packets.
Definition: socket.c:50
#define PACKET_DATA_FORMAT
Format of string to place at start of TCP/UDP packet.
Definition: socket.c:55
int parse_protocol_str(const char *protocol, uint8_t len)
Parse the protocol from a string to an MBEDTLS protocol integer.
Definition: socket.c:116
#define PACKET_SEND_DURATION_MS
Length of time in ms to wait for packet to send.
Definition: socket.c:58
#define DEFAULT_IP_PROTOCOL_STR
Default protocol in string form.
Definition: socket.c:42
#define PWR_MEAS_DELAY_MS(delay_ms)
Disable delays which are only useful for power consumption accuracy.
Definition: socket.c:70
#define CONNECT_MAX_ATTEMPTS
Number of times to attempt mbedtls connect.
Definition: socket.c:60
#define DEFAULT_PACKET_INTERVAL_MS
Default period between transmissions in ms.
Definition: socket.c:47
#define DEFAULT_IP_PROTOCOL
Default protocol to use as an mbedtls int code.
Definition: socket.c:39
void app_init(void)
Main entry point to the application.
Definition: socket.c:154
uint8_t buf[MAX_DATA_SIZE_BYTES]
Buffer holding UDP/TCP packet data.
Definition: socket.c:76
#define DEFAULT_TARGET_ADDR
Default IP address of target server.
Definition: socket.c:35
@ DEBUG_STATE_INIT
Initial state at startup.
Definition: socket.c:86
@ DEBUG_STATE_MBEDTLS_CONNECTING
Indicates we are connecting to the TCP server on the AP.
Definition: socket.c:99
@ DEBUG_STATE_BOOTING_CHIP
Indicates that we are booting the MM chip (note that this will also include the host MCU startup time...
Definition: socket.c:89
@ DEBUG_STATE_MBEDTLS_SEND
Indicates we are sending a TCP packet to the AP.
Definition: socket.c:101
@ DEBUG_STATE_CONNECTED
Indicates we are connected to the AP.
Definition: socket.c:93
@ DEBUG_STATE_MBEDTLS_SEND_DONE
Indicates we have sent a TCP packet to the AP and are waiting for communications to cool down.
Definition: socket.c:104
@ DEBUG_STATE_MBEDTLS_INIT
Indicates we are initializing the mbedtls client.
Definition: socket.c:97
@ DEBUG_STATE_TERMINATING
Indicates that we are disconnecting from the AP.
Definition: socket.c:106
@ DEBUG_STATE_CONNECTED_IDLE
Indicates that we have connected to the AP, but have not connected to the TCP server.
Definition: socket.c:95
@ DEBUG_STATE_CONNECTING
Indicates we are connecting to the AP.
Definition: socket.c:91
void generate_packet_data(uint32_t packet_idx, uint32_t len, unsigned char *buf)
Handle a report at the end of an iperf transfer.
Definition: socket.c:141
IPv4 configuration structure.
Definition: mmipal.h:95
enum mmipal_addr_mode mode
IP address allocation mode.
Definition: mmipal.h:97
mmipal_ip_addr_t gateway_addr
Gateway address.
Definition: mmipal.h:103