/* * * AT chat library with GLib integration * * Copyright (C) 2008-2011 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "gatutil.h" void g_at_util_debug_chat(gboolean in, const char *str, gsize len, GAtDebugFunc debugf, gpointer user_data) { char type = in ? '<' : '>'; gsize escaped = 2; /* Enough for '<', ' ' */ char *escaped_str; const char *esc = ""; gsize esc_size = strlen(esc); const char *ctrlz = ""; gsize ctrlz_size = strlen(ctrlz); gsize i; if (debugf == NULL || !len) return; for (i = 0; i < len; i++) { char c = str[i]; if (g_ascii_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; } escaped_str = g_try_malloc(escaped + 1); if (escaped_str == NULL) return; escaped_str[0] = type; escaped_str[1] = ' '; memset(escaped_str + 2, '\0', escaped - 1); for (escaped = 2, i = 0; i < len; i++) { unsigned 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: memcpy(escaped_str + escaped, ctrlz, ctrlz_size); escaped += ctrlz_size; break; case 25: memcpy(escaped_str + escaped, esc, esc_size); escaped += esc_size; break; default: if (g_ascii_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); } } } debugf(escaped_str, user_data); g_free(escaped_str); } void g_at_util_debug_dump(gboolean in, const unsigned char *buf, gsize len, GAtDebugFunc debugf, gpointer user_data) { char type = in ? '<' : '>'; GString *str; gsize i; if (debugf == NULL || !len) return; str = g_string_sized_new(1 + (len * 2)); if (str == NULL) return; g_string_append_c(str, type); for (i = 0; i < len; i++) g_string_append_printf(str, " %02x", buf[i]); debugf(str->str, user_data); g_string_free(str, TRUE); } void g_at_util_debug_hexdump(gboolean in, const unsigned char *buf, gsize len, GAtDebugFunc debugf, gpointer user_data) { static const char hexdigits[] = "0123456789abcdef"; char str[68]; gsize i; if (debugf == NULL || !len) return; str[0] = in ? '<' : '>'; for (i = 0; i < len; i++) { str[((i % 16) * 3) + 1] = ' '; str[((i % 16) * 3) + 2] = hexdigits[buf[i] >> 4]; str[((i % 16) * 3) + 3] = hexdigits[buf[i] & 0xf]; str[(i % 16) + 51] = g_ascii_isprint(buf[i]) ? buf[i] : '.'; if ((i + 1) % 16 == 0) { str[49] = ' '; str[50] = ' '; str[67] = '\0'; debugf(str, user_data); str[0] = ' '; } } if (i % 16 > 0) { gsize j; for (j = (i % 16); j < 16; j++) { str[(j * 3) + 1] = ' '; str[(j * 3) + 2] = ' '; str[(j * 3) + 3] = ' '; str[j + 51] = ' '; } str[49] = ' '; str[50] = ' '; str[67] = '\0'; debugf(str, user_data); } } gboolean g_at_util_setup_io(GIOChannel *io, GIOFlags flags) { GIOFlags io_flags; if (g_io_channel_set_encoding(io, NULL, NULL) != G_IO_STATUS_NORMAL) return FALSE; g_io_channel_set_buffered(io, FALSE); if (flags & G_IO_FLAG_SET_MASK) { io_flags = g_io_channel_get_flags(io); io_flags |= (flags & G_IO_FLAG_SET_MASK); if (g_io_channel_set_flags(io, io_flags, NULL) != G_IO_STATUS_NORMAL) return FALSE; } g_io_channel_set_close_on_unref(io, TRUE); return TRUE; }