summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Gu <yang.gu@intel.com>2009-11-24 23:55:45 +0800
committerMarcel Holtmann <marcel@holtmann.org>2009-11-24 18:07:02 +0100
commita2960d4e6fdc6b8d6dddeab7af6bb79e0fb85064 (patch)
treeccfab11094918684770fbe5f3549d82b6965ef9d
parent28b30d86b0cf9ab047839bb318721e64284990b8 (diff)
downloadconnman-a2960d4e6fdc6b8d6dddeab7af6bb79e0fb85064.tar.gz
connman-a2960d4e6fdc6b8d6dddeab7af6bb79e0fb85064.tar.bz2
connman-a2960d4e6fdc6b8d6dddeab7af6bb79e0fb85064.zip
Framework to support non-standard terminator
-rw-r--r--gatchat/gatchat.c59
-rw-r--r--gatchat/gatchat.h3
2 files changed, 52 insertions, 10 deletions
diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c
index 7ec1784c..ce041426 100644
--- a/gatchat/gatchat.c
+++ b/gatchat/gatchat.c
@@ -90,6 +90,13 @@ struct _GAtChat {
GTimer *wakeup_timer; /* Keep track of elapsed time */
GAtSyntax *syntax;
gboolean destroyed; /* Re-entrancy guard */
+ GSList *terminator_list; /* Non-standard terminator */
+};
+
+struct terminator_info {
+ char *terminator;
+ int len;
+ gboolean success;
};
static gint at_notify_node_compare_by_id(gconstpointer a, gconstpointer b)
@@ -206,6 +213,14 @@ static void at_command_destroy(struct at_command *cmd)
g_free(cmd);
}
+static void free_terminator(struct terminator_info *info)
+{
+ g_free(info->terminator);
+ info->terminator = NULL;
+ g_free(info);
+ info = NULL;
+}
+
static void g_at_chat_cleanup(GAtChat *chat)
{
struct at_command *c;
@@ -253,6 +268,13 @@ static void g_at_chat_cleanup(GAtChat *chat)
chat->syntax = NULL;
chat->channel = NULL;
+
+ if (chat->terminator_list) {
+ g_slist_foreach(chat->terminator_list,
+ (GFunc)free_terminator, NULL);
+ g_slist_free(chat->terminator_list);
+ chat->terminator_list = NULL;
+ }
}
static void read_watcher_destroy_notify(GAtChat *chat)
@@ -361,12 +383,6 @@ static void g_at_chat_finish_command(GAtChat *p, gboolean ok,
at_command_destroy(cmd);
}
-struct terminator_info {
- const char *terminator;
- int len;
- gboolean success;
-};
-
static struct terminator_info terminator_table[] = {
{ "OK", -1, TRUE },
{ "ERROR", -1, FALSE },
@@ -380,6 +396,27 @@ static struct terminator_info terminator_table[] = {
{ "+EXT ERROR:", 11, FALSE }
};
+void g_at_chat_add_terminator(GAtChat *chat, char *terminator,
+ int len, gboolean success)
+{
+ struct terminator_info *info = g_new0(struct terminator_info, 1);
+ info->terminator = g_strdup(terminator);
+ info->len = len;
+ info->success = success;
+ chat->terminator_list = g_slist_prepend(chat->terminator_list, info);
+}
+
+static gboolean check_terminator(struct terminator_info *info, char *line)
+{
+ if (info->len == -1 && !strcmp(line, info->terminator))
+ return TRUE;
+
+ if (info->len > 0 && !strncmp(line, info->terminator, info->len))
+ return TRUE;
+
+ return FALSE;
+}
+
static gboolean g_at_chat_handle_command_response(GAtChat *p,
struct at_command *cmd,
char *line)
@@ -387,17 +424,19 @@ static gboolean g_at_chat_handle_command_response(GAtChat *p,
int i;
int size = sizeof(terminator_table) / sizeof(struct terminator_info);
int hint;
+ GSList *l;
for (i = 0; i < size; i++) {
struct terminator_info *info = &terminator_table[i];
-
- if (info->len == -1 && !strcmp(line, info->terminator)) {
+ if (check_terminator(info, line)) {
g_at_chat_finish_command(p, info->success, line);
return TRUE;
}
+ }
- if (info->len > 0 &&
- !strncmp(line, info->terminator, info->len)) {
+ for (l = p->terminator_list; l; l = l->next) {
+ struct terminator_info *info = l->data;
+ if (check_terminator(info, line)) {
g_at_chat_finish_command(p, info->success, line);
return TRUE;
}
diff --git a/gatchat/gatchat.h b/gatchat/gatchat.h
index fe5b97bc..249c8cfc 100644
--- a/gatchat/gatchat.h
+++ b/gatchat/gatchat.h
@@ -128,6 +128,9 @@ gboolean g_at_chat_unregister(GAtChat *chat, guint id);
gboolean g_at_chat_set_wakeup_command(GAtChat *chat, const char *cmd,
guint timeout, guint msec);
+void g_at_chat_add_terminator(GAtChat *chat, char *terminator,
+ int len, gboolean success);
+
#ifdef __cplusplus
}