Ignore files generated in the dependency checks.
[libpri-bristuff.git] / q931.c
blobc9ffdfb2795193c9b2172eb7416941e25cab83fc
1 /*
2 * libpri: An implementation of Primary Rate ISDN
4 * Written by Mark Spencer <markster@linux-support.net>
6 * Copyright (C) 2001-2005, Digium, Inc.
7 * All Rights Reserved.
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.
25 #include "compat.h"
26 #include "libpri.h"
27 #include "pri_internal.h"
28 #include "pri_q921.h"
29 #include "pri_q931.h"
30 #include "pri_facility.h"
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <time.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <stdio.h>
38 #include <limits.h>
40 #define MAX_MAND_IES 10
42 struct msgtype {
43 int msgnum;
44 char *name;
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 } },
65 /* Miscellaneous */
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 } },
75 /* Call Management */
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" },
89 /* Maintenance */
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
203 #define LOC_USER 0x0
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
212 struct q921_call {
213 int tei;
214 int proc;
215 int channel;
216 q921_call *next;
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)
228 #if 1
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; \
235 } while (0)
236 #else
237 /* Update call state with no trace. */
238 #define UPDATE_OURCALLSTATE(pri,c,newstate) c->ourcallstate = newstate
239 #endif
241 struct ie {
242 /* Maximal count of same IEs at the message (0 - any, 1..n - limited) */
243 int max_count;
244 /* IE code */
245 int ie;
246 /* IE friendly name */
247 char *name;
248 /* Dump an IE for debugging (preceed all lines by prefix) */
249 FUNC_DUMP(*dump);
250 /* Handle IE returns 0 on success, -1 on failure */
251 FUNC_RECV(*receive);
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)
258 int x;
259 for (x=0;x<max; x++)
260 if (codes[x].msgnum == code)
261 return codes[x].name;
262 return "Unknown";
265 static void call_init(struct q931_call *c)
267 memset(c, 0, sizeof(*c));
268 c->con_acked = 0;
269 c->alive = 0;
270 c->sendhangupack = 0;
271 c->forceinvert = -1;
272 c->cr = -1;
273 c->slotmap = -1;
274 c->channelno = -1;
275 c->ds1no = 0;
276 c->ds1explicit = 0;
277 c->chanflags = 0;
278 c->next = NULL;
279 c->sentchannel = 0;
280 c->newcall = 1;
281 c->t303timer = 0;
282 c->t303running = 0;
283 c->aoc = 0;
284 c->phones = NULL;
285 c->ourcallstate = Q931_CALL_STATE_NULL;
286 c->peercallstate = Q931_CALL_STATE_NULL;
287 c->llc[0] = '\0';
288 c->cause = -1;
289 c->causecode = -1;
290 c->causeloc = -1;
293 static char *binary(int b, int len) {
294 static char res[33];
295 int x;
296 memset(res, 0, sizeof(res));
297 if (len > 32)
298 len = 32;
299 for (x=1;x<=len;x++)
300 res[x-1] = b & (1 << (len - x)) ? '1' : '0';
301 return res;
304 static FUNC_RECV(receive_channel_id)
306 int x;
307 int pos=0;
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
314 return 0;
316 #ifndef NOAUTO_CHANNEL_SELECTION_SUPPORT
317 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
318 switch (ie->data[0] & 3) {
319 case 0:
320 call->justsignalling = 1;
321 break;
322 case 1:
323 break;
324 default:
325 pri_error(pri, "!! Unexpected Channel selection %d\n", ie->data[0] & 3);
326 return -1;
329 #endif
330 if (ie->data[0] & 0x08)
331 call->chanflags = FLAG_EXCLUSIVE;
332 else
333 call->chanflags = FLAG_PREFERRED;
334 pos++;
335 if (ie->data[0] & 0x40) {
336 /* DS1 specified -- stop here */
337 call->ds1no = ie->data[1] & 0x7f;
338 call->ds1explicit = 1;
339 pos++;
340 } else
341 call->ds1explicit = 0;
343 if (pos+2 < len) {
344 /* More coming */
345 if ((ie->data[pos] & 0x0f) != 3) {
346 pri_error(pri, "!! Unexpected Channel Type %d\n", ie->data[1] & 0x0f);
347 return -1;
349 if ((ie->data[pos] & 0x60) != 0) {
350 pri_error(pri, "!! Invalid CCITT coding %d\n", (ie->data[1] & 0x60) >> 5);
351 return -1;
353 if (ie->data[pos] & 0x10) {
354 /* Expect Slot Map */
355 call->slotmap = 0;
356 pos++;
357 for (x=0;x<3;x++) {
358 call->slotmap <<= 8;
359 call->slotmap |= ie->data[x + pos];
361 return 0;
362 } else {
363 pos++;
364 /* Only expect a particular channel */
365 call->channelno = ie->data[pos] & 0x7f;
366 return 0;
368 } else
369 return 0;
370 return -1;
373 static FUNC_SEND(transmit_channel_id)
375 int pos=0;
378 /* We are ready to transmit single IE only */
379 if (order > 1)
380 return 0;
382 if (call->justsignalling) {
383 ie->data[pos++] = 0xac; /* Read the standards docs to figure this out
384 ECMA-165 section 7.3 */
385 return pos + 2;
388 /* Start with standard stuff */
389 if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
390 ie->data[pos] = 0x69;
391 } else {
392 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
393 ie->data[pos] = 0xa1;
394 } else {
395 // BRI
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 */
404 return 0;
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;
412 } else
413 pos++;
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;
421 return pos + 2;
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);
429 return pos + 2;
431 } else {
432 // BRI
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;
441 } else {
442 if (call->channelno > -1) {
443 ie->data[pos-1] |= call->channelno;
446 } else {
447 if (call->channelno > -1) {
448 ie->data[pos-1] |= call->channelno;
451 return pos + 2;
453 } else {
454 if (pri->localtype == BRI_CPE) {
455 ie->data[pos++] = 0x80 | 3;
456 return pos + 2;
460 if (call->ds1no > 0) {
461 /* We're done */
462 return pos + 2;
464 if (msgtype == Q931_RESTART_ACKNOWLEDGE) {
465 /* restart complete interface! */
466 return 0;
468 pri_error(pri, "!! No channel map, no channel, and no ds1? What am I supposed to identify?\n");
469 return -1;
472 static FUNC_DUMP(dump_channel_id)
474 int pos=0;
475 int x;
476 int res = 0;
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)]);
488 pos++;
489 len--;
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);
493 pos++;
494 } else {
495 /* Implicitly defined DS1 */
497 if (pos+2 < len) {
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 */
504 pos++;
505 pri_message(pri, "%c Ext: %d Channel: %d ]\n", prefix, (ie->data[pos] & 0x80) >> 7,
506 (ie->data[pos]) & 0x7f);
507 } else {
508 pos++;
509 /* Map specified */
510 for (x=0;x<3;x++) {
511 res <<= 8;
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)
537 /* Pretty simple */
538 call->ri = ie->data[0] & 0x7;
539 return 0;
542 static FUNC_SEND(transmit_restart_indicator)
544 /* Pretty simple */
545 switch(call->ri) {
546 case 0:
547 case 6:
548 case 7:
549 ie->data[0] = 0x80 | (call->ri & 0x7);
550 break;
551 case 5:
552 /* Switch compatibility */
553 ie->data[0] = 0xA0 | (call->ri & 0x7);
554 break;
555 default:
556 pri_error(pri, "!! Invalid restart indicator value %d\n", call->ri);
557 return-1;
559 return 3;
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)
656 int pos=2;
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);
664 pos++;
667 /* don't count the IE num and length as part of the data */
668 len -= 2;
670 /* Look for octet 5; this is identified by bits 5,6 == 01 */
671 if (pos < len &&
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);
681 pos++;
683 /* octet 5a? */
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",
689 prefix,
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);
694 pos++;
697 /* octet 5b? */
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),
706 (data & 0x60)>>5,
707 (data & 0x10)?1:0,
708 (data & 0x08)?1:0,
709 (data & 0x04)?1:0,
710 (data & 0x02)?1:0);
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,
715 (data & 0x40)?1:0,
716 (data & 0x20)?1:0,
717 (data & 0x10)?1:0,
718 (data & 0x08)?1:0,
719 (data & 0x04)?1:0,
720 (data & 0x02)?1:0);
721 } else {
722 pri_message(pri, "%c Unknown octet 5b: 0x%x\n", data );
724 pos++;
727 /* octet 5c? */
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)]);
741 pos++;
744 /* octet 5d? */
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);
749 pos++;
754 /* Look for octet 6; this is identified by bits 5,6 == 10 */
755 if (pos < len &&
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);
760 pos++;
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);
768 pos++;
770 /* octets 7a and 7b? */
771 if (pos + 1 < len && !(ie->data[pos-1] & 0x80) &&
772 !(ie->data[pos] & 0x80)) {
773 unsigned int proto;
774 proto = ((ie->data[pos] & 0xF) << 4 ) |
775 (ie->data[pos+1] & 0xF);
777 pri_message(pri, "%c Network layer: 0x%x\n", prefix,
778 proto );
779 pos += 2;
784 static FUNC_RECV(receive_bearer_capability)
786 int pos=2;
787 if (ie->data[0] & 0x60) {
788 pri_error(pri, "!! non-standard Q.931 standard field\n");
789 return -1;
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 */
800 if (pos < len &&
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;
806 pos++;
808 /* octet 5a? */
809 if (pos < len && !(ie->data[pos-1] & 0x80)) {
810 call->rateadaption = ie->data[pos] & 0x7f;
811 pos++;
814 /* octets 5b through 5d? */
815 while (pos < len && !(ie->data[pos-1] & 0x80)) {
816 pos++;
821 /* Look for octet 6; this is identified by bits 5,6 == 10 */
822 if (pos < len &&
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 */
828 if (pos < len &&
829 (ie->data[pos] & 0x60) == 0x60) {
830 call->userl3 = ie->data[pos++] & 0x1f;
832 return 0;
835 static FUNC_SEND(transmit_bearer_capability)
837 int tc;
838 int pos;
840 /* We are ready to transmit single IE only */
841 if(order > 1)
842 return 0;
844 tc = call->transcapability;
845 if (pri->subchannel) {
846 /* Bearer capability is *hard coded* in GR-303 */
847 ie->data[0] = 0x88;
848 ie->data[1] = 0x90;
849 return 4;
852 if (call->justsignalling) {
853 ie->data[0] = 0xa8;
854 ie->data[1] = 0x80;
855 return 4;
858 ie->data[0] = 0x80 | tc;
859 ie->data[1] = call->transmoderate | 0x80;
861 pos = 2;
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 */
870 return 4;
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;
879 return pos + 2;
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);
897 return pos + 2;
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)
967 if (len < 0) {
968 pri_error(NULL, "q931_get_number received invalid len = %d\n", len);
969 return;
971 if (len > maxlen - 1) {
972 num[0] = 0;
973 return;
975 memcpy(num, src, len);
976 num[len] = 0;
979 static FUNC_DUMP(dump_called_party_number)
981 char cnum[256];
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)
990 char cnum[256];
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)
1000 char cnum[256];
1001 if (ie->data[0] & 0x80)
1002 q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
1003 else
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);
1008 else
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)
1014 char cnum[256];
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)
1024 char cnum[256];
1025 int i = 0;
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 */
1028 do {
1029 switch(i) {
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);
1033 break;
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);
1037 break;
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);
1041 break;
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)
1051 char cnum[256];
1052 int i = 0;
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 */
1055 do {
1056 switch(i) {
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);
1060 break;
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);
1064 break;
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)
1075 int i = 0;
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 */
1079 do {
1080 switch(i) {
1081 case 0:
1082 call->redirectingplan = ie->data[i] & 0x7f;
1083 break;
1084 case 1:
1085 call->redirectingpres = ie->data[i] & 0x7f;
1086 break;
1087 case 2:
1088 call->redirectingreason = ie->data[i] & 0x0f;
1089 break;
1092 while(!(ie->data[i++] & 0x80));
1093 q931_get_number(call->redirectingnum, sizeof(call->redirectingnum), ie->data + i, ie->len - i);
1094 return 0;
1097 static FUNC_SEND(transmit_redirecting_number)
1099 if (order > 1)
1100 return 0;
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;
1108 return 0;
1111 static FUNC_DUMP(dump_redirecting_subaddr)
1113 char cnum[256];
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);
1125 return 0;
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;
1133 return 0;
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)
1146 u_int8_t *data;
1147 size_t length;
1149 if (ie->data[0] & 0x80) {
1150 data = ie->data + 1;
1151 length = len - 3;
1152 call->callerpres = 0; /* PI presentation allowed SI user-provided, not screened */
1153 } else {
1154 data = ie->data + 2;
1155 length = len - 4;
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;
1169 } else {
1170 q931_get_number((char *)call->callernum, sizeof(call->callernum), data, length);
1171 call->callerplan = ie->data[0] & 0x7f;
1174 return 0;
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)
1188 int x;
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 */
1200 if (len >= 3) {
1201 q931_get_number(call->useruserinfo, sizeof(call->useruserinfo), ie->data + 1, len - 3);
1202 } else {
1203 pri_error(call->pri, "User-User Information (len=%2d) too short.\n", len);
1206 return 0;
1209 static FUNC_RECV(receive_call_identity)
1211 if (len >= 2) {
1212 q931_get_number(call->callid, sizeof(call->callid), ie->data, len - 2);
1213 } else {
1214 pri_error(call->pri, "Call Identity (len=%2d) too short.\n", len);
1216 return 0;
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)
1228 return 0;
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) {
1234 ie->data[0] = 0x91;
1235 ie->data[1] = 0x81;
1236 return 4;
1238 return 0;
1241 static FUNC_DUMP(dump_high_layer_compat)
1243 int x;
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)
1253 if (len > 0) {
1254 if (len > 16) {
1255 pri_error(pri, "%d bytes LLC too long\n", len);
1256 call->llc[0] = 0;
1257 } else {
1258 pri_error(pri, "copying %d bytes LLC \n", len);
1259 call->llc[0] = len;
1260 memcpy(call->llc+1, ie->data, len);
1263 return 0;
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)
1275 int x;
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);
1285 if (datalen > 0) {
1286 /* Restricted to 35 characters */
1287 if (msgtype == Q931_USER_INFORMATION) {
1288 if (datalen > 260)
1289 datalen = 260;
1290 } else {
1291 if (datalen > 35)
1292 datalen = 35;
1294 ie->data[0] = 4; /* IA5 characters */
1295 memcpy(&ie->data[1], call->useruserinfo, datalen);
1296 call->useruserinfo[0] = '\0';
1297 return datalen + 3;
1300 return 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;
1357 data = ie->data;
1358 if (data[0] & 0x80) {
1359 /* Skip over character set */
1360 data++;
1361 len--;
1363 q931_get_number((char *) call->callername, sizeof(call->callername), data, len - 2);
1364 return 0;
1367 static FUNC_SEND(transmit_display)
1369 int i;
1371 if ((pri->switchtype == PRI_SWITCH_QSIG) ||
1372 ((pri->switchtype == PRI_SWITCH_EUROISDN_E1) && (pri->localtype == PRI_CPE)) ||
1373 !call->callername[0])
1374 return 0;
1376 i = 0;
1377 if(pri->switchtype != PRI_SWITCH_EUROISDN_E1) {
1378 ie->data[0] = 0xb1;
1379 ++i;
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;
1392 break;
1393 case Q931_PROG_CALLED_NOT_ISDN:
1394 call->progressmask |= PRI_PROG_CALLED_NOT_ISDN;
1395 break;
1396 case Q931_PROG_CALLER_NOT_ISDN:
1397 call->progressmask |= PRI_PROG_CALLER_NOT_ISDN;
1398 break;
1399 case Q931_PROG_CALLER_RETURNED_TO_ISDN:
1400 call->progressmask |= PRI_PROG_CALLER_RETURNED_TO_ISDN;
1401 break;
1402 case Q931_PROG_INBAND_AVAILABLE:
1403 call->progressmask |= PRI_PROG_INBAND_AVAILABLE;
1404 break;
1405 case Q931_PROG_DELAY_AT_INTERF:
1406 call->progressmask |= PRI_PROG_DELAY_AT_INTERF;
1407 break;
1408 case Q931_PROG_INTERWORKING_WITH_PUBLIC:
1409 call->progressmask |= PRI_PROG_INTERWORKING_WITH_PUBLIC;
1410 break;
1411 case Q931_PROG_INTERWORKING_NO_RELEASE:
1412 call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE;
1413 break;
1414 case Q931_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER:
1415 call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE_PRE_ANSWER;
1416 break;
1417 case Q931_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER:
1418 call->progressmask |= PRI_PROG_INTERWORKING_NO_RELEASE_POST_ANSWER;
1419 break;
1420 default:
1421 pri_error(pri, "XXX Invalid Progress indicator value received: %02x\n",(ie->data[1] & 0x7f));
1422 break;
1424 return 0;
1427 #if 0
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++];
1438 switch (cpt_tag) {
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");
1443 break;
1445 invoke_id_len = ie->data[pos++]; // 4
1446 while (invoke_id_len > 0) {
1447 invoke_id = (invoke_id << 8) | (ie->data[pos++] & 0xFF);
1448 invoke_id_len--;
1450 operation_value_tag = ie->data[pos++];
1451 if (operation_value_tag != 0x02) {
1452 // pri_error(call->pri, "operation value tag != 0x02\n");
1453 break;
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;
1464 break;
1465 case 0x0D: /* call deflection */
1466 call->facility = operation_value;
1467 /* dirty hack! */
1468 arg_len -= 6;
1469 if (arg_len > 0) {
1470 pos += 6;
1471 q931_get_number(call->redirectingnum, sizeof(call->redirectingnum), ie->data + pos, arg_len);
1473 /* now retrieve the number */
1474 break;
1475 case 0x22: /* AOC-D */
1476 break;
1477 case 0x24: /* AOC-E */
1478 break;
1480 break;
1481 case 2: /* return result */
1482 break;
1483 case 3: /* return error */
1484 break;
1485 case 4: /* reject */
1486 break;
1488 } else {
1489 /* OLD DIRTY ULAW HACK */
1490 if (ie->len < 14) {
1491 pri_error(call->pri, "!! Facility message shorter than 14 bytes\n");
1492 return 0;
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;
1499 return 0;
1502 static FUNC_SEND(transmit_facility_kpj)
1504 int i = 0;
1505 return i;
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 */
1515 switch (msgtype) {
1516 case Q931_SETUP:
1517 ie->data[i++] = 0x26; /* operation value AOC-S */
1518 break;
1519 case Q931_DISCONNECT:
1520 ie->data[i++] = 0x24; /* operation value AOC-E */
1521 break;
1522 default:
1523 ie->data[i++] = 0x22; /* operation value AOC-D */
1524 break;
1526 // ARGUMENTS!
1528 // return 2 + i;
1530 #endif
1532 static FUNC_SEND(transmit_facility)
1534 struct apdu_event *tmp;
1535 int i = 0;
1537 for (tmp = call->apdus; tmp; tmp = tmp->next) {
1538 if ((tmp->message == msgtype) && !tmp->sent)
1539 break;
1542 if (!tmp) /* No APDU found */
1543 return 0;
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);
1547 return 0;
1550 memcpy(&ie->data[i], tmp->apdu, tmp->apdu_len);
1551 i += tmp->apdu_len;
1552 tmp->sent = 1;
1554 return i + 2;
1557 #if 0
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)))) {
1568 do {
1569 first_i = i;
1570 ie->data[i] = 0x80 | Q932_PROTOCOL_EXTENSIONS;
1571 i++;
1572 /* Interpretation component */
1573 ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, ie->data, i, 0x00 /* Discard unrecognized invokes */);
1575 /* Invoke ID */
1576 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, ie->data, i);
1577 ASN1_PUSH(compstk, compsp, comp);
1579 /* Invoke component contents */
1580 /* Invoke ID */
1581 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, ie->data, i, ++pri->last_invoke);
1583 /* Operation Tag */
1584 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, ie->data, i, SS_CNID_CALLINGNAME);
1586 /* Arugement Tag */
1587 j = asn1_string_encode(ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE, &ie->data[i], len - i, 15, call->callername, namelen);
1588 if (j < 0) {
1589 i = first_i;
1590 break;
1592 i += j;
1594 /* Fix length of stacked components */
1595 while(compsp > 0) {
1596 ASN1_FIXUP(compstk, compsp, ie->data, i);
1598 } while (0);
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));
1646 if (j < 0) {
1647 i = first_i;
1648 goto finish2;
1650 i += j;
1651 ASN1_FIXUP(compstk, compsp, ie->data, i);
1652 ASN1_FIXUP(compstk, compsp, ie->data, i);
1653 break;
1655 /* fall through */
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);
1659 break;
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);
1666 break;
1667 default:
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);
1671 break;
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));
1694 if (j < 0) {
1695 i = first_i;
1696 goto finish2;
1698 i += j;
1699 ASN1_FIXUP(compstk, compsp, ie->data, i);
1700 ASN1_FIXUP(compstk, compsp, ie->data, i);
1701 break;
1703 /* fall through */
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);
1707 break;
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);
1714 break;
1715 default:
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);
1719 break;
1721 ASN1_FIXUP(compstk, compsp, ie->data, i);
1723 /* Fix length of stacked components */
1724 while(compsp > 0) {
1725 ASN1_FIXUP(compstk, compsp, ie->data, i);
1728 finish2:
1729 return (i ? i+2 : 0);
1731 #endif
1733 static FUNC_RECV(receive_facility)
1735 int i = 0;
1736 int protocol, next_protocol;
1737 struct rose_component *comp = NULL;
1738 enum {
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) \
1745 case component: \
1746 if(state > my_state) { \
1747 pri_error(pri, "!! %s component received in wrong place\n"); \
1748 break; \
1750 state = my_state; \
1751 if (pri->debug) \
1752 pri_message(pri, "Handle Q.932 %s component\n", name); \
1753 (handler)(pri, call, comp->data, comp->len); \
1754 break;
1755 #define Q932_HANDLE_NULL(component, my_state, name, handle) \
1756 case component: \
1757 if(state > my_state) { \
1758 pri_error(pri, "!! %s component received in wrong place\n"); \
1759 break; \
1761 state = my_state; \
1762 if (pri->debug & PRI_DEBUG_APDU) \
1763 pri_message(pri, "Q.932 %s component is not handled\n", name); \
1764 break;
1766 if (ie->len < 1)
1767 return -1;
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);
1774 return -1;
1775 case Q932_PROTOCOL_EXTENSIONS:
1776 state = Q932_STATE_NFE;
1777 next_protocol = Q932_PROTOCOL_ROSE;
1778 break;
1779 case Q932_PROTOCOL_ROSE:
1780 break;
1781 default:
1782 pri_error(pri, "!! Invalid Q.932 Protocol Profile of type 0x%X received\n", protocol);
1783 return -1;
1785 /* Service indicator octet - Just ignore for now */
1786 if (!(ie->data[i] & 0x80))
1787 i++;
1788 i++;
1790 if (ie->len < 3)
1791 return -1;
1793 while ((i+1 < ie->len) && (&ie->data[i])) {
1794 comp = (struct rose_component*)&ie->data[i];
1795 if (comp->type) {
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);
1801 default:
1802 protocol = next_protocol;
1803 break;
1806 switch (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);
1813 default:
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);
1816 break;
1818 break;
1819 case Q932_PROTOCOL_CMIP:
1820 switch (comp->type) {
1821 default:
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);
1824 break;
1826 break;
1827 case Q932_PROTOCOL_ACSE:
1828 switch (comp->type) {
1829 default:
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);
1832 break;
1834 break;
1837 i += (comp->len + 2);
1839 #undef Q932_HANDLE
1841 return 0;
1844 static FUNC_SEND(transmit_progress_indicator)
1846 int code, mask;
1847 /* Can't send progress indicator on GR-303 -- EVER! */
1848 if (pri->subchannel)
1849 return 0;
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;
1869 else {
1870 code = 0;
1871 pri_error(pri, "XXX Undefined progress bit: %x\n", call->progressmask);
1873 if (code) {
1874 ie->data[0] = 0x80 | (call->progcode << 5) | (call->progloc);
1875 ie->data[1] = 0x80 | code;
1876 call->progressmask &= ~mask;
1877 return 4;
1880 /* Leave off */
1881 return 0;
1883 static FUNC_SEND(transmit_call_state)
1885 if (call->ourcallstate > -1 ) {
1886 ie->data[0] = call->ourcallstate;
1887 return 3;
1889 return 0;
1892 static FUNC_RECV(receive_call_state)
1894 call->sugcallstate = ie->data[0] & 0x3f;
1895 return 0;
1898 static char *callstate2str(int callstate)
1900 static struct msgtype callstates[] = {
1901 { 0, "Null" },
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" },
1910 { 10, "Active" },
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" },
1919 { 62, "Restart" },
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)
1933 int x;
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)
1943 return 0;
1946 static FUNC_SEND(transmit_time_date) {
1947 time_t now;
1948 struct tm *timedate;
1949 time(&now);
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;
1956 return 7;
1959 static FUNC_DUMP(dump_time_date)
1961 pri_message(pri, "%c Time Date (len=%2d) [ ", prefix, len);
1962 if (ie->len > 0)
1963 pri_message(pri, "%02d", ie->data[0]);
1964 if (ie->len > 1)
1965 pri_message(pri, "-%02d", ie->data[1]);
1966 if (ie->len > 2)
1967 pri_message(pri, "-%02d", ie->data[2]);
1968 if (ie->len > 3)
1969 pri_message(pri, " %02d", ie->data[3]);
1970 if (ie->len > 4)
1971 pri_message(pri, ":%02d", ie->data[4]);
1972 if (ie->len > 5)
1973 pri_message(pri, ":%02d", ie->data[5]);
1974 pri_message(pri, " ]\n");
1977 static FUNC_DUMP(dump_keypad_facility)
1979 char tmp[64] = "";
1981 if (ie->len == 0 || ie->len > sizeof(tmp))
1982 return;
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)
1991 int mylen;
1993 if (ie->len == 0)
1994 return -1;
1996 if (ie->len > (sizeof(call->keypad_digits) - 1))
1997 mylen = (sizeof(call->keypad_digits) - 1);
1998 else
1999 mylen = ie->len;
2001 memcpy(call->keypad_digits, ie->data, mylen);
2002 call->keypad_digits[mylen] = 0;
2004 return 0;
2007 static FUNC_SEND(transmit_keypad_facility)
2009 int sublen;
2011 sublen = strlen(call->keypad_digits);
2013 if (sublen > 32) {
2014 sublen = 32;
2015 call->keypad_digits[32] = '\0';
2018 if (sublen) {
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';
2022 return sublen + 2;
2023 } else
2024 return 0;
2027 static FUNC_DUMP(dump_display)
2029 int x, y;
2030 char *buf = malloc(len + 1);
2031 char tmp[80] = "";
2032 if (buf) {
2033 x=y=0;
2034 if ((x < ie->len) && (ie->data[x] & 0x80)) {
2035 sprintf(tmp, "Charset: %02x ", ie->data[x] & 0x7f);
2036 ++x;
2038 for (y=x; x<ie->len; x++)
2039 buf[x] = ie->data[x] & 0x7f;
2040 buf[x] = '\0';
2041 pri_message(pri, "%c Display (len=%2d) %s[ %s ]\n", prefix, ie->len, tmp, &buf[y]);
2042 free(buf);
2046 #define CHECK_OVERFLOW(limit) \
2047 if (tmpptr - tmp + limit >= sizeof(tmp)) { \
2048 *tmpptr = '\0'; \
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;
2056 int lastascii = 0;
2057 tmpptr = tmp;
2058 for (; len; --len, ++c) {
2059 CHECK_OVERFLOW(7);
2060 if (isprint(*c)) {
2061 if (!lastascii) {
2062 if (tmpptr != tmp) {
2063 *tmpptr++ = ',';
2064 *tmpptr++ = ' ';
2066 *tmpptr++ = '\'';
2067 lastascii = 1;
2069 *tmpptr++ = *c;
2070 } else {
2071 if (lastascii) {
2072 *tmpptr++ = '\'';
2073 lastascii = 0;
2075 if (tmpptr != tmp) {
2076 *tmpptr++ = ',';
2077 *tmpptr++ = ' ';
2079 *tmpptr++ = '0';
2080 *tmpptr++ = 'x';
2081 *tmpptr++ = hexs[(*c >> 4) & 0x0f];
2082 *tmpptr++ = hexs[(*c) & 0x0f];
2085 if (lastascii)
2086 *tmpptr++ = '\'';
2087 *tmpptr = '\0';
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");
2097 if (ie->len > 1) {
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])));
2110 else
2111 dump_ie_data(pri, ie->data, ie->len);
2112 pri_message(pri, " ]\n");
2115 static FUNC_RECV(receive_network_spec_fac)
2117 return 0;
2120 static FUNC_SEND(transmit_network_spec_fac)
2122 /* We are ready to transmit single IE only */
2123 if (order > 1)
2124 return 0;
2126 if (pri->nsf != PRI_NSF_NONE) {
2127 ie->data[0] = 0x00;
2128 ie->data[1] = pri->nsf;
2129 return 4;
2131 /* Leave off */
2132 return 0;
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)
2157 int x;
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);
2164 if (ie->len < 3)
2165 return;
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]));
2171 break;
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]));
2175 break;
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");
2184 break;
2185 default:
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]);
2188 break;
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);
2197 return 0;
2200 static FUNC_SEND(transmit_cause)
2202 /* We are ready to transmit single IE only */
2203 if (order > 1)
2204 return 0;
2206 if (call->cause > 0) {
2207 ie->data[0] = 0x80 | (call->causecode << 5) | (call->causeloc);
2208 ie->data[1] = 0x80 | (call->cause);
2209 return 4;
2210 } else {
2211 /* Leave off */
2212 return 0;
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. */
2224 call->complete = 1;
2225 return 0;
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 */
2234 return 1;
2236 return 0;
2239 static char *notify2str(int info)
2241 /* ITU-T Q.763 */
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;
2277 return 0;
2280 static FUNC_SEND(transmit_notify)
2282 if (call->notify >= 0) {
2283 ie->data[0] = 0x80 | call->notify;
2284 return 3;
2286 return 0;
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];
2334 return 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) {
2341 ie->data[0] = 0;
2342 return 3;
2344 #endif
2345 return 0;
2349 static char *gdencoding2str(int encoding)
2351 static struct msgtype gdencoding[] = {
2352 { 0, "BCD even" },
2353 { 1, "BCD odd" },
2354 { 2, "IA5" },
2355 { 3, "Binary" },
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" },
2364 { 1, "Auth Code" },
2365 { 2, "Customer ID" },
2366 { 3, "Universal Access" },
2367 { 4, "Info Digits" },
2368 { 5, "Callid" },
2369 { 6, "Opart" },
2370 { 7, "TCN" },
2371 { 9, "Adin" },
2373 return code2str(type, gdtype, sizeof(gdtype) / sizeof(gdtype[0]));
2376 static FUNC_DUMP(dump_generic_digits)
2378 int encoding;
2379 int type;
2380 int idx;
2381 int value;
2382 if (len < 3) {
2383 pri_message(pri, "%c Generic Digits (len=%02d): Invalid length\n", prefix, len);
2384 return;
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");
2391 return;
2393 if (len == 3) /* No number information */
2394 return;
2395 pri_message(pri, "%c Digits: ");
2396 value = 0;
2397 for(idx = 3; idx < len; ++idx) {
2398 switch(encoding) {
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);
2407 break;
2408 case 2: /* IA5 */
2409 pri_message(pri, "%c", ie->data[idx-2]);
2410 value = value * 10 + ie->data[idx-2] - '0';
2411 break;
2414 switch(type) {
2415 case 4: /* Info Digits */
2416 pri_message(pri, " - %s", lineinfo2str(value));
2417 break;
2419 pri_message(pri, "\n");
2422 static FUNC_RECV(receive_generic_digits)
2424 int encoding;
2425 int type;
2426 int idx;
2427 int value;
2428 int num_idx;
2429 char number[260];
2431 if (len < 3) {
2432 pri_error(pri, "Invalid length of Generic Digits IE\n");
2433 return -1;
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");
2439 return 0;
2441 if (len == 3) /* No number information */
2442 return 0;
2443 value = 0;
2444 switch(type) {
2445 /* Integer value handling */
2446 case 4: /* Info Digits */
2447 for(idx = 3; idx < len; ++idx) {
2448 switch(encoding) {
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);
2454 break;
2455 case 2: /* IA5 */
2456 value = value * 10 + (ie->data[idx-2] - '0');
2457 break;
2460 break;
2461 /* String value handling */
2462 case 5: /* Callid */
2463 num_idx = 0;
2464 for(idx = 3; (idx < len) && (num_idx < sizeof(number) - 4); ++idx) {
2465 switch(encoding) {
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);
2471 break;
2472 case 2:
2473 number[num_idx++] = ie->data[idx-2];
2474 break;
2477 number[num_idx] = '\0';
2478 break;
2480 switch(type) {
2481 case 4: /* Info Digits */
2482 call->ani2 = value;
2483 break;
2484 #if 0
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;
2491 break;
2492 #endif
2494 return 0;
2497 static FUNC_SEND(transmit_generic_digits)
2499 #if 0 /* XXX Is this IE possible for other switches? XXX */
2500 if (order > 1)
2501 return 0;
2503 if(pri->switchtype == PRI_SWITCH_NI1) {
2504 ie->data[0] = 0x04; /* BCD even, Info Digits */
2505 ie->data[1] = 0x00; /* POTS */
2506 return 4;
2508 #endif
2509 return 0;
2513 static char *signal2str(int signal)
2515 /* From Q.931 4.5.8 Table 4-24 */
2516 static struct msgtype mtsignal[] = {
2517 { 0, "Dial tone" },
2518 { 1, "Ring back tone" },
2519 { 2, "Intercept tone" },
2520 { 3, "Network congestion tone" },
2521 { 4, "Busy 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);
2545 if (len < 3) {
2546 pri_message(pri, "Invalid length\n");
2547 return;
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);
2556 if (len < 3) {
2557 pri_message(pri, "Invalid length\n");
2558 return;
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 },
2625 /* Codeset 7 */
2628 static char *ie2str(int ie)
2630 unsigned int x;
2632 /* Special handling for Locking/Non-Locking Shifts */
2633 switch (ie & 0xf8) {
2634 case Q931_LOCKING_SHIFT:
2635 switch (ie & 7) {
2636 case 0:
2637 return "!! INVALID Locking Shift To Codeset 0";
2638 case 1:
2639 return "Locking Shift To Codeset 1";
2640 case 2:
2641 return "Locking Shift To Codeset 2";
2642 case 3:
2643 return "Locking Shift To Codeset 3";
2644 case 4:
2645 return "Locking Shift To Codeset 4";
2646 case 5:
2647 return "Locking Shift To Codeset 5";
2648 case 6:
2649 return "Locking Shift To Codeset 6";
2650 case 7:
2651 return "Locking Shift To Codeset 7";
2653 case Q931_NON_LOCKING_SHIFT:
2654 switch (ie & 7) {
2655 case 0:
2656 return "Non-Locking Shift To Codeset 0";
2657 case 1:
2658 return "Non-Locking Shift To Codeset 1";
2659 case 2:
2660 return "Non-Locking Shift To Codeset 2";
2661 case 3:
2662 return "Non-Locking Shift To Codeset 3";
2663 case 4:
2664 return "Non-Locking Shift To Codeset 4";
2665 case 5:
2666 return "Non-Locking Shift To Codeset 5";
2667 case 6:
2668 return "Non-Locking Shift To Codeset 6";
2669 case 7:
2670 return "Non-Locking Shift To Codeset 7";
2672 default:
2673 for (x=0;x<sizeof(ies) / sizeof(ies[0]); x++)
2674 if (ie == ies[x].ie)
2675 return ies[x].name;
2676 return "Unknown Information Element";
2680 static inline unsigned int ielen(q931_ie *ie)
2682 if ((ie->ie & 0x80) != 0)
2683 return 1;
2684 else
2685 return 2 + ie->len;
2688 static char *msg2str(int msg)
2690 unsigned int x;
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)
2699 int cr = 0;
2700 int x;
2701 if (h->crlen > 3) {
2702 pri_error(NULL, "Call Reference Length Too long: %d\n", h->crlen);
2703 return -1;
2705 switch (h->crlen) {
2706 case 2:
2707 for (x=0;x<h->crlen;x++) {
2708 cr <<= 8;
2709 cr |= h->crv[x];
2711 break;
2712 case 1:
2713 cr = h->crv[0];
2714 /* if (cr & 0x80) {
2715 cr &= ~0x80;
2716 cr |= 0x8000;
2717 } */
2718 break;
2719 default:
2720 pri_error(NULL, "Call Reference Length not supported: %d\n", h->crlen);
2722 return cr;
2725 static inline void q931_dumpie(struct pri *pri, int codeset, q931_ie *ie, char prefix)
2727 unsigned int x;
2728 int full_ie = Q931_FULL_IE(codeset, ie->ie);
2729 int base_ie;
2730 char *buf = malloc(ielen(ie) * 3 + 1);
2731 int buflen = 0;
2733 buf[0] = '\0';
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);
2740 free(buf);
2742 /* Special treatment for shifts */
2743 if((full_ie & 0xf0) == Q931_LOCKING_SHIFT)
2744 full_ie &= 0xff;
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) {
2750 if (ies[x].dump)
2751 ies[x].dump(full_ie, pri, ie, ielen(ie), prefix);
2752 else
2753 pri_message(pri, "%c IE: %s (len = %d)\n", prefix, ies[x].name, ielen(ie));
2754 return;
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)
2762 q921_call *cur;
2763 cur = c->phones;
2764 while(cur) {
2765 if (cur->tei == tei) {
2766 return cur;
2768 cur = cur->next;
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));
2775 cur->tei = tei;
2776 cur->proc = 0;
2777 cur->channel = -1;
2778 cur->next = c->phones;
2779 c->phones = cur;
2780 return cur;
2783 static q931_call *q931_getcall(struct pri *pri, int cr, int tei)
2785 q931_call *cur, *prev;
2786 cur = *pri->callpool;
2787 prev = NULL;
2788 while(cur) {
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)))
2793 return cur;
2794 // or we might not be the 1st responding, then we need to clone
2795 // the call struct to hangup properly
2796 } else {
2797 if (cur->cr == cr)
2798 return cur;
2800 prev = cur;
2801 cur = cur->next;
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));
2807 if (cur) {
2808 call_init(cur);
2809 /* Call reference */
2810 cur->cr = cr;
2811 cur->pri = pri;
2812 cur->tei = tei;
2813 /* Append to end of list */
2814 if (prev)
2815 prev->next = cur;
2816 else
2817 *pri->callpool = cur;
2819 return cur;
2822 q931_call *q931_new_call(struct pri *pri)
2824 q931_call *cur;
2825 do {
2826 cur = *pri->callpool;
2827 pri->cref++;
2828 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
2829 if (pri->cref > 32767)
2830 pri->cref = 1;
2831 } else {
2832 // BRI
2833 if (pri->cref > 127)
2834 pri->cref = 1;
2836 while(cur) {
2837 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
2838 if (cur->cr == (0x8000 | pri->cref))
2839 break;
2840 } else {
2841 // BRIs have only 1 bye cref
2842 if (cur->cr == (0x80 | pri->cref))
2843 break;
2845 cur = cur->next;
2847 } while(cur);
2848 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
2849 return q931_getcall(pri, pri->cref | 0x8000, 0);
2850 } else {
2851 // BRI
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;
2859 prev = NULL;
2860 cur = *pri->callpool;
2861 while(cur) {
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))))) {
2864 if (prev)
2865 prev->next = cur->next;
2866 else
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);
2872 if (cur->t303timer)
2873 pri_schedule_del(pri, cur->t303timer);
2874 pri_call_apdu_queue_cleanup(cur);
2875 free(cur);
2876 return;
2878 prev = cur;
2879 cur = cur->next;
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)
2892 if (pri && c)
2893 q931_destroy(pri,0, c, c->tei);
2894 return;
2897 static int add_ie(struct pri *pri, q931_call *call, int msgtype, int ie, q931_ie *iet, int maxlen, int *codeset)
2899 unsigned int x;
2900 int res, total_res;
2901 int have_shift;
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);
2911 have_shift = 1;
2912 iet = (q931_ie *)((char *)iet + 1);
2913 maxlen--;
2915 else
2916 have_shift = 0;
2917 ies_count = ies[x].max_count;
2918 if (ies_count == 0)
2919 ies_count = INT_MAX;
2920 order = 0;
2921 total_res = 0;
2922 do {
2923 iet->ie = ie;
2924 res = ies[x].transmit(ie, pri, call, msgtype, iet, maxlen, ++order);
2925 /* Error if res < 0 or ignored if res == 0 */
2926 if (res < 0)
2927 return res;
2928 if (res > 0) {
2929 if ((iet->ie & 0x80) == 0) /* Multibyte IE */
2930 iet->len = res - 2;
2931 total_res += res;
2932 maxlen -= res;
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 */
2942 return total_res;
2943 } else {
2944 pri_error(pri, "!! Don't know how to add an IE %s (%d)\n", ie2str(ie), ie);
2945 return -1;
2949 pri_error(pri, "!! Unknown IE %d (%s)\n", ie, ie2str(ie));
2950 return -1;
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)
2966 q931_mh *mh;
2967 char c;
2968 int x=0, r;
2969 int cur_codeset;
2970 int codeset;
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;
2980 while(x < len) {
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;
2987 break;
2988 case Q931_NON_LOCKING_SHIFT:
2989 cur_codeset = mh->data[x] & 7;
2990 break;
2991 default:
2992 /* Reset temporary codeset change */
2993 cur_codeset = codeset;
2995 x += r;
2997 if (x > len)
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)
3003 unsigned int x;
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));
3007 return -1;
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) {
3013 if (ies[x].receive)
3014 return ies[x].receive(full_ie, pri, c, msg, ie, ielen(ie));
3015 else {
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));
3018 return -1;
3022 pri_message(pri, "!! Unknown IE %d (cs%d, %s)\n", ie->ie, codeset, ie2str(full_ie));
3023 return -1;
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;
3030 q931_mh *mh;
3031 h->pd = pri->protodisc;
3032 h->x0 = 0; /* Reserved 0 */
3034 if (briflag == 1) {
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);
3039 } else {
3040 /* Unless of course this has no call reference */
3041 h->crv[0] = 0;
3043 *len -= 4;
3044 } else {
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);
3050 } else {
3051 /* Unless of course this has no call reference */
3052 h->crv[0] = 0;
3053 h->crv[1] = 0;
3055 *len -= 5;
3057 if (pri->subchannel) {
3058 /* On GR-303, top bit is always 0 */
3059 h->crv[0] &= 0x7f;
3061 mh->f = 0;
3062 *hb = h;
3063 *mhb = mh;
3066 static int q931_xmit(struct pri *pri, q931_h *h, int len, int cr, int tei)
3068 q931_mh *mh;
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);
3073 } else {
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);
3078 } else {
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++;
3088 #endif
3089 return 0;
3092 static int send_message(struct pri *pri, q931_call *c, int msgtype, int ies[])
3094 unsigned char buf[1024];
3095 q931_h *h;
3096 q931_mh *mh;
3097 int len;
3098 int res;
3099 int offset=0;
3100 int x;
3101 int codeset;
3103 memset(buf, 0, sizeof(buf));
3104 len = sizeof(buf);
3105 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
3106 init_header(pri, c, buf, &h, &mh, &len, 0);
3107 } else {
3108 init_header(pri, c, buf, &h, &mh, &len, 1);
3110 mh->msg = msgtype;
3111 x=0;
3112 codeset = 0;
3113 while(ies[x] > -1) {
3114 res = add_ie(pri, c, mh->msg, ies[x], (q931_ie *)(mh->data + offset), len, &codeset);
3116 if (res < 0) {
3117 pri_error(pri, "!! Unable to add IE '%s'\n", ie2str(ies[x]));
3118 return -1;
3121 offset += res;
3122 len -= res;
3123 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);
3129 } else {
3130 q931_xmit(pri, h, len, 1, c->tei);
3132 c->acked = 1;
3133 return 0;
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;
3141 if (!cause)
3142 cause = PRI_CAUSE_RESPONSE_TO_STATUS_ENQUIRY;
3143 if (c->cr > -1)
3144 cur = *pri->callpool;
3145 while(cur) {
3146 if (cur->cr == c->cr) {
3147 cur->cause=cause;
3148 cur->causecode = CODE_CCITT;
3149 cur->causeloc = LOC_USER;
3150 break;
3152 cur = cur->next;
3154 if (!cur) {
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;
3159 cur=c;
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)
3185 int res=0;
3186 char temp[256];
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));
3192 return res;
3195 int q931_add_display(struct pri *pri, q931_call *c, char *display)
3197 strncpy(c->display, display, sizeof(c->display));
3198 return 0;
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))
3225 return 0;
3227 if (info >= 0)
3228 c->notify = info & 0x7F;
3229 else
3230 c->notify = -1;
3231 return send_message(pri, c, Q931_NOTIFY, notify_ies);
3234 #ifdef ALERTING_NO_PROGRESS
3235 static int call_progress_ies[] = { -1 };
3236 #else
3237 static int call_progress_ies[] = { Q931_PROGRESS_INDICATOR, -1 };
3238 #endif
3240 int q931_call_progress(struct pri *pri, q931_call *c, int channel, int info)
3242 if (channel) {
3243 c->ds1no = (channel & 0xff00) >> 8;
3244 c->ds1explicit = (channel & 0x10000) >> 16;
3245 channel &= 0xff;
3246 c->channelno = channel;
3248 if (info) {
3249 c->progloc = LOC_PRIV_NET_LOCAL_USER;
3250 c->progcode = CODE_CCITT;
3251 c->progressmask = PRI_PROG_INBAND_AVAILABLE;
3252 } else {
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;
3257 c->alive = 1;
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 };
3263 #else
3264 static int call_proceeding_ies[] = { Q931_CHANNEL_IDENT, Q931_PROGRESS_INDICATOR, -1 };
3265 #endif
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;
3271 if (channel) {
3272 c->ds1no = (channel & 0xff00) >> 8;
3273 c->ds1explicit = (channel & 0x10000) >> 16;
3274 channel &= 0xff;
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;
3281 if (info) {
3282 c->progloc = LOC_PRIV_NET_LOCAL_USER;
3283 c->progcode = CODE_CCITT;
3284 c->progressmask = PRI_PROG_INBAND_AVAILABLE;
3285 } else
3286 c->progressmask = 0;
3287 c->proc = 1;
3288 c->alive = 1;
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 };
3293 #else
3294 static int alerting_ies[] = { -1 };
3295 #endif
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;
3303 if (!c->proc)
3304 q931_call_proceeding(pri, c, channel, 0);
3305 if (info) {
3306 c->progloc = LOC_PRIV_NET_LOCAL_USER;
3307 c->progcode = CODE_CCITT;
3308 c->progressmask = PRI_PROG_INBAND_AVAILABLE;
3309 } else
3310 c->progressmask = 0;
3311 UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_CALL_RECEIVED);
3312 c->peercallstate = Q931_CALL_STATE_CALL_DELIVERED;
3313 c->alert = 1;
3314 c->alive = 1;
3315 if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)) {
3316 return send_message(pri, c, Q931_ALERTING, alerting_ies);
3317 } else {
3318 if ((pri->localtype == BRI_NETWORK) || (pri->localtype == BRI_NETWORK_PTMP)) {
3319 return send_message(pri, c, Q931_ALERTING, alerting_ies);
3320 } else {
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)
3338 c->cause = 12;
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)
3348 if (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];
3367 int res;
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);
3375 return res;
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];
3383 int res;
3384 strncpy(tempcallername,c->callername,sizeof(tempcallername));
3385 strncpy(c->callername,display,sizeof(c->callername));
3386 c->cause = 12;
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));
3391 return res;
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];
3399 int res;
3400 c->cause = 12;
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));
3407 return res;
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];
3415 int res;
3416 if (channel)
3417 c->channelno = channel;
3418 c->chanflags &= ~FLAG_PREFERRED;
3419 c->chanflags |= FLAG_EXCLUSIVE;
3420 c->alive = 1;
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));
3427 return res;
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;
3437 if (channel) {
3438 c->ds1no = (channel & 0xff00) >> 8;
3439 c->ds1explicit = (channel & 0x10000) >> 16;
3440 channel &= 0xff;
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;
3449 } else
3450 c->progressmask = 0;
3451 UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_OVERLAP_RECEIVING);
3452 c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING;
3453 c->alive = 1;
3454 if (network) {
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;
3466 if (!c) return;
3467 pri = c->pri;
3468 if (!pri) return;
3469 c->alive = 1;
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");
3473 pri->schedev = 1;
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;
3480 } else {
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");
3503 c->t308_timedout++;
3504 c->alive = 1;
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;
3512 c->alive = 1;
3513 if (pri->debug & PRI_DEBUG_Q931_STATE)
3514 pri_message(pri, "Final time-out looking for release complete\n");
3515 c->t308_timedout++;
3516 c->ourcallstate = Q931_CALL_STATE_NULL;
3517 c->peercallstate = Q931_CALL_STATE_NULL;
3518 pri->schedev = 1;
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");
3535 c->alive = 1;
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;
3542 if (channel) {
3543 c->ds1no = (channel & 0xff00) >> 8;
3544 c->ds1explicit = (channel & 0x10000) >> 16;
3545 channel &= 0xff;
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;
3554 } else
3555 c->progressmask = 0;
3556 if(network || pri->switchtype == PRI_SWITCH_QSIG) {
3557 UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_ACTIVE);
3558 } else {
3559 UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_CONNECT_REQUEST);
3561 c->peercallstate = Q931_CALL_STATE_ACTIVE;
3562 c->alive = 1;
3563 c->con_acked = 0;
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);
3570 if (network) {
3571 /* networks may send datetime */
3572 return send_message(pri, c, Q931_CONNECT, connect_NET_ies);
3573 } else {
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 */
3586 if (c->alive) {
3587 c->alive = 0;
3588 c->cause = cause;
3589 c->causecode = CODE_CCITT;
3590 c->causeloc = LOC_PRIV_NET_LOCAL_USER;
3591 if (c->acked) {
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);
3596 } else {
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);
3602 c->aoc_units = -1;
3603 return send_message(pri, c, Q931_RELEASE, release_aoce_ies);
3604 } else {
3605 return send_message(pri, c, Q931_RELEASE, release_ies);
3607 } else
3608 return send_message(pri, c, Q931_RELEASE_COMPLETE, release_ies); /* Yes, release_ies, not release_complete_ies */
3609 } else
3610 return 0;
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);
3619 if (!c)
3620 return -1;
3621 if (!channel)
3622 return -1;
3623 c->ri = 0;
3624 c->ds1no = (channel & 0xff00) >> 8;
3625 c->ds1explicit = (channel & 0x10000) >> 16;
3626 channel &= 0xff;
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;
3643 if (c->alive) {
3644 c->alive = 0;
3645 c->cause = cause;
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);
3655 c->aoc_units = -1;
3656 return send_message(pri, c, Q931_DISCONNECT, disconnect_aoce_ies);
3657 } else {
3658 return send_message(pri, c, Q931_DISCONNECT, disconnect_ies);
3660 } else
3661 return 0;
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)
3683 int res;
3684 int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
3686 if (pri->localtype == BRI_NETWORK_PTMP) {
3687 c->tei = 127;
3688 } else {
3689 c->tei = 0;
3692 c->transcapability = req->transmode;
3693 c->transmoderate = TRANS_MODE_64_CIRCUIT;
3694 if (!req->userl1)
3695 req->userl1 = PRI_LAYER_1_ULAW;
3696 c->userl1 = req->userl1;
3697 c->userl2 = -1;
3698 c->userl3 = -1;
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) {
3703 req->channel = 0;
3704 req->exclusive = 0;
3707 c->channelno = req->channel;
3708 c->slotmap = -1;
3709 c->nonisdn = req->nonisdn;
3710 c->newcall = 0;
3711 c->justsignalling = req->justsignalling;
3712 c->complete = req->numcomplete;
3713 if (req->exclusive)
3714 c->chanflags = FLAG_EXCLUSIVE;
3715 else if (c->channelno)
3716 c->chanflags = FLAG_PREFERRED;
3717 memcpy(c->llc, req->llc, sizeof(c->llc));
3718 if (req->caller) {
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));
3723 else
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;
3732 } else {
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;
3749 } else {
3750 c->redirectingnum[0] = '\0';
3751 c->redirectingplan = PRI_UNKNOWN;
3752 c->redirectingpres = PRES_NUMBER_NOT_AVAILABLE;
3753 c->redirectingreason = PRI_REDIR_UNKNOWN;
3755 if (req->called) {
3756 libpri_copy_string(c->callednum, req->called, sizeof(c->callednum));
3757 c->calledplan = req->calledplan;
3758 } else
3759 return -1;
3761 if (req->useruserinfo)
3762 libpri_copy_string(c->useruserinfo, req->useruserinfo, sizeof(c->useruserinfo));
3763 else
3764 c->useruserinfo[0] = '\0';
3766 if (req->nonisdn && (pri->switchtype == PRI_SWITCH_NI2))
3767 c->progressmask = PRI_PROG_CALLER_NOT_ISDN;
3768 else
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);
3781 } else {
3782 res = send_message(pri, c, Q931_SETUP, setup_cpe_ies);
3784 if (!res) {
3785 c->alive = 1;
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);
3791 c->t303running = 1;
3793 return res;
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)
3801 int res = 0;
3802 UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_NULL);
3803 c->peercallstate = Q931_CALL_STATE_NULL;
3804 if (cause > -1) {
3805 c->cause = cause;
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;
3809 } else {
3810 c->causeloc = LOC_USER;
3812 /* release_ies has CAUSE in it */
3813 res = send_message(pri, c, Q931_RELEASE_COMPLETE, release_ies);
3814 } else
3815 res = send_message(pri, c, Q931_RELEASE_COMPLETE, release_complete_ies);
3816 c->alive = 0;
3817 /* release the structure */
3818 res += q931_hangup(pri,c,cause);
3819 return res;
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);
3831 } else
3832 return send_message(pri, c, Q931_CONNECT_ACKNOWLEDGE, connect_acknowledge_ies);
3833 return 0;
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;
3840 int tc;
3841 int ttei;
3842 int res=0;
3844 if (!pri || !c)
3845 return -1;
3847 if (pri->localtype != BRI_NETWORK_PTMP){
3848 return 0;
3850 // pri_error(pri, "q921_hangup(%d, %d)\n", c->cr, tei);
3852 if (tei == 127) {
3853 tei = c->tei;
3855 // pri_error(pri, "tei %d\n", tei);
3857 cur = c->phones;
3859 tc = c->cause;
3860 ttei = c->tei;
3861 while (cur) {
3862 if (cur->tei != tei) {
3863 c->cause = PRI_CAUSE_NORMAL_CLEARING;
3864 c->tei = cur->tei;
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);
3869 prev = cur;
3870 cur = cur->next;
3871 if (prev) {
3872 free(prev);
3873 prev = NULL;
3876 c->phones = NULL;
3877 c->tei = ttei;
3878 c->cause = tc;
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; */
3888 return res;
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;
3897 int left=0;
3898 int res=0;
3900 if (!pri || !c)
3901 return -1;
3903 if (pri->localtype != BRI_NETWORK_PTMP){
3904 return 0;
3907 cur = c->phones;
3909 while (cur) {
3910 if (cur->tei == tei) {
3911 match = cur;
3912 if (prev) {
3913 prev->next = cur->next;
3914 cur = prev;
3915 } else {
3916 c->phones = cur->next;
3918 free(match);
3920 prev = cur;
3921 if (cur) cur = cur->next;
3924 cur = c->phones;
3926 while (cur) {
3927 left++;
3928 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)) {
3934 c->t303running = 0;
3935 pri_schedule_del(pri, c->t303timer);
3937 #endif
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;
3950 return res;
3955 int q931_hangup(struct pri *pri, q931_call *c, int cause)
3957 int disconnect = 1;
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));
3961 if (!pri || !c)
3962 return -1;
3963 /* If mandatory IE was missing, insist upon that cause code */
3964 if (c->cause == PRI_CAUSE_MANDATORY_IE_MISSING)
3965 cause = c->cause;
3966 if (cause == 34 || cause == 44 || cause == 82 || cause == 1 || cause == 81 || cause == 17) {
3967 /* We'll send RELEASE_COMPLETE with these causes */
3968 disconnect = 0;
3969 release_compl = 1;
3971 if (cause == 6 || cause == 7 || cause == 26) {
3972 /* We'll send RELEASE with these causes */
3973 disconnect = 0;
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);
3983 break;
3984 case Q931_CALL_STATE_CALL_INITIATED:
3985 /* we sent SETUP */
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:
3995 /* sent ALERTING */
3996 case Q931_CALL_STATE_CONNECT_REQUEST:
3997 /* sent CONNECT */
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) {
4006 break;
4009 if (disconnect)
4010 q931_disconnect(pri,c,cause);
4011 else if (release_compl)
4012 q931_release_complete(pri,c,cause);
4013 else
4014 q931_release(pri,c,cause);
4015 } else
4016 pri_error(pri, "Wierd, doing nothing but this shouldn't happen, ourstate %s, peerstate %s\n",callstate2str(c->ourcallstate),callstate2str(c->peercallstate));
4017 break;
4018 case Q931_CALL_STATE_ACTIVE:
4019 /* received CONNECT */
4020 q931_disconnect(pri,c,cause);
4021 break;
4022 case Q931_CALL_STATE_DISCONNECT_REQUEST:
4023 /* sent DISCONNECT */
4024 q931_release(pri,c,cause);
4025 break;
4026 case Q931_CALL_STATE_DISCONNECT_INDICATION:
4027 /* received DISCONNECT */
4028 if (pri->localtype == BRI_NETWORK_PTMP) {
4029 if (c->tei == 127) {
4030 break;
4033 if (c->peercallstate == Q931_CALL_STATE_DISCONNECT_REQUEST) {
4034 c->alive = 1;
4035 // pri_error(pri, "sending release to %d\n", c->tei);
4036 q931_release(pri,c,cause);
4038 break;
4039 case Q931_CALL_STATE_RELEASE_REQUEST:
4040 /* sent RELEASE */
4041 /* don't do anything, waiting for RELEASE_COMPLETE */
4042 break;
4043 case Q931_CALL_STATE_RESTART:
4044 case Q931_CALL_STATE_RESTART_REQUEST:
4045 /* sent RESTART */
4046 pri_error(pri, "q931_hangup shouldn't be called in this state, ourstate %s, peerstate %s\n",callstate2str(c->ourcallstate),callstate2str(c->peercallstate));
4047 break;
4048 default:
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));
4050 return -1;
4052 /* we did handle hangup properly at this point */
4053 return 0;
4056 int q931_receive(struct pri *pri, q931_h *h, int len, int tei)
4058 q931_mh *mh;
4059 q921_call *l2c;
4060 q931_call *c;
4061 q931_ie *ie;
4062 unsigned int x;
4063 int y;
4064 int res;
4065 int r;
4066 int mandies[MAX_MAND_IES];
4067 int missingmand;
4068 int codeset, cur_codeset;
4069 int last_ie[8];
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++;
4078 #endif
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);
4086 return 0;
4087 } else if (h->pd != pri->protodisc) {
4088 pri_error(pri, "Warning: unknown/inappropriate protocol discriminator received (%02x/%d)\n", h->pd, h->pd);
4089 return 0;
4091 c = q931_getcall(pri, q931_cr(h), tei);
4092 if (!c) {
4093 pri_error(pri, "Unable to locate call %d\n", q931_cr(h));
4094 return -1;
4096 /* Preliminary handling */
4097 switch(mh->msg) {
4098 case Q931_RESTART:
4099 if (pri->debug & PRI_DEBUG_Q931_STATE)
4100 pri_message(pri, "-- Processing Q.931 Restart\n");
4101 /* Reset information */
4102 c->channelno = -1;
4103 c->slotmap = -1;
4104 c->chanflags = 0;
4105 c->ds1no = 0;
4106 c->ri = -1;
4107 break;
4108 case Q931_FACILITY:
4109 c->callername[0] = '\0';
4110 break;
4111 case Q931_SETUP:
4112 if (pri->debug & PRI_DEBUG_Q931_STATE)
4113 pri_message(pri, "-- Processing Q.931 Call Setup\n");
4114 c->tei = tei;
4115 c->channelno = -1;
4116 c->slotmap = -1;
4117 c->chanflags = 0;
4118 c->ds1no = 0;
4119 c->ri = -1;
4120 c->transcapability = -1;
4121 c->transmoderate = -1;
4122 c->transmultiple = -1;
4123 c->userl1 = -1;
4124 c->userl2 = -1;
4125 c->userl3 = -1;
4126 c->rateadaption = -1;
4127 c->calledplan = -1;
4128 c->callerplan = -1;
4129 c->callerpres = -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';
4147 c->complete = 0;
4148 c->nonisdn = 0;
4149 c->aoc_units = -1;
4150 c->digits[0] = '\0';
4151 c->display[0] = '\0';
4152 c->progress = -1;
4153 c->progressmask = 0;
4154 /* Fall through */
4155 case Q931_ALERTING:
4156 case Q931_PROGRESS:
4157 if (c->t303timer) {
4158 c->t303running = 0;
4159 pri_schedule_del(pri, c->t303timer);
4161 c->useruserinfo[0] = '\0';
4162 c->cause = -1;
4163 c->progress = -1;
4164 c->progressmask = 0;
4165 break;
4166 case Q931_CALL_PROCEEDING:
4167 /* Fall through */
4168 case Q931_CONNECT:
4169 if (c->t303timer) {
4170 c->t303running = 0;
4171 pri_schedule_del(pri, c->t303timer);
4173 c->useruserinfo[0] = '\0';
4174 c->t303timer = 0;
4175 c->progress = -1;
4176 c->progressmask = 0;
4177 break;
4178 case Q931_CONNECT_ACKNOWLEDGE:
4179 if (c->retranstimer)
4180 pri_schedule_del(pri, c->retranstimer);
4181 c->retranstimer = 0;
4182 break;
4183 case Q931_RELEASE:
4184 case Q931_DISCONNECT:
4185 c->cause = -1;
4186 c->causecode = -1;
4187 c->causeloc = -1;
4188 c->aoc_units = -1;
4189 if (c->retranstimer)
4190 pri_schedule_del(pri, c->retranstimer);
4191 c->retranstimer = 0;
4192 c->useruserinfo[0] = '\0';
4193 if (c->t303timer) {
4194 c->t303running = 0;
4195 pri_schedule_del(pri, c->t303timer);
4197 c->t303timer = 0;
4198 break;
4199 case Q931_RELEASE_COMPLETE:
4200 if (c->retranstimer)
4201 pri_schedule_del(pri, c->retranstimer);
4202 c->retranstimer = 0;
4203 if (c->t303timer) {
4204 c->t303running = 0;
4205 pri_schedule_del(pri, c->t303timer);
4207 c->useruserinfo[0] = '\0';
4208 /* Fall through */
4209 case Q931_STATUS:
4210 c->cause = -1;
4211 c->causecode = -1;
4212 c->causeloc = -1;
4213 c->sugcallstate = -1;
4214 c->aoc_units = -1;
4215 break;
4216 case Q931_RESTART_ACKNOWLEDGE:
4217 c->channelno = -1;
4218 break;
4219 case Q931_INFORMATION:
4220 c->callednum[0] = '\0';
4221 break;
4222 case Q931_STATUS_ENQUIRY:
4223 break;
4224 case Q931_SETUP_ACKNOWLEDGE:
4225 if (c->t303timer) {
4226 c->t303running = 0;
4227 pri_schedule_del(pri, c->t303timer);
4229 c->t303timer = 0;
4230 break;
4231 case Q931_NOTIFY:
4232 break;
4233 case Q931_HOLD:
4234 break;
4235 case Q931_RETRIEVE:
4236 break;
4237 case Q931_RESUME:
4238 c->tei = tei;
4239 break;
4240 case Q931_SUSPEND:
4241 break;
4242 case Q931_USER_INFORMATION:
4243 case Q931_SEGMENT:
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);
4254 /* Fall through */
4255 default:
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);
4258 if (c->newcall)
4259 q931_destroycall(pri,c->cr,c->tei);
4260 return -1;
4262 /* Handle IEs */
4263 memset(mandies, 0, sizeof(mandies));
4264 missingmand = 0;
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));
4270 x = 0;
4271 /* Do real IE processing */
4272 len -= (h->crlen + 3);
4273 codeset = cur_codeset = 0;
4274 while(len) {
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))
4278 mandies[y] = 0;
4280 r = ielen(ie);
4281 if (r > len) {
4282 pri_error(pri, "XXX Message longer than it should be?? XXX\n");
4283 return -1;
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);
4292 if (y > 0) {
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;
4297 else {
4298 /* Locking shift to codeset 0 is forbidden by all specifications */
4299 pri_error(pri, "!! Invalid locking shift to codeset 0 !!\n");
4301 break;
4302 case Q931_NON_LOCKING_SHIFT:
4303 cur_codeset = ie->ie & 7;
4304 break;
4305 default:
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]);
4312 else
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);
4322 break;
4324 /* Fall through */
4325 default:
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;
4334 x += r;
4335 len -= r;
4337 missingmand = 0;
4338 for (x=0;x<MAX_MAND_IES;x++) {
4339 if (mandies[x]) {
4340 /* check if there is no channel identification when we're configured as network -> that's not an error */
4341 if (network) {
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? ;-) */
4345 } else {
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]));
4347 missingmand++;
4349 } else {
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]));
4351 missingmand++;
4356 /* Post handling */
4357 switch(mh->msg) {
4358 case Q931_RESTART:
4359 if (missingmand) {
4360 q931_status(pri, c, PRI_CAUSE_MANDATORY_IE_MISSING);
4361 q931_destroycall(pri, c->cr, c->tei);
4362 break;
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;
4372 case Q931_SETUP:
4373 if (missingmand) {
4374 q931_release_complete(pri, c, PRI_CAUSE_MANDATORY_IE_MISSING);
4375 break;
4377 /* Must be new call */
4378 if (!c->newcall) {
4379 pri_error(pri, "received SETUP message for call that is not a new call (retransmission). \n");
4380 break;
4382 if (c->progressmask & PRI_PROG_CALLER_NOT_ISDN)
4383 c->nonisdn = 1;
4384 c->newcall = 0;
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 */
4388 c->alive = 0;
4389 if (c->transmoderate != TRANS_MODE_64_CIRCUIT) {
4390 q931_release_complete(pri, c, PRI_CAUSE_BEARERCAPABILITY_NOTIMPL);
4391 break;
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));
4408 } else {
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;
4431 case Q931_ALERTING:
4432 if (c->newcall) {
4433 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4434 break;
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';
4450 cur = c->apdus;
4451 while (cur) {
4452 if (!cur->sent && cur->message == Q931_FACILITY) {
4453 q931_facility(pri, c);
4454 break;
4456 cur = cur->next;
4459 return Q931_RES_HAVEEVENT;
4460 case Q931_CONNECT:
4461 if (c->newcall) {
4462 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4463 break;
4465 if (c->ourcallstate == Q931_CALL_STATE_ACTIVE) {
4466 q931_status(pri, c, PRI_CAUSE_WRONG_MESSAGE);
4467 break;
4469 /* TEI got the call */
4470 c->tei = tei;
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);
4489 break;
4490 } else
4491 return Q931_RES_HAVEEVENT;
4492 case Q931_FACILITY:
4493 if (c->newcall) {
4494 if ((pri->localtype == PRI_CPE) || (pri->localtype == PRI_NETWORK)) {
4495 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4496 } else {
4497 // BRI uses the dummy cref for sservices like ccnr
4499 break;
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;
4510 break;
4511 case 0x0D: /* CD */
4512 pri->ev.facility.operation = 0x0D;
4513 libpri_copy_string(pri->ev.facility.forwardnum, c->redirectingnum, sizeof(pri->ev.facility.forwardnum));
4514 break;
4515 default:
4516 pri->ev.facility.operation = c->facility;
4518 } else {
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;
4527 case Q931_PROGRESS:
4528 if (missingmand) {
4529 q931_status(pri, c, PRI_CAUSE_MANDATORY_IE_MISSING);
4530 q931_destroycall(pri, c->cr, c->tei);
4531 break;
4533 pri->ev.e = PRI_EVENT_PROGRESS;
4534 pri->ev.proceeding.cause = c->cause;
4535 /* Fall through */
4536 case Q931_CALL_PROCEEDING:
4537 if (c->newcall) {
4538 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4539 break;
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);
4546 break;
4548 if (pri->localtype == BRI_NETWORK_PTMP) {
4549 l2c = q921_getcall(pri, c, tei);
4550 l2c->proc = 1;
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;
4564 cur = c->apdus;
4565 while (cur) {
4566 if (!cur->sent && cur->message == Q931_FACILITY) {
4567 q931_facility(pri, c);
4568 break;
4570 cur = cur->next;
4572 return Q931_RES_HAVEEVENT;
4573 case Q931_CONNECT_ACKNOWLEDGE:
4574 if (c->newcall) {
4575 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4576 break;
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);
4582 break;
4584 UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_ACTIVE);
4585 c->peercallstate = Q931_CALL_STATE_ACTIVE;
4586 c->con_acked = 1;
4587 break;
4588 case Q931_STATUS:
4589 if (missingmand) {
4590 q931_status(pri, c, PRI_CAUSE_MANDATORY_IE_MISSING);
4591 q931_destroycall(pri, c->cr, c->tei);
4592 break;
4594 if (c->newcall) {
4595 if (c->cr & 0x7fff)
4596 q931_release_complete(pri,c,PRI_CAUSE_WRONG_CALL_STATE);
4597 break;
4599 /* Do nothing */
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;
4615 if (c->alive) {
4616 pri->ev.e = PRI_EVENT_HANGUP;
4617 res = Q931_RES_HAVEEVENT;
4618 c->alive = 0;
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);
4623 } else {
4624 q931_hangup(pri, c, c->cause);
4625 res = 0;
4627 if (res)
4628 return res;
4630 break;
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 */
4634 if (c->t303timer) {
4635 c->t303running = 0;
4636 pri_schedule_del(pri, c->t303timer);
4637 c->t303timer = 0;
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 */
4651 if (c->alive) {
4652 pri->ev.e = PRI_EVENT_HANGUP;
4653 res = Q931_RES_HAVEEVENT;
4654 c->alive = 0;
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);
4659 } else
4660 res = 0;
4661 if (res)
4662 return res;
4663 else
4664 q931_hangup(pri,c,c->cause);
4665 } else {
4666 /* BRI_NET_PTMP
4667 ignoring relase_complete */
4668 res = q921_handle_hangup(pri,c,tei);
4669 if (res)
4670 return res;
4672 break;
4673 case Q931_RELEASE:
4674 if (missingmand) {
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;
4680 else {
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 */
4695 if (c->newcall)
4696 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4697 else
4698 return Q931_RES_HAVEEVENT;
4699 break;
4700 case Q931_DISCONNECT:
4701 if (missingmand) {
4702 /* Still let user call release */
4703 c->cause = PRI_CAUSE_MANDATORY_IE_MISSING;
4705 if (c->newcall) {
4706 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4707 break;
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))
4716 break;
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;
4728 } else {
4729 pri->ev.hangup.inband_progress = 0;
4731 pri->ev.hangup.aoc_units = c->aoc_units;
4732 if (c->alive)
4733 return Q931_RES_HAVEEVENT;
4734 else
4735 q931_hangup(pri,c,c->cause);
4736 break;
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
4747 XXX */
4748 if (c->newcall) {
4749 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4750 break;
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:
4769 if (c->newcall) {
4770 q931_release_complete(pri, c, PRI_CAUSE_INVALID_CALL_REFERENCE);
4771 } else
4772 q931_status(pri,c, 0);
4773 break;
4774 case Q931_SETUP_ACKNOWLEDGE:
4775 if (c->newcall) {
4776 q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
4777 break;
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;
4784 cur = c->apdus;
4785 while (cur) {
4786 if (!cur->sent && cur->message == Q931_FACILITY) {
4787 q931_facility(pri, c);
4788 break;
4790 cur = cur->next;
4793 return Q931_RES_HAVEEVENT;
4794 case Q931_NOTIFY:
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;
4799 case Q931_HOLD:
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;
4806 break;
4807 case Q931_RETRIEVE:
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;
4814 break;
4815 case Q931_SUSPEND:
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;
4823 break;
4824 case Q931_RESUME:
4825 if (pri->localtype == BRI_NETWORK_PTMP) {
4826 l2c = q921_getcall(pri, c, tei);
4828 c->newcall = 0;
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;
4836 break;
4837 case Q931_USER_INFORMATION:
4838 case Q931_SEGMENT:
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);
4849 /* Fall through */
4850 default:
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);
4854 if (c->newcall)
4855 q931_destroycall(pri,c->cr,c->tei);
4856 return -1;
4858 return 0;
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;
4866 int res;
4868 if (c->retranstimer)
4869 pri_schedule_del(pri, c->retranstimer);
4870 c->retranstimer = 0;
4871 c->useruserinfo[0] = '\0';
4872 c->cause = -1;
4873 c->causecode = -1;
4874 c->causeloc = -1;
4875 c->sugcallstate = -1;
4876 c->aoc_units = -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 */
4888 if (c->alive) {
4889 pri->ev.e = PRI_EVENT_HANGUP;
4890 res = Q931_RES_HAVEEVENT;
4891 c->alive = 0;
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);
4896 } else {
4897 res = 0;
4898 q931_hangup(pri, c, c->cause);
4901 return res;
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)
4914 pri->schedev = 1;
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)
4927 pri->schedev = 1;
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)
4937 return;
4939 switch (event) {
4940 case PRI_EVENT_DCHAN_DOWN:
4941 pri_message(pri, DBGHEAD "link is DOWN\n", DBGINFO);
4942 cur = *pri->callpool;
4943 while(cur) {
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);
4958 cur = cur->next;
4960 break;
4961 case PRI_EVENT_DCHAN_UP:
4962 pri_message(pri, DBGHEAD "link is UP\n", DBGINFO);
4963 cur = *pri->callpool;
4964 while(cur) {
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);
4978 cur = cur->next;
4980 break;
4981 default:
4982 pri_message(pri, DBGHEAD "unexpected event %d.\n", DBGINFO, event);
4986 int q931_call_getcrv(struct pri *pri, q931_call *call, int *callmode)
4988 if (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);
4997 return 0;