blob: a3dc89b189e0925505c03b501ceccee10fa866c1 [file] [log] [blame]
/*
* 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.
*
* <Configuration utility for AR3001>
*
* <btconfig.c>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <signal.h>
#include <time.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include "compat/getline.h"
#include "btconfig.h"
#include "masterblaster.h"
#define BT_PORT 2398
/* Global Variables */
static int sid, cid, aid;
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<RamPatch[i].Len;j++){
buf[4+j]=RamPatch[i].Data[j];
}
iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_PS,RamPatch[i].Len + PS_COMMAND_HEADER, buf);
if(buf[iRet-1] != 0){
return FALSE;
}
}
break;
case ENABLE_PATCH:
Length =0;
i=0;
LoadPSHeader(buf,Opcode,Length,i);
iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,PS_COMMAND_HEADER, buf);
if(buf[iRet-1] != 0){
return FALSE;
}
break;
case PS_RESET:
Length =0;
i=0;
LoadPSHeader(buf,Opcode,Length,i);
buf[8] = (Param1 & 0xFF);
buf[9] = ((Param1 >> 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<PsTagEntry[i].TagLen;j++){
buf[4+j]=PsTagEntry[i].TagData[j];
}
iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS,PsTagEntry[i].TagLen + PS_COMMAND_HEADER, buf);
if(buf[iRet-1] != 0){
return FALSE;
}
}
break;
case PS_DYNMEM_OVERRIDE:
LoadPSHeader(buf,Opcode,RamDynMemOverride.Len,RamDynMemOverride.Len);
for(j=0;j<RamDynMemOverride.Len;j++){
buf[4+j]=RamDynMemOverride.Data[j];
}
iRet = writeHciCommand(dd, OGF_VENDOR_CMD,OCF_PS,RamDynMemOverride.Len + PS_COMMAND_HEADER, buf);
if(buf[iRet-1] != 0){
return FALSE;
}
break;
case PS_VERIFY_CRC:
//printf("PSOperations - PS_VERIFY_CRC:VALUE of CRC:%d\r\n",Param1);
Length =0;
LoadPSHeader(buf,Opcode,Length,Param1);
iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS, PS_COMMAND_HEADER, buf);
if(buf[iRet-1] != 0){
return FALSE;
}
break;
case PS_GET_LENGTH: {
ssize_t plen = 0;
LoadPSHeader(buf,Opcode,0,Param1);
iRet = writeHciCommand(dd, OGF_VENDOR_CMD, OCF_PS, 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);
*((UINT16 *)out) = (buf[HCI_EVENT_HEADER_SIZE + 2] << 8) | buf[HCI_EVENT_HEADER_SIZE + 1];
break;
}
}
return TRUE;
}
static int GetDeviceType(int dd){
UCHAR buf[HCI_MAX_EVENT_SIZE];
int iRet;
unsigned int Reg = 0;
memset(&buf,0,sizeof(buf));
buf[0] = (FPGA_REGISTER & 0xFF);
buf[1] = ((FPGA_REGISTER >> 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;
}
/* 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<Tag_Count; i++){
if(PsTagEntry[i].TagId == 1){
BDADDR_Present = TRUE;
//printf("ReadPSFiles - BD ADDR is present in Patch File \r\n");
}
if(PsTagEntry[i].TagLen % 2 == 1){
Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen + 1;
}
else{
Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen;
}
}
}
if(Tag_Count > 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<Tag_Count;i++){
printf("\nTAG ID :%X LEN:%X\n",PsTagEntry[i].TagId,PsTagEntry[i].TagLen);
for(j=0;j<PsTagEntry[i].TagLen;j++)
printf("\t %x",PsTagEntry[i].TagData[j]);
}
printf("\n");
printf("\nPATCH_COUNT %d\n",Patch_Count);
for(i=0;i<Patch_Count;i++){
printf("\tPATCH LEN:%X\t",RamPatch[i].Len);
for(j=0;j<RamPatch[i].Len;j++)
printf("\t %x",RamPatch[i].Data[j]);
}
printf("\n");
printf("\tDYMA LEN:%X\t",RamDynMemOverride.Len);
for(j=0;j<RamDynMemOverride.Len;j++)
printf("\t %x",RamDynMemOverride.Data[j]);
printf("\n");
}
*/
static const char *psreset_help =
"Usage:\n"
"\n psreset\n";
static void cmd_psreset(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",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 <bdaddr>\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 <Channel>\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 newfd, FieldNum,dd,iRet,need_raw, iDataSize, address,width,value,mask, fdmax, k, l;
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;
fd_set master, read_fds;
uint32_t m_BerTotalBits, m_BerGoodBits;
uint8_t m_pattern[16];
uint16_t m_pPatternlength;
struct hci_filter flt;
struct hci_dev_info di;
struct timeval timeout;
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);
m_BerGoodBits = 0;
m_BerTotalBits = 0;
m_pattern[0] = 0x0f;
m_pPatternlength = 1;
FD_ZERO(&master);
FD_ZERO(&read_fds);
FD_SET(0, &master);
fdmax = 0;
newfd = -1;
while (1) {
read_fds = master;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
iRet = select(fdmax+1, &read_fds, NULL, NULL, &timeout);
if (iRet == -1) {
perror("cmd_mb select() error!");
goto exits_mb;
}
if (iRet == 0) continue;
for(i = 0; i <= fdmax; i++) {
if(FD_ISSET(i, &read_fds)) {
if (i==0) { // input
scanf("%s",buf);
FieldAlias = (char)buf[0];
FieldNum = CheckField(MasterBlaster, &FieldAlias);
if (FieldNum == INVALID_MASTERBLASTER_FIELD) {
printf ("\nERROR ---> Invalid command. Try again.\n");
printf ("mb>");
continue;
}
if (!strncmp(&FieldAlias, MasterBlasterMenu[EXX].Alias, 1)) {
printf("\nExit the Master Blaster Mode without reset\n");
goto exits_mb;
}
// if the test is in rx and the key is neither 'd' nor 'g', then stop the test, renew the option, and procced
// if the test is in tx and the key is not 'e', then stop the test, renew the option, and procced
// if the test is in (LE) continuous rx/tx and the key is not 'j' , then stop the test, renew the option, and procced
if (((TestEnabled == MB_RX_TEST) && strncmp(&FieldAlias, MasterBlasterMenu[RX].Alias, 1) && strncmp(&FieldAlias, MasterBlasterMenu[GB].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;
}
if (TestEnabled == MB_RX_TEST) {
if (need_raw) {
if (ioctl(dd, HCISETRAW, 0) < 0)
perror("Can't clear raw mode \n");
}
FD_CLR(newfd, &master);
newfd = -1;
fdmax = 0;
}
// Ok = Diag::Reset (Unit, "");
//PSInit(dd);
// The default setting is sleep mode enabled.
memset(&buf,0,sizeof(buf));
buf[0] = 1;
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]);
}
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)) { // Exit
TestEnabled = MB_NO_TEST;
printf ("\n Exit ..\n");
goto exits_mb;
} else if (!strncmp(&FieldAlias,MasterBlasterMenu[ST].Alias,1)) { // Stop Test
TestEnabled = MB_NO_TEST;
PrintMasterBlasterMenu (&MasterBlaster);
continue;
} else if (!strncmp(&FieldAlias,MasterBlasterMenu[GB].Alias,1)) { // get BER
printf("\n\tGoodBits %d, total is %d\n", m_BerGoodBits, m_BerTotalBits);
printf("mb>\n");
continue;
} else if (!strncmp(&FieldAlias,MasterBlasterMenu[PO].Alias,1)) { // set Power
MasterBlasterMenu[FieldNum].pFunc (&MasterBlaster, &FieldAlias);
} else if (!MasterBlasterMenu[FieldNum].pFunc (&MasterBlaster, MasterBlasterMenu[FieldNum].Options)) {
printf ("\nERROR ---> Invalid option. Try again.\n");
printf ("mb>");
continue;
}
PrintMasterBlasterMenu(&MasterBlaster);
// Enable RX test mode
if ((!strncmp(&FieldAlias, MasterBlasterMenu[RX].Alias, 1) && (TestEnabled == MB_NO_TEST))
|| (strncmp(&FieldAlias, MasterBlasterMenu[RX].Alias, 1) && (TestEnabled == MB_RX_TEST))) {
Ok = Dut(dd);
if (!Ok) {
printf("\nERROR ---> Could not enter DUT mode\n");
printf("mb>");
continue;
}
printf(".");
if (hci_devinfo(dev_id, &di) < 0) {
printf("Can't get device info\n");
printf("mb>");
continue;
}
need_raw = !hci_test_bit(HCI_RAW, &di.flags);
memset(&buf,0,HCI_MAX_EVENT_SIZE);
buf[0] = eBRM_TestMode_Rx;
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_RX_TESTER, 15, buf);
if (buf[6] != 0) {
printf("\nRx 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(" rx test is in progress. Press 's' to stop the test\n");
TestEnabled = MB_RX_TEST;
hci_filter_clear(&flt);
hci_filter_all_ptypes(&flt);
hci_filter_all_events(&flt);
if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
printf("Can't set filter for hci\n");
printf("mb>");
continue;
}
if (need_raw) {
if (ioctl(dd, HCISETRAW, 1) < 0) {
printf("Can't set raw mode on hci\n");
printf("mb>");
continue;
}
}
newfd = dd;
FD_SET(newfd, &master);
fdmax = dd;
}
printf("mb>");
continue;
} else if ((!strncmp(&FieldAlias, MasterBlasterMenu[RX].Alias, 1)) && (TestEnabled == MB_RX_TEST)) {
printf(" rx test is in progress. Press 's' to stop the test\n");
printf("mb>");
continue;
}
// 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("\nTx 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(" tx 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(" tx 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;
}
}
else if (i == newfd) {
iRet = read(i, buf, sizeof(buf));
iDataSize = iRet - 5;
// printf("first:%x,nbyte:%d, packet:%d, pattern:%x\n",buf[0], iRet, (uint16_t)(buf[3] | (buf[4] << 8)), buf[5]);
if (buf[0] == 0x2) { // ACL data
m_BerTotalBits = m_BerTotalBits + iDataSize * 8;
for(j=0,l=0;j<iDataSize;j++,l++) {
if (l == m_pPatternlength) l = 0;
for(k=0;k<8;k++){
if((m_pattern[l]&(1<<k)) == (buf[8+j]&(1<<k)))
m_BerGoodBits++;
}
}
}
}
}
}
}
exits_mb:
if (need_raw) {
if (ioctl(dd, HCISETRAW, 0) < 0)
perror("Can't clear raw mode \n");
}
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 <address> <length> \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 =