summaryrefslogtreecommitdiff
path: root/gatchat
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2009-08-06 15:50:10 -0500
committerDenis Kenzior <denkenz@gmail.com>2009-08-06 16:38:46 -0500
commit88b327cff57b24c1a64248fcb8e10c63e5969232 (patch)
tree637c7aa5a79c5c2b31fae41ff40860b6e7f430b5 /gatchat
parentd66fd48bf962079e13a3e3a7a97174e79c582c4f (diff)
Cleanup the debug support patch
Diffstat (limited to 'gatchat')
-rw-r--r--gatchat/gatchat.c97
-rw-r--r--gatchat/gatchat.h8
2 files changed, 78 insertions, 27 deletions
diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c
index 9f69c8a2..1347f183 100644
--- a/gatchat/gatchat.c
+++ b/gatchat/gatchat.c
@@ -29,6 +29,7 @@
#include <string.h>
#include <assert.h>
#include <termios.h>
+#include <ctype.h>
#include <glib.h>
@@ -78,7 +79,7 @@ struct _GAtChat {
guint read_so_far; /* Number of bytes processed */
gboolean disconnecting; /* Whether we're disconnecting */
GAtDebugFunc debugf; /* debugging output function */
- gpointer debug_func_user_data;
+ gpointer debug_data; /* Data to pass to debug func */
char *pdu_notify; /* Unsolicited Resp w/ PDU */
GSList *response_lines; /* char * lines of the response */
char *wakeup; /* command sent to wakeup modem */
@@ -592,33 +593,79 @@ 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)
+static void debug_chat(GAtChat *chat, gboolean in, const char *str, gsize len)
{
- char type = is_read ? '<' : '>';
- char *t1, *t2;
+ char type = in ? '<' : '>';
+ gsize escaped = 2; /* Enough for '<', ' ' */
+ char *escaped_str;
+ const char *esc = "<ESC>";
+ gsize esc_size = strlen(esc);
+ const char *ctrlz = "<CtrlZ>";
+ gsize ctrlz_size = strlen(ctrlz);
+ gsize i;
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;
+ for (i = 0; i < len; i++) {
+ char c = str[i];
+
+ if (isprint(c))
+ escaped += 1;
+ else if (c == '\r' || c == '\t' || c == '\n')
+ escaped += 2;
+ else if (c == 26)
+ escaped += ctrlz_size;
+ else if (c == 25)
+ escaped += esc_size;
+ else
+ escaped += 4;
}
- /* 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';
+ escaped_str = g_malloc(escaped + 1);
+ escaped_str[0] = type;
+ escaped_str[1] = ' ';
+ escaped_str[2] = '\0';
+ escaped_str[escaped] = '\0';
- t2 = g_strescape(t1, "\"");
- chat->debugf(t2, chat->debug_func_user_data);
- g_free(t1);
- g_free(t2);
+ for (escaped = 2, i = 0; i < len; i++) {
+ char c = str[i];
+
+ switch (c) {
+ case '\r':
+ escaped_str[escaped++] = '\\';
+ escaped_str[escaped++] = 'r';
+ break;
+ case '\t':
+ escaped_str[escaped++] = '\\';
+ escaped_str[escaped++] = 't';
+ break;
+ case '\n':
+ escaped_str[escaped++] = '\\';
+ escaped_str[escaped++] = 'n';
+ break;
+ case 26:
+ strncpy(&escaped_str[escaped], ctrlz, ctrlz_size);
+ escaped += ctrlz_size;
+ break;
+ case 25:
+ strncpy(&escaped_str[escaped], esc, esc_size);
+ escaped += esc_size;
+ break;
+ default:
+ if (isprint(c))
+ escaped_str[escaped++] = c;
+ else {
+ escaped_str[escaped++] = '\\';
+ escaped_str[escaped++] = '0' + ((c >> 6) & 07);
+ escaped_str[escaped++] = '0' + ((c >> 3) & 07);
+ escaped_str[escaped++] = '0' + (c & 07);
+ }
+ }
+ }
+
+ chat->debugf(escaped_str, chat->debug_data);
+ g_free(escaped_str);
}
static gboolean received_data(GIOChannel *channel, GIOCondition cond,
@@ -646,7 +693,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);
+ debug_chat(chat, TRUE, (char *)buf, rbytes);
total_read += rbytes;
@@ -773,7 +820,7 @@ static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
return FALSE;
}
- g_at_chat_debug_log(chat, FALSE, cmd->cmd + chat->cmd_bytes_written,
+ debug_chat(chat, FALSE, cmd->cmd + chat->cmd_bytes_written,
bytes_written);
chat->cmd_bytes_written += bytes_written;
@@ -964,14 +1011,14 @@ gboolean g_at_chat_set_disconnect_function(GAtChat *chat,
return TRUE;
}
-gboolean g_at_chat_set_debugging(GAtChat *chat, GAtDebugFunc func,
- gpointer user_data)
+gboolean g_at_chat_set_debug(GAtChat *chat, GAtDebugFunc func, gpointer user)
{
if (chat == NULL)
return FALSE;
chat->debugf = func;
- chat->debug_func_user_data = user_data;
+ chat->debug_data = user;
+
return TRUE;
}
diff --git a/gatchat/gatchat.h b/gatchat/gatchat.h
index 9bfcab1d..5822f1b2 100644
--- a/gatchat/gatchat.h
+++ b/gatchat/gatchat.h
@@ -57,8 +57,12 @@ 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);
+/*!
+ * If the function is not NULL, then on every read/write from the GIOChannel
+ * provided to GAtChat the logging function will be called with the
+ * input/output string and user data
+ */
+gboolean g_at_chat_set_debug(GAtChat *chat, GAtDebugFunc func, gpointer user);
/*!
* Queue an AT command for execution. The command contents are given