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); } } }
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); }
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"); }
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]); } } }
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; } } }
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; }