1214501Srpaulo/* 2214501Srpaulo * WPA Supplicant / dbus-based control interface 3214501Srpaulo * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. 4214501Srpaulo * 5252190Srpaulo * This software may be distributed under the terms of the BSD license. 6252190Srpaulo * See README for more details. 7214501Srpaulo */ 8214501Srpaulo 9214501Srpaulo#include "includes.h" 10214501Srpaulo#include <dbus/dbus.h> 11214501Srpaulo 12214501Srpaulo#include "common.h" 13252190Srpaulo#include "wpabuf.h" 14214501Srpaulo#include "dbus_dict_helpers.h" 15214501Srpaulo 16214501Srpaulo 17214501Srpaulo/** 18214501Srpaulo * Start a dict in a dbus message. Should be paired with a call to 19214501Srpaulo * wpa_dbus_dict_close_write(). 20214501Srpaulo * 21214501Srpaulo * @param iter A valid dbus message iterator 22214501Srpaulo * @param iter_dict (out) A dict iterator to pass to further dict functions 23214501Srpaulo * @return TRUE on success, FALSE on failure 24214501Srpaulo * 25214501Srpaulo */ 26214501Srpaulodbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter, 27214501Srpaulo DBusMessageIter *iter_dict) 28214501Srpaulo{ 29214501Srpaulo dbus_bool_t result; 30214501Srpaulo 31214501Srpaulo if (!iter || !iter_dict) 32214501Srpaulo return FALSE; 33214501Srpaulo 34214501Srpaulo result = dbus_message_iter_open_container( 35214501Srpaulo iter, 36214501Srpaulo DBUS_TYPE_ARRAY, 37214501Srpaulo DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 38214501Srpaulo DBUS_TYPE_STRING_AS_STRING 39214501Srpaulo DBUS_TYPE_VARIANT_AS_STRING 40214501Srpaulo DBUS_DICT_ENTRY_END_CHAR_AS_STRING, 41214501Srpaulo iter_dict); 42214501Srpaulo return result; 43214501Srpaulo} 44214501Srpaulo 45214501Srpaulo 46214501Srpaulo/** 47214501Srpaulo * End a dict element in a dbus message. Should be paired with 48214501Srpaulo * a call to wpa_dbus_dict_open_write(). 49214501Srpaulo * 50214501Srpaulo * @param iter valid dbus message iterator, same as passed to 51214501Srpaulo * wpa_dbus_dict_open_write() 52214501Srpaulo * @param iter_dict a dbus dict iterator returned from 53214501Srpaulo * wpa_dbus_dict_open_write() 54214501Srpaulo * @return TRUE on success, FALSE on failure 55214501Srpaulo * 56214501Srpaulo */ 57214501Srpaulodbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter, 58214501Srpaulo DBusMessageIter *iter_dict) 59214501Srpaulo{ 60214501Srpaulo if (!iter || !iter_dict) 61214501Srpaulo return FALSE; 62214501Srpaulo 63214501Srpaulo return dbus_message_iter_close_container(iter, iter_dict); 64214501Srpaulo} 65214501Srpaulo 66214501Srpaulo 67214501Srpauloconst char * wpa_dbus_type_as_string(const int type) 68214501Srpaulo{ 69281806Srpaulo switch (type) { 70214501Srpaulo case DBUS_TYPE_BYTE: 71214501Srpaulo return DBUS_TYPE_BYTE_AS_STRING; 72214501Srpaulo case DBUS_TYPE_BOOLEAN: 73214501Srpaulo return DBUS_TYPE_BOOLEAN_AS_STRING; 74214501Srpaulo case DBUS_TYPE_INT16: 75214501Srpaulo return DBUS_TYPE_INT16_AS_STRING; 76214501Srpaulo case DBUS_TYPE_UINT16: 77214501Srpaulo return DBUS_TYPE_UINT16_AS_STRING; 78214501Srpaulo case DBUS_TYPE_INT32: 79214501Srpaulo return DBUS_TYPE_INT32_AS_STRING; 80214501Srpaulo case DBUS_TYPE_UINT32: 81214501Srpaulo return DBUS_TYPE_UINT32_AS_STRING; 82214501Srpaulo case DBUS_TYPE_INT64: 83214501Srpaulo return DBUS_TYPE_INT64_AS_STRING; 84214501Srpaulo case DBUS_TYPE_UINT64: 85214501Srpaulo return DBUS_TYPE_UINT64_AS_STRING; 86214501Srpaulo case DBUS_TYPE_DOUBLE: 87214501Srpaulo return DBUS_TYPE_DOUBLE_AS_STRING; 88214501Srpaulo case DBUS_TYPE_STRING: 89214501Srpaulo return DBUS_TYPE_STRING_AS_STRING; 90214501Srpaulo case DBUS_TYPE_OBJECT_PATH: 91214501Srpaulo return DBUS_TYPE_OBJECT_PATH_AS_STRING; 92214501Srpaulo case DBUS_TYPE_ARRAY: 93214501Srpaulo return DBUS_TYPE_ARRAY_AS_STRING; 94214501Srpaulo default: 95214501Srpaulo return NULL; 96214501Srpaulo } 97214501Srpaulo} 98214501Srpaulo 99214501Srpaulo 100214501Srpaulostatic dbus_bool_t _wpa_dbus_add_dict_entry_start( 101214501Srpaulo DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry, 102214501Srpaulo const char *key, const int value_type) 103214501Srpaulo{ 104214501Srpaulo if (!dbus_message_iter_open_container(iter_dict, 105214501Srpaulo DBUS_TYPE_DICT_ENTRY, NULL, 106214501Srpaulo iter_dict_entry)) 107214501Srpaulo return FALSE; 108214501Srpaulo 109281806Srpaulo return dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING, 110281806Srpaulo &key); 111214501Srpaulo} 112214501Srpaulo 113214501Srpaulo 114214501Srpaulostatic dbus_bool_t _wpa_dbus_add_dict_entry_end( 115214501Srpaulo DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry, 116214501Srpaulo DBusMessageIter *iter_dict_val) 117214501Srpaulo{ 118214501Srpaulo if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val)) 119214501Srpaulo return FALSE; 120214501Srpaulo 121281806Srpaulo return dbus_message_iter_close_container(iter_dict, iter_dict_entry); 122214501Srpaulo} 123214501Srpaulo 124214501Srpaulo 125214501Srpaulostatic dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict, 126214501Srpaulo const char *key, 127214501Srpaulo const int value_type, 128214501Srpaulo const void *value) 129214501Srpaulo{ 130214501Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val; 131214501Srpaulo const char *type_as_string = NULL; 132214501Srpaulo 133214501Srpaulo if (key == NULL) 134214501Srpaulo return FALSE; 135214501Srpaulo 136214501Srpaulo type_as_string = wpa_dbus_type_as_string(value_type); 137214501Srpaulo if (!type_as_string) 138214501Srpaulo return FALSE; 139214501Srpaulo 140214501Srpaulo if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry, 141281806Srpaulo key, value_type) || 142281806Srpaulo !dbus_message_iter_open_container(&iter_dict_entry, 143214501Srpaulo DBUS_TYPE_VARIANT, 144281806Srpaulo type_as_string, &iter_dict_val) || 145281806Srpaulo !dbus_message_iter_append_basic(&iter_dict_val, value_type, value)) 146214501Srpaulo return FALSE; 147214501Srpaulo 148281806Srpaulo return _wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry, 149281806Srpaulo &iter_dict_val); 150214501Srpaulo} 151214501Srpaulo 152214501Srpaulo 153214501Srpaulostatic dbus_bool_t _wpa_dbus_add_dict_entry_byte_array( 154214501Srpaulo DBusMessageIter *iter_dict, const char *key, 155214501Srpaulo const char *value, const dbus_uint32_t value_len) 156214501Srpaulo{ 157214501Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; 158214501Srpaulo dbus_uint32_t i; 159214501Srpaulo 160214501Srpaulo if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry, 161281806Srpaulo key, DBUS_TYPE_ARRAY) || 162281806Srpaulo !dbus_message_iter_open_container(&iter_dict_entry, 163214501Srpaulo DBUS_TYPE_VARIANT, 164214501Srpaulo DBUS_TYPE_ARRAY_AS_STRING 165214501Srpaulo DBUS_TYPE_BYTE_AS_STRING, 166281806Srpaulo &iter_dict_val) || 167281806Srpaulo !dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY, 168214501Srpaulo DBUS_TYPE_BYTE_AS_STRING, 169214501Srpaulo &iter_array)) 170214501Srpaulo return FALSE; 171214501Srpaulo 172214501Srpaulo for (i = 0; i < value_len; i++) { 173214501Srpaulo if (!dbus_message_iter_append_basic(&iter_array, 174214501Srpaulo DBUS_TYPE_BYTE, 175214501Srpaulo &(value[i]))) 176214501Srpaulo return FALSE; 177214501Srpaulo } 178214501Srpaulo 179214501Srpaulo if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array)) 180214501Srpaulo return FALSE; 181214501Srpaulo 182281806Srpaulo return _wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry, 183281806Srpaulo &iter_dict_val); 184214501Srpaulo} 185214501Srpaulo 186214501Srpaulo 187214501Srpaulo/** 188214501Srpaulo * Add a string entry to the dict. 189214501Srpaulo * 190214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 191214501Srpaulo * wpa_dbus_dict_open_write() 192214501Srpaulo * @param key The key of the dict item 193214501Srpaulo * @param value The string value 194214501Srpaulo * @return TRUE on success, FALSE on failure 195214501Srpaulo * 196214501Srpaulo */ 197214501Srpaulodbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict, 198214501Srpaulo const char *key, const char *value) 199214501Srpaulo{ 200214501Srpaulo if (!value) 201214501Srpaulo return FALSE; 202214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING, 203214501Srpaulo &value); 204214501Srpaulo} 205214501Srpaulo 206214501Srpaulo 207214501Srpaulo/** 208214501Srpaulo * Add a byte entry to the dict. 209214501Srpaulo * 210214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 211214501Srpaulo * wpa_dbus_dict_open_write() 212214501Srpaulo * @param key The key of the dict item 213214501Srpaulo * @param value The byte value 214214501Srpaulo * @return TRUE on success, FALSE on failure 215214501Srpaulo * 216214501Srpaulo */ 217214501Srpaulodbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict, 218214501Srpaulo const char *key, const char value) 219214501Srpaulo{ 220214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BYTE, 221214501Srpaulo &value); 222214501Srpaulo} 223214501Srpaulo 224214501Srpaulo 225214501Srpaulo/** 226214501Srpaulo * Add a boolean entry to the dict. 227214501Srpaulo * 228214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 229214501Srpaulo * wpa_dbus_dict_open_write() 230214501Srpaulo * @param key The key of the dict item 231214501Srpaulo * @param value The boolean value 232214501Srpaulo * @return TRUE on success, FALSE on failure 233214501Srpaulo * 234214501Srpaulo */ 235214501Srpaulodbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict, 236214501Srpaulo const char *key, const dbus_bool_t value) 237214501Srpaulo{ 238214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, 239214501Srpaulo DBUS_TYPE_BOOLEAN, &value); 240214501Srpaulo} 241214501Srpaulo 242214501Srpaulo 243214501Srpaulo/** 244214501Srpaulo * Add a 16-bit signed integer entry to the dict. 245214501Srpaulo * 246214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 247214501Srpaulo * wpa_dbus_dict_open_write() 248214501Srpaulo * @param key The key of the dict item 249214501Srpaulo * @param value The 16-bit signed integer value 250214501Srpaulo * @return TRUE on success, FALSE on failure 251214501Srpaulo * 252214501Srpaulo */ 253214501Srpaulodbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict, 254214501Srpaulo const char *key, 255214501Srpaulo const dbus_int16_t value) 256214501Srpaulo{ 257214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16, 258214501Srpaulo &value); 259214501Srpaulo} 260214501Srpaulo 261214501Srpaulo 262214501Srpaulo/** 263214501Srpaulo * Add a 16-bit unsigned integer entry to the dict. 264214501Srpaulo * 265214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 266214501Srpaulo * wpa_dbus_dict_open_write() 267214501Srpaulo * @param key The key of the dict item 268214501Srpaulo * @param value The 16-bit unsigned integer value 269214501Srpaulo * @return TRUE on success, FALSE on failure 270214501Srpaulo * 271214501Srpaulo */ 272214501Srpaulodbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict, 273214501Srpaulo const char *key, 274214501Srpaulo const dbus_uint16_t value) 275214501Srpaulo{ 276214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16, 277214501Srpaulo &value); 278214501Srpaulo} 279214501Srpaulo 280214501Srpaulo 281214501Srpaulo/** 282214501Srpaulo * Add a 32-bit signed integer to the dict. 283214501Srpaulo * 284214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 285214501Srpaulo * wpa_dbus_dict_open_write() 286214501Srpaulo * @param key The key of the dict item 287214501Srpaulo * @param value The 32-bit signed integer value 288214501Srpaulo * @return TRUE on success, FALSE on failure 289214501Srpaulo * 290214501Srpaulo */ 291214501Srpaulodbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict, 292214501Srpaulo const char *key, 293214501Srpaulo const dbus_int32_t value) 294214501Srpaulo{ 295214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32, 296214501Srpaulo &value); 297214501Srpaulo} 298214501Srpaulo 299214501Srpaulo 300214501Srpaulo/** 301214501Srpaulo * Add a 32-bit unsigned integer entry to the dict. 302214501Srpaulo * 303214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 304214501Srpaulo * wpa_dbus_dict_open_write() 305214501Srpaulo * @param key The key of the dict item 306214501Srpaulo * @param value The 32-bit unsigned integer value 307214501Srpaulo * @return TRUE on success, FALSE on failure 308214501Srpaulo * 309214501Srpaulo */ 310214501Srpaulodbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict, 311214501Srpaulo const char *key, 312214501Srpaulo const dbus_uint32_t value) 313214501Srpaulo{ 314214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32, 315214501Srpaulo &value); 316214501Srpaulo} 317214501Srpaulo 318214501Srpaulo 319214501Srpaulo/** 320214501Srpaulo * Add a 64-bit integer entry to the dict. 321214501Srpaulo * 322214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 323214501Srpaulo * wpa_dbus_dict_open_write() 324214501Srpaulo * @param key The key of the dict item 325214501Srpaulo * @param value The 64-bit integer value 326214501Srpaulo * @return TRUE on success, FALSE on failure 327214501Srpaulo * 328214501Srpaulo */ 329214501Srpaulodbus_bool_t wpa_dbus_dict_append_int64(DBusMessageIter *iter_dict, 330214501Srpaulo const char *key, 331214501Srpaulo const dbus_int64_t value) 332214501Srpaulo{ 333214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT64, 334214501Srpaulo &value); 335214501Srpaulo} 336214501Srpaulo 337214501Srpaulo 338214501Srpaulo/** 339214501Srpaulo * Add a 64-bit unsigned integer entry to the dict. 340214501Srpaulo * 341214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 342214501Srpaulo * wpa_dbus_dict_open_write() 343214501Srpaulo * @param key The key of the dict item 344214501Srpaulo * @param value The 64-bit unsigned integer value 345214501Srpaulo * @return TRUE on success, FALSE on failure 346214501Srpaulo * 347214501Srpaulo */ 348214501Srpaulodbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict, 349214501Srpaulo const char *key, 350214501Srpaulo const dbus_uint64_t value) 351214501Srpaulo{ 352214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT64, 353214501Srpaulo &value); 354214501Srpaulo} 355214501Srpaulo 356214501Srpaulo 357214501Srpaulo/** 358214501Srpaulo * Add a double-precision floating point entry to the dict. 359214501Srpaulo * 360214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 361214501Srpaulo * wpa_dbus_dict_open_write() 362214501Srpaulo * @param key The key of the dict item 363214501Srpaulo * @param value The double-precision floating point value 364214501Srpaulo * @return TRUE on success, FALSE on failure 365214501Srpaulo * 366214501Srpaulo */ 367214501Srpaulodbus_bool_t wpa_dbus_dict_append_double(DBusMessageIter *iter_dict, 368214501Srpaulo const char *key, const double value) 369214501Srpaulo{ 370214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_DOUBLE, 371214501Srpaulo &value); 372214501Srpaulo} 373214501Srpaulo 374214501Srpaulo 375214501Srpaulo/** 376214501Srpaulo * Add a DBus object path entry to the dict. 377214501Srpaulo * 378214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 379214501Srpaulo * wpa_dbus_dict_open_write() 380214501Srpaulo * @param key The key of the dict item 381214501Srpaulo * @param value The DBus object path value 382214501Srpaulo * @return TRUE on success, FALSE on failure 383214501Srpaulo * 384214501Srpaulo */ 385214501Srpaulodbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict, 386214501Srpaulo const char *key, 387214501Srpaulo const char *value) 388214501Srpaulo{ 389214501Srpaulo if (!value) 390214501Srpaulo return FALSE; 391214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, 392214501Srpaulo DBUS_TYPE_OBJECT_PATH, &value); 393214501Srpaulo} 394214501Srpaulo 395214501Srpaulo 396214501Srpaulo/** 397214501Srpaulo * Add a byte array entry to the dict. 398214501Srpaulo * 399214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 400214501Srpaulo * wpa_dbus_dict_open_write() 401214501Srpaulo * @param key The key of the dict item 402214501Srpaulo * @param value The byte array 403214501Srpaulo * @param value_len The length of the byte array, in bytes 404214501Srpaulo * @return TRUE on success, FALSE on failure 405214501Srpaulo * 406214501Srpaulo */ 407214501Srpaulodbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict, 408214501Srpaulo const char *key, 409214501Srpaulo const char *value, 410214501Srpaulo const dbus_uint32_t value_len) 411214501Srpaulo{ 412281806Srpaulo if (!key || (!value && value_len != 0)) 413214501Srpaulo return FALSE; 414214501Srpaulo return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value, 415214501Srpaulo value_len); 416214501Srpaulo} 417214501Srpaulo 418214501Srpaulo 419214501Srpaulo/** 420252190Srpaulo * Begin an array entry in the dict 421214501Srpaulo * 422214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 423214501Srpaulo * wpa_dbus_dict_open_write() 424214501Srpaulo * @param key The key of the dict item 425252190Srpaulo * @param type The type of the contained data 426214501Srpaulo * @param iter_dict_entry A private DBusMessageIter provided by the caller to 427214501Srpaulo * be passed to wpa_dbus_dict_end_string_array() 428214501Srpaulo * @param iter_dict_val A private DBusMessageIter provided by the caller to 429214501Srpaulo * be passed to wpa_dbus_dict_end_string_array() 430214501Srpaulo * @param iter_array On return, the DBusMessageIter to be passed to 431214501Srpaulo * wpa_dbus_dict_string_array_add_element() 432214501Srpaulo * @return TRUE on success, FALSE on failure 433214501Srpaulo * 434214501Srpaulo */ 435252190Srpaulodbus_bool_t wpa_dbus_dict_begin_array(DBusMessageIter *iter_dict, 436252190Srpaulo const char *key, const char *type, 437252190Srpaulo DBusMessageIter *iter_dict_entry, 438252190Srpaulo DBusMessageIter *iter_dict_val, 439252190Srpaulo DBusMessageIter *iter_array) 440214501Srpaulo{ 441252190Srpaulo char array_type[10]; 442252190Srpaulo int err; 443252190Srpaulo 444252190Srpaulo err = os_snprintf(array_type, sizeof(array_type), 445252190Srpaulo DBUS_TYPE_ARRAY_AS_STRING "%s", 446252190Srpaulo type); 447281806Srpaulo if (os_snprintf_error(sizeof(array_type), err)) 448252190Srpaulo return FALSE; 449252190Srpaulo 450281806Srpaulo if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array || 451281806Srpaulo !_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry, 452281806Srpaulo key, DBUS_TYPE_ARRAY) || 453281806Srpaulo !dbus_message_iter_open_container(iter_dict_entry, 454214501Srpaulo DBUS_TYPE_VARIANT, 455252190Srpaulo array_type, 456214501Srpaulo iter_dict_val)) 457214501Srpaulo return FALSE; 458214501Srpaulo 459281806Srpaulo return dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY, 460281806Srpaulo type, iter_array); 461214501Srpaulo} 462214501Srpaulo 463214501Srpaulo 464252190Srpaulodbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict, 465252190Srpaulo const char *key, 466252190Srpaulo DBusMessageIter *iter_dict_entry, 467252190Srpaulo DBusMessageIter *iter_dict_val, 468252190Srpaulo DBusMessageIter *iter_array) 469252190Srpaulo{ 470252190Srpaulo return wpa_dbus_dict_begin_array( 471252190Srpaulo iter_dict, key, 472252190Srpaulo DBUS_TYPE_STRING_AS_STRING, 473252190Srpaulo iter_dict_entry, iter_dict_val, iter_array); 474252190Srpaulo} 475252190Srpaulo 476252190Srpaulo 477214501Srpaulo/** 478214501Srpaulo * Add a single string element to a string array dict entry 479214501Srpaulo * 480214501Srpaulo * @param iter_array A valid DBusMessageIter returned from 481214501Srpaulo * wpa_dbus_dict_begin_string_array()'s 482214501Srpaulo * iter_array parameter 483214501Srpaulo * @param elem The string element to be added to the dict entry's string array 484214501Srpaulo * @return TRUE on success, FALSE on failure 485214501Srpaulo * 486214501Srpaulo */ 487214501Srpaulodbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array, 488214501Srpaulo const char *elem) 489214501Srpaulo{ 490214501Srpaulo if (!iter_array || !elem) 491214501Srpaulo return FALSE; 492214501Srpaulo 493214501Srpaulo return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING, 494214501Srpaulo &elem); 495214501Srpaulo} 496214501Srpaulo 497214501Srpaulo 498214501Srpaulo/** 499252190Srpaulo * Add a single byte array element to a string array dict entry 500214501Srpaulo * 501252190Srpaulo * @param iter_array A valid DBusMessageIter returned from 502252190Srpaulo * wpa_dbus_dict_begin_array()'s iter_array 503252190Srpaulo * parameter -- note that wpa_dbus_dict_begin_array() 504252190Srpaulo * must have been called with "ay" as the type 505252190Srpaulo * @param value The data to be added to the dict entry's array 506252190Srpaulo * @param value_len The length of the data 507252190Srpaulo * @return TRUE on success, FALSE on failure 508252190Srpaulo * 509252190Srpaulo */ 510252190Srpaulodbus_bool_t wpa_dbus_dict_bin_array_add_element(DBusMessageIter *iter_array, 511252190Srpaulo const u8 *value, 512252190Srpaulo size_t value_len) 513252190Srpaulo{ 514252190Srpaulo DBusMessageIter iter_bytes; 515252190Srpaulo size_t i; 516252190Srpaulo 517281806Srpaulo if (!iter_array || !value || 518281806Srpaulo !dbus_message_iter_open_container(iter_array, DBUS_TYPE_ARRAY, 519252190Srpaulo DBUS_TYPE_BYTE_AS_STRING, 520252190Srpaulo &iter_bytes)) 521252190Srpaulo return FALSE; 522252190Srpaulo 523252190Srpaulo for (i = 0; i < value_len; i++) { 524252190Srpaulo if (!dbus_message_iter_append_basic(&iter_bytes, 525252190Srpaulo DBUS_TYPE_BYTE, 526252190Srpaulo &(value[i]))) 527252190Srpaulo return FALSE; 528252190Srpaulo } 529252190Srpaulo 530281806Srpaulo return dbus_message_iter_close_container(iter_array, &iter_bytes); 531252190Srpaulo} 532252190Srpaulo 533252190Srpaulo 534252190Srpaulo/** 535252190Srpaulo * End an array dict entry 536252190Srpaulo * 537214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 538214501Srpaulo * wpa_dbus_dict_open_write() 539214501Srpaulo * @param iter_dict_entry A private DBusMessageIter returned from 540252190Srpaulo * wpa_dbus_dict_begin_string_array() or 541252190Srpaulo * wpa_dbus_dict_begin_array() 542214501Srpaulo * @param iter_dict_val A private DBusMessageIter returned from 543252190Srpaulo * wpa_dbus_dict_begin_string_array() or 544252190Srpaulo * wpa_dbus_dict_begin_array() 545214501Srpaulo * @param iter_array A DBusMessageIter returned from 546252190Srpaulo * wpa_dbus_dict_begin_string_array() or 547252190Srpaulo * wpa_dbus_dict_begin_array() 548214501Srpaulo * @return TRUE on success, FALSE on failure 549214501Srpaulo * 550214501Srpaulo */ 551252190Srpaulodbus_bool_t wpa_dbus_dict_end_array(DBusMessageIter *iter_dict, 552252190Srpaulo DBusMessageIter *iter_dict_entry, 553252190Srpaulo DBusMessageIter *iter_dict_val, 554252190Srpaulo DBusMessageIter *iter_array) 555214501Srpaulo{ 556281806Srpaulo if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array || 557281806Srpaulo !dbus_message_iter_close_container(iter_dict_val, iter_array)) 558214501Srpaulo return FALSE; 559214501Srpaulo 560281806Srpaulo return _wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry, 561281806Srpaulo iter_dict_val); 562214501Srpaulo} 563214501Srpaulo 564214501Srpaulo 565214501Srpaulo/** 566214501Srpaulo * Convenience function to add an entire string array to the dict. 567214501Srpaulo * 568214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 569214501Srpaulo * wpa_dbus_dict_open_write() 570214501Srpaulo * @param key The key of the dict item 571214501Srpaulo * @param items The array of strings 572214501Srpaulo * @param num_items The number of strings in the array 573214501Srpaulo * @return TRUE on success, FALSE on failure 574214501Srpaulo * 575214501Srpaulo */ 576214501Srpaulodbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict, 577214501Srpaulo const char *key, 578214501Srpaulo const char **items, 579214501Srpaulo const dbus_uint32_t num_items) 580214501Srpaulo{ 581214501Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; 582214501Srpaulo dbus_uint32_t i; 583214501Srpaulo 584281806Srpaulo if (!key || (!items && num_items != 0) || 585281806Srpaulo !wpa_dbus_dict_begin_string_array(iter_dict, key, 586214501Srpaulo &iter_dict_entry, &iter_dict_val, 587214501Srpaulo &iter_array)) 588214501Srpaulo return FALSE; 589214501Srpaulo 590214501Srpaulo for (i = 0; i < num_items; i++) { 591214501Srpaulo if (!wpa_dbus_dict_string_array_add_element(&iter_array, 592214501Srpaulo items[i])) 593214501Srpaulo return FALSE; 594214501Srpaulo } 595214501Srpaulo 596281806Srpaulo return wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry, 597281806Srpaulo &iter_dict_val, &iter_array); 598214501Srpaulo} 599214501Srpaulo 600214501Srpaulo 601252190Srpaulo/** 602252190Srpaulo * Convenience function to add an wpabuf binary array to the dict. 603252190Srpaulo * 604252190Srpaulo * @param iter_dict A valid DBusMessageIter returned from 605252190Srpaulo * wpa_dbus_dict_open_write() 606252190Srpaulo * @param key The key of the dict item 607252190Srpaulo * @param items The array of wpabuf structures 608252190Srpaulo * @param num_items The number of strings in the array 609252190Srpaulo * @return TRUE on success, FALSE on failure 610252190Srpaulo * 611252190Srpaulo */ 612252190Srpaulodbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict, 613252190Srpaulo const char *key, 614252190Srpaulo const struct wpabuf **items, 615252190Srpaulo const dbus_uint32_t num_items) 616252190Srpaulo{ 617252190Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; 618252190Srpaulo dbus_uint32_t i; 619252190Srpaulo 620281806Srpaulo if (!key || 621281806Srpaulo (!items && num_items != 0) || 622281806Srpaulo !wpa_dbus_dict_begin_array(iter_dict, key, 623252190Srpaulo DBUS_TYPE_ARRAY_AS_STRING 624252190Srpaulo DBUS_TYPE_BYTE_AS_STRING, 625252190Srpaulo &iter_dict_entry, &iter_dict_val, 626252190Srpaulo &iter_array)) 627252190Srpaulo return FALSE; 628252190Srpaulo 629252190Srpaulo for (i = 0; i < num_items; i++) { 630252190Srpaulo if (!wpa_dbus_dict_bin_array_add_element(&iter_array, 631252190Srpaulo wpabuf_head(items[i]), 632252190Srpaulo wpabuf_len(items[i]))) 633252190Srpaulo return FALSE; 634252190Srpaulo } 635252190Srpaulo 636281806Srpaulo return wpa_dbus_dict_end_array(iter_dict, &iter_dict_entry, 637281806Srpaulo &iter_dict_val, &iter_array); 638252190Srpaulo} 639252190Srpaulo 640252190Srpaulo 641214501Srpaulo/*****************************************************/ 642214501Srpaulo/* Stuff for reading dicts */ 643214501Srpaulo/*****************************************************/ 644214501Srpaulo 645214501Srpaulo/** 646214501Srpaulo * Start reading from a dbus dict. 647214501Srpaulo * 648214501Srpaulo * @param iter A valid DBusMessageIter pointing to the start of the dict 649214501Srpaulo * @param iter_dict (out) A DBusMessageIter to be passed to 650214501Srpaulo * wpa_dbus_dict_read_next_entry() 651252190Srpaulo * @error on failure a descriptive error 652214501Srpaulo * @return TRUE on success, FALSE on failure 653214501Srpaulo * 654214501Srpaulo */ 655214501Srpaulodbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter, 656252190Srpaulo DBusMessageIter *iter_dict, 657252190Srpaulo DBusError *error) 658214501Srpaulo{ 659281806Srpaulo int type; 660281806Srpaulo 661281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: start reading a dict entry", __func__); 662252190Srpaulo if (!iter || !iter_dict) { 663252190Srpaulo dbus_set_error_const(error, DBUS_ERROR_FAILED, 664281806Srpaulo "[internal] missing message iterators"); 665214501Srpaulo return FALSE; 666252190Srpaulo } 667214501Srpaulo 668281806Srpaulo type = dbus_message_iter_get_arg_type(iter); 669281806Srpaulo if (type != DBUS_TYPE_ARRAY || 670252190Srpaulo dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) { 671281806Srpaulo wpa_printf(MSG_DEBUG, 672281806Srpaulo "%s: unexpected message argument types (arg=%c element=%c)", 673281806Srpaulo __func__, type, 674281806Srpaulo type != DBUS_TYPE_ARRAY ? '?' : 675281806Srpaulo dbus_message_iter_get_element_type(iter)); 676252190Srpaulo dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, 677281806Srpaulo "unexpected message argument types"); 678214501Srpaulo return FALSE; 679252190Srpaulo } 680214501Srpaulo 681214501Srpaulo dbus_message_iter_recurse(iter, iter_dict); 682214501Srpaulo return TRUE; 683214501Srpaulo} 684214501Srpaulo 685214501Srpaulo 686214501Srpaulo#define BYTE_ARRAY_CHUNK_SIZE 34 687214501Srpaulo#define BYTE_ARRAY_ITEM_SIZE (sizeof(char)) 688214501Srpaulo 689214501Srpaulostatic dbus_bool_t _wpa_dbus_dict_entry_get_byte_array( 690252190Srpaulo DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry) 691214501Srpaulo{ 692214501Srpaulo dbus_uint32_t count = 0; 693214501Srpaulo dbus_bool_t success = FALSE; 694252190Srpaulo char *buffer, *nbuffer; 695214501Srpaulo 696214501Srpaulo entry->bytearray_value = NULL; 697214501Srpaulo entry->array_type = DBUS_TYPE_BYTE; 698214501Srpaulo 699252190Srpaulo buffer = os_calloc(BYTE_ARRAY_CHUNK_SIZE, BYTE_ARRAY_ITEM_SIZE); 700214501Srpaulo if (!buffer) 701214501Srpaulo return FALSE; 702214501Srpaulo 703214501Srpaulo entry->array_len = 0; 704214501Srpaulo while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) { 705214501Srpaulo char byte; 706214501Srpaulo 707214501Srpaulo if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) { 708252190Srpaulo nbuffer = os_realloc_array( 709252190Srpaulo buffer, count + BYTE_ARRAY_CHUNK_SIZE, 710252190Srpaulo BYTE_ARRAY_ITEM_SIZE); 711214501Srpaulo if (nbuffer == NULL) { 712214501Srpaulo os_free(buffer); 713281806Srpaulo wpa_printf(MSG_ERROR, 714281806Srpaulo "dbus: %s out of memory trying to retrieve the string array", 715281806Srpaulo __func__); 716214501Srpaulo goto done; 717214501Srpaulo } 718214501Srpaulo buffer = nbuffer; 719214501Srpaulo } 720214501Srpaulo 721214501Srpaulo dbus_message_iter_get_basic(iter, &byte); 722281806Srpaulo buffer[count] = byte; 723214501Srpaulo entry->array_len = ++count; 724214501Srpaulo dbus_message_iter_next(iter); 725214501Srpaulo } 726281806Srpaulo entry->bytearray_value = buffer; 727281806Srpaulo wpa_hexdump_key(MSG_MSGDUMP, "dbus: byte array contents", 728281806Srpaulo entry->bytearray_value, entry->array_len); 729214501Srpaulo 730214501Srpaulo /* Zero-length arrays are valid. */ 731214501Srpaulo if (entry->array_len == 0) { 732214501Srpaulo os_free(entry->bytearray_value); 733214501Srpaulo entry->bytearray_value = NULL; 734214501Srpaulo } 735214501Srpaulo 736214501Srpaulo success = TRUE; 737214501Srpaulo 738214501Srpaulodone: 739214501Srpaulo return success; 740214501Srpaulo} 741214501Srpaulo 742214501Srpaulo 743214501Srpaulo#define STR_ARRAY_CHUNK_SIZE 8 744214501Srpaulo#define STR_ARRAY_ITEM_SIZE (sizeof(char *)) 745214501Srpaulo 746214501Srpaulostatic dbus_bool_t _wpa_dbus_dict_entry_get_string_array( 747214501Srpaulo DBusMessageIter *iter, int array_type, 748214501Srpaulo struct wpa_dbus_dict_entry *entry) 749214501Srpaulo{ 750214501Srpaulo dbus_uint32_t count = 0; 751214501Srpaulo char **buffer, **nbuffer; 752214501Srpaulo 753214501Srpaulo entry->strarray_value = NULL; 754281806Srpaulo entry->array_len = 0; 755214501Srpaulo entry->array_type = DBUS_TYPE_STRING; 756214501Srpaulo 757252190Srpaulo buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE); 758214501Srpaulo if (buffer == NULL) 759214501Srpaulo return FALSE; 760214501Srpaulo 761214501Srpaulo while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) { 762214501Srpaulo const char *value; 763214501Srpaulo char *str; 764214501Srpaulo 765214501Srpaulo if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) { 766252190Srpaulo nbuffer = os_realloc_array( 767252190Srpaulo buffer, count + STR_ARRAY_CHUNK_SIZE, 768252190Srpaulo STR_ARRAY_ITEM_SIZE); 769214501Srpaulo if (nbuffer == NULL) { 770281806Srpaulo wpa_printf(MSG_ERROR, 771281806Srpaulo "dbus: %s out of memory trying to retrieve the string array", 772281806Srpaulo __func__); 773281806Srpaulo goto fail; 774214501Srpaulo } 775214501Srpaulo buffer = nbuffer; 776214501Srpaulo } 777214501Srpaulo 778214501Srpaulo dbus_message_iter_get_basic(iter, &value); 779281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: string_array value: %s", 780281806Srpaulo __func__, wpa_debug_show_keys ? value : "[omitted]"); 781214501Srpaulo str = os_strdup(value); 782214501Srpaulo if (str == NULL) { 783281806Srpaulo wpa_printf(MSG_ERROR, 784281806Srpaulo "dbus: %s out of memory trying to duplicate the string array", 785281806Srpaulo __func__); 786281806Srpaulo goto fail; 787214501Srpaulo } 788281806Srpaulo buffer[count++] = str; 789214501Srpaulo dbus_message_iter_next(iter); 790214501Srpaulo } 791281806Srpaulo entry->strarray_value = buffer; 792281806Srpaulo entry->array_len = count; 793281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: string_array length %u", 794281806Srpaulo __func__, entry->array_len); 795214501Srpaulo 796214501Srpaulo /* Zero-length arrays are valid. */ 797214501Srpaulo if (entry->array_len == 0) { 798214501Srpaulo os_free(entry->strarray_value); 799214501Srpaulo entry->strarray_value = NULL; 800214501Srpaulo } 801214501Srpaulo 802281806Srpaulo return TRUE; 803214501Srpaulo 804281806Srpaulofail: 805281806Srpaulo while (count > 0) { 806281806Srpaulo count--; 807281806Srpaulo os_free(buffer[count]); 808281806Srpaulo } 809281806Srpaulo os_free(buffer); 810281806Srpaulo return FALSE; 811214501Srpaulo} 812214501Srpaulo 813214501Srpaulo 814252190Srpaulo#define BIN_ARRAY_CHUNK_SIZE 10 815252190Srpaulo#define BIN_ARRAY_ITEM_SIZE (sizeof(struct wpabuf *)) 816252190Srpaulo 817252190Srpaulostatic dbus_bool_t _wpa_dbus_dict_entry_get_binarray( 818252190Srpaulo DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry) 819252190Srpaulo{ 820252190Srpaulo struct wpa_dbus_dict_entry tmpentry; 821252190Srpaulo size_t buflen = 0; 822281806Srpaulo int i, type; 823252190Srpaulo 824252190Srpaulo entry->array_type = WPAS_DBUS_TYPE_BINARRAY; 825252190Srpaulo entry->array_len = 0; 826252190Srpaulo entry->binarray_value = NULL; 827252190Srpaulo 828281806Srpaulo type = dbus_message_iter_get_arg_type(iter); 829281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: parsing binarray type %c", __func__, type); 830281806Srpaulo if (type == DBUS_TYPE_INVALID) { 831281806Srpaulo /* Likely an empty array of arrays */ 832281806Srpaulo return TRUE; 833281806Srpaulo } 834281806Srpaulo if (type != DBUS_TYPE_ARRAY) { 835281806Srpaulo wpa_printf(MSG_DEBUG, "%s: not an array type: %c", 836281806Srpaulo __func__, type); 837281806Srpaulo return FALSE; 838281806Srpaulo } 839281806Srpaulo 840281806Srpaulo type = dbus_message_iter_get_element_type(iter); 841281806Srpaulo if (type != DBUS_TYPE_BYTE) { 842281806Srpaulo wpa_printf(MSG_DEBUG, "%s: unexpected element type %c", 843281806Srpaulo __func__, type); 844281806Srpaulo return FALSE; 845281806Srpaulo } 846281806Srpaulo 847252190Srpaulo while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) { 848252190Srpaulo DBusMessageIter iter_array; 849252190Srpaulo 850252190Srpaulo if (entry->array_len == buflen) { 851252190Srpaulo struct wpabuf **newbuf; 852252190Srpaulo 853252190Srpaulo buflen += BIN_ARRAY_CHUNK_SIZE; 854252190Srpaulo 855252190Srpaulo newbuf = os_realloc_array(entry->binarray_value, 856252190Srpaulo buflen, BIN_ARRAY_ITEM_SIZE); 857252190Srpaulo if (!newbuf) 858252190Srpaulo goto cleanup; 859252190Srpaulo entry->binarray_value = newbuf; 860252190Srpaulo } 861252190Srpaulo 862252190Srpaulo dbus_message_iter_recurse(iter, &iter_array); 863281806Srpaulo os_memset(&tmpentry, 0, sizeof(tmpentry)); 864281806Srpaulo tmpentry.type = DBUS_TYPE_ARRAY; 865252190Srpaulo if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry) 866281806Srpaulo == FALSE) 867252190Srpaulo goto cleanup; 868252190Srpaulo 869252190Srpaulo entry->binarray_value[entry->array_len] = 870252190Srpaulo wpabuf_alloc_ext_data((u8 *) tmpentry.bytearray_value, 871252190Srpaulo tmpentry.array_len); 872252190Srpaulo if (entry->binarray_value[entry->array_len] == NULL) { 873252190Srpaulo wpa_dbus_dict_entry_clear(&tmpentry); 874252190Srpaulo goto cleanup; 875252190Srpaulo } 876252190Srpaulo entry->array_len++; 877252190Srpaulo dbus_message_iter_next(iter); 878252190Srpaulo } 879281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: binarray length %u", 880281806Srpaulo __func__, entry->array_len); 881252190Srpaulo 882252190Srpaulo return TRUE; 883252190Srpaulo 884252190Srpaulo cleanup: 885252190Srpaulo for (i = 0; i < (int) entry->array_len; i++) 886252190Srpaulo wpabuf_free(entry->binarray_value[i]); 887252190Srpaulo os_free(entry->binarray_value); 888252190Srpaulo entry->array_len = 0; 889252190Srpaulo entry->binarray_value = NULL; 890252190Srpaulo return FALSE; 891252190Srpaulo} 892252190Srpaulo 893252190Srpaulo 894214501Srpaulostatic dbus_bool_t _wpa_dbus_dict_entry_get_array( 895214501Srpaulo DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry) 896214501Srpaulo{ 897214501Srpaulo int array_type = dbus_message_iter_get_element_type(iter_dict_val); 898214501Srpaulo dbus_bool_t success = FALSE; 899214501Srpaulo DBusMessageIter iter_array; 900214501Srpaulo 901281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: array_type %c", __func__, array_type); 902214501Srpaulo 903214501Srpaulo dbus_message_iter_recurse(iter_dict_val, &iter_array); 904214501Srpaulo 905281806Srpaulo switch (array_type) { 906214501Srpaulo case DBUS_TYPE_BYTE: 907214501Srpaulo success = _wpa_dbus_dict_entry_get_byte_array(&iter_array, 908214501Srpaulo entry); 909214501Srpaulo break; 910214501Srpaulo case DBUS_TYPE_STRING: 911214501Srpaulo success = _wpa_dbus_dict_entry_get_string_array(&iter_array, 912214501Srpaulo array_type, 913214501Srpaulo entry); 914214501Srpaulo break; 915252190Srpaulo case DBUS_TYPE_ARRAY: 916252190Srpaulo success = _wpa_dbus_dict_entry_get_binarray(&iter_array, entry); 917281806Srpaulo break; 918214501Srpaulo default: 919281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: unsupported array type %c", 920281806Srpaulo __func__, array_type); 921214501Srpaulo break; 922214501Srpaulo } 923214501Srpaulo 924214501Srpaulo return success; 925214501Srpaulo} 926214501Srpaulo 927214501Srpaulo 928214501Srpaulostatic dbus_bool_t _wpa_dbus_dict_fill_value_from_variant( 929214501Srpaulo struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter) 930214501Srpaulo{ 931214501Srpaulo const char *v; 932214501Srpaulo 933214501Srpaulo switch (entry->type) { 934214501Srpaulo case DBUS_TYPE_OBJECT_PATH: 935281806Srpaulo dbus_message_iter_get_basic(iter, &v); 936281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: object path value: %s", 937281806Srpaulo __func__, v); 938281806Srpaulo entry->str_value = os_strdup(v); 939281806Srpaulo if (entry->str_value == NULL) 940281806Srpaulo return FALSE; 941281806Srpaulo break; 942214501Srpaulo case DBUS_TYPE_STRING: 943214501Srpaulo dbus_message_iter_get_basic(iter, &v); 944281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: string value: %s", 945281806Srpaulo __func__, wpa_debug_show_keys ? v : "[omitted]"); 946214501Srpaulo entry->str_value = os_strdup(v); 947214501Srpaulo if (entry->str_value == NULL) 948214501Srpaulo return FALSE; 949214501Srpaulo break; 950214501Srpaulo case DBUS_TYPE_BOOLEAN: 951214501Srpaulo dbus_message_iter_get_basic(iter, &entry->bool_value); 952281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: boolean value: %d", 953281806Srpaulo __func__, entry->bool_value); 954214501Srpaulo break; 955214501Srpaulo case DBUS_TYPE_BYTE: 956214501Srpaulo dbus_message_iter_get_basic(iter, &entry->byte_value); 957281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: byte value: %d", 958281806Srpaulo __func__, entry->byte_value); 959214501Srpaulo break; 960214501Srpaulo case DBUS_TYPE_INT16: 961214501Srpaulo dbus_message_iter_get_basic(iter, &entry->int16_value); 962281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: int16 value: %d", 963281806Srpaulo __func__, entry->int16_value); 964214501Srpaulo break; 965214501Srpaulo case DBUS_TYPE_UINT16: 966214501Srpaulo dbus_message_iter_get_basic(iter, &entry->uint16_value); 967281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: uint16 value: %d", 968281806Srpaulo __func__, entry->uint16_value); 969214501Srpaulo break; 970214501Srpaulo case DBUS_TYPE_INT32: 971214501Srpaulo dbus_message_iter_get_basic(iter, &entry->int32_value); 972281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: int32 value: %d", 973281806Srpaulo __func__, entry->int32_value); 974214501Srpaulo break; 975214501Srpaulo case DBUS_TYPE_UINT32: 976214501Srpaulo dbus_message_iter_get_basic(iter, &entry->uint32_value); 977281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: uint32 value: %d", 978281806Srpaulo __func__, entry->uint32_value); 979214501Srpaulo break; 980214501Srpaulo case DBUS_TYPE_INT64: 981214501Srpaulo dbus_message_iter_get_basic(iter, &entry->int64_value); 982281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: int64 value: %lld", 983281806Srpaulo __func__, (long long int) entry->int64_value); 984214501Srpaulo break; 985214501Srpaulo case DBUS_TYPE_UINT64: 986214501Srpaulo dbus_message_iter_get_basic(iter, &entry->uint64_value); 987281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: uint64 value: %llu", 988281806Srpaulo __func__, 989281806Srpaulo (unsigned long long int) entry->uint64_value); 990214501Srpaulo break; 991214501Srpaulo case DBUS_TYPE_DOUBLE: 992214501Srpaulo dbus_message_iter_get_basic(iter, &entry->double_value); 993281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: double value: %f", 994281806Srpaulo __func__, entry->double_value); 995214501Srpaulo break; 996214501Srpaulo case DBUS_TYPE_ARRAY: 997214501Srpaulo return _wpa_dbus_dict_entry_get_array(iter, entry); 998214501Srpaulo default: 999281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: unsupported type %c", 1000281806Srpaulo __func__, entry->type); 1001214501Srpaulo return FALSE; 1002214501Srpaulo } 1003214501Srpaulo 1004214501Srpaulo return TRUE; 1005214501Srpaulo} 1006214501Srpaulo 1007214501Srpaulo 1008214501Srpaulo/** 1009214501Srpaulo * Read the current key/value entry from the dict. Entries are dynamically 1010214501Srpaulo * allocated when needed and must be freed after use with the 1011214501Srpaulo * wpa_dbus_dict_entry_clear() function. 1012214501Srpaulo * 1013214501Srpaulo * The returned entry object will be filled with the type and value of the next 1014214501Srpaulo * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error 1015214501Srpaulo * occurred. 1016214501Srpaulo * 1017214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 1018214501Srpaulo * wpa_dbus_dict_open_read() 1019214501Srpaulo * @param entry A valid dict entry object into which the dict key and value 1020214501Srpaulo * will be placed 1021214501Srpaulo * @return TRUE on success, FALSE on failure 1022214501Srpaulo * 1023214501Srpaulo */ 1024214501Srpaulodbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict, 1025214501Srpaulo struct wpa_dbus_dict_entry * entry) 1026214501Srpaulo{ 1027214501Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val; 1028214501Srpaulo int type; 1029214501Srpaulo const char *key; 1030214501Srpaulo 1031281806Srpaulo if (!iter_dict || !entry || 1032281806Srpaulo dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY) { 1033281806Srpaulo wpa_printf(MSG_DEBUG, "%s: not a dict entry", __func__); 1034214501Srpaulo goto error; 1035281806Srpaulo } 1036214501Srpaulo 1037214501Srpaulo dbus_message_iter_recurse(iter_dict, &iter_dict_entry); 1038214501Srpaulo dbus_message_iter_get_basic(&iter_dict_entry, &key); 1039281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: dict entry key: %s", __func__, key); 1040214501Srpaulo entry->key = key; 1041214501Srpaulo 1042281806Srpaulo if (!dbus_message_iter_next(&iter_dict_entry)) { 1043281806Srpaulo wpa_printf(MSG_DEBUG, "%s: no variant in dict entry", __func__); 1044214501Srpaulo goto error; 1045281806Srpaulo } 1046214501Srpaulo type = dbus_message_iter_get_arg_type(&iter_dict_entry); 1047281806Srpaulo if (type != DBUS_TYPE_VARIANT) { 1048281806Srpaulo wpa_printf(MSG_DEBUG, 1049281806Srpaulo "%s: unexpected dict entry variant type: %c", 1050281806Srpaulo __func__, type); 1051214501Srpaulo goto error; 1052281806Srpaulo } 1053214501Srpaulo 1054214501Srpaulo dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val); 1055214501Srpaulo entry->type = dbus_message_iter_get_arg_type(&iter_dict_val); 1056281806Srpaulo wpa_printf(MSG_MSGDUMP, "%s: dict entry variant content type: %c", 1057281806Srpaulo __func__, entry->type); 1058281806Srpaulo entry->array_type = DBUS_TYPE_INVALID; 1059281806Srpaulo if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val)) { 1060281806Srpaulo wpa_printf(MSG_DEBUG, 1061281806Srpaulo "%s: failed to fetch dict values from variant", 1062281806Srpaulo __func__); 1063214501Srpaulo goto error; 1064281806Srpaulo } 1065214501Srpaulo 1066214501Srpaulo dbus_message_iter_next(iter_dict); 1067214501Srpaulo return TRUE; 1068214501Srpaulo 1069214501Srpauloerror: 1070214501Srpaulo if (entry) { 1071214501Srpaulo wpa_dbus_dict_entry_clear(entry); 1072214501Srpaulo entry->type = DBUS_TYPE_INVALID; 1073214501Srpaulo entry->array_type = DBUS_TYPE_INVALID; 1074214501Srpaulo } 1075214501Srpaulo 1076214501Srpaulo return FALSE; 1077214501Srpaulo} 1078214501Srpaulo 1079214501Srpaulo 1080214501Srpaulo/** 1081214501Srpaulo * Return whether or not there are additional dictionary entries. 1082214501Srpaulo * 1083214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 1084214501Srpaulo * wpa_dbus_dict_open_read() 1085214501Srpaulo * @return TRUE if more dict entries exists, FALSE if no more dict entries 1086214501Srpaulo * exist 1087214501Srpaulo */ 1088214501Srpaulodbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict) 1089214501Srpaulo{ 1090214501Srpaulo if (!iter_dict) 1091214501Srpaulo return FALSE; 1092214501Srpaulo return dbus_message_iter_get_arg_type(iter_dict) == 1093214501Srpaulo DBUS_TYPE_DICT_ENTRY; 1094214501Srpaulo} 1095214501Srpaulo 1096214501Srpaulo 1097214501Srpaulo/** 1098214501Srpaulo * Free any memory used by the entry object. 1099214501Srpaulo * 1100214501Srpaulo * @param entry The entry object 1101214501Srpaulo */ 1102214501Srpaulovoid wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry) 1103214501Srpaulo{ 1104214501Srpaulo unsigned int i; 1105214501Srpaulo 1106214501Srpaulo if (!entry) 1107214501Srpaulo return; 1108214501Srpaulo switch (entry->type) { 1109214501Srpaulo case DBUS_TYPE_OBJECT_PATH: 1110214501Srpaulo case DBUS_TYPE_STRING: 1111214501Srpaulo os_free(entry->str_value); 1112214501Srpaulo break; 1113214501Srpaulo case DBUS_TYPE_ARRAY: 1114214501Srpaulo switch (entry->array_type) { 1115214501Srpaulo case DBUS_TYPE_BYTE: 1116214501Srpaulo os_free(entry->bytearray_value); 1117214501Srpaulo break; 1118214501Srpaulo case DBUS_TYPE_STRING: 1119281806Srpaulo if (!entry->strarray_value) 1120281806Srpaulo break; 1121214501Srpaulo for (i = 0; i < entry->array_len; i++) 1122214501Srpaulo os_free(entry->strarray_value[i]); 1123214501Srpaulo os_free(entry->strarray_value); 1124214501Srpaulo break; 1125252190Srpaulo case WPAS_DBUS_TYPE_BINARRAY: 1126252190Srpaulo for (i = 0; i < entry->array_len; i++) 1127252190Srpaulo wpabuf_free(entry->binarray_value[i]); 1128252190Srpaulo os_free(entry->binarray_value); 1129252190Srpaulo break; 1130214501Srpaulo } 1131214501Srpaulo break; 1132214501Srpaulo } 1133214501Srpaulo 1134252190Srpaulo os_memset(entry, 0, sizeof(struct wpa_dbus_dict_entry)); 1135214501Srpaulo} 1136