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