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     hal_info *mInfo;
    217     WifiRequest mMsg;
    218     Condition mCondition;
    219     wifi_request_id mId;
    220     interface_info *mIfaceInfo;
    221     int mRefs;
    222 public:
    223     WifiCommand(wifi_handle handle, wifi_request_id id)
    224             : mMsg(getHalInfo(handle)->nl80211_family_id), mId(id), mRefs(1)
    225     {
    226         mIfaceInfo = NULL;
    227         mInfo = getHalInfo(handle);
    228         // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
    229     }
    230 
    231     WifiCommand(wifi_interface_handle iface, wifi_request_id id)
    232             : mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), mId(id), mRefs(1)
    233     {
    234         mIfaceInfo = getIfaceInfo(iface);
    235         mInfo = getHalInfo(iface);
    236         // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
    237     }
    238 
    239     virtual ~WifiCommand() {
    240         // ALOGD("WifiCommand %p destroyed", this);
    241     }
    242 
    243     wifi_request_id id() {
    244         return mId;
    245     }
    246 
    247     virtual void addRef() {
    248         int refs = __sync_add_and_fetch(&mRefs, 1);
    249         // ALOGD("addRef: WifiCommand %p has %d references", this, refs);
    250     }
    251 
    252     virtual void releaseRef() {
    253         int refs = __sync_sub_and_fetch(&mRefs, 1);
    254         if (refs == 0) {
    255             delete this;
    256         } else {
    257             // ALOGD("releaseRef: WifiCommand %p has %d references", this, refs);
    258         }
    259     }
    260 
    261     virtual int create() {
    262         /* by default there is no way to cancel */
    263         ALOGD("WifiCommand %p can't be created", this);
    264         return WIFI_ERROR_NOT_SUPPORTED;
    265     }
    266 
    267     virtual int cancel() {
    268         /* by default there is no way to cancel */
    269         return WIFI_ERROR_NOT_SUPPORTED;
    270     }
    271 
    272     int requestResponse();
    273     int requestEvent(int cmd);
    274     int requestVendorEvent(uint32_t id, int subcmd);
    275     int requestResponse(WifiRequest& request);
    276 
    277 protected:
    278     wifi_handle wifiHandle() {
    279         return getWifiHandle(mInfo);
    280     }
    281 
    282     wifi_interface_handle ifaceHandle() {
    283         return getIfaceHandle(mIfaceInfo);
    284     }
    285 
    286     int familyId() {
    287         return mInfo->nl80211_family_id;
    288     }
    289 
    290     int ifaceId() {
    291         return mIfaceInfo->id;
    292     }
    293 
    294     /* Override this method to parse reply and dig out data; save it in the object */
    295     virtual int handleResponse(WifiEvent& reply) {
    296         ALOGI("skipping a response");
    297         return NL_SKIP;
    298     }
    299 
    300     /* Override this method to parse event and dig out data; save it in the object */
    301     virtual int handleEvent(WifiEvent& event) {
    302         ALOGI("skipping an event");
    303         return NL_SKIP;
    304     }
    305 
    306     int registerHandler(int cmd) {
    307         return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
    308     }
    309 
    310     void unregisterHandler(int cmd) {
    311         wifi_unregister_handler(wifiHandle(), cmd);
    312     }
    313 
    314     int registerVendorHandler(uint32_t id, int subcmd) {
    315         return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
    316     }
    317 
    318     void unregisterVendorHandler(uint32_t id, int subcmd) {
    319         wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
    320     }
    321 
    322 private:
    323     WifiCommand(const WifiCommand& );           // hide copy constructor to prevent copies
    324 
    325     /* Event handling */
    326     static int response_handler(struct nl_msg *msg, void *arg);
    327 
    328     static int event_handler(struct nl_msg *msg, void *arg);
    329 
    330     /* Other event handlers */
    331     static int valid_handler(struct nl_msg *msg, void *arg);
    332 
    333     static int ack_handler(struct nl_msg *msg, void *arg);
    334 
    335     static int finish_handler(struct nl_msg *msg, void *arg);
    336 
    337     static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
    338 };
    339 
    340 /* nl message processing macros (required to pass C++ type checks) */
    341 
    342 #define for_each_attr(pos, nla, rem) \
    343     for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
    344         nla_ok(pos, rem); \
    345         pos = (nlattr *)nla_next(pos, &(rem)))
    346 
    347