* [PATCH 01/11] Rename g_at_server_send_result
@ 2010-03-17 14:30 Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 02/11] Add framework of server parser Zhenhua Zhang
2010-03-17 14:38 ` [PATCH 01/11] Rename g_at_server_send_result Zhenhua Zhang
0 siblings, 2 replies; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1337 bytes --]
Rename it to g_at_server_send_final.
---
gatchat/gatserver.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 7577de2..46fa423 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -148,7 +148,7 @@ static void send_common(GAtServer *server, const char *buf, unsigned int len)
g_at_server_wakeup_writer(server);
}
-static void g_at_server_send_result(GAtServer *server, GAtServerResult result)
+static void g_at_server_send_final(GAtServer *server, GAtServerResult result)
{
struct v250_settings v250 = server->v250;
const char *result_str = server_result_to_string(result);
@@ -353,7 +353,7 @@ static void new_bytes(GAtServer *p)
* According to section 5.2.4 and 5.6 of V250,
* Empty commands must be OK by the DCE
*/
- g_at_server_send_result(p, G_AT_SERVER_RESULT_OK);
+ g_at_server_send_final(p, G_AT_SERVER_RESULT_OK);
ring_buffer_drain(p->read_buf, p->read_so_far);
break;
@@ -363,7 +363,7 @@ static void new_bytes(GAtServer *p)
case PARSER_RESULT_REPEAT_LAST:
/* TODO */
- g_at_server_send_result(p, G_AT_SERVER_RESULT_OK);
+ g_at_server_send_final(p, G_AT_SERVER_RESULT_OK);
ring_buffer_drain(p->read_buf, p->read_so_far);
break;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/11] Add framework of server parser
2010-03-17 14:30 [PATCH 01/11] Rename g_at_server_send_result Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 03/11] Add basic command parsing Zhenhua Zhang
2010-03-17 17:55 ` [PATCH 02/11] Add framework of server parser Denis Kenzior
2010-03-17 14:38 ` [PATCH 01/11] Rename g_at_server_send_result Zhenhua Zhang
1 sibling, 2 replies; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2795 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 | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 95 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 46fa423..fb82ad4 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -173,8 +173,103 @@ static void g_at_server_send_final(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(const 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_command_notify(GAtServer *server, char *command,
+ char *prefix)
+{
+ GAtServerResult res = G_AT_SERVER_RESULT_ERROR;
+
+ return res;
+}
+
+static char *parse_extended_command(GAtServer *server, const char *buf,
+ char *prefix)
+{
+ return NULL;
+}
+
+static char *parse_basic_command(GAtServer *server, const char *buf,
+ char *prefix)
+{
+ return NULL;
+}
+
+static char *parse_next_command(GAtServer *server, const char *buf,
+ char *prefix)
+{
+ char *command = NULL;
+ char c = *buf;
+
+ /* fetch one command and get its prefix */
+ if (is_extended_command_prefix(c))
+ command = parse_extended_command(server, buf, prefix);
+ else if (is_basic_command_prefix(buf))
+ command = parse_basic_command(server, buf, prefix);
+
+ return command;
+}
+
static void server_parse_line(GAtServer *server, char *line)
{
+ GAtServerResult res = G_AT_SERVER_RESULT_ERROR;
+ char *buf = line;
+ char *command = NULL;
+ char prefix[20];
+
+ while (buf) {
+ char c = *buf;
+
+ /* skip semicolon */
+ if (c == ';')
+ c = *(++buf);
+
+ if (c == '\0') {
+ res = G_AT_SERVER_RESULT_OK;
+ break;
+ }
+
+ command = parse_next_command(server, buf, prefix);
+ if (!command) {
+ res = G_AT_SERVER_RESULT_ERROR;
+ break;
+ }
+
+ res = at_command_notify(server, command, prefix);
+ if (res != G_AT_SERVER_RESULT_OK) {
+ g_free(command);
+ break;
+ }
+
+ buf += strlen(command);
+
+ g_free(command);
+ }
+
+ g_at_server_send_final(server, res);
+
g_free(line);
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 03/11] Add basic command parsing
2010-03-17 14:30 ` [PATCH 02/11] Add framework of server parser Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 04/11] Add extended " Zhenhua Zhang
2010-03-17 18:02 ` [PATCH 03/11] Add basic command parsing Denis Kenzior
2010-03-17 17:55 ` [PATCH 02/11] Add framework of server parser Denis Kenzior
1 sibling, 2 replies; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2237 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 | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 67 insertions(+), 1 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index fb82ad4..b68894d 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -211,10 +211,67 @@ static char *parse_extended_command(GAtServer *server, const char *buf,
return NULL;
}
+static gboolean get_basic_prefix(const char *buf, char *prefix)
+{
+ char c = *buf;
+
+ 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';
+ }
+ } else if (c == '&') {
+ prefix[0] = '&';
+ prefix[1] = g_ascii_toupper(buf[1]);
+ prefix[2] = '\0';
+ } else
+ return FALSE;
+
+ return TRUE;
+}
+
static char *parse_basic_command(GAtServer *server, const char *buf,
char *prefix)
{
- return NULL;
+ char t = server->v250.s3;
+ int i;
+
+ if (!get_basic_prefix(buf, prefix))
+ return NULL;
+
+ 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 {
+ /* Skip '=', '?' if have */
+ if (buf[i] == '=')
+ i++;
+
+ if (buf[i] == '?')
+ i++;
+
+ /* V.250 5.3.1 The subparameter are all digits if have */
+ while (g_ascii_isdigit(buf[i]))
+ i++;
+ }
+
+ return g_strndup(buf, i);
}
static char *parse_next_command(GAtServer *server, const char *buf,
@@ -263,6 +320,15 @@ static void server_parse_line(GAtServer *server, char *line)
break;
}
+ /* Commands like ATA, ATD, ATZ cause the remainder line
+ * to be ignored.
+ */
+ if (!strcmp(prefix, "A") || !strcmp(prefix, "D") ||
+ !strcmp(prefix, "Z")) {
+ g_free(command);
+ break;
+ }
+
buf += strlen(command);
g_free(command);
--
1.6.6.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/11] Add extended command parsing
2010-03-17 14:30 ` [PATCH 03/11] Add basic command parsing Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 05/11] Add server at command data structure Zhenhua Zhang
2010-03-17 18:02 ` [PATCH 03/11] Add basic command parsing Denis Kenzior
1 sibling, 1 reply; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1731 bytes --]
---
gatchat/gatserver.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 56 insertions(+), 1 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index b68894d..f3807eb 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -197,6 +197,28 @@ 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 GAtServerResult at_command_notify(GAtServer *server, char *command,
char *prefix)
{
@@ -205,10 +227,43 @@ static GAtServerResult at_command_notify(GAtServer *server, char *command,
return res;
}
+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 char *parse_extended_command(GAtServer *server, const char *buf,
char *prefix)
{
- return NULL;
+ char *command;
+ 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);
+
+ return command;
}
static gboolean get_basic_prefix(const char *buf, char *prefix)
--
1.6.6.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/11] Add server at command data structure
2010-03-17 14:30 ` [PATCH 04/11] Add extended " Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 06/11] Add notify at command callback Zhenhua Zhang
0 siblings, 1 reply; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3614 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 f3807eb..bbaef52 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 supported at command */
struct ring_buffer *read_buf; /* Current read buffer */
GQueue *write_queue; /* Write buffer queue */
guint max_read_attempts; /* Max reads per select */
@@ -733,6 +741,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;
}
@@ -778,6 +789,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;
@@ -792,6 +813,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;
@@ -816,6 +840,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] 16+ messages in thread
* [PATCH 06/11] Add notify at command callback
2010-03-17 14:30 ` [PATCH 05/11] Add server at command data structure Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 07/11] Add g_at_server_register and unregister callback Zhenhua Zhang
2010-03-17 18:23 ` [PATCH 06/11] Add notify at command callback Denis Kenzior
0 siblings, 2 replies; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1682 bytes --]
---
gatchat/gatserver.c | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index bbaef52..6e3347c 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -227,10 +227,48 @@ 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 GAtServerResult 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)
+ return res;
+
+ result.lines = g_slist_prepend(NULL, command);
+ result.final_or_pdu = 0;
+
+ res = node->notify(type, &result, node->user_data);
+ }
return res;
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/11] Add g_at_server_register and unregister callback
2010-03-17 14:30 ` [PATCH 06/11] Add notify at command callback Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 08/11] Add G_AT_SERVER_RESULT_EXT_ERROR Zhenhua Zhang
2010-03-17 18:23 ` [PATCH 06/11] Add notify at command callback Denis Kenzior
1 sibling, 1 reply; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 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 6e3347c..c17a7b5 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -970,3 +970,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] 16+ messages in thread
* [PATCH 08/11] Add G_AT_SERVER_RESULT_EXT_ERROR
2010-03-17 14:30 ` [PATCH 07/11] Add g_at_server_register and unregister callback Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 09/11] Fix do not emit error if extended error has emitted Zhenhua Zhang
0 siblings, 1 reply; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 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] 16+ messages in thread
* [PATCH 09/11] Fix do not emit error if extended error has emitted
2010-03-17 14:30 ` [PATCH 08/11] Add G_AT_SERVER_RESULT_EXT_ERROR Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 10/11] Refactor g_at_server_send_final Zhenhua Zhang
0 siblings, 1 reply; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 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 c17a7b5..b0138d6 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] 16+ messages in thread
* [PATCH 10/11] Refactor g_at_server_send_final
2010-03-17 14:30 ` [PATCH 09/11] Fix do not emit error if extended error has emitted Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 11/11] Add utilities to send server response Zhenhua Zhang
0 siblings, 1 reply; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2266 bytes --]
---
gatchat/gatserver.c | 43 +++++++++++++++++++++++++++----------------
1 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index b0138d6..7ac6d34 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 {
@@ -156,35 +158,44 @@ 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_final(GAtServer *server, GAtServerResult 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 gboolean is_extended_command_prefix(const char c)
{
switch (c) {
--
1.6.6.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/11] Add utilities to send server response
2010-03-17 14:30 ` [PATCH 10/11] Refactor g_at_server_send_final Zhenhua Zhang
@ 2010-03-17 14:30 ` Zhenhua Zhang
0 siblings, 0 replies; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2417 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 | 37 +++++++++++++++++++++++++++++++++++++
gatchat/gatserver.h | 11 +++++++++++
2 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 7ac6d34..06ea912 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -196,6 +196,43 @@ static void g_at_server_send_final(GAtServer *server, GAtServerResult result)
send_result_common(server, buf);
}
+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..19d7cb5 100644
--- a/gatchat/gatserver.h
+++ b/gatchat/gatserver.h
@@ -88,6 +88,17 @@ gboolean g_at_server_register(GAtServer *server, char *prefix,
GDestroyNotify destroy_notify);
gboolean g_at_server_unregister(GAtServer *server, const char *prefix);
+/* 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] 16+ messages in thread
* Re: [PATCH 01/11] Rename g_at_server_send_result
2010-03-17 14:30 [PATCH 01/11] Rename g_at_server_send_result Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 02/11] Add framework of server parser Zhenhua Zhang
@ 2010-03-17 14:38 ` Zhenhua Zhang
2010-03-17 18:24 ` Denis Kenzior
1 sibling, 1 reply; 16+ messages in thread
From: Zhenhua Zhang @ 2010-03-17 14:38 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 346 bytes --]
Hi
On 03/17/2010 10:30 PM, Zhang, Zhenhua wrote:
> Rename it to g_at_server_send_final.
> ---
> gatchat/gatserver.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
Sorry, I forgot the first patch. Please review the first patch as
attached. Otherwise, these patches could not be applied.
Thanks.
Zhenhua
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Remove-old-server_parse_line.patch --]
[-- Type: text/x-patch, Size: 1748 bytes --]
>From 588126076e1fc10f57b75afe734d51046ab46d6d Mon Sep 17 00:00:00 2001
From: Zhenhua Zhang <zhenhua.zhang@intel.com>
Date: Wed, 17 Mar 2010 16:36:22 +0800
Subject: [PATCH] Remove old server_parse_line
---
gatchat/gatserver.c | 49 -------------------------------------------------
1 files changed, 0 insertions(+), 49 deletions(-)
diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 079451f..7577de2 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -173,57 +173,8 @@ static void g_at_server_send_result(GAtServer *server, GAtServerResult result)
send_common(server, buf, MIN(len, sizeof(buf)-1));
}
-static inline gboolean is_at_command_prefix(const char c)
-{
- switch (c) {
- case '+':
- case '*':
- case '!':
- case '%':
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-static void parse_at_command(GAtServer *server, char *buf)
-{
- g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR);
-}
-
-static void parse_v250_settings(GAtServer *server, char *buf)
-{
- g_at_server_send_result(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_result(server, G_AT_SERVER_RESULT_ERROR);
- goto done;
- }
-
- if (line[0] == '\0') {
- g_at_server_send_result(server, G_AT_SERVER_RESULT_OK);
- goto done;
- }
-
- c = line[i];
- /* skip semicolon */
- if (c == ';')
- c = line[++i];
-
- if (is_at_command_prefix(c) || c == 'A' || c == 'D' || c == 'H')
- parse_at_command(server, line + i);
- else if (g_ascii_isalpha(c) || c == '&')
- parse_v250_settings(server, line + i);
- else
- g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR);
-
-done:
g_free(line);
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 02/11] Add framework of server parser
2010-03-17 14:30 ` [PATCH 02/11] Add framework of server parser Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 03/11] Add basic command parsing Zhenhua Zhang
@ 2010-03-17 17:55 ` Denis Kenzior
1 sibling, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2010-03-17 17:55 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2727 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.
> ---
> gatchat/gatserver.c | 95
> +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed,
95
> insertions(+), 0 deletions(-)
>
> diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
> index 46fa423..fb82ad4 100644
> --- a/gatchat/gatserver.c
> +++ b/gatchat/gatserver.c
> @@ -173,8 +173,103 @@ static void g_at_server_send_final(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;
> + }
> +}
So I don't see the point of a patch that removes the entire function, then
puts the same function back in with the same name. If you want to rename it,
send a patch to do so.
> static void server_parse_line(GAtServer *server, char *line)
> {
> + GAtServerResult res = G_AT_SERVER_RESULT_ERROR;
> + char *buf = line;
> + char *command = NULL;
> + char prefix[20];
> +
> + while (buf) {
So this part is wrong, buf will never be NULL. I suggest you preserve the
logic of the current implementation here.
> + char c = *buf;
> +
> + /* skip semicolon */
> + if (c == ';')
> + c = *(++buf);
> +
> + if (c == '\0') {
> + res = G_AT_SERVER_RESULT_OK;
> + break;
> + }
> +
> + command = parse_next_command(server, buf, prefix);
> + if (!command) {
> + res = G_AT_SERVER_RESULT_ERROR;
> + break;
> + }
Why is a char * being allocated by parse_next_command? What is the purpose?
I suggest you get rid of this and perform notifications there. It is too hard
to keep track of who should free what and where otherwise.
> +
> + res = at_command_notify(server, command, prefix);
I've mentioned this before, I don't like returning a result here. We should
simply store the last result given to g_at_server_send_final or
g_at_server_send_ext_final (e.g. do not send it out right away). If it is not
OK then quit command processing and send the final result.
> + if (res != G_AT_SERVER_RESULT_OK) {
> + g_free(command);
> + break;
> + }
> +
> + buf += strlen(command);
> +
> + g_free(command);
> + }
> +
> + g_at_server_send_final(server, res);
> +
> g_free(line);
> }
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 03/11] Add basic command parsing
2010-03-17 14:30 ` [PATCH 03/11] Add basic command parsing Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 04/11] Add extended " Zhenhua Zhang
@ 2010-03-17 18:02 ` Denis Kenzior
1 sibling, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2010-03-17 18:02 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1847 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.
> ---
> gatchat/gatserver.c | 68
> ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed,
67
> insertions(+), 1 deletions(-)
>
> diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
> index fb82ad4..b68894d 100644
> --- a/gatchat/gatserver.c
> +++ b/gatchat/gatserver.c
> @@ -211,10 +211,67 @@ static char *parse_extended_command(GAtServer
> *server, const char *buf, return NULL;
> }
>
> +static gboolean get_basic_prefix(const char *buf, char *prefix)
> +{
> + char c = *buf;
> +
> + if (g_ascii_isalpha(c)) {
if (!g_ascii_isalpha && c != '&')
return
No nested ifs if you can avoid them please.
> + 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';
> + }
> + } else if (c == '&') {
> + prefix[0] = '&';
> + prefix[1] = g_ascii_toupper(buf[1]);
> + prefix[2] = '\0';
> + } else
> + return FALSE;
> +
> + return TRUE;
> +}
> +
> static char *parse_next_command(GAtServer *server, const char *buf,
> @@ -263,6 +320,15 @@ static void server_parse_line(GAtServer *server, char
> *line) break;
> }
>
> + /* Commands like ATA, ATD, ATZ cause the remainder line
> + * to be ignored.
> + */
> + if (!strcmp(prefix, "A") || !strcmp(prefix, "D") ||
> + !strcmp(prefix, "Z")) {
> + g_free(command);
> + break;
> + }
> +
strcmp might be overkill here
> buf += strlen(command);
>
> g_free(command);
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 06/11] Add notify at command callback
2010-03-17 14:30 ` [PATCH 06/11] Add notify at command callback Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 07/11] Add g_at_server_register and unregister callback Zhenhua Zhang
@ 2010-03-17 18:23 ` Denis Kenzior
1 sibling, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2010-03-17 18:23 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1200 bytes --]
Hi Zhenhua,
> ---
> gatchat/gatserver.c | 38 ++++++++++++++++++++++++++++++++++++++
> 1 files changed, 38 insertions(+), 0 deletions(-)
>
> diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
> index bbaef52..6e3347c 100644
> --- a/gatchat/gatserver.c
> +++ b/gatchat/gatserver.c
> @@ -227,10 +227,48 @@ static gboolean is_extended_character(const char c)
> }
> }
>
> static GAtServerResult 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)
> + return res;
> +
> + result.lines = g_slist_prepend(NULL, command);
> + result.final_or_pdu = 0;
> +
> + res = node->notify(type, &result, node->user_data);
> + }
Are you freeing the slist anywhere? In general you might want to run valgrind
before submitting patches just to make sure there are no visible leaks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 01/11] Rename g_at_server_send_result
2010-03-17 14:38 ` [PATCH 01/11] Rename g_at_server_send_result Zhenhua Zhang
@ 2010-03-17 18:24 ` Denis Kenzior
0 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2010-03-17 18:24 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 348 bytes --]
Hi Zhenhua,
> Sorry, I forgot the first patch. Please review the first patch as
> attached. Otherwise, these patches could not be applied.
Please get rid of this patch and rebase the rest appropriately. I mentioned
in the other reply, there's no sense to remove a bunch of code only to add
nearly the same back in.
Regards,
-Denis
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2010-03-17 18:24 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-17 14:30 [PATCH 01/11] Rename g_at_server_send_result Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 02/11] Add framework of server parser Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 03/11] Add basic command parsing Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 04/11] Add extended " Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 05/11] Add server at command data structure Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 06/11] Add notify at command callback Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 07/11] Add g_at_server_register and unregister callback Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 08/11] Add G_AT_SERVER_RESULT_EXT_ERROR Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 09/11] Fix do not emit error if extended error has emitted Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 10/11] Refactor g_at_server_send_final Zhenhua Zhang
2010-03-17 14:30 ` [PATCH 11/11] Add utilities to send server response Zhenhua Zhang
2010-03-17 18:23 ` [PATCH 06/11] Add notify at command callback Denis Kenzior
2010-03-17 18:02 ` [PATCH 03/11] Add basic command parsing Denis Kenzior
2010-03-17 17:55 ` [PATCH 02/11] Add framework of server parser Denis Kenzior
2010-03-17 14:38 ` [PATCH 01/11] Rename g_at_server_send_result Zhenhua Zhang
2010-03-17 18:24 ` 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.