diff options
author | Zhenhua Zhang <zhenhua.zhang@intel.com> | 2010-03-24 09:47:30 +0800 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2010-03-24 16:02:10 -0500 |
commit | 7c8fa919fa5ea1111606331b4b0fb6b024be32ac (patch) | |
tree | e80264e0c85cfc5edbf55f03fad7f0a90bc6e347 /gatchat/gatserver.c | |
parent | c1c3b5502e082d186ce6be5a40e1f9f2a0e861b5 (diff) | |
download | ofono-7c8fa919fa5ea1111606331b4b0fb6b024be32ac.tar.bz2 |
Add basic command parsing
Diffstat (limited to 'gatchat/gatserver.c')
-rw-r--r-- | gatchat/gatserver.c | 112 |
1 files changed, 111 insertions, 1 deletions
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index 6579b389..72abb00a 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -308,9 +308,119 @@ next: return i + 1; } +static gboolean get_basic_prefix(const char *buf, char *prefix) +{ + char c = *buf; + + if (!g_ascii_isalpha(c) && c != '&') + return FALSE; + + if (g_ascii_isalpha(c)) { + c = g_ascii_toupper(c); + if (c == 'S') { + int i = 0; + + prefix[0] = 'S'; + + /* V.250 5.3.2 'S' command follows with a parameter + * number. Limited to two digits since 100 + * S-registers should be enough. + */ + while (i <= 2 && g_ascii_isdigit(buf[++i])) + prefix[i] = buf[i]; + + prefix[i] = '\0'; + } else { + prefix[0] = c; + prefix[1] = '\0'; + } + } else if (c == '&') { + prefix[0] = '&'; + prefix[1] = g_ascii_toupper(buf[1]); + prefix[2] = '\0'; + } + + return TRUE; +} + static unsigned int parse_basic_command(GAtServer *server, char *buf) { - return 0; + char *command; + char prefix[4]; + unsigned int i; + GAtServerRequestType type; + gboolean seen_equals = FALSE; + + if (!get_basic_prefix(buf, prefix)) + return 0; + + i = strlen(prefix); + + if (*prefix == 'D') { + type = G_AT_SERVER_REQUEST_TYPE_SET; + + /* All characters appearing on the same line, up to a + * semicolon character (IA5 3/11) or the end of the + * command line is the part of the call. + */ + while (buf[i] != '\0' || buf[i] != ';') + i += 1; + + goto done; + } + + if (buf[i] == '\0' || buf[i] == ';') { + type = G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY; + goto done; + } + + /* Additional commands may follow a command without any character + * required for separation. + */ + if (is_basic_command_prefix(&buf[i])) { + type = G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY; + goto done; + } + + /* Match '?', '=', '=?' and '=xxx' */ + if (buf[i] == '=') { + seen_equals = TRUE; + i += 1; + } + + if (buf[i] == '?') { + i += 1; + + if (seen_equals) + type = G_AT_SERVER_REQUEST_TYPE_SUPPORT; + else + type = G_AT_SERVER_REQUEST_TYPE_QUERY; + } else { + /* V.250 5.3.1 The subparameter (if any) are all digits */ + while (g_ascii_isdigit(buf[i])) + i++; + + type = G_AT_SERVER_REQUEST_TYPE_SET; + } + +done: + command = g_strndup(buf, i); + + at_command_notify(server, command, prefix, type); + + g_free(command); + + /* Commands like ATA, ATZ cause the remainder line + * to be ignored. + */ + if (*prefix == 'A' || *prefix == 'Z') + return strlen(buf); + + /* Consumed the seperator ';' */ + if (buf[i] == ';') + i += 1; + + return i; } static void server_parse_line(GAtServer *server, char *line) |