From 9abbc61e4a4ecca37b2fffdeac99af77a3498602 Mon Sep 17 00:00:00 2001 From: Sathish Narasimman Date: Mon, 14 Nov 2016 13:36:01 +0530 Subject: [PATCH] Bluetooth: AT: Command parsing for range of values This patch contains API's which is used to parse range of values eg. (0,3). This patch also parses the string, reads, process and move the buffer accordingly. Change-Id: I8dba5b7d630f65b87967c101557c5c7ffd297dd1 Signed-off-by: Sathish Narasimman --- subsys/bluetooth/host/at.c | 107 +++++++++++++++++++++++++++++++++++++ subsys/bluetooth/host/at.h | 5 ++ 2 files changed, 112 insertions(+) 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);