1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Portions copyright (C) 2017 Broadcom Limited 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 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: 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 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: 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 } 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: 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 int create(int family, uint8_t cmd, int flags, int hdrlen); 187 int create(uint8_t cmd) { 188 return create(mFamily, cmd, 0, 0); 189 } 190 191 int create(uint32_t id, int subcmd); 192 193 int put(int attribute, void *ptr, unsigned len) { 194 return nla_put(mMsg, attribute, len, ptr); 195 } 196 int put_u8(int attribute, uint8_t value) { 197 return nla_put(mMsg, attribute, sizeof(value), &value); 198 } 199 int put_u16(int attribute, uint16_t value) { 200 return nla_put(mMsg, attribute, sizeof(value), &value); 201 } 202 int put_u32(int attribute, uint32_t value) { 203 return nla_put(mMsg, attribute, sizeof(value), &value); 204 } 205 int put_u64(int attribute, uint64_t value) { 206 return nla_put(mMsg, attribute, sizeof(value), &value); 207 } 208 int put_string(int attribute, const char *value) { 209 return nla_put(mMsg, attribute, strlen(value) + 1, value); 210 } 211 int put_addr(int attribute, mac_addr value) { 212 return nla_put(mMsg, attribute, sizeof(mac_addr), value); 213 } 214 215 struct nlattr * attr_start(int attribute) { 216 return nla_nest_start(mMsg, attribute); 217 } 218 void attr_end(struct nlattr *attr) { 219 nla_nest_end(mMsg, attr); 220 } 221 222 int set_iface_id(int ifindex) { 223 return put_u32(NL80211_ATTR_IFINDEX, ifindex); 224 } 225 private: 226 WifiRequest(const WifiRequest&); // hide copy constructor to prevent copies 227 228 }; 229 230 class WifiCommand 231 { 232 protected: 233 const char *mType; 234 hal_info *mInfo; 235 WifiRequest mMsg; 236 Condition mCondition; 237 wifi_request_id mId; 238 interface_info *mIfaceInfo; 239 int mRefs; 240 public: 241 WifiCommand(const char *type, wifi_handle handle, wifi_request_id id) 242 : mType(type), mMsg(getHalInfo(handle)->nl80211_family_id), mId(id), mRefs(1) 243 { 244 mIfaceInfo = NULL; 245 mInfo = getHalInfo(handle); 246 // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo); 247 } 248 249 WifiCommand(const char *type, wifi_interface_handle iface, wifi_request_id id) 250 : mType(type), mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), 251 mId(id), mRefs(1) 252 { 253 mIfaceInfo = getIfaceInfo(iface); 254 mInfo = getHalInfo(iface); 255 // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo); 256 } 257 258 virtual ~WifiCommand() { 259 // ALOGD("WifiCommand %p destroyed", this); 260 } 261 262 wifi_request_id id() { 263 return mId; 264 } 265 266 const char *getType() { 267 return mType; 268 } 269 270 virtual void addRef() { 271 int refs = __sync_add_and_fetch(&mRefs, 1); 272 // ALOGD("addRef: WifiCommand %p has %d references", this, refs); 273 } 274 275 virtual void releaseRef() { 276 int refs = __sync_sub_and_fetch(&mRefs, 1); 277 if (refs == 0) { 278 delete this; 279 } else { 280 // ALOGD("releaseRef: WifiCommand %p has %d references", this, refs); 281 } 282 } 283 284 virtual int create() { 285 /* by default there is no way to cancel */ 286 ALOGD("WifiCommand %p can't be created", this); 287 return WIFI_ERROR_NOT_SUPPORTED; 288 } 289 290 virtual int cancel() { 291 /* by default there is no way to cancel */ 292 return WIFI_ERROR_NOT_SUPPORTED; 293 } 294 295 int requestResponse(); 296 int requestEvent(int cmd); 297 int requestVendorEvent(uint32_t id, int subcmd); 298 int requestResponse(WifiRequest& request); 299 300 protected: 301 wifi_handle wifiHandle() { 302 return getWifiHandle(mInfo); 303 } 304 305 wifi_interface_handle ifaceHandle() { 306 return getIfaceHandle(mIfaceInfo); 307 } 308 309 int familyId() { 310 return mInfo->nl80211_family_id; 311 } 312 313 int ifaceId() { 314 return mIfaceInfo->id; 315 } 316 317 /* Override this method to parse reply and dig out data; save it in the object */ 318 virtual int handleResponse(WifiEvent& reply) { 319 ALOGI("skipping a response"); 320 return NL_SKIP; 321 } 322 323 /* Override this method to parse event and dig out data; save it in the object */ 324 virtual int handleEvent(WifiEvent& event) { 325 ALOGI("skipping an event"); 326 return NL_SKIP; 327 } 328 329 int registerHandler(int cmd) { 330 return wifi_register_handler(wifiHandle(), cmd, &event_handler, this); 331 } 332 333 void unregisterHandler(int cmd) { 334 wifi_unregister_handler(wifiHandle(), cmd); 335 } 336 337 int registerVendorHandler(uint32_t id, int subcmd) { 338 return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this); 339 } 340 341 void unregisterVendorHandler(uint32_t id, int subcmd) { 342 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); 343 } 344 345 private: 346 WifiCommand(const WifiCommand& ); // hide copy constructor to prevent copies 347 348 /* Event handling */ 349 static int response_handler(struct nl_msg *msg, void *arg); 350 351 static int event_handler(struct nl_msg *msg, void *arg); 352 353 /* Other event handlers */ 354 static int valid_handler(struct nl_msg *msg, void *arg); 355 356 static int ack_handler(struct nl_msg *msg, void *arg); 357 358 static int finish_handler(struct nl_msg *msg, void *arg); 359 360 static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg); 361 }; 362 363 /* nl message processing macros (required to pass C++ type checks) */ 364 365 #define for_each_attr(pos, nla, rem) \ 366 for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \ 367 nla_ok(pos, rem); \ 368 pos = (nlattr *)nla_next(pos, &(rem))) 369 370