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 */ 74 int 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( 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, 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