1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16#ifndef __WIFI_HAL_CPP_BINDINGS_H__ 17#define __WIFI_HAL_CPP_BINDINGS_H__ 18 19#include "wifi_hal.h" 20#include "common.h" 21#include "sync.h" 22 23class WifiEvent 24{ 25 /* TODO: remove this when nl headers are updated */ 26 static const unsigned NL80211_ATTR_MAX_INTERNAL = 256; 27private: 28 struct nl_msg *mMsg; 29 struct genlmsghdr *mHeader; 30 struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1]; 31 32public: 33 WifiEvent(nl_msg *msg) { 34 mMsg = msg; 35 mHeader = NULL; 36 memset(mAttributes, 0, sizeof(mAttributes)); 37 } 38 ~WifiEvent() { 39 /* don't destroy mMsg; it doesn't belong to us */ 40 } 41 42 void log(); 43 44 int parse(); 45 46 genlmsghdr *header() { 47 return mHeader; 48 } 49 50 int get_cmd() { 51 return mHeader->cmd; 52 } 53 54 int get_vendor_id() { 55 return get_u32(NL80211_ATTR_VENDOR_ID); 56 } 57 58 int get_vendor_subcmd() { 59 return get_u32(NL80211_ATTR_VENDOR_SUBCMD); 60 } 61 62 void *get_vendor_data() { 63 return get_data(NL80211_ATTR_VENDOR_DATA); 64 } 65 66 int get_vendor_data_len() { 67 return get_len(NL80211_ATTR_VENDOR_DATA); 68 } 69 70 const char *get_cmdString(); 71 72 nlattr ** attributes() { 73 return mAttributes; 74 } 75 76 nlattr *get_attribute(int attribute) { 77 return mAttributes[attribute]; 78 } 79 80 uint8_t get_u8(int attribute) { 81 return mAttributes[attribute] ? nla_get_u8(mAttributes[attribute]) : 0; 82 } 83 84 uint16_t get_u16(int attribute) { 85 return mAttributes[attribute] ? nla_get_u16(mAttributes[attribute]) : 0; 86 } 87 88 uint32_t get_u32(int attribute) { 89 return mAttributes[attribute] ? nla_get_u32(mAttributes[attribute]) : 0; 90 } 91 92 uint64_t get_u64(int attribute) { 93 return mAttributes[attribute] ? nla_get_u64(mAttributes[attribute]) : 0; 94 } 95 96 int get_len(int attribute) { 97 return mAttributes[attribute] ? nla_len(mAttributes[attribute]) : 0; 98 } 99 100 void *get_data(int attribute) { 101 return mAttributes[attribute] ? nla_data(mAttributes[attribute]) : NULL; 102 } 103 104private: 105 WifiEvent(const WifiEvent&); // hide copy constructor to prevent copies 106}; 107 108class nl_iterator { 109 struct nlattr *pos; 110 int rem; 111public: 112 nl_iterator(struct nlattr *attr) { 113 pos = (struct nlattr *)nla_data(attr); 114 rem = nla_len(attr); 115 } 116 bool has_next() { 117 return nla_ok(pos, rem); 118 } 119 void next() { 120 pos = (struct nlattr *)nla_next(pos, &(rem)); 121 } 122 struct nlattr *get() { 123 return pos; 124 } 125 uint16_t get_type() { 126 return pos->nla_type; 127 } 128 uint8_t get_u8() { 129 return nla_get_u8(pos); 130 } 131 uint16_t get_u16() { 132 return nla_get_u16(pos); 133 } 134 uint32_t get_u32() { 135 return nla_get_u32(pos); 136 } 137 uint64_t get_u64() { 138 return nla_get_u64(pos); 139 } 140 void* get_data() { 141 return nla_data(pos); 142 } 143 int get_len() { 144 return nla_len(pos); 145 } 146private: 147 nl_iterator(const nl_iterator&); // hide copy constructor to prevent copies 148}; 149 150class WifiRequest 151{ 152private: 153 int mFamily; 154 int mIface; 155 struct nl_msg *mMsg; 156 157public: 158 WifiRequest(int family) { 159 mMsg = NULL; 160 mFamily = family; 161 mIface = -1; 162 } 163 164 WifiRequest(int family, int iface) { 165 mMsg = NULL; 166 mFamily = family; 167 mIface = iface; 168 } 169 170 ~WifiRequest() { 171 destroy(); 172 } 173 174 void destroy() { 175 if (mMsg) { 176 nlmsg_free(mMsg); 177 mMsg = NULL; 178 } 179 } 180 181 nl_msg *getMessage() { 182 return mMsg; 183 } 184 185 /* Command assembly helpers */ 186 wifi_error create(int family, uint8_t cmd, int flags, int hdrlen); 187 wifi_error create(uint8_t cmd, int flags, int hdrlen) { 188 return create(mFamily, cmd, flags, hdrlen); 189 } 190 wifi_error create(uint8_t cmd) { 191 return create(mFamily, cmd, 0, 0); 192 } 193 194 wifi_error create(uint32_t id, int subcmd); 195 196 wifi_error wifi_nla_put(struct nl_msg *msg, int attr, 197 int attrlen, const void *data) 198 { 199 int status; 200 201 status = nla_put(msg, attr, attrlen, data); 202 if (status < 0) 203 ALOGE("Failed to put attr with size = %d, type = %d, error = %d", 204 attrlen, attr, status); 205 return mapKernelErrortoWifiHalError(status); 206 } 207 wifi_error put_u8(int attribute, uint8_t value) { 208 return wifi_nla_put(mMsg, attribute, sizeof(value), &value); 209 } 210 wifi_error put_u16(int attribute, uint16_t value) { 211 return wifi_nla_put(mMsg, attribute, sizeof(value), &value); 212 } 213 wifi_error put_u32(int attribute, uint32_t value) { 214 return wifi_nla_put(mMsg, attribute, sizeof(value), &value); 215 } 216 217 wifi_error put_u64(int attribute, uint64_t value) { 218 return wifi_nla_put(mMsg, attribute, sizeof(value), &value); 219 } 220 221 wifi_error put_s8(int attribute, s8 value) { 222 return wifi_nla_put(mMsg, attribute, sizeof(int8_t), &value); 223 } 224 wifi_error put_s16(int attribute, s16 value) { 225 return wifi_nla_put(mMsg, attribute, sizeof(int16_t), &value); 226 } 227 wifi_error put_s32(int attribute, s32 value) { 228 return wifi_nla_put(mMsg, attribute, sizeof(int32_t), &value); 229 } 230 wifi_error put_s64(int attribute, s64 value) { 231 return wifi_nla_put(mMsg, attribute, sizeof(int64_t), &value); 232 } 233 wifi_error put_flag(int attribute) { 234 int status; 235 236 status = nla_put_flag(mMsg, attribute); 237 if(status < 0) 238 ALOGE("Failed to put flag attr of type = %d, error = %d", 239 attribute, status); 240 return mapKernelErrortoWifiHalError(status); 241 } 242 243 u8 get_u8(const struct nlattr *nla) 244 { 245 return *(u8 *) nla_data(nla); 246 } 247 u16 get_u16(const struct nlattr *nla) 248 { 249 return *(u16 *) nla_data(nla); 250 } 251 u32 get_u32(const struct nlattr *nla) 252 { 253 return *(u32 *) nla_data(nla); 254 } 255 u64 get_u64(const struct nlattr *nla) 256 { 257 return *(u64 *) nla_data(nla); 258 } 259 260 s8 get_s8(const struct nlattr *nla) 261 { 262 return *(s8 *) nla_data(nla); 263 } 264 265 s16 get_s16(const struct nlattr *nla) 266 { 267 return *(s16 *) nla_data(nla); 268 } 269 s32 get_s32(const struct nlattr *nla) 270 { 271 return *(s32 *) nla_data(nla); 272 } 273 s64 get_s64(const struct nlattr *nla) 274 { 275 return *(s64 *) nla_data(nla); 276 } 277 278 wifi_error put_string(int attribute, const char *value) { 279 return wifi_nla_put(mMsg, attribute, strlen(value) + 1, value); 280 } 281 wifi_error put_addr(int attribute, mac_addr value) { 282 return wifi_nla_put(mMsg, attribute, sizeof(mac_addr), value); 283 } 284 285 struct nlattr * attr_start(int attribute) { 286 return nla_nest_start(mMsg, attribute); 287 } 288 void attr_end(struct nlattr *attr) { 289 nla_nest_end(mMsg, attr); 290 } 291 292 wifi_error set_iface_id(int ifindex) { 293 return put_u32(NL80211_ATTR_IFINDEX, ifindex); 294 } 295 296 wifi_error put_bytes(int attribute, const char *data, int len) { 297 return wifi_nla_put(mMsg, attribute, len, data); 298 } 299 300private: 301 WifiRequest(const WifiRequest&); // hide copy constructor to prevent copies 302 303}; 304 305class WifiCommand 306{ 307protected: 308 hal_info *mInfo; 309 WifiRequest mMsg; 310 Condition mCondition; 311 wifi_request_id mId; 312 interface_info *mIfaceInfo; 313public: 314 WifiCommand(wifi_handle handle, wifi_request_id id) 315 : mMsg(getHalInfo(handle)->nl80211_family_id), mId(id) 316 { 317 mIfaceInfo = NULL; 318 mInfo = getHalInfo(handle); 319 } 320 321 WifiCommand(wifi_interface_handle iface, wifi_request_id id) 322 : mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), mId(id) 323 { 324 mIfaceInfo = getIfaceInfo(iface); 325 mInfo = getHalInfo(iface); 326 } 327 328 virtual ~WifiCommand() { 329 } 330 331 wifi_request_id id() { 332 return mId; 333 } 334 335 virtual wifi_error create() { 336 /* by default there is no way to cancel */ 337 return WIFI_ERROR_NOT_SUPPORTED; 338 } 339 340 virtual wifi_error cancel() { 341 /* by default there is no way to cancel */ 342 return WIFI_ERROR_NOT_SUPPORTED; 343 } 344 345 wifi_error requestResponse(); 346 wifi_error requestEvent(int cmd); 347 wifi_error requestVendorEvent(uint32_t id, int subcmd); 348 wifi_error requestResponse(WifiRequest& request); 349 350protected: 351 wifi_handle wifiHandle() { 352 return getWifiHandle(mInfo); 353 } 354 355 wifi_interface_handle ifaceHandle() { 356 return getIfaceHandle(mIfaceInfo); 357 } 358 359 int familyId() { 360 return mInfo->nl80211_family_id; 361 } 362 363 int ifaceId() { 364 return mIfaceInfo->id; 365 } 366 367 /* Override this method to parse reply and dig out data; save it in the object */ 368 virtual int handleResponse(WifiEvent& reply) { 369 UNUSED(reply); 370 return NL_SKIP; 371 } 372 373 /* Override this method to parse event and dig out data; save it in the object */ 374 virtual int handleEvent(WifiEvent& event) { 375 UNUSED(event); 376 return NL_SKIP; 377 } 378 379 int registerHandler(int cmd) { 380 return wifi_register_handler(wifiHandle(), cmd, &event_handler, this); 381 } 382 383 void unregisterHandler(int cmd) { 384 wifi_unregister_handler(wifiHandle(), cmd); 385 } 386 387 wifi_error registerVendorHandler(uint32_t id, int subcmd) { 388 return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this); 389 } 390 391 void unregisterVendorHandler(uint32_t id, int subcmd) { 392 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); 393 } 394 395private: 396 WifiCommand(const WifiCommand& ); // hide copy constructor to prevent copies 397 398 /* Event handling */ 399 static int response_handler(struct nl_msg *msg, void *arg); 400 401 static int event_handler(struct nl_msg *msg, void *arg); 402 403 /* Other event handlers */ 404 static int valid_handler(struct nl_msg *msg, void *arg); 405 406 static int ack_handler(struct nl_msg *msg, void *arg); 407 408 static int finish_handler(struct nl_msg *msg, void *arg); 409 410 static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg); 411}; 412 413//WifiVendorCommand class 414class WifiVendorCommand: public WifiCommand 415{ 416protected: 417 u32 mVendor_id; 418 u32 mSubcmd; 419 char *mVendorData; 420 u32 mDataLen; 421 422 423public: 424 WifiVendorCommand(wifi_handle handle, wifi_request_id id, u32 vendor_id, u32 subcmd); 425 426 virtual ~WifiVendorCommand(); 427 428 virtual wifi_error create(); 429 430 virtual wifi_error requestResponse(); 431 432 virtual wifi_error requestEvent(); 433 434 virtual wifi_error put_u8(int attribute, uint8_t value); 435 436 virtual wifi_error put_u16(int attribute, uint16_t value); 437 438 virtual wifi_error put_u32(int attribute, uint32_t value); 439 440 virtual wifi_error put_u64(int attribute, uint64_t value); 441 442 virtual wifi_error put_s8(int attribute, s8 value); 443 444 virtual wifi_error put_s16(int attribute, s16 value); 445 446 virtual wifi_error put_s32(int attribute, s32 value); 447 448 virtual wifi_error put_s64(int attribute, s64 value); 449 450 wifi_error put_flag(int attribute); 451 452 virtual u8 get_u8(const struct nlattr *nla); 453 virtual u16 get_u16(const struct nlattr *nla); 454 virtual u32 get_u32(const struct nlattr *nla); 455 virtual u64 get_u64(const struct nlattr *nla); 456 457 virtual s8 get_s8(const struct nlattr *nla); 458 virtual s16 get_s16(const struct nlattr *nla); 459 virtual s32 get_s32(const struct nlattr *nla); 460 virtual s64 get_s64(const struct nlattr *nla); 461 462 virtual wifi_error put_string(int attribute, const char *value); 463 464 virtual wifi_error put_addr(int attribute, mac_addr value); 465 466 virtual struct nlattr * attr_start(int attribute); 467 468 virtual void attr_end(struct nlattr *attribute); 469 470 virtual wifi_error set_iface_id(const char* name); 471 472 virtual wifi_error put_bytes(int attribute, const char *data, int len); 473 474 virtual wifi_error get_mac_addr(struct nlattr **tb_vendor, 475 int attribute, 476 mac_addr addr); 477 478protected: 479 480 /* Override this method to parse reply and dig out data; save it in the corresponding 481 object */ 482 virtual int handleResponse(WifiEvent &reply); 483 484 /* Override this method to parse event and dig out data; save it in the object */ 485 virtual int handleEvent(WifiEvent &event); 486}; 487 488/* nl message processing macros (required to pass C++ type checks) */ 489 490#define for_each_attr(pos, nla, rem) \ 491 for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \ 492 nla_ok(pos, rem); \ 493 pos = (nlattr *)nla_next(pos, &(rem))) 494 495wifi_error initialize_vendor_cmd(wifi_interface_handle iface, 496 wifi_request_id id, 497 u32 subcmd, 498 WifiVendorCommand **vCommand); 499#endif 500