Home | History | Annotate | Download | only in wifi_hal
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Portions copyright (C) 2017 Broadcom Limited
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     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) {
    188         return create(mFamily, cmd, 0, 0);
    189     }
    190 
    191     int create(uint32_t id, int subcmd);
    192 
    193     int put(int attribute, void *ptr, unsigned len) {
    194         return nla_put(mMsg, attribute, len, ptr);
    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     int put_u64(int attribute, uint64_t value) {
    206         return nla_put(mMsg, attribute, sizeof(value), &value);
    207     }
    208     int put_string(int attribute, const char *value) {
    209         return nla_put(mMsg, attribute, strlen(value) + 1, value);
    210     }
    211     int put_addr(int attribute, mac_addr value) {
    212         return nla_put(mMsg, attribute, sizeof(mac_addr), value);
    213     }
    214 
    215     struct nlattr * attr_start(int attribute) {
    216         return nla_nest_start(mMsg, attribute);
    217     }
    218     void attr_end(struct nlattr *attr) {
    219         nla_nest_end(mMsg, attr);
    220     }
    221 
    222     int set_iface_id(int ifindex) {
    223         return put_u32(NL80211_ATTR_IFINDEX, ifindex);
    224     }
    225 private:
    226     WifiRequest(const WifiRequest&);        // hide copy constructor to prevent copies
    227 
    228 };
    229 
    230 class WifiCommand
    231 {
    232 protected:
    233     const char *mType;
    234     hal_info *mInfo;
    235     WifiRequest mMsg;
    236     Condition mCondition;
    237     wifi_request_id mId;
    238     interface_info *mIfaceInfo;
    239     int mRefs;
    240 public:
    241     WifiCommand(const char *type, wifi_handle handle, wifi_request_id id)
    242             : mType(type), mMsg(getHalInfo(handle)->nl80211_family_id), mId(id), mRefs(1)
    243     {
    244         mIfaceInfo = NULL;
    245         mInfo = getHalInfo(handle);
    246         // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
    247     }
    248 
    249     WifiCommand(const char *type, wifi_interface_handle iface, wifi_request_id id)
    250             : mType(type), mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id),
    251             mId(id), mRefs(1)
    252     {
    253         mIfaceInfo = getIfaceInfo(iface);
    254         mInfo = getHalInfo(iface);
    255         // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
    256     }
    257 
    258     virtual ~WifiCommand() {
    259         // ALOGD("WifiCommand %p destroyed", this);
    260     }
    261 
    262     wifi_request_id id() {
    263         return mId;
    264     }
    265 
    266     const char *getType() {
    267         return mType;
    268     }
    269 
    270     virtual void addRef() {
    271         int refs = __sync_add_and_fetch(&mRefs, 1);
    272         // ALOGD("addRef: WifiCommand %p has %d references", this, refs);
    273     }
    274 
    275     virtual void releaseRef() {
    276         int refs = __sync_sub_and_fetch(&mRefs, 1);
    277         if (refs == 0) {
    278             delete this;
    279         } else {
    280             // ALOGD("releaseRef: WifiCommand %p has %d references", this, refs);
    281         }
    282     }
    283 
    284     virtual int create() {
    285         /* by default there is no way to cancel */
    286         ALOGD("WifiCommand %p can't be created", this);
    287         return WIFI_ERROR_NOT_SUPPORTED;
    288     }
    289 
    290     virtual int cancel() {
    291         /* by default there is no way to cancel */
    292         return WIFI_ERROR_NOT_SUPPORTED;
    293     }
    294 
    295     int requestResponse();
    296     int requestEvent(int cmd);
    297     int requestVendorEvent(uint32_t id, int subcmd);
    298     int requestResponse(WifiRequest& request);
    299 
    300 protected:
    301     wifi_handle wifiHandle() {
    302         return getWifiHandle(mInfo);
    303     }
    304 
    305     wifi_interface_handle ifaceHandle() {
    306         return getIfaceHandle(mIfaceInfo);
    307     }
    308 
    309     int familyId() {
    310         return mInfo->nl80211_family_id;
    311     }
    312 
    313     int ifaceId() {
    314         return mIfaceInfo->id;
    315     }
    316 
    317     /* Override this method to parse reply and dig out data; save it in the object */
    318     virtual int handleResponse(WifiEvent& reply) {
    319         ALOGI("skipping a response");
    320         return NL_SKIP;
    321     }
    322 
    323     /* Override this method to parse event and dig out data; save it in the object */
    324     virtual int handleEvent(WifiEvent& event) {
    325         ALOGI("skipping an event");
    326         return NL_SKIP;
    327     }
    328 
    329     int registerHandler(int cmd) {
    330         return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
    331     }
    332 
    333     void unregisterHandler(int cmd) {
    334         wifi_unregister_handler(wifiHandle(), cmd);
    335     }
    336 
    337     int registerVendorHandler(uint32_t id, int subcmd) {
    338         return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
    339     }
    340 
    341     void unregisterVendorHandler(uint32_t id, int subcmd) {
    342         wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
    343     }
    344 
    345 private:
    346     WifiCommand(const WifiCommand& );           // hide copy constructor to prevent copies
    347 
    348     /* Event handling */
    349     static int response_handler(struct nl_msg *msg, void *arg);
    350 
    351     static int event_handler(struct nl_msg *msg, void *arg);
    352 
    353     /* Other event handlers */
    354     static int valid_handler(struct nl_msg *msg, void *arg);
    355 
    356     static int ack_handler(struct nl_msg *msg, void *arg);
    357 
    358     static int finish_handler(struct nl_msg *msg, void *arg);
    359 
    360     static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
    361 };
    362 
    363 /* nl message processing macros (required to pass C++ type checks) */
    364 
    365 #define for_each_attr(pos, nla, rem) \
    366     for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
    367         nla_ok(pos, rem); \
    368         pos = (nlattr *)nla_next(pos, &(rem)))
    369 
    370