/*--------------------------------------------------------------------------- * RADIO_EventHandler_Default() *--------------------------------------------------------------------------- * * Synopsis: Handles HCI events for radios. * * Returns: <See RADIO_EventHandler in hcitrans.h> */ void RADIO_EventHandler_Default(U8 Event, HciCallbackParms *Parms) { BtStatus status; RadioEvent radioEvent; if ( (Event == HCI_CONTROLLER_EVENT) && #if defined(BTMTK_ON_LINUX) #ifdef __MTK_BT_EXTERNAL_PLATFORM__ (LEtoHost16(&(Parms->ptr.hciEvent->parms[1])) == HCC_RESET) #else (LEtoHost16(&(Parms->ptr.hciEvent->parms[1])) == HCC_READ_LOCAL_VERSION) #endif #else (LEtoHost16(&(Parms->ptr.hciEvent->parms[1])) == HCC_RESET) #endif ){ radioEvent = RADIO_INIT_STATUS; if(Parms->status == BT_STATUS_SUCCESS) { radioState = RADIO_STATE_READY; status = BT_STATUS_SUCCESS; } else { radioState = RADIO_STATE_INIT; status = BT_STATUS_FAILED; } /* Deliver event to Radio Manager */ radioCallback(radioEvent, status); return; } }
void A2MPHandleFlowSpecModifyComplete(const BtEvent *Event) { BT_AMP_HCI_EVENT_FLOW_STATUS_MODIFY result; U8 *parm; U8 controllerId; parm = (U8 *)Event->p.hciAmpEvent.parms; controllerId = Event->p.hciAmpEvent.controllerId; result.status = parm[0]; result.con_hdl = LEtoHost16(parm+1); }
void A2MPHandleReadLocalAMPInfo(const BtEvent *Event) { BtA2MPGetInfoRsp result; U8 *parm; U8 controllerId; U8 i=0; A2MP_MAIN_CONN *main_channel; parm = (U8 *)Event->p.hciAmpEvent.parms; result.controllerId = Event->p.hciAmpEvent.controllerId; if(Event->errCode ==0) result.status = 0x00; /* AMP get info response success*/ else result.status = 0x01; /* AMP get info response failed */ result.total_bandwidth = LEtoHost32(parm+2); result.max_guarantee_bandwidth = LEtoHost32(parm+6); result.min_latency = LEtoHost32(parm+10); result.max_pdu_size = LEtoHost32(parm+14); result.controller_type = parm[18]; result.pal_capability = LEtoHost16(parm+19); result.max_amp_assoc_length = LEtoHost16(parm+21); result.max_flush_timeout = LEtoHost32(parm+23); result.best_effort_flush_timeout= LEtoHost32(parm+27); for(i=0;i<NUM_BT_DEVICES; i++) { if(A2MPC(a2mp_main_channel)[i].state == A2MP_STATE_ALLOCATED) { main_channel = &A2MPC(a2mp_main_channel)[i]; if(main_channel->last_rxCmdopcode == A2MP_CODE_GET_INFO_REQ) { BTA2MP_SendGetInfoResponse(main_channel->remDev, &result); main_channel->last_rxCmdopcode = A2MP_CODE_INVALID; } } } }
void A2MPHandleLogicalLinkComplete(const BtEvent *Event) { BT_AMP_HCI_EVENT_LOGICAL_LINK_COMPLETE result; U8 *parm; U8 controllerId; A2MP_MAIN_CONN *a2mp_main_channel; U8 i=0; BtRemoteAMPDevice *link; parm = (U8 *)Event->p.hciAmpEvent.parms; controllerId = Event->p.hciAmpEvent.controllerId; result.status = parm[0]; result.logical_link_hdl = LEtoHost16(parm+1); result.physical_link_hdl = parm[3]; result.tx_flow_spec_id = parm[4]; a2mp_main_channel = A2MP_FindMainChannelByPhysicalLink(result.physical_link_hdl); if(a2mp_main_channel ==0) Assert(0); link = &a2mp_main_channel->remDev->remoteWifiAMP; for(i=0;i< BT_AMP_SUPPORTED_LOGICAL_CHANNEL; i++) { if(link->logicalLink[i].logical_link_sate == BDS_LOGICAL_CON) { if (result.status == 0x00) { link->logicalLink[i].logical_link_sate = BDS_CONNECTED; Report(("Create Logical Link success")); L2Cap_NotifyLogicalChannelCreated(link->logicalLink[i].l2cap_id, BT_STATUS_SUCCESS); } else { Report(("Create Logical Link failed")); link->logicalLink[i].logical_link_sate = BDS_DISCONNECTED; L2Cap_NotifyLogicalChannelCreated(link->logicalLink[i].l2cap_id, BT_STATUS_FAILED); } } } }
/*--------------------------------------------------------------------------- * notifyReadAcl() * Called from lower layer when ACL data is available for reading. * * Requires: * * Parameters: * * Returns: */ static BOOL notifyReadAcl(void) { UsbRxStateContext *st; U16 cntRead=1, len; BtStatus status; HciHandle hciConnHandle; /* Point to our state context */ st = &USTRAN(rxContext[ACL_STATE]); /* Loop while there is data to be read */ do { if (st->state == USB_RXS_GET_INIT) { st->headerLen = 4; /* Set up for the next state */ st->ptr = st->header; st->maxReadLen = st->headerLen; st->ptr = st->header; st->maxReadLen = st->headerLen; st->state = USB_RXS_GET_HEADER; } if (st->state != USB_RXS_GET_BUFFER) { /* Read available data */ cntRead = (U16)USB_ReadBulk(st->ptr, st->maxReadLen); Assert(cntRead >= 0); st->ptr += cntRead; /* See if enough data is available */ if (cntRead != st->maxReadLen) { st->maxReadLen = (U16)(st->maxReadLen - cntRead); return TRUE; } } /* All the data for the previous state has been read, now progress * to the next state. */ switch (st->state) { case USB_RXS_GET_HEADER: /* Header was read above. Go to next state. */ st->state = USB_RXS_GET_BUFFER; /* drop through to next state */ case USB_RXS_GET_BUFFER: len = (U16)(LEtoHost16(&(st->header[2])) + st->headerLen); hciConnHandle = LEtoHost16(&(st->header[0])); status = HCI_GetAclBuffer(&st->rxBuffHandle, hciConnHandle, len); if (status == BT_STATUS_SUCCESS) { /* Got an ACL buffer */ st->ptr = HCI_GetRxPtr(st->rxBuffHandle); st->maxReadLen = LEtoHost16(&(st->header[2])); } else if (status == BT_STATUS_NO_RESOURCES) { /* No receive buffer available */ bt_trace(TRACE_GROUP_1,TRANS_NO_ACL_BUFFERS); return FALSE; } Assert(status != BT_STATUS_INVALID_PARM); OS_MemCopy(st->ptr, st->header, st->headerLen); /* Set up for next state */ st->ptr += st->headerLen; st->state = USB_RXS_GET_DATA; break; case USB_RXS_GET_DATA: /* Pass it up */ HCI_RxBufferInd(st->rxBuffHandle, BT_STATUS_SUCCESS); /* Reset to first state */ st->state = USB_RXS_GET_INIT; break; } } while (cntRead); return TRUE; }
int encodec_sbc( U8 min_bit_pool, U8 block_len, // b0: 16, b1: 12, b2: 8, b3: 4 U8 subband_num, // b0: 8, b1: 4 U8 alloc_method, // b0: loudness, b1: SNR U8 sample_rate, // b0: 48000, b1: 44100, b2: 32000, b3: 16000 U8 channel_mode // b0: joint stereo, b1: stereo, b2: dual channel, b3: mono ) { FILE *wavIn, *sbcOut; SbcPcmData pcmData; SbcEncoder encoder; U16 bytesToRead; U16 bytesToEncode; U16 bytesEncoded; XaStatus status; U8 *fNameIn; U8 *fNameOut; U32 sampleFreq = 0; U32 chunk2Size = 0; U16 sbcLen; U8 pathBuf[_MAX_PATH] = {0}; int encodedFrameLen; /* Initialize default encoder settings */ SBC_InitEncoder(&encoder); fNameOut = BT_A2DP_SBC_FILE; switch(sample_rate) { case 0x01: /* 48.0K*/ fNameIn = (U8 *)&BT_A2DP_SRC48_FILE; break; case 0x02: fNameIn = (U8 *)&BT_A2DP_SRC44_FILE; break; case 0x04: fNameIn = (U8 *)&BT_A2DP_SRC32_FILE; break; case 0x08: fNameIn = (U8 *)&BT_A2DP_SRC16_FILE; break; } switch(block_len) { case 0x01: encoder.streamInfo.numBlocks = 16; break; case 0x02: encoder.streamInfo.numBlocks = 12; break; case 0x04: encoder.streamInfo.numBlocks = 8; break; case 0x08: encoder.streamInfo.numBlocks = 4; break; } switch(subband_num) { case 0x01: encoder.streamInfo.numSubBands = 8; break; case 0x02: encoder.streamInfo.numSubBands = 4; break; } switch(alloc_method) { case 0x01: encoder.streamInfo.allocMethod = SBC_ALLOC_METHOD_LOUDNESS; break; case 0x02: encoder.streamInfo.allocMethod = SBC_ALLOC_METHOD_SNR; break; } switch(channel_mode) { case 0x01: encoder.streamInfo.channelMode = SBC_CHNL_MODE_JOINT_STEREO; break; case 0x02: encoder.streamInfo.channelMode = SBC_CHNL_MODE_STEREO; break; case 0x04: encoder.streamInfo.channelMode = SBC_CHNL_MODE_DUAL_CHNL; break; case 0x08: encoder.streamInfo.channelMode = SBC_CHNL_MODE_MONO; break; } encoder.streamInfo.bitPool = min_bit_pool; #if 0 encoder.streamInfo.numBlocks = 16; encoder.streamInfo.numSubBands = 8; encoder.streamInfo.allocMethod = SBC_ALLOC_METHOD_LOUDNESS; encoder.streamInfo.channelMode = SBC_CHNL_MODE_JOINT_STEREO; encoder.streamInfo.bitPool = 35; #endif /* Open the WAV file */ memset(pathBuf, 0, sizeof(pathBuf)); translateFilePath(fNameIn, pathBuf); wavIn = fopen(pathBuf, "rb"); if(wavIn == NULL) return -1; memset(pathBuf, 0, sizeof(pathBuf)); OS_MemSet(pathBuf, 0, sizeof(pathBuf)); translateFilePath(fNameOut, pathBuf); sbcOut = fopen(pathBuf, "wb"); if(sbcOut == NULL) return -1; /**** Parse the WAV header ****/ if (fread(pcmBuffer, 1, 4, wavIn) == 4) { if (memcmp(pcmBuffer, "RIFF", 4) != 0) { printf("Invalid RIFF file format\n"); return -1; } } else { printf("Error reading WAV file\n"); return -1; } /* Read format */ fseek(wavIn, 8, 0); if (fread(pcmBuffer, 1, 4, wavIn) == 4) { if (memcmp(pcmBuffer, "WAVE", 4) != 0) { printf("Invalid WAV format\n"); return -1; } } else { printf("Error reading WAV file\n"); return -1; } /**** Start subchunk 1 ****/ fseek(wavIn, 12, 0); if (fread(pcmBuffer, 1, 4, wavIn) == 4) { if (memcmp(pcmBuffer, "fmt", 3) != 0) { printf("Invalid format chunk\n"); return -1; } } else { printf("Error reading WAV file\n"); return -1; } /* PCM */ fseek(wavIn, 20, 0); if (fread(pcmBuffer, 1, 2, wavIn) == 2) { if (LEtoHost16(pcmBuffer) != 1) { printf("Unsupported audio format\n"); return -1; } } else { printf("Error reading WAV file\n"); return -1; } /* Channels */ if (fread(pcmBuffer, 1, 2, wavIn) == 2) { encoder.streamInfo.numChannels = pcmBuffer[0]; } else { printf("Error reading WAV file\n"); return -1; } /* Sample frequency */ if (fread(pcmBuffer, 1, 4, wavIn) == 4) { sampleFreq = LEtoHost32(pcmBuffer); switch (sampleFreq) { case 48000: encoder.streamInfo.sampleFreq = SBC_CHNL_SAMPLE_FREQ_48; break; case 44100: encoder.streamInfo.sampleFreq = SBC_CHNL_SAMPLE_FREQ_44_1; break; case 32000: encoder.streamInfo.sampleFreq = SBC_CHNL_SAMPLE_FREQ_32; break; case 16000: encoder.streamInfo.sampleFreq = SBC_CHNL_SAMPLE_FREQ_16; break; default: printf("Unsupported sampling frequency %d\n", sampleFreq); return -1; } } else { printf("Error reading WAV file\n"); return -1; } /* Bits per sample */ fseek(wavIn, 34, 0); if (fread(pcmBuffer, 1, 2, wavIn) == 2) { if (LEtoHost32(pcmBuffer) != 16) { printf("Unsupported sample size\n"); } } /**** Data chunk ****/ fseek(wavIn, 44, 0); /* Print out SBC format */ printf("Start\n"); printf("Sampling Frequency = %d\n", sampleFreq); if (encoder.streamInfo.numChannels == 1) { if (encoder.streamInfo.channelMode != SBC_CHNL_MODE_MONO) { printf("Switching to mono mode...\n"); } encoder.streamInfo.channelMode = SBC_CHNL_MODE_MONO; printf("Mode = Mono\n"); } else { switch (encoder.streamInfo.channelMode) { case SBC_CHNL_MODE_JOINT_STEREO: printf("Mode = Joint Stereo\n"); break; case SBC_CHNL_MODE_STEREO: printf("Mode = Stereo\n"); break; case SBC_CHNL_MODE_DUAL_CHNL: printf("Mode = Dual Channel\n"); break; default: printf("Mode = Unknown\n"); } } printf("Blocks = %d\n", encoder.streamInfo.numBlocks); printf("Subbands = %d\n", encoder.streamInfo.numSubBands); if (encoder.streamInfo.allocMethod == SBC_ALLOC_METHOD_SNR) { printf("Allocation = SNR\n"); } else if(encoder.streamInfo.allocMethod == SBC_ALLOC_METHOD_LOUDNESS) { printf("Allocation = LOUDNESS\n"); } else { printf("Allocation = Unknown\n"); } printf("Bitpool = %d\n", encoder.streamInfo.bitPool); /* Initialize PCM data structure */ pcmData.data = pcmBuffer; bytesToRead = encoder.streamInfo.numChannels * encoder.streamInfo.numSubBands * encoder.streamInfo.numBlocks * 2; bytesToRead = (PCM_BUFF_SIZE / bytesToRead) * bytesToRead; /* Start reading the SBC data and encoding */ while ((bytesToEncode = fread(pcmBuffer, 1, bytesToRead, wavIn))) { pcmData.data = pcmBuffer; pcmData.dataLen = bytesToEncode; while (bytesToEncode) { /* Encode the PCM buffer into the SBC buffer */ status = SBC_EncodeFrames(&encoder, &pcmData, &bytesEncoded, sbcBuffer, &sbcLen, SBC_BUFF_SIZE); bytesToEncode -= bytesEncoded; pcmData.data += bytesEncoded; pcmData.dataLen -= bytesEncoded; if (status == XA_STATUS_SUCCESS) { /* Block encoded */ if (fwrite(sbcBuffer, 1, sbcLen, sbcOut) != sbcLen) { printf("Error writing SBC data\n"); return -1; } } else if (status != XA_STATUS_CONTINUE) { /* Parsing error */ printf("Error encoding SBC stream\n"); return -1; } else { /* Not enough data left to encode a frame */ break; } } } printf("Done\n"); fclose(wavIn); fclose(sbcOut); encodedFrameLen = SBC_FrameLen(&encoder.streamInfo); return encodedFrameLen; }
void A2MPHandleReadLocalAMPAssoc(const BtEvent *Event) { BT_AMP_HCI_EVENT_READ_LOCAL_AMP_ASSOC result; U8 *parm; U8 controllerId; A2MP_MAIN_CONN *a2mp_channel; U8 length; U8 amp_assoc_size; BtA2MPGetAMPAssocRsp a2mp_parm; BtA2MPCreatePhysicalLinkReq a2mp_create_parm; parm = (U8 *)Event->p.hciAmpEvent.parms; controllerId = Event->p.hciAmpEvent.controllerId; result.physical_link_handle = parm[1]; result.amp_assoc_remaining_length = LEtoHost16(parm+2); result.amp_assoc_fragment = parm+4; a2mp_channel = A2MP_FindMainChannelByPhysicalLink(result.physical_link_handle); if(a2mp_channel ==0) { /* Error*/ Assert(0); } if(Event->errCode !=0) { a2mp_parm.controllerId = controllerId; a2mp_parm.ampAssocSize = 0x00; a2mp_parm.ampAssoc = NULL; a2mp_parm.status = 0x01; BTA2MP_SendGetAMPAssocResponse(a2mp_channel->remDev, &a2mp_parm); return; } if(parm[0] <= 4) Assert(0); amp_assoc_size = (parm[0] -4); a2mp_channel->remDev->remoteWifiAMP.read_local_assoc.amp_assoc_length = 248; a2mp_channel->remDev->remoteWifiAMP.read_local_assoc.length_so_far += amp_assoc_size; memcpy(a2mp_channel->local_amp_assoc + a2mp_channel->local_amp_assoc_size, result.amp_assoc_fragment, amp_assoc_size); a2mp_channel->local_amp_assoc_size += amp_assoc_size; if((result.amp_assoc_remaining_length - amp_assoc_size) !=0) ME_ReadLocalAMPAssoc(&a2mp_channel->remDev->remoteWifiAMP); else { if(a2mp_channel->last_rxCmdopcode == A2MP_CODE_GET_AMP_ASSOC_REQ) { a2mp_parm.controllerId = controllerId; a2mp_parm.ampAssocSize = a2mp_channel->local_amp_assoc_size; a2mp_parm.ampAssoc = a2mp_channel->local_amp_assoc; a2mp_parm.status = 0x00; BTA2MP_SendGetAMPAssocResponse(a2mp_channel->remDev, &a2mp_parm); } if(a2mp_channel->ampNeedToCreatePhysicalLink == 1) { a2mp_channel->ampNeedToCreatePhysicalLink = 0; a2mp_create_parm.ampAssoc = a2mp_channel->local_amp_assoc; a2mp_create_parm.ampAssocSize = a2mp_channel->local_amp_assoc_size; a2mp_create_parm.localControllerId = a2mp_channel->localControllerId; a2mp_create_parm.remoteControllerId = a2mp_channel->remDev->remoteWifiAMP.remoteControllerId; BTA2MP_SendCreatePhysicalLinkRequest(a2mp_channel->remDev, &a2mp_create_parm); } } }