blob: 1ab5d188e85e15551da84dfc44ca35f3603f1095 [file] [log] [blame]
#include <stdio.h>
#include "sdk_qs_utils.h"
/*
* These files are required by all applications. "vp_api.h" includes all of the
* API libraries required by the application. "ZLR965324H_SM2_FULL_ASR.h" includes the
* profiles used by the application. At a minimum, there must be a Device
* Profile for the device to initialize.
*/
#include "vp_api.h"
#include "ZLR965324H_SM2_FULL_ASR.h"
#include "user_intf.h"
#include "vp886_registers.h"
extern VpLineCtxType lineCtx[];
extern int MISLIC_APITest_HandleEvents(void);
bool quit_loop = false;
static pthread_t APITest_MainLoopTask;
int user_selection = 15;
/*
* CID Message of DTMF mode, ASCII encoding
* - The start code for calling number shall be either DTMF "A" or "D".
* - The start code for redirecting number shall be DTMF "D".
* - The start code for information values shall be DTMF "B".
* - The information may be sent in any order and shall always end with DTMF "C".
*/
char cidMessageDTMF[] = "A9876543210C";
/*
* CID Message of FSK mode, ASCII encoding
*/
#if 1
char cidMessageFSK[] =
"\x80" /* MDMF Type */
"\x17" /* Message Length */
"\x01" /* Date/Time Param *//*-----message body begin-----*/
"\x08" /* 8-byte Date/Time */
"07040815" /* July 4th 08:15 am */
"\x02" /* Calling Number Param */
"\x0B" /* 11-byte Calling Number */
"13914750000" /* Phone Number *//*-----message body end-----*/
"\x00" /* Placeholder for Checksum */
"\x00" /* Markout */
;
#else
char cidMessageFSK[] =
"\x04" /* SDMF Type */
"\x12" /* Message Length */
"05251856" /* May 25th 18:56 pm */
"9876543210" /* Phone Number */
"\x00" /* Placeholder for Checksum */
"\x00" /* Markout */
;
#endif
/**
* PrintEvent(VpEventType *pEvent)
*
* Description: This function prints all the events
* for debugging purpose.
*/
void
UtilPrintEvent(
VpEventType *pEvent)
{
VpEventCategoryType eventCategory = pEvent->eventCategory;
uint16 eventId = pEvent->eventId;
char *eventCategorySt[] = {
"VP_EVCAT_FAULT",
"VP_EVCAT_SIGNALING",
"VP_EVCAT_RESPONSE",
"VP_EVCAT_TEST",
"VP_EVCAT_PROCESS",
"VP_EVCAT_FXO",
"VP_EVCAT_PACKET",
};
if (eventCategory < VP_NUM_EVCATS) {
QS_DEBUG("\t\teventCategory = %s\n", eventCategorySt[eventCategory]);
} else {
QS_DEBUG("\t\teventCategory = INVALID (0x%x)\n", eventCategory);
}
QS_DEBUG("\t\teventId = ");
if (eventCategory == VP_EVCAT_FAULT) {
switch (eventId) {
case VP_DEV_EVID_BAT_FLT:
QS_DEBUG("VP_DEV_EVID_BAT_FLT\n"); break;
case VP_DEV_EVID_CLK_FLT:
QS_DEBUG("VP_DEV_EVID_CLK_FLT\n"); break;
case VP_LINE_EVID_THERM_FLT:
QS_DEBUG("VP_LINE_EVID_THERM_FLT\n"); break;
case VP_LINE_EVID_DC_FLT:
QS_DEBUG("VP_LINE_EVID_DC_FLT\n"); break;
case VP_LINE_EVID_AC_FLT:
QS_DEBUG("VP_LINE_EVID_AC_FLT\n"); break;
case VP_DEV_EVID_EVQ_OFL_FLT:
QS_DEBUG("VP_DEV_EVID_EVQ_OFL_FLT\n"); break;
case VP_DEV_EVID_WDT_FLT:
QS_DEBUG("VP_DEV_EVID_WDT_FLT\n"); break;
default:
QS_DEBUG("INVALID (0x%x)\n", eventId); break;
}
} else if (eventCategory == VP_EVCAT_SIGNALING) {
switch (eventId) {
case VP_LINE_EVID_HOOK_OFF:
QS_DEBUG("VP_LINE_EVID_HOOK_OFF\n"); break;
case VP_LINE_EVID_HOOK_ON:
QS_DEBUG("VP_LINE_EVID_HOOK_ON\n"); break;
case VP_LINE_EVID_GKEY_DET:
QS_DEBUG("VP_LINE_EVID_GKEY_DET\n"); break;
case VP_LINE_EVID_GKEY_REL:
QS_DEBUG("VP_LINE_EVID_GKEY_REL\n"); break;
case VP_LINE_EVID_FLASH:
QS_DEBUG("VP_LINE_EVID_FLASH\n"); break;
case VP_LINE_EVID_STARTPULSE:
QS_DEBUG("VP_LINE_EVID_STARTPULSE\n"); break;
case VP_LINE_EVID_DTMF_DIG:
QS_DEBUG("VP_LINE_EVID_DTMF_DIG\n"); break;
case VP_LINE_EVID_PULSE_DIG:
QS_DEBUG("VP_LINE_EVID_PULSE_DIG\n"); break;
case VP_LINE_EVID_MTONE:
QS_DEBUG("VP_LINE_EVID_MTONE\n"); break;
case VP_DEV_EVID_TS_ROLLOVER:
QS_DEBUG("VP_DEV_EVID_TS_ROLLOVER\n"); break;
default:
QS_DEBUG("INVALID (0x%x)\n", eventId); break;
}
} else if (eventCategory == VP_EVCAT_RESPONSE) {
switch (eventId) {
case VP_DEV_EVID_BOOT_CMP:
QS_DEBUG("VP_DEV_EVID_BOOT_CMP\n"); break;
case VP_LINE_EVID_LLCMD_TX_CMP:
QS_DEBUG("VP_LINE_EVID_LLCMD_TX_CMP\n"); break;
case VP_LINE_EVID_LLCMD_RX_CMP:
QS_DEBUG("VP_LINE_EVID_LLCMD_RX_CMP\n"); break;
case VP_DEV_EVID_DNSTR_MBOX:
QS_DEBUG("VP_DEV_EVID_DNSTR_MBOX\n"); break;
case VP_LINE_EVID_RD_OPTION:
QS_DEBUG("VP_LINE_EVID_RD_OPTION\n"); break;
case VP_LINE_EVID_RD_LOOP:
QS_DEBUG("VP_LINE_EVID_RD_LOOP\n"); break;
case VP_EVID_CAL_CMP:
QS_DEBUG("VP_EVID_CAL_CMP\n"); break;
case VP_EVID_CAL_BUSY:
QS_DEBUG("VP_EVID_CAL_BUSY\n"); break;
case VP_LINE_EVID_GAIN_CMP:
QS_DEBUG("VP_LINE_EVID_GAIN_CMP\n"); break;
case VP_DEV_EVID_DEV_INIT_CMP:
QS_DEBUG("VP_DEV_EVID_DEV_INIT_CMP\n"); break;
case VP_LINE_EVID_LINE_INIT_CMP:
QS_DEBUG("VP_LINE_EVID_LINE_INIT_CMP\n"); break;
case VP_DEV_EVID_IO_ACCESS_CMP:
QS_DEBUG("VP_DEV_EVID_IO_ACCESS_CMP\n"); break;
default:
QS_DEBUG("INVALID (0x%x)\n", eventId); break;
}
} else if (eventCategory == VP_EVCAT_TEST) {
switch (eventId) {
case VP_LINE_EVID_TEST_CMP:
QS_DEBUG("VP_LINE_EVID_TEST_CMP\n"); break;
case VP_LINE_EVID_DTONE_DET:
QS_DEBUG("VP_LINE_EVID_DTONE_DET\n"); break;
case VP_LINE_EVID_DTONE_LOSS:
QS_DEBUG("VP_LINE_EVID_DTONE_LOSS\n"); break;
case VP_DEV_EVID_STEST_CMP:
QS_DEBUG("VP_DEV_EVID_STEST_CMP\n"); break;
case VP_DEV_EVID_CHKSUM:
QS_DEBUG("VP_DEV_EVID_CHKSUM\n"); break;
default:
QS_DEBUG("INVALID (0x%x)\n", eventId); break;
}
} else if(eventCategory == VP_EVCAT_PROCESS) {
switch (eventId) {
case VP_LINE_EVID_MTR_CMP:
QS_DEBUG("VP_LINE_EVID_MTR_CMP\n"); break;
case VP_LINE_EVID_MTR_ABORT:
QS_DEBUG("VP_LINE_EVID_MTR_ABORT\n"); break;
case VP_LINE_EVID_CID_DATA:
QS_DEBUG("VP_LINE_EVID_CID_DATA\n"); break;
case VP_LINE_EVID_RING_CAD:
QS_DEBUG("VP_LINE_EVID_RING_CAD\n"); break;
case VP_LINE_EVID_GEN_TIMER:
QS_DEBUG("VP_LINE_EVID_GEN_TIMER\n"); break;
default:
QS_DEBUG("INVALID (0x%x)\n", eventId); break;
}
} else if(eventCategory == VP_EVCAT_FXO) {
switch (eventId) {
case VP_LINE_EVID_RING_ON:
QS_DEBUG("VP_LINE_EVID_RING_ON\n"); break;
case VP_LINE_EVID_RING_OFF:
QS_DEBUG("VP_LINE_EVID_RING_OFF\n"); break;
case VP_LINE_EVID_LIU:
QS_DEBUG("VP_LINE_EVID_LIU\n"); break;
case VP_LINE_EVID_LNIU:
QS_DEBUG("VP_LINE_EVID_LNIU\n"); break;
case VP_LINE_EVID_FEED_DIS:
QS_DEBUG("VP_LINE_EVID_FEED_DIS\n"); break;
case VP_LINE_EVID_FEED_EN:
QS_DEBUG("VP_LINE_EVID_FEED_EN\n"); break;
case VP_LINE_EVID_DISCONNECT:
QS_DEBUG("VP_LINE_EVID_DISCONNECT\n"); break;
case VP_LINE_EVID_RECONNECT:
QS_DEBUG("VP_LINE_EVID_RECONNECT\n"); break;
case VP_LINE_EVID_POLREV:
QS_DEBUG("VP_LINE_EVID_POLREV\n"); break;
case VP_LINE_EVID_POH:
QS_DEBUG("VP_LINE_EVID_POH\n"); break;
case VP_LINE_EVID_PNOH:
QS_DEBUG("VP_LINE_EVID_PNOH\n"); break;
default:
QS_DEBUG("INVALID (0x%x)\n", eventId); break;
}
} else {
QS_DEBUG("0x%x\n", eventId);
}
}
char *
MapStatus(
VpStatusType status)
{
int idx = 0;
static char buff[50];
static const char *strTable[VP_STATUS_NUM_TYPES] = {
"VP_STATUS_SUCCESS",
"VP_STATUS_FAILURE",
"VP_STATUS_FUNC_NOT_SUPPORTED",
"VP_STATUS_INVALID_ARG",
"VP_STATUS_MAILBOX_BUSY",
"VP_STATUS_ERR_VTD_CODE",
"VP_STATUS_OPTION_NOT_SUPPORTED",
"VP_STATUS_ERR_VERIFY",
"VP_STATUS_DEVICE_BUSY",
"VP_STATUS_MAILBOX_EMPTY",
"VP_STATUS_ERR_MAILBOX_DATA",
"VP_STATUS_ERR_HBI",
"VP_STATUS_ERR_IMAGE",
"VP_STATUS_IN_CRTCL_SECTN",
"VP_STATUS_DEV_NOT_INITIALIZED",
"VP_STATUS_ERR_PROFILE",
"VP_STATUS_INVALID_VOICE_STREAM",
"VP_STATUS_CUSTOM_TERM_NOT_CFG",
"VP_STATUS_DEDICATED_PINS",
"VP_STATUS_INVALID_LINE",
"VP_STATUS_LINE_NOT_CONFIG",
"VP_STATUS_ERR_SPI"
};
if (status < VP_STATUS_NUM_TYPES) {
idx = sprintf(&buff[idx], "(%s)", (char *)strTable[status]);
}
idx = sprintf(&buff[idx], " = %d", (uint16)status);
return buff;
}
/*******************************************************************************\
* Function: sig_handler
* handle the signal of "CTRL+C" and "kill -15" to end the RingingwithCID
\*******************************************************************************/
static void APITest_sig_handler(int sig)
{
quit_loop = true;
printf("%s: signal number: %d.\n", __FUNCTION__, sig);
return;
}
void DTMF_RingingwithCID(void)
{
uint8 channelId = 0;
VpLineCtxType *pLineCtx = &lineCtx[channelId];
uint8 cidLen;
uint8 initCidLen;
VpStatusType status;
cidLen = strlen(cidMessageDTMF);
/* We can initialize a maximum of 32 bytes */
if (cidLen >= 32) {
initCidLen = 32;
} else {
initCidLen = cidLen;
}
status = VpInitRing(pLineCtx, CR_CN, CID_DTMF);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpInitRing on channel %d: %s\n", channelId, MapStatus(status));
return;
}
/* Initialize up to 32 bytes of the CID data */
status = VpInitCid(pLineCtx, initCidLen, cidMessageDTMF);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpInitCid on channel %d: %s\n", channelId, MapStatus(status));
return;
}
/* Begin the ringing + CID cadence */
status = VpSetLineState(pLineCtx, VP_LINE_RINGING);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpSetLineState on channel %d: %s\n", channelId, MapStatus(status));
return;
}
}
void FSK_RingingwithCID(void)
{
uint8 channelId = 0;
VpLineCtxType *pLineCtx = &lineCtx[channelId];
uint8 cidLen;
uint8 initCidLen;
VpStatusType status;
cidLen = strlen(cidMessageFSK);
/* We can initialize a maximum of 32 bytes */
if (cidLen >= 32) {
initCidLen = 32;
} else {
initCidLen = cidLen;
}
/* Provide the ringing cadence and CID profiles */
status = VpInitRing(pLineCtx, CR_CN, CID_TYPE1_CN);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpInitRing on channel %d: %s\n", channelId, MapStatus(status));
return;
}
/* Initialize up to 32 bytes of the CID data */
status = VpInitCid(pLineCtx, initCidLen, cidMessageFSK);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpInitCid on channel %d: %s\n", channelId, MapStatus(status));
return;
}
/* Begin the ringing + CID cadence */
status = VpSetLineState(pLineCtx, VP_LINE_RINGING);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpSetLineState on channel %d: %s\n", channelId, MapStatus(status));
return;
}
}
void RingingwithCID(uint8 mode)
{
uint8 channelId = 0;
VpLineCtxType *pLineCtx = &lineCtx[channelId];
uint8 cidLen;
uint8 initCidLen;
VpStatusType status;
if(mode == 0) {
cidLen = strlen(cidMessageFSK);
LOG_OUT_D("%s:FSK CID.\n", __FUNCTION__);
}
else {
cidLen = strlen(cidMessageDTMF);
LOG_OUT_D("%s:DTMF CID.\n", __FUNCTION__);
}
/* We can initialize a maximum of 32 bytes */
if (cidLen >= 32) {
initCidLen = 32;
} else {
initCidLen = cidLen;
}
/* Provide the ringing cadence and CID profiles */
if(mode == 0)
status = VpInitRing(pLineCtx, CR_CN, CID_TYPE1_CN);
else
status = VpInitRing(pLineCtx, CR_CN, CID_DTMF);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpInitRing on channel %d: %s\n", channelId, MapStatus(status));
return;
}
/* Initialize up to 32 bytes of the CID data */
if(mode == 0)
status = VpInitCid(pLineCtx, initCidLen, cidMessageFSK);
else
status = VpInitCid(pLineCtx, initCidLen, cidMessageDTMF);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpInitCid on channel %d: %s\n", channelId, MapStatus(status));
return;
}
/* Begin the ringing + CID cadence */
status = VpSetLineState(pLineCtx, VP_LINE_RINGING);
if (status != VP_STATUS_SUCCESS) {
LOG_OUT_E("Error running VpSetLineState on channel %d: %s\n", channelId, MapStatus(status));
return;
}
}
pthread_t thread_stress_test_spi;
int on_stress_testing = TRUE;
extern VpDeviceIdType deviceId;
/* Read the revision and product code */
void MISLIC_read_RCNPCN(void)
{
uint8 readBuffer[16] = {0};
/* Read the revision and product code */
VpMpiCmd(deviceId, VP886_EC_GLOBAL, VP886_R_RCNPCN_RD, VP886_R_RCNPCN_LEN, &readBuffer[0]);
//if ((0x08 != readBuffer[0]) || (0x49 != readBuffer[1]))
{
printf("Revision code 0x%02X, product code 0x%02X\n", readBuffer[0], readBuffer[1]);
}
return;
}
static void MISLIC_test_lib_spi(void *arg)
{
while (on_stress_testing)
{
MISLIC_read_RCNPCN();
}
return;
}
void MISLIC_start_SPI_stress_test(void)
{
int rc = 0;
rc = pthread_create(&thread_stress_test_spi, NULL, (void *)&MISLIC_test_lib_spi, NULL);
if (rc < 0) {
fprintf(stderr,"%s: error creating thread_start!\n", __FUNCTION__);
}
return;
}
void MISLIC_stop_SPI_stress_test(void)
{
on_stress_testing = FALSE;
pthread_detach(thread_stress_test_spi);
return;
}
/*****************************************************************************************************/
static void APITest_MainLoop(void)
{
while (1)
{
usleep(5000);
MISLIC_APITest_HandleEvents();
switch(user_selection)
{
case 0:
VpSetLineState(&lineCtx[0], VP_LINE_ACTIVE);
printf("Stop Ringing.\n");
break;
case 1:
VpSetLineState(&lineCtx[0], VP_LINE_RINGING);
printf("Start Ringing.\n");
break;
case 2:
RingingwithCID(0);
printf("Ring with CID in FSK.\n");
break;
case 3:
RingingwithCID(1);
printf("Ring with CID in DTMF.\n");
break;
case 4:
MISLIC_stop_SPI_stress_test();
printf("Stop SPI stress test.\n");
break;
case 5:
MISLIC_start_SPI_stress_test();
printf("Start SPI stress test.\n");
break;
default:
break;
}
user_selection = 15;
if (quit_loop) {
printf("normal quit the APITest_MainLoop.\n");
return;
}
}
}
void MISLIC_APITest_Menu()
{
pthread_attr_t tattr;
const char *menu_items[] =
{
"Stop Ringing",
"Start Ringing",
"Ring with CID in FSK",
"Ring with CID in DTMF",
"Stop SPI stress test",
"Start SPI stress test",
NULL
};
/* install signal handler and begin to capture signal for close */
signal(SIGINT, APITest_sig_handler);
signal(SIGTERM, APITest_sig_handler);
/*Create thread to poll interrupts*/
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
pthread_create(&APITest_MainLoopTask, &tattr, (void *)APITest_MainLoop, NULL);
do
{
user_selection = get_menu_selection( display_menu("MISLIC API Test Menu", menu_items), 0);
printf("\n\n");
if (quit_loop) {
printf("normal quit the select loop.\n");
goto EXIT_APITEST;
}
}
while(user_selection != QUIT_MENU);
EXIT_APITEST:
//Cancel pooling thread
pthread_cancel(APITest_MainLoopTask);
}