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{ 69214501Srpaulo 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 109214501Srpaulo if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING, 110214501Srpaulo &key)) 111214501Srpaulo return FALSE; 112214501Srpaulo 113214501Srpaulo return TRUE; 114214501Srpaulo} 115214501Srpaulo 116214501Srpaulo 117214501Srpaulostatic dbus_bool_t _wpa_dbus_add_dict_entry_end( 118214501Srpaulo DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry, 119214501Srpaulo DBusMessageIter *iter_dict_val) 120214501Srpaulo{ 121214501Srpaulo if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val)) 122214501Srpaulo return FALSE; 123214501Srpaulo if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry)) 124214501Srpaulo return FALSE; 125214501Srpaulo 126214501Srpaulo return TRUE; 127214501Srpaulo} 128214501Srpaulo 129214501Srpaulo 130214501Srpaulostatic dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict, 131214501Srpaulo const char *key, 132214501Srpaulo const int value_type, 133214501Srpaulo const void *value) 134214501Srpaulo{ 135214501Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val; 136214501Srpaulo const char *type_as_string = NULL; 137214501Srpaulo 138214501Srpaulo if (key == NULL) 139214501Srpaulo return FALSE; 140214501Srpaulo 141214501Srpaulo type_as_string = wpa_dbus_type_as_string(value_type); 142214501Srpaulo if (!type_as_string) 143214501Srpaulo return FALSE; 144214501Srpaulo 145214501Srpaulo if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry, 146214501Srpaulo key, value_type)) 147214501Srpaulo return FALSE; 148214501Srpaulo 149214501Srpaulo if (!dbus_message_iter_open_container(&iter_dict_entry, 150214501Srpaulo DBUS_TYPE_VARIANT, 151214501Srpaulo type_as_string, &iter_dict_val)) 152214501Srpaulo return FALSE; 153214501Srpaulo 154214501Srpaulo if (!dbus_message_iter_append_basic(&iter_dict_val, value_type, value)) 155214501Srpaulo return FALSE; 156214501Srpaulo 157214501Srpaulo if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry, 158214501Srpaulo &iter_dict_val)) 159214501Srpaulo return FALSE; 160214501Srpaulo 161214501Srpaulo return TRUE; 162214501Srpaulo} 163214501Srpaulo 164214501Srpaulo 165214501Srpaulostatic dbus_bool_t _wpa_dbus_add_dict_entry_byte_array( 166214501Srpaulo DBusMessageIter *iter_dict, const char *key, 167214501Srpaulo const char *value, const dbus_uint32_t value_len) 168214501Srpaulo{ 169214501Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; 170214501Srpaulo dbus_uint32_t i; 171214501Srpaulo 172214501Srpaulo if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry, 173214501Srpaulo key, DBUS_TYPE_ARRAY)) 174214501Srpaulo return FALSE; 175214501Srpaulo 176214501Srpaulo if (!dbus_message_iter_open_container(&iter_dict_entry, 177214501Srpaulo DBUS_TYPE_VARIANT, 178214501Srpaulo DBUS_TYPE_ARRAY_AS_STRING 179214501Srpaulo DBUS_TYPE_BYTE_AS_STRING, 180214501Srpaulo &iter_dict_val)) 181214501Srpaulo return FALSE; 182214501Srpaulo 183214501Srpaulo if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY, 184214501Srpaulo DBUS_TYPE_BYTE_AS_STRING, 185214501Srpaulo &iter_array)) 186214501Srpaulo return FALSE; 187214501Srpaulo 188214501Srpaulo for (i = 0; i < value_len; i++) { 189214501Srpaulo if (!dbus_message_iter_append_basic(&iter_array, 190214501Srpaulo DBUS_TYPE_BYTE, 191214501Srpaulo &(value[i]))) 192214501Srpaulo return FALSE; 193214501Srpaulo } 194214501Srpaulo 195214501Srpaulo if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array)) 196214501Srpaulo return FALSE; 197214501Srpaulo 198214501Srpaulo if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry, 199214501Srpaulo &iter_dict_val)) 200214501Srpaulo return FALSE; 201214501Srpaulo 202214501Srpaulo return TRUE; 203214501Srpaulo} 204214501Srpaulo 205214501Srpaulo 206214501Srpaulo/** 207214501Srpaulo * Add a string entry to the dict. 208214501Srpaulo * 209214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 210214501Srpaulo * wpa_dbus_dict_open_write() 211214501Srpaulo * @param key The key of the dict item 212214501Srpaulo * @param value The string value 213214501Srpaulo * @return TRUE on success, FALSE on failure 214214501Srpaulo * 215214501Srpaulo */ 216214501Srpaulodbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict, 217214501Srpaulo const char *key, const char *value) 218214501Srpaulo{ 219214501Srpaulo if (!value) 220214501Srpaulo return FALSE; 221214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING, 222214501Srpaulo &value); 223214501Srpaulo} 224214501Srpaulo 225214501Srpaulo 226214501Srpaulo/** 227214501Srpaulo * Add a byte entry to the dict. 228214501Srpaulo * 229214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 230214501Srpaulo * wpa_dbus_dict_open_write() 231214501Srpaulo * @param key The key of the dict item 232214501Srpaulo * @param value The byte value 233214501Srpaulo * @return TRUE on success, FALSE on failure 234214501Srpaulo * 235214501Srpaulo */ 236214501Srpaulodbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict, 237214501Srpaulo const char *key, const char value) 238214501Srpaulo{ 239214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BYTE, 240214501Srpaulo &value); 241214501Srpaulo} 242214501Srpaulo 243214501Srpaulo 244214501Srpaulo/** 245214501Srpaulo * Add a boolean entry to the dict. 246214501Srpaulo * 247214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 248214501Srpaulo * wpa_dbus_dict_open_write() 249214501Srpaulo * @param key The key of the dict item 250214501Srpaulo * @param value The boolean value 251214501Srpaulo * @return TRUE on success, FALSE on failure 252214501Srpaulo * 253214501Srpaulo */ 254214501Srpaulodbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict, 255214501Srpaulo const char *key, const dbus_bool_t value) 256214501Srpaulo{ 257214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, 258214501Srpaulo DBUS_TYPE_BOOLEAN, &value); 259214501Srpaulo} 260214501Srpaulo 261214501Srpaulo 262214501Srpaulo/** 263214501Srpaulo * Add a 16-bit signed 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 signed integer value 269214501Srpaulo * @return TRUE on success, FALSE on failure 270214501Srpaulo * 271214501Srpaulo */ 272214501Srpaulodbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict, 273214501Srpaulo const char *key, 274214501Srpaulo const dbus_int16_t value) 275214501Srpaulo{ 276214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16, 277214501Srpaulo &value); 278214501Srpaulo} 279214501Srpaulo 280214501Srpaulo 281214501Srpaulo/** 282214501Srpaulo * Add a 16-bit unsigned integer entry 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 16-bit unsigned integer value 288214501Srpaulo * @return TRUE on success, FALSE on failure 289214501Srpaulo * 290214501Srpaulo */ 291214501Srpaulodbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict, 292214501Srpaulo const char *key, 293214501Srpaulo const dbus_uint16_t value) 294214501Srpaulo{ 295214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16, 296214501Srpaulo &value); 297214501Srpaulo} 298214501Srpaulo 299214501Srpaulo 300214501Srpaulo/** 301214501Srpaulo * Add a 32-bit signed integer 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 signed integer value 307214501Srpaulo * @return TRUE on success, FALSE on failure 308214501Srpaulo * 309214501Srpaulo */ 310214501Srpaulodbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict, 311214501Srpaulo const char *key, 312214501Srpaulo const dbus_int32_t value) 313214501Srpaulo{ 314214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32, 315214501Srpaulo &value); 316214501Srpaulo} 317214501Srpaulo 318214501Srpaulo 319214501Srpaulo/** 320214501Srpaulo * Add a 32-bit unsigned 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 32-bit unsigned integer value 326214501Srpaulo * @return TRUE on success, FALSE on failure 327214501Srpaulo * 328214501Srpaulo */ 329214501Srpaulodbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict, 330214501Srpaulo const char *key, 331214501Srpaulo const dbus_uint32_t value) 332214501Srpaulo{ 333214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32, 334214501Srpaulo &value); 335214501Srpaulo} 336214501Srpaulo 337214501Srpaulo 338214501Srpaulo/** 339214501Srpaulo * Add a 64-bit 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 integer value 345214501Srpaulo * @return TRUE on success, FALSE on failure 346214501Srpaulo * 347214501Srpaulo */ 348214501Srpaulodbus_bool_t wpa_dbus_dict_append_int64(DBusMessageIter *iter_dict, 349214501Srpaulo const char *key, 350214501Srpaulo const dbus_int64_t value) 351214501Srpaulo{ 352214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT64, 353214501Srpaulo &value); 354214501Srpaulo} 355214501Srpaulo 356214501Srpaulo 357214501Srpaulo/** 358214501Srpaulo * Add a 64-bit unsigned integer 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 64-bit unsigned integer value 364214501Srpaulo * @return TRUE on success, FALSE on failure 365214501Srpaulo * 366214501Srpaulo */ 367214501Srpaulodbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict, 368214501Srpaulo const char *key, 369214501Srpaulo const dbus_uint64_t value) 370214501Srpaulo{ 371214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT64, 372214501Srpaulo &value); 373214501Srpaulo} 374214501Srpaulo 375214501Srpaulo 376214501Srpaulo/** 377214501Srpaulo * Add a double-precision floating point entry to the dict. 378214501Srpaulo * 379214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 380214501Srpaulo * wpa_dbus_dict_open_write() 381214501Srpaulo * @param key The key of the dict item 382214501Srpaulo * @param value The double-precision floating point value 383214501Srpaulo * @return TRUE on success, FALSE on failure 384214501Srpaulo * 385214501Srpaulo */ 386214501Srpaulodbus_bool_t wpa_dbus_dict_append_double(DBusMessageIter *iter_dict, 387214501Srpaulo const char *key, const double value) 388214501Srpaulo{ 389214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_DOUBLE, 390214501Srpaulo &value); 391214501Srpaulo} 392214501Srpaulo 393214501Srpaulo 394214501Srpaulo/** 395214501Srpaulo * Add a DBus object path entry to the dict. 396214501Srpaulo * 397214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 398214501Srpaulo * wpa_dbus_dict_open_write() 399214501Srpaulo * @param key The key of the dict item 400214501Srpaulo * @param value The DBus object path value 401214501Srpaulo * @return TRUE on success, FALSE on failure 402214501Srpaulo * 403214501Srpaulo */ 404214501Srpaulodbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict, 405214501Srpaulo const char *key, 406214501Srpaulo const char *value) 407214501Srpaulo{ 408214501Srpaulo if (!value) 409214501Srpaulo return FALSE; 410214501Srpaulo return _wpa_dbus_add_dict_entry_basic(iter_dict, key, 411214501Srpaulo DBUS_TYPE_OBJECT_PATH, &value); 412214501Srpaulo} 413214501Srpaulo 414214501Srpaulo 415214501Srpaulo/** 416214501Srpaulo * Add a byte array entry to the dict. 417214501Srpaulo * 418214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 419214501Srpaulo * wpa_dbus_dict_open_write() 420214501Srpaulo * @param key The key of the dict item 421214501Srpaulo * @param value The byte array 422214501Srpaulo * @param value_len The length of the byte array, in bytes 423214501Srpaulo * @return TRUE on success, FALSE on failure 424214501Srpaulo * 425214501Srpaulo */ 426214501Srpaulodbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict, 427214501Srpaulo const char *key, 428214501Srpaulo const char *value, 429214501Srpaulo const dbus_uint32_t value_len) 430214501Srpaulo{ 431214501Srpaulo if (!key) 432214501Srpaulo return FALSE; 433214501Srpaulo if (!value && (value_len != 0)) 434214501Srpaulo return FALSE; 435214501Srpaulo return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value, 436214501Srpaulo value_len); 437214501Srpaulo} 438214501Srpaulo 439214501Srpaulo 440214501Srpaulo/** 441252190Srpaulo * Begin an array entry in the dict 442214501Srpaulo * 443214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 444214501Srpaulo * wpa_dbus_dict_open_write() 445214501Srpaulo * @param key The key of the dict item 446252190Srpaulo * @param type The type of the contained data 447214501Srpaulo * @param iter_dict_entry A private DBusMessageIter provided by the caller to 448214501Srpaulo * be passed to wpa_dbus_dict_end_string_array() 449214501Srpaulo * @param iter_dict_val A private DBusMessageIter provided by the caller to 450214501Srpaulo * be passed to wpa_dbus_dict_end_string_array() 451214501Srpaulo * @param iter_array On return, the DBusMessageIter to be passed to 452214501Srpaulo * wpa_dbus_dict_string_array_add_element() 453214501Srpaulo * @return TRUE on success, FALSE on failure 454214501Srpaulo * 455214501Srpaulo */ 456252190Srpaulodbus_bool_t wpa_dbus_dict_begin_array(DBusMessageIter *iter_dict, 457252190Srpaulo const char *key, const char *type, 458252190Srpaulo DBusMessageIter *iter_dict_entry, 459252190Srpaulo DBusMessageIter *iter_dict_val, 460252190Srpaulo DBusMessageIter *iter_array) 461214501Srpaulo{ 462252190Srpaulo char array_type[10]; 463252190Srpaulo int err; 464252190Srpaulo 465252190Srpaulo err = os_snprintf(array_type, sizeof(array_type), 466252190Srpaulo DBUS_TYPE_ARRAY_AS_STRING "%s", 467252190Srpaulo type); 468252190Srpaulo if (err < 0 || err > (int) sizeof(array_type)) 469252190Srpaulo return FALSE; 470252190Srpaulo 471214501Srpaulo if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array) 472214501Srpaulo return FALSE; 473214501Srpaulo 474214501Srpaulo if (!_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry, 475214501Srpaulo key, DBUS_TYPE_ARRAY)) 476214501Srpaulo return FALSE; 477214501Srpaulo 478214501Srpaulo if (!dbus_message_iter_open_container(iter_dict_entry, 479214501Srpaulo DBUS_TYPE_VARIANT, 480252190Srpaulo array_type, 481214501Srpaulo iter_dict_val)) 482214501Srpaulo return FALSE; 483214501Srpaulo 484214501Srpaulo if (!dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY, 485252190Srpaulo type, iter_array)) 486214501Srpaulo return FALSE; 487214501Srpaulo 488214501Srpaulo return TRUE; 489214501Srpaulo} 490214501Srpaulo 491214501Srpaulo 492252190Srpaulodbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict, 493252190Srpaulo const char *key, 494252190Srpaulo DBusMessageIter *iter_dict_entry, 495252190Srpaulo DBusMessageIter *iter_dict_val, 496252190Srpaulo DBusMessageIter *iter_array) 497252190Srpaulo{ 498252190Srpaulo return wpa_dbus_dict_begin_array( 499252190Srpaulo iter_dict, key, 500252190Srpaulo DBUS_TYPE_STRING_AS_STRING, 501252190Srpaulo iter_dict_entry, iter_dict_val, iter_array); 502252190Srpaulo} 503252190Srpaulo 504252190Srpaulo 505214501Srpaulo/** 506214501Srpaulo * Add a single string element to a string array dict entry 507214501Srpaulo * 508214501Srpaulo * @param iter_array A valid DBusMessageIter returned from 509214501Srpaulo * wpa_dbus_dict_begin_string_array()'s 510214501Srpaulo * iter_array parameter 511214501Srpaulo * @param elem The string element to be added to the dict entry's string array 512214501Srpaulo * @return TRUE on success, FALSE on failure 513214501Srpaulo * 514214501Srpaulo */ 515214501Srpaulodbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array, 516214501Srpaulo const char *elem) 517214501Srpaulo{ 518214501Srpaulo if (!iter_array || !elem) 519214501Srpaulo return FALSE; 520214501Srpaulo 521214501Srpaulo return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING, 522214501Srpaulo &elem); 523214501Srpaulo} 524214501Srpaulo 525214501Srpaulo 526214501Srpaulo/** 527252190Srpaulo * Add a single byte array element to a string array dict entry 528214501Srpaulo * 529252190Srpaulo * @param iter_array A valid DBusMessageIter returned from 530252190Srpaulo * wpa_dbus_dict_begin_array()'s iter_array 531252190Srpaulo * parameter -- note that wpa_dbus_dict_begin_array() 532252190Srpaulo * must have been called with "ay" as the type 533252190Srpaulo * @param value The data to be added to the dict entry's array 534252190Srpaulo * @param value_len The length of the data 535252190Srpaulo * @return TRUE on success, FALSE on failure 536252190Srpaulo * 537252190Srpaulo */ 538252190Srpaulodbus_bool_t wpa_dbus_dict_bin_array_add_element(DBusMessageIter *iter_array, 539252190Srpaulo const u8 *value, 540252190Srpaulo size_t value_len) 541252190Srpaulo{ 542252190Srpaulo DBusMessageIter iter_bytes; 543252190Srpaulo size_t i; 544252190Srpaulo 545252190Srpaulo if (!iter_array || !value) 546252190Srpaulo return FALSE; 547252190Srpaulo 548252190Srpaulo if (!dbus_message_iter_open_container(iter_array, DBUS_TYPE_ARRAY, 549252190Srpaulo DBUS_TYPE_BYTE_AS_STRING, 550252190Srpaulo &iter_bytes)) 551252190Srpaulo return FALSE; 552252190Srpaulo 553252190Srpaulo for (i = 0; i < value_len; i++) { 554252190Srpaulo if (!dbus_message_iter_append_basic(&iter_bytes, 555252190Srpaulo DBUS_TYPE_BYTE, 556252190Srpaulo &(value[i]))) 557252190Srpaulo return FALSE; 558252190Srpaulo } 559252190Srpaulo 560252190Srpaulo if (!dbus_message_iter_close_container(iter_array, &iter_bytes)) 561252190Srpaulo return FALSE; 562252190Srpaulo 563252190Srpaulo return TRUE; 564252190Srpaulo} 565252190Srpaulo 566252190Srpaulo 567252190Srpaulo/** 568252190Srpaulo * End an array dict entry 569252190Srpaulo * 570214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 571214501Srpaulo * wpa_dbus_dict_open_write() 572214501Srpaulo * @param iter_dict_entry A private DBusMessageIter returned from 573252190Srpaulo * wpa_dbus_dict_begin_string_array() or 574252190Srpaulo * wpa_dbus_dict_begin_array() 575214501Srpaulo * @param iter_dict_val A private DBusMessageIter returned from 576252190Srpaulo * wpa_dbus_dict_begin_string_array() or 577252190Srpaulo * wpa_dbus_dict_begin_array() 578214501Srpaulo * @param iter_array A DBusMessageIter returned from 579252190Srpaulo * wpa_dbus_dict_begin_string_array() or 580252190Srpaulo * wpa_dbus_dict_begin_array() 581214501Srpaulo * @return TRUE on success, FALSE on failure 582214501Srpaulo * 583214501Srpaulo */ 584252190Srpaulodbus_bool_t wpa_dbus_dict_end_array(DBusMessageIter *iter_dict, 585252190Srpaulo DBusMessageIter *iter_dict_entry, 586252190Srpaulo DBusMessageIter *iter_dict_val, 587252190Srpaulo DBusMessageIter *iter_array) 588214501Srpaulo{ 589214501Srpaulo if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array) 590214501Srpaulo return FALSE; 591214501Srpaulo 592214501Srpaulo if (!dbus_message_iter_close_container(iter_dict_val, iter_array)) 593214501Srpaulo return FALSE; 594214501Srpaulo 595214501Srpaulo if (!_wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry, 596214501Srpaulo iter_dict_val)) 597214501Srpaulo return FALSE; 598214501Srpaulo 599214501Srpaulo return TRUE; 600214501Srpaulo} 601214501Srpaulo 602214501Srpaulo 603214501Srpaulo/** 604214501Srpaulo * Convenience function to add an entire string array to the dict. 605214501Srpaulo * 606214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 607214501Srpaulo * wpa_dbus_dict_open_write() 608214501Srpaulo * @param key The key of the dict item 609214501Srpaulo * @param items The array of strings 610214501Srpaulo * @param num_items The number of strings in the array 611214501Srpaulo * @return TRUE on success, FALSE on failure 612214501Srpaulo * 613214501Srpaulo */ 614214501Srpaulodbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict, 615214501Srpaulo const char *key, 616214501Srpaulo const char **items, 617214501Srpaulo const dbus_uint32_t num_items) 618214501Srpaulo{ 619214501Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; 620214501Srpaulo dbus_uint32_t i; 621214501Srpaulo 622214501Srpaulo if (!key) 623214501Srpaulo return FALSE; 624214501Srpaulo if (!items && (num_items != 0)) 625214501Srpaulo return FALSE; 626214501Srpaulo 627214501Srpaulo if (!wpa_dbus_dict_begin_string_array(iter_dict, key, 628214501Srpaulo &iter_dict_entry, &iter_dict_val, 629214501Srpaulo &iter_array)) 630214501Srpaulo return FALSE; 631214501Srpaulo 632214501Srpaulo for (i = 0; i < num_items; i++) { 633214501Srpaulo if (!wpa_dbus_dict_string_array_add_element(&iter_array, 634214501Srpaulo items[i])) 635214501Srpaulo return FALSE; 636214501Srpaulo } 637214501Srpaulo 638214501Srpaulo if (!wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry, 639214501Srpaulo &iter_dict_val, &iter_array)) 640214501Srpaulo return FALSE; 641214501Srpaulo 642214501Srpaulo return TRUE; 643214501Srpaulo} 644214501Srpaulo 645214501Srpaulo 646252190Srpaulo/** 647252190Srpaulo * Convenience function to add an wpabuf binary array to the dict. 648252190Srpaulo * 649252190Srpaulo * @param iter_dict A valid DBusMessageIter returned from 650252190Srpaulo * wpa_dbus_dict_open_write() 651252190Srpaulo * @param key The key of the dict item 652252190Srpaulo * @param items The array of wpabuf structures 653252190Srpaulo * @param num_items The number of strings in the array 654252190Srpaulo * @return TRUE on success, FALSE on failure 655252190Srpaulo * 656252190Srpaulo */ 657252190Srpaulodbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict, 658252190Srpaulo const char *key, 659252190Srpaulo const struct wpabuf **items, 660252190Srpaulo const dbus_uint32_t num_items) 661252190Srpaulo{ 662252190Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; 663252190Srpaulo dbus_uint32_t i; 664252190Srpaulo 665252190Srpaulo if (!key) 666252190Srpaulo return FALSE; 667252190Srpaulo if (!items && (num_items != 0)) 668252190Srpaulo return FALSE; 669252190Srpaulo 670252190Srpaulo if (!wpa_dbus_dict_begin_array(iter_dict, key, 671252190Srpaulo DBUS_TYPE_ARRAY_AS_STRING 672252190Srpaulo DBUS_TYPE_BYTE_AS_STRING, 673252190Srpaulo &iter_dict_entry, &iter_dict_val, 674252190Srpaulo &iter_array)) 675252190Srpaulo return FALSE; 676252190Srpaulo 677252190Srpaulo for (i = 0; i < num_items; i++) { 678252190Srpaulo if (!wpa_dbus_dict_bin_array_add_element(&iter_array, 679252190Srpaulo wpabuf_head(items[i]), 680252190Srpaulo wpabuf_len(items[i]))) 681252190Srpaulo return FALSE; 682252190Srpaulo } 683252190Srpaulo 684252190Srpaulo if (!wpa_dbus_dict_end_array(iter_dict, &iter_dict_entry, 685252190Srpaulo &iter_dict_val, &iter_array)) 686252190Srpaulo return FALSE; 687252190Srpaulo 688252190Srpaulo return TRUE; 689252190Srpaulo} 690252190Srpaulo 691252190Srpaulo 692214501Srpaulo/*****************************************************/ 693214501Srpaulo/* Stuff for reading dicts */ 694214501Srpaulo/*****************************************************/ 695214501Srpaulo 696214501Srpaulo/** 697214501Srpaulo * Start reading from a dbus dict. 698214501Srpaulo * 699214501Srpaulo * @param iter A valid DBusMessageIter pointing to the start of the dict 700214501Srpaulo * @param iter_dict (out) A DBusMessageIter to be passed to 701214501Srpaulo * wpa_dbus_dict_read_next_entry() 702252190Srpaulo * @error on failure a descriptive error 703214501Srpaulo * @return TRUE on success, FALSE on failure 704214501Srpaulo * 705214501Srpaulo */ 706214501Srpaulodbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter, 707252190Srpaulo DBusMessageIter *iter_dict, 708252190Srpaulo DBusError *error) 709214501Srpaulo{ 710252190Srpaulo if (!iter || !iter_dict) { 711252190Srpaulo dbus_set_error_const(error, DBUS_ERROR_FAILED, 712252190Srpaulo "[internal] missing message iterators"); 713214501Srpaulo return FALSE; 714252190Srpaulo } 715214501Srpaulo 716214501Srpaulo if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY || 717252190Srpaulo dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) { 718252190Srpaulo dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, 719252190Srpaulo "unexpected message argument types"); 720214501Srpaulo return FALSE; 721252190Srpaulo } 722214501Srpaulo 723214501Srpaulo dbus_message_iter_recurse(iter, iter_dict); 724214501Srpaulo return TRUE; 725214501Srpaulo} 726214501Srpaulo 727214501Srpaulo 728214501Srpaulo#define BYTE_ARRAY_CHUNK_SIZE 34 729214501Srpaulo#define BYTE_ARRAY_ITEM_SIZE (sizeof(char)) 730214501Srpaulo 731214501Srpaulostatic dbus_bool_t _wpa_dbus_dict_entry_get_byte_array( 732252190Srpaulo DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry) 733214501Srpaulo{ 734214501Srpaulo dbus_uint32_t count = 0; 735214501Srpaulo dbus_bool_t success = FALSE; 736252190Srpaulo char *buffer, *nbuffer; 737214501Srpaulo 738214501Srpaulo entry->bytearray_value = NULL; 739214501Srpaulo entry->array_type = DBUS_TYPE_BYTE; 740214501Srpaulo 741252190Srpaulo buffer = os_calloc(BYTE_ARRAY_CHUNK_SIZE, BYTE_ARRAY_ITEM_SIZE); 742214501Srpaulo if (!buffer) 743214501Srpaulo return FALSE; 744214501Srpaulo 745214501Srpaulo entry->bytearray_value = buffer; 746214501Srpaulo entry->array_len = 0; 747214501Srpaulo while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) { 748214501Srpaulo char byte; 749214501Srpaulo 750214501Srpaulo if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) { 751252190Srpaulo nbuffer = os_realloc_array( 752252190Srpaulo buffer, count + BYTE_ARRAY_CHUNK_SIZE, 753252190Srpaulo BYTE_ARRAY_ITEM_SIZE); 754214501Srpaulo if (nbuffer == NULL) { 755214501Srpaulo os_free(buffer); 756214501Srpaulo wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_" 757214501Srpaulo "entry_get_byte_array out of " 758214501Srpaulo "memory trying to retrieve the " 759214501Srpaulo "string array"); 760214501Srpaulo goto done; 761214501Srpaulo } 762214501Srpaulo buffer = nbuffer; 763214501Srpaulo } 764214501Srpaulo entry->bytearray_value = buffer; 765214501Srpaulo 766214501Srpaulo dbus_message_iter_get_basic(iter, &byte); 767214501Srpaulo entry->bytearray_value[count] = byte; 768214501Srpaulo entry->array_len = ++count; 769214501Srpaulo dbus_message_iter_next(iter); 770214501Srpaulo } 771214501Srpaulo 772214501Srpaulo /* Zero-length arrays are valid. */ 773214501Srpaulo if (entry->array_len == 0) { 774214501Srpaulo os_free(entry->bytearray_value); 775214501Srpaulo entry->bytearray_value = NULL; 776214501Srpaulo } 777214501Srpaulo 778214501Srpaulo success = TRUE; 779214501Srpaulo 780214501Srpaulodone: 781214501Srpaulo return success; 782214501Srpaulo} 783214501Srpaulo 784214501Srpaulo 785214501Srpaulo#define STR_ARRAY_CHUNK_SIZE 8 786214501Srpaulo#define STR_ARRAY_ITEM_SIZE (sizeof(char *)) 787214501Srpaulo 788214501Srpaulostatic dbus_bool_t _wpa_dbus_dict_entry_get_string_array( 789214501Srpaulo DBusMessageIter *iter, int array_type, 790214501Srpaulo struct wpa_dbus_dict_entry *entry) 791214501Srpaulo{ 792214501Srpaulo dbus_uint32_t count = 0; 793214501Srpaulo dbus_bool_t success = FALSE; 794214501Srpaulo char **buffer, **nbuffer; 795214501Srpaulo 796214501Srpaulo entry->strarray_value = NULL; 797214501Srpaulo entry->array_type = DBUS_TYPE_STRING; 798214501Srpaulo 799252190Srpaulo buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE); 800214501Srpaulo if (buffer == NULL) 801214501Srpaulo return FALSE; 802214501Srpaulo 803214501Srpaulo entry->strarray_value = buffer; 804214501Srpaulo entry->array_len = 0; 805214501Srpaulo while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) { 806214501Srpaulo const char *value; 807214501Srpaulo char *str; 808214501Srpaulo 809214501Srpaulo if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) { 810252190Srpaulo nbuffer = os_realloc_array( 811252190Srpaulo buffer, count + STR_ARRAY_CHUNK_SIZE, 812252190Srpaulo STR_ARRAY_ITEM_SIZE); 813214501Srpaulo if (nbuffer == NULL) { 814214501Srpaulo os_free(buffer); 815214501Srpaulo wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_" 816214501Srpaulo "entry_get_string_array out of " 817214501Srpaulo "memory trying to retrieve the " 818214501Srpaulo "string array"); 819214501Srpaulo goto done; 820214501Srpaulo } 821214501Srpaulo buffer = nbuffer; 822214501Srpaulo } 823214501Srpaulo entry->strarray_value = buffer; 824214501Srpaulo 825214501Srpaulo dbus_message_iter_get_basic(iter, &value); 826214501Srpaulo str = os_strdup(value); 827214501Srpaulo if (str == NULL) { 828214501Srpaulo wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_entry_get_" 829214501Srpaulo "string_array out of memory trying to " 830214501Srpaulo "duplicate the string array"); 831214501Srpaulo goto done; 832214501Srpaulo } 833214501Srpaulo entry->strarray_value[count] = str; 834214501Srpaulo entry->array_len = ++count; 835214501Srpaulo dbus_message_iter_next(iter); 836214501Srpaulo } 837214501Srpaulo 838214501Srpaulo /* Zero-length arrays are valid. */ 839214501Srpaulo if (entry->array_len == 0) { 840214501Srpaulo os_free(entry->strarray_value); 841214501Srpaulo entry->strarray_value = NULL; 842214501Srpaulo } 843214501Srpaulo 844214501Srpaulo success = TRUE; 845214501Srpaulo 846214501Srpaulodone: 847214501Srpaulo return success; 848214501Srpaulo} 849214501Srpaulo 850214501Srpaulo 851252190Srpaulo#define BIN_ARRAY_CHUNK_SIZE 10 852252190Srpaulo#define BIN_ARRAY_ITEM_SIZE (sizeof(struct wpabuf *)) 853252190Srpaulo 854252190Srpaulostatic dbus_bool_t _wpa_dbus_dict_entry_get_binarray( 855252190Srpaulo DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry) 856252190Srpaulo{ 857252190Srpaulo struct wpa_dbus_dict_entry tmpentry; 858252190Srpaulo size_t buflen = 0; 859252190Srpaulo int i; 860252190Srpaulo 861252190Srpaulo if (dbus_message_iter_get_element_type(iter) != DBUS_TYPE_BYTE) 862252190Srpaulo return FALSE; 863252190Srpaulo 864252190Srpaulo entry->array_type = WPAS_DBUS_TYPE_BINARRAY; 865252190Srpaulo entry->array_len = 0; 866252190Srpaulo entry->binarray_value = NULL; 867252190Srpaulo 868252190Srpaulo while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) { 869252190Srpaulo DBusMessageIter iter_array; 870252190Srpaulo 871252190Srpaulo if (entry->array_len == buflen) { 872252190Srpaulo struct wpabuf **newbuf; 873252190Srpaulo 874252190Srpaulo buflen += BIN_ARRAY_CHUNK_SIZE; 875252190Srpaulo 876252190Srpaulo newbuf = os_realloc_array(entry->binarray_value, 877252190Srpaulo buflen, BIN_ARRAY_ITEM_SIZE); 878252190Srpaulo if (!newbuf) 879252190Srpaulo goto cleanup; 880252190Srpaulo entry->binarray_value = newbuf; 881252190Srpaulo } 882252190Srpaulo 883252190Srpaulo dbus_message_iter_recurse(iter, &iter_array); 884252190Srpaulo if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry) 885252190Srpaulo == FALSE) 886252190Srpaulo goto cleanup; 887252190Srpaulo 888252190Srpaulo entry->binarray_value[entry->array_len] = 889252190Srpaulo wpabuf_alloc_ext_data((u8 *) tmpentry.bytearray_value, 890252190Srpaulo tmpentry.array_len); 891252190Srpaulo if (entry->binarray_value[entry->array_len] == NULL) { 892252190Srpaulo wpa_dbus_dict_entry_clear(&tmpentry); 893252190Srpaulo goto cleanup; 894252190Srpaulo } 895252190Srpaulo entry->array_len++; 896252190Srpaulo dbus_message_iter_next(iter); 897252190Srpaulo } 898252190Srpaulo 899252190Srpaulo return TRUE; 900252190Srpaulo 901252190Srpaulo cleanup: 902252190Srpaulo for (i = 0; i < (int) entry->array_len; i++) 903252190Srpaulo wpabuf_free(entry->binarray_value[i]); 904252190Srpaulo os_free(entry->binarray_value); 905252190Srpaulo entry->array_len = 0; 906252190Srpaulo entry->binarray_value = NULL; 907252190Srpaulo return FALSE; 908252190Srpaulo} 909252190Srpaulo 910252190Srpaulo 911214501Srpaulostatic dbus_bool_t _wpa_dbus_dict_entry_get_array( 912214501Srpaulo DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry) 913214501Srpaulo{ 914214501Srpaulo int array_type = dbus_message_iter_get_element_type(iter_dict_val); 915214501Srpaulo dbus_bool_t success = FALSE; 916214501Srpaulo DBusMessageIter iter_array; 917214501Srpaulo 918214501Srpaulo if (!entry) 919214501Srpaulo return FALSE; 920214501Srpaulo 921214501Srpaulo dbus_message_iter_recurse(iter_dict_val, &iter_array); 922214501Srpaulo 923214501Srpaulo switch (array_type) { 924214501Srpaulo case DBUS_TYPE_BYTE: 925214501Srpaulo success = _wpa_dbus_dict_entry_get_byte_array(&iter_array, 926214501Srpaulo entry); 927214501Srpaulo break; 928214501Srpaulo case DBUS_TYPE_STRING: 929214501Srpaulo success = _wpa_dbus_dict_entry_get_string_array(&iter_array, 930214501Srpaulo array_type, 931214501Srpaulo entry); 932214501Srpaulo break; 933252190Srpaulo case DBUS_TYPE_ARRAY: 934252190Srpaulo success = _wpa_dbus_dict_entry_get_binarray(&iter_array, entry); 935214501Srpaulo default: 936214501Srpaulo break; 937214501Srpaulo } 938214501Srpaulo 939214501Srpaulo return success; 940214501Srpaulo} 941214501Srpaulo 942214501Srpaulo 943214501Srpaulostatic dbus_bool_t _wpa_dbus_dict_fill_value_from_variant( 944214501Srpaulo struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter) 945214501Srpaulo{ 946214501Srpaulo const char *v; 947214501Srpaulo 948214501Srpaulo switch (entry->type) { 949214501Srpaulo case DBUS_TYPE_OBJECT_PATH: 950214501Srpaulo case DBUS_TYPE_STRING: 951214501Srpaulo dbus_message_iter_get_basic(iter, &v); 952214501Srpaulo entry->str_value = os_strdup(v); 953214501Srpaulo if (entry->str_value == NULL) 954214501Srpaulo return FALSE; 955214501Srpaulo break; 956214501Srpaulo case DBUS_TYPE_BOOLEAN: 957214501Srpaulo dbus_message_iter_get_basic(iter, &entry->bool_value); 958214501Srpaulo break; 959214501Srpaulo case DBUS_TYPE_BYTE: 960214501Srpaulo dbus_message_iter_get_basic(iter, &entry->byte_value); 961214501Srpaulo break; 962214501Srpaulo case DBUS_TYPE_INT16: 963214501Srpaulo dbus_message_iter_get_basic(iter, &entry->int16_value); 964214501Srpaulo break; 965214501Srpaulo case DBUS_TYPE_UINT16: 966214501Srpaulo dbus_message_iter_get_basic(iter, &entry->uint16_value); 967214501Srpaulo break; 968214501Srpaulo case DBUS_TYPE_INT32: 969214501Srpaulo dbus_message_iter_get_basic(iter, &entry->int32_value); 970214501Srpaulo break; 971214501Srpaulo case DBUS_TYPE_UINT32: 972214501Srpaulo dbus_message_iter_get_basic(iter, &entry->uint32_value); 973214501Srpaulo break; 974214501Srpaulo case DBUS_TYPE_INT64: 975214501Srpaulo dbus_message_iter_get_basic(iter, &entry->int64_value); 976214501Srpaulo break; 977214501Srpaulo case DBUS_TYPE_UINT64: 978214501Srpaulo dbus_message_iter_get_basic(iter, &entry->uint64_value); 979214501Srpaulo break; 980214501Srpaulo case DBUS_TYPE_DOUBLE: 981214501Srpaulo dbus_message_iter_get_basic(iter, &entry->double_value); 982214501Srpaulo break; 983214501Srpaulo case DBUS_TYPE_ARRAY: 984214501Srpaulo return _wpa_dbus_dict_entry_get_array(iter, entry); 985214501Srpaulo default: 986214501Srpaulo return FALSE; 987214501Srpaulo } 988214501Srpaulo 989214501Srpaulo return TRUE; 990214501Srpaulo} 991214501Srpaulo 992214501Srpaulo 993214501Srpaulo/** 994214501Srpaulo * Read the current key/value entry from the dict. Entries are dynamically 995214501Srpaulo * allocated when needed and must be freed after use with the 996214501Srpaulo * wpa_dbus_dict_entry_clear() function. 997214501Srpaulo * 998214501Srpaulo * The returned entry object will be filled with the type and value of the next 999214501Srpaulo * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error 1000214501Srpaulo * occurred. 1001214501Srpaulo * 1002214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 1003214501Srpaulo * wpa_dbus_dict_open_read() 1004214501Srpaulo * @param entry A valid dict entry object into which the dict key and value 1005214501Srpaulo * will be placed 1006214501Srpaulo * @return TRUE on success, FALSE on failure 1007214501Srpaulo * 1008214501Srpaulo */ 1009214501Srpaulodbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict, 1010214501Srpaulo struct wpa_dbus_dict_entry * entry) 1011214501Srpaulo{ 1012214501Srpaulo DBusMessageIter iter_dict_entry, iter_dict_val; 1013214501Srpaulo int type; 1014214501Srpaulo const char *key; 1015214501Srpaulo 1016214501Srpaulo if (!iter_dict || !entry) 1017214501Srpaulo goto error; 1018214501Srpaulo 1019214501Srpaulo if (dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY) 1020214501Srpaulo goto error; 1021214501Srpaulo 1022214501Srpaulo dbus_message_iter_recurse(iter_dict, &iter_dict_entry); 1023214501Srpaulo dbus_message_iter_get_basic(&iter_dict_entry, &key); 1024214501Srpaulo entry->key = key; 1025214501Srpaulo 1026214501Srpaulo if (!dbus_message_iter_next(&iter_dict_entry)) 1027214501Srpaulo goto error; 1028214501Srpaulo type = dbus_message_iter_get_arg_type(&iter_dict_entry); 1029214501Srpaulo if (type != DBUS_TYPE_VARIANT) 1030214501Srpaulo goto error; 1031214501Srpaulo 1032214501Srpaulo dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val); 1033214501Srpaulo entry->type = dbus_message_iter_get_arg_type(&iter_dict_val); 1034214501Srpaulo if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val)) 1035214501Srpaulo goto error; 1036214501Srpaulo 1037214501Srpaulo dbus_message_iter_next(iter_dict); 1038214501Srpaulo return TRUE; 1039214501Srpaulo 1040214501Srpauloerror: 1041214501Srpaulo if (entry) { 1042214501Srpaulo wpa_dbus_dict_entry_clear(entry); 1043214501Srpaulo entry->type = DBUS_TYPE_INVALID; 1044214501Srpaulo entry->array_type = DBUS_TYPE_INVALID; 1045214501Srpaulo } 1046214501Srpaulo 1047214501Srpaulo return FALSE; 1048214501Srpaulo} 1049214501Srpaulo 1050214501Srpaulo 1051214501Srpaulo/** 1052214501Srpaulo * Return whether or not there are additional dictionary entries. 1053214501Srpaulo * 1054214501Srpaulo * @param iter_dict A valid DBusMessageIter returned from 1055214501Srpaulo * wpa_dbus_dict_open_read() 1056214501Srpaulo * @return TRUE if more dict entries exists, FALSE if no more dict entries 1057214501Srpaulo * exist 1058214501Srpaulo */ 1059214501Srpaulodbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict) 1060214501Srpaulo{ 1061214501Srpaulo if (!iter_dict) 1062214501Srpaulo return FALSE; 1063214501Srpaulo return dbus_message_iter_get_arg_type(iter_dict) == 1064214501Srpaulo DBUS_TYPE_DICT_ENTRY; 1065214501Srpaulo} 1066214501Srpaulo 1067214501Srpaulo 1068214501Srpaulo/** 1069214501Srpaulo * Free any memory used by the entry object. 1070214501Srpaulo * 1071214501Srpaulo * @param entry The entry object 1072214501Srpaulo */ 1073214501Srpaulovoid wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry) 1074214501Srpaulo{ 1075214501Srpaulo unsigned int i; 1076214501Srpaulo 1077214501Srpaulo if (!entry) 1078214501Srpaulo return; 1079214501Srpaulo switch (entry->type) { 1080214501Srpaulo case DBUS_TYPE_OBJECT_PATH: 1081214501Srpaulo case DBUS_TYPE_STRING: 1082214501Srpaulo os_free(entry->str_value); 1083214501Srpaulo break; 1084214501Srpaulo case DBUS_TYPE_ARRAY: 1085214501Srpaulo switch (entry->array_type) { 1086214501Srpaulo case DBUS_TYPE_BYTE: 1087214501Srpaulo os_free(entry->bytearray_value); 1088214501Srpaulo break; 1089214501Srpaulo case DBUS_TYPE_STRING: 1090214501Srpaulo for (i = 0; i < entry->array_len; i++) 1091214501Srpaulo os_free(entry->strarray_value[i]); 1092214501Srpaulo os_free(entry->strarray_value); 1093214501Srpaulo break; 1094252190Srpaulo case WPAS_DBUS_TYPE_BINARRAY: 1095252190Srpaulo for (i = 0; i < entry->array_len; i++) 1096252190Srpaulo wpabuf_free(entry->binarray_value[i]); 1097252190Srpaulo os_free(entry->binarray_value); 1098252190Srpaulo break; 1099214501Srpaulo } 1100214501Srpaulo break; 1101214501Srpaulo } 1102214501Srpaulo 1103252190Srpaulo os_memset(entry, 0, sizeof(struct wpa_dbus_dict_entry)); 1104214501Srpaulo} 1105