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_s32(int attribute, int32_t value) {
    207         return nla_put(mMsg, attribute, sizeof(int32_t), &value);
    208     }
    209 
    210     int put_u64(int attribute, uint64_t value) {
    211         return nla_put(mMsg, attribute, sizeof(value), &value);
    212     }
    213     int put_string(int attribute, const char *value) {
    214         return nla_put(mMsg, attribute, strlen(value) + 1, value);
    215     }
    216     int put_addr(int attribute, mac_addr value) {
    217         return nla_put(mMsg, attribute, sizeof(mac_addr), value);
    218     }
    219 
    220     struct nlattr * attr_start(int attribute) {
    221         return nla_nest_start(mMsg, attribute);
    222     }
    223     void attr_end(struct nlattr *attr) {
    224         nla_nest_end(mMsg, attr);
    225     }
    226 
    227     int set_iface_id(int ifindex) {
    228         return put_u32(NL80211_ATTR_IFINDEX, ifindex);
    229     }
    230 
    231     int put_bytes(int attribute, const char *data, int len) {
    232         return nla_put(mMsg, attribute, len, data);
    233     }
    234 private:
    235     WifiRequest(const WifiRequest&);        // hide copy constructor to prevent copies
    236 
    237 };
    238 
    239 class WifiCommand
    240 {
    241 protected:
    242     hal_info *mInfo;
    243     WifiRequest mMsg;
    244     Condition mCondition;
    245     wifi_request_id mId;
    246     interface_info *mIfaceInfo;
    247 public:
    248     WifiCommand(wifi_handle handle, wifi_request_id id)
    249             : mMsg(getHalInfo(handle)->nl80211_family_id), mId(id)
    250     {
    251         mIfaceInfo = NULL;
    252         mInfo = getHalInfo(handle);
    253         // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
    254     }
    255 
    256     WifiCommand(wifi_interface_handle iface, wifi_request_id id)
    257             : mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), mId(id)
    258     {
    259         mIfaceInfo = getIfaceInfo(iface);
    260         mInfo = getHalInfo(iface);
    261         // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
    262     }
    263 
    264     virtual ~WifiCommand() {
    265         // ALOGD("WifiCommand %p destroyed", this);
    266     }
    267 
    268     wifi_request_id id() {
    269         return mId;
    270     }
    271 
    272     virtual int create() {
    273         /* by default there is no way to cancel */
    274         ALOGD("WifiCommand %p can't be created", this);
    275         return WIFI_ERROR_NOT_SUPPORTED;
    276     }
    277 
    278     virtual int cancel() {
    279         /* by default there is no way to cancel */
    280         return WIFI_ERROR_NOT_SUPPORTED;
    281     }
    282 
    283     int requestResponse();
    284     int requestEvent(int cmd);
    285     int requestVendorEvent(uint32_t id, int subcmd);
    286     int requestResponse(WifiRequest& request);
    287 
    288 protected:
    289     wifi_handle wifiHandle() {
    290         return getWifiHandle(mInfo);
    291     }
    292 
    293     wifi_interface_handle ifaceHandle() {
    294         return getIfaceHandle(mIfaceInfo);
    295     }
    296 
    297     int familyId() {
    298         return mInfo->nl80211_family_id;
    299     }
    300 
    301     int ifaceId() {
    302         return mIfaceInfo->id;
    303     }
    304 
    305     /* Override this method to parse reply and dig out data; save it in the object */
    306     virtual int handleResponse(WifiEvent& reply) {
    307         ALOGI("skipping a response");
    308         return NL_SKIP;
    309     }
    310 
    311     /* Override this method to parse event and dig out data; save it in the object */
    312     virtual int handleEvent(WifiEvent& event) {
    313         ALOGI("skipping an event");
    314         return NL_SKIP;
    315     }
    316 
    317     int registerHandler(int cmd) {
    318         return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
    319     }
    320 
    321     void unregisterHandler(int cmd) {
    322         wifi_unregister_handler(wifiHandle(), cmd);
    323     }
    324 
    325     int registerVendorHandler(uint32_t id, int subcmd) {
    326         return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
    327     }
    328 
    329     void unregisterVendorHandler(uint32_t id, int subcmd) {
    330         wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
    331     }
    332 
    333 private:
    334     WifiCommand(const WifiCommand& );           // hide copy constructor to prevent copies
    335 
    336     /* Event handling */
    337     static int response_handler(struct nl_msg *msg, void *arg);
    338 
    339     static int event_handler(struct nl_msg *msg, void *arg);
    340 
    341     /* Other event handlers */
    342     static int valid_handler(struct nl_msg *msg, void *arg);
    343 
    344     static int ack_handler(struct nl_msg *msg, void *arg);
    345 
    346     static int finish_handler(struct nl_msg *msg, void *arg);
    347 
    348     static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
    349 };
    350 
    351 //WifiVendorCommand class
    352 class WifiVendorCommand: public WifiCommand
    353 {
    354 protected:
    355     u32 mVendor_id;
    356     u32 mSubcmd;
    357     char *mVendorData;
    358     u32 mDataLen;
    359 
    360 
    361 public:
    362     WifiVendorCommand(wifi_handle handle, wifi_request_id id, u32 vendor_id, u32 subcmd);
    363 
    364     virtual ~WifiVendorCommand();
    365 
    366     virtual int create();
    367 
    368     virtual int requestEvent();
    369 
    370     virtual int put_u8(int attribute, uint8_t value);
    371 
    372     virtual int put_u16(int attribute, uint16_t value);
    373 
    374     virtual int put_u32(int attribute, uint32_t value);
    375 
    376     virtual int put_s32(int attribute, int32_t value);
    377 
    378     virtual int put_u64(int attribute, uint64_t value);
    379 
    380     virtual int put_string(int attribute, const char *value);
    381 
    382     virtual int put_addr(int attribute, mac_addr value);
    383 
    384     virtual struct nlattr * attr_start(int attribute);
    385 
    386     virtual void attr_end(struct nlattr *attribute);
    387 
    388     virtual int set_iface_id(const char* name);
    389 
    390     virtual int put_bytes(int attribute, const char *data, int len);
    391 
    392 protected:
    393 
    394     /* Override this method to parse reply and dig out data; save it in the corresponding
    395        object */
    396     virtual int handleResponse(WifiEvent &reply);
    397 
    398     /* Override this method to parse event and dig out data; save it in the object */
    399     virtual int handleEvent(WifiEvent &event);
    400 };
    401 
    402 /* nl message processing macros (required to pass C++ type checks) */
    403 
    404 #define for_each_attr(pos, nla, rem) \
    405     for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
    406         nla_ok(pos, rem); \
    407         pos = (nlattr *)nla_next(pos, &(rem)))
    408 
    409 #endif
    410