📄 hf_demo_app.c
字号:
/******************************************************************************************************
(c) Cambridge Silicon Radio Ltd, 2006
All rights reserved
FILE: hf_demo_app.c
DESCRIPTION: This is a simple demo application to show how to utilise
the Profile Managers from CSR. This application
executes with user interaction through the keyboard
and a standard console as output.
REVISION: $Revision: #3 $
*******************************************************************************************************/
/* standard include files */
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include <stdarg.h>
/* profile manager include files */
#include "sched/types.h"
#include "sched/pmalloc.h"
#include "sched/env_prim.h"
#include "bchs_tasks.h"
#include "bluetooth.h"
#include "profiles.h"
#include "cm_prim.h"
#include "cm_lib.h"
#include "dmlib.h"
#include "sc_prim.h"
#include "sc_lib.h"
#include "util.h"
#include "hf_prim.h"
#include "hf_lib.h"
#include "sco_audio.h"
#include "hf_demo_app_lib.h"
#include "platform.h"
#ifdef _BCHS_EXTERNAL_
#undef bchs_msg_transport
#define bchs_msg_transport peer_put_message
#ifdef __KERNEL__
#include "peer_com_linux_u2k.h"
#else
#include "peer_com_linux_u2u.h"
#endif
#else
#endif
#define ENABLE_UNPLUGGED (1)
#define PRINT_AT_CMD (0)
#define PRINT_AT_CMD_VERBOSE (0)
#undef INCLUDE_SC_HANDLER
/* The time to wait for bonding and connection in number of seconds */
#define KEYB_CHECK_TIMEOUT (200000)
/* the number of rings and the time between consequetive rings */
#define SPK_VOLUME_CHANGE_GAIN (5)
#define MIC_VOLUME_CHANGE_GAIN (5)
#define MAX_MIC_GAIN (15)
#define MIN_MIC_GAIN (0)
#define MAX_SPK_GAIN (15)
#define MIN_SPK_GAIN (0)
/* SCO/eSCO parameters */
#define SCO_PACKET_TYPE (0)
#define SCO_TX_BANDWIDTH (0)
#define SCO_RX_BANDWIDTH (0)
#define SCO_MAX_LATENCY (0)
#define SCO_VOICE_SETTINGS (0)
#define SCO_RETRANSMISSION_EFFORT (0)
#define PCM_SLOT (PCM_DONT_CARE)
#define PCM_SLOT_REALLOCATE (FALSE)
#define SCO_HANDLE_UNUSED (0xFFFF)
#define TO_UPPER(x) ((((x) >= 'a') && ((x) <= 'z')) ? ((x) & 0xDF) : (x))
#define IS_DIGIT_CHAR(x) ((((x) >= '0') && ((x) <= '9')) ? TRUE : FALSE)
#define C2C_SF_COMMAND "AT+CSRSF=1,1,1,1,1\r"
#define C2C_SF_COMMAND_LEN (19)
#define C2C_SF_RESPONSE "\r\n+CSRSF: "
#define C2C_SF_RESPONSE_LEN (10)
#define C2C_POWER_COMMAND "AT+CSRPWR=?\r"
#define C2C_POWER_COMMAND_LEN (12)
#define C2C_POWER_COMMAND_IDX (10)
#define C2C_BATTERY_COMMAND "AT+CSRBATT=?\r"
#define C2C_BATTERY_COMMAND_LEN (13)
#define C2C_BATTERY_COMMAND_IDX (11)
#define C2C_GET_SMS_COMMAND "AT+CSRGETSMS=42\r"
#define C2C_GET_SMS_COMMAND_LEN (16)
#define C2C_CSR_COMMAND "AT+CSR=(1,1),(2,1),(3,1),(4,1),(5,1)\r"
#define C2C_CSR_COMMAND2 "AT+CSR=(1,0),(2,0),(3,0),(4,0),(5,0)\r"
#define C2C_CSR_COMMAND_LEN (37)
#define C2C_SMS_COMMAND "\r\n+CSRSMS: "
#define C2C_SMS_COMMAND_LEN (11)
#define MAX_NUM_CONNECTION 2
#define STARTUP_MIC 0
#define STARTUP_DONE 2
typedef struct
{
uint8_t length;
unsigned char phoneNumber[50];
} phoneNumber_t;
typedef struct
{
uint8_t ATCommandLen;
unsigned char ATCommand[128];
}ATCommand_t;
typedef struct
{
bool_t specified;
uint8_t index;
}callIdentity_t;
/* demoapp states */
typedef enum
{
idle,
pairing,
dialing,
enteringCommand,
operatorQuery,
} HfDemoStates_t;
typedef enum
{
cliMainMenu,
cliSubMenuAT,
cliSubMenuCallHandling,
cliSubMenuCallSpecify
}HfDemoStatesCLI_t;
typedef enum
{
disconnected_s,
connected_s
} HfLinkState_t;
typedef enum
{
sequence0,
sequence1,
sequence2,
sequence3,
sequence4,
sequence5,
sequence6,
sequence7,
serviceLevelConn
} HfAtServiceLevelConnStates_t;
typedef struct
{
char *name;
uint16_t mode_connection;
uint16_t format;
} OperatorInfo_t;
typedef struct
{
uint8_t startup;
HfLinkState_t linkState;
deviceAddr_t bdAddr;
HfAtServiceLevelConnStates_t atState;
bool_t audioOn;
uint8_t speakerGain;
uint8_t micGain;
bool_t voiceRecognition;
uint8_t atResultCounter;
bool_t threeWayCallingSupported;
uint16_t supportedFeatures;
uint16_t scoHandle;
uint8_t cmeErrorCodes;
bool_t cmerStatus;
} HfHsCommonInstData_t;
typedef struct
{
HfDemoStates_t state;
deviceAddr_t bondingDevAddr;
uint8_t passkeyLength;
uint8_t passkey[PASSKEY_MAX_LEN];
HfHsCommonInstData_t conInstData[MAX_NUM_CONNECTION];
ConType_t currentConnection;
phoneNumber_t myPhoneNumber;
void *recvMsgP;
bool_t serverActivated;
HfDemoStatesCLI_t cliState;
ATCommand_t myATCommand;
OperatorInfo_t operatorInfo;
callIdentity_t selectedCall;
phandle_t app_hdl;
uint8_t batteryLevel;
HfDemoStates_t preState;
} DemoInstdata_t;
void inComingBscpSound(char * theData)
{
SendScoData(theData);
}
/* forward declarations for handler functions */
void handleKeybPrim(DemoInstdata_t * instData);
void handleHfPrim(DemoInstdata_t * instData);
void handleCmPrim(DemoInstdata_t * instData);
void handleScPrim(DemoInstdata_t * instData);
/* forward declarations for menu handler functions */
void cliMainMenuKeySwitch(uint8_t theChar, DemoInstdata_t * instData);
void cliSubMenuATKeySwitch(uint8_t theChar, DemoInstdata_t * instData);
void cliSubMenuCallHandlingKeySwitch(uint8_t theChar, DemoInstdata_t * instData);
int _kbhit( void );
int _getch( void );
void* createEnvCleanup(void* vPtr)
{
ENV_CLEANUP_IND_T *prim;
prim = pmalloc(sizeof(ENV_CLEANUP_IND_T));
prim->type = ENV_CLEANUP_IND;
prim->phandle = TESTQUEUE;
return((void*)prim);
}
void inComingBcspSound(char * theData)
{
SendScoData(theData);
}
static void startup_mic_gain(uint16_t m, void *v)
{
DemoInstdata_t * instData;
instData = (DemoInstdata_t*)v;
HfMicGainReqSend(instData->conInstData[m].micGain, (uint8_t)(m & 0xff));
}
void KeyMessageService(uint16_t m ,void *data)
{
if (_kbhit())
{
BchsKeyPress_t *key;
key = pmalloc(sizeof(BchsKeyPress_t));
key->type = KEY_MESSAGE;
key->key =_getch();
put_message(TESTQUEUE, KEY_MESSAGE, key);
}
timed_event_in(KEYB_CHECK_TIMEOUT, KeyMessageService, m, data);
}
static char * getHfHsString(ConType_t theConnectionType)
{
switch (theConnectionType)
{
case HF_CONNECTION:
{
return "HF";
break;
}
case HS_CONNECTION:
{
return "HS";
break;
}
default:
{
return "None";
break;
}
}
}
void sendC2cInit(void)
{
uint8_t *body;
body = pmalloc(C2C_SF_COMMAND_LEN);
MemCpy(body, C2C_SF_COMMAND, C2C_SF_COMMAND_LEN);
HfAtCmdReqSend(C2C_SF_COMMAND_LEN, body, HF_CONNECTION);
printf("C2C initialisation command sent\n");
}
void sendPowerStatus(DemoInstdata_t * instData, uint8_t powerStatus)
{
uint8_t *body;
body = pmalloc(C2C_POWER_COMMAND_LEN);
MemCpy(body, C2C_POWER_COMMAND, C2C_POWER_COMMAND_LEN);
body[C2C_POWER_COMMAND_IDX] = powerStatus + '0';
HfAtCmdReqSend(C2C_POWER_COMMAND_LEN, body, HF_CONNECTION);
printf("C2C power status (%d) sent\n", powerStatus);
}
void sendBatteryLevel(DemoInstdata_t * instData, uint8_t batteryLevel)
{
uint8_t *body;
body = pmalloc(C2C_BATTERY_COMMAND_LEN);
MemCpy(body, C2C_BATTERY_COMMAND, C2C_BATTERY_COMMAND_LEN);
body[C2C_BATTERY_COMMAND_IDX] = batteryLevel + '0';
HfAtCmdReqSend(C2C_BATTERY_COMMAND_LEN, body, HF_CONNECTION);
printf("C2C battery level (%d) sent\n", batteryLevel);
}
void sendGetSms(DemoInstdata_t *instData, uint8_t smsIndex)
{
uint8_t *body;
body = pmalloc(C2C_GET_SMS_COMMAND_LEN);
MemCpy(body, C2C_GET_SMS_COMMAND, C2C_GET_SMS_COMMAND_LEN);
/*body[C2C_GET_SMS_COMMAND_IDX] = smsIndex + '0';*/
HfAtCmdReqSend(C2C_GET_SMS_COMMAND_LEN, body, HF_CONNECTION);
printf("SMS (%d) requested\n", smsIndex);
}
void playMenu(DemoInstdata_t * instData)
{
printf("\nHandsfree Demo: %s\n", (instData->serverActivated ? "Activated" : "Deactivated"));
printf("Hit <ESC> to quit program!\n");
printf("\n");
printf("Current connection: %s", getHfHsString(instData->currentConnection));
printf("\n");
printf("Options: \n\n");
printf(" 0) Deactivate HF Server\n");
printf(" 1) Activate HF Server (With Remote Audio Control Enabled)\n");
printf(" 2) Activate HF server (allow others to connect)\n");
printf(" 3) Establish connection to other device\n");
printf(" 4) Reject an established connection\n");
printf(" 5) Toggle audio on/off\n");
printf(" 6) Disconnect an established service level connection\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -