Home | History | Annotate | Download | only in wifi_hal
      1 
      2 #include <stdint.h>
      3 #include <fcntl.h>
      4 #include <sys/socket.h>
      5 #include <netlink/genl/genl.h>
      6 #include <netlink/genl/family.h>
      7 #include <netlink/genl/ctrl.h>
      8 #include <linux/rtnetlink.h>
      9 #include <netpacket/packet.h>
     10 #include <linux/filter.h>
     11 #include <linux/errqueue.h>
     12 
     13 #include <linux/pkt_sched.h>
     14 #include <netlink/object-api.h>
     15 #include <netlink/netlink.h>
     16 #include <netlink/socket.h>
     17 #include <netlink/handlers.h>
     18 
     19 #include <ctype.h>
     20 
     21 #include "wifi_hal.h"
     22 #include "common.h"
     23 #include "cpp_bindings.h"
     24 
     25 void appendFmt(char *buf, int &offset, const char *fmt, ...)
     26 {
     27     va_list params;
     28     va_start(params, fmt);
     29     offset += vsprintf(buf + offset, fmt, params);
     30     va_end(params);
     31 }
     32 
     33 #define C2S(x)  case x: return #x;
     34 
     35 static const char *cmdToString(int cmd)
     36 {
     37 	switch (cmd) {
     38 	C2S(NL80211_CMD_UNSPEC)
     39 	C2S(NL80211_CMD_GET_WIPHY)
     40 	C2S(NL80211_CMD_SET_WIPHY)
     41 	C2S(NL80211_CMD_NEW_WIPHY)
     42 	C2S(NL80211_CMD_DEL_WIPHY)
     43 	C2S(NL80211_CMD_GET_INTERFACE)
     44 	C2S(NL80211_CMD_SET_INTERFACE)
     45 	C2S(NL80211_CMD_NEW_INTERFACE)
     46 	C2S(NL80211_CMD_DEL_INTERFACE)
     47 	C2S(NL80211_CMD_GET_KEY)
     48 	C2S(NL80211_CMD_SET_KEY)
     49 	C2S(NL80211_CMD_NEW_KEY)
     50 	C2S(NL80211_CMD_DEL_KEY)
     51 	C2S(NL80211_CMD_GET_BEACON)
     52 	C2S(NL80211_CMD_SET_BEACON)
     53 	C2S(NL80211_CMD_START_AP)
     54 	C2S(NL80211_CMD_STOP_AP)
     55 	C2S(NL80211_CMD_GET_STATION)
     56 	C2S(NL80211_CMD_SET_STATION)
     57 	C2S(NL80211_CMD_NEW_STATION)
     58 	C2S(NL80211_CMD_DEL_STATION)
     59 	C2S(NL80211_CMD_GET_MPATH)
     60 	C2S(NL80211_CMD_SET_MPATH)
     61 	C2S(NL80211_CMD_NEW_MPATH)
     62 	C2S(NL80211_CMD_DEL_MPATH)
     63 	C2S(NL80211_CMD_SET_BSS)
     64 	C2S(NL80211_CMD_SET_REG)
     65 	C2S(NL80211_CMD_REQ_SET_REG)
     66 	C2S(NL80211_CMD_GET_MESH_CONFIG)
     67 	C2S(NL80211_CMD_SET_MESH_CONFIG)
     68 	C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
     69 	C2S(NL80211_CMD_GET_REG)
     70 	C2S(NL80211_CMD_GET_SCAN)
     71 	C2S(NL80211_CMD_TRIGGER_SCAN)
     72 	C2S(NL80211_CMD_NEW_SCAN_RESULTS)
     73 	C2S(NL80211_CMD_SCAN_ABORTED)
     74 	C2S(NL80211_CMD_REG_CHANGE)
     75 	C2S(NL80211_CMD_AUTHENTICATE)
     76 	C2S(NL80211_CMD_ASSOCIATE)
     77 	C2S(NL80211_CMD_DEAUTHENTICATE)
     78 	C2S(NL80211_CMD_DISASSOCIATE)
     79 	C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
     80 	C2S(NL80211_CMD_REG_BEACON_HINT)
     81 	C2S(NL80211_CMD_JOIN_IBSS)
     82 	C2S(NL80211_CMD_LEAVE_IBSS)
     83 	C2S(NL80211_CMD_TESTMODE)
     84 	C2S(NL80211_CMD_CONNECT)
     85 	C2S(NL80211_CMD_ROAM)
     86 	C2S(NL80211_CMD_DISCONNECT)
     87 	C2S(NL80211_CMD_SET_WIPHY_NETNS)
     88 	C2S(NL80211_CMD_GET_SURVEY)
     89 	C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
     90 	C2S(NL80211_CMD_SET_PMKSA)
     91 	C2S(NL80211_CMD_DEL_PMKSA)
     92 	C2S(NL80211_CMD_FLUSH_PMKSA)
     93 	C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
     94 	C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
     95 	C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
     96 	C2S(NL80211_CMD_REGISTER_FRAME)
     97 	C2S(NL80211_CMD_FRAME)
     98 	C2S(NL80211_CMD_FRAME_TX_STATUS)
     99 	C2S(NL80211_CMD_SET_POWER_SAVE)
    100 	C2S(NL80211_CMD_GET_POWER_SAVE)
    101 	C2S(NL80211_CMD_SET_CQM)
    102 	C2S(NL80211_CMD_NOTIFY_CQM)
    103 	C2S(NL80211_CMD_SET_CHANNEL)
    104 	C2S(NL80211_CMD_SET_WDS_PEER)
    105 	C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
    106 	C2S(NL80211_CMD_JOIN_MESH)
    107 	C2S(NL80211_CMD_LEAVE_MESH)
    108 	C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
    109 	C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
    110 	C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
    111 	C2S(NL80211_CMD_GET_WOWLAN)
    112 	C2S(NL80211_CMD_SET_WOWLAN)
    113 	C2S(NL80211_CMD_START_SCHED_SCAN)
    114 	C2S(NL80211_CMD_STOP_SCHED_SCAN)
    115 	C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
    116 	C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
    117 	C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
    118 	C2S(NL80211_CMD_PMKSA_CANDIDATE)
    119 	C2S(NL80211_CMD_TDLS_OPER)
    120 	C2S(NL80211_CMD_TDLS_MGMT)
    121 	C2S(NL80211_CMD_UNEXPECTED_FRAME)
    122 	C2S(NL80211_CMD_PROBE_CLIENT)
    123 	C2S(NL80211_CMD_REGISTER_BEACONS)
    124 	C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
    125 	C2S(NL80211_CMD_SET_NOACK_MAP)
    126 	C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
    127 	C2S(NL80211_CMD_START_P2P_DEVICE)
    128 	C2S(NL80211_CMD_STOP_P2P_DEVICE)
    129 	C2S(NL80211_CMD_CONN_FAILED)
    130 	C2S(NL80211_CMD_SET_MCAST_RATE)
    131 	C2S(NL80211_CMD_SET_MAC_ACL)
    132 	C2S(NL80211_CMD_RADAR_DETECT)
    133 	C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
    134 	C2S(NL80211_CMD_UPDATE_FT_IES)
    135 	C2S(NL80211_CMD_FT_EVENT)
    136 	C2S(NL80211_CMD_CRIT_PROTOCOL_START)
    137 	C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
    138 	C2S(NL80211_CMD_GET_COALESCE)
    139 	C2S(NL80211_CMD_SET_COALESCE)
    140 	C2S(NL80211_CMD_CHANNEL_SWITCH)
    141 	C2S(NL80211_CMD_VENDOR)
    142 	C2S(NL80211_CMD_SET_QOS_MAP)
    143 	default:
    144 		return "NL80211_CMD_UNKNOWN";
    145 	}
    146 }
    147 
    148 const char *attributeToString(int attribute)
    149 {
    150     switch (attribute) {
    151 	C2S(NL80211_ATTR_UNSPEC)
    152 
    153 	C2S(NL80211_ATTR_WIPHY)
    154 	C2S(NL80211_ATTR_WIPHY_NAME)
    155 
    156 	C2S(NL80211_ATTR_IFINDEX)
    157 	C2S(NL80211_ATTR_IFNAME)
    158 	C2S(NL80211_ATTR_IFTYPE)
    159 
    160 	C2S(NL80211_ATTR_MAC)
    161 
    162 	C2S(NL80211_ATTR_KEY_DATA)
    163 	C2S(NL80211_ATTR_KEY_IDX)
    164 	C2S(NL80211_ATTR_KEY_CIPHER)
    165 	C2S(NL80211_ATTR_KEY_SEQ)
    166 	C2S(NL80211_ATTR_KEY_DEFAULT)
    167 
    168 	C2S(NL80211_ATTR_BEACON_INTERVAL)
    169 	C2S(NL80211_ATTR_DTIM_PERIOD)
    170 	C2S(NL80211_ATTR_BEACON_HEAD)
    171 	C2S(NL80211_ATTR_BEACON_TAIL)
    172 
    173 	C2S(NL80211_ATTR_STA_AID)
    174 	C2S(NL80211_ATTR_STA_FLAGS)
    175 	C2S(NL80211_ATTR_STA_LISTEN_INTERVAL)
    176 	C2S(NL80211_ATTR_STA_SUPPORTED_RATES)
    177 	C2S(NL80211_ATTR_STA_VLAN)
    178 	C2S(NL80211_ATTR_STA_INFO)
    179 
    180 	C2S(NL80211_ATTR_WIPHY_BANDS)
    181 
    182 	C2S(NL80211_ATTR_MNTR_FLAGS)
    183 
    184 	C2S(NL80211_ATTR_MESH_ID)
    185 	C2S(NL80211_ATTR_STA_PLINK_ACTION)
    186 	C2S(NL80211_ATTR_MPATH_NEXT_HOP)
    187 	C2S(NL80211_ATTR_MPATH_INFO)
    188 
    189 	C2S(NL80211_ATTR_BSS_CTS_PROT)
    190 	C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE)
    191 	C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME)
    192 
    193 	C2S(NL80211_ATTR_HT_CAPABILITY)
    194 
    195 	C2S(NL80211_ATTR_SUPPORTED_IFTYPES)
    196 
    197 	C2S(NL80211_ATTR_REG_ALPHA2)
    198 	C2S(NL80211_ATTR_REG_RULES)
    199 
    200 	C2S(NL80211_ATTR_MESH_CONFIG)
    201 
    202 	C2S(NL80211_ATTR_BSS_BASIC_RATES)
    203 
    204 	C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS)
    205 	C2S(NL80211_ATTR_WIPHY_FREQ)
    206 	C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE)
    207 
    208 	C2S(NL80211_ATTR_KEY_DEFAULT_MGMT)
    209 
    210 	C2S(NL80211_ATTR_MGMT_SUBTYPE)
    211 	C2S(NL80211_ATTR_IE)
    212 
    213 	C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS)
    214 
    215 	C2S(NL80211_ATTR_SCAN_FREQUENCIES)
    216 	C2S(NL80211_ATTR_SCAN_SSIDS)
    217 	C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */
    218 	C2S(NL80211_ATTR_BSS)
    219 
    220 	C2S(NL80211_ATTR_REG_INITIATOR)
    221 	C2S(NL80211_ATTR_REG_TYPE)
    222 
    223 	C2S(NL80211_ATTR_SUPPORTED_COMMANDS)
    224 
    225 	C2S(NL80211_ATTR_FRAME)
    226 	C2S(NL80211_ATTR_SSID)
    227 	C2S(NL80211_ATTR_AUTH_TYPE)
    228 	C2S(NL80211_ATTR_REASON_CODE)
    229 
    230 	C2S(NL80211_ATTR_KEY_TYPE)
    231 
    232 	C2S(NL80211_ATTR_MAX_SCAN_IE_LEN)
    233 	C2S(NL80211_ATTR_CIPHER_SUITES)
    234 
    235 	C2S(NL80211_ATTR_FREQ_BEFORE)
    236 	C2S(NL80211_ATTR_FREQ_AFTER)
    237 
    238 	C2S(NL80211_ATTR_FREQ_FIXED)
    239 
    240 
    241 	C2S(NL80211_ATTR_WIPHY_RETRY_SHORT)
    242 	C2S(NL80211_ATTR_WIPHY_RETRY_LONG)
    243 	C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD)
    244 	C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD)
    245 
    246 	C2S(NL80211_ATTR_TIMED_OUT)
    247 
    248 	C2S(NL80211_ATTR_USE_MFP)
    249 
    250 	C2S(NL80211_ATTR_STA_FLAGS2)
    251 
    252 	C2S(NL80211_ATTR_CONTROL_PORT)
    253 
    254 	C2S(NL80211_ATTR_TESTDATA)
    255 
    256 	C2S(NL80211_ATTR_PRIVACY)
    257 
    258 	C2S(NL80211_ATTR_DISCONNECTED_BY_AP)
    259 	C2S(NL80211_ATTR_STATUS_CODE)
    260 
    261 	C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE)
    262 	C2S(NL80211_ATTR_CIPHER_SUITE_GROUP)
    263 	C2S(NL80211_ATTR_WPA_VERSIONS)
    264 	C2S(NL80211_ATTR_AKM_SUITES)
    265 
    266 	C2S(NL80211_ATTR_REQ_IE)
    267 	C2S(NL80211_ATTR_RESP_IE)
    268 
    269 	C2S(NL80211_ATTR_PREV_BSSID)
    270 
    271 	C2S(NL80211_ATTR_KEY)
    272 	C2S(NL80211_ATTR_KEYS)
    273 
    274 	C2S(NL80211_ATTR_PID)
    275 
    276 	C2S(NL80211_ATTR_4ADDR)
    277 
    278 	C2S(NL80211_ATTR_SURVEY_INFO)
    279 
    280 	C2S(NL80211_ATTR_PMKID)
    281 	C2S(NL80211_ATTR_MAX_NUM_PMKIDS)
    282 
    283 	C2S(NL80211_ATTR_DURATION)
    284 
    285 	C2S(NL80211_ATTR_COOKIE)
    286 
    287 	C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS)
    288 
    289 	C2S(NL80211_ATTR_TX_RATES)
    290 
    291 	C2S(NL80211_ATTR_FRAME_MATCH)
    292 
    293 	C2S(NL80211_ATTR_ACK)
    294 
    295 	C2S(NL80211_ATTR_PS_STATE)
    296 
    297 	C2S(NL80211_ATTR_CQM)
    298 
    299 	C2S(NL80211_ATTR_LOCAL_STATE_CHANGE)
    300 
    301 	C2S(NL80211_ATTR_AP_ISOLATE)
    302 
    303 	C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING)
    304 	C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL)
    305 
    306 	C2S(NL80211_ATTR_TX_FRAME_TYPES)
    307 	C2S(NL80211_ATTR_RX_FRAME_TYPES)
    308 	C2S(NL80211_ATTR_FRAME_TYPE)
    309 
    310 	C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
    311 	C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)
    312 
    313 	C2S(NL80211_ATTR_SUPPORT_IBSS_RSN)
    314 
    315 	C2S(NL80211_ATTR_WIPHY_ANTENNA_TX)
    316 	C2S(NL80211_ATTR_WIPHY_ANTENNA_RX)
    317 
    318 	C2S(NL80211_ATTR_MCAST_RATE)
    319 
    320 	C2S(NL80211_ATTR_OFFCHANNEL_TX_OK)
    321 
    322 	C2S(NL80211_ATTR_BSS_HT_OPMODE)
    323 
    324 	C2S(NL80211_ATTR_KEY_DEFAULT_TYPES)
    325 
    326 	C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION)
    327 
    328 	C2S(NL80211_ATTR_MESH_SETUP)
    329 
    330 	C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX)
    331 	C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX)
    332 
    333 	C2S(NL80211_ATTR_SUPPORT_MESH_AUTH)
    334 	C2S(NL80211_ATTR_STA_PLINK_STATE)
    335 
    336 	C2S(NL80211_ATTR_WOWLAN_TRIGGERS)
    337 	C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED)
    338 
    339 	C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL)
    340 
    341 	C2S(NL80211_ATTR_INTERFACE_COMBINATIONS)
    342 	C2S(NL80211_ATTR_SOFTWARE_IFTYPES)
    343 
    344 	C2S(NL80211_ATTR_REKEY_DATA)
    345 
    346 	C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS)
    347 	C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN)
    348 
    349 	C2S(NL80211_ATTR_SCAN_SUPP_RATES)
    350 
    351 	C2S(NL80211_ATTR_HIDDEN_SSID)
    352 
    353 	C2S(NL80211_ATTR_IE_PROBE_RESP)
    354 	C2S(NL80211_ATTR_IE_ASSOC_RESP)
    355 
    356 	C2S(NL80211_ATTR_STA_WME)
    357 	C2S(NL80211_ATTR_SUPPORT_AP_UAPSD)
    358 
    359 	C2S(NL80211_ATTR_ROAM_SUPPORT)
    360 
    361 	C2S(NL80211_ATTR_SCHED_SCAN_MATCH)
    362 	C2S(NL80211_ATTR_MAX_MATCH_SETS)
    363 
    364 	C2S(NL80211_ATTR_PMKSA_CANDIDATE)
    365 
    366 	C2S(NL80211_ATTR_TX_NO_CCK_RATE)
    367 
    368 	C2S(NL80211_ATTR_TDLS_ACTION)
    369 	C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN)
    370 	C2S(NL80211_ATTR_TDLS_OPERATION)
    371 	C2S(NL80211_ATTR_TDLS_SUPPORT)
    372 	C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP)
    373 
    374 	C2S(NL80211_ATTR_DEVICE_AP_SME)
    375 
    376 	C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK)
    377 
    378 	C2S(NL80211_ATTR_FEATURE_FLAGS)
    379 
    380 	C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD)
    381 
    382 	C2S(NL80211_ATTR_PROBE_RESP)
    383 
    384 	C2S(NL80211_ATTR_DFS_REGION)
    385 
    386 	C2S(NL80211_ATTR_DISABLE_HT)
    387 	C2S(NL80211_ATTR_HT_CAPABILITY_MASK)
    388 
    389 	C2S(NL80211_ATTR_NOACK_MAP)
    390 
    391 	C2S(NL80211_ATTR_INACTIVITY_TIMEOUT)
    392 
    393 	C2S(NL80211_ATTR_RX_SIGNAL_DBM)
    394 
    395 	C2S(NL80211_ATTR_BG_SCAN_PERIOD)
    396 
    397 	C2S(NL80211_ATTR_WDEV)
    398 
    399 	C2S(NL80211_ATTR_USER_REG_HINT_TYPE)
    400 
    401 	C2S(NL80211_ATTR_CONN_FAILED_REASON)
    402 
    403 	C2S(NL80211_ATTR_SAE_DATA)
    404 
    405 	C2S(NL80211_ATTR_VHT_CAPABILITY)
    406 
    407 	C2S(NL80211_ATTR_SCAN_FLAGS)
    408 
    409 	C2S(NL80211_ATTR_CHANNEL_WIDTH)
    410 	C2S(NL80211_ATTR_CENTER_FREQ1)
    411 	C2S(NL80211_ATTR_CENTER_FREQ2)
    412 
    413 	C2S(NL80211_ATTR_P2P_CTWINDOW)
    414 	C2S(NL80211_ATTR_P2P_OPPPS)
    415 
    416 	C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE)
    417 
    418 	C2S(NL80211_ATTR_ACL_POLICY)
    419 
    420 	C2S(NL80211_ATTR_MAC_ADDRS)
    421 
    422 	C2S(NL80211_ATTR_MAC_ACL_MAX)
    423 
    424 	C2S(NL80211_ATTR_RADAR_EVENT)
    425 
    426 	C2S(NL80211_ATTR_EXT_CAPA)
    427 	C2S(NL80211_ATTR_EXT_CAPA_MASK)
    428 
    429 	C2S(NL80211_ATTR_STA_CAPABILITY)
    430 	C2S(NL80211_ATTR_STA_EXT_CAPABILITY)
    431 
    432 	C2S(NL80211_ATTR_PROTOCOL_FEATURES)
    433 	C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP)
    434 
    435 	C2S(NL80211_ATTR_DISABLE_VHT)
    436 	C2S(NL80211_ATTR_VHT_CAPABILITY_MASK)
    437 
    438 	C2S(NL80211_ATTR_MDID)
    439 	C2S(NL80211_ATTR_IE_RIC)
    440 
    441 	C2S(NL80211_ATTR_CRIT_PROT_ID)
    442 	C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION)
    443 
    444 	C2S(NL80211_ATTR_PEER_AID)
    445 
    446 	C2S(NL80211_ATTR_COALESCE_RULE)
    447 
    448 	C2S(NL80211_ATTR_CH_SWITCH_COUNT)
    449 	C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX)
    450 	C2S(NL80211_ATTR_CSA_IES)
    451 	C2S(NL80211_ATTR_CSA_C_OFF_BEACON)
    452 	C2S(NL80211_ATTR_CSA_C_OFF_PRESP)
    453 
    454 	C2S(NL80211_ATTR_RXMGMT_FLAGS)
    455 
    456 	C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS)
    457 
    458 	C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES)
    459 
    460 	C2S(NL80211_ATTR_HANDLE_DFS)
    461 
    462 	C2S(NL80211_ATTR_SUPPORT_5_MHZ)
    463 	C2S(NL80211_ATTR_SUPPORT_10_MHZ)
    464 
    465 	C2S(NL80211_ATTR_OPMODE_NOTIF)
    466 
    467 	C2S(NL80211_ATTR_VENDOR_ID)
    468 	C2S(NL80211_ATTR_VENDOR_SUBCMD)
    469 	C2S(NL80211_ATTR_VENDOR_DATA)
    470 	C2S(NL80211_ATTR_VENDOR_EVENTS)
    471 
    472 	C2S(NL80211_ATTR_QOS_MAP)
    473     default:
    474         return "NL80211_ATTR_UNKNOWN";
    475     }
    476 }
    477 
    478 void WifiEvent::log() {
    479     parse();
    480 
    481     byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
    482     int len = genlmsg_attrlen(mHeader, 0);
    483     ALOGD("cmd = %s, len = %d", get_cmdString(), len);
    484     ALOGD("vendor_id = %04x, vendor_subcmd = %d", get_vendor_id(), get_vendor_subcmd());
    485 
    486     for (int i = 0; i < len; i += 16) {
    487         char line[81];
    488         int linelen = min(16, len - i);
    489         int offset = 0;
    490         appendFmt(line, offset, "%02x", data[i]);
    491         for (int j = 1; j < linelen; j++) {
    492             appendFmt(line, offset, " %02x", data[i+j]);
    493         }
    494 
    495         for (int j = linelen; j < 16; j++) {
    496             appendFmt(line, offset, "   ");
    497         }
    498 
    499         line[23] = '-';
    500 
    501         appendFmt(line, offset, "  ");
    502 
    503         for (int j = 0; j < linelen; j++) {
    504             if (isprint(data[i+j])) {
    505                 appendFmt(line, offset, "%c", data[i+j]);
    506             } else {
    507                 appendFmt(line, offset, "-");
    508             }
    509         }
    510 
    511         ALOGD("%s", line);
    512     }
    513 
    514     for (unsigned i = 0; i < NL80211_ATTR_MAX_INTERNAL; i++) {
    515         if (mAttributes[i] != NULL) {
    516             ALOGD("found attribute %s", attributeToString(i));
    517         }
    518     }
    519 
    520     ALOGD("-- End of message --");
    521 }
    522 
    523 const char *WifiEvent::get_cmdString() {
    524     return cmdToString(get_cmd());
    525 }
    526 
    527 
    528 int WifiEvent::parse() {
    529     if (mHeader != NULL) {
    530         return WIFI_SUCCESS;
    531     }
    532     mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
    533     int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
    534           genlmsg_attrlen(mHeader, 0), NULL);
    535 
    536     // ALOGD("event len = %d", nlmsg_hdr(mMsg)->nlmsg_len);
    537     return result;
    538 }
    539 
    540 int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
    541     mMsg = nlmsg_alloc();
    542     if (mMsg != NULL) {
    543         genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
    544                 hdrlen, flags, cmd, /* version = */ 0);
    545         return WIFI_SUCCESS;
    546     } else {
    547         return WIFI_ERROR_OUT_OF_MEMORY;
    548     }
    549 }
    550 
    551 int WifiRequest::create(uint32_t id, int subcmd) {
    552     int res = create(NL80211_CMD_VENDOR);
    553     if (res < 0) {
    554         return res;
    555     }
    556 
    557     res = put_u32(NL80211_ATTR_VENDOR_ID, id);
    558     if (res < 0) {
    559         return res;
    560     }
    561 
    562     res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
    563     if (res < 0) {
    564         return res;
    565     }
    566 
    567     if (mIface != -1) {
    568         res = set_iface_id(mIface);
    569     }
    570 
    571     return res;
    572 }
    573 
    574 
    575 static int no_seq_check(struct nl_msg *msg, void *arg)
    576 {
    577 	return NL_OK;
    578 }
    579 
    580 int WifiCommand::requestResponse() {
    581     int err = create();                 /* create the message */
    582     if (err < 0) {
    583         return err;
    584     }
    585 
    586     return requestResponse(mMsg);
    587 }
    588 
    589 int WifiCommand::requestResponse(WifiRequest& request) {
    590     int err = 0;
    591 
    592     struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
    593     if (!cb)
    594         goto out;
    595 
    596     err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage());    /* send message */
    597     if (err < 0)
    598         goto out;
    599 
    600     err = 1;
    601 
    602     nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
    603     nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
    604     nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
    605     nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
    606     nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
    607 
    608     while (err > 0) {                   /* wait for reply */
    609         int res = nl_recvmsgs(mInfo->cmd_sock, cb);
    610         if (res) {
    611             ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
    612         }
    613     }
    614 out:
    615     nl_cb_put(cb);
    616     return err;
    617 }
    618 
    619 int WifiCommand::requestEvent(int cmd) {
    620 
    621     ALOGD("requesting event %d", cmd);
    622 
    623     int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
    624     if (res < 0) {
    625         return res;
    626     }
    627 
    628     res = create();                                                 /* create the message */
    629     if (res < 0)
    630         goto out;
    631 
    632     ALOGD("waiting for response %d", cmd);
    633 
    634     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
    635     if (res < 0)
    636         goto out;
    637 
    638     ALOGD("waiting for event %d", cmd);
    639     res = mCondition.wait();
    640     if (res < 0)
    641         goto out;
    642 
    643 out:
    644     wifi_unregister_handler(wifiHandle(), cmd);
    645     return res;
    646 }
    647 
    648 int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
    649 
    650     int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
    651     if (res < 0) {
    652         return res;
    653     }
    654 
    655     res = create();                                                 /* create the message */
    656     if (res < 0)
    657         goto out;
    658 
    659     res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage());    /* send message */
    660     if (res < 0)
    661         goto out;
    662 
    663     res = mCondition.wait();
    664     if (res < 0)
    665         goto out;
    666 
    667 out:
    668     wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
    669     return res;
    670 }
    671 
    672 /* Event handlers */
    673 int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
    674     // ALOGD("response_handler called");
    675     WifiCommand *cmd = (WifiCommand *)arg;
    676     WifiEvent reply(msg);
    677     int res = reply.parse();
    678     if (res < 0) {
    679         ALOGE("Failed to parse reply message = %d", res);
    680         return NL_SKIP;
    681     } else {
    682         // reply.log();
    683         return cmd->handleResponse(reply);
    684     }
    685 }
    686 
    687 int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
    688     WifiCommand *cmd = (WifiCommand *)arg;
    689     WifiEvent event(msg);
    690     int res = event.parse();
    691     if (res < 0) {
    692         ALOGE("Failed to parse event = %d", res);
    693         res = NL_SKIP;
    694     } else {
    695         res = cmd->handleEvent(event);
    696     }
    697 
    698     cmd->mCondition.signal();
    699     return res;
    700 }
    701 
    702 /* Other event handlers */
    703 int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
    704     // ALOGD("valid_handler called");
    705     int *err = (int *)arg;
    706     *err = 0;
    707     return NL_SKIP;
    708 }
    709 
    710 int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
    711     // ALOGD("ack_handler called");
    712     int *err = (int *)arg;
    713     *err = 0;
    714     return NL_STOP;
    715 }
    716 
    717 int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
    718     // ALOGD("finish_handler called");
    719     int *ret = (int *)arg;
    720     *ret = 0;
    721     return NL_SKIP;
    722 }
    723 
    724 int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
    725     int *ret = (int *)arg;
    726     *ret = err->error;
    727 
    728     // ALOGD("error_handler received : %d", err->error);
    729     return NL_SKIP;
    730 }
    731