1 /*
2 * ParsEvent.c
3 *
4 * Copyright 2001-2009 Texas Instruments, Inc. - http://www.ti.com/
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 /****************************************************************************
20 *
21 * MODULE: ParsEvent.c
22 *
23 * PURPOSE:
24 *
25 * DESCRIPTION:
26 * ============
27 *
28 *
29 ****************************************************************************/
30
31 /* includes */
32 /************/
33 #include <stdint.h>
34 #include <sys/types.h>
35 #ifdef ANDROID
36 #include <net/if_ether.h>
37 #else
38 #include <netinet/if_ether.h>
39 #endif
40 #include <linux/rtnetlink.h>
41 #include <net/if.h>
42 #include <linux/wireless.h>
43 #include "ParsEvent.h"
44 #include "cu_osapi.h"
45
46 #define IW_DESCR_FLAG_NONE 0x0000
47 #define IW_DESCR_FLAG_DUMP 0x0001
48 #define IW_DESCR_FLAG_EVENT 0x0002
49 #define IW_DESCR_FLAG_RESTRICT 0x0004
50 #define IW_DESCR_FLAG_NOMAX 0x0008
51 #define IW_DESCR_FLAG_WAIT 0x0100
52
53 /* local types */
54 /***************/
55 static int ParsEvent_GetEventParam( unsigned short uEventCmd,
56 unsigned int* uEventLen,
57 unsigned int* pEventFlag,
58 unsigned short* pMaxPayload,
59 unsigned short* pPayloadNum,
60 unsigned int* bIsPoint);
61 /**
62 * \fn ParsEvent_GetEvent()
63 * \brief get next event from the event stream.
64 * support the following events that CLI uses: SIOCGIWAP, SIOCGIWESSID, SIOCGIWNAME, SIOCGIWMODE,
65 * SIOCGIWFREQ, IWEVQUAL, SIOCGIWENCODE, SIOCGIWRATE, IWEVCUSTOM,
66 * IWEVMICHAELMICFAILURE, SIOCGIWSCAN, IWEVASSOCREQIE, IWEVASSOCRESPIE,
67 * IWEVPMKIDCAND.
68 * \note
69 * \param pEventStream - Event stream pointer.
70 * \param pEvent - return Event.
71 * \return value > 0 meens valide event
72 * \sa
73 */
ParsEvent_GetEvent(struct stream_descr * pEventStream,struct iw_event * pEvent)74 int
75 ParsEvent_GetEvent(struct stream_descr* pEventStream, struct iw_event* pEvent)
76
77 {
78 unsigned int uStatus = 0;
79 char* pPtr;
80 unsigned int uEventLen = 1;
81 unsigned int uDataLen = 0;
82 unsigned int uEventFlag = 0;
83 unsigned short uMaxPayload = 0;
84 unsigned short uPayloadNum = 0;
85 unsigned int uMoreLen;
86 unsigned int bIsPoint = 0;
87
88 /* Check validity */
89 if((pEventStream->current + IW_EV_LCP_LEN) > pEventStream->end)
90 {
91 return 0;
92 }
93
94 /* copy tha event */
95 os_memcpy((char *)pEvent, pEventStream->current, IW_EV_LCP_LEN);
96
97 /* Check validity */
98 if(pEvent->len <= IW_EV_LCP_LEN)
99 {
100 return 0;
101 }
102
103 /* get event parameters */
104 uStatus = ParsEvent_GetEventParam(
105 pEvent->cmd, &uEventLen, &uEventFlag, &uMaxPayload, &uPayloadNum, &bIsPoint);
106
107 if(uEventLen <= IW_EV_LCP_LEN)
108 {
109 /* jump to next event */
110 pEventStream->current += pEvent->len;
111 return 1;
112 }
113
114 /* get payload */
115 if(pEventStream->value == NULL)
116 {
117 pPtr = pEventStream->current + IW_EV_LCP_LEN;
118 }
119 else
120 {
121 pPtr = pEventStream->value;
122 }
123
124 uDataLen = uEventLen - IW_EV_LCP_LEN;
125
126 /* Check validity */
127 if((pPtr + uDataLen) > pEventStream->end)
128 {
129 /* jump to next event */
130 pEventStream->current += pEvent->len;
131 return 0;
132 }
133
134 if(bIsPoint == TRUE)
135 {
136 os_memcpy((char *) pEvent + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
137 pPtr, uDataLen);
138 }
139 else
140 {
141 os_memcpy((char *) pEvent + IW_EV_LCP_LEN, pPtr, uDataLen);
142 }
143
144 /* jump to next event */
145 pPtr = pPtr + uDataLen;
146
147 if(bIsPoint == FALSE)
148 {
149 /* verify more values */
150 if((pPtr + uDataLen) > (pEventStream->current + pEvent->len))
151 {
152 pEventStream->current += pEvent->len;
153 pEventStream->value = NULL;
154 }
155 else
156 {
157 pEventStream->value = pPtr;
158 }
159
160 }
161 else
162 {
163 uMoreLen = pEvent->len - uEventLen;
164
165 if((uMoreLen == 0) ||
166 ( uStatus == 0) ||
167 (!(uEventFlag & IW_DESCR_FLAG_NOMAX) && (pEvent->u.data.length > uMaxPayload)) ||
168 ((pEvent->u.data.length * uPayloadNum) > uMoreLen)
169 )
170 {
171 pEvent->u.data.pointer = NULL;
172 }
173 else
174 {
175 pEvent->u.data.pointer = pPtr;
176 }
177
178 pEventStream->current += pEvent->len;
179 }
180
181 return 1;
182 }
183
184
185 static int ParsEvent_GetEventParam( unsigned short uEventCmd,
186 unsigned int* uEventLen,
187 unsigned int* pEventFlag,
188 unsigned short* pMaxPayload,
189 unsigned short* pPayloadNum,
190 unsigned int* bIsPoint)
191 {
192
193 switch(uEventCmd)
194 {
195 case SIOCGIWAP:
196 *uEventLen = IW_EV_ADDR_LEN;
197 *pEventFlag = IW_DESCR_FLAG_DUMP;
198 *bIsPoint = FALSE;
199 break;
200
201 case SIOCGIWESSID:
202 *uEventLen = IW_EV_POINT_LEN;
203 *pEventFlag = IW_DESCR_FLAG_DUMP;
204 *pMaxPayload = IW_ESSID_MAX_SIZE + 1;
205 *pPayloadNum = 1;
206 *bIsPoint = TRUE;
207 break;
208
209 case SIOCGIWNAME:
210 *uEventLen = IW_EV_CHAR_LEN;
211 *pEventFlag = IW_DESCR_FLAG_DUMP;
212 *bIsPoint = FALSE;
213 break;
214 case SIOCGIWMODE:
215 *uEventLen = IW_EV_UINT_LEN;
216 *pEventFlag = IW_DESCR_FLAG_DUMP;
217 *bIsPoint = FALSE;
218 break;
219 case SIOCGIWFREQ:
220 *uEventLen = IW_EV_FREQ_LEN;
221 *pEventFlag = IW_DESCR_FLAG_DUMP;
222 *bIsPoint = FALSE;
223 break;
224 case IWEVQUAL:
225 *uEventLen = IW_EV_QUAL_LEN;
226 *bIsPoint = FALSE;
227 break;
228 case SIOCGIWENCODE:
229 *uEventLen = IW_EV_POINT_LEN;
230 *pEventFlag = IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT;
231 *pMaxPayload = IW_ENCODING_TOKEN_MAX;
232 *pPayloadNum = 1;
233 *bIsPoint = TRUE;
234 break;
235 case SIOCGIWRATE:
236 *uEventLen = IW_EV_PARAM_LEN;
237 *bIsPoint = FALSE;
238 break;
239 case IWEVCUSTOM:
240 *uEventLen = IW_EV_POINT_LEN;
241 *pMaxPayload = IW_CUSTOM_MAX;
242 *pPayloadNum = 1;
243 *bIsPoint = TRUE;
244 break;
245 case IWEVMICHAELMICFAILURE:
246 *uEventLen = IW_EV_POINT_LEN;
247 *pMaxPayload = sizeof(struct iw_michaelmicfailure);
248 *pPayloadNum = 1;
249 *bIsPoint = TRUE;
250 break;
251 case SIOCGIWSCAN:
252 *uEventLen = IW_EV_POINT_LEN;
253 *pEventFlag = IW_DESCR_FLAG_NOMAX;
254 *pMaxPayload = IW_SCAN_MAX_DATA;
255 *pPayloadNum = 1;
256 *bIsPoint = TRUE;
257 break;
258 case IWEVASSOCREQIE:
259 *uEventLen = IW_EV_POINT_LEN;
260 *pMaxPayload = IW_GENERIC_IE_MAX;
261 *pPayloadNum = 1;
262 *bIsPoint = TRUE;
263 break;
264 case IWEVASSOCRESPIE :
265 *uEventLen = IW_EV_POINT_LEN;
266 *pMaxPayload = IW_GENERIC_IE_MAX;
267 *pPayloadNum = 1;
268 *bIsPoint = TRUE;
269 break;
270 case IWEVPMKIDCAND:
271 *uEventLen = IW_EV_POINT_LEN;
272 *pMaxPayload = sizeof(struct iw_pmkid_cand);
273 *pPayloadNum = 1;
274 *bIsPoint = TRUE;
275 break;
276 default:
277 return 0;
278 }
279
280 return 1;
281 }
282
283