modem: chat: implement helper defines/structs

Those helpers allow to define some typical kinds of chat matches and
scripts with more ease/less boilerplate.

Signed-off-by: Tomi Fontanilles <tomi.fontanilles@nordicsemi.no>
This commit is contained in:
Tomi Fontanilles 2024-04-22 16:19:35 +03:00 committed by Anas Nashif
parent d20889d26f
commit a986905df5
3 changed files with 36 additions and 21 deletions

View file

@ -78,17 +78,6 @@ struct quectel_lcx6g_data {
k_timeout_t pm_timeout;
};
#define MODEM_CHAT_SCRIPT_NO_ABORT_DEFINE(_sym, _script_chats, _callback, _timeout) \
static struct modem_chat_script _sym = { \
.name = #_sym, \
.script_chats = _script_chats, \
.script_chats_size = ARRAY_SIZE(_script_chats), \
.abort_matches = NULL, \
.abort_matches_size = 0, \
.callback = _callback, \
.timeout = _timeout, \
}
#ifdef CONFIG_PM_DEVICE
MODEM_CHAT_MATCH_DEFINE(pair003_success_match, "$PAIR001,003,0*38", "", NULL);
MODEM_CHAT_SCRIPT_CMDS_DEFINE(
@ -100,11 +89,10 @@ MODEM_CHAT_SCRIPT_NO_ABORT_DEFINE(suspend_script, suspend_script_cmds,
NULL, QUECTEL_LCX6G_SCRIPT_TIMEOUT_S);
#endif /* CONFIG_PM_DEVICE */
MODEM_CHAT_MATCH_DEFINE(any_match, "", "", NULL);
MODEM_CHAT_MATCH_DEFINE(pair062_ack_match, "$PAIR001,062,0*3F", "", NULL);
MODEM_CHAT_SCRIPT_CMDS_DEFINE(
resume_script_cmds,
MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR002*38", any_match),
MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR002*38", modem_chat_any_match),
MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,0,1*3F", pair062_ack_match),
MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,1,0*3F", pair062_ack_match),
MODEM_CHAT_SCRIPT_CMD_RESP("$PAIR062,2,0*3C", pair062_ack_match),

View file

@ -81,9 +81,15 @@ struct modem_chat_match {
#define MODEM_CHAT_MATCH_DEFINE(_sym, _match, _separators, _callback) \
const static struct modem_chat_match _sym = MODEM_CHAT_MATCH(_match, _separators, _callback)
/* Helper struct to match any response without callback. */
extern const struct modem_chat_match modem_chat_any_match;
#define MODEM_CHAT_MATCHES_DEFINE(_sym, ...) \
const static struct modem_chat_match _sym[] = {__VA_ARGS__}
/* Helper struct to match nothing. */
extern const struct modem_chat_match modem_chat_empty_matches[0];
/**
* @brief Modem chat script chat
*/
@ -118,18 +124,21 @@ struct modem_chat_script_chat {
.timeout = 0, \
}
#define MODEM_CHAT_SCRIPT_CMD_RESP_NONE(_request, _timeout) \
#define MODEM_CHAT_SCRIPT_CMD_RESP_NONE(_request, _timeout_ms) \
{ \
.request = (uint8_t *)(_request), \
.request_size = (uint16_t)(sizeof(_request) - 1), \
.response_matches = NULL, \
.response_matches_size = 0, \
.timeout = _timeout, \
.timeout = _timeout_ms, \
}
#define MODEM_CHAT_SCRIPT_CMDS_DEFINE(_sym, ...) \
const struct modem_chat_script_chat _sym[] = {__VA_ARGS__}
/* Helper struct to have no chat script command. */
extern const struct modem_chat_script_chat modem_chat_empty_script_chats[0];
enum modem_chat_script_result {
MODEM_CHAT_SCRIPT_RESULT_SUCCESS,
MODEM_CHAT_SCRIPT_RESULT_ABORT,
@ -166,7 +175,7 @@ struct modem_chat_script {
uint32_t timeout;
};
#define MODEM_CHAT_SCRIPT_DEFINE(_sym, _script_chats, _abort_matches, _callback, _timeout) \
#define MODEM_CHAT_SCRIPT_DEFINE(_sym, _script_chats, _abort_matches, _callback, _timeout_s) \
const static struct modem_chat_script _sym = { \
.name = #_sym, \
.script_chats = _script_chats, \
@ -174,9 +183,16 @@ struct modem_chat_script {
.abort_matches = _abort_matches, \
.abort_matches_size = ARRAY_SIZE(_abort_matches), \
.callback = _callback, \
.timeout = _timeout, \
.timeout = _timeout_s, \
}
#define MODEM_CHAT_SCRIPT_NO_ABORT_DEFINE(_sym, _script_chats, _callback, _timeout_s) \
MODEM_CHAT_SCRIPT_DEFINE(_sym, _script_chats, modem_chat_empty_matches, \
_callback, _timeout_s)
#define MODEM_CHAT_SCRIPT_EMPTY_DEFINE(_sym) \
MODEM_CHAT_SCRIPT_NO_ABORT_DEFINE(_sym, modem_chat_empty_script_chats, NULL, 0)
enum modem_chat_script_send_state {
/* No data to send */
MODEM_CHAT_SCRIPT_SEND_STATE_IDLE,

View file

@ -12,6 +12,10 @@ LOG_MODULE_REGISTER(modem_chat, CONFIG_MODEM_MODULES_LOG_LEVEL);
#include <zephyr/modem/chat.h>
const struct modem_chat_match modem_chat_any_match = MODEM_CHAT_MATCH("", "", NULL);
const struct modem_chat_match modem_chat_empty_matches[0];
const struct modem_chat_script_chat modem_chat_empty_script_chats[0];
#define MODEM_CHAT_MATCHES_INDEX_RESPONSE (0)
#define MODEM_CHAT_MATCHES_INDEX_ABORT (1)
#define MODEM_CHAT_MATCHES_INDEX_UNSOL (2)
@ -227,7 +231,7 @@ static bool modem_chat_script_chat_is_no_response(struct modem_chat *chat)
const struct modem_chat_script_chat *script_chat =
&chat->script->script_chats[chat->script_chat_it];
return (script_chat->response_matches_size == 0) ? true : false;
return (script_chat->response_matches_size == 0);
}
static uint16_t modem_chat_script_chat_get_send_timeout(struct modem_chat *chat)
@ -267,6 +271,9 @@ static bool modem_chat_send_script_request_part(struct modem_chat *chat)
request_part_size = request_size - chat->script_send_pos;
ret = modem_pipe_transmit(chat->pipe, request_part, request_part_size);
if (ret < 1) {
if (ret < 0) {
LOG_ERR("Failed to %s %u bytes. (%d)", "transmit", request_part_size, ret);
}
return false;
}
@ -754,8 +761,12 @@ int modem_chat_run_script_async(struct modem_chat *chat, const struct modem_chat
}
/* Validate script */
if ((script->script_chats == NULL) || (script->script_chats_size == 0) ||
((script->abort_matches != NULL) && (script->abort_matches_size == 0))) {
if (script->script_chats == NULL ||
(script->script_chats_size == 0
&& script->script_chats != modem_chat_empty_script_chats) ||
(script->abort_matches_size == 0
&& script->abort_matches != NULL
&& script->abort_matches != modem_chat_empty_matches)) {
return -EINVAL;
}
@ -795,7 +806,7 @@ int modem_chat_run_script(struct modem_chat *chat, const struct modem_chat_scrip
return ret;
}
return chat->script_result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS ? 0 : -EAGAIN;
return (chat->script_result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS) ? 0 : -EAGAIN;
}
void modem_chat_script_abort(struct modem_chat *chat)