* Add parse framework for GAtServer
@ 2010-03-19 9:44 Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 01/10] Add framework of server parser Zhenhua Zhang
0 siblings, 1 reply; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 64 bytes --]
Update patches based on comments and rebase with latest git.
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 01/10] Add framework of server parser
2010-03-19 9:44 Add parse framework for GAtServer Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 02/10] Add basic command parsing Zhenhua Zhang
2010-03-22 18:02 ` [PATCH 01/10] Add framework of server parser Denis Kenzior
0 siblings, 2 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2293 bytes --]
a. The parser fetch and parse one command per loop. The prefix is
the command prefix without parameter. For example, the prefix of
"AT+CLIP=1" is "+CLIP".
b. Search registered notification node in command_list. Invoke the
callback if found.
c. Termiate the execution if the result is an error. Otherwise,
parse next command.
---
gatchat/gatserver.c | 46 ++++++++++++++++++++++++++--------------------
1 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 4df3f06..8e7955c 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -197,42 +197,48 @@ static gboolean is_basic_command_prefix(const char *buf)
return FALSE;
}
-static void parse_extended_command(GAtServer *server, char *buf)
+static void parse_extended_command(GAtServer *server, char *buf,
+ unsigned int *len)
{
g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
}
-static void parse_basic_command(GAtServer *server, char *buf)
+static void parse_basic_command(GAtServer *server, char *buf,
+ unsigned int *len)
{
g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
}
static void server_parse_line(GAtServer *server, char *line)
{
- gsize i = 0;
- char c;
-
- if (line == NULL) {
- g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
- goto done;
- }
+ char *buf = line;
- if (line[0] == '\0') {
+ if (*buf == '\0') {
g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
goto done;
}
- c = line[i];
- /* skip semicolon */
- if (c == ';')
- c = line[++i];
+ while (*buf) {
+ unsigned int len = 0;
+ char c = *buf;
- if (is_extended_command_prefix(c))
- parse_extended_command(server, line + i);
- else if (is_basic_command_prefix(line + i))
- parse_basic_command(server, line + i);
- else
- g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+ /* skip semicolon */
+ if (c == ';')
+ c = *(++buf);
+
+ if (c == '\0')
+ break;
+
+ if (is_extended_command_prefix(c))
+ parse_extended_command(server, buf, &len);
+ else if (is_basic_command_prefix(buf))
+ parse_basic_command(server, buf, &len);
+
+ if (len == 0)
+ break;
+
+ buf += len;
+ }
done:
g_free(line);
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 02/10] Add basic command parsing
2010-03-19 9:44 ` [PATCH 01/10] Add framework of server parser Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 03/10] Add extended " Zhenhua Zhang
2010-03-22 18:19 ` [PATCH 02/10] Add basic " Denis Kenzior
2010-03-22 18:02 ` [PATCH 01/10] Add framework of server parser Denis Kenzior
1 sibling, 2 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2820 bytes --]
According to V.250 5.3.1, the basic command is either a single
character or the '&' followed by a single character.
---
gatchat/gatserver.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 8e7955c..2c53d84 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -197,16 +197,111 @@ static gboolean is_basic_command_prefix(const char *buf)
return FALSE;
}
+static gboolean at_command_notify(GAtServer *server, char *command,
+ char *prefix)
+{
+ return FALSE;
+}
+
static void parse_extended_command(GAtServer *server, char *buf,
unsigned int *len)
{
g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
}
-static void parse_basic_command(GAtServer *server, char *buf,
+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.
+ */
+ while (g_ascii_isdigit(buf[++i]))
+ prefix[i] = buf[i];
+
+ prefix[i] = '\0';
+ } else {
+ prefix[0] = c;
+ prefix[1] = '\0';
+ }
+ }
+
+ if (c == '&') {
+ prefix[0] = '&';
+ prefix[1] = g_ascii_toupper(buf[1]);
+ prefix[2] = '\0';
+ }
+
+ return TRUE;
+}
+
+static unsigned int get_basic_length(const char *buf, char *prefix, char t)
+{
+ unsigned int i;
+
+ i = strlen(prefix);
+
+ if (*buf == 'D' || *buf == 'd') {
+ /* All following characters are the part of the call */
+ while (buf[i] && buf[i] != t)
+ i++;
+ } else {
+ /* Match '?', '=', '=?' or '=123' */
+ if (buf[i] == '=')
+ i++;
+
+ if (buf[i] == '?')
+ i++;
+ else {
+ /* V.250 5.3.1 The subparameter are all digits */
+ while (g_ascii_isdigit(buf[i]))
+ i++;
+ }
+ }
+
+ return i;
+}
+
+static void parse_basic_command(GAtServer *server, const char *buf,
unsigned int *len)
{
- g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+ char *command = NULL;
+ char prefix[20];
+ unsigned int i = 0;
+
+ if (!get_basic_prefix(buf, prefix))
+ goto done;
+
+ i = get_basic_length(buf, prefix, server->v250.s3);
+
+ command = g_strndup(buf, i);
+
+ if (!at_command_notify(server, command, prefix)) {
+ i = 0;
+ goto done;
+ }
+
+ /* Commands like ATA, ATD, ATZ cause the remainder line
+ * to be ignored.
+ */
+ if (*prefix == 'A' || *prefix == 'D' || *prefix == 'Z')
+ i = 0;
+
+done:
+ if (command)
+ g_free(command);
+
+ *len = i;
}
static void server_parse_line(GAtServer *server, char *line)
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 03/10] Add extended command parsing
2010-03-19 9:44 ` [PATCH 02/10] Add basic command parsing Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 04/10] Add server at command data structure Zhenhua Zhang
2010-03-22 18:01 ` [PATCH 03/10] Add extended command parsing Denis Kenzior
2010-03-22 18:19 ` [PATCH 02/10] Add basic " Denis Kenzior
1 sibling, 2 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1862 bytes --]
---
gatchat/gatserver.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 2c53d84..0658553 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -197,16 +197,77 @@ static gboolean is_basic_command_prefix(const char *buf)
return FALSE;
}
+static gboolean is_extended_character(const char c)
+{
+ if (g_ascii_isalpha(c))
+ return TRUE;
+
+ if (g_ascii_isdigit(c))
+ return TRUE;
+
+ switch (c) {
+ case '!':
+ case '%':
+ case '-':
+ case '.':
+ case '/':
+ case ':':
+ case '_':
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
static gboolean at_command_notify(GAtServer *server, char *command,
char *prefix)
{
return FALSE;
}
-static void parse_extended_command(GAtServer *server, char *buf,
+static gboolean get_extended_prefix(const char *buf, char *prefix)
+{
+ char c;
+ int i = 0;
+
+ /* Skip '+' */
+ prefix[0] = buf[0];
+
+ while ((c = buf[++i])) {
+ /* V.250 5.4.1 Extended command naming rules */
+ if (!is_extended_character(c))
+ break;
+
+ prefix[i] = g_ascii_toupper(c);
+ }
+
+ prefix[i] = '\0';
+
+ return TRUE;
+}
+
+static void parse_extended_command(GAtServer *server, const char *buf,
unsigned int *len)
{
- g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+ char *command = NULL;
+ char prefix[20];
+ char t = server->v250.s3;
+ char c = *buf;
+ int i = 0;
+
+ while (c && c != t && c != ';')
+ c = buf[++i];
+
+ command = g_strndup(buf, i);
+
+ get_extended_prefix(command, prefix);
+
+ if (at_command_notify(server, command, prefix))
+ *len = i;
+ else
+ *len = 0;
+
+ g_free(command);
}
static gboolean get_basic_prefix(const char *buf, char *prefix)
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 04/10] Add server at command data structure
2010-03-19 9:44 ` [PATCH 03/10] Add extended " Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 05/10] Add notify at command callback Zhenhua Zhang
2010-03-22 18:22 ` [PATCH 04/10] Add server at command data structure Denis Kenzior
2010-03-22 18:01 ` [PATCH 03/10] Add extended command parsing Denis Kenzior
1 sibling, 2 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3605 bytes --]
---
gatchat/gatserver.c | 27 +++++++++++++++++++++++++++
gatchat/gatserver.h | 22 ++++++++++++++++++++++
2 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 0658553..6173765 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -88,6 +88,13 @@ struct v250_settings {
unsigned int c108; /* set by &D<val> */
};
+/* AT command set that server supported */
+struct at_command {
+ GAtServerNotifyFunc notify;
+ gpointer user_data;
+ GDestroyNotify destroy_notify;
+};
+
struct _GAtServer {
gint ref_count; /* Ref count */
struct v250_settings v250; /* V.250 command setting */
@@ -99,6 +106,7 @@ struct _GAtServer {
gpointer user_disconnect_data; /* User disconnect data */
GAtDebugFunc debugf; /* Debugging output function */
gpointer debug_data; /* Data to pass to debug func */
+ GHashTable *command_list; /* List of AT commands */
struct ring_buffer *read_buf; /* Current read buffer */
GQueue *write_queue; /* Write buffer queue */
guint max_read_attempts; /* Max reads per select */
@@ -740,6 +748,9 @@ static void g_at_server_cleanup(GAtServer *server)
/* Cleanup pending data to write */
write_queue_free(server->write_queue);
+ g_hash_table_destroy(server->command_list);
+ server->command_list = NULL;
+
server->channel = NULL;
}
@@ -785,6 +796,16 @@ static void v250_settings_create(struct v250_settings *v250)
v250->c108 = 0;
}
+static void at_notify_node_destroy(gpointer data)
+{
+ struct at_command *node = data;
+
+ if (node->destroy_notify)
+ node->destroy_notify(node->user_data);
+
+ g_free(node);
+}
+
GAtServer *g_at_server_new(GIOChannel *io)
{
GAtServer *server;
@@ -799,6 +820,9 @@ GAtServer *g_at_server_new(GIOChannel *io)
server->ref_count = 1;
v250_settings_create(&server->v250);
server->channel = io;
+ server->command_list = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free,
+ at_notify_node_destroy);
server->read_buf = ring_buffer_new(BUF_SIZE);
if (!server->read_buf)
goto error;
@@ -823,6 +847,9 @@ GAtServer *g_at_server_new(GIOChannel *io)
return server;
error:
+ if (server->command_list)
+ g_hash_table_destroy(server->command_list);
+
if (server->read_buf)
ring_buffer_free(server->read_buf);
diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h
index 698f7e0..1c12a0d 100644
--- a/gatchat/gatserver.h
+++ b/gatchat/gatserver.h
@@ -26,6 +26,7 @@
extern "C" {
#endif
+#include "gatresult.h"
#include "gatutil.h"
struct _GAtServer;
@@ -46,6 +47,27 @@ enum _GAtServerResult {
typedef enum _GAtServerResult GAtServerResult;
+/* Types of AT command:
+ * COMMAND_ONLY: command without any sub-parameters, e.g. ATA, AT+CLCC
+ * QUERY: command followed by '?', e.g. AT+CPIN?
+ * SUPPORT: command followed by '=?', e.g. AT+CSMS=?
+ * SET: command followed by '=', e.g. AT+CLIP=1
+ * or, basic command followed with sub-parameters, e.g. ATD12345;
+ */
+enum _GAtServerRequestType {
+ G_AT_SERVER_REQUEST_TYPE_ERROR,
+ G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY,
+ G_AT_SERVER_REQUEST_TYPE_QUERY,
+ G_AT_SERVER_REQUEST_TYPE_SUPPORT,
+ G_AT_SERVER_REQUEST_TYPE_SET,
+};
+
+typedef enum _GAtServerRequestType GAtServerRequestType;
+
+typedef GAtServerResult (*GAtServerNotifyFunc)(GAtServerRequestType type,
+ GAtResult *result,
+ gpointer user_data);
+
GAtServer *g_at_server_new(GIOChannel *io);
GAtServer *g_at_server_ref(GAtServer *server);
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 05/10] Add notify at command callback
2010-03-19 9:44 ` [PATCH 04/10] Add server at command data structure Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 06/10] Add g_at_server_register and unregister callback Zhenhua Zhang
2010-03-22 18:22 ` [PATCH 05/10] Add notify at command callback Denis Kenzior
2010-03-22 18:22 ` [PATCH 04/10] Add server at command data structure Denis Kenzior
1 sibling, 2 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1831 bytes --]
---
gatchat/gatserver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 6173765..3f60f1c 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -227,9 +227,57 @@ static gboolean is_extended_character(const char c)
}
}
+static GAtServerRequestType get_command_type(char *buf, char *prefix)
+{
+ GAtServerRequestType type = G_AT_SERVER_REQUEST_TYPE_ERROR;
+
+ buf += strlen(prefix);
+
+ if (buf[0] == '\0')
+ /* Action command could have no sub-parameters */
+ type = G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY;
+ else if (buf[0] == '?')
+ type = G_AT_SERVER_REQUEST_TYPE_QUERY;
+ else if (buf[0] == '=' && buf[1] == '?')
+ type = G_AT_SERVER_REQUEST_TYPE_SUPPORT;
+ else if (buf[0] == '=')
+ type = G_AT_SERVER_REQUEST_TYPE_SET;
+ else if (is_basic_command_prefix(prefix))
+ /* Basic command could follow digits value, like ATE1 */
+ type = G_AT_SERVER_REQUEST_TYPE_SET;
+
+ return type;
+}
+
static gboolean at_command_notify(GAtServer *server, char *command,
char *prefix)
{
+ GAtServerResult res = G_AT_SERVER_RESULT_ERROR;
+ struct at_command *node;
+
+ node = g_hash_table_lookup(server->command_list, prefix);
+ if (node && node->notify) {
+ GAtServerRequestType type;
+ GAtResult result;
+
+ type = get_command_type(command, prefix);
+ if (type == G_AT_SERVER_REQUEST_TYPE_ERROR)
+ goto done;
+
+ result.lines = g_slist_prepend(NULL, command);
+ result.final_or_pdu = 0;
+
+ res = node->notify(type, &result, node->user_data);
+
+ g_slist_free(result.lines);
+ }
+
+done:
+ g_at_server_send_final(server, res);
+
+ if (res == G_AT_SERVER_RESULT_OK)
+ return TRUE;
+
return FALSE;
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 06/10] Add g_at_server_register and unregister callback
2010-03-19 9:44 ` [PATCH 05/10] Add notify at command callback Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR Zhenhua Zhang
2010-03-22 18:24 ` [PATCH 06/10] Add g_at_server_register and unregister callback Denis Kenzior
2010-03-22 18:22 ` [PATCH 05/10] Add notify at command callback Denis Kenzior
1 sibling, 2 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2077 bytes --]
---
gatchat/gatserver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
gatchat/gatserver.h | 6 ++++++
2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 3f60f1c..1ffc2c3 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -987,3 +987,51 @@ gboolean g_at_server_set_debug(GAtServer *server, GAtDebugFunc func,
return TRUE;
}
+
+gboolean g_at_server_register(GAtServer *server, char *prefix,
+ GAtServerNotifyFunc notify,
+ gpointer user_data,
+ GDestroyNotify destroy_notify)
+{
+ struct at_command *node;
+
+ if (server == NULL || server->command_list == NULL)
+ return FALSE;
+
+ if (notify == NULL)
+ return FALSE;
+
+ if (prefix == NULL || strlen(prefix) == 0)
+ return FALSE;
+
+ node = g_try_new0(struct at_command, 1);
+ if (!node)
+ return FALSE;
+
+ node->notify = notify;
+ node->user_data = user_data;
+ node->destroy_notify = destroy_notify;
+
+ g_hash_table_replace(server->command_list, g_strdup(prefix), node);
+
+ return TRUE;
+}
+
+gboolean g_at_server_unregister(GAtServer *server, const char *prefix)
+{
+ struct at_command *node;
+
+ if (server == NULL || server->command_list == NULL)
+ return FALSE;
+
+ if (prefix == NULL || strlen(prefix) == 0)
+ return FALSE;
+
+ node = g_hash_table_lookup(server->command_list, prefix);
+ if (!node)
+ return FALSE;
+
+ g_hash_table_remove(server->command_list, prefix);
+
+ return TRUE;
+}
diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h
index 1c12a0d..5e9eb62 100644
--- a/gatchat/gatserver.h
+++ b/gatchat/gatserver.h
@@ -81,6 +81,12 @@ gboolean g_at_server_set_debug(GAtServer *server,
GAtDebugFunc func,
gpointer user);
+gboolean g_at_server_register(GAtServer *server, char *prefix,
+ GAtServerNotifyFunc notify,
+ gpointer user_data,
+ GDestroyNotify destroy_notify);
+gboolean g_at_server_unregister(GAtServer *server, const char *prefix);
+
#ifdef __cplusplus
}
#endif
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR
2010-03-19 9:44 ` [PATCH 06/10] Add g_at_server_register and unregister callback Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Zhenhua Zhang
2010-03-22 18:24 ` [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR Denis Kenzior
2010-03-22 18:24 ` [PATCH 06/10] Add g_at_server_register and unregister callback Denis Kenzior
1 sibling, 2 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 493 bytes --]
---
gatchat/gatserver.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h
index 5e9eb62..6fb78bd 100644
--- a/gatchat/gatserver.h
+++ b/gatchat/gatserver.h
@@ -43,6 +43,7 @@ enum _GAtServerResult {
G_AT_SERVER_RESULT_NO_DIALTONE = 6,
G_AT_SERVER_RESULT_BUSY = 7,
G_AT_SERVER_RESULT_NO_ANSWER = 8,
+ G_AT_SERVER_RESULT_EXT_ERROR = 256,
};
typedef enum _GAtServerResult GAtServerResult;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 08/10] Fix do not emit error if extended error has emitted
2010-03-19 9:44 ` [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 09/10] Refactor g_at_server_send_final Zhenhua Zhang
2010-03-22 18:27 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Denis Kenzior
2010-03-22 18:24 ` [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR Denis Kenzior
1 sibling, 2 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 560 bytes --]
---
gatchat/gatserver.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 1ffc2c3..9683fa3 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -165,6 +165,10 @@ static void g_at_server_send_final(GAtServer *server, GAtServerResult result)
char r = v250.s4;
unsigned int len;
+ /* Do not emit error if extended error has already been emitted */
+ if (result == G_AT_SERVER_RESULT_EXT_ERROR)
+ return;
+
if (v250.quiet)
return;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 09/10] Refactor g_at_server_send_final
2010-03-19 9:44 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 10/10] Add utilities to send server response Zhenhua Zhang
2010-03-22 18:27 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Denis Kenzior
1 sibling, 1 reply; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3632 bytes --]
Cache the result code as last_result from at command callback. And
flush out the last result code when the whole command line is parsed,
except the last result is an extended error code, like +CMS ERROR or
+CME ERROR.
---
gatchat/gatserver.c | 55 ++++++++++++++++++++++++++++++++++++--------------
1 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 9683fa3..b4f7563 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -33,6 +33,8 @@
#include "gatserver.h"
#define BUF_SIZE 4096
+/* <cr><lf> + the max length of information text + <cr><lf> */
+#define MAX_TEXT_SIZE 2048+4
/* #define WRITE_SCHEDULER_DEBUG 1 */
enum ParserState {
@@ -112,6 +114,7 @@ struct _GAtServer {
guint max_read_attempts; /* Max reads per select */
enum ParserState parser_state;
gboolean destroyed; /* Re-entrancy guard */
+ GAtServerResult last_result; /* Result of last command */
};
static void g_at_server_wakeup_writer(GAtServer *server);
@@ -156,35 +159,52 @@ static void send_common(GAtServer *server, const char *buf, unsigned int len)
g_at_server_wakeup_writer(server);
}
-static void g_at_server_send_final(GAtServer *server, GAtServerResult result)
+static void send_result_common(GAtServer *server, const char *result)
{
- struct v250_settings v250 = server->v250;
- const char *result_str = server_result_to_string(result);
- char buf[1024];
- char t = v250.s3;
- char r = v250.s4;
+ char buf[MAX_TEXT_SIZE];
+ char t = server->v250.s3;
+ char r = server->v250.s4;
unsigned int len;
- /* Do not emit error if extended error has already been emitted */
- if (result == G_AT_SERVER_RESULT_EXT_ERROR)
- return;
-
- if (v250.quiet)
+ if (server->v250.quiet)
return;
- if (result_str == NULL)
+ if (result == NULL)
return;
- if (v250.is_v1)
- len = snprintf(buf, sizeof(buf), "%c%c%s%c%c", t, r, result_str,
+ if (server->v250.is_v1)
+ len = snprintf(buf, sizeof(buf), "%c%c%s%c%c", t, r, result,
t, r);
else
- len = snprintf(buf, sizeof(buf), "%u%c", (unsigned int) result,
- t);
+ len = snprintf(buf, sizeof(buf), "%s%c", result, t);
send_common(server, buf, MIN(len, sizeof(buf)-1));
}
+static void g_at_server_send_flush(GAtServer *server)
+{
+ GAtServerResult result = server->last_result;
+ char buf[1024];
+
+ /* Do not emit error if extended error has already been emitted */
+ if (result == G_AT_SERVER_RESULT_EXT_ERROR)
+ return;
+
+ if (server->v250.is_v1)
+ sprintf(buf, "%s", server_result_to_string(result));
+ else
+ sprintf(buf, "%u", (unsigned int)result);
+
+ send_result_common(server, buf);
+}
+
+static inline void g_at_server_send_final(GAtServer *server,
+ GAtServerResult result)
+{
+ /* Cache the result until the whole command line is parsed */
+ server->last_result = result;
+}
+
static inline gboolean is_extended_command_prefix(const char c)
{
switch (c) {
@@ -633,16 +653,19 @@ static void new_bytes(GAtServer *p)
* Empty commands must be OK by the DCE
*/
g_at_server_send_final(p, G_AT_SERVER_RESULT_OK);
+ g_at_server_send_flush(p);
ring_buffer_drain(p->read_buf, p->read_so_far);
break;
case PARSER_RESULT_COMMAND:
server_parse_line(p, extract_line(p));
+ g_at_server_send_flush(p);
break;
case PARSER_RESULT_REPEAT_LAST:
/* TODO */
g_at_server_send_final(p, G_AT_SERVER_RESULT_OK);
+ g_at_server_send_flush(p);
ring_buffer_drain(p->read_buf, p->read_so_far);
break;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 10/10] Add utilities to send server response
2010-03-19 9:44 ` [PATCH 09/10] Refactor g_at_server_send_final Zhenhua Zhang
@ 2010-03-19 9:44 ` Zhenhua Zhang
0 siblings, 0 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-19 9:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2826 bytes --]
The server response could be either result code or information text.
Result code types: final, intermediate and unsolicited.
Information text: one or multiple lines of text.
---
gatchat/gatserver.c | 42 ++++++++++++++++++++++++++++++++++++++++++
gatchat/gatserver.h | 17 +++++++++++++++++
2 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index b4f7563..1072230 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -205,6 +205,48 @@ static inline void g_at_server_send_final(GAtServer *server,
server->last_result = result;
}
+void g_at_server_send_ext_final(GAtServer *server, const char *result)
+{
+ send_result_common(server, result);
+}
+
+void g_at_server_send_intermediate(GAtServer *server, const char *result)
+{
+ send_result_common(server, result);
+}
+
+void g_at_server_send_unsolicited(GAtServer *server, const char *result)
+{
+ send_result_common(server, result);
+}
+
+void g_at_server_send_info_text(GAtServer *server, GSList *text)
+{
+ char buf[MAX_TEXT_SIZE];
+ char t = server->v250.s3;
+ char r = server->v250.s4;
+ unsigned int len;
+ GSList *l = text;
+ char *line;
+
+ if (!text)
+ return;
+
+ while (l) {
+ line = l->data;
+ if (!line)
+ return;
+
+ len = snprintf(buf, sizeof(buf), "%c%c%s", t, r, line);
+ send_common(server, buf, MIN(len, sizeof(buf)-1));
+
+ l = l->next;
+ }
+
+ len = snprintf(buf, sizeof(buf), "%c%c", t, r);
+ send_common(server, buf, len);
+}
+
static inline gboolean is_extended_command_prefix(const char c)
{
switch (c) {
diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h
index 6fb78bd..fc82e3b 100644
--- a/gatchat/gatserver.h
+++ b/gatchat/gatserver.h
@@ -88,6 +88,23 @@ gboolean g_at_server_register(GAtServer *server, char *prefix,
GDestroyNotify destroy_notify);
gboolean g_at_server_unregister(GAtServer *server, const char *prefix);
+/* Send an extended final result code. E.g. +CME ERROR: SIM failure.
+ * In this case, callback should return G_AT_SERVER_RESULT_EXT_ERROR as
+ * result so that server will not send final result code again.
+ */
+void g_at_server_send_ext_final(GAtServer *server, const char *result);
+
+/* Send an intermediate result code to report the progress. E.g. CONNECT */
+void g_at_server_send_intermediate(GAtServer *server, const char *result);
+
+/* Send an unsolicited result code. E.g. RING */
+void g_at_server_send_unsolicited(GAtServer *server, const char *result);
+
+/* Send an information text. The text could contain multiple lines. Each
+ * line, including line terminators, should not exceed 2048 characters.
+ */
+void g_at_server_send_info_text(GAtServer *server, GSList *text);
+
#ifdef __cplusplus
}
#endif
--
1.6.6.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 03/10] Add extended command parsing
2010-03-19 9:44 ` [PATCH 03/10] Add extended " Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 04/10] Add server at command data structure Zhenhua Zhang
@ 2010-03-22 18:01 ` Denis Kenzior
1 sibling, 0 replies; 20+ messages in thread
From: Denis Kenzior @ 2010-03-22 18:01 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 244 bytes --]
Hi Zhenhua,
> ---
> gatchat/gatserver.c | 65
> +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 63
> insertions(+), 2 deletions(-)
I applied this patch but refactored it heavily afterwards.
Regards,
-Denis
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 01/10] Add framework of server parser
2010-03-19 9:44 ` [PATCH 01/10] Add framework of server parser Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 02/10] Add basic command parsing Zhenhua Zhang
@ 2010-03-22 18:02 ` Denis Kenzior
1 sibling, 0 replies; 20+ messages in thread
From: Denis Kenzior @ 2010-03-22 18:02 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 460 bytes --]
Hi Zhenhua,
> a. The parser fetch and parse one command per loop. The prefix is
> the command prefix without parameter. For example, the prefix of
> "AT+CLIP=1" is "+CLIP".
>
> b. Search registered notification node in command_list. Invoke the
> callback if found.
>
> c. Termiate the execution if the result is an error. Otherwise,
> parse next command.
I applied this patch but refactored it heavily afterwards. Thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 02/10] Add basic command parsing
2010-03-19 9:44 ` [PATCH 02/10] Add basic command parsing Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 03/10] Add extended " Zhenhua Zhang
@ 2010-03-22 18:19 ` Denis Kenzior
1 sibling, 0 replies; 20+ messages in thread
From: Denis Kenzior @ 2010-03-22 18:19 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 216 bytes --]
Hi Zhenhua,
> According to V.250 5.3.1, the basic command is either a single
> character or the '&' followed by a single character.
Can you rebase this patch against upstream and resubmit?
Thanks,
-Denis
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 04/10] Add server at command data structure
2010-03-19 9:44 ` [PATCH 04/10] Add server at command data structure Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 05/10] Add notify at command callback Zhenhua Zhang
@ 2010-03-22 18:22 ` Denis Kenzior
1 sibling, 0 replies; 20+ messages in thread
From: Denis Kenzior @ 2010-03-22 18:22 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 250 bytes --]
Hi Zhenhua,
> ---
> gatchat/gatserver.c | 27 +++++++++++++++++++++++++++
> gatchat/gatserver.h | 22 ++++++++++++++++++++++
> 2 files changed, 49 insertions(+), 0 deletions(-)
This patch has been applied. Thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 05/10] Add notify at command callback
2010-03-19 9:44 ` [PATCH 05/10] Add notify at command callback Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 06/10] Add g_at_server_register and unregister callback Zhenhua Zhang
@ 2010-03-22 18:22 ` Denis Kenzior
1 sibling, 0 replies; 20+ messages in thread
From: Denis Kenzior @ 2010-03-22 18:22 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 239 bytes --]
Hi Zhenhua,
> ---
> gatchat/gatserver.c | 48
> ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 48
> insertions(+), 0 deletions(-)
I applied this patch but refactored heavily afterwards.
Regards,
-Denis
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 06/10] Add g_at_server_register and unregister callback
2010-03-19 9:44 ` [PATCH 06/10] Add g_at_server_register and unregister callback Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR Zhenhua Zhang
@ 2010-03-22 18:24 ` Denis Kenzior
1 sibling, 0 replies; 20+ messages in thread
From: Denis Kenzior @ 2010-03-22 18:24 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 242 bytes --]
Hi Zhenhua,
> ---
> gatchat/gatserver.c | 48
> ++++++++++++++++++++++++++++++++++++++++++++++++ gatchat/gatserver.h |
> 6 ++++++
> 2 files changed, 54 insertions(+), 0 deletions(-)
>
This patch has been applied, thanks.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR
2010-03-19 9:44 ` [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Zhenhua Zhang
@ 2010-03-22 18:24 ` Denis Kenzior
1 sibling, 0 replies; 20+ messages in thread
From: Denis Kenzior @ 2010-03-22 18:24 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 172 bytes --]
Hi Zhenhua,
> ---
> gatchat/gatserver.h | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
This patch has been applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 08/10] Fix do not emit error if extended error has emitted
2010-03-19 9:44 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 09/10] Refactor g_at_server_send_final Zhenhua Zhang
@ 2010-03-22 18:27 ` Denis Kenzior
2010-03-23 9:10 ` Zhenhua Zhang
1 sibling, 1 reply; 20+ messages in thread
From: Denis Kenzior @ 2010-03-22 18:27 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 770 bytes --]
Hi Zhenhua,
> ---
> gatchat/gatserver.c | 4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
> index 1ffc2c3..9683fa3 100644
> --- a/gatchat/gatserver.c
> +++ b/gatchat/gatserver.c
> @@ -165,6 +165,10 @@ static void g_at_server_send_final(GAtServer *server,
> GAtServerResult result) char r = v250.s4;
> unsigned int len;
>
> + /* Do not emit error if extended error has already been emitted */
> + if (result == G_AT_SERVER_RESULT_EXT_ERROR)
> + return;
> +
I really don't get it, why would anyone call g_at_server_send_final with
EXT_ERROR? Don't we have g_at_server_send_ext_final or something for that?
> if (v250.quiet)
> return;
>
Regards,
-Denis
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 08/10] Fix do not emit error if extended error has emitted
2010-03-22 18:27 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Denis Kenzior
@ 2010-03-23 9:10 ` Zhenhua Zhang
0 siblings, 0 replies; 20+ messages in thread
From: Zhenhua Zhang @ 2010-03-23 9:10 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1301 bytes --]
Hi Denis,
On 03/23/2010 02:27 AM, Denis Kenzior wrote:
> Hi Zhenhua,
>
>> ---
>> gatchat/gatserver.c | 4 ++++
>> 1 files changed, 4 insertions(+), 0 deletions(-)
>>
>> diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
>> index 1ffc2c3..9683fa3 100644
>> --- a/gatchat/gatserver.c
>> +++ b/gatchat/gatserver.c
>> @@ -165,6 +165,10 @@ static void g_at_server_send_final(GAtServer *server,
>> GAtServerResult result) char r = v250.s4;
>> unsigned int len;
>>
>> + /* Do not emit error if extended error has already been emitted */
>> + if (result == G_AT_SERVER_RESULT_EXT_ERROR)
>> + return;
>> +
>
> I really don't get it, why would anyone call g_at_server_send_final with
> EXT_ERROR? Don't we have g_at_server_send_ext_final or something for that?
I understand your point. My thinking is that callback should return
GAtServrResult so that the main logic know whether we should parse the
next command or abort parsing. But if the function call is
asynchronized, I don't know, do you want send_final able to abort the
parsing iteration?
>> if (v250.quiet)
>> return;
>>
>
> Regards,
> -Denis
> _______________________________________________
> ofono mailing list
> ofono(a)ofono.org
> http://lists.ofono.org/listinfo/ofono
>
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2010-03-23 9:10 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-19 9:44 Add parse framework for GAtServer Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 01/10] Add framework of server parser Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 02/10] Add basic command parsing Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 03/10] Add extended " Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 04/10] Add server at command data structure Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 05/10] Add notify at command callback Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 06/10] Add g_at_server_register and unregister callback Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 09/10] Refactor g_at_server_send_final Zhenhua Zhang
2010-03-19 9:44 ` [PATCH 10/10] Add utilities to send server response Zhenhua Zhang
2010-03-22 18:27 ` [PATCH 08/10] Fix do not emit error if extended error has emitted Denis Kenzior
2010-03-23 9:10 ` Zhenhua Zhang
2010-03-22 18:24 ` [PATCH 07/10] Add G_AT_SERVER_RESULT_EXT_ERROR Denis Kenzior
2010-03-22 18:24 ` [PATCH 06/10] Add g_at_server_register and unregister callback Denis Kenzior
2010-03-22 18:22 ` [PATCH 05/10] Add notify at command callback Denis Kenzior
2010-03-22 18:22 ` [PATCH 04/10] Add server at command data structure Denis Kenzior
2010-03-22 18:01 ` [PATCH 03/10] Add extended command parsing Denis Kenzior
2010-03-22 18:19 ` [PATCH 02/10] Add basic " Denis Kenzior
2010-03-22 18:02 ` [PATCH 01/10] Add framework of server parser Denis Kenzior
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.