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