drivers/modem/modem_cmd_handler: Update API
There is currently not a clear separation between user configuration and internal context when using the modem_cmd_handler library. This update adds a clear separation, placing user configuration in a seperate struct passed to modem_cmd_handler_init alongside the internal context modem_cmd_handler_data. There is also a lack of documentation of the user configurations, these have been added to the new config struct. The new API function modem_cmd_handler_process has been added to remove the need for the user to directly access the process member of the internal context. This ensures that the user is not encouraged to access any internal context members. Some whitespace errors exist in the modem_cmd_handler.c file, these are outside of the scope of this PR. These can be addressed in a later PR as they are not functional changes. Signed-off-by: Bjarki Arge Andreasen <baa@trackunit.com>
This commit is contained in:
parent
a4afcf8c93
commit
aa6ecc59d1
7 changed files with 175 additions and 72 deletions
|
|
@ -177,8 +177,7 @@ static void gsm_rx(struct gsm_modem *gsm)
|
|||
modem_iface_uart_rx_wait(&gsm->context.iface, K_FOREVER);
|
||||
|
||||
/* The handler will listen AT channel */
|
||||
gsm->context.cmd_handler.process(&gsm->context.cmd_handler,
|
||||
&gsm->context.iface);
|
||||
modem_cmd_handler_process(&gsm->context.cmd_handler, &gsm->context.iface);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1273,19 +1272,24 @@ static int gsm_init(const struct device *dev)
|
|||
(void)k_mutex_init(&gsm->lock);
|
||||
gsm->dev = dev;
|
||||
|
||||
gsm->cmd_handler_data.cmds[CMD_RESP] = response_cmds;
|
||||
gsm->cmd_handler_data.cmds_len[CMD_RESP] = ARRAY_SIZE(response_cmds);
|
||||
gsm->cmd_handler_data.match_buf = &gsm->cmd_match_buf[0];
|
||||
gsm->cmd_handler_data.match_buf_len = sizeof(gsm->cmd_match_buf);
|
||||
gsm->cmd_handler_data.buf_pool = &gsm_recv_pool;
|
||||
gsm->cmd_handler_data.alloc_timeout = K_NO_WAIT;
|
||||
gsm->cmd_handler_data.eol = "\r";
|
||||
const struct modem_cmd_handler_config cmd_handler_config = {
|
||||
.match_buf = &gsm->cmd_match_buf[0],
|
||||
.match_buf_len = sizeof(gsm->cmd_match_buf),
|
||||
.buf_pool = &gsm_recv_pool,
|
||||
.alloc_timeout = K_NO_WAIT,
|
||||
.eol = "\r",
|
||||
.user_data = NULL,
|
||||
.response_cmds = response_cmds,
|
||||
.response_cmds_len = ARRAY_SIZE(response_cmds),
|
||||
.unsol_cmds = NULL,
|
||||
.unsol_cmds_len = 0,
|
||||
};
|
||||
|
||||
(void)k_sem_init(&gsm->sem_response, 0, 1);
|
||||
(void)k_sem_init(&gsm->sem_if_down, 0, 1);
|
||||
|
||||
ret = modem_cmd_handler_init(&gsm->context.cmd_handler,
|
||||
&gsm->cmd_handler_data);
|
||||
ret = modem_cmd_handler_init(&gsm->context.cmd_handler, &gsm->cmd_handler_data,
|
||||
&cmd_handler_config);
|
||||
if (ret < 0) {
|
||||
LOG_DBG("cmd handler error %d", ret);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -646,25 +646,47 @@ void modem_cmd_handler_tx_unlock(struct modem_cmd_handler *handler)
|
|||
}
|
||||
|
||||
int modem_cmd_handler_init(struct modem_cmd_handler *handler,
|
||||
struct modem_cmd_handler_data *data)
|
||||
struct modem_cmd_handler_data *data,
|
||||
const struct modem_cmd_handler_config *config)
|
||||
{
|
||||
if (!handler || !data) {
|
||||
/* Verify arguments */
|
||||
if (handler == NULL || data == NULL || config == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!data->match_buf_len) {
|
||||
/* Verify config */
|
||||
if ((config->match_buf == NULL) ||
|
||||
(config->match_buf_len == 0) ||
|
||||
(config->buf_pool == NULL) ||
|
||||
(NULL != config->response_cmds && 0 == config->response_cmds_len) ||
|
||||
(NULL != config->unsol_cmds && 0 == config->unsol_cmds_len)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data->eol == NULL) {
|
||||
data->eol_len = 0;
|
||||
} else {
|
||||
data->eol_len = strlen(data->eol);
|
||||
}
|
||||
|
||||
/* Assign data to command handler */
|
||||
handler->cmd_handler_data = data;
|
||||
|
||||
/* Assign command process implementation to command handler */
|
||||
handler->process = cmd_handler_process;
|
||||
|
||||
/* Store arguments */
|
||||
data->match_buf = config->match_buf;
|
||||
data->match_buf_len = config->match_buf_len;
|
||||
data->buf_pool = config->buf_pool;
|
||||
data->alloc_timeout = config->alloc_timeout;
|
||||
data->eol = config->eol;
|
||||
data->cmds[CMD_RESP] = config->response_cmds;
|
||||
data->cmds_len[CMD_RESP] = config->response_cmds_len;
|
||||
data->cmds[CMD_UNSOL] = config->unsol_cmds;
|
||||
data->cmds_len[CMD_UNSOL] = config->unsol_cmds_len;
|
||||
|
||||
/* Process end of line */
|
||||
data->eol_len = data->eol == NULL ? 0 : strlen(data->eol);
|
||||
|
||||
/* Store optional user data */
|
||||
data->user_data = config->user_data;
|
||||
|
||||
/* Initialize command handler data members */
|
||||
k_sem_init(&data->sem_tx_lock, 1, 1);
|
||||
k_sem_init(&data->sem_parse_lock, 1, 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -266,15 +266,56 @@ int modem_cmd_handler_setup_cmds_nolock(struct modem_iface *iface,
|
|||
k_timeout_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Init command handler
|
||||
* @brief Modem command handler configuration
|
||||
*
|
||||
* @param *handler: command handler to initialize
|
||||
* @param *data: command handler data to use
|
||||
* @details Contains user configuration which is used to set up
|
||||
* command handler data context. The struct is initialized and then passed
|
||||
* to modem_cmd_handler_init().
|
||||
*
|
||||
* @retval 0 if ok, < 0 if error.
|
||||
* @param match_buf Buffer used for matching commands
|
||||
* @param match_buf_len Length of buffer used for matching commands
|
||||
* @param buf_pool Initialized buffer pool used to store incoming data
|
||||
* @param alloc_timeout Timeout for allocating data in buffer pool
|
||||
* @param eol End of line represented as string
|
||||
* @param user_data Free to use data which can be retrieved from within command handlers
|
||||
* @param response_cmds Array of response command handlers
|
||||
* @param response_cmds_len Length of response command handlers array
|
||||
* @param unsol_cmds Array of unsolicitet command handlers
|
||||
* @param unsol_cmds_len Length of unsolicitet command handlers array
|
||||
*/
|
||||
struct modem_cmd_handler_config {
|
||||
char *match_buf;
|
||||
size_t match_buf_len;
|
||||
struct net_buf_pool *buf_pool;
|
||||
k_timeout_t alloc_timeout;
|
||||
const char *eol;
|
||||
void *user_data;
|
||||
const struct modem_cmd *response_cmds;
|
||||
size_t response_cmds_len;
|
||||
const struct modem_cmd *unsol_cmds;
|
||||
size_t unsol_cmds_len;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialize modem command handler
|
||||
*
|
||||
* @details This function is called once for each command handler, before any
|
||||
* incoming data is processed.
|
||||
*
|
||||
* @note All arguments passed to this function, including the referenced data
|
||||
* contained in the setup struct, must persist as long as the command handler itself.
|
||||
*
|
||||
* @param handler Command handler to initialize
|
||||
* @param data Command handler data to use
|
||||
* @param setup Command handler setup
|
||||
*
|
||||
* @return -EINVAL if any argument is invalid
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int modem_cmd_handler_init(struct modem_cmd_handler *handler,
|
||||
struct modem_cmd_handler_data *data);
|
||||
struct modem_cmd_handler_data *data,
|
||||
const struct modem_cmd_handler_config *config);
|
||||
|
||||
/**
|
||||
* @brief Lock the modem for sending cmds
|
||||
|
|
@ -299,6 +340,25 @@ int modem_cmd_handler_tx_lock(struct modem_cmd_handler *handler,
|
|||
*/
|
||||
void modem_cmd_handler_tx_unlock(struct modem_cmd_handler *handler);
|
||||
|
||||
/**
|
||||
* @brief Process incoming data
|
||||
*
|
||||
* @details This function will process any data available from the interface
|
||||
* using the command handler. The command handler will invoke any matching modem
|
||||
* command which has been registered using @ref modem_cmd_handler_init_cmds or
|
||||
* @ref modem_cmd_handler_update_cmds. Once handled, the function will return.
|
||||
*
|
||||
* @note This function should be invoked from a dedicated thread, which only handles
|
||||
* commands.
|
||||
*
|
||||
* @param handler The handler wich will handle the command when processed
|
||||
* @param iface The interface which receives incoming data
|
||||
*/
|
||||
static inline void modem_cmd_handler_process(struct modem_cmd_handler *handler,
|
||||
struct modem_iface *iface)
|
||||
{
|
||||
handler->process(handler, iface);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -850,7 +850,7 @@ static void modem_rx(void)
|
|||
/* Wait for incoming data */
|
||||
modem_iface_uart_rx_wait(&mctx.iface, K_FOREVER);
|
||||
|
||||
mctx.cmd_handler.process(&mctx.cmd_handler, &mctx.iface);
|
||||
modem_cmd_handler_process(&mctx.cmd_handler, &mctx.iface);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1153,17 +1153,22 @@ static int modem_init(const struct device *dev)
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* cmd handler */
|
||||
mdata.cmd_handler_data.cmds[CMD_RESP] = response_cmds;
|
||||
mdata.cmd_handler_data.cmds_len[CMD_RESP] = ARRAY_SIZE(response_cmds);
|
||||
mdata.cmd_handler_data.cmds[CMD_UNSOL] = unsol_cmds;
|
||||
mdata.cmd_handler_data.cmds_len[CMD_UNSOL] = ARRAY_SIZE(unsol_cmds);
|
||||
mdata.cmd_handler_data.match_buf = &mdata.cmd_match_buf[0];
|
||||
mdata.cmd_handler_data.match_buf_len = sizeof(mdata.cmd_match_buf);
|
||||
mdata.cmd_handler_data.buf_pool = &mdm_recv_pool;
|
||||
mdata.cmd_handler_data.alloc_timeout = BUF_ALLOC_TIMEOUT;
|
||||
mdata.cmd_handler_data.eol = "\r\n";
|
||||
ret = modem_cmd_handler_init(&mctx.cmd_handler, &mdata.cmd_handler_data);
|
||||
/* cmd handler setup */
|
||||
const struct modem_cmd_handler_config cmd_handler_config = {
|
||||
.match_buf = &mdata.cmd_match_buf[0],
|
||||
.match_buf_len = sizeof(mdata.cmd_match_buf),
|
||||
.buf_pool = &mdm_recv_pool,
|
||||
.alloc_timeout = BUF_ALLOC_TIMEOUT,
|
||||
.eol = "\r\n",
|
||||
.user_data = NULL,
|
||||
.response_cmds = response_cmds,
|
||||
.response_cmds_len = ARRAY_SIZE(response_cmds),
|
||||
.unsol_cmds = unsol_cmds,
|
||||
.unsol_cmds_len = ARRAY_SIZE(unsol_cmds),
|
||||
};
|
||||
|
||||
ret = modem_cmd_handler_init(&mctx.cmd_handler, &mdata.cmd_handler_data,
|
||||
&cmd_handler_config);
|
||||
if (ret < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -808,7 +808,7 @@ static void modem_rx(void)
|
|||
/* Wait for incoming data */
|
||||
modem_iface_uart_rx_wait(&mctx.iface, K_FOREVER);
|
||||
|
||||
mctx.cmd_handler.process(&mctx.cmd_handler, &mctx.iface);
|
||||
modem_cmd_handler_process(&mctx.cmd_handler, &mctx.iface);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2349,16 +2349,21 @@ static int modem_init(const struct device *dev)
|
|||
change_state(SIM7080_STATE_INIT);
|
||||
|
||||
/* Command handler. */
|
||||
mdata.cmd_handler_data.cmds[CMD_RESP] = response_cmds;
|
||||
mdata.cmd_handler_data.cmds_len[CMD_RESP] = ARRAY_SIZE(response_cmds);
|
||||
mdata.cmd_handler_data.cmds[CMD_UNSOL] = unsolicited_cmds;
|
||||
mdata.cmd_handler_data.cmds_len[CMD_UNSOL] = ARRAY_SIZE(unsolicited_cmds);
|
||||
mdata.cmd_handler_data.match_buf = &mdata.cmd_match_buf[0];
|
||||
mdata.cmd_handler_data.match_buf_len = sizeof(mdata.cmd_match_buf);
|
||||
mdata.cmd_handler_data.buf_pool = &mdm_recv_pool;
|
||||
mdata.cmd_handler_data.alloc_timeout = BUF_ALLOC_TIMEOUT;
|
||||
mdata.cmd_handler_data.eol = "\r\n";
|
||||
ret = modem_cmd_handler_init(&mctx.cmd_handler, &mdata.cmd_handler_data);
|
||||
const struct modem_cmd_handler_config cmd_handler_config = {
|
||||
.match_buf = &mdata.cmd_match_buf[0],
|
||||
.match_buf_len = sizeof(mdata.cmd_match_buf),
|
||||
.buf_pool = &mdm_recv_pool,
|
||||
.alloc_timeout = BUF_ALLOC_TIMEOUT,
|
||||
.eol = "\r\n",
|
||||
.user_data = NULL,
|
||||
.response_cmds = response_cmds,
|
||||
.response_cmds_len = ARRAY_SIZE(response_cmds),
|
||||
.unsol_cmds = unsolicited_cmds,
|
||||
.unsol_cmds_len = ARRAY_SIZE(unsolicited_cmds),
|
||||
};
|
||||
|
||||
ret = modem_cmd_handler_init(&mctx.cmd_handler, &mdata.cmd_handler_data,
|
||||
&cmd_handler_config);
|
||||
if (ret < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -942,7 +942,7 @@ static void modem_rx(void)
|
|||
/* wait for incoming data */
|
||||
modem_iface_uart_rx_wait(&mctx.iface, K_FOREVER);
|
||||
|
||||
mctx.cmd_handler.process(&mctx.cmd_handler, &mctx.iface);
|
||||
modem_cmd_handler_process(&mctx.cmd_handler, &mctx.iface);
|
||||
|
||||
/* give up time if we have a solid stream of data */
|
||||
k_yield();
|
||||
|
|
@ -2149,17 +2149,21 @@ static int modem_init(const struct device *dev)
|
|||
}
|
||||
|
||||
/* cmd handler */
|
||||
mdata.cmd_handler_data.cmds[CMD_RESP] = response_cmds;
|
||||
mdata.cmd_handler_data.cmds_len[CMD_RESP] = ARRAY_SIZE(response_cmds);
|
||||
mdata.cmd_handler_data.cmds[CMD_UNSOL] = unsol_cmds;
|
||||
mdata.cmd_handler_data.cmds_len[CMD_UNSOL] = ARRAY_SIZE(unsol_cmds);
|
||||
mdata.cmd_handler_data.match_buf = &mdata.cmd_match_buf[0];
|
||||
mdata.cmd_handler_data.match_buf_len = sizeof(mdata.cmd_match_buf);
|
||||
mdata.cmd_handler_data.buf_pool = &mdm_recv_pool;
|
||||
mdata.cmd_handler_data.alloc_timeout = K_NO_WAIT;
|
||||
mdata.cmd_handler_data.eol = "\r";
|
||||
ret = modem_cmd_handler_init(&mctx.cmd_handler,
|
||||
&mdata.cmd_handler_data);
|
||||
const struct modem_cmd_handler_config cmd_handler_config = {
|
||||
.match_buf = &mdata.cmd_match_buf[0],
|
||||
.match_buf_len = sizeof(mdata.cmd_match_buf),
|
||||
.buf_pool = &mdm_recv_pool,
|
||||
.alloc_timeout = K_NO_WAIT,
|
||||
.eol = "\r",
|
||||
.user_data = NULL,
|
||||
.response_cmds = response_cmds,
|
||||
.response_cmds_len = ARRAY_SIZE(response_cmds),
|
||||
.unsol_cmds = unsol_cmds,
|
||||
.unsol_cmds_len = ARRAY_SIZE(unsol_cmds),
|
||||
};
|
||||
|
||||
ret = modem_cmd_handler_init(&mctx.cmd_handler, &mdata.cmd_handler_data,
|
||||
&cmd_handler_config);
|
||||
if (ret < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,8 +205,7 @@ static void esp_rx(struct esp_data *data)
|
|||
/* wait for incoming data */
|
||||
modem_iface_uart_rx_wait(&data->mctx.iface, K_FOREVER);
|
||||
|
||||
data->mctx.cmd_handler.process(&data->mctx.cmd_handler,
|
||||
&data->mctx.iface);
|
||||
modem_cmd_handler_process(&data->mctx.cmd_handler, &data->mctx.iface);
|
||||
|
||||
/* give up time if we have a solid stream of data */
|
||||
k_yield();
|
||||
|
|
@ -1270,17 +1269,21 @@ static int esp_init(const struct device *dev)
|
|||
k_thread_name_set(&data->workq.thread, "esp_workq");
|
||||
|
||||
/* cmd handler */
|
||||
data->cmd_handler_data.cmds[CMD_RESP] = response_cmds;
|
||||
data->cmd_handler_data.cmds_len[CMD_RESP] = ARRAY_SIZE(response_cmds);
|
||||
data->cmd_handler_data.cmds[CMD_UNSOL] = unsol_cmds;
|
||||
data->cmd_handler_data.cmds_len[CMD_UNSOL] = ARRAY_SIZE(unsol_cmds);
|
||||
data->cmd_handler_data.match_buf = &data->cmd_match_buf[0];
|
||||
data->cmd_handler_data.match_buf_len = sizeof(data->cmd_match_buf);
|
||||
data->cmd_handler_data.buf_pool = &mdm_recv_pool;
|
||||
data->cmd_handler_data.alloc_timeout = K_NO_WAIT;
|
||||
data->cmd_handler_data.eol = "\r\n";
|
||||
ret = modem_cmd_handler_init(&data->mctx.cmd_handler,
|
||||
&data->cmd_handler_data);
|
||||
const struct modem_cmd_handler_config cmd_handler_config = {
|
||||
.match_buf = &data->cmd_match_buf[0],
|
||||
.match_buf_len = sizeof(data->cmd_match_buf),
|
||||
.buf_pool = &mdm_recv_pool,
|
||||
.alloc_timeout = K_NO_WAIT,
|
||||
.eol = "\r\n",
|
||||
.user_data = NULL,
|
||||
.response_cmds = response_cmds,
|
||||
.response_cmds_len = ARRAY_SIZE(response_cmds),
|
||||
.unsol_cmds = unsol_cmds,
|
||||
.unsol_cmds_len = ARRAY_SIZE(unsol_cmds),
|
||||
};
|
||||
|
||||
ret = modem_cmd_handler_init(&data->mctx.cmd_handler, &data->cmd_handler_data,
|
||||
&cmd_handler_config);
|
||||
if (ret < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue