1. The parser fetches one basic or extended command per iteration.
The prefix is the command prefix without parameter. For example, in
command "AT+CLIP=1", prefix is "+CLIP".
2. Search registered notification node in command_list. If found,
get command type and invoke callback, and then return result.
3. Termiate the execution if the result in an error. Otherwise,
fetch next command.
---
gatchat/gatserver.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 94 insertions(+), 1 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 4175112..c54170e 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -173,9 +173,99 @@ static void g_at_server_send_result(GAtServer *server,
GAtServerResult result)
send_common(server, buf, MIN(len, sizeof(buf)-1));
}
+static inline gboolean is_extended_command_prefix(const char c)
+{
+ switch (c) {
+ case '+':
+ case '*':
+ case '!':
+ case '%':
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static gboolean is_basic_command_prefix(char *buf)
+{
+ if (g_ascii_isalpha(buf[0]))
+ return TRUE;
+
+ if (buf[0] == '&' && g_ascii_isalpha(buf[1]))
+ return TRUE;
+
+ return FALSE;
+}
+
+static GAtServerResult at_notify_callback(GAtServer *server, char *command,
+ char *prefix)
+{
+ int res = G_AT_SERVER_RESULT_ERROR;
+
+ return res;
+}
+
+static char *parse_extended_command(GAtServer *server, char *buf,
+ char *prefix)
+{
+ return NULL;
+}
+
+static char *parse_basic_command(GAtServer *server, char *buf, char *prefix)
+{
+ return NULL;
+}
+
+static char *server_parse_next_command(GAtServer *server, char *buf,
+ char *prefix)
+{
+ char *command = NULL;
+
+ if (is_extended_command_prefix(*buf))
+ command = parse_extended_command(server, buf, prefix);
+ else if (is_basic_command_prefix(buf))
+ command = parse_basic_command(server, buf, prefix);
+
+ return command;
+}
+
static GAtServerResult server_parse_line(GAtServer *server, char *line)
{
GAtServerResult res = G_AT_SERVER_RESULT_ERROR;
+ char *command = NULL;
+ char prefix[20];
+
+ while (line) {
+ if (*line == '\0') {
+ res = G_AT_SERVER_RESULT_OK;
+ break;
+ }
+
+ /* skip semicolon */
+ if (*line == ';')
+ line++;
+
+ memset(prefix, 0, sizeof(prefix));
+
+ command = server_parse_next_command(server, line, prefix);
+ if (!command) {
+ res = G_AT_SERVER_RESULT_ERROR;
+ break;
+ }
+
+ res = at_notify_callback(server, command, prefix);
+ /* Termiate the execution if command result in an error */
+ if (res != G_AT_SERVER_RESULT_OK)
+ break;
+
+ line += strlen(command);
+
+ g_free(command);
+ command = NULL;
+ }
+
+ if (command)
+ g_free(command);
return res;
}
@@ -331,6 +421,7 @@ static void new_bytes(GAtServer *p)
unsigned char *buf = ring_buffer_read_ptr(p->read_buf, p->read_so_far);
enum ParserState state;
GAtServerResult result;
+ char *line;
while (p->channel && (p->read_so_far < len)) {
gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
@@ -361,8 +452,10 @@ static void new_bytes(GAtServer *p)
break;
case PARSER_RESULT_COMMAND:
- result = server_parse_line(p, extract_line(p));
+ line = extract_line(p);
+ result = server_parse_line(p, line);
g_at_server_send_result(p, result);
+ g_free(line);
break;
case PARSER_RESULT_REPEAT_LAST:
--
1.6.6.1