drivers: modem: Add support for commands that don't have a line ending
Some commands need to be processed before a "\r\n" is available and there might also be commands that have "\r\n" as data but doesn't mean the end of the command. To solve this a MODEM_CMD_DIRECT has been added. cmd_handler_process() will look for matching direct commands before checking if a whole line is available for matching the normal commands. A direct command can return either -EAGAIN, meaning that more data is needed or it will return the number of bytes to skip forward, ie the length of the command that was handled. Signed-off-by: Tobias Svehagen <tobias.svehagen@gmail.com>
This commit is contained in:
parent
6ec675ca2f
commit
990ab00e30
2 changed files with 73 additions and 0 deletions
|
@ -70,6 +70,30 @@ static u16_t findcrlf(struct modem_cmd_handler_data *data,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool starts_with(struct net_buf *buf, const char *str)
|
||||||
|
{
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
while (buf && buf->len && *str) {
|
||||||
|
if (*(buf->data + pos) == *str) {
|
||||||
|
str++;
|
||||||
|
pos++;
|
||||||
|
if (pos >= buf->len) {
|
||||||
|
buf = buf->frags;
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*str == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cmd Handler Functions
|
* Cmd Handler Functions
|
||||||
*/
|
*/
|
||||||
|
@ -208,6 +232,29 @@ static struct modem_cmd *find_cmd_match(struct modem_cmd_handler_data *data)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct modem_cmd *find_cmd_direct_match(
|
||||||
|
struct modem_cmd_handler_data *data)
|
||||||
|
{
|
||||||
|
int j, i;
|
||||||
|
|
||||||
|
for (j = 0; j < ARRAY_SIZE(data->cmds); j++) {
|
||||||
|
if (!data->cmds[j] || data->cmds_len[j] == 0U) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < data->cmds_len[j]; i++) {
|
||||||
|
/* match start of cmd */
|
||||||
|
if (data->cmds[j][i].direct &&
|
||||||
|
(data->cmds[j][i].cmd[0] == '\0' ||
|
||||||
|
starts_with(data->rx_buf, data->cmds[j][i].cmd))) {
|
||||||
|
return &data->cmds[j][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void cmd_handler_process(struct modem_cmd_handler *cmd_handler,
|
static void cmd_handler_process(struct modem_cmd_handler *cmd_handler,
|
||||||
struct modem_iface *iface)
|
struct modem_iface *iface)
|
||||||
{
|
{
|
||||||
|
@ -263,6 +310,19 @@ static void cmd_handler_process(struct modem_cmd_handler *cmd_handler,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd = find_cmd_direct_match(data);
|
||||||
|
if (cmd && cmd->func) {
|
||||||
|
ret = cmd->func(data, cmd->cmd_len, NULL, 0);
|
||||||
|
if (ret == -EAGAIN) {
|
||||||
|
/* Wait for more data */
|
||||||
|
break;
|
||||||
|
} else if (ret > 0) {
|
||||||
|
data->rx_buf = net_buf_skip(data->rx_buf, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
frag = NULL;
|
frag = NULL;
|
||||||
/* locate next CR/LF */
|
/* locate next CR/LF */
|
||||||
len = findcrlf(data, &frag, &offset);
|
len = findcrlf(data, &frag, &offset);
|
||||||
|
|
|
@ -31,6 +31,18 @@ static int name_(struct modem_cmd_handler_data *data, u16_t len, \
|
||||||
.func = func_cb_, \
|
.func = func_cb_, \
|
||||||
.arg_count = acount_, \
|
.arg_count = acount_, \
|
||||||
.delim = adelim_, \
|
.delim = adelim_, \
|
||||||
|
.direct = false, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MODEM_CMD_DIRECT_DEFINE(name_) MODEM_CMD_DEFINE(name_)
|
||||||
|
|
||||||
|
#define MODEM_CMD_DIRECT(cmd_, func_cb_) { \
|
||||||
|
.cmd = cmd_, \
|
||||||
|
.cmd_len = (u16_t)sizeof(cmd_)-1, \
|
||||||
|
.func = func_cb_, \
|
||||||
|
.arg_count = 0, \
|
||||||
|
.delim = "", \
|
||||||
|
.direct = true, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CMD_RESP 0
|
#define CMD_RESP 0
|
||||||
|
@ -47,6 +59,7 @@ struct modem_cmd {
|
||||||
const char *delim;
|
const char *delim;
|
||||||
u16_t cmd_len;
|
u16_t cmd_len;
|
||||||
u16_t arg_count;
|
u16_t arg_count;
|
||||||
|
bool direct;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SETUP_CMD(cmd_send_, match_cmd_, func_cb_, num_param_, delim_) { \
|
#define SETUP_CMD(cmd_send_, match_cmd_, func_cb_, num_param_, delim_) { \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue