⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mh_handset.c

📁 DSP 播放语音文件例子
💻 C
📖 第 1 页 / 共 4 页
字号:
    LEDOFF(LED_ID_RING);  }}/************************************************************************** * HandsetVMWI *   Turn on/off the VMWI on a given handset *     oLineNumber - line on which to set the VMWI *     bOn - 1=ON, 0=OFF **************************************************************************/void HandsetVMWI(OCTET oLineNumber,                  BOOL bOn){  HANDSET *pHandset = &pxHandset[oLineNumber-1];  if (!g_bHandsetStarted) return;    if ((!pHandset->bOffHook) &&      (pHandset->oPhoneState == HSTATE_ONHOOK_IDLE)) {    /* Start VMWI OSI state, pull line power low */    _HandsetStartStateSequence(oLineNumber, pSEQ_VMWI);  }  pHandset->oVMWIStatus = bOn?VMWI_TURN_ON:VMWI_TURN_OFF;}/************************************************************************** * HandsetGenerateTone *   Turn a given tone on or off. If bOn = ON, the currently active tone *   is switched off and the new tone dwTone is played locally. If bOn = OFF *   the tone dwTone is removed from the tone queue. If dwTone is currently *   playing, it will be switched off. It dwTone has been queued to play at *   a later stage, it will be removed from the tone queue. *     oLineNumber - Line on which to activate tone *     dwTone - tone to switch on/off. *     bOn - 0=OFF, 1=ON **************************************************************************/void HandsetGenerateTone(OCTET oLineNumber, DWORD dwTone, BOOL bOn){  HANDSET *pHandset = &pxHandset[oLineNumber-1];    if (!g_bHandsetStarted) return;#ifdef HOOKER  HandsetHookerSendToneEvent(oLineNumber, dwTone, bOn);#endif  /* Handle special tones (e.g. ring tone, CWT, VMWI etc...) */  switch (dwTone) {      /* Ring tones - handled differently */  case HANDSET_RING0: case HANDSET_RING1: case HANDSET_RING2:  case HANDSET_RING3: case HANDSET_RING4: case HANDSET_RING5:  case HANDSET_RING6: case HANDSET_RING7: case HANDSET_RING8:  case HANDSET_RING9:    if (!pHandset->bOffHook) {      if (bOn) {        /* Load the appropriate ring cadence pattern */        LoadRingCadencePattern(&(pHandset->xRingCadencePattern),dwTone);        pHandset->bFirstRing = TRUE;        pHandset->oRingPatternCount = 0;        pHandset->dwRingTimer = pHandset->xRingCadencePattern.wPatternDurations[0];                /* Make sure there is power on the line */        _HandsetLineVoltagePolarity(oLineNumber,1);        HandsetLinePower(oLineNumber,1);                /* Do we have CID info to display?*/        if (pHandset->pCID != NULL) {          _HandsetStartStateSequence(oLineNumber,pSEQ_RING_WITH_CID);        } else {           /* Before ring sequence starts, wait a short while (100ms) for CID info           * to arrive from the application */          _HandsetStartStateSequence(oLineNumber,pSEQ_RING_WITH_WAIT_FOR_CID);        }      }      else {        HandsetRinger(oLineNumber,OFF);        pHandset->bRinging = FALSE;        pHandset->bFirstRing = FALSE;        _HandsetSetState(oLineNumber,HSTATE_ONHOOK_IDLE,INDEFINITE);      }    }    break;      /* All tones, includes ring tone */  case AUDIO_TONE_ALL:    if (!bOn) {      if (pHandset->bRinging) {        _HandsetSetState(oLineNumber,HSTATE_ONHOOK_IDLE,INDEFINITE);        pHandset->bRinging = FALSE;        pHandset->bFirstRing = FALSE;      }      if (pHandset->bOffHook)        _HandsetSetState(oLineNumber,HSTATE_OFFHOOK_IDLE,INDEFINITE);    }    _HandsetPlayTone(oLineNumber,dwTone,bOn);    break;      /* Call waiting tone - need to start timer for subsequent CID info */  case AUDIO_CALLWAITING:  case AUDIO_CALLWAITING2:  case AUDIO_CALLWAITING3:  case AUDIO_CALLWAITING4:    if (bOn && pHandset->oPhoneState != HSTATE_OFFHOOK_CWT_ON) {      _HandsetSetState(oLineNumber,HSTATE_OFFHOOK_CWT_ON,500);      _HandsetPlayTone(oLineNumber,dwTone,bOn);    }    break;      default:    _HandsetPlayTone(oLineNumber,dwTone,bOn);    break;  }}#ifndef HANDSET_NO_CALLER_ID/************************************************************************** * HandsetDisplayCallerID *   Saves and prepares CID data for sending to handset *     oLineNumber - line number to send CID data to *     pxCID - CALLER_ID_INFO structure containing caller ID data * * NOTE: This *SHOULD* be called before HandsetGenerateTone(HANDSET_RING) *       if caller ID is to be accompanied with ringing **************************************************************************/void HandsetDisplayCallerID(OCTET oLineNumber, CALLER_ID_INFO *pxCID){  HANDSET *pHandset = &pxHandset[oLineNumber-1];  if (!g_bHandsetStarted) return;    if (pHandset->pCID != NULL) {    free(pHandset->pCID);  }    /* Copy and store CID info */  pHandset->pCID = (CALLER_ID_INFO *)calloc(1,sizeof(CALLER_ID_INFO));  pHandset->pCID->tmCallTime = pxCID->tmCallTime;  if (strlen(pxCID->pcCallerName))    strncpy(pHandset->pCID->pcCallerName,pxCID->pcCallerName,CALLERNAME_MAX_LENGTH);  if (strlen(pxCID->pcCallerNumber))    strncpy(pHandset->pCID->pcCallerNumber,pxCID->pcCallerNumber,CALLERNUMBER_MAX_LENGTH);    /* Is the handset off-hook and no call waiting tone is busy playing? If so,   * send CID data in off-hook transmission mode */  if (pHandset->oPhoneState == HSTATE_OFFHOOK_IDLE) {    _SendCallerIDData(oLineNumber,FALSE);    _HandsetSetState(oLineNumber,HSTATE_OFFHOOK_CWT_ON,500);  }    /* Check to see if ringing state sequence has started. This might happen   * if the ring signal arrives from the top application before the caller ID    * data is sent. Some ring sequences start with a 100ms general delay to    * wait for any caller ID info to arrive from the application, as they   * need to do special things to send CID before ringing starts. */    else if (!pHandset->bOffHook &&            pHandset->oPhoneState == HSTATE_WAITING_FOR_CID) {    /* CID arrived, start ring sequence with CID */    _HandsetStartStateSequence(oLineNumber,pSEQ_RING_WITH_CID);            }}/************************************************************************** * HandsetDisplayCallerIDWithCWT *   Saves and prepares CID data for sending to handset *   Also plays CWT before sending CID data *     oLineNumber - line number to send CID data to *     pxCID - CALLER_ID_INFO structure containing caller ID data **************************************************************************/void HandsetDisplayCallerIDWithCWT(OCTET oLineNumber, CALLER_ID_INFO *pxCID){  if (!g_bHandsetStarted) return;  HandsetGenerateTone(oLineNumber,AUDIO_CALLWAITING,1);  HandsetDisplayCallerID(oLineNumber,pxCID);}/************************************************************************** * HandsetStoreCallerID *   Append a caller ID info to the calls history list *     oLineNumber - line number to send CID data to *     pxCallerInfo - pointer to the incoming CALLER_ID_INFO **************************************************************************/void HandsetStoreCallerID(OCTET oLineNumber, CALLER_ID_INFO *pxCallerInfo){}#endif // HANDSET_NO_CALLER_ID/************************************************************************** * HandsetProcess *   Queries a handset for any events (hook events, DTMF events) * *   NOTE: This function should be called from within the main application *         loop (i.e. it should be called every 10ms). All timers in the *         handset state machine are thus assumed to clock every 10ms. * *   The following are returned to the calling application under the various *   scenarios: * *   HANDSET_HOOK_DOWN_EVENT:               [Returned by MediaHub and IPPhone]    *       Hookswitch has been pressed, may be start of "hit", "flash" or "true"  *       onhook event * *   HANDSET_ON_HOOK_EVENT:                 [Returned by MediaHub and IPPhone]    *       "True" long term on-hook event (i.e. not hook "hit" or "flash") * *   HANDSET_HIT_HOOK_EVENT:                [Returned by MediaHub and IPPhone]    *       Hookswitch has been lifted, but it's hook "hit" event  *       (on hook for < 200ms) * *   HANDSET_FLASH_HOOK_EVENT:              [Returned by MediaHub and IPPhone]    *       Hookswitch has been lifted, but it's hook "flash" event  *       (on hook for > 200ms and < 1100ms) * *   HANDSET_OFF_HOOK_EVENT:                [Returned by MediaHub and IPPhone]  *       Hookswitch has been lifted. It's a "True" long term off-hook event  *       (i.e. not part of hook "hit" or "flash") * *   HANDSET_DIAL_EVENT:                            [Returned by IPPhone only]  *       A number is to be dialled. This would be returned if the handset is  *       off hook and/or speakerphone mode is on. The number to redial is  *       returned in chKeyPressed. * *   HANDSET_OFF_HOOK_WITH_DIAL_EVENT:              [Returned by IPPhone only]  *       Same as HANDSET_OFF_HOOK_EVENT, but there is also a number to be  *       dialled at the same time. This would occur if REDIAL key pressed  *       while handset is on hook and speakerphone mode is off. The number  *       to dial is returned in chKeyPressed * *   HANDSET_KEY_DOWN_EVENT:                [Returned by MediaHub and IPPhone] *       Returned at start of a key press event. The key character is returned  *       in chKeyPressed. * *   HANDSET_KEY_UP_EVENT:                  [Returned by MediaHub and IPPhone] *       Returned at end of a key press event. The key character is returned  *       in chKeyPressed. * *   HANDSET_MODEM_TONE_EVENT:                     [Returned by MediaHub only] *       Returned when a modem tone (V.21) is detected. * *   HANDSET_FAX_TONE_EVENT:                       [Returned by MediaHub only] *       Returned when a fax tone (CNG) is detected. * *   HANDSET_ANSWER_TONE_EVENT:                    [Returned by MediaHub only] *       Returned when a modem answer tone is detected. * *   HANDSET_LONG_DURATION_DTMF_EVENT:      [Returned by MediaHub and IPPhone] *       Returned when a DTMF key is held down (or detected) for more than 2s. * *   HANDSET_NO_EVENT:                      [Returned by MediaHub and IPPhone] *       No handset activity * *       oLineNumber - Line number of query *       chKeyPressed - the key that was pressed, or the number that was *                      (re)dialled (returned) * *   This function also handles special key functions such as: *       Volume control buttons *       Speakerphone button *       Mute button *       Call review buttons (left/right) *       Call delete button *       Dial button *       Redial button *       DTMF buttons (store in redial string, play local DTMF tone) *       Mode button **************************************************************************/E_HANDSET_RETURN_VALUES HandsetProcess(OCTET oLineNumber,                                        unsigned char *chKeyPressed){  HANDSET *pHandset = &pxHandset[oLineNumber-1];  E_HANDSET_RETURN_VALUES eReturn = 0;  OCTET oHookState;    if (!g_bHandsetStarted || oLineNumber > g_oNumHandsetLines) {    return HANDSET_NO_EVENT;  }      /* Get hook state */  ioctl(g_iSlicFd, SLIC_IOCTL_GETHOOKSTATE, (OCTET)oLineNumber,         (BOOL*)&oHookState);    if (g_bPulseDial && pHandset->oPhoneState == HSTATE_OFFHOOK_IDLE) {    pHandset->oSamplingCount++;    pHandset->oCurrentPulseSample = oHookState;  }  #ifdef HOOKER  eReturn = HandsetHookerProcess(oLineNumber, chKeyPressed);  if (eReturn != HANDSET_NO_EVENT) {    return eReturn;  }#endif    /* Update the handset state */  if ((eReturn=_HandsetUpdateState(oLineNumber)) > 0) {    return eReturn;  }  #ifdef HANDSET_USEDISPLAY  /* Process menu & LCD */  if (--g_dwDisplayCounter == 0) {    _HandsetUpdateLCD();  }#endif // HANDSET_USEDISPLAY      /* First, process the hook state */  if (!pHandset->bOffHook && oHookState == 0) {    LONG lReturn = HANDSET_OFF_HOOK_EVENT;   /* Default unless hit or flash */        /* Check if flash hit */    if (pHandset->oPhoneState == HSTATE_ONHOOK_WAITING_FOR_FLASH) {      if((pHandset->dwStateTimer < FLASH_HOOK_TIMER) &&          (pHandset->dwStateTimer > (FLASH_HOOK_TIMER - 20))) {        /* 200ms not up yet. this is a hook hit - ignore */        lReturn = HANDSET_HIT_HOOK_EVENT;      } else if (pHandset->dwStateTimer <= (FLASH_HOOK_TIMER - 20)) {        /* Phone picked up during flash-timer countdown, therefore flash hook has occurred */        lReturn = HANDSET_FLASH_HOOK_EVENT;      }    }     #ifndef HANDSET_NO_CALLER_ID /* process Japanese caller ID */    if (pHandset->oPhoneState == HSTATE_ONHOOK_WAIT_FOR_CONNECT) {      _HandsetNextState(oLineNumber);      return 0;    }    else if (pHandset->oPhoneState == HSTATE_DELAY) {      pHandset->bRinging = FALSE;      pHandset->bFirstRing = FALSE;      return 0;    }    else if (pHandset->oPhoneState == HSTATE_ONHOOK_WAIT_FOR_DISCONNECT) {      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];      return 0;    }    else if(pHandset->oPhoneState == HSTATE_DELAYINDEF){      _HandsetNextState(oLineNumber);    }#endif        _ProcessOffHookEvent(oLineNumber);        if (g_bPulseDial) {      pHandset->oLastPulseSample = oHookState;      pHandset->oPulseCount = 0;    }        return lReturn;  }#ifndef HANDSET_NO_CALLER_ID  else if (pHandset->oPhoneState==HSTATE_ONHOOK_WAIT_FOR_DISCONNECT &&            oHookState==1) {    _HandsetNextState(oLineNumber);    return 0;  }#endif  else if (!g_bPulseDial && pHandset->bOffHook && oHookState == 1) {    /* Hookswitch has been pressed */    _ProcessOnHookEvent(oLineNumber);    return HANDSET_HOOK_DOWN_EVENT;  }    if (g_bPulseDial && pHandset->oPhoneState == HSTATE_OFFHOOK_IDLE) {    if (pHandset->oLastPulseSample == 0 && pHandset->oCurrentPulseSample == 1) {      pHandset->oSamplingCount = 1;    }    else if (pHandset->oLastPulseSample == 1 &&              pHandset->oCurrentPulseSample == 0) {      if (pHandset->oSamplingCount >= 4 && pHandset->oSamplingCount <= 8) {        pHandset->oPulseCount++;      }      pHandset->oSamplingCount = 1;    }    else if (pHandset->oLastPulseSample == 1 &&              pHandset->oCurrentPulseSample == 1 &&             pHandset->oSamplingCount > 10) {      /* Assume back on hook */      _ProcessOnHookEvent(oLineNumber);      return HANDSET_HOOK_DOWN_EVENT;    }    else if (pHandset->oLastPulseSample == 0 &&              pHandset->oCurrentPulseSample == 0 &&             pHandset->oSamplingCount > 7 && pHandset->oPulseCount > 0) {      /* Assume number has been completed */      if (pHandset->oPulseCount > 9) pHandset->oPulseCount = 0;      pHandset->oDtmfPressed = '0' + pHandset->oPulseCount;      pHandset->oDtmfStatus = 255;      pHandset->oPulseCount = 0;    }         pHandset->oLastPulseSample = pHandset->oCurrentPulseSample;  }    /* Check if any DTMFs have been detected */  if (pHandset->oDtmfPressed != 0xff) {    OCTET chKey = pHandset->oDtmfPressed;    *chKeyPressed = chKey;    pHandset->oDtmfPressed = 0xff;        switch(chKey) {    /* DTMF digit */    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    case '*': case '#': case 'A': case 'B': case 'C':    case 'D':      if (g_bPulseDial && pHandset->oDtmfStatus == 255) {        SYSLOG(LOG_DEBUG,"PULSE DIAL %c digit detected on line %d\n",chKey,oLineNumber);        return HANDSET_PULSE_DIAL_EVENT;      } else if (pHandset->oDtmfStatus == 0) {        /* The DTMF event has just been detected */        SYSLOG(LOG_DEBUG,"DTMF %d tone start detected on line %d\n",chKey,oLineNumber);        return HANDSET_KEY_DOWN_EVENT;      } else {        /* The DTMF event has stopped */        SYSLOG(LOG_DEBUG,"DTMF %d tone stop detected on line %d\n",chKey,oLineNumber);        return HANDSET_KEY_UP_EVENT;      }          /* Fax tone detected */    case 'F':      *chKeyPressed = 'X';   /* use 'X' to avoid conflict with flash hook 'F' */      SYSLOG(LOG_DEBUG,"Fax tone detected on line %d\n",oLineNumber);      return HANDSET_FAX_TONE_EVENT;          /* Modem tone detected */    case 'M':      SYSLOG(LOG_DEBUG,"Modem tone detected on line %d\n",oLineNumber);      return HANDSET_MODEM_TONE_EVENT;    /* Answer tone detected */    case 'R':      SYSLOG(LOG_DEBUG,"Answer tone detected on line %d\n",oLineNumber);      return HANDSET_ANSWER_TONE_EVENT;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -