modem: modem_cellular: Configurable MTU for CMUX
Allow configuring MTU for CMUX. Some AT manual and specification define this as a frame size. Linux ldattach default to 127 bytes, 3GPP TS 27.010 defaults to 31. We should limit our CMUX frames to a size that remote end is capable of handling. Linux silently drops oversized frames. Also, remove MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE as this was only limiting a buffer sizes, and resulted CMUX frames to be capped to same value. Use MODEM_CMUX_WORK_BUFFER_SIZE and MODEM_CMUX_MTU instead. Also rename CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES to CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZE as it is now only used as a Chat module. DLCI pipes use CONFIG_MODEM_CMUX_WORK_BUFFER_SIZE. Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
This commit is contained in:
parent
2df9e371f5
commit
c78081e5cf
11 changed files with 75 additions and 23 deletions
|
@ -42,15 +42,8 @@ config MODEM_CELLULAR_UART_BUFFER_SIZES
|
|||
int "The UART receive and transmit buffer sizes in bytes."
|
||||
default 512
|
||||
|
||||
config MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE
|
||||
int "The maximum CMUX frame size in bytes."
|
||||
default 32 if DT_HAS_U_BLOX_LARA_R6_ENABLED
|
||||
default 128
|
||||
help
|
||||
This value affects the size of buffers used to receive and transmit CMUX frames.
|
||||
|
||||
config MODEM_CELLULAR_CHAT_BUFFER_SIZES
|
||||
int "The size of the buffers used for the chat scripts in bytes."
|
||||
config MODEM_CELLULAR_CHAT_BUFFER_SIZE
|
||||
int "The size of the buffer used for the chat scripts in bytes."
|
||||
default 128
|
||||
|
||||
config MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES
|
||||
|
|
|
@ -90,8 +90,8 @@ struct modem_cellular_data {
|
|||
|
||||
/* CMUX */
|
||||
struct modem_cmux cmux;
|
||||
uint8_t cmux_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
|
||||
uint8_t cmux_transmit_buf[2 * CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
|
||||
uint8_t cmux_receive_buf[CONFIG_MODEM_CMUX_WORK_BUFFER_SIZE];
|
||||
uint8_t cmux_transmit_buf[CONFIG_MODEM_CMUX_WORK_BUFFER_SIZE];
|
||||
|
||||
struct modem_cmux_dlci dlci1;
|
||||
struct modem_cmux_dlci dlci2;
|
||||
|
@ -99,13 +99,13 @@ struct modem_cellular_data {
|
|||
struct modem_pipe *dlci2_pipe;
|
||||
/* Points to dlci2_pipe or NULL. Used for shutdown script if not NULL */
|
||||
struct modem_pipe *cmd_pipe;
|
||||
uint8_t dlci1_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
|
||||
uint8_t dlci1_receive_buf[CONFIG_MODEM_CMUX_WORK_BUFFER_SIZE];
|
||||
/* DLCI 2 is only used for chat scripts. */
|
||||
uint8_t dlci2_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES];
|
||||
uint8_t dlci2_receive_buf[CONFIG_MODEM_CMUX_WORK_BUFFER_SIZE];
|
||||
|
||||
/* Modem chat */
|
||||
struct modem_chat chat;
|
||||
uint8_t chat_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES];
|
||||
uint8_t chat_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZE];
|
||||
uint8_t *chat_delimiter;
|
||||
uint8_t *chat_filter;
|
||||
uint8_t *chat_argv[32];
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
CONFIG_MODEM_HL7800=n
|
||||
CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE=255
|
||||
CONFIG_NET_BUF_TX_COUNT=32
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_UART_1_ASYNC=y
|
|||
CONFIG_UART_1_INTERRUPT_DRIVEN=n
|
||||
|
||||
# Align with the Serial LTE Modem (SLM) application.
|
||||
CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE=1500
|
||||
CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES=6000
|
||||
|
||||
# Print logs and printk() output on uart0.
|
||||
|
|
|
@ -3,7 +3,6 @@ CONFIG_UART_1_ASYNC=y
|
|||
CONFIG_UART_1_INTERRUPT_DRIVEN=n
|
||||
|
||||
# Align with the Serial LTE Modem (SLM) application.
|
||||
CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE=1500
|
||||
CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES=6000
|
||||
|
||||
# Prevent sockets getting offloaded to the modem.
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
CONFIG_MODEM_HL7800=n
|
||||
CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE=255
|
||||
CONFIG_NET_BUF_TX_COUNT=32
|
||||
|
|
|
@ -29,10 +29,34 @@ config MODEM_CMUX
|
|||
|
||||
if MODEM_CMUX
|
||||
|
||||
config MODEM_CMUX_DEFAULT_MTU_127
|
||||
bool
|
||||
default y if (DT_HAS_QUECTEL_BG95_ENABLED || DT_HAS_QUECTEL_EG25_G_ENABLED || \
|
||||
DT_HAS_SIMCOM_SIM7080_ENABLED || DT_HAS_U_BLOX_SARA_R4_ENABLED || \
|
||||
DT_HAS_U_BLOX_SARA_R5_ENABLED || DT_HAS_SWIR_HL7800_ENABLED || \
|
||||
DT_HAS_TELIT_ME910G1_ENABLED || DT_HAS_TELIT_ME310G1_ENABLED || \
|
||||
DT_HAS_SQN_GM02S_ENABLED)
|
||||
help
|
||||
Use the default MTU size of 127 bytes for the CMUX module on certain modems.
|
||||
This must match the AT+CMUX commands in the modem_cellular driver.
|
||||
|
||||
config MODEM_CMUX_MTU
|
||||
int "CMUX MTU size in bytes"
|
||||
range 16 1500
|
||||
default 127 if MODEM_CMUX_DEFAULT_MTU_127
|
||||
default 31
|
||||
help
|
||||
Maximum Transmission Unit (MTU) size for the CMUX module.
|
||||
Linux ldattach defaults to 127 bytes, 3GPP TS 27.010 to 31.
|
||||
|
||||
config MODEM_CMUX_WORK_BUFFER_SIZE
|
||||
int "CMUX module work buffer size in bytes"
|
||||
range 16 1500
|
||||
default 64
|
||||
range 23 1507
|
||||
default 134 if MODEM_CMUX_DEFAULT_MTU_127
|
||||
default 38
|
||||
help
|
||||
Size of the work buffer used by the CMUX module.
|
||||
Recommended size is MODEM_CMUX_MTU + 7 (CMUX header size).
|
||||
|
||||
module = MODEM_CMUX
|
||||
module-str = modem_cmux
|
||||
|
|
|
@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(modem_cmux, CONFIG_MODEM_CMUX_LOG_LEVEL);
|
|||
#define MODEM_CMUX_EA (0x01)
|
||||
#define MODEM_CMUX_CR (0x02)
|
||||
#define MODEM_CMUX_PF (0x10)
|
||||
#define MODEM_CMUX_FRAME_SIZE_MAX (0x08)
|
||||
#define MODEM_CMUX_FRAME_SIZE_MAX (0x07)
|
||||
#define MODEM_CMUX_DATA_SIZE_MIN (0x08)
|
||||
#define MODEM_CMUX_DATA_FRAME_SIZE_MIN (MODEM_CMUX_FRAME_SIZE_MAX + \
|
||||
MODEM_CMUX_DATA_SIZE_MIN)
|
||||
|
@ -274,6 +274,7 @@ static uint16_t modem_cmux_transmit_frame(struct modem_cmux *cmux,
|
|||
|
||||
space = ring_buf_space_get(&cmux->transmit_rb) - MODEM_CMUX_FRAME_SIZE_MAX;
|
||||
data_len = MIN(space, frame->data_len);
|
||||
data_len = MIN(data_len, CONFIG_MODEM_CMUX_MTU);
|
||||
|
||||
/* SOF */
|
||||
buf[0] = 0xF9;
|
||||
|
@ -797,6 +798,12 @@ static void modem_cmux_process_received_byte(struct modem_cmux *cmux, uint8_t by
|
|||
break;
|
||||
}
|
||||
|
||||
if (cmux->frame.data_len > CONFIG_MODEM_CMUX_MTU) {
|
||||
LOG_ERR("Too large frame");
|
||||
cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_DROP;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if no data field */
|
||||
if (cmux->frame.data_len == 0) {
|
||||
/* Await FCS */
|
||||
|
@ -816,6 +823,12 @@ static void modem_cmux_process_received_byte(struct modem_cmux *cmux, uint8_t by
|
|||
/* Get last 8 bits of data length */
|
||||
cmux->frame.data_len |= ((uint16_t)byte) << 7;
|
||||
|
||||
if (cmux->frame.data_len > CONFIG_MODEM_CMUX_MTU) {
|
||||
LOG_ERR("Too large frame");
|
||||
cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_DROP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmux->frame.data_len > cmux->receive_buf_size) {
|
||||
LOG_ERR("Indicated frame data length %u exceeds receive buffer size %u",
|
||||
cmux->frame.data_len, cmux->receive_buf_size);
|
||||
|
@ -1239,9 +1252,11 @@ void modem_cmux_init(struct modem_cmux *cmux, const struct modem_cmux_config *co
|
|||
__ASSERT_NO_MSG(cmux != NULL);
|
||||
__ASSERT_NO_MSG(config != NULL);
|
||||
__ASSERT_NO_MSG(config->receive_buf != NULL);
|
||||
__ASSERT_NO_MSG(config->receive_buf_size >= 126);
|
||||
__ASSERT_NO_MSG(config->receive_buf_size >=
|
||||
(CONFIG_MODEM_CMUX_MTU + MODEM_CMUX_FRAME_SIZE_MAX));
|
||||
__ASSERT_NO_MSG(config->transmit_buf != NULL);
|
||||
__ASSERT_NO_MSG(config->transmit_buf_size >= 148);
|
||||
__ASSERT_NO_MSG(config->transmit_buf_size >=
|
||||
(CONFIG_MODEM_CMUX_MTU + MODEM_CMUX_FRAME_SIZE_MAX));
|
||||
|
||||
memset(cmux, 0x00, sizeof(*cmux));
|
||||
cmux->callback = config->callback;
|
||||
|
|
|
@ -5,5 +5,6 @@ CONFIG_NO_OPTIMIZATIONS=y
|
|||
|
||||
CONFIG_MODEM_MODULES=y
|
||||
CONFIG_MODEM_CMUX=y
|
||||
CONFIG_MODEM_CMUX_MTU=64
|
||||
|
||||
CONFIG_ZTEST=y
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#define EVENT_CMUX_DLCI1_CLOSED BIT(7)
|
||||
#define EVENT_CMUX_DLCI2_CLOSED BIT(8)
|
||||
#define EVENT_CMUX_DISCONNECTED BIT(9)
|
||||
#define CMUX_BASIC_HRD_SMALL_SIZE 6
|
||||
#define CMUX_BASIC_HRD_LARGE_SIZE 7
|
||||
|
||||
/*************************************************************************************************/
|
||||
/* Instances */
|
||||
|
@ -195,6 +197,8 @@ static uint8_t cmux_frame_data_dlci2_ppp_18[] = {0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0
|
|||
0x7D, 0x22, 0x7D, 0x21, 0x7D, 0x20,
|
||||
0x7D, 0x24, 0x7D, 0x3C, 0x90, 0x7E};
|
||||
|
||||
static uint8_t cmux_frame_data_large[127] = { [0 ... 126] = 0xAA };
|
||||
|
||||
const static struct modem_backend_mock_transaction transaction_control_cld = {
|
||||
.get = cmux_frame_control_cld_cmd,
|
||||
.get_size = sizeof(cmux_frame_control_cld_cmd),
|
||||
|
@ -864,4 +868,22 @@ ZTEST(modem_cmux, test_modem_drop_frames_with_invalid_length)
|
|||
"Incorrect data received");
|
||||
}
|
||||
|
||||
ZTEST(modem_cmux, test_modem_cmux_split_large_data)
|
||||
{
|
||||
int ret;
|
||||
uint32_t events;
|
||||
|
||||
ret = modem_pipe_transmit(dlci2_pipe, cmux_frame_data_large,
|
||||
sizeof(cmux_frame_data_large));
|
||||
zassert_true(ret == CONFIG_MODEM_CMUX_MTU, "Failed to split large data %d", ret);
|
||||
|
||||
events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE, false, K_MSEC(200));
|
||||
zassert_equal(events, EVENT_CMUX_DLCI2_TRANSMIT_IDLE,
|
||||
"Transmit idle event not received for DLCI2 pipe");
|
||||
|
||||
ret = modem_backend_mock_get(&bus_mock, buffer2, sizeof(buffer2));
|
||||
zassert_true(ret == CONFIG_MODEM_CMUX_MTU + CMUX_BASIC_HRD_SMALL_SIZE,
|
||||
"Incorrect number of bytes transmitted %d", ret);
|
||||
}
|
||||
|
||||
ZTEST_SUITE(modem_cmux, NULL, test_modem_cmux_setup, test_modem_cmux_before, NULL, NULL);
|
||||
|
|
|
@ -5,5 +5,6 @@ CONFIG_NO_OPTIMIZATIONS=y
|
|||
|
||||
CONFIG_MODEM_MODULES=y
|
||||
CONFIG_MODEM_CMUX=y
|
||||
CONFIG_MODEM_CMUX_MTU=64
|
||||
|
||||
CONFIG_ZTEST=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue