s_modem: Make "AT+CGMR" response parsing be compatible with the modem only return...
[platform/core/telephony/tel-plugin-imc.git] / src / s_common.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24
25 #include <glib.h>
26
27
28 #include "s_common.h"
29
30 #include <plugin.h>
31
32 #undef  MAX
33 #define MAX(a, b)  (((a) > (b)) ? (a) : (b))
34
35 #undef  MIN
36 #define MIN(a, b)  (((a) < (b)) ? (a) : (b))
37
38 #define bitsize(type) (sizeof(type) * 8)
39
40 #define copymask(type) ((0xffffffff) >> (32 - bitsize(type)))
41
42 #define MASK(width, offset, data) \
43         (((width) == bitsize(data)) ? (data) :   \
44          ((((copymask(data) << (bitsize(data) - ((width) % bitsize(data)))) & copymask(data)) >> (offset)) & (data))) \
45
46
47 #define MASK_AND_SHIFT(width, offset, shift, data)      \
48         ((((signed) (shift)) < 0) ?               \
49          MASK((width), (offset), (data)) << -(shift) :  \
50          MASK((width), (offset), (data)) >> (((signed) (shift)))) \
51
52 char _util_unpackb(const char *src, int pos, int len);
53 char _util_convert_byte_hexChar(char val);
54 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
55
56 void util_hex_dump(char *pad, int size, const void *data)
57 {
58         char buf[255] = {0, };
59         char hex[4] = {0, };
60         int i;
61         unsigned char *p;
62
63         if (size <= 0) {
64                 msg("%sno data", pad);
65                 return;
66         }
67
68         p = (unsigned char *) data;
69
70         snprintf(buf, 255, "%s%04X: ", pad, 0);
71         for (i = 0; i < size; i++) {
72                 snprintf(hex, 4, "%02X ", p[i]);
73                 strcat(buf, hex);
74
75                 if ((i + 1) % 8 == 0) {
76                         if ((i + 1) % 16 == 0) {
77                                 msg("%s", buf);
78                                 memset(buf, 0, 255);
79                                 snprintf(buf, 255, "%s%04X: ", pad, i + 1);
80                         } else {
81                                 strcat(buf, "  ");
82                         }
83                 }
84         }
85
86         msg("%s", buf);
87 }
88
89 void hook_hex_dump(enum direction_e d, int size, const void *data)
90 {
91         msg("=== TX data DUMP =====");
92         util_hex_dump("          ", size, data);
93         msg("=== TX data DUMP =====");
94 }
95
96 unsigned int util_assign_message_sequence_id(TcorePlugin *p)
97 {
98         struct global_data *gd;
99
100         if (!p) {
101                 dbg("plugin is NULL");
102                 return -1;
103         }
104
105         gd = tcore_plugin_ref_user_data(p);
106         if (!gd) {
107                 dbg("global data is NULL");
108                 return -1;
109         }
110
111         if (gd->msg_auto_id_current == 0) {
112                 gd->msg_auto_id_current = gd->msg_auto_id_start;
113                 dbg("pending_auto_id_current is 0, reset to start");
114         } else if (gd->msg_auto_id_current >= gd->msg_auto_id_end) {
115                 gd->msg_auto_id_current = gd->msg_auto_id_start;
116                 dbg("pending_auto_id_current is over, reset to start");
117         } else {
118                 gd->msg_auto_id_current++;
119         }
120
121         dbg("message_sequence_id = %d", gd->msg_auto_id_current);
122
123         return gd->msg_auto_id_current;
124 }
125
126 gboolean util_add_waiting_job(GQueue *queue, unsigned int id, UserRequest *ur)
127 {
128         struct work_queue_data *wqd;
129
130         if (!queue)
131                 return FALSE;
132
133         wqd = calloc(sizeof(struct work_queue_data), 1);
134         if (!wqd)
135                 return FALSE;
136
137         wqd->id = id;
138         wqd->ur = tcore_user_request_ref(ur);
139         g_queue_push_tail(queue, wqd);
140
141         dbg("id = %d, ur = 0x%x", wqd->id, wqd->ur);
142         return TRUE;
143 }
144
145 UserRequest* util_pop_waiting_job(GQueue *queue, unsigned int id)
146 {
147         int i = 0;
148         UserRequest *ur;
149         struct work_queue_data *wqd;
150
151         if (!queue)
152                 return NULL;
153
154
155         dbg("before waiting job count: %d", g_queue_get_length(queue));
156
157         do {
158                 wqd = g_queue_peek_nth(queue, i);
159                 if (!wqd)
160                         return NULL;
161
162                 if (wqd->id == id) {
163                         wqd = g_queue_pop_nth(queue, i);
164                         break;
165                 }
166
167                 i++;
168         } while (wqd != NULL);
169
170         dbg("after  waiting job count: %d", g_queue_get_length(queue));
171
172         if (!wqd)
173                 return NULL;
174
175         ur = wqd->ur;
176         free(wqd);
177
178         return ur;
179 }
180
181 unsigned char util_hexCharToInt(char c)
182 {
183         if (c >= '0' && c <= '9')
184                 return (c - '0');
185         else if (c >= 'A' && c <= 'F')
186                 return (c - 'A' + 10);
187         else if (c >= 'a' && c <= 'f')
188                 return (c - 'a' + 10);
189         else {
190                 dbg("invalid charater!!");
191                 return -1;
192         }
193 }
194
195 char* util_hexStringToBytes(char *s)
196 {
197         char *ret;
198         int i;
199         int sz;
200
201         if (s == NULL)
202                 return NULL;
203
204         sz = strlen(s);
205
206         ret = calloc((sz / 2) + 1, 1);
207
208         dbg("Convert String to Binary!!");
209
210         for (i = 0; i < sz; i += 2) {
211                 ret[i / 2] = (char) ((util_hexCharToInt(s[i]) << 4) | util_hexCharToInt(s[i + 1]));
212                 dbg("[%02x]", ret[i / 2]);
213         }
214
215         return ret;
216 }
217
218 char _util_unpackb(const char *src, int pos, int len)
219 {
220         char result = 0;
221         int rshift = 0;
222
223         src += pos / 8;
224         pos %= 8;
225
226         rshift = MAX(8 - (pos + len), 0);
227
228         if (rshift > 0) {
229                 result = MASK_AND_SHIFT(len, pos, rshift, *src);
230         } else {
231                 result = MASK(8 - pos, pos, *src);
232                 src++;
233                 len -= 8 - pos;
234
235                 if (len > 0) result = (result << len) | (*src >> (8 - len));   // if any bits left
236         }
237
238         return result;
239 }
240
241 char _util_convert_byte_hexChar(char val)
242 {
243         char hex_char;
244
245         if (val <= 9) {
246                 hex_char = (char) (val + '0');
247         } else if (val >= 10 && val <= 15) {
248                 hex_char = (char) (val - 10 + 'A');
249         } else {
250                 hex_char = '0';
251         }
252
253         return (hex_char);
254 }
255
256 gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes)
257 {
258         int i;
259         char nibble;
260         int buf_pos = 0;
261
262         for (i = 0; i < num_bytes * 2; i++) {
263                 nibble = _util_unpackb(byte_pdu, buf_pos, 4);
264                 buf_pos += 4;
265                 hex_pdu[i] = _util_convert_byte_hexChar(nibble);
266         }
267
268         return TRUE;
269 }
270
271 char* util_removeQuotes(void *data)
272 {
273         char *tmp = NULL;
274         int data_len = 0;
275
276         data_len = strlen((const char *) data);
277         dbg("data_len: %d----%s", data_len, data);
278         if (data_len <= 0) {
279                 return NULL;
280         }
281         tmp = calloc(1, data_len - 1);
282         memcpy(tmp, data + 1, data_len - 2);
283         dbg("tmp: %s", tmp);
284
285         return tmp;
286 }