예제 #1
0
A_STATUS Abf_HciLibInit(A_UINT32 *btfiltFlags)
{        
#ifdef STATIC_LINK_HCILIBS
    pfn_HCIUTILS_RegisterHCINotification = HCIUTILS_RegisterHCINotification;
    pfn_HCIUTILS_SendCmd = HCIUTILS_SendCmd;
    pfn_HCIUTILS_UnRegisterHCINotification = HCIUTILS_UnRegisterHCINotification;
    /* We don't force to set ONLY DBUS flags here since we are static linking */
    return A_OK;
#else
    g_hciHandle = dlopen("hciutils.so", RTLD_NOW);
    if( g_hciHandle == NULL){
        A_ERR( "%s : Error loading library hciutils.so %s\n", __FUNCTION__, dlerror());
        return A_ERROR;
    } else {
        A_DEBUG( "Load hciutils.so successfully\n");
        pfn_HCIUTILS_RegisterHCINotification = dlsym(g_hciHandle, "HCIUTILS_RegisterHCINotification");
        pfn_HCIUTILS_SendCmd = dlsym(g_hciHandle, "HCIUTILS_SendCmd");
        pfn_HCIUTILS_UnRegisterHCINotification = dlsym(g_hciHandle, "HCIUTILS_UnRegisterHCINotification");
        if ( (NULL == pfn_HCIUTILS_RegisterHCINotification) || (NULL == pfn_HCIUTILS_SendCmd) || 
              (NULL == pfn_HCIUTILS_UnRegisterHCINotification) )
        {
		    A_ERR("ERROR GETTING HCIUTILS SYMBOLS \n");
            dlclose(g_hciHandle);
            g_hciHandle = NULL;
            return A_ERROR;
        }
        /* Make sure we enable ONLY DBUS flags */
        *btfiltFlags |= ABF_USE_ONLY_DBUS_FILTERING;
        return A_OK;
    }
#endif
}
예제 #2
0
파일: http.c 프로젝트: nqv/aranea
/** Parse each line of the header
 */
static
char *http_parse_header(struct request_t *self, char *data, int len) {
    char *val, *end;

    /* search for "key: value" */
    val = memchr(data, ':', len);
    if (val == NULL) {
        A_ERR("no delimiter %d: %.*s", len, len, data);
        return NULL;
    }
    *val = '\0';
    ++val;
    while (*val == ' ') {           /* skip spaces */
        ++val;
    }
    len -= val - data;
    if (len <= 0) {
        A_ERR("no val %d", len);
        return NULL;
    }
    end = memchr(val, '\n', len);
    if (end == NULL) {
        A_ERR("no line ending %d: %.*s", len, len, val);
        return NULL;
    }
    if (*(end - 1) == '\r') {       /* \r\n */
        *(end - 1) = '\0';
    } else {
        *end = '\0';
    }
    /* check if the header is supported */
    http_save_header(self, data, val);
    return end + 1;
}
예제 #3
0
파일: http.c 프로젝트: nqv/aranea
/**
 * Only get the first range if a list is given
 */
static
void http_parse_range(struct request_t *self, char *val) {
    char *delim;

    if (strncmp(val, "bytes=", 6) != 0) {
        A_ERR("ranges are not in bytes: %s", val);
        return;
    }
    val += 6;
    delim = strchr(val, '-');
    if (delim == NULL) {
        A_ERR("no hyphen: %s", val);
        return;
    }
    if (delim == val) {         /* range_from is not given */
        self->range_from = NULL;
    } else {
        *delim = '\0';
        self->range_from = val;
    }
    self->range_to = delim + 1;
    delim = strchr(self->range_to, ',');
    if (delim != NULL) {
        *delim = '\0';          /* only the first range in the list */
    }
}
예제 #4
0
A_STATUS
Abf_WlanIssueFrontEndConfig(ATHBT_FILTER_INFO * pInfo)
{
    WMI_SET_BTCOEX_FE_ANT_CMD btcoexFeAntCmd;
    WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD btcoexCoLocatedBtCmd;
    A_UINT32  buf_fe_ant_cmd[sizeof(A_UINT32) + sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)];
    A_UINT32  buf_co_located_bt_cmd[sizeof(A_UINT32) + sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)];
    A_STATUS status;

    /* Set co-located bt type to 1, generic for any PTA based bluetooth */
    buf_co_located_bt_cmd[0] = AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV;

    if (pInfo->Flags & ABF_BT_CHIP_IS_QCOM) {
        btcoexCoLocatedBtCmd.btcoexCoLocatedBTdev = 2;
    } else {
        btcoexCoLocatedBtCmd.btcoexCoLocatedBTdev = 1;
    }

    A_MEMCPY(&buf_co_located_bt_cmd[1], (void *)&btcoexCoLocatedBtCmd,
             sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));

    status = Abf_WlanDispatchIO(pInfo, AR6000_IOCTL_EXTENDED,
                                (void *)buf_co_located_bt_cmd,
                                (sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD) + sizeof(A_UINT32)));

    if (A_FAILED(status)) {
        A_ERR("[%s] Failed to issue Co-located BT configuration\n", __FUNCTION__);
        return A_ERROR;
    }

    if(pInfo->Flags & ABF_FE_ANT_IS_SA) {
        /* Indicate front end antenna configuration as single antenna  */
        A_INFO("FLAGS = %x, Issue FE antenna configuration as single \n", pInfo->Flags);
        btcoexFeAntCmd.btcoexFeAntType = WMI_BTCOEX_FE_ANT_SINGLE;
    }else {
        A_INFO("FLAGS = %x, Issue FE antenna configuration as dual \n", pInfo->Flags);
        btcoexFeAntCmd.btcoexFeAntType = WMI_BTCOEX_FE_ANT_DUAL;
    }

    buf_fe_ant_cmd[0] = AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT;

    A_MEMCPY(&buf_fe_ant_cmd[1], (void *)&btcoexFeAntCmd, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));


    status = Abf_WlanDispatchIO(pInfo, AR6000_IOCTL_EXTENDED,
                                (void *)buf_fe_ant_cmd,
                                (sizeof(WMI_SET_BTCOEX_FE_ANT_CMD) + sizeof(A_UINT32)));

    if (A_FAILED(status)) {
        A_ERR("[%s] Failed to issue FE ant configuration\n", __FUNCTION__);
        return A_ERROR;
    }

    return A_OK;

}
void Abf_WlanCheckSettings(A_CHAR *wifname, A_UINT32 *btfiltFlags)
{
    int sd;
#ifdef ANDROID 
    char ifprop[PROPERTY_VALUE_MAX];
    if (wifname[0] == '\0' && property_get("wifi.interface", ifprop, NULL)) {
        strcpy(wifname, ifprop);
    }
#endif

    if (wifname[0] == '\0') {
        char linebuf[1024];
        FILE *f = fopen("/proc/net/wireless", "r");
        if (f) {
            while(fgets(linebuf, sizeof(linebuf)-1, f)) {
                if (strchr(linebuf, ':')) {
                    char *dest = wifname;
                    char *p = linebuf;
                    while(*p && isspace(*p)) ++p;
                    while (*p && *p != ':')
                        *dest++ = *p++;
                    *dest = '\0';
                    break;
                }
            }
            fclose(f);
        }
    }
    A_DEBUG("%s : wlan: %s\n", __FUNCTION__, wifname);
    if (wifname[0] == '\0') {
        return;
    }

    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        A_ERR("[%s] Error creating socket: %d\n", __FUNCTION__, sd);
        return;
    }

    do {
        A_UINT32 flags = *btfiltFlags;
        struct ifreq ifr;
        struct ar6000_version revinfo;
        A_MEMZERO(&revinfo, sizeof(revinfo));
        strncpy(ifr.ifr_name, wifname, sizeof(ifr.ifr_name));
        ifr.ifr_data = (void *)&revinfo;
        if (ioctl(sd, AR6000_IOCTL_WMI_GETREV, &ifr) < 0) {
            break;              
        }                       
        if ( (revinfo.target_ver & 0xff000000)==0x30000000) {
            *btfiltFlags |= ABF_WIFI_CHIP_IS_VENUS;
        } else {
            *btfiltFlags &= ~ABF_WIFI_CHIP_IS_VENUS;
        }
        if (*btfiltFlags != flags) {
            A_DEBUG("Change btfilt flags from %u to %u isVenus %d\n", flags, *btfiltFlags, 
                        (*btfiltFlags & ABF_WIFI_CHIP_IS_VENUS) ? "yes" : "no");
        }
    } while (0);
    close(sd);
}
예제 #6
0
A_STATUS  Abf_IssueAFHViaHciLib (ABF_BT_INFO  * pAbfBtInfo,
                                int CurrentWLANChannel)
{
    A_UINT32 center;
    tHCIUTILS_HCICMD_SET_AFH_CHANNELS setChannels;

    A_INFO("WLAN Operating Channel: %d \n", CurrentWLANChannel);

    if(!CurrentWLANChannel) {
        setChannels.first = 79;
        setChannels.last = 79;
        center = 0;
   }else {
        if( (CurrentWLANChannel < 2412) || 
           (CurrentWLANChannel >  2470))
        {
            return A_ERROR;
        }
        center = CurrentWLANChannel;
        center = center - 2400;
        setChannels.first = center - 10;
        setChannels.last = center + 10;
  }

    if (pfn_HCIUTILS_SendCmd) {
        (*pfn_HCIUTILS_SendCmd) (HCIUTILS_SET_AFH_CHANNELS, &setChannels);
        A_DEBUG("Issue AFH first =%x, last = %x, center =%x\n",
                setChannels.first, setChannels.last, center);
    } else {
        A_ERR( "%s : Fail to issue AFH due to NULL pointer of pfn_HCIUTILS_SendCmd\n", __FUNCTION__);
        return A_ERROR;
    }

   return A_OK;
}
예제 #7
0
A_STATUS
Abf_WlanDispatchIO(ATHBT_FILTER_INFO *pInfo, unsigned long int req, 
                   void *data, int size)
{
    int ret;
    struct ifreq ifr;
    char ifname[IFNAMSIZ], *ethIf;
    ABF_WLAN_INFO *pAbfWlanInfo = pInfo->pWlanInfo;
    ATH_BT_FILTER_INSTANCE *pInstance = pInfo->pInstance;
 
    if (!pAbfWlanInfo->Handle) {
        /* No adapter to issue ioctl on */
        return A_DEVICE_NOT_FOUND;
    }

    /* Get the adpater name from command line if specified */
    if (pInstance->pWlanAdapterName != NULL) {
        ethIf = pInstance->pWlanAdapterName;
    } else {
        if ((ethIf = getenv("NETIF")) == NULL) {
            ethIf = pAbfWlanInfo->IfName;
        }
    }
    /* Frame and issue the requested ioctl to the WLAN adapter */
    A_MEMZERO(ifname, IFNAMSIZ);
    strcpy(ifname, ethIf);
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    ifr.ifr_data = (void *)data;
    if ((ret = ioctl(pAbfWlanInfo->Handle, req, &ifr)) < 0) {
        A_ERR("[%s] [%s] IOCTL (req:0x%X, data: 0x%X size:%d) call failed!: %d\n", 
            __FUNCTION__, ifr.ifr_name, req, (A_UINT32)ifr.ifr_data, size, ret);
        return A_ERROR;
    }
    return A_OK;
}
예제 #8
0
/* APIs exported to other modules */
A_STATUS
Abf_WlanStackNotificationInit(ATH_BT_FILTER_INSTANCE *pInstance, A_UINT32 flags)
{
    A_STATUS status;
    ATHBT_FILTER_INFO *pInfo;
    ABF_WLAN_INFO *pAbfWlanInfo;

    pInfo = (ATHBT_FILTER_INFO *)pInstance->pContext;
    if (pInfo->pWlanInfo) {
        return A_OK;
    }

    pAbfWlanInfo = (ABF_WLAN_INFO *)A_MALLOC(sizeof(ABF_WLAN_INFO));
    A_MEMZERO(pAbfWlanInfo,sizeof(ABF_WLAN_INFO));

    A_MUTEX_INIT(&pAbfWlanInfo->hWaitEventLock);
    A_COND_INIT(&pAbfWlanInfo->hWaitEvent);
    A_MEMZERO(pAbfWlanInfo, sizeof(ABF_WLAN_INFO));
    pAbfWlanInfo->pInfo = pInfo;
    pAbfWlanInfo->Loop = TRUE;
    pInfo->pWlanInfo = pAbfWlanInfo;

    /* Spawn a thread which will be used to process events from WLAN */
    status = A_TASK_CREATE(&pInfo->hWlanThread, WlanEventThread, pAbfWlanInfo);
    if (A_FAILED(status)) {
        A_ERR("[%s] Failed to spawn a WLAN thread\n", __FUNCTION__);
        return A_ERROR;
    }

    A_INFO("WLAN Stack Notification init complete\n");

    return A_OK;
}
예제 #9
0
static A_STATUS
GetAdapterInfo(ABF_WLAN_INFO *pAbfWlanInfo)
{
    A_STATUS status;
    struct ar6000_version *revinfo;

    revinfo = (struct ar6000_version *)A_MALLOC(sizeof(struct ar6000_version));

    if (revinfo == NULL) {
        A_ERR("[%s] Failed to alloc WLAN revision info\n", __FUNCTION__);
        return A_ERROR;    
    }

 
    /* Get the revision info */
    status = Abf_WlanDispatchIO(pAbfWlanInfo->pInfo, AR6000_IOCTL_WMI_GETREV, 
                                (void *)revinfo, sizeof(struct ar6000_version));
    if (A_FAILED(status)) {
        A_ERR("[%s] Failed to get WLAN revision\n", __FUNCTION__);
        return A_ERROR;
    }

    pAbfWlanInfo->HostVersion = revinfo->host_ver;
    pAbfWlanInfo->TargetVersion = revinfo->target_ver;
    A_INFO("Host Rev: 0x%x(%u.%u.%u.%u), Target Rev: 0x%x(%u.%u.%u.%u)\n",
           revinfo->host_ver,
           ((revinfo->host_ver)&0xf0000000)>>28,
           ((revinfo->host_ver)&0x0f000000)>>24,
           ((revinfo->host_ver)&0x00ff0000)>>16,
           ((revinfo->host_ver)&0x0000ffff),
           revinfo->target_ver,
           ((revinfo->target_ver)&0xf0000000)>>28,
           ((revinfo->target_ver)&0x0f000000)>>24,
           ((revinfo->target_ver)&0x00ff0000)>>16,
           ((revinfo->target_ver)&0x0000ffff));

    A_FREE(revinfo);

    return A_OK;
}
예제 #10
0
/* Mutual exclusion operations */
INLINE A_STATUS
A_MUTEX_INIT(A_MUTEX_OBJECT *mutex)
{
    int ret;

    ret = pthread_mutex_init(mutex, NULL);
    if (ret) {
        A_ERR("%s Failed: %d\n", __FUNCTION__, ret);
        return A_ERROR;
    }

    return A_OK;
}
예제 #11
0
/* Conditional Variable operations */
INLINE A_STATUS
A_COND_INIT(A_COND_OBJECT *cond)
{
    int ret;

    ret = pthread_cond_init(cond, NULL);
    if (ret) {
        A_ERR("%s Failed: %d\n", __FUNCTION__, ret);
        return A_ERROR;
    }

    return A_OK;
}
예제 #12
0
INLINE A_STATUS
A_TASK_JOIN(A_TASK_HANDLE *handle)
{
    int ret;

    ret = pthread_join(*handle, NULL);
    if (ret) {
        A_ERR("%s Failed: %d\n", __FUNCTION__, ret);
        return A_ERROR;
    }

    return A_OK;
}
예제 #13
0
void CAListener::SetVel( const TVec &roVel ) const
{
#ifdef A_USE_OAL_DUMMY
#else
	ALint iError;
	alGetError();
	alListenerfv( AL_VELOCITY, roVel );
	if( ( iError = alGetError() ) != AL_NO_ERROR )
	{
		A_ERR( "alListenerfv VELOCITY (%s)\n", GetALErrorString_( iError ) );
		return;
	}
#endif // A_USE_OAL_DUMMY
}
예제 #14
0
void CAListener::SetPos( const TVec &roPos ) const
{
#ifdef A_USE_OAL_DUMMY
#else
	ALint iError;
	alGetError();
	alListenerfv( AL_POSITION, roPos );
	if( ( iError = alGetError() ) != AL_NO_ERROR )
	{
		A_ERR( "alListenerfv POSITION (%s)\n", GetALErrorString_( iError ) );
		return;
	}
#endif // A_USE_OAL_DUMMY
}
예제 #15
0
static A_STATUS
AcquireWlanAdapter(ABF_WLAN_INFO *pAbfWlanInfo)
{
    int sd;
    A_STATUS status;

    if (pAbfWlanInfo->Handle != 0) {
        return A_OK;    
    }

    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        A_ERR("[%s] Error creating socket: %d\n", __FUNCTION__, sd);
        return A_ERROR;
    }

    pAbfWlanInfo->Handle = sd;
    status = GetAdapterInfo(pAbfWlanInfo);
    if (A_FAILED(status)) {
        A_ERR("[%s] Failed to get Adapter Info\n", __FUNCTION__);
        close(sd);
        pAbfWlanInfo->Handle = 0;
        return A_ERROR;
    } else {
        /* Try to get RTS to determinate that wlan is enabled */
        A_UCHAR buf[sizeof(int)+sizeof(WMI_SET_RTS_CMD)];
        ((int *)buf)[0] = AR6000_XIOCTL_AP_GET_RTS;
        status = Abf_WlanDispatchIO(pAbfWlanInfo->pInfo, AR6000_IOCTL_EXTENDED, 
                                (void *)buf, sizeof(buf));
        if (A_FAILED(status)) {
            A_INFO("WMI is ready but wlan is disabled.\n");
            return A_ERROR;
        }
    }

    return A_OK;
}
예제 #16
0
void CAListener::SetAmp( float fAmp ) const
{
#ifdef A_USE_OAL_DUMMY
#else
	// Position.
	ALint iError;
	alGetError();
	alListenerfv( AL_GAIN, &fAmp );
	if( ( iError = alGetError() ) != AL_NO_ERROR )
	{
		A_ERR( "alListenerfv GAIN (%s)\n", GetALErrorString_( iError ) );
		return;
	}
#endif // A_USE_OAL_DUMMY
}
예제 #17
0
A_STATUS
Abf_WlanGetSleepState(ATHBT_FILTER_INFO * pInfo)
{
    /* setup ioctl cmd */
    A_UINT32 cmd = AR6000_XIOCTL_GET_WLAN_SLEEP_STATE;

    A_STATUS status = Abf_WlanDispatchIO(pInfo, AR6000_IOCTL_EXTENDED,
                                         (void *)&cmd,
                                         sizeof(A_UINT32));

    if (A_FAILED(status)) {
        A_ERR("[%s] Failed to issue get WLAN sleep state\n", __FUNCTION__);
        return A_ERROR;
    }

    return A_OK;
}
예제 #18
0
/* Task specific operations */
INLINE A_STATUS
A_TASK_CREATE(A_TASK_HANDLE *handle, void *(*func)(void *), void *arg)
{
    int ret;
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    ret = pthread_create(handle, &attr, func, arg);
    if (ret) {
        A_ERR("%s Failed: %d\n", __FUNCTION__, ret);
        return A_ERROR;
    }

    pthread_attr_destroy(&attr);
    return A_OK;
}
예제 #19
0
파일: http.c 프로젝트: nqv/aranea
const char *http_string_status(int code) {
    if (code < 300) {               /* 2xx */
        switch (code) {
        case HTTP_STATUS_OK:
            return "OK";
        case HTTP_STATUS_PARTIALCONTENT:
            return "Partial Content";
        }
    } else if (code < 400) {        /* 3xx */
        switch (code) {
        case HTTP_STATUS_MOVEDPERMANENTLY:
            return "Moved Permanently";
        case 302:
            return "Moved Temporarily ";
        case 303:
            return "See Other";
        case HTTP_STATUS_NOTMODIFIED:
            return "Not Modified";
        }
    } else if (code < 500) {        /* 4xx */
        switch (code) {
        case HTTP_STATUS_BADREQUEST:
            return "Bad Request";
        case HTTP_STATUS_AUTHORIZATIONREQUIRED:
            return "Authorization Required";
        case HTTP_STATUS_FORBIDDEN:
            return "Forbidden";
        case HTTP_STATUS_NOTFOUND:
            return "Not Found";
        case HTTP_STATUS_ENTITYTOOLARGE:
            return "Request Entity Too Large";
        case HTTP_STATUS_RANGENOTSATISFIABLE:
            return "Requested Range Not Satisfiable";
        }
    } else {
        switch (code) {             /* 5xx */
        case HTTP_STATUS_SERVERERROR:
            return "Server Error";
        case HTTP_STATUS_NOTIMPLEMENTED:
            return "Not Implemented";
        }
    }
    A_ERR("unknown code %d", code);
    return "Unknown";
}
예제 #20
0
파일: http.c 프로젝트: nqv/aranea
/** Parse the initial request line
 * Also modify data of client (padding NULL)
 * @return position of the last char parsed
 *         NULL on error
 */
static
char *http_parse_request(struct request_t *self, char *data, int len) {
    char *end;

    /* method */
    end = memchr(data, ' ', len);
    if (end == NULL) {
        A_ERR("no method %d: %.*s", len, len, data);
        return NULL;
    }
    *end = '\0';
    self->method = data;
    /* url */
    len -= end - data + 1;
    if (len <= 0) {
        A_ERR("no url %d", len);
        return NULL;
    }
    data = end + 1;
    if (*data != '/') {
        A_ERR("url does not start with / %.*s", len, data);
        return NULL;
    }
    end = memchr(data + 1, ' ', len);       /* already know the first char */
    if (end == NULL) {
        A_ERR("no url %d: %.*s", len, len, data);
        return NULL;
    }
    *end = '\0';
    self->url = data;
    /* query string in url */
    self->query_string = http_parse_querystring(self->url);
    /* version */
    len -= end - data + 1;
    if (len <= 0) {
        A_ERR("no version %d", len);
        return NULL;
    }
    data = end + 1;
    end = memchr(data, '\n', len);
    if (end == NULL) {
        A_ERR("no version %d: %.*s", len, len, data);
        return NULL;
    }
    if (*(end - 1) == '\r') {           /* \r\n */
        *(end - 1) = '\0';
    } else {
        *end = '\0';
    }
    self->version = data;
    return end + 1;
}
예제 #21
0
void CAListener::SetOrient( const TVec &roOrient, const TVec &roUp ) const
{
#ifdef A_USE_OAL_DUMMY
#else
	ALint iError;
	alGetError();
	
	// http://www.gamedev.net/community/forums/topic.asp?topic_id=389321
	const ALfloat afOri[] = {
		roOrient[0], roOrient[1], roOrient[2],
		roUp[0], roUp[1], roUp[2]
	};
	alListenerfv( AL_ORIENTATION, afOri );
	if( ( iError = alGetError() ) != AL_NO_ERROR )
	{
		A_ERR( "alListenerfv ORIENTATION (%s)\n", GetALErrorString_( iError ) );
		return;
	}
#endif // A_USE_OAL_DUMMY
}
예제 #22
0
INLINE A_STATUS
A_COND_WAIT(A_COND_OBJECT *cond, A_MUTEX_OBJECT *mutex, int timeout)
{
    int ret;
    struct timespec ts;

    if (timeout != WAITFOREVER) {
        /* TODO: support for values equal to or more than a second */
        clock_gettime(CLOCK_REALTIME, &ts);
        ts.tv_nsec += (timeout * 1000000);
        ret = pthread_cond_timedwait(cond, mutex, &ts);
    } else {
        ret = pthread_cond_wait(cond, mutex);
    }

    if (ret) {
        A_ERR("%s Failed: %d\n", __FUNCTION__, ret);
        return A_ERROR;
    }

    return A_OK;
}
예제 #23
0
static void
WirelessEvent(ATH_BT_FILTER_INSTANCE *pInstance, char *data, int len)
{
    int event_type = 0;
    A_STATUS status = A_OK;
    unsigned int event_len = 1;
    struct iw_event iwe_buf, *iwe = &iwe_buf;
    char *pos, *end, *buf, *ptr, *custom;

    pos = data;
    end = data + len;

    while ((pos + IW_EV_LCP_PK_LEN <= end) && (status == A_OK)) {
        /* 
         * Event data may be unaligned, so make a local, aligned copy 
         * before processing 
         */
        A_MEMCPY((char *)iwe, pos, IW_EV_LCP_PK_LEN);
        //A_DEBUG("Wireless Event: cmd=0x%x len=%d\n", iwe->cmd, iwe->len);
        if (iwe->len <= IW_EV_LCP_PK_LEN) {
            A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
            break;
        }

        /* 
         * Get the type and length of that event. We will assume it 
         * instead of deriving it since its a lengthy process. May be 
         * some day ... TODO 
         */
        event_type = IW_HEADER_TYPE_POINT;
        event_len = IW_EV_POINT_PK_LEN;

        if ((WIRELESS_EXT <= 18) && (event_type == IW_HEADER_TYPE_POINT)) {
            event_len += IW_EV_POINT_OFF;
        }

        if (event_len <= IW_EV_LCP_PK_LEN) {
            A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
            break;
        }
        event_len -= IW_EV_LCP_PK_LEN;
        ptr = pos + IW_EV_LCP_PK_LEN;

        if((WIRELESS_EXT > 18) && (event_type == IW_HEADER_TYPE_POINT)) {
            A_MEMCPY((char *) iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
                      ptr, event_len);
        } else {
            A_MEMCPY((char *) iwe + IW_EV_LCP_LEN, ptr, event_len);
        }

        switch (iwe->cmd) {
        case SIOCGIWAP:
            break;
        case IWEVCUSTOM:
            custom = pos + IW_EV_POINT_LEN;
            if (custom + iwe->u.data.length > end) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            buf = A_MALLOC(iwe->u.data.length + 1);
            if (buf == NULL) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            A_MEMCPY(buf, custom, iwe->u.data.length);
            status = WirelessCustomEvent(pInstance, buf, iwe->u.data.length);
            A_FREE(buf);
            break;
        case SIOCGIWSCAN:
            break;
        case SIOCSIWESSID:
            break;
        default:
            break;
        }

        pos += iwe->len;
    }
}
예제 #24
0
static A_STATUS
WirelessCustomEvent(ATH_BT_FILTER_INSTANCE *pInstance, char *buf, int len)
{
    char *ptr;
    int length, i;
    A_UINT16 eventid;
    WMI_READY_EVENT *ev1;
    WMI_CONNECT_EVENT *ev2;
    WMI_REPORT_SLEEP_STATE_EVENT * ev3;
    A_STATUS status = A_OK;
    ATHBT_FILTER_INFO *pInfo = (ATHBT_FILTER_INFO *)pInstance->pContext;
    ABF_WLAN_INFO *pAbfWlanInfo = pInfo->pWlanInfo;

    do {
        eventid = *((A_UINT16 *)buf);
        ptr = buf + 2; //Skip the event id
        length = len - 2;
        switch (eventid) {
        case (WMI_READY_EVENTID):
            if (length < sizeof(WMI_READY_EVENT)) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            ev1 = (WMI_READY_EVENT *)ptr;
            A_MEMCPY(pAbfWlanInfo->AdapterName, ev1->macaddr, ATH_MAC_LEN);
            pAbfWlanInfo->PhyCapability = ev1->phyCapability;
            A_DEBUG("WMI READY: Capability: %d, Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", 
                    pAbfWlanInfo->PhyCapability, 
                    (pAbfWlanInfo->AdapterName[0]), 
                    (pAbfWlanInfo->AdapterName[1]),
                    (pAbfWlanInfo->AdapterName[2]),
                    (pAbfWlanInfo->AdapterName[3]), 
                    (pAbfWlanInfo->AdapterName[4]),
                    (pAbfWlanInfo->AdapterName[5]));

            /*
             * Open a handle for the ioctls that will be issued later
             * Try 10 times because the driver may not yet be ready to receive
             * IOCTLs, so we give the driver time to get ready by looping here
             */
            for (i = 0; i <= 10; i++) {
                status = AcquireWlanAdapter(pAbfWlanInfo);
                if (A_SUCCESS(status)) {
                    break; /* Break out of FOR loop, but not out of switch case statement */
		}
                sleep(1);
            }

            if (A_FAILED(status)) {
                A_ERR("[%s] Failed to acquire WLAN adapter\n", __FUNCTION__);
                break;
            }

            /* Communicate this to the Filter task */
            HandleAdapterEvent(pInfo, ATH_ADAPTER_ARRIVED);
            A_INFO("WLAN Adapter Added\n");
            break;    
        case (WMI_CONNECT_EVENTID):
            if (length < sizeof(WMI_CONNECT_EVENT)) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            ev2 = (WMI_CONNECT_EVENT *)ptr;
            pAbfWlanInfo->Channel = ev2->u.infra_ibss_bss.channel;
            A_DEBUG("WMI CONNECT: Channel: %d\n", ev2->u.infra_ibss_bss.channel);
            IndicateCurrentWLANOperatingChannel(pInfo, pAbfWlanInfo->Channel);
            break;
        case (WMI_DISCONNECT_EVENTID):
            A_DEBUG("WMI DISCONNECT: %d\n", len);
            IndicateCurrentWLANOperatingChannel(pInfo, 0);
            break;
        case (WMI_ERROR_REPORT_EVENTID):
            A_DEBUG("WMI ERROR REPORT: %d\n", len);
            break;
        case (WMI_SCAN_COMPLETE_EVENTID):
            A_DEBUG("WMI SCAN COMPLETE: %d\n", len);
            break;
        case (WMI_REPORT_SLEEP_STATE_EVENTID):
            A_DEBUG("WMI_REPORT_SLEEP_STATE_EVENTID: %d\n", len);
            if(length < sizeof(WMI_REPORT_SLEEP_STATE_EVENT)) {
                A_ERR("[%s]Incorrect length passed - length = %d, len =%d\n", __FUNCTION__, length, len);
            }
            ev3 = (WMI_REPORT_SLEEP_STATE_EVENT *)ptr;
            switch(ev3->sleepState) {
                case  WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP:
                    HandleAdapterEvent(pInfo, ATH_ADAPTER_REMOVED);
                    break;
                case WMI_REPORT_SLEEP_STATUS_IS_AWAKE:
                    Abf_WlanIssueFrontEndConfig( pInfo);
                    HandleAdapterEvent(pInfo, ATH_ADAPTER_ARRIVED);
                    break;
            }
            break;
        default:
            //A_DEBUG("Event: 0x%x, Not Handled\n", eventid);
            break;
        }
    } while (FALSE);

    return status;
}
예제 #25
0
static void
WirelessEvent(ATH_BT_FILTER_INSTANCE *pInstance, char *data, int len)
{
    A_STATUS status = A_OK;
    struct iw_event iwe_buf, *iwe = &iwe_buf;
    char *pos, *end, *custom, *buf;

    pos = data;
    end = data + len;

    while ((pos + IW_EV_LCP_PK_LEN <= end) && (status == A_OK)) {
        /* Event data may be unaligned, so make a local, aligned copy
         * before processing. */
        A_MEMCPY(&iwe_buf, pos, IW_EV_LCP_LEN);
        if (iwe->len <= IW_EV_LCP_LEN) {
            status = A_ERROR;
            break;
        }

        custom = pos + IW_EV_POINT_LEN;
        if (WIRELESS_EXT > 18 &&
            (iwe->cmd == IWEVMICHAELMICFAILURE ||
             iwe->cmd == IWEVCUSTOM ||
             iwe->cmd == IWEVASSOCREQIE ||
             iwe->cmd == IWEVASSOCRESPIE ||
             iwe->cmd == IWEVPMKIDCAND ||
             iwe->cmd == IWEVGENIE)) {
            /* WE-19 removed the pointer from struct iw_point */
            char *dpos = (char *) &iwe_buf.u.data.length;
            int dlen = dpos - (char *) &iwe_buf;
            A_MEMCPY(dpos, pos + IW_EV_LCP_LEN,
                   sizeof(struct iw_event) - dlen);
        } else {
            A_MEMCPY(&iwe_buf, pos, sizeof(struct iw_event));
            custom += IW_EV_POINT_OFF;
        }

        switch (iwe->cmd) {
        case SIOCGIWAP:
            break;
        case IWEVCUSTOM:
            if (custom + iwe->u.data.length > end) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            buf = A_MALLOC(iwe->u.data.length + 1);
            if (buf == NULL) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            A_MEMCPY(buf, custom, iwe->u.data.length);
            status = WirelessCustomEvent(pInstance, buf, iwe->u.data.length);
            A_FREE(buf);
            break;
        case SIOCGIWSCAN:
            break;
        case SIOCSIWESSID:
            break;
        case IWEVGENIE:
            if (custom + iwe->u.data.length > end || (iwe->u.data.length < 2)) {
                A_ERR("event = IWEVGENIE with wrong length %d remain %d\n", 
                                      iwe->u.data.length, (end-custom));
                status = A_ERROR;
                break;
            }
            buf = A_MALLOC(iwe->u.data.length + 1);
            if (buf == NULL) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            A_MEMCPY(buf, custom, iwe->u.data.length);
            status = WirelessCustomEvent(pInstance, buf, iwe->u.data.length);
            A_FREE(buf);
            break;
        default:
            break;
        }

        pos += iwe->len;
    }
}
예제 #26
0
/* Internal functions */
static void *
WlanEventThread(void *arg)
{
    int left, ret, sd;
    struct timeval tv;
    socklen_t fromlen;
    struct nlmsghdr *h;
    fd_set readfds, tempfds;
    char buf[WLAN_EVENT_SIZE_MAX];
    struct sockaddr_nl from, local;
    ABF_WLAN_INFO *pAbfWlanInfo = (ABF_WLAN_INFO *)arg;
    ATHBT_FILTER_INFO *pInfo = pAbfWlanInfo->pInfo;
    ATH_BT_FILTER_INSTANCE *pInstance = pInfo->pInstance;
    A_STATUS status;
    
    A_INFO("Starting the WLAN Event Handler task\n");

    A_INFO("Checking WLAN adapter on startup .. \n");

    if (!pInstance->pWlanAdapterName) {
        Abf_WlanCheckSettings(pAbfWlanInfo->IfName, NULL);
        if (pAbfWlanInfo->IfName[0]) {
            pAbfWlanInfo->IfIndex = if_nametoindex(pAbfWlanInfo->IfName);
        }
    }
    status = AcquireWlanAdapter(pAbfWlanInfo);
 
    if (A_FAILED(status)) {
        A_INFO("No WLAN adapter on startup (OKAY) \n");
    }else {
        /* Communicate this to the Filter task */
        HandleAdapterEvent(pInfo, ATH_ADAPTER_ARRIVED);
        A_INFO("WLAN Adapter Added\n");
    }


    do {
        sd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
        if (sd < 0) {
            A_ERR("[%s] socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE): %d\n", 
                  __FUNCTION__, sd);
            break;
        }

        A_MEMZERO(&local, sizeof(struct sockaddr_nl));
        local.nl_family = AF_NETLINK;
        local.nl_groups = RTMGRP_LINK;
        if ((ret = bind(sd, (struct sockaddr *) &local, sizeof(local))) < 0) {
            A_ERR("[%s] bind(netlink): %d\n", __FUNCTION__, ret);
            close(sd);
            break;
        }

        FD_ZERO(&readfds);
        FD_SET(sd, &readfds);
        while (pAbfWlanInfo->Loop) {
            A_MEMCPY(&tempfds, &readfds, sizeof(fd_set));
            tv.tv_sec = 1;
            tv.tv_usec = 0;
            ret = select(sd+1, &tempfds, NULL, NULL, &tv);
            if ((ret < 0) && (errno != EINTR)) {
                A_ERR("[%s] select failed: %d\n", __FUNCTION__, ret);
                break;
            } else if ((ret > 0) && (FD_ISSET(sd, &tempfds))) {
                fromlen = sizeof(from);
                do {
                    left = recvfrom(sd, buf, sizeof(buf), 0,
                                    (struct sockaddr *) &from, &fromlen);
                } while (left == -1 && errno == EINTR);

                if (left < 0) {
                    A_ERR("[%s] recvfrom(netlink)\n", __FUNCTION__);
                    continue;
                 //   break;
                }

                h = (struct nlmsghdr *) buf;
                while (left >= sizeof(*h)) {
                    int len, plen;

                    len = h->nlmsg_len;
                    plen = len - sizeof(*h);
                    if (len > left || plen < 0) {
                        A_ERR("[%s] malformed netlink message\n", __FUNCTION__);
                        continue;
                    }

                    //A_DEBUG("RTM Message Type: %s\n", 
                    //        ((h->nlmsg_type == RTM_NEWLINK) ? 
                    //         "RTM_NEWLINK" : ((h->nlmsg_type == RTM_DELLINK) ? 
                    //         "RTM_DELLINK" : "RTM_OTHER")));
                    switch (h->nlmsg_type) {
                    case RTM_NEWLINK:
                        NewLinkEvent(pInstance, h, plen);
                        break;
                    case RTM_DELLINK:
                        DelLinkEvent(pInstance, h, plen);
                        break;
                    default:
                        break;
                    }

                    len = NLMSG_ALIGN(len);
                    left -= len;
                    h = (struct nlmsghdr *) ((char *) h + len);
                }
            }
        }

        close(sd);
    } while (FALSE);

    /* Clean up the resources allocated in this task */
    A_INFO("Terminating the WLAN Event Handler task\n");
    A_MUTEX_LOCK(&pAbfWlanInfo->hWaitEventLock);
    pAbfWlanInfo->Loop = FALSE;
    A_COND_SIGNAL(&pAbfWlanInfo->hWaitEvent);
    A_MUTEX_UNLOCK(&pAbfWlanInfo->hWaitEventLock);

    return NULL;
}
예제 #27
0
int
main(int argc, char *argv[])
{
    int ret;
    char *config_file = NULL;
    int opt = 0, daemonize = 1, debug = 0, console_output=0;
    progname = argv[0];
    A_STATUS status;
    struct sigaction sa;
    ATHBT_FILTER_INFO *pInfo;
    A_UINT32 btfiltFlags = 0;

    A_MEMZERO(&g_AthBtFilterInstance, sizeof(ATH_BT_FILTER_INSTANCE));

    /*
     * Keep an option to specify the wireless extension. By default,
     * assume it to be equal to WIRELESS_EXT TODO
     */

    /* Get user specified options */
    while ((opt = getopt(argc, argv, "bsvandczxf:w:")) != EOF) {
        switch (opt) {
        case 'n':
            daemonize = 0;
            break;

        case 'd':
            debug = 1;
            break;

        case 'f':
            if (optarg) {
                config_file = strdup(optarg);
            }
            break;
        case 'c':
            console_output = 1;
            break;
        case 'a':
            btfiltFlags |= ABF_ENABLE_AFH_CHANNEL_CLASSIFICATION;
            break;
        case 'z':
            btfiltFlags |= ABF_USE_HCI_FILTER_FOR_HEADSET_PROFILE;
            break;
        case 'v':
            btfiltFlags |= ABF_WIFI_CHIP_IS_VENUS ;
            A_DEBUG("wifi chip is venus\n");
            break;
        case 'x':
            btfiltFlags |= ABF_BT_CHIP_IS_ATHEROS ;
            A_DEBUG("bt chip is atheros\n");
            break;
        case 's':
            btfiltFlags |= ABF_FE_ANT_IS_SA ;
            A_DEBUG("Front End Antenna Configuration is single antenna \n");
            break;
        case 'w':
            memset(wifname, '\0', IFNAMSIZ);
            strcpy(wifname, optarg);
            g_AthBtFilterInstance.pWlanAdapterName = (A_CHAR *)&wifname;
            break;
	case 'b':
	    btfiltFlags |= ABF_USE_ONLY_DBUS_FILTERING;
	    break;
        default:
            usage();
            exit(1);
        }
    }

    /* Launch the daemon if desired */
    if (daemonize && daemon(0, console_output ? 1 : 0)) {
        printf("Can't daemonize: %s\n", strerror(errno));
        exit(1);
    }

    /* Initialize the debug infrastructure */
    A_DBG_INIT("ATHBT", "Ath BT Filter Daemon");
    if (debug) {
        if (console_output) {
            A_DBG_SET_OUTPUT_TO_CONSOLE();
        }
       // setlogmask(LOG_INFO | LOG_DEBUG | LOG_ERR);
        A_INFO("Enabling Debug Information\n");
        A_SET_DEBUG(1);
    }

    if (config_file) {
        A_DEBUG("Config file: %s\n", config_file);
        if (!(gConfigFile = fopen(config_file, "r")))
        {
            A_ERR("[%s] fopen failed\n", __FUNCTION__);
        }
    }

    A_MEMZERO(&sa, sizeof(struct sigaction));
    sa.sa_flags = SA_NOCLDSTOP;
    sa.sa_handler = Abf_SigTerm;
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT,  &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction(SIGPIPE, &sa, NULL);

    Abf_HciLibInit(&btfiltFlags);

    /* Initialize the Filter core */
    do {
        Abf_WlanCheckSettings(wifname, &btfiltFlags);
        ret = AthBtFilter_Attach(&g_AthBtFilterInstance, btfiltFlags );
        if (ret) {
            A_ERR("Filter initialization failed\n");
            break;
        }

        /* Initialize the WLAN notification mechanism */
        status = Abf_WlanStackNotificationInit(&g_AthBtFilterInstance, btfiltFlags );
        if (A_FAILED(status)) {
            AthBtFilter_Detach(&g_AthBtFilterInstance);
            A_ERR("WLAN stack notification init failed\n");
            break;
        }

        /* Initialize the BT notification mechanism */
        status = Abf_BtStackNotificationInit(&g_AthBtFilterInstance,btfiltFlags);
        if (A_FAILED(status)) {
            Abf_WlanStackNotificationDeInit(&g_AthBtFilterInstance);
            AthBtFilter_Detach(&g_AthBtFilterInstance);
            A_ERR("BT stack notification init failed\n");
            break;
        }

        /* Check for errors on the return value TODO */
        pInfo = g_AthBtFilterInstance.pContext;
        GpInfo = pInfo;

        A_DEBUG("Service running, waiting for termination .... \n");

            /* wait for termination signal */
        while (!terminated) {
            sleep(1);
        }
    } while(FALSE);

    /* Initiate the shutdown sequence */
    if(GpInfo != NULL) {
        AthBtFilter_State_Off(GpInfo);
    }
    Abf_ShutDown();

    Abf_HciLibDeInit();
    /* Shutdown */
    if (gConfigFile) {
        fclose(gConfigFile);
    }

    if (config_file) {
        A_FREE(config_file);
    }

    A_DEBUG("Service terminated \n");
    A_MEMZERO(&g_AthBtFilterInstance, sizeof(ATH_BT_FILTER_INSTANCE));
    A_DBG_DEINIT();

    return 0;
}
예제 #28
0
int main (int argc, char **argv)
{
    void (*reportCB)(void *) = NULL;
    void (*cmdRespCB)(void *) = cmdReplyFunc_readThermal;
#endif /* ATHTESTCMD_LIB */
    int c, s=-1;
    char ifname[IFNAMSIZ];
    unsigned int cmd = 0;
    progname = argv[0];
    struct ifreq ifr;
    char buf[2048];
    TCMD_CONT_TX *txCmd = (TCMD_CONT_TX *)((A_UINT32 *)buf + 1); /* first 32-bit is XIOCTL_CMD */
    TCMD_CONT_RX *rxCmd   = (TCMD_CONT_RX *)((A_UINT32 *)buf + 1);
    TCMD_PM *pmCmd = (TCMD_PM *)((A_UINT32 *)buf + 1);
    WMI_SET_LPREAMBLE_CMD *setLpreambleCmd = (WMI_SET_LPREAMBLE_CMD *)((A_UINT32 *)buf + 1);
    TCMD_SET_REG *setRegCmd = (TCMD_SET_REG *)((A_UINT32 *)buf + 1);
    TC_CMDS  *tCmds = (TC_CMDS *)((A_UINT32 *)buf + 1);
    A_BOOL needRxReport = FALSE;    
#ifndef ATHTESTCMD_LIB
    A_UINT16 efuse_begin = 0, efuse_end = (VENUS_OTP_SIZE - 1);
    A_UINT8  efuseBuf[VENUS_OTP_SIZE];
    A_UINT8  efuseWriteBuf[VENUS_OTP_SIZE];
    A_UINT16 data_length = 0;
#endif
    txCmd->numPackets = 0;
    txCmd->wlanMode = TCMD_WLAN_MODE_NOHT;
    txCmd->tpcm = TPC_TX_PWR;
/* default to tx power */
    rxCmd->u.para.wlanMode = TCMD_WLAN_MODE_NOHT;
#ifdef ATHTESTCMD_LIB
    if (setjmp(*jbuf)!=0) {
        if (s>=0)
            close(s);
        return -1;
    }
#endif 

    if (argc == 1) {
        usage();
    }

    memset(buf, 0, sizeof(buf));
    memset(ifname, '\0', IFNAMSIZ);
    strcpy(ifname, "eth1");
    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0) {
        A_ERR(1, "socket");
    }

    while (1) {
        int option_index = 0;
        static struct option long_options[] = {
            {"version", 0, NULL, 'v'},
            {"interface", 1, NULL, 'i'},
            {"tx", 1, NULL, 't'},
            {"txfreq", 1, NULL, 'f'},
            {"txrate", 1, NULL, 'g'},
            {"txpwr", 1, NULL, 'h'},
            {"tgtpwr", 0, NULL, 'H'},
            {"pcdac", 1, NULL, 'I'},
            {"txantenna", 1, NULL, 'j'},
            {"txpktsz", 1, NULL, 'z'},
            {"txpattern", 1, NULL, 'e'},
            {"rx", 1, NULL, 'r'},
            {"rxfreq", 1, NULL, 'p'},
            {"rxantenna", 1, NULL, 'q'},
            {"pm", 1, NULL, 'x'},
            {"setmac", 1, NULL, 's'},
            {"ani", 0, NULL, 'a'},
            {"scrambleroff", 0, NULL, 'o'},
            {"aifsn", 1, NULL, 'u'},
            {"SetAntSwitchTable", 1, NULL, 'S'},
            {"shortguard", 0, NULL, 'G'},
            {"numpackets", 1, NULL, 'n'},
            {"mode", 1, NULL, 'M'},
            {"setlongpreamble", 1, NULL, 'l'},
            {"setreg", 1, NULL, 'R'},                  
            {"regval", 1, NULL, 'V'},                
            {"flag", 1, NULL, 'F'},     
            {"writeotp", 0, NULL, 'w'},  	
            {"otpregdmn", 1, NULL, 'E'},		
#ifndef ATHTESTCMD_LIB
            {"efusedump", 0, NULL, 'm'},
            {"efusewrite", 0, NULL, 'W'},
            {"start", 1, NULL, 'A'},
            {"end", 1, NULL, 'L'},
            {"data", 1, NULL, 'U'},
            {"otpwrite", 0, NULL, 'O'},
            {"otpdump", 0, NULL, 'P'},
#endif
            {"btaddr", 1, NULL, 'B'},			
            {"therm", 0, NULL, 'c'},
            {0, 0, 0, 0}
        };

        c = getopt_long(argc, argv, "vi:t:f:g:h:HI:r:p:q:x:u:ao:M:A:L:mU:WOP",
                         long_options, &option_index);
        if (c == -1)
            break;

        switch (c) {
        case 'i':
            memset(ifname, '\0', 8);
            strcpy(ifname, optarg);
            break;
        case 't':
            cmd = TESTMODE_CONT_TX;
			txCmd->testCmdId = TCMD_CONT_TX_ID;
            if (!strcmp(optarg, "sine")) {
                txCmd->mode = TCMD_CONT_TX_SINE;
            } else if (!strcmp(optarg, "frame")) {
                txCmd->mode = TCMD_CONT_TX_FRAME;
            } else if (!strcmp(optarg, "tx99")) {
                txCmd->mode = TCMD_CONT_TX_TX99;
            } else if (!strcmp(optarg, "tx100")) {
                txCmd->mode = TCMD_CONT_TX_TX100;
            } else if (!strcmp(optarg, "off")) {
                txCmd->mode = TCMD_CONT_TX_OFF;
            }else {
                cmd = 0;
            }
            break;
        case 'f':
            txCmd->freq = freqValid(atoi(optarg));
            break;
        case 'G':
            txCmd->shortGuard = 1;
            break;
        case 'M':
            if(cmd == TESTMODE_CONT_TX) {
                if (!strcmp(optarg, "ht20")) {
                    txCmd->wlanMode = TCMD_WLAN_MODE_HT20;
                } else if (!strcmp(optarg, "ht40plus")) {
                    txCmd->wlanMode = TCMD_WLAN_MODE_HT40PLUS;
                } else if (!strcmp(optarg, "ht40minus")) {
                    txCmd->wlanMode = TCMD_WLAN_MODE_HT40MINUS;
                }
            } else if(cmd == TESTMODE_CONT_RX) {
                if (!strcmp(optarg, "ht20")) {
                    rxCmd->u.para.wlanMode = TCMD_WLAN_MODE_HT20;
                } else if (!strcmp(optarg, "ht40plus")) {
                    rxCmd->u.para.wlanMode = TCMD_WLAN_MODE_HT40PLUS;
                } else if (!strcmp(optarg, "ht40minus")) {
                    rxCmd->u.para.wlanMode = TCMD_WLAN_MODE_HT40MINUS;
                }
            }
            break;
        case 'n':
            txCmd->numPackets = atoi(optarg);
            break;
        case 'g':
            /* let user input index of rateTable instead of string parse */
            txCmd->dataRate = rateValid(atoi(optarg), txCmd->freq);
            break;
        case 'h':
        {
            int txPowerAsInt;
            /* Get tx power from user.  This is given in the form of a number
             * that's supposed to be either an integer, or an integer + 0.5
             */
            double txPowerIndBm = atof(optarg);

            /*
             * Check to make sure that the number given is either an integer
             * or an integer + 0.5
             */
            txPowerAsInt = (int)txPowerIndBm;
            if (((txPowerIndBm - (double)txPowerAsInt) == 0) ||
                (((txPowerIndBm - (double)txPowerAsInt)) == 0.5) ||
                (((txPowerIndBm - (double)txPowerAsInt)) == -0.5)) {
                if (txCmd->mode != TCMD_CONT_TX_SINE) {
                    txCmd->txPwr = txPowerIndBm * 2;
                } else {
                    txCmd->txPwr = txPowerIndBm;
                }
           } else {
                printf("Bad argument to --txpwr, must be in steps of 0.5 dBm\n");
                cmd = 0;
           }
             
            txCmd->tpcm = TPC_TX_PWR;
        }
            break;
        case 'H':
            txCmd->tpcm = TPC_TGT_PWR;
            break;
        case 'I':
            txCmd->tpcm = TPC_FORCED_GAIN;
            txCmd->txPwr = atof(optarg);
            break;
        case 'j':
            txCmd->antenna = antValid(atoi(optarg));
            break;       
        case 'z':
            txCmd->pktSz = pktSzValid(atoi(optarg));
            break;
        case 'e':
            txCmd->txPattern = atoi(optarg);
            break;
        case 'r':
            cmd = TESTMODE_CONT_RX;
			rxCmd->testCmdId = TCMD_CONT_RX_ID;
            if (!strcmp(optarg, "promis")) {
                rxCmd->act = TCMD_CONT_RX_PROMIS;
			 	printf(" Its cont Rx promis mode \n");
            } else if (!strcmp(optarg, "filter")) {
                rxCmd->act = TCMD_CONT_RX_FILTER;
				printf(" Its cont Rx  filter  mode \n");
            } else if (!strcmp(optarg, "report")) {
				 printf(" Its cont Rx report  mode \n");
                rxCmd->act = TCMD_CONT_RX_REPORT;
                needRxReport = TRUE;
            } else {
                cmd = 0;
            }
            break;
        case 'p':
            rxCmd->u.para.freq = freqValid(atoi(optarg));
            break;
        case 'q':
            rxCmd->u.para.antenna = antValid(atoi(optarg));
            break;
        case 'x':
            cmd = TESTMODE_PM;
			pmCmd->testCmdId = TCMD_PM_ID;
            if (!strcmp(optarg, "wakeup")) {
                pmCmd->mode = TCMD_PM_WAKEUP;
            } else if (!strcmp(optarg, "sleep")) {
                pmCmd->mode = TCMD_PM_SLEEP;
            } else if (!strcmp(optarg, "deepsleep")) {
                pmCmd->mode = TCMD_PM_DEEPSLEEP;
            } else {
                cmd = 0;
            }
            break;
        case 's':
            {
                A_UINT8 mac[ATH_MAC_LEN];

                cmd = TESTMODE_CONT_RX;
                rxCmd->testCmdId = TCMD_CONT_RX_ID;
                rxCmd->act = TCMD_CONT_RX_SETMAC;
                if (ath_ether_aton(optarg, mac) != A_OK) {
                    A_ERR(-1, "Invalid mac address format! \n");
                }
                memcpy(rxCmd->u.mac.addr, mac, ATH_MAC_LEN);
#ifdef TCMD_DEBUG
                printf("JLU: tcmd: setmac 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", 
                        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
#endif
                break;
            }
        case 'u':
            {
                txCmd->aifsn = atoi(optarg) & 0xff;
                printf("AIFS:%d\n", txCmd->aifsn);
            }
            break;
        case 'a':
            if(cmd == TESTMODE_CONT_TX) {
                txCmd->enANI = TRUE;
            } else if(cmd == TESTMODE_CONT_RX) {
                rxCmd->enANI = TRUE;
            }
            break;
        case 'o':
            txCmd->scramblerOff = TRUE;
            break;
        case 'S':
            if (argc < 4)
                usage();
            cmd = TESTMODE_CONT_RX;
            rxCmd->testCmdId = TCMD_CONT_RX_ID;		
            rxCmd->act = TCMD_CONT_RX_SET_ANT_SWITCH_TABLE;				
            rxCmd->u.antswitchtable.antswitch1 = strtoul(argv[2], (char **)NULL,0);
            rxCmd->u.antswitchtable.antswitch2 = strtoul(argv[3], (char **)NULL,0);
            break;
        case 'l':
            cmd = TESTMODE_SETLPREAMBLE;
            setLpreambleCmd->status = atoi(optarg);
            break;
        case 'R':
            if (argc < 5) {
                printf("usage:athtestcmd -i eth0 --setreg 0x1234 --regval 0x01 --flag 0\n");
            }
            cmd = TESTMODE_SETREG;
            setRegCmd->testCmdId = TCMD_SET_REG_ID;
            setRegCmd->regAddr   = strtoul(optarg, (char **)NULL, 0);//atoi(optarg);
            break; 
        case 'V':
            setRegCmd->val = strtoul(optarg, (char **)NULL, 0);
            break;            
        case 'F':
            setRegCmd->flag = atoi(optarg);
            break;                       
        case 'w':
            rxCmd->u.mac.otpWriteFlag = 1;	
            break;		
        case 'E':
            rxCmd->u.mac.regDmn[0] = 0xffff&(strtoul(optarg, (char **)NULL, 0));
            rxCmd->u.mac.regDmn[1] = 0xffff&(strtoul(optarg, (char **)NULL, 0)>>16);		
            break;		
        case 'B':
            {    				           
                A_UINT8 btaddr[ATH_MAC_LEN];
                if (ath_ether_aton(optarg, btaddr) != A_OK) {
                    A_ERR(-1, "Invalid mac address format! \n");
                } 
                memcpy(rxCmd->u.mac.btaddr, btaddr, ATH_MAC_LEN);
#ifdef TCMD_DEBUG
                printf("JLU: tcmd: setbtaddr 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", 
                        btaddr[0], btaddr[1], btaddr[2], btaddr[3], btaddr[4], btaddr[5]);
#endif		
            }
            break;		
        case 'c':
            cmd = TESTMODE_CMDS;
            tCmds->hdr.testCmdId = TC_CMDS_ID;
            {
                tCmds->hdr.u.parm.length = (A_UINT16)0;    
                tCmds->hdr.u.parm.version = TC_CMDS_VERSION_TS;    
                tCmds->hdr.act = TC_CMDS_READTHERMAL;//TC_CMDS_CAL_THERMALVOLT;
            }
            break;
	
#ifndef ATHTESTCMD_LIB
        case 'A':
            efuse_begin = atoi(optarg);
            break;

        case 'L':
            efuse_end = atoi(optarg);
            break;

        case 'U':
            {
                A_UINT8* pucArg = (A_UINT8*)optarg;
                A_UINT8  c;
                A_UINT8  strBuf[256];
                A_UINT8  pos = 0;
                A_UINT16 length = 0;
                A_UINT32  data;

                /* Sweep string to end */
                while (1) {
                    c = *pucArg++;
                    if (isHex(c)) {
                        strBuf[pos++] = c;
                    } else {
                        strBuf[pos] = '\0';
                        pos = 0;
                        sscanf(((char *)&strBuf), "%x", &data);
                        efuseWriteBuf[length++] = (data & 0xFF);

                        /* End of arg string */
                        if (c == '\0') {
                            break;
                        }
                    }
                }

                data_length = length;
            }
            break;

        case 'm':
            cmd = TESTMODE_CMDS;
            tCmds->hdr.testCmdId      = TC_CMDS_ID;
            tCmds->hdr.act            = TC_CMDS_EFUSEDUMP;
            cmdRespCB = cmdReplyFunc;
            break;

        case 'W':
            cmd = TESTMODE_CMDS;
            tCmds->hdr.testCmdId      = TC_CMDS_ID;
            tCmds->hdr.act            = TC_CMDS_EFUSEWRITE;
            cmdRespCB = cmdReplyFunc;
            break;

        case 'O':
            cmd = TESTMODE_CMDS;
            tCmds->hdr.testCmdId      = TC_CMDS_ID;
            tCmds->hdr.act            = TC_CMDS_OTPSTREAMWRITE;
            cmdRespCB = cmdReplyFunc;
            break;

        case 'P':
            cmd = TESTMODE_CMDS;
            tCmds->hdr.testCmdId      = TC_CMDS_ID;
            tCmds->hdr.act            = TC_CMDS_OTPDUMP;
            cmdRespCB = cmdReplyFunc;
            break;
#endif		
        default:
            usage();
        }
    }

    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));

    switch (cmd) {
    case TESTMODE_CONT_TX:
#ifdef CONFIG_HOST_TCMD_SUPPORT
        *(A_UINT32 *)buf = AR6000_XIOCTL_TCMD_CONT_TX;

        txPwrValid(txCmd);

        ifr.ifr_data = (void *)buf;
        if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
            A_ERR(1, "%s", ifr.ifr_name);
        }
#endif /* CONFIG_HOST_TCMD_SUPPORT */
        break;
    case TESTMODE_CONT_RX:
#ifdef CONFIG_HOST_TCMD_SUPPORT
        *(A_UINT32 *)buf = AR6000_XIOCTL_TCMD_CONT_RX;

        if (rxCmd->act == TCMD_CONT_RX_PROMIS ||
             rxCmd->act == TCMD_CONT_RX_FILTER) {
            if (rxCmd->u.para.freq == 0)
                rxCmd->u.para.freq = 2412;
        }

        ifr.ifr_data = (void *)buf;
        if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
            A_ERR(1, "%s", ifr.ifr_name);
        }
        if (reportCB) {
            reportCB(ifr.ifr_data);
        }
        if (needRxReport) {
            rxReport(ifr.ifr_data);
            needRxReport = FALSE;
        }
#endif /* CONFIG_HOST_TCMD_SUPPORT */
        break;
    case TESTMODE_PM:
#ifdef CONFIG_HOST_TCMD_SUPPORT
        *(A_UINT32 *)buf = AR6000_XIOCTL_TCMD_PM;
        ifr.ifr_data = (void *)buf;
        if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
            A_ERR(1, "%s", ifr.ifr_name);
        }
#endif /* CONFIG_HOST_TCMD_SUPPORT */
        break;
    case TESTMODE_SETLPREAMBLE:
        *(A_UINT32 *)buf = AR6000_XIOCTL_WMI_SET_LPREAMBLE;
        ifr.ifr_data = (void *)buf;
        if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
            A_ERR(1, "%s", ifr.ifr_name);
        }   
        break;   
    case TESTMODE_SETREG:
        *(A_UINT32 *)buf = AR6000_XIOCTL_TCMD_SETREG;
        ifr.ifr_data = (void *)buf;
        if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
            printf("%s", ifr.ifr_name);
        }   
        break;
#ifndef ATHTESTCMD_LIB              
    case TESTMODE_CMDS:
        if (tCmds->hdr.act == TC_CMDS_EFUSEDUMP) {
            int i, k;
            int blkNum;
            A_UINT16 efuseEnd   = efuse_end;
            A_UINT16 efuseBegin = efuse_begin;
            A_UINT16 efusePrintAnkor;
            A_UINT16 numPlaceHolder;

            /* Input check */
            if (efuseEnd > (VENUS_OTP_SIZE - 1)) {
                efuseEnd = (VENUS_OTP_SIZE - 1);
            }

            if (efuseBegin > efuseEnd) {
                efuseBegin = efuseEnd;
            }

            efusePrintAnkor = efuseBegin;

            blkNum = ((efuseEnd - efuseBegin) / TC_CMDS_SIZE_MAX) + 1;

            /* Request data in several trys */
            for (i = 0; i < blkNum; i++) {
                tCmds->hdr.testCmdId      = TC_CMDS_ID;
                tCmds->hdr.act            = TC_CMDS_EFUSEDUMP;
                tCmds->hdr.u.parm.length  = 4;    
                tCmds->hdr.u.parm.version = TC_CMDS_VERSION_TS;  

                tCmds->buf[0] = (efuseBegin & 0xFF);
                tCmds->buf[1] = (efuseBegin >> 8) & 0xFF;
                tCmds->buf[2] = (efuseEnd & 0xFF);
                tCmds->buf[3] = (efuseEnd >> 8) & 0xFF;      

                *(A_UINT32 *)buf = AR6000_XIOCTL_TCMD_CMDS;

                ifr.ifr_data = (void *)buf;

                if (ioctl(s, AR6000_IOCTL_EXTENDED, &ifr) < 0) {
                    A_ERR(1,"%s", ifr.ifr_name);
                }

                if (cmdRespCB) {
                    cmdRespCB(ifr.ifr_data);
                }

                /* Last block? */
                if ((efuseEnd - efuseBegin + 1) < TC_CMDS_SIZE_MAX) {
                    memcpy((void*)(efuseBuf + efuseBegin), (void*)&(sTcCmds.buf[0]), (efuseEnd - efuseBegin + 1));
                } else {
                    memcpy((void*)(efuseBuf + efuseBegin), (void*)&(sTcCmds.buf[0]), TC_CMDS_SIZE_MAX);
                }

                /* Adjust the efuseBegin but keep efuseEnd unchanged */
                efuseBegin += TC_CMDS_SIZE_MAX;
            }

            /* Output Dump */
            printf("------------------- eFuse Dump ----------------------");
            for (i = efusePrintAnkor; i <= efuseEnd; i++) {
                /* Cosmetics */
                if (i == efusePrintAnkor) {
                    numPlaceHolder = (efusePrintAnkor & 0x0F);
                    printf("\n%04X:", (efusePrintAnkor & 0xFFF0));
                    for (k = 0; k < numPlaceHolder; k++) {
                        printf("   ");
                    }
                } else if ((i & 0x0F) == 0) {
                    printf("\n%04X:", i);
                }

                printf(" %02X", efuseBuf[i]);
            }
            printf("\n\n");
        } else if (tCmds->hdr.act == TC_CMDS_EFUSEWRITE) {