Home | History | Annotate | Download | only in wifi_hal
      1 
      2 #include "wifi_hal.h"
      3 #include "common.h"
      4 #include "sync.h"
      5 
      6 class WifiEvent
      7 {
      8     /* TODO: remove this when nl headers are updated */
      9     static const unsigned NL80211_ATTR_MAX_INTERNAL = 256;
     10 private:
     11     struct nl_msg *mMsg;
     12     struct genlmsghdr *mHeader;
     13     struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1];
     14 
     15 public:
     16     WifiEvent(nl_msg *msg) {
     17         mMsg = msg;
     18         mHeader = NULL;
     19         memset(mAttributes, 0, sizeof(mAttributes));
     20     }
     21     ~WifiEvent() {
     22         /* don't destroy mMsg; it doesn't belong to us */
     23     }
     24 
     25     void log();
     26 
     27     int parse();
     28 
     29     genlmsghdr *header() {
     30         return mHeader;
     31     }
     32 
     33     int get_cmd() {
     34         return mHeader->cmd;
     35     }
     36 
     37     int get_vendor_id() {
     38         return get_u32(NL80211_ATTR_VENDOR_ID);
     39     }
     40 
     41     int get_vendor_subcmd() {
     42         return get_u32(NL80211_ATTR_VENDOR_SUBCMD);
     43     }
     44 
     45     void *get_vendor_data() {
     46         return get_data(NL80211_ATTR_VENDOR_DATA);
     47     }
     48 
     49     int get_vendor_data_len() {
     50         return get_len(NL80211_ATTR_VENDOR_DATA);
     51     }
     52 
     53     const char *get_cmdString();
     54 
     55     nlattr ** attributes() {
     56         return mAttributes;
     57     }
     58 
     59     nlattr *get_attribute(int attribute) {
     60         return mAttributes[attribute];
     61     }
     62 
     63     uint8_t get_u8(int attribute) {
     64         return mAttributes[attribute] ? nla_get_u8(mAttributes[attribute]) : 0;
     65     }
     66 
     67     uint16_t get_u16(int attribute) {
     68         return mAttributes[attribute] ? nla_get_u16(mAttributes[attribute]) : 0;
     69     }
     70 
     71     uint32_t get_u32(int attribute) {
     72         return mAttributes[attribute] ? nla_get_u32(mAttributes[attribute]) : 0;
     73     }
     74 
     75     uint64_t get_u64(int attribute) {
     76         return mAttributes[attribute] ? nla_get_u64(mAttributes[attribute]) : 0;
     77     }
     78 
     79     int get_len(int attribute) {
     80         return mAttributes[attribute] ? nla_len(mAttributes[attribute]) : 0;
     81     }
     82 
     83     void *get_data(int attribute) {
     84         return mAttributes[attribute] ? nla_data(mAttributes[attribute]) : NULL;
     85     }
     86 
     87 private:
     88     WifiEvent(const WifiEvent&);        // hide copy constructor to prevent copies
     89 };
     90 
     91 class nl_iterator {
     92     struct nlattr *pos;
     93     int rem;
     94 public:
     95     nl_iterator(struct nlattr *attr) {
     96         pos = (struct nlattr *)nla_data(attr);
     97         rem = nla_len(attr);
     98     }
     99     bool has_next() {
    100         return nla_ok(pos, rem);
    101     }
    102     void next() {
    103         pos = (struct nlattr *)nla_next(pos, &(rem));
    104     }
    105     struct nlattr *get() {
    106         return pos;
    107     }
    108     uint16_t get_type() {
    109         return pos->nla_type;
    110     }
    111     uint8_t get_u8() {
    112         return nla_get_u8(pos);
    113     }
    114     uint16_t get_u16() {
    115         return nla_get_u16(pos);
    116     }
    117     uint32_t get_u32() {
    118         return nla_get_u32(pos);
    119     }
    120     uint64_t get_u64() {
    121         return nla_get_u64(pos);
    122     }
    123     void* get_data() {
    124         return nla_data(pos);
    125     }
    126     int get_len() {
    127         return nla_len(pos);
    128     }
    129 private:
    130     nl_iterator(const nl_iterator&);    // hide copy constructor to prevent copies
    131 };
    132 
    133 class WifiRequest
    134 {
    135 private:
    136     int mFamily;
    137     int mIface;
    138     struct nl_msg *mMsg;
    139 
    140 public:
    141     WifiRequest(int family) {
    142         mMsg = NULL;
    143         mFamily = family;
    144         mIface = -1;
    145     }
    146 
    147     WifiRequest(int family, int iface) {
    148         mMsg = NULL;
    149         mFamily = family;
    150         mIface = iface;
    151     }
    152 
    153     ~WifiRequest() {
    154         destroy();
    155     }
    156 
    157     void destroy() {
    158         if (mMsg) {
    159             nlmsg_free(mMsg);
    160             mMsg = NULL;
    161         }
    162     }
    163 
    164     nl_msg *getMessage() {
    165         return mMsg;
    166     }
    167 
    168     /* Command assembly helpers */
    169     int create(int family, uint8_t cmd, int flags, int hdrlen);
    170     int create(uint8_t cmd) {
    171         return create(mFamily, cmd, 0, 0);
    172     }
    173 
    174     int create(uint32_t id, int subcmd);
    175 
    176     int put(int attribute, void *ptr, unsigned len) {
    177         return nla_put(mMsg, attribute, len, ptr);
    178     }
    179     int put_u8(int attribute, uint8_t value) {
    180         return nla_put(mMsg, attribute, sizeof(value), &value);
    181     }
    182     int put_u16(int attribute, uint16_t value) {
    183         return nla_put(mMsg, attribute, sizeof(value), &value);
    184     }
    185     int put_u32(int attribute, uint32_t value) {
    186         return nla_put(mMsg, attribute, sizeof(value), &value);
    187     }
    188     int put_u64(int attribute, uint64_t value) {
    189         return nla_put(mMsg, attribute, sizeof(value), &value);
    190     }
    191     int put_string(int attribute, const char *value) {
    192         return nla_put(mMsg, attribute, strlen(value) + 1, value);
    193     }
    194     int put_addr(int attribute, mac_addr value) {
    195         return nla_put(mMsg, attribute, sizeof(mac_addr), value);
    196     }
    197 
    198     struct nlattr * attr_start(int attribute) {
    199         return nla_nest_start(mMsg, attribute);
    200     }
    201     void attr_end(struct nlattr *attr) {
    202         nla_nest_end(mMsg, attr);
    203     }
    204 
    205     int set_iface_id(int ifindex) {
    206         return put_u32(NL80211_ATTR_IFINDEX, ifindex);
    207     }
    208 private:
    209     WifiRequest(const WifiRequest&);        // hide copy constructor to prevent copies
    210 
    211 };
    212 
    213 class WifiCommand
    214 {
    215 protected:
    216     const char *mType;
    217     hal_info *mInfo;
    218     WifiRequest mMsg;
    219     Condition mCondition;
    220     wifi_request_id mId;
    221     interface_info *mIfaceInfo;
    222     int mRefs;
    223 public:
    224     WifiCommand(const char *type, wifi_handle handle, wifi_request_id id)
    225             : mType(type), mMsg(getHalInfo(handle)->nl80211_family_id), mId(id), mRefs(1)
    226     {
    227         mIfaceInfo = NULL;
    228         mInfo = getHalInfo(handle);
    229         // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
    230     }
    231 
    232     WifiCommand(const char *type, wifi_interface_handle iface, wifi_request_id id)
    233             : mType(type), mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id),
    234             mId(id), mRefs(1)
    235     {
    236         mIfaceInfo = getIfaceInfo(iface);
    237         mInfo = getHalInfo(iface);
    238         // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
    239     }
    240 
    241     virtual ~WifiCommand() {
    242         // ALOGD("WifiCommand %p destroyed", this);
    243     }
    244 
    245     wifi_request_id id() {
    246         return mId;
    247     }
    248 
    249     const char *getType() {
    250         return mType;
    251     }
    252 
    253     virtual void addRef() {
    254         int refs = __sync_add_and_fetch(&mRefs, 1);
    255         // ALOGD("addRef: WifiCommand %p has %d references", this, refs);
    256     }
    257 
    258     virtual void releaseRef() {
    259         int refs = __sync_sub_and_fetch(&mRefs, 1);
    260         if (refs == 0) {
    261             delete this;
    262         } else {
    263             // ALOGD("releaseRef: WifiCommand %p has %d references", this, refs);
    264         }
    265     }
    266 
    267     virtual int create() {
    268         /* by default there is no way to cancel */
    269         ALOGD("WifiCommand %p can't be created", this);
    270         return WIFI_ERROR_NOT_SUPPORTED;
    271     }
    272 
    273     virtual int cancel() {
    274         /* by default there is no way to cancel */
    275         return WIFI_ERROR_NOT_SUPPORTED;
    276     }
    277 
    278     int requestResponse();
    279     int requestEvent(int cmd);
    280     int requestVendorEvent(uint32_t id, int subcmd);
    281     int requestResponse(WifiRequest& request);
    282 
    283 protected:
    284     wifi_handle wifiHandle() {
    285         return getWifiHandle(mInfo);
    286     }
    287 
    288     wifi_interface_handle ifaceHandle() {
    289         return getIfaceHandle(mIfaceInfo);
    290     }
    291 
    292     int familyId() {
    293         return mInfo->nl80211_family_id;
    294     }
    295 
    296     int ifaceId() {
    297         return mIfaceInfo->id;
    298     }
    299 
    300     /* Override this method to parse reply and dig out data; save it in the object */
    301     virtual int handleResponse(WifiEvent& reply) {
    302         ALOGI("skipping a response");
    303         return NL_SKIP;
    304     }
    305 
    306     /* Override this method to parse event and dig out data; save it in the object */
    307     virtual int handleEvent(WifiEvent& event) {
    308         ALOGI("skipping an event");
    309         return NL_SKIP;
    310     }
    311 
    312     int registerHandler(int cmd) {
    313         return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
    314     }
    315 
    316     void unregisterHandler(int cmd) {
    317         wifi_unregister_handler(wifiHandle(), cmd);
    318     }
    319 
    320     int registerVendorHandler(uint32_t id, int subcmd) {
    321         return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
    322     }
    323 
    324     void unregisterVendorHandler(uint32_t id, int subcmd) {
    325         wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
    326     }
    327 
    328 private:
    329     WifiCommand(const WifiCommand& );           // hide copy constructor to prevent copies
    330 
    331     /* Event handling */
    332     static int response_handler(struct nl_msg *msg, void *arg);
    333 
    334     static int event_handler(struct nl_msg *msg, void *arg);
    335 
    336     /* Other event handlers */
    337     static int valid_handler(struct nl_msg *msg, void *arg);
    338 
    339     static int ack_handler(struct nl_msg *msg, void *arg);
    340 
    341     static int finish_handler(struct nl_msg *msg, void *arg);
    342 
    343     static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
    344 };
    345 
    346 /* nl message processing macros (required to pass C++ type checks) */
    347 
    348 #define for_each_attr(pos, nla, rem) \
    349     for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
    350         nla_ok(pos, rem); \
    351         pos = (nlattr *)nla_next(pos, &(rem)))
    352 
    353