📄 mh_handset.c
字号:
Pl/************************************************************************** * * mh_handset.c * * Media-hub handset API functions * * Copyright 2002 Netergy Microelectronics * **************************************************************************/#include <NNstyle.h>#include "flavor.h"#ifdef HANDSET_MH#include <syslog.h>#include <sys/types.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <time.h>#include <pthread.h>#include "gpioapi.h"#include "ledapi.h"#include "configapi.h"#include "ntpapi.h"#include "audioapi.h"#include "dllist.h"#include "callerid.h"#include "dev_aud.h"#include "handsetapi.h"#include "handset.h"#include "mh_defs.h"#include "handsethooker.h"#ifdef HANDSET_VODSLMH#include "shpotsspiapi.h"#else#include "slicapi.h"#endif // HANDSET_VODSLMH#ifdef HANDSET_USEDISPLAY#include "keypadapi.h"#include "displayapi.h"#endif // HANDSET_USEDISPLAY#ifdef HANDSET_PROFILE#include <profile.h>#endif // HANDSET_PROFILE/************************************************************************** * GLOBAL VARIABLES **************************************************************************//* Device driver file handles */int g_iSlicFd=-1;#ifdef HANDSET_USEDISPLAYint g_iKeypadFd=-1;int g_iDisplayFd=-1;#endif // HANDSET_USEDISPLAY/* Number of lines (slics) detected */extern OCTET g_oNumHandsetLines;BOOL g_bPulseDial = FALSE;/* Handset structures */HANDSET *pxHandset = NULL;/* Information strings */extern char *g_pcInfoString[];extern char **g_pcOnHookDisplayString; extern char **g_pcOnHookDisplayNumber;/* Composite Handset tones */extern HANDSET_TONE_CONFIG asHandsetToneConfig[];#ifdef HANDSET_USEDISPLAY/* Display mode */DWORD g_dwDisplayCounter = 100;OCTET g_oDisplayMode = 0;#endif // HANDSET_USEDISPLAY/* Clock globals */#define TIMEUPDATECOUNTDOWN (100)BOOL g_bDSTObserved=TRUE;struct tm g_tmTimeLastUpdate;int g_iTimeUpdateCountdown=TIMEUPDATECOUNTDOWN;LONG g_lTimeZone=-8*60; /* Pacific Time *//* Line 1 ring LED state */OCTET g_oRingLedState=0;/* callback function for the DbgKey */extern HANDSET_DBGKEY_CBK pHandsetDbgKeyCbk;BOOL g_bHandsetStarted = FALSE;/************************************************************************** * PRIVATE FUNCTION PROTOTYPES **************************************************************************/void _HandsetSetState(OCTET, E_HANDSET_PHONE_STATE, DWORD);void _ProcessOffHookEvent(OCTET);void _ProcessOnHookEvent(OCTET);void _SendCallerIDData(OCTET, BOOL);void _SendVMWIData(OCTET, BOOL);LONG _AudSetMicDevice(DWORD, DWORD);LONG _AudSetSpkrDevice(DWORD, DWORD);void _DtmfCallBack(DWORD, CHAR, DWORD, DWORD, SHORT);E_HANDSET_RETURN_VALUES _HandsetUpdateState(OCTET);void _DisplayNetworkInfo(void);void _HandsetUpdateLCD(void);#ifdef MEM_CHECKvoid _DisplayMemInfo(void);#endif // MEM_CHECK/************************************************************************** * PRIVATE FUNCTIONS **************************************************************************/#ifdef HANDSET_USEDISPLAY/************************************************************************** * _DisplayNetworkInfo * Displays pertinent network information on MH2 LCD **************************************************************************/void _DisplayNetworkInfo(void){ HandsetDisplayString(" NETWORK INFO ",1); HandsetDisplayString("--------------------",2); HandsetDisplayString(g_pcInfoString[0],3); HandsetDisplayString(g_pcInfoString[1],4); HandsetDisplayString(g_pcInfoString[2],5); g_oDisplayMode=2;}#endif // HANDSET_USEDISPLAY#ifdef MEM_CHECK/************************************************************************** * _DisplayMemInfo * Displays pertinent memory usage information on MH2 LCD **************************************************************************/void _DisplayMemInfo(void){#ifdef HANDSET_USEDISPLAY char ucTempString[31] = {0}; if (g_oDisplayMode != 3) { HandsetDisplayString(" MEMORY INFO ",1); HandsetDisplayString("--------------------",2); g_oDisplayMode = 3; } /* Heap base min */ sprintf(ucTempString,"HeapBaseMin: %07ld", (DWORD)GetHeapBaseMin()); HandsetDisplayString(ucTempString,3); /* Heap base max = (heap base min) + (malloc total max) */ sprintf(ucTempString,"HeapBaseMax: %07ld", (DWORD)(GetHeapBaseMin() + MallocGetTotalMax())); HandsetDisplayString(ucTempString,4); /* Malloc max */ sprintf(ucTempString,"MallocMax : %07ld", (DWORD)MallocGetTotalMax()); HandsetDisplayString(ucTempString,5); /* Malloc (NOT ACCURATE: 1s sampling) */ sprintf(ucTempString,"Malloc : %07ld", (DWORD)MallocGetTotal()); HandsetDisplayString(ucTempString,6);#endif // HANDSET_USEDISPLAY}#endif // MEM_CHECK/************************************************************************* * Special Cadence Structure for Japanese Phone *************************************************************************/HANDSET_RING_CADENCE g_xJPRingCadences[2]={ {1,1,{500,500,0,0,0,0,0,0}}, {1,1,{1000,2000,0,0,0,0,0,0}}};/************************************************************************** * _HandsetPlayTone * generates a tone on the given line * oLineNumber - handset to play tone on * dwTone - tone to play * bOn - 1 = turn tone on * 0 = turn tone off **************************************************************************/void _HandsetPlayTone(OCTET oLineNumber,DWORD dwTone,BOOL bOn){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; /* If a new tone is to be turned on, switch off the currently active tone first */ if ((bOn) && (dwTone != AUDIO_TONE_ALL)) { HandsetQueueTone(oLineNumber,pHandset->dwLastAudioTone,OFF); } /* Switch the new tone on/off */ HandsetQueueTone(oLineNumber,dwTone, bOn); /* save current tone status */ pHandset->dwLastAudioTone=dwTone;}/************************************************************************** * _HandsetStartStateSequence * Starts a sequence of states (state machine) * oLineNumber - handset to start sequence on * pStateSequence - sequence to start **************************************************************************/void _HandsetStartStateSequence(OCTET oLineNumber, STATE_SEQUENCE *pStateSequence){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; pHandset->pStateSequence = pStateSequence; pHandset->oStateIndex = 0; /* Start the ball rolling */ _HandsetSetState(oLineNumber, pHandset->pStateSequence[0].eState, pHandset->pStateSequence[0].dwDuration);}/************************************************************************** * _HandsetNextState * Move to the next state in the state machine sequence * oLineNumber - handset line number **************************************************************************/void _HandsetNextState(OCTET oLineNumber){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; if ((pHandset->oStateIndex == 0xFF) || (++pHandset->oStateIndex == SEQUENCE_SIZE) || (pHandset->pStateSequence[pHandset->oStateIndex].eState == 0)) { /* State sequence is finished, move to idle */ _HandsetSetState(oLineNumber, pHandset->bOffHook?HSTATE_OFFHOOK_IDLE:HSTATE_ONHOOK_IDLE, INDEFINITE); pHandset->oStateIndex = 0xFF; } else { _HandsetSetState(oLineNumber, pHandset->pStateSequence[pHandset->oStateIndex].eState, pHandset->pStateSequence[pHandset->oStateIndex].dwDuration); }}/************************************************************************** * _HandsetSetState * change the state of a handset * oLineNumber - handset to update * eState - new handset state * dwStateDuration - duration to stay in this state **************************************************************************/void _HandsetSetState(OCTET oLineNumber, E_HANDSET_PHONE_STATE eState, DWORD dwStateDuration){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; pHandset->oPhoneState = eState; pHandset->dwStateTimer = dwStateDuration/10; /* Set the new state */ switch(eState) { case HSTATE_OFFHOOK_IDLE: break; case HSTATE_ONHOOK_IDLE: /* Make sure line power is on whilst in ONHOOK_IDLE state */ _HandsetLineVoltagePolarity(oLineNumber,1); HandsetLinePower(oLineNumber,1); if (pHandset->oVMWIStatus != VMWI_CURRENT) { /* VMWI is not current and needs updating, start onhook VMWI send process */ _HandsetStartStateSequence(oLineNumber,pSEQ_VMWI); } break; case HSTATE_ONHOOK_OSI_START: HandsetLinePower(oLineNumber,0); break; case HSTATE_ONHOOK_OSI_END: HandsetLinePower(oLineNumber,1); break;#ifndef HANDSET_NO_CALLER_ID case HSTATE_ONHOOK_SENDING_CID: if (pHandset->pCID != NULL) { _SendCallerIDData(oLineNumber,TRUE); } else { pHandset->dwStateTimer = 0; } break; case HSTATE_ONHOOK_SENDING_VMWI: _SendVMWIData(oLineNumber,(pHandset->oVMWIStatus == VMWI_TURN_ON)); break;#endif // HANDSET_NO_CALLER_ID case HSTATE_ONHOOK_BATTERY_REVERSAL: _HandsetLineVoltagePolarity(oLineNumber,0); break; case HSTATE_ONHOOK_BATTERY_JP_REVERSAL: _HandsetLineVoltagePolarity(oLineNumber,0); memcpy(&(pHandset->xRingCadencePattern),&g_xJPRingCadences[0], sizeof(HANDSET_RING_CADENCE)); pHandset->bFirstRing = TRUE; pHandset->oRingPatternCount = 0; pHandset->xRingCadencePattern.wPatternDurations[0]/=10; pHandset->xRingCadencePattern.wPatternDurations[1]/=10; pHandset->dwRingTimer = pHandset->xRingCadencePattern.wPatternDurations[0]; break; case HSTATE_ONHOOK_BATTERY_NORMAL: _HandsetLineVoltagePolarity(oLineNumber,1); break; case HSTATE_ONHOOK_BRIEF_RING_START: HandsetRinger(oLineNumber,1); break; case HSTATE_ONHOOK_BRIEF_RING_END: HandsetRinger(oLineNumber,0); break; case HSTATE_ONHOOK_RINGING: if (pHandset->bRinging == FALSE) { HandsetRinger(oLineNumber,ON); pHandset->bRinging = TRUE; } break; default: break; } if (pHandset->dwStateTimer == 0) { /* This state does not require a timeout, move immediately to next state */ _HandsetNextState(oLineNumber); } }/************************************************************************** * _ProcessOffHookEvent * An off hook event has occurred. * oLineNumber - handset on which off hook event occurred **************************************************************************/void _ProcessOffHookEvent(OCTET oLineNumber){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; /* Unmute the input audio */ AudioUpdInputMute(oLineNumber, FALSE); #ifndef HANDSET_NO_CALLER_ID { LONG eErr; if ((eErr = AudioCancelCallerId(oLineNumber)) == AUDIO_CHANNEL_MESSAGE_NOERR) { DEBUG(printf("Handset %d::Onhook data send aborted\n",oLineNumber)); } }#endif // HANDSET_NO_CALLER_ID if (pHandset->pCID) { free(pHandset->pCID); pHandset->pCID = NULL; } SYSLOG(LOG_INFO,"Handset %d went off hook\n",oLineNumber); pHandset->bOffHook = TRUE; pHandset->bRinging = FALSE; pHandset->bFirstRing = FALSE; /* Change to off-hook idle state */ _HandsetSetState(oLineNumber,HSTATE_OFFHOOK_IDLE,INDEFINITE); #ifdef HANDSET_USEDISPLAY if (g_oDisplayMode==1) { char ucTempString[41]={0}; sprintf(ucTempString,"%d: Off hook",oLineNumber); HandsetDisplayString(ucTempString,oLineNumber+2); }#endif // HANDSET_USEDISPLAY /* Line 1 has a ring/inuse LED */ if (oLineNumber == 1) { LEDON(LED_ID_RING, LED_COLOR_ANY); }}/************************************************************************** * _ProcessOnHookEvent * An on hook event has occurred. * oLineNumber - handset on which on hook event occurred **************************************************************************/void _ProcessOnHookEvent(OCTET oLineNumber){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; SYSLOG(LOG_INFO,"Handset %d went on hook\n",oLineNumber); pHandset->bOffHook = FALSE; /* Mute the input audio (to avoid echo problems at other end) */ AudioUpdInputMute(oLineNumber, TRUE); /* Start flash hook timer state */ _HandsetSetState(oLineNumber, HSTATE_ONHOOK_WAITING_FOR_FLASH, FLASH_HOOK_TIMER*10); #ifdef HANDSET_USEDISPLAY if (g_oDisplayMode==1) { char ucTempString[21]={0}; sprintf(ucTempString,"%d: %s",oLineNumber, (g_pcOnHookDisplayNumber[oLineNumber-1]!=NULL?g_pcOnHookDisplayNumber[oLineNumber-1]:"On hook")); HandsetDisplayString(ucTempString,oLineNumber+2); }#endif // HANDSET_USEDISPLAY /* Line 1 has a ring/inuse LED */ if (oLineNumber == 1) { LEDOFF(LED_ID_RING); }}/************************************************************************** * _CheckStringIsNumber * Returns -1 if a string is not a numeric string ('0' - '9') * pcString - string to check **************************************************************************/LONG _CheckStringIsNumber(char *pcString){ int i; if (pcString == NULL) return -1; for (i=0;i<strlen(pcString);i++) { if (pcString[i] < '0' || pcString[i] > '9') return -1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -