summaryrefslogtreecommitdiffstats
path: root/gatchat
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@collabora.co.uk>2009-08-05 17:18:34 -0400
committerDenis Kenzior <denkenz@gmail.com>2009-08-06 16:38:45 -0500
commitd66fd48bf962079e13a3e3a7a97174e79c582c4f (patch)
treea569d9230524e3b64c22a207245acdeae21f0f49 /gatchat
parent1418c2aec18ec81b3ce4806bae46614cc1fe672c (diff)
downloadofono-d66fd48bf962079e13a3e3a7a97174e79c582c4f.tar.bz2
gatchat: add debugging infrastructure
This patch adds debugging support to GAtChat (specifically of what's going across the serial line). Callbacks can be set via g_at_chat_set_debugging, and that callback is called after any channel reads or writes.
Diffstat (limited to 'gatchat')
-rw-r--r--gatchat/gatchat.c46
-rw-r--r--gatchat/gatchat.h4
2 files changed, 50 insertions, 0 deletions
diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c
index 6cb52074..9f69c8a2 100644
--- a/gatchat/gatchat.c
+++ b/gatchat/gatchat.c
@@ -77,6 +77,8 @@ struct _GAtChat {
struct ring_buffer *buf; /* Current read buffer */
guint read_so_far; /* Number of bytes processed */
gboolean disconnecting; /* Whether we're disconnecting */
+ GAtDebugFunc debugf; /* debugging output function */
+ gpointer debug_func_user_data;
char *pdu_notify; /* Unsolicited Resp w/ PDU */
GSList *response_lines; /* char * lines of the response */
char *wakeup; /* command sent to wakeup modem */
@@ -590,6 +592,35 @@ static void new_bytes(GAtChat *p)
g_at_chat_shutdown(p);
}
+static void g_at_chat_debug_log(GAtChat *chat, gboolean is_read,
+ const char *str, gsize len)
+{
+ char type = is_read ? '<' : '>';
+ char *t1, *t2;
+
+ if (!chat->debugf || !len)
+ return;
+
+ if (len > 2048) {
+ /* 27.007 specifies a max command result length of 2048 */
+ t1 = g_strdup_printf("%c (ignoring string of length %d)", type, len);
+ chat->debugf(t1, chat->debug_func_user_data);
+ g_free(t1);
+ return;
+ }
+
+ /* prefix with "> " or "< ", and ensure null-termination */
+ t1 = g_malloc(len + 3);
+ g_sprintf(t1, "%c ", type);
+ g_memmove(t1 + 2, str, len);
+ t1[len + 2] = '\0';
+
+ t2 = g_strescape(t1, "\"");
+ chat->debugf(t2, chat->debug_func_user_data);
+ g_free(t1);
+ g_free(t2);
+}
+
static gboolean received_data(GIOChannel *channel, GIOCondition cond,
gpointer data)
{
@@ -615,6 +646,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
buf = ring_buffer_write_ptr(chat->buf);
err = g_io_channel_read(channel, (char *) buf, toread, &rbytes);
+ g_at_chat_debug_log(chat, TRUE, buf, rbytes);
total_read += rbytes;
@@ -741,6 +773,8 @@ static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
return FALSE;
}
+ g_at_chat_debug_log(chat, FALSE, cmd->cmd + chat->cmd_bytes_written,
+ bytes_written);
chat->cmd_bytes_written += bytes_written;
if (bytes_written < towrite)
@@ -784,6 +818,7 @@ GAtChat *g_at_chat_new(GIOChannel *channel, GAtSyntax *syntax)
chat->ref_count = 1;
chat->next_cmd_id = 1;
chat->next_notify_id = 1;
+ chat->debugf = NULL;
chat->buf = ring_buffer_new(4096);
@@ -929,6 +964,17 @@ gboolean g_at_chat_set_disconnect_function(GAtChat *chat,
return TRUE;
}
+gboolean g_at_chat_set_debugging(GAtChat *chat, GAtDebugFunc func,
+ gpointer user_data)
+{
+ if (chat == NULL)
+ return FALSE;
+
+ chat->debugf = func;
+ chat->debug_func_user_data = user_data;
+ return TRUE;
+}
+
static guint send_common(GAtChat *chat, const char *cmd,
const char **prefix_list,
GAtNotifyFunc listing, GAtResultFunc func,
diff --git a/gatchat/gatchat.h b/gatchat/gatchat.h
index d0a59b83..9bfcab1d 100644
--- a/gatchat/gatchat.h
+++ b/gatchat/gatchat.h
@@ -37,6 +37,7 @@ typedef void (*GAtResultFunc)(gboolean success, GAtResult *result,
gpointer user_data);
typedef void (*GAtNotifyFunc)(GAtResult *result, gpointer user_data);
typedef void (*GAtDisconnectFunc)(gpointer user_data);
+typedef void (*GAtDebugFunc)(const char *str, gpointer user_data);
enum _GAtChatFlags {
G_AT_CHAT_FLAG_NO_LEADING_CRLF = 1, /* Some emulators are broken */
@@ -56,6 +57,9 @@ gboolean g_at_chat_shutdown(GAtChat *chat);
gboolean g_at_chat_set_disconnect_function(GAtChat *chat,
GAtDisconnectFunc disconnect, gpointer user_data);
+gboolean g_at_chat_set_debugging(GAtChat *chat, GAtDebugFunc func,
+ gpointer user_data);
+
/*!
* Queue an AT command for execution. The command contents are given
* in cmd. Once the command executes, the callback function given by