modem: chat: Add runtime API to modem chat matches

Add APIs for changing the contents of modem chat matches
safely at runtime.

This allows for reusing a single modem_chat_match at the cost
of placing the match and its buffers in RAM.

Signed-off-by: Bjarki Arge Andreasen <bjarki@arge-andreasen.me>
This commit is contained in:
Bjarki Arge Andreasen 2024-02-27 09:02:37 +01:00 committed by Alberto Escolar
parent ab8c0dd3c0
commit 8b4822861b
3 changed files with 134 additions and 2 deletions

View File

@ -45,9 +45,9 @@ struct modem_chat_match {
/** Size of separators array */
uint8_t separators_size;
/** Set if modem chat instance shall use wildcards when matching */
uint8_t wildcards : 1;
bool wildcards;
/** Set if script shall not continue to next step in case of match */
uint8_t partial : 1;
bool partial;
/** Type of modem chat instance */
modem_chat_match_callback callback;
};
@ -376,6 +376,56 @@ void modem_chat_script_abort(struct modem_chat *chat);
*/
void modem_chat_release(struct modem_chat *chat);
/**
* @brief Initialize modem chat match
* @param chat_match Modem chat match instance
*/
void modem_chat_match_init(struct modem_chat_match *chat_match);
/**
* @brief Set match of modem chat match instance
* @param chat_match Modem chat match instance
* @param match Match to set
* @note The lifetime of match must match or exceed the lifetime of chat_match
* @warning Always call this API after match is modified
*
* @retval 0 if successful, negative errno code otherwise
*/
int modem_chat_match_set_match(struct modem_chat_match *chat_match, const char *match);
/**
* @brief Set separators of modem chat match instance
* @param chat_match Modem chat match instance
* @param separators Separators to set
* @note The lifetime of separators must match or exceed the lifetime of chat_match
* @warning Always call this API after separators are modified
*
* @retval 0 if successful, negative errno code otherwise
*/
int modem_chat_match_set_separators(struct modem_chat_match *chat_match, const char *separators);
/**
* @brief Set modem chat match callback
* @param chat_match Modem chat match instance
* @param callback Callback to set
*/
void modem_chat_match_set_callback(struct modem_chat_match *chat_match,
modem_chat_match_callback callback);
/**
* @brief Set modem chat match partial flag
* @param chat_match Modem chat match instance
* @param partial Partial flag to set
*/
void modem_chat_match_set_partial(struct modem_chat_match *chat_match, bool partial);
/**
* @brief Set modem chat match wildcards flag
* @param chat_match Modem chat match instance
* @param enable Enable/disable Wildcards
*/
void modem_chat_match_enable_wildcards(struct modem_chat_match *chat_match, bool enable);
#ifdef __cplusplus
}
#endif

View File

@ -4,6 +4,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(modem_chat, CONFIG_MODEM_MODULES_LOG_LEVEL);
@ -929,3 +932,54 @@ void modem_chat_release(struct modem_chat *chat)
chat->matches[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = NULL;
chat->matches_size[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = 0;
}
void modem_chat_match_init(struct modem_chat_match *chat_match)
{
memset(chat_match, 0, sizeof(struct modem_chat_match));
}
int modem_chat_match_set_match(struct modem_chat_match *chat_match, const char *match)
{
size_t size;
size = strnlen(match, UINT8_MAX + 1);
if (size == (UINT8_MAX + 1)) {
return -ENOMEM;
}
chat_match->match = match;
chat_match->match_size = (uint8_t)size;
return 0;
}
int modem_chat_match_set_separators(struct modem_chat_match *chat_match, const char *separators)
{
size_t size;
size = strnlen(separators, UINT8_MAX + 1);
if (size == (UINT8_MAX + 1)) {
return -ENOMEM;
}
chat_match->separators = separators;
chat_match->separators_size = (uint8_t)size;
return 0;
}
void modem_chat_match_set_callback(struct modem_chat_match *match,
modem_chat_match_callback callback)
{
match->callback = callback;
}
void modem_chat_match_set_partial(struct modem_chat_match *match, bool partial)
{
match->partial = partial;
}
void modem_chat_match_enable_wildcards(struct modem_chat_match *match, bool enable)
{
match->wildcards = enable;
}

View File

@ -676,6 +676,34 @@ ZTEST(modem_chat, test_script_chat_timeout_cmd)
"Script sent too many requests");
}
ZTEST(modem_chat, test_runtime_match)
{
int ret;
struct modem_chat_match test_match;
modem_chat_match_init(&test_match);
ret = modem_chat_match_set_match(&test_match, "AT345");
zassert_ok(ret, "Failed to set match");
zassert_ok(strcmp(test_match.match, "AT345"), "Failed to set match");
zassert_equal(test_match.match_size, 5, "Failed to set size of match");
ret = modem_chat_match_set_separators(&test_match, ",*");
zassert_ok(ret, "Failed to set match");
zassert_ok(strcmp(test_match.separators, ",*"), "Failed to set separators");
zassert_equal(test_match.separators_size, 2, "Failed to set size of separators");
modem_chat_match_set_partial(&test_match, true);
zassert_equal(test_match.partial, true);
modem_chat_match_set_partial(&test_match, false);
zassert_equal(test_match.partial, false);
modem_chat_match_enable_wildcards(&test_match, true);
zassert_equal(test_match.wildcards, true);
modem_chat_match_enable_wildcards(&test_match, false);
zassert_equal(test_match.wildcards, false);
}
/*************************************************************************************************/
/* Test suite */
/*************************************************************************************************/