Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c286f741be | ||
|
|
183cd86a8d | ||
|
|
c955ba2510 | ||
|
|
a0c05f9908 | ||
|
|
9b5066cc78 | ||
|
|
9648194287 | ||
|
|
ff36053fdd | ||
|
|
d9276a9c5e | ||
|
|
c3cc1ed5b0 | ||
|
|
cd8d727df8 | ||
|
|
4e591eb689 | ||
|
|
eb0586daa1 |
157
ChangeLog
157
ChangeLog
@@ -1,3 +1,160 @@
|
||||
2010-08-30 Leif Madsen <lmadsen@digium.com>
|
||||
|
||||
* libpri 1.4.11.4 released.
|
||||
|
||||
2010-08-30 22:34 +0000 [r1939-1949] Richard Mudgett <rmudgett@digium.com>
|
||||
|
||||
* q931.c, q921.c: Merged revisions 1923,1928-1929 via svnmerge from
|
||||
https://origsvn.digium.com/svn/libpri/branches/1.4 ........ r1923
|
||||
| rmudgett | 2010-08-30 14:31:46 -0500 (Mon, 30 Aug 2010) | 18
|
||||
lines Q.921 improvements from comparing Q.921 SDL diagrams with
|
||||
implementation. * Handle sending and receiving DM response frames
|
||||
as needed. * Added handling of received FRMR frames. * Completed
|
||||
implementation of Q921_AWAITING_RELEASE state. (State is
|
||||
currently unreachable since we have no API to initiate sending
|
||||
the DISC message.) * Better NT PTMP TEI allocation. * Reduced
|
||||
more ERROR level severity messages so users will stop panicking
|
||||
when they see ERROR. This is especially true for the Q.921
|
||||
MDL-ERROR messages. * Added better Q.921 visibility when normal
|
||||
debug message level is enabled. ........ r1928 | rmudgett |
|
||||
2010-08-30 15:30:59 -0500 (Mon, 30 Aug 2010) | 9 lines
|
||||
Q.921/Q.931 message debug output improvements. The Q.931 message
|
||||
decode debug output now will follow the correct Q.921 header
|
||||
decode if Q.921 message dumping is enabled. Also the Q.931
|
||||
message decode will happen when the message actually goes out on
|
||||
the line instead of when Q.931 passes the message to Q.921. Q.921
|
||||
may have to request a TEI, bring the connection up, or retransmit
|
||||
previous frames before it can actually send the new message.
|
||||
........ r1929 | rmudgett | 2010-08-30 15:49:11 -0500 (Mon, 30
|
||||
Aug 2010) | 2 lines Reduced fake MDL-ERROR (Z) message severity
|
||||
to be visible only when debugging enabled. ........
|
||||
|
||||
* q921.c: Merged revisions 1918 via svnmerge from
|
||||
https://origsvn.digium.com/svn/libpri/branches/1.4 ........ r1918
|
||||
| rmudgett | 2010-08-30 12:53:33 -0500 (Mon, 30 Aug 2010) | 41
|
||||
lines ISDN BRI does not recover from line faults Q.921 was
|
||||
getting stuck in state 2 (Q921_ASSIGN_AWAITING_TEI). For some
|
||||
reason the network was removing the TEI. Libpri then immediately
|
||||
tried to get a new TEI assigned. The network did not reply to the
|
||||
N202(3) attempts to get a new TEI. Libpri then just gave up
|
||||
trying but did not leave the state. Some paths in Q.921 Figure
|
||||
B.3 were not implemented. Q.921 now transitions to the
|
||||
Q921_TEI_UNASSIGNED state when the N202 count is exceeded. Q.921
|
||||
will wait there until an incoming or outgoing call is attempted.
|
||||
* Fixed initializing the n202_counter. Not initializing the
|
||||
n202_counter would cause the Q921_TEI_IDENTITY_REQUEST to
|
||||
unexpectedly not go out and due to how state transitions were
|
||||
done, Q.921 would get stuck in the Q921_ASSIGN_AWAITING_TEI
|
||||
state. * Fixed start T202 timer fail causing Q.921 to get stuck
|
||||
in the Q921_ASSIGN_AWAITING_TEI state if the network did not
|
||||
respond to the request. * Fixed handling of
|
||||
Q921_TEI_IDENTITY_REMOVE to do the MDL-REMOVE primitive
|
||||
(q921_mdl_remove()) instead of transitioning directly to the
|
||||
Q921_TEI_UNASSIGNED state. Necessary state clean-up was not
|
||||
getting done. * Minor tweaks to q921_mdl_remove(). The worst
|
||||
problem was erroneously generating an error message. * Fixed
|
||||
potential for sending I-frames with an invalid TEI. The I-frame
|
||||
could have been queued when Q.921 did not have an assigned TEI. *
|
||||
Fixed testing of the q931_receive() return value when a UI-frame
|
||||
is received. (closes issue #17570) Reported by: jcovert Patches:
|
||||
issue17570_v1.4.11.3_v3.patch uploaded by rmudgett (license 664)
|
||||
issue17570_v1.4_v3.patch uploaded by rmudgett (license 664)
|
||||
Tested by: jcovert, rmudgett ........
|
||||
|
||||
* rose.c, rosetest.c: Merged revisions 1904 via svnmerge from
|
||||
https://origsvn.digium.com/svn/libpri/branches/1.4 ........ r1904
|
||||
| rmudgett | 2010-08-27 10:54:17 -0500 (Fri, 27 Aug 2010) | 15
|
||||
lines Add support to receive ECMA-164 2nd edition OID name ROSE
|
||||
messages. NOTE: To add support to send the old style name
|
||||
messages will require implementing them as new ROSE operation
|
||||
message types. NOTE: To actually use them would likely require
|
||||
implementing another version of the Q.SIG switch type. Like (NI1
|
||||
& NI2) and (4ess & 5ess) for example. Patches: libpri37.patch
|
||||
uploaded by rmudgett (license 664) JIRA SWP-2100 JIRA LIBPRI-37
|
||||
........
|
||||
|
||||
* rosetest.c, pri.c, q921.c: Merged revisions 1878,1883-1884,1894
|
||||
via svnmerge from
|
||||
https://origsvn.digium.com/svn/libpri/branches/1.4 ........ r1878
|
||||
| mattf | 2010-08-23 17:13:44 -0500 (Mon, 23 Aug 2010) | 1 line
|
||||
Add silly fake MDL error Z for kicking L2 to reactivate if a DISC
|
||||
or DM is received in proper states on PTP links. ........ r1883 |
|
||||
rmudgett | 2010-08-25 11:38:29 -0500 (Wed, 25 Aug 2010) | 2 lines
|
||||
Don't silently fail to post our fake MDL-ERROR(Z). ........ r1884
|
||||
| rmudgett | 2010-08-25 12:17:09 -0500 (Wed, 25 Aug 2010) | 2
|
||||
lines Added gripe check to rosetest for invalid operation and
|
||||
error codes. ........ r1894 | rmudgett | 2010-08-26 18:26:16
|
||||
-0500 (Thu, 26 Aug 2010) | 1 line Make pri_dump_event() only
|
||||
print the event name. ........
|
||||
|
||||
* q931.c: Merged revisions 1853 via svnmerge from
|
||||
https://origsvn.digium.com/svn/libpri/branches/1.4 ........ r1853
|
||||
| rmudgett | 2010-08-06 13:35:35 -0500 (Fri, 06 Aug 2010) | 18
|
||||
lines No audio on inbound J1 calls. Incoming calls specifying the
|
||||
channel using a slot map could not negotiate a B channel
|
||||
correctly. Libpri historically has handled this as an any channel
|
||||
request. However, when chan_dahdi picked a new channel, libpri
|
||||
sent out the recorded slot map and not the new channel selected.
|
||||
Thus the two endpoints would be attached to different B channels
|
||||
and the parties would not hear anything or would hear the wrong
|
||||
parties. This patch restores the historical preference of sending
|
||||
out the channel id using the channel number method if a channel
|
||||
number is available. JIRA LIBPRI-35 Patches:
|
||||
libpri-35_v1.4.11.3.patch uploaded by rmudgett (license 664)
|
||||
libpri-35_v1.4.patch uploaded by rmudgett (license 664) Tested
|
||||
by: rmudgett ........
|
||||
|
||||
* q931.c, q921.c: Merged revisions 1848,1852 via svnmerge from
|
||||
https://origsvn.digium.com/svn/libpri/branches/1.4 ........ r1848
|
||||
| rmudgett | 2010-08-03 18:04:52 -0500 (Tue, 03 Aug 2010) | 11
|
||||
lines Improved Q.921/Q.931 debug output. * Debug output for a
|
||||
sent Q.931 message in TE PTMP now uses the best available TEI
|
||||
number instead of always using 127. It could still be wrong if
|
||||
layer 2 does not have a TEI assigned. * Q.921 debug output is
|
||||
grouped better so a decoded message is not split by a blank line.
|
||||
* The Q.921 state is also decoded to a name. ........ r1852 |
|
||||
rmudgett | 2010-08-06 13:22:39 -0500 (Fri, 06 Aug 2010) | 1 line
|
||||
Learn (AGAIN!) why state 7 and state 8 transitions were
|
||||
suppressed. ........
|
||||
|
||||
* q921.c: Merged revisions 1845 via svnmerge from
|
||||
https://origsvn.digium.com/svn/libpri/branches/1.4 ........ r1845
|
||||
| rmudgett | 2010-08-03 12:33:54 -0500 (Tue, 03 Aug 2010) | 10
|
||||
lines Q921_TIMER_RECOVERY SDL issue in q921_rnr_rx() Added
|
||||
missing code specified by Q.921 (Figure B.8 Page 85) when receive
|
||||
RNR in "Timer Recovery" state. (closes issue #16791) Reported by:
|
||||
alecdavis Patches: rnr_timer_recovery.diff.txt uploaded by
|
||||
alecdavis (license 585) ........
|
||||
|
||||
* rosetest.c, q921.c: Merged revisions 1829-1830,1842 via svnmerge
|
||||
from https://origsvn.digium.com/svn/libpri/branches/1.4 ........
|
||||
r1829 | rmudgett | 2010-07-16 12:15:07 -0500 (Fri, 16 Jul 2010) |
|
||||
1 line Added a libpri version output line as a sanity check for
|
||||
rosetest. ........ r1830 | rmudgett | 2010-07-16 12:20:21 -0500
|
||||
(Fri, 16 Jul 2010) | 1 line Only need to output one version of
|
||||
the version message. ........ r1842 | rmudgett | 2010-08-02
|
||||
13:47:10 -0500 (Mon, 02 Aug 2010) | 5 lines Renamed local struct
|
||||
pri *pri variables to struct pri *ctrl in q921.c. The context
|
||||
tagging for my editor is much happier now that the struct and the
|
||||
variable do not have the same name. (At least for this file.)
|
||||
........
|
||||
|
||||
* rosetest.c, rose_qsig_name.c: Merged revisions 1828 via svnmerge
|
||||
from https://origsvn.digium.com/svn/libpri/branches/1.4 ........
|
||||
r1828 | rmudgett | 2010-07-16 11:37:07 -0500 (Fri, 16 Jul 2010) |
|
||||
18 lines Calling name not successfully processed on inbound QSIG
|
||||
PRI calls from Mitel PBX The alternate form of the Q.SIG Name
|
||||
sequence that allows manufacturer extensions for CallingName,
|
||||
CalledName, ConnectedName, and BusyName was not consuming the
|
||||
next ASN.1 tag. The code that processed the ASN.1 Name structure
|
||||
was then using a stale tag value. The stale tag value was then
|
||||
rejected with the "Did not expect" message. I have added a test
|
||||
case using the supplied PRI debug output to the rosetest utility
|
||||
to verify that this alternate encoding is tested in the future.
|
||||
(closes issue #17619) Reported by: jims8650 Patches:
|
||||
issue17619_v1.4.11.3.patch uploaded by rmudgett (license 664)
|
||||
Tested by: rmudgett ........
|
||||
|
||||
2010-06-29 Leif Madsen <lmadsen@digium.com>
|
||||
|
||||
* libpri 1.4.11.3 released.
|
||||
|
||||
72
pri.c
72
pri.c
@@ -434,32 +434,32 @@ char *pri_event2str(int id)
|
||||
char *name;
|
||||
} events[] = {
|
||||
/* *INDENT-OFF* */
|
||||
{ PRI_EVENT_DCHAN_UP, "D-Channel Up" },
|
||||
{ PRI_EVENT_DCHAN_DOWN, "D-channel Down" },
|
||||
{ PRI_EVENT_RESTART, "Restart channel" },
|
||||
{ PRI_EVENT_CONFIG_ERR, "Configuration Error" },
|
||||
{ PRI_EVENT_RING, "Ring" },
|
||||
{ PRI_EVENT_HANGUP, "Hangup" },
|
||||
{ PRI_EVENT_RINGING, "Ringing" },
|
||||
{ PRI_EVENT_ANSWER, "Answer" },
|
||||
{ PRI_EVENT_HANGUP_ACK, "Hangup ACK" },
|
||||
{ PRI_EVENT_RESTART_ACK, "Restart ACK" },
|
||||
{ PRI_EVENT_FACILITY, "Facility" },
|
||||
{ PRI_EVENT_INFO_RECEIVED, "Info Received" },
|
||||
{ PRI_EVENT_PROCEEDING, "Proceeding" },
|
||||
{ PRI_EVENT_SETUP_ACK, "Setup ACK" },
|
||||
{ PRI_EVENT_HANGUP_REQ, "Hangup Req" },
|
||||
{ PRI_EVENT_NOTIFY, "Notify" },
|
||||
{ PRI_EVENT_PROGRESS, "Progress" },
|
||||
{ PRI_EVENT_KEYPAD_DIGIT, "Keypad Digit" },
|
||||
{ PRI_EVENT_SERVICE, "Service" },
|
||||
{ PRI_EVENT_SERVICE_ACK, "Service ACK" },
|
||||
{ PRI_EVENT_HOLD, "Hold" },
|
||||
{ PRI_EVENT_HOLD_ACK, "Hold Ack" },
|
||||
{ PRI_EVENT_HOLD_REJ, "Hold Rej" },
|
||||
{ PRI_EVENT_RETRIEVE, "Retrieve" },
|
||||
{ PRI_EVENT_RETRIEVE_ACK, "Retrieve ACK" },
|
||||
{ PRI_EVENT_RETRIEVE_REJ, "Retrieve Rej" },
|
||||
{ PRI_EVENT_DCHAN_UP, "PRI_EVENT_DCHAN_UP" },
|
||||
{ PRI_EVENT_DCHAN_DOWN, "PRI_EVENT_DCHAN_DOWN" },
|
||||
{ PRI_EVENT_RESTART, "PRI_EVENT_RESTART" },
|
||||
{ PRI_EVENT_CONFIG_ERR, "PRI_EVENT_CONFIG_ERR" },
|
||||
{ PRI_EVENT_RING, "PRI_EVENT_RING" },
|
||||
{ PRI_EVENT_HANGUP, "PRI_EVENT_HANGUP" },
|
||||
{ PRI_EVENT_RINGING, "PRI_EVENT_RINGING" },
|
||||
{ PRI_EVENT_ANSWER, "PRI_EVENT_ANSWER" },
|
||||
{ PRI_EVENT_HANGUP_ACK, "PRI_EVENT_HANGUP_ACK" },
|
||||
{ PRI_EVENT_RESTART_ACK, "PRI_EVENT_RESTART_ACK" },
|
||||
{ PRI_EVENT_FACILITY, "PRI_EVENT_FACILITY" },
|
||||
{ PRI_EVENT_INFO_RECEIVED, "PRI_EVENT_INFO_RECEIVED" },
|
||||
{ PRI_EVENT_PROCEEDING, "PRI_EVENT_PROCEEDING" },
|
||||
{ PRI_EVENT_SETUP_ACK, "PRI_EVENT_SETUP_ACK" },
|
||||
{ PRI_EVENT_HANGUP_REQ, "PRI_EVENT_HANGUP_REQ" },
|
||||
{ PRI_EVENT_NOTIFY, "PRI_EVENT_NOTIFY" },
|
||||
{ PRI_EVENT_PROGRESS, "PRI_EVENT_PROGRESS" },
|
||||
{ PRI_EVENT_KEYPAD_DIGIT, "PRI_EVENT_KEYPAD_DIGIT" },
|
||||
{ PRI_EVENT_SERVICE, "PRI_EVENT_SERVICE" },
|
||||
{ PRI_EVENT_SERVICE_ACK, "PRI_EVENT_SERVICE_ACK" },
|
||||
{ PRI_EVENT_HOLD, "PRI_EVENT_HOLD" },
|
||||
{ PRI_EVENT_HOLD_ACK, "PRI_EVENT_HOLD_ACK" },
|
||||
{ PRI_EVENT_HOLD_REJ, "PRI_EVENT_HOLD_REJ" },
|
||||
{ PRI_EVENT_RETRIEVE, "PRI_EVENT_RETRIEVE" },
|
||||
{ PRI_EVENT_RETRIEVE_ACK, "PRI_EVENT_RETRIEVE_ACK" },
|
||||
{ PRI_EVENT_RETRIEVE_REJ, "PRI_EVENT_RETRIEVE_REJ" },
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
@@ -1019,26 +1019,6 @@ void pri_dump_event(struct pri *pri, pri_event *e)
|
||||
if (!pri || !e)
|
||||
return;
|
||||
pri_message(pri, "Event type: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
|
||||
switch(e->gen.e) {
|
||||
case PRI_EVENT_DCHAN_UP:
|
||||
case PRI_EVENT_DCHAN_DOWN:
|
||||
break;
|
||||
case PRI_EVENT_CONFIG_ERR:
|
||||
pri_message(pri, "Error: %s", e->err.err);
|
||||
break;
|
||||
case PRI_EVENT_RESTART:
|
||||
pri_message(pri, "Restart on channel %d\n", e->restart.channel);
|
||||
case PRI_EVENT_RING:
|
||||
pri_message(pri, "Calling number: %s (%s, %s)\n", e->ring.callingnum, pri_plan2str(e->ring.callingplan), pri_pres2str(e->ring.callingpres));
|
||||
pri_message(pri, "Called number: %s (%s)\n", e->ring.callednum, pri_plan2str(e->ring.calledplan));
|
||||
pri_message(pri, "Channel: %d (%s) Reference number: %d\n", e->ring.channel, e->ring.flexible ? "Flexible" : "Not Flexible", e->ring.cref);
|
||||
break;
|
||||
case PRI_EVENT_HANGUP:
|
||||
pri_message(pri, "Hangup, reference number: %d, reason: %s\n", e->hangup.cref, pri_cause2str(e->hangup.cause));
|
||||
break;
|
||||
default:
|
||||
pri_message(pri, "Don't know how to dump events of type %d\n", e->gen.e);
|
||||
}
|
||||
}
|
||||
|
||||
static void pri_sr_init(struct pri_sr *req)
|
||||
|
||||
192
q931.c
192
q931.c
@@ -885,7 +885,12 @@ static int receive_channel_id(int full_ie, struct pri *ctrl, q931_call *call, in
|
||||
return -1;
|
||||
}
|
||||
if (ie->data[pos] & 0x10) {
|
||||
/* Expect Slot Map */
|
||||
/*
|
||||
* Expect Slot Map
|
||||
* Note that we are assuming only T1's use slot maps which is wrong
|
||||
* but oh well... We would need to know what type of line we are
|
||||
* connected with (T1 or E1) to interpret the map correctly anyway.
|
||||
*/
|
||||
call->slotmap = 0;
|
||||
pos++;
|
||||
for (x=0;x<3;x++) {
|
||||
@@ -963,22 +968,26 @@ static int transmit_channel_id(int full_ie, struct pri *ctrl, q931_call *call, i
|
||||
&& !(call->chanflags & FLAG_WHOLE_INTERFACE)) {
|
||||
/* The 3.2 and 3.3 octets need to be present */
|
||||
ie->data[pos] = 0x83;
|
||||
if (call->slotmap != -1) {
|
||||
int octet;
|
||||
|
||||
/* We have to send a channel map */
|
||||
ie->data[pos++] |= 0x10;
|
||||
for (octet = 3; octet--;) {
|
||||
ie->data[pos++] = (call->slotmap >> (8 * octet)) & 0xff;
|
||||
}
|
||||
} else {
|
||||
/* Channel number specified */
|
||||
if (0 < call->channelno && call->channelno != 0xff) {
|
||||
/* Channel number specified and preferred over slot map if we have one. */
|
||||
++pos;
|
||||
if (ctrl->chan_mapping_logical && call->channelno > 16) {
|
||||
ie->data[pos++] = 0x80 | (call->channelno - 1);
|
||||
} else {
|
||||
ie->data[pos++] = 0x80 | call->channelno;
|
||||
}
|
||||
} else if (call->slotmap != -1) {
|
||||
int octet;
|
||||
|
||||
/* We have to send a slot map */
|
||||
ie->data[pos++] |= 0x10;
|
||||
for (octet = 3; octet--;) {
|
||||
ie->data[pos++] = (call->slotmap >> (8 * octet)) & 0xff;
|
||||
}
|
||||
} else {
|
||||
pri_error(ctrl, "XXX We need either a channelno or slotmap but have neither!\n");
|
||||
/* Discard this malformed ie. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3915,6 +3924,85 @@ static char *disc2str(int disc)
|
||||
return code2str(disc, discs, sizeof(discs) / sizeof(discs[0]));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Dump the Q.931 message header.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param tei TEI the packet is associated with.
|
||||
* \param h Q.931 packet contents/header.
|
||||
* \param len Received length of the Q.931 packet.
|
||||
* \param c Message direction prefix character.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int q931_dump_header(struct pri *ctrl, int tei, q931_h *h, int len, char c)
|
||||
{
|
||||
q931_mh *mh;
|
||||
int cref;
|
||||
|
||||
pri_message(ctrl, "%c Protocol Discriminator: %s (%d) len=%d\n", c, disc2str(h->pd), h->pd, len);
|
||||
|
||||
if (len < 2 || len < 2 + h->crlen) {
|
||||
pri_message(ctrl, "%c Message too short for call reference. len=%d\n",
|
||||
c, len);
|
||||
return -1;
|
||||
}
|
||||
cref = q931_cr(h);
|
||||
pri_message(ctrl, "%c TEI=%d Call Ref: len=%2d (reference %d/0x%X) (%s)\n",
|
||||
c, tei, h->crlen, cref & ~Q931_CALL_REFERENCE_FLAG,
|
||||
cref & ~Q931_CALL_REFERENCE_FLAG, (cref == Q931_DUMMY_CALL_REFERENCE)
|
||||
? "Dummy"
|
||||
: (cref & Q931_CALL_REFERENCE_FLAG)
|
||||
? "Sent to originator" : "Sent from originator");
|
||||
|
||||
if (len < 3 + h->crlen) {
|
||||
pri_message(ctrl, "%c Message too short for supported protocols. len=%d\n",
|
||||
c, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Message header begins at the end of the call reference number */
|
||||
mh = (q931_mh *)(h->contents + h->crlen);
|
||||
switch (h->pd) {
|
||||
case MAINTENANCE_PROTOCOL_DISCRIMINATOR_1:
|
||||
case MAINTENANCE_PROTOCOL_DISCRIMINATOR_2:
|
||||
pri_message(ctrl, "%c Message Type: %s (%d)\n", c, maintenance_msg2str(mh->msg, h->pd), mh->msg);
|
||||
break;
|
||||
default:
|
||||
/* Unknown protocol discriminator but we will treat it as Q.931 anyway. */
|
||||
case GR303_PROTOCOL_DISCRIMINATOR:
|
||||
case Q931_PROTOCOL_DISCRIMINATOR:
|
||||
pri_message(ctrl, "%c Message Type: %s (%d)\n", c, msg2str(mh->msg), mh->msg);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Q.931 is passing this message to Q.921 debug indication.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param tei TEI the packet is associated with.
|
||||
* \param h Q.931 packet contents/header.
|
||||
* \param len Received length of the Q.931 packet
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void q931_to_q921_passing_dump(struct pri *ctrl, int tei, q931_h *h, int len)
|
||||
{
|
||||
char c;
|
||||
|
||||
c = '>';
|
||||
|
||||
pri_message(ctrl, "\n");
|
||||
pri_message(ctrl, "%c DL-DATA request\n", c);
|
||||
q931_dump_header(ctrl, tei, h, len, c);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Debug dump the given Q.931 packet.
|
||||
*
|
||||
@@ -3934,46 +4022,19 @@ void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx)
|
||||
int r;
|
||||
int cur_codeset;
|
||||
int codeset;
|
||||
int cref;
|
||||
|
||||
c = txrx ? '>' : '<';
|
||||
|
||||
pri_message(ctrl, "%c Protocol Discriminator: %s (%d) len=%d\n", c, disc2str(h->pd), h->pd, len);
|
||||
|
||||
if (len < 2 || len < 2 + h->crlen) {
|
||||
pri_message(ctrl, "%c Message too short for call reference. len=%d\n",
|
||||
c, len);
|
||||
return;
|
||||
if (!(ctrl->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))) {
|
||||
/* Put out a blank line if Q.921 is not dumping. */
|
||||
pri_message(ctrl, "\n");
|
||||
}
|
||||
cref = q931_cr(h);
|
||||
pri_message(ctrl, "%c TEI=%d Call Ref: len=%2d (reference %d/0x%X) (%s)\n",
|
||||
c, tei, h->crlen, cref & ~Q931_CALL_REFERENCE_FLAG,
|
||||
cref & ~Q931_CALL_REFERENCE_FLAG, (cref == Q931_DUMMY_CALL_REFERENCE)
|
||||
? "Dummy"
|
||||
: (cref & Q931_CALL_REFERENCE_FLAG)
|
||||
? "Sent to originator" : "Sent from originator");
|
||||
|
||||
if (len < 3 + h->crlen) {
|
||||
pri_message(ctrl, "%c Message too short for supported protocols. len=%d\n",
|
||||
c, len);
|
||||
if (q931_dump_header(ctrl, tei, h, len, c)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Message header begins at the end of the call reference number */
|
||||
mh = (q931_mh *)(h->contents + h->crlen);
|
||||
switch (h->pd) {
|
||||
case MAINTENANCE_PROTOCOL_DISCRIMINATOR_1:
|
||||
case MAINTENANCE_PROTOCOL_DISCRIMINATOR_2:
|
||||
pri_message(ctrl, "%c Message Type: %s (%d)\n", c, maintenance_msg2str(mh->msg, h->pd), mh->msg);
|
||||
break;
|
||||
default:
|
||||
/* Unknown protocol discriminator but we will treat it as Q.931 anyway. */
|
||||
case GR303_PROTOCOL_DISCRIMINATOR:
|
||||
case Q931_PROTOCOL_DISCRIMINATOR:
|
||||
pri_message(ctrl, "%c Message Type: %s (%d)\n", c, msg2str(mh->msg), mh->msg);
|
||||
break;
|
||||
}
|
||||
/* Drop length of header, including call reference */
|
||||
mh = (q931_mh *)(h->contents + h->crlen);
|
||||
len -= (h->crlen + 3);
|
||||
codeset = cur_codeset = 0;
|
||||
for (x = 0; x < len; x += r) {
|
||||
@@ -4067,19 +4128,32 @@ static void init_header(struct pri *ctrl, q931_call *call, unsigned char *buf, q
|
||||
|
||||
static int q931_xmit(struct pri *ctrl, int tei, q931_h *h, int len, int cr, int uiframe)
|
||||
{
|
||||
if (uiframe) {
|
||||
q921_transmit_uiframe(ctrl, h, len);
|
||||
} else {
|
||||
q921_transmit_iframe(ctrl, tei, h, len, cr);
|
||||
}
|
||||
/* The transmit operation might dump the q921 header, so logging the q931
|
||||
message body after the transmit puts the sections of the message in the
|
||||
right order in the log */
|
||||
if (ctrl->debug & PRI_DEBUG_Q931_DUMP)
|
||||
q931_dump(ctrl, tei, h, len, 1);
|
||||
#ifdef LIBPRI_COUNTERS
|
||||
ctrl->q931_txcount++;
|
||||
#endif
|
||||
if (uiframe) {
|
||||
q921_transmit_uiframe(ctrl, h, len);
|
||||
if (ctrl->debug & PRI_DEBUG_Q931_DUMP) {
|
||||
/*
|
||||
* The transmit operation might dump the Q.921 header, so logging
|
||||
* the Q.931 message body after the transmit puts the sections of
|
||||
* the message in the right order in the log,
|
||||
*/
|
||||
q931_dump(ctrl, tei, h, len, 1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Indicate passing the Q.931 message to Q.921 first. Q.921 may
|
||||
* have to request a TEI or bring the connection up before it can
|
||||
* actually send the message. Therefore, the Q.931 message may
|
||||
* actually get sent a few seconds later. Q.921 will dump the
|
||||
* Q.931 message as appropriate at that time.
|
||||
*/
|
||||
if (ctrl->debug & PRI_DEBUG_Q931_DUMP) {
|
||||
q931_to_q921_passing_dump(ctrl, tei, h, len);
|
||||
}
|
||||
q921_transmit_iframe(ctrl, tei, h, len, cr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4109,6 +4183,7 @@ static int send_message(struct pri *ctrl, q931_call *call, int msgtype, int ies[
|
||||
int x;
|
||||
int codeset;
|
||||
int uiframe;
|
||||
int tei;
|
||||
|
||||
if (call->outboundbroadcast && call->master_call == call && msgtype != Q931_SETUP) {
|
||||
pri_error(ctrl,
|
||||
@@ -4137,6 +4212,7 @@ static int send_message(struct pri *ctrl, q931_call *call, int msgtype, int ies[
|
||||
/* Invert the logic */
|
||||
len = sizeof(buf) - len;
|
||||
|
||||
tei = call->pri->tei;
|
||||
uiframe = 0;
|
||||
if (BRI_NT_PTMP(ctrl)) {
|
||||
/* NT PTMP is the only mode that can broadcast Q.931 messages. */
|
||||
@@ -4153,7 +4229,7 @@ static int send_message(struct pri *ctrl, q931_call *call, int msgtype, int ies[
|
||||
uiframe = 1;
|
||||
break;
|
||||
case Q931_FACILITY:
|
||||
if (call->pri->tei == Q921_TEI_GROUP) {
|
||||
if (tei == Q921_TEI_GROUP) {
|
||||
/* Broadcast TEI. */
|
||||
if (q931_is_dummy_call(call)) {
|
||||
/*
|
||||
@@ -4178,8 +4254,14 @@ static int send_message(struct pri *ctrl, q931_call *call, int msgtype, int ies[
|
||||
"Sending message for call %p on call->pri: %p with TEI/SAPI %d/%d\n",
|
||||
call, call->pri, call->pri->tei, call->pri->sapi);
|
||||
}
|
||||
} else if (call->pri->subchannel && BRI_TE_PTMP(ctrl)) {
|
||||
/*
|
||||
* Get the best available TEI value for the debug dump display.
|
||||
* We may not actually have a TEI assigned at the moment.
|
||||
*/
|
||||
tei = call->pri->subchannel->tei;
|
||||
}
|
||||
q931_xmit(call->pri, call->pri->tei, h, len, 1, uiframe);
|
||||
q931_xmit(call->pri, tei, h, len, 1, uiframe);
|
||||
call->acked = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
45
rose.c
45
rose.c
@@ -470,6 +470,21 @@ static const struct rose_convert_error rose_etsi_errors[] = {
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/*
|
||||
* Note the first value in oid.values[] is really the first two
|
||||
* OID subidentifiers. They are compressed using this formula:
|
||||
* First_Value = (First_Subidentifier * 40) + Second_Subidentifier
|
||||
*/
|
||||
|
||||
/*! \brief ECMA private-isdn-signalling-domain prefix. */
|
||||
static const struct asn1_oid rose_qsig_isdn_domain = {
|
||||
/* *INDENT-OFF* */
|
||||
/* {iso(1) identified-organization(3) icd-ecma(12) private-isdn-signalling-domain(9)} */
|
||||
3, { 43, 12, 9 }
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
|
||||
/*! \brief Q.SIG specific invoke/result encode/decode message table */
|
||||
static const struct rose_convert_msg rose_qsig_msgs[] = {
|
||||
/* *INDENT-OFF* */
|
||||
@@ -479,7 +494,7 @@ static const struct rose_convert_msg rose_qsig_msgs[] = {
|
||||
* decode_invoke_args, decode_result_args
|
||||
*/
|
||||
/*
|
||||
* localValue's from Q.SIG Name-Operations
|
||||
* localValue's from Q.SIG Name-Operations 4th edition
|
||||
* { iso(1) standard(0) pss1-name(13868) name-operations(0) }
|
||||
*/
|
||||
{
|
||||
@@ -503,6 +518,34 @@ static const struct rose_convert_msg rose_qsig_msgs[] = {
|
||||
rose_dec_qsig_BusyName_ARG, NULL
|
||||
},
|
||||
|
||||
/*
|
||||
* globalValue's (OIDs) from Q.SIG Name-Operations 2nd edition
|
||||
* { iso(1) identified-organization(3) icd-ecma(12) standard(0) qsig-name(164) name-operations(0) }
|
||||
*
|
||||
* This older version of the Q.SIG switch is not supported.
|
||||
* However, we will accept receiving these messages anyway.
|
||||
*/
|
||||
{
|
||||
ROSE_QSIG_CallingName, &rose_qsig_isdn_domain, 0,
|
||||
rose_enc_qsig_CallingName_ARG, NULL,
|
||||
rose_dec_qsig_CallingName_ARG, NULL
|
||||
},
|
||||
{
|
||||
ROSE_QSIG_CalledName, &rose_qsig_isdn_domain, 1,
|
||||
rose_enc_qsig_CalledName_ARG, NULL,
|
||||
rose_dec_qsig_CalledName_ARG, NULL
|
||||
},
|
||||
{
|
||||
ROSE_QSIG_ConnectedName, &rose_qsig_isdn_domain, 2,
|
||||
rose_enc_qsig_ConnectedName_ARG, NULL,
|
||||
rose_dec_qsig_ConnectedName_ARG, NULL
|
||||
},
|
||||
{
|
||||
ROSE_QSIG_BusyName, &rose_qsig_isdn_domain, 3,
|
||||
rose_enc_qsig_BusyName_ARG, NULL,
|
||||
rose_dec_qsig_BusyName_ARG, NULL
|
||||
},
|
||||
|
||||
/*
|
||||
* localValue's from Q.SIG SS-AOC-Operations
|
||||
* { iso(1) standard(0) pss1-advice-of-charge(15050) advice-of-charge-operations(0) }
|
||||
|
||||
@@ -382,6 +382,7 @@ static const unsigned char *rose_dec_qsig_PartyName_ARG_Backend(struct pri *ctrl
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "name", tag, pos, seq_end,
|
||||
&party->name));
|
||||
|
||||
|
||||
98
rosetest.c
98
rosetest.c
@@ -2132,6 +2132,80 @@ static unsigned char rose_qsig_multiple_msg[] = {
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
static unsigned char rose_qsig_name_alt_encode_msg[] = {
|
||||
/* *INDENT-OFF* */
|
||||
/*
|
||||
* Context Specific/C [10 0x0A] <AA> Len:6 <06>
|
||||
* Context Specific [0 0x00] <80> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [2 0x02] <82> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [11 0x0B] <8B> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific/C [1 0x01] <A1> Len:21 <15>
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <1D> - "~"
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Sequence/C(48 0x30) <30> Len:13 <0D>
|
||||
* Context Specific [0 0x00] <80> Len:11 <0B>
|
||||
* <55 54 49 4C 49 54 59 20-54 45 4C> - "UTILITY TEL"
|
||||
*/
|
||||
0x9F,
|
||||
0xAA, 0x06,
|
||||
0x80, 0x01,
|
||||
0x00,
|
||||
0x82, 0x01,
|
||||
0x00,
|
||||
0x8B, 0x01,
|
||||
0x00,
|
||||
0xA1, 0x15,
|
||||
0x02, 0x01,
|
||||
0x1D,
|
||||
0x02, 0x01,
|
||||
0x00,
|
||||
0x30, 0x0D,
|
||||
0x80, 0x0B,
|
||||
0x55, 0x54, 0x49, 0x4C, 0x49, 0x54, 0x59, 0x20, 0x54, 0x45, 0x4C
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
static unsigned char rose_qsig_name_2nd_encode_msg[] = {
|
||||
/* *INDENT-OFF* */
|
||||
/*
|
||||
* Context Specific/C [10 0x0A] <AA> Len:6 <06>
|
||||
* Context Specific [0 0x00] <80> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [2 0x02] <82> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [11 0x0B] <8B> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific/C [1 0x01] <A1> Len:26 <1A>
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <40> - "@"
|
||||
* OID(6 0x06) <06> Len:4 <04>
|
||||
* <2B 0C 09 00> - "+~~~"
|
||||
* Context Specific [0 0x00] <80> Len:15 <0F>
|
||||
* <4D 6F 64 65 6D 20 44 69-73 63 6F 42 61 6C 6C> - "Modem DiscoBall"
|
||||
*/
|
||||
0x91,
|
||||
0xaa, 0x06,
|
||||
0x80, 0x01,
|
||||
0x00,
|
||||
0x82, 0x01,
|
||||
0x00,
|
||||
0x8b, 0x01,
|
||||
0x00,
|
||||
0xa1, 0x1a,
|
||||
0x02, 0x01,
|
||||
0x40,
|
||||
0x06, 0x04,
|
||||
0x2b, 0x0c, 0x09, 0x00,
|
||||
0x80, 0x0f,
|
||||
0x4d, 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x42, 0x61, 0x6c, 0x6c
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
|
||||
static const struct rose_message rose_dms100_msgs[] = {
|
||||
/* *INDENT-OFF* */
|
||||
@@ -2318,6 +2392,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned index;
|
||||
unsigned offset;
|
||||
const char *str;
|
||||
static struct pri dummy_ctrl;
|
||||
|
||||
pri_set_message(rose_pri_message);
|
||||
@@ -2326,6 +2401,9 @@ int main(int argc, char *argv[])
|
||||
memset(&dummy_ctrl, 0, sizeof(dummy_ctrl));
|
||||
dummy_ctrl.debug = PRI_DEBUG_APDU;
|
||||
|
||||
/* For sanity specify what version of libpri we are testing. */
|
||||
pri_error(&dummy_ctrl, "libpri version tested: %s\n", pri_get_version());
|
||||
|
||||
offset = 0;
|
||||
pri_message(&dummy_ctrl, "Encode/decode message(s)\n");
|
||||
if (argc <= 1) {
|
||||
@@ -2420,12 +2498,23 @@ int main(int argc, char *argv[])
|
||||
rose_test_exception(&dummy_ctrl, "Multiple component messages",
|
||||
rose_qsig_multiple_msg, sizeof(rose_qsig_multiple_msg));
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "Alternate name encoded messages",
|
||||
rose_qsig_name_alt_encode_msg, sizeof(rose_qsig_name_alt_encode_msg));
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "2nd edition name encoded messages",
|
||||
rose_qsig_name_2nd_encode_msg, sizeof(rose_qsig_name_2nd_encode_msg));
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
pri_message(&dummy_ctrl, "\n\n"
|
||||
"List of operation codes:\n");
|
||||
for (index = 0; index < ROSE_Num_Operation_Codes; ++index) {
|
||||
pri_message(&dummy_ctrl, "%d: %s\n", index, rose_operation2str(index));
|
||||
str = rose_operation2str(index);
|
||||
if (!strncmp(str, "Invalid code:", 13)) {
|
||||
pri_error(&dummy_ctrl, "%d: %s\n", index, str);
|
||||
} else {
|
||||
pri_message(&dummy_ctrl, "%d: %s\n", index, str);
|
||||
}
|
||||
}
|
||||
pri_message(&dummy_ctrl, "\n\n"
|
||||
"************************************************************\n");
|
||||
@@ -2435,7 +2524,12 @@ int main(int argc, char *argv[])
|
||||
pri_message(&dummy_ctrl, "\n\n"
|
||||
"List of error codes:\n");
|
||||
for (index = 0; index < ROSE_ERROR_Num_Codes; ++index) {
|
||||
pri_message(&dummy_ctrl, "%d: %s\n", index, rose_error2str(index));
|
||||
str = rose_error2str(index);
|
||||
if (!strncmp(str, "Invalid code:", 13)) {
|
||||
pri_error(&dummy_ctrl, "%d: %s\n", index, str);
|
||||
} else {
|
||||
pri_message(&dummy_ctrl, "%d: %s\n", index, str);
|
||||
}
|
||||
}
|
||||
pri_message(&dummy_ctrl, "\n\n"
|
||||
"************************************************************\n");
|
||||
|
||||
Reference in New Issue
Block a user