示例#1
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;

}
示例#2
0
void
Abf_ShutDown(void)
{
    A_INFO("Shutting Down\n");

    /* Clean up all the resources */
    Abf_BtStackNotificationDeInit(&g_AthBtFilterInstance);
    Abf_WlanStackNotificationDeInit(&g_AthBtFilterInstance);
    AthBtFilter_Detach(&g_AthBtFilterInstance);
    
    A_INFO("Shutting Down Complete\n");
}
示例#3
0
void
Abf_WlanStackNotificationDeInit(ATH_BT_FILTER_INSTANCE *pInstance)
{
    ATHBT_FILTER_INFO *pInfo = (ATHBT_FILTER_INFO *)pInstance->pContext;
    ABF_WLAN_INFO *pAbfWlanInfo = pInfo->pWlanInfo;

    if (!pAbfWlanInfo) return;

    /* Terminate and wait for the WLAN Event Handler task to finish */
    A_MUTEX_LOCK(&pAbfWlanInfo->hWaitEventLock);
    if (pAbfWlanInfo->Loop) {
        pAbfWlanInfo->Loop = FALSE;
        A_COND_WAIT(&pAbfWlanInfo->hWaitEvent, &pAbfWlanInfo->hWaitEventLock, 
                    WAITFOREVER);
    }
    A_MUTEX_UNLOCK(&pAbfWlanInfo->hWaitEventLock);

    /* Flush all the BT actions from the filter core */
    HandleAdapterEvent(pInfo, ATH_ADAPTER_REMOVED);
    pInfo->pWlanInfo = NULL;
    A_MUTEX_DEINIT(&pAbfWlanInfo->hWaitEventLock);
    A_COND_DEINIT(&pAbfWlanInfo->hWaitEvent);
    A_MEMZERO(pAbfWlanInfo, sizeof(ABF_WLAN_INFO));
    A_FREE(pAbfWlanInfo);

    A_INFO("WLAN Stack Notification de-init complete\n");
}
示例#4
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;
}
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;
}
void
Abf_RegisterToHciLib( ABF_BT_INFO * pAbfBtInfo)
{
    void *                                      handle = 0;
    tHCIUTILS_STATUS                            ret;

    char * pparam = NULL;
    int n_opcode = 0, n_type = 0;
    int i;
    A_INFO("Register To HCI LIB \n");

    if (pfn_HCIUTILS_RegisterHCINotification) {
        for (i=0; i <= 2;i++) {
            ret = (*pfn_HCIUTILS_RegisterHCINotification)
                  (
                  HCIUTILS_COMMAND,
                  hciCmdList[i],
                  eventNotificationCallback,
                  (void *) pAbfBtInfo
                  );
            A_DEBUG("Registered for HCI cmd %x, ret= %d\n", hciCmdList[i],ret);
        }
        for (i=0; i <= 8; i++) {
            ret = (*pfn_HCIUTILS_RegisterHCINotification)
                  (
                  HCIUTILS_EVENT,
                  hciEventList[i],
                  eventNotificationCallback,
                  (void *)pAbfBtInfo
                  );
            A_DEBUG("Hcievent List[%d] =%x, ret =%x\n",i, hciEventList[i], ret);
        }
    }
}
示例#7
0
static void
DelLinkEvent(ATH_BT_FILTER_INSTANCE *pInstance, struct nlmsghdr *h, int len)
{
    A_BOOL found;
    struct ifinfomsg *ifi;
    struct rtattr * attr;
    int attrlen, nlmsg_len, rta_len;
    ATHBT_FILTER_INFO *pInfo = (ATHBT_FILTER_INFO *)pInstance->pContext;
    ABF_WLAN_INFO *pAbfWlanInfo = (ABF_WLAN_INFO *)pInfo->pWlanInfo;

    if (!pAbfWlanInfo->Handle) return;

    if (len < sizeof(*ifi)) {
        A_DEBUG("packet too short\n");
        return;
    }

    ifi = NLMSG_DATA(h);

    nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));

    attrlen = h->nlmsg_len - nlmsg_len;
    if (attrlen < 0) {
        A_DEBUG("bad attrlen\n");
        return;
    }

    attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);

    rta_len = RTA_ALIGN(sizeof(struct rtattr));
    found = FALSE;
    while (RTA_OK(attr, attrlen)) {
        if (attr->rta_type == IFLA_IFNAME) {
            /* 
             * Shall be used to get the socket descriptor. Also we should do 
             * it only until we get the adapter we are interested in 
             */
            if (!(strcmp(pAbfWlanInfo->IfName, ((char *)attr + rta_len)))) {
                found = TRUE;
            }
        }

        attr = RTA_NEXT(attr, attrlen);
    }

    if (!found) return;

    /* Flush all the BT actions from the filter core */
    HandleAdapterEvent(pInfo, ATH_ADAPTER_REMOVED);

    ReleaseWlanAdapter(pAbfWlanInfo);

    /* Reset the WLAN adapter specific info */
    A_MEMZERO(pAbfWlanInfo->AdapterName, WLAN_ADAPTER_NAME_SIZE_MAX);
    pAbfWlanInfo->PhyCapability = 0;

    A_INFO("WLAN Adapter Removed\n");
}
示例#8
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;
}
示例#9
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;
}
示例#10
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;
}
static void eventNotificationCallback ( tHCIUTILS_NOTIFICATION * pEvent)
{
    ABF_BT_INFO     *pAbfBtInfo = (ABF_BT_INFO *)g_pAbfBtInfo;
    ATHBT_FILTER_INFO *pInfo = pAbfBtInfo->pInfo;
    ATH_BT_FILTER_INSTANCE *pInstance = pInfo->pInstance;

    if(pEvent->tType == HCIUTILS_COMMAND) {
        if(pEvent->nOpCode == HCI_CMD_OPCODE_INQUIRY_START) {
 	        A_DEBUG("Device Inquiry Started \n");
            pAbfBtInfo->btInquiryState |= (1 << 0);
            AthBtIndicateState(pInstance, ATH_BT_INQUIRY, STATE_ON);
        }
        if(pEvent->nOpCode == HCI_CMD_OPCODE_INQUIRY_CANCEL  ) {
 	        A_DEBUG("Device Inquiry cancelled \n");
            if(pAbfBtInfo->btInquiryState) {
	            pAbfBtInfo->btInquiryState &= ~(1 << 0);
                AthBtIndicateState(pInstance, ATH_BT_INQUIRY, STATE_OFF);
	        }
 	    }
        if(pEvent->nOpCode == HCI_CMD_OPCODE_CONNECT) {
            A_DEBUG("Bt-Connect\n");
        }
    }
	if(pEvent->tType == HCIUTILS_EVENT) {

#define LMP_FEATURE_ACL_EDR_2MBPS_BYTE_INDEX  3
#define LMP_FEATURE_ACL_EDR_2MBPS_BIT_MASK    0x2
#define LMP_FEATURE_ACL_EDR_3MBPS_BYTE_INDEX  3
#define LMP_FEATURE_ACL_EDR_3MBPS_BIT_MASK    0x4
#define LMP_FEATURES_LENGTH                   8
	    if(pEvent->nOpCode == HCI_EVT_REMOTE_DEV_LMP_VERSION) {
	        A_UINT32 i = 0;
            A_UINT32 len = pEvent->n_data_length;
	        A_UCHAR * eventPtr = (A_UCHAR *)pEvent->p_notification_data_buf;
            A_UINT8 *lmp_features;

          /* Process LMP Features */


            A_DUMP_BUFFER(eventPtr, len,"Remote Device LMP Features:");

            eventPtr += 1;
            len -= 1 ;
            lmp_features = &eventPtr[3];
            A_DUMP_BUFFER(lmp_features, sizeof(lmp_features),"Remote Device LMP Features:");

            if ((lmp_features[LMP_FEATURE_ACL_EDR_2MBPS_BYTE_INDEX] & LMP_FEATURE_ACL_EDR_2MBPS_BIT_MASK)  ||    
                (lmp_features[LMP_FEATURE_ACL_EDR_3MBPS_BYTE_INDEX] & LMP_FEATURE_ACL_EDR_3MBPS_BIT_MASK)) 
            {
                A_DEBUG("Device is EDR capable \n");
                pAbfBtInfo->DefaultAudioDeviceLmpVersion = 3;
            } else {
                A_DEBUG("Device is NOT EDR capable \n");
                pAbfBtInfo->DefaultAudioDeviceLmpVersion = 2;
            }
            pAbfBtInfo->DefaultRemoteAudioDevicePropsValid = TRUE;
            pInfo->A2DPConnection_LMPVersion =  pInfo->SCOConnection_LMPVersion = 
                                                pAbfBtInfo->DefaultAudioDeviceLmpVersion;
        }
        if(pEvent->nOpCode ==  HCI_EVT_REMOTE_DEV_VERSION) {
	        A_UCHAR * eventPtr = (A_UCHAR *)pEvent->p_notification_data_buf;
            A_UINT32 len = pEvent->n_data_length;

            A_DUMP_BUFFER(eventPtr, len,"Remote Device Version");
            eventPtr += 1;
            len -= 1;
            A_DUMP_BUFFER(eventPtr, len,"Remote Device Version");

	        if (eventPtr[3] == 0) {
                strcpy(&pAbfBtInfo->DefaultRemoteAudioDeviceVersion[0], "1.0");
                pAbfBtInfo->DefaultAudioDeviceLmpVersion = 0;
		        A_DEBUG("Its 1.0 \n");
	        } else if (eventPtr[3] == 1) {
	            strcpy(&pAbfBtInfo->DefaultRemoteAudioDeviceVersion[0], "1.1");
                pAbfBtInfo->DefaultAudioDeviceLmpVersion = 1;
		        A_DEBUG("Its 1.1 \n");
        	} else if (eventPtr[3] == 2) {
	            strcpy(&pAbfBtInfo->DefaultRemoteAudioDeviceVersion[0], "1.2");
                pAbfBtInfo->DefaultAudioDeviceLmpVersion = 2;
    		    A_DEBUG("Its 1.2 \n");
        	} else if (eventPtr[3] == 3) {
	            strcpy(&pAbfBtInfo->DefaultRemoteAudioDeviceVersion[0], "2.0");
/*                    pAbfBtInfo->DefaultAudioDeviceLmpVersion = 3; */
	    	    A_DEBUG("Its 2.0 \n");
        	}else {
	            strcpy(&pAbfBtInfo->DefaultRemoteAudioDeviceVersion[0], "2.1");
/*                    pAbfBtInfo->DefaultAudioDeviceLmpVersion = 4; */
		        A_DEBUG("Its 2.1 \n");
            }
           
            pInfo->A2DPConnection_LMPVersion =  pInfo->SCOConnection_LMPVersion = 
                                                pAbfBtInfo->DefaultAudioDeviceLmpVersion;
	    }
        if (pEvent->nOpCode == EVT_INQUIRY_COMPLETE) {
            A_DEBUG("Device Inquiry Completed\n");
            if(pAbfBtInfo->btInquiryState) {
            	pAbfBtInfo->btInquiryState &= ~(1 << 0);
                AthBtIndicateState(pInstance, ATH_BT_INQUIRY, STATE_OFF);
            }
        }
        if (pEvent->nOpCode == EVT_PIN_CODE_REQ) {
            A_DEBUG("Pin Code Request\n");
        }

        if (pEvent->nOpCode == EVT_LINK_KEY_NOTIFY) {
           A_DEBUG("link key notify\n");
        }
	    if(pEvent->nOpCode == HCI_EVT_ROLE_CHANGE) {
	        A_DEBUG("Role Change\n");
    	    A_UCHAR * eventPtr = (A_UCHAR *)pEvent->p_notification_data_buf;
            A_UINT32 len = pEvent->n_data_length;

            A_DUMP_BUFFER(eventPtr, len,"Remote Device Role ");
            eventPtr += 8;
            len -= 8;
	        if(*eventPtr == 0x00) {
	            A_DEBUG("ROLE IS MASTER \n");
                pAbfBtInfo->pInfo->A2DPConnection_Role = 0x0;
            }
    	    if(*eventPtr == 0x01) {
	            A_DEBUG("ROLE IS SLAVE \n");
                pAbfBtInfo->pInfo->A2DPConnection_Role = 0x1;
            }
        }
        if(pEvent->nOpCode == EVT_CONN_COMPLETE) {
            A_DEBUG("Conn complete\n");
            if(pAbfBtInfo->btInquiryState) {
            	pAbfBtInfo->btInquiryState &= ~(1 << 1);
                AthBtIndicateState(pInstance, ATH_BT_INQUIRY, STATE_OFF);
            }
        }

        if(pEvent->nOpCode == HCI_EVT_SCO_CONNECT_COMPLETE) {
            A_UINT32 len = pEvent->n_data_length;
	        A_UCHAR * eventPtr = (A_UCHAR*)pEvent->p_notification_data_buf;

            A_DUMP_BUFFER(eventPtr, len,"SCO CONNECT_COMPLETE");
	        A_DEBUG("SCO CONNECT COMPLETE \n");
            pInfo->SCOConnection_LMPVersion =
                               pAbfBtInfo->DefaultAudioDeviceLmpVersion;

            pInfo->SCOConnectInfo.LinkType = eventPtr[10];
            pInfo->SCOConnectInfo.TransmissionInterval = eventPtr[11];
            pInfo->SCOConnectInfo.RetransmissionInterval = eventPtr[12];
            pInfo->SCOConnectInfo.RxPacketLength = eventPtr[13];
            pInfo->SCOConnectInfo.TxPacketLength = eventPtr[15];
            pInfo->SCOConnectInfo.Valid = TRUE;

            A_INFO("HCI SYNC_CONN_COMPLETE event captured, conn info (%d, %d, %d, %d, %d) \n",
                pInfo->SCOConnectInfo.LinkType,
                pInfo->SCOConnectInfo.TransmissionInterval,
                pInfo->SCOConnectInfo.RetransmissionInterval,
                pInfo->SCOConnectInfo.RxPacketLength,
                pInfo->SCOConnectInfo.TxPacketLength);

            AthBtIndicateState(pInstance,
                	      pInfo->SCOConnectInfo.LinkType == BT_LINK_TYPE_ESCO? ATH_BT_ESCO: ATH_BT_SCO,
                              STATE_ON);
        }
        if(pEvent->nOpCode == HCI_EVT_DISCONNECT) {
           A_UINT32 bitmap = FCore_GetCurrentBTStateBitMap(&pInfo->FilterCore);

	        A_DEBUG("HCI_EVT_DISCONNECT event \n");

            if( (bitmap & (1 << ATH_BT_SCO))|| (bitmap & (1 << ATH_BT_ESCO))) {
                AthBtIndicateState(pInstance,
                	      pInfo->SCOConnectInfo.LinkType == BT_LINK_TYPE_ESCO? ATH_BT_ESCO: ATH_BT_SCO,
                              STATE_OFF);
            }
            ForgetRemoteAudioDevice(pAbfBtInfo);
            pInfo->SCOConnectInfo.Valid = FALSE;
            pAbfBtInfo->pInfo->A2DPConnection_Role = 0x0;
        }
   }
}
示例#12
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;
}