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