📄 mh_handset.c
字号:
/************************************************************************** * _SendCallerIDData * Send caller ID data to a handset * oLineNumber - handset to send CID info to * bOnHook - method by which to send data (on-hook, or off-hook) **************************************************************************/#ifndef HANDSET_NO_CALLER_IDvoid _SendCallerIDData(OCTET oLineNumber, BOOL bOnHook){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; if (pHandset->pCID == NULL) { } else if (pHandset->bOffHook == bOnHook) { /* Make sure we are in correct hook state */ DEBUG(printf("Handset %d::Can't send caller ID data now\n",oLineNumber)); } else { OCTET* pcDirNumber = NULL; OCTET* pcCallerName = NULL; OCTET oAbsentDN = 0; OCTET oAbsentCN = 0; LONG eErr; DEBUG(printf("Handset %d::Trying to send caller ID data\n",oLineNumber)); /* switch slic into onhook TX (this is a high power dissipation mode so * use sparingly) */ _HandsetOnHookTx(oLineNumber, TRUE); if ((strcasecmp(pHandset->pCID->pcCallerNumber,"") == 0) || (_CheckStringIsNumber(pHandset->pCID->pcCallerNumber)) < 0) { oAbsentDN = 'O'; } else if (strcasecmp(pHandset->pCID->pcCallerNumber,"P") == 0) { oAbsentDN = 'P'; } else { pcDirNumber = pHandset->pCID->pcCallerNumber; } if (strcasecmp(pHandset->pCID->pcCallerName,"") == 0) { oAbsentCN = 'O'; } else if (strcasecmp(pHandset->pCID->pcCallerName,"P") == 0) { oAbsentCN = 'P'; } else { pcCallerName = pHandset->pCID->pcCallerName; } if ((eErr=AudioPlayCallerId(oLineNumber, bOnHook, pcDirNumber, pcCallerName, oAbsentDN, oAbsentCN, &(pHandset->pCID->tmCallTime))) != AUDIO_CHANNEL_MESSAGE_NOERR) { DEBUG(printf("Handset %d::CALLER_ID_START error=%ld\n",oLineNumber,eErr)); _HandsetOnHookTx(oLineNumber, FALSE); } /* Free the caller ID data after sending */ free(pHandset->pCID); pHandset->pCID = NULL; }}/************************************************************************** * _SendVMWIData * Send VMWI data to a handset * oLineNumber - handset to send VMWI info to * bOn - turn VMWI on/off (1=ON, 0=OFF) **************************************************************************/void _SendVMWIData(OCTET oLineNumber, BOOL bOn){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; /* Only send VMWI data if on hook and pre-VMWI silence has completed */ if (!pHandset->bOffHook) { /* switch slic into onhook TX (this is a high power dissipation mode so * use sparingly) */ _HandsetOnHookTx(oLineNumber, TRUE); AudioSendVMWI(oLineNumber, bOn); SYSLOG(LOG_INFO,"VMWI on line %d set to %s\n", oLineNumber, bOn?"ON":"OFF"); pHandset->oVMWIStatus = VMWI_CURRENT; } /* Line 1 message waiting has its own LED */ if ((oLineNumber == 1) && bOn) { LEDON(LED_ID_MESSAGE,LED_COLOR_ANY); } else { LEDOFF(LED_ID_MESSAGE); }}/************************************************************************** * _CallerIdCallBack * Callback from the audio caller ID subsystem * dwChannel - channel number * eStatus - CID channel status **************************************************************************/void _CallerIdCallBack(DWORD dwChannel, AUDIO_CALLER_ID_STATUS eStatus){ HANDSET *pHandset = &pxHandset[dwChannel];#ifndef HANDSET_NO_ONHOOKTX OCTET oLineNumber=((OCTET)dwChannel)+1;#endif if (eStatus == AUDIO_CALLER_ID_DONE && (pHandset->oPhoneState == HSTATE_ONHOOK_SENDING_CID || pHandset->oPhoneState == HSTATE_ONHOOK_SENDING_VMWI)) { /* switch to normal power mode */ _HandsetOnHookTx(oLineNumber, FALSE); pHandset->dwStateTimer = 1; }}#endif // HANDSET_NO_CALLER_ID/************************************************************************** * _DtmfCallBack * DTMF detection callback function * dwChannel - channel * cKey - DTMF (or Fax/modem event) that was detected * dwStatus - event started (0) or stopped (1) * dwTimeStamp - timestamp of event occurrence * nLevel - DTMF event volume **************************************************************************/void _DtmfCallBack(DWORD dwChannel, CHAR cKey, DWORD dwStatus, DWORD dwTimeStamp, SHORT nLevel){ /* Ignore DTMF if on hook */ if (pxHandset[dwChannel].bOffHook) { pxHandset[dwChannel].oDtmfPressed=cKey; pxHandset[dwChannel].oDtmfStatus=dwStatus; }}#ifdef HANDSET_USEDISPLAY/************************************************************************** * _HandsetUpdateLCD * Update the MH2 LCD **************************************************************************/void _HandsetUpdateLCD(void){ char chKey;#ifndef NO_VOXPROMT extern LONG PlayIPAddress(char *, DWORD);#endif // NO_VOXPROMPT g_dwDisplayCounter = 100; /* Update every second */#ifdef MEM_CHECK if (g_oDisplayMode==3) /* Update the memory usage display */ _DisplayMemInfo();#endif // MEM_CHECK /* Check if a key has been pressed */ if (read(g_iKeypadFd,&chKey,1) > 0) { switch (chKey) { case '1': if (g_oDisplayMode!=2) { HandsetClearDisplay(); _DisplayNetworkInfo(); } else { HandsetClearDisplay(); HandsetDisplayHandsetStatus(); }#ifndef NO_VOXPROMT PlayIPAddress(g_pcInfoString[0],TRUE); // send IP address#endif // NO_VOXPROMPT break; case '2':#ifdef MEM_CHECK if (g_oDisplayMode!=3) { HandsetClearDisplay(); _DisplayMemInfo(); } else { HandsetClearDisplay(); HandsetDisplayHandsetStatus(); }#endif // MEM_CHECK break; case '3': if (NULL != pHandsetDbgKeyCbk) (*pHandsetDbgKeyCbk)(); break; } }}#endif // HANDSET_USEDISPLAY/************************************************************************** * _HandsetUpdateState * Process handset state machine and update state if necessary * oLineNumber - line number to update **************************************************************************/E_HANDSET_RETURN_VALUES _HandsetUpdateState(OCTET oLineNumber){ HANDSET *pHandset = &pxHandset[oLineNumber-1]; /* Line 1 has a ring LED. Pulse during ringing */ if ((oLineNumber==1) && (pHandset->bRinging) && ((pHandset->oRingPatternCount & 0x01)==0)) { g_oRingLedState++; if (g_oRingLedState==1) { LEDON(LED_ID_RING, LED_COLOR_ANY); } else if (g_oRingLedState==3) { LEDOFF(LED_ID_RING); } else if (g_oRingLedState>4) { g_oRingLedState=0; } } /* Process the handset ring timer, if ringing */ if ((pHandset->bRinging) && (--pHandset->dwRingTimer == 0)) { /* Ring timer has expired */ if (++pHandset->oRingPatternCount < pHandset->xRingCadencePattern.oRingsPerCycle<<1) { /* the ring cycle has not yet ended */ if (pHandset->oRingPatternCount & 0x01) { /* If new ring count is odd, then ring has ended, stop ringer */ HandsetRinger(oLineNumber,0); } else { /* Silence has ended, start ring period */ HandsetRinger(oLineNumber,1); } } if (pHandset->oRingPatternCount == (pHandset->xRingCadencePattern.oRingsPerCycle<<1)-1) { /* The ring "ON" cycle has ended (the last ring of this cycle has just ended) */ /* Was it the first ring cycle ? And do we need to send CID data ? */ if ((pHandset->oPhoneState == HSTATE_ONHOOK_RINGING) && (pHandset->bFirstRing == TRUE) && (pHandset->pCID)) { /* There is caller ID info to send */ _HandsetNextState(oLineNumber); } } else if (pHandset->oRingPatternCount == pHandset->xRingCadencePattern.oRingsPerCycle<<1) { /* The entire ring cycle is over, prepare for next ring */ pHandset->oRingPatternCount = 0; pHandset->bFirstRing = FALSE; if (!pHandset->xRingCadencePattern.bRepeat) { /* Do not repeat cycle again */ pHandset->bRinging = FALSE; HandsetRinger(oLineNumber,0); _HandsetSetState(oLineNumber,HSTATE_ONHOOK_IDLE,INDEFINITE); } else { /* start first ring of next cycle */ HandsetRinger(oLineNumber,1); } } /* Start next pattern timer */ pHandset->dwRingTimer = pHandset->xRingCadencePattern.wPatternDurations[pHandset->oRingPatternCount]; } /* Process the handset state timer */ if (pHandset->dwStateTimer > 0 && pHandset->dwStateTimer != INDEFINITE) { if (--pHandset->dwStateTimer == 0) { /* The timer has expired, move to next state */ switch (pHandset->oPhoneState) { case HSTATE_ONHOOK_WAITING_FOR_FLASH: /* Flash timer expired, no flash hook occurred therefore on-hook state */ _HandsetSetState(oLineNumber,HSTATE_ONHOOK_IDLE,INDEFINITE); /* Notify top layer app that ON-HOOK event occurred */ return HANDSET_ON_HOOK_EVENT; case HSTATE_ONHOOK_BATTERY_REVERSAL: case HSTATE_ONHOOK_BATTERY_JP_REVERSAL: case HSTATE_DELAY: case HSTATE_ONHOOK_BATTERY_NORMAL: case HSTATE_ONHOOK_SENDING_CID: case HSTATE_ONHOOK_SENDING_VMWI: case HSTATE_ONHOOK_OSI_START: case HSTATE_ONHOOK_OSI_END: case HSTATE_ONHOOK_BRIEF_RING_START: case HSTATE_ONHOOK_BRIEF_RING_END: case HSTATE_WAITING_FOR_CID: _HandsetNextState(oLineNumber); break; case HSTATE_OFFHOOK_CWT_ON: /* Call waiting tone has completed, send offhook CID if any */#ifndef HANDSET_NO_CALLER_ID _SendCallerIDData(oLineNumber,FALSE);#endif // HANDSET_NO_CALLER_ID _HandsetSetState(oLineNumber,HSTATE_OFFHOOK_IDLE,INDEFINITE); break;#ifndef HANDSET_NO_CALLER_ID case HSTATE_ONHOOK_WAIT_FOR_CONNECT: /* No answer, start normal ringing */ memcpy(&(pHandset->xRingCadencePattern),&g_xJPRingCadences[1], sizeof(HANDSET_RING_CADENCE)); pHandset->bFirstRing = FALSE; pHandset->oRingPatternCount = 0; pHandset->xRingCadencePattern.wPatternDurations[0]/=10; pHandset->xRingCadencePattern.wPatternDurations[1]/=10; pHandset->dwRingTimer = pHandset->xRingCadencePattern.wPatternDurations[0]; _HandsetSetState(oLineNumber, HSTATE_ONHOOK_RINGING, INDEFINITE); break; case HSTATE_ONHOOK_WAIT_FOR_DISCONNECT: /* No response */ _HandsetSetState(oLineNumber, HSTATE_OFFHOOK_IDLE, INDEFINITE); break;#endif } } } return HANDSET_NO_EVENT;}/************************************************************************** * HANDSET API FUNCTIONS **************************************************************************//************************************************************************** * HandsetDisplayHandsetStatus * Displays handset status information on LCD **************************************************************************/void HandsetDisplayHandsetStatus(void){#ifdef HANDSET_USEDISPLAY char ucTempString[41] = {0}; int i; g_oDisplayMode=1; HandsetDisplayDateAndTime(g_tmTimeLastUpdate); HandsetDisplayString("--------------------",2); for (i=0;i<HANDSET_MAXLINES;i++) { sprintf(ucTempString,"%d: %s",i+1, pxHandset[i].bOffHook?"Off hook": (g_pcOnHookDisplayNumber[i]!=NULL?g_pcOnHookDisplayNumber[i]:"On hook")); HandsetDisplayString(ucTempString,3+i); }#endif // HANDSET_USEDISPLAY} /************************************************************************** * HandsetClearDisplay * Clears the display **************************************************************************/void HandsetClearDisplay(void){#ifdef HANDSET_USEDISPLAY OCTET oi; for (oi=1;oi<7;oi++) HandsetClearDisplayLine(oi); g_oDisplayMode = 0;#endif // HANDSET_USEDISPLAY}/************************************************************************** * HandsetDisplayString * Display string chString on the LCD * chString - string to display * oDisplayLineNumber - Line to display string on **************************************************************************/void HandsetDisplayString(char *chString, OCTET oDisplayLineNumber){#ifdef HANDSET_USEDISPLAY if (oDisplayLineNumber <= 6) { ioctl(g_iDisplayFd,DISPLAY_IOCTL_DISPLAY, (OCTET)(DISPLAY_ELEMENT_LINE1 + oDisplayLineNumber - 1), " ",(OCTET)0,(BOOL)FALSE); if (chString) { ioctl(g_iDisplayFd,DISPLAY_IOCTL_DISPLAY, (OCTET)(DISPLAY_ELEMENT_LINE1 + oDisplayLineNumber - 1), chString,(OCTET)0,(BOOL)FALSE); } }#else SYSLOG(LOG_DEBUG,"%s\n",chString);#endif // HANDSET_USEDISPLAY}/************************************************************************** * HandsetDisplayDateAndTime * Display time and date on the LCD display * tmTime - time structure containing date and time information **************************************************************************/void HandsetDisplayDateAndTime(struct tm tmTime){#ifdef HANDSET_USEDISPLAY char chString[31]={0}; BOOL bPM=FALSE; int iHour=tmTime.tm_hour; if (iHour>=12) { bPM=TRUE; iHour-=12; } if (iHour==0) { iHour=12; } sprintf(chString,"%02d:%02d%s %02d/%02d",iHour,tmTime.tm_min, bPM?"PM":"AM",tmTime.tm_mon+1,tmTime.tm_mday); if (g_oDisplayMode == 1) { HandsetDisplayString(chString,1); }#endif // HANDSET_USEDISPLAY}/************************************************************************** * HandsetLinePower * controls the line power on a given handset * oLineNumber - handset * bOn - 1 = turn power on (close loop) * 0 = turn power off (open loop) **************************************************************************/void HandsetLinePower(OCTET oLineNumber, BOOL bOn){ ioctl(g_iSlicFd, SLIC_IOCTL_LINEPOWER, (OCTET)oLineNumber, (BOOL)bOn);}/************************************************************************** * HandsetRinger * controls the ringer on a given handset * oLineNumber - handset ringer to control * bOn - 1 = turn ringer on * 0 = turn ringer off **************************************************************************/void HandsetRinger(OCTET oLineNumber, BOOL bOn){ ioctl(g_iSlicFd, SLIC_IOCTL_RING, (OCTET)oLineNumber, (BOOL)bOn); /* line 1 has ring/inuse LED */ if ((oLineNumber == 1) && !bOn) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -