Add option to give numbers or ranges to complete en-block dialing
This commit is contained in:
parent
887aaddeee
commit
f2500899b8
|
@ -104,6 +104,12 @@ static void print_help()
|
|||
printf(" Enable en-block dialing, to collect number before setup. The value\n");
|
||||
printf(" given is the number of seconds to wait for more digits to be dialed.\n");
|
||||
printf(" (default = %d)\n", enblock);
|
||||
printf(" -D --dial-hint xxxx | xxxx-yyyy\n");
|
||||
printf(" The given one or multpiple hits for numbers with a fixed length. This\n");
|
||||
printf(" can be a single number or a range of number. If a range is given, xxxx\n");
|
||||
printf(" and yyyy must have equal length. If one of the given numbers are dialed,\n");
|
||||
printf(" the en-block dialing is complete and there is no need to wait for the\n");
|
||||
printf(" timeout.\n");
|
||||
printf(" --recall\n");
|
||||
printf(" Enable recall / call waiting. (disabled by default)\n");
|
||||
printf(" -R --ringing-type-incoming <type>\n");
|
||||
|
@ -166,6 +172,7 @@ static void add_options(void)
|
|||
option_add(OPT_TX_CID_BELL, "cid-bell", 0);
|
||||
option_add(OPT_TX_CID_DTMF, "cid-dtmf", 1);
|
||||
option_add(OPT_TX_ENBLOCK, "enblock", 1);
|
||||
option_add('D', "dial-hint", 1);
|
||||
option_add(OPT_TX_RECALL, "recall", 0);
|
||||
option_add(OPT_TX_RING_I, "ringing-type-incoming", 1);
|
||||
option_add(OPT_TX_RING_H, "ringing-type-hold", 1);
|
||||
|
@ -245,6 +252,13 @@ static int handle_options(int short_option, int argi, char **argv)
|
|||
case OPT_TX_RECALL:
|
||||
recall = 1;
|
||||
break;
|
||||
case 'D':
|
||||
rc = add_dial_hint(argv[argi]);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Given dial hint '%s' is not valid, please use -h for help.\n", argv[argi]);
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
case OPT_TX_RING_I:
|
||||
if (ringing_type_incoming_num == SUBSCRIBER_MAX) {
|
||||
fprintf(stderr, "Cannot define more than %d ringing types.\n", SUBSCRIBER_MAX);
|
||||
|
@ -425,6 +439,8 @@ error:
|
|||
pstn_destroy(pstn_ep);
|
||||
}
|
||||
|
||||
purge_dial_hints();
|
||||
|
||||
options_free();
|
||||
|
||||
/* exit fm */
|
||||
|
|
120
src/pstn/pstn.c
120
src/pstn/pstn.c
|
@ -159,6 +159,112 @@ static const char *timer_ident_name(enum timer_ident ident)
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* dial hints
|
||||
*/
|
||||
|
||||
static struct dial_hint *dial_hints = NULL;
|
||||
|
||||
int add_dial_hint(const char *arg)
|
||||
{
|
||||
struct dial_hint *hint;
|
||||
int i, dash;
|
||||
|
||||
hint = calloc(1, sizeof(*hint));
|
||||
if (!hint)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0, dash = -1; arg[i]; i++) {
|
||||
if (arg[i] == '-') {
|
||||
/* only single dash is allowed */
|
||||
if (dash >= 0)
|
||||
goto error;
|
||||
dash = i;
|
||||
continue;
|
||||
}
|
||||
/* only digits 0..9 are allowd */
|
||||
if (arg[i] < '0' || arg[i] > '9')
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dash < 0) {
|
||||
/* number must have at least one digit */
|
||||
if (i < 1)
|
||||
goto error;
|
||||
hint->length = i;
|
||||
hint->from = calloc(1, i + 1);
|
||||
if (!hint->from)
|
||||
goto error;
|
||||
strcpy(hint->from, arg);
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Added dial hint '%s'\n", hint->from);
|
||||
} else {
|
||||
/* both numbers must have same lenth */
|
||||
if (dash != i - dash - 1)
|
||||
goto error;
|
||||
/* there must be digits at all */
|
||||
if (dash < 1)
|
||||
goto error;
|
||||
hint->length = dash;
|
||||
hint->from = calloc(1, dash + 1);
|
||||
if (!hint->from)
|
||||
goto error;
|
||||
strncpy(hint->from, arg, dash);
|
||||
hint->to = calloc(1, dash + 1);
|
||||
if (!hint->to)
|
||||
goto error;
|
||||
strcpy(hint->to, arg + dash + 1);
|
||||
/* second string must be greater than first string */
|
||||
if (strcmp(hint->from, hint->to) > 0)
|
||||
goto error;
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Added dial hint '%s' - '%s'\n", hint->from, hint->to);
|
||||
}
|
||||
|
||||
hint->next = dial_hints;
|
||||
dial_hints = hint;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(hint->from);
|
||||
free(hint->to);
|
||||
free(hint);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int check_dial_hint(const char *number)
|
||||
{
|
||||
struct dial_hint *hint;
|
||||
size_t length = strlen(number);
|
||||
|
||||
for (hint = dial_hints; hint; hint = hint->next) {
|
||||
if (hint->length != length)
|
||||
continue;
|
||||
if (hint->from && !hint->to) {
|
||||
if (strncmp(number, hint->from, hint->length) == 0)
|
||||
return 1;
|
||||
}
|
||||
if (hint->from && hint->to) {
|
||||
if (strncmp(number, hint->from, hint->length) >= 0
|
||||
&& strncmp(number, hint->to, hint->length) <= 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void purge_dial_hints(void)
|
||||
{
|
||||
struct dial_hint *hint;
|
||||
|
||||
while ((hint = dial_hints)) {
|
||||
dial_hints = hint->next;
|
||||
free(hint->from);
|
||||
free(hint->to);
|
||||
free(hint);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Endpoint instance
|
||||
*/
|
||||
|
@ -521,7 +627,7 @@ void recv_dtmf(void *priv, char digit, dtmf_meas_t __attribute__((unused)) *meas
|
|||
/* if we are receiving digits en block */
|
||||
if (pstn->call[PSTN_CALL_ACTIVE]->state == CALL_STATE_ENBLOCK) {
|
||||
if (digit == '#') {
|
||||
PDEBUG(DTEL, DEBUG_DEBUG, "Number is complete, send setup\n");
|
||||
PDEBUG(DTEL, DEBUG_DEBUG, "Digit '#' received, number is complete, send setup\n");
|
||||
/* setup (en block) */
|
||||
setup_ind(pstn, PSTN_CALL_ACTIVE, pstn->dialing, 1);
|
||||
return;
|
||||
|
@ -531,6 +637,12 @@ void recv_dtmf(void *priv, char digit, dtmf_meas_t __attribute__((unused)) *meas
|
|||
char called[2] = { digit, '\0' };
|
||||
strncat(pstn->dialing, called, sizeof(pstn->dialing) - 1);
|
||||
PDEBUG(DTEL, DEBUG_DEBUG, "Appending digit, so dial string is now: '%s'.\n", pstn->dialing);
|
||||
if (check_dial_hint(pstn->dialing)) {
|
||||
PDEBUG(DTEL, DEBUG_DEBUG, "Number in list of dial hints received, number is complete, send setup\n");
|
||||
/* setup (en block) */
|
||||
setup_ind(pstn, PSTN_CALL_ACTIVE, pstn->dialing, 1);
|
||||
return;
|
||||
}
|
||||
/* start dial timer */
|
||||
timer_on(pstn, (double)pstn->enblock, TIMER_IDENT_DIALING);
|
||||
return;
|
||||
|
@ -1492,6 +1604,12 @@ static void v5_sig_ind(pstn_t *pstn, uint8_t *data, int len)
|
|||
/* append digit */
|
||||
strncat(pstn->dialing, called, sizeof(pstn->dialing) - 1);
|
||||
PDEBUG(DTEL, DEBUG_DEBUG, "Appending digit, so dial string is now: '%s'.\n", pstn->dialing);
|
||||
if (check_dial_hint(pstn->dialing)) {
|
||||
PDEBUG(DTEL, DEBUG_DEBUG, "Number in list of dial hints received, number is complete, send setup\n");
|
||||
/* setup (en block) */
|
||||
setup_ind(pstn, PSTN_CALL_ACTIVE, pstn->dialing, 1);
|
||||
break;
|
||||
}
|
||||
/* start dial timer */
|
||||
timer_on(pstn, (double)pstn->enblock, TIMER_IDENT_DIALING);
|
||||
break;
|
||||
|
|
|
@ -104,6 +104,12 @@ struct call {
|
|||
int on_hold; /* track hold/retrieval notification */
|
||||
};
|
||||
|
||||
struct dial_hint {
|
||||
struct dial_hint *next;
|
||||
size_t length;
|
||||
char *from, *to;
|
||||
};
|
||||
|
||||
typedef struct pstn {
|
||||
osmo_cc_endpoint_t cc_ep;
|
||||
|
||||
|
@ -119,6 +125,7 @@ typedef struct pstn {
|
|||
int cid_bell; /* use V.23 or Bell 202 FSK tones */
|
||||
int cid_dtmf; /* use DTMF instead of FSK caller ID */
|
||||
int enblock; /* receive digits before transmitting them via SETUP message (timeout as given) */
|
||||
struct dial_hint dial_hints; /* list of numbers that are complete */
|
||||
int recall; /* support recall / waiting call */
|
||||
int *ringing_types_incoming;/* cadenced rining on incoming call */
|
||||
int ringing_type_hold; /* cadenced rining on waiting call */
|
||||
|
@ -153,9 +160,10 @@ typedef struct pstn {
|
|||
int tx_buffer_pos; /* current position in transmit audio buffer */
|
||||
} pstn_t;
|
||||
|
||||
int add_dial_hint(const char *arg);
|
||||
void purge_dial_hints(void);
|
||||
void pstn_destroy(pstn_t *pstn_ep);
|
||||
pstn_t *pstn_create(void);
|
||||
int pstn_init(pstn_t *pstn, const char *name, const char *socketname, const char **subscribers, int subscriber_num, uint8_t serving_location, int tx_delay, enum pstn_cid_method clip, int cid_bell, int cid_dtmf, int clip_date, int enblock, int recall, int *ringing_types_incoming, int ringing_type_hold, enum tones_type tones_type, char law);
|
||||
void cc_message(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg);
|
||||
void rtp_work(pstn_t *pstn_ep);
|
||||
|
||||
|
|
Loading…
Reference in New Issue