Morse Micro IoT SDK  2.11.2
m2m_controller.c
Go to the documentation of this file.
1/*
2 * Copyright 2024 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
164#include "mmhal_app.h"
165#include "mmhal_core.h"
166#include "mmosal.h"
167#include "mmutils.h"
168#include "mmagic_controller.h"
169
170/* Default SSID */
171#ifndef SSID
173#define SSID MorseMicro
174#endif
175
176/* Default passphrase */
177#ifndef SAE_PASSPHRASE
180#define SAE_PASSPHRASE 12345678
181#endif
182
184#define _STRINGIFY(x) #x
186#define STRINGIFY(x) _STRINGIFY(x)
187
189#define LINK_STATE_TIMEOUT_MS 20000
190
192#define TCP_ECHCO_SERVER_PORT 5000
193
200void agent_start_handler(struct mmagic_controller *controller, void *arg)
201{
202 MM_UNUSED(controller);
203 struct mmosal_semb *started = (struct mmosal_semb *)arg;
204 printf("Agent start notification received\n");
205 mmosal_semb_give(started);
206}
207
209static struct mmosal_semb *agent_started_semb = NULL;
210
219static bool wlan_connect(struct mmagic_controller *controller)
220{
221 printf("\n\n#### Example WLAN Connect using MMAGIC Controller ####\n\n");
222 enum mmagic_status status;
223
224 printf("Attempting to connect to %s with passphrase %s\n", STRINGIFY(SSID),
226 printf("This may take some time (~10 seconds)\n");
227 status = mmagic_controller_set_wlan_ssid(controller, STRINGIFY(SSID));
228 if (status != MMAGIC_STATUS_OK)
229 {
230 printf("Error %d setting the wlan ssid\n", status);
231 return false;
232 }
233
235 if (status != MMAGIC_STATUS_OK)
236 {
237 printf("Error %d setting the wlan password\n", status);
238 return false;
239 }
240
241 struct mmagic_core_wlan_connect_cmd_args connect_args = {
242 .timeout = 120000,
243 };
244 status = mmagic_controller_wlan_connect(controller, &connect_args);
245 if (status != MMAGIC_STATUS_OK)
246 {
247 printf("Error %d after sending the connect command\n", status);
248 return false;
249 }
250
251 struct mmagic_core_ip_status_rsp_args ip_status_rsp_args = {};
252 uint32_t timeout = mmosal_get_time_ms() + LINK_STATE_TIMEOUT_MS;
253 while (mmosal_time_lt(mmosal_get_time_ms(), timeout))
254 {
255 status = mmagic_controller_ip_status(controller, &ip_status_rsp_args);
256 if ((status == MMAGIC_STATUS_OK) &&
257 (ip_status_rsp_args.status.link_state == MMAGIC_IP_LINK_STATE_UP))
258 {
259 printf("Link Up\n");
260 printf("Link is up %s. Time: %lu ms, ",
261 ip_status_rsp_args.status.dhcp_enabled ? "(DHCP)" : "(Static)",
263 printf("IP: %s, ", ip_status_rsp_args.status.ip_addr.addr);
264 printf("Netmask: %s, ", ip_status_rsp_args.status.netmask.addr);
265 printf("Gateway: %s", ip_status_rsp_args.status.gateway.addr);
266 printf("\n");
267 return true;
268 }
270 }
271
272 return false;
273}
274
283static bool is_wlan_connected(struct mmagic_controller *controller)
284{
286 printf("\n\n#### Example check WLAN connection using MMAGIC Controller ####\n\n");
288
289 printf("Checking SSID and password match expected values\n");
290 struct string32 agent_ssid = {};
291 const size_t ssid_len = sizeof(STRINGIFY(SSID)) - 1;
292 status = mmagic_controller_get_wlan_ssid(controller, &agent_ssid);
293 if (status != MMAGIC_STATUS_OK)
294 {
295 printf("Error %d getting the wlan ssid\n", status);
296 return false;
297 }
298 if ((ssid_len != agent_ssid.len) || memcmp(agent_ssid.data, STRINGIFY(SSID), ssid_len + 1))
299 {
300 printf("SSID mismatch\n");
301 return false;
302 }
303
304 struct string100 agent_pwd = {};
305 const size_t pwd_len = sizeof(STRINGIFY(SAE_PASSPHRASE)) - 1;
306 status = mmagic_controller_get_wlan_password(controller, &agent_pwd);
307 if (status != MMAGIC_STATUS_OK)
308 {
309 printf("Error %d getting the wlan password\n", status);
310 return false;
311 }
312 if ((pwd_len != agent_pwd.len) || memcmp(agent_pwd.data, STRINGIFY(SAE_PASSPHRASE),
313 pwd_len + 1))
314 {
315 printf("Password mismatch\n");
316 return false;
317 }
318
319 printf("Checking STA connection status\n");
320 struct mmagic_core_wlan_get_sta_status_rsp_args rsp_args = {};
321 status = mmagic_controller_wlan_get_sta_status(controller, &rsp_args);
322 if (status != MMAGIC_STATUS_OK)
323 {
324 printf("Error %d getting wlan sta status\n", status);
325 return false;
326 }
327 if (rsp_args.sta_status != MMAGIC_STA_STATE_CONNECTED)
328 {
329 printf("STA not connected\n");
330 return false;
331 }
332
333 printf("Checking link status\n");
334 struct mmagic_core_ip_status_rsp_args ip_status_rsp_args = {};
335 for (int attempts = 2; attempts > 0; --attempts)
336 {
337 status = mmagic_controller_ip_status(controller, &ip_status_rsp_args);
338 if ((status == MMAGIC_STATUS_OK) &&
339 (ip_status_rsp_args.status.link_state == MMAGIC_IP_LINK_STATE_UP))
340 {
341 printf("Link is up %s. Time: %lu ms, ",
342 ip_status_rsp_args.status.dhcp_enabled ? "(DHCP)" : "(Static)",
344 printf("IP: %s, ", ip_status_rsp_args.status.ip_addr.addr);
345 printf("Netmask: %s, ", ip_status_rsp_args.status.netmask.addr);
346 printf("Gateway: %s", ip_status_rsp_args.status.gateway.addr);
347 printf("\n");
348 return true;
349 }
351 }
352
353 printf("Link Down\n");
354 return false;
355}
356
361{
363 struct mmagic_controller *controller;
365 uint8_t stream_id;
366};
367
375 const struct mmagic_wlan_beacon_rx_event_args *args, void *arg)
376{
377 uint32_t offset = 0;
378
379 MM_UNUSED(arg);
380
381 while (offset < args->vendor_ies.len)
382 {
383 uint8_t ie_type;
384 uint8_t ie_len;
385 uint32_t ii;
386
387 if (offset + 2 > args->vendor_ies.len)
388 {
389 printf("Beacon IEs malformed!\n");
390 break;
391 }
392
393 ie_type = args->vendor_ies.data[offset];
394 ie_len = args->vendor_ies.data[offset + 1];
395
396 offset += 2;
397
398 if (offset + ie_len > args->vendor_ies.len)
399 {
400 printf("Beacon IEs malformed!\n");
401 break;
402 }
403
404 printf(" IE type 0x%02x, IE len 0x%02x, Contents: ", ie_type, ie_len);
405 for (ii = 0; ii < ie_len; ii++)
406 {
407 printf("%02x", args->vendor_ies.data[offset++]);
408 }
409 printf("\n");
410 }
411}
412
420static void beacon_monitor_example_start(struct mmagic_controller *controller)
421{
422 enum mmagic_status status;
423
424 printf("\n\n#### Example Beacon Monitor using MMAGIC Controller ####\n\n");
425
426 struct mmagic_core_wlan_beacon_monitor_enable_cmd_args beacon_monitor_args = {
427 /* OUI for default Microsoft WMN/WME IE */
428 .oui_filter = {.count = 1, .ouis = { { { 0x00, 0x50, 0xF2 } } }}
429 };
430
432
433 status = mmagic_controller_wlan_beacon_monitor_enable(controller, &beacon_monitor_args);
434 if (status != MMAGIC_STATUS_OK)
435 {
436 printf("Error %d enabling beacon monitor\n", status);
437 return;
438 }
439 printf("Enabled beacon monitor for OUI %02x:%02x:%02x\n",
440 beacon_monitor_args.oui_filter.ouis[0].oui[0],
441 beacon_monitor_args.oui_filter.ouis[0].oui[1],
442 beacon_monitor_args.oui_filter.ouis[0].oui[2]);
443}
444
453static void tcp_client_example(struct mmagic_controller *controller,
454 struct mmosal_semb *rx_ready_semb)
455{
456 printf("\n\n#### Example TCP Client using MMAGIC Controller ####\n\n");
457 enum mmagic_status status;
458
459 struct mmagic_core_socket_connect_cmd_args tcp_connect_args = {
460 .url = {.data = "google.com", .len = strlen("google.com")},
461 .port = 80,
462 .protocol = MMAGIC_SOCKET_PROTO_TCP,
463 };
464 struct mmagic_core_socket_connect_rsp_args tcp_rsp_args = {};
465 status = mmagic_controller_socket_connect(controller, &tcp_connect_args, &tcp_rsp_args);
466 if (status != MMAGIC_STATUS_OK)
467 {
468 printf("Error %d establishing TCP connection\n", status);
469 MMOSAL_ASSERT(false);
470 }
471 uint8_t tcp_stream_id = tcp_rsp_args.stream_id;
472 printf("Opened TCP socket on stream_id %u\n", tcp_stream_id);
473
475 .stream_id = tcp_stream_id,
476 .enabled = true,
477 };
478 status = mmagic_controller_socket_set_rx_ready_evt_enabled(controller, &args);
479 bool rx_ready_event_enabled = false;
480 if (status == MMAGIC_STATUS_OK)
481 {
482 rx_ready_event_enabled = true;
483 }
484 else if (status == MMAGIC_STATUS_NOT_SUPPORTED)
485 {
486 printf("RX ready event not supported.\n");
487 }
488 else
489 {
490 printf("Error %d enabling rx ready event\n", status);
491 }
492
493 struct mmagic_core_socket_send_cmd_args tcp_send_cmd_args = {
494 .stream_id = tcp_stream_id,
495 .buffer = {.data = "GET /\n\n", .len = strlen("GET /\n\n")}
496 };
497 status = mmagic_controller_socket_send(controller, &tcp_send_cmd_args);
498 if (status != MMAGIC_STATUS_OK)
499 {
500 printf("Error %d whilst sending data\n", status);
501 MMOSAL_ASSERT(false);
502 }
503 printf("Successfully sent GET request\n");
504
505 if (rx_ready_event_enabled)
506 {
507 printf("Waiting for RX ready event...\n");
508 mmosal_semb_wait(rx_ready_semb, UINT32_MAX);
509 }
510
511 struct mmagic_core_socket_recv_cmd_args tcp_recv_cmd_args = {
512 .stream_id = tcp_stream_id,
513 .len = 1536,
514 .timeout = 5000,
515 };
516 struct mmagic_core_socket_recv_rsp_args tcp_recv_rsp_args = {};
517 status = mmagic_controller_socket_recv(controller, &tcp_recv_cmd_args, &tcp_recv_rsp_args);
518 if (status != MMAGIC_STATUS_OK)
519 {
520 printf("Error %d whilst receiving data\n", status);
521 }
522 else
523 {
524 printf("Received: %.12s, Length %u\n", tcp_recv_rsp_args.buffer.data,
525 tcp_recv_rsp_args.buffer.len);
526 }
527
528 struct mmagic_core_socket_close_cmd_args tcp_close_cmd_args = {.stream_id = tcp_stream_id};
529 status = mmagic_controller_socket_close(controller, &tcp_close_cmd_args);
530 if (status != MMAGIC_STATUS_OK)
531 {
532 printf("Error %d whilst closing tcp socket\n", status);
533 MMOSAL_ASSERT(false);
534 }
535 printf("Closed TCP Socket\n");
536}
537
542{
544 struct mmagic_controller *controller;
546 uint8_t stream_id;
547};
548
554static void tcp_echo_server_task(void *args)
555{
556 enum mmagic_status status;
557 struct tcp_echo_server_thread_args *thread_args =
558 (struct tcp_echo_server_thread_args *)args;
559 struct mmagic_controller *controller = thread_args->controller;
560 uint8_t stream_id = thread_args->stream_id;
561
562 printf("Accepted a TCP connection on stream_id %u\n", stream_id);
563
564 struct mmagic_core_socket_recv_cmd_args tcp_recv_cmd_args = {
566 .len = 1536,
567 .timeout = 1000,
568 };
569 struct mmagic_core_socket_recv_rsp_args tcp_recv_rsp_args = {};
570 struct mmagic_core_socket_send_cmd_args tcp_send_cmd_args =
571 {
573 };
574
575 while (true)
576 {
577 status = mmagic_controller_socket_recv(controller, &tcp_recv_cmd_args, &tcp_recv_rsp_args);
578 if (status == MMAGIC_STATUS_TIMEOUT)
579 {
580 continue;
581 }
582 else if (status == MMAGIC_STATUS_CLOSED)
583 {
584 printf("Connection closed by the other side!\n");
585 break;
586 }
587 else if (status != MMAGIC_STATUS_OK)
588 {
589 printf("Error %d whilst receiving data\n", status);
590 break;
591 }
592 printf("Received: %d bytes, echoing.\n", tcp_recv_rsp_args.buffer.len);
593
594 memcpy(tcp_send_cmd_args.buffer.data, tcp_recv_rsp_args.buffer.data,
595 tcp_recv_rsp_args.buffer.len);
596 tcp_send_cmd_args.buffer.len = tcp_recv_rsp_args.buffer.len;
597 status = mmagic_controller_socket_send(controller, &tcp_send_cmd_args);
598 if (status != MMAGIC_STATUS_OK)
599 {
600 printf("Error %d whilst sending data\n", status);
601 break;
602 }
603 }
604
605 struct mmagic_core_socket_close_cmd_args tcp_close_cmd_args =
606 {
608 };
609 status = mmagic_controller_socket_close(controller, &tcp_close_cmd_args);
610 if (status != MMAGIC_STATUS_OK)
611 {
612 printf("Error %u whilst trying to close the TCP socket on stream_id %u\n",
613 status, stream_id);
614 }
615 printf("Closed TCP socket\n");
616}
617
627static enum mmagic_status tcp_echo_server_start(struct mmagic_controller *controller, uint16_t port)
628{
629 printf("\n\n#### Example TCP Echo Server using MMAGIC Controller ####\n\n");
630 enum mmagic_status status;
631 static struct tcp_echo_server_thread_args thread_args;
632
633 struct mmagic_core_socket_bind_cmd_args tcp_bind_cmd_args = {.port = port, .protocol = MMAGIC_SOCKET_PROTO_TCP};
634 struct mmagic_core_socket_bind_rsp_args tcp_bind_rsp_args = {};
635 status = mmagic_controller_socket_bind(controller, &tcp_bind_cmd_args, &tcp_bind_rsp_args);
636 if (status != MMAGIC_STATUS_OK)
637 {
638 printf("Error %u whilst opening the tcp socket\n", status);
639 return status;
640 }
641 uint8_t tcp_socket_stream_id = tcp_bind_rsp_args.stream_id;
642 printf("Opened listening socket (Port %u) on stream_id %u\n",
643 tcp_bind_cmd_args.port, tcp_socket_stream_id);
644
645 struct mmagic_core_socket_accept_cmd_args tcp_accept_cmd_args = {
646 .stream_id = tcp_socket_stream_id
647 };
648 struct mmagic_core_socket_accept_rsp_args tcp_accept_rsp_args = {};
649 while (true)
650 {
651 status = mmagic_controller_socket_accept(controller,
652 &tcp_accept_cmd_args,
653 &tcp_accept_rsp_args);
654 if (status != MMAGIC_STATUS_OK)
655 {
656 printf("Error %u whilst trying to accept a TCP connection\n", status);
657 break;
658 }
659
660 thread_args.stream_id = tcp_accept_rsp_args.stream_id;
661 thread_args.controller = controller;
662
664 MMOSAL_TASK_PRI_LOW, 2048, "tcp_echo_server_task");
665 }
666
667 struct mmagic_core_socket_close_cmd_args tcp_close_cmd_args =
668 {
669 .stream_id = tcp_socket_stream_id
670 };
671 status = mmagic_controller_socket_close(controller, &tcp_close_cmd_args);
672 if (status != MMAGIC_STATUS_OK)
673 {
674 printf("Error %u whilst trying to close the listening socket on stream_id %u\n",
675 status, tcp_socket_stream_id);
676 }
677 else
678 {
679 printf("Closed listening socket\n");
680 }
681 return status;
682}
683
691 const struct mmagic_socket_rx_ready_event_args *event_args,
692 void *arg)
693{
694 MM_UNUSED(event_args);
695 printf("Socket RX ready event\n");
696 struct mmosal_semb *rx_ready_semb = (struct mmosal_semb *)arg;
697 mmosal_semb_give(rx_ready_semb);
698}
699
705static void run_examples_task(void *args)
706{
707 MM_UNUSED(args);
708
709 agent_started_semb = mmosal_semb_create("agent_started");
712 init_args.agent_start_arg = (void *)agent_started_semb;
713
714 struct mmagic_controller *controller = mmagic_controller_init(&init_args);
715
716 enum {
717 AGENT_ACTION_TIMEOUT_MS = 1000,
718 };
719
720 bool agent_already_running = false;
721 enum mmagic_status status;
722 printf("M2M Controller enabled. Awaiting Agent start\n");
723 if (mmosal_semb_wait(agent_started_semb, AGENT_ACTION_TIMEOUT_MS))
724 {
725 goto agent_started;
726 }
727
728 printf("No agent start notification, agent may already be running.\n");
729 printf("Attempting sync to recover connection.\n");
730 status = mmagic_controller_agent_sync(controller, AGENT_ACTION_TIMEOUT_MS);
731 if (status == MMAGIC_STATUS_OK)
732 {
733 agent_already_running = true;
734 /* Check for existing connection */
735 if (is_wlan_connected(controller))
736 {
737 printf("WLAN connection reattached\n");
738 goto agent_connected;
739 }
740 goto agent_started;
741 }
742
743 printf("Sync failed with status %d, attempting LLC agent reset.\n", status);
744 status = mmagic_controller_request_agent_reset(controller);
745 if (mmosal_semb_wait(agent_started_semb, AGENT_ACTION_TIMEOUT_MS))
746 {
747 goto agent_started;
748 }
749
750 printf("LLC reset failed with status %d. Please hard reset the agent.\n", status);
752
753agent_started:
754 struct mmagic_core_sys_get_version_rsp_args version_rsp = {};
755 status = mmagic_controller_sys_get_version(controller, &version_rsp);
756 if (status != MMAGIC_STATUS_OK)
757 {
758 printf("Get version failed with status %d\n", status);
759 return;
760 }
761
762 printf("-----------------------------------\n");
763 printf("Morselib version: %s\n", version_rsp.results.morselib_version.data);
764 printf("Morse firmware version: %s\n", version_rsp.results.morse_firmware_version.data);
765 printf("Application version: %s\n", version_rsp.results.application_version.data);
766 printf("User Hardware version: %s\n", version_rsp.results.user_hardware_version.data);
767 printf("Morse HW version: %s\n", version_rsp.results.morse_hardware_version.data);
768 printf("-----------------------------------\n");
769
770 if (!wlan_connect(controller))
771 {
772 printf("Failed to connect\n");
773 return;
774 }
775 printf("WLAN connection established\n");
776
777agent_connected:
779
780 struct mmosal_semb *rx_ready_semb = mmosal_semb_create("rxready");
781 MMOSAL_ASSERT(rx_ready_semb != NULL);
783
784 tcp_client_example(controller, rx_ready_semb);
785
786 status = tcp_echo_server_start(controller, TCP_ECHCO_SERVER_PORT);
787 if ((status == MMAGIC_STATUS_SOCKET_LISTEN_FAILED) && agent_already_running)
788 {
789 /* Socket may already be open from previous run, try another port */
790 status = tcp_echo_server_start(controller, TCP_ECHCO_SERVER_PORT + mmhal_random_u32(1, 10));
791 printf("TCP echo server ended with status %d\n", status);
792 }
793}
794
799void app_init(void)
800{
801 printf("\n\nM2M Controller Example (Built " __DATE__ " " __TIME__ ")\n\n");
802
803 /* Keep controller awake for now */
805
806 /* Run the examples in a different task to cater for the higher stack size requirements */
808 MMOSAL_TASK_PRI_LOW, 2048, "run_examples_task");
809}
enum MM_PACKED mmagic_status
Enumeration of return status codes.
struct mmagic_controller * mmagic_controller_init(const struct mmagic_controller_init_args *args)
Initialize the Controller.
#define MMAGIC_CONTROLLER_ARGS_INIT
Initializer for mmagic_controller_init_args.
enum mmagic_status mmagic_controller_agent_sync(struct mmagic_controller *controller, uint32_t timeout_ms)
Sends a sync request to the agent and waits for a sync response.
enum mmagic_status mmagic_controller_request_agent_reset(struct mmagic_controller *controller)
Sends a reset request to the agent.
static enum mmagic_status mmagic_controller_ip_status(struct mmagic_controller *controller, struct mmagic_core_ip_status_rsp_args *rsp_args)
Gets the status of the IP stack.
static enum mmagic_status mmagic_controller_socket_connect(struct mmagic_controller *controller, struct mmagic_core_socket_connect_cmd_args *cmd_args, struct mmagic_core_socket_connect_rsp_args *rsp_args)
Opens a client socket and returns its stream ID.
static enum mmagic_status mmagic_controller_socket_recv(struct mmagic_controller *controller, struct mmagic_core_socket_recv_cmd_args *cmd_args, struct mmagic_core_socket_recv_rsp_args *rsp_args)
Reads from a socket.
void mmagic_controller_register_socket_rx_ready_handler(struct mmagic_controller *controller, mmagic_socket_rx_ready_event_handler_t handler, void *arg)
Register a handler for the socket-rx_ready event.
static enum mmagic_status mmagic_controller_socket_close(struct mmagic_controller *controller, struct mmagic_core_socket_close_cmd_args *cmd_args)
Closes and frees the socket.
static enum mmagic_status mmagic_controller_socket_set_rx_ready_evt_enabled(struct mmagic_controller *controller, struct mmagic_core_socket_set_rx_ready_evt_enabled_cmd_args *cmd_args)
Sets whether the RX ready event should be enabled for the given socket.
static enum mmagic_status mmagic_controller_socket_accept(struct mmagic_controller *controller, struct mmagic_core_socket_accept_cmd_args *cmd_args, struct mmagic_core_socket_accept_rsp_args *rsp_args)
Waits for an incoming socket connection and returns a new stream ID.
static enum mmagic_status mmagic_controller_socket_send(struct mmagic_controller *controller, struct mmagic_core_socket_send_cmd_args *cmd_args)
Writes to a socket.
static enum mmagic_status mmagic_controller_socket_bind(struct mmagic_controller *controller, struct mmagic_core_socket_bind_cmd_args *cmd_args, struct mmagic_core_socket_bind_rsp_args *rsp_args)
Opens a server socket and returns its stream ID.
static enum mmagic_status mmagic_controller_sys_get_version(struct mmagic_controller *controller, struct mmagic_core_sys_get_version_rsp_args *rsp_args)
Gets the device firmware and hardware versions.
static enum mmagic_status mmagic_controller_set_wlan_ssid(struct mmagic_controller *controller, const char *var)
Sets ssid setting for module wlan.
static enum mmagic_status mmagic_controller_set_wlan_password(struct mmagic_controller *controller, const char *var)
Sets password setting for module wlan.
static enum mmagic_status mmagic_controller_get_wlan_ssid(struct mmagic_controller *controller, struct string32 *var)
Gets ssid setting for module wlan.
static enum mmagic_status mmagic_controller_get_wlan_password(struct mmagic_controller *controller, struct string100 *var)
Gets password setting for module wlan.
static enum mmagic_status mmagic_controller_wlan_beacon_monitor_enable(struct mmagic_controller *controller, struct mmagic_core_wlan_beacon_monitor_enable_cmd_args *cmd_args)
Enable beacon monitoring with the given filter settings.
static enum mmagic_status mmagic_controller_wlan_get_sta_status(struct mmagic_controller *controller, struct mmagic_core_wlan_get_sta_status_rsp_args *rsp_args)
Retrieves the STA status of the WLAN interface.
void mmagic_controller_register_wlan_beacon_rx_handler(struct mmagic_controller *controller, mmagic_wlan_beacon_rx_event_handler_t handler, void *arg)
Register a handler for the wlan-beacon_rx event.
static enum mmagic_status mmagic_controller_wlan_connect(struct mmagic_controller *controller, struct mmagic_core_wlan_connect_cmd_args *cmd_args)
Brings up the WLAN interface and connects to the AP with configured parameters.
void mmhal_set_deep_sleep_veto(uint8_t veto_id)
Sets a deep sleep veto that will prevent the device from entering deep sleep.
uint32_t mmhal_random_u32(uint32_t min, uint32_t max)
Generate a random 32 bit integer within the given range.
@ MMHAL_VETO_ID_APP_MIN
Start of deep sleep veto ID range that is available for application use.
Definition: mmhal_core.h:41
#define MMOSAL_ASSERT(expr)
Assert that the given expression evaluates to true and abort execution if not.
Definition: mmosal.h:1006
bool mmosal_semb_wait(struct mmosal_semb *semb, uint32_t timeout_ms)
Wait for a counting semaphore.
struct mmosal_semb * mmosal_semb_create(const char *name)
Create a new binary semaphore.
bool mmosal_semb_give(struct mmosal_semb *semb)
Give a binary semaphore.
struct mmosal_task * mmosal_task_create(mmosal_task_fn_t task_fn, void *argument, enum mmosal_task_priority priority, unsigned stack_size_u32, const char *name)
Create a new task.
void mmosal_task_sleep(uint32_t duration_ms)
Sleep for a period of time, yielding during that time.
@ MMOSAL_TASK_PRI_LOW
Low priority.
Definition: mmosal.h:256
uint32_t mmosal_get_time_ms(void)
Get the system time in milliseconds.
static bool mmosal_time_lt(uint32_t a, uint32_t b)
Check if time a is less than time b, taking into account wrapping.
Definition: mmosal.h:737
#define MM_UNUSED(_x)
Casts the given expression to void to avoid "unused" warnings from the compiler.
Definition: mmutils.h:70
static void tcp_echo_server_task(void *args)
This task handles a single incoming TCP connection.
static void run_examples_task(void *args)
Runs the examples.
static struct mmosal_semb * agent_started_semb
Binary semaphore used to indicate when an agent start notification has been received.
static bool wlan_connect(struct mmagic_controller *controller)
This function illustrates how to establish a wlan connection using the mmagic_controller interface.
#define TCP_ECHCO_SERVER_PORT
Port the the TCP echo server will bind to.
void beacon_monitor_rx_handler(const struct mmagic_wlan_beacon_rx_event_args *args, void *arg)
Handler for the beacon monitor event handler callback.
static enum mmagic_status tcp_echo_server_start(struct mmagic_controller *controller, uint16_t port)
This function illustrates how to start a TCP server and listen for a connection.
#define STRINGIFY(x)
Convert the content of the given macro to a string.
#define SAE_PASSPHRASE
Passphrase of the AP (ignored if security type is not SAE).
static bool is_wlan_connected(struct mmagic_controller *controller)
This function illustrates how to check if the agent already has an active connection.
#define LINK_STATE_TIMEOUT_MS
Duration to wait for the link to be established after WLAN reports connected.
#define SSID
SSID of the AP to connect to.
static void socket_rx_ready_event_handler(const struct mmagic_socket_rx_ready_event_args *event_args, void *arg)
Handler for data receive ready event callback.
void app_init(void)
Main entry point to the application.
void agent_start_handler(struct mmagic_controller *controller, void *arg)
Handler for the "Agent start" callback.
static void tcp_client_example(struct mmagic_controller *controller, struct mmosal_semb *rx_ready_semb)
This function illustrates how to open a tcp client, send and receive some data and close the connecti...
static void beacon_monitor_example_start(struct mmagic_controller *controller)
This function illustrates how to subscribe to and receive custom vendor IEs from beacons.
Arguments for beacon monitor task.
uint8_t stream_id
The stream ID.
struct mmagic_controller * controller
The controller reference.
Initialization structure for mmagic_controller.
mmagic_controller_agent_start_cb_t agent_start_cb
Callback function to executed any time a event that the agent has started is received.
void * agent_start_arg
User argument that will be passed when the agent_start_cb is executed.
Response arguments structure for ip_status.
struct struct_ip_status status
Reference to the struct to return the IP status retrieved from the network stack.
Command arguments structure for socket_accept.
uint8_t stream_id
Stream ID of the bound socket.
Response arguments structure for socket_accept.
uint8_t stream_id
Stream ID of the new incoming connection.
Command arguments structure for socket_bind.
uint16_t port
Port to listen on.
Response arguments structure for socket_bind.
uint8_t stream_id
Stream ID of the opened socket.
Command arguments structure for socket_close.
uint8_t stream_id
Stream ID of the socket to close.
Command arguments structure for socket_connect.
struct string254 url
URL of the server to connect to.
Response arguments structure for socket_connect.
uint8_t stream_id
Stream ID of the opened socket.
Command arguments structure for socket_recv.
uint8_t stream_id
Stream ID of the socket to receive from.
Response arguments structure for socket_recv.
struct raw1536 buffer
Buffer of read data.
Command arguments structure for socket_send.
struct raw1536 buffer
Buffer to send.
uint8_t stream_id
Stream ID of the socket to send on.
Command arguments structure for socket_set_rx_ready_evt_enabled.
uint8_t stream_id
Stream ID of the socket to close.
Response arguments structure for sys_get_version.
struct struct_version_info results
Reference to structure to store the version information.
Command arguments structure for wlan_beacon_monitor_enable.
struct struct_oui_list oui_filter
OUIs to monitor.
Command arguments structure for wlan_connect.
uint32_t timeout
Duration in milliseconds to wait for connection establish, if connection does not get established an ...
Response arguments structure for wlan_get_sta_status.
enum mmagic_sta_state sta_status
The current STA status.
Event arguments structure for socket_rx_ready.
Event arguments structure for wlan_beacon_rx.
struct raw1536 vendor_ies
Raw octet string of Vendor Information Elements contained in the beacon.
uint8_t data[1536]
The actual data buffer.
uint16_t len
Length of data.
String type with maximum length of 100 (excluding null terminator).
uint8_t len
Length of string contents (excluding null terminator).
char data[100+1]
The string contents.
char data[254+1]
The string contents.
String type with maximum length of 32 (excluding null terminator).
uint8_t len
Length of string contents (excluding null terminator).
char data[32+1]
The string contents.
char addr[48]
Array containing the IP string.
struct struct_ip_addr netmask
Current IP network mask.
struct struct_ip_addr ip_addr
Current IP address.
bool dhcp_enabled
Whether or not dhcp is enabled.
enum mmagic_ip_link_state link_state
Current link state.
struct struct_ip_addr gateway
Current IP gateway.
struct struct_oui ouis[5]
The OUI data.
uint8_t count
The number of OUIs in the list.
uint8_t oui[3]
The 3 octet OUI.
struct string32 application_version
Version of the application software.
struct string32 morse_hardware_version
Version of the Morse hardware.
struct string32 user_hardware_version
Version of the user hardware.
struct string32 morse_firmware_version
Version of the Morse firmware.
struct string32 morselib_version
Version of the Morse IoT SDK library.
Arguments for TCP echo server task.
uint8_t stream_id
The stream ID.
struct mmagic_controller * controller
The controller reference.