~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to wpa_supplicant/dbus_dict_helpers.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2008-03-12 20:03:04 UTC
  • mfrom: (1.1.10 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20080312200304-4331y9wj46pdd34z
Tags: 0.6.3-1
* New upstream release.
* Drop patches applied upstream:
  - debian/patches/30_wpa_gui_qt4_eventhistoryui_rework.patch
  - debian/patches/31_wpa_gui_qt4_eventhistory_always_scrollbar.patch
  - debian/patches/32_wpa_gui_qt4_eventhistory_scroll_with_events.patch
  - debian/patches/40_dbus_ssid_data.patch
* Tidy up the clean target of debian/rules. Now that the madwifi headers are
  handled differently we no longer need to do any cleanup.
* Fix formatting error in debian/ifupdown/wpa_action.8 to make lintian
  quieter.
* Add patch to fix formatting errors in manpages build from sgml source. Use
  <emphasis> tags to hightlight keywords instead of surrounding them in
  strong quotes.
  - debian/patches/41_manpage_format_fixes.patch
* wpasupplicant binary package no longer suggests pcscd, guessnet, iproute
  or wireless-tools, nor does it recommend dhcp3-client. These are not
  needed.
* Add debian/patches/10_silence_siocsiwauth_icotl_failure.patch to disable
  ioctl failure messages that occur under normal conditions.
* Cherry pick two upstream git commits concerning the dbus interface:
  - debian/patches/11_avoid_dbus_version_namespace.patch
  - debian/patches/12_fix_potential_use_after_free.patch
* Add debian/patches/42_manpage_explain_available_drivers.patch to explain
  that not all of the driver backends are available in the provided
  wpa_supplicant binary, and that the canonical list of supported driver
  backends can be retrieved from the wpa_supplicant -h (help) output.
  (Closes: #466910)
* Add debian/patches/20_wpa_gui_qt4_disable_link_prl.patch to remove
  link_prl CONFIG compile flag added by qmake-qt4 >= 4.3.4-2 to avoid excess
  linking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * WPA Supplicant / dbus-based control interface
 
3
 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
#include <dbus/dbus.h>
 
17
 
 
18
#include "common.h"
 
19
#include "dbus_dict_helpers.h"
 
20
 
 
21
 
 
22
/**
 
23
 * Start a dict in a dbus message.  Should be paired with a call to
 
24
 * {@link wpa_dbus_dict_close_write}.
 
25
 *
 
26
 * @param iter A valid dbus message iterator
 
27
 * @param iter_dict (out) A dict iterator to pass to further dict functions
 
28
 * @return TRUE on success, FALSE on failure
 
29
 *
 
30
 */
 
31
dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
 
32
                                     DBusMessageIter *iter_dict)
 
33
{
 
34
        dbus_bool_t result;
 
35
 
 
36
        if (!iter || !iter_dict)
 
37
                return FALSE;
 
38
 
 
39
        result = dbus_message_iter_open_container(
 
40
                iter,
 
41
                DBUS_TYPE_ARRAY,
 
42
                DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
 
43
                DBUS_TYPE_STRING_AS_STRING
 
44
                DBUS_TYPE_VARIANT_AS_STRING
 
45
                DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
 
46
                iter_dict);
 
47
        return result;
 
48
}
 
49
 
 
50
 
 
51
/**
 
52
 * End a dict element in a dbus message.  Should be paired with
 
53
 * a call to {@link wpa_dbus_dict_open_write}.
 
54
 *
 
55
 * @param iter valid dbus message iterator, same as passed to
 
56
 *    wpa_dbus_dict_open_write()
 
57
 * @param iter_dict a dbus dict iterator returned from
 
58
 *    {@link wpa_dbus_dict_open_write}
 
59
 * @return TRUE on success, FALSE on failure
 
60
 *
 
61
 */
 
62
dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
 
63
                                      DBusMessageIter *iter_dict)
 
64
{
 
65
        if (!iter || !iter_dict)
 
66
                return FALSE;
 
67
 
 
68
        return dbus_message_iter_close_container(iter, iter_dict);
 
69
}
 
70
 
 
71
 
 
72
static const char * _wpa_get_type_as_string_from_type(const int type)
 
73
{
 
74
        switch(type) {
 
75
        case DBUS_TYPE_BYTE:
 
76
                return DBUS_TYPE_BYTE_AS_STRING;
 
77
        case DBUS_TYPE_BOOLEAN:
 
78
                return DBUS_TYPE_BOOLEAN_AS_STRING;
 
79
        case DBUS_TYPE_INT16:
 
80
                return DBUS_TYPE_INT16_AS_STRING;
 
81
        case DBUS_TYPE_UINT16:
 
82
                return DBUS_TYPE_UINT16_AS_STRING;
 
83
        case DBUS_TYPE_INT32:
 
84
                return DBUS_TYPE_INT32_AS_STRING;
 
85
        case DBUS_TYPE_UINT32:
 
86
                return DBUS_TYPE_UINT32_AS_STRING;
 
87
        case DBUS_TYPE_INT64:
 
88
                return DBUS_TYPE_INT64_AS_STRING;
 
89
        case DBUS_TYPE_UINT64:
 
90
                return DBUS_TYPE_UINT64_AS_STRING;
 
91
        case DBUS_TYPE_DOUBLE:
 
92
                return DBUS_TYPE_DOUBLE_AS_STRING;
 
93
        case DBUS_TYPE_STRING:
 
94
                return DBUS_TYPE_STRING_AS_STRING;
 
95
        case DBUS_TYPE_OBJECT_PATH:
 
96
                return DBUS_TYPE_OBJECT_PATH_AS_STRING;
 
97
        case DBUS_TYPE_ARRAY:
 
98
                return DBUS_TYPE_ARRAY_AS_STRING;
 
99
        default:
 
100
                return NULL;
 
101
        }
 
102
}
 
103
 
 
104
 
 
105
static dbus_bool_t _wpa_dbus_add_dict_entry_start(
 
106
        DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
 
107
        const char *key, const int value_type)
 
108
{
 
109
        if (!dbus_message_iter_open_container(iter_dict,
 
110
                                              DBUS_TYPE_DICT_ENTRY, NULL,
 
111
                                              iter_dict_entry))
 
112
                return FALSE;
 
113
 
 
114
        if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
 
115
                                            &key))
 
116
                return FALSE;
 
117
 
 
118
        return TRUE;
 
119
}
 
120
 
 
121
 
 
122
static dbus_bool_t _wpa_dbus_add_dict_entry_end(
 
123
        DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
 
124
        DBusMessageIter *iter_dict_val)
 
125
{
 
126
        if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
 
127
                return FALSE;
 
128
        if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry))
 
129
                return FALSE;
 
130
 
 
131
        return TRUE;
 
132
}
 
133
 
 
134
 
 
135
static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict,
 
136
                                                  const char *key,
 
137
                                                  const int value_type,
 
138
                                                  const void *value)
 
139
{
 
140
        DBusMessageIter iter_dict_entry, iter_dict_val;
 
141
        const char *type_as_string = NULL;
 
142
 
 
143
        type_as_string = _wpa_get_type_as_string_from_type(value_type);
 
144
        if (!type_as_string)
 
145
                return FALSE;
 
146
 
 
147
        if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
 
148
                                            key, value_type))
 
149
                return FALSE;
 
150
 
 
151
        if (!dbus_message_iter_open_container(&iter_dict_entry,
 
152
                                              DBUS_TYPE_VARIANT,
 
153
                                              type_as_string, &iter_dict_val))
 
154
                return FALSE;
 
155
 
 
156
        if (!dbus_message_iter_append_basic(&iter_dict_val, value_type, value))
 
157
                return FALSE;
 
158
 
 
159
        if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
 
160
                                          &iter_dict_val))
 
161
                return FALSE;
 
162
 
 
163
        return TRUE;
 
164
}
 
165
 
 
166
 
 
167
static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
 
168
        DBusMessageIter *iter_dict, const char *key,
 
169
        const char *value, const dbus_uint32_t value_len)
 
170
{
 
171
        DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
 
172
        dbus_uint32_t i;
 
173
 
 
174
        if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
 
175
                                            key, DBUS_TYPE_ARRAY))
 
176
                return FALSE;
 
177
 
 
178
        if (!dbus_message_iter_open_container(&iter_dict_entry,
 
179
                                              DBUS_TYPE_VARIANT,
 
180
                                              DBUS_TYPE_ARRAY_AS_STRING
 
181
                                              DBUS_TYPE_BYTE_AS_STRING,
 
182
                                              &iter_dict_val))
 
183
                return FALSE;
 
184
 
 
185
        if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
 
186
                                              DBUS_TYPE_BYTE_AS_STRING,
 
187
                                              &iter_array))
 
188
                return FALSE;
 
189
 
 
190
        for (i = 0; i < value_len; i++) {
 
191
                if (!dbus_message_iter_append_basic(&iter_array,
 
192
                                                    DBUS_TYPE_BYTE,
 
193
                                                    &(value[i])))
 
194
                        return FALSE;
 
195
        }
 
196
 
 
197
        if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
 
198
                return FALSE;
 
199
 
 
200
        if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
 
201
                                          &iter_dict_val))
 
202
                return FALSE;
 
203
 
 
204
        return TRUE;
 
205
}
 
206
 
 
207
 
 
208
/**
 
209
 * Add a string entry to the dict.
 
210
 *
 
211
 * @param iter_dict A valid DBusMessageIter returned from
 
212
 *    {@link wpa_dbus_dict_open_write}
 
213
 * @param key The key of the dict item
 
214
 * @param value The string value
 
215
 * @return TRUE on success, FALSE on failure
 
216
 *
 
217
 */
 
218
dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
 
219
                                        const char *key, const char *value)
 
220
{
 
221
        if (!key || !value)
 
222
                return FALSE;
 
223
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING,
 
224
                                              &value);
 
225
}
 
226
 
 
227
 
 
228
/**
 
229
 * Add a byte entry to the dict.
 
230
 *
 
231
 * @param iter_dict A valid DBusMessageIter returned from
 
232
 *    {@link wpa_dbus_dict_open_write}
 
233
 * @param key The key of the dict item
 
234
 * @param value The byte value
 
235
 * @return TRUE on success, FALSE on failure
 
236
 *
 
237
 */
 
238
dbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict,
 
239
                                      const char *key, const char value)
 
240
{
 
241
        if (!key)
 
242
                return FALSE;
 
243
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BYTE,
 
244
                                              &value);
 
245
}
 
246
 
 
247
 
 
248
/**
 
249
 * Add a boolean entry to the dict.
 
250
 *
 
251
 * @param iter_dict A valid DBusMessageIter returned from
 
252
 *    {@link wpa_dbus_dict_open_write}
 
253
 * @param key The key of the dict item
 
254
 * @param value The boolean value
 
255
 * @return TRUE on success, FALSE on failure
 
256
 *
 
257
 */
 
258
dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
 
259
                                      const char *key, const dbus_bool_t value)
 
260
{
 
261
        if (!key)
 
262
                return FALSE;
 
263
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
 
264
                                              DBUS_TYPE_BOOLEAN, &value);
 
265
}
 
266
 
 
267
 
 
268
/**
 
269
 * Add a 16-bit signed integer entry to the dict.
 
270
 *
 
271
 * @param iter_dict A valid DBusMessageIter returned from
 
272
 *    {@link wpa_dbus_dict_open_write}
 
273
 * @param key The key of the dict item
 
274
 * @param value The 16-bit signed integer value
 
275
 * @return TRUE on success, FALSE on failure
 
276
 *
 
277
 */
 
278
dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict,
 
279
                                       const char *key,
 
280
                                       const dbus_int16_t value)
 
281
{
 
282
        if (!key)
 
283
                return FALSE;
 
284
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16,
 
285
                                              &value);
 
286
}
 
287
 
 
288
 
 
289
/**
 
290
 * Add a 16-bit unsigned integer entry to the dict.
 
291
 *
 
292
 * @param iter_dict A valid DBusMessageIter returned from
 
293
 *    {@link wpa_dbus_dict_open_write}
 
294
 * @param key The key of the dict item
 
295
 * @param value The 16-bit unsigned integer value
 
296
 * @return TRUE on success, FALSE on failure
 
297
 *
 
298
 */
 
299
dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
 
300
                                        const char *key,
 
301
                                        const dbus_uint16_t value)
 
302
{
 
303
        if (!key)
 
304
                return FALSE;
 
305
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16,
 
306
                                              &value);
 
307
}
 
308
 
 
309
 
 
310
/**
 
311
 * Add a 32-bit signed integer to the dict.
 
312
 *
 
313
 * @param iter_dict A valid DBusMessageIter returned from
 
314
 *    {@link wpa_dbus_dict_open_write}
 
315
 * @param key The key of the dict item
 
316
 * @param value The 32-bit signed integer value
 
317
 * @return TRUE on success, FALSE on failure
 
318
 *
 
319
 */
 
320
dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
 
321
                                       const char *key,
 
322
                                       const dbus_int32_t value)
 
323
{
 
324
        if (!key)
 
325
                return FALSE;
 
326
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32,
 
327
                                              &value);
 
328
}
 
329
 
 
330
 
 
331
/**
 
332
 * Add a 32-bit unsigned integer entry to the dict.
 
333
 *
 
334
 * @param iter_dict A valid DBusMessageIter returned from
 
335
 *    {@link wpa_dbus_dict_open_write}
 
336
 * @param key The key of the dict item
 
337
 * @param value The 32-bit unsigned integer value
 
338
 * @return TRUE on success, FALSE on failure
 
339
 *
 
340
 */
 
341
dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
 
342
                                        const char *key,
 
343
                                        const dbus_uint32_t value)
 
344
{
 
345
        if (!key)
 
346
                return FALSE;
 
347
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32,
 
348
                                              &value);
 
349
}
 
350
 
 
351
 
 
352
/**
 
353
 * Add a 64-bit integer entry to the dict.
 
354
 *
 
355
 * @param iter_dict A valid DBusMessageIter returned from
 
356
 *    {@link wpa_dbus_dict_open_write}
 
357
 * @param key The key of the dict item
 
358
 * @param value The 64-bit integer value
 
359
 * @return TRUE on success, FALSE on failure
 
360
 *
 
361
 */
 
362
dbus_bool_t wpa_dbus_dict_append_int64(DBusMessageIter *iter_dict,
 
363
                                       const char *key,
 
364
                                       const dbus_int64_t value)
 
365
{
 
366
        if (!key)
 
367
                return FALSE;
 
368
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT64,
 
369
                                              &value);
 
370
}
 
371
 
 
372
 
 
373
/**
 
374
 * Add a 64-bit unsigned integer entry to the dict.
 
375
 *
 
376
 * @param iter_dict A valid DBusMessageIter returned from
 
377
 *    {@link wpa_dbus_dict_open_write}
 
378
 * @param key The key of the dict item
 
379
 * @param value The 64-bit unsigned integer value
 
380
 * @return TRUE on success, FALSE on failure
 
381
 *
 
382
 */
 
383
dbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict,
 
384
                                        const char *key,
 
385
                                        const dbus_uint64_t value)
 
386
{
 
387
        if (!key)
 
388
                return FALSE;
 
389
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT64,
 
390
                                              &value);
 
391
}
 
392
 
 
393
 
 
394
/**
 
395
 * Add a double-precision floating point entry to the dict.
 
396
 *
 
397
 * @param iter_dict A valid DBusMessageIter returned from
 
398
 *    {@link wpa_dbus_dict_open_write}
 
399
 * @param key The key of the dict item
 
400
 * @param value The double-precision floating point value
 
401
 * @return TRUE on success, FALSE on failure
 
402
 *
 
403
 */
 
404
dbus_bool_t wpa_dbus_dict_append_double(DBusMessageIter *iter_dict,
 
405
                                        const char * key,
 
406
                                        const double value)
 
407
{
 
408
        if (!key)
 
409
                return FALSE;
 
410
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_DOUBLE,
 
411
                                              &value);
 
412
}
 
413
 
 
414
 
 
415
/**
 
416
 * Add a DBus object path entry to the dict.
 
417
 *
 
418
 * @param iter_dict A valid DBusMessageIter returned from
 
419
 *    {@link wpa_dbus_dict_open_write}
 
420
 * @param key The key of the dict item
 
421
 * @param value The DBus object path value
 
422
 * @return TRUE on success, FALSE on failure
 
423
 *
 
424
 */
 
425
dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
 
426
                                             const char *key,
 
427
                                             const char *value)
 
428
{
 
429
        if (!key || !value)
 
430
                return FALSE;
 
431
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
 
432
                                              DBUS_TYPE_OBJECT_PATH, &value);
 
433
}
 
434
 
 
435
 
 
436
/**
 
437
 * Add a byte array entry to the dict.
 
438
 *
 
439
 * @param iter_dict A valid DBusMessageIter returned from
 
440
 *    {@link wpa_dbus_dict_open_write}
 
441
 * @param key The key of the dict item
 
442
 * @param value The byte array
 
443
 * @param value_len The length of the byte array, in bytes
 
444
 * @return TRUE on success, FALSE on failure
 
445
 *
 
446
 */
 
447
dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
 
448
                                            const char *key,
 
449
                                            const char *value,
 
450
                                            const dbus_uint32_t value_len)
 
451
{
 
452
        if (!key)
 
453
                return FALSE;
 
454
        if (!value && (value_len != 0))
 
455
                return FALSE;
 
456
        return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
 
457
                                                   value_len);
 
458
}
 
459
 
 
460
 
 
461
/**
 
462
 * Begin a string array entry in the dict
 
463
 *
 
464
 * @param iter_dict A valid DBusMessageIter returned from
 
465
 *                  {@link nmu_dbus_dict_open_write}
 
466
 * @param key The key of the dict item
 
467
 * @param iter_dict_entry A private DBusMessageIter provided by the caller to
 
468
 *                        be passed to {@link wpa_dbus_dict_end_string_array}
 
469
 * @param iter_dict_val A private DBusMessageIter provided by the caller to
 
470
 *                      be passed to {@link wpa_dbus_dict_end_string_array}
 
471
 * @param iter_array On return, the DBusMessageIter to be passed to
 
472
 *                   {@link wpa_dbus_dict_string_array_add_element}
 
473
 * @return TRUE on success, FALSE on failure
 
474
 *
 
475
 */
 
476
dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
 
477
                                             const char *key,
 
478
                                             DBusMessageIter *iter_dict_entry,
 
479
                                             DBusMessageIter *iter_dict_val,
 
480
                                             DBusMessageIter *iter_array)
 
481
{
 
482
        if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
 
483
                return FALSE;
 
484
 
 
485
        if (!_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry,
 
486
                                            key, DBUS_TYPE_ARRAY))
 
487
                return FALSE;
 
488
 
 
489
        if (!dbus_message_iter_open_container(iter_dict_entry,
 
490
                                              DBUS_TYPE_VARIANT,
 
491
                                              DBUS_TYPE_ARRAY_AS_STRING
 
492
                                              DBUS_TYPE_STRING_AS_STRING,
 
493
                                              iter_dict_val))
 
494
                return FALSE;
 
495
 
 
496
        if (!dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY,
 
497
                                              DBUS_TYPE_BYTE_AS_STRING,
 
498
                                              iter_array))
 
499
                return FALSE;
 
500
 
 
501
        return TRUE;
 
502
}
 
503
 
 
504
 
 
505
/**
 
506
 * Add a single string element to a string array dict entry
 
507
 *
 
508
 * @param iter_array A valid DBusMessageIter returned from
 
509
 *                   {@link wpa_dbus_dict_begin_string_array}'s
 
510
 *                   iter_array parameter
 
511
 * @param elem The string element to be added to the dict entry's string array
 
512
 * @return TRUE on success, FALSE on failure
 
513
 *
 
514
 */
 
515
dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
 
516
                                                   const char *elem)
 
517
{
 
518
        if (!iter_array || !elem)
 
519
                return FALSE;
 
520
 
 
521
        return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING,
 
522
                                              &elem);
 
523
}
 
524
 
 
525
 
 
526
/**
 
527
 * End a string array dict entry
 
528
 *
 
529
 * @param iter_dict A valid DBusMessageIter returned from
 
530
 *                  {@link nmu_dbus_dict_open_write}
 
531
 * @param iter_dict_entry A private DBusMessageIter returned from
 
532
 *                        {@link wpa_dbus_dict_end_string_array}
 
533
 * @param iter_dict_val A private DBusMessageIter returned from
 
534
 *                      {@link wpa_dbus_dict_end_string_array}
 
535
 * @param iter_array A DBusMessageIter returned from
 
536
 *                   {@link wpa_dbus_dict_end_string_array}
 
537
 * @return TRUE on success, FALSE on failure
 
538
 *
 
539
 */
 
540
dbus_bool_t wpa_dbus_dict_end_string_array(DBusMessageIter *iter_dict,
 
541
                                           DBusMessageIter *iter_dict_entry,
 
542
                                           DBusMessageIter *iter_dict_val,
 
543
                                           DBusMessageIter *iter_array)
 
544
{
 
545
        if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
 
546
                return FALSE;
 
547
 
 
548
        if (!dbus_message_iter_close_container(iter_dict_val, iter_array))
 
549
                return FALSE;
 
550
 
 
551
        if (!_wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry,
 
552
                                          iter_dict_val))
 
553
                return FALSE;
 
554
 
 
555
        return TRUE;
 
556
}
 
557
 
 
558
 
 
559
/**
 
560
 * Convenience function to add an entire string array to the dict.
 
561
 *
 
562
 * @param iter_dict A valid DBusMessageIter returned from
 
563
 *                  {@link nmu_dbus_dict_open_write}
 
564
 * @param key The key of the dict item
 
565
 * @param items The array of strings
 
566
 * @param num_items The number of strings in the array
 
567
 * @return TRUE on success, FALSE on failure
 
568
 *
 
569
 */
 
570
dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
 
571
                                              const char *key,
 
572
                                              const char **items,
 
573
                                              const dbus_uint32_t num_items)
 
574
{
 
575
        DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
 
576
        dbus_uint32_t i;
 
577
 
 
578
        if (!key)
 
579
                return FALSE;
 
580
        if (!items && (num_items != 0))
 
581
                return FALSE;
 
582
 
 
583
        if (!wpa_dbus_dict_begin_string_array(iter_dict, key,
 
584
                                              &iter_dict_entry, &iter_dict_val,
 
585
                                              &iter_array))
 
586
                return FALSE;
 
587
 
 
588
        for (i = 0; i < num_items; i++) {
 
589
                if (!wpa_dbus_dict_string_array_add_element(&iter_array,
 
590
                                                            items[i]))
 
591
                        return FALSE;
 
592
        }
 
593
 
 
594
        if (!wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry,
 
595
                                            &iter_dict_val, &iter_array))
 
596
                return FALSE;
 
597
 
 
598
        return TRUE;
 
599
}
 
600
 
 
601
 
 
602
/*****************************************************/
 
603
/* Stuff for reading dicts                           */
 
604
/*****************************************************/
 
605
 
 
606
/**
 
607
 * Start reading from a dbus dict.
 
608
 *
 
609
 * @param iter A valid DBusMessageIter pointing to the start of the dict
 
610
 * @param iter_dict (out) A DBusMessageIter to be passed to
 
611
 *    {@link wpa_dbus_dict_read_next_entry}
 
612
 * @return TRUE on success, FALSE on failure
 
613
 *
 
614
 */
 
615
dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
 
616
                                    DBusMessageIter *iter_dict)
 
617
{
 
618
        if (!iter || !iter_dict)
 
619
                return FALSE;
 
620
 
 
621
        if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
 
622
            dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY)
 
623
                return FALSE;
 
624
 
 
625
        dbus_message_iter_recurse(iter, iter_dict);
 
626
        return TRUE;
 
627
}
 
628
 
 
629
 
 
630
#define BYTE_ARRAY_CHUNK_SIZE 34
 
631
#define BYTE_ARRAY_ITEM_SIZE (sizeof(char))
 
632
 
 
633
static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
 
634
        DBusMessageIter *iter, int array_type,
 
635
        struct wpa_dbus_dict_entry *entry)
 
636
{
 
637
        dbus_uint32_t count = 0;
 
638
        dbus_bool_t success = FALSE;
 
639
        char *buffer;
 
640
 
 
641
        entry->bytearray_value = NULL;
 
642
        entry->array_type = DBUS_TYPE_BYTE;
 
643
 
 
644
        buffer = os_zalloc(BYTE_ARRAY_ITEM_SIZE * BYTE_ARRAY_CHUNK_SIZE);
 
645
        if (!buffer) {
 
646
                perror("_wpa_dbus_dict_entry_get_byte_array[dbus]: out of "
 
647
                       "memory");
 
648
                goto done;
 
649
        }
 
650
 
 
651
        entry->bytearray_value = buffer;
 
652
        entry->array_len = 0;
 
653
        while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
 
654
                char byte;
 
655
 
 
656
                if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
 
657
                        buffer = realloc(buffer, BYTE_ARRAY_ITEM_SIZE *
 
658
                                         (count + BYTE_ARRAY_CHUNK_SIZE));
 
659
                        if (buffer == NULL) {
 
660
                                perror("_wpa_dbus_dict_entry_get_byte_array["
 
661
                                       "dbus] out of memory trying to "
 
662
                                       "retrieve the string array");
 
663
                                goto done;
 
664
                        }
 
665
                }
 
666
                entry->bytearray_value = buffer;
 
667
 
 
668
                dbus_message_iter_get_basic(iter, &byte);
 
669
                entry->bytearray_value[count] = byte;
 
670
                entry->array_len = ++count;
 
671
                dbus_message_iter_next(iter);
 
672
        }
 
673
 
 
674
        /* Zero-length arrays are valid. */
 
675
        if (entry->array_len == 0) {
 
676
                free(entry->bytearray_value);
 
677
                entry->strarray_value = NULL;
 
678
        }
 
679
 
 
680
        success = TRUE;
 
681
 
 
682
done:
 
683
        return success;
 
684
}
 
685
 
 
686
 
 
687
#define STR_ARRAY_CHUNK_SIZE 8
 
688
#define STR_ARRAY_ITEM_SIZE (sizeof(char *))
 
689
 
 
690
static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
 
691
        DBusMessageIter *iter, int array_type,
 
692
        struct wpa_dbus_dict_entry *entry)
 
693
{
 
694
        dbus_uint32_t count = 0;
 
695
        dbus_bool_t success = FALSE;
 
696
        char **buffer;
 
697
 
 
698
        entry->strarray_value = NULL;
 
699
        entry->array_type = DBUS_TYPE_STRING;
 
700
 
 
701
        buffer = os_zalloc(STR_ARRAY_ITEM_SIZE * STR_ARRAY_CHUNK_SIZE);
 
702
        if (buffer == NULL) {
 
703
                perror("_wpa_dbus_dict_entry_get_string_array[dbus] out of "
 
704
                       "memory trying to retrieve a string array");
 
705
                goto done;
 
706
        }
 
707
 
 
708
        entry->strarray_value = buffer;
 
709
        entry->array_len = 0;
 
710
        while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
 
711
                const char *value;
 
712
                char *str;
 
713
 
 
714
                if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
 
715
                        buffer = realloc(buffer, STR_ARRAY_ITEM_SIZE *
 
716
                                         (count + STR_ARRAY_CHUNK_SIZE));
 
717
                        if (buffer == NULL) {
 
718
                                perror("_wpa_dbus_dict_entry_get_string_array["
 
719
                                       "dbus] out of memory trying to "
 
720
                                       "retrieve the string array");
 
721
                                goto done;
 
722
                        }
 
723
                }
 
724
                entry->strarray_value = buffer;
 
725
 
 
726
                dbus_message_iter_get_basic(iter, &value);
 
727
                str = strdup(value);
 
728
                if (str == NULL) {
 
729
                        perror("_wpa_dbus_dict_entry_get_string_array[dbus] "
 
730
                               "out of memory trying to duplicate the string "
 
731
                               "array");
 
732
                        goto done;
 
733
                }
 
734
                entry->strarray_value[count] = str;
 
735
                entry->array_len = ++count;
 
736
                dbus_message_iter_next(iter);
 
737
        }
 
738
 
 
739
        /* Zero-length arrays are valid. */
 
740
        if (entry->array_len == 0) {
 
741
                free(entry->strarray_value);
 
742
                entry->strarray_value = NULL;
 
743
        }
 
744
 
 
745
        success = TRUE;
 
746
 
 
747
done:
 
748
        return success;
 
749
}
 
750
 
 
751
 
 
752
static dbus_bool_t _wpa_dbus_dict_entry_get_array(
 
753
        DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
 
754
{
 
755
        int array_type = dbus_message_iter_get_element_type(iter_dict_val);
 
756
        dbus_bool_t success = FALSE;
 
757
        DBusMessageIter iter_array;
 
758
 
 
759
        if (!entry)
 
760
                return FALSE;
 
761
 
 
762
        dbus_message_iter_recurse(iter_dict_val, &iter_array);
 
763
 
 
764
        switch (array_type) {
 
765
        case DBUS_TYPE_BYTE:
 
766
                success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
 
767
                                                              array_type,
 
768
                                                              entry);
 
769
                break;
 
770
        case DBUS_TYPE_STRING:
 
771
                success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
 
772
                                                                array_type,
 
773
                                                                entry);
 
774
                break;
 
775
        default:
 
776
                break;
 
777
        }
 
778
 
 
779
        return success;
 
780
}
 
781
 
 
782
 
 
783
static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant(
 
784
        struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter_dict_val)
 
785
{
 
786
        dbus_bool_t success = TRUE;
 
787
 
 
788
        switch (entry->type) {
 
789
        case DBUS_TYPE_STRING: {
 
790
                const char *v;
 
791
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
792
                entry->str_value = strdup(v);
 
793
                break;
 
794
        }
 
795
        case DBUS_TYPE_BOOLEAN: {
 
796
                dbus_bool_t v;
 
797
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
798
                entry->bool_value = v;
 
799
                break;
 
800
        }
 
801
        case DBUS_TYPE_BYTE: {
 
802
                char v;
 
803
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
804
                entry->byte_value = v;
 
805
                break;
 
806
        }
 
807
        case DBUS_TYPE_INT16: {
 
808
                dbus_int16_t v;
 
809
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
810
                entry->int16_value = v;
 
811
                break;
 
812
        }
 
813
        case DBUS_TYPE_UINT16: {
 
814
                dbus_uint16_t v;
 
815
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
816
                entry->uint16_value = v;
 
817
                break;
 
818
        }
 
819
        case DBUS_TYPE_INT32: {
 
820
                dbus_int32_t v;
 
821
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
822
                entry->int32_value = v;
 
823
                break;
 
824
        }
 
825
        case DBUS_TYPE_UINT32: {
 
826
                dbus_uint32_t v;
 
827
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
828
                entry->uint32_value = v;
 
829
                break;
 
830
        }
 
831
        case DBUS_TYPE_INT64: {
 
832
                dbus_int64_t v;
 
833
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
834
                entry->int64_value = v;
 
835
                break;
 
836
        }
 
837
        case DBUS_TYPE_UINT64: {
 
838
                dbus_uint64_t v;
 
839
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
840
                entry->uint64_value = v;
 
841
                break;
 
842
        }
 
843
        case DBUS_TYPE_DOUBLE: {
 
844
                double v;
 
845
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
846
                entry->double_value = v;
 
847
                break;
 
848
        }
 
849
        case DBUS_TYPE_OBJECT_PATH: {
 
850
                char *v;
 
851
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
852
                entry->str_value = strdup(v);
 
853
                break;
 
854
        }
 
855
        case DBUS_TYPE_ARRAY: {
 
856
                success = _wpa_dbus_dict_entry_get_array(iter_dict_val, entry);
 
857
                break;
 
858
        }
 
859
        default:
 
860
                success = FALSE;
 
861
                break;
 
862
        }
 
863
 
 
864
        return success;
 
865
}
 
866
 
 
867
 
 
868
/**
 
869
 * Read the current key/value entry from the dict.  Entries are dynamically
 
870
 * allocated when needed and must be freed after use with the
 
871
 * {@link wpa_dbus_dict_entry_clear} function.
 
872
 *
 
873
 * The returned entry object will be filled with the type and value of the next
 
874
 * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
 
875
 * occurred.
 
876
 *
 
877
 * @param iter_dict A valid DBusMessageIter returned from
 
878
 *    {@link wpa_dbus_dict_open_read}
 
879
 * @param entry A valid dict entry object into which the dict key and value
 
880
 *    will be placed
 
881
 * @return TRUE on success, FALSE on failure
 
882
 *
 
883
 */
 
884
dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
 
885
                                    struct wpa_dbus_dict_entry * entry)
 
886
{
 
887
        DBusMessageIter iter_dict_entry, iter_dict_val;
 
888
        int type;
 
889
        const char *key;
 
890
 
 
891
        if (!iter_dict || !entry)
 
892
                goto error;
 
893
 
 
894
        if (dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY)
 
895
                goto error;
 
896
 
 
897
        dbus_message_iter_recurse(iter_dict, &iter_dict_entry);
 
898
        dbus_message_iter_get_basic(&iter_dict_entry, &key);
 
899
        entry->key = key;
 
900
 
 
901
        if (!dbus_message_iter_next(&iter_dict_entry))
 
902
                goto error;
 
903
        type = dbus_message_iter_get_arg_type(&iter_dict_entry);
 
904
        if (type != DBUS_TYPE_VARIANT)
 
905
                goto error;
 
906
 
 
907
        dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val);
 
908
        entry->type = dbus_message_iter_get_arg_type(&iter_dict_val);
 
909
        if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val))
 
910
                goto error;
 
911
 
 
912
        dbus_message_iter_next(iter_dict);
 
913
        return TRUE;
 
914
 
 
915
error:
 
916
        if (entry) {
 
917
                wpa_dbus_dict_entry_clear(entry);
 
918
                entry->type = DBUS_TYPE_INVALID;
 
919
                entry->array_type = DBUS_TYPE_INVALID;
 
920
        }
 
921
 
 
922
        return FALSE;
 
923
}
 
924
 
 
925
 
 
926
/**
 
927
 * Return whether or not there are additional dictionary entries.
 
928
 *
 
929
 * @param iter_dict A valid DBusMessageIter returned from
 
930
 *    {@link wpa_dbus_dict_open_read}
 
931
 * @return TRUE if more dict entries exists, FALSE if no more dict entries
 
932
 * exist
 
933
 */
 
934
dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict)
 
935
{
 
936
        if (!iter_dict) {
 
937
                perror("wpa_dbus_dict_has_dict_entry[dbus]: out of memory");
 
938
                return FALSE;
 
939
        }
 
940
        return dbus_message_iter_get_arg_type(iter_dict) ==
 
941
                DBUS_TYPE_DICT_ENTRY;
 
942
}
 
943
 
 
944
 
 
945
/**
 
946
 * Free any memory used by the entry object.
 
947
 *
 
948
 * @param entry The entry object
 
949
 */
 
950
void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
 
951
{
 
952
        unsigned int i;
 
953
 
 
954
        if (!entry)
 
955
                return;
 
956
        switch (entry->type) {
 
957
        case DBUS_TYPE_OBJECT_PATH:
 
958
        case DBUS_TYPE_STRING:
 
959
                free(entry->str_value);
 
960
                break;
 
961
        case DBUS_TYPE_ARRAY:
 
962
                switch (entry->array_type) {
 
963
                case DBUS_TYPE_BYTE:
 
964
                        free(entry->bytearray_value);
 
965
                        break;
 
966
                case DBUS_TYPE_STRING:
 
967
                        for (i = 0; i < entry->array_len; i++)
 
968
                                free(entry->strarray_value[i]);
 
969
                        free(entry->strarray_value);
 
970
                        break;
 
971
                }
 
972
                break;
 
973
        }
 
974
 
 
975
        memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));
 
976
}