Home | History | Annotate | Download | only in src
      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