1350 lines
37 KiB
C
Executable File
1350 lines
37 KiB
C
Executable File
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "cpr_types.h"
|
|
#include "cpr_memory.h"
|
|
#include "cpr_stdio.h"
|
|
#include "cpr_string.h"
|
|
#include "cpr_timers.h"
|
|
#include "cpr_ipc.h"
|
|
#include "debug.h"
|
|
#include "phone_debug.h"
|
|
#include "phntask.h"
|
|
#include "prot_configmgr.h"
|
|
#include "logger.h"
|
|
#include "logmsg.h"
|
|
#include "upgrade.h"
|
|
#include "dialplan.h"
|
|
#include "singly_link_list.h"
|
|
#include "ccsip_subsmanager.h"
|
|
#include "kpmlmap.h"
|
|
#include "dialplanint.h"
|
|
#include "ccapi.h"
|
|
#include "lsm.h"
|
|
#include "gsm.h"
|
|
#include "fsm.h"
|
|
#include "regmgrapi.h"
|
|
#include "ccsip_register.h"
|
|
|
|
#define PRIME_LINE_ID 1
|
|
cc_int32_t DpintDebug = 0;
|
|
static dp_data_t g_dp_int;
|
|
|
|
/* note that we do not allow file with size more than DIALPLAN_MAX_SIZE (8k) */
|
|
uint8_t dpLoadArea[DIALPLAN_MAX_SIZE - 1];
|
|
|
|
|
|
#define KPML_DEFAULT_DIALPLAN "<DIALTEMPLATE><TEMPLATE MATCH=\".\" Timeout=\"0\" User=\"Phone\"/></DIALTEMPLATE>"
|
|
|
|
#define DIAL_KEY 0x82
|
|
|
|
static void dp_check_dialplan(line_t line, callid_t call_id,
|
|
unsigned char digit);
|
|
static void dp_restart_dial_timer (line_t line, callid_t call_id, int timeout);
|
|
|
|
extern cprBuffer_t cc_get_msg_buf(int min_size);
|
|
extern cc_int32_t show_dialplan_cmd(cc_int32_t argc, const char *argv[]);
|
|
|
|
|
|
static void
|
|
dp_int_message (line_t line, callid_t call_id, char digit,
|
|
char *digit_str, boolean collect_more, void *tmr_data,
|
|
int msg_id, char *g_call_id, monitor_mode_t monitor_mode)
|
|
{
|
|
char fname[] = "dp_int_message";
|
|
dp_int_t *pmsg;
|
|
|
|
pmsg = (dp_int_t *) cc_get_msg_buf(sizeof(dp_int_t));
|
|
|
|
if (!pmsg) {
|
|
err_msg(get_debug_string(CC_NO_MSG_BUFFER), fname);
|
|
return;
|
|
}
|
|
|
|
pmsg->line = line;
|
|
pmsg->call_id = call_id;
|
|
pmsg->digit = digit;
|
|
if (digit_str) {
|
|
sstrncpy(pmsg->digit_str, digit_str, MAX_DIALSTRING);
|
|
}
|
|
pmsg->collect_more = collect_more;
|
|
pmsg->tmr_ptr = tmr_data;
|
|
if (digit_str) {
|
|
sstrncpy(pmsg->global_call_id, g_call_id, CC_GCID_LEN);
|
|
}
|
|
|
|
pmsg->monitor_mode = monitor_mode;
|
|
if (gsm_send_msg(msg_id, (cprBuffer_t) pmsg, sizeof(dp_int_t)) !=
|
|
CPR_SUCCESS) {
|
|
err_msg(get_debug_string(CC_SEND_FAILURE), fname);
|
|
}
|
|
}
|
|
|
|
void
|
|
dp_int_init_dialing_data (line_t line, callid_t call_id)
|
|
{
|
|
dp_int_message(line, call_id, 0, NULL, FALSE, NULL, DP_MSG_INIT_DIALING,
|
|
NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_dial_timeout (void *data)
|
|
{
|
|
DPINT_DEBUG(DEB_F_PREFIX"\n", DEB_F_PREFIX_ARGS(DIALPLAN, "dp_dial_timeout"));
|
|
dp_int_message(0, 0, 0, NULL, FALSE, &data, DP_MSG_DIGIT_TIMER, NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_int_update_key_string (line_t line, callid_t call_id, char *digits)
|
|
{
|
|
dp_int_message(line, call_id, 0, digits, FALSE, NULL, DP_MSG_DIGIT_STR,
|
|
NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_int_store_digit_string (line_t line, callid_t call_id, char* digit_str)
|
|
{
|
|
dp_int_message(line, call_id, 0, digit_str, FALSE, NULL, DP_MSG_STORE_DIGIT,
|
|
NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_int_update_keypress (line_t line, callid_t call_id, unsigned char digit)
|
|
{
|
|
dp_int_message(line, call_id, digit, NULL, FALSE,
|
|
NULL, DP_MSG_DIGIT, NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_int_dial_immediate (line_t line, callid_t call_id, boolean collect_more,
|
|
char *digit_str, char *g_call_id,
|
|
monitor_mode_t monitor_mode)
|
|
{
|
|
dp_int_message(line, call_id, 0, digit_str, collect_more, NULL,
|
|
DP_MSG_DIAL_IMMEDIATE, g_call_id, monitor_mode);
|
|
}
|
|
|
|
void
|
|
dp_int_do_redial (line_t line, callid_t call_id)
|
|
{
|
|
dp_int_message(line, call_id, 0, NULL, FALSE,
|
|
NULL, DP_MSG_REDIAL, NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_int_onhook (line_t line, callid_t call_id)
|
|
{
|
|
dp_int_message(line, call_id, 0, NULL, FALSE,
|
|
NULL, DP_MSG_ONHOOK, NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_int_offhook (line_t line, callid_t call_id)
|
|
{
|
|
dp_int_message(line, call_id, 0, NULL, FALSE,
|
|
NULL, DP_MSG_OFFHOOK, NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_int_update (line_t line, callid_t call_id, string_t called_num)
|
|
{
|
|
dp_int_message(line, call_id, 0, (char *) called_num, FALSE, NULL,
|
|
DP_MSG_UPDATE, NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
void
|
|
dp_int_cancel_offhook_timer (line_t line, callid_t call_id)
|
|
{
|
|
dp_int_message(line, call_id, 0, NULL, FALSE,
|
|
NULL, DP_MSG_CANCEL_OFFHOOK_TIMER, NULL, CC_MONITOR_NONE);
|
|
}
|
|
|
|
static void
|
|
dp_store_digit_string (line_t line, callid_t call_id, char *digit_str)
|
|
{
|
|
const char fname[] = "dp_store_digit_string";
|
|
|
|
if (g_dp_int.line != line && g_dp_int.call_id != call_id) {
|
|
return;
|
|
}
|
|
|
|
sstrncpy(g_dp_int.gDialed, digit_str, MAX_DIALSTRING);
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"stored digits = %s", DEB_F_PREFIX_ARGS(DIALPLAN, fname), &g_dp_int.gDialed[0]);
|
|
}
|
|
|
|
|
|
void
|
|
dp_store_digits (line_t line, callid_t call_id, unsigned char digit)
|
|
{
|
|
const char fname[] = "dp_store_digits";
|
|
short len;
|
|
|
|
if (g_dp_int.line != line && g_dp_int.call_id != call_id) {
|
|
return;
|
|
}
|
|
|
|
if (digit == BKSPACE_KEY) {
|
|
return;
|
|
}
|
|
|
|
g_dp_int.line = line;
|
|
g_dp_int.call_id = call_id;
|
|
|
|
len = (short) strlen(g_dp_int.gDialed);
|
|
if (len >= MAX_DIALSTRING-1)
|
|
{ // safety check to prevent going out of bounds
|
|
CCAPP_ERROR(DEB_F_PREFIX"Unexpected dialstring [%s] (length [%d] > max [%d]) received", DEB_F_PREFIX_ARGS(DIALPLAN, fname), g_dp_int.gDialed,
|
|
len, MAX_DIALSTRING);
|
|
return;
|
|
}
|
|
|
|
g_dp_int.gDialed[len] = digit;
|
|
g_dp_int.gDialed[len + 1] = 0;
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"digit = %c, dig_str = %s", DEB_F_PREFIX_ARGS(DIALPLAN, fname), digit,
|
|
&g_dp_int.gDialed[0]);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_check_plar_warmline()
|
|
*
|
|
* Parameters: line - line number
|
|
* call_id - call indentification
|
|
*
|
|
* Description: Check if the line is warmline or plar. Since digit is
|
|
* detected, cancel the warmline timer.
|
|
*
|
|
* Returns: boolean
|
|
*/
|
|
static boolean
|
|
dp_check_plar_warmline (line_t line, callid_t call_id)
|
|
{
|
|
/* Check the timeout (timeout==0 for plar) to make sure it is not warm line.
|
|
* If it is warm line then cancel the timer to stop sending a INV
|
|
*/
|
|
if (g_dp_int.empty_rewrite[0] && (g_dp_int.offhook_timeout == 0)) {
|
|
|
|
//plar
|
|
return (TRUE);
|
|
|
|
} else if (g_dp_int.empty_rewrite[0] && g_dp_int.offhook_timeout) {
|
|
|
|
//warm line
|
|
(void) cprCancelTimer(g_dp_int.dial_timer);
|
|
memset(g_dp_int.empty_rewrite, 0, sizeof(g_dp_int.empty_rewrite));
|
|
}
|
|
return (FALSE);
|
|
}
|
|
|
|
|
|
/*
|
|
* Function: dp_delete_last_digit
|
|
*
|
|
* Parameters:
|
|
* line_id : line identifier
|
|
* call_id : call identifier
|
|
* Description:
|
|
* remove last digit from dial buffer. tell UI to remove it from input box
|
|
*
|
|
*/
|
|
void
|
|
dp_delete_last_digit (line_t line_id, callid_t call_id)
|
|
{
|
|
int len;
|
|
|
|
/* remove the last digit from gDialed */
|
|
len = strlen(g_dp_int.gDialed);
|
|
if (len) {
|
|
g_dp_int.gDialed[len - 1] = 0;
|
|
}
|
|
|
|
/* tell ui to remove the digit from input box */
|
|
ui_delete_last_digit(line_id, call_id);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_update_keypress()
|
|
*
|
|
* Parameters: line - line number
|
|
* call_id - call indentification
|
|
* digit - collected digit
|
|
*
|
|
* Description: Dialplan interface function to pass the collected
|
|
* digits. This routine will source collected digits
|
|
* (including backspace) to dialplan and KPML.
|
|
* Digits are passed during connected state and dialing
|
|
* state.
|
|
*
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static void
|
|
dp_update_keypress (line_t line, callid_t call_id, unsigned char digit)
|
|
{
|
|
const char fname[] = "dp_update_keypress";
|
|
lsm_states_t lsm_state;
|
|
int skMask[MAX_SOFT_KEYS];
|
|
|
|
DEF_DEBUG(DEB_L_C_F_PREFIX"KEY .\n", DEB_L_C_F_PREFIX_ARGS(DP_API, line, call_id, fname) );
|
|
|
|
lsm_state = lsm_get_state(call_id);
|
|
|
|
if (lsm_state == LSM_S_NONE) {
|
|
DPINT_DEBUG(DEB_F_PREFIX"call not found\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
return;
|
|
}
|
|
|
|
/* If the call is in connected state, digits are DTMF key presses
|
|
* pass this to GSM and KPML module
|
|
*/
|
|
if (lsm_state == LSM_S_RINGOUT ||
|
|
lsm_state == LSM_S_CONNECTED || lsm_state == LSM_S_HOLDING) {
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"digit received in LSM state %s\n",
|
|
DEB_F_PREFIX_ARGS(DIALPLAN, fname), lsm_state_name(lsm_state));
|
|
cc_digit_begin(CC_SRC_GSM, g_dp_int.call_id, g_dp_int.line, digit);
|
|
if (!kpml_update_dialed_digits(line, call_id, digit)) {
|
|
kpml_quarantine_digits(line, call_id, digit);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (g_dp_int.line != line) {
|
|
DPINT_DEBUG(DEB_F_PREFIX"line %d does not match dialplan line %d\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname),
|
|
line, g_dp_int.line);
|
|
return;
|
|
}
|
|
|
|
if (dp_check_plar_warmline(line, call_id)) {
|
|
DPINT_DEBUG(DEB_F_PREFIX"warm line\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
return;
|
|
}
|
|
|
|
if (digit == 0) {
|
|
DPINT_DEBUG(DEB_F_PREFIX"digit is 0\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
return;
|
|
}
|
|
|
|
ui_control_feature(line, call_id, skMask, 1, FALSE);
|
|
|
|
|
|
/* if not in URL dialing mode pass it through kpml dialing
|
|
* to quarantine digits
|
|
*/
|
|
if (g_dp_int.url_dialing == FALSE) {
|
|
|
|
if (!kpml_update_dialed_digits(line, call_id, digit)) {
|
|
/*
|
|
* no valid subscription case:
|
|
* if user pressed backspace, we can approve the delete without waiting
|
|
* for any response.
|
|
*/
|
|
if (digit == BKSPACE_KEY) {
|
|
dp_delete_last_digit(line, call_id);
|
|
}
|
|
|
|
kpml_quarantine_digits(line, call_id, digit);
|
|
}
|
|
} else {
|
|
if (digit == BKSPACE_KEY) {
|
|
/* no kpml for URL; go ahead and approve the delete */
|
|
dp_delete_last_digit(line, call_id);
|
|
}
|
|
}
|
|
|
|
/* no further processing for back space key */
|
|
if (digit == BKSPACE_KEY) {
|
|
return;
|
|
}
|
|
|
|
/* Make sure that call is in dialing state
|
|
* if not then do not check the dial plan
|
|
*/
|
|
switch (lsm_state) {
|
|
case LSM_S_OFFHOOK:
|
|
|
|
dp_check_dialplan(line, call_id, digit);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* Function: dp_get_dialing_call_id()
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* Description: retun call_id of dialing call.
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static callid_t
|
|
dp_get_dialing_call_id (void)
|
|
{
|
|
return (g_dp_int.call_id);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_update_key_string()
|
|
*
|
|
* Parameters: line - line number
|
|
* call_id - call indentification
|
|
* digitstr - Pointer to collected digits
|
|
*
|
|
* Description: Dialplan interface function to pass the collected
|
|
* digits. This routine will source collected digits
|
|
* (including backspace) to dialplan and KPML.
|
|
* Digits are passed during connected state and dialing
|
|
* state.
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static void
|
|
dp_update_key_string (line_t line, callid_t call_id, char *digits)
|
|
{
|
|
short indx = 0;
|
|
|
|
/* Get dialing call id if the call id is null */
|
|
|
|
if (call_id == CC_NO_CALL_ID) {
|
|
|
|
call_id = dp_get_dialing_call_id();
|
|
}
|
|
|
|
while (digits[indx]) {
|
|
dp_update_keypress(line, call_id, digits[indx++]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function: dp_dial_timeout_event()
|
|
*
|
|
* Parameters: timer - timer pointer
|
|
*
|
|
* Description: Handles dial timeout for dialplan
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static void
|
|
dp_dial_timeout_event (void *data)
|
|
{
|
|
const char fname[] = "dp_dial_timeout_event";
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d call_id=%d dialed digits=%s\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname),
|
|
g_dp_int.line, g_dp_int.call_id, g_dp_int.gDialed);
|
|
|
|
|
|
/* if there is a timeout without dialing digit
|
|
* then do the onhook
|
|
*/
|
|
if (g_dp_int.empty_rewrite[0] != NUL) {
|
|
|
|
kpml_flush_quarantine_buffer(g_dp_int.line, g_dp_int.call_id);
|
|
|
|
cc_dialstring(CC_SRC_GSM,
|
|
g_dp_int.call_id, g_dp_int.line, g_dp_int.empty_rewrite);
|
|
} else if ((g_dp_int.gDialed[0] == NUL) &&
|
|
(g_dp_int.gDialplanDone == FALSE)) {
|
|
|
|
/* Go onhook if no digits are dialed. Dialplandone is checked to see
|
|
* if the timeout happens during KPML digit collection
|
|
*/
|
|
cc_onhook(CC_SRC_GSM, g_dp_int.call_id, g_dp_int.line, FALSE);
|
|
} else {
|
|
/* KPML subscription will not be rejected in this case.
|
|
* even though it is timeout which triggered invite
|
|
* remote party may have more digits to collect through
|
|
* Kpml
|
|
*/
|
|
kpml_flush_quarantine_buffer(g_dp_int.line, g_dp_int.call_id);
|
|
cc_dialstring(CC_SRC_GSM,
|
|
g_dp_int.call_id, g_dp_int.line, g_dp_int.gDialed);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function: dp_cancel_offhook_timer
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Description:
|
|
* called to cancel offhook timer.
|
|
|
|
* Returns: none
|
|
*/
|
|
void dp_cancel_offhook_timer (void)
|
|
{
|
|
if ((g_dp_int.gTimerType == DP_OFFHOOK_TIMER) && (g_dp_int.dial_timer)) {
|
|
(void) cprCancelTimer(g_dp_int.dial_timer);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function: dp_restart_dial_timer()
|
|
*
|
|
* Parameters: line - line number
|
|
* call_id - call indentification
|
|
* timeout - timeout value for the dial timer
|
|
*
|
|
* Description: Start dial timer
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static void
|
|
dp_restart_dial_timer (line_t line, callid_t call_id, int timeout)
|
|
{
|
|
const char fname[] = "dp_restart_dial_timer";
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d call_id=%d timeout=%u\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line,
|
|
call_id, timeout);
|
|
|
|
g_dp_int.timer_info.index.line = line;
|
|
g_dp_int.timer_info.index.call_id = call_id;
|
|
|
|
if (g_dp_int.dial_timer) {
|
|
(void) cprCancelTimer(g_dp_int.dial_timer);
|
|
|
|
(void) cprStartTimer(g_dp_int.dial_timer, timeout,
|
|
&g_dp_int.timer_info);
|
|
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function: dp_check_dialplan()
|
|
*
|
|
* Parameters: line - line number
|
|
* call_id - call indentification
|
|
* cursor - indicates number digits in the dial string
|
|
* strDigs - collected digit string.
|
|
*
|
|
* Description: Check dial plan with collected digits.
|
|
*
|
|
* Returns: None
|
|
*/
|
|
static void
|
|
dp_check_dialplan (line_t line, callid_t call_id, unsigned char digit)
|
|
{
|
|
const char fname[] = "dp_check_dialplan";
|
|
int timeout = DIAL_TIMEOUT;
|
|
DialMatchAction action;
|
|
vcm_tones_t tone;
|
|
lsm_states_t lsm_state;
|
|
|
|
/* if the dialing is done then don't
|
|
* do anything
|
|
*/
|
|
if (g_dp_int.gDialplanDone) {
|
|
DPINT_DEBUG(DEB_F_PREFIX"Dialplan Match Completed: line=%d call_id=%d digits=%d",
|
|
DEB_F_PREFIX_ARGS(DIALPLAN, fname), line, call_id, digit);
|
|
return;
|
|
}
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d call_id=%d digits=%s", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line,
|
|
call_id, &g_dp_int.gDialed[0]);
|
|
|
|
dp_store_digits(line, call_id, digit);
|
|
|
|
/* get current digit in GSM format */
|
|
if (digit == '*') {
|
|
digit = 0x0E;
|
|
} else if (digit == '#') {
|
|
digit = 0x0F;
|
|
} else {
|
|
digit = digit - '0';
|
|
}
|
|
|
|
/* see if we match any dial plans */
|
|
action =
|
|
MatchDialTemplate(g_dp_int.gDialed, line, &timeout, NULL, 0, NULL,
|
|
&tone);
|
|
|
|
switch (action) {
|
|
|
|
case DIAL_FULLPATTERN:
|
|
DPINT_DEBUG(DEB_F_PREFIX"Full pattern match\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
|
|
if (timeout <= 0) {
|
|
cc_dialstring(CC_SRC_GSM, g_dp_int.call_id, g_dp_int.line,
|
|
g_dp_int.gDialed);
|
|
/* flush collected digits. Invite has been sent */
|
|
kpml_flush_quarantine_buffer(line, call_id);
|
|
|
|
(void) cprCancelTimer(g_dp_int.dial_timer);
|
|
|
|
g_dp_int.gDialplanDone = TRUE;
|
|
return;
|
|
}
|
|
|
|
cc_digit_begin(CC_SRC_GSM, call_id, line, digit);
|
|
break;
|
|
|
|
case DIAL_IMMEDIATELY:
|
|
DPINT_DEBUG(DEB_F_PREFIX"Dial immediately\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
/*
|
|
* The user pressed the # key and the phone should dial immediately
|
|
*/
|
|
(void) cprCancelTimer(g_dp_int.dial_timer);
|
|
g_dp_int.gDialplanDone = TRUE;
|
|
|
|
cc_dialstring(CC_SRC_GSM, g_dp_int.call_id, g_dp_int.line,
|
|
g_dp_int.gDialed);
|
|
|
|
//kpml_set_subscription_reject(line, call_id);
|
|
|
|
kpml_flush_quarantine_buffer(line, call_id);
|
|
|
|
return;
|
|
|
|
case DIAL_GIVETONE:
|
|
DPINT_DEBUG(DEB_F_PREFIX"Give tone\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
|
|
/* we need new dial tone */
|
|
lsm_state = lsm_get_state(call_id);
|
|
|
|
if (lsm_state == LSM_S_NONE) {
|
|
DPINT_DEBUG(DEB_F_PREFIX"call not found\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
return;
|
|
}
|
|
|
|
(void)cc_call_action(call_id, LSM_NO_LINE, CC_ACTION_STOP_TONE, NULL);
|
|
vcmToneStart(tone, FALSE, CREATE_CALL_HANDLE(line, call_id), 0 /* group_id */,
|
|
0/* stream_id */, VCM_PLAY_TONE_TO_EAR);
|
|
break;
|
|
|
|
default:
|
|
DPINT_DEBUG(DEB_F_PREFIX"No match\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
cc_digit_begin(CC_SRC_GSM, call_id, line, digit);
|
|
break;
|
|
}
|
|
|
|
dp_restart_dial_timer(line, call_id, timeout * 1000);
|
|
g_dp_int.gTimerType = DP_INTERDIGIT_TIMER;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* Function: dp_get_kpml_state()
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Description: Function called to check if the KPML is enabled. If the KPML is
|
|
* enabled then function returns true. But under certain conditions like redial
|
|
* or speed dial (dial immediately) dialing is completed and phone does not expect
|
|
* any KPML subscriptions. So do not collect any more digits in this and UI state
|
|
* will be set to proceed and frozen. To facilitate this allo_proceed variable is
|
|
* added, if this is set to TRUE then function returns false (as if KPML is disabled).
|
|
* As mentioned earlier this is called for redial and dial immediate functions.
|
|
* Allow_proceed value is reset in this function, and dp_clear_dialing_data() function
|
|
*
|
|
* Returns: TRUE to indicate, more digits has to be collected
|
|
* FALSE to indicate no more digits to collect.
|
|
*/
|
|
boolean
|
|
dp_get_kpml_state (void)
|
|
{
|
|
if (g_dp_int.allow_proceed) {
|
|
|
|
g_dp_int.allow_proceed = FALSE;
|
|
return (FALSE);
|
|
|
|
} else {
|
|
|
|
return (kpml_get_state());
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function: dp_get_gdialed_digits()
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Description: Return dialed digits to the caller.
|
|
*
|
|
*
|
|
* Returns: none
|
|
*/
|
|
char *
|
|
dp_get_gdialed_digits (void)
|
|
{
|
|
const char fname[] = "dp_get_gdialed_digits";
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"Dialed digits:%s\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), g_dp_int.gDialed);
|
|
|
|
/* Digits are copied to Redial buffer after 180 is received
|
|
* after dp_update (). Afterthat gDialed buffer is cleared. So the dialed
|
|
* value is moved into gRedialed buffer
|
|
*/
|
|
|
|
if (g_dp_int.gDialed[0] != NUL) {
|
|
|
|
return (&g_dp_int.gDialed[0]);
|
|
}
|
|
|
|
return (&g_dp_int.gReDialed[0]);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_get_redial_line()
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* Description: returns redial line.
|
|
*
|
|
*
|
|
* Returns: none
|
|
*/
|
|
line_t
|
|
dp_get_redial_line (void)
|
|
{
|
|
return (g_dp_int.gRedialLine);
|
|
}
|
|
|
|
static void
|
|
dp_do_redial (line_t line, callid_t call_id)
|
|
{
|
|
const char fname[] = "dp_do_redial";
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d call_id=%d\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line, call_id);
|
|
|
|
if (line == 0) {
|
|
line = dp_get_redial_line();
|
|
}
|
|
//CSCsz63263, use prime line instead if last redialed line is unregistered
|
|
if(ccsip_is_line_registered(line) == FALSE) {
|
|
DPINT_DEBUG(DEB_F_PREFIX"line %d unregistered, use line %d instead \n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line,
|
|
PRIME_LINE_ID);
|
|
line = PRIME_LINE_ID;
|
|
if( ccsip_is_line_registered(line) == FALSE) {
|
|
DPINT_DEBUG(DEB_F_PREFIX" prime line %d unregistered\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line);
|
|
return;
|
|
}
|
|
}
|
|
if (g_dp_int.gReDialed[0] == NUL) {
|
|
DPINT_DEBUG(DEB_F_PREFIX"NO DIAL STRING line=%d call_id=%d\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line,
|
|
call_id);
|
|
|
|
return;
|
|
}
|
|
|
|
sstrncpy(g_dp_int.gDialed, g_dp_int.gReDialed, MAX_DIALSTRING);
|
|
|
|
g_dp_int.line = line;
|
|
|
|
g_dp_int.call_id = call_id;
|
|
|
|
g_dp_int.allow_proceed = TRUE;
|
|
|
|
/*
|
|
* If we are doing redial, then we won't be entering any more digits
|
|
*/
|
|
g_dp_int.gDialplanDone = TRUE;
|
|
|
|
(void) cprCancelTimer(g_dp_int.dial_timer);
|
|
|
|
kpml_set_subscription_reject(line, call_id);
|
|
|
|
kpml_flush_quarantine_buffer(line, call_id);
|
|
|
|
cc_dialstring(CC_SRC_GSM, call_id, line, &g_dp_int.gReDialed[0]);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_start_dialing()
|
|
*
|
|
* Parameters: line - line number
|
|
* call_id - call indentification
|
|
*
|
|
* Description: Start dialing and initilize dialing data.
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static void
|
|
dp_init_dialing_data (line_t line, callid_t call_id)
|
|
{
|
|
const char fname[] = "dp_init_dialing_data";
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d call_id=%d\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line, call_id);
|
|
|
|
g_dp_int.call_id = call_id;
|
|
g_dp_int.line = line;
|
|
g_dp_int.gDialplanDone = FALSE;
|
|
g_dp_int.url_dialing = FALSE;
|
|
g_dp_int.gTimerType = DP_NONE_TIMER;
|
|
|
|
memset(g_dp_int.gDialed, 0, sizeof(g_dp_int.gDialed));
|
|
|
|
/* get offhook timeout */
|
|
g_dp_int.offhook_timeout = DIAL_TIMEOUT;
|
|
|
|
config_get_value(CFGID_OFFHOOK_TO_FIRST_DIGIT_TIMER,
|
|
&g_dp_int.offhook_timeout,
|
|
sizeof(g_dp_int.offhook_timeout));
|
|
|
|
/* Flush any collected KPML digits on this line */
|
|
kpml_flush_quarantine_buffer(line, call_id);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_clear_dialing_data()
|
|
*
|
|
* Parameters: line - line number
|
|
* call_id - call indentification
|
|
*
|
|
* Description: This routine is called to stop and clean up dialing data.
|
|
*
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static void
|
|
dp_clear_dialing_data (line_t line, callid_t call_id)
|
|
{
|
|
const char fname[] = "dp_clear_dialing_data";
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d call_id=%d\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line, call_id);
|
|
|
|
g_dp_int.call_id = 0;
|
|
g_dp_int.line = 0;
|
|
g_dp_int.gDialplanDone = FALSE;
|
|
g_dp_int.allow_proceed = FALSE;
|
|
|
|
memset(g_dp_int.gDialed, 0, sizeof(g_dp_int.gDialed));
|
|
memset(g_dp_int.empty_rewrite, 0, sizeof(g_dp_int.empty_rewrite));
|
|
|
|
/* Stop interdigit timer */
|
|
(void) cprCancelTimer(g_dp_int.dial_timer);
|
|
|
|
/* Flush any collected KPML digits on this line */
|
|
//kpml_flush_quarantine_buffer (line, call_id);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_onhook
|
|
*
|
|
* Parameters: none
|
|
*
|
|
* Description: Function called to indicate onhook.
|
|
*
|
|
* Returns: none.
|
|
*/
|
|
static void
|
|
dp_onhook (line_t line, callid_t call_id)
|
|
{
|
|
if ((g_dp_int.line == line) && (g_dp_int.call_id == call_id)) {
|
|
dp_clear_dialing_data(line, call_id);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Function: dp_check_plar_line
|
|
*
|
|
* Parameters: line
|
|
*
|
|
* Description: Function returns true if the call and line is plar.
|
|
*
|
|
* Returns: TRUE - if plar configured and dialing completed.
|
|
*/
|
|
boolean
|
|
dp_check_for_plar_line (line_t line)
|
|
{
|
|
static char fname[] = "dp_check_for_plar_line";
|
|
DialMatchAction action;
|
|
char empty_rewrite[MAX_DIALSTRING];
|
|
char empty[1];
|
|
int timeout = 0;
|
|
|
|
empty[0] = '\0'; // This empty (i.e. "") pattern.
|
|
//Check dialplan to generate empty invite
|
|
action = MatchDialTemplate(empty, line, (int *) &timeout,
|
|
empty_rewrite, sizeof(empty_rewrite),
|
|
NULL, NULL);
|
|
|
|
if (action == DIAL_FULLMATCH) {
|
|
|
|
/* Plar line is only when timeout == 0 or else it is warm line
|
|
*/
|
|
if (timeout <= 0) {
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d PLAR line\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line);
|
|
return (TRUE);
|
|
|
|
}
|
|
}
|
|
return (FALSE);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_check_and_handle_plar_dialing
|
|
*
|
|
* Parameters: call_id and line
|
|
*
|
|
* Description: Responsible for checking if the line is plar line and
|
|
* if so it will dial plar DN.
|
|
*
|
|
* Returns: TRUE - if plar configured.
|
|
*/
|
|
boolean dp_check_and_handle_plar_dialing (line_t line, callid_t call_id)
|
|
{
|
|
DialMatchAction action;
|
|
char empty[1];
|
|
int timeout = 0;
|
|
|
|
timeout = g_dp_int.offhook_timeout;
|
|
|
|
empty[0] = '\0'; // This empty (i.e. "") pattern.
|
|
//Check dialplan to generate empty invite
|
|
action = MatchDialTemplate(empty, line, (int *) &timeout,
|
|
g_dp_int.empty_rewrite,
|
|
sizeof(g_dp_int.empty_rewrite), NULL, NULL);
|
|
|
|
|
|
if (timeout != (int) g_dp_int.offhook_timeout) {
|
|
// Dialplan has timeout value convert that in to msec.
|
|
g_dp_int.offhook_timeout = timeout * 1000;
|
|
}
|
|
if (action == DIAL_FULLMATCH) {
|
|
/* This is either hotline (i.e. plar) or warmline. Timeout is
|
|
* what tells us the difference.
|
|
*/
|
|
if (g_dp_int.offhook_timeout <= 0) {
|
|
|
|
g_dp_int.gDialplanDone = TRUE;
|
|
|
|
g_dp_int.allow_proceed = FALSE;
|
|
|
|
kpml_set_subscription_reject(g_dp_int.line, g_dp_int.call_id);
|
|
|
|
kpml_flush_quarantine_buffer(line, call_id);
|
|
|
|
cc_dialstring(CC_SRC_GSM, g_dp_int.call_id, g_dp_int.line,
|
|
g_dp_int.empty_rewrite);
|
|
|
|
// copy rewrite into dialed digits so that it will be logged in the placed calls history.
|
|
memcpy(g_dp_int.gDialed, g_dp_int.empty_rewrite, MAX_DIALSTRING);
|
|
return (TRUE);
|
|
|
|
}
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
/*
|
|
* Function: dp_offhook
|
|
*
|
|
* Parameters: none
|
|
*
|
|
* Description: Function called to indicate offhook.
|
|
*
|
|
* Returns: TRUE - if plar configured and dialing completed.
|
|
*/
|
|
boolean dp_offhook (line_t line, callid_t call_id)
|
|
{
|
|
const char fname[] = "dp_offhook";
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d call_id=%d\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), line, call_id);
|
|
|
|
/*
|
|
* If this line and call_id is same that means
|
|
* dialing has been initialized already. In addition, if
|
|
* gDialplanDone is true, there won't be any further digit entry
|
|
* so don't start the dial timer.
|
|
* Example case where remote-cc or speedial initates the call
|
|
* then caller will initialize the dp_int data structure. That
|
|
* also initilizes gDialpalnDone to True. So Do not restart the
|
|
* timer or process anything else in these cases.
|
|
*/
|
|
if ((g_dp_int.line == line) && (g_dp_int.call_id == call_id)) {
|
|
|
|
if (g_dp_int.gDialplanDone == FALSE) {
|
|
dp_restart_dial_timer(line, call_id, g_dp_int.offhook_timeout);
|
|
g_dp_int.gTimerType = DP_OFFHOOK_TIMER;
|
|
}
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
//Start offhook timer
|
|
dp_init_dialing_data(line, call_id);
|
|
|
|
if (dp_check_and_handle_plar_dialing(line, call_id) == TRUE) {
|
|
return(TRUE);
|
|
}
|
|
|
|
/*
|
|
* Only start the dial timer if dialing is not yet completed.
|
|
*/
|
|
if (g_dp_int.gDialplanDone == FALSE) {
|
|
dp_restart_dial_timer(line, call_id, g_dp_int.offhook_timeout);
|
|
g_dp_int.gTimerType = DP_OFFHOOK_TIMER;
|
|
}
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
/*
|
|
* Function: dp_dial_immediate
|
|
*
|
|
* Parameters:
|
|
* line_id - line number
|
|
* call_id - call indentification
|
|
*
|
|
* Description:
|
|
* called when the client wants DP module to stop matching and
|
|
* send the dialstring. This used for example when User pressed Dial Softkey.
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static void
|
|
dp_dial_immediate (line_t line, callid_t call_id, boolean collect_more,
|
|
char *digit_str, char *global_call_id,
|
|
monitor_mode_t monitor_mode)
|
|
{
|
|
const char fname[] = "dp_dial_immediate";
|
|
|
|
if (g_dp_int.line != line || g_dp_int.call_id != call_id) {
|
|
return;
|
|
}
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"line=%d call_id=%d dialed digits=%s\n",
|
|
DEB_F_PREFIX_ARGS(DIALPLAN, fname), line, call_id, g_dp_int.gDialed);
|
|
|
|
/* Do not dial anything else even if UI asks to do so, if the line is PLAR */
|
|
if (dp_check_and_handle_plar_dialing(line, call_id) == TRUE) {
|
|
return;
|
|
}
|
|
|
|
if (g_dp_int.dial_timer) {
|
|
(void) cprCancelTimer(g_dp_int.dial_timer);
|
|
}
|
|
|
|
|
|
if (g_dp_int.gDialplanDone) {
|
|
|
|
// if used with CCM, we should allow user to continue to input more digits
|
|
// after they've entered partial destination number onhook then press dial
|
|
if (sip_regmgr_get_cc_mode(line) == REG_MODE_CCM) {
|
|
return;
|
|
}
|
|
// KPML mode and user pressed DIAL softkey. So send 0x82 digit to KPML
|
|
if (!kpml_update_dialed_digits(line, call_id, (char)DIAL_KEY)) {
|
|
|
|
kpml_quarantine_digits(line, call_id, (char)DIAL_KEY);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* CTI applications can do a initcallreq without providing the dialstring
|
|
* In this case generate just the offhook event to GSM
|
|
*/
|
|
|
|
if (digit_str[0] == 0 && global_call_id[0] != 0) {
|
|
|
|
cc_offhook_ext(CC_SRC_GSM, call_id, line,
|
|
global_call_id, monitor_mode);
|
|
return;
|
|
}
|
|
|
|
g_dp_int.gDialplanDone = TRUE;
|
|
|
|
if (digit_str[0] != 0) {
|
|
sstrncpy(g_dp_int.gDialed, digit_str, MAX_DIALSTRING);
|
|
}
|
|
|
|
/* This case should not happen, as dial softkey is displayed only after the
|
|
* 1st digit. dp_dial_immediate function is called for dial softkey invocation.
|
|
*/
|
|
if (g_dp_int.gDialed[0] == 0) {
|
|
return;
|
|
|
|
} else {
|
|
g_dp_int.line = line;
|
|
g_dp_int.call_id = call_id;
|
|
|
|
kpml_flush_quarantine_buffer(line, call_id);
|
|
|
|
cc_dialstring_ext(CC_SRC_GSM, call_id, line, g_dp_int.gDialed,
|
|
global_call_id, monitor_mode);
|
|
}
|
|
|
|
if (collect_more == FALSE) {
|
|
/*
|
|
* Since no more digits are collected,
|
|
* allow proceed event to go through UI.
|
|
*/
|
|
g_dp_int.allow_proceed = TRUE;
|
|
|
|
kpml_set_subscription_reject(line, call_id);
|
|
|
|
kpml_flush_quarantine_buffer(line, call_id);
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* Function: dp_update
|
|
*
|
|
* Parameters: none
|
|
*
|
|
* Description: Function called to indicate alerting.
|
|
*
|
|
* Returns: none
|
|
*/
|
|
static void
|
|
dp_update (line_t line, callid_t call_id, string_t called_num)
|
|
{
|
|
uint32_t line_feature = 0;
|
|
|
|
config_get_line_value(CFGID_LINE_FEATURE, &line_feature,
|
|
sizeof(line_feature), line);
|
|
|
|
/* Do not store PLAR redial string.
|
|
*/
|
|
|
|
if (g_dp_int.gDialed[0] &&
|
|
(strcmp(g_dp_int.gDialed, CISCO_PLAR_STRING) != 0) &&
|
|
(strncmp(g_dp_int.gDialed, CISCO_BLFPICKUP_STRING, (sizeof(CISCO_BLFPICKUP_STRING) - 1)) != 0)) {
|
|
|
|
sstrncpy(g_dp_int.gReDialed, g_dp_int.gDialed, MAX_DIALSTRING);
|
|
g_dp_int.gRedialLine = line;
|
|
}
|
|
|
|
// fix bug CSCsm56180
|
|
if ((g_dp_int.line == line) && (g_dp_int.call_id == call_id)) {
|
|
dp_clear_dialing_data(line, call_id);
|
|
/* Clear kpml data and collected digits */
|
|
kpml_flush_quarantine_buffer(line, call_id);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Function: dp_reset()
|
|
*
|
|
* Parameters: none
|
|
*
|
|
* Description: Called during soft reset
|
|
*
|
|
* Returns: none
|
|
*/
|
|
void
|
|
dp_reset (void)
|
|
{
|
|
DPINT_DEBUG(DEB_F_PREFIX"Reset dp_int module\n", DEB_F_PREFIX_ARGS(DIALPLAN, "dp_reset"));
|
|
/* cleanup redial buffer */
|
|
memset(g_dp_int.gReDialed, 0, sizeof(g_dp_int.gReDialed));
|
|
}
|
|
|
|
/*
|
|
* Function: dp_init()
|
|
*
|
|
* Parameters: gsmMsgQueue - the msg queue for the GSM task. Used
|
|
* to tell CPR where to send the timer expiration
|
|
* msgs for the dialplan timer.
|
|
*
|
|
* Description: Initialize dialplan and KPML
|
|
*
|
|
*
|
|
* Returns: none
|
|
*/
|
|
void
|
|
dp_init (void *gsmMsgQueue)
|
|
{
|
|
|
|
g_dp_int.dial_timer =
|
|
cprCreateTimer("dial_timeout", GSM_DIAL_TIMEOUT_TIMER, TIMER_EXPIRATION,
|
|
(cprMsgQueue_t) gsmMsgQueue);
|
|
|
|
}
|
|
|
|
/*
|
|
* Function: dp_shutdown()
|
|
*
|
|
* Parameters: none
|
|
*
|
|
* Description: shutdown dialplan and cleanup memory
|
|
*
|
|
*
|
|
* Returns: none
|
|
*/
|
|
void
|
|
dp_shutdown (void)
|
|
{
|
|
if (g_dp_int.dial_timer != NULL) {
|
|
(void)cprDestroyTimer(g_dp_int.dial_timer);
|
|
g_dp_int.dial_timer = NULL;
|
|
}
|
|
FreeDialTemplates();
|
|
}
|
|
|
|
/*
|
|
* Function: dp_init_template
|
|
*
|
|
* Parameters: maxSize - maximum size of the dialplan
|
|
*
|
|
* Description: initialize dialplan template from downloaded file
|
|
* This is triggered by Adapter module when it triggers download of DP.
|
|
*
|
|
*/
|
|
int dp_init_template(const char * dial_plan_string, int length) {
|
|
static const char fname[] = "dp_init_template";
|
|
char *TemplateData = (char *) &dpLoadArea;
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"Reading Dialplan string. Length=[%d]\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), length);
|
|
|
|
|
|
/* Clear existing dialplan templates before building a new one */
|
|
FreeDialTemplates();
|
|
memset(dpLoadArea, 0, sizeof(dpLoadArea));
|
|
|
|
//Copy over data
|
|
memcpy (dpLoadArea, dial_plan_string, length);
|
|
|
|
if (length == 0 || ParseDialTemplate(TemplateData) == FALSE) {
|
|
|
|
if (kpml_get_state()) {
|
|
|
|
/**
|
|
* There is a error in the parsing so set the default dialplan when KPML is enabled
|
|
*/
|
|
DPINT_DEBUG(DEB_F_PREFIX"Loading Default Dialplan with KPML enabled",
|
|
DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
memcpy(dpLoadArea, (const char *) KPML_DEFAULT_DIALPLAN,
|
|
sizeof(KPML_DEFAULT_DIALPLAN));
|
|
length = sizeof(KPML_DEFAULT_DIALPLAN);
|
|
TemplateData[length] = '\00';
|
|
(void) ParseDialTemplate(TemplateData);
|
|
} else {
|
|
/**
|
|
* There is a error either in parsing so release any parsed dialplan structures
|
|
*/
|
|
DPINT_DEBUG(DEB_F_PREFIX"Loading Default Dialplan with KPML disabled",
|
|
DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
FreeDialTemplates();
|
|
}
|
|
|
|
|
|
return (-1);
|
|
}
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"Successfully Parsed Dialplan. \n", DEB_F_PREFIX_ARGS(DIALPLAN, fname));
|
|
return (0);
|
|
}
|
|
|
|
char *
|
|
dp_get_msg_string (uint32_t cmd)
|
|
{
|
|
switch (cmd) {
|
|
|
|
case DP_MSG_INIT_DIALING:
|
|
return ("DP_MSG_INIT_DIALING");
|
|
|
|
case DP_MSG_DIGIT_TIMER:
|
|
return ("DP_MSG_DIGIT_TIMER");
|
|
|
|
case DP_MSG_DIGIT_STR:
|
|
return ("DP_MSG_DIGIT_STR");
|
|
|
|
case DP_MSG_STORE_DIGIT:
|
|
return ("DP_MSG_STORE_DIGIT");
|
|
|
|
case DP_MSG_DIGIT:
|
|
return ("DP_MSG_DIGIT");
|
|
|
|
case DP_MSG_DIAL_IMMEDIATE:
|
|
return ("DP_MSG_DIAL_IMMEDIATE");
|
|
|
|
case DP_MSG_REDIAL:
|
|
return ("DP_MSG_REDIAL");
|
|
|
|
case DP_MSG_ONHOOK:
|
|
return ("DP_MSG_ONHOOK");
|
|
|
|
case DP_MSG_OFFHOOK:
|
|
return ("DP_MSG_OFFHOOK");
|
|
|
|
case DP_MSG_CANCEL_OFFHOOK_TIMER:
|
|
return ("DP_MSG_CANCEL_OFFHOOK_TIMER");
|
|
|
|
|
|
case DP_MSG_UPDATE:
|
|
return ("DP_MSG_UPDATE");
|
|
|
|
default:
|
|
return ("DP_MSG_UNKNOWN_CMD");
|
|
}
|
|
}
|
|
|
|
void
|
|
dp_process_msg (uint32_t cmd, void *msg)
|
|
{
|
|
static const char fname[] = "dp_process_msg";
|
|
dp_int_t *dp_int_msg = (dp_int_t *) msg;
|
|
|
|
DPINT_DEBUG(DEB_F_PREFIX"cmd= %s\n", DEB_F_PREFIX_ARGS(DIALPLAN, fname), dp_get_msg_string(cmd));
|
|
|
|
switch (cmd) {
|
|
|
|
case DP_MSG_INIT_DIALING:
|
|
dp_init_dialing_data(dp_int_msg->line, dp_int_msg->call_id);
|
|
break;
|
|
|
|
case DP_MSG_DIGIT_TIMER:
|
|
dp_dial_timeout_event(dp_int_msg->tmr_ptr);
|
|
break;
|
|
|
|
case DP_MSG_DIGIT_STR:
|
|
dp_update_key_string(dp_int_msg->line, dp_int_msg->call_id,
|
|
&(dp_int_msg->digit_str[0]));
|
|
break;
|
|
|
|
case DP_MSG_STORE_DIGIT:
|
|
dp_store_digit_string(dp_int_msg->line, dp_int_msg->call_id,
|
|
&(dp_int_msg->digit_str[0]));
|
|
break;
|
|
|
|
case DP_MSG_DIGIT:
|
|
dp_update_keypress(dp_int_msg->line, dp_int_msg->call_id,
|
|
dp_int_msg->digit);
|
|
break;
|
|
|
|
case DP_MSG_DIAL_IMMEDIATE:
|
|
dp_dial_immediate(dp_int_msg->line, dp_int_msg->call_id,
|
|
dp_int_msg->collect_more, &(dp_int_msg->digit_str[0]),
|
|
&(dp_int_msg->global_call_id[0]),
|
|
dp_int_msg->monitor_mode);
|
|
break;
|
|
|
|
case DP_MSG_REDIAL:
|
|
dp_do_redial(dp_int_msg->line, dp_int_msg->call_id);
|
|
break;
|
|
|
|
case DP_MSG_ONHOOK:
|
|
dp_onhook(dp_int_msg->line, dp_int_msg->call_id);
|
|
break;
|
|
|
|
case DP_MSG_OFFHOOK:
|
|
(void) dp_offhook(dp_int_msg->line, dp_int_msg->call_id);
|
|
break;
|
|
|
|
case DP_MSG_CANCEL_OFFHOOK_TIMER:
|
|
dp_cancel_offhook_timer();
|
|
break;
|
|
|
|
case DP_MSG_UPDATE:
|
|
dp_update(dp_int_msg->line, dp_int_msg->call_id,
|
|
&(dp_int_msg->digit_str[0]));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|