1 2 #include "wifi_hal.h" 3 #include "common.h" 4 #include "sync.h" 5 6 class WifiEvent 7 { 8 /* TODO: remove this when nl headers are updated */ 9 static const unsigned NL80211_ATTR_MAX_INTERNAL = 256; 10 private: 11 struct nl_msg *mMsg; 12 struct genlmsghdr *mHeader; 13 struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1]; 14 15 public: WifiEvent(nl_msg * msg)16 WifiEvent(nl_msg *msg) { 17 mMsg = msg; 18 mHeader = NULL; 19 memset(mAttributes, 0, sizeof(mAttributes)); 20 } ~WifiEvent()21 ~WifiEvent() { 22 /* don't destroy mMsg; it doesn't belong to us */ 23 } 24 25 void log(); 26 27 int parse(); 28 header()29 genlmsghdr *header() { 30 return mHeader; 31 } 32 get_cmd()33 int get_cmd() { 34 return mHeader->cmd; 35 } 36 get_vendor_id()37 int get_vendor_id() { 38 return get_u32(NL80211_ATTR_VENDOR_ID); 39 } 40 get_vendor_subcmd()41 int get_vendor_subcmd() { 42 return get_u32(NL80211_ATTR_VENDOR_SUBCMD); 43 } 44 get_vendor_data()45 void *get_vendor_data() { 46 return get_data(NL80211_ATTR_VENDOR_DATA); 47 } 48 get_vendor_data_len()49 int get_vendor_data_len() { 50 return get_len(NL80211_ATTR_VENDOR_DATA); 51 } 52 53 const char *get_cmdString(); 54 attributes()55 nlattr ** attributes() { 56 return mAttributes; 57 } 58 get_attribute(int attribute)59 nlattr *get_attribute(int attribute) { 60 return mAttributes[attribute]; 61 } 62 get_u8(int attribute)63 uint8_t get_u8(int attribute) { 64 return mAttributes[attribute] ? nla_get_u8(mAttributes[attribute]) : 0; 65 } 66 get_u16(int attribute)67 uint16_t get_u16(int attribute) { 68 return mAttributes[attribute] ? nla_get_u16(mAttributes[attribute]) : 0; 69 } 70 get_u32(int attribute)71 uint32_t get_u32(int attribute) { 72 return mAttributes[attribute] ? nla_get_u32(mAttributes[attribute]) : 0; 73 } 74 get_u64(int attribute)75 uint64_t get_u64(int attribute) { 76 return mAttributes[attribute] ? nla_get_u64(mAttributes[attribute]) : 0; 77 } 78 get_len(int attribute)79 int get_len(int attribute) { 80 return mAttributes[attribute] ? nla_len(mAttributes[attribute]) : 0; 81 } 82 get_data(int attribute)83 void *get_data(int attribute) { 84 return mAttributes[attribute] ? nla_data(mAttributes[attribute]) : NULL; 85 } 86 87 private: 88 WifiEvent(const WifiEvent&); // hide copy constructor to prevent copies 89 }; 90 91 class nl_iterator { 92 struct nlattr *pos; 93 int rem; 94 public: nl_iterator(struct nlattr * attr)95 nl_iterator(struct nlattr *attr) { 96 pos = (struct nlattr *)nla_data(attr); 97 rem = nla_len(attr); 98 } has_next()99 bool has_next() { 100 return nla_ok(pos, rem); 101 } next()102 void next() { 103 pos = (struct nlattr *)nla_next(pos, &(rem)); 104 } get()105 struct nlattr *get() { 106 return pos; 107 } get_type()108 uint16_t get_type() { 109 return pos->nla_type; 110 } get_u8()111 uint8_t get_u8() { 112 return nla_get_u8(pos); 113 } get_u16()114 uint16_t get_u16() { 115 return nla_get_u16(pos); 116 } get_u32()117 uint32_t get_u32() { 118 return nla_get_u32(pos); 119 } get_u64()120 uint64_t get_u64() { 121 return nla_get_u64(pos); 122 } get_data()123 void* get_data() { 124 return nla_data(pos); 125 } get_len()126 int get_len() { 127 return nla_len(pos); 128 } 129 private: 130 nl_iterator(const nl_iterator&); // hide copy constructor to prevent copies 131 }; 132 133 class WifiRequest 134 { 135 private: 136 int mFamily; 137 int mIface; 138 struct nl_msg *mMsg; 139 140 public: WifiRequest(int family)141 WifiRequest(int family) { 142 mMsg = NULL; 143 mFamily = family; 144 mIface = -1; 145 } 146 WifiRequest(int family,int iface)147 WifiRequest(int family, int iface) { 148 mMsg = NULL; 149 mFamily = family; 150 mIface = iface; 151 } 152 ~WifiRequest()153 ~WifiRequest() { 154 destroy(); 155 } 156 destroy()157 void destroy() { 158 if (mMsg) { 159 nlmsg_free(mMsg); 160 mMsg = NULL; 161 } 162 } 163 getMessage()164 nl_msg *getMessage() { 165 return mMsg; 166 } 167 168 /* Command assembly helpers */ 169 int create(int family, uint8_t cmd, int flags, int hdrlen); create(uint8_t cmd)170 int create(uint8_t cmd) { 171 return create(mFamily, cmd, 0, 0); 172 } 173 174 int create(uint32_t id, int subcmd); 175 put(int attribute,void * ptr,unsigned len)176 int put(int attribute, void *ptr, unsigned len) { 177 return nla_put(mMsg, attribute, len, ptr); 178 } put_u8(int attribute,uint8_t value)179 int put_u8(int attribute, uint8_t value) { 180 return nla_put(mMsg, attribute, sizeof(value), &value); 181 } put_u16(int attribute,uint16_t value)182 int put_u16(int attribute, uint16_t value) { 183 return nla_put(mMsg, attribute, sizeof(value), &value); 184 } put_u32(int attribute,uint32_t value)185 int put_u32(int attribute, uint32_t value) { 186 return nla_put(mMsg, attribute, sizeof(value), &value); 187 } put_u64(int attribute,uint64_t value)188 int put_u64(int attribute, uint64_t value) { 189 return nla_put(mMsg, attribute, sizeof(value), &value); 190 } put_string(int attribute,const char * value)191 int put_string(int attribute, const char *value) { 192 return nla_put(mMsg, attribute, strlen(value) + 1, value); 193 } put_addr(int attribute,mac_addr value)194 int put_addr(int attribute, mac_addr value) { 195 return nla_put(mMsg, attribute, sizeof(mac_addr), value); 196 } 197 attr_start(int attribute)198 struct nlattr * attr_start(int attribute) { 199 return nla_nest_start(mMsg, attribute); 200 } attr_end(struct nlattr * attr)201 void attr_end(struct nlattr *attr) { 202 nla_nest_end(mMsg, attr); 203 } 204 set_iface_id(int ifindex)205 int set_iface_id(int ifindex) { 206 return put_u32(NL80211_ATTR_IFINDEX, ifindex); 207 } 208 private: 209 WifiRequest(const WifiRequest&); // hide copy constructor to prevent copies 210 211 }; 212 213 class WifiCommand 214 { 215 protected: 216 const char *mType; 217 hal_info *mInfo; 218 WifiRequest mMsg; 219 Condition mCondition; 220 wifi_request_id mId; 221 interface_info *mIfaceInfo; 222 int mRefs; 223 public: WifiCommand(const char * type,wifi_handle handle,wifi_request_id id)224 WifiCommand(const char *type, wifi_handle handle, wifi_request_id id) 225 : mType(type), mMsg(getHalInfo(handle)->nl80211_family_id), mId(id), mRefs(1) 226 { 227 mIfaceInfo = NULL; 228 mInfo = getHalInfo(handle); 229 // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo); 230 } 231 WifiCommand(const char * type,wifi_interface_handle iface,wifi_request_id id)232 WifiCommand(const char *type, wifi_interface_handle iface, wifi_request_id id) 233 : mType(type), mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), 234 mId(id), mRefs(1) 235 { 236 mIfaceInfo = getIfaceInfo(iface); 237 mInfo = getHalInfo(iface); 238 // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo); 239 } 240 ~WifiCommand()241 virtual ~WifiCommand() { 242 // ALOGD("WifiCommand %p destroyed", this); 243 } 244 id()245 wifi_request_id id() { 246 return mId; 247 } 248 getType()249 const char *getType() { 250 return mType; 251 } 252 addRef()253 virtual void addRef() { 254 int refs = __sync_add_and_fetch(&mRefs, 1); 255 // ALOGD("addRef: WifiCommand %p has %d references", this, refs); 256 } 257 releaseRef()258 virtual void releaseRef() { 259 int refs = __sync_sub_and_fetch(&mRefs, 1); 260 if (refs == 0) { 261 delete this; 262 } else { 263 // ALOGD("releaseRef: WifiCommand %p has %d references", this, refs); 264 } 265 } 266 create()267 virtual int create() { 268 /* by default there is no way to cancel */ 269 ALOGD("WifiCommand %p can't be created", this); 270 return WIFI_ERROR_NOT_SUPPORTED; 271 } 272 cancel()273 virtual int cancel() { 274 /* by default there is no way to cancel */ 275 return WIFI_ERROR_NOT_SUPPORTED; 276 } 277 278 int requestResponse(); 279 int requestEvent(int cmd); 280 int requestVendorEvent(uint32_t id, int subcmd); 281 int requestResponse(WifiRequest& request); 282 283 protected: wifiHandle()284 wifi_handle wifiHandle() { 285 return getWifiHandle(mInfo); 286 } 287 ifaceHandle()288 wifi_interface_handle ifaceHandle() { 289 return getIfaceHandle(mIfaceInfo); 290 } 291 familyId()292 int familyId() { 293 return mInfo->nl80211_family_id; 294 } 295 ifaceId()296 int ifaceId() { 297 return mIfaceInfo->id; 298 } 299 300 /* Override this method to parse reply and dig out data; save it in the object */ handleResponse(WifiEvent & reply)301 virtual int handleResponse(WifiEvent& reply) { 302 ALOGI("skipping a response"); 303 return NL_SKIP; 304 } 305 306 /* Override this method to parse event and dig out data; save it in the object */ handleEvent(WifiEvent & event)307 virtual int handleEvent(WifiEvent& event) { 308 ALOGI("skipping an event"); 309 return NL_SKIP; 310 } 311 registerHandler(int cmd)312 int registerHandler(int cmd) { 313 return wifi_register_handler(wifiHandle(), cmd, &event_handler, this); 314 } 315 unregisterHandler(int cmd)316 void unregisterHandler(int cmd) { 317 wifi_unregister_handler(wifiHandle(), cmd); 318 } 319 registerVendorHandler(uint32_t id,int subcmd)320 int registerVendorHandler(uint32_t id, int subcmd) { 321 return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this); 322 } 323 unregisterVendorHandler(uint32_t id,int subcmd)324 void unregisterVendorHandler(uint32_t id, int subcmd) { 325 wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); 326 } 327 328 private: 329 WifiCommand(const WifiCommand& ); // hide copy constructor to prevent copies 330 331 /* Event handling */ 332 static int response_handler(struct nl_msg *msg, void *arg); 333 334 static int event_handler(struct nl_msg *msg, void *arg); 335 336 /* Other event handlers */ 337 static int valid_handler(struct nl_msg *msg, void *arg); 338 339 static int ack_handler(struct nl_msg *msg, void *arg); 340 341 static int finish_handler(struct nl_msg *msg, void *arg); 342 343 static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg); 344 }; 345 346 /* nl message processing macros (required to pass C++ type checks) */ 347 348 #define for_each_attr(pos, nla, rem) \ 349 for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \ 350 nla_ok(pos, rem); \ 351 pos = (nlattr *)nla_next(pos, &(rem))) 352 353