Commit aa6ecc59 authored by Bjarki Arge Andreasen's avatar Bjarki Arge Andreasen Committed by Carles Cufi
Browse files

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: default avatarBjarki Arge Andreasen <baa@trackunit.com>
parent a4afcf8c
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -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;
+31 −9
Original line number Diff line number Diff line
@@ -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);

+64 −4
Original line number Diff line number Diff line
@@ -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
}
+17 −12
Original line number Diff line number Diff line
@@ -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;
	}
+16 −11
Original line number Diff line number Diff line
@@ -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;
	}
Loading