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