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: https://origsvn.digium.com/svn/asterisk/trunk@189735 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/1.8.6
Richard Mudgett 17 years ago
parent cf95f3a118
commit 6bb2b6c096

@ -61,7 +61,25 @@ mISDN channel driver (chan_misdn) changes
subscriberprefix, and abbreviatedprefix in misdn.conf to prefix any subscriberprefix, and abbreviatedprefix in misdn.conf to prefix any
received number from the ISDN link if that number has the corresponding received number from the ISDN link if that number has the corresponding
Type-Of-Number. 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 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_EARLY_BCONNECT, /* int (bool) */
MISDN_CFG_INCOMING_EARLY_AUDIO, /* int (bool) */ MISDN_CFG_INCOMING_EARLY_AUDIO, /* int (bool) */
MISDN_CFG_ECHOCANCEL, /* int */ MISDN_CFG_ECHOCANCEL, /* int */
MISDN_CFG_CC_REQUEST_RETENTION,/* bool */
#ifdef MISDN_1_2 #ifdef MISDN_1_2
MISDN_CFG_PIPELINE, /* char[] */ MISDN_CFG_PIPELINE, /* char[] */
#endif #endif

@ -1,4 +1,3 @@
/* /*
* Chan_Misdn -- Channel Driver for Asterisk * Chan_Misdn -- Channel Driver for Asterisk
* *
@ -39,11 +38,11 @@
#define MISDN_IE_DEBG 0 #define MISDN_IE_DEBG 0
/* support stuff */ /* 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) if (len > dst_len-1)
len = dst_len-1; len = dst_len-1;
strncpy((char *)dest, (char *)src, len); strncpy(dest, src, len);
dest[len] = '\0'; 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)); 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; *type = -1;
*plan = -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; *type = -1;
*plan = -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; *type = -1;
*plan = -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) static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, int nt, struct misdn_bchannel *bc)
{ {
unsigned char *p; 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; int l;
if (!display[0]) if (!display[0])
@ -893,27 +892,28 @@ static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, in
return; 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__); l = 80;
display[80] = '\0'; 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) if (nt)
*ntmode = p+1; *ntmode = p + 1;
else 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[0] = IE_DISPLAY;
p[1] = l; p[1] = l;
strncpy((char *)p+2, (char *)display, strlen((char *)display)); strncpy((char *) p + 2, display, l);
} }
#if 0 #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'; *display = '\0';
@ -965,7 +965,7 @@ static void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, char *keypad, int
} }
#endif #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'; *keypad = '\0';
@ -990,7 +990,6 @@ static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, int k
/* IE_NOTIFY */ /* IE_NOTIFY */
#if 0
static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc) static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc)
{ {
unsigned char *p; 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[1] = l;
p[2] = 0x80 + notify; 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) static void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt, struct misdn_bchannel *bc)
{ {
*notify = -1; *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); if (MISDN_IE_DEBG) printf(" notify=%d\n", *notify);
} }
#endif
/* IE_PROGRESS */ /* 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; *type = -1;
*plan = -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) */ /* 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) 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; 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; int l;
if (type<0 || type>7) 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); p = msg_put(msg, l+2);
if (nt) if (nt)
*ntmode = p+1; *ntmode = p+1;
else else {
/* #warning REINSERT redir_dn, when included in te-mode */ qi->QI_ELEMENT(redirect_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t);
/*qi->QI_ELEMENT(redir_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t)*/; }
p[0] = IE_REDIR_DN; p[0] = IE_REDIR_DN;
p[1] = l; p[1] = l;
if (present >= 0) 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)); 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, size_t 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, int number_len, int nt, struct misdn_bchannel *bc)
{ {
*type = -1; *type = -1;
*plan = -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) if (!nt)
{ {
p = NULL; p = NULL;
/* #warning REINSERT redir_dn, when included in te-mode */ if (qi->QI_ELEMENT(redirect_dn))
/* if (qi->QI_ELEMENT(redir_dn)) */ p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_dn) + 1;
/* p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redir_dn) + 1; */
} }
if (!p) if (!p)
return; 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); if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
} }
#endif
/* IE_USERUSER */ /* 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); Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
int l; int l;
char debug[768];
int i;
if (protocol<0 || protocol>127) if (protocol<0 || protocol>127)
{ {
printf("%s: ERROR: protocol(%d) is out of range.\n", __FUNCTION__, protocol); 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; return;
} }
i = 0; if (MISDN_IE_DEBG) {
while(i < user_len) size_t i;
{ char debug[768];
if (MISDN_IE_DEBG) sprintf(debug+(i*3), " %02x", user[i]);
i++;
}
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; l = user_len+1;
p = msg_put(msg, l+3); 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 #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) 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; *user_len = 0;
*protocol = -1; *protocol = -1;
@ -1390,15 +1377,16 @@ static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, ch
*protocol = p[1]; *protocol = p[1];
memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */ memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
i = 0; if (MISDN_IE_DEBG) {
while(i < *user_len) int i;
{ char debug[768];
if (MISDN_IE_DEBG) sprintf(debug+(i*3), " %02x", user[i]);
i++;
}
debug[i*3] = '\0';
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 #endif

File diff suppressed because it is too large Load Diff

@ -133,6 +133,7 @@ enum event_e {
EVENT_PROCEEDING, EVENT_PROCEEDING,
EVENT_PROGRESS, EVENT_PROGRESS,
EVENT_SETUP, EVENT_SETUP,
EVENT_REGISTER,
EVENT_ALERTING, EVENT_ALERTING,
EVENT_CONNECT, EVENT_CONNECT,
EVENT_SETUP_ACKNOWLEDGE, EVENT_SETUP_ACKNOWLEDGE,
@ -216,6 +217,25 @@ enum mISDN_REDIRECTING_REASON {
mISDN_REDIRECTING_REASON_CALL_FWD = 0xF 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*/ enum { /*CODECS*/
INFO_CODEC_ULAW=2, INFO_CODEC_ULAW=2,
INFO_CODEC_ALAW=3 INFO_CODEC_ALAW=3
@ -241,6 +261,21 @@ enum layer_e {
/*! Maximum keypad facility content length plus null terminator */ /*! Maximum keypad facility content length plus null terminator */
#define MISDN_MAX_KEYPAD_LEN (31 + 1) #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 */ /*! \brief Connected-Line/Calling/Redirecting ID info struct */
struct misdn_party_id { struct misdn_party_id {
/*! \brief Number presentation restriction code /*! \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) */ /*! \brief Who is redirecting the call (Sent to the party the call is redirected toward) */
struct misdn_party_id from; 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) */ /*! \brief Reason a call is being redirected (Q.931 field value) */
enum mISDN_REDIRECTING_REASON reason; 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 */ /*! \brief B channel send locking structure */
struct send_lock *send_lock; 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 /*! \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_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 * \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 */ /*! \brief TRUE if the B channel number is preselected */
int channel_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 */ /*! \brief TRUE if B channel record is in use */
int in_use; int in_use;
@ -382,8 +440,6 @@ struct misdn_bchannel {
/*! \brief Not used. Contents are setup but not used. */ /*! \brief Not used. Contents are setup but not used. */
void *astbuf; void *astbuf;
void *misdnbuf; /* Not used */
/*! \brief TRUE if the TE side should choose the B channel to use /*! \brief TRUE if the TE side should choose the B channel to use
* \note This value is user configurable in /etc/asterisk/misdn.conf * \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 */ /*! \brief TRUE if the user set the presentation restriction code */
int set_presentation; int set_presentation;
/*! \brief Notification indicator ie description code */
enum mISDN_NOTIFY_CODE notify_description_code;
/*! \brief SETUP message bearer capability field code value */ /*! \brief SETUP message bearer capability field code value */
int capability; int capability;
@ -560,32 +619,12 @@ struct misdn_bchannel {
int hdlc; int hdlc;
/* V110 */ /* 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. /*! \brief Display message that can be displayed by the user phone.
* \note Maximum displayable length is 34 or 82 octets. * \note Maximum displayable length is 34 or 82 octets.
* It is also settable by the misdn_set_opt() application. * It is also settable by the misdn_set_opt() application.
*/ */
char display[84]; 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 /*! \brief Q.931 Keypad Facility IE contents
* \note Contents exported and imported to Asterisk variable MISDN_KEYPAD * \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); 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); 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_activate(struct misdn_bchannel *bc);
void manager_bchannel_deactivate(struct misdn_bchannel * bc); void manager_bchannel_deactivate(struct misdn_bchannel * bc);

@ -51,7 +51,15 @@ struct isdn_msg {
/* for isdn_msg_parser.c */ /* for isdn_msg_parser.c */
msg_t *create_l3msg(int prim, int mt, int dinfo , int size, int nt); 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 { struct misdn_stack {
/** is first element because &nst equals &mISDNlist **/ /** is first element because &nst equals &mISDNlist **/
@ -87,8 +95,6 @@ struct misdn_stack {
/*! \brief TRUE if Layer 2 is UP */ /*! \brief TRUE if Layer 2 is UP */
int l2link; int l2link;
time_t l2establish; /* Not used */
/*! \brief TRUE if Layer 1 is UP */ /*! \brief TRUE if Layer 1 is UP */
int l1link; int l1link;
@ -105,7 +111,7 @@ struct misdn_stack {
int pri; int pri;
/*! \brief CR Process ID allocation table. TRUE if ID allocated */ /*! \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 */ /*! \brief Queue of Event messages to send to mISDN */
msg_queue_t downqueue; msg_queue_t downqueue;
@ -115,13 +121,17 @@ struct misdn_stack {
/*! \brief Logical Layer 1 port associated with this stack */ /*! \brief Logical Layer 1 port associated with this stack */
int port; 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_list; /* Not used */ */
struct misdn_bchannel bc[MAX_BCHANS + 1 + MISDN_MAX_REGISTER_LINKS];
/*! \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 */ /*! \brief List of holded channels */
struct misdn_bchannel *holding; 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) 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) 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; 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); //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_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 #ifdef DEBUG
printf("Parsing PROCEEDING Msg\n"); printf("Parsing PROCEEDING Msg\n");
@ -124,6 +201,11 @@ static msg_t *build_proceeding (struct isdn_msg msgs[], struct misdn_bchannel *b
if (nt) if (nt)
enc_ie_progress(&proceeding->PROGRESS, msg, 0, nt?1:5, 8, nt,bc); 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 #ifdef DEBUG
printf("Building PROCEEDING Msg\n"); 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) 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; 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); //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); dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)alerting, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
#ifdef DEBUG #ifdef DEBUG
@ -158,6 +244,13 @@ static msg_t *build_alerting (struct isdn_msg msgs[], struct misdn_bchannel *bc,
if (nt) if (nt)
enc_ie_progress(&alerting->PROGRESS, msg, 0, nt?1:5, 8, nt,bc); 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 #ifdef DEBUG
printf("Building ALERTING Msg\n"); printf("Building ALERTING Msg\n");
#endif #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) 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; 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); //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_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 #ifdef DEBUG
printf("Parsing PROGRESS Msg\n"); printf("Parsing PROGRESS Msg\n");
#endif #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)); 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 #ifdef DEBUG
printf("Building PROGRESS Msg\n"); printf("Building PROGRESS Msg\n");
#endif #endif
return msg; 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) 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; int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
SETUP_t *setup= (SETUP_t*)((unsigned long)msg->data+HEADER_LEN); SETUP_t *setup = (SETUP_t *) (msg->data + HEADER_LEN);
Q931_info_t *qi=(Q931_info_t*)((unsigned long)msg->data+HEADER_LEN); Q931_info_t *qi = (Q931_info_t *) (msg->data + HEADER_LEN);
int type; int type;
int plan; int plan;
int present; 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"); printf("Parsing SETUP Msg\n");
#endif #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_type = type;
bc->caller.number_plan = plan; bc->caller.number_plan = plan;
switch (present) { 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 */ 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_type = type;
bc->dialed.number_plan = plan; 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_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_type = type;
bc->redirecting.from.number_plan = plan; bc->redirecting.from.number_plan = plan;
switch (present) { 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); 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' */ #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 else
enc_ie_channel_id(&setup->CHANNEL_ID, msg, 1, bc->channel, nt,bc); 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, 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); 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 (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, 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.presentation, bc->redirecting.from.screening, bc->redirecting.reason,
bc->redirecting.from.number, nt, bc); bc->redirecting.from.number, nt, bc);
#endif
} }
if (bc->keypad[0]) { 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); 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 #ifdef DEBUG
printf("Building SETUP Msg\n"); printf("Building SETUP Msg\n");
#endif #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) 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; 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 type;
int plan; int plan;
int pres; 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_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, 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_type = type;
bc->connected.number_plan = plan; bc->connected.number_plan = plan;
switch (pres) { 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 */ 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); 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 #ifdef DEBUG
printf("Building CONNECT Msg\n"); printf("Building CONNECT Msg\n");
#endif #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) 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; 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; 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_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 #ifdef DEBUG
printf("Parsing SETUP_ACKNOWLEDGE Msg\n"); printf("Parsing SETUP_ACKNOWLEDGE Msg\n");
#endif #endif
@ -528,6 +727,10 @@ static msg_t *build_setup_acknowledge (struct isdn_msg msgs[], struct misdn_bcha
if (nt) if (nt)
enc_ie_progress(&setup_acknowledge->PROGRESS, msg, 0, nt?1:5, 8, nt,bc); 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 #ifdef DEBUG
printf("Building SETUP_ACKNOWLEDGE Msg\n"); printf("Building SETUP_ACKNOWLEDGE Msg\n");
#endif #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) 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; 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 location;
int cause; int cause;
dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &cause, nt,bc); dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &cause, nt,bc);
if (cause>0) bc->cause=cause; 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); dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
#ifdef DEBUG #ifdef DEBUG
printf("Parsing DISCONNECT Msg\n"); 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)); disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN));
enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc); 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) { if (bc->uulen) {
int protocol=4; 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) 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; 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); 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) 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; 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 location;
int cause; int cause;
dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &cause, nt,bc); dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &cause, nt,bc);
if (cause>0) bc->cause=cause; if (cause>0) bc->cause=cause;
dec_ie_facility(release->FACILITY, (Q931_info_t *) release, &bc->fac_in, nt, bc);
#ifdef DEBUG #ifdef DEBUG
printf("Parsing RELEASE Msg\n"); printf("Parsing RELEASE Msg\n");
#endif #endif
@ -968,6 +1182,10 @@ static msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc,
if (bc->out_cause>= 0) if (bc->out_cause>= 0)
enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc); 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) { if (bc->uulen) {
int protocol=4; int protocol=4;
enc_ie_useruser(&release->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc); 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) 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; 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 location;
int cause; int cause;
iframe_t *frm = (iframe_t*) msg->data; 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); dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &cause, nt,bc);
if (cause>0) bc->cause=cause; if (cause>0) bc->cause=cause;
dec_ie_facility(release_complete->FACILITY, (Q931_info_t *) release_complete, &bc->fac_in, nt, bc);
#ifdef DEBUG #ifdef DEBUG
printf("Parsing RELEASE_COMPLETE Msg\n"); printf("Parsing RELEASE_COMPLETE Msg\n");
#endif #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); 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) { if (bc->uulen) {
int protocol=4; int protocol=4;
enc_ie_useruser(&release_complete->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc); 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); FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN); Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
unsigned char *p = NULL; unsigned char *p = NULL;
int err;
#ifdef DEBUG #ifdef DEBUG
printf("Parsing FACILITY Msg\n"); printf("Parsing FACILITY Msg\n");
#endif #endif
bc->fac_in.Function = Fac_None;
if (!bc->nt) { if (!bc->nt) {
if (qi->QI_ELEMENT(facility)) if (qi->QI_ELEMENT(facility))
p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1; 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) if (!p)
return; return;
err = decodeFac(p, &(bc->fac_in)); if (decodeFac(p, &bc->fac_in)) {
if (err) { cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
cb_log(5, bc->port, "Decoding FACILITY failed! (%d)\n", err);
} }
} }
@ -1079,7 +1303,11 @@ static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc,
len = encodeFac(fac_tmp, &(bc->fac_out)); len = encodeFac(fac_tmp, &(bc->fac_out));
if (len <= 0) { 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; 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); memcpy(ie_fac, fac_tmp, len);
/* Clear facility information */
bc->fac_out.Function = Fac_None;
if (*bc->display) { if (*bc->display) {
#ifdef DEBUG #ifdef DEBUG
printf("Sending %s as Display\n", bc->display); 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; 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(&reg->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) 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 #ifdef DEBUG
printf("Parsing NOTIFY Msg\n"); printf("Parsing NOTIFY Msg\n");
#endif #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) 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; NOTIFY_t *notify;
msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY, bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt); 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 #ifdef DEBUG
printf("Building NOTIFY Msg\n"); printf("Building NOTIFY Msg\n");
#endif #endif
notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
enc_ie_notify(&notify->NOTIFY, msg, bc->notify_description_code, nt, bc);
if (bc->redirecting.to_changed) {
bc->redirecting.to_changed = 0;
enc_ie_redir_dn(&notify->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; 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) 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; 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; 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_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) - 1, nt, bc); dec_ie_keypad(information->KEYPAD, (Q931_info_t *) information, bc->keypad, sizeof(bc->keypad), nt, bc);
#ifdef DEBUG #ifdef DEBUG
printf("Parsing INFORMATION Msg\n"); 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) 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; 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 location;
int cause; int cause;
@ -1253,6 +1588,9 @@ struct isdn_msg msgs_g[] = {
{ CC_ALERTING, EVENT_ALERTING, parse_alerting, build_alerting, "ALERTING" }, { CC_ALERTING, EVENT_ALERTING, parse_alerting, build_alerting, "ALERTING" },
{ CC_PROGRESS, EVENT_PROGRESS, parse_progress, build_progress, "PROGRESS" }, { CC_PROGRESS, EVENT_PROGRESS, parse_progress, build_progress, "PROGRESS" },
{ CC_SETUP, EVENT_SETUP, parse_setup, build_setup, "SETUP" }, { 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_CONNECT, EVENT_CONNECT, parse_connect, build_connect, "CONNECT" },
{ CC_SETUP_ACKNOWLEDGE, EVENT_SETUP_ACKNOWLEDGE, parse_setup_acknowledge, build_setup_acknowledge, "SETUP_ACKNOWLEDGE" }, { 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 " }, { 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" "MSN's for TE ports, listen on those numbers on the above ports, and\n"
"\tindicate the incoming calls to Asterisk.\n" "\tindicate the incoming calls to Asterisk.\n"
"\tHere you can give a comma separated list, or simply an '*' for any msn." }, "\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[] = { static const struct misdn_cfg_spec gen_spec[] = {

@ -161,7 +161,10 @@ context=misdn
language=en 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 musicclass=default
@ -190,10 +193,10 @@ far_alerting=no
; ;
allowed_bearers=all 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, ; inserted before any number (caller, dialed, connected, redirecting,
; redirection) received from the ISDN link if that number has the ; redirection) received from the ISDN link if that number has the
; correspondng Type-Of-Number. ; corresponding Type-Of-Number.
; See the dialplan options. ; See the dialplan options.
; ;
; default values: ; default values:
@ -456,6 +459,17 @@ max_incoming=-1
; ;
max_outgoing=-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] [intern]
; define your ports, e.g. 1,2 (depends on mISDN-driver loading order) ; define your ports, e.g. 1,2 (depends on mISDN-driver loading order)
ports=1,2 ports=1,2

Loading…
Cancel
Save