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);
        }
    }
}
Beispiel #2
0
void 
A_DUMP_BUFFER(A_UCHAR *buffer, int length, char *pDescription)
{
    A_CHAR    stream[60];
    int       i;
    int       offset, count;

    if (!debug_enabled) {
        return;    
    }
    
    A_DEBUG("<---------Dumping %d Bytes : %s ------>\n", length, pDescription);

    count = 0;
    offset = 0;
    for(i = 0; i < length; i++) {
        sprintf(stream + offset, "%2.2X ", buffer[i]);
        count ++;
        offset += 3;

        if (count == 16) {
            count = 0;
            offset = 0;
            A_DEBUG("[H]: %s\n", stream);
            A_MEMZERO(stream, sizeof(stream));
        }
    }

    if (offset != 0) {
        A_DEBUG("[H]: %s\n", stream);
    }
    
    A_DEBUG("<------------------------------------------------->\n");
}
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);
}
Beispiel #4
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");
}
Beispiel #5
0
static void
NewLinkEvent(ATH_BT_FILTER_INSTANCE *pInstance, struct nlmsghdr *h, int len)
{
    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 (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));
    while (RTA_OK(attr, attrlen)) {
        if (attr->rta_type == IFLA_WIRELESS) {
            /* 
             * We need to ensure that the event is from the WLAN instance 
             * that we are interested in TODO 
             */
            WirelessEvent(pInstance, ((char*)attr) + rta_len, 
                          attr->rta_len - rta_len);
        } else 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 (!pAbfWlanInfo->Handle) {
                A_DEBUG("WLAN Adapter Interface: %s, Len: %d\n", 
                        (((char *)attr) + rta_len), attr->rta_len - rta_len);
                A_MEMCPY(pAbfWlanInfo->IfName, ((char *)attr + rta_len), 
                         attr->rta_len - rta_len);
                pAbfWlanInfo->IfIndex = if_nametoindex(pAbfWlanInfo->IfName);
            } else if (ifi->ifi_change && pAbfWlanInfo->IfIndex == ifi->ifi_index) {
                A_CHAR ifName[IFNAMSIZ];                
                A_MEMCPY(ifName, ((char *)attr + rta_len), attr->rta_len - rta_len);
                if (A_MEMCMP(pAbfWlanInfo->IfName, ifName, sizeof(ifName))!=0) {
                    A_MEMCPY(pAbfWlanInfo->IfName, ifName, sizeof(ifName));
                }
            }
        }
        attr = RTA_NEXT(attr, attrlen);
    }
}
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
}
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_UnRegisterToHciLib( ABF_BT_INFO * pAbfBtInfo)
{
    A_DEBUG("Unregistering HCI library handler\n");
    if(pfn_HCIUTILS_UnRegisterHCINotification) {
        int i;
        for (i=0; i <= 2;i++) {
            (*pfn_HCIUTILS_UnRegisterHCINotification)
                  (
                  HCIUTILS_COMMAND,
                  hciCmdList[i]
                  );
            A_DEBUG("Unregistered for HCI cmd %x\n", hciCmdList[i]);
        }
        for (i=0; i <= 8; i++) {
            (*pfn_HCIUTILS_UnRegisterHCINotification)
                  (
                  HCIUTILS_EVENT,
                  hciEventList[i]
                  );
            A_DEBUG("Unregistered Hcievent List[%d] =%x\n",i, hciEventList[i]);
        }
    }
}
Beispiel #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;
}
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;
        }
   }
}
Beispiel #11
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;
}