Home | History | Annotate | Download | only in wifi_hal
      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:
     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, int flags, int hdrlen) {
    188         return create(mFamily, cmd, flags, hdrlen);
    189     }
    190     int create(uint8_t cmd) {
    191         return create(mFamily, cmd, 0, 0);
    192     }
    193 
    194     int create(uint32_t id, int subcmd);
    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 
    206     int put_u64(int attribute, uint64_t value) {
    207         return nla_put(mMsg, attribute, sizeof(value), &value);
    208     }
    209 
    210     int put_s8(int attribute, s8 value) {
    211         return nla_put(mMsg, attribute, sizeof(int8_t), &value);
    212     }
    213     int put_s16(int attribute, s16 value) {
    214         return nla_put(mMsg, attribute, sizeof(int16_t), &value);
    215     }
    216     int put_s32(int attribute, s32 value) {
    217         return nla_put(mMsg, attribute, sizeof(int32_t), &value);
    218     }
    219     int put_s64(int attribute, s64 value) {
    220         return nla_put(mMsg, attribute, sizeof(int64_t), &value);
    221     }
    222 
    223     u8 get_u8(const struct nlattr *nla)
    224     {
    225         return *(u8 *) nla_data(nla);
    226     }
    227     u16 get_u16(const struct nlattr *nla)
    228     {
    229         return *(u16 *) nla_data(nla);
    230     }
    231     u32 get_u32(const struct nlattr *nla)
    232     {
    233         return *(u32 *) nla_data(nla);
    234     }
    235     u64 get_u64(const struct nlattr *nla)
    236     {
    237         return *(u64 *) nla_data(nla);
    238     }
    239 
    240     s8 get_s8(const struct nlattr *nla)
    241     {
    242         return *(s8 *) nla_data(nla);
    243     }
    244 
    245     s16 get_s16(const struct nlattr *nla)
    246     {
    247         return *(s16 *) nla_data(nla);
    248     }
    249     s32 get_s32(const struct nlattr *nla)
    250     {
    251         return *(s32 *) nla_data(nla);
    252     }
    253     s64 get_s64(const struct nlattr *nla)
    254     {
    255         return *(s64 *) nla_data(nla);
    256     }
    257 
    258     int put_string(int attribute, const char *value) {
    259         return nla_put(mMsg, attribute, strlen(value) + 1, value);
    260     }
    261     int put_addr(int attribute, mac_addr value) {
    262         return nla_put(mMsg, attribute, sizeof(mac_addr), value);
    263     }
    264 
    265     struct nlattr * attr_start(int attribute) {
    266         return nla_nest_start(mMsg, attribute);
    267     }
    268     void attr_end(struct nlattr *attr) {
    269         nla_nest_end(mMsg, attr);
    270     }
    271 
    272     int set_iface_id(int ifindex) {
    273         return put_u32(NL80211_ATTR_IFINDEX, ifindex);
    274     }
    275 
    276     int put_bytes(int attribute, const char *data, int len) {
    277         return nla_put(mMsg, attribute, len, data);
    278     }
    279 
    280 private:
    281     WifiRequest(const WifiRequest&);        // hide copy constructor to prevent copies
    282 
    283 };
    284 
    285 class WifiCommand
    286 {
    287 protected:
    288     hal_info *mInfo;
    289     WifiRequest mMsg;
    290     Condition mCondition;
    291     wifi_request_id mId;
    292     interface_info *mIfaceInfo;
    293 public:
    294     WifiCommand(wifi_handle handle, wifi_request_id id)
    295             : mMsg(getHalInfo(handle)->nl80211_family_id), mId(id)
    296     {
    297         mIfaceInfo = NULL;
    298         mInfo = getHalInfo(handle);
    299     }
    300 
    301     WifiCommand(wifi_interface_handle iface, wifi_request_id id)
    302             : mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), mId(id)
    303     {
    304         mIfaceInfo = getIfaceInfo(iface);
    305         mInfo = getHalInfo(iface);
    306     }
    307 
    308     virtual ~WifiCommand() {
    309     }
    310 
    311     wifi_request_id id() {
    312         return mId;
    313     }
    314 
    315     virtual int create() {
    316         /* by default there is no way to cancel */
    317         return WIFI_ERROR_NOT_SUPPORTED;
    318     }
    319 
    320     virtual int cancel() {
    321         /* by default there is no way to cancel */
    322         return WIFI_ERROR_NOT_SUPPORTED;
    323     }
    324 
    325     int requestResponse();
    326     int requestEvent(int cmd);
    327     int requestVendorEvent(uint32_t id, int subcmd);
    328     int requestResponse(WifiRequest& request);
    329 
    330 protected:
    331     wifi_handle wifiHandle() {
    332         return getWifiHandle(mInfo);
    333     }
    334 
    335     wifi_interface_handle ifaceHandle() {
    336         return getIfaceHandle(mIfaceInfo);
    337     }
    338 
    339     int familyId() {
    340         return mInfo->nl80211_family_id;
    341     }
    342 
    343     int ifaceId() {
    344         return mIfaceInfo->id;
    345     }
    346 
    347     /* Override this method to parse reply and dig out data; save it in the object */
    348     virtual int handleResponse(WifiEvent& reply) {
    349         return NL_SKIP;
    350     }
    351 
    352     /* Override this method to parse event and dig out data; save it in the object */
    353     virtual int handleEvent(WifiEvent& event) {
    354         return NL_SKIP;
    355     }
    356 
    357     int registerHandler(int cmd) {
    358         return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
    359     }
    360 
    361     void unregisterHandler(int cmd) {
    362         wifi_unregister_handler(wifiHandle(), cmd);
    363     }
    364 
    365     int registerVendorHandler(uint32_t id, int subcmd) {
    366         return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
    367     }
    368 
    369     void unregisterVendorHandler(uint32_t id, int subcmd) {
    370         wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
    371     }
    372 
    373 private:
    374     WifiCommand(const WifiCommand& );           // hide copy constructor to prevent copies
    375 
    376     /* Event handling */
    377     static int response_handler(struct nl_msg *msg, void *arg);
    378 
    379     static int event_handler(struct nl_msg *msg, void *arg);
    380 
    381     /* Other event handlers */
    382     static int valid_handler(struct nl_msg *msg, void *arg);
    383 
    384     static int ack_handler(struct nl_msg *msg, void *arg);
    385 
    386     static int finish_handler(struct nl_msg *msg, void *arg);
    387 
    388     static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
    389 };
    390 
    391 //WifiVendorCommand class
    392 class WifiVendorCommand: public WifiCommand
    393 {
    394 protected:
    395     u32 mVendor_id;
    396     u32 mSubcmd;
    397     char *mVendorData;
    398     u32 mDataLen;
    399 
    400 
    401 public:
    402     WifiVendorCommand(wifi_handle handle, wifi_request_id id, u32 vendor_id, u32 subcmd);
    403 
    404     virtual ~WifiVendorCommand();
    405 
    406     virtual int create();
    407 
    408     virtual int requestResponse();
    409 
    410     virtual int requestEvent();
    411 
    412     virtual int put_u8(int attribute, uint8_t value);
    413 
    414     virtual int put_u16(int attribute, uint16_t value);
    415 
    416     virtual int put_u32(int attribute, uint32_t value);
    417 
    418     virtual int put_u64(int attribute, uint64_t value);
    419 
    420     virtual int put_s8(int attribute, s8 value);
    421 
    422     virtual int put_s16(int attribute, s16 value);
    423 
    424     virtual int put_s32(int attribute, s32 value);
    425 
    426     virtual int put_s64(int attribute, s64 value);
    427 
    428     virtual u8 get_u8(const struct nlattr *nla);
    429     virtual u16 get_u16(const struct nlattr *nla);
    430     virtual u32 get_u32(const struct nlattr *nla);
    431     virtual u64 get_u64(const struct nlattr *nla);
    432 
    433     virtual s8 get_s8(const struct nlattr *nla);
    434     virtual s16 get_s16(const struct nlattr *nla);
    435     virtual s32 get_s32(const struct nlattr *nla);
    436     virtual s64 get_s64(const struct nlattr *nla);
    437 
    438     virtual int put_string(int attribute, const char *value);
    439 
    440     virtual int put_addr(int attribute, mac_addr value);
    441 
    442     virtual struct nlattr * attr_start(int attribute);
    443 
    444     virtual void attr_end(struct nlattr *attribute);
    445 
    446     virtual int set_iface_id(const char* name);
    447 
    448     virtual int put_bytes(int attribute, const char *data, int len);
    449 
    450     virtual wifi_error get_mac_addr(struct nlattr **tb_vendor,
    451                                 int attribute,
    452                                 mac_addr addr);
    453 
    454 protected:
    455 
    456     /* Override this method to parse reply and dig out data; save it in the corresponding
    457        object */
    458     virtual int handleResponse(WifiEvent &reply);
    459 
    460     /* Override this method to parse event and dig out data; save it in the object */
    461     virtual int handleEvent(WifiEvent &event);
    462 };
    463 
    464 /* nl message processing macros (required to pass C++ type checks) */
    465 
    466 #define for_each_attr(pos, nla, rem) \
    467     for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
    468         nla_ok(pos, rem); \
    469         pos = (nlattr *)nla_next(pos, &(rem)))
    470 
    471 wifi_error initialize_vendor_cmd(wifi_interface_handle iface,
    472                                  wifi_request_id id,
    473                                  u32 subcmd,
    474                                  WifiVendorCommand **vCommand);
    475 #endif
    476