modem: chat: Add synchronous functions for script exec

This commit adds one new feature, modem_chat_run_script(),
which synchronously runs a script.

The existing function modem_chat_script_run() is async,
and doesn't follow the naming convention created for the
other modem modules, specifically, all functions are sync,
unless appended with _async.

To preserve backwards compatibility, the existing function
modem_chat_script_run() will remain until deprecated. It
simply calls modem_chat_run_script_async().

Signed-off-by: Bjarki Arge Andreasen <bjarkix123@gmail.com>
This commit is contained in:
Bjarki Arge Andreasen 2023-09-15 13:45:56 +02:00 committed by Fabio Baltieri
commit c9bc07a4f3
2 changed files with 64 additions and 9 deletions

View file

@ -227,6 +227,8 @@ struct modem_chat {
struct k_work script_abort_work;
uint16_t script_chat_it;
atomic_t script_state;
enum modem_chat_script_result script_result;
struct k_sem script_stopped_sem;
/* Script sending */
uint16_t script_send_request_pos;
@ -293,6 +295,18 @@ int modem_chat_init(struct modem_chat *chat, const struct modem_chat_config *con
*/
int modem_chat_attach(struct modem_chat *chat, struct modem_pipe *pipe);
/**
* @brief Run script asynchronously
* @param chat Chat instance
* @param script Script to run
* @returns 0 if script successfully started
* @returns -EBUSY if a script is currently running
* @returns -EPERM if modem pipe is not attached
* @returns -EINVAL if arguments or script is invalid
* @note Script runs asynchronously until complete or aborted.
*/
int modem_chat_run_script_async(struct modem_chat *chat, const struct modem_chat_script *script);
/**
* @brief Run script
* @param chat Chat instance
@ -301,9 +315,25 @@ int modem_chat_attach(struct modem_chat *chat, struct modem_pipe *pipe);
* @returns -EBUSY if a script is currently running
* @returns -EPERM if modem pipe is not attached
* @returns -EINVAL if arguments or script is invalid
* @note Script runs asynchronously until complete or aborted.
* @note Script runs until complete or aborted.
*/
int modem_chat_script_run(struct modem_chat *chat, const struct modem_chat_script *script);
int modem_chat_run_script(struct modem_chat *chat, const struct modem_chat_script *script);
/**
* @brief Run script asynchronously
* @note Function exists for backwards compatibility and should be deprecated
* @param chat Chat instance
* @param script Script to run
* @returns 0 if script successfully started
* @returns -EBUSY if a script is currently running
* @returns -EPERM if modem pipe is not attached
* @returns -EINVAL if arguments or script is invalid
*/
static inline int modem_chat_script_run(struct modem_chat *chat,
const struct modem_chat_script *script)
{
return modem_chat_run_script_async(chat, script);
}
/**
* @brief Abort script

View file

@ -69,9 +69,6 @@ static void modem_chat_script_stop(struct modem_chat *chat, enum modem_chat_scri
LOG_WRN("%s: timed out", chat->script->name);
}
/* Clear script running state */
atomic_clear_bit(&chat->script_state, MODEM_CHAT_SCRIPT_STATE_RUNNING_BIT);
/* Call back with result */
if (chat->script->callback != NULL) {
chat->script->callback(chat, result, chat->user_data);
@ -88,6 +85,15 @@ static void modem_chat_script_stop(struct modem_chat *chat, enum modem_chat_scri
/* Cancel timeout work */
k_work_cancel_delayable(&chat->script_timeout_work);
/* Clear script running state */
atomic_clear_bit(&chat->script_state, MODEM_CHAT_SCRIPT_STATE_RUNNING_BIT);
/* Store result of script for script stoppted indication */
chat->script_result = result;
/* Indicate script stopped */
k_sem_give(&chat->script_stopped_sem);
}
static void modem_chat_script_send(struct modem_chat *chat)
@ -680,9 +686,6 @@ static void modem_chat_pipe_callback(struct modem_pipe *pipe, enum modem_pipe_ev
}
}
/*********************************************************
* GLOBAL FUNCTIONS
*********************************************************/
int modem_chat_init(struct modem_chat *chat, const struct modem_chat_config *config)
{
__ASSERT_NO_MSG(chat != NULL);
@ -711,6 +714,7 @@ int modem_chat_init(struct modem_chat *chat, const struct modem_chat_config *con
chat->matches_size[MODEM_CHAT_MATCHES_INDEX_UNSOL] = config->unsol_matches_size;
chat->process_timeout = config->process_timeout;
atomic_set(&chat->script_state, 0);
k_sem_init(&chat->script_stopped_sem, 0, 1);
k_work_init_delayable(&chat->process_work, modem_chat_process_handler);
k_work_init(&chat->script_run_work, modem_chat_script_run_handler);
k_work_init_delayable(&chat->script_timeout_work, modem_chat_script_timeout_handler);
@ -730,7 +734,7 @@ int modem_chat_attach(struct modem_chat *chat, struct modem_pipe *pipe)
return 0;
}
int modem_chat_script_run(struct modem_chat *chat, const struct modem_chat_script *script)
int modem_chat_run_script_async(struct modem_chat *chat, const struct modem_chat_script *script)
{
bool script_is_running;
@ -764,6 +768,25 @@ int modem_chat_script_run(struct modem_chat *chat, const struct modem_chat_scrip
return 0;
}
int modem_chat_run_script(struct modem_chat *chat, const struct modem_chat_script *script)
{
int ret;
k_sem_reset(&chat->script_stopped_sem);
ret = modem_chat_run_script_async(chat, script);
if (ret < 0) {
return ret;
}
ret = k_sem_take(&chat->script_stopped_sem, K_FOREVER);
if (ret < 0) {
return ret;
}
return chat->script_result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS ? 0 : -EAGAIN;
}
void modem_chat_script_abort(struct modem_chat *chat)
{
k_work_submit(&chat->script_abort_work);
@ -789,6 +812,8 @@ void modem_chat_release(struct modem_chat *chat)
chat->script = NULL;
chat->script_chat_it = 0;
atomic_set(&chat->script_state, 0);
chat->script_result = MODEM_CHAT_SCRIPT_RESULT_ABORT;
k_sem_reset(&chat->script_stopped_sem);
chat->script_send_request_pos = 0;
chat->script_send_delimiter_pos = 0;
chat->parse_match = NULL;