Morse Micro IoT SDK  2.9.7
rf-test.c
Go to the documentation of this file.
1/*
2 * Copyright 2024 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
19#include <endian.h>
20#include <string.h>
21#include "mmbuf.h"
22#include "mmcrc.h"
23#include "mmhal.h"
24#include "mmhal_uart.h"
25#include "mmosal.h"
26#include "mmutils.h"
27#include "mmwlan.h"
28#include "mm_app_common.h"
29#include "slip.h"
30
32#define SEQ_NUM_LEN (4)
34#define COMMAND_MAX_LEN (252)
36#define RESPONSE_MAX_LEN (2048)
38#define RESPONSE_HDR_LEN (12)
39
48static int slip_tx_handler(uint8_t c, void *arg)
49{
50 MM_UNUSED(arg);
51 mmhal_uart_tx(&c, 1);
52 return 0;
53}
54
60static void rf_test_handle_command(struct mmbuf *cmd_buf)
61{
62 uint8_t *seq_num;
63 struct mmbuf *rsp_buf = NULL;
64 uint32_t response_len;
65 enum mmwlan_status status;
66 int ret;
67 uint16_t crc;
68
69 seq_num = mmbuf_remove_from_end(cmd_buf, SEQ_NUM_LEN);
70 if (seq_num == NULL)
71 {
72 printf("Received command packet too short\n");
73 goto exit;
74 }
75
77
78 /*
79 * `response_len` is initialized to the size of the response buffer before
80 * `mmwlan_ate_execute_command()` is invoked and will be set to the actual length of the
81 * response on success
82 */
83 response_len = RESPONSE_MAX_LEN;
84
85 printf("Executing command...\n");
88 mmbuf_append(rsp_buf, 0), &response_len);
89
90 if (status == MMWLAN_SUCCESS)
91 {
92 (void)mmbuf_append(rsp_buf, response_len);
93 printf("Command executed successfully. Sending response...\n");
94 }
95 else
96 {
97 uint8_t *hdr;
98 uint8_t result_code[4] = {};
99
100 printf("Failed to execute command. Status code %d\n", status);
101
102 switch (status)
103 {
104 case MMWLAN_NO_MEM:
105 result_code[0] = MM_ENOMEM;
106 break;
107
109 result_code[0] = MM_ENODEV;
110 break;
111
113 result_code[0] = MM_EINVAL;
114 break;
115
116 case MMWLAN_TIMED_OUT:
117 result_code[0] = MM_ETIMEDOUT;
118 break;
119
120 default:
121 result_code[0] = MM_EFAULT;
122 break;
123 }
124
125 /* Craft a response with an errno based error code in the response buffer. */
126 hdr = mmbuf_append(rsp_buf, RESPONSE_HDR_LEN);
127 memset(hdr, 0, RESPONSE_HDR_LEN);
128 mmbuf_append_data(rsp_buf, result_code, sizeof(result_code));
129 }
130
131 mmbuf_append_data(rsp_buf, seq_num, SEQ_NUM_LEN);
132 crc = htole16(mmcrc_16_xmodem(0, mmbuf_get_data_start(rsp_buf),
133 mmbuf_get_data_length(rsp_buf)));
134 mmbuf_append_data(rsp_buf, (uint8_t*)&crc, sizeof(crc));
135
136 ret = slip_tx(slip_tx_handler, NULL,
138 if (ret != 0)
139 {
140 printf("Failed to send response (%d)\n", ret);
141 }
142 else
143 {
144 printf("Response sent\n");
145 }
146exit:
147 mmbuf_release(cmd_buf);
148 mmbuf_release(rsp_buf);
149}
150
158static void uart_rx_handler(const uint8_t *data, size_t length, void *arg)
159{
160 size_t ii;
161 enum slip_rx_status status;
162 struct slip_rx_state *slip_state = (struct slip_rx_state *)arg;
163
164 for (ii = 0; ii < length; ii++)
165 {
166 status = slip_rx(slip_state, data[ii]);
167 if (status == SLIP_RX_COMPLETE)
168 {
169 uint16_t crc;
170
171 if (slip_state->length < sizeof(uint16_t))
172 {
173 printf("Received command packet too short. Ignoring...\n");
174 continue;
175 }
176
177 crc = mmcrc_16_xmodem(0, slip_state->buffer, slip_state->length - sizeof(uint16_t));
178 if ((slip_state->buffer[slip_state->length - 2] == (crc & 0xFF)) &&
179 (slip_state->buffer[slip_state->length - 1] == (crc >> 8)))
180 {
181 /* CRC matches, so allocate an mmbuf and pass to command handler function. */
182 struct mmbuf* mmbuffer = mmbuf_alloc_on_heap(0, slip_state->length);
183 if (mmbuffer == NULL)
184 {
185 /* Insufficient memory to receive packet */
186 slip_state->length = 0;
187 printf("Error: memory allocation failure\n");
188 continue;
189 }
190 mmbuf_append_data(mmbuffer, slip_state->buffer,
191 slip_state->length);
192 mmbuf_remove_from_end(mmbuffer, sizeof(uint16_t));
193 rf_test_handle_command(mmbuffer);
194 }
195 else
196 {
197 printf("CRC validation failure\n");
198 }
199 slip_state->length = 0;
200 }
201 }
202}
203
204
210
215void app_init(void)
216{
217 /* RF-test application does not need to worry about power saving. Take a deep sleep
218 * veto and never release it so that we do not enter deep sleep. */
220
221 printf("\n\nRF Test Application (Built "__DATE__ " " __TIME__ ")\n\n");
222
224
225 /* Explicitly prevent the Morse Micro chip from entering it's power save state during rf-test
226 * operations. */
228
230}
static uint8_t * mmbuf_append(struct mmbuf *mmbuf, uint32_t len)
Reserves space immediately after the data currently in the given mmbuf and returns a pointer to this ...
Definition: mmbuf.h:238
static uint32_t mmbuf_get_data_length(struct mmbuf *mmbuf)
Gets the length of the data currently in the mmbuf.
Definition: mmbuf.h:158
static uint8_t * mmbuf_remove_from_end(struct mmbuf *mmbuf, uint32_t len)
Remove data from the end of the mmbuf.
Definition: mmbuf.h:294
struct mmbuf * mmbuf_alloc_on_heap(uint32_t space_at_start, uint32_t space_at_end)
Allocate a new mmbuf on the heap (using mmosal_malloc()).
void mmbuf_release(struct mmbuf *mmbuf)
Release a reference to the given mmbuf.
static void mmbuf_append_data(struct mmbuf *mmbuf, const uint8_t *data, uint32_t len)
Appends the given data to the data already in the mmbuf.
Definition: mmbuf.h:255
static uint8_t * mmbuf_get_data_start(struct mmbuf *mmbuf)
Gets a pointer to the start of the data in the mmbuf.
Definition: mmbuf.h:133
uint16_t mmcrc_16_xmodem(uint16_t crc, const void *data, size_t data_len)
Compute the CRC-16 for the data buffer using the XMODEM model.
void mmhal_uart_tx(const uint8_t *data, size_t length)
Transmit data on the UART.
void mmhal_uart_init(mmhal_uart_rx_cb_t rx_cb, void *rx_cb_arg)
Initialize the UART HAL and perform any setup necessary.
void mmhal_set_deep_sleep_veto(uint8_t veto_id)
Sets a deep sleep veto that will prevent the device from entering deep sleep.
@ MMHAL_VETO_ID_APP_MIN
Start of deep sleep veto ID range that is available for application use.
Definition: mmhal.h:300
#define MM_UNUSED(_x)
Casts the given expression to void to avoid "unused" warnings from the compiler.
Definition: mmutils.h:69
enum mmwlan_status mmwlan_set_power_save_mode(enum mmwlan_ps_mode mode)
Sets whether or not the 802.11 power save is enabled.
enum mmwlan_status mmwlan_ate_execute_command(uint8_t *command, uint32_t command_len, uint8_t *response, uint32_t *response_len)
Execute a test/debug command.
mmwlan_status
Enumeration of status return codes.
Definition: mmwlan.h:50
@ MMWLAN_INVALID_ARGUMENT
The operation failed due to an invalid argument.
Definition: mmwlan.h:56
@ MMWLAN_TIMED_OUT
Failed due to timeout.
Definition: mmwlan.h:65
@ MMWLAN_SUCCESS
The operation was successful.
Definition: mmwlan.h:52
@ MMWLAN_NO_MEM
Failed due to memory allocation failure.
Definition: mmwlan.h:63
@ MMWLAN_UNAVAILABLE
Functionality is temporarily unavailable.
Definition: mmwlan.h:58
@ MMWLAN_PS_DISABLED
Power save disabled.
Definition: mmwlan.h:150
enum slip_rx_status slip_rx(struct slip_rx_state *state, uint8_t c)
Handle reception of a character in a SLIP stream.
#define SLIP_RX_STATE_INIT(_buffer, _buffer_length)
Static initializer for slip_rx_state.
Definition: slip.h:59
int slip_tx(slip_transport_tx_fn transport_tx_fn, void *transport_tx_arg, const uint8_t *packet, size_t packet_len)
Transmit a packet with SLIP framing.
slip_rx_status
Enumeration of SLIP status codes.
Definition: slip.h:82
#define SLIP_RX_BUFFER_SIZE
Recommended RX buffer size.
Definition: slip.h:25
@ SLIP_RX_COMPLETE
A complete packet with length > 0 has been received.
Definition: slip.h:83
Morse Micro application helper routines for initializing/de-initializing the Wireless LAN interface a...
void app_wlan_init(void)
Initializes the WLAN interface (and dependencies) using settings specified in the config store.
#define RESPONSE_HDR_LEN
Length of a response header (excluding status field).
Definition: rf-test.c:38
#define RESPONSE_MAX_LEN
Maximum possible length of a response that we may wish to send.
Definition: rf-test.c:36
static void rf_test_handle_command(struct mmbuf *cmd_buf)
Callback to handle reception of a command packet from the data-link HAL.
Definition: rf-test.c:60
static struct slip_rx_state rx_slip_state
State data for SLIP processing on receive path.
Definition: rf-test.c:208
static void uart_rx_handler(const uint8_t *data, size_t length, void *arg)
Handler for UART HAL RX callback.
Definition: rf-test.c:158
static uint8_t slip_rx_buffer[SLIP_RX_BUFFER_SIZE]
Buffer for SLIP processing on receive path.
Definition: rf-test.c:206
void app_init(void)
Main entry point to the application.
Definition: rf-test.c:215
#define SEQ_NUM_LEN
Length of the sequence number field appended to command/response packets.
Definition: rf-test.c:32
static int slip_tx_handler(uint8_t c, void *arg)
TX callback handler for SLIP.
Definition: rf-test.c:48
Core mmbuf data structure.
Definition: mmbuf.h:53
Structure used to contain the current state for the SLIP receiver.
Definition: slip.h:43
uint8_t * buffer
Reference to buffer where processed bytes are received.
Definition: slip.h:44
size_t length
Length of the currently received frame, excluding escape bytes.
Definition: slip.h:46