Morse Micro IoT SDK  2.10.4
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_core.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");
87 mmbuf_get_data_length(cmd_buf),
88 mmbuf_append(rsp_buf, 0),
89 &response_len);
90
91 if (status == MMWLAN_SUCCESS)
92 {
93 (void)mmbuf_append(rsp_buf, response_len);
94 printf("Command executed successfully. Sending response...\n");
95 }
96 else
97 {
98 uint8_t *hdr;
99 uint8_t result_code[4] = {};
100
101 printf("Failed to execute command. Status code %d\n", status);
102
103 switch (status)
104 {
105 case MMWLAN_NO_MEM:
106 result_code[0] = MM_ENOMEM;
107 break;
108
110 result_code[0] = MM_ENODEV;
111 break;
112
114 result_code[0] = MM_EINVAL;
115 break;
116
117 case MMWLAN_TIMED_OUT:
118 result_code[0] = MM_ETIMEDOUT;
119 break;
120
121 default:
122 result_code[0] = MM_EFAULT;
123 break;
124 }
125
126 /* Craft a response with an errno based error code in the response buffer. */
127 hdr = mmbuf_append(rsp_buf, RESPONSE_HDR_LEN);
128 memset(hdr, 0, RESPONSE_HDR_LEN);
129 mmbuf_append_data(rsp_buf, result_code, sizeof(result_code));
130 }
131
132 mmbuf_append_data(rsp_buf, seq_num, SEQ_NUM_LEN);
133 crc =
134 htole16(mmcrc_16_xmodem(0, mmbuf_get_data_start(rsp_buf), mmbuf_get_data_length(rsp_buf)));
135 mmbuf_append_data(rsp_buf, (uint8_t *)&crc, sizeof(crc));
136
138 NULL,
139 mmbuf_get_data_start(rsp_buf),
140 mmbuf_get_data_length(rsp_buf));
141 if (ret != 0)
142 {
143 printf("Failed to send response (%d)\n", ret);
144 }
145 else
146 {
147 printf("Response sent\n");
148 }
149exit:
150 mmbuf_release(cmd_buf);
151 mmbuf_release(rsp_buf);
152}
153
161static void uart_rx_handler(const uint8_t *data, size_t length, void *arg)
162{
163 size_t ii;
164 enum slip_rx_status status;
165 struct slip_rx_state *slip_state = (struct slip_rx_state *)arg;
166
167 for (ii = 0; ii < length; ii++)
168 {
169 status = slip_rx(slip_state, data[ii]);
170 if (status == SLIP_RX_COMPLETE)
171 {
172 uint16_t crc;
173
174 if (slip_state->length < sizeof(uint16_t))
175 {
176 printf("Received command packet too short. Ignoring...\n");
177 continue;
178 }
179
180 crc = mmcrc_16_xmodem(0, slip_state->buffer, slip_state->length - sizeof(uint16_t));
181 if ((slip_state->buffer[slip_state->length - 2] == (crc & 0xFF)) &&
182 (slip_state->buffer[slip_state->length - 1] == (crc >> 8)))
183 {
184 /* CRC matches, so allocate an mmbuf and pass to command handler function. */
185 struct mmbuf *mmbuffer = mmbuf_alloc_on_heap(0, slip_state->length);
186 if (mmbuffer == NULL)
187 {
188 /* Insufficient memory to receive packet */
189 slip_state->length = 0;
190 printf("Error: memory allocation failure\n");
191 continue;
192 }
193 mmbuf_append_data(mmbuffer, slip_state->buffer, slip_state->length);
194 mmbuf_remove_from_end(mmbuffer, sizeof(uint16_t));
195 rf_test_handle_command(mmbuffer);
196 }
197 else
198 {
199 printf("CRC validation failure\n");
200 }
201 slip_state->length = 0;
202 }
203 }
204}
205
211
216void app_init(void)
217{
218 /* RF-test application does not need to worry about power saving. Take a deep sleep
219 * veto and never release it so that we do not enter deep sleep. */
221
222 printf("\n\nRF Test Application (Built "__DATE__
223 " " __TIME__ ")\n\n");
224
226
227 /* Explicitly prevent the Morse Micro chip from entering it's power save state during rf-test
228 * operations. */
230
232}
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:242
static uint32_t mmbuf_get_data_length(struct mmbuf *mmbuf)
Gets the length of the data currently in the mmbuf.
Definition: mmbuf.h:162
static uint8_t * mmbuf_remove_from_end(struct mmbuf *mmbuf, uint32_t len)
Remove data from the end of the mmbuf.
Definition: mmbuf.h:298
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:259
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:137
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_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_core.h:41
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.
#define MM_UNUSED(_x)
Casts the given expression to void to avoid "unused" warnings from the compiler.
Definition: mmutils.h:70
enum mmwlan_status mmwlan_set_power_save_mode(enum mmwlan_ps_mode mode)
Sets whether or not the 802.11 power save is enabled.
@ MMWLAN_PS_DISABLED
Power save disabled.
Definition: mmwlan.h:981
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:51
@ MMWLAN_INVALID_ARGUMENT
The operation failed due to an invalid argument.
Definition: mmwlan.h:57
@ MMWLAN_TIMED_OUT
Failed due to timeout.
Definition: mmwlan.h:66
@ MMWLAN_SUCCESS
The operation was successful.
Definition: mmwlan.h:53
@ MMWLAN_NO_MEM
Failed due to memory allocation failure.
Definition: mmwlan.h:64
@ MMWLAN_UNAVAILABLE
Functionality is temporarily unavailable.
Definition: mmwlan.h:59
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:83
#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:84
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:209
static void uart_rx_handler(const uint8_t *data, size_t length, void *arg)
Handler for UART HAL RX callback.
Definition: rf-test.c:161
static uint8_t slip_rx_buffer[SLIP_RX_BUFFER_SIZE]
Buffer for SLIP processing on receive path.
Definition: rf-test.c:207
void app_init(void)
Main entry point to the application.
Definition: rf-test.c:216
#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:54
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