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     wifi_error create(int family, uint8_t cmd, int flags, int hdrlen);
create(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     }
create(uint8_t cmd)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 
wifi_nla_put(struct nl_msg * msg,int attr,int attrlen,const void * data)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     }
put_u8(int attribute,uint8_t value)207     wifi_error put_u8(int attribute, uint8_t value) {
208         return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
209     }
put_u16(int attribute,uint16_t value)210     wifi_error put_u16(int attribute, uint16_t value) {
211         return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
212     }
put_u32(int attribute,uint32_t value)213     wifi_error put_u32(int attribute, uint32_t value) {
214         return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
215     }
216 
put_u64(int attribute,uint64_t value)217     wifi_error put_u64(int attribute, uint64_t value) {
218         return wifi_nla_put(mMsg, attribute, sizeof(value), &value);
219     }
220 
put_s8(int attribute,s8 value)221     wifi_error put_s8(int attribute, s8 value) {
222         return wifi_nla_put(mMsg, attribute, sizeof(int8_t), &value);
223     }
put_s16(int attribute,s16 value)224     wifi_error put_s16(int attribute, s16 value) {
225         return wifi_nla_put(mMsg, attribute, sizeof(int16_t), &value);
226     }
put_s32(int attribute,s32 value)227     wifi_error put_s32(int attribute, s32 value) {
228         return wifi_nla_put(mMsg, attribute, sizeof(int32_t), &value);
229     }
put_s64(int attribute,s64 value)230     wifi_error put_s64(int attribute, s64 value) {
231         return wifi_nla_put(mMsg, attribute, sizeof(int64_t), &value);
232     }
put_flag(int attribute)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 
get_u8(const struct nlattr * nla)243     u8 get_u8(const struct nlattr *nla)
244     {
245         return *(u8 *) nla_data(nla);
246     }
get_u16(const struct nlattr * nla)247     u16 get_u16(const struct nlattr *nla)
248     {
249         return *(u16 *) nla_data(nla);
250     }
get_u32(const struct nlattr * nla)251     u32 get_u32(const struct nlattr *nla)
252     {
253         return *(u32 *) nla_data(nla);
254     }
get_u64(const struct nlattr * nla)255     u64 get_u64(const struct nlattr *nla)
256     {
257         return *(u64 *) nla_data(nla);
258     }
259 
get_s8(const struct nlattr * nla)260     s8 get_s8(const struct nlattr *nla)
261     {
262         return *(s8 *) nla_data(nla);
263     }
264 
get_s16(const struct nlattr * nla)265     s16 get_s16(const struct nlattr *nla)
266     {
267         return *(s16 *) nla_data(nla);
268     }
get_s32(const struct nlattr * nla)269     s32 get_s32(const struct nlattr *nla)
270     {
271         return *(s32 *) nla_data(nla);
272     }
get_s64(const struct nlattr * nla)273     s64 get_s64(const struct nlattr *nla)
274     {
275         return *(s64 *) nla_data(nla);
276     }
277 
put_string(int attribute,const char * value)278     wifi_error put_string(int attribute, const char *value) {
279         return wifi_nla_put(mMsg, attribute, strlen(value) + 1, value);
280     }
put_addr(int attribute,mac_addr value)281     wifi_error put_addr(int attribute, mac_addr value) {
282         return wifi_nla_put(mMsg, attribute, sizeof(mac_addr), value);
283     }
284 
attr_start(int attribute)285     struct nlattr * attr_start(int attribute) {
286         return nla_nest_start(mMsg, attribute);
287     }
attr_end(struct nlattr * attr)288     void attr_end(struct nlattr *attr) {
289         nla_nest_end(mMsg, attr);
290     }
291 
set_iface_id(int ifindex)292     wifi_error set_iface_id(int ifindex) {
293         return put_u32(NL80211_ATTR_IFINDEX, ifindex);
294     }
295 
put_bytes(int attribute,const char * data,int len)296     wifi_error put_bytes(int attribute, const char *data, int len) {
297         return wifi_nla_put(mMsg, attribute, len, data);
298     }
299 
300 private:
301     WifiRequest(const WifiRequest&);        // hide copy constructor to prevent copies
302 
303 };
304 
305 class WifiCommand
306 {
307 protected:
308     hal_info *mInfo;
309     WifiRequest mMsg;
310     Condition mCondition;
311     wifi_request_id mId;
312     interface_info *mIfaceInfo;
313 public:
WifiCommand(wifi_handle handle,wifi_request_id id)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 
WifiCommand(wifi_interface_handle iface,wifi_request_id id)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 
~WifiCommand()328     virtual ~WifiCommand() {
329     }
330 
id()331     wifi_request_id id() {
332         return mId;
333     }
334 
create()335     virtual wifi_error create() {
336         /* by default there is no way to cancel */
337         return WIFI_ERROR_NOT_SUPPORTED;
338     }
339 
cancel()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 
350 protected:
wifiHandle()351     wifi_handle wifiHandle() {
352         return getWifiHandle(mInfo);
353     }
354 
ifaceHandle()355     wifi_interface_handle ifaceHandle() {
356         return getIfaceHandle(mIfaceInfo);
357     }
358 
familyId()359     int familyId() {
360         return mInfo->nl80211_family_id;
361     }
362 
ifaceId()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 */
handleResponse(WifiEvent & reply)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 */
handleEvent(WifiEvent & event)374     virtual int handleEvent(WifiEvent& event) {
375         UNUSED(event);
376         return NL_SKIP;
377     }
378 
registerHandler(int cmd)379     int registerHandler(int cmd) {
380         return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
381     }
382 
unregisterHandler(int cmd)383     void unregisterHandler(int cmd) {
384         wifi_unregister_handler(wifiHandle(), cmd);
385     }
386 
registerVendorHandler(uint32_t id,int subcmd)387     wifi_error registerVendorHandler(uint32_t id, int subcmd) {
388         return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
389     }
390 
unregisterVendorHandler(uint32_t id,int subcmd)391     void unregisterVendorHandler(uint32_t id, int subcmd) {
392         wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
393     }
394 
395 private:
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
414 class WifiVendorCommand: public WifiCommand
415 {
416 protected:
417     u32 mVendor_id;
418     u32 mSubcmd;
419     char *mVendorData;
420     u32 mDataLen;
421 
422 
423 public:
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 
478 protected:
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 
495 wifi_error initialize_vendor_cmd(wifi_interface_handle iface,
496                                  wifi_request_id id,
497                                  u32 subcmd,
498                                  WifiVendorCommand **vCommand);
499 #endif
500