Added CCBS/CCNR Party A support and enhanced COLP support.
This change adds the following features to chan_misdn: * CCBS/CCNR Party A support for PTMP and PTP modes. * Enhances COLP support for call diversion and explicit call transfer. These enhanced features require a modified version of mISDN. The latest modified mISDN v1.1.x based version is available at: http://svn.digium.com/svn/thirdparty/mISDN/trunk http://svn.digium.com/svn/thirdparty/mISDNuser/trunk Taged versions of the modified mISDN code are available under: http://svn.digium.com/svn/thirdparty/mISDN/tags http://svn.digium.com/svn/thirdparty/mISDNuser/tags Review: http://reviewboard.digium.com/r/218/ Merged from team/rmudgett/misdn_facility branch. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@189735 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
69331f19c4
commit
fa490a06b5
18
CHANGES
18
CHANGES
|
@ -61,7 +61,25 @@ mISDN channel driver (chan_misdn) changes
|
|||
subscriberprefix, and abbreviatedprefix in misdn.conf to prefix any
|
||||
received number from the ISDN link if that number has the corresponding
|
||||
Type-Of-Number.
|
||||
* Added new dialplan application misdn_command which permits controlling
|
||||
the CCBS/CCNR functionality.
|
||||
* Added new dialplan function mISDN_CC which permits retrieval of various
|
||||
values from an active call completion record.
|
||||
|
||||
thirdparty mISDN enhancements
|
||||
-----------------------------
|
||||
mISDN has been modified by Digium, Inc. to greatly expand facility message
|
||||
support to allow:
|
||||
* Enhanced COLP support for call diversion and transfer.
|
||||
* CCBS/CCNR support.
|
||||
|
||||
The latest modified mISDN v1.1.x based version is available at:
|
||||
http://svn.digium.com/svn/thirdparty/mISDN/trunk
|
||||
http://svn.digium.com/svn/thirdparty/mISDNuser/trunk
|
||||
|
||||
Taged versions of the modified mISDN code are available under:
|
||||
http://svn.digium.com/svn/thirdparty/mISDN/tags
|
||||
http://svn.digium.com/svn/thirdparty/mISDNuser/tags
|
||||
|
||||
SIP channel driver (chan_sip) changes
|
||||
-------------------------------------------
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -65,6 +65,7 @@ enum misdn_cfg_elements {
|
|||
MISDN_CFG_EARLY_BCONNECT, /* int (bool) */
|
||||
MISDN_CFG_INCOMING_EARLY_AUDIO, /* int (bool) */
|
||||
MISDN_CFG_ECHOCANCEL, /* int */
|
||||
MISDN_CFG_CC_REQUEST_RETENTION,/* bool */
|
||||
#ifdef MISDN_1_2
|
||||
MISDN_CFG_PIPELINE, /* char[] */
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* Chan_Misdn -- Channel Driver for Asterisk
|
||||
*
|
||||
|
@ -39,11 +38,11 @@
|
|||
#define MISDN_IE_DEBG 0
|
||||
|
||||
/* support stuff */
|
||||
static void strnncpy(char *dest, char *src, int len, int dst_len)
|
||||
static void strnncpy(char *dest, const char *src, size_t len, size_t dst_len)
|
||||
{
|
||||
if (len > dst_len-1)
|
||||
len = dst_len-1;
|
||||
strncpy((char *)dest, (char *)src, len);
|
||||
strncpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
|
||||
|
@ -380,7 +379,7 @@ static void enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int p
|
|||
strncpy((char *)p+3, (char *)number, strlen((char *)number));
|
||||
}
|
||||
|
||||
static void dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, char *number, int number_len, int nt, struct misdn_bchannel *bc)
|
||||
static void dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
*type = -1;
|
||||
*plan = -1;
|
||||
|
@ -464,7 +463,7 @@ static void enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int
|
|||
}
|
||||
}
|
||||
|
||||
static void dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, int number_len, int nt, struct misdn_bchannel *bc)
|
||||
static void dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
*type = -1;
|
||||
*plan = -1;
|
||||
|
@ -566,7 +565,7 @@ static void enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, in
|
|||
}
|
||||
}
|
||||
|
||||
static void dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, int number_len, int nt, struct misdn_bchannel *bc)
|
||||
static void dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
*type = -1;
|
||||
*plan = -1;
|
||||
|
@ -884,7 +883,7 @@ static void enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int nt, s
|
|||
static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
unsigned char *p;
|
||||
Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
|
||||
Q931_info_t *qi = (Q931_info_t *) (msg->data + mISDN_HEADER_LEN);
|
||||
int l;
|
||||
|
||||
if (!display[0])
|
||||
|
@ -893,27 +892,28 @@ static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, in
|
|||
return;
|
||||
}
|
||||
|
||||
if (strlen((char *)display) > 80)
|
||||
l = strlen(display);
|
||||
if (80 < l)
|
||||
{
|
||||
printf("%s: WARNING: display text too long (max 80 chars), cutting.\n", __FUNCTION__);
|
||||
display[80] = '\0';
|
||||
l = 80;
|
||||
printf("%s: WARNING: display text too long (max %d chars), cutting.\n", __FUNCTION__, l);
|
||||
display[l] = '\0';
|
||||
}
|
||||
|
||||
/* if (MISDN_IE_DEBG) printf(" display='%s' (len=%d)\n", display, strlen((char *)display)); */
|
||||
/* if (MISDN_IE_DEBG) printf(" display='%s' (len=%d)\n", display, l); */
|
||||
|
||||
l = strlen((char *)display);
|
||||
p = msg_put(msg, l+2);
|
||||
p = msg_put(msg, l + 2);
|
||||
if (nt)
|
||||
*ntmode = p+1;
|
||||
*ntmode = p + 1;
|
||||
else
|
||||
qi->QI_ELEMENT(display) = p - (unsigned char *)qi - sizeof(Q931_info_t);
|
||||
qi->QI_ELEMENT(display) = p - (unsigned char *) qi - sizeof(Q931_info_t);
|
||||
p[0] = IE_DISPLAY;
|
||||
p[1] = l;
|
||||
strncpy((char *)p+2, (char *)display, strlen((char *)display));
|
||||
strncpy((char *) p + 2, display, l);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void dec_ie_display(unsigned char *p, Q931_info_t *qi, char *display, int display_len, int nt, struct misdn_bchannel *bc)
|
||||
static void dec_ie_display(unsigned char *p, Q931_info_t *qi, char *display, size_t display_len, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
*display = '\0';
|
||||
|
||||
|
@ -965,7 +965,7 @@ static void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, char *keypad, int
|
|||
}
|
||||
#endif
|
||||
|
||||
static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, int keypad_len, int nt, struct misdn_bchannel *bc)
|
||||
static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, size_t keypad_len, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
*keypad = '\0';
|
||||
|
||||
|
@ -990,7 +990,6 @@ static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, int k
|
|||
|
||||
|
||||
/* IE_NOTIFY */
|
||||
#if 0
|
||||
static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
@ -1015,9 +1014,7 @@ static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt
|
|||
p[1] = l;
|
||||
p[2] = 0x80 + notify;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
*notify = -1;
|
||||
|
@ -1040,7 +1037,6 @@ static void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt
|
|||
|
||||
if (MISDN_IE_DEBG) printf(" notify=%d\n", *notify);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* IE_PROGRESS */
|
||||
|
@ -1184,7 +1180,7 @@ static void enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int pl
|
|||
}
|
||||
}
|
||||
|
||||
static void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, char *number, int number_len, int nt, struct misdn_bchannel *bc)
|
||||
static void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
*type = -1;
|
||||
*plan = -1;
|
||||
|
@ -1231,11 +1227,10 @@ static void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *p
|
|||
|
||||
|
||||
/* IE_REDIR_DN (redirection = during MT_NOTIFY) */
|
||||
#if 0
|
||||
static void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, char *number, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
unsigned char *p;
|
||||
/* Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN); */
|
||||
Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
|
||||
int l;
|
||||
|
||||
if (type<0 || type>7)
|
||||
|
@ -1264,9 +1259,9 @@ static void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int pl
|
|||
p = msg_put(msg, l+2);
|
||||
if (nt)
|
||||
*ntmode = p+1;
|
||||
else
|
||||
/* #warning REINSERT redir_dn, when included in te-mode */
|
||||
/*qi->QI_ELEMENT(redir_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t)*/;
|
||||
else {
|
||||
qi->QI_ELEMENT(redirect_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t);
|
||||
}
|
||||
p[0] = IE_REDIR_DN;
|
||||
p[1] = l;
|
||||
if (present >= 0)
|
||||
|
@ -1282,10 +1277,8 @@ static void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int pl
|
|||
strncpy((char *)p+3, (char *)number, strlen((char *)number));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, char *number, int number_len, int nt, struct misdn_bchannel *bc)
|
||||
static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
*type = -1;
|
||||
*plan = -1;
|
||||
|
@ -1295,9 +1288,8 @@ static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *p
|
|||
if (!nt)
|
||||
{
|
||||
p = NULL;
|
||||
/* #warning REINSERT redir_dn, when included in te-mode */
|
||||
/* if (qi->QI_ELEMENT(redir_dn)) */
|
||||
/* p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redir_dn) + 1; */
|
||||
if (qi->QI_ELEMENT(redirect_dn))
|
||||
p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_dn) + 1;
|
||||
}
|
||||
if (!p)
|
||||
return;
|
||||
|
@ -1320,7 +1312,6 @@ static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *p
|
|||
|
||||
if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* IE_USERUSER */
|
||||
|
@ -1331,9 +1322,6 @@ static void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, ch
|
|||
Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
|
||||
int l;
|
||||
|
||||
char debug[768];
|
||||
int i;
|
||||
|
||||
if (protocol<0 || protocol>127)
|
||||
{
|
||||
printf("%s: ERROR: protocol(%d) is out of range.\n", __FUNCTION__, protocol);
|
||||
|
@ -1344,14 +1332,16 @@ static void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, ch
|
|||
return;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while(i < user_len)
|
||||
{
|
||||
if (MISDN_IE_DEBG) sprintf(debug+(i*3), " %02x", user[i]);
|
||||
i++;
|
||||
}
|
||||
if (MISDN_IE_DEBG) {
|
||||
size_t i;
|
||||
char debug[768];
|
||||
|
||||
if (MISDN_IE_DEBG) printf(" protocol=%d user-user%s\n", protocol, debug);
|
||||
for (i = 0; i < user_len; ++i) {
|
||||
sprintf(debug + (i * 3), " %02x", user[i]);
|
||||
}
|
||||
debug[i * 3] = 0;
|
||||
printf(" protocol=%d user-user%s\n", protocol, debug);
|
||||
}
|
||||
|
||||
l = user_len+1;
|
||||
p = msg_put(msg, l+3);
|
||||
|
@ -1369,9 +1359,6 @@ static void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, ch
|
|||
#if 1
|
||||
static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, char *user, int *user_len, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
char debug[768];
|
||||
int i;
|
||||
|
||||
*user_len = 0;
|
||||
*protocol = -1;
|
||||
|
||||
|
@ -1390,15 +1377,16 @@ static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, ch
|
|||
*protocol = p[1];
|
||||
memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
|
||||
|
||||
i = 0;
|
||||
while(i < *user_len)
|
||||
{
|
||||
if (MISDN_IE_DEBG) sprintf(debug+(i*3), " %02x", user[i]);
|
||||
i++;
|
||||
}
|
||||
debug[i*3] = '\0';
|
||||
if (MISDN_IE_DEBG) {
|
||||
int i;
|
||||
char debug[768];
|
||||
|
||||
if (MISDN_IE_DEBG) printf(" protocol=%d user-user%s\n", *protocol, debug);
|
||||
for (i = 0; i < *user_len; ++i) {
|
||||
sprintf(debug + (i * 3), " %02x", user[i]);
|
||||
}
|
||||
debug[i * 3] = 0;
|
||||
printf(" protocol=%d user-user%s\n", *protocol, debug);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -133,6 +133,7 @@ enum event_e {
|
|||
EVENT_PROCEEDING,
|
||||
EVENT_PROGRESS,
|
||||
EVENT_SETUP,
|
||||
EVENT_REGISTER,
|
||||
EVENT_ALERTING,
|
||||
EVENT_CONNECT,
|
||||
EVENT_SETUP_ACKNOWLEDGE,
|
||||
|
@ -216,6 +217,25 @@ enum mISDN_REDIRECTING_REASON {
|
|||
mISDN_REDIRECTING_REASON_CALL_FWD = 0xF
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Notification description code enumeration
|
||||
*/
|
||||
enum mISDN_NOTIFY_CODE {
|
||||
mISDN_NOTIFY_CODE_INVALID = -1,
|
||||
/*! Call is placed on hold (Q.931) */
|
||||
mISDN_NOTIFY_CODE_USER_SUSPEND = 0x00,
|
||||
/*! Call is taken off of hold (Q.931) */
|
||||
mISDN_NOTIFY_CODE_USER_RESUME = 0x01,
|
||||
/*! Call is diverting (EN 300 207-1 Section 7.2.1) */
|
||||
mISDN_NOTIFY_CODE_CALL_IS_DIVERTING = 0x7B,
|
||||
/*! Call diversion is enabled (cfu, cfb, cfnr) (EN 300 207-1 Section 7.2.1) */
|
||||
mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED = 0x68,
|
||||
/*! Call transfer, alerting (EN 300 369-1 Section 7.2) */
|
||||
mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING = 0x69,
|
||||
/*! Call transfer, active(answered) (EN 300 369-1 Section 7.2) */
|
||||
mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE = 0x6A,
|
||||
};
|
||||
|
||||
enum { /*CODECS*/
|
||||
INFO_CODEC_ULAW=2,
|
||||
INFO_CODEC_ALAW=3
|
||||
|
@ -241,6 +261,21 @@ enum layer_e {
|
|||
/*! Maximum keypad facility content length plus null terminator */
|
||||
#define MISDN_MAX_KEYPAD_LEN (31 + 1)
|
||||
|
||||
/*! \brief Dialed/Called information struct */
|
||||
struct misdn_party_dialing {
|
||||
/*! \brief Type-of-number in ISDN terms for the dialed/called number */
|
||||
enum mISDN_NUMBER_TYPE number_type;
|
||||
|
||||
/*! \brief Type-of-number numbering plan. */
|
||||
enum mISDN_NUMBER_PLAN number_plan;
|
||||
|
||||
/*! \brief Dialed/Called Phone Number (Address) */
|
||||
char number[MISDN_MAX_NUMBER_LEN];
|
||||
|
||||
/*! \brief Dialed/Called Subaddress number */
|
||||
char subaddress[MISDN_MAX_SUBADDRESS_LEN];
|
||||
};
|
||||
|
||||
/*! \brief Connected-Line/Calling/Redirecting ID info struct */
|
||||
struct misdn_party_id {
|
||||
/*! \brief Number presentation restriction code
|
||||
|
@ -278,8 +313,17 @@ struct misdn_party_redirecting {
|
|||
/*! \brief Who is redirecting the call (Sent to the party the call is redirected toward) */
|
||||
struct misdn_party_id from;
|
||||
|
||||
/*! \brief Where the call is being redirected toward (Sent to the calling party) */
|
||||
struct misdn_party_id to;
|
||||
|
||||
/*! \brief Reason a call is being redirected (Q.931 field value) */
|
||||
enum mISDN_REDIRECTING_REASON reason;
|
||||
|
||||
/*! \brief Number of times the call has been redirected */
|
||||
int count;
|
||||
|
||||
/*! \brief TRUE if the redirecting.to information has changed */
|
||||
int to_changed;
|
||||
};
|
||||
|
||||
|
||||
|
@ -288,6 +332,17 @@ struct misdn_bchannel {
|
|||
/*! \brief B channel send locking structure */
|
||||
struct send_lock *send_lock;
|
||||
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
/*! \brief The BC, HLC (optional) and LLC (optional) contents from the SETUP message. */
|
||||
struct Q931_Bc_Hlc_Llc setup_bc_hlc_llc;
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
|
||||
/*!
|
||||
* \brief Dialed/Called information struct
|
||||
* \note The number_type element is set to "dialplan" in /etc/asterisk/misdn.conf for outgoing calls
|
||||
*/
|
||||
struct misdn_party_dialing dialed;
|
||||
|
||||
/*! \brief Originating/Caller ID information struct
|
||||
* \note The number_type element can be set to "localdialplan" in /etc/asterisk/misdn.conf for outgoing calls
|
||||
* \note The number element can be set to "callerid" in /etc/asterisk/misdn.conf for outgoing calls
|
||||
|
@ -360,6 +415,9 @@ struct misdn_bchannel {
|
|||
/*! \brief TRUE if the B channel number is preselected */
|
||||
int channel_preselected;
|
||||
|
||||
/*! \brief TRUE if the B channel is allocated from the REGISTER pool */
|
||||
int is_register_pool;
|
||||
|
||||
/*! \brief TRUE if B channel record is in use */
|
||||
int in_use;
|
||||
|
||||
|
@ -382,8 +440,6 @@ struct misdn_bchannel {
|
|||
/*! \brief Not used. Contents are setup but not used. */
|
||||
void *astbuf;
|
||||
|
||||
void *misdnbuf; /* Not used */
|
||||
|
||||
/*! \brief TRUE if the TE side should choose the B channel to use
|
||||
* \note This value is user configurable in /etc/asterisk/misdn.conf
|
||||
*/
|
||||
|
@ -530,6 +586,9 @@ struct misdn_bchannel {
|
|||
/*! \brief TRUE if the user set the presentation restriction code */
|
||||
int set_presentation;
|
||||
|
||||
/*! \brief Notification indicator ie description code */
|
||||
enum mISDN_NOTIFY_CODE notify_description_code;
|
||||
|
||||
/*! \brief SETUP message bearer capability field code value */
|
||||
int capability;
|
||||
|
||||
|
@ -560,32 +619,12 @@ struct misdn_bchannel {
|
|||
int hdlc;
|
||||
/* V110 */
|
||||
|
||||
/*! \brief Dialed/Called information struct */
|
||||
struct {
|
||||
/*! \brief Type-of-number in ISDN terms for the dialed/called number
|
||||
* \note This value is set to "dialplan" in /etc/asterisk/misdn.conf for outgoing calls
|
||||
*/
|
||||
enum mISDN_NUMBER_TYPE number_type;
|
||||
|
||||
/*! \brief Type-of-number numbering plan. */
|
||||
enum mISDN_NUMBER_PLAN number_plan;
|
||||
|
||||
/*! \brief Dialed/Called Phone Number (Address) */
|
||||
char number[MISDN_MAX_NUMBER_LEN];
|
||||
|
||||
/*! \brief Dialed/Called Subaddress number */
|
||||
char subaddress[MISDN_MAX_SUBADDRESS_LEN];
|
||||
} dialed;
|
||||
|
||||
/*! \brief Display message that can be displayed by the user phone.
|
||||
* \note Maximum displayable length is 34 or 82 octets.
|
||||
* It is also settable by the misdn_set_opt() application.
|
||||
*/
|
||||
char display[84];
|
||||
|
||||
/*! \brief Not used. Contents are setup but not used. */
|
||||
char msn[MISDN_MAX_NUMBER_LEN];
|
||||
|
||||
/*! \brief Q.931 Keypad Facility IE contents
|
||||
* \note Contents exported and imported to Asterisk variable MISDN_KEYPAD
|
||||
*/
|
||||
|
@ -696,6 +735,9 @@ char *manager_isdn_get_info(enum event_e event);
|
|||
void misdn_lib_transfer(struct misdn_bchannel* holded_bc);
|
||||
|
||||
struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel, int inout, int dec);
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
struct misdn_bchannel *misdn_lib_get_register_bc(int port);
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
|
||||
void manager_bchannel_activate(struct misdn_bchannel *bc);
|
||||
void manager_bchannel_deactivate(struct misdn_bchannel * bc);
|
||||
|
|
|
@ -51,7 +51,15 @@ struct isdn_msg {
|
|||
/* for isdn_msg_parser.c */
|
||||
msg_t *create_l3msg(int prim, int mt, int dinfo , int size, int nt);
|
||||
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
/* Max call-completion REGISTER signaling links per stack/port */
|
||||
#define MISDN_MAX_REGISTER_LINKS MAX_BCHANS
|
||||
#else
|
||||
/* Max call-completion REGISTER signaling links per stack/port */
|
||||
#define MISDN_MAX_REGISTER_LINKS 0
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
|
||||
#define MAXPROCS 0x100
|
||||
|
||||
struct misdn_stack {
|
||||
/** is first element because &nst equals &mISDNlist **/
|
||||
|
@ -87,8 +95,6 @@ struct misdn_stack {
|
|||
/*! \brief TRUE if Layer 2 is UP */
|
||||
int l2link;
|
||||
|
||||
time_t l2establish; /* Not used */
|
||||
|
||||
/*! \brief TRUE if Layer 1 is UP */
|
||||
int l1link;
|
||||
|
||||
|
@ -105,7 +111,7 @@ struct misdn_stack {
|
|||
int pri;
|
||||
|
||||
/*! \brief CR Process ID allocation table. TRUE if ID allocated */
|
||||
int procids[0x100+1];
|
||||
int procids[MAXPROCS];
|
||||
|
||||
/*! \brief Queue of Event messages to send to mISDN */
|
||||
msg_queue_t downqueue;
|
||||
|
@ -115,13 +121,17 @@ struct misdn_stack {
|
|||
/*! \brief Logical Layer 1 port associated with this stack */
|
||||
int port;
|
||||
|
||||
/*! \brief B Channel record pool array */
|
||||
struct misdn_bchannel bc[MAX_BCHANS + 1];
|
||||
/*!
|
||||
* \brief B Channel record pool array
|
||||
* (Must be dimensioned the same as struct misdn_stack.channels[])
|
||||
*/
|
||||
struct misdn_bchannel bc[MAX_BCHANS + 1 + MISDN_MAX_REGISTER_LINKS];
|
||||
|
||||
struct misdn_bchannel* bc_list; /* Not used */
|
||||
|
||||
/*! \brief Array of B channels in use (a[0] = B1). TRUE if B channel in use */
|
||||
int channels[MAX_BCHANS + 1];
|
||||
/*!
|
||||
* \brief Array of B channels in use (a[0] = B1). TRUE if B channel in use.
|
||||
* (Must be dimensioned the same as struct misdn_stack.bc[])
|
||||
*/
|
||||
char channels[MAX_BCHANS + 1 + MISDN_MAX_REGISTER_LINKS];
|
||||
|
||||
/*! \brief List of holded channels */
|
||||
struct misdn_bchannel *holding;
|
||||
|
|
|
@ -61,6 +61,80 @@ static void build_display_str(char *display, size_t display_length, int display_
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the Facility IE and put it into the message structure.
|
||||
*
|
||||
* \param ntmode Where the encoded facility was put when in NT mode.
|
||||
* \param msg General message structure
|
||||
* \param fac Data to encode into the facility ie.
|
||||
* \param nt TRUE if in NT mode.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void enc_ie_facility(unsigned char **ntmode, msg_t *msg, struct FacParm *fac, int nt)
|
||||
{
|
||||
int len;
|
||||
Q931_info_t *qi;
|
||||
unsigned char *p;
|
||||
unsigned char buf[256];
|
||||
|
||||
len = encodeFac(buf, fac);
|
||||
if (len <= 0) {
|
||||
/*
|
||||
* mISDN does not know how to build the requested facility structure
|
||||
* Clear facility information
|
||||
*/
|
||||
fac->Function = Fac_None;
|
||||
return;
|
||||
}
|
||||
|
||||
p = msg_put(msg, len);
|
||||
if (nt) {
|
||||
*ntmode = p + 1;
|
||||
} else {
|
||||
qi = (Q931_info_t *) (msg->data + mISDN_HEADER_LEN);
|
||||
qi->QI_ELEMENT(facility) = p - (unsigned char *) qi - sizeof(Q931_info_t);
|
||||
}
|
||||
|
||||
memcpy(p, buf, len);
|
||||
|
||||
/* Clear facility information */
|
||||
fac->Function = Fac_None;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Decode the Facility IE.
|
||||
*
|
||||
* \param p Encoded facility ie data to decode. (NT mode)
|
||||
* \param qi Encoded facility ie data to decode. (TE mode)
|
||||
* \param fac Where to put the decoded facility ie data if it is available.
|
||||
* \param nt TRUE if in NT mode.
|
||||
* \param bc Associated B channel
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void dec_ie_facility(unsigned char *p, Q931_info_t *qi, struct FacParm *fac, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
fac->Function = Fac_None;
|
||||
|
||||
if (!nt) {
|
||||
p = NULL;
|
||||
if (qi->QI_ELEMENT(facility)) {
|
||||
p = (unsigned char *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
|
||||
}
|
||||
}
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (decodeFac(p, fac)) {
|
||||
cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void set_channel(struct misdn_bchannel *bc, int channel)
|
||||
{
|
||||
|
@ -93,7 +167,7 @@ static void set_channel(struct misdn_bchannel *bc, int channel)
|
|||
static void parse_proceeding (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
CALL_PROCEEDING_t *proceeding=(CALL_PROCEEDING_t*)((unsigned long)msg->data+ HEADER_LEN);
|
||||
CALL_PROCEEDING_t *proceeding = (CALL_PROCEEDING_t *) (msg->data + HEADER_LEN);
|
||||
//struct misdn_stack *stack=get_stack_by_bc(bc);
|
||||
|
||||
{
|
||||
|
@ -106,6 +180,9 @@ static void parse_proceeding (struct isdn_msg msgs[], msg_t *msg, struct misdn_b
|
|||
|
||||
dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)proceeding, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
|
||||
|
||||
dec_ie_facility(proceeding->FACILITY, (Q931_info_t *) proceeding, &bc->fac_in, nt, bc);
|
||||
|
||||
/* dec_ie_redir_dn */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Parsing PROCEEDING Msg\n");
|
||||
|
@ -124,6 +201,11 @@ static msg_t *build_proceeding (struct isdn_msg msgs[], struct misdn_bchannel *b
|
|||
if (nt)
|
||||
enc_ie_progress(&proceeding->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&proceeding->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
/* enc_ie_redir_dn */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Building PROCEEDING Msg\n");
|
||||
|
@ -134,9 +216,13 @@ static msg_t *build_proceeding (struct isdn_msg msgs[], struct misdn_bchannel *b
|
|||
static void parse_alerting (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
ALERTING_t *alerting=(ALERTING_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
ALERTING_t *alerting = (ALERTING_t *) (msg->data + HEADER_LEN);
|
||||
//Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
|
||||
|
||||
dec_ie_facility(alerting->FACILITY, (Q931_info_t *) alerting, &bc->fac_in, nt, bc);
|
||||
|
||||
/* dec_ie_redir_dn */
|
||||
|
||||
dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)alerting, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -158,6 +244,13 @@ static msg_t *build_alerting (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
|
||||
if (nt)
|
||||
enc_ie_progress(&alerting->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&alerting->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
/* enc_ie_redir_dn */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Building ALERTING Msg\n");
|
||||
#endif
|
||||
|
@ -168,11 +261,13 @@ static msg_t *build_alerting (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
static void parse_progress (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
PROGRESS_t *progress=(PROGRESS_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
PROGRESS_t *progress = (PROGRESS_t *) (msg->data + HEADER_LEN);
|
||||
//Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
|
||||
|
||||
dec_ie_progress(progress->PROGRESS, (Q931_info_t *)progress, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
|
||||
|
||||
dec_ie_facility(progress->FACILITY, (Q931_info_t *) progress, &bc->fac_in, nt, bc);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Parsing PROGRESS Msg\n");
|
||||
#endif
|
||||
|
@ -186,17 +281,92 @@ static msg_t *build_progress (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
|
||||
progress=(PROGRESS_t*)((msg->data+HEADER_LEN));
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&progress->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Building PROGRESS Msg\n");
|
||||
#endif
|
||||
return msg;
|
||||
}
|
||||
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Extract the SETUP message's BC, HLC, and LLC encoded ie contents.
|
||||
*
|
||||
* \param setup Indexed setup message contents
|
||||
* \param nt TRUE if in NT mode.
|
||||
* \param bc Associated B channel
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void extract_setup_Bc_Hlc_Llc(SETUP_t *setup, int nt, struct misdn_bchannel *bc)
|
||||
{
|
||||
__u8 *p;
|
||||
Q931_info_t *qi;
|
||||
|
||||
qi = (Q931_info_t *) setup;
|
||||
|
||||
/* Extract Bearer Capability */
|
||||
if (nt) {
|
||||
p = (__u8 *) setup->BEARER;
|
||||
} else {
|
||||
if (qi->QI_ELEMENT(bearer_capability)) {
|
||||
p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
|
||||
} else {
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Bc.Contents) < *p) {
|
||||
bc->setup_bc_hlc_llc.Bc.Length = 0;
|
||||
} else {
|
||||
bc->setup_bc_hlc_llc.Bc.Length = *p;
|
||||
memcpy(bc->setup_bc_hlc_llc.Bc.Contents, p + 1, *p);
|
||||
}
|
||||
|
||||
/* Extract Low Layer Compatibility */
|
||||
if (nt) {
|
||||
p = (__u8 *) setup->LLC;
|
||||
} else {
|
||||
if (qi->QI_ELEMENT(llc)) {
|
||||
p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
|
||||
} else {
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Llc.Contents) < *p) {
|
||||
bc->setup_bc_hlc_llc.Llc.Length = 0;
|
||||
} else {
|
||||
bc->setup_bc_hlc_llc.Llc.Length = *p;
|
||||
memcpy(bc->setup_bc_hlc_llc.Llc.Contents, p + 1, *p);
|
||||
}
|
||||
|
||||
/* Extract High Layer Compatibility */
|
||||
if (nt) {
|
||||
p = (__u8 *) setup->HLC;
|
||||
} else {
|
||||
if (qi->QI_ELEMENT(hlc)) {
|
||||
p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(hlc) + 1;
|
||||
} else {
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Hlc.Contents) < *p) {
|
||||
bc->setup_bc_hlc_llc.Hlc.Length = 0;
|
||||
} else {
|
||||
bc->setup_bc_hlc_llc.Hlc.Length = *p;
|
||||
memcpy(bc->setup_bc_hlc_llc.Hlc.Contents, p + 1, *p);
|
||||
}
|
||||
}
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
|
||||
static void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
SETUP_t *setup= (SETUP_t*)((unsigned long)msg->data+HEADER_LEN);
|
||||
Q931_info_t *qi=(Q931_info_t*)((unsigned long)msg->data+HEADER_LEN);
|
||||
SETUP_t *setup = (SETUP_t *) (msg->data + HEADER_LEN);
|
||||
Q931_info_t *qi = (Q931_info_t *) (msg->data + HEADER_LEN);
|
||||
int type;
|
||||
int plan;
|
||||
int present;
|
||||
|
@ -207,7 +377,7 @@ static void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchann
|
|||
printf("Parsing SETUP Msg\n");
|
||||
#endif
|
||||
|
||||
dec_ie_calling_pn(setup->CALLING_PN, qi, &type, &plan, &present, &screen, bc->caller.number, sizeof(bc->caller.number) - 1, nt, bc);
|
||||
dec_ie_calling_pn(setup->CALLING_PN, qi, &type, &plan, &present, &screen, bc->caller.number, sizeof(bc->caller.number), nt, bc);
|
||||
bc->caller.number_type = type;
|
||||
bc->caller.number_plan = plan;
|
||||
switch (present) {
|
||||
|
@ -228,15 +398,17 @@ static void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchann
|
|||
bc->caller.screening = 0; /* Unscreened */
|
||||
}
|
||||
|
||||
dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *) setup, &type, &plan, bc->dialed.number, sizeof(bc->dialed.number) - 1, nt, bc);
|
||||
dec_ie_facility(setup->FACILITY, (Q931_info_t *) setup, &bc->fac_in, nt, bc);
|
||||
|
||||
dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *) setup, &type, &plan, bc->dialed.number, sizeof(bc->dialed.number), nt, bc);
|
||||
bc->dialed.number_type = type;
|
||||
bc->dialed.number_plan = plan;
|
||||
|
||||
dec_ie_keypad(setup->KEYPAD, (Q931_info_t *) setup, bc->keypad, sizeof(bc->keypad) - 1, nt, bc);
|
||||
dec_ie_keypad(setup->KEYPAD, (Q931_info_t *) setup, bc->keypad, sizeof(bc->keypad), nt, bc);
|
||||
|
||||
dec_ie_complete(setup->COMPLETE, (Q931_info_t *) setup, &bc->sending_complete, nt, bc);
|
||||
|
||||
dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *) setup, &type, &plan, &present, &screen, &reason, bc->redirecting.from.number, sizeof(bc->redirecting.from.number) - 1, nt, bc);
|
||||
dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *) setup, &type, &plan, &present, &screen, &reason, bc->redirecting.from.number, sizeof(bc->redirecting.from.number), nt, bc);
|
||||
bc->redirecting.from.number_type = type;
|
||||
bc->redirecting.from.number_plan = plan;
|
||||
switch (present) {
|
||||
|
@ -317,6 +489,9 @@ static void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchann
|
|||
|
||||
dec_ie_progress(setup->PROGRESS, (Q931_info_t *)setup, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
|
||||
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
extract_setup_Bc_Hlc_Llc(setup, nt, bc);
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
}
|
||||
|
||||
#define ANY_CHANNEL 0xff /* IE attribute for 'any channel' */
|
||||
|
@ -333,6 +508,9 @@ static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, in
|
|||
else
|
||||
enc_ie_channel_id(&setup->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&setup->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
enc_ie_calling_pn(&setup->CALLING_PN, msg, bc->caller.number_type, bc->caller.number_plan,
|
||||
bc->caller.presentation, bc->caller.screening, bc->caller.number, nt, bc);
|
||||
|
@ -342,9 +520,17 @@ static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, in
|
|||
}
|
||||
|
||||
if (bc->redirecting.from.number[0]) {
|
||||
#if 1
|
||||
/* ETSI and Q.952 do not define the screening field */
|
||||
enc_ie_redir_nr(&setup->REDIR_NR, msg, bc->redirecting.from.number_type, bc->redirecting.from.number_plan,
|
||||
bc->redirecting.from.presentation, 0, bc->redirecting.reason,
|
||||
bc->redirecting.from.number, nt, bc);
|
||||
#else
|
||||
/* Q.931 defines the screening field */
|
||||
enc_ie_redir_nr(&setup->REDIR_NR, msg, bc->redirecting.from.number_type, bc->redirecting.from.number_plan,
|
||||
bc->redirecting.from.presentation, bc->redirecting.from.screening, bc->redirecting.reason,
|
||||
bc->redirecting.from.number, nt, bc);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bc->keypad[0]) {
|
||||
|
@ -409,6 +595,10 @@ static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, in
|
|||
cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
|
||||
}
|
||||
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
extract_setup_Bc_Hlc_Llc(setup, nt, bc);
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Building SETUP Msg\n");
|
||||
#endif
|
||||
|
@ -418,7 +608,7 @@ static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, in
|
|||
static void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
CONNECT_t *connect=(CONNECT_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
CONNECT_t *connect = (CONNECT_t *) (msg->data + HEADER_LEN);
|
||||
int type;
|
||||
int plan;
|
||||
int pres;
|
||||
|
@ -429,7 +619,7 @@ static void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bcha
|
|||
dec_ie_progress(connect->PROGRESS, (Q931_info_t *)connect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
|
||||
|
||||
dec_ie_connected_pn(connect->CONNECT_PN, (Q931_info_t *) connect, &type, &plan,
|
||||
&pres, &screen, bc->connected.number, sizeof(bc->connected.number) - 1, nt, bc);
|
||||
&pres, &screen, bc->connected.number, sizeof(bc->connected.number), nt, bc);
|
||||
bc->connected.number_type = type;
|
||||
bc->connected.number_plan = plan;
|
||||
switch (pres) {
|
||||
|
@ -450,6 +640,8 @@ static void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bcha
|
|||
bc->connected.screening = 0; /* Unscreened */
|
||||
}
|
||||
|
||||
dec_ie_facility(connect->FACILITY, (Q931_info_t *) connect, &bc->fac_in, nt, bc);
|
||||
|
||||
/*
|
||||
cb_log(1,bc->port,"CONNETED PN: %s cpn_dialplan:%d\n", connected_pn, type);
|
||||
*/
|
||||
|
@ -488,6 +680,10 @@ static msg_t *build_connect (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
}
|
||||
}
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&connect->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Building CONNECT Msg\n");
|
||||
#endif
|
||||
|
@ -497,7 +693,7 @@ static msg_t *build_connect (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
static void parse_setup_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
SETUP_ACKNOWLEDGE_t *setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
SETUP_ACKNOWLEDGE_t *setup_acknowledge = (SETUP_ACKNOWLEDGE_t *) (msg->data + HEADER_LEN);
|
||||
|
||||
{
|
||||
int exclusive, channel;
|
||||
|
@ -508,6 +704,9 @@ static void parse_setup_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct
|
|||
}
|
||||
|
||||
dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)setup_acknowledge, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
|
||||
|
||||
dec_ie_facility(setup_acknowledge->FACILITY, (Q931_info_t *) setup_acknowledge, &bc->fac_in, nt, bc);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Parsing SETUP_ACKNOWLEDGE Msg\n");
|
||||
#endif
|
||||
|
@ -528,6 +727,10 @@ static msg_t *build_setup_acknowledge (struct isdn_msg msgs[], struct misdn_bcha
|
|||
if (nt)
|
||||
enc_ie_progress(&setup_acknowledge->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&setup_acknowledge->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Building SETUP_ACKNOWLEDGE Msg\n");
|
||||
#endif
|
||||
|
@ -862,12 +1065,14 @@ static msg_t *build_retrieve_reject (struct isdn_msg msgs[], struct misdn_bchann
|
|||
static void parse_disconnect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
DISCONNECT_t *disconnect=(DISCONNECT_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
DISCONNECT_t *disconnect = (DISCONNECT_t *) (msg->data + HEADER_LEN);
|
||||
int location;
|
||||
int cause;
|
||||
dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &cause, nt,bc);
|
||||
if (cause>0) bc->cause=cause;
|
||||
|
||||
dec_ie_facility(disconnect->FACILITY, (Q931_info_t *) disconnect, &bc->fac_in, nt, bc);
|
||||
|
||||
dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
|
||||
#ifdef DEBUG
|
||||
printf("Parsing DISCONNECT Msg\n");
|
||||
|
@ -885,7 +1090,13 @@ static msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *b
|
|||
disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN));
|
||||
|
||||
enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc);
|
||||
if (nt) enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt?1:5, 8 ,nt,bc);
|
||||
if (nt) {
|
||||
enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt ? 1 : 5, 8, nt, bc);
|
||||
}
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&disconnect->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
if (bc->uulen) {
|
||||
int protocol=4;
|
||||
|
@ -902,7 +1113,7 @@ static msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *b
|
|||
static void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
RESTART_t *restart=(RESTART_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
RESTART_t *restart = (RESTART_t *) (msg->data + HEADER_LEN);
|
||||
|
||||
struct misdn_stack *stack=get_stack_by_bc(bc);
|
||||
|
||||
|
@ -944,12 +1155,15 @@ static msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
static void parse_release (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
RELEASE_t *release=(RELEASE_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
RELEASE_t *release = (RELEASE_t *) (msg->data + HEADER_LEN);
|
||||
int location;
|
||||
int cause;
|
||||
|
||||
dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &cause, nt,bc);
|
||||
if (cause>0) bc->cause=cause;
|
||||
|
||||
dec_ie_facility(release->FACILITY, (Q931_info_t *) release, &bc->fac_in, nt, bc);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Parsing RELEASE Msg\n");
|
||||
#endif
|
||||
|
@ -968,6 +1182,10 @@ static msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
if (bc->out_cause>= 0)
|
||||
enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&release->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
if (bc->uulen) {
|
||||
int protocol=4;
|
||||
enc_ie_useruser(&release->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
|
||||
|
@ -983,7 +1201,7 @@ static msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
static void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
RELEASE_COMPLETE_t *release_complete=(RELEASE_COMPLETE_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
RELEASE_COMPLETE_t *release_complete = (RELEASE_COMPLETE_t *) (msg->data + HEADER_LEN);
|
||||
int location;
|
||||
int cause;
|
||||
iframe_t *frm = (iframe_t*) msg->data;
|
||||
|
@ -1009,6 +1227,8 @@ static void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct m
|
|||
dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &cause, nt,bc);
|
||||
if (cause>0) bc->cause=cause;
|
||||
|
||||
dec_ie_facility(release_complete->FACILITY, (Q931_info_t *) release_complete, &bc->fac_in, nt, bc);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Parsing RELEASE_COMPLETE Msg\n");
|
||||
#endif
|
||||
|
@ -1024,6 +1244,10 @@ static msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchan
|
|||
|
||||
enc_ie_cause(&release_complete->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(&release_complete->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
if (bc->uulen) {
|
||||
int protocol=4;
|
||||
enc_ie_useruser(&release_complete->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
|
||||
|
@ -1042,12 +1266,13 @@ static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bch
|
|||
FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
|
||||
Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
|
||||
unsigned char *p = NULL;
|
||||
int err;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Parsing FACILITY Msg\n");
|
||||
#endif
|
||||
|
||||
bc->fac_in.Function = Fac_None;
|
||||
|
||||
if (!bc->nt) {
|
||||
if (qi->QI_ELEMENT(facility))
|
||||
p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
|
||||
|
@ -1057,9 +1282,8 @@ static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bch
|
|||
if (!p)
|
||||
return;
|
||||
|
||||
err = decodeFac(p, &(bc->fac_in));
|
||||
if (err) {
|
||||
cb_log(5, bc->port, "Decoding FACILITY failed! (%d)\n", err);
|
||||
if (decodeFac(p, &bc->fac_in)) {
|
||||
cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1079,7 +1303,11 @@ static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
|
||||
len = encodeFac(fac_tmp, &(bc->fac_out));
|
||||
if (len <= 0) {
|
||||
/* mISDN does not know how to build the requested facility structure */
|
||||
/*
|
||||
* mISDN does not know how to build the requested facility structure
|
||||
* Clear facility information
|
||||
*/
|
||||
bc->fac_out.Function = Fac_None;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1097,6 +1325,9 @@ static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
|
||||
memcpy(ie_fac, fac_tmp, len);
|
||||
|
||||
/* Clear facility information */
|
||||
bc->fac_out.Function = Fac_None;
|
||||
|
||||
if (*bc->display) {
|
||||
#ifdef DEBUG
|
||||
printf("Sending %s as Display\n", bc->display);
|
||||
|
@ -1107,11 +1338,106 @@ static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc,
|
|||
return msg;
|
||||
}
|
||||
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse a received REGISTER message
|
||||
*
|
||||
* \param msgs Search table entry that called us.
|
||||
* \param msg Received message contents
|
||||
* \param bc Associated B channel
|
||||
* \param nt TRUE if in NT mode.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void parse_register(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN;
|
||||
REGISTER_t *reg;
|
||||
|
||||
HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
|
||||
reg = (REGISTER_t *) (msg->data + HEADER_LEN);
|
||||
|
||||
/*
|
||||
* A facility ie is optional.
|
||||
* The peer may just be establishing a connection to send
|
||||
* messages later.
|
||||
*/
|
||||
dec_ie_facility(reg->FACILITY, (Q931_info_t *) reg, &bc->fac_in, nt, bc);
|
||||
}
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Construct a REGISTER message
|
||||
*
|
||||
* \param msgs Search table entry that called us.
|
||||
* \param bc Associated B channel
|
||||
* \param nt TRUE if in NT mode.
|
||||
*
|
||||
* \return Allocated built message
|
||||
*/
|
||||
static msg_t *build_register(struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN;
|
||||
REGISTER_t *reg;
|
||||
msg_t *msg;
|
||||
|
||||
msg = (msg_t *) create_l3msg(CC_REGISTER | REQUEST, MT_REGISTER, bc ? bc->l3_id : -1, sizeof(REGISTER_t), nt);
|
||||
HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
|
||||
reg = (REGISTER_t *) (msg->data + HEADER_LEN);
|
||||
|
||||
if (bc->fac_out.Function != Fac_None) {
|
||||
enc_ie_facility(®->FACILITY, msg, &bc->fac_out, nt);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
|
||||
static void parse_notify (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
|
||||
NOTIFY_t *notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
|
||||
int description_code;
|
||||
int type;
|
||||
int plan;
|
||||
int present;
|
||||
char number[sizeof(bc->redirecting.to.number)];
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Parsing NOTIFY Msg\n");
|
||||
#endif
|
||||
|
||||
dec_ie_notify(notify->NOTIFY, (Q931_info_t *) notify, &description_code, nt, bc);
|
||||
if (description_code < 0) {
|
||||
bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
|
||||
} else {
|
||||
bc->notify_description_code = description_code;
|
||||
}
|
||||
|
||||
dec_ie_redir_dn(notify->REDIR_DN, (Q931_info_t *) notify, &type, &plan, &present, number, sizeof(number), nt, bc);
|
||||
if (0 <= type) {
|
||||
bc->redirecting.to_changed = 1;
|
||||
|
||||
bc->redirecting.to.number_type = type;
|
||||
bc->redirecting.to.number_plan = plan;
|
||||
switch (present) {
|
||||
default:
|
||||
case 0:
|
||||
bc->redirecting.to.presentation = 0; /* presentation allowed */
|
||||
break;
|
||||
case 1:
|
||||
bc->redirecting.to.presentation = 1; /* presentation restricted */
|
||||
break;
|
||||
case 2:
|
||||
bc->redirecting.to.presentation = 2; /* Number not available */
|
||||
break;
|
||||
}
|
||||
bc->redirecting.to.screening = 0; /* Unscreened */
|
||||
strcpy(bc->redirecting.to.number, number);
|
||||
}
|
||||
}
|
||||
|
||||
static msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
|
||||
|
@ -1120,11 +1446,20 @@ static msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, i
|
|||
NOTIFY_t *notify;
|
||||
msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY, bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt);
|
||||
|
||||
notify=(NOTIFY_t*)((msg->data+HEADER_LEN));
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Building NOTIFY Msg\n");
|
||||
#endif
|
||||
|
||||
notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
|
||||
|
||||
enc_ie_notify(¬ify->NOTIFY, msg, bc->notify_description_code, nt, bc);
|
||||
|
||||
if (bc->redirecting.to_changed) {
|
||||
bc->redirecting.to_changed = 0;
|
||||
enc_ie_redir_dn(¬ify->REDIR_DN, msg, bc->redirecting.to.number_type,
|
||||
bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
|
||||
bc->redirecting.to.number, nt, bc);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
@ -1152,11 +1487,11 @@ static msg_t *build_status_enquiry (struct isdn_msg msgs[], struct misdn_bchanne
|
|||
static void parse_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
INFORMATION_t *information=(INFORMATION_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
INFORMATION_t *information = (INFORMATION_t *) (msg->data + HEADER_LEN);
|
||||
int type, plan;
|
||||
|
||||
dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *) information, &type, &plan, bc->info_dad, sizeof(bc->info_dad) - 1, nt, bc);
|
||||
dec_ie_keypad(information->KEYPAD, (Q931_info_t *) information, bc->keypad, sizeof(bc->keypad) - 1, nt, bc);
|
||||
dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *) information, &type, &plan, bc->info_dad, sizeof(bc->info_dad), nt, bc);
|
||||
dec_ie_keypad(information->KEYPAD, (Q931_info_t *) information, bc->keypad, sizeof(bc->keypad), nt, bc);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Parsing INFORMATION Msg\n");
|
||||
|
@ -1191,7 +1526,7 @@ static msg_t *build_information (struct isdn_msg msgs[], struct misdn_bchannel *
|
|||
static void parse_status (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||
{
|
||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
STATUS_t *status=(STATUS_t*)((unsigned long)(msg->data+HEADER_LEN));
|
||||
STATUS_t *status = (STATUS_t *) (msg->data + HEADER_LEN);
|
||||
int location;
|
||||
int cause;
|
||||
|
||||
|
@ -1253,6 +1588,9 @@ struct isdn_msg msgs_g[] = {
|
|||
{ CC_ALERTING, EVENT_ALERTING, parse_alerting, build_alerting, "ALERTING" },
|
||||
{ CC_PROGRESS, EVENT_PROGRESS, parse_progress, build_progress, "PROGRESS" },
|
||||
{ CC_SETUP, EVENT_SETUP, parse_setup, build_setup, "SETUP" },
|
||||
#if defined(AST_MISDN_ENHANCEMENTS)
|
||||
{ CC_REGISTER, EVENT_REGISTER, parse_register, build_register, "REGISTER" },
|
||||
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
|
||||
{ CC_CONNECT, EVENT_CONNECT, parse_connect, build_connect, "CONNECT" },
|
||||
{ CC_SETUP_ACKNOWLEDGE, EVENT_SETUP_ACKNOWLEDGE, parse_setup_acknowledge, build_setup_acknowledge, "SETUP_ACKNOWLEDGE" },
|
||||
{ CC_CONNECT_ACKNOWLEDGE, EVENT_CONNECT_ACKNOWLEDGE, parse_connect_acknowledge, build_connect_acknowledge, "CONNECT_ACKNOWLEDGE " },
|
||||
|
|
|
@ -361,6 +361,8 @@ static const struct misdn_cfg_spec port_spec[] = {
|
|||
"MSN's for TE ports, listen on those numbers on the above ports, and\n"
|
||||
"\tindicate the incoming calls to Asterisk.\n"
|
||||
"\tHere you can give a comma separated list, or simply an '*' for any msn." },
|
||||
{ "cc_request_retention", MISDN_CFG_CC_REQUEST_RETENTION, MISDN_CTYPE_BOOL, "yes", NONE,
|
||||
"Enable/Disable call-completion request retention support (ptp)." },
|
||||
};
|
||||
|
||||
static const struct misdn_cfg_spec gen_spec[] = {
|
||||
|
|
|
@ -161,7 +161,10 @@ context=misdn
|
|||
language=en
|
||||
|
||||
;
|
||||
; sets the musiconhold class
|
||||
; This option specifies a default music on hold class to
|
||||
; use when put on hold if the channel's moh class was not
|
||||
; explicitly set with Set(CHANNEL(musicclass)=whatever) and
|
||||
; the peer channel did not suggest a class to use.
|
||||
;
|
||||
musicclass=default
|
||||
|
||||
|
@ -190,10 +193,10 @@ far_alerting=no
|
|||
;
|
||||
allowed_bearers=all
|
||||
|
||||
; Prefixes for national and international Type-Of-Number. These are
|
||||
; Incoming number prefixes for the indicated Type-Of-Number. These are
|
||||
; inserted before any number (caller, dialed, connected, redirecting,
|
||||
; redirection) received from the ISDN link if that number has the
|
||||
; correspondng Type-Of-Number.
|
||||
; corresponding Type-Of-Number.
|
||||
; See the dialplan options.
|
||||
;
|
||||
; default values:
|
||||
|
@ -456,6 +459,17 @@ max_incoming=-1
|
|||
;
|
||||
max_outgoing=-1
|
||||
|
||||
;
|
||||
; Enable/disable the call-completion retention option support (ptp only).
|
||||
;
|
||||
; Note: To use the CCBS/CCNR supplementary service feature and other
|
||||
; supplementary services using FACILITY messages requires a
|
||||
; modified version of mISDN from:
|
||||
; http://svn.digium.com/svn/thirdparty/mISDN/trunk
|
||||
; http://svn.digium.com/svn/thirdparty/mISDNuser/trunk
|
||||
;
|
||||
cc_request_retention=yes
|
||||
|
||||
[intern]
|
||||
; define your ports, e.g. 1,2 (depends on mISDN-driver loading order)
|
||||
ports=1,2
|
||||
|
|
Reference in New Issue