LCOV - code coverage report
Current view: top level - wpa_supplicant/dbus - dbus_dict_helpers.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1422976643 Lines: 338 383 88.3 %
Date: 2015-02-03 Functions: 31 35 88.6 %

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

Generated by: LCOV version 1.10