upload tizen1.0 source
[profile/ivi/obexd.git] / src / map_ap.c
1 /*
2  *
3  *  OBEX Server
4  *
5  *  Copyright (C) 2010-2011  Nokia Corporation
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 #ifdef OPENSOURCE_PATCH
28 #include <string.h>
29
30 #include "log.h"
31 #endif
32 #include "map_ap.h"
33
34 #ifdef OPENSOURCE_PATCH
35 enum ap_type {
36         APT_UINT8,
37         APT_UINT16,
38         APT_UINT32,
39         APT_STR
40 };
41
42 /* NOTE: ap_defs array has to be kept in sync with map_ap_tag. */
43 static const struct ap_def {
44         const char *name;
45         enum ap_type type;
46 } ap_defs[] = {
47         { "MAXLISTCOUNT",               APT_UINT16 },
48         { "STARTOFFSET",                APT_UINT16 },
49         { "FILTERMESSAGETYPE",          APT_UINT8  },
50         { "FILTERPERIODBEGIN",          APT_STR    },
51         { "FILTERPERIODEND",            APT_STR    },
52         { "FILTERREADSTATUS",           APT_UINT8  },
53         { "FILTERRECIPIENT",            APT_STR    },
54         { "FILTERORIGINATOR",           APT_STR    },
55         { "FILTERPRIORITY",             APT_UINT8  },
56         { "ATTACHMENT",                 APT_UINT8  },
57         { "TRANSPARENT",                APT_UINT8  },
58         { "RETRY",                      APT_UINT8  },
59         { "NEWMESSAGE",                 APT_UINT8  },
60         { "NOTIFICATIONSTATUS",         APT_UINT8  },
61         { "MASINSTANCEID",              APT_UINT8  },
62         { "PARAMETERMASK",              APT_UINT32 },
63         { "FOLDERLISTINGSIZE",          APT_UINT16 },
64         { "MESSAGESLISTINGSIZE",        APT_UINT16 },
65         { "SUBJECTLENGTH",              APT_UINT8  },
66         { "CHARSET",                    APT_UINT8  },
67         { "FRACTIONREQUEST",            APT_UINT8  },
68         { "FRACTIONDELIVER",            APT_UINT8  },
69         { "STATUSINDICATOR",            APT_UINT8  },
70         { "STATUSVALUE",                APT_UINT8  },
71         { "MSETIME",                    APT_STR    },
72 };
73
74 struct ap_entry {
75         enum map_ap_tag tag;
76         union {
77                 uint32_t u32;
78                 uint16_t u16;
79                 uint8_t u8;
80                 char *str;
81         } val;
82 };
83
84 /* This comes from OBEX specs */
85 struct obex_ap_header {
86         uint8_t tag;
87         uint8_t len;
88         uint8_t val[0];
89 } __attribute__ ((packed));
90
91 static int find_ap_def_offset(uint8_t tag)
92 {
93         if (tag == 0 || tag > G_N_ELEMENTS(ap_defs))
94                 return -1;
95
96         return tag - 1;
97 }
98
99 static void ap_entry_dump(gpointer tag, gpointer val, gpointer user_data)
100 {
101         struct ap_entry *entry = val;
102         int offset;
103
104         offset = find_ap_def_offset(GPOINTER_TO_INT(tag));
105
106         switch (ap_defs[offset].type) {
107         case APT_UINT8:
108                 DBG("%-30s %08x", ap_defs[offset].name, entry->val.u8);
109                 break;
110         case APT_UINT16:
111                 DBG("%-30s %08x", ap_defs[offset].name, entry->val.u16);
112                 break;
113         case APT_UINT32:
114                 DBG("%-30s %08x", ap_defs[offset].name, entry->val.u32);
115                 break;
116         case APT_STR:
117                 DBG("%-30s %s", ap_defs[offset].name, entry->val.str);
118                 break;
119         }
120 }
121
122 static void ap_entry_free(gpointer val)
123 {
124         struct ap_entry *entry = val;
125         int offset;
126
127         offset = find_ap_def_offset(entry->tag);
128
129         if (offset >= 0 && ap_defs[offset].type == APT_STR)
130                 g_free(entry->val.str);
131
132         g_free(entry);
133 }
134 #endif
135
136 map_ap_t *map_ap_new(void)
137 {
138 #ifdef OPENSOURCE_PATCH
139         return g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
140                                                                 ap_entry_free);
141 #else
142         return NULL;
143 #endif
144 }
145
146 void map_ap_free(map_ap_t *ap)
147 {
148 #ifdef OPENSOURCE_PATCH
149         if (!ap)
150                 return;
151
152         g_hash_table_destroy(ap);
153 #endif
154 }
155
156 #ifdef OPENSOURCE_PATCH
157 static void ap_decode_u8(map_ap_t *ap, const struct obex_ap_header *hdr)
158 {
159         if (hdr->len != 1) {
160                 DBG("Value of tag %u is %u byte(s) long instead of expected "
161                                 "1 byte - skipped!", hdr->tag, hdr->len);
162                 return;
163         }
164
165         map_ap_set_u8(ap, hdr->tag, hdr->val[0]);
166 }
167
168 static void ap_decode_u16(map_ap_t *ap, const struct obex_ap_header *hdr)
169 {
170         uint16_t val;
171
172         if (hdr->len != 2) {
173                 DBG("Value of tag %u is %u byte(s) long instead of expected "
174                                 "2 bytes - skipped!", hdr->tag, hdr->len);
175                 return;
176         }
177
178         memcpy(&val, hdr->val, sizeof(val));
179         map_ap_set_u16(ap, hdr->tag, GUINT16_FROM_BE(val));
180 }
181
182 static void ap_decode_u32(map_ap_t *ap, const struct obex_ap_header *hdr)
183 {
184         uint32_t val;
185
186         if (hdr->len != 4) {
187                 DBG("Value of tag %u is %u byte(s) long instead of expected "
188                                 "4 bytes - skipped!", hdr->tag, hdr->len);
189                 return;
190         }
191
192         memcpy(&val, hdr->val, sizeof(val));
193         map_ap_set_u32(ap, hdr->tag, GUINT32_FROM_BE(val));
194 }
195
196 static void ap_decode_str(map_ap_t *ap, const struct obex_ap_header *hdr)
197 {
198         char *val = g_malloc0(hdr->len + 1);
199
200         memcpy(val, hdr->val, hdr->len);
201         map_ap_set_string(ap, hdr->tag, val);
202
203         g_free(val);
204 }
205 #endif
206
207 map_ap_t *map_ap_decode(const uint8_t *buffer, size_t length)
208 {
209 #ifdef OPENSOURCE_PATCH
210         map_ap_t *ap;
211         struct obex_ap_header *hdr;
212         uint32_t done;
213         int offset;
214
215         ap = map_ap_new();
216         if (!ap)
217                 return NULL;
218
219         for (done = 0; done < length; done += hdr->len + sizeof(*hdr)) {
220                 hdr = (struct obex_ap_header *)(buffer + done);
221
222                 offset = find_ap_def_offset(hdr->tag);
223
224                 if (offset < 0) {
225                         DBG("Unknown tag %u (length %u) - skipped.",
226                                                         hdr->tag, hdr->len);
227                         continue;
228                 }
229
230                 switch (ap_defs[offset].type) {
231                 case APT_UINT8:
232                         ap_decode_u8(ap, hdr);
233                         break;
234                 case APT_UINT16:
235                         ap_decode_u16(ap, hdr);
236                         break;
237                 case APT_UINT32:
238                         ap_decode_u32(ap, hdr);
239                         break;
240                 case APT_STR:
241                         ap_decode_str(ap, hdr);
242                         break;
243                 }
244         }
245
246         g_hash_table_foreach(ap, ap_entry_dump, NULL);
247
248         return ap;
249 #else
250         return NULL;
251 #endif
252 }
253
254 uint8_t *map_ap_encode(map_ap_t *ap, size_t *length)
255 {
256         *length = 0;
257
258         return NULL;
259 }
260
261 gboolean map_ap_get_u8(map_ap_t *ap, enum map_ap_tag tag, uint8_t *val)
262 {
263 #ifdef TIZEN_PATCH
264         struct ap_entry *entry;
265         int offset = find_ap_def_offset(tag);
266
267         if (offset < 0 || ap_defs[offset].type != APT_UINT8)
268                 return FALSE;
269
270         entry = g_hash_table_lookup(ap, GINT_TO_POINTER(tag));
271
272         if (!entry)
273                 return FALSE;
274
275         *val = entry->val.u8;
276
277         return TRUE;
278 #else
279         return FALSE;
280 #endif
281 }
282
283 gboolean map_ap_get_u16(map_ap_t *ap, enum map_ap_tag tag, uint16_t *val)
284 {
285 #ifdef TIZEN_PATCH
286         struct ap_entry *entry;
287         int offset = find_ap_def_offset(tag);
288
289         if (offset < 0 || ap_defs[offset].type != APT_UINT16)
290                 return FALSE;
291
292         entry = g_hash_table_lookup(ap, GINT_TO_POINTER(tag));
293
294         if (!entry)
295                 return FALSE;
296
297         *val = entry->val.u16;
298
299         return TRUE;
300 #else
301         return FALSE;
302 #endif
303 }
304
305 gboolean map_ap_get_u32(map_ap_t *ap, enum map_ap_tag tag, uint32_t *val)
306 {
307 #ifdef TIZEN_PATCH
308         struct ap_entry *entry;
309         int offset = find_ap_def_offset(tag);
310
311         if (offset < 0 || ap_defs[offset].type != APT_UINT32)
312                 return FALSE;
313
314         entry = g_hash_table_lookup(ap, GINT_TO_POINTER(tag));
315
316         if (!entry)
317                 return FALSE;
318
319         *val = entry->val.u32;
320
321         return TRUE;
322 #else
323         return FALSE;
324 #endif
325 }
326
327 const char *map_ap_get_string(map_ap_t *ap, enum map_ap_tag tag)
328 {
329 #ifdef TIZEN_PATCH
330         struct ap_entry *entry;
331         int offset = find_ap_def_offset(tag);
332
333         if (offset < 0 || ap_defs[offset].type != APT_STR)
334                 return NULL;
335
336         entry = g_hash_table_lookup(ap, GINT_TO_POINTER(tag));
337
338         if (!entry)
339                 return NULL;
340
341         return g_strdup(entry->val.str);
342 #else
343         return NULL;
344 #endif
345 }
346
347 gboolean map_ap_set_u8(map_ap_t *ap, enum map_ap_tag tag, uint8_t val)
348 {
349 #ifdef OPENSOURCE_PATCH
350         struct ap_entry *entry;
351         int offset = find_ap_def_offset(tag);
352
353         if (offset < 0 || ap_defs[offset].type != APT_UINT8)
354                 return FALSE;
355
356         entry = g_new0(struct ap_entry, 1);
357         entry->tag = tag;
358         entry->val.u8 = val;
359
360         g_hash_table_insert(ap, GINT_TO_POINTER(tag), entry);
361
362         return TRUE;
363 #else
364         return FALSE;
365 #endif
366 }
367
368 gboolean map_ap_set_u16(map_ap_t *ap, enum map_ap_tag tag, uint16_t val)
369 {
370 #ifdef OPENSOURCE_PATCH
371         struct ap_entry *entry;
372         int offset = find_ap_def_offset(tag);
373
374         if (offset < 0 || ap_defs[offset].type != APT_UINT16)
375                 return FALSE;
376
377         entry = g_new0(struct ap_entry, 1);
378         entry->tag = tag;
379         entry->val.u16 = val;
380
381         g_hash_table_insert(ap, GINT_TO_POINTER(tag), entry);
382
383         return TRUE;
384 #else
385         return FALSE;
386 #endif
387 }
388
389 gboolean map_ap_set_u32(map_ap_t *ap, enum map_ap_tag tag, uint32_t val)
390 {
391 #ifdef OPENSOURCE_PATCH
392         struct ap_entry *entry;
393         int offset = find_ap_def_offset(tag);
394
395         if (offset < 0 || ap_defs[offset].type != APT_UINT32)
396                 return FALSE;
397
398         entry = g_new0(struct ap_entry, 1);
399         entry->tag = tag;
400         entry->val.u32 = val;
401
402         g_hash_table_insert(ap, GINT_TO_POINTER(tag), entry);
403
404         return TRUE;
405 #else
406         return FALSE;
407 #endif
408 }
409
410 gboolean map_ap_set_string(map_ap_t *ap, enum map_ap_tag tag, const char *val)
411 {
412 #ifdef OPENSOURCE_PATCH
413         struct ap_entry *entry;
414         int offset = find_ap_def_offset(tag);
415
416         if (offset < 0 || ap_defs[offset].type != APT_STR)
417                 return FALSE;
418
419         entry = g_new0(struct ap_entry, 1);
420         entry->tag = tag;
421         entry->val.str = g_strdup(val);
422
423         g_hash_table_insert(ap, GINT_TO_POINTER(tag), entry);
424
425         return TRUE;
426 #else
427         return FALSE;
428 #endif
429 }