7ca1d3f9d0fbccf78d4f7d989da2a019c1e23755
[platform/upstream/connman.git] / gatchat / gatutil.c
1 /*
2  *
3  *  AT chat library with GLib integration
4  *
5  *  Copyright (C) 2008-2010  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <ctype.h>
28
29 #include <glib.h>
30
31 #include "gatutil.h"
32
33 void g_at_util_debug_chat(gboolean in, const char *str, gsize len,
34                                 GAtDebugFunc debugf, gpointer user_data)
35 {
36         char type = in ? '<' : '>';
37         gsize escaped = 2; /* Enough for '<', ' ' */
38         char *escaped_str;
39         const char *esc = "<ESC>";
40         gsize esc_size = strlen(esc);
41         const char *ctrlz = "<CtrlZ>";
42         gsize ctrlz_size = strlen(ctrlz);
43         gsize i;
44
45         if (!debugf || !len)
46                 return;
47
48         for (i = 0; i < len; i++) {
49                 char c = str[i];
50
51                 if (isprint(c))
52                         escaped += 1;
53                 else if (c == '\r' || c == '\t' || c == '\n')
54                         escaped += 2;
55                 else if (c == 26)
56                         escaped += ctrlz_size;
57                 else if (c == 25)
58                         escaped += esc_size;
59                 else
60                         escaped += 4;
61         }
62
63         escaped_str = g_malloc(escaped + 1);
64         escaped_str[0] = type;
65         escaped_str[1] = ' ';
66         escaped_str[2] = '\0';
67         escaped_str[escaped] = '\0';
68
69         for (escaped = 2, i = 0; i < len; i++) {
70                 char c = str[i];
71
72                 switch (c) {
73                 case '\r':
74                         escaped_str[escaped++] = '\\';
75                         escaped_str[escaped++] = 'r';
76                         break;
77                 case '\t':
78                         escaped_str[escaped++] = '\\';
79                         escaped_str[escaped++] = 't';
80                         break;
81                 case '\n':
82                         escaped_str[escaped++] = '\\';
83                         escaped_str[escaped++] = 'n';
84                         break;
85                 case 26:
86                         strncpy(&escaped_str[escaped], ctrlz, ctrlz_size);
87                         escaped += ctrlz_size;
88                         break;
89                 case 25:
90                         strncpy(&escaped_str[escaped], esc, esc_size);
91                         escaped += esc_size;
92                         break;
93                 default:
94                         if (isprint(c))
95                                 escaped_str[escaped++] = c;
96                         else {
97                                 escaped_str[escaped++] = '\\';
98                                 escaped_str[escaped++] = '0' + ((c >> 6) & 07);
99                                 escaped_str[escaped++] = '0' + ((c >> 3) & 07);
100                                 escaped_str[escaped++] = '0' + (c & 07);
101                         }
102                 }
103         }
104
105         debugf(escaped_str, user_data);
106         g_free(escaped_str);
107 }
108
109 gboolean g_at_util_setup_io(GIOChannel *io, GIOFlags flags)
110 {
111         GIOFlags io_flags;
112
113         if (g_io_channel_set_encoding(io, NULL, NULL) !=
114                         G_IO_STATUS_NORMAL)
115                 return FALSE;
116
117         io_flags = g_io_channel_get_flags(io);
118
119         io_flags |= (flags & G_IO_FLAG_SET_MASK);
120
121         if (g_io_channel_set_flags(io, io_flags, NULL) !=
122                         G_IO_STATUS_NORMAL)
123                 return FALSE;
124
125         g_io_channel_set_close_on_unref(io, TRUE);
126
127         return TRUE;
128 }
129