1a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam/*
2a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * Copyright (C) 2014 The Android Open Source Project
3a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam *
4a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * Licensed under the Apache License, Version 2.0 (the "License");
5a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * you may not use this file except in compliance with the License.
6a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * You may obtain a copy of the License at
7a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam *
8a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam *     http://www.apache.org/licenses/LICENSE-2.0
9a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam *
10a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * Unless required by applicable law or agreed to in writing, software
11a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * distributed under the License is distributed on an "AS IS" BASIS,
12a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * See the License for the specific language governing permissions and
14a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam * limitations under the License.
15a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam */
16a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam#ifndef __WIFI_HAL_CPP_BINDINGS_H__
17a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam#define __WIFI_HAL_CPP_BINDINGS_H__
18b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
19b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde#include "wifi_hal.h"
20b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde#include "common.h"
21b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde#include "sync.h"
22b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
23b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeclass WifiEvent
24b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde{
25b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    /* TODO: remove this when nl headers are updated */
26b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    static const unsigned NL80211_ATTR_MAX_INTERNAL = 256;
27b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeprivate:
28b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    struct nl_msg *mMsg;
29b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    struct genlmsghdr *mHeader;
30b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1];
31b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
32b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndepublic:
33b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiEvent(nl_msg *msg) {
34b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mMsg = msg;
35b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mHeader = NULL;
36b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        memset(mAttributes, 0, sizeof(mAttributes));
37b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
38b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    ~WifiEvent() {
39b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        /* don't destroy mMsg; it doesn't belong to us */
40b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
41b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
42b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void log();
43b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
44b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int parse();
45b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
46b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    genlmsghdr *header() {
47b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mHeader;
48b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
49b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
50b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int get_cmd() {
51b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mHeader->cmd;
52b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
53b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
54b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int get_vendor_id() {
55b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return get_u32(NL80211_ATTR_VENDOR_ID);
56b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
57b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
58b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int get_vendor_subcmd() {
59b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return get_u32(NL80211_ATTR_VENDOR_SUBCMD);
60b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
61b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
62b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void *get_vendor_data() {
63b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return get_data(NL80211_ATTR_VENDOR_DATA);
64b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
65b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
66b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int get_vendor_data_len() {
67b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return get_len(NL80211_ATTR_VENDOR_DATA);
68b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
69b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
70b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    const char *get_cmdString();
71b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
72b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    nlattr ** attributes() {
73b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mAttributes;
74b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
75b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
76b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    nlattr *get_attribute(int attribute) {
77b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mAttributes[attribute];
78b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
79b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
80b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint8_t get_u8(int attribute) {
81b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mAttributes[attribute] ? nla_get_u8(mAttributes[attribute]) : 0;
82b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
83b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
84b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint16_t get_u16(int attribute) {
85b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mAttributes[attribute] ? nla_get_u16(mAttributes[attribute]) : 0;
86b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
87b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
88b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint32_t get_u32(int attribute) {
89b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mAttributes[attribute] ? nla_get_u32(mAttributes[attribute]) : 0;
90b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
91b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
92b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint64_t get_u64(int attribute) {
93b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mAttributes[attribute] ? nla_get_u64(mAttributes[attribute]) : 0;
94b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
95b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
96b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int get_len(int attribute) {
97b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mAttributes[attribute] ? nla_len(mAttributes[attribute]) : 0;
98b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
99b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
100b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void *get_data(int attribute) {
101b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mAttributes[attribute] ? nla_data(mAttributes[attribute]) : NULL;
102b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
103b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
104b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeprivate:
105b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiEvent(const WifiEvent&);        // hide copy constructor to prevent copies
106b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde};
107b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
108b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeclass nl_iterator {
109b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    struct nlattr *pos;
110b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int rem;
111b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndepublic:
112b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    nl_iterator(struct nlattr *attr) {
113b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        pos = (struct nlattr *)nla_data(attr);
114b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        rem = nla_len(attr);
115b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
116b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    bool has_next() {
117b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_ok(pos, rem);
118b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
119b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void next() {
120b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        pos = (struct nlattr *)nla_next(pos, &(rem));
121b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
122b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    struct nlattr *get() {
123b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return pos;
124b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
125b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint16_t get_type() {
126b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return pos->nla_type;
127b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
128b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint8_t get_u8() {
129b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_get_u8(pos);
130b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
131b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint16_t get_u16() {
132b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_get_u16(pos);
133b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
134b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint32_t get_u32() {
135b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_get_u32(pos);
136b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
137b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    uint64_t get_u64() {
138b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_get_u64(pos);
139b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
140b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void* get_data() {
141b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_data(pos);
142b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
143b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int get_len() {
144b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_len(pos);
145b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
146b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeprivate:
147b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    nl_iterator(const nl_iterator&);    // hide copy constructor to prevent copies
148b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde};
149b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
150b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeclass WifiRequest
151b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde{
152b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeprivate:
153b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int mFamily;
154b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int mIface;
155b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    struct nl_msg *mMsg;
156b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
157b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndepublic:
158b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiRequest(int family) {
159b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mMsg = NULL;
160b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mFamily = family;
161b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mIface = -1;
162b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
163b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
164b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiRequest(int family, int iface) {
165b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mMsg = NULL;
166b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mFamily = family;
167b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mIface = iface;
168b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
169b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
170b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    ~WifiRequest() {
171b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        destroy();
172b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
173b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
174b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void destroy() {
175b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        if (mMsg) {
176b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde            nlmsg_free(mMsg);
177b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde            mMsg = NULL;
178b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        }
179b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
180b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
181b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    nl_msg *getMessage() {
182b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mMsg;
183b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
184b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
185b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    /* Command assembly helpers */
186b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int create(int family, uint8_t cmd, int flags, int hdrlen);
187a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    int create(uint8_t cmd, int flags, int hdrlen) {
188a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam        return create(mFamily, cmd, flags, hdrlen);
189a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    }
190b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int create(uint8_t cmd) {
191b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return create(mFamily, cmd, 0, 0);
192b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
193b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
194b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int create(uint32_t id, int subcmd);
195b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
196b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int put_u8(int attribute, uint8_t value) {
197b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_put(mMsg, attribute, sizeof(value), &value);
198b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
199b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int put_u16(int attribute, uint16_t value) {
200b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_put(mMsg, attribute, sizeof(value), &value);
201b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
202b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int put_u32(int attribute, uint32_t value) {
203b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_put(mMsg, attribute, sizeof(value), &value);
204b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
2058abcd11e6ffef0ed6948497ff03df2c55abc5bb9Amarnath Hullur Subramanyam
2068abcd11e6ffef0ed6948497ff03df2c55abc5bb9Amarnath Hullur Subramanyam    int put_s32(int attribute, int32_t value) {
2078abcd11e6ffef0ed6948497ff03df2c55abc5bb9Amarnath Hullur Subramanyam        return nla_put(mMsg, attribute, sizeof(int32_t), &value);
2088abcd11e6ffef0ed6948497ff03df2c55abc5bb9Amarnath Hullur Subramanyam    }
2098abcd11e6ffef0ed6948497ff03df2c55abc5bb9Amarnath Hullur Subramanyam
210b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int put_u64(int attribute, uint64_t value) {
211b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_put(mMsg, attribute, sizeof(value), &value);
212b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
213b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int put_string(int attribute, const char *value) {
214b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_put(mMsg, attribute, strlen(value) + 1, value);
215b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
216b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int put_addr(int attribute, mac_addr value) {
217b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_put(mMsg, attribute, sizeof(mac_addr), value);
218b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
219b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
220b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    struct nlattr * attr_start(int attribute) {
221b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return nla_nest_start(mMsg, attribute);
222b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
223b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void attr_end(struct nlattr *attr) {
224b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        nla_nest_end(mMsg, attr);
225b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
226b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
227b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int set_iface_id(int ifindex) {
228b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return put_u32(NL80211_ATTR_IFINDEX, ifindex);
229b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
230a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
231a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    int put_bytes(int attribute, const char *data, int len) {
232a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam        return nla_put(mMsg, attribute, len, data);
233a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    }
234b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeprivate:
235b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiRequest(const WifiRequest&);        // hide copy constructor to prevent copies
236b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
237b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde};
238b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
239b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeclass WifiCommand
240b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde{
241b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeprotected:
242b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    hal_info *mInfo;
243b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiRequest mMsg;
244b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    Condition mCondition;
245b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    wifi_request_id mId;
246b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    interface_info *mIfaceInfo;
247b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndepublic:
248b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiCommand(wifi_handle handle, wifi_request_id id)
249b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde            : mMsg(getHalInfo(handle)->nl80211_family_id), mId(id)
250b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    {
251b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mIfaceInfo = NULL;
252b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mInfo = getHalInfo(handle);
253b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
254b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
255b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
256b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiCommand(wifi_interface_handle iface, wifi_request_id id)
257b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde            : mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), mId(id)
258b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    {
259b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mIfaceInfo = getIfaceInfo(iface);
260b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        mInfo = getHalInfo(iface);
261b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        // ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
262b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
263b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
264b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    virtual ~WifiCommand() {
265b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        // ALOGD("WifiCommand %p destroyed", this);
266b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
267b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
268b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    wifi_request_id id() {
269b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mId;
270b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
271b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
272b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    virtual int create() {
273b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        /* by default there is no way to cancel */
274b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        ALOGD("WifiCommand %p can't be created", this);
275b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return WIFI_ERROR_NOT_SUPPORTED;
276b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
277b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
278b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    virtual int cancel() {
279b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        /* by default there is no way to cancel */
280b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return WIFI_ERROR_NOT_SUPPORTED;
281b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
282b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
283b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int requestResponse();
284b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int requestEvent(int cmd);
285b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int requestVendorEvent(uint32_t id, int subcmd);
286b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int requestResponse(WifiRequest& request);
287b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
288b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeprotected:
289b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    wifi_handle wifiHandle() {
290b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return getWifiHandle(mInfo);
291b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
292b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
293b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    wifi_interface_handle ifaceHandle() {
294b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return getIfaceHandle(mIfaceInfo);
295b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
296b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
297b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int familyId() {
298b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mInfo->nl80211_family_id;
299b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
300b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
301b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int ifaceId() {
302b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return mIfaceInfo->id;
303b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
304b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
305b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    /* Override this method to parse reply and dig out data; save it in the object */
306b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    virtual int handleResponse(WifiEvent& reply) {
307b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        ALOGI("skipping a response");
308b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return NL_SKIP;
309b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
310b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
311b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    /* Override this method to parse event and dig out data; save it in the object */
312b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    virtual int handleEvent(WifiEvent& event) {
313b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        ALOGI("skipping an event");
314b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return NL_SKIP;
315b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
316b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
317b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int registerHandler(int cmd) {
318b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
319b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
320b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
321b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void unregisterHandler(int cmd) {
322b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        wifi_unregister_handler(wifiHandle(), cmd);
323b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
324b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
325b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    int registerVendorHandler(uint32_t id, int subcmd) {
326b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
327b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
328b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
329b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    void unregisterVendorHandler(uint32_t id, int subcmd) {
330b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
331b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    }
332b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
333b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapndeprivate:
334b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    WifiCommand(const WifiCommand& );           // hide copy constructor to prevent copies
335b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
336b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    /* Event handling */
337b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    static int response_handler(struct nl_msg *msg, void *arg);
338b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
339b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    static int event_handler(struct nl_msg *msg, void *arg);
340b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
341b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    /* Other event handlers */
342b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    static int valid_handler(struct nl_msg *msg, void *arg);
343b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
344b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    static int ack_handler(struct nl_msg *msg, void *arg);
345b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
346b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    static int finish_handler(struct nl_msg *msg, void *arg);
347b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
348b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
349b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde};
350b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
351a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam//WifiVendorCommand class
352a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyamclass WifiVendorCommand: public WifiCommand
353a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam{
354a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyamprotected:
355a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    u32 mVendor_id;
356a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    u32 mSubcmd;
357a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    char *mVendorData;
358a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    u32 mDataLen;
359a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
360a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
361a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyampublic:
362a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    WifiVendorCommand(wifi_handle handle, wifi_request_id id, u32 vendor_id, u32 subcmd);
363a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
364a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual ~WifiVendorCommand();
365a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
366a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int create();
367a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
368a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int requestEvent();
369a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
370a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int put_u8(int attribute, uint8_t value);
371a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
372a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int put_u16(int attribute, uint16_t value);
373a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
374a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int put_u32(int attribute, uint32_t value);
375a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
3768abcd11e6ffef0ed6948497ff03df2c55abc5bb9Amarnath Hullur Subramanyam    virtual int put_s32(int attribute, int32_t value);
3778abcd11e6ffef0ed6948497ff03df2c55abc5bb9Amarnath Hullur Subramanyam
378a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int put_u64(int attribute, uint64_t value);
379a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
380a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int put_string(int attribute, const char *value);
381a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
382a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int put_addr(int attribute, mac_addr value);
383a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
384a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual struct nlattr * attr_start(int attribute);
385a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
386a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual void attr_end(struct nlattr *attribute);
387a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
388a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int set_iface_id(const char* name);
389a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
390a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int put_bytes(int attribute, const char *data, int len);
391a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
392a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyamprotected:
393a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
394a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    /* Override this method to parse reply and dig out data; save it in the corresponding
395a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam       object */
396a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int handleResponse(WifiEvent &reply);
397a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
398a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    /* Override this method to parse event and dig out data; save it in the object */
399a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam    virtual int handleEvent(WifiEvent &event);
400a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam};
401a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam
402b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde/* nl message processing macros (required to pass C++ type checks) */
403b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
404b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde#define for_each_attr(pos, nla, rem) \
405b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde    for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
406b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        nla_ok(pos, rem); \
407b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde        pos = (nlattr *)nla_next(pos, &(rem)))
408b573b879161949728b9cbdb0ef2dc8db32a47bfcVinit Deshapnde
409a779e36f603bbb1b3cd82afeeb4d519d69f6c9fcAmarnath Hullur Subramanyam#endif
410