1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 04:52:59 +01:00

drivers/at: add URC registering and parsing feature

This commit is contained in:
Vincent Dupont 2018-06-26 10:03:10 -07:00
parent 011b80cb92
commit 3393888cea
3 changed files with 106 additions and 0 deletions

View File

@ -266,3 +266,52 @@ out:
}
return res;
}
#ifdef MODULE_AT_URC
void at_add_urc(at_dev_t *dev, at_urc_t *urc)
{
assert(urc);
assert(urc->code);
assert(strlen(urc->code) != 0);
assert(urc->cb);
clist_rpush(&dev->urc_list, &urc->list_node);
}
void at_remove_urc(at_dev_t *dev, at_urc_t *urc)
{
clist_remove(&dev->urc_list, &urc->list_node);
}
static int _check_urc(clist_node_t *node, void *arg)
{
const char *buf = arg;
at_urc_t *urc = container_of(node, at_urc_t, list_node);
DEBUG("Trying to match with %s\n", urc->code);
if (strncmp(buf, urc->code, strlen(urc->code)) == 0) {
urc->cb(urc->arg, buf);
return 1;
}
return 0;
}
void at_process_urc(at_dev_t *dev, uint32_t timeout)
{
char buf[AT_BUF_SIZE];
DEBUG("Processing URC (timeout=%" PRIu32 "us)\n", timeout);
ssize_t res;
/* keep reading while received data are shorter than EOL */
while ((res = at_readline(dev, buf, sizeof(buf), true, timeout)) <
(ssize_t)sizeof(AT_RECV_EOL_1 AT_RECV_EOL_2) - 1) {
if (res < 0) {
return;
}
}
clist_foreach(&dev->urc_list, _check_urc, buf);
}
#endif

View File

@ -39,6 +39,7 @@
#include "isrpipe.h"
#include "periph/uart.h"
#include "clist.h"
#ifdef __cplusplus
extern "C" {
@ -77,12 +78,41 @@ extern "C" {
#define AT_RECV_ERROR "ERROR"
#endif
#if defined(MODULE_AT_URC) || DOXYGEN
#ifndef AT_BUF_SIZE
/** Internal buffer size used to process unsolicited result code data */
#define AT_BUF_SIZE (128)
#endif
/**
* @brief Unsolicited result code callback
*
* @param[in] arg optional argument
* @param[in] code urc string received from the device
*/
typedef void (*at_urc_cb_t)(void *arg, const char *code);
/**
* @brief Unsolicited result code data structure
*/
typedef struct {
clist_node_t list_node; /**< node list */
at_urc_cb_t cb; /**< callback */
const char *code; /**< URC string which must match */
void *arg; /**< optional argument */
} at_urc_t;
#endif /* MODULE_AT_URC */
/**
* @brief AT device structure
*/
typedef struct {
isrpipe_t isrpipe; /**< isrpipe used for getting data from uart */
uart_t uart; /**< UART device where the AT device is attached */
#ifdef MODULE_AT_URC
clist_node_t urc_list; /**< list to keep track of all registered urc's */
#endif
} at_dev_t;
/**
@ -226,6 +256,32 @@ ssize_t at_readline(at_dev_t *dev, char *resp_buf, size_t len, bool keep_eol, ui
*/
void at_drain(at_dev_t *dev);
#if defined(MODULE_AT_URC) || DOXYGEN
/**
* @brief Add a callback for an unsolicited response code
*
* @param[in] dev device to operate on
* @param[in] urc unsolicited result code to register
*/
void at_add_urc(at_dev_t *dev, at_urc_t *urc);
/**
* @brief Remove an unsolicited response code from the list
*
* @param[in] dev device to operate on
* @param[in] urc unsolicited result code to remove
*/
void at_remove_urc(at_dev_t *dev, at_urc_t *urc);
/**
* @brief Process out-of-band data received from the device
*
* @param[in] dev device to operate on
* @param[in] timeout timeout (in usec)
*/
void at_process_urc(at_dev_t *dev, uint32_t timeout);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,3 +1,4 @@
PSEUDOMODULES += at_urc
PSEUDOMODULES += auto_init_gnrc_rpl
PSEUDOMODULES += can_mbox
PSEUDOMODULES += can_pm