diff --git a/subsys/bluetooth/host/at.c b/subsys/bluetooth/host/at.c index 97adc381b0b..3baad1c0236 100644 --- a/subsys/bluetooth/host/at.c +++ b/subsys/bluetooth/host/at.c @@ -27,6 +27,13 @@ #include "at.h" +static void next_stream(struct at_client *at) +{ + if (at->buf[at->pos] == ',') { + at->pos++; + } +} + int at_check_byte(struct net_buf *buf, char check_byte) { const char *str = buf->data; @@ -60,6 +67,7 @@ int at_get_number(struct at_client *at, uint32_t *val) return -ENODATA; } + next_stream(at); return 0; } @@ -339,6 +347,105 @@ int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, return 0; } +int at_has_next_stream(struct at_client *at) +{ + return at->buf[at->pos] != '\0'; +} + +int at_open_stream(struct at_client *at) +{ + skip_whitespace(at); + + /* The stream shall start with '(' open parenthesis */ + if (at->buf[at->pos] != '(') { + return -ENODATA; + } + at->pos++; + + return 0; +} + +int at_close_stream(struct at_client *at) +{ + skip_whitespace(at); + + if (at->buf[at->pos] != ')') { + return -ENODATA; + } + at->pos++; + + next_stream(at); + + return 0; +} + +int at_stream_get_string(struct at_client *at, char *name, uint8_t len) +{ + int i = 0; + + skip_whitespace(at); + + if (at->buf[at->pos] != '"') { + return -ENODATA; + } + at->pos++; + + while (at->buf[at->pos] != '\0' && at->buf[at->pos] != '"') { + if (i == len) { + return -ENODATA; + } + name[i++] = at->buf[at->pos++]; + } + + if (i == len) { + return -ENODATA; + } + + name[i] = '\0'; + + if (at->buf[at->pos] != '"') { + return -ENODATA; + } + at->pos++; + + skip_whitespace(at); + next_stream(at); + + return 0; +} + +int at_stream_get_range(struct at_client *at, uint32_t *min, uint32_t *max) +{ + uint32_t low, high; + int ret; + + ret = at_get_number(at, &low); + if (ret < 0) { + return ret; + } + + if (at->buf[at->pos] == '-') { + at->pos++; + goto out; + } + + if (!isdigit(at->buf[at->pos])) { + return -ENODATA; + } +out: + ret = at_get_number(at, &high); + if (ret < 0) { + return ret; + } + + *min = low; + *max = high; + + next_stream(at); + + return 0; +} + void at_register(struct at_client *at, at_resp_cb_t resp, at_finish_cb_t finish) { at->resp = resp; diff --git a/subsys/bluetooth/host/at.h b/subsys/bluetooth/host/at.h index 96a334cad45..b1dff110549 100644 --- a/subsys/bluetooth/host/at.h +++ b/subsys/bluetooth/host/at.h @@ -80,3 +80,8 @@ int at_parse_input(struct at_client *at, struct net_buf *buf); int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, const char *prefix, parse_val_t func); int at_check_byte(struct net_buf *buf, char check_byte); +int at_stream_get_range(struct at_client *at, uint32_t *min, uint32_t *max); +int at_stream_get_string(struct at_client *at, char *name, uint8_t len); +int at_close_stream(struct at_client *at); +int at_open_stream(struct at_client *at); +int at_has_next_stream(struct at_client *at);