/* * Copyright (c) 2008-2009 Atheros Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * * * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "btconfig.h" #include "masterblaster.h" /* Global Variables */ static int Tag_Count = 0; static int Patch_Count = 0; static unsigned short DynMem_Count = 0; static int Total_tag_lenght = 0; static BOOL CtrlCBreak = FALSE; bdaddr_t BdAddr; /* Function Declarations */ static int LoadConfFile(const char *path, int basetag, int format); static int ParseFiles(FILE *fpt, int basetag, int format); static void LoadPSHeader(UCHAR *HCI_PS_Command,UCHAR opcode,int length,int index); static BOOL PSOperations(int dd, UCHAR Opcode, int Param1, UINT32 *out); static BOOL SU_LERxTest(int dev_id, UCHAR channel); static BOOL SU_LETxTest(int dev_id, UCHAR channel, UCHAR length, UCHAR payload); static int PSInit(int dd); static void usage(void); static int writeHciCommand(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, UCHAR *buf); static int MemBlkRead(int dd, UINT32 Address,UCHAR *pBuffer, UINT32 Length); static int MemBlkwrite(int dd, UINT32 Address,UCHAR *pBuffer, UINT32 Length); static int Dut(int dd); static int ReadAudioStats(int dd); static int ReadGlobalDMAStats(int dd); static int ResetGlobalDMAStats(int dd); static int ReadTpcTable(int dd); static int ReadHostInterest(int dd,tBtHostInterest *pHostInt); static int ReadMemoryBlock(int dd, int StartAddress,UCHAR *pBufToWrite, int Length ); static int WriteMemoryBlock(int dd, int StartAddress,UCHAR *pBufToWrite, int Length ); static int write_otpRaw(int dev_id, int address, int length, UCHAR *data); static int read_otpRaw(int dev_id, int address, int length, UCHAR *data); static void dumpHex(UCHAR *buf, int length, int col); static void sig_term(int sig); static UCHAR LEMode = 0; static struct option main_options[] = { { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, { 0, 0, 0, 0 } }; //Read the configuration files, file paths are hardcoded in btconfig.h static int LoadConfFile(const char *path, int basetag, int format){ FILE *fp; //printf("\nOpening file :%s\n",path); fp = fopen(path,"r"); if(fp == NULL){ // perror("File open error"); return FALSE; } // Parse file if(!ParseFiles(fp,basetag,format)){ printf("\nError :Invalid file format\n"); return FALSE; } // Load conf data to PS fclose(fp); return TRUE; } unsigned int uGetInputDataFormat(char **str, struct ST_PS_DATA_FORMAT *pstFormat) { char *pCharLine = *str; if(pCharLine[0] != '[') { pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; return TRUE; } switch(pCharLine[1]) { case 'H': case 'h': if(pCharLine[2]==':') { if((pCharLine[3]== 'a') || (pCharLine[3]== 'A')) { if(pCharLine[4] == ']') { pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 5; *str += 5; return TRUE; } else { printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); //[H:A return FALSE; } } if((pCharLine[3]== 'S') || (pCharLine[3]== 's')) { if(pCharLine[4] == ']') { pstFormat->eDataType = eHex; pstFormat->bIsArray = FALSE; //pCharLine += 5; *str += 5; //printf("\nDEBUG H-1:%s\n",pCharLine); return TRUE; } else { printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); //[H:A return FALSE; } } else if(pCharLine[3] == ']') { //[H:] pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 4; *str += 4; return TRUE; } else { //[H: printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); return FALSE; } } else if(pCharLine[2]==']') { //[H] pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 3; *str += 5; return TRUE; } else { //[H printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); return FALSE; } break; case 'A': case 'a': if(pCharLine[2]==':') { if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) { if(pCharLine[4] == ']') { pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 5; *str += 5; return TRUE; } else { printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); //[A:H return FALSE; } } else if(pCharLine[3]== ']') { //[A:] pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 4; *str += 5; return TRUE; } else { //[A: printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); return FALSE; } } else if(pCharLine[2]==']') { //[H] pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 3; *str += 5; return TRUE; } else { //[H printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); return FALSE; } break; case 'S': case 's': if(pCharLine[2]==':') { if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) { if(pCharLine[4] == ']') { pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 5; *str += 5; return TRUE; } else { printf("\nuGetInputDataFormat - Invalid Data Format \r\n");//[A:H return FALSE; } } else if(pCharLine[3]== ']') { //[A:] pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 4; *str += 5; return TRUE; } else { //[A: printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); return FALSE; } } else if(pCharLine[2]==']') { //[H] pstFormat->eDataType = eHex; pstFormat->bIsArray = TRUE; //pCharLine += 3; *str += 5; return TRUE; } else { //[H printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); return FALSE; } break; default: printf("\nuGetInputDataFormat - Invalid Data Format \r\n"); return FALSE; } } unsigned int uReadDataInSection(char *pCharLine, struct ST_PS_DATA_FORMAT stPS_DataFormat) { if(stPS_DataFormat.eDataType == eHex) { if(stPS_DataFormat.bIsArray == TRUE) { //Not implemented printf("\nNO IMP\n"); return (0x0FFF); } else { //printf("\nDEBUG H-2 %d\n",strtol(pCharLine, NULL, 16)); return (strtol(pCharLine, NULL, 16)); } } else { //Not implemented printf("\nNO IMP-1\n"); return (0x0FFF); } } static int ParseFiles(FILE *fpt, int basetag, int format){ int i,j,k,linecnt,ByteCount=0,ByteCount_Org =0,data,Cnt; char *str,line[LINE_SIZE_MAX],byte[3]; int ParseSelection=RAM_PS_SECTION; struct ST_PS_DATA_FORMAT stPS_DataFormat; struct ST_READ_STATUS stReadStatus = {0, 0, 0,0}; unsigned int uReadCount; switch(format){ case MB_FILEFORMAT_PS: linecnt = 0; j=0; while ((str = fgets(line, LINE_SIZE_MAX, fpt)) != NULL) { SKIP_BLANKS(str); //Comment line if ((str[0]== '/') && (str[1]== '/')) continue; if (str[0]== '#'){ if (stReadStatus.uSection != 0){ printf("\nParseFiles - Invalid file format %d\r\n",ParseSelection); return FALSE; } else { stReadStatus.uSection = 1; continue; } } if ((str[0]== '/') && (str[1]== '*')) { str+=2; SKIP_BLANKS(str); if(!strncmp(str,"PA",2)||!strncmp(str,"Pa",2)||!strncmp(str,"pa",2)){ ParseSelection=RAM_PATCH_SECTION; } if(!strncmp(str,"DY",2)||!strncmp(str,"Dy",2)||!strncmp(str,"dy",2)){ ParseSelection=RAM_DYN_MEM_SECTION; } if(!strncmp(str,"PS",2)||!strncmp(str,"Ps",2)||!strncmp(str,"ps",2)){ ParseSelection=RAM_PS_SECTION; } linecnt = 0; stReadStatus.uSection = 0; continue; } switch(ParseSelection){ case RAM_PS_SECTION: if (stReadStatus.uSection == 1){ //TagID SKIP_BLANKS(str); if(!uGetInputDataFormat(&str, &stPS_DataFormat)) { return FALSE; } PsTagEntry[Tag_Count].TagId = uReadDataInSection(str, stPS_DataFormat); stReadStatus.uSection = 2; } else if (stReadStatus.uSection == 2){ //TagLength if(!uGetInputDataFormat(&str, &stPS_DataFormat)) { return FALSE; } ByteCount = uReadDataInSection(str, stPS_DataFormat); if (ByteCount > RAMPS_MAX_PS_DATA_PER_TAG){ printf("\nParseFiles - INVALID %d: One of the table exceeds maximum table size of %d\r\n",ParseSelection, MAX_RADIO_CFG_TABLE_SIZE); return FALSE; } PsTagEntry[Tag_Count].TagLen = (ByteCount & 0xFF); stReadStatus.uSection = 3; stReadStatus.uLineCount = 0; } else if( stReadStatus.uSection == 3) { //Data if(stReadStatus.uLineCount == 0) { if(!uGetInputDataFormat(&str,&stPS_DataFormat)) { return FALSE; } } SKIP_BLANKS(str); stReadStatus.uCharCount = 0; uReadCount = (ByteCount > BYTES_OF_PS_DATA_PER_LINE)? BYTES_OF_PS_DATA_PER_LINE: ByteCount; if((stPS_DataFormat.eDataType == eHex) && stPS_DataFormat.bIsArray == TRUE) { while(uReadCount > 0) { PsTagEntry[Tag_Count].TagData[stReadStatus.uByteCount] = (UCHAR)(CONV_HEX_DIGIT_TO_VALUE(str[stReadStatus.uCharCount]) << 4) | (UCHAR)(CONV_HEX_DIGIT_TO_VALUE(str[stReadStatus.uCharCount + 1])); PsTagEntry[Tag_Count].TagData[stReadStatus.uByteCount+1] = (UCHAR)(CONV_HEX_DIGIT_TO_VALUE(str[stReadStatus.uCharCount + 3]) << 4) | (UCHAR)(CONV_HEX_DIGIT_TO_VALUE(str[stReadStatus.uCharCount + 4])); stReadStatus.uCharCount += 6; // read two bytes, plus a space; stReadStatus.uByteCount += 2; uReadCount -= 2; } if(ByteCount > BYTES_OF_PS_DATA_PER_LINE) { ByteCount -= BYTES_OF_PS_DATA_PER_LINE; } else { ByteCount = 0; } } else { //to be implemented printf("\nParseFiles - To be implemented"); } stReadStatus.uLineCount++; if(ByteCount == 0) { stReadStatus.uSection = 0; stReadStatus.uCharCount = 0; stReadStatus.uLineCount = 0; stReadStatus.uByteCount = 0; } else { stReadStatus.uCharCount = 0; } if((stReadStatus.uSection == 0)&&(++Tag_Count == RAMPS_MAX_PS_TAGS_PER_FILE)) { printf("\n ParseFiles - INVALID %d: Number of tables exceeds %d\r\n",ParseSelection, RAMPS_MAX_PS_TAGS_PER_FILE); return FALSE; } } break; default: { printf("\nParseFiles - Invalid file format %d\r\n",ParseSelection); return FALSE; } break; } linecnt++; } break; case MB_FILEFORMAT_DY: { linecnt = 0; while ((str = fgets(line, LINE_SIZE_MAX, fpt)) != NULL) { SKIP_BLANKS(str); //Comment line if ((str[0]== '/') && (str[1]== '/')) continue; if ((str[0]== '/') && (str[1]== '*')) { continue; } if((linecnt % 2) == 0) { ByteCount = (UINT16)strtol(str, NULL, 16); RamDynMemOverride.Len= (ByteCount & 0xFF); } else { for (i=0,k=0; k < ByteCount; i += 2,k++) { memcpy(byte, &str[i], 2); byte[2] = '\0'; data = strtoul(byte, NULL, 16); RamDynMemOverride.Data[k] = (data & 0xFF); } DynMem_Count = TRUE; } linecnt++; } } break; case MB_FILEFORMAT_PATCH: { j=0; Cnt=0; linecnt = 0; while ((str = fgets(line, LINE_SIZE_MAX, fpt)) != NULL) { SKIP_BLANKS(str); //Comment line if ((str[0]== '/') && (str[1]== '/')) continue; if ((str[0]== '/') && (str[1]== '*')) { continue; } if(linecnt==0) { ByteCount = (UINT16)strtol(str, NULL, 16); ByteCount_Org = ByteCount; while(ByteCount > MAX_BYTE_LENGTH){ RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH; Patch_Count ++; ByteCount= ByteCount - MAX_BYTE_LENGTH; } RamPatch[Patch_Count].Len= (ByteCount & 0xFF); Patch_Count ++; } else { while(ByteCount_Org > MAX_BYTE_LENGTH){ for (i = 0, k=0; i < MAX_BYTE_LENGTH*2; i += 2,k++) { memcpy(byte, &str[Cnt], 2); byte[2] = '\0'; data = strtoul(byte, NULL, 16); RamPatch[j].Data[k] = (data & 0xFF); Cnt += 2; } j++; ByteCount_Org = ByteCount_Org - MAX_BYTE_LENGTH; } if(j == 0){ j++; } for (k=0; k < ByteCount_Org;k++) { memcpy(byte, &str[Cnt], 2); byte[2] = '\0'; data = strtoul(byte, NULL, 16); RamPatch[j].Data[k] = (data & 0xFF); Cnt += 2; } } linecnt++; } } break; } return TRUE; } static void LoadPSHeader(UCHAR *HCI_PS_Command,UCHAR opcode,int length,int index) { HCI_PS_Command[0]= opcode; HCI_PS_Command[1]= (index & 0xFF); HCI_PS_Command[2]= ((index>>8) & 0xFF); HCI_PS_Command[3]= length; } static BOOL PSOperations(int dd, UCHAR Opcode, int Param1, UINT32 *out) { UCHAR buf[HCI_MAX_EVENT_SIZE]; int Length,i,j,iRet; memset(&buf,0,sizeof(buf)); switch(Opcode){ case WRITE_PATCH: for(i=0;i< Param1;i++){ LoadPSHeader(buf,Opcode,RamPatch[i].Len,i); for(j=0;j> 8) & 0xFF); Length = 6; iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,Length + PS_COMMAND_HEADER, buf); if(buf[iRet-1] != 0){ return FALSE; } break; case PS_READ: { UCHAR *len = (UCHAR *)out; ssize_t plen = 0; Length = len[0] | ( len[1] << 8); LoadPSHeader(buf,Opcode,Length,Param1); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS, Length + PS_COMMAND_HEADER, buf); if(buf[iRet-1] != 0) { return FALSE; } do { plen = read(dd, buf, HCI_MAX_EVENT_SIZE); if (plen < 0) return FALSE; } while (buf[HCI_EVENT_HEADER_SIZE] != DEBUG_EVENT_TYPE_PS); memcpy((UCHAR *)out, buf + HCI_EVENT_HEADER_SIZE + 1, plen - HCI_EVENT_HEADER_SIZE - 1); break; } case PS_WRITE: for(i=0;i< Param1;i++){ LoadPSHeader(buf,Opcode,PsTagEntry[i].TagLen,PsTagEntry[i].TagId); for(j=0;j> 8) & 0xFF); buf[2] = ((FPGA_REGISTER >> 16) & 0xFF); buf[3] = ((FPGA_REGISTER >> 24) & 0xFF); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_READ_MEMORY,4, buf); if(buf[6] != 0){ return FALSE; } Reg = buf[10]; Reg = ((Reg << 8) | buf[9]); Reg = ((Reg << 8) | buf[8]); Reg = ((Reg << 8) | buf[7]); return Reg; } #endif /* PS Operations */ static int PSInit(int dd){ int i,Crc=0,DevType =0; BOOL BDADDR_Present = 0; BOOL File_Present = 0; //DevType = GetDeviceType(dd); //printf("\nDevice Type:%x\n",DevType); if(DevType){ if(DevType == 0xdeadc0de){ if(!LoadConfFile(PS_ASIC_FILENAME,0xFFFFFFFF,MB_FILEFORMAT_PS)){ printf("\nPlease copy PS file to :%s\n",PS_ASIC_FILENAME); //return FALSE; } else File_Present = 1; } else{ if(!LoadConfFile(PS_FPGA_FILENAME,0xFFFFFFFF,MB_FILEFORMAT_PS)){ printf("\nPlease copy PS file to :%s\n",PS_FPGA_FILENAME); File_Present = 1; //return FALSE; } else File_Present = 1; } } else{ if(!LoadConfFile(PS_ASIC_FILENAME,0xFFFFFFFF,MB_FILEFORMAT_PS)){ printf("\nPlease copy PS file to :%s\n",PS_ASIC_FILENAME); File_Present = 1; //return FALSE; } else File_Present = 1; } if(!LoadConfFile(PATCH_FILENAME,0xFFFFFFFF,MB_FILEFORMAT_PATCH)){ printf("\nPlease copy Patch file to :%s\n",PATCH_FILENAME); File_Present = 1; } else File_Present = 1; if(!File_Present){ printf("\nPS and Patch files are not present\n"); return FALSE; } if(Tag_Count == 0){ Total_tag_lenght = 10; } else{ for(i=0; i 0 && !BDADDR_Present){ //printf("\nReadPSFiles - BD ADDR is not present adding 10 extra bytes \r\n"); Total_tag_lenght=Total_tag_lenght + 10; } Total_tag_lenght = Total_tag_lenght+ 10 + (Tag_Count*4); // printf("\nPSInitialize - PATCH:%d, DYN:%d, TAG:%d Total_tag_lenght:%d\n",Patch_Count,DynMem_Count,Tag_Count,Total_tag_lenght); if(Patch_Count > 0) Crc |= RAM_PATCH_REGION; if(DynMem_Count) Crc |= RAM_DYN_MEM_REGION; if(Tag_Count > 0) Crc |= RAM_PS_REGION; if(Patch_Count || DynMem_Count || Tag_Count ){ if(Patch_Count > 0){ if(!PSOperations(dd,WRITE_PATCH,Patch_Count, NULL)){ printf("\nPSInitialize - *** WRITE_PATCH FAILED**** \r\n"); return FALSE; } if(!PSOperations(dd,ENABLE_PATCH,0, NULL)){ printf("\nPSInitialize - *** ENABLE_PATCH FAILED**** \r\n"); return FALSE; } } if(DynMem_Count){ if(!PSOperations(dd,PS_DYNMEM_OVERRIDE,DynMem_Count, NULL)){ printf("\nPSInitialize - *** PS_DYNMEM_OVERRIDE FAILED**** \r\n"); return FALSE; } } if(!PSOperations(dd,PS_RESET,Total_tag_lenght, NULL)){ printf("\nPSInitialize - *** PS RESET FAILED**** \r\n"); return FALSE; } if(Tag_Count > 0){ if(!PSOperations(dd,PS_WRITE,Tag_Count, NULL)){ printf("\nPSInitialize - *** PS_WRITE FAILED**** \r\n"); return FALSE; } } } if(!PSOperations(dd,PS_VERIFY_CRC,Crc, NULL)){ printf("\nVerify CRC failed\n"); return FALSE; } return TRUE; } static int writeHciCommand(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, UCHAR *buf){ #ifdef DUMP_DEBUG #define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) #if __BYTE_ORDER == __LITTLE_ENDIAN #define htobs(d) (d) #elif __BYTE_ORDER == __BIG_ENDIAN #define htobs(d) bswap_16(d); #else #error "Unknown byte order" #endif int i = 0, j = 0; uint16_t opcode = htobs(cmd_opcode_pack(ogf, ocf)); printf("\nDump:\n"); printf("0x%02X ", opcode & 0xff); i++; printf("0x%02X ", (opcode & 0xff00) >> 8); i++; printf("0x%02X ", plen); i++; for (j = 0; j < plen; i++, j++) { printf("0x%02X ", buf[j]); if (((i+1) % 8) == 0 && i != 0) printf("\n"); } if (((i+1) % 8) != 0) printf("\n"); buf[6] = 0; return plen; #else struct hci_filter flt; uint16_t opcode, topcode; /* Setup filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_all_events(&flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("HCI filter setup failed"); exit(EXIT_FAILURE); } //printf("< HCI Command: ogf 0x%02x, ocf 0x%04x, plen %d\n", ogf, ocf, plen); if (hci_send_cmd(dd, ogf, ocf, plen, buf) < 0) { perror("Send failed"); hci_close_dev(dd); exit(EXIT_FAILURE); } sleep(0.4); opcode = (ogf << 10 | ocf); do { plen = read(dd, buf,HCI_MAX_EVENT_SIZE); if (plen < 0) { perror("Read failed"); hci_close_dev(dd); exit(EXIT_FAILURE); } topcode=(uint16_t)(buf[4] | (buf[5] << 8)); }while(topcode != opcode); return plen; #endif } static int MemBlkRead(int dd,UINT32 Address,UCHAR *pBuffer, UINT32 Length){ UINT32 Size, ByteLeft,IntCnt; UCHAR *pData,*pTemp=pBuffer; int iRet; int TempVal; IntCnt =0; TempVal = (Length % 4); if (TempVal !=0) { Length = Length + (4- (Length%4)); } ByteLeft = Length; while (ByteLeft > 0) { Size = (ByteLeft > MEM_BLK_DATA_MAX) ? MEM_BLK_DATA_MAX : ByteLeft; // printf("\nMemBlkwrite : Size :%x Address :%x\n",Size, Address); pData = (UCHAR *) malloc(Size + 6); pData[0]= 0x00;//depot/esw/projects/azure/AR3001_3_0/src/hci/Hci_Vsc_Proc.c pData[1]= (Address & 0xFF); pData[2]= ((Address >> 8) & 0xFF); pData[3]= ((Address >> 16) & 0xFF); pData[4]= ((Address >> 24) & 0xFF); pData[5]= Size; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_MEMOP,6,pData); if(pData[6]!= 0){ printf("\nwrite memory command failed due to reason 0x%X\n",pData[6]); free(pData); return FALSE; } if ((read(dd, pData,HCI_MAX_EVENT_SIZE)) < 0) { perror("Read failed"); exit(EXIT_FAILURE); } if(pData[3]!=3) { perror("Read failed"); exit(EXIT_FAILURE); } memcpy(pTemp,(pData+4),Size); pTemp+=Size; IntCnt = Size; ByteLeft -= Size; Address += Size; free(pData); } return TRUE; } static int MemBlkwrite(int dd,UINT32 Address,UCHAR *pBuffer, UINT32 Length){ UINT32 Size, ByteLeft,IntCnt; UCHAR *pData; int iRet; ByteLeft = Length; IntCnt =0; while (ByteLeft > 0) { Size = (ByteLeft > MEM_BLK_DATA_MAX) ? MEM_BLK_DATA_MAX : ByteLeft; // printf("\nMemBlkwrite : Size :%x Address :%x\n",Size, Address); pData = (UCHAR *) malloc(Size + 6); pData[0]= 0x01; pData[1]= (Address & 0xFF); pData[2]= ((Address >> 8) & 0xFF); pData[3]= ((Address >> 16) & 0xFF); pData[4]= ((Address >> 24) & 0xFF); pData[5]= Size; memcpy(&pData[6],&pBuffer[IntCnt],Size); iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_MEMOP,Size+6,pData); if(pData[6]!= 0){ printf("\nwrite memory command faileddue to reason 0x%X\n",pData[6]); free(pData); return FALSE; } IntCnt = Size; ByteLeft -= Size; Address += Size; free(pData); } return TRUE; } static int Dut(int dd){ int iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 3; //All scan enabled iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, buf); if(buf[6] != 0){ printf("\nWrite scan mode command failed due to reason 0x%X\n",buf[6]); return FALSE; } sleep(1); memset(&buf,0,HCI_MAX_EVENT_SIZE); iRet = writeHciCommand(dd, OGF_TEST_CMD, OCF_ENABLE_DEVICE_UNDER_TEST_MODE, 0, buf); if(buf[6] != 0){ printf("\nDUT mode command failed due to reason 0x%X\n",buf[6]); return FALSE; } memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 0; //SEQN Track enable =0 iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_TEST_MODE_SEQN_TRACKING , 1, buf); if(buf[6] != 0){ printf("\nTest Mode seqn Tracking failed due to reason 0x%X\n",buf[6]); return FALSE; } return TRUE; } void Audio_DumpStats(tAudioStat *AudioStats) { printf("\n\n"); printf(" Audio Statistics\n"); printf(">RxCmplt: %d\n",AudioStats->RxCmplt); printf(">TxCmplt: %d\n",AudioStats->TxCmplt); printf(">RxSilenceInsert: %d\n",AudioStats->RxSilenceInsert); printf(">RxAirPktDump: %d\n",AudioStats->RxAirPktDump); printf(">MaxPLCGenInterval: %d\n",AudioStats->MaxPLCGenInterval); printf(">RxAirPktStatusGood: %d\n",AudioStats->RxAirPktStatusGood); printf(">RxAirPktStatusError: %d\n",AudioStats->RxAirPktStatusError); printf(">RxAirPktStatusLost: %d\n",AudioStats->RxAirPktStatusLost); printf(">RxAirPktStatusPartial: %d\n",AudioStats->RxAirPktStatusPartial); printf(">SampleMin: %d\n",AudioStats->SampleMin); printf(">SampleMax: %d\n",AudioStats->SampleMax); printf(">SampleCounter: %d\n",AudioStats->SampleCounter); printf("\n\n"); memset((UCHAR *)AudioStats, 0, sizeof(tAudioStat)); AudioStats->SampleMax =SHRT_MIN; AudioStats->SampleMin =SHRT_MAX; } static int ReadAudioStats(int dd){ tBtHostInterest HostInt; tAudioStat Stats; ReadHostInterest(dd, &HostInt); if(!HostInt.AudioStatAddr || (HostInt.Version < 0x0300)){ printf("\nAudio Stat not present\n"); return FALSE; } ReadMemoryBlock(dd,HostInt.AudioStatAddr,(UCHAR *)&Stats,sizeof(tAudioStat)); Audio_DumpStats(&Stats); return TRUE; } void BRM_DumpStats(tBRM_Stats *Stats) { printf("\n Link Controller Voice DMA Statistics\n"); printf(" %22s: %u\n", "VoiceTxDmaIntrs", Stats->VoiceTxDmaIntrs); printf(" %22s: %u\n", "VoiceTxPktAvail", Stats->VoiceTxPktAvail); printf(" %22s: %u\n", "VoiceTxPktDumped", Stats->VoiceTxPktDumped); printf(" %22s: %u\n", "VoiceTxErrors", Stats->VoiceTxErrorIntrs); printf(" %22s: %u\n", "VoiceTxDmaErrors", Stats->VoiceTxDmaErrorIntrs); printf(" %22s: %u\n", "VoiceTxSilenceInserts", Stats->VoiceTxDmaSilenceInserts); printf("\n"); printf(" %22s: %u\n", "VoiceRxDmaIntrs", Stats->VoiceRxDmaIntrs); printf(" %22s: %u\n", "VoiceRxGoodPkts", Stats->VoiceRxGoodPkts); printf(" %22s: %u\n", "VoiceRxPktDumped", Stats->VoiceRxPktDumped); printf(" %22s: %u\n", "VoiceRxErrors", Stats->VoiceRxErrorIntrs); printf(" %22s: %u\n", "VoiceRxCRC", Stats->VoiceRxErrCrc); printf(" %22s: %u\n", "VoiceRxUnderOverFlow", Stats->VoiceRxErrUnderOverFlow); printf("\n"); printf(" %22s: %u\n", "SchedOnVoiceError", Stats->SchedOnVoiceError); printf(" %22s: %u\n", "VoiceTxReapOnError", Stats->VoiceTxReapOnError); printf(" %22s: %u\n", "VoiceRxReapOnError", Stats->VoiceRxReapOnError); printf(" %22s: %u\n", "VoiceSchedulingError", Stats->VoiceSchedulingError); printf("\n Link Controller ACL DMA Statistics\n"); printf(" %22s: %u\n", "DmaIntrs", Stats->DmaIntrs); printf(" %22s: %u\n", "ErrWrongLlid", Stats->ErrWrongLlid); printf(" %22s: %u\n", "ErrL2CapLen", Stats->ErrL2CapLen); printf(" %22s: %u\n", "ErrUnderOverFlow", Stats->ErrUnderOverFlow); printf(" %22s: %u\n", "RxBufferDumped", Stats->RxBufferDumped); printf(" %22s: %u\n", "ErrWrongLmpPktType", Stats->ErrWrongLmpPktType); printf(" %22s: %u\n", "ErrWrongL2CapPktType", Stats->ErrWrongL2CapPktType); printf(" %22s: %u\n", "IgnoredPkts", Stats->IgnoredPkts); printf("\n"); printf(" %22s: %u\n", "Data TxBuffers", Stats->DataTxBuffers); printf(" %22s: %u\n", "Data RxBuffers", Stats->DataRxBuffers); printf(" %22s: %u\n", "LMP TxBuffers", Stats->LmpTxBuffers); printf(" %22s: %u\n", "LMP RxBuffers", Stats->LmpRxBuffers); printf(" %22s: %u\n", "HEC Errors", Stats->HecFailPkts); printf(" %22s: %u\n", "CRC Errors", Stats->CrcFailPkts); // Buffer Management printf("\n Buffer Management Statistics\n"); printf(" %22s: %u\n", "CtrlErrNoLmpBufs", Stats->CtrlErrNoLmpBufs); printf("\n Sniff Statistics\n"); printf(" %22s: %u\n", "SniffSchedulingError", Stats->SniffSchedulingError); printf(" %22s: %u\n", "SniffIntervalNoCorr", Stats->SniffIntervalNoCorr); // Other stats printf("\n Other Statistics\n"); printf(" %22s: %u\n", "ForceOverQosJob", Stats->ForceOverQosJob); //printf(" %22s: %u\n", "Temp 1", Stats->Temp1); //printf(" %22s: %u\n", "Temp 2", Stats->Temp2); // Test Mode Stats printf("\n Test Mode Statistics\n"); printf(" %22s: %u\n", "TestModeDroppedTxPkts", Stats->TestModeDroppedTxPkts); printf(" %22s: %u\n", "TestModeDroppedLmps", Stats->TestModeDroppedLmps); // Error Stats printf("\n General Error Statistics\n"); printf(" %22s: %u\n", "TimePassedIntrs", Stats->TimePassedIntrs); printf(" %22s: %u\n", "NoCommandIntrs", Stats->NoCommandIntrs); } static int ReadGlobalDMAStats(int dd){ tBtHostInterest HostInt; tBRM_Stats Stats; ReadHostInterest(dd, &HostInt); if(!HostInt.GlobalDmaStats || (HostInt.Version < 0x0100)){ printf("\nGlobal DMA stats not present\n"); return FALSE; } ReadMemoryBlock(dd,HostInt.GlobalDmaStats,(UCHAR *)&Stats,sizeof(tBRM_Stats)); BRM_DumpStats(&Stats); return TRUE; } static int ResetGlobalDMAStats(int dd){ tBtHostInterest HostInt; tBRM_Stats Stats; ReadHostInterest(dd, &HostInt); if(!HostInt.GlobalDmaStats || (HostInt.Version < 0x0100)){ printf("\nGlobal DMA stats not present\n"); return FALSE; } memset(&Stats,0,sizeof(Stats)); printf("\nHarry\n"); WriteMemoryBlock(dd,HostInt.GlobalDmaStats,(UCHAR *)&Stats,sizeof(tBRM_Stats)); printf("\nDMA stattestics has been reset\n"); return TRUE; } static int ReadTpcTable(int dd){ tBtHostInterest HostInt; tPsSysCfgTransmitPowerControlTable TpcTable; int i; ReadHostInterest(dd, &HostInt); if(!HostInt.TpcTableAddr || (HostInt.Version < 0x0100)){ printf("\nTPC table not present\n"); return FALSE; } ReadMemoryBlock(dd,HostInt.TpcTableAddr,(UCHAR *)&TpcTable,sizeof(TpcTable)); for(i=0;i< TpcTable.NumOfEntries; i++){ printf("Level [%d] represents %3d dBm\n",i,TpcTable.t[i].TxPowerLevel); } return TRUE; } /* static void dump_conf_data(){ printf("\nTAG_COUNT %d\n",Tag_Count); int i=0,j=0; for(i=0;i 1){ printf("\n%s\n",psreset_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } PSInit(dd); memset(&buf,0,sizeof(buf)); iRet = writeHciCommand(dd, OGF_HOST_CTL,OCF_RESET,Length,buf); if(buf[6] != 0){ printf("\nError: HCI RESET failed due to reason 0x%X\n",buf[6]); return; } // Bttest work around for external 32k int IsForeverRepeat=0; int IsCmdIdle=0; int address=0, width = 0, value=0; int loop=0,Reg=0; do { address = 0x00020024; width = 4; buf[0] = (address & 0xFF); buf[1] = ((address >>8) & 0xFF); buf[2] = ((address>>16) & 0xFF); buf[3] = ((address>>24) & 0xFF); buf[4] = (UCHAR)width; //Memory width iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_READ_MEMORY, 5, buf); if(buf[6] != 0){ printf("\nRead Memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } value = buf[10]; value = ((value << 8) | buf[9]); value = ((value << 8) | buf[8]); value = ((value << 8) | buf[7]); if(value&0x40000000) IsForeverRepeat=1; else IsForeverRepeat=0; address = 0x00020020; width = 4; buf[0] = (address & 0xFF); buf[1] = ((address >>8) & 0xFF); buf[2] = ((address>>16) & 0xFF); buf[3] = ((address>>24) & 0xFF); buf[4] = (UCHAR)width; //Memory width iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_READ_MEMORY, 5, buf); if(buf[6] != 0){ printf("\nRead Memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } value = buf[10]; value = ((value << 8) | buf[9]); value = ((value << 8) | buf[8]); value = ((value << 8) | buf[7]); if((value&0x0000000f)==0x8) IsCmdIdle=1; else IsCmdIdle=0; } while(!(IsForeverRepeat&IsCmdIdle));//Wait til brm issues forever idle address = 0x000200a8; width = 4; buf[0] = (address & 0xFF); buf[1] = ((address >>8) & 0xFF); buf[2] = ((address>>16) & 0xFF); buf[3] = ((address>>24) & 0xFF); buf[4] = (UCHAR)width; //Memory width iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_READ_MEMORY, 5, buf); if(buf[6] != 0){ printf("\nRead Memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } value = buf[10]; value = ((value << 8) | buf[9]); value = ((value << 8) | buf[8]); value = ((value << 8) | buf[7]); value |= 0x1; loop = 0; while ( loop < 10 ) { loop++; address = 0x000200a8; width = 4; buf[0] = (address & 0xFF); buf[1] = ((address >>8) & 0xFF); buf[2] = ((address>>16) & 0xFF); buf[3] = ((address>>24) & 0xFF); buf[4] = width; //Memory width buf[5] = (value & 0xFF); buf[6] = ((value >> 8) & 0xFF); buf[7] = ((value >> 16) & 0xFF); buf[8] = ((value >> 24) & 0xFF); buf[9] = 0xFF; buf[10] = 0xFF; buf[11] = 0xFF; buf[12] = 0xFF; iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite memory address failed\n"); hci_close_dev(dd); return; } address = 0x00004064; width = 4; buf[0] = (address & 0xFF); buf[1] = ((address >>8) & 0xFF); buf[2] = ((address>>16) & 0xFF); buf[3] = ((address>>24) & 0xFF); buf[4] = (UCHAR)width; //Memory width iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_READ_MEMORY, 5, buf); if(buf[6] != 0){ printf("\nRead Memory address failed\n"); hci_close_dev(dd); return; } Reg = buf[10]; Reg = ((Reg << 8) | buf[9]); Reg = ((Reg << 8) | buf[8]); Reg = ((Reg << 8) | buf[7]); if(Reg & 0x04) { break; } } //-------------------------------------------------------------- hci_close_dev(dd); printf("\nReset Done\n"); } static const char *reset_help = "Usage:\n" "\n reset\n"; static void cmd_reset(int dev_id, int argc, char **argv){ int dd,Length =0,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if(argc > 1) { printf("\n%s\n",reset_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,sizeof(buf)); iRet = writeHciCommand(dd, OGF_HOST_CTL,OCF_RESET,Length,buf); if(buf[6] != 0){ printf("\nError: HCI RESET failed due to reason 0x%X\n",buf[6]); return; } hci_close_dev(dd); printf("\nReset Done\n"); } static const char *rba_help = "Usage:\n" "\n rba\n"; static void cmd_rba(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if(argc > 1){ printf("\n%s\n",rba_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); iRet = writeHciCommand(dd, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, buf); if(buf[6] != 0){ printf("\nread bdaddr command failed due to reason 0x%X\n",buf[6] ); return; } printf("\nBD ADDRESS: \n"); int i; for(i=iRet-1;i > 7;i--){ printf("%02X:",buf[i]); } printf("%X \n\n",buf[7]); hci_close_dev(dd); } static const char *dtx_help = "Usage:\n" "\n dtx\n"; static void cmd_dtx(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if(argc > 1){ printf("\n%s\n",dtx_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_DISABLE_TX, 0, buf); if(buf[6] != 0){ printf("\nDisable TX command failed due to reason 0x%X\n",buf[6]); return; } else { printf("\nDisable TX command passed\n"); } hci_close_dev(dd); } static const char *ssm_help = "Usage:\n" "\n ssm [0|1]\n" "\nExample:\n" "\tssm 0\t(Sleep disabled)\n" "\tssm 1\t(Sleep enabled)\n"; static void cmd_ssm(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if(argc != 2){ printf("\n%s\n",ssm_help); return; } if(atoi(argv[1]) > 1){ printf("\nInvalid sleep mode :%d\n",atoi(argv[1])); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = atoi(argv[1]);; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_SLEEP_MODE, 1, buf); if(buf[6] != 0){ printf("\nSet sleep mode command failed due to reason 0x%X\n",buf[6]); return; } else { printf("\nSet sleep mode command passed\n"); } hci_close_dev(dd); } static const char *wba_help = "Usage:\n" "\n wba \n" "\nExample:\n" "\n wba 00:03:ff:56:23:89\n"; static void cmd_wba(int dev_id, int argc, char **argv){ //printf("\nFeature not implemented\n"); int dd,iRet; bdaddr_t bdaddr; UCHAR buf[HCI_MAX_EVENT_SIZE]; if(argc < 2){ printf("\n%s\n",wba_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } str2ba(argv[1],&bdaddr); if((strlen(argv[1]) < 17)||(strlen(argv[1]) > 17)){ printf("\nInvalid BD address : %s\n",argv[1]); printf("\n%s\n",wba_help); hci_close_dev(dd); return; } LoadPSHeader(buf,PS_WRITE,BD_ADDR_SIZE,BD_ADDR_PSTAG); int i,j=0; for(i= 0,j=4;i< BD_ADDR_SIZE;i++,j++){ buf[j] = bdaddr.b[i]; } iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,BD_ADDR_SIZE + PS_COMMAND_HEADER, buf); if(buf[6] != 0){ printf("\n Write BD address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } memset(&buf,0,sizeof(buf)); iRet = writeHciCommand(dd, OGF_HOST_CTL,OCF_RESET,0,buf); if(buf[iRet-1] != 0){ printf("\nError: HCI RESET failed\n"); hci_close_dev(dd); return; } memset(&buf,0,sizeof(buf)); iRet = writeHciCommand(dd, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, buf); if(buf[6] != 0){ printf("\nread bdaddr command failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } printf("\nBD address changed successfully\n"); hci_close_dev(dd); } static const char *edutm_help = "Usage:\n" "\n edutm\n"; static void cmd_edutm(int dev_id, int argc, char **argv){ int Crc = 0; int dd; //UCHAR buf[HCI_MAX_EVENT_SIZE]; UCHAR ZeroBuf[MEM_BLK_DATA_MAX*2] = {0}; if(argc > 1){ printf("\n%s\n",edutm_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } /* Patch_Count = 20; for(i=0; i < Patch_Count; i++){ RamPatch[i].Len = MAX_BYTE_LENGTH; memset(&RamPatch[i].Data,0,MAX_BYTE_LENGTH); } printf("\nCMD DUT MODE\n"); */ //When Patch file is present write the patch, if not present just enter DUT mode if(!LoadConfFile(TESTPATCH_FILENAME,0xFFFFFFFF,MB_FILEFORMAT_PATCH)){ if(!Dut(dd)){ hci_close_dev(dd); return; } printf("\nDevice is in test mode ...\n"); hci_close_dev(dd); return; } //dump_conf_data(); Crc |= RAM_PATCH_REGION; if(!MemBlkwrite(dd,(UINT32)MC_BCAM_COMPARE_ADDRESS, ZeroBuf, HCI_3_PATCH_SPACE_LENGTH_1)){ printf("\nError in clearing the patch space 1\n"); return; } if(!MemBlkwrite(dd,(UINT32)MC_BCAM_VALID_ADDRESS, ZeroBuf, HCI_3_PATCH_SPACE_LENGTH_1)){ printf("\nError in clearing the patch space 2\n"); return; } printf("\nLoading Patch from file :%s\n",TESTPATCH_FILENAME); if(!PSOperations(dd,WRITE_PATCH,Patch_Count, NULL)){ printf("EnterDUT_HCI_3 : patch write failed \r\n"); return; } if(!PSOperations(dd,ENABLE_PATCH,0, NULL)){ printf("EnterDUT_HCI_3 : patch enable failed \r\n"); return; } if(!PSOperations(dd,PS_VERIFY_CRC,Crc, NULL)){ printf("EnterDUT_HCI_3 : verify crc failed \r\n"); return; } if(!Dut(dd)){ hci_close_dev(dd); return; } printf("\nDevice is in test mode ...\n"); hci_close_dev(dd); } static int ReadMemorySmallBlock(int dd, int StartAddress,UCHAR *pBufToWrite, int Length ){ int iRet; UCHAR *pData; UCHAR buf[HCI_MAX_EVENT_SIZE]; pData = (UCHAR *) malloc(Length + 6); memset(pData,0,Length+6); pData[0]= 0x00; //Memory Read Opcode pData[1]= (StartAddress & 0xFF); pData[2]= ((StartAddress >> 8) & 0xFF); pData[3]= ((StartAddress >> 16) & 0xFF); pData[4]= ((StartAddress >> 24) & 0xFF); pData[5]= Length; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_MEMOP,Length+6,pData); if(pData[6]!= 0){ printf("\nwrite memory command failed due to reason 0x%X\n",pData[6]); free(pData); return FALSE; } int plen =0; do{ plen = read(dd, buf,HCI_MAX_EVENT_SIZE); if (plen < 0) { free(pData); perror("Read failed"); exit(EXIT_FAILURE); } }while (buf[HCI_EVENT_HEADER_SIZE] != DEBUG_EVENT_TYPE_MEMBLK); memcpy(pBufToWrite,(buf+HCI_EVENT_HEADER_SIZE+1),Length); free(pData); return TRUE; } static int ReadMemoryBlock(int dd, int StartAddress,UCHAR *pBufToWrite, int Length ){ int ModResult,i; if(Length > MEM_BLK_DATA_MAX){ ModResult = Length % MEM_BLK_DATA_MAX; for(i=0;i < (Length - ModResult);i += MEM_BLK_DATA_MAX) { ReadMemorySmallBlock(dd, (StartAddress + i),(pBufToWrite + i), MEM_BLK_DATA_MAX); } if(ModResult){ ReadMemorySmallBlock(dd, (StartAddress + i),(pBufToWrite + i), ModResult); } } else{ ReadMemorySmallBlock(dd, StartAddress, pBufToWrite, Length); } return TRUE; } static int WriteMemorySmallBlock(int dd, int StartAddress,UCHAR *pBufToWrite, int Length ){ int iRet; UCHAR *pData; printf("\nStart Address:%x Length:%x %x\n",StartAddress,Length,MEM_BLK_DATA_MAX); /*if(Length <= MEM_BLK_DATA_MAX) return FALSE; */ pData = (UCHAR *) malloc(Length + 6); memset(pData,0,Length+6); pData[0]= 0x01; //Write Read Opcode pData[1]= (StartAddress & 0xFF); pData[2]= ((StartAddress >> 8) & 0xFF); pData[3]= ((StartAddress >> 16) & 0xFF); pData[4]= ((StartAddress >> 24) & 0xFF); pData[5]= Length; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_MEMOP,Length+6,pData); if(pData[6]!= 0){ printf("\nwrite memory command failed due to reason 0x%X\n",pData[6]); free(pData); return FALSE; } free(pData); return TRUE; } static int WriteMemoryBlock(int dd, int StartAddress,UCHAR *pBufToWrite, int Length ){ int ModResult,i; if(Length > MEM_BLK_DATA_MAX){ ModResult = Length % MEM_BLK_DATA_MAX; for(i=0;i < (Length - ModResult);i += MEM_BLK_DATA_MAX) { WriteMemorySmallBlock(dd, (StartAddress + i),(pBufToWrite + i), MEM_BLK_DATA_MAX); } if(ModResult){ WriteMemorySmallBlock(dd, (StartAddress + i),(pBufToWrite + i), ModResult); } } else{ WriteMemorySmallBlock(dd, StartAddress, pBufToWrite, Length); } return TRUE; } static int ReadHostInterest(int dd,tBtHostInterest *pHostInt){ UCHAR buf[HCI_MAX_EVENT_SIZE]; int iRet; int HostInterestAddress; memset(&buf,0,HCI_MAX_EVENT_SIZE); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_HOST_INTEREST, 0, buf); if(buf[6] != 0){ printf("\nhost interest command failed due to reason 0x%X\n",buf[6]); return FALSE; } HostInterestAddress = buf[iRet-1]; HostInterestAddress = ((HostInterestAddress << 8)|buf[iRet-2]); HostInterestAddress = ((HostInterestAddress << 8)|buf[iRet-3]); HostInterestAddress = ((HostInterestAddress << 8)|buf[iRet-4]); ReadMemoryBlock(dd, HostInterestAddress,(UCHAR*)pHostInt, sizeof(tBtHostInterest)); if(pHostInt->MagicNumber != HI_MAGIC_NUMBER){ if((pHostInt->MagicNumber != 0xFBAD)|| (pHostInt->Version != 0xDECA)) return 0; } return TRUE; } static int contRxAtGivenChannel(int dd, UCHAR *pString){ int Address, Mask, Reg, RxFreq,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; //1. Disable all scans and set intervals and scan windows eually memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 0; //All scan disabled iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, buf); if(buf[6] != 0){ printf("\nWrite scan mode command failed due to reason 0x%X\n",buf[6]); return 0; } short int inq_scan = 0x1000; memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = (inq_scan&0xFF); buf[1] = ((inq_scan >> 8)& 0xFF); buf[2] = (inq_scan&0xFF); buf[3] = ((inq_scan >> 8)& 0xFF); iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_WRITE_INQ_ACTIVITY, 4, buf); if(buf[6] != 0){ printf("\nWrite inquiry scan activity command failed due to reason 0x%X\n",buf[6]); return 0; } memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = (inq_scan&0xFF); buf[1] = ((inq_scan >> 8)& 0xFF); buf[2] = (inq_scan&0xFF); buf[3] = ((inq_scan >> 8)& 0xFF); iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_ACTIVITY, 4, buf); if(buf[6] != 0){ printf("\nWrite page scan activity command failed due to reason 0x%X\n",buf[6]); return 0; } //2. Disbable AGC Address = LC_JTAG_MODEM_REGS_ADDRESS + AGC_BYPASS_ADDRESS; Mask = AGC_BYPASS_ENABLE_MASK; Reg = AGC_BYPASS_ENABLE_SET(1); memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = (Address & 0xFF); buf[1] = ((Address >>8) & 0xFF); buf[2] = ((Address>>16) & 0xFF); buf[3] = ((Address>>24) & 0xFF); buf[4] = 0x04; //Memory width buf[5] = (Reg & 0xFF); buf[6] = ((Reg >> 8) & 0xFF); buf[7] = ((Reg >> 16) & 0xFF); buf[8] = ((Reg >> 24) & 0xFF); buf[9] = (Mask & 0xFF); buf[10] = ((Mask >>8) & 0xFF); buf[11] = ((Mask>>16) & 0xFF); buf[12] = ((Mask>>24) & 0xFF); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite to AGC bypass register failed due to reason 0x%X\n",buf[6]); return 0; } // 3. Disable frequency hoping and set rx frequency RxFreq = (int)pString; Address = LC_DEV_PARAM_CTL_ADDRESS; Mask = LC_DEV_PARAM_CTL_FREQ_HOP_EN_MASK | LC_DEV_PARAM_CTL_RX_FREQ_MASK | LC_DEV_PARAM_CTL_WHITEN_EN_MASK; Reg = LC_DEV_PARAM_CTL_RX_FREQ_SET(RxFreq); memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = (Address & 0xFF); buf[1] = ((Address >>8) & 0xFF); buf[2] = ((Address>>16) & 0xFF); buf[3] = ((Address>>24) & 0xFF); buf[4] = 0x04; //Memory width buf[5] = (Reg & 0xFF); buf[6] = ((Reg >> 8) & 0xFF); buf[7] = ((Reg >> 16) & 0xFF); buf[8] = ((Reg >> 24) & 0xFF); buf[9] = (Mask & 0xFF); buf[10] = ((Mask >>8) & 0xFF); buf[11] = ((Mask>>16) & 0xFF); buf[12] = ((Mask>>24) & 0xFF); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite to Rx Freq register failed due to reason 0x%X\n",buf[6]); return 0; } // 4. Enable page scan only (Note: the old way puts device into inq scan mode only ???) memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 2; //Page scan enabled iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, buf); if(buf[6] != 0){ printf("\nPage scan enable command failed due to reason 0x%X\n",buf[6]); return 0; } // 5. Increase correlator Address = LC_JTAG_MODEM_REGS_ADDRESS + CORR_PARAM1_ADDRESS; Mask = CORR_PARAM1_TIM_THR_MASK; Reg = CORR_PARAM1_TIM_THR_SET(0x3f); memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = (Address & 0xFF); buf[1] = ((Address >>8) & 0xFF); buf[2] = ((Address>>16) & 0xFF); buf[3] = ((Address>>24) & 0xFF); buf[4] = 0x04; //Memory width buf[5] = (Reg & 0xFF); buf[6] = ((Reg >> 8) & 0xFF); buf[7] = ((Reg >> 16) & 0xFF); buf[8] = ((Reg >> 24) & 0xFF); buf[9] = (Mask & 0xFF); buf[10] = ((Mask >>8) & 0xFF); buf[11] = ((Mask>>16) & 0xFF); buf[12] = ((Mask>>24) & 0xFF); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_WRITE_MEMORY, 12, buf); if(buf[6] != 0){ printf("\nWrite to Correlator register failed due to reason 0x%X\n",buf[6]); return 0; } return TRUE; } static const char *cwrx_help = "Usage:\n" "\n cwrx \n"; static void cmd_cwrx(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; UCHAR channel; BOOL Ok = TRUE; if(argc != 2){ printf("\n%s\n",cwrx_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); channel = atoi(argv[1]); if(channel > 78 || channel < 0){ printf("\nPlease enter channel 0-78!\n"); return; } dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } // Disable sleep mode memset(&buf,0,sizeof(buf)); buf[0] = 0; iRet = writeHciCommand(dd,OGF_VENDOR_CMD,OCF_SLEEP_MODE,1,buf); if(buf[6] != 0){ printf("\nError: Sleep mode failed due to reason 0x%X\n",buf[6]); Ok = 0; } printf (" Continuoux Rx at channel %d\n",channel); Ok = contRxAtGivenChannel(dd, &channel); // All modes come here if (Ok) { printf (" Continuoux Rx at channel %d Done...\n",channel); } else { printf ("\nERROR ---> Could not enter continuous Rx mode\n"); } hci_close_dev(dd); } static const char *mb_help = "Usage:\n" "\n mb\n"; static void cmd_mb(int dev_id, int argc, char **argv){ int dd,iRet; int InChar; int FieldNum; bdaddr_t bdaddr; tBRM_Control_packet MasterBlaster; UCHAR SkipRxSlot; UCHAR buf[HCI_MAX_EVENT_SIZE]; char FieldAlias; BOOL TestEnabled = 0,Ok = TRUE; UINT8 setContTxType; tBtHostInterest HostInt; int address,width,value,mask; if(argc > 1) { printf("\n%s\n",mb_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); iRet = writeHciCommand(dd, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, buf); if (buf[6] != 0) { printf("\nread bdaddr command failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } int i,j; char bda[18]; for (i=iRet-1,j=0;i>7;i--,j+=3) { sprintf(&bda[j],"%X",((buf[i]>>4)&0xFF)); sprintf(&bda[j+1],"%X",(buf[i]&0x0F)); sprintf(&bda[j+2],":"); } sprintf(&bda[15],"%X",((buf[7]>>4)&0xFF)); sprintf(&bda[16],"%X",(buf[7]&0x0F)); bda[18] ='\0'; str2ba(bda,&bdaddr); InitMasterBlaster(&MasterBlaster, &bdaddr, &SkipRxSlot); #ifndef DUMP_DEBUG Ok = ReadHostInterest(dd,&HostInt); if(Ok) { if (HostInt.TpcTableAddr && (HostInt.Version >= 0x0100)) { Ok = ReadMemoryBlock(dd, HostInt.TpcTableAddr, (UCHAR *)&TpcTable, sizeof(TpcTable)); MasterBlaster.testCtrl.Power = TpcTable.NumOfEntries - 1; } } if(!Ok) { printf ("\nCould not load TPC table.\n"); sleep (2); Ok = TRUE; } #endif PrintMasterBlasterMenu (&MasterBlaster); while (1) { InChar = getchar(); FieldAlias = (char)InChar; FieldNum = CheckField(MasterBlaster, &FieldAlias); if (FieldNum == INVALID_MASTERBLASTER_FIELD) { printf ("\nERROR ---> Invalid command. Try again.\n"); printf ("mb>"); getchar(); continue; } if (!strncmp(&FieldAlias, MasterBlasterMenu[EXX].Alias, 1)) { printf("\nExit the Master Blaster Mode without reset\n"); break; } // If test has been enabled and the key is not 'e', send reset to stop the test if (((TestEnabled == MB_RX_TEST) && strncmp(&FieldAlias, MasterBlasterMenu[RX].Alias, 1)) || ((TestEnabled == MB_TX_TEST) && strncmp(&FieldAlias, MasterBlasterMenu[TX].Alias, 1)) || ((TestEnabled == MB_CONT_RX_TEST || TestEnabled == MB_CONT_TX_TEST || TestEnabled == MB_LE_RX_TEST || TestEnabled == MB_LE_TX_TEST) && (strncmp(&FieldAlias, MasterBlasterMenu[EN].Alias, 1)))) { printf (" ... Please wait ..."); if (MasterBlaster.ContTxMode) { memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 255; iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_CONT_TX_TESTER, 14, buf); if(buf[6] != 0) { printf("\nContinious Tx Tester command failed due to reason 0x%X\n",buf[6]); Ok = 0; } else Ok = TRUE; } // Ok = Diag::Reset (Unit, ""); PSInit(dd); memset(&buf,0,sizeof(buf)); iRet = writeHciCommand(dd,OGF_HOST_CTL,OCF_RESET,0,buf); if (buf[6] != 0) { printf("\nError: HCI RESET failed due to reason 0x%X\n",buf[6]); Ok = FALSE; } else Ok = TRUE; if (!Ok) { printf ("\nERROR ---> Could not stop test mode\n"); } else if (!strncmp(&FieldAlias, MasterBlasterMenu[RX].Alias, 1) || !strncmp(&FieldAlias, MasterBlasterMenu[TX].Alias, 1) || ((TestEnabled != MB_NO_TEST) && (!strncmp(&FieldAlias, MasterBlasterMenu[CR].Alias, 1) || !strncmp(&FieldAlias, MasterBlasterMenu[CT].Alias, 1) || !strncmp(&FieldAlias, MasterBlasterMenu[LR].Alias, 1) || !strncmp(&FieldAlias, MasterBlasterMenu[LT].Alias, 1))) || !strncmp(&FieldAlias, MasterBlasterMenu[EN].Alias, 1)) { TestEnabled = MB_NO_TEST; } sleep(1); } if (!strncmp(&FieldAlias,MasterBlasterMenu[EX].Alias,1)) { TestEnabled = MB_NO_TEST; printf ("\n Exit ..\n"); break; } else if (!strncmp(&FieldAlias,MasterBlasterMenu[ST].Alias,1)) { TestEnabled = MB_NO_TEST; getchar(); PrintMasterBlasterMenu (&MasterBlaster); continue; } else if (!strncmp(&FieldAlias,MasterBlasterMenu[GB].Alias,1)) { memset(&buf,0,sizeof(buf)); buf[0] = MasterBlaster.BERType; iRet = writeHciCommand(dd,OGF_VENDOR_CMD,OCF_GET_BERTYPE,0,buf); if(buf[6] != 0) { printf("Could not get BER info.\n"); } else { int crcfail = buf[7] + (buf[8]<<8) + (buf[9]<<16) + (buf[10]<<24); int total = buf[11] + (buf[12]<<8) + (buf[13]<<16) + (buf[14]<<24); printf("\n\tCRCFail is %d, total is %d\n", crcfail, total); } } else if (!MasterBlasterMenu[FieldNum].pFunc (&MasterBlaster, MasterBlasterMenu[FieldNum].Options)) { printf ("----%c\n", FieldAlias); printf ("\nERROR ---> Invalid option. Try again.\n"); printf ("mb>"); getchar(); continue; } getchar(); PrintMasterBlasterMenu(&MasterBlaster); // Enable TX test mode if ((!strncmp(&FieldAlias, MasterBlasterMenu[TX].Alias, 1) && (TestEnabled == MB_NO_TEST)) || (strncmp(&FieldAlias, MasterBlasterMenu[TX].Alias, 1) && (TestEnabled == MB_TX_TEST))) { // Disable sleep mode printf ("."); Ok = TRUE; memset(&buf,0,sizeof(buf)); buf[0] = 0; iRet = writeHciCommand(dd,OGF_VENDOR_CMD,OCF_SLEEP_MODE,1,buf); if(buf[6] != 0) { printf("\nError: Sleep mode failed due to reason 0x%X\n",buf[6]); Ok = 0; } if (!Ok) { printf ("\nERROR ---> Could not disable sleep mode\n"); printf ("mb>"); continue; } printf ("."); Ok = Dut(dd); if (!Ok) { printf("\nERROR ---> Could not enter DUT mode\n"); printf("mb>"); continue; } printf("."); memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = MasterBlaster.testCtrl.Mode ; buf[1] = MasterBlaster.testCtrl.Packet; buf[2] = MasterBlaster.testCtrl.DataLen & 0xFF; buf[3] = ((MasterBlaster.testCtrl.DataLen>>8) & 0xFF); buf[4] = MasterBlaster.testCtrl.HopMode; buf[5] = MasterBlaster.testCtrl.TxFreq; buf[6] = MasterBlaster.testCtrl.Power; buf[7] = MasterBlaster.testCtrl.RxFreq; buf[8] = MasterBlaster.bdaddr[0]; buf[9] = MasterBlaster.bdaddr[1]; buf[10] = MasterBlaster.bdaddr[2]; buf[11] = MasterBlaster.bdaddr[3]; buf[12] = MasterBlaster.bdaddr[4]; buf[13] = MasterBlaster.bdaddr[5]; buf[14] = SkipRxSlot; iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_TX_TESTER, 15, buf); if (buf[6] != 0) { printf("\nContinious Tx Tester command failed due to reason 0x%X\n",buf[6]); printf("\nERROR --> Could not enable master blaster mode\n"); TestEnabled = MB_NO_TEST; Ok = 0; } else { printf(" test is in progress. Press 's' to stop the test\n"); TestEnabled = MB_TX_TEST; } printf("mb>"); continue; } else if ((!strncmp(&FieldAlias, MasterBlasterMenu[TX].Alias, 1)) && TestEnabled == MB_TX_TEST) { printf("test is in progress. Press 's' to stop the test\n"); printf("mb>"); continue; } /* Enable (LE) continuous tx/rx test modes */ if (((!strncmp(&FieldAlias, MasterBlasterMenu[EN].Alias, 1)) && (TestEnabled == MB_NO_TEST)) || (strncmp(&FieldAlias, MasterBlasterMenu[EN].Alias, 1) && (TestEnabled == MB_CONT_RX_TEST || TestEnabled == MB_CONT_TX_TEST || TestEnabled == MB_LE_RX_TEST || TestEnabled == MB_LE_TX_TEST))) { // Disable sleep mode printf ("."); Ok = TRUE; memset(&buf,0,sizeof(buf)); buf[0] = 0; iRet = writeHciCommand(dd,OGF_VENDOR_CMD,OCF_SLEEP_MODE,1,buf); if (buf[6] != 0) { printf("\nError: Sleep mode failed due to reason 0x%X\n",buf[6]); Ok = 0; } if (!Ok) { printf ("\nERROR ---> Could not disable sleep mode\n"); printf ("mb>"); continue; } /* LE Rx Mode */ if (MasterBlaster.LERxMode == ENABLE) { Ok = SU_LERxTest(dd, MasterBlaster.testCtrl.RxFreq); TestEnabled = MB_LE_RX_TEST; } else if (MasterBlaster.LETxMode == ENABLE) { Ok = SU_LETxTest(dd, MasterBlaster.testCtrl.TxFreq, MasterBlaster.testCtrl.DataLen, MasterBlaster.LETxParms.PktPayload); TestEnabled = MB_LE_TX_TEST; } else if (MasterBlaster.ContRxMode == ENABLE) { UCHAR RxFreq = MasterBlaster.testCtrl.RxFreq; Ok = contRxAtGivenChannel(dd, &RxFreq); TestEnabled = MB_CONT_RX_TEST; } else /* Continous TX mode */ { printf("."); Ok = Dut(dd); if (!Ok) { printf("\nERROR ---> Could not enter DUT mode\n"); printf("mb>"); continue; } /* Enable master blaster mode */ printf("."); if (CW_Single_Tone == MasterBlaster.ContTxType) setContTxType = Cont_Tx_Raw_1MHz; else setContTxType = MasterBlaster.ContTxType; memset(&buf, 0, HCI_MAX_EVENT_SIZE); buf[0] = MasterBlaster.testCtrl.Mode ; buf[1] = MasterBlaster.testCtrl.Packet; buf[2] = MasterBlaster.testCtrl.DataLen & 0xFF; buf[3] = ((MasterBlaster.testCtrl.DataLen>>8) & 0xFF); buf[4] = MasterBlaster.ContTxType; buf[5] = MasterBlaster.testCtrl.TxFreq; buf[6] = MasterBlaster.testCtrl.Power; buf[7] = MasterBlaster.testCtrl.RxFreq; buf[8] = MasterBlaster.bdaddr[0]; buf[9] = MasterBlaster.bdaddr[1]; buf[10] = MasterBlaster.bdaddr[2]; buf[11] = MasterBlaster.bdaddr[3]; buf[12] = MasterBlaster.bdaddr[4]; buf[13] = MasterBlaster.bdaddr[5]; iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_CONT_TX_TESTER, 14, buf); if(buf[6] != 0){ printf("\nContinious Tx Tester command failed due to reason 0x%X\n",buf[6]); Ok = FALSE; } else Ok = TRUE; memset(&buf,0,HCI_MAX_EVENT_SIZE); address = 0x00022914; value = 0x00200000; mask = 0x00200000; width = 4; buf[0] = (address & 0xFF); buf[1] = ((address >>8) & 0xFF); buf[2] = ((address>>16) & 0xFF); buf[3] = ((address>>24) & 0xFF); buf[4] = width; //Memory width buf[5] = (value & 0xFF); buf[6] = ((value >> 8) & 0xFF); buf[7] = ((value >> 16) & 0xFF); buf[8] = ((value >> 24) & 0xFF); buf[9] = (mask & 0xFF); buf[10] = ((mask >>8) & 0xFF); buf[11] = ((mask>>16) & 0xFF); buf[12] = ((mask>>24) & 0xFF); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite memory address failed due to reason 0x%X\n",buf[6]); Ok = FALSE; } else Ok = TRUE; TestEnabled = MB_CONT_TX_TEST; } if (Ok) { printf("Test is in progress. Press 's' to stop the test\n"); } else { printf("\nERROR ---> Could not enable master blaster mode\n"); TestEnabled = MB_NO_TEST; } printf("mb>"); continue; } else if ((!strncmp(&FieldAlias, MasterBlasterMenu[EN].Alias, 1)) && TestEnabled) { printf (" Test mode is in progress. Press 's' to stop the test\n"); printf ("mb>"); continue; } } hci_close_dev(dd); } /* static void cmd_gid(int dev_id, int argc, char **argv){ printf("\nFeature not implemented\n"); } */ static const char *wsm_help = "Usage:\n" "\n wsm [0|1|2|3]\n" "\nExample:\n" "\twsm 0\t(Scan disabled)\n" "\twsm 1\t(Inquiry scan enabled)\n" "\twsm 2\t(Page scan enabled)\n" "\twsm 3\t(Inquiry and Page scan enabled)\n"; static void cmd_wsm(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if(argc < 2){ printf("\n%s\n",wsm_help); return; } if(atoi(argv[1]) > 3){ printf("\nInvalid scan mode :%d\n",atoi(argv[1])); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = atoi(argv[1]); iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, buf); if(buf[6] != 0){ printf("\nWrite scan mode command failed due to reason 0x%X\n",buf[6]); return; } hci_close_dev(dd); printf("\nScan Mode set to :%d\n",atoi(argv[1])); } static void dumpHex(UCHAR *buf, int length, int col) { int i; for (i = 0; i < length; i++) { printf("0x%02x ", buf[i]); if (((i+1) % col) == 0 && i != 0) printf("\n"); } if (((i+1) % col) != 0) printf("\n"); } static void ReverseHexString(char *pStr) { int i, j; char temp; int len = strlen(pStr); for (i = 0; pStr[i] == ' ' || pStr[i] == '\t'; i++); if (pStr[i] == '0' && pStr[i+1] == 'x') i += 2; for (j = len - 1; i < j - 2; i += 2, j -= 2) { temp = pStr[i]; pStr[i] = pStr[j - 1]; pStr[j - 1] = temp; temp = pStr[i + 1]; pStr[i + 1] = pStr[j]; pStr[j] = temp; } } static void GetByteSeq(UCHAR *pDst, UCHAR *pSrc, int Size) { UCHAR LowNibble, Nibble = 0; UCHAR *pLastHex; UCHAR *pStr = pSrc; while (*pStr == ' ' || *pStr == '\t') pStr++; if ((pStr[0] == '0') && (pStr[1] == 'x')) pStr += 2; pLastHex = pStr - 1; while (IS_HEX(*(pLastHex + 1))) pLastHex++; LowNibble = 0; while (Size > 0) { if (pStr <= pLastHex) { Nibble = CONV_HEX_DIGIT_TO_VALUE(*pStr); pStr++; } else { Nibble = 0; } if (LowNibble) { *pDst |= (UCHAR)(Nibble & 0x0F); LowNibble = 0; pDst++; Size--; } else { *pDst = (UCHAR)((Nibble << 4) & 0xF0); LowNibble = 1; } } } unsigned int GetUInt(char **ppLine, unsigned int DefaultValue) { char *pStr = *ppLine; unsigned int Value = 0; // Is it a hex value? if ((*pStr == '0') && (*(pStr+1) == 'x')) { // We have a hex value pStr += 2; while (IS_HEX(*pStr)) { Value = CONV_HEX_DIGIT_TO_VALUE(*pStr) + (Value*16); pStr++; } } else if (IS_DIGIT(*pStr)) { // We have a decimal value while (IS_DIGIT(*pStr)) { Value = CONV_DEC_DIGIT_TO_VALUE(*pStr) + (Value*10); pStr++; } } else { // We don't have a value at all - return default value return DefaultValue; } // Update the BtString ptr *ppLine = pStr; return Value; } static const char *mbr_help = "Usage:\n" "\n mbr
\n" "\n Example \n" "\n mbr 0x00004FFC 10 \n" "\n mbr 0x00004FFC 0x10 \n"; static void cmd_mbr(int dev_id, int argc, char **argv){ int dd; UCHAR buf[HCI_MAX_EVENT_SIZE*20]; if(argc != 3){ printf("\n%s\n",mbr_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } int length = GetUInt(&(argv[2]),0); int address = GetUInt(&(argv[1]),0); if ((address == 0) || (length==0)){ return; } memset(&buf,0,HCI_MAX_EVENT_SIZE*20); if(!MemBlkRead(dd,address,buf, length)) { printf("\nmemory bulk read command failed\n"); return; } printf("\ndata: \n"); int i; for(i=0;i < length;i+=4){ printf("%08X: ",address+i); printf("%08X",*((int*)(buf+i))); printf("\n"); } printf("\n"); hci_close_dev(dd); } static const char *psr_help = "Usage:\n" "\n psr \n"; static void cmd_psr(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if(argc > 1){ printf("\n%s\n",psr_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); LoadPSHeader(buf,PS_RESET,0,0); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,PS_COMMAND_HEADER+2, buf); if(buf[7] != 0){ /* Check for status */ printf("\n PS Reset failed\n"); hci_close_dev(dd); return; } hci_close_dev(dd); printf("PS reset done\n"); } static const char *rpst_help = "Usage:\n" "\n rpst \n" "\n Example:\n" "\n rpst 1 6 \n"; static void cmd_rpst(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; int tag_id,tag_len,i,j; if(argc != 3){ printf("\n%s\n",rpst_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); tag_id = GetUInt(&(argv[1]),0); tag_len = GetUInt(&(argv[2]),0); LoadPSHeader(buf,PS_READ,tag_len,tag_id); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,PS_COMMAND_HEADER, buf); if(buf[6] != 0){ printf("\n read PS tag failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); iRet = read(dd,&buf,HCI_MAX_EVENT_SIZE); if(iRet < 0){ printf("\n read PS tag failed\n"); hci_close_dev(dd); return; } printf("\nTag ID :%X\nTag Length:%X\nTag Data:\n",tag_id,tag_len); for(i=4,j=1;i \n" "\n Example:\n" "\n wpst 1 6 00 03 F4 55 AB 77 \n"; static void cmd_wpst(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; int tag_id,tag_len,i; if(argc < 4){ printf("\n%s\n",wpst_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); tag_id = GetUInt(&(argv[1]),0); tag_len = GetUInt(&(argv[2]),0); if(argc < tag_len+3){ printf("\n Tag Data is less than Tag Length\n"); hci_close_dev(dd); return; } LoadPSHeader(buf,PS_WRITE,tag_len,tag_id); for(i=0;i \n" "\nstorage medium: 0-RAM 1-EEPROM\n" "\naccess mode: 0-Read-only 1-Write-only 2-Read-Write 3- Disabled\n" "\nExample:\n" "\nsetam 0 3\n"; static void cmd_setam(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; int medium,mode; if(argc !=3){ printf("\n%s\n",setam_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); medium = GetUInt(&(argv[1]),0); mode = GetUInt(&(argv[2]),0); LoadPSHeader(buf,PS_SET_ACCESS_MODE,mode,medium); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,PS_COMMAND_HEADER, buf); if(buf[6] != 0){ printf("\nSet Access mode failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } hci_close_dev(dd); printf("\nAccess mode changed successfully!\n"); } static const char *setap_help = "Usage:\n" "\nsetap \n" "\nstorage medium: 0-RAM 1-EEPROM\n" "\npriority: #Highest number corresponds to highest priority\n" "\nExample:\n" "\nsetap 0 1\n"; static void cmd_setap(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; int medium,priority; if(argc !=3){ printf("\n%s\n",setap_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); medium = GetUInt(&(argv[1]),0); priority = GetUInt(&(argv[2]),0); LoadPSHeader(buf,PS_SET_ACCESS_MODE,priority,medium); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,PS_COMMAND_HEADER, buf); if(buf[6] != 0){ printf("\nSet Access priority failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } hci_close_dev(dd); printf("\nPriority changed successfully!\n"); } static const char *rpsraw_help = "Usage:\n" "\n rpsraw \n" "\n Example:\n" "\n rpsraw 0x012c 10\n"; static void cmd_rpsraw(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; int offset,len,i,j; if(argc != 3){ printf("\n%s\n",rpsraw_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); offset = GetUInt(&(argv[1]),0); len = GetUInt(&(argv[2]),0); LoadPSHeader(buf,PS_READ_RAW,len,offset); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,PS_COMMAND_HEADER, buf); if(buf[6] != 0){ printf("\n read PS raw failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); iRet = read(dd,&buf,HCI_MAX_EVENT_SIZE); if(iRet < 0){ printf("\n read PS raw failed\n"); hci_close_dev(dd); return; } printf("\nOffset :%X\nLength:%X\nData:\n",offset,len); for(i=4,j=1;i \n" "\n Example:\n" "\n wpsraw 0x012C 6 00 03 F4 55 AB 77 \n"; static void cmd_wpsraw(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; int offset,len,i; if(argc < 4){ printf("\n%s\n",wpsraw_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); offset = GetUInt(&(argv[1]),0); len = GetUInt(&(argv[2]),0); if(argc < len+3){ printf("\nData is less than Length\n"); hci_close_dev(dd); return; } LoadPSHeader(buf,PS_WRITE_RAW,len,offset); for(i=0;i \n" "\nExample:\n" "\npeek 0x00004FFC 5\n"; static void cmd_peek(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; int address,width,value; if(argc < 2){ printf("\n%s\n",peek_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); address = GetUInt(&(argv[1]),0); if(argc == 3) width = GetUInt(&(argv[2]),0x4); else width = 4; buf[0] = (address & 0xFF); buf[1] = ((address >>8) & 0xFF); buf[2] = ((address>>16) & 0xFF); buf[3] = ((address>>24) & 0xFF); buf[4] = (UCHAR)width; //Memory width iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_READ_MEMORY, 5, buf); if(buf[6] != 0){ printf("\nRead Memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } value = buf[10]; value = ((value << 8) | buf[9]); value = ((value << 8) | buf[8]); value = ((value << 8) | buf[7]); printf("\n0x%X : 0x%X \n",address,value); //printf("\n0x%X : 0x%02X%02X%02X%02X \n",address,buf[7],buf[8],buf[9],buf[10]); hci_close_dev(dd); } static const char *cwtx_help = "\nUsage:" "\ncwtx \n" "\nExample:\n" "\ncwtx 40" "\n\n"; static void cmd_cwtx(int dev_id, int argc, char **argv){ int dd,iRet, Length = 0; UCHAR buf[HCI_MAX_EVENT_SIZE]; char channel; if(argc != 2){ printf("\n%s\n",cwtx_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); channel = atoi(argv[1]); if(channel > 78 || channel < 0){ printf("\nPlease enter channel 0-78!\n"); hci_close_dev(dd); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); iRet = writeHciCommand(dd, OGF_HOST_CTL,OCF_RESET,Length,buf); if(buf[6] != 0){ printf("\nWrite memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 0x80; buf[1] = 0x20; buf[2] = 0x02; buf[3] = 0x00; buf[4] = 0x04; buf[5] = 0xFF; buf[6] = 0x08; buf[7] = 0xC0; buf[8] = 0x00; buf[9] = 0xFF; buf[10] = 0xFF; buf[11] = 0xFF; buf[12] = 0xFF; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } /* hcitool cmd 0x3F 0x06 0x34 0x20 0x02 0x00 0x04 0x88 0xA0 0x00 0x02 0xFF 0xFF 0xFF 0xFF */ memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 0x34; buf[1] = 0x20; buf[2] = 0x02; buf[3] = 0x00; buf[4] = 0x04; buf[5] = 0x88; buf[6] = 0xA0; buf[7] = 0x00; buf[8] = 0x02; buf[9] = 0xFF; buf[10] = 0xFF; buf[11] = 0xFF; buf[12] = 0xFF; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } /* hcitool cmd 0x3F 0x06 0x28 0x20 0x02 0x00 0x04 0x00 0x90 0x05 0x20 0xFF 0xFF 0xFF 0xFF */ memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 0x28; buf[1] = 0x20; buf[2] = 0x02; buf[3] = 0x00; buf[4] = 0x04; buf[5] = 0x00; buf[6] = 0x90; buf[7] = 0x05; buf[8] = 0x20; buf[9] = 0xFF; buf[10] = 0xFF; buf[11] = 0xFF; buf[12] = 0xFF; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } /* hcitool cmd 0x3F 0x06 0x7C 0x08 0x02 0x00 0x04 0x01 0x00 0x00 0x4B 0xFF 0xFF 0xFF 0xFF */ memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 0x7C; buf[1] = 0x08; buf[2] = 0x02; buf[3] = 0x00; buf[4] = 0x04; buf[5] = 0x01; buf[6] = 0x00; buf[7] = 0x00; buf[8] = 0x4B; buf[9] = 0xFF; buf[10] = 0xFF; buf[11] = 0xFF; buf[12] = 0xFF; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } /* hcitool cmd 0x3F 0x06 0x00 0x08 0x02 0x00 0x04 $number 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF */ memset(&buf,0,HCI_MAX_EVENT_SIZE); buf[0] = 0x00; buf[1] = 0x08; buf[2] = 0x02; buf[3] = 0x00; buf[4] = 0x04; buf[5] = channel; /* Num */ buf[6] = 0x00; buf[7] = 0x00; buf[8] = 0x00; buf[9] = 0xFF; buf[10] = 0xFF; buf[11] = 0xFF; buf[12] = 0xFF; iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } printf("\nEntering continuous wave Tx on channel %d\n",channel); hci_close_dev(dd); } static const char *poke_help = "\nUsage:" "\npoke
\n" "\nExample:\n" "\npoke 0x580000 0x22005FF 0xFFFFFFFF 4" "\n\n"; static void cmd_poke(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; int address,width,value,mask; if(argc < 2){ printf("\n%s\n",poke_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); address = GetUInt(&(argv[1]),0); value = GetUInt(&(argv[2]),0); printf("\nARGC :%d\n",argc); if(argc < 4) mask = 0xffffffff; else mask = GetUInt(&(argv[3]),0xFFFFFFFF); if(argc < 5) width = 4; else width = GetUInt(&(argv[4]),0x4); buf[0] = (address & 0xFF); buf[1] = ((address >>8) & 0xFF); buf[2] = ((address>>16) & 0xFF); buf[3] = ((address>>24) & 0xFF); buf[4] = width; //Memory width buf[5] = (value & 0xFF); buf[6] = ((value >> 8) & 0xFF); buf[7] = ((value >> 16) & 0xFF); buf[8] = ((value >> 24) & 0xFF); buf[9] = (mask & 0xFF); buf[10] = ((mask >>8) & 0xFF); buf[11] = ((mask>>16) & 0xFF); buf[12] = ((mask>>24) & 0xFF); iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_WRITE_MEMORY, 13, buf); if(buf[6] != 0){ printf("\nWrite memory address failed due to reason 0x%X\n",buf[6]); hci_close_dev(dd); return; } printf("\nPoke successful!\n"); hci_close_dev(dd); } static const char *dump_help = "\nUsage:" "\ndump audio - Display Audio statistics\n" "\ndump dma- Display DMA statistics\n" "\ndump dma r - Display and Reset DMA statistics\n" "\ndump tpc - Dump TPC tables\n" "\nExample:\n" "\ndump audio" "\ndump dma" "\ndump dma r" "\ndump tpc" "\n"; static void cmd_dump(int dev_id, int argc, char **argv){ int dd; if(argc < 2){ printf("\n%s\n",dump_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } if(!strncmp(argv[1],"audio",5)){ ReadAudioStats(dd); } else if(!strncmp(argv[1],"dma",3)){ ReadGlobalDMAStats(dd); if(argc == 3 && !strncmp(argv[2],"r",1)){ ResetGlobalDMAStats(dd); } } else if(!strncmp(argv[1],"tpc",3)){ ReadTpcTable(dd); } else{ printf("\nInvalid option"); printf("\n%s\n",dump_help); } hci_close_dev(dd); return; } static const char *rafh_help = "\nUsage:" "\nrafh \n" "\nExample:\n" "\nrafh 0x15" "\n\n"; static void cmd_rafh(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; short int handle; if(argc < 2){ printf("\n%s\n",rafh_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); handle = GetUInt(&(argv[1]),0); buf[0] = (handle & 0xFF); buf[1] = ((handle >>8) & 0xFF); iRet = writeHciCommand(dd, OGF_STATUS_PARAM,OCF_READ_AFH_MAP, 2, buf); if(buf[6] != 0){ printf("\nRead AFH failed due to reason :0x%X\n",buf[6]); hci_close_dev(dd); return; } if(buf[9] == 0) printf(" AFH is disabled"); else printf(" AFH is enabled"); handle = (buf[7] | (buf[8] << 8)); printf("\n AFH chaneel classification for handle: 0x%X",handle); int i; printf("\n Channel Classification Map :"); for(i=iRet-1; i>9 ; i--){ printf("%X",buf[i]); } printf("\n"); hci_close_dev(dd); } static const char *safh_help = "\nUsage:" "\nsafh \n" "\nExample:\n" "\nsafh 0x7FFFFFFFFFFFFFFFFFFF" "\n\n"; static void cmd_safh(int dev_id, int argc, char **argv){ int dd,iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if(argc < 2){ printf("\n%s\n",safh_help); return; } int i,j; i = strlen(argv[1]); if(i > 20 || i < 20){ printf("\n%s\n",safh_help); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(&buf,0,HCI_MAX_EVENT_SIZE); const char *map = argv[1]; char byte[3]; int data; for (i = 0,j=9; i < 20 ; i+=2,j--) { memcpy(byte,&map[i],2); byte[2] = '\0'; data = strtol(byte, NULL, 16); buf[j] = (data & 0xFF); } iRet = writeHciCommand(dd, OGF_HOST_CTL,OCF_SET_AFH_CLASSIFICATION,10, buf); if(buf[6] != 0){ printf("\nSet AFH failed due to reason :0x%X\n",buf[6]); hci_close_dev(dd); return; } printf("\nSet AFH successful!\n"); hci_close_dev(dd); } static const char *wotp_help = "\nUsage:" "\nwotp
[length=1]\n" "\nExample:\n" "\nwotp 0x15 0x2020 2" "\n\n"; static void cmd_wotp(int dev_id, int argc, char **argv) { int address, length; if (argc < 3) { printf("\n%s\n", wotp_help); return; } if (argc == 4) length = GetUInt(&argv[3], 1); else length = 1; address = GetUInt(&argv[1], 0xffffffff); if (address == 0xffffffff) { printf("\n%s\n", wotp_help); return; } ReverseHexString(argv[2]); if (!write_otpRaw(dev_id, address, length, (UCHAR *)argv[2])) printf("Write to OTP successful!\n"); } static int write_otpRaw(int dev_id, int address, int length, UCHAR *data) { int dd, iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return dd; } memset(&buf, 0, HCI_MAX_EVENT_SIZE); buf[0] = 0x12; /* write RAW OTP */ buf[1] = address & 0xFF; /* PS tag */ buf[2] = (address >> 8) & 0xFF; buf[3] = length; /* Entry Size */ GetByteSeq(buf + 4, data, 244); /* Entry Data */ iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS, 244 + PS_COMMAND_HEADER, buf); if (buf[6] != 0) { printf("\nWrite to OTP failed due to reason :0x%X\n", buf[6]); hci_close_dev(dd); return buf[6]; } hci_close_dev(dd); return 0; } static const char *rotp_help = "\nUsage:" "\nrotp
[length=1]\n" "\nExample:\n" "\nrotp 0x15 2" "\n\n"; static void cmd_rotp(int dev_id, int argc, char **argv) { int address, length; UCHAR buf[HCI_MAX_EVENT_SIZE]; if (argc < 2) { printf("\n%s\n", rotp_help); return; } if (argc == 3) length = GetUInt(&argv[2], 1); else length = 1; address = GetUInt(&argv[1], 0xffffffff); if (address == 0xffffffff) { printf("\n%s\n", rotp_help); return; } if (!read_otpRaw(dev_id, address, length, buf)) dumpHex(buf, length, 8); } static int read_otpRaw(int dev_id, int address, int length, UCHAR *data) { int dd, iRet, plen; UCHAR buf[HCI_MAX_EVENT_SIZE]; if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return dd; } memset(&buf, 0, HCI_MAX_EVENT_SIZE); buf[0] = 0x11; /* read OTP */ buf[1] = address & 0xFF; /* PS tag */ buf[2] = (address >> 8) & 0xFF; buf[3] = length; /* Entry Size */ buf[4] = 0x00; /* Entry Data */ iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS, 244 + PS_COMMAND_HEADER, buf); if (buf[6] != 0) { printf("\nRead from OTP failed due to reason :0x%X\n", buf[6]); hci_close_dev(dd); return buf[6]; } do { plen = read(dd, buf, HCI_MAX_EVENT_SIZE); if (plen < 0) { perror("Read OTP error\n"); exit(EXIT_FAILURE); } } while (buf[HCI_EVENT_HEADER_SIZE] != DEBUG_EVENT_TYPE_PS); memcpy(data, buf + HCI_EVENT_HEADER_SIZE + 1, length); hci_close_dev(dd); return 0; } static int SU_GetId(int dev_id, char *pStr, tSU_RevInfo *pRetRevInfo) { tSU_RevInfo RevInfo; int dd, iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; RevInfo.RomVersion = 0x99999999; RevInfo.BuildVersion = 0x99999999; RevInfo.RadioFormat = 0xffff; RevInfo.SysCfgFormat = 0xffff; memset(buf, 0, HCI_MAX_EVENT_SIZE); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return dd; } iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_READ_VERSION, 0, buf); if (buf[6] != 0) { printf("\nRead version failed due to reason :0x%X\n", buf[6]); return buf[6]; } RevInfo.RomVersion = buf[7] + (buf[8]<<8) + (buf[9]<<16) + (buf[10]<<24); RevInfo.BuildVersion = buf[11] + (buf[12]<<8) + (buf[13]<<16) + (buf[14]<<24); return 0; } /*static const char *otp_help = "\nUsage:" "\notp [dump|imp|exp|test|rpid|wpid|rvid|wvid|rba|wba|hid|cpw|cpw|pwridx|ledo] [file]\n" "\notp wba :\n" "\n\n"; */ static void cmd_otp(int dev_id, int argc, char **argv) { UCHAR buf[512], format[16]; FILE *pF = NULL; UINT32 data; int i; if (argc == 1 || !strcmp(argv[1], "dump")) { printf("dump:\n"); for (i = 0; i < 4; i++) { if (read_otpRaw(dev_id, 128 * i, 128, &buf[128*i])) { printf("read failed\n"); return; } } dumpHex(buf, 512, 8); } else if (!strcmp(argv[1], "test")) { printf("test:\n"); printf("To be continue.\n"); } else if (!strcmp(argv[1], "imp")) { if (argc < 3 || !*argv[2]) { printf("Import file content into OTP. File name is required\n"); return; } printf("Import from %s into OTP:\n", argv[2]); if (!(pF = fopen(argv[2], "rb"))) { printf("Open file failed\n"); return; } fread(&buf[0], sizeof(buf), 1, pF); fclose(pF); for (i = 0; i < 512; i += 4) { data = buf[i]; data <<= 8; data += buf[i+1]; data <<= 8; data += buf[i+2]; data <<= 8; data += buf[i+3]; sprintf((char *)&format, "0x%08x", data); if (write_otpRaw(dev_id, i, 4, (UCHAR *)format)) { printf("Failed!(%d)\n", i); return; } } printf("Done\n"); } else if (!strcmp(argv[1], "exp")) { for (i = 0; i < 4; i++) { if (read_otpRaw(dev_id, 128 * i, 128, &buf[128*i])) { printf("Failed\n"); return; } } if (argc < 3 || !*argv[2] || (!(pF = fopen(argv[2], "wb")))) { /* export the content to the screen */ dumpHex(buf, 512, 8); } else { /* export the content to the file */ fwrite(&buf[0], sizeof(buf), 1, pF); fclose(pF); } printf("Done\n"); } else if (!strcmp(argv[1], "ledo")) { int opendrain; tSU_RevInfo RevInfo; if (SU_GetId(dev_id, NULL, &RevInfo)) return; printf("RomVer:%02X.%02X.%02X.%02X \n", (UINT8)((RevInfo.RomVersion >> (8*3)) & 0xff), (UINT8)((RevInfo.RomVersion >> (8*2)) & 0xff), (UINT8)((RevInfo.RomVersion >> 8) & 0xff), (UINT8)(RevInfo.RomVersion & 0xff)); if (((UINT8)((RevInfo.RomVersion >> (8*3)) & 0xff) == 0x01) && ((UINT8)((RevInfo.RomVersion >> (8*2)) & 0xff) == 0x02) && ((UINT8)((RevInfo.RomVersion >> 8) & 0xff) == 0x02) && ((UINT8)(RevInfo.RomVersion & 0xff) == 0x00)) { UINT8 LedValue[] = {0xCE, 0xDA, 0x04, 0x0C, 0x58, 0x04, 0x05, 0x06, 0xff, 0x50, 0x40, 0x01, 0x24, 0x08, 0x00, 0x00}; for (opendrain = 112; opendrain < 128; opendrain++) { if (write_otpRaw(dev_id, opendrain, 1, &LedValue[opendrain-112])) { printf("Failed\n"); return; } } printf("OTP led opendrain done\n"); } else { printf("Wrong RomVer\n"); } } else if (!strcmp(argv[1], "cpw")) { UINT32 cin_value = 0, cout_value = 0; char tempStr[8]; if (argc < 3) { printf("\n Enter cin_value : "); scanf("%d", &cin_value); } else cin_value = GetUInt(&argv[2], 0); if (cin_value < 0 || cin_value > 128) { printf("Invalid cin_value = %d\n", cin_value); return; } if (argc < 4) { printf("\n Enter cout_value : "); scanf("%d", &cout_value); } else cout_value = GetUInt(&argv[3], 0); if (cout_value < 0 || cout_value > 128) { printf("Invalid cout_value = %d\n", cout_value); return; } if (cout_value & 0x01) cin_value += 0x80; sprintf(tempStr, "0x%02x", cin_value); if (write_otpRaw(dev_id, 4, 1, (UCHAR *)tempStr)) { printf("CapTune Error\n"); return; } sprintf(tempStr, "0x%02x", cout_value >> 1); if (write_otpRaw(dev_id, 5, 1, (UCHAR *)tempStr)) { printf("CapTune Error\n"); return; } sprintf(tempStr, "0x40"); if (write_otpRaw(dev_id, 5, 1, (UCHAR *)tempStr)) { printf("CapTune Error\n"); return; } printf("Done\n"); } else if (!strcmp(argv[1], "pwridx")) { char tempStr[8]; sprintf(tempStr, "0x02"); if (write_otpRaw(dev_id, 21, 1, (UCHAR *)tempStr)) { printf("Failed\n"); return; } printf("Done\n"); } else if (!strcmp(argv[1], "hid")) { char tempStr[8]; UINT32 value = 0; if (argc < 3 || !*argv[2]) { printf("\n Enter HID value(0|1) : "); scanf("%d", &value); } else value = GetUInt(&argv[2], 0); if (value != 0 && value != 1) { printf("\n Error: Syntax \"otp hid 0x00|0x01\"\n"); return; } sprintf(tempStr, "0x%02x", value); if (write_otpRaw(dev_id, 12, 1, (UCHAR *)tempStr)) { printf("Failed\n"); return; } printf("Done\n"); } else if (!strcmp(argv[1], "wpid")) { UINT32 offset = 134; size_t len = 0; char pid[8] = {0}; char *ofs = NULL; printf("\n Enter OTP_PID_OFFSET(default 134) : "); getline(&ofs, &len, stdin); sscanf(ofs, "%d", &offset); if (ofs) free(ofs); memset(pid, 0, sizeof(pid)); if (argc < 3 || !*argv[2]) { printf("\n Enter PID : "); fgets((char *)pid, 7, stdin); } else strncpy((char *)pid, argv[2], 7); len = strlen(pid) - 1; if (pid[len] == '\n' || pid[len] == '\r') pid[len] = 0; ReverseHexString(pid); if (write_otpRaw(dev_id, offset, 4, (UCHAR *)pid)) { printf("Failed\n"); return; } printf("Done\n"); } else if (!strcmp(argv[1], "rpid")) { UINT32 offset = 134; size_t len = 0; UCHAR Data[2]; char *ofs = NULL; printf("\n Enter OTP_PID_OFFSET(default 134) : "); getline(&ofs, &len, stdin); sscanf(ofs, "%d", &offset); if (ofs) free(ofs); if (read_otpRaw(dev_id, offset, 2, Data)) { printf("Failed\n"); return; } printf("The OTP PID is 0x%02x%02x\n", Data[1], Data[0]); } else if (!strcmp(argv[1], "wvid")) { UINT32 offset = 136; size_t len = 0; char vid[8] = {0}; char *ofs = NULL; printf("\n Enter OTP_VID_OFFSET(default 136) : "); getline(&ofs, &len, stdin); sscanf(ofs, "%d", &offset); if (ofs) free(ofs); memset(vid, 0, sizeof(vid)); if (argc < 3 || !*argv[2]) { printf("\n Enter VID : "); fgets(vid, 8, stdin); } else strncpy(vid, argv[2], 7); len = strlen(vid) - 1; if (vid[len] == '\n' || vid[len] == '\r') vid[len] = 0; ReverseHexString(vid); if (write_otpRaw(dev_id, offset, 2, (UCHAR *)vid)) { printf("Failed\n"); return; } printf("Done\n"); } else if (!strcmp(argv[1], "rvid")) { UINT32 offset = 136; size_t len = 0; char *ofs = NULL; UCHAR Data[2]; printf("\n Enter OTP_VID_OFFSET(default 136) : "); getline(&ofs, &len, stdin); sscanf(ofs, "%d", &offset); if (ofs) free(ofs); if (read_otpRaw(dev_id, offset, 2, Data)) { printf("Failed\n"); return; } printf("The OTP VID is 0x%02x%02x\n", Data[1], Data[0]); } else if (!strcmp(argv[1], "wba")) { UINT32 offset = 128; size_t len = 0; char bdaddr[16] = {0}; char *ofs = NULL; printf("\n Enter OTP_BDA_OFFSET(default 128) : "); getline(&ofs, &len, stdin); sscanf(ofs, "%d", &offset); if (ofs) free(ofs); memset(bdaddr, 0, sizeof(bdaddr)); if (argc < 3 || !*argv[2]) { printf("\n Enter BDADDR : "); fgets(bdaddr, 16, stdin); } else strncpy(bdaddr, argv[2], 15); len = strlen(bdaddr) - 1; if (bdaddr[len] == '\n' || bdaddr[len] == '\r') bdaddr[len] = 0; ReverseHexString(bdaddr); if (write_otpRaw(dev_id, offset, 6, (UCHAR *)bdaddr)) { printf("Failed\n"); return; } printf("Done\n"); } else if (!strcmp(argv[1], "rba")) { UINT32 offset = 128; size_t len = 0; char *ofs = NULL; UCHAR Data[6]; printf("\n Enter OTP_BDA_OFFSET(default 128) : "); getline(&ofs, &len, stdin); sscanf(ofs, "%d", &offset); if (ofs) free(ofs); if (read_otpRaw(dev_id, offset, 6, Data)) { printf("Failed\n"); return; } printf("The OTP BDADDR is 0x%02x%02x%02x%02x%02x%02x\n", Data[5], Data[4], Data[3], Data[2], Data[1], Data[0]); } } #if 0 static const char *plb_help = "\nUsage:" "\nplb [1|0]\n" "\nplb 1\n" "\n\n"; #endif static void cmd_plb(int dev_id, int argc, char **argv) { int dd, enable, iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if (argc < 2) enable = 1; else enable = GetUInt(&argv[1], 1); if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(buf, 0, HCI_MAX_EVENT_SIZE); buf[0] = 0x09; /* audio commmand opcode */ buf[4] = (enable == 0) ? 0x00 : 0x01; /* audio command param */ iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_AUDIO_CMD, 8, buf); if (buf[6] != 0) { printf("\nError in setting PCM CODEC loopback :0x%X\n", buf[6]); hci_close_dev(dd); return; } printf("\nPCM CODEC loopback is %s\n", (enable == 0) ? "OFF" : "ON"); hci_close_dev(dd); } #if 0 static const char *psw_help = "\nUsage:" "\npsw [1|0] [Frequency]\n" "\npsw 1 3000\n" "\n\n"; #endif static void cmd_psw(int dev_id, int argc, char **argv) { int dd, enable, freq, iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if (argc < 2) { enable = 1; freq = 440; } else if (argc < 3) { printf("aa\n"); enable = GetUInt(&argv[1], 1); freq = 440; } else { enable = GetUInt(&argv[1], 1); freq = GetUInt(&argv[2], 440); } if (freq > 3700) { printf("Invalid frequency. It should be in the range of 0 to 3700\n"); return; } if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(buf, 0, HCI_MAX_EVENT_SIZE); buf[0] = 0x0a; /* audio command opcode */ buf[4] = (enable == 0) ? 0x00 : 0x01; /* audio command param */ buf[5] = 0x00; buf[6] = freq & 0xff; buf[7] = (freq >> 8) & 0xff; iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_AUDIO_CMD, 8, buf); if (buf[6] != 0) { printf("\nError in running PCM sine wave playback :0x%X\n", buf[6]); hci_close_dev(dd); return; } printf("PCM CODEC PCM sine wave playback is %s\n", (enable == 0) ? "OFF" : "ON"); hci_close_dev(dd); } static const char *lert_help= "\nUsage:" "\nlert \n" "\nlert 30 \n" "\n\n"; static void cmd_lert(int dev_id, int argc, char **argv) { int dd; UCHAR channel; if (argc < 2) { printf("\n%s\n", lert_help); return; } channel = (UCHAR)GetUInt(&argv[1], 0); if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } SU_LERxTest(dd, channel); hci_close_dev(dd); } static BOOL SU_LERxTest(int dd, UCHAR channel) { int iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if (channel < MB_MIN_FREQUENCY_LE || channel > MB_MAX_FREQUENCY_LE) { printf("Invalid rx channel. It should be in the range of %d to %d\n", MB_MIN_FREQUENCY_LE, MB_MAX_FREQUENCY_LE); return FALSE; } memset(buf, 0, HCI_MAX_EVENT_SIZE); buf[0] = channel; /* rx_channel */ iRet = writeHciCommand(dd, OGF_LE_CTL, OCF_LE_RECEIVER_TEST, 1, buf); if (buf[6] != 0) { printf("\nError in putting the device into LE RX mode\n"); return FALSE; } return TRUE; } static const char *lett_help= "\nUsage:" "\nlett \n" "\nlett 30 30 5\n" "\n\n"; static void cmd_lett(int dev_id, int argc, char **argv) { int dd; UCHAR channel, length, payload; if (argc < 4) { printf("\n%s\n", lett_help); return; } channel = (UCHAR)GetUInt(&argv[1], 0); length = (UCHAR)GetUInt(&argv[2], 0); payload = (UCHAR)GetUInt(&argv[3], 0); if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } SU_LETxTest(dd, channel, length, payload); hci_close_dev(dd); } static BOOL SU_LETxTest(int dd, UCHAR channel, UCHAR length, UCHAR payload) { int iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if (channel < MB_MIN_FREQUENCY_LE || channel > MB_MAX_FREQUENCY_LE) { printf("Invalid tx channel. It should be in the range of %d to %d\n", MB_MIN_FREQUENCY_LE, MB_MAX_FREQUENCY_LE); return FALSE; } if (length < MB_MIN_DATALEN_LE || length > MB_MAX_DATALEN_LE) { printf("Invalid data length. It should be in the range of %d to %d\n", MB_MIN_DATALEN_LE, MB_MAX_DATALEN_LE); return FALSE; } if (payload > 7) { printf("Invalid packet payload. It should be in the range of 0 to 7\n"); return FALSE; } memset(buf, 0, HCI_MAX_EVENT_SIZE); buf[0] = channel; /* tx_channel */ buf[1] = length; /* length of test data */ buf[2] = payload; /* packet payload */ iRet = writeHciCommand(dd, OGF_LE_CTL, OCF_LE_TRANSMITTER_TEST, 3, buf); if (buf[6] != 0) { printf("\nError in putting the device into LE TX mode\n"); return FALSE; } return TRUE; } #if 0 static const char *lete_help = "\nUsage:" "\nlete\n" "\n\n"; #endif static void cmd_lete(int dev_id, int argc, char **argv) { int dd, iRet; UCHAR buf[HCI_MAX_EVENT_SIZE]; if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } memset(buf, 0, HCI_MAX_EVENT_SIZE); iRet = writeHciCommand(dd, OGF_LE_CTL, OCF_LE_TEST_END, 0, buf); if (buf[6] != 0) { printf("\nError in ending LE test\n"); hci_close_dev(dd); return; } printf("Number of packets = %d\n", buf[7] | (buf[8] << 8)); hci_close_dev(dd); } static const char *tputs_help = "\nUsage:" "\ntput-s [BD_Addr] [Judgment value] Logfile times" "\ntput-s 11:22:33:44:55:66 150 log.txt 10" "\n\n"; static void CalculateTput(int dd, UINT16 hci_handle, char *filename, double threshold, int tx_size) { time_t start, finish, checkbreak; UCHAR buf[1009]; FILE *fp = NULL; int aclnum = 8; int retval; unsigned long sentnum = 0; double TimeResult = 0; fd_set rfds; struct hci_filter flt; struct timeval tv1, tv2, timeout; unsigned long long start_utime, end_utime, time_diff; unsigned long long throughput; hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_NUM_COMP_PKTS, &flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("HCI filter setup failed"); exit(EXIT_FAILURE); } start = time(NULL); gettimeofday(&tv1, NULL); start_utime = tv1.tv_sec*1000000 + tv1.tv_usec; while (sentnum < 1024 * tx_size) { while (aclnum > 0) { aclnum--; buf[0] = HCI_ACLDATA_PKT; /* ACL packet header */ buf[1] = hci_handle & 0xFF; buf[2] = ((hci_handle >> 8) & 0x0E); buf[3] = 1004 & 0xff; buf[4] = (1004 >> 8) & 0xff; /* L2CAP packet header */ buf[5] = 1000 & 0xff; buf[6] = (1000 >> 8) & 0xff; buf[7] = 0x40 & 0xff; buf[8] = 0; memset(buf+9, sentnum++, 1000); while (write(dd, (const void *)buf, 1009) < 0) { if (errno == EAGAIN || errno == EINTR) continue; perror("HCI send packet failed"); exit(EXIT_FAILURE); } } timeout.tv_sec = 5; timeout.tv_usec = 0; FD_ZERO(&rfds); FD_SET(dd, &rfds); retval = select(dd+1, &rfds, NULL, NULL, &timeout); if (retval == -1) { perror("select()"); exit(EXIT_FAILURE); } else if (retval) { /* Data is available now */ ssize_t plen; UCHAR buffer[64]; int i; plen = read(dd, buffer, 64); if (plen < 0) { perror("HCI read buffer failed"); exit(EXIT_FAILURE); } for (i = 0; i < buffer[HCI_EVENT_HEADER_SIZE]; i++) aclnum += (buffer[HCI_EVENT_HEADER_SIZE+(i+1)*2+1] | (buffer[HCI_EVENT_HEADER_SIZE+(i+1)*2+2] << 8)); } checkbreak = time(NULL); if ((checkbreak - start) >= 300) break; } finish = time(NULL); gettimeofday(&tv2, NULL); end_utime = tv2.tv_sec*1000000 + tv2.tv_usec; time_diff = end_utime - start_utime; throughput = time_diff/1000; throughput = (sentnum * 1000)/throughput; printf("Transfer Completed! throughput [%0d KB/s]", (int)throughput); printf(" result [%s]\n", threshold > throughput ? " Fail " : " Pass "); if (filename && *filename) fp = fopen(filename, "at+"); if (fp) { fprintf(fp, "Transfer Completed! throughput [%.0f KB/s]", TimeResult); fprintf(fp, " result [%s]\n", threshold > TimeResult ? " Fail " : " Pass "); fclose(fp); } } static void cmd_tputs(int dev_id, int argc, char **argv) { int j, dd, iRet, loop = 1, tx_test_size = 1; UINT16 Ps_EntrySize = 0; UINT16 hci_handle = 0; double threshold = 0.0; char *filename = NULL; struct sigaction sa; FILE *fp = NULL; bdaddr_t bdaddr; UCHAR buf[HCI_MAX_EVENT_SIZE]; UCHAR Ps_Data[HCI_MAX_EVENT_SIZE]; UINT16 *pPs_Data; BOOL Ok = FALSE; char timeString[9] = {0}; char dateString[15] = {0}; time_t current_time; struct tm *time_info; tSU_RevInfo RevInfo; if (argc < 3) { printf("\n%s\n", tputs_help); return; } if (str2ba(argv[1],&bdaddr)) { printf("\nPlease input valid bdaddr.\n"); return; } threshold = atof(argv[2]); if (!threshold) { printf("\nPlease input valid throughput threshold.\n"); return; } if (argc > 3) filename = strdup(argv[3]); if (argc > 4) loop = GetUInt(&argv[4], 1); if (argc > 5) tx_test_size = GetUInt(&argv[5],1); if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } CtrlCBreak = FALSE; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); PSInit(dd); memset(buf, 0, sizeof(buf)); iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_RESET, 0, buf); if (buf[6] != 0) { printf("Error: HCI RESET failed.\n"); hci_close_dev(dd); return; } sleep(1); for (j = 0; j < loop; j++) { int i = 0; if (!j) sleep(1); printf("\n-----------------------------------"); printf("\nTimes %d/%d\n", j + 1, loop); time(¤t_time); time_info = localtime(¤t_time); strftime(timeString, sizeof(timeString), "%H %M %S", time_info); strftime(dateString, sizeof(dateString), "%b %d %Y", time_info); if (j == 0) { if (filename && *filename) fp = fopen(filename, "at+"); if (fp != NULL) fprintf(fp, "\n[%s %s] \nCMD : TPUT-S %s %f %s %d\n", dateString, timeString, argv[1], threshold, filename, loop); /* SFLAGS FW */ Ok = PSOperations(dd, PS_GET_LENGTH, PSTAG_RF_TEST_BLOCK_START, (UINT32 *)&Ps_EntrySize); if (Ok) { Ps_Data[0] = Ps_EntrySize & 0xff; Ps_Data[1] = (Ps_EntrySize >> 8) & 0xff; Ok = PSOperations(dd, PS_READ, PSTAG_RF_TEST_BLOCK_START, (UINT32 *)&Ps_Data); if (Ok) { pPs_Data = (UINT16 *)&Ps_Data[0]; if (*pPs_Data == BT_SOC_INIT_TOOL_START_MAGIC_WORD) { RevInfo.RadioFormat = *(pPs_Data + 1); RevInfo.RadioContent = *(pPs_Data + 2); } } } /* Get syscfg info */ Ok = PSOperations(dd, PS_GET_LENGTH, PSTAG_SYSCFG_PARAM_TABLE0, (UINT32 *)&Ps_EntrySize); if (Ok) { Ps_Data[0] = Ps_EntrySize & 0xff; Ps_Data[1] = (Ps_EntrySize >> 8) & 0xff; Ok = PSOperations(dd, PS_READ, PSTAG_SYSCFG_PARAM_TABLE0, (UINT32 *)&Ps_Data); if (Ok) { pPs_Data = (UINT16 *)&Ps_Data[0]; if (*pPs_Data == 0xC1C1) { RevInfo.SysCfgFormat = *(pPs_Data + 1); RevInfo.SysCfgContent = *(pPs_Data + 2); } } } if (RevInfo.SysCfgFormat != 0xff) { printf("SysCfg - Format: %d.%d\n",((RevInfo.SysCfgFormat >> 4) & 0xfff), (RevInfo.SysCfgFormat & 0xf)); printf(" Content: %d\n", RevInfo.SysCfgContent); if (fp) { fprintf(fp, "SysCfg - Format: %d.%d\n",((RevInfo.SysCfgFormat >> 4) & 0xfff), (RevInfo.SysCfgFormat & 0xf)); fprintf(fp, " Content: %d\n", RevInfo.SysCfgContent); } } else { printf("SysCfg - N/A\n"); if(fp) fprintf(fp, "SysCfg - N/A\n"); } /* bd addr */ memset(&buf, 0, sizeof(buf)); iRet = writeHciCommand(dd, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, buf); if (buf[6] != 0) { printf("\nCould not read the BD_ADDR (time out)\n"); } else { char temp[16] = {0}; memset(temp, 0, sizeof(temp)); sprintf(temp, "%02X%02X%02X%02X%02X%02X", buf[iRet-1], buf[iRet-2], buf[iRet-3], buf[iRet-4], buf[iRet-5], buf[iRet-6]); printf("\nLocal BDAddress : 0x%s\n", temp); if (fp) fprintf(fp, "Local BDAddress : 0x%s\n", temp); } if (fp) { fclose(fp); fp = NULL; } } printf("Sending packages to 0x%s\n", argv[1]); while (i++ < 3) { iRet = hci_create_connection(dd, &bdaddr, 0xCC18, 0, 0, &hci_handle, 0); if (!iRet || CtrlCBreak) break; } if (iRet) { if (filename && *filename) { fp = fopen(filename, "at+"); if (fp) { fprintf(fp, "Transfer Failed! \n"); fclose(fp); fp = NULL; } } printf("Transfer Failed! \n"); CtrlCBreak = TRUE; hci_close_dev(dd); return; } CalculateTput(dd, hci_handle, filename, threshold, tx_test_size); hci_disconnect(dd, hci_handle, 0, 30); if (CtrlCBreak) break; } CtrlCBreak = TRUE; hci_close_dev(dd); } static void cmd_tputr(int dev_id, int argc, char **argv) { int dd, iRet; ssize_t plen; UINT16 hci_handle = 0; UCHAR buf[HCI_MAX_EVENT_SIZE]; struct hci_filter flt; struct sigaction sa; if (dev_id < 0) dev_id = hci_get_route(NULL); dd = hci_open_dev(dev_id); if (dd < 0) { perror("\nERROR: Can not open HCI device\n"); return; } CtrlCBreak = FALSE; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); memset(buf, 0, sizeof(buf)); iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_RESET, 0, buf); if (buf[6] != 0) { printf("Error: HCI RESET failed.\n"); hci_close_dev(dd); return; } sleep(1); memset(buf, 0, sizeof(buf)); buf[0] = 0x02; iRet = writeHciCommand(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, buf); if (buf[6] != 0) { printf("Error: Write scan failed\n"); return; } hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_all_events(&flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("HCI filter setup failed"); exit(EXIT_FAILURE); } printf("Start listening ...\n"); do { plen = read(dd, buf, HCI_MAX_EVENT_SIZE); if (plen < 0) { printf("reading failed...\n"); if (errno == EAGAIN || errno == EINTR) continue; else { perror("HCI read failed"); exit(EXIT_FAILURE); } } if (buf[1] == EVT_CONN_REQUEST) { int i, j; ssize_t plen = 0; printf("Connection come in\n"); for (i = 0, j = 3; i < BD_ADDR_SIZE; i++, j++) buf[i] = buf[j]; buf[BD_ADDR_SIZE] = 0x01; if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, 7, buf)) { printf("Accept connection error\n"); return; } do { plen = read(dd, buf, HCI_MAX_EVENT_SIZE); if (plen < 0) { perror("Read failed"); exit(EXIT_FAILURE); } } while (buf[1] != EVT_CONN_COMPLETE); if (buf[3] == 0) { printf("Connection up\n"); } else { printf("Connection failed\n"); } hci_handle = (buf[4] | (buf[5] << 8)) & 0x0EFF; } else if (buf[1] == EVT_DISCONN_COMPLETE) { UINT16 hdl = buf[4] | (buf[5] << 8); printf("Disconnect...\n"); if (hdl == hci_handle) { break; } } else if (CtrlCBreak) { printf("CtrlBreak...\n"); break; } } while (plen >= 0); CtrlCBreak = TRUE; hci_close_dev(dd); } static void sig_term(int sig) { if (CtrlCBreak) return; CtrlCBreak = TRUE; } static struct { char *cmd; char *cmd_option; void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { { "psreset"," ", cmd_psreset, "Download PS files and Reset Target" }, { "reset"," ", cmd_reset, "Reset Target" }, { "rba"," ", cmd_rba, "Read BD Address" }, { "wba"," ", cmd_wba, "Write BD Address" }, { "edutm"," ", cmd_edutm, "Enter DUT Mode" }, { "wsm"," ", cmd_wsm, "Write Scan Mode" }, { "mb"," ", cmd_mb, "Enter Master Blaster Mode" }, { "mbr","
", cmd_mbr, "Block memory read" }, { "peek","
", cmd_peek, "Read Value of an Address" }, { "poke","
", cmd_poke, "Write Value to an Address" }, { "cwtx"," ", cmd_cwtx, "Enter Continuous wave Tx" }, { "cwrx"," ", cmd_cwrx, "Enter Continuous wave Rx" }, { "rpst"," ", cmd_rpst, "Read PS Tag" }, { "wpst"," ", cmd_wpst, "Write PS Tag" }, { "psr"," ", cmd_psr, "PS Reset" }, { "setap"," ", cmd_setap, "Set Access Priority" }, { "setam"," ", cmd_setam, "Set Access Mode" }, { "rpsraw"," ", cmd_rpsraw, "Read Raw PS" }, { "wpsraw"," ", cmd_wpsraw, "Write Raw PS" }, { "ssm"," ", cmd_ssm, "Set Sleep Mode" }, { "dtx"," ", cmd_dtx, "Disable TX" }, { "dump","