2 * libpri: An implementation of Primary Rate ISDN
4 * Written by Mark Spencer <markster@linux-support.net>
6 * Copyright (C) 2001-2005, Digium, Inc.
8 * Copyright (C) 2003-2006 Junghanns.NET GmbH
9 * Klaus-Peter Junghanns <kpj@junghanns.net>
13 * See http://www.asterisk.org for more information about
14 * the Asterisk project. Please do not directly contact
15 * any of the maintainers of this project for assistance;
16 * the project provides a web site, mailing lists and IRC
17 * channels for your use.
19 * This program is free software, distributed under the terms of
20 * the GNU General Public License Version 2 as published by the
21 * Free Software Foundation. See the LICENSE file included with
22 * this program for more details.
27 #include "pri_internal.h"
30 #include "pri_facility.h"
40 #define MAX_MAND_IES 10
45 int mandies
[MAX_MAND_IES
];
48 static struct msgtype msgs
[] = {
49 /* Call establishment messages */
50 { Q931_ALERTING
, "ALERTING" },
51 { Q931_CALL_PROCEEDING
, "CALL PROCEEDING" },
52 { Q931_CONNECT
, "CONNECT" },
53 { Q931_CONNECT_ACKNOWLEDGE
, "CONNECT ACKNOWLEDGE" },
54 { Q931_PROGRESS
, "PROGRESS", { Q931_PROGRESS_INDICATOR
} },
55 { Q931_SETUP
, "SETUP", { Q931_BEARER_CAPABILITY
, Q931_CHANNEL_IDENT
} },
56 { Q931_SETUP_ACKNOWLEDGE
, "SETUP ACKNOWLEDGE" },
58 /* Call disestablishment messages */
59 { Q931_DISCONNECT
, "DISCONNECT", { Q931_CAUSE
} },
60 { Q931_RELEASE
, "RELEASE" },
61 { Q931_RELEASE_COMPLETE
, "RELEASE COMPLETE" },
62 { Q931_RESTART
, "RESTART", { Q931_RESTART_INDICATOR
} },
63 { Q931_RESTART_ACKNOWLEDGE
, "RESTART ACKNOWLEDGE", { Q931_RESTART_INDICATOR
} },
66 { Q931_STATUS
, "STATUS", { Q931_CAUSE
, Q931_CALL_STATE
} },
67 { Q931_STATUS_ENQUIRY
, "STATUS ENQUIRY" },
68 { Q931_USER_INFORMATION
, "USER_INFORMATION" },
69 { Q931_SEGMENT
, "SEGMENT" },
70 { Q931_CONGESTION_CONTROL
, "CONGESTION CONTROL" },
71 { Q931_INFORMATION
, "INFORMATION" },
72 { Q931_FACILITY
, "FACILITY" },
73 { Q931_NOTIFY
, "NOTIFY", { Q931_IE_NOTIFY_IND
} },
76 { Q931_HOLD
, "HOLD" },
77 { Q931_HOLD_ACKNOWLEDGE
, "HOLD ACKNOWLEDGE" },
78 { Q931_HOLD_REJECT
, "HOLD REJECT" },
79 { Q931_RETRIEVE
, "RETRIEVE" },
80 { Q931_RETRIEVE_ACKNOWLEDGE
, "RETRIEVE ACKNOWLEDGE" },
81 { Q931_RETRIEVE_REJECT
, "RETRIEVE REJECT" },
82 { Q931_RESUME
, "RESUME" },
83 { Q931_RESUME_ACKNOWLEDGE
, "RESUME ACKNOWLEDGE", { Q931_CHANNEL_IDENT
} },
84 { Q931_RESUME_REJECT
, "RESUME REJECT", { Q931_CAUSE
} },
85 { Q931_SUSPEND
, "SUSPEND" },
86 { Q931_SUSPEND_ACKNOWLEDGE
, "SUSPEND ACKNOWLEDGE" },
87 { Q931_SUSPEND_REJECT
, "SUSPEND REJECT" },
90 { NATIONAL_SERVICE
, "SERVICE" },
91 { NATIONAL_SERVICE_ACKNOWLEDGE
, "SERVICE ACKNOWLEDGE" },
94 static struct msgtype causes
[] = {
95 { PRI_CAUSE_UNALLOCATED
, "Unallocated (unassigned) number" },
96 { PRI_CAUSE_NO_ROUTE_TRANSIT_NET
, "No route to specified transmit network" },
97 { PRI_CAUSE_NO_ROUTE_DESTINATION
, "No route to destination" },
98 { PRI_CAUSE_CHANNEL_UNACCEPTABLE
, "Channel unacceptable" },
99 { PRI_CAUSE_CALL_AWARDED_DELIVERED
, "Call awarded and being delivered in an established channel" },
100 { PRI_CAUSE_NORMAL_CLEARING
, "Normal Clearing" },
101 { PRI_CAUSE_USER_BUSY
, "User busy" },
102 { PRI_CAUSE_NO_USER_RESPONSE
, "No user responding" },
103 { PRI_CAUSE_NO_ANSWER
, "User alerting, no answer" },
104 { PRI_CAUSE_CALL_REJECTED
, "Call Rejected" },
105 { PRI_CAUSE_NUMBER_CHANGED
, "Number changed" },
106 { PRI_CAUSE_DESTINATION_OUT_OF_ORDER
, "Destination out of order" },
107 { PRI_CAUSE_INVALID_NUMBER_FORMAT
, "Invalid number format" },
108 { PRI_CAUSE_FACILITY_REJECTED
, "Facility rejected" },
109 { PRI_CAUSE_RESPONSE_TO_STATUS_ENQUIRY
, "Response to STATus ENQuiry" },
110 { PRI_CAUSE_NORMAL_UNSPECIFIED
, "Normal, unspecified" },
111 { PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
, "Circuit/channel congestion" },
112 { PRI_CAUSE_NETWORK_OUT_OF_ORDER
, "Network out of order" },
113 { PRI_CAUSE_NORMAL_TEMPORARY_FAILURE
, "Temporary failure" },
114 { PRI_CAUSE_SWITCH_CONGESTION
, "Switching equipment congestion" },
115 { PRI_CAUSE_ACCESS_INFO_DISCARDED
, "Access information discarded" },
116 { PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
, "Requested channel not available" },
117 { PRI_CAUSE_PRE_EMPTED
, "Pre-empted" },
118 { PRI_CAUSE_FACILITY_NOT_SUBSCRIBED
, "Facility not subscribed" },
119 { PRI_CAUSE_OUTGOING_CALL_BARRED
, "Outgoing call barred" },
120 { PRI_CAUSE_INCOMING_CALL_BARRED
, "Incoming call barred" },
121 { PRI_CAUSE_BEARERCAPABILITY_NOTAUTH
, "Bearer capability not authorized" },
122 { PRI_CAUSE_BEARERCAPABILITY_NOTAVAIL
, "Bearer capability not available" },
123 { PRI_CAUSE_BEARERCAPABILITY_NOTIMPL
, "Bearer capability not implemented" },
124 { PRI_CAUSE_SERVICEOROPTION_NOTAVAIL
, "Service or option not available, unspecified" },
125 { PRI_CAUSE_CHAN_NOT_IMPLEMENTED
, "Channel not implemented" },
126 { PRI_CAUSE_FACILITY_NOT_IMPLEMENTED
, "Facility not implemented" },
127 { PRI_CAUSE_INVALID_CALL_REFERENCE
, "Invalid call reference value" },
128 { PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST
, "Identified channel does not exist" },
129 { PRI_CAUSE_INCOMPATIBLE_DESTINATION
, "Incompatible destination" },
130 { PRI_CAUSE_INVALID_MSG_UNSPECIFIED
, "Invalid message unspecified" },
131 { PRI_CAUSE_MANDATORY_IE_MISSING
, "Mandatory information element is missing" },
132 { PRI_CAUSE_MESSAGE_TYPE_NONEXIST
, "Message type nonexist." },
133 { PRI_CAUSE_WRONG_MESSAGE
, "Wrong message" },
134 { PRI_CAUSE_IE_NONEXIST
, "Info. element nonexist or not implemented" },
135 { PRI_CAUSE_INVALID_IE_CONTENTS
, "Invalid information element contents" },
136 { PRI_CAUSE_WRONG_CALL_STATE
, "Message not compatible with call state" },
137 { PRI_CAUSE_RECOVERY_ON_TIMER_EXPIRE
, "Recover on timer expiry" },
138 { PRI_CAUSE_MANDATORY_IE_LENGTH_ERROR
, "Mandatory IE length error" },
139 { PRI_CAUSE_PROTOCOL_ERROR
, "Protocol error, unspecified" },
140 { PRI_CAUSE_INTERWORKING
, "Interworking, unspecified" },
143 static struct msgtype facilities
[] = {
144 { PRI_NSF_SID_PREFERRED
, "CPN (SID) preferred" },
145 { PRI_NSF_ANI_PREFERRED
, "BN (ANI) preferred" },
146 { PRI_NSF_SID_ONLY
, "CPN (SID) only" },
147 { PRI_NSF_ANI_ONLY
, "BN (ANI) only" },
148 { PRI_NSF_CALL_ASSOC_TSC
, "Call Associated TSC" },
149 { PRI_NSF_NOTIF_CATSC_CLEARING
, "Notification of CATSC Clearing or Resource Unavailable" },
150 { PRI_NSF_OPERATOR
, "Operator" },
151 { PRI_NSF_PCCO
, "Pre-subscribed Common Carrier Operator (PCCO)" },
152 { PRI_NSF_SDN
, "SDN (including GSDN)" },
153 { PRI_NSF_TOLL_FREE_MEGACOM
, "Toll Free MEGACOM" },
154 { PRI_NSF_MEGACOM
, "MEGACOM" },
155 { PRI_NSF_ACCUNET
, "ACCUNET Switched Digital Service" },
156 { PRI_NSF_LONG_DISTANCE_SERVICE
, "Long Distance Service" },
157 { PRI_NSF_INTERNATIONAL_TOLL_FREE
, "International Toll Free Service" },
158 { PRI_NSF_ATT_MULTIQUEST
, "AT&T MultiQuest" },
159 { PRI_NSF_CALL_REDIRECTION_SERVICE
, "Call Redirection Service" }
162 #define FLAG_PREFERRED 2
163 #define FLAG_EXCLUSIVE 4
165 #define RESET_INDICATOR_CHANNEL 0
166 #define RESET_INDICATOR_DS1 6
167 #define RESET_INDICATOR_PRI 7
169 #define TRANS_MODE_64_CIRCUIT 0x10
170 #define TRANS_MODE_2x64_CIRCUIT 0x11
171 #define TRANS_MODE_384_CIRCUIT 0x13
172 #define TRANS_MODE_1536_CIRCUIT 0x15
173 #define TRANS_MODE_1920_CIRCUIT 0x17
174 #define TRANS_MODE_MULTIRATE 0x18
175 #define TRANS_MODE_PACKET 0x40
177 #define RATE_ADAPT_56K 0x0f
179 #define LAYER_2_LAPB 0x46
181 #define LAYER_3_X25 0x66
183 /* The 4ESS uses a different audio field */
184 #define PRI_TRANS_CAP_AUDIO_4ESS 0x08
186 /* Don't forget to update PRI_PROG_xxx at libpri.h */
187 #define Q931_PROG_CALL_NOT_E2E_ISDN 0x01
188 #define Q931_PROG_CALLED_NOT_ISDN 0x02
189 #define Q931_PROG_CALLER_NOT_ISDN 0x03
190 #define Q931_PROG_CALLER_RETURNED_TO_ISDN 0x04
191 #define Q931_PROG_INBAND_AVAILABLE 0x08
192 #define Q931_PROG_DELAY_AT_INTERF 0x0a
193 #define Q931_PROG_INTERWORKING_WITH_PUBLIC 0x10
194 #define Q931_PROG_INTERWORKING_NO_RELEASE 0x11
195 #define Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER 0x12
196 #define Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER 0x13
198 #define CODE_CCITT 0x0
199 #define CODE_INTERNATIONAL 0x1
200 #define CODE_NATIONAL 0x2
201 #define CODE_NETWORK_SPECIFIC 0x3
204 #define LOC_PRIV_NET_LOCAL_USER 0x1
205 #define LOC_PUB_NET_LOCAL_USER 0x2
206 #define LOC_TRANSIT_NET 0x3
207 #define LOC_PUB_NET_REMOTE_USER 0x4
208 #define LOC_PRIV_NET_REMOTE_USER 0x5
209 #define LOC_INTERNATIONAL_NETWORK 0x7
210 #define LOC_NETWORK_BEYOND_INTERWORKING 0xa
220 static char *ie2str(int ie
);
221 static char *msg2str(int msg
);
224 #define FUNC_DUMP(name) void ((name))(int full_ie, struct pri *pri, q931_ie *ie, int len, char prefix)
225 #define FUNC_RECV(name) int ((name))(int full_ie, struct pri *pri, q931_call *call, int msgtype, q931_ie *ie, int len)
226 #define FUNC_SEND(name) int ((name))(int full_ie, struct pri *pri, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
229 /* Update call state with transition trace. */
230 #define UPDATE_OURCALLSTATE(pri,c,newstate) do {\
231 if (pri->debug & (PRI_DEBUG_Q931_STATE) && c->ourcallstate != newstate) \
232 pri_message(pri, DBGHEAD "call %d on channel %d enters state %d (%s)\n", DBGINFO, \
233 c->cr, c->channelno, newstate, callstate2str(newstate)); \
234 c->ourcallstate = newstate; \
237 /* Update call state with no trace. */
238 #define UPDATE_OURCALLSTATE(pri,c,newstate) c->ourcallstate = newstate
242 /* Maximal count of same IEs at the message (0 - any, 1..n - limited) */
246 /* IE friendly name */
248 /* Dump an IE for debugging (preceed all lines by prefix) */
250 /* Handle IE returns 0 on success, -1 on failure */
252 /* Add IE to a message, return the # of bytes added or -1 on failure */
253 FUNC_SEND(*transmit
);
256 static char *code2str(int code
, struct msgtype
*codes
, int max
)
260 if (codes
[x
].msgnum
== code
)
261 return codes
[x
].name
;
265 static void call_init(struct q931_call
*c
)
267 memset(c
, 0, sizeof(*c
));
270 c
->sendhangupack
= 0;
285 c
->ourcallstate
= Q931_CALL_STATE_NULL
;
286 c
->peercallstate
= Q931_CALL_STATE_NULL
;
293 static char *binary(int b
, int len
) {
296 memset(res
, 0, sizeof(res
));
300 res
[x
-1] = b
& (1 << (len
- x
)) ? '1' : '0';
304 static FUNC_RECV(receive_channel_id
)
308 if ((pri
->localtype
!= PRI_CPE
) && (pri
->localtype
!= PRI_NETWORK
)) {
309 // pri_error(pri, "!! BRI type %d!?\n",ie->data[0] & 0x03);
310 call
->channelno
= ie
->data
[0] & 0x03;
311 if (call
->channelno
== 3) {
312 call
->channelno
= -1; // any channel
316 #ifndef NOAUTO_CHANNEL_SELECTION_SUPPORT
317 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== PRI_CPE
)) {
318 switch (ie
->data
[0] & 3) {
320 call
->justsignalling
= 1;
325 pri_error(pri
, "!! Unexpected Channel selection %d\n", ie
->data
[0] & 3);
330 if (ie
->data
[0] & 0x08)
331 call
->chanflags
= FLAG_EXCLUSIVE
;
333 call
->chanflags
= FLAG_PREFERRED
;
335 if (ie
->data
[0] & 0x40) {
336 /* DS1 specified -- stop here */
337 call
->ds1no
= ie
->data
[1] & 0x7f;
338 call
->ds1explicit
= 1;
341 call
->ds1explicit
= 0;
345 if ((ie
->data
[pos
] & 0x0f) != 3) {
346 pri_error(pri
, "!! Unexpected Channel Type %d\n", ie
->data
[1] & 0x0f);
349 if ((ie
->data
[pos
] & 0x60) != 0) {
350 pri_error(pri
, "!! Invalid CCITT coding %d\n", (ie
->data
[1] & 0x60) >> 5);
353 if (ie
->data
[pos
] & 0x10) {
354 /* Expect Slot Map */
359 call
->slotmap
|= ie
->data
[x
+ pos
];
364 /* Only expect a particular channel */
365 call
->channelno
= ie
->data
[pos
] & 0x7f;
373 static FUNC_SEND(transmit_channel_id
)
378 /* We are ready to transmit single IE only */
382 if (call
->justsignalling
) {
383 ie
->data
[pos
++] = 0xac; /* Read the standards docs to figure this out
384 ECMA-165 section 7.3 */
388 /* Start with standard stuff */
389 if (pri
->switchtype
== PRI_SWITCH_GR303_TMC
) {
390 ie
->data
[pos
] = 0x69;
392 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== PRI_CPE
)) {
393 ie
->data
[pos
] = 0xa1;
396 ie
->data
[pos
] = 0x80;
399 /* Add exclusive flag if necessary */
400 if (call
->chanflags
& FLAG_EXCLUSIVE
)
401 ie
->data
[pos
] |= 0x08;
402 else if (!(call
->chanflags
& FLAG_PREFERRED
)) {
403 /* Don't need this IE */
407 if (((pri
->switchtype
!= PRI_SWITCH_QSIG
) && (call
->ds1no
> 0)) || call
->ds1explicit
) {
408 /* Note that we are specifying the identifier */
409 ie
->data
[pos
++] |= 0x40;
410 /* We need to use the Channel Identifier Present thingy. Just specify it and we're done */
411 ie
->data
[pos
++] = 0x80 | call
->ds1no
;
414 if ((call
->channelno
> -1) || (call
->slotmap
!= -1)) {
415 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== PRI_CPE
)) {
416 /* We'll have the octet 8.2 and 8.3's present */
417 ie
->data
[pos
++] = 0x83;
418 if (call
->channelno
> -1) {
419 /* Channel number specified */
420 ie
->data
[pos
++] = 0x80 | call
->channelno
;
423 /* We have to send a channel map */
424 if (call
->slotmap
!= -1) {
425 ie
->data
[pos
-1] |= 0x10;
426 ie
->data
[pos
++] = (call
->slotmap
& 0xff0000) >> 16;
427 ie
->data
[pos
++] = (call
->slotmap
& 0xff00) >> 8;
428 ie
->data
[pos
++] = (call
->slotmap
& 0xff);
433 // pri_error(pri, "channelno %d, ds1no %d data %d\n",call->channelno,call->ds1no,ie->data[pos-1]);
434 if (pri
->localtype
== BRI_CPE_PTMP
) {
435 if (msgtype
== Q931_SETUP
) {
436 // network, you decide!
437 if (call
->channelno
> -1) {
438 // ie->data[pos-1] = 0x83;
439 ie
->data
[pos
-1] = 0x80 | call
->channelno
;
442 if (call
->channelno
> -1) {
443 ie
->data
[pos
-1] |= call
->channelno
;
447 if (call
->channelno
> -1) {
448 ie
->data
[pos
-1] |= call
->channelno
;
454 if (pri
->localtype
== BRI_CPE
) {
455 ie
->data
[pos
++] = 0x80 | 3;
460 if (call
->ds1no
> 0) {
464 if (msgtype
== Q931_RESTART_ACKNOWLEDGE
) {
465 /* restart complete interface! */
468 pri_error(pri
, "!! No channel map, no channel, and no ds1? What am I supposed to identify?\n");
472 static FUNC_DUMP(dump_channel_id
)
477 static const char* msg_chan_sel
[] = {
478 "No channel selected", "B1 channel", "B2 channel","Any channel selected",
479 "No channel selected", "As indicated in following octets", "Reserved","Any channel selected"
482 pri_message(pri
, "%c Channel ID (len=%2d) [ Ext: %d IntID: %s %s Spare: %d %s Dchan: %d\n",
483 prefix
, len
, (ie
->data
[0] & 0x80) ? 1 : 0, (ie
->data
[0] & 0x40) ? "Explicit" : "Implicit",
484 (ie
->data
[0] & 0x20) ? "PRI" : "Other", (ie
->data
[0] & 0x10) ? 1 : 0,
485 (ie
->data
[0] & 0x08) ? "Exclusive" : "Preferred", (ie
->data
[0] & 0x04) ? 1 : 0);
486 pri_message(pri
, "%c ChanSel: %s\n",
487 prefix
, msg_chan_sel
[(ie
->data
[0] & 0x3) + ((ie
->data
[0]>>3) & 0x4)]);
490 if (ie
->data
[0] & 0x40) {
491 /* Explicitly defined DS1 */
492 pri_message(pri
, "%c Ext: %d DS1 Identifier: %d \n", prefix
, (ie
->data
[pos
] & 0x80) >> 7, ie
->data
[pos
] & 0x7f);
495 /* Implicitly defined DS1 */
498 /* Still more information here */
499 pri_message(pri
, "%c Ext: %d Coding: %d %s Specified Channel Type: %d\n",
500 prefix
, (ie
->data
[pos
] & 0x80) >> 7, (ie
->data
[pos
] & 60) >> 5,
501 (ie
->data
[pos
] & 0x10) ? "Slot Map" : "Number", ie
->data
[pos
] & 0x0f);
502 if (!(ie
->data
[pos
] & 0x10)) {
503 /* Number specified */
505 pri_message(pri
, "%c Ext: %d Channel: %d ]\n", prefix
, (ie
->data
[pos
] & 0x80) >> 7,
506 (ie
->data
[pos
]) & 0x7f);
512 res
|= ie
->data
[pos
++];
514 pri_message(pri
, "%c Map: %s ]\n", prefix
, binary(res
, 24));
516 } else pri_message(pri
, " ]\n");
519 static char *ri2str(int ri
)
521 static struct msgtype ris
[] = {
522 { 0, "Indicated Channel" },
523 { 6, "Single DS1 Facility" },
524 { 7, "All DS1 Facilities" },
526 return code2str(ri
, ris
, sizeof(ris
) / sizeof(ris
[0]));
529 static FUNC_DUMP(dump_restart_indicator
)
531 pri_message(pri
, "%c Restart Indentifier (len=%2d) [ Ext: %d Spare: %d Resetting %s (%d) ]\n",
532 prefix
, len
, (ie
->data
[0] & 0x80) >> 7, (ie
->data
[0] & 0x78) >> 3, ri2str(ie
->data
[0] & 0x7), ie
->data
[0] & 0x7);
535 static FUNC_RECV(receive_restart_indicator
)
538 call
->ri
= ie
->data
[0] & 0x7;
542 static FUNC_SEND(transmit_restart_indicator
)
549 ie
->data
[0] = 0x80 | (call
->ri
& 0x7);
552 /* Switch compatibility */
553 ie
->data
[0] = 0xA0 | (call
->ri
& 0x7);
556 pri_error(pri
, "!! Invalid restart indicator value %d\n", call
->ri
);
562 static char *redirection_reason2str(int mode
)
564 static struct msgtype modes
[] = {
565 { PRI_REDIR_UNKNOWN
, "Unknown" },
566 { PRI_REDIR_FORWARD_ON_BUSY
, "Forwarded on busy" },
567 { PRI_REDIR_FORWARD_ON_NO_REPLY
, "Forwarded on no reply" },
568 { PRI_REDIR_DEFLECTION
, "Call deflected" },
569 { PRI_REDIR_DTE_OUT_OF_ORDER
, "Called DTE out of order" },
570 { PRI_REDIR_FORWARDED_BY_DTE
, "Forwarded by called DTE" },
571 { PRI_REDIR_UNCONDITIONAL
, "Forwarded unconditionally" },
573 return code2str(mode
, modes
, sizeof(modes
) / sizeof(modes
[0]));
576 static char *cap2str(int mode
)
578 static struct msgtype modes
[] = {
579 { PRI_TRANS_CAP_SPEECH
, "Speech" },
580 { PRI_TRANS_CAP_DIGITAL
, "Unrestricted digital information" },
581 { PRI_TRANS_CAP_RESTRICTED_DIGITAL
, "Restricted digital information" },
582 { PRI_TRANS_CAP_3_1K_AUDIO
, "3.1kHz audio" },
583 { PRI_TRANS_CAP_DIGITAL_W_TONES
, "Unrestricted digital information with tones/announcements" },
584 { PRI_TRANS_CAP_VIDEO
, "Video" },
585 { PRI_TRANS_CAP_AUDIO_4ESS
, "3.1khz audio (4ESS)" },
587 return code2str(mode
, modes
, sizeof(modes
) / sizeof(modes
[0]));
590 static char *mode2str(int mode
)
592 static struct msgtype modes
[] = {
593 { TRANS_MODE_64_CIRCUIT
, "64kbps, circuit-mode" },
594 { TRANS_MODE_2x64_CIRCUIT
, "2x64kbps, circuit-mode" },
595 { TRANS_MODE_384_CIRCUIT
, "384kbps, circuit-mode" },
596 { TRANS_MODE_1536_CIRCUIT
, "1536kbps, circuit-mode" },
597 { TRANS_MODE_1920_CIRCUIT
, "1920kbps, circuit-mode" },
598 { TRANS_MODE_MULTIRATE
, "Multirate (Nx64kbps)" },
599 { TRANS_MODE_PACKET
, "Packet Mode" },
601 return code2str(mode
, modes
, sizeof(modes
) / sizeof(modes
[0]));
604 static char *l12str(int proto
)
606 static struct msgtype protos
[] = {
607 { PRI_LAYER_1_ITU_RATE_ADAPT
, "V.110 Rate Adaption" },
608 { PRI_LAYER_1_ULAW
, "u-Law" },
609 { PRI_LAYER_1_ALAW
, "A-Law" },
610 { PRI_LAYER_1_G721
, "G.721 ADPCM" },
611 { PRI_LAYER_1_G722_G725
, "G.722/G.725 7kHz Audio" },
612 { PRI_LAYER_1_H223_H245
, "H.223/H.245 Multimedia" },
613 { PRI_LAYER_1_NON_ITU_ADAPT
, "Non-ITU Rate Adaption" },
614 { PRI_LAYER_1_V120_RATE_ADAPT
, "V.120 Rate Adaption" },
615 { PRI_LAYER_1_X31_RATE_ADAPT
, "X.31 Rate Adaption" },
617 return code2str(proto
, protos
, sizeof(protos
) / sizeof(protos
[0]));
620 static char *ra2str(int proto
)
622 static struct msgtype protos
[] = {
623 { PRI_RATE_ADAPT_9K6
, "9.6 kbit/s" },
625 return code2str(proto
, protos
, sizeof(protos
) / sizeof(protos
[0]));
628 static char *l22str(int proto
)
630 static struct msgtype protos
[] = {
631 { LAYER_2_LAPB
, "LAPB" },
633 return code2str(proto
, protos
, sizeof(protos
) / sizeof(protos
[0]));
636 static char *l32str(int proto
)
638 static struct msgtype protos
[] = {
639 { LAYER_3_X25
, "X.25" },
641 return code2str(proto
, protos
, sizeof(protos
) / sizeof(protos
[0]));
644 static char *int_rate2str(int proto
)
646 static struct msgtype protos
[] = {
647 { PRI_INT_RATE_8K
, "8 kbit/s" },
648 { PRI_INT_RATE_16K
, "16 kbit/s" },
649 { PRI_INT_RATE_32K
, "32 kbit/s" },
651 return code2str(proto
, protos
, sizeof(protos
) / sizeof(protos
[0]));
654 static FUNC_DUMP(dump_bearer_capability
)
657 pri_message(pri
, "%c Bearer Capability (len=%2d) [ Ext: %d Q.931 Std: %d Info transfer capability: %s (%d)\n",
658 prefix
, len
, (ie
->data
[0] & 0x80 ) >> 7, (ie
->data
[0] & 0x60) >> 5, cap2str(ie
->data
[0] & 0x1f), (ie
->data
[0] & 0x1f));
659 pri_message(pri
, "%c Ext: %d Trans mode/rate: %s (%d)\n", prefix
, (ie
->data
[1] & 0x80) >> 7, mode2str(ie
->data
[1] & 0x7f), ie
->data
[1] & 0x7f);
661 /* octet 4.1 exists iff mode/rate is multirate */
662 if ((ie
->data
[1] & 0x7f) == 0x18) {
663 pri_message(pri
, "%c Ext: %d Transfer rate multiplier: %d x 64\n", prefix
, (ie
->data
[2] & 0x80) >> 7, ie
->data
[2] & 0x7f);
667 /* don't count the IE num and length as part of the data */
670 /* Look for octet 5; this is identified by bits 5,6 == 01 */
672 (ie
->data
[pos
] & 0x60) == 0x20) {
674 /* although the layer1 is only the bottom 5 bits of the byte,
675 previous versions of this library passed bits 5&6 through
676 too, so we have to do the same for binary compatability */
677 u_int8_t layer1
= ie
->data
[pos
] & 0x7f;
679 pri_message(pri
, "%c User information layer 1: %s (%d)\n",
680 prefix
, l12str(layer1
), layer1
);
684 if (pos
< len
&& !(ie
->data
[pos
-1] & 0x80)) {
685 int ra
= ie
->data
[pos
] & 0x7f;
687 pri_message(pri
, "%c Async: %d, Negotiation: %d, "
688 "User rate: %s (%#x)\n",
690 ra
& PRI_RATE_ADAPT_ASYNC
? 1 : 0,
691 ra
& PRI_RATE_ADAPT_NEGOTIATION_POSS
? 1 : 0,
692 ra2str(ra
& PRI_RATE_USER_RATE_MASK
),
693 ra
& PRI_RATE_USER_RATE_MASK
);
698 if (pos
< len
&& !(ie
->data
[pos
-1] & 0x80)) {
699 u_int8_t data
= ie
->data
[pos
];
700 if (layer1
== PRI_LAYER_1_ITU_RATE_ADAPT
) {
701 pri_message(pri
, "%c Intermediate rate: %s (%d), "
702 "NIC on Tx: %d, NIC on Rx: %d, "
703 "Flow control on Tx: %d, "
704 "Flow control on Rx: %d\n",
705 prefix
, int_rate2str((data
& 0x60)>>5),
711 } else if (layer1
== PRI_LAYER_1_V120_RATE_ADAPT
) {
712 pri_message(pri
, "%c Hdr: %d, Multiframe: %d, Mode: %d, "
713 "LLI negot: %d, Assignor: %d, "
714 "In-band neg: %d\n", prefix
,
722 pri_message(pri
, "%c Unknown octet 5b: 0x%x\n", data
);
728 if (pos
< len
&& !(ie
->data
[pos
-1] & 0x80)) {
729 u_int8_t data
= ie
->data
[pos
];
730 const char *stop_bits
[] = {"?","1","1.5","2"};
731 const char *data_bits
[] = {"?","5","7","8"};
732 const char *parity
[] = {"Odd","?","Even","None",
733 "zero","one","?","?"};
735 pri_message(pri
, "%c Stop bits: %s, data bits: %s, "
736 "parity: %s\n", prefix
,
737 stop_bits
[(data
& 0x60) >> 5],
738 data_bits
[(data
& 0x18) >> 3],
739 parity
[(data
& 0x7)]);
745 if (pos
< len
&& !(ie
->data
[pos
-1] & 0x80)) {
746 u_int8_t data
= ie
->data
[pos
];
747 pri_message(pri
, "%c Duplex mode: %d, modem type: %d\n",
748 prefix
, (data
& 0x40) ? 1 : 0,data
& 0x3F);
754 /* Look for octet 6; this is identified by bits 5,6 == 10 */
756 (ie
->data
[pos
] & 0x60) == 0x40) {
757 pri_message(pri
, "%c User information layer 2: %s (%d)\n",
758 prefix
, l22str(ie
->data
[pos
] & 0x1f),
759 ie
->data
[pos
] & 0x1f);
763 /* Look for octet 7; this is identified by bits 5,6 == 11 */
764 if (pos
< len
&& (ie
->data
[pos
] & 0x60) == 0x60) {
765 pri_message(pri
, "%c User information layer 3: %s (%d)\n",
766 prefix
, l32str(ie
->data
[pos
] & 0x1f),
767 ie
->data
[pos
] & 0x1f);
770 /* octets 7a and 7b? */
771 if (pos
+ 1 < len
&& !(ie
->data
[pos
-1] & 0x80) &&
772 !(ie
->data
[pos
] & 0x80)) {
774 proto
= ((ie
->data
[pos
] & 0xF) << 4 ) |
775 (ie
->data
[pos
+1] & 0xF);
777 pri_message(pri
, "%c Network layer: 0x%x\n", prefix
,
784 static FUNC_RECV(receive_bearer_capability
)
787 if (ie
->data
[0] & 0x60) {
788 pri_error(pri
, "!! non-standard Q.931 standard field\n");
791 call
->transcapability
= ie
->data
[0] & 0x1f;
792 call
->transmoderate
= ie
->data
[1] & 0x7f;
794 /* octet 4.1 exists iff mode/rate is multirate */
795 if (call
->transmoderate
== TRANS_MODE_MULTIRATE
) {
796 call
->transmultiple
= ie
->data
[pos
++] & 0x7f;
799 /* Look for octet 5; this is identified by bits 5,6 == 01 */
801 (ie
->data
[pos
] & 0x60) == 0x20 ) {
802 /* although the layer1 is only the bottom 5 bits of the byte,
803 previous versions of this library passed bits 5&6 through
804 too, so we have to do the same for binary compatability */
805 call
->userl1
= ie
->data
[pos
] & 0x7f;
809 if (pos
< len
&& !(ie
->data
[pos
-1] & 0x80)) {
810 call
->rateadaption
= ie
->data
[pos
] & 0x7f;
814 /* octets 5b through 5d? */
815 while (pos
< len
&& !(ie
->data
[pos
-1] & 0x80)) {
821 /* Look for octet 6; this is identified by bits 5,6 == 10 */
823 (ie
->data
[pos
] & 0x60) == 0x40) {
824 call
->userl2
= ie
->data
[pos
++] & 0x1f;
827 /* Look for octet 7; this is identified by bits 5,6 == 11 */
829 (ie
->data
[pos
] & 0x60) == 0x60) {
830 call
->userl3
= ie
->data
[pos
++] & 0x1f;
835 static FUNC_SEND(transmit_bearer_capability
)
840 /* We are ready to transmit single IE only */
844 tc
= call
->transcapability
;
845 if (pri
->subchannel
) {
846 /* Bearer capability is *hard coded* in GR-303 */
852 if (call
->justsignalling
) {
858 ie
->data
[0] = 0x80 | tc
;
859 ie
->data
[1] = call
->transmoderate
| 0x80;
862 /* octet 4.1 exists iff mode/rate is multirate */
863 if (call
->transmoderate
== TRANS_MODE_MULTIRATE
) {
864 ie
->data
[pos
++] = call
->transmultiple
| 0x80;
867 if ((tc
& PRI_TRANS_CAP_DIGITAL
) && (pri
->switchtype
== PRI_SWITCH_EUROISDN_E1
) &&
868 (call
->transmoderate
== TRANS_MODE_PACKET
)) {
869 /* Apparently EuroISDN switches don't seem to like user layer 2/3 */
872 if (call
->transmoderate
!= TRANS_MODE_PACKET
) {
873 /* If you have an AT&T 4ESS, you don't send any more info */
874 if ((pri
->switchtype
!= PRI_SWITCH_ATT4ESS
) && (call
->userl1
> -1)) {
875 ie
->data
[pos
++] = call
->userl1
| 0x80; /* XXX Ext bit? XXX */
876 if (call
->userl1
== PRI_LAYER_1_ITU_RATE_ADAPT
) {
877 ie
->data
[pos
++] = call
->rateadaption
| 0x80;
882 ie
->data
[pos
++] = 0xa0 | (call
->userl1
& 0x1f);
884 if (call
->userl1
== PRI_LAYER_1_ITU_RATE_ADAPT
) {
885 ie
->data
[pos
-1] &= ~0x80; /* clear EXT bit in octet 5 */
886 ie
->data
[pos
++] = call
->rateadaption
| 0x80;
891 if (call
->userl2
!= -1)
892 ie
->data
[pos
++] = 0xc0 | (call
->userl2
& 0x1f);
894 if (call
->userl3
!= -1)
895 ie
->data
[pos
++] = 0xe0 | (call
->userl3
& 0x1f);
900 char *pri_plan2str(int plan
)
902 static struct msgtype plans
[] = {
903 { PRI_INTERNATIONAL_ISDN
, "International number in ISDN" },
904 { PRI_NATIONAL_ISDN
, "National number in ISDN" },
905 { PRI_LOCAL_ISDN
, "Local number in ISDN" },
906 { PRI_PRIVATE
, "Private numbering plan" },
907 { PRI_UNKNOWN
, "Unknown numbering plan" },
909 return code2str(plan
, plans
, sizeof(plans
) / sizeof(plans
[0]));
912 static char *npi2str(int plan
)
914 static struct msgtype plans
[] = {
915 { PRI_NPI_UNKNOWN
, "Unknown Number Plan" },
916 { PRI_NPI_E163_E164
, "ISDN/Telephony Numbering Plan (E.164/E.163)" },
917 { PRI_NPI_X121
, "Data Numbering Plan (X.121)" },
918 { PRI_NPI_F69
, "Telex Numbering Plan (F.69)" },
919 { PRI_NPI_NATIONAL
, "National Standard Numbering Plan" },
920 { PRI_NPI_PRIVATE
, "Private Numbering Plan" },
921 { PRI_NPI_RESERVED
, "Reserved Number Plan" },
923 return code2str(plan
, plans
, sizeof(plans
) / sizeof(plans
[0]));
926 static char *ton2str(int plan
)
928 static struct msgtype plans
[] = {
929 { PRI_TON_UNKNOWN
, "Unknown Number Type" },
930 { PRI_TON_INTERNATIONAL
, "International Number" },
931 { PRI_TON_NATIONAL
, "National Number" },
932 { PRI_TON_NET_SPECIFIC
, "Network Specific Number" },
933 { PRI_TON_SUBSCRIBER
, "Subscriber Number" },
934 { PRI_TON_ABBREVIATED
, "Abbreviated number" },
935 { PRI_TON_RESERVED
, "Reserved Number" },
937 return code2str(plan
, plans
, sizeof(plans
) / sizeof(plans
[0]));
940 static char *subaddrtype2str(int plan
)
942 static struct msgtype plans
[] = {
943 { 0, "NSAP (X.213/ISO 8348 AD2)" },
944 { 2, "User Specified" },
946 return code2str(plan
, plans
, sizeof(plans
) / sizeof(plans
[0]));
949 char *pri_pres2str(int pres
)
951 static struct msgtype press
[] = {
952 { PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
, "Presentation permitted, user number not screened" },
953 { PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
, "Presentation permitted, user number passed network screening" },
954 { PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN
, "Presentation permitted, user number failed network screening" },
955 { PRES_ALLOWED_NETWORK_NUMBER
, "Presentation allowed of network provided number" },
956 { PRES_PROHIB_USER_NUMBER_NOT_SCREENED
, "Presentation prohibited, user number not screened" },
957 { PRES_PROHIB_USER_NUMBER_PASSED_SCREEN
, "Presentation prohibited, user number passed network screening" },
958 { PRES_PROHIB_USER_NUMBER_FAILED_SCREEN
, "Presentation prohibited, user number failed network screening" },
959 { PRES_PROHIB_NETWORK_NUMBER
, "Presentation prohibited of network provided number" },
960 { PRES_NUMBER_NOT_AVAILABLE
, "Number not available" },
962 return code2str(pres
, press
, sizeof(press
) / sizeof(press
[0]));
965 static void q931_get_number(char *num
, int maxlen
, unsigned char *src
, int len
)
968 pri_error(NULL
, "q931_get_number received invalid len = %d\n", len
);
971 if (len
> maxlen
- 1) {
975 memcpy(num
, src
, len
);
979 static FUNC_DUMP(dump_called_party_number
)
983 q931_get_number(cnum
, sizeof(cnum
), ie
->data
+ 1, len
- 3);
984 pri_message(pri
, "%c Called Number (len=%2d) [ Ext: %d TON: %s (%d) NPI: %s (%d) '%s' ]\n",
985 prefix
, len
, ie
->data
[0] >> 7, ton2str((ie
->data
[0] >> 4) & 0x07), (ie
->data
[0] >> 4) & 0x07, npi2str(ie
->data
[0] & 0x0f), ie
->data
[0] & 0x0f, cnum
);
988 static FUNC_DUMP(dump_called_party_subaddr
)
991 q931_get_number(cnum
, sizeof(cnum
), ie
->data
+ 1, len
- 3);
992 pri_message(pri
, "%c Called Sub-Address (len=%2d) [ Ext: %d Type: %s (%d) O: %d '%s' ]\n",
993 prefix
, len
, ie
->data
[0] >> 7,
994 subaddrtype2str((ie
->data
[0] & 0x70) >> 4), (ie
->data
[0] & 0x70) >> 4,
995 (ie
->data
[0] & 0x08) >> 3, cnum
);
998 static FUNC_DUMP(dump_calling_party_number
)
1001 if (ie
->data
[0] & 0x80)
1002 q931_get_number(cnum
, sizeof(cnum
), ie
->data
+ 1, len
- 3);
1004 q931_get_number(cnum
, sizeof(cnum
), ie
->data
+ 2, len
- 4);
1005 pri_message(pri
, "%c Calling Number (len=%2d) [ Ext: %d TON: %s (%d) NPI: %s (%d)\n", prefix
, len
, ie
->data
[0] >> 7, ton2str((ie
->data
[0] >> 4) & 0x07), (ie
->data
[0] >> 4) & 0x07, npi2str(ie
->data
[0] & 0x0f), ie
->data
[0] & 0x0f);
1006 if (ie
->data
[0] & 0x80)
1007 pri_message(pri
, "%c Presentation: %s (%d) '%s' ]\n", prefix
, pri_pres2str(0), 0, cnum
);
1009 pri_message(pri
, "%c Presentation: %s (%d) '%s' ]\n", prefix
, pri_pres2str(ie
->data
[1] & 0x7f), ie
->data
[1] & 0x7f, cnum
);
1012 static FUNC_DUMP(dump_calling_party_subaddr
)
1015 q931_get_number(cnum
, sizeof(cnum
), ie
->data
+ 1, len
- 3);
1016 pri_message(pri
, "%c Calling Sub-Address (len=%2d) [ Ext: %d Type: %s (%d) O: %d '%s' ]\n",
1017 prefix
, len
, ie
->data
[0] >> 7,
1018 subaddrtype2str((ie
->data
[0] & 0x70) >> 4), (ie
->data
[0] & 0x70) >> 4,
1019 (ie
->data
[0] & 0x08) >> 3, cnum
);
1022 static FUNC_DUMP(dump_redirecting_number
)
1026 /* To follow Q.931 (4.5.1), we must search for start of octet 4 by
1027 walking through all bytes until one with ext bit (8) set to 1 */
1030 case 0: /* Octet 3 */
1031 pri_message(pri
, "%c Redirecting Number (len=%2d) [ Ext: %d TON: %s (%d) NPI: %s (%d)",
1032 prefix
, len
, ie
->data
[0] >> 7, ton2str((ie
->data
[0] >> 4) & 0x07), (ie
->data
[0] >> 4) & 0x07, npi2str(ie
->data
[0] & 0x0f), ie
->data
[0] & 0x0f);
1034 case 1: /* Octet 3a */
1035 pri_message(pri
, "\n%c Ext: %d Presentation: %s (%d)",
1036 prefix
, ie
->data
[1] >> 7, pri_pres2str(ie
->data
[1] & 0x7f), ie
->data
[1] & 0x7f);
1038 case 2: /* Octet 3b */
1039 pri_message(pri
, "\n%c Ext: %d Reason: %s (%d)",
1040 prefix
, ie
->data
[2] >> 7, redirection_reason2str(ie
->data
[2] & 0x7f), ie
->data
[2] & 0x7f);
1044 while(!(ie
->data
[i
++]& 0x80));
1045 q931_get_number(cnum
, sizeof(cnum
), ie
->data
+ i
, ie
->len
- i
);
1046 pri_message(pri
, " '%s' ]\n", cnum
);
1049 static FUNC_DUMP(dump_connected_number
)
1053 /* To follow Q.931 (4.5.1), we must search for start of octet 4 by
1054 walking through all bytes until one with ext bit (8) set to 1 */
1057 case 0: /* Octet 3 */
1058 pri_message(pri
, "%c Connected Number (len=%2d) [ Ext: %d TON: %s (%d) NPI: %s (%d)",
1059 prefix
, len
, ie
->data
[0] >> 7, ton2str((ie
->data
[0] >> 4) & 0x07), (ie
->data
[0] >> 4) & 0x07, npi2str(ie
->data
[0] & 0x0f), ie
->data
[0] & 0x0f);
1061 case 1: /* Octet 3a */
1062 pri_message(pri
, "\n%c Ext: %d Presentation: %s (%d)",
1063 prefix
, ie
->data
[1] >> 7, pri_pres2str(ie
->data
[1] & 0x7f), ie
->data
[1] & 0x7f);
1067 while(!(ie
->data
[i
++]& 0x80));
1068 q931_get_number(cnum
, sizeof(cnum
), ie
->data
+ i
, ie
->len
- i
);
1069 pri_message(pri
, " '%s' ]\n", cnum
);
1073 static FUNC_RECV(receive_redirecting_number
)
1077 /* To follow Q.931 (4.5.1), we must search for start of octet 4 by
1078 walking through all bytes until one with ext bit (8) set to 1 */
1082 call
->redirectingplan
= ie
->data
[i
] & 0x7f;
1085 call
->redirectingpres
= ie
->data
[i
] & 0x7f;
1088 call
->redirectingreason
= ie
->data
[i
] & 0x0f;
1092 while(!(ie
->data
[i
++] & 0x80));
1093 q931_get_number(call
->redirectingnum
, sizeof(call
->redirectingnum
), ie
->data
+ i
, ie
->len
- i
);
1097 static FUNC_SEND(transmit_redirecting_number
)
1101 if (call
->redirectingnum
&& strlen(call
->redirectingnum
)) {
1102 ie
->data
[0] = call
->redirectingplan
;
1103 ie
->data
[1] = call
->redirectingpres
;
1104 ie
->data
[2] = (call
->redirectingreason
& 0x0f) | 0x80;
1105 memcpy(ie
->data
+ 3, call
->redirectingnum
, strlen(call
->redirectingnum
));
1106 return strlen(call
->redirectingnum
) + 3 + 2;
1111 static FUNC_DUMP(dump_redirecting_subaddr
)
1114 q931_get_number(cnum
, sizeof(cnum
), ie
->data
+ 2, len
- 4);
1115 pri_message(pri
, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d Type: %s (%d) O: %d '%s' ]\n",
1116 prefix
, len
, ie
->data
[0] >> 7,
1117 subaddrtype2str((ie
->data
[0] & 0x70) >> 4), (ie
->data
[0] & 0x70) >> 4,
1118 (ie
->data
[0] & 0x08) >> 3, cnum
);
1121 static FUNC_RECV(receive_calling_party_subaddr
)
1123 /* copy digits to call->callingsubaddr */
1124 q931_get_number(call
->callingsubaddr
, sizeof(call
->callingsubaddr
), ie
->data
+ 1, len
- 3);
1128 static FUNC_RECV(receive_called_party_number
)
1130 /* copy digits to call->callednum */
1131 q931_get_number(call
->callednum
, sizeof(call
->callednum
), ie
->data
+ 1, len
- 3);
1132 call
->calledplan
= ie
->data
[0] & 0x7f;
1136 static FUNC_SEND(transmit_called_party_number
)
1138 ie
->data
[0] = 0x80 | call
->calledplan
;
1139 if (*call
->callednum
)
1140 memcpy(ie
->data
+ 1, call
->callednum
, strlen(call
->callednum
));
1141 return strlen(call
->callednum
) + 3;
1144 static FUNC_RECV(receive_calling_party_number
)
1149 if (ie
->data
[0] & 0x80) {
1150 data
= ie
->data
+ 1;
1152 call
->callerpres
= 0; /* PI presentation allowed SI user-provided, not screened */
1154 data
= ie
->data
+ 2;
1156 call
->callerpres
= ie
->data
[1] & 0x7f;
1159 if (call
->callerpres
== PRES_ALLOWED_NETWORK_NUMBER
||
1160 call
->callerpres
== PRES_PROHIB_NETWORK_NUMBER
) {
1161 q931_get_number((char *)call
->callerani
, sizeof(call
->callerani
), data
, length
);
1162 call
->callerplanani
= ie
->data
[0] & 0x7f;
1164 if (!*call
->callernum
) { /*Copy ANI to CallerID if CallerID is not already set */
1165 libpri_copy_string(call
->callernum
, call
->callerani
, sizeof(call
->callernum
));
1166 call
->callerplan
= call
->callerplanani
;
1170 q931_get_number((char *)call
->callernum
, sizeof(call
->callernum
), data
, length
);
1171 call
->callerplan
= ie
->data
[0] & 0x7f;
1177 static FUNC_SEND(transmit_calling_party_number
)
1179 ie
->data
[0] = call
->callerplan
;
1180 ie
->data
[1] = 0x80 | call
->callerpres
;
1181 if (strlen(call
->callernum
))
1182 memcpy(ie
->data
+ 2, call
->callernum
, strlen(call
->callernum
));
1183 return strlen(call
->callernum
) + 4;
1186 static FUNC_DUMP(dump_user_user
)
1189 pri_message(pri
, "%c User-User Information (len=%2d) [", prefix
, len
);
1190 for (x
=0;x
<ie
->len
;x
++)
1191 pri_message(pri
, " %02x", ie
->data
[x
] & 0x7f);
1192 pri_message(pri
, " ]\n");
1196 static FUNC_RECV(receive_user_user
)
1198 call
->useruserprotocoldisc
= ie
->data
[0] & 0xff;
1199 if (call
->useruserprotocoldisc
== 4) { /* IA5 */
1201 q931_get_number(call
->useruserinfo
, sizeof(call
->useruserinfo
), ie
->data
+ 1, len
- 3);
1203 pri_error(call
->pri
, "User-User Information (len=%2d) too short.\n", len
);
1209 static FUNC_RECV(receive_call_identity
)
1212 q931_get_number(call
->callid
, sizeof(call
->callid
), ie
->data
, len
- 2);
1214 pri_error(call
->pri
, "Call Identity (len=%2d) too short.\n", len
);
1219 static FUNC_SEND(transmit_call_identity
)
1221 if (strlen(call
->callid
))
1222 memcpy(ie
->data
, call
->callid
, strlen(call
->callid
));
1223 return strlen(call
->callednum
) + 3;
1226 static FUNC_RECV(receive_high_layer_compat
)
1231 static FUNC_SEND(transmit_high_layer_compat
)
1233 if (call
->transcapability
!= PRI_TRANS_CAP_RESTRICTED_DIGITAL
&& call
->transcapability
!= PRI_TRANS_CAP_DIGITAL
&& call
->transcapability
!= PRI_TRANS_CAP_DIGITAL_W_TONES
) {
1241 static FUNC_DUMP(dump_high_layer_compat
)
1244 pri_message(pri
, "%c High-layer compatibilty (len=%2d) [ ", prefix
, len
);
1245 for (x
=0;x
<ie
->len
;x
++)
1246 pri_message(pri
, "0x%02X ", ie
->data
[x
]);
1247 pri_message(pri
, " ]\n");
1251 static FUNC_RECV(receive_low_layer_compat
)
1255 pri_error(pri
, "%d bytes LLC too long\n", len
);
1258 pri_error(pri
, "copying %d bytes LLC \n", len
);
1260 memcpy(call
->llc
+1, ie
->data
, len
);
1266 static FUNC_SEND(transmit_low_layer_compat
)
1268 if (call
->llc
[0] == 0) return 0;
1269 memcpy(ie
->data
, call
->llc
+ 1, call
->llc
[0]);
1270 return call
->llc
[0] + 2;
1273 static FUNC_DUMP(dump_low_layer_compat
)
1276 pri_message(pri
, "%c Low-layer compatibilty (len=%2d) [ ", prefix
, len
);
1277 for (x
=0;x
<ie
->len
;x
++)
1278 pri_message(pri
, "0x%02X ", ie
->data
[x
]);
1279 pri_message(pri
, " ]\n");
1282 static FUNC_SEND(transmit_user_user
)
1284 int datalen
= strlen(call
->useruserinfo
);
1286 /* Restricted to 35 characters */
1287 if (msgtype
== Q931_USER_INFORMATION
) {
1294 ie
->data
[0] = 4; /* IA5 characters */
1295 memcpy(&ie
->data
[1], call
->useruserinfo
, datalen
);
1296 call
->useruserinfo
[0] = '\0';
1303 static char *prog2str(int prog
)
1305 static struct msgtype progs
[] = {
1306 { Q931_PROG_CALL_NOT_E2E_ISDN
, "Call is not end-to-end ISDN; further call progress information may be available inband." },
1307 { Q931_PROG_CALLED_NOT_ISDN
, "Called equipment is non-ISDN." },
1308 { Q931_PROG_CALLER_NOT_ISDN
, "Calling equipment is non-ISDN." },
1309 { Q931_PROG_INBAND_AVAILABLE
, "Inband information or appropriate pattern now available." },
1310 { Q931_PROG_DELAY_AT_INTERF
, "Delay in response at called Interface." },
1311 { Q931_PROG_INTERWORKING_WITH_PUBLIC
, "Interworking with a public network." },
1312 { Q931_PROG_INTERWORKING_NO_RELEASE
, "Interworking with a network unable to supply a release signal." },
1313 { Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER
, "Interworking with a network unable to supply a release signal before answer." },
1314 { Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER
, "Interworking with a network unable to supply a release signal after answer." },
1316 return code2str(prog
, progs
, sizeof(progs
) / sizeof(progs
[0]));
1319 static char *coding2str(int cod
)
1321 static struct msgtype cods
[] = {
1322 { CODE_CCITT
, "CCITT (ITU) standard" },
1323 { CODE_INTERNATIONAL
, "Non-ITU international standard" },
1324 { CODE_NATIONAL
, "National standard" },
1325 { CODE_NETWORK_SPECIFIC
, "Network specific standard" },
1327 return code2str(cod
, cods
, sizeof(cods
) / sizeof(cods
[0]));
1330 static char *loc2str(int loc
)
1332 static struct msgtype locs
[] = {
1333 { LOC_USER
, "User" },
1334 { LOC_PRIV_NET_LOCAL_USER
, "Private network serving the local user" },
1335 { LOC_PUB_NET_LOCAL_USER
, "Public network serving the local user" },
1336 { LOC_TRANSIT_NET
, "Transit network" },
1337 { LOC_PUB_NET_REMOTE_USER
, "Public network serving the remote user" },
1338 { LOC_PRIV_NET_REMOTE_USER
, "Private network serving the remote user" },
1339 { LOC_INTERNATIONAL_NETWORK
, "International network" },
1340 { LOC_NETWORK_BEYOND_INTERWORKING
, "Network beyond the interworking point" },
1342 return code2str(loc
, locs
, sizeof(locs
) / sizeof(locs
[0]));
1345 static FUNC_DUMP(dump_progress_indicator
)
1347 pri_message(pri
, "%c Progress Indicator (len=%2d) [ Ext: %d Coding: %s (%d) 0: %d Location: %s (%d)\n",
1348 prefix
, len
, ie
->data
[0] >> 7, coding2str((ie
->data
[0] & 0x60) >> 5), (ie
->data
[0] & 0x60) >> 5,
1349 (ie
->data
[0] & 0x10) >> 4, loc2str(ie
->data
[0] & 0xf), ie
->data
[0] & 0xf);
1350 pri_message(pri
, "%c Ext: %d Progress Description: %s (%d) ]\n",
1351 prefix
, ie
->data
[1] >> 7, prog2str(ie
->data
[1] & 0x7f), ie
->data
[1] & 0x7f);
1354 static FUNC_RECV(receive_display
)
1356 unsigned char *data
;
1358 if (data
[0] & 0x80) {
1359 /* Skip over character set */
1363 q931_get_number((char *) call
->callername
, sizeof(call
->callername
), data
, len
- 2);
1367 static FUNC_SEND(transmit_display
)
1371 if ((pri
->switchtype
== PRI_SWITCH_QSIG
) ||
1372 ((pri
->switchtype
== PRI_SWITCH_EUROISDN_E1
) && (pri
->localtype
== PRI_CPE
)) ||
1373 !call
->callername
[0])
1377 if(pri
->switchtype
!= PRI_SWITCH_EUROISDN_E1
) {
1381 memcpy(ie
->data
+ i
, call
->callername
, strlen(call
->callername
));
1382 return 2 + i
+ strlen(call
->callername
);
1385 static FUNC_RECV(receive_progress_indicator
)
1387 call
->progloc
= ie
->data
[0] & 0xf;
1388 call
->progcode
= (ie
->data
[0] & 0x60) >> 5;
1389 switch (call
->progress
= (ie
->data
[1] & 0x7f)) {
1390 case Q931_PROG_CALL_NOT_E2E_ISDN
:
1391 call
->progressmask
|= PRI_PROG_CALL_NOT_E2E_ISDN
;
1393 case Q931_PROG_CALLED_NOT_ISDN
:
1394 call
->progressmask
|= PRI_PROG_CALLED_NOT_ISDN
;
1396 case Q931_PROG_CALLER_NOT_ISDN
:
1397 call
->progressmask
|= PRI_PROG_CALLER_NOT_ISDN
;
1399 case Q931_PROG_CALLER_RETURNED_TO_ISDN
:
1400 call
->progressmask
|= PRI_PROG_CALLER_RETURNED_TO_ISDN
;
1402 case Q931_PROG_INBAND_AVAILABLE
:
1403 call
->progressmask
|= PRI_PROG_INBAND_AVAILABLE
;
1405 case Q931_PROG_DELAY_AT_INTERF
:
1406 call
->progressmask
|= PRI_PROG_DELAY_AT_INTERF
;
1408 case Q931_PROG_INTERWORKING_WITH_PUBLIC
:
1409 call
->progressmask
|= PRI_PROG_INTERWORKING_WITH_PUBLIC
;
1411 case Q931_PROG_INTERWORKING_NO_RELEASE
:
1412 call
->progressmask
|= PRI_PROG_INTERWORKING_NO_RELEASE
;
1414 case Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER
:
1415 call
->progressmask
|= PRI_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER
;
1417 case Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER
:
1418 call
->progressmask
|= PRI_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER
;
1421 pri_error(pri
, "XXX Invalid Progress indicator value received: %02x\n",(ie
->data
[1] & 0x7f));
1428 static FUNC_RECV(receive_facility_kpj
)
1430 unsigned char cpt_tag
, cp_len
, invoke_id_tag
, invoke_id_len
, operation_value_len
, operation_value_tag
;
1431 unsigned char arg_len
= 0;
1432 unsigned char pos
= 0;
1433 short invoke_id
= 0, operation_value
= 0;
1434 if ((ie
->data
[pos
++] & 0x1F) == 0x11) {
1435 /* service discriminator == supplementary services */
1436 cpt_tag
= ie
->data
[pos
++] & 0x1F;
1437 cp_len
= ie
->data
[pos
++];
1439 case 1: /* invoke */
1440 invoke_id_tag
= ie
->data
[pos
++];
1441 if (invoke_id_tag
!= 0x02) {
1442 // pri_error(call->pri, "invoke id tag != 0x02\n");
1445 invoke_id_len
= ie
->data
[pos
++]; // 4
1446 while (invoke_id_len
> 0) {
1447 invoke_id
= (invoke_id
<< 8) | (ie
->data
[pos
++] & 0xFF);
1450 operation_value_tag
= ie
->data
[pos
++];
1451 if (operation_value_tag
!= 0x02) {
1452 // pri_error(call->pri, "operation value tag != 0x02\n");
1455 operation_value_len
= ie
->data
[pos
++];
1456 while (operation_value_len
> 0) {
1457 operation_value
= (operation_value
<< 8) | (ie
->data
[pos
++] & 0xFF);
1458 operation_value_len
--;
1460 arg_len
= ie
->len
- pos
;
1461 switch (operation_value
) {
1462 case 0x06: /* ECT execute */
1463 call
->facility
= operation_value
;
1465 case 0x0D: /* call deflection */
1466 call
->facility
= operation_value
;
1471 q931_get_number(call
->redirectingnum
, sizeof(call
->redirectingnum
), ie
->data
+ pos
, arg_len
);
1473 /* now retrieve the number */
1475 case 0x22: /* AOC-D */
1477 case 0x24: /* AOC-E */
1481 case 2: /* return result */
1483 case 3: /* return error */
1485 case 4: /* reject */
1489 /* OLD DIRTY ULAW HACK */
1491 pri_error(call
->pri
, "!! Facility message shorter than 14 bytes\n");
1494 if (ie
->data
[13] + 14 == ie
->len
) {
1495 q931_get_number(call
->callername
, sizeof(call
->callername
) - 1, ie
->data
+ 14, ie
->len
- 14);
1497 call
->facility
= 0x0;
1502 static FUNC_SEND(transmit_facility_kpj
)
1506 if (call
->aoc
&& (pri
->switchtype
== PRI_SWITCH_EUROISDN_E1
) && ((pri
->localtype
== BRI_NETWORK
) || (pri
->localtype
== BRI_NETWORK_PTMP
) || (pri
->localtype
== PRI_NETWORK
))) {
1507 ie
->data
[0] = 0x90; /* PP remote operations */
1508 ie
->data
[i
++] = 0x00; /* component tag */
1509 ie
->data
[i
++] = 0x02; /* invoke id tag */
1510 ie
->data
[i
++] = 0x02; /* invoke id len */
1511 ie
->data
[i
++] = 0x34; /* invoke id */
1512 ie
->data
[i
++] = 0x56; /* invoke id */
1513 ie
->data
[i
++] = 0x02; /* operation value tag */
1514 ie
->data
[i
++] = 0x01; /* operation value len */
1517 ie
->data
[i
++] = 0x26; /* operation value AOC-S */
1519 case Q931_DISCONNECT
:
1520 ie
->data
[i
++] = 0x24; /* operation value AOC-E */
1523 ie
->data
[i
++] = 0x22; /* operation value AOC-D */
1532 static FUNC_SEND(transmit_facility
)
1534 struct apdu_event
*tmp
;
1537 for (tmp
= call
->apdus
; tmp
; tmp
= tmp
->next
) {
1538 if ((tmp
->message
== msgtype
) && !tmp
->sent
)
1542 if (!tmp
) /* No APDU found */
1545 if (tmp
->apdu_len
> 235) { /* TODO: find out how much space we can use */
1546 pri_message(pri
, "Requested APDU (%d bytes) is too long\n", tmp
->apdu_len
);
1550 memcpy(&ie
->data
[i
], tmp
->apdu
, tmp
->apdu_len
);
1558 static FUNC_SEND(transmit_facility
)
1560 int i
= 0, j
, first_i
, compsp
= 0;
1561 struct rose_component
*comp
, *compstk
[10];
1562 unsigned char namelen
= strlen(call
->callername
);
1564 if ((pri
->switchtype
== PRI_SWITCH_NI2
) && (namelen
> 15))
1565 namelen
= 15; /* According to GR-1367, for NI2 switches it can't be > 15 characters */
1566 if ((namelen
> 0) && ((pri
->switchtype
== PRI_SWITCH_QSIG
) ||
1567 ((pri
->switchtype
== PRI_SWITCH_NI2
) && (pri
->localtype
== PRI_NETWORK
)))) {
1570 ie
->data
[i
] = 0x80 | Q932_PROTOCOL_EXTENSIONS
;
1572 /* Interpretation component */
1573 ASN1_ADD_BYTECOMP(comp
, COMP_TYPE_INTERPRETATION
, ie
->data
, i
, 0x00 /* Discard unrecognized invokes */);
1576 ASN1_ADD_SIMPLE(comp
, COMP_TYPE_INVOKE
, ie
->data
, i
);
1577 ASN1_PUSH(compstk
, compsp
, comp
);
1579 /* Invoke component contents */
1581 ASN1_ADD_BYTECOMP(comp
, ASN1_INTEGER
, ie
->data
, i
, ++pri
->last_invoke
);
1584 ASN1_ADD_BYTECOMP(comp
, ASN1_INTEGER
, ie
->data
, i
, SS_CNID_CALLINGNAME
);
1587 j
= asn1_string_encode(ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE
, &ie
->data
[i
], len
- i
, 15, call
->callername
, namelen
);
1594 /* Fix length of stacked components */
1596 ASN1_FIXUP(compstk
, compsp
, ie
->data
, i
);
1600 if (/*(pri->switchtype == PRI_SWITCH_EUROISDN_E1) &&*/ call
->redirectingnum
&& strlen(call
->redirectingnum
)) {
1601 if (!(first_i
= i
)) {
1602 /* Add protocol information header */
1603 ie
->data
[i
++] = 0x80 | Q932_PROTOCOL_ROSE
;
1606 /* ROSE invoke component */
1607 ASN1_ADD_SIMPLE(comp
, COMP_TYPE_INVOKE
, ie
->data
, i
);
1608 ASN1_PUSH(compstk
, compsp
, comp
);
1610 /* ROSE invokeId component */
1611 ASN1_ADD_BYTECOMP(comp
, ASN1_INTEGER
, ie
->data
, i
, ++pri
->last_invoke
);
1613 /* ROSE operationId component */
1614 ASN1_ADD_BYTECOMP(comp
, ASN1_INTEGER
, ie
->data
, i
, ROSE_DIVERTING_LEG_INFORMATION2
);
1616 /* ROSE ARGUMENT component */
1617 ASN1_ADD_SIMPLE(comp
, 0x30, ie
->data
, i
);
1618 ASN1_PUSH(compstk
, compsp
, comp
);
1620 /* ROSE DivertingLegInformation2.diversionCounter component */
1621 /* Always is 1 because other isn't available in the current design */
1622 ASN1_ADD_BYTECOMP(comp
, ASN1_INTEGER
, ie
->data
, i
, 1);
1624 /* ROSE DivertingLegInformation2.diversionReason component */
1625 ASN1_ADD_BYTECOMP(comp
, ASN1_ENUMERATED
, ie
->data
, i
, redirectingreason_from_q931(pri
, call
->redirectingreason
));
1627 /* ROSE DivertingLegInformation2.divertingNr component */
1628 ASN1_ADD_SIMPLE(comp
, 0xA1, ie
->data
, i
);
1629 ASN1_PUSH(compstk
, compsp
, comp
);
1631 /* Redirecting information always not screened */
1632 switch(call
->redirectingpres
) {
1633 case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
:
1634 case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
:
1635 if (call
->redirectingnum
&& strlen(call
->redirectingnum
)) {
1636 ASN1_ADD_SIMPLE(comp
, 0xA0, ie
->data
, i
);
1637 ASN1_PUSH(compstk
, compsp
, comp
);
1639 /* NPI of redirected number is not supported in the current design */
1640 ASN1_ADD_SIMPLE(comp
, 0xA1, ie
->data
, i
);
1641 ASN1_PUSH(compstk
, compsp
, comp
);
1643 ASN1_ADD_BYTECOMP(comp
, ASN1_ENUMERATED
, ie
->data
, i
, typeofnumber_from_q931(pri
, call
->redirectingplan
>> 4));
1645 j
= asn1_string_encode(ASN1_NUMERICSTRING
, &ie
->data
[i
], len
- i
, 20, call
->redirectingnum
, strlen(call
->redirectingnum
));
1651 ASN1_FIXUP(compstk
, compsp
, ie
->data
, i
);
1652 ASN1_FIXUP(compstk
, compsp
, ie
->data
, i
);
1656 case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN
:
1657 case PRES_PROHIB_USER_NUMBER_NOT_SCREENED
:
1658 ASN1_ADD_SIMPLE(comp
, 0x81, ie
->data
, i
);
1660 /* Don't know how to handle this */
1661 case PRES_ALLOWED_NETWORK_NUMBER
:
1662 case PRES_PROHIB_NETWORK_NUMBER
:
1663 case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN
:
1664 case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN
:
1665 ASN1_ADD_SIMPLE(comp
, 0x81, ie
->data
, i
);
1668 pri_message(pri
, "!! Undefined presentation value for redirecting number: %d\n", call
->redirectingpres
);
1669 case PRES_NUMBER_NOT_AVAILABLE
:
1670 ASN1_ADD_SIMPLE(comp
, 0x82, ie
->data
, i
);
1673 ASN1_FIXUP(compstk
, compsp
, ie
->data
, i
);
1675 /* ROSE DivertingLegInformation2.originalCalledNr component */
1676 /* This information isn't supported by current design - duplicate divertingNr */
1677 ASN1_ADD_SIMPLE(comp
, 0xA2, ie
->data
, i
);
1678 ASN1_PUSH(compstk
, compsp
, comp
);
1680 /* Redirecting information always not screened */
1681 switch(call
->redirectingpres
) {
1682 case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
:
1683 case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
:
1684 if (call
->redirectingnum
&& strlen(call
->redirectingnum
)) {
1685 ASN1_ADD_SIMPLE(comp
, 0xA0, ie
->data
, i
);
1686 ASN1_PUSH(compstk
, compsp
, comp
);
1688 ASN1_ADD_SIMPLE(comp
, 0xA1, ie
->data
, i
);
1689 ASN1_PUSH(compstk
, compsp
, comp
);
1691 ASN1_ADD_BYTECOMP(comp
, ASN1_ENUMERATED
, ie
->data
, i
, typeofnumber_from_q931(pri
, call
->redirectingplan
>> 4));
1693 j
= asn1_string_encode(ASN1_NUMERICSTRING
, &ie
->data
[i
], len
- i
, 20, call
->redirectingnum
, strlen(call
->redirectingnum
));
1699 ASN1_FIXUP(compstk
, compsp
, ie
->data
, i
);
1700 ASN1_FIXUP(compstk
, compsp
, ie
->data
, i
);
1704 case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN
:
1705 case PRES_PROHIB_USER_NUMBER_NOT_SCREENED
:
1706 ASN1_ADD_SIMPLE(comp
, 0x81, ie
->data
, i
);
1708 /* Don't know how to handle this */
1709 case PRES_ALLOWED_NETWORK_NUMBER
:
1710 case PRES_PROHIB_NETWORK_NUMBER
:
1711 case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN
:
1712 case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN
:
1713 ASN1_ADD_SIMPLE(comp
, 0x81, ie
->data
, i
);
1716 pri_message(pri
, "!! Undefined presentation value for redirecting number: %d\n", call
->redirectingpres
);
1717 case PRES_NUMBER_NOT_AVAILABLE
:
1718 ASN1_ADD_SIMPLE(comp
, 0x82, ie
->data
, i
);
1721 ASN1_FIXUP(compstk
, compsp
, ie
->data
, i
);
1723 /* Fix length of stacked components */
1725 ASN1_FIXUP(compstk
, compsp
, ie
->data
, i
);
1729 return (i
? i
+2 : 0);
1733 static FUNC_RECV(receive_facility
)
1736 int protocol
, next_protocol
;
1737 struct rose_component
*comp
= NULL
;
1739 Q932_STATE_NFE
, /* Network facility extension */
1740 Q932_STATE_NPP
, /* Network protocol profile */
1741 Q932_STATE_INTERPRETATION
, /* Interpretation component */
1742 Q932_STATE_SERVICE
/* Service component(s) */
1743 } state
= Q932_STATE_SERVICE
;
1744 #define Q932_HANDLE_PROC(component, my_state, name, handler) \
1746 if(state > my_state) { \
1747 pri_error(pri, "!! %s component received in wrong place\n"); \
1752 pri_message(pri, "Handle Q.932 %s component\n", name); \
1753 (handler)(pri, call, comp->data, comp->len); \
1755 #define Q932_HANDLE_NULL(component, my_state, name, handle) \
1757 if(state > my_state) { \
1758 pri_error(pri, "!! %s component received in wrong place\n"); \
1762 if (pri->debug & PRI_DEBUG_APDU) \
1763 pri_message(pri, "Q.932 %s component is not handled\n", name); \
1769 switch(next_protocol
= protocol
= (ie
->data
[i
] & 0x1f)) {
1770 case Q932_PROTOCOL_CMIP
:
1771 case Q932_PROTOCOL_ACSE
:
1772 if (pri
->debug
& PRI_DEBUG_APDU
)
1773 pri_message(pri
, "!! Don't know how to handle Q.932 Protocol Profile of type 0x%X\n", protocol
);
1775 case Q932_PROTOCOL_EXTENSIONS
:
1776 state
= Q932_STATE_NFE
;
1777 next_protocol
= Q932_PROTOCOL_ROSE
;
1779 case Q932_PROTOCOL_ROSE
:
1782 pri_error(pri
, "!! Invalid Q.932 Protocol Profile of type 0x%X received\n", protocol
);
1785 /* Service indicator octet - Just ignore for now */
1786 if (!(ie
->data
[i
] & 0x80))
1793 while ((i
+1 < ie
->len
) && (&ie
->data
[i
])) {
1794 comp
= (struct rose_component
*)&ie
->data
[i
];
1796 if (protocol
== Q932_PROTOCOL_EXTENSIONS
) {
1797 switch (comp
->type
) {
1798 Q932_HANDLE_NULL(COMP_TYPE_INTERPRETATION
, Q932_STATE_INTERPRETATION
, "Interpretation", NULL
);
1799 Q932_HANDLE_NULL(COMP_TYPE_NFE
, Q932_STATE_NFE
, "Network facility extensions", NULL
);
1800 Q932_HANDLE_NULL(COMP_TYPE_NETWORK_PROTOCOL_PROFILE
, Q932_STATE_NPP
, "Network protocol profile", NULL
);
1802 protocol
= next_protocol
;
1807 case Q932_PROTOCOL_ROSE
:
1808 switch (comp
->type
) {
1809 Q932_HANDLE_PROC(COMP_TYPE_INVOKE
, Q932_STATE_SERVICE
, "ROSE Invoke", rose_invoke_decode
);
1810 Q932_HANDLE_PROC(COMP_TYPE_RETURN_RESULT
, Q932_STATE_SERVICE
, "ROSE return result", rose_return_result_decode
);
1811 Q932_HANDLE_PROC(COMP_TYPE_RETURN_ERROR
, Q932_STATE_SERVICE
, "ROSE return error", rose_return_error_decode
);
1812 Q932_HANDLE_PROC(COMP_TYPE_REJECT
, Q932_STATE_SERVICE
, "ROSE reject", rose_reject_decode
);
1814 if (pri
->debug
& PRI_DEBUG_APDU
)
1815 pri_message(pri
, "Don't know how to handle ROSE component of type 0x%X\n", comp
->type
);
1819 case Q932_PROTOCOL_CMIP
:
1820 switch (comp
->type
) {
1822 if (pri
->debug
& PRI_DEBUG_APDU
)
1823 pri_message(pri
, "Don't know how to handle CMIP component of type 0x%X\n", comp
->type
);
1827 case Q932_PROTOCOL_ACSE
:
1828 switch (comp
->type
) {
1830 if (pri
->debug
& PRI_DEBUG_APDU
)
1831 pri_message(pri
, "Don't know how to handle ACSE component of type 0x%X\n", comp
->type
);
1837 i
+= (comp
->len
+ 2);
1844 static FUNC_SEND(transmit_progress_indicator
)
1847 /* Can't send progress indicator on GR-303 -- EVER! */
1848 if (pri
->subchannel
)
1850 if (call
->progressmask
> 0) {
1851 if (call
->progressmask
& (mask
= PRI_PROG_CALL_NOT_E2E_ISDN
))
1852 code
= Q931_PROG_CALL_NOT_E2E_ISDN
;
1853 else if (call
->progressmask
& (mask
= PRI_PROG_CALLED_NOT_ISDN
))
1854 code
= Q931_PROG_CALLED_NOT_ISDN
;
1855 else if (call
->progressmask
& (mask
= PRI_PROG_CALLER_NOT_ISDN
))
1856 code
= Q931_PROG_CALLER_NOT_ISDN
;
1857 else if (call
->progressmask
& (mask
= PRI_PROG_INBAND_AVAILABLE
))
1858 code
= Q931_PROG_INBAND_AVAILABLE
;
1859 else if (call
->progressmask
& (mask
= PRI_PROG_DELAY_AT_INTERF
))
1860 code
= Q931_PROG_DELAY_AT_INTERF
;
1861 else if (call
->progressmask
& (mask
= PRI_PROG_INTERWORKING_WITH_PUBLIC
))
1862 code
= Q931_PROG_INTERWORKING_WITH_PUBLIC
;
1863 else if (call
->progressmask
& (mask
= PRI_PROG_INTERWORKING_NO_RELEASE
))
1864 code
= Q931_PROG_INTERWORKING_NO_RELEASE
;
1865 else if (call
->progressmask
& (mask
= PRI_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER
))
1866 code
= Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER
;
1867 else if (call
->progressmask
& (mask
= PRI_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER
))
1868 code
= Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER
;
1871 pri_error(pri
, "XXX Undefined progress bit: %x\n", call
->progressmask
);
1874 ie
->data
[0] = 0x80 | (call
->progcode
<< 5) | (call
->progloc
);
1875 ie
->data
[1] = 0x80 | code
;
1876 call
->progressmask
&= ~mask
;
1883 static FUNC_SEND(transmit_call_state
)
1885 if (call
->ourcallstate
> -1 ) {
1886 ie
->data
[0] = call
->ourcallstate
;
1892 static FUNC_RECV(receive_call_state
)
1894 call
->sugcallstate
= ie
->data
[0] & 0x3f;
1898 static char *callstate2str(int callstate
)
1900 static struct msgtype callstates
[] = {
1902 { 1, "Call Initiated" },
1903 { 2, "Overlap sending" },
1904 { 3, "Outgoing call Proceeding" },
1905 { 4, "Call Delivered" },
1906 { 6, "Call Present" },
1907 { 7, "Call Received" },
1908 { 8, "Connect Request" },
1909 { 9, "Incoming Call Proceeding" },
1911 { 11, "Disconnect Request" },
1912 { 12, "Disconnect Indication" },
1913 { 15, "Suspend Request" },
1914 { 17, "Resume Request" },
1915 { 19, "Release Request" },
1916 { 22, "Call Abort" },
1917 { 25, "Overlap Receiving" },
1918 { 61, "Restart Request" },
1921 return code2str(callstate
, callstates
, sizeof(callstates
) / sizeof(callstates
[0]));
1924 static FUNC_DUMP(dump_call_state
)
1926 pri_message(pri
, "%c Call State (len=%2d) [ Ext: %d Coding: %s (%d) Call state: %s (%d)\n",
1927 prefix
, len
, ie
->data
[0] >> 7, coding2str((ie
->data
[0] & 0xC0) >> 6), (ie
->data
[0] & 0xC0) >> 6,
1928 callstate2str(ie
->data
[0] & 0x3f), ie
->data
[0] & 0x3f);
1931 static FUNC_DUMP(dump_call_identity
)
1934 pri_message(pri
, "%c Call Identity (len=%2d) [ ", prefix
, len
);
1935 for (x
=0;x
<ie
->len
;x
++)
1936 pri_message(pri
, "0x%02X ", ie
->data
[x
]);
1937 pri_message(pri
, " ]\n");
1941 static FUNC_RECV(receive_time_date
)
1946 static FUNC_SEND(transmit_time_date
) {
1948 struct tm
*timedate
;
1950 timedate
= localtime(&now
);
1951 ie
->data
[0] = timedate
->tm_year
- 100; // 1900+
1952 ie
->data
[1] = timedate
->tm_mon
+ 1;
1953 ie
->data
[2] = timedate
->tm_mday
;
1954 ie
->data
[3] = timedate
->tm_hour
;
1955 ie
->data
[4] = timedate
->tm_min
;
1959 static FUNC_DUMP(dump_time_date
)
1961 pri_message(pri
, "%c Time Date (len=%2d) [ ", prefix
, len
);
1963 pri_message(pri
, "%02d", ie
->data
[0]);
1965 pri_message(pri
, "-%02d", ie
->data
[1]);
1967 pri_message(pri
, "-%02d", ie
->data
[2]);
1969 pri_message(pri
, " %02d", ie
->data
[3]);
1971 pri_message(pri
, ":%02d", ie
->data
[4]);
1973 pri_message(pri
, ":%02d", ie
->data
[5]);
1974 pri_message(pri
, " ]\n");
1977 static FUNC_DUMP(dump_keypad_facility
)
1981 if (ie
->len
== 0 || ie
->len
> sizeof(tmp
))
1984 memcpy(tmp
, ie
->data
, ie
->len
);
1985 tmp
[ie
->len
] = '\0';
1986 pri_message(pri
, "%c Keypad Facility (len=%2d) [ %s ]\n", prefix
, ie
->len
, tmp
);
1989 static FUNC_RECV(receive_keypad_facility
)
1996 if (ie
->len
> (sizeof(call
->keypad_digits
) - 1))
1997 mylen
= (sizeof(call
->keypad_digits
) - 1);
2001 memcpy(call
->keypad_digits
, ie
->data
, mylen
);
2002 call
->keypad_digits
[mylen
] = 0;
2007 static FUNC_SEND(transmit_keypad_facility
)
2011 sublen
= strlen(call
->keypad_digits
);
2015 call
->keypad_digits
[32] = '\0';
2019 libpri_copy_string((char *)ie
->data
, (char *)call
->keypad_digits
, sizeof(call
->keypad_digits
));
2020 /* Make sure we clear the field */
2021 call
->keypad_digits
[0] = '\0';
2027 static FUNC_DUMP(dump_display
)
2030 char *buf
= malloc(len
+ 1);
2034 if ((x
< ie
->len
) && (ie
->data
[x
] & 0x80)) {
2035 sprintf(tmp
, "Charset: %02x ", ie
->data
[x
] & 0x7f);
2038 for (y
=x
; x
<ie
->len
; x
++)
2039 buf
[x
] = ie
->data
[x
] & 0x7f;
2041 pri_message(pri
, "%c Display (len=%2d) %s[ %s ]\n", prefix
, ie
->len
, tmp
, &buf
[y
]);
2046 #define CHECK_OVERFLOW(limit) \
2047 if (tmpptr - tmp + limit >= sizeof(tmp)) { \
2049 pri_message(pri, "%s", tmpptr = tmp); \
2052 static void dump_ie_data(struct pri
*pri
, unsigned char *c
, int len
)
2054 static char hexs
[16] = "0123456789ABCDEF";
2055 char tmp
[1024], *tmpptr
;
2058 for (; len
; --len
, ++c
) {
2062 if (tmpptr
!= tmp
) {
2075 if (tmpptr
!= tmp
) {
2081 *tmpptr
++ = hexs
[(*c
>> 4) & 0x0f];
2082 *tmpptr
++ = hexs
[(*c
) & 0x0f];
2088 pri_message(pri
, "%s", tmp
);
2091 static FUNC_DUMP(dump_facility
)
2093 int dataat
= (ie
->data
[0] & 0x80) ? 1 : 2;
2094 pri_message(pri
, "%c Facility (len=%2d, codeset=%d) [ ", prefix
, len
, Q931_IE_CODESET(full_ie
));
2095 dump_ie_data(pri
, ie
->data
, ie
->len
);
2096 pri_message(NULL
, " ]\n");
2098 pri_message(pri
, "PROTOCOL %02X\n", ie
->data
[0] & ASN1_TYPE_MASK
);
2099 asn1_dump(pri
, &ie
->data
[dataat
], ie
->len
- dataat
);
2104 static FUNC_DUMP(dump_network_spec_fac
)
2106 pri_message(pri
, "%c Network-Specific Facilities (len=%2d) [ ", prefix
, ie
->len
);
2107 if (ie
->data
[0] == 0x00) {
2108 pri_message(pri
, "%s", code2str(ie
->data
[1], facilities
, sizeof(facilities
) / sizeof(facilities
[0])));
2111 dump_ie_data(pri
, ie
->data
, ie
->len
);
2112 pri_message(pri
, " ]\n");
2115 static FUNC_RECV(receive_network_spec_fac
)
2120 static FUNC_SEND(transmit_network_spec_fac
)
2122 /* We are ready to transmit single IE only */
2126 if (pri
->nsf
!= PRI_NSF_NONE
) {
2128 ie
->data
[1] = pri
->nsf
;
2135 char *pri_cause2str(int cause
)
2137 return code2str(cause
, causes
, sizeof(causes
) / sizeof(causes
[0]));
2140 static char *pri_causeclass2str(int cause
)
2142 static struct msgtype causeclasses
[] = {
2143 { 0, "Normal Event" },
2144 { 1, "Normal Event" },
2145 { 2, "Network Congestion (resource unavailable)" },
2146 { 3, "Service or Option not Available" },
2147 { 4, "Service or Option not Implemented" },
2148 { 5, "Invalid message (e.g. parameter out of range)" },
2149 { 6, "Protocol Error (e.g. unknown message)" },
2150 { 7, "Interworking" },
2152 return code2str(cause
, causeclasses
, sizeof(causeclasses
) / sizeof(causeclasses
[0]));
2155 static FUNC_DUMP(dump_cause
)
2158 pri_message(pri
, "%c Cause (len=%2d) [ Ext: %d Coding: %s (%d) Spare: %d Location: %s (%d)\n",
2159 prefix
, len
, ie
->data
[0] >> 7, coding2str((ie
->data
[0] & 0x60) >> 5), (ie
->data
[0] & 0x60) >> 5,
2160 (ie
->data
[0] & 0x10) >> 4, loc2str(ie
->data
[0] & 0xf), ie
->data
[0] & 0xf);
2161 pri_message(pri
, "%c Ext: %d Cause: %s (%d), class = %s (%d) ]\n",
2162 prefix
, (ie
->data
[1] >> 7), pri_cause2str(ie
->data
[1] & 0x7f), ie
->data
[1] & 0x7f,
2163 pri_causeclass2str((ie
->data
[1] & 0x7f) >> 4), (ie
->data
[1] & 0x7f) >> 4);
2166 /* Dump cause data in readable form */
2167 switch(ie
->data
[1] & 0x7f) {
2168 case PRI_CAUSE_IE_NONEXIST
:
2169 for (x
=2;x
<ie
->len
;x
++)
2170 pri_message(pri
, "%c Cause data %d: %02x (%d, %s IE)\n", prefix
, x
-1, ie
->data
[x
], ie
->data
[x
], ie2str(ie
->data
[x
]));
2172 case PRI_CAUSE_WRONG_CALL_STATE
:
2173 for (x
=2;x
<ie
->len
;x
++)
2174 pri_message(pri
, "%c Cause data %d: %02x (%d, %s message)\n", prefix
, x
-1, ie
->data
[x
], ie
->data
[x
], msg2str(ie
->data
[x
]));
2176 case PRI_CAUSE_RECOVERY_ON_TIMER_EXPIRE
:
2177 pri_message(pri
, "%c Cause data:", prefix
);
2178 for (x
=2;x
<ie
->len
;x
++)
2179 pri_message(pri
, " %02x", ie
->data
[x
]);
2180 pri_message(pri
, " (Timer T");
2181 for (x
=2;x
<ie
->len
;x
++)
2182 pri_message(pri
, "%c", ((ie
->data
[x
] >= ' ') && (ie
->data
[x
] < 0x7f)) ? ie
->data
[x
] : '.');
2183 pri_message(pri
, ")\n");
2186 for (x
=2;x
<ie
->len
;x
++)
2187 pri_message(pri
, "%c Cause data %d: %02x (%d)\n", prefix
, x
-1, ie
->data
[x
], ie
->data
[x
]);
2192 static FUNC_RECV(receive_cause
)
2194 call
->causeloc
= ie
->data
[0] & 0xf;
2195 call
->causecode
= (ie
->data
[0] & 0x60) >> 5;
2196 call
->cause
= (ie
->data
[1] & 0x7f);
2200 static FUNC_SEND(transmit_cause
)
2202 /* We are ready to transmit single IE only */
2206 if (call
->cause
> 0) {
2207 ie
->data
[0] = 0x80 | (call
->causecode
<< 5) | (call
->causeloc
);
2208 ie
->data
[1] = 0x80 | (call
->cause
);
2216 static FUNC_DUMP(dump_sending_complete
)
2218 pri_message(pri
, "%c Sending Complete (len=%2d)\n", prefix
, len
);
2221 static FUNC_RECV(receive_sending_complete
)
2223 /* We've got a "Complete" message: Exect no further digits. */
2228 static FUNC_SEND(transmit_sending_complete
)
2230 if ((pri
->overlapdial
&& call
->complete
) || /* Explicit */
2231 (!pri
->overlapdial
&& ((pri
->switchtype
== PRI_SWITCH_EUROISDN_E1
) ||
2232 /* Implicit */ (pri
->switchtype
== PRI_SWITCH_EUROISDN_T1
)))) {
2233 /* Include this single-byte IE */
2239 static char *notify2str(int info
)
2242 static struct msgtype notifies
[] = {
2243 { PRI_NOTIFY_USER_SUSPENDED
, "User suspended" },
2244 { PRI_NOTIFY_USER_RESUMED
, "User resumed" },
2245 { PRI_NOTIFY_BEARER_CHANGE
, "Bearer service change (DSS1)" },
2246 { PRI_NOTIFY_ASN1_COMPONENT
, "ASN.1 encoded component (DSS1)" },
2247 { PRI_NOTIFY_COMPLETION_DELAY
, "Call completion delay" },
2248 { PRI_NOTIFY_CONF_ESTABLISHED
, "Conference established" },
2249 { PRI_NOTIFY_CONF_DISCONNECTED
, "Conference disconnected" },
2250 { PRI_NOTIFY_CONF_PARTY_ADDED
, "Other party added" },
2251 { PRI_NOTIFY_CONF_ISOLATED
, "Isolated" },
2252 { PRI_NOTIFY_CONF_REATTACHED
, "Reattached" },
2253 { PRI_NOTIFY_CONF_OTHER_ISOLATED
, "Other party isolated" },
2254 { PRI_NOTIFY_CONF_OTHER_REATTACHED
, "Other party reattached" },
2255 { PRI_NOTIFY_CONF_OTHER_SPLIT
, "Other party split" },
2256 { PRI_NOTIFY_CONF_OTHER_DISCONNECTED
, "Other party disconnected" },
2257 { PRI_NOTIFY_CONF_FLOATING
, "Conference floating" },
2258 { PRI_NOTIFY_WAITING_CALL
, "Call is waiting call" },
2259 { PRI_NOTIFY_DIVERSION_ACTIVATED
, "Diversion activated (DSS1)" },
2260 { PRI_NOTIFY_TRANSFER_ALERTING
, "Call transfer, alerting" },
2261 { PRI_NOTIFY_TRANSFER_ACTIVE
, "Call transfer, active" },
2262 { PRI_NOTIFY_REMOTE_HOLD
, "Remote hold" },
2263 { PRI_NOTIFY_REMOTE_RETRIEVAL
, "Remote retrieval" },
2264 { PRI_NOTIFY_CALL_DIVERTING
, "Call is diverting" },
2266 return code2str(info
, notifies
, sizeof(notifies
) / sizeof(notifies
[0]));
2269 static FUNC_DUMP(dump_notify
)
2271 pri_message(pri
, "%c Notification indicator (len=%2d): Ext: %d %s (%d)\n", prefix
, len
, ie
->data
[0] >> 7, notify2str(ie
->data
[0] & 0x7f), ie
->data
[0] & 0x7f);
2274 static FUNC_RECV(receive_notify
)
2276 call
->notify
= ie
->data
[0] & 0x7F;
2280 static FUNC_SEND(transmit_notify
)
2282 if (call
->notify
>= 0) {
2283 ie
->data
[0] = 0x80 | call
->notify
;
2289 static FUNC_DUMP(dump_shift
)
2291 pri_message(pri
, "%c %sLocking Shift (len=%02d): Requested codeset %d\n", prefix
, (full_ie
& 8) ? "Non-" : "", len
, full_ie
& 7);
2294 static char *lineinfo2str(int info
)
2296 /* NAPNA ANI II digits */
2297 static struct msgtype lineinfo
[] = {
2298 { 0, "Plain Old Telephone Service (POTS)" },
2299 { 1, "Multiparty line (more than 2)" },
2300 { 2, "ANI failure" },
2301 { 6, "Station Level Rating" },
2302 { 7, "Special Operator Handling Required" },
2303 { 20, "Automatic Identified Outward Dialing (AIOD)" },
2304 { 23, "Coing or Non-Coin" },
2305 { 24, "Toll free translated to POTS originated for non-pay station" },
2306 { 25, "Toll free translated to POTS originated from pay station" },
2307 { 27, "Pay station with coin control signalling" },
2308 { 29, "Prison/Inmate Service" },
2309 { 30, "Intercept (blank)" },
2310 { 31, "Intercept (trouble)" },
2311 { 32, "Intercept (regular)" },
2312 { 34, "Telco Operator Handled Call" },
2313 { 52, "Outward Wide Area Telecommunications Service (OUTWATS)" },
2314 { 60, "TRS call from unrestricted line" },
2315 { 61, "Cellular/Wireless PCS (Type 1)" },
2316 { 62, "Cellular/Wireless PCS (Type 2)" },
2317 { 63, "Cellular/Wireless PCS (Roaming)" },
2318 { 66, "TRS call from hotel/motel" },
2319 { 67, "TRS call from restricted line" },
2320 { 70, "Line connected to pay station" },
2321 { 93, "Private virtual network call" },
2323 return code2str(info
, lineinfo
, sizeof(lineinfo
) / sizeof(lineinfo
[0]));
2326 static FUNC_DUMP(dump_line_information
)
2328 pri_message(pri
, "%c Originating Line Information (len=%02d): %s (%d)\n", prefix
, len
, lineinfo2str(ie
->data
[0]), ie
->data
[0]);
2331 static FUNC_RECV(receive_line_information
)
2333 call
->ani2
= ie
->data
[0];
2337 static FUNC_SEND(transmit_line_information
)
2339 #if 0 /* XXX Is this IE possible for 4ESS only? XXX */
2340 if(pri
->switchtype
== PRI_SWITCH_ATT4ESS
) {
2349 static char *gdencoding2str(int encoding
)
2351 static struct msgtype gdencoding
[] = {
2357 return code2str(encoding
, gdencoding
, sizeof(gdencoding
) / sizeof(gdencoding
[0]));
2360 static char *gdtype2str(int type
)
2362 static struct msgtype gdtype
[] = {
2363 { 0, "Account Code" },
2365 { 2, "Customer ID" },
2366 { 3, "Universal Access" },
2367 { 4, "Info Digits" },
2373 return code2str(type
, gdtype
, sizeof(gdtype
) / sizeof(gdtype
[0]));
2376 static FUNC_DUMP(dump_generic_digits
)
2383 pri_message(pri
, "%c Generic Digits (len=%02d): Invalid length\n", prefix
, len
);
2386 encoding
= (ie
->data
[0] >> 5) & 7;
2387 type
= ie
->data
[0] & 0x1F;
2388 pri_message(pri
, "%c Generic Digits (len=%02d): Encoding %s Type %s\n", prefix
, len
, gdencoding2str(encoding
), gdtype2str(type
));
2389 if (encoding
== 3) { /* Binary */
2390 pri_message(pri
, "%c Don't know how to handle binary encoding\n");
2393 if (len
== 3) /* No number information */
2395 pri_message(pri
, "%c Digits: ");
2397 for(idx
= 3; idx
< len
; ++idx
) {
2399 case 0: /* BCD even */
2400 case 1: /* BCD odd */
2401 pri_message(pri
, "%d", ie
->data
[idx
-2] & 0x0f);
2402 value
= value
* 10 + (ie
->data
[idx
-2] & 0x0f);
2403 if(!encoding
|| (idx
+1 < len
)) { /* Special handling for BCD odd */
2404 pri_message(pri
, "%d", (ie
->data
[idx
-2] >> 4) & 0x0f);
2405 value
= value
* 10 + ((ie
->data
[idx
-2] >> 4) & 0x0f);
2409 pri_message(pri
, "%c", ie
->data
[idx
-2]);
2410 value
= value
* 10 + ie
->data
[idx
-2] - '0';
2415 case 4: /* Info Digits */
2416 pri_message(pri
, " - %s", lineinfo2str(value
));
2419 pri_message(pri
, "\n");
2422 static FUNC_RECV(receive_generic_digits
)
2432 pri_error(pri
, "Invalid length of Generic Digits IE\n");
2435 encoding
= (ie
->data
[0] >> 5) & 7;
2436 type
= ie
->data
[0] & 0x1F;
2437 if (encoding
== 3) { /* Binary */
2438 pri_message(pri
, "!! Unable to handle binary encoded Generic Digits IE\n");
2441 if (len
== 3) /* No number information */
2445 /* Integer value handling */
2446 case 4: /* Info Digits */
2447 for(idx
= 3; idx
< len
; ++idx
) {
2449 case 0: /* BCD even */
2450 case 1: /* BCD odd */
2451 value
= value
* 10 + (ie
->data
[idx
-2] & 0x0f);
2452 if(!encoding
|| (idx
+1 < len
)) /* Special handling for BCD odd */
2453 value
= value
* 10 + ((ie
->data
[idx
-2] >> 4) & 0x0f);
2456 value
= value
* 10 + (ie
->data
[idx
-2] - '0');
2461 /* String value handling */
2462 case 5: /* Callid */
2464 for(idx
= 3; (idx
< len
) && (num_idx
< sizeof(number
) - 4); ++idx
) {
2466 case 0: /* BCD even */
2467 case 1: /* BCD odd */
2468 number
[num_idx
++] = '0' + (ie
->data
[idx
-2] & 0x0f);
2469 if(!encoding
|| (idx
+1 < len
)) /* Special handling for BCD odd */
2470 number
[num_idx
++] = '0' + ((ie
->data
[idx
-2] >> 4) & 0x0f);
2473 number
[num_idx
++] = ie
->data
[idx
-2];
2477 number
[num_idx
] = '\0';
2481 case 4: /* Info Digits */
2485 case 5: /* Callid */
2486 if (!call
->callernum
[0]) {
2487 memcpy(call
->callernum
, number
, sizeof(call
->callernum
)-1);
2488 call
->callerpres
= 0;
2489 call
->callerplan
= 0;
2497 static FUNC_SEND(transmit_generic_digits
)
2499 #if 0 /* XXX Is this IE possible for other switches? XXX */
2503 if(pri
->switchtype
== PRI_SWITCH_NI1
) {
2504 ie
->data
[0] = 0x04; /* BCD even, Info Digits */
2505 ie
->data
[1] = 0x00; /* POTS */
2513 static char *signal2str(int signal
)
2515 /* From Q.931 4.5.8 Table 4-24 */
2516 static struct msgtype mtsignal
[] = {
2518 { 1, "Ring back tone" },
2519 { 2, "Intercept tone" },
2520 { 3, "Network congestion tone" },
2522 { 5, "Confirm tone" },
2523 { 6, "Answer tone" },
2524 { 7, "Call waiting tone" },
2525 { 8, "Off-hook warning tone" },
2526 { 9, "Pre-emption tone" },
2527 { 63, "Tones off" },
2528 { 64, "Alerting on - pattern 0" },
2529 { 65, "Alerting on - pattern 1" },
2530 { 66, "Alerting on - pattern 2" },
2531 { 67, "Alerting on - pattern 3" },
2532 { 68, "Alerting on - pattern 4" },
2533 { 69, "Alerting on - pattern 5" },
2534 { 70, "Alerting on - pattern 6" },
2535 { 71, "Alerting on - pattern 7" },
2536 { 79, "Alerting off" },
2538 return code2str(signal
, mtsignal
, sizeof(mtsignal
) / sizeof(mtsignal
[0]));
2542 static FUNC_DUMP(dump_signal
)
2544 pri_message(pri
, "%c Signal (len=%02d): ", prefix
, len
);
2546 pri_message(pri
, "Invalid length\n");
2549 pri_message(pri
, "Signal %s (%d)\n", signal2str(ie
->data
[0]), ie
->data
[0]);
2552 static FUNC_DUMP(dump_transit_count
)
2554 /* Defined in ECMA-225 */
2555 pri_message(pri
, "%c Transit Count (len=%02d): ", prefix
, len
);
2557 pri_message(pri
, "Invalid length\n");
2560 pri_message(pri
, "Count=%d (0x%02x)\n", ie
->data
[0] & 0x1f, ie
->data
[0] & 0x1f);
2564 static struct ie ies
[] = {
2565 /* Codeset 0 - Common */
2566 { 1, NATIONAL_CHANGE_STATUS
, "Change Status" },
2567 { 0, Q931_LOCKING_SHIFT
, "Locking Shift", dump_shift
},
2568 { 0, Q931_BEARER_CAPABILITY
, "Bearer Capability", dump_bearer_capability
, receive_bearer_capability
, transmit_bearer_capability
},
2569 { 0, Q931_CAUSE
, "Cause", dump_cause
, receive_cause
, transmit_cause
},
2570 { 1, Q931_CALL_STATE
, "Call State", dump_call_state
, receive_call_state
, transmit_call_state
},
2571 { 0, Q931_CHANNEL_IDENT
, "Channel Identification", dump_channel_id
, receive_channel_id
, transmit_channel_id
},
2572 { 0, Q931_PROGRESS_INDICATOR
, "Progress Indicator", dump_progress_indicator
, receive_progress_indicator
, transmit_progress_indicator
},
2573 { 0, Q931_NETWORK_SPEC_FAC
, "Network-Specific Facilities", dump_network_spec_fac
, receive_network_spec_fac
, transmit_network_spec_fac
},
2574 { 1, Q931_INFORMATION_RATE
, "Information Rate" },
2575 { 1, Q931_TRANSIT_DELAY
, "End-to-End Transit Delay" },
2576 { 1, Q931_TRANS_DELAY_SELECT
, "Transmit Delay Selection and Indication" },
2577 { 1, Q931_BINARY_PARAMETERS
, "Packet-layer Binary Parameters" },
2578 { 1, Q931_WINDOW_SIZE
, "Packet-layer Window Size" },
2579 { 1, Q931_CLOSED_USER_GROUP
, "Closed User Group" },
2580 { 1, Q931_REVERSE_CHARGE_INDIC
, "Reverse Charging Indication" },
2581 { 1, Q931_CALLING_PARTY_NUMBER
, "Calling Party Number", dump_calling_party_number
, receive_calling_party_number
, transmit_calling_party_number
},
2582 { 1, Q931_CALLING_PARTY_SUBADDR
, "Calling Party Subaddress", dump_calling_party_subaddr
, receive_calling_party_subaddr
},
2583 { 1, Q931_CALLED_PARTY_NUMBER
, "Called Party Number", dump_called_party_number
, receive_called_party_number
, transmit_called_party_number
},
2584 { 1, Q931_CALLED_PARTY_SUBADDR
, "Called Party Subaddress", dump_called_party_subaddr
},
2585 { 0, Q931_REDIRECTING_NUMBER
, "Redirecting Number", dump_redirecting_number
, receive_redirecting_number
, transmit_redirecting_number
},
2586 { 1, Q931_REDIRECTING_SUBADDR
, "Redirecting Subaddress", dump_redirecting_subaddr
},
2587 { 0, Q931_TRANSIT_NET_SELECT
, "Transit Network Selection" },
2588 { 1, Q931_RESTART_INDICATOR
, "Restart Indicator", dump_restart_indicator
, receive_restart_indicator
, transmit_restart_indicator
},
2589 { 0, Q931_LOW_LAYER_COMPAT
, "Low-layer Compatibility" , dump_low_layer_compat
, receive_low_layer_compat
, transmit_low_layer_compat
},
2590 { 1, Q931_HIGH_LAYER_COMPAT
, "High-layer Compatibility" , dump_high_layer_compat
, receive_high_layer_compat
, transmit_high_layer_compat
},
2591 { 1, Q931_PACKET_SIZE
, "Packet Size" },
2592 { 0, Q931_IE_FACILITY
, "Facility" , dump_facility
, receive_facility
, transmit_facility
},
2593 { 1, Q931_IE_REDIRECTION_NUMBER
, "Redirection Number" },
2594 { 1, Q931_IE_REDIRECTION_SUBADDR
, "Redirection Subaddress" },
2595 { 1, Q931_IE_FEATURE_ACTIVATE
, "Feature Activation" },
2596 { 1, Q931_IE_INFO_REQUEST
, "Feature Request" },
2597 { 1, Q931_IE_FEATURE_IND
, "Feature Indication" },
2598 { 1, Q931_IE_SEGMENTED_MSG
, "Segmented Message" },
2599 { 1, Q931_IE_CALL_IDENTITY
, "Call Identity", dump_call_identity
, receive_call_identity
, transmit_call_identity
},
2600 { 1, Q931_IE_ENDPOINT_ID
, "Endpoint Identification" },
2601 { 1, Q931_IE_NOTIFY_IND
, "Notification Indicator", dump_notify
, receive_notify
, transmit_notify
},
2602 { 1, Q931_DISPLAY
, "Display", dump_display
, receive_display
, transmit_display
},
2603 { 1, Q931_IE_TIME_DATE
, "Date/Time", dump_time_date
, receive_time_date
, transmit_time_date
},
2604 { 1, Q931_IE_KEYPAD_FACILITY
, "Keypad Facility", dump_keypad_facility
, receive_keypad_facility
, transmit_keypad_facility
},
2605 { 0, Q931_IE_SIGNAL
, "Signal", dump_signal
},
2606 { 1, Q931_IE_SWITCHHOOK
, "Switch-hook" },
2607 { 1, Q931_IE_USER_USER
, "User-User", dump_user_user
, receive_user_user
, transmit_user_user
},
2608 { 1, Q931_IE_ESCAPE_FOR_EXT
, "Escape for Extension" },
2609 { 1, Q931_IE_CALL_STATUS
, "Call Status" },
2610 { 1, Q931_IE_CHANGE_STATUS
, "Change Status" },
2611 { 1, Q931_COLP
, "Connect Line ID Presentation", dump_connected_number
},
2612 { 1, Q931_IE_CONNECTED_ADDR
, "Connected Number", dump_connected_number
},
2613 { 1, Q931_IE_CONNECTED_NUM
, "Connected Number", dump_connected_number
},
2614 { 1, Q931_IE_ORIGINAL_CALLED_NUMBER
, "Original Called Number", dump_redirecting_number
, receive_redirecting_number
, transmit_redirecting_number
},
2615 { 1, Q931_IE_USER_USER_FACILITY
, "User-User Facility" },
2616 { 1, Q931_IE_UPDATE
, "Update" },
2617 { 1, Q931_SENDING_COMPLETE
, "Sending Complete", dump_sending_complete
, receive_sending_complete
, transmit_sending_complete
},
2618 /* Codeset 4 - Q.SIG specific */
2619 { 1, QSIG_IE_TRANSIT_COUNT
| Q931_CODESET(4), "Transit Count", dump_transit_count
},
2620 /* Codeset 6 - Network specific */
2621 { 1, Q931_IE_ORIGINATING_LINE_INFO
, "Originating Line Information", dump_line_information
, receive_line_information
, transmit_line_information
},
2622 { 1, Q931_IE_FACILITY
| Q931_CODESET(6), "Facility", dump_facility
, receive_facility
, transmit_facility
},
2623 { 1, Q931_DISPLAY
| Q931_CODESET(6), "Display (CS6)", dump_display
, receive_display
, transmit_display
},
2624 { 0, Q931_IE_GENERIC_DIGITS
, "Generic Digits", dump_generic_digits
, receive_generic_digits
, transmit_generic_digits
},
2628 static char *ie2str(int ie
)
2632 /* Special handling for Locking/Non-Locking Shifts */
2633 switch (ie
& 0xf8) {
2634 case Q931_LOCKING_SHIFT
:
2637 return "!! INVALID Locking Shift To Codeset 0";
2639 return "Locking Shift To Codeset 1";
2641 return "Locking Shift To Codeset 2";
2643 return "Locking Shift To Codeset 3";
2645 return "Locking Shift To Codeset 4";
2647 return "Locking Shift To Codeset 5";
2649 return "Locking Shift To Codeset 6";
2651 return "Locking Shift To Codeset 7";
2653 case Q931_NON_LOCKING_SHIFT
:
2656 return "Non-Locking Shift To Codeset 0";
2658 return "Non-Locking Shift To Codeset 1";
2660 return "Non-Locking Shift To Codeset 2";
2662 return "Non-Locking Shift To Codeset 3";
2664 return "Non-Locking Shift To Codeset 4";
2666 return "Non-Locking Shift To Codeset 5";
2668 return "Non-Locking Shift To Codeset 6";
2670 return "Non-Locking Shift To Codeset 7";
2673 for (x
=0;x
<sizeof(ies
) / sizeof(ies
[0]); x
++)
2674 if (ie
== ies
[x
].ie
)
2676 return "Unknown Information Element";
2680 static inline unsigned int ielen(q931_ie
*ie
)
2682 if ((ie
->ie
& 0x80) != 0)
2688 static char *msg2str(int msg
)
2691 for (x
=0;x
<sizeof(msgs
) / sizeof(msgs
[0]); x
++)
2692 if (msgs
[x
].msgnum
== msg
)
2693 return msgs
[x
].name
;
2694 return "Unknown Message Type";
2697 static inline int q931_cr(q931_h
*h
)
2702 pri_error(NULL
, "Call Reference Length Too long: %d\n", h
->crlen
);
2707 for (x
=0;x
<h
->crlen
;x
++) {
2720 pri_error(NULL
, "Call Reference Length not supported: %d\n", h
->crlen
);
2725 static inline void q931_dumpie(struct pri
*pri
, int codeset
, q931_ie
*ie
, char prefix
)
2728 int full_ie
= Q931_FULL_IE(codeset
, ie
->ie
);
2730 char *buf
= malloc(ielen(ie
) * 3 + 1);
2734 if (!(ie
->ie
& 0x80)) {
2735 buflen
+= sprintf(buf
, " %02x", ielen(ie
)-2);
2736 for (x
= 0; x
+ 2 < ielen(ie
); ++x
)
2737 buflen
+= sprintf(buf
+ buflen
, " %02x", ie
->data
[x
]);
2739 pri_message(pri
, "%c [%02x%s]\n", prefix
, ie
->ie
, buf
);
2742 /* Special treatment for shifts */
2743 if((full_ie
& 0xf0) == Q931_LOCKING_SHIFT
)
2746 base_ie
= (((full_ie
& ~0x7f) == Q931_FULL_IE(0, 0x80)) && ((full_ie
& 0x70) != 0x20)) ? full_ie
& ~0x0f : full_ie
;
2748 for (x
=0;x
<sizeof(ies
) / sizeof(ies
[0]); x
++)
2749 if (ies
[x
].ie
== base_ie
) {
2751 ies
[x
].dump(full_ie
, pri
, ie
, ielen(ie
), prefix
);
2753 pri_message(pri
, "%c IE: %s (len = %d)\n", prefix
, ies
[x
].name
, ielen(ie
));
2757 pri_error(pri
, "!! %c Unknown IE %d (cs%d, len = %d)\n", prefix
, Q931_IE_IE(base_ie
), Q931_IE_CODESET(base_ie
), ielen(ie
));
2760 static q921_call
*q921_getcall(struct pri
*pri
, struct q931_call
*c
, int tei
)
2765 if (cur
->tei
== tei
) {
2770 /* No call exists, make a new one */
2771 if (pri
->debug
& PRI_DEBUG_Q921_STATE
)
2772 pri_message(pri
, "-- Making new q921 call for cref %d tei %d\n", c
->cr
, tei
);
2773 cur
= malloc(sizeof(struct q921_call
));
2774 memset(cur
, 0, sizeof(cur
));
2778 cur
->next
= c
->phones
;
2783 static q931_call
*q931_getcall(struct pri
*pri
, int cr
, int tei
)
2785 q931_call
*cur
, *prev
;
2786 cur
= *pri
->callpool
;
2789 if ((pri
->localtype
== BRI_NETWORK_PTMP
) && (tei
>= 0)) {
2790 // hmm...ok, we might be the 1st responding to the setup
2791 // or it is really our call
2792 if ((cur
->cr
== cr
) && ((cur
->tei
== tei
) || (cur
->tei
== 127)))
2794 // or we might not be the 1st responding, then we need to clone
2795 // the call struct to hangup properly
2803 /* No call exists, make a new one */
2804 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
2805 pri_message(pri
, "-- Making new call for cr %d\n", cr
);
2806 cur
= malloc(sizeof(struct q931_call
));
2809 /* Call reference */
2813 /* Append to end of list */
2817 *pri
->callpool
= cur
;
2822 q931_call
*q931_new_call(struct pri
*pri
)
2826 cur
= *pri
->callpool
;
2828 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== PRI_CPE
)) {
2829 if (pri
->cref
> 32767)
2833 if (pri
->cref
> 127)
2837 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== PRI_CPE
)) {
2838 if (cur
->cr
== (0x8000 | pri
->cref
))
2841 // BRIs have only 1 bye cref
2842 if (cur
->cr
== (0x80 | pri
->cref
))
2848 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== PRI_CPE
)) {
2849 return q931_getcall(pri
, pri
->cref
| 0x8000, 0);
2852 return q931_getcall(pri
, pri
->cref
| 0x80, 0);
2856 static void q931_destroy(struct pri
*pri
, int cr
, q931_call
*c
, int tei
)
2858 q931_call
*cur
, *prev
;
2860 cur
= *pri
->callpool
;
2862 // if ((c && (cur == c)) || (!c && (cur->cr == cr))) {
2863 if ((c
&& (cur
== c
)) || (!c
&& ((cur
->cr
== cr
) && ((pri
->localtype
!= BRI_NETWORK_PTMP
) || (cur
->tei
== tei
))))) {
2865 prev
->next
= cur
->next
;
2867 *pri
->callpool
= cur
->next
;
2868 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
2869 pri_message(pri
, "NEW_HANGUP DEBUG: Destroying the call, ourstate %s, peerstate %s\n",callstate2str(cur
->ourcallstate
),callstate2str(cur
->peercallstate
));
2870 if (cur
->retranstimer
)
2871 pri_schedule_del(pri
, cur
->retranstimer
);
2873 pri_schedule_del(pri
, cur
->t303timer
);
2874 pri_call_apdu_queue_cleanup(cur
);
2881 pri_error(pri
, "Can't destroy call %d!\n", cr
);
2884 static void q931_destroycall(struct pri
*pri
, int cr
, int tei
)
2886 return q931_destroy(pri
, cr
, NULL
, tei
);
2890 void __q931_destroycall(struct pri
*pri
, q931_call
*c
)
2893 q931_destroy(pri
,0, c
, c
->tei
);
2897 static int add_ie(struct pri
*pri
, q931_call
*call
, int msgtype
, int ie
, q931_ie
*iet
, int maxlen
, int *codeset
)
2902 int ies_count
, order
;
2903 for (x
=0;x
<sizeof(ies
) / sizeof(ies
[0]);x
++) {
2904 if (ies
[x
].ie
== ie
) {
2905 /* This is our baby */
2906 if (ies
[x
].transmit
) {
2907 /* Prepend with CODE SHIFT IE if required */
2908 if (*codeset
!= Q931_IE_CODESET(ies
[x
].ie
)) {
2909 /* Locking shift to codeset 0 isn't possible */
2910 iet
->ie
= Q931_IE_CODESET(ies
[x
].ie
) | (Q931_IE_CODESET(ies
[x
].ie
) ? Q931_LOCKING_SHIFT
: Q931_NON_LOCKING_SHIFT
);
2912 iet
= (q931_ie
*)((char *)iet
+ 1);
2917 ies_count
= ies
[x
].max_count
;
2919 ies_count
= INT_MAX
;
2924 res
= ies
[x
].transmit(ie
, pri
, call
, msgtype
, iet
, maxlen
, ++order
);
2925 /* Error if res < 0 or ignored if res == 0 */
2929 if ((iet
->ie
& 0x80) == 0) /* Multibyte IE */
2933 iet
= (q931_ie
*)((char *)iet
+ res
);
2936 while (res
> 0 && order
< ies_count
);
2937 if (have_shift
&& total_res
) {
2938 if (Q931_IE_CODESET(ies
[x
].ie
))
2939 *codeset
= Q931_IE_CODESET(ies
[x
].ie
);
2940 return total_res
+ 1; /* Shift is single-byte IE */
2944 pri_error(pri
, "!! Don't know how to add an IE %s (%d)\n", ie2str(ie
), ie
);
2949 pri_error(pri
, "!! Unknown IE %d (%s)\n", ie
, ie2str(ie
));
2953 static char *disc2str(int disc
)
2955 static struct msgtype discs
[] = {
2956 { Q931_PROTOCOL_DISCRIMINATOR
, "Q.931" },
2957 { GR303_PROTOCOL_DISCRIMINATOR
, "GR-303" },
2958 { 0x3, "AT&T Maintenance" },
2959 { 0x43, "New AT&T Maintenance" },
2961 return code2str(disc
, discs
, sizeof(discs
) / sizeof(discs
[0]));
2964 void q931_dump(struct pri
*pri
, q931_h
*h
, int len
, int txrx
)
2971 c
= txrx
? '>' : '<';
2972 pri_message(pri
, "%c Protocol Discriminator: %s (%d) len=%d\n", c
, disc2str(h
->pd
), h
->pd
, len
);
2973 pri_message(pri
, "%c Call Ref: len=%2d (reference %d/0x%X) (%s)\n", c
, h
->crlen
, q931_cr(h
) & 0x7FFF, q931_cr(h
) & 0x7FFF, (h
->crv
[0] & 0x80) ? "Terminator" : "Originator");
2974 /* Message header begins at the end of the call reference number */
2975 mh
= (q931_mh
*)(h
->contents
+ h
->crlen
);
2976 pri_message(pri
, "%c Message type: %s (%d)\n", c
, msg2str(mh
->msg
), mh
->msg
);
2977 /* Drop length of header, including call reference */
2978 len
-= (h
->crlen
+ 3);
2979 codeset
= cur_codeset
= 0;
2981 r
= ielen((q931_ie
*)(mh
->data
+ x
));
2982 q931_dumpie(pri
, cur_codeset
, (q931_ie
*)(mh
->data
+ x
), c
);
2983 switch (mh
->data
[x
] & 0xf8) {
2984 case Q931_LOCKING_SHIFT
:
2985 if ((mh
->data
[x
] & 7) > 0)
2986 codeset
= cur_codeset
= mh
->data
[x
] & 7;
2988 case Q931_NON_LOCKING_SHIFT
:
2989 cur_codeset
= mh
->data
[x
] & 7;
2992 /* Reset temporary codeset change */
2993 cur_codeset
= codeset
;
2998 pri_error(pri
, "XXX Message longer than it should be?? XXX\n");
3001 static int q931_handle_ie(int codeset
, struct pri
*pri
, q931_call
*c
, int msg
, q931_ie
*ie
)
3004 int full_ie
= Q931_FULL_IE(codeset
, ie
->ie
);
3005 if (ielen(ie
) > Q931_IE_MAX_LEN
) {
3006 pri_error(pri
, "!! Invalid IE length %d (len = %d)\n", full_ie
, ielen(ie
));
3009 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
3010 pri_message(pri
, "-- Processing IE %d (cs%d, %s)\n", ie
->ie
, codeset
, ie2str(full_ie
));
3011 for (x
=0;x
<sizeof(ies
) / sizeof(ies
[0]);x
++) {
3012 if (full_ie
== ies
[x
].ie
) {
3014 return ies
[x
].receive(full_ie
, pri
, c
, msg
, ie
, ielen(ie
));
3016 if (pri
->debug
& PRI_DEBUG_Q931_ANOMALY
)
3017 pri_error(pri
, "!! No handler for IE %d (cs%d, %s)\n", ie
->ie
, codeset
, ie2str(full_ie
));
3022 pri_message(pri
, "!! Unknown IE %d (cs%d, %s)\n", ie
->ie
, codeset
, ie2str(full_ie
));
3026 static void init_header(struct pri
*pri
, q931_call
*call
, unsigned char *buf
, q931_h
**hb
, q931_mh
**mhb
, int *len
, int briflag
)
3028 /* Returns header and message header and modifies length in place */
3029 q931_h
*h
= (q931_h
*)buf
;
3031 h
->pd
= pri
->protodisc
;
3032 h
->x0
= 0; /* Reserved 0 */
3035 mh
= (q931_mh
*)(h
->contents
+ 1);
3036 h
->crlen
= 1; /* One bytes of Call Reference. Invert the top bit to make it from our sense */
3037 if (call
->cr
|| call
->forceinvert
) {
3038 h
->crv
[0] = (call
->cr
^ 0x80);
3040 /* Unless of course this has no call reference */
3045 mh
= (q931_mh
*)(h
->contents
+ 2);
3046 h
->crlen
= 2; /* Two bytes of Call Reference. Invert the top bit to make it from our sense */
3047 if (call
->cr
|| call
->forceinvert
) {
3048 h
->crv
[0] = ((call
->cr
^ 0x8000) & 0xff00) >> 8;
3049 h
->crv
[1] = (call
->cr
& 0xff);
3051 /* Unless of course this has no call reference */
3057 if (pri
->subchannel
) {
3058 /* On GR-303, top bit is always 0 */
3066 static int q931_xmit(struct pri
*pri
, q931_h
*h
, int len
, int cr
, int tei
)
3069 if (pri
->localtype
== BRI_NETWORK_PTMP
) {
3070 mh
= (q931_mh
*)(h
->contents
+ 1);
3071 if (mh
->msg
== Q931_SETUP
) {
3072 q921_transmit_uframe(pri
, h
, len
, cr
, tei
);
3074 q921_transmit_iframe(pri
, h
, len
, cr
, tei
);
3076 } else if (pri
->localtype
== BRI_CPE_PTMP
) {
3077 q921_transmit_iframe(pri
, h
, len
, cr
, pri
->tei
);
3079 q921_transmit_iframe(pri
, h
, len
, cr
, tei
);
3081 /* The transmit operation might dump the q921 header, so logging the q931
3082 message body after the transmit puts the sections of the message in the
3083 right order in the log */
3084 if (pri
->debug
& PRI_DEBUG_Q931_DUMP
)
3085 q931_dump(pri
, h
, len
, 1);
3086 #ifdef LIBPRI_COUNTERS
3087 pri
->q931_txcount
++;
3092 static int send_message(struct pri
*pri
, q931_call
*c
, int msgtype
, int ies
[])
3094 unsigned char buf
[1024];
3103 memset(buf
, 0, sizeof(buf
));
3105 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== PRI_CPE
)) {
3106 init_header(pri
, c
, buf
, &h
, &mh
, &len
, 0);
3108 init_header(pri
, c
, buf
, &h
, &mh
, &len
, 1);
3113 while(ies
[x
] > -1) {
3114 res
= add_ie(pri
, c
, mh
->msg
, ies
[x
], (q931_ie
*)(mh
->data
+ offset
), len
, &codeset
);
3117 pri_error(pri
, "!! Unable to add IE '%s'\n", ie2str(ies
[x
]));
3125 /* Invert the logic */
3126 len
= sizeof(buf
) - len
;
3127 if (pri
->localtype
== BRI_CPE_PTMP
) {
3128 q931_xmit(pri
, h
, len
, 1, pri
->tei
);
3130 q931_xmit(pri
, h
, len
, 1, c
->tei
);
3136 static int status_ies
[] = { Q931_CAUSE
, Q931_CALL_STATE
, -1 };
3138 static int q931_status(struct pri
*pri
, q931_call
*c
, int cause
)
3140 q931_call
*cur
= NULL
;
3142 cause
= PRI_CAUSE_RESPONSE_TO_STATUS_ENQUIRY
;
3144 cur
= *pri
->callpool
;
3146 if (cur
->cr
== c
->cr
) {
3148 cur
->causecode
= CODE_CCITT
;
3149 cur
->causeloc
= LOC_USER
;
3155 pri_message(pri
, "YYY Here we get reset YYY\n");
3156 /* something went wrong, respond with "no such call" */
3157 c
->ourcallstate
= Q931_CALL_STATE_NULL
;
3158 c
->peercallstate
= Q931_CALL_STATE_NULL
;
3161 return send_message(pri
, cur
, Q931_STATUS
, status_ies
);
3164 static int information_ies
[] = { Q931_IE_KEYPAD_FACILITY
, Q931_CALLED_PARTY_NUMBER
, -1 };
3166 int q931_information(struct pri
*pri
, q931_call
*c
, char digit
)
3168 c
->callednum
[0] = digit
;
3169 c
->callednum
[1] = '\0';
3170 return send_message(pri
, c
, Q931_INFORMATION
, information_ies
);
3173 static int keypad_facility_ies
[] = { Q931_IE_KEYPAD_FACILITY
, -1 };
3175 int q931_keypad_facility(struct pri
*pri
, q931_call
*call
, char *digits
)
3177 libpri_copy_string(call
->keypad_digits
, digits
, sizeof(call
->keypad_digits
));
3178 return send_message(pri
, call
, Q931_INFORMATION
, keypad_facility_ies
);
3181 static int information_display_ies
[] = { Q931_DISPLAY
, -1 };
3183 int q931_information_display(struct pri
*pri
, q931_call
*c
, char *display
)
3187 if (!display
) return -1;
3188 strncpy(temp
, c
->callername
, sizeof(temp
));
3189 strncpy(c
->callername
, display
, sizeof(c
->callername
));
3190 res
= send_message(pri
, c
, Q931_INFORMATION
, information_display_ies
);
3191 strncpy(c
->callername
, temp
, sizeof(c
->callername
));
3195 int q931_add_display(struct pri
*pri
, q931_call
*c
, char *display
)
3197 strncpy(c
->display
, display
, sizeof(c
->display
));
3201 static int restart_ack_ies
[] = { Q931_CHANNEL_IDENT
, Q931_RESTART_INDICATOR
, -1 };
3203 static int restart_ack(struct pri
*pri
, q931_call
*c
)
3205 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_NULL
);
3206 c
->peercallstate
= Q931_CALL_STATE_NULL
;
3207 c
->chanflags
&= ~FLAG_PREFERRED
;
3208 c
->chanflags
|= FLAG_EXCLUSIVE
;
3209 return send_message(pri
, c
, Q931_RESTART_ACKNOWLEDGE
, restart_ack_ies
);
3212 static int facility_ies
[] = { Q931_IE_FACILITY
, -1 };
3214 int q931_facility(struct pri
*pri
, q931_call
*c
)
3216 return send_message(pri
, c
, Q931_FACILITY
, facility_ies
);
3219 static int notify_ies
[] = { Q931_IE_NOTIFY_IND
, -1 };
3221 int q931_notify(struct pri
*pri
, q931_call
*c
, int channel
, int info
)
3223 if ((pri
->switchtype
== PRI_SWITCH_EUROISDN_T1
) || (pri
->switchtype
!= PRI_SWITCH_EUROISDN_E1
)) {
3224 if ((info
> 0x2) || (info
< 0x00))
3228 c
->notify
= info
& 0x7F;
3231 return send_message(pri
, c
, Q931_NOTIFY
, notify_ies
);
3234 #ifdef ALERTING_NO_PROGRESS
3235 static int call_progress_ies
[] = { -1 };
3237 static int call_progress_ies
[] = { Q931_PROGRESS_INDICATOR
, -1 };
3240 int q931_call_progress(struct pri
*pri
, q931_call
*c
, int channel
, int info
)
3243 c
->ds1no
= (channel
& 0xff00) >> 8;
3244 c
->ds1explicit
= (channel
& 0x10000) >> 16;
3246 c
->channelno
= channel
;
3249 c
->progloc
= LOC_PRIV_NET_LOCAL_USER
;
3250 c
->progcode
= CODE_CCITT
;
3251 c
->progressmask
= PRI_PROG_INBAND_AVAILABLE
;
3253 /* PI is mandatory IE for PROGRESS message - Q.931 3.1.8 */
3254 pri_error(pri
, "XXX Progress message requested but no information is provided\n");
3255 c
->progressmask
= 0;
3258 return send_message(pri
, c
, Q931_PROGRESS
, call_progress_ies
);
3261 #ifdef ALERTING_NO_PROGRESS
3262 static int call_proceeding_ies
[] = { Q931_CHANNEL_IDENT
, -1 };
3264 static int call_proceeding_ies
[] = { Q931_CHANNEL_IDENT
, Q931_PROGRESS_INDICATOR
, -1 };
3267 int q931_call_proceeding(struct pri
*pri
, q931_call
*c
, int channel
, int info
)
3269 // never send two PROCEEDINGs!
3270 if (c
->proc
> 0) return 0;
3272 c
->ds1no
= (channel
& 0xff00) >> 8;
3273 c
->ds1explicit
= (channel
& 0x10000) >> 16;
3275 c
->channelno
= channel
;
3277 c
->chanflags
&= ~FLAG_PREFERRED
;
3278 c
->chanflags
|= FLAG_EXCLUSIVE
;
3279 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_INCOMING_CALL_PROCEEDING
);
3280 c
->peercallstate
= Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING
;
3282 c
->progloc
= LOC_PRIV_NET_LOCAL_USER
;
3283 c
->progcode
= CODE_CCITT
;
3284 c
->progressmask
= PRI_PROG_INBAND_AVAILABLE
;
3286 c
->progressmask
= 0;
3289 return send_message(pri
, c
, Q931_CALL_PROCEEDING
, call_proceeding_ies
);
3291 #ifndef ALERTING_NO_PROGRESS
3292 static int alerting_ies
[] = { Q931_PROGRESS_INDICATOR
, Q931_IE_USER_USER
, -1 };
3294 static int alerting_ies
[] = { -1 };
3297 static int alerting_BRI_ies
[] = { -1 };
3299 int q931_alerting(struct pri
*pri
, q931_call
*c
, int channel
, int info
)
3301 // never send two ALERTINGs!
3302 if (c
->alert
> 0) return 0;
3304 q931_call_proceeding(pri
, c
, channel
, 0);
3306 c
->progloc
= LOC_PRIV_NET_LOCAL_USER
;
3307 c
->progcode
= CODE_CCITT
;
3308 c
->progressmask
= PRI_PROG_INBAND_AVAILABLE
;
3310 c
->progressmask
= 0;
3311 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_CALL_RECEIVED
);
3312 c
->peercallstate
= Q931_CALL_STATE_CALL_DELIVERED
;
3315 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== PRI_CPE
)) {
3316 return send_message(pri
, c
, Q931_ALERTING
, alerting_ies
);
3318 if ((pri
->localtype
== BRI_NETWORK
) || (pri
->localtype
== BRI_NETWORK_PTMP
)) {
3319 return send_message(pri
, c
, Q931_ALERTING
, alerting_ies
);
3321 /* no PROGRESS_INDICATOR for BRI please */
3322 return send_message(pri
, c
, Q931_ALERTING
, alerting_BRI_ies
);
3327 static int hold_acknowledge_ies
[] = { -1 };
3329 int q931_hold_acknowledge(struct pri
*pri
, q931_call
*c
)
3331 return send_message(pri
, c
, Q931_HOLD_ACKNOWLEDGE
, hold_acknowledge_ies
);
3334 static int hold_reject_ies
[] = { Q931_CAUSE
, -1 };
3336 int q931_hold_reject(struct pri
*pri
, q931_call
*c
)
3339 c
->causecode
= CODE_CCITT
;
3340 c
->causeloc
= LOC_PRIV_NET_LOCAL_USER
;
3341 return send_message(pri
, c
, Q931_HOLD_REJECT
, hold_reject_ies
);
3344 static int retrieve_acknowledge_ies
[] = { Q931_CHANNEL_IDENT
, -1 };
3346 int q931_retrieve_acknowledge(struct pri
*pri
, q931_call
*c
, int channel
)
3349 c
->channelno
= channel
;
3350 c
->chanflags
&= ~FLAG_PREFERRED
;
3351 c
->chanflags
|= FLAG_EXCLUSIVE
;
3352 return send_message(pri
, c
, Q931_RETRIEVE_ACKNOWLEDGE
, retrieve_acknowledge_ies
);
3355 static int retrieve_reject_ies
[] = { -1 };
3357 int q931_retrieve_reject(struct pri
*pri
, q931_call
*c
)
3359 return send_message(pri
, c
, Q931_RETRIEVE_REJECT
, retrieve_reject_ies
);
3362 static int suspend_acknowledge_ies
[] = { Q931_DISPLAY
, -1 };
3364 int q931_suspend_acknowledge(struct pri
*pri
, q931_call
*c
, char *display
)
3366 char tempcallername
[256];
3368 c
->ourcallstate
= Q931_CALL_STATE_NULL
;
3369 c
->peercallstate
= Q931_CALL_STATE_NULL
;
3370 strncpy(tempcallername
,c
->callername
,sizeof(tempcallername
));
3371 strncpy(c
->callername
,display
,sizeof(c
->callername
));
3372 res
= send_message(pri
, c
, Q931_SUSPEND_ACKNOWLEDGE
, suspend_acknowledge_ies
);
3373 strncpy(c
->callername
,tempcallername
,sizeof(c
->callername
));
3374 __q931_destroycall(pri
, c
);
3378 static int suspend_reject_ies
[] = { Q931_DISPLAY
, Q931_CAUSE
, -1 };
3380 int q931_suspend_reject(struct pri
*pri
, q931_call
*c
, char *display
)
3382 char tempcallername
[256];
3384 strncpy(tempcallername
,c
->callername
,sizeof(tempcallername
));
3385 strncpy(c
->callername
,display
,sizeof(c
->callername
));
3387 c
->causecode
= CODE_CCITT
;
3388 c
->causeloc
= LOC_PRIV_NET_LOCAL_USER
;
3389 res
= send_message(pri
, c
, Q931_SUSPEND_REJECT
, suspend_reject_ies
);
3390 strncpy(c
->callername
,tempcallername
,sizeof(c
->callername
));
3394 static int resume_reject_ies
[] = { Q931_CAUSE
, Q931_DISPLAY
, -1 };
3396 int q931_resume_reject(struct pri
*pri
, q931_call
*c
, char *display
)
3398 char tempcallername
[256];
3401 c
->causecode
= CODE_CCITT
;
3402 c
->causeloc
= LOC_PRIV_NET_LOCAL_USER
;
3403 strncpy(tempcallername
,c
->callername
,sizeof(tempcallername
));
3404 strncpy(c
->callername
,display
,sizeof(c
->callername
));
3405 res
= send_message(pri
, c
, Q931_RESUME_REJECT
, resume_reject_ies
);
3406 strncpy(c
->callername
,tempcallername
,sizeof(c
->callername
));
3410 static int resume_acknowledge_ies
[] = { Q931_CHANNEL_IDENT
, Q931_DISPLAY
, -1 };
3412 int q931_resume_acknowledge(struct pri
*pri
, q931_call
*c
, int channel
, char *display
)
3414 char tempcallername
[256];
3417 c
->channelno
= channel
;
3418 c
->chanflags
&= ~FLAG_PREFERRED
;
3419 c
->chanflags
|= FLAG_EXCLUSIVE
;
3421 c
->ourcallstate
= Q931_CALL_STATE_ACTIVE
;
3422 c
->peercallstate
= Q931_CALL_STATE_ACTIVE
;
3423 strncpy(tempcallername
,c
->callername
,sizeof(tempcallername
));
3424 strncpy(c
->callername
,display
,sizeof(c
->callername
));
3425 res
= send_message(pri
, c
, Q931_RESUME_ACKNOWLEDGE
, resume_acknowledge_ies
);
3426 strncpy(c
->callername
,tempcallername
,sizeof(c
->callername
));
3431 static int connect_ies
[] = { Q931_CHANNEL_IDENT
, Q931_PROGRESS_INDICATOR
, Q931_DISPLAY
, -1 };
3432 static int connect_NET_ies
[] = { Q931_CHANNEL_IDENT
, Q931_PROGRESS_INDICATOR
, Q931_IE_TIME_DATE
, -1 };
3434 int q931_setup_ack(struct pri
*pri
, q931_call
*c
, int channel
, int nonisdn
)
3436 int network
= pri
->localtype
== PRI_NETWORK
|| pri
->localtype
== BRI_NETWORK
|| pri
->localtype
== BRI_NETWORK_PTMP
;
3438 c
->ds1no
= (channel
& 0xff00) >> 8;
3439 c
->ds1explicit
= (channel
& 0x10000) >> 16;
3441 c
->channelno
= channel
;
3443 c
->chanflags
&= ~FLAG_PREFERRED
;
3444 c
->chanflags
|= FLAG_EXCLUSIVE
;
3445 if (nonisdn
&& (pri
->switchtype
!= PRI_SWITCH_DMS100
)) {
3446 c
->progloc
= LOC_PRIV_NET_LOCAL_USER
;
3447 c
->progcode
= CODE_CCITT
;
3448 c
->progressmask
= PRI_PROG_CALLED_NOT_ISDN
;
3450 c
->progressmask
= 0;
3451 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_OVERLAP_RECEIVING
);
3452 c
->peercallstate
= Q931_CALL_STATE_OVERLAP_SENDING
;
3455 c
->progloc
= LOC_PRIV_NET_LOCAL_USER
;
3456 c
->progcode
= CODE_CCITT
;
3457 c
->progressmask
= Q931_PROG_INBAND_AVAILABLE
;
3459 return send_message(pri
, c
, Q931_SETUP_ACKNOWLEDGE
, connect_ies
);
3462 static void pri_setup_response_timeout(void *data
)
3464 struct q931_call
*c
= data
;
3465 struct pri
*pri
= NULL
;
3470 c
->cause
= PRI_CAUSE_NO_USER_RESPONSE
;
3471 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
3472 pri_message(pri
, "No response to SETUP message\n");
3474 pri
->ev
.e
= PRI_EVENT_HANGUP
;
3475 pri
->ev
.hangup
.channel
= c
->channelno
;
3476 pri
->ev
.hangup
.cref
= c
->cr
;
3477 pri
->ev
.hangup
.aoc_units
= -1;
3478 if (c
->cause
== -1) {
3479 pri
->ev
.hangup
.cause
= PRI_CAUSE_SWITCH_CONGESTION
;
3481 pri
->ev
.hangup
.cause
= c
->cause
;
3483 pri
->ev
.hangup
.call
= c
;
3484 q931_hangup(pri
, c
, c
->cause
);
3487 static void pri_connect_timeout(void *data
)
3489 struct q931_call
*c
= data
;
3490 struct pri
*pri
= c
->pri
;
3491 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
3492 pri_message(pri
, "Timed out looking for connect acknowledge\n");
3493 q931_disconnect(pri
, c
, PRI_CAUSE_NORMAL_CLEARING
);
3497 static void pri_release_timeout(void *data
)
3499 struct q931_call
*c
= data
;
3500 struct pri
*pri
= c
->pri
;
3501 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
3502 pri_message(pri
, "Timed out looking for release complete\n");
3505 q931_release(pri
, c
, PRI_CAUSE_NORMAL_CLEARING
);
3508 static void pri_release_finaltimeout(void *data
)
3510 struct q931_call
*c
= data
;
3511 struct pri
*pri
= c
->pri
;
3513 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
3514 pri_message(pri
, "Final time-out looking for release complete\n");
3516 c
->ourcallstate
= Q931_CALL_STATE_NULL
;
3517 c
->peercallstate
= Q931_CALL_STATE_NULL
;
3519 pri
->ev
.e
= PRI_EVENT_HANGUP_ACK
;
3520 pri
->ev
.hangup
.channel
= c
->channelno
;
3521 pri
->ev
.hangup
.cause
= c
->cause
;
3522 pri
->ev
.hangup
.cref
= c
->cr
;
3523 pri
->ev
.hangup
.call
= c
;
3524 pri
->ev
.hangup
.aoc_units
= c
->aoc_units
;
3525 libpri_copy_string(pri
->ev
.hangup
.useruserinfo
, c
->useruserinfo
, sizeof(pri
->ev
.hangup
.useruserinfo
));
3526 q931_hangup(pri
, c
, c
->cause
);
3529 static void pri_disconnect_timeout(void *data
)
3531 struct q931_call
*c
= data
;
3532 struct pri
*pri
= c
->pri
;
3533 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
3534 pri_message(pri
, "Timed out looking for release\n");
3536 q931_release(pri
, c
, PRI_CAUSE_NORMAL_CLEARING
);
3539 int q931_connect(struct pri
*pri
, q931_call
*c
, int channel
, int nonisdn
)
3541 int network
= pri
->localtype
== PRI_NETWORK
|| pri
->localtype
== BRI_NETWORK
|| pri
->localtype
== BRI_NETWORK_PTMP
;
3543 c
->ds1no
= (channel
& 0xff00) >> 8;
3544 c
->ds1explicit
= (channel
& 0x10000) >> 16;
3546 c
->channelno
= channel
;
3548 c
->chanflags
&= ~FLAG_PREFERRED
;
3549 c
->chanflags
|= FLAG_EXCLUSIVE
;
3550 if (nonisdn
&& (pri
->switchtype
!= PRI_SWITCH_DMS100
)) {
3551 c
->progloc
= LOC_PRIV_NET_LOCAL_USER
;
3552 c
->progcode
= CODE_CCITT
;
3553 c
->progressmask
= PRI_PROG_CALLED_NOT_ISDN
;
3555 c
->progressmask
= 0;
3556 if(network
|| pri
->switchtype
== PRI_SWITCH_QSIG
) {
3557 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_ACTIVE
);
3559 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_CONNECT_REQUEST
);
3561 c
->peercallstate
= Q931_CALL_STATE_ACTIVE
;
3564 /* Connect request timer */
3565 if (c
->retranstimer
)
3566 pri_schedule_del(pri
, c
->retranstimer
);
3567 c
->retranstimer
= 0;
3568 if ((c
->ourcallstate
== Q931_CALL_STATE_CONNECT_REQUEST
) && (!pri
->subchannel
))
3569 c
->retranstimer
= pri_schedule_event(pri
, pri
->timers
[PRI_TIMER_T313
], pri_connect_timeout
, c
);
3571 /* networks may send datetime */
3572 return send_message(pri
, c
, Q931_CONNECT
, connect_NET_ies
);
3574 return send_message(pri
, c
, Q931_CONNECT
, connect_ies
);
3578 static int release_aoce_ies
[] = { Q931_CAUSE
, Q931_IE_USER_USER
, Q931_IE_FACILITY
, -1 };
3579 static int release_ies
[] = { Q931_CAUSE
, Q931_IE_USER_USER
, -1 };
3581 int q931_release(struct pri
*pri
, q931_call
*c
, int cause
)
3583 int network
= pri
->localtype
== PRI_NETWORK
|| pri
->localtype
== BRI_NETWORK
|| pri
->localtype
== BRI_NETWORK_PTMP
;
3584 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_RELEASE_REQUEST
);
3585 /* c->peercallstate stays the same */
3589 c
->causecode
= CODE_CCITT
;
3590 c
->causeloc
= LOC_PRIV_NET_LOCAL_USER
;
3592 if (c
->retranstimer
)
3593 pri_schedule_del(pri
, c
->retranstimer
);
3594 if (!c
->t308_timedout
) {
3595 c
->retranstimer
= pri_schedule_event(pri
, pri
->timers
[PRI_TIMER_T308
], pri_release_timeout
, c
);
3597 c
->retranstimer
= pri_schedule_event(pri
, pri
->timers
[PRI_TIMER_T308
], pri_release_finaltimeout
, c
);
3599 if (network
&& (c
->aoc_units
> -1)) {
3600 /* include FACILITY IE for AOC-E */
3601 aoc_aoce_charging_unit_encode(pri
, c
, c
->aoc_units
, Q931_RELEASE
);
3603 return send_message(pri
, c
, Q931_RELEASE
, release_aoce_ies
);
3605 return send_message(pri
, c
, Q931_RELEASE
, release_ies
);
3608 return send_message(pri
, c
, Q931_RELEASE_COMPLETE
, release_ies
); /* Yes, release_ies, not release_complete_ies */
3613 static int restart_ies
[] = { Q931_CHANNEL_IDENT
, Q931_RESTART_INDICATOR
, -1 };
3615 int q931_restart(struct pri
*pri
, int channel
)
3617 struct q931_call
*c
;
3618 c
= q931_getcall(pri
, 0 | 0x8000, 0);
3624 c
->ds1no
= (channel
& 0xff00) >> 8;
3625 c
->ds1explicit
= (channel
& 0x10000) >> 16;
3627 c
->channelno
= channel
;
3628 c
->chanflags
&= ~FLAG_PREFERRED
;
3629 c
->chanflags
|= FLAG_EXCLUSIVE
;
3630 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_RESTART
);
3631 c
->peercallstate
= Q931_CALL_STATE_RESTART_REQUEST
;
3632 return send_message(pri
, c
, Q931_RESTART
, restart_ies
);
3635 static int disconnect_aoce_ies
[] = { Q931_CAUSE
, Q931_IE_USER_USER
, Q931_IE_FACILITY
, -1 };
3636 static int disconnect_ies
[] = { Q931_CAUSE
, Q931_IE_USER_USER
, -1 };
3638 int q931_disconnect(struct pri
*pri
, q931_call
*c
, int cause
)
3640 int network
= pri
->localtype
== PRI_NETWORK
|| pri
->localtype
== BRI_NETWORK
|| pri
->localtype
== BRI_NETWORK_PTMP
;
3641 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_DISCONNECT_REQUEST
);
3642 c
->peercallstate
= Q931_CALL_STATE_DISCONNECT_INDICATION
;
3646 c
->causecode
= CODE_CCITT
;
3647 c
->causeloc
= LOC_PRIV_NET_LOCAL_USER
;
3648 c
->sendhangupack
= 1;
3649 if (c
->retranstimer
)
3650 pri_schedule_del(pri
, c
->retranstimer
);
3651 c
->retranstimer
= pri_schedule_event(pri
, pri
->timers
[PRI_TIMER_T305
], pri_disconnect_timeout
, c
);
3652 if (network
&& (c
->aoc_units
> -1)) {
3653 /* include FACILITY IE for AOC-E */
3654 aoc_aoce_charging_unit_encode(pri
, c
, c
->aoc_units
, Q931_DISCONNECT
);
3656 return send_message(pri
, c
, Q931_DISCONNECT
, disconnect_aoce_ies
);
3658 return send_message(pri
, c
, Q931_DISCONNECT
, disconnect_ies
);
3664 //static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_DISPLAY, Q931_PROGRESS_INDICATOR,
3665 // Q931_IE_SIGNAL, Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_SENDING_COMPLETE, -1 };
3667 static int setup_ies
[] = { Q931_BEARER_CAPABILITY
, Q931_CHANNEL_IDENT
, Q931_IE_FACILITY
, Q931_PROGRESS_INDICATOR
, Q931_NETWORK_SPEC_FAC
, Q931_DISPLAY
,
3668 Q931_CALLING_PARTY_NUMBER
, Q931_CALLED_PARTY_NUMBER
, Q931_REDIRECTING_NUMBER
, Q931_IE_USER_USER
, Q931_SENDING_COMPLETE
,
3669 Q931_IE_ORIGINATING_LINE_INFO
, Q931_IE_GENERIC_DIGITS
, -1 };
3671 static int setup_cpe_ies
[] = { Q931_BEARER_CAPABILITY
, Q931_CHANNEL_IDENT
, Q931_IE_FACILITY
, Q931_PROGRESS_INDICATOR
, Q931_NETWORK_SPEC_FAC
, Q931_IE_USER_USER
,
3672 Q931_CALLING_PARTY_NUMBER
, Q931_CALLED_PARTY_NUMBER
, Q931_REDIRECTING_NUMBER
, Q931_SENDING_COMPLETE
, Q931_IE_ORIGINATING_LINE_INFO
, Q931_IE_GENERIC_DIGITS
, -1 };
3674 static int setup_bri_ies
[] = { Q931_BEARER_CAPABILITY
, Q931_CHANNEL_IDENT
, Q931_IE_FACILITY
, Q931_PROGRESS_INDICATOR
, Q931_NETWORK_SPEC_FAC
, Q931_DISPLAY
, Q931_IE_USER_USER
,
3675 Q931_CALLING_PARTY_NUMBER
, Q931_CALLED_PARTY_NUMBER
, Q931_REDIRECTING_NUMBER
, Q931_SENDING_COMPLETE
, Q931_IE_ORIGINATING_LINE_INFO
, Q931_IE_GENERIC_DIGITS
, Q931_HIGH_LAYER_COMPAT
, Q931_LOW_LAYER_COMPAT
, -1 };
3677 static int gr303_setup_ies
[] = { Q931_BEARER_CAPABILITY
, Q931_CHANNEL_IDENT
, -1 };
3679 static int cis_setup_ies
[] = { Q931_BEARER_CAPABILITY
, Q931_CHANNEL_IDENT
, Q931_IE_FACILITY
, Q931_CALLED_PARTY_NUMBER
, -1 };
3681 int q931_setup(struct pri
*pri
, q931_call
*c
, struct pri_sr
*req
)
3684 int network
= pri
->localtype
== PRI_NETWORK
|| pri
->localtype
== BRI_NETWORK
|| pri
->localtype
== BRI_NETWORK_PTMP
;
3686 if (pri
->localtype
== BRI_NETWORK_PTMP
) {
3692 c
->transcapability
= req
->transmode
;
3693 c
->transmoderate
= TRANS_MODE_64_CIRCUIT
;
3695 req
->userl1
= PRI_LAYER_1_ULAW
;
3696 c
->userl1
= req
->userl1
;
3699 c
->ds1no
= (req
->channel
& 0xff00) >> 8;
3700 c
->ds1explicit
= (req
->channel
& 0x10000) >> 16;
3701 req
->channel
&= 0xff;
3702 if ((pri
->localtype
== PRI_CPE
) && pri
->subchannel
) {
3707 c
->channelno
= req
->channel
;
3709 c
->nonisdn
= req
->nonisdn
;
3711 c
->justsignalling
= req
->justsignalling
;
3712 c
->complete
= req
->numcomplete
;
3714 c
->chanflags
= FLAG_EXCLUSIVE
;
3715 else if (c
->channelno
)
3716 c
->chanflags
= FLAG_PREFERRED
;
3717 memcpy(c
->llc
, req
->llc
, sizeof(c
->llc
));
3719 libpri_copy_string(c
->callernum
, req
->caller
, sizeof(c
->callernum
));
3720 c
->callerplan
= req
->callerplan
;
3721 if (req
->callername
)
3722 libpri_copy_string(c
->callername
, req
->callername
, sizeof(c
->callername
));
3724 c
->callername
[0] = '\0';
3725 if ((pri
->switchtype
== PRI_SWITCH_DMS100
) ||
3726 (pri
->switchtype
== PRI_SWITCH_ATT4ESS
)) {
3727 /* Doesn't like certain presentation types */
3728 if (!(req
->callerpres
& 0x7c))
3729 req
->callerpres
= PRES_ALLOWED_NETWORK_NUMBER
;
3731 c
->callerpres
= req
->callerpres
;
3733 c
->callernum
[0] = '\0';
3734 c
->callername
[0] = '\0';
3735 c
->callerplan
= PRI_UNKNOWN
;
3736 c
->callerpres
= PRES_NUMBER_NOT_AVAILABLE
;
3738 if (req
->redirectingnum
) {
3739 libpri_copy_string(c
->redirectingnum
, req
->redirectingnum
, sizeof(c
->redirectingnum
));
3740 c
->redirectingplan
= req
->redirectingplan
;
3741 if ((pri
->switchtype
== PRI_SWITCH_DMS100
) ||
3742 (pri
->switchtype
== PRI_SWITCH_ATT4ESS
)) {
3743 /* Doesn't like certain presentation types */
3744 if (!(req
->redirectingpres
& 0x7c))
3745 req
->redirectingpres
= PRES_ALLOWED_NETWORK_NUMBER
;
3747 c
->redirectingpres
= req
->redirectingpres
;
3748 c
->redirectingreason
= req
->redirectingreason
;
3750 c
->redirectingnum
[0] = '\0';
3751 c
->redirectingplan
= PRI_UNKNOWN
;
3752 c
->redirectingpres
= PRES_NUMBER_NOT_AVAILABLE
;
3753 c
->redirectingreason
= PRI_REDIR_UNKNOWN
;
3756 libpri_copy_string(c
->callednum
, req
->called
, sizeof(c
->callednum
));
3757 c
->calledplan
= req
->calledplan
;
3761 if (req
->useruserinfo
)
3762 libpri_copy_string(c
->useruserinfo
, req
->useruserinfo
, sizeof(c
->useruserinfo
));
3764 c
->useruserinfo
[0] = '\0';
3766 if (req
->nonisdn
&& (pri
->switchtype
== PRI_SWITCH_NI2
))
3767 c
->progressmask
= PRI_PROG_CALLER_NOT_ISDN
;
3769 c
->progressmask
= 0;
3771 pri_call_add_standard_apdus(pri
, c
);
3773 if (pri
->subchannel
) {
3774 res
= send_message(pri
, c
, Q931_SETUP
, gr303_setup_ies
);
3775 } else if (c
->justsignalling
) {
3776 res
= send_message(pri
, c
, Q931_SETUP
, cis_setup_ies
);
3777 } else if (pri
->localtype
== BRI_NETWORK
|| pri
->localtype
== BRI_NETWORK_PTMP
) {
3778 res
= send_message(pri
, c
, Q931_SETUP
, setup_bri_ies
);
3779 } else if (network
) {
3780 res
= send_message(pri
, c
, Q931_SETUP
, setup_ies
);
3782 res
= send_message(pri
, c
, Q931_SETUP
, setup_cpe_ies
);
3786 /* make sure we call PRI_EVENT_HANGUP_ACK once we send/receive RELEASE_COMPLETE */
3787 c
->sendhangupack
= 1;
3788 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_CALL_INITIATED
);
3789 c
->peercallstate
= Q931_CALL_STATE_OVERLAP_SENDING
;
3790 c
->t303timer
= pri_schedule_event(pri
, pri
->timers
[PRI_TIMER_T303
], pri_setup_response_timeout
, c
);
3797 static int release_complete_ies
[] = { Q931_IE_USER_USER
, -1 };
3799 static int q931_release_complete(struct pri
*pri
, q931_call
*c
, int cause
)
3802 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_NULL
);
3803 c
->peercallstate
= Q931_CALL_STATE_NULL
;
3806 c
->causecode
= CODE_CCITT
;
3807 if ((pri
->localtype
== PRI_NETWORK
) || (pri
->localtype
== BRI_NETWORK
) || (pri
->localtype
== BRI_NETWORK_PTMP
)) {
3808 c
->causeloc
= LOC_PRIV_NET_LOCAL_USER
;
3810 c
->causeloc
= LOC_USER
;
3812 /* release_ies has CAUSE in it */
3813 res
= send_message(pri
, c
, Q931_RELEASE_COMPLETE
, release_ies
);
3815 res
= send_message(pri
, c
, Q931_RELEASE_COMPLETE
, release_complete_ies
);
3817 /* release the structure */
3818 res
+= q931_hangup(pri
,c
,cause
);
3822 static int connect_acknowledge_ies
[] = { -1 };
3824 static int gr303_connect_acknowledge_ies
[] = { Q931_CHANNEL_IDENT
, -1 };
3826 static int q931_connect_acknowledge(struct pri
*pri
, q931_call
*c
)
3828 if (pri
->subchannel
) {
3829 if (pri
->localtype
== PRI_CPE
)
3830 return send_message(pri
, c
, Q931_CONNECT_ACKNOWLEDGE
, gr303_connect_acknowledge_ies
);
3832 return send_message(pri
, c
, Q931_CONNECT_ACKNOWLEDGE
, connect_acknowledge_ies
);
3836 /* here we cleanly hangup the phones that responded to our call but didnt get the call */
3837 int q921_hangup(struct pri
*pri
, q931_call
*c
, int tei
)
3839 q921_call
*cur
,*prev
;
3847 if (pri
->localtype
!= BRI_NETWORK_PTMP
){
3850 // pri_error(pri, "q921_hangup(%d, %d)\n", c->cr, tei);
3855 // pri_error(pri, "tei %d\n", tei);
3862 if (cur
->tei
!= tei
) {
3863 c
->cause
= PRI_CAUSE_NORMAL_CLEARING
;
3865 if (pri
->debug
& PRI_DEBUG_Q921_STATE
)
3866 pri_message(pri
, "sending RELEASE for TEI %d\n", cur
->tei
);
3867 send_message(pri
, c
, Q931_RELEASE
, release_ies
);
3880 if (c
->tei
== 127) {
3881 q931_destroycall(pri
, c
->cr
, c
->tei
);
3882 // make sure * frees the channel
3883 /* pri_error(pri, "returning PRI_EVENT_HANGUP_ACK\n");
3884 res = Q931_RES_HAVEEVENT;
3885 pri->ev.hangup.channel = c->channelno;
3886 pri->ev.e = PRI_EVENT_HANGUP_ACK; */
3891 /* here we handle release_completes from the phones
3892 because some (elmeg) phones do not send a disconnect
3893 message when the phone is busy */
3894 int q921_handle_hangup(struct pri
*pri
, q931_call
*c
, int tei
)
3896 q921_call
*cur
,*match
,*prev
=NULL
;
3903 if (pri
->localtype
!= BRI_NETWORK_PTMP
){
3910 if (cur
->tei
== tei
) {
3913 prev
->next
= cur
->next
;
3916 c
->phones
= cur
->next
;
3921 if (cur
) cur
= cur
->next
;
3931 // if all phones have signalled busy AND the timer is not running anymore!
3932 #ifdef FASTBUSYONBUSY
3933 if ((c
->cause
== PRI_CAUSE_USER_BUSY
) && (c
->t303timer
)) {
3935 pri_schedule_del(pri
, c
->t303timer
);
3939 if ((left
==0) && (c
->cause
== PRI_CAUSE_USER_BUSY
) && (c
->t303running
== 0)) {
3940 // pri_error(pri, "q921_handle_hangup(%d, %d, %d)\n", c->cr, tei, c->tei);
3941 // make sure * frees the channel
3942 res
= Q931_RES_HAVEEVENT
;
3943 pri
->ev
.hangup
.cause
= PRI_CAUSE_USER_BUSY
;
3944 pri
->ev
.hangup
.channel
= c
->channelno
| (c
->ds1no
<< 8);
3945 pri
->ev
.hangup
.cref
= c
->cr
;
3946 pri
->ev
.hangup
.call
= c
;
3947 pri
->ev
.hangup
.aoc_units
= 0;
3948 pri
->ev
.e
= PRI_EVENT_HANGUP
;
3955 int q931_hangup(struct pri
*pri
, q931_call
*c
, int cause
)
3958 int release_compl
= 0;
3959 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
3960 pri_message(pri
, "NEW_HANGUP DEBUG: Calling q931_hangup, ourstate %s, peerstate %s\n",callstate2str(c
->ourcallstate
),callstate2str(c
->peercallstate
));
3963 /* If mandatory IE was missing, insist upon that cause code */
3964 if (c
->cause
== PRI_CAUSE_MANDATORY_IE_MISSING
)
3966 if (cause
== 34 || cause
== 44 || cause
== 82 || cause
== 1 || cause
== 81 || cause
== 17) {
3967 /* We'll send RELEASE_COMPLETE with these causes */
3971 if (cause
== 6 || cause
== 7 || cause
== 26) {
3972 /* We'll send RELEASE with these causes */
3975 /* All other causes we send with DISCONNECT */
3976 switch(c
->ourcallstate
) {
3977 case Q931_CALL_STATE_NULL
:
3978 if (c
->peercallstate
== Q931_CALL_STATE_NULL
)
3979 /* free the resources if we receive or send REL_COMPL */
3980 q931_destroycall(pri
, c
->cr
, c
->tei
);
3981 else if (c
->peercallstate
== Q931_CALL_STATE_RELEASE_REQUEST
)
3982 q931_release_complete(pri
,c
,cause
);
3984 case Q931_CALL_STATE_CALL_INITIATED
:
3986 case Q931_CALL_STATE_OVERLAP_SENDING
:
3987 /* received SETUP_ACKNOWLEDGE */
3988 case Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING
:
3989 /* received CALL_PROCEEDING */
3990 case Q931_CALL_STATE_CALL_DELIVERED
:
3991 /* received ALERTING */
3992 case Q931_CALL_STATE_CALL_PRESENT
:
3993 /* received SETUP */
3994 case Q931_CALL_STATE_CALL_RECEIVED
:
3996 case Q931_CALL_STATE_CONNECT_REQUEST
:
3998 case Q931_CALL_STATE_INCOMING_CALL_PROCEEDING
:
3999 /* we sent CALL_PROCEEDING */
4000 case Q931_CALL_STATE_OVERLAP_RECEIVING
:
4001 /* received SETUP_ACKNOWLEDGE */
4002 /* send DISCONNECT in general */
4003 if (c
->peercallstate
!= Q931_CALL_STATE_NULL
&& c
->peercallstate
!= Q931_CALL_STATE_DISCONNECT_REQUEST
&& c
->peercallstate
!= Q931_CALL_STATE_DISCONNECT_INDICATION
&& c
->peercallstate
!= Q931_CALL_STATE_RELEASE_REQUEST
&& c
->peercallstate
!= Q931_CALL_STATE_RESTART_REQUEST
&& c
->peercallstate
!= Q931_CALL_STATE_RESTART
) {
4004 if (pri
->localtype
== BRI_NETWORK_PTMP
) {
4005 if (c
->tei
== 127) {
4010 q931_disconnect(pri
,c
,cause
);
4011 else if (release_compl
)
4012 q931_release_complete(pri
,c
,cause
);
4014 q931_release(pri
,c
,cause
);
4016 pri_error(pri
, "Wierd, doing nothing but this shouldn't happen, ourstate %s, peerstate %s\n",callstate2str(c
->ourcallstate
),callstate2str(c
->peercallstate
));
4018 case Q931_CALL_STATE_ACTIVE
:
4019 /* received CONNECT */
4020 q931_disconnect(pri
,c
,cause
);
4022 case Q931_CALL_STATE_DISCONNECT_REQUEST
:
4023 /* sent DISCONNECT */
4024 q931_release(pri
,c
,cause
);
4026 case Q931_CALL_STATE_DISCONNECT_INDICATION
:
4027 /* received DISCONNECT */
4028 if (pri
->localtype
== BRI_NETWORK_PTMP
) {
4029 if (c
->tei
== 127) {
4033 if (c
->peercallstate
== Q931_CALL_STATE_DISCONNECT_REQUEST
) {
4035 // pri_error(pri, "sending release to %d\n", c->tei);
4036 q931_release(pri
,c
,cause
);
4039 case Q931_CALL_STATE_RELEASE_REQUEST
:
4041 /* don't do anything, waiting for RELEASE_COMPLETE */
4043 case Q931_CALL_STATE_RESTART
:
4044 case Q931_CALL_STATE_RESTART_REQUEST
:
4046 pri_error(pri
, "q931_hangup shouldn't be called in this state, ourstate %s, peerstate %s\n",callstate2str(c
->ourcallstate
),callstate2str(c
->peercallstate
));
4049 pri_error(pri
, "We're not yet handling hanging up when our state is %d, contact support@digium.com, ourstate %s, peerstate %s\n",callstate2str(c
->ourcallstate
),callstate2str(c
->peercallstate
));
4052 /* we did handle hangup properly at this point */
4056 int q931_receive(struct pri
*pri
, q931_h
*h
, int len
, int tei
)
4066 int mandies
[MAX_MAND_IES
];
4068 int codeset
, cur_codeset
;
4070 struct apdu_event
*cur
= NULL
;
4071 int network
= pri
->localtype
== PRI_NETWORK
|| pri
->localtype
== BRI_NETWORK
|| pri
->localtype
== BRI_NETWORK_PTMP
;
4073 memset(last_ie
, 0, sizeof(last_ie
));
4074 if (pri
->debug
& PRI_DEBUG_Q931_DUMP
)
4075 q931_dump(pri
, h
, len
, 0);
4076 #ifdef LIBPRI_COUNTERS
4077 pri
->q931_rxcount
++;
4079 mh
= (q931_mh
*)(h
->contents
+ h
->crlen
);
4080 if ((h
->pd
== 0x3) || (h
->pd
== 0x43)) {
4081 /* This is the weird maintenance stuff. We majorly
4082 KLUDGE this by changing byte 4 from a 0xf (SERVICE)
4083 to a 0x7 (SERVICE ACKNOWLEDGE) */
4084 h
->raw
[h
->crlen
+ 2] -= 0x8;
4085 q931_xmit(pri
, h
, len
, 1, tei
);
4087 } else if (h
->pd
!= pri
->protodisc
) {
4088 pri_error(pri
, "Warning: unknown/inappropriate protocol discriminator received (%02x/%d)\n", h
->pd
, h
->pd
);
4091 c
= q931_getcall(pri
, q931_cr(h
), tei
);
4093 pri_error(pri
, "Unable to locate call %d\n", q931_cr(h
));
4096 /* Preliminary handling */
4099 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
4100 pri_message(pri
, "-- Processing Q.931 Restart\n");
4101 /* Reset information */
4109 c
->callername
[0] = '\0';
4112 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
4113 pri_message(pri
, "-- Processing Q.931 Call Setup\n");
4120 c
->transcapability
= -1;
4121 c
->transmoderate
= -1;
4122 c
->transmultiple
= -1;
4126 c
->rateadaption
= -1;
4130 c
->callernum
[0] = '\0';
4131 c
->callednum
[0] = '\0';
4132 c
->callername
[0] = '\0';
4133 c
->callerani
[0] = '\0';
4134 c
->callerplanani
= -1;
4135 c
->redirectingplan
= -1;
4136 c
->redirectingpres
= -1;
4137 c
->redirectingreason
= -1;
4138 c
->origcalledplan
= -1;
4139 c
->origcalledpres
= -1;
4140 c
->origredirectingreason
= -1;
4141 c
->redirectingnum
[0] = '\0';
4142 c
->origcallednum
[0] = '\0';
4143 c
->redirectingname
[0] = '\0';
4144 c
->origcalledname
[0] = '\0';
4145 c
->useruserprotocoldisc
= -1;
4146 c
->useruserinfo
[0] = '\0';
4150 c
->digits
[0] = '\0';
4151 c
->display
[0] = '\0';
4153 c
->progressmask
= 0;
4159 pri_schedule_del(pri
, c
->t303timer
);
4161 c
->useruserinfo
[0] = '\0';
4164 c
->progressmask
= 0;
4166 case Q931_CALL_PROCEEDING
:
4171 pri_schedule_del(pri
, c
->t303timer
);
4173 c
->useruserinfo
[0] = '\0';
4176 c
->progressmask
= 0;
4178 case Q931_CONNECT_ACKNOWLEDGE
:
4179 if (c
->retranstimer
)
4180 pri_schedule_del(pri
, c
->retranstimer
);
4181 c
->retranstimer
= 0;
4184 case Q931_DISCONNECT
:
4189 if (c
->retranstimer
)
4190 pri_schedule_del(pri
, c
->retranstimer
);
4191 c
->retranstimer
= 0;
4192 c
->useruserinfo
[0] = '\0';
4195 pri_schedule_del(pri
, c
->t303timer
);
4199 case Q931_RELEASE_COMPLETE
:
4200 if (c
->retranstimer
)
4201 pri_schedule_del(pri
, c
->retranstimer
);
4202 c
->retranstimer
= 0;
4205 pri_schedule_del(pri
, c
->t303timer
);
4207 c
->useruserinfo
[0] = '\0';
4213 c
->sugcallstate
= -1;
4216 case Q931_RESTART_ACKNOWLEDGE
:
4219 case Q931_INFORMATION
:
4220 c
->callednum
[0] = '\0';
4222 case Q931_STATUS_ENQUIRY
:
4224 case Q931_SETUP_ACKNOWLEDGE
:
4227 pri_schedule_del(pri
, c
->t303timer
);
4242 case Q931_USER_INFORMATION
:
4244 case Q931_CONGESTION_CONTROL
:
4245 case Q931_HOLD_ACKNOWLEDGE
:
4246 case Q931_HOLD_REJECT
:
4247 case Q931_RETRIEVE_ACKNOWLEDGE
:
4248 case Q931_RETRIEVE_REJECT
:
4249 case Q931_RESUME_ACKNOWLEDGE
:
4250 case Q931_RESUME_REJECT
:
4251 case Q931_SUSPEND_ACKNOWLEDGE
:
4252 case Q931_SUSPEND_REJECT
:
4253 pri_error(pri
, "!! Not yet handling pre-handle message type %s (%d)\n", msg2str(mh
->msg
), mh
->msg
);
4256 pri_error(pri
, "!! Don't know how to pre-handle message type %s (%d)\n", msg2str(mh
->msg
), mh
->msg
);
4257 q931_status(pri
,c
, PRI_CAUSE_MESSAGE_TYPE_NONEXIST
);
4259 q931_destroycall(pri
,c
->cr
,c
->tei
);
4263 memset(mandies
, 0, sizeof(mandies
));
4265 for (x
=0;x
<sizeof(msgs
) / sizeof(msgs
[0]); x
++) {
4266 if (msgs
[x
].msgnum
== mh
->msg
) {
4267 memcpy(mandies
, msgs
[x
].mandies
, sizeof(mandies
));
4271 /* Do real IE processing */
4272 len
-= (h
->crlen
+ 3);
4273 codeset
= cur_codeset
= 0;
4275 ie
= (q931_ie
*)(mh
->data
+ x
);
4276 for (y
=0;y
<MAX_MAND_IES
;y
++) {
4277 if (mandies
[y
] == Q931_FULL_IE(cur_codeset
, ie
->ie
))
4282 pri_error(pri
, "XXX Message longer than it should be?? XXX\n");
4285 /* Special processing for codeset shifts */
4286 switch (ie
->ie
& 0xf8) {
4287 case Q931_LOCKING_SHIFT
:
4288 y
= ie
->ie
& 7; /* Requested codeset */
4289 /* Locking shifts couldn't go to lower codeset, and couldn't follows non-locking shifts - verify this */
4290 if ((cur_codeset
!= codeset
) && (pri
->debug
& PRI_DEBUG_Q931_ANOMALY
))
4291 pri_message(pri
, "XXX Locking shift immediately follows non-locking shift (from %d through %d to %d) XXX\n", codeset
, cur_codeset
, y
);
4293 if ((y
< codeset
) && (pri
->debug
& PRI_DEBUG_Q931_ANOMALY
))
4294 pri_error(pri
, "!! Trying to locked downshift codeset from %d to %d !!\n", codeset
, y
);
4295 codeset
= cur_codeset
= y
;
4298 /* Locking shift to codeset 0 is forbidden by all specifications */
4299 pri_error(pri
, "!! Invalid locking shift to codeset 0 !!\n");
4302 case Q931_NON_LOCKING_SHIFT
:
4303 cur_codeset
= ie
->ie
& 7;
4306 /* Sanity check for IE code order */
4307 if (!(ie
->ie
& 0x80)) {
4308 if (last_ie
[cur_codeset
] > ie
->ie
) {
4309 if ((pri
->debug
& PRI_DEBUG_Q931_ANOMALY
))
4310 pri_message(pri
, "XXX Out-of-order IE %d at codeset %d (last was %d)\n", ie
->ie
, cur_codeset
, last_ie
[cur_codeset
]);
4313 last_ie
[cur_codeset
] = ie
->ie
;
4315 /* Ignore non-locking shifts for TR41459-based signalling */
4316 switch (pri
->switchtype
) {
4317 case PRI_SWITCH_LUCENT5E
:
4318 case PRI_SWITCH_ATT4ESS
:
4319 if (cur_codeset
!= codeset
) {
4320 if ((pri
->debug
& PRI_DEBUG_Q931_DUMP
))
4321 pri_message(pri
, "XXX Ignoring IE %d for temporary codeset %d XXX\n", ie
->ie
, cur_codeset
);
4326 y
= q931_handle_ie(cur_codeset
, pri
, c
, mh
->msg
, ie
);
4327 /* XXX Applicable to codeset 0 only? XXX */
4328 if (!cur_codeset
&& !(ie
->ie
& 0xf0) && (y
< 0))
4329 mandies
[MAX_MAND_IES
- 1] = Q931_FULL_IE(cur_codeset
, ie
->ie
);
4331 /* Reset current codeset */
4332 cur_codeset
= codeset
;
4338 for (x
=0;x
<MAX_MAND_IES
;x
++) {
4340 /* check if there is no channel identification when we're configured as network -> that's not an error */
4342 if (((mh
->msg
== Q931_SETUP
) && (mandies
[x
] == Q931_CHANNEL_IDENT
)) ||
4343 ((mh
->msg
== Q931_PROGRESS
) && (mandies
[x
] == Q931_PROGRESS_INDICATOR
))) {
4344 /* according to ets 300 102-1 a progress indicator is mandatory, but so what? ;-) */
4346 pri_error(pri
, "XXX Missing handling for mandatory IE %d (cs%d, %s) XXX\n", Q931_IE_IE(mandies
[x
]), Q931_IE_CODESET(mandies
[x
]), ie2str(mandies
[x
]));
4350 pri_error(pri
, "XXX Missing handling for mandatory IE %d (cs%d, %s) XXX\n", Q931_IE_IE(mandies
[x
]), Q931_IE_CODESET(mandies
[x
]), ie2str(mandies
[x
]));
4360 q931_status(pri
, c
, PRI_CAUSE_MANDATORY_IE_MISSING
);
4361 q931_destroycall(pri
, c
->cr
, c
->tei
);
4364 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_RESTART
);
4365 c
->peercallstate
= Q931_CALL_STATE_RESTART_REQUEST
;
4366 /* Send back the Restart Acknowledge */
4367 restart_ack(pri
, c
);
4368 /* Notify user of restart event */
4369 pri
->ev
.e
= PRI_EVENT_RESTART
;
4370 pri
->ev
.restart
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4371 return Q931_RES_HAVEEVENT
;
4374 q931_release_complete(pri
, c
, PRI_CAUSE_MANDATORY_IE_MISSING
);
4377 /* Must be new call */
4379 pri_error(pri
, "received SETUP message for call that is not a new call (retransmission). \n");
4382 if (c
->progressmask
& PRI_PROG_CALLER_NOT_ISDN
)
4385 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_CALL_PRESENT
);
4386 c
->peercallstate
= Q931_CALL_STATE_CALL_INITIATED
;
4387 /* it's not yet a call since higher level can respond with RELEASE or RELEASE_COMPLETE */
4389 if (c
->transmoderate
!= TRANS_MODE_64_CIRCUIT
) {
4390 q931_release_complete(pri
, c
, PRI_CAUSE_BEARERCAPABILITY_NOTIMPL
);
4393 pri
->ev
.e
= PRI_EVENT_RING
;
4394 pri
->ev
.ring
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4395 pri
->ev
.ring
.callingpres
= c
->callerpres
;
4396 pri
->ev
.ring
.callingplan
= c
->callerplan
;
4397 pri
->ev
.ring
.callingplanrdnis
= c
->redirectingplan
;
4398 pri
->ev
.ring
.callingplanorigcalled
= c
->origcalledplan
;
4399 pri
->ev
.ring
.ani2
= c
->ani2
;
4400 libpri_copy_string(pri
->ev
.ring
.callingani
, c
->callerani
, sizeof(pri
->ev
.ring
.callingani
));
4401 pri
->ev
.ring
.callingplanani
= c
->callerplanani
;
4402 libpri_copy_string(pri
->ev
.ring
.callingnum
, c
->callernum
, sizeof(pri
->ev
.ring
.callingnum
));
4403 libpri_copy_string(pri
->ev
.ring
.callingname
, c
->callername
, sizeof(pri
->ev
.ring
.callingname
));
4404 pri
->ev
.ring
.calledplan
= c
->calledplan
;
4405 libpri_copy_string(pri
->ev
.ring
.callingsubaddr
, c
->callingsubaddr
, sizeof(pri
->ev
.ring
.callingsubaddr
));
4406 if (!strlen(c
->callednum
) && strlen(c
->keypad_digits
)) {
4407 libpri_copy_string(pri
->ev
.ring
.callednum
, c
->keypad_digits
, sizeof(pri
->ev
.ring
.callednum
));
4409 libpri_copy_string(pri
->ev
.ring
.callednum
, c
->callednum
, sizeof(pri
->ev
.ring
.callednum
));
4411 libpri_copy_string(pri
->ev
.ring
.origcalledname
, c
->origcalledname
, sizeof(pri
->ev
.ring
.origcalledname
));
4412 libpri_copy_string(pri
->ev
.ring
.origcallednum
, c
->origcallednum
, sizeof(pri
->ev
.ring
.origcallednum
));
4413 libpri_copy_string(pri
->ev
.ring
.redirectingnum
, c
->redirectingnum
, sizeof(pri
->ev
.ring
.redirectingnum
));
4414 libpri_copy_string(pri
->ev
.ring
.redirectingname
, c
->redirectingname
, sizeof(pri
->ev
.ring
.redirectingname
));
4415 libpri_copy_string(pri
->ev
.ring
.useruserinfo
, c
->useruserinfo
, sizeof(pri
->ev
.ring
.useruserinfo
));
4416 c
->useruserinfo
[0] = '\0';
4417 pri
->ev
.ring
.redirectingreason
= c
->redirectingreason
;
4418 pri
->ev
.ring
.origredirectingreason
= c
->origredirectingreason
;
4419 pri
->ev
.ring
.flexible
= ! (c
->chanflags
& FLAG_EXCLUSIVE
);
4420 pri
->ev
.ring
.tei
= c
->tei
;
4421 pri
->ev
.ring
.call
= c
;
4422 pri
->ev
.ring
.cref
= c
->cr
;
4423 pri
->ev
.ring
.layer1
= c
->userl1
;
4424 pri
->ev
.ring
.complete
= c
->complete
;
4425 pri
->ev
.ring
.ctype
= c
->transcapability
;
4426 memcpy(pri
->ev
.ring
.lowlayercompat
, c
->llc
, sizeof(pri
->ev
.ring
.lowlayercompat
));
4427 pri
->ev
.ring
.redirectingreason
= c
->redirectingreason
;
4428 pri
->ev
.ring
.progress
= c
->progress
;
4429 pri
->ev
.ring
.progressmask
= c
->progressmask
;
4430 return Q931_RES_HAVEEVENT
;
4433 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4436 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_CALL_DELIVERED
);
4437 c
->peercallstate
= Q931_CALL_STATE_CALL_RECEIVED
;
4438 if (pri
->localtype
== BRI_NETWORK_PTMP
) {
4439 l2c
= q921_getcall(pri
, c
, tei
);
4441 pri
->ev
.e
= PRI_EVENT_RINGING
;
4442 pri
->ev
.ringing
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4443 pri
->ev
.ringing
.cref
= c
->cr
;
4444 pri
->ev
.ringing
.call
= c
;
4445 pri
->ev
.ringing
.progress
= c
->progress
;
4446 pri
->ev
.ringing
.progressmask
= c
->progressmask
;
4447 libpri_copy_string(pri
->ev
.ringing
.useruserinfo
, c
->useruserinfo
, sizeof(pri
->ev
.ringing
.useruserinfo
));
4448 c
->useruserinfo
[0] = '\0';
4452 if (!cur
->sent
&& cur
->message
== Q931_FACILITY
) {
4453 q931_facility(pri
, c
);
4459 return Q931_RES_HAVEEVENT
;
4462 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4465 if (c
->ourcallstate
== Q931_CALL_STATE_ACTIVE
) {
4466 q931_status(pri
, c
, PRI_CAUSE_WRONG_MESSAGE
);
4469 /* TEI got the call */
4471 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_ACTIVE
);
4472 c
->peercallstate
= Q931_CALL_STATE_CONNECT_REQUEST
;
4473 pri
->ev
.e
= PRI_EVENT_ANSWER
;
4474 pri
->ev
.answer
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4475 pri
->ev
.answer
.cref
= c
->cr
;
4476 pri
->ev
.answer
.call
= c
;
4477 pri
->ev
.answer
.tei
= c
->tei
;
4478 pri
->ev
.answer
.progress
= c
->progress
;
4479 pri
->ev
.answer
.progressmask
= c
->progressmask
;
4480 libpri_copy_string(pri
->ev
.answer
.useruserinfo
, c
->useruserinfo
, sizeof(pri
->ev
.answer
.useruserinfo
));
4481 c
->useruserinfo
[0] = '\0';
4482 q931_connect_acknowledge(pri
, c
);
4483 if (pri
->localtype
== BRI_NETWORK_PTMP
) {
4484 /* Release all other TEIs */
4485 q921_hangup(pri
, c
, tei
);
4487 if (c
->justsignalling
) { /* Make sure WE release when we initiatie a signalling only connection */
4488 q931_release(pri
, c
, PRI_CAUSE_NORMAL_CLEARING
);
4491 return Q931_RES_HAVEEVENT
;
4494 if ((pri
->localtype
== PRI_CPE
) || (pri
->localtype
== PRI_NETWORK
)) {
4495 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4497 // BRI uses the dummy cref for sservices like ccnr
4501 if (c
->facility
> 0) {
4502 pri
->ev
.e
= PRI_EVENT_FACILITY
;
4503 pri
->ev
.facility
.channel
= c
->channelno
| (c
->ds1no
<< 8);
4504 pri
->ev
.facility
.cref
= c
->cr
;
4505 pri
->ev
.facility
.tei
= c
->tei
;
4506 pri
->ev
.facility
.call
= c
;
4507 switch (c
->facility
) {
4508 case 0x06: /* ECT execute */
4509 pri
->ev
.facility
.operation
= 0x06;
4512 pri
->ev
.facility
.operation
= 0x0D;
4513 libpri_copy_string(pri
->ev
.facility
.forwardnum
, c
->redirectingnum
, sizeof(pri
->ev
.facility
.forwardnum
));
4516 pri
->ev
.facility
.operation
= c
->facility
;
4519 pri
->ev
.e
= PRI_EVENT_FACNAME
;
4520 libpri_copy_string(pri
->ev
.facname
.callingname
, c
->callername
, sizeof(pri
->ev
.facname
.callingname
));
4521 libpri_copy_string(pri
->ev
.facname
.callingnum
, c
->callernum
, sizeof(pri
->ev
.facname
.callingname
));
4522 pri
->ev
.facname
.channel
= c
->channelno
| (c
->ds1no
<< 8);
4523 pri
->ev
.facname
.cref
= c
->cr
;
4524 pri
->ev
.facname
.call
= c
;
4526 return Q931_RES_HAVEEVENT
;
4529 q931_status(pri
, c
, PRI_CAUSE_MANDATORY_IE_MISSING
);
4530 q931_destroycall(pri
, c
->cr
, c
->tei
);
4533 pri
->ev
.e
= PRI_EVENT_PROGRESS
;
4534 pri
->ev
.proceeding
.cause
= c
->cause
;
4536 case Q931_CALL_PROCEEDING
:
4538 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4541 if ((c
->ourcallstate
!= Q931_CALL_STATE_CALL_INITIATED
) &&
4542 (c
->ourcallstate
!= Q931_CALL_STATE_OVERLAP_SENDING
) &&
4543 (c
->ourcallstate
!= Q931_CALL_STATE_CALL_DELIVERED
) &&
4544 (c
->ourcallstate
!= Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING
)) {
4545 q931_status(pri
,c
,PRI_CAUSE_WRONG_MESSAGE
);
4548 if (pri
->localtype
== BRI_NETWORK_PTMP
) {
4549 l2c
= q921_getcall(pri
, c
, tei
);
4551 l2c
->channel
= c
->channelno
;
4553 pri
->ev
.proceeding
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4554 if (mh
->msg
== Q931_CALL_PROCEEDING
) {
4555 pri
->ev
.e
= PRI_EVENT_PROCEEDING
;
4556 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING
);
4557 c
->peercallstate
= Q931_CALL_STATE_INCOMING_CALL_PROCEEDING
;
4559 pri
->ev
.proceeding
.progress
= c
->progress
;
4560 pri
->ev
.proceeding
.progressmask
= c
->progressmask
;
4561 pri
->ev
.proceeding
.cref
= c
->cr
;
4562 pri
->ev
.proceeding
.call
= c
;
4566 if (!cur
->sent
&& cur
->message
== Q931_FACILITY
) {
4567 q931_facility(pri
, c
);
4572 return Q931_RES_HAVEEVENT
;
4573 case Q931_CONNECT_ACKNOWLEDGE
:
4575 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4578 if (!(c
->ourcallstate
== Q931_CALL_STATE_CONNECT_REQUEST
) &&
4579 !(c
->ourcallstate
== Q931_CALL_STATE_ACTIVE
&&
4580 (network
|| pri
->switchtype
== PRI_SWITCH_QSIG
))) {
4581 q931_status(pri
,c
,PRI_CAUSE_WRONG_MESSAGE
);
4584 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_ACTIVE
);
4585 c
->peercallstate
= Q931_CALL_STATE_ACTIVE
;
4590 q931_status(pri
, c
, PRI_CAUSE_MANDATORY_IE_MISSING
);
4591 q931_destroycall(pri
, c
->cr
, c
->tei
);
4596 q931_release_complete(pri
,c
,PRI_CAUSE_WRONG_CALL_STATE
);
4600 /* Also when the STATUS asks for the call of an unexisting reference send RELEASE_COMPL */
4601 if ((pri
->debug
& PRI_DEBUG_Q931_ANOMALY
) &&
4602 (c
->cause
!= PRI_CAUSE_INTERWORKING
))
4603 pri_error(pri
, "Received unsolicited status: %s\n", pri_cause2str(c
->cause
));
4604 /* Workaround for S-12 ver 7.3 - it responds for invalid/non-implemented IEs at SETUP with null call state */
4605 if (!c
->sugcallstate
&& (c
->ourcallstate
!= Q931_CALL_STATE_CALL_INITIATED
)) {
4606 pri
->ev
.hangup
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4607 pri
->ev
.hangup
.cause
= c
->cause
;
4608 pri
->ev
.hangup
.cref
= c
->cr
;
4609 pri
->ev
.hangup
.call
= c
;
4610 pri
->ev
.hangup
.aoc_units
= c
->aoc_units
;
4611 libpri_copy_string(pri
->ev
.hangup
.useruserinfo
, c
->useruserinfo
, sizeof(pri
->ev
.hangup
.useruserinfo
));
4612 /* Free resources */
4613 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_NULL
);
4614 c
->peercallstate
= Q931_CALL_STATE_NULL
;
4616 pri
->ev
.e
= PRI_EVENT_HANGUP
;
4617 res
= Q931_RES_HAVEEVENT
;
4619 } else if (c
->sendhangupack
) {
4620 res
= Q931_RES_HAVEEVENT
;
4621 pri
->ev
.e
= PRI_EVENT_HANGUP_ACK
;
4622 q931_hangup(pri
, c
, c
->cause
);
4624 q931_hangup(pri
, c
, c
->cause
);
4631 case Q931_RELEASE_COMPLETE
:
4632 if (pri
->localtype
!= BRI_NETWORK_PTMP
) {
4633 /* only stop the T303 timer if WE are not a BRI PTMP network */
4636 pri_schedule_del(pri
, c
->t303timer
);
4640 if ((pri
->localtype
!= BRI_NETWORK_PTMP
) || (c
->tei
== tei
)) {
4641 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_NULL
);
4642 c
->peercallstate
= Q931_CALL_STATE_NULL
;
4643 pri
->ev
.hangup
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4644 pri
->ev
.hangup
.cause
= c
->cause
;
4645 pri
->ev
.hangup
.cref
= c
->cr
;
4646 pri
->ev
.hangup
.call
= c
;
4647 pri
->ev
.hangup
.aoc_units
= c
->aoc_units
;
4648 libpri_copy_string(pri
->ev
.hangup
.useruserinfo
, c
->useruserinfo
, sizeof(pri
->ev
.hangup
.useruserinfo
));
4649 c
->useruserinfo
[0] = '\0';
4650 /* Free resources */
4652 pri
->ev
.e
= PRI_EVENT_HANGUP
;
4653 res
= Q931_RES_HAVEEVENT
;
4655 } else if (c
->sendhangupack
) {
4656 res
= Q931_RES_HAVEEVENT
;
4657 pri
->ev
.e
= PRI_EVENT_HANGUP_ACK
;
4658 pri_hangup(pri
, c
, c
->cause
, -1);
4664 q931_hangup(pri
,c
,c
->cause
);
4667 ignoring relase_complete */
4668 res
= q921_handle_hangup(pri
,c
,tei
);
4675 /* Force cause to be mandatory IE missing */
4676 c
->cause
= PRI_CAUSE_MANDATORY_IE_MISSING
;
4678 if (c
->ourcallstate
== Q931_CALL_STATE_RELEASE_REQUEST
)
4679 c
->peercallstate
= Q931_CALL_STATE_NULL
;
4681 c
->peercallstate
= Q931_CALL_STATE_RELEASE_REQUEST
;
4683 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_NULL
);
4684 pri
->ev
.e
= PRI_EVENT_HANGUP
;
4685 pri
->ev
.hangup
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4686 pri
->ev
.hangup
.cref
= c
->cr
;
4687 pri
->ev
.hangup
.tei
= c
->tei
;
4688 pri
->ev
.hangup
.cause
= c
->cause
;
4689 pri
->ev
.hangup
.call
= c
;
4690 pri
->ev
.hangup
.aoc_units
= c
->aoc_units
;
4691 libpri_copy_string(pri
->ev
.hangup
.useruserinfo
, c
->useruserinfo
, sizeof(pri
->ev
.ring
.useruserinfo
));
4692 c
->useruserinfo
[0] = '\0';
4693 /* Don't send release complete if they send us release
4694 while we sent it, assume a NULL state */
4696 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4698 return Q931_RES_HAVEEVENT
;
4700 case Q931_DISCONNECT
:
4702 /* Still let user call release */
4703 c
->cause
= PRI_CAUSE_MANDATORY_IE_MISSING
;
4706 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4709 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_DISCONNECT_INDICATION
);
4710 c
->peercallstate
= Q931_CALL_STATE_DISCONNECT_REQUEST
;
4711 c
->sendhangupack
= 1;
4713 /* wait for a RELEASE so that sufficient time has passed
4714 for the inband audio to be heard */
4715 if (pri
->acceptinbanddisconnect
&& (c
->progressmask
& PRI_PROG_INBAND_AVAILABLE
))
4718 /* Return such an event */
4719 pri
->ev
.e
= PRI_EVENT_HANGUP_REQ
;
4720 pri
->ev
.hangup
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4721 pri
->ev
.hangup
.cref
= c
->cr
;
4722 pri
->ev
.hangup
.tei
= c
->tei
;
4723 pri
->ev
.hangup
.cause
= c
->cause
;
4724 pri
->ev
.hangup
.call
= c
;
4725 pri
->ev
.hangup
.aoc_units
= c
->aoc_units
;
4726 if (c
->progressmask
& PRI_PROG_INBAND_AVAILABLE
) {
4727 pri
->ev
.hangup
.inband_progress
= 1;
4729 pri
->ev
.hangup
.inband_progress
= 0;
4731 pri
->ev
.hangup
.aoc_units
= c
->aoc_units
;
4733 return Q931_RES_HAVEEVENT
;
4735 q931_hangup(pri
,c
,c
->cause
);
4737 case Q931_RESTART_ACKNOWLEDGE
:
4738 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_NULL
);
4739 c
->peercallstate
= Q931_CALL_STATE_NULL
;
4740 pri
->ev
.e
= PRI_EVENT_RESTART_ACK
;
4741 pri
->ev
.restartack
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4742 return Q931_RES_HAVEEVENT
;
4743 case Q931_INFORMATION
:
4744 /* XXX We're handling only INFORMATION messages that contain
4745 overlap dialing received digit
4746 + the "Complete" msg which is basically an EOF on further digits
4749 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4752 if (c
->ourcallstate
!= Q931_CALL_STATE_OVERLAP_RECEIVING
) {
4753 pri
->ev
.e
= PRI_EVENT_KEYPAD_DIGIT
;
4754 pri
->ev
.digit
.call
= c
;
4755 pri
->ev
.digit
.channel
= c
->channelno
| (c
->ds1no
<< 8);
4756 libpri_copy_string(pri
->ev
.digit
.digits
, c
->keypad_digits
, sizeof(pri
->ev
.digit
.digits
));
4757 /* Make sure we clear it out before we return */
4758 c
->keypad_digits
[0] = '\0';
4759 return Q931_RES_HAVEEVENT
;
4761 pri
->ev
.e
= PRI_EVENT_INFO_RECEIVED
;
4762 pri
->ev
.ring
.call
= c
;
4763 pri
->ev
.ring
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4764 libpri_copy_string(pri
->ev
.ring
.callednum
, c
->callednum
, sizeof(pri
->ev
.ring
.callednum
));
4765 libpri_copy_string(pri
->ev
.ring
.callingsubaddr
, c
->callingsubaddr
, sizeof(pri
->ev
.ring
.callingsubaddr
));
4766 pri
->ev
.ring
.complete
= c
->complete
; /* this covers IE 33 (Sending Complete) */
4767 return Q931_RES_HAVEEVENT
;
4768 case Q931_STATUS_ENQUIRY
:
4770 q931_release_complete(pri
, c
, PRI_CAUSE_INVALID_CALL_REFERENCE
);
4772 q931_status(pri
,c
, 0);
4774 case Q931_SETUP_ACKNOWLEDGE
:
4776 q931_release_complete(pri
,c
,PRI_CAUSE_INVALID_CALL_REFERENCE
);
4779 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_OVERLAP_SENDING
);
4780 c
->peercallstate
= Q931_CALL_STATE_OVERLAP_RECEIVING
;
4781 pri
->ev
.e
= PRI_EVENT_SETUP_ACK
;
4782 pri
->ev
.setup_ack
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4783 pri
->ev
.setup_ack
.call
= c
;
4786 if (!cur
->sent
&& cur
->message
== Q931_FACILITY
) {
4787 q931_facility(pri
, c
);
4793 return Q931_RES_HAVEEVENT
;
4795 pri
->ev
.e
= PRI_EVENT_NOTIFY
;
4796 pri
->ev
.notify
.channel
= c
->channelno
;
4797 pri
->ev
.notify
.info
= c
->notify
;
4798 return Q931_RES_HAVEEVENT
;
4800 pri
->ev
.e
= PRI_EVENT_HOLD_REQ
;
4801 pri
->ev
.hold_req
.call
= c
;
4802 pri
->ev
.hold_req
.cref
= c
->cr
;
4803 pri
->ev
.hold_req
.tei
= c
->tei
;
4804 pri
->ev
.hold_req
.channel
= c
->channelno
;
4805 return Q931_RES_HAVEEVENT
;
4808 pri
->ev
.e
= PRI_EVENT_RETRIEVE_REQ
;
4809 pri
->ev
.retrieve_req
.call
= c
;
4810 pri
->ev
.retrieve_req
.cref
= c
->cr
;
4811 pri
->ev
.retrieve_req
.tei
= c
->tei
;
4812 pri
->ev
.retrieve_req
.channel
= c
->channelno
;
4813 return Q931_RES_HAVEEVENT
;
4816 pri
->ev
.e
= PRI_EVENT_SUSPEND_REQ
;
4817 pri
->ev
.suspend_req
.call
= c
;
4818 pri
->ev
.suspend_req
.cref
= c
->cr
;
4819 pri
->ev
.suspend_req
.tei
= c
->tei
;
4820 pri
->ev
.suspend_req
.channel
= c
->channelno
;
4821 strncpy(pri
->ev
.suspend_req
.callid
, c
->callid
, sizeof(pri
->ev
.suspend_req
.callid
) - 1);
4822 return Q931_RES_HAVEEVENT
;
4825 if (pri
->localtype
== BRI_NETWORK_PTMP
) {
4826 l2c
= q921_getcall(pri
, c
, tei
);
4829 pri
->ev
.e
= PRI_EVENT_RESUME_REQ
;
4830 pri
->ev
.resume_req
.call
= c
;
4831 pri
->ev
.resume_req
.cref
= c
->cr
;
4832 pri
->ev
.resume_req
.tei
= c
->tei
;
4833 pri
->ev
.resume_req
.channel
= c
->channelno
;
4834 strncpy(pri
->ev
.resume_req
.callid
, c
->callid
, sizeof(pri
->ev
.resume_req
.callid
) - 1);
4835 return Q931_RES_HAVEEVENT
;
4837 case Q931_USER_INFORMATION
:
4839 case Q931_CONGESTION_CONTROL
:
4840 case Q931_HOLD_ACKNOWLEDGE
:
4841 case Q931_HOLD_REJECT
:
4842 case Q931_RETRIEVE_ACKNOWLEDGE
:
4843 case Q931_RETRIEVE_REJECT
:
4844 case Q931_RESUME_ACKNOWLEDGE
:
4845 case Q931_RESUME_REJECT
:
4846 case Q931_SUSPEND_ACKNOWLEDGE
:
4847 case Q931_SUSPEND_REJECT
:
4848 pri_error(pri
, "!! Not yet handling post-handle message type %s (%d)\n", msg2str(mh
->msg
), mh
->msg
);
4852 pri_error(pri
, "!! Don't know how to post-handle message type %s (%d)\n", msg2str(mh
->msg
), mh
->msg
);
4853 q931_status(pri
,c
, PRI_CAUSE_MESSAGE_TYPE_NONEXIST
);
4855 q931_destroycall(pri
,c
->cr
,c
->tei
);
4861 /* Clear a call, although we did not receive any hangup notification. */
4862 static int pri_internal_clear(void *data
)
4864 struct q931_call
*c
= data
;
4865 struct pri
*pri
= c
->pri
;
4868 if (c
->retranstimer
)
4869 pri_schedule_del(pri
, c
->retranstimer
);
4870 c
->retranstimer
= 0;
4871 c
->useruserinfo
[0] = '\0';
4875 c
->sugcallstate
= -1;
4878 UPDATE_OURCALLSTATE(pri
, c
, Q931_CALL_STATE_NULL
);
4879 c
->peercallstate
= Q931_CALL_STATE_NULL
;
4880 pri
->ev
.hangup
.channel
= c
->channelno
| (c
->ds1no
<< 8) | (c
->ds1explicit
<< 16);
4881 pri
->ev
.hangup
.cause
= c
->cause
;
4882 pri
->ev
.hangup
.cref
= c
->cr
;
4883 pri
->ev
.hangup
.call
= c
;
4884 pri
->ev
.hangup
.aoc_units
= c
->aoc_units
;
4885 libpri_copy_string(pri
->ev
.hangup
.useruserinfo
, c
->useruserinfo
, sizeof(pri
->ev
.hangup
.useruserinfo
));
4887 /* Free resources */
4889 pri
->ev
.e
= PRI_EVENT_HANGUP
;
4890 res
= Q931_RES_HAVEEVENT
;
4892 } else if (c
->sendhangupack
) {
4893 res
= Q931_RES_HAVEEVENT
;
4894 pri
->ev
.e
= PRI_EVENT_HANGUP_ACK
;
4895 q931_hangup(pri
, c
, c
->cause
);
4898 q931_hangup(pri
, c
, c
->cause
);
4904 /* Handle T309 timeout for an active call. */
4905 static void pri_dl_down_timeout(void *data
)
4907 struct q931_call
*c
= data
;
4908 struct pri
*pri
= c
->pri
;
4909 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
4910 pri_message(pri
, DBGHEAD
"Timed out waiting for data link re-establishment\n", DBGINFO
);
4912 c
->cause
= PRI_CAUSE_DESTINATION_OUT_OF_ORDER
;
4913 if (pri_internal_clear(c
) == Q931_RES_HAVEEVENT
)
4917 /* Handle Layer 2 down event for a non active call. */
4918 static void pri_dl_down_cancelcall(void *data
)
4920 struct q931_call
*c
= data
;
4921 struct pri
*pri
= c
->pri
;
4922 if (pri
->debug
& PRI_DEBUG_Q931_STATE
)
4923 pri_message(pri
, DBGHEAD
"Cancel non active call after data link failure\n", DBGINFO
);
4925 c
->cause
= PRI_CAUSE_DESTINATION_OUT_OF_ORDER
;
4926 if (pri_internal_clear(c
) == Q931_RES_HAVEEVENT
)
4930 /* Receive an indication from Layer 2 */
4931 void q931_dl_indication(struct pri
*pri
, int event
)
4933 q931_call
*cur
= NULL
;
4935 /* Just return if T309 is not enabled. */
4936 if (!pri
|| pri
->timers
[PRI_TIMER_T309
] < 0)
4940 case PRI_EVENT_DCHAN_DOWN
:
4941 pri_message(pri
, DBGHEAD
"link is DOWN\n", DBGINFO
);
4942 cur
= *pri
->callpool
;
4944 if (cur
->ourcallstate
== Q931_CALL_STATE_ACTIVE
) {
4945 /* For a call in Active state, activate T309 only if there is no timer already running. */
4946 if (!cur
->retranstimer
) {
4947 pri_message(pri
, DBGHEAD
"activate T309 for call %d on channel %d\n", DBGINFO
, cur
->cr
, cur
->channelno
);
4948 cur
->retranstimer
= pri_schedule_event(pri
, pri
->timers
[PRI_TIMER_T309
], pri_dl_down_timeout
, cur
);
4950 } else if (cur
->ourcallstate
!= Q931_CALL_STATE_NULL
) {
4951 /* For a call that is not in Active state, schedule internal clearing of the call 'ASAP' (delay 0). */
4952 pri_message(pri
, DBGHEAD
"cancel call %d on channel %d in state %d (%s)\n", DBGINFO
,
4953 cur
->cr
, cur
->channelno
, cur
->ourcallstate
, callstate2str(cur
->ourcallstate
));
4954 if (cur
->retranstimer
)
4955 pri_schedule_del(pri
, cur
->retranstimer
);
4956 cur
->retranstimer
= pri_schedule_event(pri
, 0, pri_dl_down_cancelcall
, cur
);
4961 case PRI_EVENT_DCHAN_UP
:
4962 pri_message(pri
, DBGHEAD
"link is UP\n", DBGINFO
);
4963 cur
= *pri
->callpool
;
4965 if (cur
->ourcallstate
== Q931_CALL_STATE_ACTIVE
&& cur
->retranstimer
) {
4966 pri_message(pri
, DBGHEAD
"cancel T309 for call %d on channel %d\n", DBGINFO
, cur
->cr
, cur
->channelno
);
4967 pri_schedule_del(pri
, cur
->retranstimer
);
4968 cur
->retranstimer
= 0;
4969 q931_status(pri
, cur
, PRI_CAUSE_NORMAL_UNSPECIFIED
);
4970 } else if (cur
->ourcallstate
!= Q931_CALL_STATE_NULL
&&
4971 cur
->ourcallstate
!= Q931_CALL_STATE_DISCONNECT_REQUEST
&&
4972 cur
->ourcallstate
!= Q931_CALL_STATE_DISCONNECT_INDICATION
&&
4973 cur
->ourcallstate
!= Q931_CALL_STATE_RELEASE_REQUEST
) {
4975 /* The STATUS message sent here is not required by Q.931, but it may help anyway. */
4976 q931_status(pri
, cur
, PRI_CAUSE_NORMAL_UNSPECIFIED
);
4982 pri_message(pri
, DBGHEAD
"unexpected event %d.\n", DBGINFO
, event
);
4986 int q931_call_getcrv(struct pri
*pri
, q931_call
*call
, int *callmode
)
4989 *callmode
= call
->cr
& 0x7;
4990 return ((call
->cr
& 0x7fff) >> 3);
4993 int q931_call_setcrv(struct pri
*pri
, q931_call
*call
, int crv
, int callmode
)
4995 call
->cr
= (crv
<< 3) & 0x7fff;
4996 call
->cr
|= (callmode
& 0x7);