1 /*
2 * libpri: An implementation of Primary Rate ISDN
3 *
4 * Copyright (C) 2009 Digium, Inc.
5 *
6 * Richard Mudgett <rmudgett@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2 as published by the
16 * Free Software Foundation. See the LICENSE file included with
17 * this program for more details.
18 *
19 * In addition, when this program is distributed with Asterisk in
20 * any form that would qualify as a 'combined work' or as a
21 * 'derivative work' (but not mere aggregation), you can redistribute
22 * and/or modify the combination under the terms of the license
23 * provided with that copy of Asterisk, instead of the license
24 * terms granted here.
25 */
26
27 /*!
28 * \file
29 * \brief Call Completion controller
30 *
31 * \author Richard Mudgett <rmudgett@digium.com>
32 */
33
34
35 #include "compat.h"
36 #include "libpri.h"
37 #include "pri_internal.h"
38 #include "pri_facility.h"
39
40 #include <stdlib.h>
41
42 /* Define CC_SANITY_CHECKS to add some consistency sanity checking. */
43 //#define CC_SANITY_CHECKS 1
44 #define CC_SANITY_CHECKS 1// BUGBUG
45
46 /*! Maximum times CCBSStatusRequest can have no response before canceling CC. */
47 #define RAW_STATUS_COUNT_MAX 3
48
49 /* ------------------------------------------------------------------- */
50
51 /*!
52 * \brief Find a cc_record by the PTMP reference_id.
53 *
54 * \param ctrl D channel controller.
55 * \param reference_id CCBS reference ID to look for in cc_record pool.
56 *
57 * \retval cc_record on success.
58 * \retval NULL on error.
59 */
pri_cc_find_by_reference(struct pri * ctrl,unsigned reference_id)60 struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned reference_id)
61 {
62 struct pri_cc_record *cc_record;
63
64 for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
65 if (cc_record->ccbs_reference_id == reference_id) {
66 /* Found the record */
67 break;
68 }
69 }
70
71 return cc_record;
72 }
73
74 /*!
75 * \brief Find a cc_record by the PTMP linkage_id.
76 *
77 * \param ctrl D channel controller.
78 * \param linkage_id Call linkage ID to look for in cc_record pool.
79 *
80 * \retval cc_record on success.
81 * \retval NULL on error.
82 */
pri_cc_find_by_linkage(struct pri * ctrl,unsigned linkage_id)83 struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_id)
84 {
85 struct pri_cc_record *cc_record;
86
87 for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
88 if (cc_record->call_linkage_id == linkage_id) {
89 /* Found the record */
90 break;
91 }
92 }
93
94 return cc_record;
95 }
96
97 /*!
98 * \internal
99 * \brief Find a cc_record by the cc_id.
100 *
101 * \param ctrl D channel controller.
102 * \param cc_id ID to look for in cc_record pool.
103 *
104 * \retval cc_record on success.
105 * \retval NULL on error.
106 */
pri_cc_find_by_id(struct pri * ctrl,long cc_id)107 static struct pri_cc_record *pri_cc_find_by_id(struct pri *ctrl, long cc_id)
108 {
109 struct pri_cc_record *cc_record;
110
111 for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
112 if (cc_record->record_id == cc_id) {
113 /* Found the record */
114 break;
115 }
116 }
117
118 return cc_record;
119 }
120
121 /*!
122 * \internal
123 * \brief Find the given ie_type in the string of q931 ies.
124 *
125 * \param ie_type Q.931 ie type to find in q931_ies.
126 * \param length Length of the given q931_ies
127 * \param q931_ies Given q931_ies
128 *
129 * \retval found-ie on success.
130 * \retval NULL on error.
131 */
pri_cc_find_ie(unsigned ie_type,unsigned length,const unsigned char * q931_ies)132 static const struct q931_ie *pri_cc_find_ie(unsigned ie_type, unsigned length, const unsigned char *q931_ies)
133 {
134 const unsigned char *pos;
135 const unsigned char *end;
136 const unsigned char *next;
137 const struct q931_ie *cur;
138
139 end = q931_ies + length;
140 for (pos = q931_ies; pos < end; pos = next) {
141 cur = (const struct q931_ie *) pos;
142 if (cur->ie & 0x80) {
143 /* Single octet ie. */
144 next = pos + 1;
145 } else {
146 /* Variable length ie. */
147 next = cur->data + cur->len;
148 }
149 if (cur->ie == ie_type && next <= end) {
150 /* Found the ie and it is within the given q931_ies body. */
151 return cur;
152 }
153 }
154 return NULL;
155 }
156
157 /*!
158 * \internal
159 * \brief Compare the specified ie type in the CC record q931_ies to the given q931_ies.
160 *
161 * \details
162 * The individual q931 ie is compared with memcmp().
163 *
164 * \param ie_type Q.931 ie type to compare.
165 * \param record_ies CC record q931_ies
166 * \param length Length of the given q931_ies
167 * \param q931_ies Given q931_ies
168 *
169 * \retval == 0 when record_ies == q931_ies.
170 * \retval != 0 when record_ies != q931_ies.
171 */
pri_cc_cmp_ie(unsigned ie_type,const struct q931_saved_ie_contents * record_ies,unsigned length,const unsigned char * q931_ies)172 static int pri_cc_cmp_ie(unsigned ie_type, const struct q931_saved_ie_contents *record_ies, unsigned length, const unsigned char *q931_ies)
173 {
174 const struct q931_ie *left;
175 const struct q931_ie *right;
176
177 left = pri_cc_find_ie(ie_type, record_ies->length, record_ies->data);
178 right = pri_cc_find_ie(ie_type, length, q931_ies);
179
180 if (!left && !right) {
181 /* Neither has the requested ie to compare so they match. */
182 return 0;
183 }
184 if (!left || !right) {
185 /* One or the other does not have the requested ie to compare. */
186 return 1;
187 }
188 if (left->len != right->len) {
189 /* They are not the same length. */
190 return 1;
191 }
192 return memcmp(left->data, right->data, right->len);
193 }
194
195 /*!
196 * \internal
197 * \brief Compare the CC record q931_ies to the given q931_ies.
198 *
199 * \note
200 * Only the first BC, HLC, and LLC ies in the given q931_ies are compared.
201 *
202 * \param record_ies CC record q931_ies
203 * \param length Length of the given q931_ies
204 * \param q931_ies Given q931_ies
205 *
206 * \retval == 0 when record_ies == q931_ies.
207 * \retval != 0 when record_ies != q931_ies.
208 */
pri_cc_cmp_q931_ies(const struct q931_saved_ie_contents * record_ies,unsigned length,const unsigned char * q931_ies)209 static int pri_cc_cmp_q931_ies(const struct q931_saved_ie_contents *record_ies, unsigned length, const unsigned char *q931_ies)
210 {
211 return pri_cc_cmp_ie(Q931_BEARER_CAPABILITY, record_ies, length, q931_ies)
212 || pri_cc_cmp_ie(Q931_HIGH_LAYER_COMPAT, record_ies, length, q931_ies)
213 || pri_cc_cmp_ie(Q931_LOW_LAYER_COMPAT, record_ies, length, q931_ies);
214 }
215
216 /*!
217 * \brief Find a cc_record by an incoming call addressing data.
218 *
219 * \param ctrl D channel controller.
220 * \param party_a Party A address.
221 * \param party_b Party B address.
222 * \param length Length of the given q931_ies.
223 * \param q931_ies BC, HLC, LLC ies to compare with CC records.
224 *
225 * \retval cc_record on success.
226 * \retval NULL on error.
227 */
pri_cc_find_by_addressing(struct pri * ctrl,const struct q931_party_address * party_a,const struct q931_party_address * party_b,unsigned length,const unsigned char * q931_ies)228 struct pri_cc_record *pri_cc_find_by_addressing(struct pri *ctrl, const struct q931_party_address *party_a, const struct q931_party_address *party_b, unsigned length, const unsigned char *q931_ies)
229 {
230 struct pri_cc_record *cc_record;
231 struct q931_party_address addr_a;
232 struct q931_party_address addr_b;
233
234 addr_a = *party_a;
235 addr_b = *party_b;
236 for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
237 /* Do not compare the number presentation. */
238 addr_a.number.presentation = cc_record->party_a.number.presentation;
239 addr_b.number.presentation = cc_record->party_b.number.presentation;
240 if (!q931_cmp_party_id_to_address(&cc_record->party_a, &addr_a)
241 && !q931_party_address_cmp(&cc_record->party_b, &addr_b)
242 && !pri_cc_cmp_q931_ies(&cc_record->saved_ie_contents, length, q931_ies)) {
243 /* Found the record */
244 break;
245 }
246 }
247
248 return cc_record;
249 }
250
251 /*!
252 * \internal
253 * \brief Allocate a new cc_record reference id.
254 *
255 * \param ctrl D channel controller.
256 *
257 * \retval reference_id on success.
258 * \retval CC_PTMP_INVALID_ID on error.
259 */
pri_cc_new_reference_id(struct pri * ctrl)260 static int pri_cc_new_reference_id(struct pri *ctrl)
261 {
262 long reference_id;
263 long first_id;
264
265 ctrl->cc.last_reference_id = (ctrl->cc.last_reference_id + 1) & 0x7F;
266 reference_id = ctrl->cc.last_reference_id;
267 first_id = reference_id;
268 while (pri_cc_find_by_reference(ctrl, reference_id)) {
269 ctrl->cc.last_reference_id = (ctrl->cc.last_reference_id + 1) & 0x7F;
270 reference_id = ctrl->cc.last_reference_id;
271 if (reference_id == first_id) {
272 /* We probably have a resource leak. */
273 pri_error(ctrl, "PTMP call completion reference id exhaustion!\n");
274 reference_id = CC_PTMP_INVALID_ID;
275 break;
276 }
277 }
278
279 return reference_id;
280 }
281
282 /*!
283 * \internal
284 * \brief Allocate a new cc_record linkage id.
285 *
286 * \param ctrl D channel controller.
287 *
288 * \retval linkage_id on success.
289 * \retval CC_PTMP_INVALID_ID on error.
290 */
pri_cc_new_linkage_id(struct pri * ctrl)291 static int pri_cc_new_linkage_id(struct pri *ctrl)
292 {
293 long linkage_id;
294 long first_id;
295
296 ctrl->cc.last_linkage_id = (ctrl->cc.last_linkage_id + 1) & 0x7F;
297 linkage_id = ctrl->cc.last_linkage_id;
298 first_id = linkage_id;
299 while (pri_cc_find_by_linkage(ctrl, linkage_id)) {
300 ctrl->cc.last_linkage_id = (ctrl->cc.last_linkage_id + 1) & 0x7F;
301 linkage_id = ctrl->cc.last_linkage_id;
302 if (linkage_id == first_id) {
303 /* We probably have a resource leak. */
304 pri_error(ctrl, "PTMP call completion linkage id exhaustion!\n");
305 linkage_id = CC_PTMP_INVALID_ID;
306 break;
307 }
308 }
309
310 return linkage_id;
311 }
312
313 /*!
314 * \internal
315 * \brief Allocate a new cc_record id.
316 *
317 * \param ctrl D channel controller.
318 *
319 * \retval cc_id on success.
320 * \retval -1 on error.
321 */
pri_cc_new_id(struct pri * ctrl)322 static long pri_cc_new_id(struct pri *ctrl)
323 {
324 long record_id;
325 long first_id;
326
327 record_id = ++ctrl->cc.last_record_id;
328 first_id = record_id;
329 while (pri_cc_find_by_id(ctrl, record_id)) {
330 record_id = ++ctrl->cc.last_record_id;
331 if (record_id == first_id) {
332 /*
333 * We have a resource leak.
334 * We should never need to allocate 64k records on a D channel.
335 */
336 pri_error(ctrl, "Too many call completion records!\n");
337 record_id = -1;
338 break;
339 }
340 }
341
342 return record_id;
343 }
344
345 /*!
346 * \internal
347 * \brief Disassociate the signaling link call from the cc_record.
348 *
349 * \param cc_record CC record to disassociate from the signaling link call.
350 *
351 * \return Nothing
352 */
pri_cc_disassociate_signaling_link(struct pri_cc_record * cc_record)353 static void pri_cc_disassociate_signaling_link(struct pri_cc_record *cc_record)
354 {
355 if (cc_record->signaling) {
356 cc_record->signaling->cc.record = NULL;
357 cc_record->signaling = NULL;
358 }
359 }
360
361 /*!
362 * \internal
363 * \brief Delete the given call completion record
364 *
365 * \param ctrl D channel controller.
366 * \param doomed Call completion record to destroy
367 *
368 * \return Nothing
369 */
pri_cc_delete_record(struct pri * ctrl,struct pri_cc_record * doomed)370 static void pri_cc_delete_record(struct pri *ctrl, struct pri_cc_record *doomed)
371 {
372 struct pri_cc_record **prev;
373 struct pri_cc_record *current;
374
375 /* Unlink CC signaling link associations. */
376 if (doomed->original_call) {
377 doomed->original_call->cc.record = NULL;
378 doomed->original_call = NULL;
379 }
380 pri_cc_disassociate_signaling_link(doomed);
381
382 for (prev = &ctrl->cc.pool, current = ctrl->cc.pool; current;
383 prev = ¤t->next, current = current->next) {
384 if (current == doomed) {
385 *prev = current->next;
386 free(doomed);
387 return;
388 }
389 }
390
391 /* The doomed node is not in the call completion database */
392 }
393
394 /*!
395 * \brief Allocate a new cc_record.
396 *
397 * \param ctrl D channel controller.
398 * \param call Q.931 call leg.
399 *
400 * \retval pointer to new call completion record
401 * \retval NULL if failed
402 */
pri_cc_new_record(struct pri * ctrl,q931_call * call)403 struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call)
404 {
405 struct pri_cc_record *cc_record;
406 long record_id;
407
408 record_id = pri_cc_new_id(ctrl);
409 if (record_id < 0) {
410 return NULL;
411 }
412 cc_record = calloc(1, sizeof(*cc_record));
413 if (!cc_record) {
414 return NULL;
415 }
416
417 /* Initialize the new record */
418 cc_record->ctrl = ctrl;
419 cc_record->record_id = record_id;
420 cc_record->call_linkage_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
421 cc_record->ccbs_reference_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
422 cc_record->party_a = call->cc.party_a;
423 cc_record->party_b = call->called;
424 cc_record->saved_ie_contents = call->cc.saved_ie_contents;
425 cc_record->bc = call->bc;
426 cc_record->option.recall_mode = ctrl->cc.option.recall_mode;
427
428 /*
429 * Append the new record to the end of the list so they are in
430 * cronological order for interrogations.
431 */
432 if (ctrl->cc.pool) {
433 struct pri_cc_record *cur;
434
435 for (cur = ctrl->cc.pool; cur->next; cur = cur->next) {
436 }
437 cur->next = cc_record;
438 } else {
439 ctrl->cc.pool = cc_record;
440 }
441
442 return cc_record;
443 }
444
445 /*!
446 * \internal
447 * \brief Encode ETSI PTP call completion event operation message.
448 *
449 * \param ctrl D channel controller for diagnostic messages or global options.
450 * \param pos Starting position to encode the facility ie contents.
451 * \param end End of facility ie contents encoding data buffer.
452 * \param operation PTP call completion event operation to encode.
453 *
454 * \retval Start of the next ASN.1 component to encode on success.
455 * \retval NULL on error.
456 */
enc_etsi_ptp_cc_operation(struct pri * ctrl,unsigned char * pos,unsigned char * end,enum rose_operation operation)457 static unsigned char *enc_etsi_ptp_cc_operation(struct pri *ctrl, unsigned char *pos,
458 unsigned char *end, enum rose_operation operation)
459 {
460 struct rose_msg_invoke msg;
461
462 pos = facility_encode_header(ctrl, pos, end, NULL);
463 if (!pos) {
464 return NULL;
465 }
466
467 memset(&msg, 0, sizeof(msg));
468 msg.invoke_id = get_invokeid(ctrl);
469 msg.operation = operation;
470
471 pos = rose_encode_invoke(ctrl, pos, end, &msg);
472
473 return pos;
474 }
475
476 /*!
477 * \internal
478 * \brief Encode ETSI PTMP call completion available message.
479 *
480 * \param ctrl D channel controller for diagnostic messages or global options.
481 * \param pos Starting position to encode the facility ie contents.
482 * \param end End of facility ie contents encoding data buffer.
483 * \param cc_record Call completion record to process event.
484 *
485 * \retval Start of the next ASN.1 component to encode on success.
486 * \retval NULL on error.
487 */
enc_etsi_ptmp_cc_available(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)488 static unsigned char *enc_etsi_ptmp_cc_available(struct pri *ctrl, unsigned char *pos,
489 unsigned char *end, struct pri_cc_record *cc_record)
490 {
491 struct rose_msg_invoke msg;
492
493 pos = facility_encode_header(ctrl, pos, end, NULL);
494 if (!pos) {
495 return NULL;
496 }
497
498 memset(&msg, 0, sizeof(msg));
499 msg.invoke_id = get_invokeid(ctrl);
500 msg.operation = ROSE_ETSI_CallInfoRetain;
501
502 msg.args.etsi.CallInfoRetain.call_linkage_id = cc_record->call_linkage_id;
503
504 pos = rose_encode_invoke(ctrl, pos, end, &msg);
505
506 return pos;
507 }
508
509 /*!
510 * \internal
511 * \brief Encode and queue a cc-available message.
512 *
513 * \param ctrl D channel controller for diagnostic messages or global options.
514 * \param call Call leg from which to encode call completion available.
515 * \param cc_record Call completion record to process event.
516 * \param msgtype Q.931 message type to put facility ie in.
517 *
518 * \retval 0 on success.
519 * \retval -1 on error.
520 */
rose_cc_available_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,int msgtype)521 static int rose_cc_available_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, int msgtype)
522 {
523 unsigned char buffer[256];
524 unsigned char *end;
525
526 switch (ctrl->switchtype) {
527 case PRI_SWITCH_EUROISDN_E1:
528 case PRI_SWITCH_EUROISDN_T1:
529 if (PTMP_MODE(ctrl)) {
530 end =
531 enc_etsi_ptmp_cc_available(ctrl, buffer, buffer + sizeof(buffer),
532 cc_record);
533 } else {
534 end =
535 enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer),
536 ROSE_ETSI_CCBS_T_Available);
537 }
538 break;
539 case PRI_SWITCH_QSIG:
540 /* Q.SIG does not have a cc-available type message. */
541 return 0;
542 default:
543 return -1;
544 }
545 if (!end) {
546 return -1;
547 }
548
549 return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
550 }
551
552 /*!
553 * \internal
554 * \brief Encode ETSI PTMP EraseCallLinkageID message.
555 *
556 * \param ctrl D channel controller for diagnostic messages or global options.
557 * \param pos Starting position to encode the facility ie contents.
558 * \param end End of facility ie contents encoding data buffer.
559 * \param cc_record Call completion record to process event.
560 *
561 * \retval Start of the next ASN.1 component to encode on success.
562 * \retval NULL on error.
563 */
enc_etsi_ptmp_erase_call_linkage(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)564 static unsigned char *enc_etsi_ptmp_erase_call_linkage(struct pri *ctrl,
565 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
566 {
567 struct rose_msg_invoke msg;
568
569 pos = facility_encode_header(ctrl, pos, end, NULL);
570 if (!pos) {
571 return NULL;
572 }
573
574 memset(&msg, 0, sizeof(msg));
575 msg.invoke_id = get_invokeid(ctrl);
576 msg.operation = ROSE_ETSI_EraseCallLinkageID;
577
578 msg.args.etsi.EraseCallLinkageID.call_linkage_id = cc_record->call_linkage_id;
579
580 pos = rose_encode_invoke(ctrl, pos, end, &msg);
581
582 return pos;
583 }
584
585 /*!
586 * \internal
587 * \brief Encode and queue an EraseCallLinkageID message.
588 *
589 * \param ctrl D channel controller for diagnostic messages or global options.
590 * \param call Call leg from which to encode EraseCallLinkageID.
591 * \param cc_record Call completion record to process event.
592 *
593 * \retval 0 on success.
594 * \retval -1 on error.
595 */
rose_erase_call_linkage_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)596 static int rose_erase_call_linkage_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
597 {
598 unsigned char buffer[256];
599 unsigned char *end;
600
601 end =
602 enc_etsi_ptmp_erase_call_linkage(ctrl, buffer, buffer + sizeof(buffer),
603 cc_record);
604 if (!end) {
605 return -1;
606 }
607
608 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
609 }
610
611 /*!
612 * \internal
613 * \brief Encode and send an EraseCallLinkageID message.
614 *
615 * \param ctrl D channel controller for diagnostic messages or global options.
616 * \param call Call leg from which to encode EraseCallLinkageID.
617 * \param cc_record Call completion record to process event.
618 *
619 * \retval 0 on success.
620 * \retval -1 on error.
621 */
send_erase_call_linkage_id(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)622 static int send_erase_call_linkage_id(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
623 {
624 if (rose_erase_call_linkage_encode(ctrl, call, cc_record)
625 || q931_facility(ctrl, call)) {
626 pri_message(ctrl,
627 "Could not schedule facility message for EraseCallLinkageID.\n");
628 return -1;
629 }
630
631 return 0;
632 }
633
634 /*!
635 * \internal
636 * \brief Encode ETSI PTMP CCBSErase message.
637 *
638 * \param ctrl D channel controller for diagnostic messages or global options.
639 * \param pos Starting position to encode the facility ie contents.
640 * \param end End of facility ie contents encoding data buffer.
641 * \param cc_record Call completion record to process event.
642 * \param reason CCBS Erase reason
643 * normal-unspecified(0), t-CCBS2-timeout(1), t-CCBS3-timeout(2), basic-call-failed(3)
644 *
645 * \retval Start of the next ASN.1 component to encode on success.
646 * \retval NULL on error.
647 */
enc_etsi_ptmp_ccbs_erase(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record,int reason)648 static unsigned char *enc_etsi_ptmp_ccbs_erase(struct pri *ctrl,
649 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record, int reason)
650 {
651 struct rose_msg_invoke msg;
652
653 pos = facility_encode_header(ctrl, pos, end, NULL);
654 if (!pos) {
655 return NULL;
656 }
657
658 memset(&msg, 0, sizeof(msg));
659 msg.invoke_id = get_invokeid(ctrl);
660 msg.operation = ROSE_ETSI_CCBSErase;
661
662 if (cc_record->saved_ie_contents.length
663 <= sizeof(msg.args.etsi.CCBSErase.q931ie_contents)) {
664 /* Saved BC, HLC, and LLC from initial SETUP */
665 msg.args.etsi.CCBSErase.q931ie.length = cc_record->saved_ie_contents.length;
666 memcpy(msg.args.etsi.CCBSErase.q931ie.contents, cc_record->saved_ie_contents.data,
667 cc_record->saved_ie_contents.length);
668 } else {
669 pri_error(ctrl, "CCBSErase q931 ie contents did not fit.\n");
670 }
671
672 q931_copy_address_to_rose(ctrl, &msg.args.etsi.CCBSErase.address_of_b,
673 &cc_record->party_b);
674 msg.args.etsi.CCBSErase.recall_mode = cc_record->option.recall_mode;
675 msg.args.etsi.CCBSErase.ccbs_reference = cc_record->ccbs_reference_id;
676 msg.args.etsi.CCBSErase.reason = reason;
677
678 pos = rose_encode_invoke(ctrl, pos, end, &msg);
679
680 return pos;
681 }
682
683 /*!
684 * \internal
685 * \brief Encode and queue an CCBSErase message.
686 *
687 * \param ctrl D channel controller for diagnostic messages or global options.
688 * \param call Call leg from which to encode CCBSErase.
689 * \param cc_record Call completion record to process event.
690 * \param reason CCBS Erase reason
691 * normal-unspecified(0), t-CCBS2-timeout(1), t-CCBS3-timeout(2), basic-call-failed(3)
692 *
693 * \retval 0 on success.
694 * \retval -1 on error.
695 */
rose_ccbs_erase_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,int reason)696 static int rose_ccbs_erase_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, int reason)
697 {
698 unsigned char buffer[256];
699 unsigned char *end;
700
701 end =
702 enc_etsi_ptmp_ccbs_erase(ctrl, buffer, buffer + sizeof(buffer), cc_record,
703 reason);
704 if (!end) {
705 return -1;
706 }
707
708 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
709 }
710
711 /*!
712 * \internal
713 * \brief Encode and send an CCBSErase message.
714 *
715 * \param ctrl D channel controller for diagnostic messages or global options.
716 * \param call Call leg from which to encode EraseCallLinkageID.
717 * \param cc_record Call completion record to process event.
718 * \param reason CCBS Erase reason
719 * normal-unspecified(0), t-CCBS2-timeout(1), t-CCBS3-timeout(2), basic-call-failed(3)
720 *
721 * \retval 0 on success.
722 * \retval -1 on error.
723 */
send_ccbs_erase(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,int reason)724 static int send_ccbs_erase(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, int reason)
725 {
726 /*
727 * XXX May need to add called-party-ie with Party A number in FACILITY message. (CCBSErase)
728 * ETSI EN 300-195-1 Section 5.41 MSN interaction.
729 */
730 if (rose_ccbs_erase_encode(ctrl, call, cc_record, reason)
731 || q931_facility(ctrl, call)) {
732 pri_message(ctrl,
733 "Could not schedule facility message for CCBSErase.\n");
734 return -1;
735 }
736
737 return 0;
738 }
739
740 /*!
741 * \internal
742 * \brief Encode ETSI PTMP CCBSStatusRequest result message.
743 *
744 * \param ctrl D channel controller for diagnostic messages or global options.
745 * \param pos Starting position to encode the facility ie contents.
746 * \param end End of facility ie contents encoding data buffer.
747 * \param cc_record Call completion record to process event.
748 * \param is_free TRUE if the Party A status is available.
749 *
750 * \retval Start of the next ASN.1 component to encode on success.
751 * \retval NULL on error.
752 */
enc_etsi_ptmp_ccbs_status_request_rsp(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record,int is_free)753 static unsigned char *enc_etsi_ptmp_ccbs_status_request_rsp(struct pri *ctrl,
754 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record, int is_free)
755 {
756 struct rose_msg_result msg;
757
758 pos = facility_encode_header(ctrl, pos, end, NULL);
759 if (!pos) {
760 return NULL;
761 }
762
763 memset(&msg, 0, sizeof(msg));
764 msg.invoke_id = cc_record->response.invoke_id;
765 msg.operation = ROSE_ETSI_CCBSStatusRequest;
766
767 msg.args.etsi.CCBSStatusRequest.free = is_free;
768
769 pos = rose_encode_result(ctrl, pos, end, &msg);
770
771 return pos;
772 }
773
774 /*!
775 * \internal
776 * \brief Encode ETSI PTMP CCBSStatusRequest message.
777 *
778 * \param ctrl D channel controller for diagnostic messages or global options.
779 * \param pos Starting position to encode the facility ie contents.
780 * \param end End of facility ie contents encoding data buffer.
781 * \param cc_record Call completion record to process event.
782 *
783 * \retval Start of the next ASN.1 component to encode on success.
784 * \retval NULL on error.
785 */
enc_etsi_ptmp_ccbs_status_request(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)786 static unsigned char *enc_etsi_ptmp_ccbs_status_request(struct pri *ctrl,
787 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
788 {
789 struct rose_msg_invoke msg;
790
791 pos = facility_encode_header(ctrl, pos, end, NULL);
792 if (!pos) {
793 return NULL;
794 }
795
796 memset(&msg, 0, sizeof(msg));
797 msg.invoke_id = get_invokeid(ctrl);
798 msg.operation = ROSE_ETSI_CCBSStatusRequest;
799
800 if (cc_record->saved_ie_contents.length
801 <= sizeof(msg.args.etsi.CCBSStatusRequest.q931ie_contents)) {
802 /* Saved BC, HLC, and LLC from initial SETUP */
803 msg.args.etsi.CCBSStatusRequest.q931ie.length =
804 cc_record->saved_ie_contents.length;
805 memcpy(msg.args.etsi.CCBSStatusRequest.q931ie.contents,
806 cc_record->saved_ie_contents.data, cc_record->saved_ie_contents.length);
807 } else {
808 pri_error(ctrl, "CCBSStatusRequest q931 ie contents did not fit.\n");
809 }
810
811 msg.args.etsi.CCBSStatusRequest.recall_mode = cc_record->option.recall_mode;
812 msg.args.etsi.CCBSStatusRequest.ccbs_reference = cc_record->ccbs_reference_id;
813
814 pos = rose_encode_invoke(ctrl, pos, end, &msg);
815
816 return pos;
817 }
818
819 /*!
820 * \internal
821 * \brief Encode ETSI PTMP CCBSRequest/CCNRRequest message.
822 *
823 * \param ctrl D channel controller for diagnostic messages or global options.
824 * \param pos Starting position to encode the facility ie contents.
825 * \param end End of facility ie contents encoding data buffer.
826 * \param cc_record Call completion record to process event.
827 *
828 * \retval Start of the next ASN.1 component to encode on success.
829 * \retval NULL on error.
830 */
enc_etsi_ptmp_cc_request(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)831 static unsigned char *enc_etsi_ptmp_cc_request(struct pri *ctrl,
832 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
833 {
834 struct rose_msg_invoke msg;
835
836 pos = facility_encode_header(ctrl, pos, end, NULL);
837 if (!pos) {
838 return NULL;
839 }
840
841 memset(&msg, 0, sizeof(msg));
842 msg.invoke_id = get_invokeid(ctrl);
843 msg.operation = cc_record->is_ccnr ? ROSE_ETSI_CCNRRequest : ROSE_ETSI_CCBSRequest;
844
845 msg.args.etsi.CCBSRequest.call_linkage_id = cc_record->call_linkage_id;
846
847 pos = rose_encode_invoke(ctrl, pos, end, &msg);
848
849 return pos;
850 }
851
852 /*!
853 * \internal
854 * \brief Encode ETSI PTP CCBS_T_Request/CCNR_T_Request message.
855 *
856 * \param ctrl D channel controller for diagnostic messages or global options.
857 * \param pos Starting position to encode the facility ie contents.
858 * \param end End of facility ie contents encoding data buffer.
859 * \param cc_record Call completion record to process event.
860 *
861 * \retval Start of the next ASN.1 component to encode on success.
862 * \retval NULL on error.
863 */
enc_etsi_ptp_cc_request(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)864 static unsigned char *enc_etsi_ptp_cc_request(struct pri *ctrl,
865 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
866 {
867 struct rose_msg_invoke msg;
868
869 pos = facility_encode_header(ctrl, pos, end, NULL);
870 if (!pos) {
871 return NULL;
872 }
873
874 memset(&msg, 0, sizeof(msg));
875 msg.invoke_id = get_invokeid(ctrl);
876 msg.operation = cc_record->is_ccnr
877 ? ROSE_ETSI_CCNR_T_Request : ROSE_ETSI_CCBS_T_Request;
878
879 if (cc_record->saved_ie_contents.length
880 <= sizeof(msg.args.etsi.CCBS_T_Request.q931ie_contents)) {
881 /* Saved BC, HLC, and LLC from initial SETUP */
882 msg.args.etsi.CCBS_T_Request.q931ie.length = cc_record->saved_ie_contents.length;
883 memcpy(msg.args.etsi.CCBS_T_Request.q931ie.contents,
884 cc_record->saved_ie_contents.data, cc_record->saved_ie_contents.length);
885 } else {
886 pri_error(ctrl, "CCBS_T_Request q931 ie contents did not fit.\n");
887 }
888
889 q931_copy_address_to_rose(ctrl, &msg.args.etsi.CCBS_T_Request.destination,
890 &cc_record->party_b);
891
892 if (cc_record->party_a.number.valid && cc_record->party_a.number.str[0]) {
893 q931_copy_id_address_to_rose(ctrl, &msg.args.etsi.CCBS_T_Request.originating,
894 &cc_record->party_a);
895
896 msg.args.etsi.CCBS_T_Request.presentation_allowed_indicator_present = 1;
897 if ((cc_record->party_a.number.presentation & PRI_PRES_RESTRICTION)
898 == PRI_PRES_ALLOWED) {
899 msg.args.etsi.CCBS_T_Request.presentation_allowed_indicator = 1;
900 }
901 }
902
903 //msg.args.etsi.CCBS_T_Request.retention_supported = 0;
904
905 pos = rose_encode_invoke(ctrl, pos, end, &msg);
906
907 return pos;
908 }
909
910 /*!
911 * \internal
912 * \brief Encode Q.SIG ccbsRequest/ccnrRequest message.
913 *
914 * \param ctrl D channel controller for diagnostic messages or global options.
915 * \param pos Starting position to encode the facility ie contents.
916 * \param end End of facility ie contents encoding data buffer.
917 * \param cc_record Call completion record to process event.
918 *
919 * \retval Start of the next ASN.1 component to encode on success.
920 * \retval NULL on error.
921 */
enc_qsig_cc_request(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)922 static unsigned char *enc_qsig_cc_request(struct pri *ctrl,
923 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
924 {
925 struct fac_extension_header header;
926 struct rose_msg_invoke msg;
927
928 memset(&header, 0, sizeof(header));
929 header.nfe_present = 1;
930 header.nfe.source_entity = 0; /* endPINX */
931 header.nfe.destination_entity = 0; /* endPINX */
932 header.interpretation_present = 1;
933 header.interpretation = 1; /* clearCallIfAnyInvokePduNotRecognised */
934 pos = facility_encode_header(ctrl, pos, end, &header);
935 if (!pos) {
936 return NULL;
937 }
938
939 memset(&msg, 0, sizeof(msg));
940 msg.invoke_id = get_invokeid(ctrl);
941 msg.operation = cc_record->is_ccnr
942 ? ROSE_QSIG_CcnrRequest : ROSE_QSIG_CcbsRequest;
943
944 /* Fill in Party B address. */
945 q931_copy_number_to_rose(ctrl, &msg.args.qsig.CcbsRequest.number_b,
946 &cc_record->party_b.number);
947 q931_copy_subaddress_to_rose(ctrl, &msg.args.qsig.CcbsRequest.subaddr_b,
948 &cc_record->party_b.subaddress);
949
950 /* Fill in Party A address. */
951 q931_copy_presented_number_unscreened_to_rose(ctrl,
952 &msg.args.qsig.CcbsRequest.number_a, &cc_record->party_a.number);
953 q931_copy_subaddress_to_rose(ctrl, &msg.args.qsig.CcbsRequest.subaddr_a,
954 &cc_record->party_a.subaddress);
955
956 /* Fill in service Q.931 ie information. */
957 if (cc_record->saved_ie_contents.length
958 <= sizeof(msg.args.qsig.CcbsRequest.q931ie_contents)) {
959 /* Saved BC, HLC, and LLC from initial SETUP */
960 msg.args.qsig.CcbsRequest.q931ie.length = cc_record->saved_ie_contents.length;
961 memcpy(msg.args.qsig.CcbsRequest.q931ie.contents,
962 cc_record->saved_ie_contents.data, cc_record->saved_ie_contents.length);
963 } else {
964 pri_error(ctrl, "CcbsRequest q931 ie contents did not fit.\n");
965 }
966
967 //msg.args.qsig.CcbsRequest.can_retain_service = 0;
968
969 switch (ctrl->cc.option.signaling_retention_req) {
970 case 0:/* Want release signaling link. */
971 cc_record->option.retain_signaling_link = 0;
972
973 msg.args.qsig.CcbsRequest.retain_sig_connection_present = 1;
974 msg.args.qsig.CcbsRequest.retain_sig_connection = 0;
975 break;
976 case 1:/* Demand retain signaling link. */
977 cc_record->option.retain_signaling_link = 1;
978
979 msg.args.qsig.CcbsRequest.retain_sig_connection_present = 1;
980 msg.args.qsig.CcbsRequest.retain_sig_connection = 1;
981 break;
982 case 2:/* Don't care about signaling link retention. */
983 default:
984 cc_record->option.retain_signaling_link = 0;
985 break;
986 }
987 if (!cc_record->party_a.number.valid || cc_record->party_a.number.str[0] == '\0') {
988 /*
989 * Party A number is not available for the other end to initiate
990 * a signaling link to us. We must require that the signaling link
991 * be retained.
992 */
993 cc_record->option.retain_signaling_link = 1;
994
995 msg.args.qsig.CcbsRequest.retain_sig_connection_present = 1;
996 msg.args.qsig.CcbsRequest.retain_sig_connection = 1;
997 }
998
999 pos = rose_encode_invoke(ctrl, pos, end, &msg);
1000
1001 return pos;
1002 }
1003
1004 /*!
1005 * \internal
1006 * \brief Encode Q.SIG ccSuspend/ccResume/ccPathReserve/ccRingout message.
1007 *
1008 * \param ctrl D channel controller for diagnostic messages or global options.
1009 * \param pos Starting position to encode the facility ie contents.
1010 * \param end End of facility ie contents encoding data buffer.
1011 * \param operation Q.SIG call completion event operation to encode.
1012 * \param interpretation Component interpretation:
1013 * discardAnyUnrecognisedInvokePdu(0),
1014 * clearCallIfAnyInvokePduNotRecognised(1),
1015 * rejectAnyUnrecognisedInvokePdu(2)
1016 *
1017 * \retval Start of the next ASN.1 component to encode on success.
1018 * \retval NULL on error.
1019 */
enc_qsig_cc_extension_event(struct pri * ctrl,unsigned char * pos,unsigned char * end,enum rose_operation operation,int interpretation)1020 static unsigned char *enc_qsig_cc_extension_event(struct pri *ctrl,
1021 unsigned char *pos, unsigned char *end, enum rose_operation operation,
1022 int interpretation)
1023 {
1024 struct fac_extension_header header;
1025 struct rose_msg_invoke msg;
1026
1027 memset(&header, 0, sizeof(header));
1028 header.nfe_present = 1;
1029 header.nfe.source_entity = 0; /* endPINX */
1030 header.nfe.destination_entity = 0; /* endPINX */
1031 header.interpretation_present = 1;
1032 header.interpretation = interpretation;
1033 pos = facility_encode_header(ctrl, pos, end, &header);
1034 if (!pos) {
1035 return NULL;
1036 }
1037
1038 memset(&msg, 0, sizeof(msg));
1039 msg.invoke_id = get_invokeid(ctrl);
1040 msg.operation = operation;
1041
1042 pos = rose_encode_invoke(ctrl, pos, end, &msg);
1043
1044 return pos;
1045 }
1046
1047 /*!
1048 * \internal
1049 * \brief Encode ETSI PTMP CCBSDeactivate message.
1050 *
1051 * \param ctrl D channel controller for diagnostic messages or global options.
1052 * \param pos Starting position to encode the facility ie contents.
1053 * \param end End of facility ie contents encoding data buffer.
1054 * \param cc_record Call completion record to process event.
1055 *
1056 * \retval Start of the next ASN.1 component to encode on success.
1057 * \retval NULL on error.
1058 */
enc_etsi_ptmp_cc_deactivate(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)1059 static unsigned char *enc_etsi_ptmp_cc_deactivate(struct pri *ctrl,
1060 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
1061 {
1062 struct rose_msg_invoke msg;
1063
1064 pos = facility_encode_header(ctrl, pos, end, NULL);
1065 if (!pos) {
1066 return NULL;
1067 }
1068
1069 memset(&msg, 0, sizeof(msg));
1070 msg.invoke_id = get_invokeid(ctrl);
1071 msg.operation = ROSE_ETSI_CCBSDeactivate;
1072
1073 msg.args.etsi.CCBSDeactivate.ccbs_reference = cc_record->ccbs_reference_id;
1074
1075 pos = rose_encode_invoke(ctrl, pos, end, &msg);
1076
1077 return pos;
1078 }
1079
1080 /*!
1081 * \internal
1082 * \brief Encode and queue an CCBSDeactivate message.
1083 *
1084 * \param ctrl D channel controller for diagnostic messages or global options.
1085 * \param call Call leg from which to encode CCBSDeactivate.
1086 * \param cc_record Call completion record to process event.
1087 *
1088 * \retval 0 on success.
1089 * \retval -1 on error.
1090 */
rose_cc_deactivate_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)1091 static int rose_cc_deactivate_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
1092 {
1093 unsigned char buffer[256];
1094 unsigned char *end;
1095
1096 end =
1097 enc_etsi_ptmp_cc_deactivate(ctrl, buffer, buffer + sizeof(buffer), cc_record);
1098 if (!end) {
1099 return -1;
1100 }
1101
1102 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
1103 }
1104
1105 /*!
1106 * \internal
1107 * \brief Encode and send an CCBSDeactivate message.
1108 *
1109 * \param ctrl D channel controller for diagnostic messages or global options.
1110 * \param call Call leg from which to encode CCBSDeactivate.
1111 * \param cc_record Call completion record to process event.
1112 *
1113 * \retval 0 on success.
1114 * \retval -1 on error.
1115 */
send_cc_deactivate_req(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)1116 static int send_cc_deactivate_req(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
1117 {
1118 if (rose_cc_deactivate_encode(ctrl, call, cc_record)
1119 || q931_facility(ctrl, call)) {
1120 pri_message(ctrl,
1121 "Could not schedule facility message for CCBSDeactivate.\n");
1122 return -1;
1123 }
1124
1125 return 0;
1126 }
1127
1128 /*!
1129 * \internal
1130 * \brief Encode ETSI PTMP CCBSBFree message.
1131 *
1132 * \param ctrl D channel controller for diagnostic messages or global options.
1133 * \param pos Starting position to encode the facility ie contents.
1134 * \param end End of facility ie contents encoding data buffer.
1135 * \param cc_record Call completion record to process event.
1136 *
1137 * \retval Start of the next ASN.1 component to encode on success.
1138 * \retval NULL on error.
1139 */
enc_etsi_ptmp_ccbs_b_free(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)1140 static unsigned char *enc_etsi_ptmp_ccbs_b_free(struct pri *ctrl,
1141 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
1142 {
1143 struct rose_msg_invoke msg;
1144
1145 pos = facility_encode_header(ctrl, pos, end, NULL);
1146 if (!pos) {
1147 return NULL;
1148 }
1149
1150 memset(&msg, 0, sizeof(msg));
1151 msg.invoke_id = get_invokeid(ctrl);
1152 msg.operation = ROSE_ETSI_CCBSBFree;
1153
1154 if (cc_record->saved_ie_contents.length
1155 <= sizeof(msg.args.etsi.CCBSBFree.q931ie_contents)) {
1156 /* Saved BC, HLC, and LLC from initial SETUP */
1157 msg.args.etsi.CCBSBFree.q931ie.length = cc_record->saved_ie_contents.length;
1158 memcpy(msg.args.etsi.CCBSBFree.q931ie.contents, cc_record->saved_ie_contents.data,
1159 cc_record->saved_ie_contents.length);
1160 } else {
1161 pri_error(ctrl, "CCBSBFree q931 ie contents did not fit.\n");
1162 }
1163
1164 q931_copy_address_to_rose(ctrl, &msg.args.etsi.CCBSBFree.address_of_b,
1165 &cc_record->party_b);
1166 msg.args.etsi.CCBSBFree.recall_mode = cc_record->option.recall_mode;
1167 msg.args.etsi.CCBSBFree.ccbs_reference = cc_record->ccbs_reference_id;
1168
1169 pos = rose_encode_invoke(ctrl, pos, end, &msg);
1170
1171 return pos;
1172 }
1173
1174 /*!
1175 * \internal
1176 * \brief Encode and queue an CCBSBFree message.
1177 *
1178 * \param ctrl D channel controller for diagnostic messages or global options.
1179 * \param call Call leg from which to encode CCBSBFree.
1180 * \param cc_record Call completion record to process event.
1181 *
1182 * \retval 0 on success.
1183 * \retval -1 on error.
1184 */
rose_ccbs_b_free_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)1185 static int rose_ccbs_b_free_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
1186 {
1187 unsigned char buffer[256];
1188 unsigned char *end;
1189
1190 end =
1191 enc_etsi_ptmp_ccbs_b_free(ctrl, buffer, buffer + sizeof(buffer), cc_record);
1192 if (!end) {
1193 return -1;
1194 }
1195
1196 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
1197 }
1198
1199 /*!
1200 * \internal
1201 * \brief Encode and send an CCBSBFree message.
1202 *
1203 * \param ctrl D channel controller for diagnostic messages or global options.
1204 * \param call Call leg from which to encode CCBSBFree.
1205 * \param cc_record Call completion record to process event.
1206 *
1207 * \retval 0 on success.
1208 * \retval -1 on error.
1209 */
send_ccbs_b_free(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)1210 static int send_ccbs_b_free(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
1211 {
1212 /*
1213 * XXX May need to add called-party-ie with Party A number in FACILITY message. (CCBSBFree)
1214 * ETSI EN 300-195-1 Section 5.41 MSN interaction.
1215 */
1216 if (rose_ccbs_b_free_encode(ctrl, call, cc_record)
1217 || q931_facility(ctrl, call)) {
1218 pri_message(ctrl,
1219 "Could not schedule facility message for CCBSBFree.\n");
1220 return -1;
1221 }
1222
1223 return 0;
1224 }
1225
1226 /*!
1227 * \internal
1228 * \brief Encode ETSI PTMP CCBSRemoteUserFree message.
1229 *
1230 * \param ctrl D channel controller for diagnostic messages or global options.
1231 * \param pos Starting position to encode the facility ie contents.
1232 * \param end End of facility ie contents encoding data buffer.
1233 * \param cc_record Call completion record to process event.
1234 *
1235 * \retval Start of the next ASN.1 component to encode on success.
1236 * \retval NULL on error.
1237 */
enc_etsi_ptmp_remote_user_free(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)1238 static unsigned char *enc_etsi_ptmp_remote_user_free(struct pri *ctrl,
1239 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
1240 {
1241 struct rose_msg_invoke msg;
1242
1243 pos = facility_encode_header(ctrl, pos, end, NULL);
1244 if (!pos) {
1245 return NULL;
1246 }
1247
1248 memset(&msg, 0, sizeof(msg));
1249 msg.invoke_id = get_invokeid(ctrl);
1250 msg.operation = ROSE_ETSI_CCBSRemoteUserFree;
1251
1252 if (cc_record->saved_ie_contents.length
1253 <= sizeof(msg.args.etsi.CCBSRemoteUserFree.q931ie_contents)) {
1254 /* Saved BC, HLC, and LLC from initial SETUP */
1255 msg.args.etsi.CCBSRemoteUserFree.q931ie.length =
1256 cc_record->saved_ie_contents.length;
1257 memcpy(msg.args.etsi.CCBSRemoteUserFree.q931ie.contents,
1258 cc_record->saved_ie_contents.data, cc_record->saved_ie_contents.length);
1259 } else {
1260 pri_error(ctrl, "CCBSRemoteUserFree q931 ie contents did not fit.\n");
1261 }
1262
1263 q931_copy_address_to_rose(ctrl, &msg.args.etsi.CCBSRemoteUserFree.address_of_b,
1264 &cc_record->party_b);
1265 msg.args.etsi.CCBSRemoteUserFree.recall_mode = cc_record->option.recall_mode;
1266 msg.args.etsi.CCBSRemoteUserFree.ccbs_reference = cc_record->ccbs_reference_id;
1267
1268 pos = rose_encode_invoke(ctrl, pos, end, &msg);
1269
1270 return pos;
1271 }
1272
1273 /*!
1274 * \internal
1275 * \brief Encode Q.SIG CcOptionalArg for ccCancel/ccExecPossible message.
1276 *
1277 * \param ctrl D channel controller for diagnostic messages or global options.
1278 * \param pos Starting position to encode the facility ie contents.
1279 * \param end End of facility ie contents encoding data buffer.
1280 * \param cc_record Call completion record to process event.
1281 * \param msgtype Q.931 message type to put facility ie in.
1282 * \param operation library encoded operation-value
1283 *
1284 * \retval Start of the next ASN.1 component to encode on success.
1285 * \retval NULL on error.
1286 */
enc_qsig_cc_optional_arg(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record,int msgtype,enum rose_operation operation)1287 static unsigned char *enc_qsig_cc_optional_arg(struct pri *ctrl,
1288 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record, int msgtype,
1289 enum rose_operation operation)
1290 {
1291 struct fac_extension_header header;
1292 struct rose_msg_invoke msg;
1293
1294 memset(&header, 0, sizeof(header));
1295 header.nfe_present = 1;
1296 header.nfe.source_entity = 0; /* endPINX */
1297 header.nfe.destination_entity = 0; /* endPINX */
1298 header.interpretation_present = 1;
1299 header.interpretation = 1; /* clearCallIfAnyInvokePduNotRecognised */
1300 pos = facility_encode_header(ctrl, pos, end, &header);
1301 if (!pos) {
1302 return NULL;
1303 }
1304
1305 memset(&msg, 0, sizeof(msg));
1306 msg.invoke_id = get_invokeid(ctrl);
1307 msg.operation = operation;
1308
1309 if (cc_record && msgtype == Q931_SETUP) {
1310 msg.args.qsig.CcCancel.full_arg_present = 1;
1311
1312 /* Fill in Party A address. */
1313 q931_copy_number_to_rose(ctrl, &msg.args.qsig.CcCancel.number_a,
1314 &cc_record->party_a.number);
1315 q931_copy_subaddress_to_rose(ctrl, &msg.args.qsig.CcCancel.subaddr_a,
1316 &cc_record->party_a.subaddress);
1317
1318 /* Fill in Party B address. */
1319 q931_copy_number_to_rose(ctrl, &msg.args.qsig.CcCancel.number_b,
1320 &cc_record->party_b.number);
1321 q931_copy_subaddress_to_rose(ctrl, &msg.args.qsig.CcCancel.subaddr_b,
1322 &cc_record->party_b.subaddress);
1323
1324 /* Fill in service Q.931 ie information. */
1325 if (cc_record->saved_ie_contents.length
1326 <= sizeof(msg.args.qsig.CcCancel.q931ie_contents)) {
1327 /* Saved BC, HLC, and LLC from initial SETUP */
1328 msg.args.qsig.CcCancel.q931ie.length = cc_record->saved_ie_contents.length;
1329 memcpy(msg.args.qsig.CcCancel.q931ie.contents,
1330 cc_record->saved_ie_contents.data, cc_record->saved_ie_contents.length);
1331 } else {
1332 pri_error(ctrl, "CcOptionalArg q931 ie contents did not fit.\n");
1333 }
1334 }
1335
1336 pos = rose_encode_invoke(ctrl, pos, end, &msg);
1337
1338 return pos;
1339 }
1340
1341 /*!
1342 * \internal
1343 * \brief Encode and queue a remote user free message.
1344 *
1345 * \param ctrl D channel controller for diagnostic messages or global options.
1346 * \param call Call leg from which to encode remote user free message.
1347 * \param cc_record Call completion record to process event.
1348 * \param msgtype Q.931 message type to put facility ie in.
1349 *
1350 * \retval 0 on success.
1351 * \retval -1 on error.
1352 */
rose_remote_user_free_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,int msgtype)1353 static int rose_remote_user_free_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, int msgtype)
1354 {
1355 unsigned char buffer[256];
1356 unsigned char *end;
1357
1358 switch (ctrl->switchtype) {
1359 case PRI_SWITCH_EUROISDN_E1:
1360 case PRI_SWITCH_EUROISDN_T1:
1361 if (PTMP_MODE(ctrl)) {
1362 end =
1363 enc_etsi_ptmp_remote_user_free(ctrl, buffer, buffer + sizeof(buffer),
1364 cc_record);
1365 } else {
1366 end =
1367 enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer),
1368 ROSE_ETSI_CCBS_T_RemoteUserFree);
1369 }
1370 break;
1371 case PRI_SWITCH_QSIG:
1372 end = enc_qsig_cc_optional_arg(ctrl, buffer, buffer + sizeof(buffer), cc_record,
1373 msgtype, ROSE_QSIG_CcExecPossible);
1374 break;
1375 default:
1376 return -1;
1377 }
1378 if (!end) {
1379 return -1;
1380 }
1381
1382 return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
1383 }
1384
1385 /*!
1386 * \internal
1387 * \brief Encode and send a CC facility event in a SETUP message.
1388 *
1389 * \param ctrl D channel controller for diagnostic messages or global options.
1390 * \param cc_record Call completion record to process event.
1391 * \param encode Function to encode facility to send out in SETUP message.
1392 *
1393 * \retval 0 on success.
1394 * \retval -1 on error.
1395 */
pri_cc_send_setup_encode(struct pri * ctrl,struct pri_cc_record * cc_record,int (* encode)(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,int msgtype))1396 static int pri_cc_send_setup_encode(struct pri *ctrl, struct pri_cc_record *cc_record,
1397 int (*encode)(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record,
1398 int msgtype))
1399 {
1400 struct pri_sr req;
1401 q931_call *call;
1402
1403 call = q931_new_call(ctrl);
1404 if (!call) {
1405 return -1;
1406 }
1407
1408 /* Link the new call as the signaling link. */
1409 cc_record->signaling = call;
1410 call->cc.record = cc_record;
1411
1412 if (encode(ctrl, call, cc_record, Q931_SETUP)) {
1413 /* Should not happen. */
1414 q931_destroycall(ctrl, call);
1415 return -1;
1416 }
1417
1418 pri_sr_init(&req);
1419 if (cc_record->is_agent) {
1420 q931_party_address_to_id(&req.caller, &cc_record->party_b);
1421 q931_party_id_to_address(&req.called, &cc_record->party_a);
1422 } else {
1423 req.caller = cc_record->party_a;
1424 req.called = cc_record->party_b;
1425 }
1426 //req.cis_auto_disconnect = 0;
1427 req.cis_call = 1;
1428 if (q931_setup(ctrl, call, &req)) {
1429 /* Should not happen. */
1430 q931_destroycall(ctrl, call);
1431 return -1;
1432 }
1433 return 0;
1434 }
1435
1436 /*!
1437 * \internal
1438 * \brief Encode and send an remote user free message.
1439 *
1440 * \param ctrl D channel controller for diagnostic messages or global options.
1441 * \param cc_record Call completion record to process event.
1442 *
1443 * \retval 0 on success.
1444 * \retval -1 on error.
1445 */
send_remote_user_free(struct pri * ctrl,struct pri_cc_record * cc_record)1446 static int send_remote_user_free(struct pri *ctrl, struct pri_cc_record *cc_record)
1447 {
1448 int retval;
1449 q931_call *call;
1450
1451 /*
1452 * XXX May need to add called-party-ie with Party A number in FACILITY message. (CCBSRemoteUserFree)
1453 * ETSI EN 300-195-1 Section 5.41 MSN interaction.
1454 */
1455 retval = -1;
1456 switch (ctrl->switchtype) {
1457 case PRI_SWITCH_EUROISDN_E1:
1458 case PRI_SWITCH_EUROISDN_T1:
1459 call = cc_record->signaling;
1460 retval = rose_remote_user_free_encode(ctrl, call, cc_record, Q931_FACILITY);
1461 if (!retval) {
1462 retval = q931_facility(ctrl, call);
1463 }
1464 break;
1465 case PRI_SWITCH_QSIG:
1466 /* ccExecPossible could be sent in FACILITY or SETUP. */
1467 call = cc_record->signaling;
1468 if (call) {
1469 retval = rose_remote_user_free_encode(ctrl, call, cc_record, Q931_FACILITY);
1470 if (!retval) {
1471 retval = q931_facility(ctrl, call);
1472 }
1473 } else {
1474 retval = pri_cc_send_setup_encode(ctrl, cc_record,
1475 rose_remote_user_free_encode);
1476 }
1477 break;
1478 default:
1479 break;
1480 }
1481 if (retval) {
1482 pri_message(ctrl, "Could not schedule message for remote user free.\n");
1483 return -1;
1484 }
1485 return 0;
1486 }
1487
1488 /*!
1489 * \internal
1490 * \brief Encode and queue a Q.SIG ccCancel message.
1491 *
1492 * \param ctrl D channel controller for diagnostic messages or global options.
1493 * \param call Call leg from which to encode remote user free message.
1494 * \param cc_record Call completion record to process event.
1495 * \param msgtype Q.931 message type to put facility ie in.
1496 *
1497 * \retval 0 on success.
1498 * \retval -1 on error.
1499 */
rose_cc_cancel(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,int msgtype)1500 static int rose_cc_cancel(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, int msgtype)
1501 {
1502 unsigned char buffer[256];
1503 unsigned char *end;
1504
1505 end = enc_qsig_cc_optional_arg(ctrl, buffer, buffer + sizeof(buffer), cc_record,
1506 msgtype, ROSE_QSIG_CcCancel);
1507 if (!end) {
1508 return -1;
1509 }
1510
1511 return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
1512 }
1513
1514 /*!
1515 * \internal
1516 * \brief Encode and send a Q.SIG ccCancel message.
1517 *
1518 * \param ctrl D channel controller for diagnostic messages or global options.
1519 * \param cc_record Call completion record to process event.
1520 *
1521 * \retval 0 on success.
1522 * \retval -1 on error.
1523 */
send_cc_cancel(struct pri * ctrl,struct pri_cc_record * cc_record)1524 static int send_cc_cancel(struct pri *ctrl, struct pri_cc_record *cc_record)
1525 {
1526 int retval;
1527 q931_call *call;
1528
1529 /*
1530 * ccCancel could be sent in SETUP or RELEASE.
1531 * If ccPathReserve is supported it could also be sent in DISCONNECT.
1532 */
1533 retval = -1;
1534 call = cc_record->signaling;
1535 if (call) {
1536 retval = rose_cc_cancel(ctrl, call, cc_record, Q931_ANY_MESSAGE);
1537 if (!retval) {
1538 retval = pri_hangup(ctrl, call, -1);
1539 }
1540 } else {
1541 retval = pri_cc_send_setup_encode(ctrl, cc_record, rose_cc_cancel);
1542 }
1543 if (retval) {
1544 pri_message(ctrl, "Could not schedule message for ccCancel.\n");
1545 return -1;
1546 }
1547 return 0;
1548 }
1549
1550 /*!
1551 * \internal
1552 * \brief Encode and queue a CC suspend message.
1553 *
1554 * \param ctrl D channel controller for diagnostic messages or global options.
1555 * \param call Call leg from which to encode CC suspend message.
1556 * \param msgtype Q.931 message type to put facility ie in.
1557 *
1558 * \retval 0 on success.
1559 * \retval -1 on error.
1560 */
rose_cc_suspend_encode(struct pri * ctrl,q931_call * call,int msgtype)1561 static int rose_cc_suspend_encode(struct pri *ctrl, q931_call *call, int msgtype)
1562 {
1563 unsigned char buffer[256];
1564 unsigned char *end;
1565
1566 switch (ctrl->switchtype) {
1567 case PRI_SWITCH_EUROISDN_E1:
1568 case PRI_SWITCH_EUROISDN_T1:
1569 end =
1570 enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer),
1571 ROSE_ETSI_CCBS_T_Suspend);
1572 break;
1573 case PRI_SWITCH_QSIG:
1574 end =
1575 enc_qsig_cc_extension_event(ctrl, buffer, buffer + sizeof(buffer),
1576 ROSE_QSIG_CcSuspend, 0/* discardAnyUnrecognisedInvokePdu */);
1577 break;
1578 default:
1579 return -1;
1580 }
1581 if (!end) {
1582 return -1;
1583 }
1584
1585 return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
1586 }
1587
1588 /*!
1589 * \internal
1590 * \brief Encode and send a CC suspend message.
1591 *
1592 * \param ctrl D channel controller for diagnostic messages or global options.
1593 * \param cc_record Call completion record to process event.
1594 *
1595 * \retval 0 on success.
1596 * \retval -1 on error.
1597 */
send_cc_suspend(struct pri * ctrl,struct pri_cc_record * cc_record)1598 static int send_cc_suspend(struct pri *ctrl, struct pri_cc_record *cc_record)
1599 {
1600 int retval;
1601 q931_call *call;
1602
1603 retval = -1;
1604 switch (ctrl->switchtype) {
1605 case PRI_SWITCH_EUROISDN_E1:
1606 case PRI_SWITCH_EUROISDN_T1:
1607 call = cc_record->signaling;
1608 retval = rose_cc_suspend_encode(ctrl, call, Q931_FACILITY);
1609 if (!retval) {
1610 retval = q931_facility(ctrl, call);
1611 }
1612 break;
1613 case PRI_SWITCH_QSIG:
1614 /*
1615 * Suspend is sent in a CONNECT or FACILITY message.
1616 * If ccPathReserve is supported, it could also be sent in
1617 * RELEASE or DISCONNECT.
1618 */
1619 call = cc_record->signaling;
1620 if (!call) {
1621 break;
1622 }
1623 retval = rose_cc_suspend_encode(ctrl, call, Q931_ANY_MESSAGE);
1624 if (!retval) {
1625 if (call->ourcallstate == Q931_CALL_STATE_ACTIVE) {
1626 retval = q931_facility(ctrl, call);
1627 } else {
1628 retval = q931_connect(ctrl, call, 0, 0);
1629 }
1630 }
1631 break;
1632 default:
1633 break;
1634 }
1635 if (retval) {
1636 pri_message(ctrl, "Could not schedule message for CC suspend.\n");
1637 return -1;
1638 }
1639 return 0;
1640 }
1641
1642 /*!
1643 * \internal
1644 * \brief Encode and queue a CC resume message.
1645 *
1646 * \param ctrl D channel controller for diagnostic messages or global options.
1647 * \param call Call leg from which to encode CC resume message.
1648 * \param msgtype Q.931 message type to put facility ie in.
1649 *
1650 * \retval 0 on success.
1651 * \retval -1 on error.
1652 */
rose_cc_resume_encode(struct pri * ctrl,q931_call * call,int msgtype)1653 static int rose_cc_resume_encode(struct pri *ctrl, q931_call *call, int msgtype)
1654 {
1655 unsigned char buffer[256];
1656 unsigned char *end;
1657
1658 switch (ctrl->switchtype) {
1659 case PRI_SWITCH_EUROISDN_E1:
1660 case PRI_SWITCH_EUROISDN_T1:
1661 end =
1662 enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer),
1663 ROSE_ETSI_CCBS_T_Resume);
1664 break;
1665 case PRI_SWITCH_QSIG:
1666 end =
1667 enc_qsig_cc_extension_event(ctrl, buffer, buffer + sizeof(buffer),
1668 ROSE_QSIG_CcResume, 0/* discardAnyUnrecognisedInvokePdu */);
1669 break;
1670 default:
1671 return -1;
1672 }
1673 if (!end) {
1674 return -1;
1675 }
1676
1677 return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
1678 }
1679
1680 /*!
1681 * \internal
1682 * \brief Encode and send a CC resume message.
1683 *
1684 * \param ctrl D channel controller for diagnostic messages or global options.
1685 * \param cc_record Call completion record to process event.
1686 *
1687 * \retval 0 on success.
1688 * \retval -1 on error.
1689 */
send_cc_resume(struct pri * ctrl,struct pri_cc_record * cc_record)1690 static int send_cc_resume(struct pri *ctrl, struct pri_cc_record *cc_record)
1691 {
1692 q931_call *call;
1693
1694 call = cc_record->signaling;
1695 if (!call
1696 || rose_cc_resume_encode(ctrl, call, Q931_FACILITY)
1697 || q931_facility(ctrl, call)) {
1698 pri_message(ctrl, "Could not schedule message for CC resume.\n");
1699 return -1;
1700 }
1701 return 0;
1702 }
1703
1704 /*!
1705 * \internal
1706 * \brief Encode ETSI PTMP CCBSStopAlerting message.
1707 *
1708 * \param ctrl D channel controller for diagnostic messages or global options.
1709 * \param pos Starting position to encode the facility ie contents.
1710 * \param end End of facility ie contents encoding data buffer.
1711 * \param cc_record Call completion record to process event.
1712 *
1713 * \retval Start of the next ASN.1 component to encode on success.
1714 * \retval NULL on error.
1715 */
enc_etsi_ptmp_ccbs_stop_alerting(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)1716 static unsigned char *enc_etsi_ptmp_ccbs_stop_alerting(struct pri *ctrl,
1717 unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
1718 {
1719 struct rose_msg_invoke msg;
1720
1721 pos = facility_encode_header(ctrl, pos, end, NULL);
1722 if (!pos) {
1723 return NULL;
1724 }
1725
1726 memset(&msg, 0, sizeof(msg));
1727 msg.invoke_id = get_invokeid(ctrl);
1728 msg.operation = ROSE_ETSI_CCBSStopAlerting;
1729
1730 msg.args.etsi.CCBSStopAlerting.ccbs_reference = cc_record->ccbs_reference_id;
1731
1732 pos = rose_encode_invoke(ctrl, pos, end, &msg);
1733
1734 return pos;
1735 }
1736
1737 /*!
1738 * \internal
1739 * \brief Encode and queue an CCBSStopAlerting message.
1740 *
1741 * \param ctrl D channel controller for diagnostic messages or global options.
1742 * \param call Call leg from which to encode CCBSStopAlerting.
1743 * \param cc_record Call completion record to process event.
1744 *
1745 * \retval 0 on success.
1746 * \retval -1 on error.
1747 */
rose_ccbs_stop_alerting_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)1748 static int rose_ccbs_stop_alerting_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
1749 {
1750 unsigned char buffer[256];
1751 unsigned char *end;
1752
1753 end =
1754 enc_etsi_ptmp_ccbs_stop_alerting(ctrl, buffer, buffer + sizeof(buffer), cc_record);
1755 if (!end) {
1756 return -1;
1757 }
1758
1759 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
1760 }
1761
1762 /*!
1763 * \internal
1764 * \brief Encode and send CCBSStopAlerting message.
1765 *
1766 * \param ctrl D channel controller for diagnostic messages or global options.
1767 * \param call Call leg from which to encode remote user free.
1768 * \param cc_record Call completion record to process event.
1769 *
1770 * \retval 0 on success.
1771 * \retval -1 on error.
1772 */
send_ccbs_stop_alerting(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)1773 static int send_ccbs_stop_alerting(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
1774 {
1775 if (rose_ccbs_stop_alerting_encode(ctrl, call, cc_record)
1776 || q931_facility(ctrl, call)) {
1777 pri_message(ctrl,
1778 "Could not schedule facility message for CCBSStopAlerting.\n");
1779 return -1;
1780 }
1781
1782 return 0;
1783 }
1784
1785 /*!
1786 * \internal
1787 * \brief Encode ETSI PTMP CCBSCall message.
1788 *
1789 * \param ctrl D channel controller for diagnostic messages or global options.
1790 * \param pos Starting position to encode the facility ie contents.
1791 * \param end End of facility ie contents encoding data buffer.
1792 * \param cc_record Call completion record to process event.
1793 *
1794 * \retval Start of the next ASN.1 component to encode on success.
1795 * \retval NULL on error.
1796 */
enc_etsi_ptmp_cc_recall(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)1797 static unsigned char *enc_etsi_ptmp_cc_recall(struct pri *ctrl, unsigned char *pos,
1798 unsigned char *end, struct pri_cc_record *cc_record)
1799 {
1800 struct rose_msg_invoke msg;
1801
1802 pos = facility_encode_header(ctrl, pos, end, NULL);
1803 if (!pos) {
1804 return NULL;
1805 }
1806
1807 memset(&msg, 0, sizeof(msg));
1808 msg.invoke_id = get_invokeid(ctrl);
1809 msg.operation = ROSE_ETSI_CCBSCall;
1810
1811 msg.args.etsi.CCBSCall.ccbs_reference = cc_record->ccbs_reference_id;
1812
1813 pos = rose_encode_invoke(ctrl, pos, end, &msg);
1814
1815 return pos;
1816 }
1817
1818 /*!
1819 * \internal
1820 * \brief Encode and queue a cc-recall message.
1821 *
1822 * \param ctrl D channel controller for diagnostic messages or global options.
1823 * \param call Call leg from which to encode cc-recall.
1824 * \param cc_record Call completion record to process event.
1825 *
1826 * \retval 0 on success.
1827 * \retval -1 on error.
1828 */
rose_cc_recall_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)1829 static int rose_cc_recall_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
1830 {
1831 unsigned char buffer[256];
1832 unsigned char *end;
1833
1834 switch (ctrl->switchtype) {
1835 case PRI_SWITCH_EUROISDN_E1:
1836 case PRI_SWITCH_EUROISDN_T1:
1837 if (PTMP_MODE(ctrl)) {
1838 end =
1839 enc_etsi_ptmp_cc_recall(ctrl, buffer, buffer + sizeof(buffer), cc_record);
1840 } else {
1841 end =
1842 enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer),
1843 ROSE_ETSI_CCBS_T_Call);
1844 }
1845 break;
1846 case PRI_SWITCH_QSIG:
1847 end =
1848 enc_qsig_cc_extension_event(ctrl, buffer, buffer + sizeof(buffer),
1849 ROSE_QSIG_CcRingout, 0/* discardAnyUnrecognisedInvokePdu */);
1850 break;
1851 default:
1852 return -1;
1853 }
1854 if (!end) {
1855 return -1;
1856 }
1857
1858 return pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer, NULL);
1859 }
1860
1861 /*!
1862 * \internal
1863 * \brief Copy the cc information into the ETSI ROSE call-information record.
1864 *
1865 * \param ctrl D channel controller for diagnostic messages or global options.
1866 * \param call_information ROSE call-information record to fill in.
1867 * \param cc_record Call completion record to process event.
1868 *
1869 * \return Nothing
1870 */
q931_copy_call_information_to_etsi_rose(struct pri * ctrl,struct roseEtsiCallInformation * call_information,const struct pri_cc_record * cc_record)1871 static void q931_copy_call_information_to_etsi_rose(struct pri *ctrl, struct roseEtsiCallInformation *call_information, const struct pri_cc_record *cc_record)
1872 {
1873 q931_copy_address_to_rose(ctrl, &call_information->address_of_b, &cc_record->party_b);
1874
1875 if (cc_record->saved_ie_contents.length
1876 <= sizeof(call_information->q931ie_contents)) {
1877 /* Saved BC, HLC, and LLC from initial SETUP */
1878 call_information->q931ie.length = cc_record->saved_ie_contents.length;
1879 memcpy(call_information->q931ie.contents, cc_record->saved_ie_contents.data,
1880 cc_record->saved_ie_contents.length);
1881 } else {
1882 pri_error(ctrl, "call-information q931 ie contents did not fit.\n");
1883 }
1884
1885 call_information->ccbs_reference = cc_record->ccbs_reference_id;
1886
1887 q931_copy_subaddress_to_rose(ctrl, &call_information->subaddress_of_a,
1888 &cc_record->party_a.subaddress);
1889 }
1890
1891 /*!
1892 * \internal
1893 * \brief Encode ETSI PTMP specific CCBSInterrogate/CCNRInterrogate result message.
1894 *
1895 * \param ctrl D channel controller for diagnostic messages or global options.
1896 * \param pos Starting position to encode the facility ie contents.
1897 * \param end End of facility ie contents encoding data buffer.
1898 * \param invoke Decoded ROSE invoke message contents.
1899 * \param cc_record Call completion record to process event.
1900 *
1901 * \retval Start of the next ASN.1 component to encode on success.
1902 * \retval NULL on error.
1903 */
enc_etsi_ptmp_cc_interrogate_rsp_specific(struct pri * ctrl,unsigned char * pos,unsigned char * end,const struct rose_msg_invoke * invoke,const struct pri_cc_record * cc_record)1904 static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_specific(struct pri *ctrl,
1905 unsigned char *pos, unsigned char *end, const struct rose_msg_invoke *invoke,
1906 const struct pri_cc_record *cc_record)
1907 {
1908 struct rose_msg_result msg;
1909
1910 pos = facility_encode_header(ctrl, pos, end, NULL);
1911 if (!pos) {
1912 return NULL;
1913 }
1914
1915 memset(&msg, 0, sizeof(msg));
1916 msg.invoke_id = invoke->invoke_id;
1917 msg.operation = invoke->operation;
1918
1919 msg.args.etsi.CCBSInterrogate.recall_mode = cc_record->option.recall_mode;
1920 msg.args.etsi.CCBSInterrogate.call_details.num_records = 1;
1921 q931_copy_call_information_to_etsi_rose(ctrl,
1922 &msg.args.etsi.CCBSInterrogate.call_details.list[0], cc_record);
1923
1924 pos = rose_encode_result(ctrl, pos, end, &msg);
1925
1926 return pos;
1927 }
1928
1929 /*!
1930 * \internal
1931 * \brief Encode ETSI PTMP general CCBSInterrogate/CCNRInterrogate result message.
1932 *
1933 * \param ctrl D channel controller for diagnostic messages or global options.
1934 * \param pos Starting position to encode the facility ie contents.
1935 * \param end End of facility ie contents encoding data buffer.
1936 * \param invoke Decoded ROSE invoke message contents.
1937 *
1938 * \retval Start of the next ASN.1 component to encode on success.
1939 * \retval NULL on error.
1940 */
enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri * ctrl,unsigned char * pos,unsigned char * end,const struct rose_msg_invoke * invoke)1941 static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
1942 unsigned char *pos, unsigned char *end, const struct rose_msg_invoke *invoke)
1943 {
1944 struct rose_msg_result msg;
1945 struct q931_party_number party_a_number;
1946 const struct pri_cc_record *cc_record;
1947 unsigned char *new_pos;
1948 unsigned idx;
1949
1950 pos = facility_encode_header(ctrl, pos, end, NULL);
1951 if (!pos) {
1952 return NULL;
1953 }
1954
1955 memset(&msg, 0, sizeof(msg));
1956 msg.invoke_id = invoke->invoke_id;
1957 msg.operation = invoke->operation;
1958
1959 msg.args.etsi.CCBSInterrogate.recall_mode = ctrl->cc.option.recall_mode;
1960
1961 /* Convert the given party A number. */
1962 q931_party_number_init(&party_a_number);
1963 if (invoke->args.etsi.CCBSInterrogate.a_party_number.length) {
1964 /* The party A number was given. */
1965 rose_copy_number_to_q931(ctrl, &party_a_number,
1966 &invoke->args.etsi.CCBSInterrogate.a_party_number);
1967 }
1968
1969 /* Build the CallDetails list. */
1970 idx = 0;
1971 for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
1972 if (cc_record->ccbs_reference_id == CC_PTMP_INVALID_ID
1973 || (!cc_record->is_ccnr) != (invoke->operation == ROSE_ETSI_CCBSInterrogate)) {
1974 /*
1975 * Record does not have a reference id yet
1976 * or is not for the requested CCBS/CCNR mode.
1977 */
1978 continue;
1979 }
1980 if (party_a_number.valid) {
1981 /* The party A number was given. */
1982 party_a_number.presentation = cc_record->party_a.number.presentation;
1983 if (q931_party_number_cmp(&party_a_number, &cc_record->party_a.number)) {
1984 /* Record party A does not match. */
1985 continue;
1986 }
1987 }
1988
1989 /* Add call information to the CallDetails list. */
1990 q931_copy_call_information_to_etsi_rose(ctrl,
1991 &msg.args.etsi.CCBSInterrogate.call_details.list[idx], cc_record);
1992
1993 ++idx;
1994 if (ARRAY_LEN(msg.args.etsi.CCBSInterrogate.call_details.list) <= idx) {
1995 /* List is full. */
1996 break;
1997 }
1998 }
1999 msg.args.etsi.CCBSInterrogate.call_details.num_records = idx;
2000
2001 new_pos = rose_encode_result(ctrl, pos, end, &msg);
2002
2003 /* Reduce the CallDetails list until it fits into the given buffer. */
2004 while (!new_pos && msg.args.etsi.CCBSInterrogate.call_details.num_records) {
2005 --msg.args.etsi.CCBSInterrogate.call_details.num_records;
2006 new_pos = rose_encode_result(ctrl, pos, end, &msg);
2007 }
2008
2009 return new_pos;
2010 }
2011
2012 /*!
2013 * \internal
2014 * \brief Encode and queue a specific CCBSInterrogate/CCNRInterrogate result message.
2015 *
2016 * \param ctrl D channel controller for diagnostic messages or global options.
2017 * \param call Call leg from which to encode CCBSInterrogate/CCNRInterrogate response.
2018 * \param invoke Decoded ROSE invoke message contents.
2019 * \param cc_record Call completion record to process event.
2020 *
2021 * \retval 0 on success.
2022 * \retval -1 on error.
2023 */
rose_cc_interrogate_rsp_specific(struct pri * ctrl,q931_call * call,const struct rose_msg_invoke * invoke,const struct pri_cc_record * cc_record)2024 static int rose_cc_interrogate_rsp_specific(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke, const struct pri_cc_record *cc_record)
2025 {
2026 unsigned char buffer[256];
2027 unsigned char *end;
2028
2029 end =
2030 enc_etsi_ptmp_cc_interrogate_rsp_specific(ctrl, buffer, buffer + sizeof(buffer),
2031 invoke, cc_record);
2032 if (!end) {
2033 return -1;
2034 }
2035
2036 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
2037 }
2038
2039 /*!
2040 * \internal
2041 * \brief Encode and queue a general CCBSInterrogate/CCNRInterrogate result message.
2042 *
2043 * \param ctrl D channel controller for diagnostic messages or global options.
2044 * \param call Call leg from which to encode CCBSInterrogate/CCNRInterrogate response.
2045 * \param invoke Decoded ROSE invoke message contents.
2046 *
2047 * \retval 0 on success.
2048 * \retval -1 on error.
2049 */
rose_cc_interrogate_rsp_general(struct pri * ctrl,q931_call * call,const struct rose_msg_invoke * invoke)2050 static int rose_cc_interrogate_rsp_general(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke)
2051 {
2052 unsigned char buffer[256];
2053 unsigned char *end;
2054
2055 end =
2056 enc_etsi_ptmp_cc_interrogate_rsp_general(ctrl, buffer, buffer + sizeof(buffer),
2057 invoke);
2058 if (!end) {
2059 return -1;
2060 }
2061
2062 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
2063 }
2064
2065 /*!
2066 * \brief Respond to the received CCBSInterrogate/CCNRInterrogate invoke message.
2067 *
2068 * \param ctrl D channel controller for diagnostic messages or global options.
2069 * \param call Call leg from which the message came.
2070 * \param invoke Decoded ROSE invoke message contents.
2071 *
2072 * \retval 0 on success.
2073 * \retval -1 on error.
2074 */
pri_cc_interrogate_rsp(struct pri * ctrl,q931_call * call,const struct rose_msg_invoke * invoke)2075 int pri_cc_interrogate_rsp(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke)
2076 {
2077 int encode_result;
2078
2079 if (!ctrl->cc_support) {
2080 /* Call completion is disabled. */
2081 return send_facility_error(ctrl, call, invoke->invoke_id,
2082 ROSE_ERROR_Gen_NotSubscribed);
2083 }
2084
2085 if (invoke->args.etsi.CCBSInterrogate.ccbs_reference_present) {
2086 struct pri_cc_record *cc_record;
2087
2088 /* Specific CC request interrogation. */
2089 cc_record = pri_cc_find_by_reference(ctrl,
2090 invoke->args.etsi.CCBSInterrogate.ccbs_reference);
2091 if (!cc_record
2092 || ((!cc_record->is_ccnr)
2093 == (invoke->operation == ROSE_ETSI_CCBSInterrogate))) {
2094 /* Record does not exist or is not for the requested CCBS/CCNR mode. */
2095 return send_facility_error(ctrl, call, invoke->invoke_id,
2096 ROSE_ERROR_CCBS_InvalidCCBSReference);
2097 }
2098 encode_result = rose_cc_interrogate_rsp_specific(ctrl, call, invoke, cc_record);
2099 } else {
2100 /* General CC request interrogation. */
2101 encode_result = rose_cc_interrogate_rsp_general(ctrl, call, invoke);
2102 }
2103
2104 if (encode_result || q931_facility(ctrl, call)) {
2105 pri_message(ctrl,
2106 "Could not schedule facility message for cc-interrogate.\n");
2107 return -1;
2108 }
2109
2110 return 0;
2111 }
2112
2113 /*!
2114 * \brief Respond to the received PTMP CCBSRequest/CCNRRequest invoke message.
2115 *
2116 * \param ctrl D channel controller for diagnostic messages or global options.
2117 * \param call Call leg from which the message came.
2118 * \param invoke Decoded ROSE invoke message contents.
2119 *
2120 * \return Nothing
2121 */
pri_cc_ptmp_request(struct pri * ctrl,q931_call * call,const struct rose_msg_invoke * invoke)2122 void pri_cc_ptmp_request(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke)
2123 {
2124 struct pri_cc_record *cc_record;
2125
2126 if (!ctrl->cc_support) {
2127 /* Call completion is disabled. */
2128 send_facility_error(ctrl, call, invoke->invoke_id,
2129 ROSE_ERROR_Gen_NotSubscribed);
2130 return;
2131 }
2132 cc_record = pri_cc_find_by_linkage(ctrl,
2133 invoke->args.etsi.CCBSRequest.call_linkage_id);
2134 if (!cc_record) {
2135 send_facility_error(ctrl, call, invoke->invoke_id,
2136 ROSE_ERROR_CCBS_InvalidCallLinkageID);
2137 return;
2138 }
2139 if (cc_record->state != CC_STATE_AVAILABLE) {
2140 send_facility_error(ctrl, call, invoke->invoke_id,
2141 ROSE_ERROR_CCBS_IsAlreadyActivated);
2142 return;
2143 }
2144 cc_record->ccbs_reference_id = pri_cc_new_reference_id(ctrl);
2145 if (cc_record->ccbs_reference_id == CC_PTMP_INVALID_ID) {
2146 /* Could not allocate a call reference id. */
2147 send_facility_error(ctrl, call, invoke->invoke_id,
2148 ROSE_ERROR_CCBS_OutgoingCCBSQueueFull);
2149 return;
2150 }
2151
2152 /* Save off data to know how to send back any response. */
2153 cc_record->response.signaling = call;
2154 cc_record->response.invoke_operation = invoke->operation;
2155 cc_record->response.invoke_id = invoke->invoke_id;
2156
2157 /* Set the requested CC mode. */
2158 cc_record->is_ccnr = (invoke->operation == ROSE_ETSI_CCNRRequest) ? 1 : 0;
2159
2160 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST);
2161 }
2162
2163 /*!
2164 * \brief Respond to the received PTP CCBS_T_Request/CCNR_T_Request invoke message.
2165 *
2166 * \param ctrl D channel controller for diagnostic messages or global options.
2167 * \param call Call leg from which the message came.
2168 * \param msgtype Q.931 message type ie is in.
2169 * \param invoke Decoded ROSE invoke message contents.
2170 *
2171 * \return Nothing
2172 */
pri_cc_ptp_request(struct pri * ctrl,q931_call * call,int msgtype,const struct rose_msg_invoke * invoke)2173 void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke)
2174 {
2175 struct pri_cc_record *cc_record;
2176 struct q931_party_address party_a;
2177 struct q931_party_address party_b;
2178
2179 if (msgtype != Q931_REGISTER) {
2180 /* Ignore CC request message since it did not come in on the correct message. */
2181 return;
2182 }
2183 if (!ctrl->cc_support) {
2184 /* Call completion is disabled. */
2185 rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
2186 ROSE_ERROR_Gen_NotSubscribed);
2187 call->cc.hangup_call = 1;
2188 return;
2189 }
2190
2191 q931_party_address_init(&party_a);
2192 if (invoke->args.etsi.CCBS_T_Request.originating.number.length) {
2193 /* The originating number is present. */
2194 rose_copy_address_to_q931(ctrl, &party_a,
2195 &invoke->args.etsi.CCBS_T_Request.originating);
2196 }
2197 q931_party_address_init(&party_b);
2198 rose_copy_address_to_q931(ctrl, &party_b,
2199 &invoke->args.etsi.CCBS_T_Request.destination);
2200 cc_record = pri_cc_find_by_addressing(ctrl, &party_a, &party_b,
2201 invoke->args.etsi.CCBS_T_Request.q931ie.length,
2202 invoke->args.etsi.CCBS_T_Request.q931ie.contents);
2203 if (!cc_record || cc_record->state != CC_STATE_AVAILABLE) {
2204 /* Could not find the record or already activated */
2205 rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
2206 ROSE_ERROR_CCBS_T_ShortTermDenial);
2207 call->cc.hangup_call = 1;
2208 return;
2209 }
2210
2211 /*
2212 * We already have the presentationAllowedIndicator in the cc_record
2213 * when we saved the original call information.
2214 */
2215 #if 0
2216 if (invoke->args.etsi.CCBS_T_Request.presentation_allowed_indicator_present) {
2217 if (invoke->args.etsi.CCBS_T_Request.presentation_allowed_indicator) {
2218 if (party_a.number.str[0]) {
2219 party_a.number.presentation =
2220 PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
2221 } else {
2222 party_a.number.presentation = PRES_NUMBER_NOT_AVAILABLE;
2223 }
2224 } else {
2225 party_a.number.presentation =
2226 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
2227 }
2228 }
2229 #endif
2230
2231 /* Link the signaling link to the cc_record. */
2232 call->cc.record = cc_record;
2233 cc_record->signaling = call;
2234
2235 /* Save off data to know how to send back any response. */
2236 //cc_record->response.signaling = call;
2237 cc_record->response.invoke_operation = invoke->operation;
2238 cc_record->response.invoke_id = invoke->invoke_id;
2239
2240 /* Set the requested CC mode. */
2241 cc_record->is_ccnr = (invoke->operation == ROSE_ETSI_CCNR_T_Request) ? 1 : 0;
2242
2243 /* Lets keep this signaling link around for awhile. */
2244 call->cis_recognized = 1;
2245
2246 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST);
2247 }
2248
2249 /*!
2250 * \brief Respond to the received Q.SIG ccbsRequest/ccnrRequest invoke message.
2251 *
2252 * \param ctrl D channel controller for diagnostic messages or global options.
2253 * \param call Call leg from which the message came.
2254 * \param msgtype Q.931 message type ie is in.
2255 * \param invoke Decoded ROSE invoke message contents.
2256 *
2257 * \return Nothing
2258 */
pri_cc_qsig_request(struct pri * ctrl,q931_call * call,int msgtype,const struct rose_msg_invoke * invoke)2259 void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke)
2260 {
2261 struct pri_cc_record *cc_record;
2262 struct q931_party_address party_a;
2263 struct q931_party_address party_b;
2264
2265 if (msgtype != Q931_SETUP) {
2266 /* Ignore CC request message since it did not come in on the correct message. */
2267 return;
2268 }
2269 if (!ctrl->cc_support) {
2270 /* Call completion is disabled. */
2271 rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
2272 ROSE_ERROR_QSIG_LongTermRejection);
2273 call->cc.hangup_call = 1;
2274 return;
2275 }
2276
2277 /* Extract Party A address. */
2278 rose_copy_presented_number_unscreened_to_q931(ctrl, &party_a.number,
2279 &invoke->args.qsig.CcbsRequest.number_a);
2280 q931_party_subaddress_init(&party_a.subaddress);
2281 rose_copy_subaddress_to_q931(ctrl, &party_a.subaddress,
2282 &invoke->args.qsig.CcbsRequest.subaddr_a);
2283
2284 /* Extract Party B address. */
2285 q931_party_address_init(&party_b);
2286 rose_copy_number_to_q931(ctrl, &party_b.number,
2287 &invoke->args.qsig.CcbsRequest.number_b);
2288 rose_copy_subaddress_to_q931(ctrl, &party_b.subaddress,
2289 &invoke->args.qsig.CcbsRequest.subaddr_b);
2290
2291 cc_record = pri_cc_find_by_addressing(ctrl, &party_a, &party_b,
2292 invoke->args.qsig.CcbsRequest.q931ie.length,
2293 invoke->args.qsig.CcbsRequest.q931ie.contents);
2294 if (!cc_record || cc_record->state != CC_STATE_AVAILABLE) {
2295 /* Could not find the record or already activated */
2296 rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
2297 ROSE_ERROR_QSIG_ShortTermRejection);
2298 call->cc.hangup_call = 1;
2299 return;
2300 }
2301
2302 /* Determine negotiated signaling retention method. */
2303 if (invoke->args.qsig.CcbsRequest.retain_sig_connection_present) {
2304 /* We will do what the originator desires. */
2305 cc_record->option.retain_signaling_link =
2306 invoke->args.qsig.CcbsRequest.retain_sig_connection;
2307 } else {
2308 /* The originator does not care. Do how we are configured. */
2309 cc_record->option.retain_signaling_link =
2310 ctrl->cc.option.signaling_retention_rsp;
2311 }
2312 if (!cc_record->party_a.number.valid || cc_record->party_a.number.str[0] == '\0') {
2313 /*
2314 * Party A number is not available for us to initiate
2315 * a signaling link. We must retain the signaling link.
2316 */
2317 cc_record->option.retain_signaling_link = 1;
2318 }
2319
2320 /* Link the signaling link to the cc_record. */
2321 call->cc.record = cc_record;
2322 cc_record->signaling = call;
2323
2324 /* Save off data to know how to send back any response. */
2325 //cc_record->response.signaling = call;
2326 cc_record->response.invoke_operation = invoke->operation;
2327 cc_record->response.invoke_id = invoke->invoke_id;
2328
2329 /* Set the requested CC mode. */
2330 cc_record->is_ccnr = (invoke->operation == ROSE_QSIG_CcnrRequest) ? 1 : 0;
2331
2332 /* Lets keep this signaling link around for awhile. */
2333 call->cis_recognized = 1;
2334
2335 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST);
2336 }
2337
2338 /*!
2339 * \brief Handle the received Q.SIG ccCancel invoke message.
2340 *
2341 * \param ctrl D channel controller for diagnostic messages or global options.
2342 * \param call Call leg from which the message came.
2343 * \param msgtype Q.931 message type ie is in.
2344 * \param invoke Decoded ROSE invoke message contents.
2345 *
2346 * \return Nothing
2347 */
pri_cc_qsig_cancel(struct pri * ctrl,q931_call * call,int msgtype,const struct rose_msg_invoke * invoke)2348 void pri_cc_qsig_cancel(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke)
2349 {
2350 struct pri_cc_record *cc_record;
2351 struct q931_party_address party_a;
2352 struct q931_party_address party_b;
2353
2354 cc_record = call->cc.record;
2355 if (!cc_record) {
2356 /* The current call is not associated with the cc_record. */
2357 if (invoke->args.qsig.CcCancel.full_arg_present) {
2358 /* Extract Party A address. */
2359 q931_party_address_init(&party_a);
2360 rose_copy_number_to_q931(ctrl, &party_a.number,
2361 &invoke->args.qsig.CcCancel.number_a);
2362 rose_copy_subaddress_to_q931(ctrl, &party_a.subaddress,
2363 &invoke->args.qsig.CcCancel.subaddr_a);
2364
2365 /* Extract Party B address. */
2366 q931_party_address_init(&party_b);
2367 rose_copy_number_to_q931(ctrl, &party_b.number,
2368 &invoke->args.qsig.CcCancel.number_b);
2369 rose_copy_subaddress_to_q931(ctrl, &party_b.subaddress,
2370 &invoke->args.qsig.CcCancel.subaddr_b);
2371
2372 cc_record = pri_cc_find_by_addressing(ctrl, &party_a, &party_b,
2373 invoke->args.qsig.CcCancel.q931ie.length,
2374 invoke->args.qsig.CcCancel.q931ie.contents);
2375 }
2376 if (!cc_record) {
2377 /*
2378 * Could not find the cc_record
2379 * or not enough information to look up a cc_record.
2380 */
2381 if (msgtype == Q931_SETUP) {
2382 call->cc.hangup_call = 1;
2383 }
2384 return;
2385 }
2386 }
2387
2388 if (msgtype == Q931_SETUP && call->cis_call) {
2389 if (cc_record->signaling) {
2390 /*
2391 * We already have a signaling link.
2392 * This could be a collision with our ccExecPossible.
2393 * Could this be an alias match?
2394 */
2395 switch (cc_record->state) {
2396 case CC_STATE_WAIT_CALLBACK:
2397 if (ctrl->debug & PRI_DEBUG_CC) {
2398 pri_message(ctrl,
2399 "-- Collision with our ccExecPossible event call. Canceling CC.\n");
2400 }
2401 break;
2402 default:
2403 pri_message(ctrl,
2404 "-- Warning: Possible Q.SIG CC alias match. Canceling CC.\n");
2405 break;
2406 }
2407 cc_record->fsm.qsig.msgtype = msgtype;
2408 pri_cc_event(ctrl, call, cc_record, CC_EVENT_LINK_CANCEL);
2409
2410 call->cc.hangup_call = 1;
2411 return;
2412 }
2413
2414 /* Link the signaling link to the cc_record. */
2415 call->cc.record = cc_record;
2416 cc_record->signaling = call;
2417
2418 /* Lets keep this signaling link around for awhile. */
2419 call->cis_recognized = 1;
2420 }
2421
2422 cc_record->fsm.qsig.msgtype = msgtype;
2423 pri_cc_event(ctrl, call, cc_record, CC_EVENT_LINK_CANCEL);
2424 }
2425
2426 /*!
2427 * \brief Handle the received Q.SIG ccExecPossible invoke message.
2428 *
2429 * \param ctrl D channel controller for diagnostic messages or global options.
2430 * \param call Call leg from which the message came.
2431 * \param msgtype Q.931 message type ie is in.
2432 * \param invoke Decoded ROSE invoke message contents.
2433 *
2434 * \return Nothing
2435 */
pri_cc_qsig_exec_possible(struct pri * ctrl,q931_call * call,int msgtype,const struct rose_msg_invoke * invoke)2436 void pri_cc_qsig_exec_possible(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke)
2437 {
2438 struct pri_cc_record *cc_record;
2439 struct q931_party_address party_a;
2440 struct q931_party_address party_b;
2441
2442 cc_record = call->cc.record;
2443 if (!cc_record) {
2444 /* The current call is not associated with the cc_record. */
2445 if (invoke->args.qsig.CcExecPossible.full_arg_present) {
2446 /* Extract Party A address. */
2447 q931_party_address_init(&party_a);
2448 rose_copy_number_to_q931(ctrl, &party_a.number,
2449 &invoke->args.qsig.CcExecPossible.number_a);
2450 rose_copy_subaddress_to_q931(ctrl, &party_a.subaddress,
2451 &invoke->args.qsig.CcExecPossible.subaddr_a);
2452
2453 /* Extract Party B address. */
2454 q931_party_address_init(&party_b);
2455 rose_copy_number_to_q931(ctrl, &party_b.number,
2456 &invoke->args.qsig.CcExecPossible.number_b);
2457 rose_copy_subaddress_to_q931(ctrl, &party_b.subaddress,
2458 &invoke->args.qsig.CcExecPossible.subaddr_b);
2459
2460 cc_record = pri_cc_find_by_addressing(ctrl, &party_a, &party_b,
2461 invoke->args.qsig.CcExecPossible.q931ie.length,
2462 invoke->args.qsig.CcExecPossible.q931ie.contents);
2463 }
2464 if (!cc_record) {
2465 /*
2466 * Could not find the cc_record
2467 * or not enough information to look up a cc_record.
2468 */
2469 rose_cc_cancel(ctrl, call, NULL, Q931_ANY_MESSAGE);
2470 if (msgtype == Q931_SETUP) {
2471 call->cc.hangup_call = 1;
2472 } else {
2473 /* msgtype should be Q931_FACILITY. */
2474 pri_hangup(ctrl, call, -1);
2475 }
2476 return;
2477 }
2478 }
2479
2480 if (msgtype == Q931_SETUP && call->cis_call) {
2481 if (cc_record->signaling) {
2482 /*
2483 * We already have a signaling link. This should not happen.
2484 * Could this be an alias match?
2485 */
2486 pri_message(ctrl,
2487 "-- Warning: Possible Q.SIG CC alias match. Sending ccCancel back.\n");
2488 rose_cc_cancel(ctrl, call, NULL, Q931_ANY_MESSAGE);
2489 call->cc.hangup_call = 1;
2490 return;
2491 }
2492
2493 /* Link the signaling link to the cc_record. */
2494 call->cc.record = cc_record;
2495 cc_record->signaling = call;
2496
2497 /* Lets keep this signaling link around for awhile. */
2498 call->cis_recognized = 1;
2499 }
2500
2501 cc_record->fsm.qsig.msgtype = msgtype;
2502 pri_cc_event(ctrl, call, cc_record, CC_EVENT_REMOTE_USER_FREE);
2503 }
2504
2505 /*!
2506 * \brief Convert the given call completion state to a string.
2507 *
2508 * \param state CC state to convert to string.
2509 *
2510 * \return String version of call completion state.
2511 */
pri_cc_fsm_state_str(enum CC_STATES state)2512 const char *pri_cc_fsm_state_str(enum CC_STATES state)
2513 {
2514 const char *str;
2515
2516 str = "Unknown";
2517 switch (state) {
2518 case CC_STATE_IDLE:
2519 str = "CC_STATE_IDLE";
2520 break;
2521 case CC_STATE_PENDING_AVAILABLE:
2522 str = "CC_STATE_PENDING_AVAILABLE";
2523 break;
2524 case CC_STATE_AVAILABLE:
2525 str = "CC_STATE_AVAILABLE";
2526 break;
2527 case CC_STATE_REQUESTED:
2528 str = "CC_STATE_REQUESTED";
2529 break;
2530 case CC_STATE_ACTIVATED:
2531 str = "CC_STATE_ACTIVATED";
2532 break;
2533 case CC_STATE_B_AVAILABLE:
2534 str = "CC_STATE_B_AVAILABLE";
2535 break;
2536 case CC_STATE_SUSPENDED:
2537 str = "CC_STATE_SUSPENDED";
2538 break;
2539 case CC_STATE_WAIT_CALLBACK:
2540 str = "CC_STATE_WAIT_CALLBACK";
2541 break;
2542 case CC_STATE_CALLBACK:
2543 str = "CC_STATE_CALLBACK";
2544 break;
2545 case CC_STATE_WAIT_DESTRUCTION:
2546 str = "CC_STATE_WAIT_DESTRUCTION";
2547 break;
2548 case CC_STATE_NUM:
2549 /* Not a real state. */
2550 break;
2551 }
2552 return str;
2553 }
2554
2555 /*!
2556 * \brief Convert the given call completion event to a string.
2557 *
2558 * \param event CC event to convert to string.
2559 *
2560 * \return String version of call completion event.
2561 */
pri_cc_fsm_event_str(enum CC_EVENTS event)2562 const char *pri_cc_fsm_event_str(enum CC_EVENTS event)
2563 {
2564 const char *str;
2565
2566 str = "Unknown";
2567 switch (event) {
2568 case CC_EVENT_AVAILABLE:
2569 str = "CC_EVENT_AVAILABLE";
2570 break;
2571 case CC_EVENT_CC_REQUEST:
2572 str = "CC_EVENT_CC_REQUEST";
2573 break;
2574 case CC_EVENT_CC_REQUEST_ACCEPT:
2575 str = "CC_EVENT_CC_REQUEST_ACCEPT";
2576 break;
2577 case CC_EVENT_CC_REQUEST_FAIL:
2578 str = "CC_EVENT_CC_REQUEST_FAIL";
2579 break;
2580 case CC_EVENT_REMOTE_USER_FREE:
2581 str = "CC_EVENT_REMOTE_USER_FREE";
2582 break;
2583 case CC_EVENT_B_FREE:
2584 str = "CC_EVENT_B_FREE";
2585 break;
2586 case CC_EVENT_STOP_ALERTING:
2587 str = "CC_EVENT_STOP_ALERTING";
2588 break;
2589 case CC_EVENT_A_STATUS:
2590 str = "CC_EVENT_A_STATUS";
2591 break;
2592 case CC_EVENT_A_FREE:
2593 str = "CC_EVENT_A_FREE";
2594 break;
2595 case CC_EVENT_A_BUSY:
2596 str = "CC_EVENT_A_BUSY";
2597 break;
2598 case CC_EVENT_SUSPEND:
2599 str = "CC_EVENT_SUSPEND";
2600 break;
2601 case CC_EVENT_RESUME:
2602 str = "CC_EVENT_RESUME";
2603 break;
2604 case CC_EVENT_RECALL:
2605 str = "CC_EVENT_RECALL";
2606 break;
2607 case CC_EVENT_LINK_CANCEL:
2608 str = "CC_EVENT_LINK_CANCEL";
2609 break;
2610 case CC_EVENT_CANCEL:
2611 str = "CC_EVENT_CANCEL";
2612 break;
2613 case CC_EVENT_INTERNAL_CLEARING:
2614 str = "CC_EVENT_INTERNAL_CLEARING";
2615 break;
2616 case CC_EVENT_SIGNALING_GONE:
2617 str = "CC_EVENT_SIGNALING_GONE";
2618 break;
2619 case CC_EVENT_HANGUP_SIGNALING:
2620 str = "CC_EVENT_HANGUP_SIGNALING";
2621 break;
2622 case CC_EVENT_MSG_ALERTING:
2623 str = "CC_EVENT_MSG_ALERTING";
2624 break;
2625 case CC_EVENT_MSG_DISCONNECT:
2626 str = "CC_EVENT_MSG_DISCONNECT";
2627 break;
2628 case CC_EVENT_MSG_RELEASE:
2629 str = "CC_EVENT_MSG_RELEASE";
2630 break;
2631 case CC_EVENT_MSG_RELEASE_COMPLETE:
2632 str = "CC_EVENT_MSG_RELEASE_COMPLETE";
2633 break;
2634 case CC_EVENT_TIMEOUT_T_ACTIVATE:
2635 str = "CC_EVENT_TIMEOUT_T_ACTIVATE";
2636 break;
2637 #if 0
2638 case CC_EVENT_TIMEOUT_T_DEACTIVATE:
2639 str = "CC_EVENT_TIMEOUT_T_DEACTIVATE";
2640 break;
2641 case CC_EVENT_TIMEOUT_T_INTERROGATE:
2642 str = "CC_EVENT_TIMEOUT_T_INTERROGATE";
2643 break;
2644 #endif
2645 case CC_EVENT_TIMEOUT_T_RETENTION:
2646 str = "CC_EVENT_TIMEOUT_T_RETENTION";
2647 break;
2648 case CC_EVENT_TIMEOUT_T_CCBS1:
2649 str = "CC_EVENT_TIMEOUT_T_CCBS1";
2650 break;
2651 case CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1:
2652 str = "CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1";
2653 break;
2654 case CC_EVENT_TIMEOUT_T_SUPERVISION:
2655 str = "CC_EVENT_TIMEOUT_T_SUPERVISION";
2656 break;
2657 case CC_EVENT_TIMEOUT_T_RECALL:
2658 str = "CC_EVENT_TIMEOUT_T_RECALL";
2659 break;
2660 }
2661 return str;
2662 }
2663
2664 static const char pri_cc_act_header[] = "%ld CC-Act: %s\n";
2665 #define PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_id) \
2666 if ((ctrl)->debug & PRI_DEBUG_CC) { \
2667 pri_message((ctrl), pri_cc_act_header, (cc_id), __FUNCTION__); \
2668 }
2669
2670 /*!
2671 * \internal
2672 * \brief FSM action to mark FSM for destruction.
2673 *
2674 * \param ctrl D channel controller.
2675 * \param cc_record Call completion record to process event.
2676 *
2677 * \return Nothing
2678 */
pri_cc_act_set_self_destruct(struct pri * ctrl,struct pri_cc_record * cc_record)2679 static void pri_cc_act_set_self_destruct(struct pri *ctrl, struct pri_cc_record *cc_record)
2680 {
2681 #if defined(CC_SANITY_CHECKS)
2682 struct apdu_event *msg;
2683 #endif /* defined(CC_SANITY_CHECKS) */
2684
2685 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2686
2687 /* Abort any pending indirect events. */
2688 pri_schedule_del(ctrl, cc_record->t_indirect);
2689 cc_record->t_indirect = 0;
2690
2691 #if defined(CC_SANITY_CHECKS)
2692 if (cc_record->t_retention) {
2693 pri_error(ctrl, "T_RETENTION still active");
2694 pri_schedule_del(ctrl, cc_record->t_retention);
2695 cc_record->t_retention = 0;
2696 }
2697 if (cc_record->t_supervision) {
2698 pri_error(ctrl, "T_SUPERVISION still active");
2699 pri_schedule_del(ctrl, cc_record->t_supervision);
2700 cc_record->t_supervision = 0;
2701 }
2702 if (cc_record->t_recall) {
2703 pri_error(ctrl, "T_RECALL still active");
2704 pri_schedule_del(ctrl, cc_record->t_recall);
2705 cc_record->t_recall = 0;
2706 }
2707 if (PTMP_MODE(ctrl)) {
2708 msg = pri_call_apdu_find(cc_record->signaling,
2709 cc_record->fsm.ptmp.t_ccbs1_invoke_id);
2710 if (msg) {
2711 pri_error(ctrl, "T_CCBS1 still active");
2712 cc_record->fsm.ptmp.t_ccbs1_invoke_id = APDU_INVALID_INVOKE_ID;
2713 pri_call_apdu_delete(cc_record->signaling, msg);
2714 }
2715 if (cc_record->fsm.ptmp.extended_t_ccbs1) {
2716 pri_error(ctrl, "Extended T_CCBS1 still active");
2717 pri_schedule_del(ctrl, cc_record->fsm.ptmp.extended_t_ccbs1);
2718 cc_record->fsm.ptmp.extended_t_ccbs1 = 0;
2719 }
2720 }
2721 if (cc_record->signaling) {
2722 msg = pri_call_apdu_find(cc_record->signaling, cc_record->t_activate_invoke_id);
2723 if (msg) {
2724 pri_error(ctrl, "T_ACTIVATE still active");
2725 cc_record->t_activate_invoke_id = APDU_INVALID_INVOKE_ID;
2726 pri_call_apdu_delete(cc_record->signaling, msg);
2727 }
2728 }
2729 #endif /* defined(CC_SANITY_CHECKS) */
2730
2731 cc_record->fsm_complete = 1;
2732 }
2733
2734 /*!
2735 * \internal
2736 * \brief FSM action to disassociate the signaling link from the cc_record.
2737 *
2738 * \param ctrl D channel controller.
2739 * \param cc_record Call completion record to process event.
2740 *
2741 * \return Nothing
2742 */
pri_cc_act_disassociate_signaling_link(struct pri * ctrl,struct pri_cc_record * cc_record)2743 static void pri_cc_act_disassociate_signaling_link(struct pri *ctrl, struct pri_cc_record *cc_record)
2744 {
2745 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2746 pri_cc_disassociate_signaling_link(cc_record);
2747 }
2748
2749 /*!
2750 * \internal
2751 * \brief FSM action to send CC available message.
2752 *
2753 * \param ctrl D channel controller.
2754 * \param cc_record Call completion record to process event.
2755 * \param call Q.931 call leg.
2756 * \param msgtype Q.931 message type to put facility ie in.
2757 *
2758 * \return Nothing
2759 */
pri_cc_act_send_cc_available(struct pri * ctrl,struct pri_cc_record * cc_record,q931_call * call,int msgtype)2760 static void pri_cc_act_send_cc_available(struct pri *ctrl, struct pri_cc_record *cc_record, q931_call *call, int msgtype)
2761 {
2762 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2763 rose_cc_available_encode(ctrl, call, cc_record, msgtype);
2764 }
2765
2766 /*!
2767 * \internal
2768 * \brief FSM action to stop the PTMP T_RETENTION timer.
2769 *
2770 * \param ctrl D channel controller.
2771 * \param cc_record Call completion record to process event.
2772 *
2773 * \return Nothing
2774 */
pri_cc_act_stop_t_retention(struct pri * ctrl,struct pri_cc_record * cc_record)2775 static void pri_cc_act_stop_t_retention(struct pri *ctrl, struct pri_cc_record *cc_record)
2776 {
2777 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2778 pri_schedule_del(ctrl, cc_record->t_retention);
2779 cc_record->t_retention = 0;
2780 }
2781
2782 /*!
2783 * \internal
2784 * \brief T_RETENTION timeout callback.
2785 *
2786 * \param data CC record pointer.
2787 *
2788 * \return Nothing
2789 */
pri_cc_timeout_t_retention(void * data)2790 static void pri_cc_timeout_t_retention(void *data)
2791 {
2792 struct pri_cc_record *cc_record = data;
2793
2794 cc_record->t_retention = 0;
2795 q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
2796 }
2797
2798 /*!
2799 * \internal
2800 * \brief FSM action to start the PTMP T_RETENTION timer.
2801 *
2802 * \param ctrl D channel controller.
2803 * \param cc_record Call completion record to process event.
2804 *
2805 * \return Nothing
2806 */
pri_cc_act_start_t_retention(struct pri * ctrl,struct pri_cc_record * cc_record)2807 static void pri_cc_act_start_t_retention(struct pri *ctrl, struct pri_cc_record *cc_record)
2808 {
2809 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2810 if (cc_record->t_retention) {
2811 pri_error(ctrl, "!! T_RETENTION is already running!");
2812 pri_schedule_del(ctrl, cc_record->t_retention);
2813 }
2814 cc_record->t_retention = pri_schedule_event(ctrl,
2815 ctrl->timers[PRI_TIMER_T_RETENTION], pri_cc_timeout_t_retention, cc_record);
2816 }
2817
2818 /*!
2819 * \internal
2820 * \brief FSM action to stop the PTMP EXTENDED_T_CCBS1 timer.
2821 *
2822 * \param ctrl D channel controller.
2823 * \param cc_record Call completion record to process event.
2824 *
2825 * \return Nothing
2826 */
pri_cc_act_stop_extended_t_ccbs1(struct pri * ctrl,struct pri_cc_record * cc_record)2827 static void pri_cc_act_stop_extended_t_ccbs1(struct pri *ctrl, struct pri_cc_record *cc_record)
2828 {
2829 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2830 pri_schedule_del(ctrl, cc_record->fsm.ptmp.extended_t_ccbs1);
2831 cc_record->fsm.ptmp.extended_t_ccbs1 = 0;
2832 }
2833
2834 /*!
2835 * \internal
2836 * \brief EXTENDED_T_CCBS1 timeout callback.
2837 *
2838 * \param data CC record pointer.
2839 *
2840 * \return Nothing
2841 */
pri_cc_timeout_extended_t_ccbs1(void * data)2842 static void pri_cc_timeout_extended_t_ccbs1(void *data)
2843 {
2844 struct pri_cc_record *cc_record = data;
2845
2846 cc_record->fsm.ptmp.extended_t_ccbs1 = 0;
2847 q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
2848 }
2849
2850 /*!
2851 * \internal
2852 * \brief FSM action to start the PTMP extended T_CCBS1 timer.
2853 *
2854 * \param ctrl D channel controller.
2855 * \param cc_record Call completion record to process event.
2856 *
2857 * \return Nothing
2858 */
pri_cc_act_start_extended_t_ccbs1(struct pri * ctrl,struct pri_cc_record * cc_record)2859 static void pri_cc_act_start_extended_t_ccbs1(struct pri *ctrl, struct pri_cc_record *cc_record)
2860 {
2861 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2862 if (cc_record->fsm.ptmp.extended_t_ccbs1) {
2863 pri_error(ctrl, "!! Extended T_CCBS1 is already running!");
2864 pri_schedule_del(ctrl, cc_record->fsm.ptmp.extended_t_ccbs1);
2865 }
2866 /* Timeout is T_CCBS1 + 2 seconds. */
2867 cc_record->fsm.ptmp.extended_t_ccbs1 = pri_schedule_event(ctrl,
2868 ctrl->timers[PRI_TIMER_T_CCBS1] + 2000, pri_cc_timeout_extended_t_ccbs1,
2869 cc_record);
2870 }
2871
2872 /*!
2873 * \internal
2874 * \brief FSM action to stop the T_SUPERVISION timer.
2875 *
2876 * \param ctrl D channel controller.
2877 * \param cc_record Call completion record to process event.
2878 *
2879 * \return Nothing
2880 */
pri_cc_act_stop_t_supervision(struct pri * ctrl,struct pri_cc_record * cc_record)2881 static void pri_cc_act_stop_t_supervision(struct pri *ctrl, struct pri_cc_record *cc_record)
2882 {
2883 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2884 pri_schedule_del(ctrl, cc_record->t_supervision);
2885 cc_record->t_supervision = 0;
2886 }
2887
2888 /*!
2889 * \internal
2890 * \brief T_SUPERVISION timeout callback.
2891 *
2892 * \param data CC record pointer.
2893 *
2894 * \return Nothing
2895 */
pri_cc_timeout_t_supervision(void * data)2896 static void pri_cc_timeout_t_supervision(void *data)
2897 {
2898 struct pri_cc_record *cc_record = data;
2899
2900 cc_record->t_supervision = 0;
2901 q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
2902 }
2903
2904 /*!
2905 * \internal
2906 * \brief FSM action to start the T_SUPERVISION timer.
2907 *
2908 * \param ctrl D channel controller.
2909 * \param cc_record Call completion record to process event.
2910 *
2911 * \return Nothing
2912 */
pri_cc_act_start_t_supervision(struct pri * ctrl,struct pri_cc_record * cc_record)2913 static void pri_cc_act_start_t_supervision(struct pri *ctrl, struct pri_cc_record *cc_record)
2914 {
2915 int timer_id;
2916 int duration;
2917
2918 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2919 if (cc_record->t_supervision) {
2920 pri_error(ctrl, "!! A CC supervision timer is already running!");
2921 pri_schedule_del(ctrl, cc_record->t_supervision);
2922 }
2923 switch (ctrl->switchtype) {
2924 case PRI_SWITCH_EUROISDN_E1:
2925 case PRI_SWITCH_EUROISDN_T1:
2926 if (PTMP_MODE(ctrl)) {
2927 /* ETSI PTMP mode. */
2928 timer_id = cc_record->is_ccnr ? PRI_TIMER_T_CCNR2 : PRI_TIMER_T_CCBS2;
2929 } else if (cc_record->is_agent) {
2930 /* ETSI PTP mode network B side. */
2931 timer_id = cc_record->is_ccnr ? PRI_TIMER_T_CCNR5 : PRI_TIMER_T_CCBS5;
2932 } else {
2933 /* ETSI PTP mode network A side. */
2934 timer_id = cc_record->is_ccnr ? PRI_TIMER_T_CCNR6 : PRI_TIMER_T_CCBS6;
2935 }
2936 duration = ctrl->timers[timer_id];
2937 break;
2938 case PRI_SWITCH_QSIG:
2939 timer_id = cc_record->is_ccnr ? PRI_TIMER_QSIG_CCNR_T2 : PRI_TIMER_QSIG_CCBS_T2;
2940 duration = ctrl->timers[timer_id];
2941 break;
2942 default:
2943 /* Timer not defined for this switch type. Should never happen. */
2944 pri_error(ctrl, "!! A CC supervision timer is not defined!");
2945 duration = 0;
2946 break;
2947 }
2948 cc_record->t_supervision = pri_schedule_event(ctrl, duration,
2949 pri_cc_timeout_t_supervision, cc_record);
2950 }
2951
2952 /*!
2953 * \internal
2954 * \brief FSM action to stop the T_RECALL timer.
2955 *
2956 * \param ctrl D channel controller.
2957 * \param cc_record Call completion record to process event.
2958 *
2959 * \return Nothing
2960 */
pri_cc_act_stop_t_recall(struct pri * ctrl,struct pri_cc_record * cc_record)2961 static void pri_cc_act_stop_t_recall(struct pri *ctrl, struct pri_cc_record *cc_record)
2962 {
2963 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2964 pri_schedule_del(ctrl, cc_record->t_recall);
2965 cc_record->t_recall = 0;
2966 }
2967
2968 /*!
2969 * \internal
2970 * \brief T_RECALL timeout callback.
2971 *
2972 * \param data CC record pointer.
2973 *
2974 * \return Nothing
2975 */
pri_cc_timeout_t_recall(void * data)2976 static void pri_cc_timeout_t_recall(void *data)
2977 {
2978 struct pri_cc_record *cc_record = data;
2979
2980 cc_record->t_recall = 0;
2981 q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
2982 }
2983
2984 /*!
2985 * \internal
2986 * \brief FSM action to start the T_RECALL timer.
2987 *
2988 * \param ctrl D channel controller.
2989 * \param cc_record Call completion record to process event.
2990 *
2991 * \return Nothing
2992 */
pri_cc_act_start_t_recall(struct pri * ctrl,struct pri_cc_record * cc_record)2993 static void pri_cc_act_start_t_recall(struct pri *ctrl, struct pri_cc_record *cc_record)
2994 {
2995 int duration;
2996
2997 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
2998 if (cc_record->t_recall) {
2999 pri_error(ctrl, "!! T_RECALL is already running!");
3000 pri_schedule_del(ctrl, cc_record->t_recall);
3001 }
3002 switch (ctrl->switchtype) {
3003 case PRI_SWITCH_EUROISDN_E1:
3004 case PRI_SWITCH_EUROISDN_T1:
3005 duration = ctrl->timers[PRI_TIMER_T_CCBS3];
3006 break;
3007 case PRI_SWITCH_QSIG:
3008 duration = ctrl->timers[PRI_TIMER_QSIG_CC_T3];
3009 break;
3010 default:
3011 /* Timer not defined for this switch type. Should never happen. */
3012 pri_error(ctrl, "!! A CC recall timer is not defined!");
3013 duration = 0;
3014 break;
3015 }
3016 cc_record->t_recall = pri_schedule_event(ctrl, duration, pri_cc_timeout_t_recall,
3017 cc_record);
3018 }
3019
3020 /*!
3021 * \internal
3022 * \brief FSM action to send the EraseCallLinkageID message.
3023 *
3024 * \param ctrl D channel controller.
3025 * \param cc_record Call completion record to process event.
3026 *
3027 * \return Nothing
3028 */
pri_cc_act_send_erase_call_linkage_id(struct pri * ctrl,struct pri_cc_record * cc_record)3029 static void pri_cc_act_send_erase_call_linkage_id(struct pri *ctrl, struct pri_cc_record *cc_record)
3030 {
3031 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3032 send_erase_call_linkage_id(ctrl, cc_record->signaling, cc_record);
3033 }
3034
3035 /*!
3036 * \internal
3037 * \brief FSM action to send the CCBSErase message.
3038 *
3039 * \param ctrl D channel controller.
3040 * \param cc_record Call completion record to process event.
3041 * \param reason CCBS Erase reason
3042 * normal-unspecified(0), t-CCBS2-timeout(1), t-CCBS3-timeout(2), basic-call-failed(3)
3043 *
3044 * \return Nothing
3045 */
pri_cc_act_send_ccbs_erase(struct pri * ctrl,struct pri_cc_record * cc_record,int reason)3046 static void pri_cc_act_send_ccbs_erase(struct pri *ctrl, struct pri_cc_record *cc_record, int reason)
3047 {
3048 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3049 send_ccbs_erase(ctrl, cc_record->signaling, cc_record, reason);
3050 }
3051
3052 /*!
3053 * \internal
3054 * \brief Find the T_CCBS1 timer/CCBSStatusRequest message.
3055 *
3056 * \param cc_record Call completion record to process event.
3057 *
3058 * \return Facility message pointer or NULL if not active.
3059 */
pri_cc_get_t_ccbs1_status(struct pri_cc_record * cc_record)3060 static struct apdu_event *pri_cc_get_t_ccbs1_status(struct pri_cc_record *cc_record)
3061 {
3062 return pri_call_apdu_find(cc_record->signaling,
3063 cc_record->fsm.ptmp.t_ccbs1_invoke_id);
3064 }
3065
3066 /*!
3067 * \internal
3068 * \brief FSM action to stop the PTMP T_CCBS1 timer.
3069 *
3070 * \param ctrl D channel controller.
3071 * \param cc_record Call completion record to process event.
3072 *
3073 * \return Nothing
3074 */
pri_cc_act_stop_t_ccbs1(struct pri * ctrl,struct pri_cc_record * cc_record)3075 static void pri_cc_act_stop_t_ccbs1(struct pri *ctrl, struct pri_cc_record *cc_record)
3076 {
3077 struct apdu_event *msg;
3078
3079 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3080
3081 msg = pri_call_apdu_find(cc_record->signaling, cc_record->fsm.ptmp.t_ccbs1_invoke_id);
3082 if (msg) {
3083 cc_record->fsm.ptmp.t_ccbs1_invoke_id = APDU_INVALID_INVOKE_ID;
3084 pri_call_apdu_delete(cc_record->signaling, msg);
3085 }
3086 }
3087
3088 /*!
3089 * \internal
3090 * \brief CCBSStatusRequest response callback function.
3091 *
3092 * \param reason Reason callback is called.
3093 * \param ctrl D channel controller.
3094 * \param call Q.931 call leg.
3095 * \param apdu APDU queued entry. Do not change!
3096 * \param msg APDU response message data. (NULL if was not the reason called.)
3097 *
3098 * \return TRUE if no more responses are expected.
3099 */
pri_cc_ccbs_status_response(enum APDU_CALLBACK_REASON reason,struct pri * ctrl,struct q931_call * call,struct apdu_event * apdu,const struct apdu_msg_data * msg)3100 static int pri_cc_ccbs_status_response(enum APDU_CALLBACK_REASON reason, struct pri *ctrl, struct q931_call *call, struct apdu_event *apdu, const struct apdu_msg_data *msg)
3101 {
3102 struct pri_cc_record *cc_record;
3103
3104 cc_record = apdu->response.user.ptr;
3105 switch (reason) {
3106 case APDU_CALLBACK_REASON_ERROR:
3107 cc_record->fsm.ptmp.t_ccbs1_invoke_id = APDU_INVALID_INVOKE_ID;
3108 break;
3109 case APDU_CALLBACK_REASON_TIMEOUT:
3110 cc_record->fsm.ptmp.t_ccbs1_invoke_id = APDU_INVALID_INVOKE_ID;
3111 pri_cc_event(ctrl, call, cc_record, CC_EVENT_TIMEOUT_T_CCBS1);
3112 break;
3113 case APDU_CALLBACK_REASON_MSG_RESULT:
3114 pri_cc_event(ctrl, call, cc_record,
3115 msg->response.result->args.etsi.CCBSStatusRequest.free
3116 ? CC_EVENT_A_FREE : CC_EVENT_A_BUSY);
3117 break;
3118 default:
3119 break;
3120 }
3121 return 0;
3122 }
3123
3124 /*!
3125 * \internal
3126 * \brief Encode and queue an CCBSStatusRequest message.
3127 *
3128 * \param ctrl D channel controller for diagnostic messages or global options.
3129 * \param call Call leg from which to encode CCBSStatusRequest.
3130 * \param cc_record Call completion record to process event.
3131 *
3132 * \retval 0 on success.
3133 * \retval -1 on error.
3134 */
rose_ccbs_status_request(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)3135 static int rose_ccbs_status_request(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
3136 {
3137 unsigned char buffer[256];
3138 unsigned char *end;
3139 struct apdu_callback_data response;
3140
3141 end =
3142 enc_etsi_ptmp_ccbs_status_request(ctrl, buffer, buffer + sizeof(buffer),
3143 cc_record);
3144 if (!end) {
3145 return -1;
3146 }
3147
3148 memset(&response, 0, sizeof(response));
3149 cc_record->fsm.ptmp.t_ccbs1_invoke_id = ctrl->last_invoke;
3150 response.invoke_id = ctrl->last_invoke;
3151 response.timeout_time = ctrl->timers[PRI_TIMER_T_CCBS1];
3152 response.callback = pri_cc_ccbs_status_response;
3153 response.user.ptr = cc_record;
3154 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, &response);
3155 }
3156
3157 /*!
3158 * \internal
3159 * \brief Encode and send an CCBSStatusRequest message.
3160 *
3161 * \param ctrl D channel controller for diagnostic messages or global options.
3162 * \param call Call leg from which to encode CCBSStatusRequest.
3163 * \param cc_record Call completion record to process event.
3164 *
3165 * \retval 0 on success.
3166 * \retval -1 on error.
3167 */
send_ccbs_status_request(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)3168 static int send_ccbs_status_request(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
3169 {
3170 /*
3171 * XXX May need to add called-party-ie with Party A number in FACILITY message. (CCBSStatusRequest)
3172 * ETSI EN 300-195-1 Section 5.41 MSN interaction.
3173 */
3174 if (rose_ccbs_status_request(ctrl, call, cc_record)
3175 || q931_facility(ctrl, call)) {
3176 pri_message(ctrl,
3177 "Could not schedule facility message for CCBSStatusRequest.\n");
3178 return -1;
3179 }
3180
3181 return 0;
3182 }
3183
3184 /*!
3185 * \internal
3186 * \brief FSM action to send the CCBSStatusRequest message.
3187 *
3188 * \param ctrl D channel controller.
3189 * \param cc_record Call completion record to process event.
3190 *
3191 * \return Nothing
3192 */
pri_cc_act_send_ccbs_status_request(struct pri * ctrl,struct pri_cc_record * cc_record)3193 static void pri_cc_act_send_ccbs_status_request(struct pri *ctrl, struct pri_cc_record *cc_record)
3194 {
3195 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3196 send_ccbs_status_request(ctrl, cc_record->signaling, cc_record);
3197 }
3198
3199 /*!
3200 * \internal
3201 * \brief FSM action to stop the PTMP T_ACTIVATE timer.
3202 *
3203 * \param ctrl D channel controller.
3204 * \param cc_record Call completion record to process event.
3205 *
3206 * \return Nothing
3207 */
pri_cc_act_stop_t_activate(struct pri * ctrl,struct pri_cc_record * cc_record)3208 static void pri_cc_act_stop_t_activate(struct pri *ctrl, struct pri_cc_record *cc_record)
3209 {
3210 struct apdu_event *msg;
3211
3212 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3213
3214 if (!cc_record->signaling) {
3215 return;
3216 }
3217 msg = pri_call_apdu_find(cc_record->signaling, cc_record->t_activate_invoke_id);
3218 if (msg) {
3219 cc_record->t_activate_invoke_id = APDU_INVALID_INVOKE_ID;
3220 pri_call_apdu_delete(cc_record->signaling, msg);
3221 }
3222 }
3223
3224 /*!
3225 * \internal
3226 * \brief cc-request PTMP response callback function.
3227 *
3228 * \param reason Reason callback is called.
3229 * \param ctrl D channel controller.
3230 * \param call Q.931 call leg.
3231 * \param apdu APDU queued entry. Do not change!
3232 * \param msg APDU response message data. (NULL if was not the reason called.)
3233 *
3234 * \return TRUE if no more responses are expected.
3235 */
pri_cc_req_response_ptmp(enum APDU_CALLBACK_REASON reason,struct pri * ctrl,struct q931_call * call,struct apdu_event * apdu,const struct apdu_msg_data * msg)3236 static int pri_cc_req_response_ptmp(enum APDU_CALLBACK_REASON reason, struct pri *ctrl, struct q931_call *call, struct apdu_event *apdu, const struct apdu_msg_data *msg)
3237 {
3238 struct pri_cc_record *cc_record;
3239
3240 cc_record = apdu->response.user.ptr;
3241
3242 switch (reason) {
3243 case APDU_CALLBACK_REASON_ERROR:
3244 cc_record->t_activate_invoke_id = APDU_INVALID_INVOKE_ID;
3245 break;
3246 case APDU_CALLBACK_REASON_TIMEOUT:
3247 cc_record->t_activate_invoke_id = APDU_INVALID_INVOKE_ID;
3248 pri_cc_event(ctrl, call, cc_record, CC_EVENT_TIMEOUT_T_ACTIVATE);
3249 break;
3250 case APDU_CALLBACK_REASON_MSG_RESULT:
3251 /*
3252 * Since we received this facility, we will not be allocating any
3253 * reference and linkage id's.
3254 */
3255 cc_record->ccbs_reference_id =
3256 msg->response.result->args.etsi.CCBSRequest.ccbs_reference & 0x7F;
3257 cc_record->option.recall_mode =
3258 msg->response.result->args.etsi.CCBSRequest.recall_mode;
3259
3260 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_ACCEPT);
3261 break;
3262 case APDU_CALLBACK_REASON_MSG_ERROR:
3263 cc_record->msg.cc_req_rsp.reason = reason;
3264 cc_record->msg.cc_req_rsp.code = msg->response.error->code;
3265
3266 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_FAIL);
3267 break;
3268 case APDU_CALLBACK_REASON_MSG_REJECT:
3269 cc_record->msg.cc_req_rsp.reason = reason;
3270 cc_record->msg.cc_req_rsp.code = msg->response.reject->code;
3271
3272 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_FAIL);
3273 break;
3274 default:
3275 break;
3276 }
3277
3278 /*
3279 * No more reponses are really expected.
3280 * However, the FSM will be removing the apdu_event itself instead.
3281 */
3282 return 0;
3283 }
3284
3285 /*!
3286 * \internal
3287 * \brief cc-request PTP response callback function.
3288 *
3289 * \param reason Reason callback is called.
3290 * \param ctrl D channel controller.
3291 * \param call Q.931 call leg.
3292 * \param apdu APDU queued entry. Do not change!
3293 * \param msg APDU response message data. (NULL if was not the reason called.)
3294 *
3295 * \return TRUE if no more responses are expected.
3296 */
pri_cc_req_response_ptp(enum APDU_CALLBACK_REASON reason,struct pri * ctrl,struct q931_call * call,struct apdu_event * apdu,const struct apdu_msg_data * msg)3297 static int pri_cc_req_response_ptp(enum APDU_CALLBACK_REASON reason, struct pri *ctrl, struct q931_call *call, struct apdu_event *apdu, const struct apdu_msg_data *msg)
3298 {
3299 struct pri_cc_record *cc_record;
3300
3301 cc_record = apdu->response.user.ptr;
3302
3303 switch (reason) {
3304 case APDU_CALLBACK_REASON_ERROR:
3305 cc_record->t_activate_invoke_id = APDU_INVALID_INVOKE_ID;
3306 break;
3307 case APDU_CALLBACK_REASON_TIMEOUT:
3308 cc_record->t_activate_invoke_id = APDU_INVALID_INVOKE_ID;
3309 pri_cc_event(ctrl, call, cc_record, CC_EVENT_TIMEOUT_T_ACTIVATE);
3310 break;
3311 case APDU_CALLBACK_REASON_MSG_RESULT:
3312 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_ACCEPT);
3313 break;
3314 case APDU_CALLBACK_REASON_MSG_ERROR:
3315 cc_record->msg.cc_req_rsp.reason = reason;
3316 cc_record->msg.cc_req_rsp.code = msg->response.error->code;
3317
3318 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_FAIL);
3319 break;
3320 case APDU_CALLBACK_REASON_MSG_REJECT:
3321 cc_record->msg.cc_req_rsp.reason = reason;
3322 cc_record->msg.cc_req_rsp.code = msg->response.reject->code;
3323
3324 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_FAIL);
3325 break;
3326 default:
3327 break;
3328 }
3329
3330 /*
3331 * No more reponses are really expected.
3332 * However, the FSM will be removing the apdu_event itself instead.
3333 */
3334 return 0;
3335 }
3336
3337 /*!
3338 * \internal
3339 * \brief cc-request Q.SIG response callback function.
3340 *
3341 * \param reason Reason callback is called.
3342 * \param ctrl D channel controller.
3343 * \param call Q.931 call leg.
3344 * \param apdu APDU queued entry. Do not change!
3345 * \param msg APDU response message data. (NULL if was not the reason called.)
3346 *
3347 * \return TRUE if no more responses are expected.
3348 */
pri_cc_req_response_qsig(enum APDU_CALLBACK_REASON reason,struct pri * ctrl,struct q931_call * call,struct apdu_event * apdu,const struct apdu_msg_data * msg)3349 static int pri_cc_req_response_qsig(enum APDU_CALLBACK_REASON reason, struct pri *ctrl, struct q931_call *call, struct apdu_event *apdu, const struct apdu_msg_data *msg)
3350 {
3351 struct pri_cc_record *cc_record;
3352
3353 cc_record = apdu->response.user.ptr;
3354
3355 switch (reason) {
3356 case APDU_CALLBACK_REASON_ERROR:
3357 cc_record->t_activate_invoke_id = APDU_INVALID_INVOKE_ID;
3358 break;
3359 case APDU_CALLBACK_REASON_TIMEOUT:
3360 cc_record->t_activate_invoke_id = APDU_INVALID_INVOKE_ID;
3361 pri_cc_event(ctrl, call, cc_record, CC_EVENT_TIMEOUT_T_ACTIVATE);
3362 break;
3363 case APDU_CALLBACK_REASON_MSG_RESULT:
3364 if (!cc_record->option.retain_signaling_link) {
3365 /* We were ambivalent about the signaling link retention option. */
3366 if (msg->type == Q931_CONNECT) {
3367 /* The far end elected to retain the signaling link. */
3368 cc_record->option.retain_signaling_link = 1;
3369 }
3370 }
3371
3372 cc_record->fsm.qsig.msgtype = msg->type;
3373 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_ACCEPT);
3374 break;
3375 case APDU_CALLBACK_REASON_MSG_ERROR:
3376 cc_record->msg.cc_req_rsp.reason = reason;
3377 cc_record->msg.cc_req_rsp.code = msg->response.error->code;
3378
3379 cc_record->fsm.qsig.msgtype = msg->type;
3380 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_FAIL);
3381 break;
3382 case APDU_CALLBACK_REASON_MSG_REJECT:
3383 cc_record->msg.cc_req_rsp.reason = reason;
3384 cc_record->msg.cc_req_rsp.code = msg->response.reject->code;
3385
3386 cc_record->fsm.qsig.msgtype = msg->type;
3387 pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_FAIL);
3388 break;
3389 default:
3390 break;
3391 }
3392
3393 /*
3394 * No more reponses are really expected.
3395 * However, the FSM will be removing the apdu_event itself instead.
3396 */
3397 return 0;
3398 }
3399
3400 /*!
3401 * \internal
3402 * \brief Encode and queue a cc-request message.
3403 *
3404 * \param ctrl D channel controller for diagnostic messages or global options.
3405 * \param call Call leg from which to encode cc-request.
3406 * \param cc_record Call completion record to process event.
3407 *
3408 * \retval 0 on success.
3409 * \retval -1 on error.
3410 */
rose_cc_request(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)3411 static int rose_cc_request(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
3412 {
3413 unsigned char buffer[256];
3414 unsigned char *end;
3415 struct apdu_callback_data response;
3416 int msgtype;
3417
3418 memset(&response, 0, sizeof(response));
3419
3420 switch (ctrl->switchtype) {
3421 case PRI_SWITCH_EUROISDN_E1:
3422 case PRI_SWITCH_EUROISDN_T1:
3423 if (PTMP_MODE(ctrl)) {
3424 end =
3425 enc_etsi_ptmp_cc_request(ctrl, buffer, buffer + sizeof(buffer),
3426 cc_record);
3427 msgtype = Q931_FACILITY;
3428 response.callback = pri_cc_req_response_ptmp;
3429 } else {
3430 end =
3431 enc_etsi_ptp_cc_request(ctrl, buffer, buffer + sizeof(buffer), cc_record);
3432 msgtype = Q931_REGISTER;
3433 response.callback = pri_cc_req_response_ptp;
3434 }
3435 response.timeout_time = ctrl->timers[PRI_TIMER_T_ACTIVATE];
3436 break;
3437 case PRI_SWITCH_QSIG:
3438 end = enc_qsig_cc_request(ctrl, buffer, buffer + sizeof(buffer), cc_record);
3439 msgtype = Q931_SETUP;
3440 response.callback = pri_cc_req_response_qsig;
3441 response.timeout_time = ctrl->timers[PRI_TIMER_QSIG_CC_T1];
3442 break;
3443 default:
3444 return -1;
3445 }
3446 if (!end) {
3447 return -1;
3448 }
3449
3450 response.user.ptr = cc_record;
3451 response.invoke_id = ctrl->last_invoke;
3452 cc_record->t_activate_invoke_id = ctrl->last_invoke;
3453 return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, &response);
3454 }
3455
3456 /*!
3457 * \internal
3458 * \brief FSM action to queue the cc-request message.
3459 *
3460 * \param ctrl D channel controller.
3461 * \param cc_record Call completion record to process event.
3462 * \param call Call leg from which to encode cc-request.
3463 *
3464 * \return Nothing
3465 */
pri_cc_act_queue_cc_request(struct pri * ctrl,struct pri_cc_record * cc_record,q931_call * call)3466 static void pri_cc_act_queue_cc_request(struct pri *ctrl, struct pri_cc_record *cc_record, q931_call *call)
3467 {
3468 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3469 if (rose_cc_request(ctrl, call, cc_record)) {
3470 pri_message(ctrl, "Could not queue message for cc-request.\n");
3471 }
3472 }
3473
3474 /*!
3475 * \internal
3476 * \brief FSM action to send the CCBSDeactivate message.
3477 *
3478 * \param ctrl D channel controller.
3479 * \param cc_record Call completion record to process event.
3480 *
3481 * \return Nothing
3482 */
pri_cc_act_send_cc_deactivate_req(struct pri * ctrl,struct pri_cc_record * cc_record)3483 static void pri_cc_act_send_cc_deactivate_req(struct pri *ctrl, struct pri_cc_record *cc_record)
3484 {
3485 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3486 send_cc_deactivate_req(ctrl, cc_record->signaling, cc_record);
3487 }
3488
3489 /*!
3490 * \internal
3491 * \brief FSM action to send the CCBSBFree message.
3492 *
3493 * \param ctrl D channel controller.
3494 * \param cc_record Call completion record to process event.
3495 *
3496 * \return Nothing
3497 */
pri_cc_act_send_ccbs_b_free(struct pri * ctrl,struct pri_cc_record * cc_record)3498 static void pri_cc_act_send_ccbs_b_free(struct pri *ctrl, struct pri_cc_record *cc_record)
3499 {
3500 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3501 send_ccbs_b_free(ctrl, cc_record->signaling, cc_record);
3502 }
3503
3504 /*!
3505 * \internal
3506 * \brief FSM action to send the remote user free message.
3507 *
3508 * \param ctrl D channel controller.
3509 * \param cc_record Call completion record to process event.
3510 *
3511 * \return Nothing
3512 */
pri_cc_act_send_remote_user_free(struct pri * ctrl,struct pri_cc_record * cc_record)3513 static void pri_cc_act_send_remote_user_free(struct pri *ctrl, struct pri_cc_record *cc_record)
3514 {
3515 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3516 send_remote_user_free(ctrl, cc_record);
3517 }
3518
3519 /*!
3520 * \internal
3521 * \brief FSM action to send the CALL_PROCEEDING message on the signaling link.
3522 *
3523 * \param ctrl D channel controller.
3524 * \param cc_record Call completion record to process event.
3525 *
3526 * \return Nothing
3527 */
pri_cc_act_send_call_proceeding(struct pri * ctrl,struct pri_cc_record * cc_record)3528 static void pri_cc_act_send_call_proceeding(struct pri *ctrl, struct pri_cc_record *cc_record)
3529 {
3530 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3531 pri_proceeding(ctrl, cc_record->signaling, 0, 0);
3532 }
3533
3534 /*!
3535 * \internal
3536 * \brief FSM action to send the CC suspend message.
3537 *
3538 * \param ctrl D channel controller.
3539 * \param cc_record Call completion record to process event.
3540 *
3541 * \return Nothing
3542 */
pri_cc_act_send_cc_suspend(struct pri * ctrl,struct pri_cc_record * cc_record)3543 static void pri_cc_act_send_cc_suspend(struct pri *ctrl, struct pri_cc_record *cc_record)
3544 {
3545 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3546 send_cc_suspend(ctrl, cc_record);
3547 }
3548
3549 /*!
3550 * \internal
3551 * \brief FSM action to send the CC resume message.
3552 *
3553 * \param ctrl D channel controller.
3554 * \param cc_record Call completion record to process event.
3555 *
3556 * \return Nothing
3557 */
pri_cc_act_send_cc_resume(struct pri * ctrl,struct pri_cc_record * cc_record)3558 static void pri_cc_act_send_cc_resume(struct pri *ctrl, struct pri_cc_record *cc_record)
3559 {
3560 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3561 send_cc_resume(ctrl, cc_record);
3562 }
3563
3564 /*!
3565 * \internal
3566 * \brief FSM action to send the ccCancel message.
3567 *
3568 * \param ctrl D channel controller.
3569 * \param cc_record Call completion record to process event.
3570 *
3571 * \return Nothing
3572 */
pri_cc_act_send_cc_cancel(struct pri * ctrl,struct pri_cc_record * cc_record)3573 static void pri_cc_act_send_cc_cancel(struct pri *ctrl, struct pri_cc_record *cc_record)
3574 {
3575 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3576 send_cc_cancel(ctrl, cc_record);
3577 }
3578
3579 /*!
3580 * \internal
3581 * \brief FSM action to send the CCBSStopAlerting message.
3582 *
3583 * \param ctrl D channel controller.
3584 * \param cc_record Call completion record to process event.
3585 *
3586 * \return Nothing
3587 */
pri_cc_act_send_ccbs_stop_alerting(struct pri * ctrl,struct pri_cc_record * cc_record)3588 static void pri_cc_act_send_ccbs_stop_alerting(struct pri *ctrl, struct pri_cc_record *cc_record)
3589 {
3590 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3591 send_ccbs_stop_alerting(ctrl, cc_record->signaling, cc_record);
3592 }
3593
3594 /*!
3595 * \internal
3596 * \brief FSM action to release the call linkage id.
3597 *
3598 * \param ctrl D channel controller.
3599 * \param cc_record Call completion record to process event.
3600 *
3601 * \return Nothing
3602 */
pri_cc_act_release_link_id(struct pri * ctrl,struct pri_cc_record * cc_record)3603 static void pri_cc_act_release_link_id(struct pri *ctrl, struct pri_cc_record *cc_record)
3604 {
3605 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3606 cc_record->call_linkage_id = CC_PTMP_INVALID_ID;
3607 }
3608
3609 /*!
3610 * \internal
3611 * \brief FSM action to set the Q.SIG retain-signaling-link option.
3612 *
3613 * \param ctrl D channel controller.
3614 * \param cc_record Call completion record to process event.
3615 *
3616 * \return Nothing
3617 */
pri_cc_act_set_retain_signaling_link(struct pri * ctrl,struct pri_cc_record * cc_record)3618 static void pri_cc_act_set_retain_signaling_link(struct pri *ctrl, struct pri_cc_record *cc_record)
3619 {
3620 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3621 cc_record->option.retain_signaling_link = 1;
3622 }
3623
3624 /*!
3625 * \internal
3626 * \brief FSM action to reset the raw A status request no response count.
3627 *
3628 * \param ctrl D channel controller.
3629 * \param cc_record Call completion record to process event.
3630 *
3631 * \return Nothing
3632 */
pri_cc_act_raw_status_count_reset(struct pri * ctrl,struct pri_cc_record * cc_record)3633 static void pri_cc_act_raw_status_count_reset(struct pri *ctrl, struct pri_cc_record *cc_record)
3634 {
3635 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3636 cc_record->fsm.ptmp.party_a_status_count = 0;
3637 }
3638
3639 /*!
3640 * \internal
3641 * \brief FSM action to increment the raw A status request no response count.
3642 *
3643 * \param ctrl D channel controller.
3644 * \param cc_record Call completion record to process event.
3645 *
3646 * \return Nothing
3647 */
pri_cc_act_raw_status_count_increment(struct pri * ctrl,struct pri_cc_record * cc_record)3648 static void pri_cc_act_raw_status_count_increment(struct pri *ctrl, struct pri_cc_record *cc_record)
3649 {
3650 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3651 ++cc_record->fsm.ptmp.party_a_status_count;
3652 }
3653
3654 /*!
3655 * \internal
3656 * \brief FSM action to reset raw A status.
3657 *
3658 * \param ctrl D channel controller.
3659 * \param cc_record Call completion record to process event.
3660 *
3661 * \return Nothing
3662 */
pri_cc_act_reset_raw_a_status(struct pri * ctrl,struct pri_cc_record * cc_record)3663 static void pri_cc_act_reset_raw_a_status(struct pri *ctrl, struct pri_cc_record *cc_record)
3664 {
3665 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3666 cc_record->fsm.ptmp.party_a_status_acc = CC_PARTY_A_AVAILABILITY_INVALID;
3667 }
3668
3669 /*!
3670 * \internal
3671 * \brief FSM action to add raw A status with busy.
3672 *
3673 * \param ctrl D channel controller.
3674 * \param cc_record Call completion record to process event.
3675 *
3676 * \return Nothing
3677 */
pri_cc_act_add_raw_a_status_busy(struct pri * ctrl,struct pri_cc_record * cc_record)3678 static void pri_cc_act_add_raw_a_status_busy(struct pri *ctrl, struct pri_cc_record *cc_record)
3679 {
3680 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3681 if (cc_record->fsm.ptmp.party_a_status_acc != CC_PARTY_A_AVAILABILITY_FREE) {
3682 cc_record->fsm.ptmp.party_a_status_acc = CC_PARTY_A_AVAILABILITY_BUSY;
3683 }
3684 }
3685
3686 /*!
3687 * \internal
3688 * \brief FSM action to set raw A status to free.
3689 *
3690 * \param ctrl D channel controller.
3691 * \param cc_record Call completion record to process event.
3692 *
3693 * \return Nothing
3694 */
pri_cc_act_set_raw_a_status_free(struct pri * ctrl,struct pri_cc_record * cc_record)3695 static void pri_cc_act_set_raw_a_status_free(struct pri *ctrl, struct pri_cc_record *cc_record)
3696 {
3697 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3698 cc_record->fsm.ptmp.party_a_status_acc = CC_PARTY_A_AVAILABILITY_FREE;
3699 }
3700
3701 /*!
3702 * \internal
3703 * \brief Fill in the status response party A status update event.
3704 *
3705 * \param ctrl D channel controller.
3706 * \param call Q.931 call leg.
3707 * \param cc_record Call completion record to process event.
3708 *
3709 * \return Nothing
3710 */
pri_cc_fill_status_rsp_a(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)3711 static void pri_cc_fill_status_rsp_a(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
3712 {
3713 struct pri_subcommand *subcmd;
3714
3715 if (cc_record->fsm.ptmp.party_a_status_acc == CC_PARTY_A_AVAILABILITY_INVALID) {
3716 /* Accumulated party A status is invalid so don't pass it up. */
3717 return;
3718 }
3719
3720 subcmd = q931_alloc_subcommand(ctrl);
3721 if (!subcmd) {
3722 return;
3723 }
3724
3725 subcmd->cmd = PRI_SUBCMD_CC_STATUS_REQ_RSP;
3726 subcmd->u.cc_status_req_rsp.cc_id = cc_record->record_id;
3727 subcmd->u.cc_status_req_rsp.status =
3728 (cc_record->fsm.ptmp.party_a_status_acc == CC_PARTY_A_AVAILABILITY_FREE)
3729 ? 0 /* free */ : 1 /* busy */;
3730 }
3731
3732 /*!
3733 * \internal
3734 * \brief Pass up party A status response to upper layer (indirectly).
3735 *
3736 * \param data CC record pointer.
3737 *
3738 * \return Nothing
3739 */
pri_cc_indirect_status_rsp_a(void * data)3740 static void pri_cc_indirect_status_rsp_a(void *data)
3741 {
3742 struct pri_cc_record *cc_record = data;
3743
3744 cc_record->t_indirect = 0;
3745 q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_rsp_a);
3746 }
3747
3748 /*!
3749 * \internal
3750 * \brief FSM action to pass up party A status response to upper layer (indirectly).
3751 *
3752 * \param ctrl D channel controller.
3753 * \param cc_record Call completion record to process event.
3754 *
3755 * \return Nothing
3756 *
3757 * \note
3758 * Warning: Must not use this action with pri_cc_act_set_self_destruct() in the
3759 * same event.
3760 */
pri_cc_act_pass_up_status_rsp_a_indirect(struct pri * ctrl,struct pri_cc_record * cc_record)3761 static void pri_cc_act_pass_up_status_rsp_a_indirect(struct pri *ctrl, struct pri_cc_record *cc_record)
3762 {
3763 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3764 if (cc_record->fsm.ptmp.party_a_status_acc != CC_PARTY_A_AVAILABILITY_INVALID) {
3765 /* Accumulated party A status is not invalid so pass it up. */
3766 if (cc_record->t_indirect) {
3767 pri_error(ctrl, "!! An indirect action is already active!");
3768 pri_schedule_del(ctrl, cc_record->t_indirect);
3769 }
3770 cc_record->t_indirect = pri_schedule_event(ctrl, 0, pri_cc_indirect_status_rsp_a,
3771 cc_record);
3772 }
3773 }
3774
3775 /*!
3776 * \internal
3777 * \brief FSM action to pass up party A status response to upper layer.
3778 *
3779 * \param ctrl D channel controller.
3780 * \param cc_record Call completion record to process event.
3781 *
3782 * \return Nothing
3783 */
pri_cc_act_pass_up_status_rsp_a(struct pri * ctrl,struct pri_cc_record * cc_record)3784 static void pri_cc_act_pass_up_status_rsp_a(struct pri *ctrl, struct pri_cc_record *cc_record)
3785 {
3786 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3787 pri_cc_fill_status_rsp_a(ctrl, cc_record->signaling, cc_record);
3788 }
3789
3790 /*!
3791 * \internal
3792 * \brief FSM action to promote raw A status.
3793 *
3794 * \param ctrl D channel controller.
3795 * \param cc_record Call completion record to process event.
3796 *
3797 * \return Nothing
3798 */
pri_cc_act_promote_raw_a_status(struct pri * ctrl,struct pri_cc_record * cc_record)3799 static void pri_cc_act_promote_raw_a_status(struct pri *ctrl, struct pri_cc_record *cc_record)
3800 {
3801 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3802 cc_record->party_a_status = cc_record->fsm.ptmp.party_a_status_acc;
3803 }
3804
3805 /*!
3806 * \internal
3807 * \brief FSM action to reset A status.
3808 *
3809 * \param ctrl D channel controller.
3810 * \param cc_record Call completion record to process event.
3811 *
3812 * \return Nothing
3813 */
pri_cc_act_reset_a_status(struct pri * ctrl,struct pri_cc_record * cc_record)3814 static void pri_cc_act_reset_a_status(struct pri *ctrl, struct pri_cc_record *cc_record)
3815 {
3816 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3817 cc_record->party_a_status = CC_PARTY_A_AVAILABILITY_INVALID;
3818 }
3819
3820 /*!
3821 * \internal
3822 * \brief FSM action to set A status as busy.
3823 *
3824 * \param ctrl D channel controller.
3825 * \param cc_record Call completion record to process event.
3826 *
3827 * \return Nothing
3828 */
pri_cc_act_set_a_status_busy(struct pri * ctrl,struct pri_cc_record * cc_record)3829 static void pri_cc_act_set_a_status_busy(struct pri *ctrl, struct pri_cc_record *cc_record)
3830 {
3831 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3832 cc_record->party_a_status = CC_PARTY_A_AVAILABILITY_BUSY;
3833 }
3834
3835 /*!
3836 * \internal
3837 * \brief FSM action to set A status as free.
3838 *
3839 * \param ctrl D channel controller.
3840 * \param cc_record Call completion record to process event.
3841 *
3842 * \return Nothing
3843 */
pri_cc_act_set_a_status_free(struct pri * ctrl,struct pri_cc_record * cc_record)3844 static void pri_cc_act_set_a_status_free(struct pri *ctrl, struct pri_cc_record *cc_record)
3845 {
3846 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3847 cc_record->party_a_status = CC_PARTY_A_AVAILABILITY_FREE;
3848 }
3849
3850 /*!
3851 * \internal
3852 * \brief Fill in the party A status update event.
3853 *
3854 * \param ctrl D channel controller.
3855 * \param call Q.931 call leg.
3856 * \param cc_record Call completion record to process event.
3857 *
3858 * \return Nothing
3859 */
pri_cc_fill_status_a(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)3860 static void pri_cc_fill_status_a(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
3861 {
3862 struct pri_subcommand *subcmd;
3863
3864 if (cc_record->party_a_status == CC_PARTY_A_AVAILABILITY_INVALID) {
3865 /* Party A status is invalid so don't pass it up. */
3866 return;
3867 }
3868
3869 subcmd = q931_alloc_subcommand(ctrl);
3870 if (!subcmd) {
3871 return;
3872 }
3873
3874 subcmd->cmd = PRI_SUBCMD_CC_STATUS;
3875 subcmd->u.cc_status.cc_id = cc_record->record_id;
3876 subcmd->u.cc_status.status =
3877 (cc_record->party_a_status == CC_PARTY_A_AVAILABILITY_FREE)
3878 ? 0 /* free */ : 1 /* busy */;
3879 }
3880
3881 /*!
3882 * \internal
3883 * \brief Pass up party A status to upper layer (indirectly).
3884 *
3885 * \param data CC record pointer.
3886 *
3887 * \return Nothing
3888 */
pri_cc_indirect_status_a(void * data)3889 static void pri_cc_indirect_status_a(void *data)
3890 {
3891 struct pri_cc_record *cc_record = data;
3892
3893 cc_record->t_indirect = 0;
3894 q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_a);
3895 }
3896
3897 /*!
3898 * \internal
3899 * \brief FSM action to pass up party A status to upper layer (indirectly).
3900 *
3901 * \param ctrl D channel controller.
3902 * \param cc_record Call completion record to process event.
3903 *
3904 * \return Nothing
3905 *
3906 * \note
3907 * Warning: Must not use this action with pri_cc_act_set_self_destruct() in the
3908 * same event.
3909 */
pri_cc_act_pass_up_a_status_indirect(struct pri * ctrl,struct pri_cc_record * cc_record)3910 static void pri_cc_act_pass_up_a_status_indirect(struct pri *ctrl, struct pri_cc_record *cc_record)
3911 {
3912 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3913 if (cc_record->party_a_status != CC_PARTY_A_AVAILABILITY_INVALID) {
3914 /* Party A status is not invalid so pass it up. */
3915 if (cc_record->t_indirect) {
3916 pri_error(ctrl, "!! An indirect action is already active!");
3917 pri_schedule_del(ctrl, cc_record->t_indirect);
3918 }
3919 cc_record->t_indirect = pri_schedule_event(ctrl, 0, pri_cc_indirect_status_a,
3920 cc_record);
3921 }
3922 }
3923
3924 /*!
3925 * \internal
3926 * \brief FSM action to pass up party A status to upper layer.
3927 *
3928 * \param ctrl D channel controller.
3929 * \param cc_record Call completion record to process event.
3930 *
3931 * \return Nothing
3932 */
pri_cc_act_pass_up_a_status(struct pri * ctrl,struct pri_cc_record * cc_record)3933 static void pri_cc_act_pass_up_a_status(struct pri *ctrl, struct pri_cc_record *cc_record)
3934 {
3935 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3936 pri_cc_fill_status_a(ctrl, cc_record->signaling, cc_record);
3937 }
3938
3939 /*!
3940 * \internal
3941 * \brief FSM action to pass up CC request (CCBS/CCNR) to upper layer.
3942 *
3943 * \param ctrl D channel controller.
3944 * \param cc_record Call completion record to process event.
3945 *
3946 * \return Nothing
3947 */
pri_cc_act_pass_up_cc_request(struct pri * ctrl,struct pri_cc_record * cc_record)3948 static void pri_cc_act_pass_up_cc_request(struct pri *ctrl, struct pri_cc_record *cc_record)
3949 {
3950 struct pri_subcommand *subcmd;
3951
3952 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3953
3954 subcmd = q931_alloc_subcommand(ctrl);
3955 if (!subcmd) {
3956 return;
3957 }
3958
3959 subcmd->cmd = PRI_SUBCMD_CC_REQ;
3960 subcmd->u.cc_request.cc_id = cc_record->record_id;
3961 subcmd->u.cc_request.mode = cc_record->is_ccnr ? 1 /* ccnr */ : 0 /* ccbs */;
3962 }
3963
3964 /*!
3965 * \internal
3966 * \brief FSM action to pass up CC cancel to upper layer.
3967 *
3968 * \param ctrl D channel controller.
3969 * \param cc_record Call completion record to process event.
3970 *
3971 * \return Nothing
3972 */
pri_cc_act_pass_up_cc_cancel(struct pri * ctrl,struct pri_cc_record * cc_record)3973 static void pri_cc_act_pass_up_cc_cancel(struct pri *ctrl, struct pri_cc_record *cc_record)
3974 {
3975 struct pri_subcommand *subcmd;
3976
3977 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
3978
3979 subcmd = q931_alloc_subcommand(ctrl);
3980 if (!subcmd) {
3981 return;
3982 }
3983
3984 subcmd->cmd = PRI_SUBCMD_CC_CANCEL;
3985 subcmd->u.cc_cancel.cc_id = cc_record->record_id;
3986 subcmd->u.cc_cancel.is_agent = cc_record->is_agent;
3987 }
3988
3989 /*!
3990 * \internal
3991 * \brief FSM action to pass up CC call to upper layer.
3992 *
3993 * \param ctrl D channel controller.
3994 * \param cc_record Call completion record to process event.
3995 *
3996 * \return Nothing
3997 */
pri_cc_act_pass_up_cc_call(struct pri * ctrl,struct pri_cc_record * cc_record)3998 static void pri_cc_act_pass_up_cc_call(struct pri *ctrl, struct pri_cc_record *cc_record)
3999 {
4000 struct pri_subcommand *subcmd;
4001
4002 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4003
4004 subcmd = q931_alloc_subcommand(ctrl);
4005 if (!subcmd) {
4006 return;
4007 }
4008
4009 subcmd->cmd = PRI_SUBCMD_CC_CALL;
4010 subcmd->u.cc_call.cc_id = cc_record->record_id;
4011 }
4012
4013 /*!
4014 * \internal
4015 * \brief FSM action to pass up CC available to upper layer.
4016 *
4017 * \param ctrl D channel controller.
4018 * \param cc_record Call completion record to process event.
4019 *
4020 * \return Nothing
4021 */
pri_cc_act_pass_up_cc_available(struct pri * ctrl,struct pri_cc_record * cc_record)4022 static void pri_cc_act_pass_up_cc_available(struct pri *ctrl, struct pri_cc_record *cc_record)
4023 {
4024 struct pri_subcommand *subcmd;
4025
4026 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4027
4028 subcmd = q931_alloc_subcommand(ctrl);
4029 if (!subcmd) {
4030 return;
4031 }
4032
4033 subcmd->cmd = PRI_SUBCMD_CC_AVAILABLE;
4034 subcmd->u.cc_available.cc_id = cc_record->record_id;
4035 }
4036
4037 /*!
4038 * \internal
4039 * \brief FSM action to pass up CC request response is success to upper layer.
4040 *
4041 * \param ctrl D channel controller.
4042 * \param cc_record Call completion record to process event.
4043 *
4044 * \return Nothing
4045 */
pri_cc_act_pass_up_cc_req_rsp_success(struct pri * ctrl,struct pri_cc_record * cc_record)4046 static void pri_cc_act_pass_up_cc_req_rsp_success(struct pri *ctrl, struct pri_cc_record *cc_record)
4047 {
4048 struct pri_subcommand *subcmd;
4049
4050 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4051
4052 subcmd = q931_alloc_subcommand(ctrl);
4053 if (!subcmd) {
4054 return;
4055 }
4056
4057 subcmd->cmd = PRI_SUBCMD_CC_REQ_RSP;
4058 subcmd->u.cc_request_rsp.cc_id = cc_record->record_id;
4059 subcmd->u.cc_request_rsp.status = 0;/* success */
4060 subcmd->u.cc_request_rsp.fail_code = 0;
4061 }
4062
4063 /*!
4064 * \internal
4065 * \brief FSM action to pass up CC request response is failed to upper layer.
4066 *
4067 * \param ctrl D channel controller.
4068 * \param cc_record Call completion record to process event.
4069 *
4070 * \return Nothing
4071 */
pri_cc_act_pass_up_cc_req_rsp_fail(struct pri * ctrl,struct pri_cc_record * cc_record)4072 static void pri_cc_act_pass_up_cc_req_rsp_fail(struct pri *ctrl, struct pri_cc_record *cc_record)
4073 {
4074 struct pri_subcommand *subcmd;
4075
4076 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4077
4078 subcmd = q931_alloc_subcommand(ctrl);
4079 if (!subcmd) {
4080 return;
4081 }
4082
4083 subcmd->cmd = PRI_SUBCMD_CC_REQ_RSP;
4084 subcmd->u.cc_request_rsp.cc_id = cc_record->record_id;
4085 subcmd->u.cc_request_rsp.status =
4086 (cc_record->msg.cc_req_rsp.reason == APDU_CALLBACK_REASON_MSG_ERROR)
4087 ? 2 /* error */ : 3 /* reject */;
4088 subcmd->u.cc_request_rsp.fail_code = cc_record->msg.cc_req_rsp.code;
4089 }
4090
4091 /*!
4092 * \internal
4093 * \brief FSM action to pass up CC request response is timeout to upper layer.
4094 *
4095 * \param ctrl D channel controller.
4096 * \param cc_record Call completion record to process event.
4097 *
4098 * \return Nothing
4099 */
pri_cc_act_pass_up_cc_req_rsp_timeout(struct pri * ctrl,struct pri_cc_record * cc_record)4100 static void pri_cc_act_pass_up_cc_req_rsp_timeout(struct pri *ctrl, struct pri_cc_record *cc_record)
4101 {
4102 struct pri_subcommand *subcmd;
4103
4104 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4105
4106 subcmd = q931_alloc_subcommand(ctrl);
4107 if (!subcmd) {
4108 return;
4109 }
4110
4111 subcmd->cmd = PRI_SUBCMD_CC_REQ_RSP;
4112 subcmd->u.cc_request_rsp.cc_id = cc_record->record_id;
4113 subcmd->u.cc_request_rsp.status = 1;/* timeout */
4114 subcmd->u.cc_request_rsp.fail_code = 0;
4115 }
4116
4117 /*!
4118 * \internal
4119 * \brief FSM action to pass up CC B free to upper layer.
4120 *
4121 * \param ctrl D channel controller.
4122 * \param cc_record Call completion record to process event.
4123 *
4124 * \return Nothing
4125 */
pri_cc_act_pass_up_b_free(struct pri * ctrl,struct pri_cc_record * cc_record)4126 static void pri_cc_act_pass_up_b_free(struct pri *ctrl, struct pri_cc_record *cc_record)
4127 {
4128 struct pri_subcommand *subcmd;
4129
4130 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4131
4132 subcmd = q931_alloc_subcommand(ctrl);
4133 if (!subcmd) {
4134 return;
4135 }
4136
4137 subcmd->cmd = PRI_SUBCMD_CC_B_FREE;
4138 subcmd->u.cc_b_free.cc_id = cc_record->record_id;
4139 }
4140
4141 /*!
4142 * \internal
4143 * \brief FSM action to pass up CC remote user free to upper layer.
4144 *
4145 * \param ctrl D channel controller.
4146 * \param cc_record Call completion record to process event.
4147 *
4148 * \return Nothing
4149 */
pri_cc_act_pass_up_remote_user_free(struct pri * ctrl,struct pri_cc_record * cc_record)4150 static void pri_cc_act_pass_up_remote_user_free(struct pri *ctrl, struct pri_cc_record *cc_record)
4151 {
4152 struct pri_subcommand *subcmd;
4153
4154 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4155
4156 subcmd = q931_alloc_subcommand(ctrl);
4157 if (!subcmd) {
4158 return;
4159 }
4160
4161 subcmd->cmd = PRI_SUBCMD_CC_REMOTE_USER_FREE;
4162 subcmd->u.cc_remote_user_free.cc_id = cc_record->record_id;
4163 }
4164
4165 /*!
4166 * \internal
4167 * \brief FSM action to pass up stop alerting to upper layer.
4168 *
4169 * \param ctrl D channel controller.
4170 * \param cc_record Call completion record to process event.
4171 *
4172 * \return Nothing
4173 */
pri_cc_act_pass_up_stop_alerting(struct pri * ctrl,struct pri_cc_record * cc_record)4174 static void pri_cc_act_pass_up_stop_alerting(struct pri *ctrl, struct pri_cc_record *cc_record)
4175 {
4176 struct pri_subcommand *subcmd;
4177
4178 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4179
4180 subcmd = q931_alloc_subcommand(ctrl);
4181 if (!subcmd) {
4182 return;
4183 }
4184
4185 subcmd->cmd = PRI_SUBCMD_CC_STOP_ALERTING;
4186 subcmd->u.cc_stop_alerting.cc_id = cc_record->record_id;
4187 }
4188
4189 /*!
4190 * \internal
4191 * \brief FSM action to send error response to recall attempt.
4192 *
4193 * \param ctrl D channel controller.
4194 * \param cc_record Call completion record to process event.
4195 * \param code Error code to put in error message response.
4196 *
4197 * \return Nothing
4198 */
pri_cc_act_send_error_recall(struct pri * ctrl,struct pri_cc_record * cc_record,enum rose_error_code code)4199 static void pri_cc_act_send_error_recall(struct pri *ctrl, struct pri_cc_record *cc_record, enum rose_error_code code)
4200 {
4201 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4202 rose_error_msg_encode(ctrl, cc_record->response.signaling, Q931_ANY_MESSAGE,
4203 cc_record->response.invoke_id, code);
4204 }
4205
4206 /*!
4207 * \internal
4208 * \brief FSM action to queue CC recall marker.
4209 *
4210 * \param ctrl D channel controller.
4211 * \param cc_record Call completion record to process event.
4212 * \param call Q.931 call leg.
4213 *
4214 * \return Nothing
4215 */
pri_cc_act_queue_setup_recall(struct pri * ctrl,struct pri_cc_record * cc_record,q931_call * call)4216 static void pri_cc_act_queue_setup_recall(struct pri *ctrl, struct pri_cc_record *cc_record, q931_call *call)
4217 {
4218 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4219 rose_cc_recall_encode(ctrl, call, cc_record);
4220 }
4221
4222 /*!
4223 * \internal
4224 * \brief FSM action to request the call be hung up.
4225 *
4226 * \param ctrl D channel controller.
4227 * \param cc_record Call completion record to process event.
4228 * \param call Q.931 call leg.
4229 *
4230 * \return Nothing
4231 */
pri_cc_act_set_call_to_hangup(struct pri * ctrl,struct pri_cc_record * cc_record,q931_call * call)4232 static void pri_cc_act_set_call_to_hangup(struct pri *ctrl, struct pri_cc_record *cc_record, q931_call *call)
4233 {
4234 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4235 call->cc.hangup_call = 1;
4236 }
4237
4238 /*!
4239 * \internal
4240 * \brief Post the CC_EVENT_HANGUP_SIGNALING event (timeout action).
4241 *
4242 * \param data CC record pointer.
4243 *
4244 * \return Nothing
4245 */
pri_cc_post_hangup_signaling(void * data)4246 static void pri_cc_post_hangup_signaling(void *data)
4247 {
4248 struct pri_cc_record *cc_record = data;
4249
4250 cc_record->t_indirect = 0;
4251 q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_HANGUP_SIGNALING);
4252 }
4253
4254 /*!
4255 * \internal
4256 * \brief FSM action to post the CC_EVENT_HANGUP_SIGNALING event indirectly.
4257 *
4258 * \param ctrl D channel controller.
4259 * \param cc_record Call completion record to process event.
4260 *
4261 * \return Nothing
4262 */
pri_cc_act_post_hangup_signaling(struct pri * ctrl,struct pri_cc_record * cc_record)4263 static void pri_cc_act_post_hangup_signaling(struct pri *ctrl, struct pri_cc_record *cc_record)
4264 {
4265 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4266 if (cc_record->t_indirect) {
4267 pri_error(ctrl, "!! An indirect action is already active!");
4268 pri_schedule_del(ctrl, cc_record->t_indirect);
4269 }
4270 cc_record->t_indirect = pri_schedule_event(ctrl, 0, pri_cc_post_hangup_signaling,
4271 cc_record);
4272 }
4273
4274 /*!
4275 * \internal
4276 * \brief FSM action to immediately hangup the signaling link.
4277 *
4278 * \param ctrl D channel controller.
4279 * \param cc_record Call completion record to process event.
4280 *
4281 * \return Nothing
4282 */
pri_cc_act_hangup_signaling_link(struct pri * ctrl,struct pri_cc_record * cc_record)4283 static void pri_cc_act_hangup_signaling_link(struct pri *ctrl, struct pri_cc_record *cc_record)
4284 {
4285 PRI_CC_ACT_DEBUG_OUTPUT(ctrl, cc_record->record_id);
4286 pri_hangup(ctrl, cc_record->signaling, -1);
4287 }
4288
4289 /*!
4290 * \internal
4291 * \brief FSM action to set original call data into recall call.
4292 *
4293 * \param ctrl D channel controller.
4294 * \param call Q.931 call leg.
4295 * \param cc_record Call completion record to process event.
4296 *
4297 * \return Nothing
4298 */
pri_cc_act_set_original_call_parameters(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)4299 static void pri_cc_act_set_original_call_parameters(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
4300 {
4301 call->called = cc_record->party_b;
4302 call->remote_id = cc_record->party_a;
4303 call->cc.saved_ie_contents = cc_record->saved_ie_contents;
4304 call->bc = cc_record->bc;
4305 }
4306
4307 /*!
4308 * \internal
4309 * \brief CC FSM PTMP agent CC_STATE_IDLE.
4310 *
4311 * \param ctrl D channel controller.
4312 * \param call Q.931 call leg.
4313 * \param cc_record Call completion record to process event.
4314 * \param event Event to process.
4315 *
4316 * \return Nothing
4317 */
pri_cc_fsm_ptmp_agent_idle(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4318 static void pri_cc_fsm_ptmp_agent_idle(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4319 {
4320 switch (event) {
4321 case CC_EVENT_AVAILABLE:
4322 cc_record->state = CC_STATE_PENDING_AVAILABLE;
4323 break;
4324 case CC_EVENT_CANCEL:
4325 pri_cc_act_set_self_destruct(ctrl, cc_record);
4326 break;
4327 default:
4328 break;
4329 }
4330 }
4331
4332 /*!
4333 * \internal
4334 * \brief CC FSM PTMP agent CC_STATE_PENDING_AVAILABLE.
4335 *
4336 * \param ctrl D channel controller.
4337 * \param call Q.931 call leg.
4338 * \param cc_record Call completion record to process event.
4339 * \param event Event to process.
4340 *
4341 * \return Nothing
4342 */
pri_cc_fsm_ptmp_agent_pend_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4343 static void pri_cc_fsm_ptmp_agent_pend_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4344 {
4345 switch (event) {
4346 case CC_EVENT_MSG_ALERTING:
4347 pri_cc_act_send_cc_available(ctrl, cc_record, call, Q931_ALERTING);
4348 cc_record->state = CC_STATE_AVAILABLE;
4349 break;
4350 case CC_EVENT_MSG_DISCONNECT:
4351 pri_cc_act_send_cc_available(ctrl, cc_record, call, Q931_DISCONNECT);
4352 cc_record->state = CC_STATE_AVAILABLE;
4353 break;
4354 case CC_EVENT_INTERNAL_CLEARING:
4355 pri_cc_act_release_link_id(ctrl, cc_record);
4356 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4357 pri_cc_act_set_self_destruct(ctrl, cc_record);
4358 cc_record->state = CC_STATE_IDLE;
4359 break;
4360 case CC_EVENT_CANCEL:
4361 pri_cc_act_release_link_id(ctrl, cc_record);
4362 pri_cc_act_set_self_destruct(ctrl, cc_record);
4363 cc_record->state = CC_STATE_IDLE;
4364 break;
4365 default:
4366 break;
4367 }
4368 }
4369
4370 /*!
4371 * \internal
4372 * \brief CC FSM PTMP agent CC_STATE_AVAILABLE.
4373 *
4374 * \param ctrl D channel controller.
4375 * \param call Q.931 call leg.
4376 * \param cc_record Call completion record to process event.
4377 * \param event Event to process.
4378 *
4379 * \return Nothing
4380 */
pri_cc_fsm_ptmp_agent_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4381 static void pri_cc_fsm_ptmp_agent_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4382 {
4383 switch (event) {
4384 case CC_EVENT_MSG_RELEASE:
4385 case CC_EVENT_MSG_RELEASE_COMPLETE:
4386 pri_cc_act_stop_t_retention(ctrl, cc_record);
4387 pri_cc_act_start_t_retention(ctrl, cc_record);
4388 break;
4389 case CC_EVENT_CC_REQUEST:
4390 pri_cc_act_pass_up_cc_request(ctrl, cc_record);
4391 pri_cc_act_stop_t_retention(ctrl, cc_record);
4392 cc_record->state = CC_STATE_REQUESTED;
4393 break;
4394 case CC_EVENT_INTERNAL_CLEARING:
4395 pri_cc_act_stop_t_retention(ctrl, cc_record);
4396 pri_cc_act_start_t_retention(ctrl, cc_record);
4397 break;
4398 case CC_EVENT_TIMEOUT_T_RETENTION:
4399 pri_cc_act_send_erase_call_linkage_id(ctrl, cc_record);
4400 pri_cc_act_release_link_id(ctrl, cc_record);
4401 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4402 pri_cc_act_stop_t_retention(ctrl, cc_record);
4403 pri_cc_act_set_self_destruct(ctrl, cc_record);
4404 cc_record->state = CC_STATE_IDLE;
4405 break;
4406 case CC_EVENT_CANCEL:
4407 pri_cc_act_send_erase_call_linkage_id(ctrl, cc_record);
4408 pri_cc_act_release_link_id(ctrl, cc_record);
4409 pri_cc_act_stop_t_retention(ctrl, cc_record);
4410 pri_cc_act_set_self_destruct(ctrl, cc_record);
4411 cc_record->state = CC_STATE_IDLE;
4412 break;
4413 default:
4414 break;
4415 }
4416 }
4417
4418 /*!
4419 * \internal
4420 * \brief CC FSM PTMP agent CC_STATE_REQUESTED.
4421 *
4422 * \param ctrl D channel controller.
4423 * \param call Q.931 call leg.
4424 * \param cc_record Call completion record to process event.
4425 * \param event Event to process.
4426 *
4427 * \return Nothing
4428 */
pri_cc_fsm_ptmp_agent_req(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4429 static void pri_cc_fsm_ptmp_agent_req(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4430 {
4431 switch (event) {
4432 case CC_EVENT_CC_REQUEST_ACCEPT:
4433 pri_cc_act_send_erase_call_linkage_id(ctrl, cc_record);
4434 pri_cc_act_release_link_id(ctrl, cc_record);
4435 pri_cc_act_start_t_supervision(ctrl, cc_record);
4436 pri_cc_act_reset_a_status(ctrl, cc_record);
4437 pri_cc_act_raw_status_count_reset(ctrl, cc_record);
4438 cc_record->state = CC_STATE_ACTIVATED;
4439 break;
4440 case CC_EVENT_CANCEL:
4441 pri_cc_act_send_erase_call_linkage_id(ctrl, cc_record);
4442 pri_cc_act_release_link_id(ctrl, cc_record);
4443 pri_cc_act_set_self_destruct(ctrl, cc_record);
4444 cc_record->state = CC_STATE_IDLE;
4445 break;
4446 default:
4447 break;
4448 }
4449 }
4450
4451 /*!
4452 * \internal
4453 * \brief CC FSM PTMP agent CC_STATE_ACTIVATED.
4454 *
4455 * \param ctrl D channel controller.
4456 * \param call Q.931 call leg.
4457 * \param cc_record Call completion record to process event.
4458 * \param event Event to process.
4459 *
4460 * \return Nothing
4461 */
pri_cc_fsm_ptmp_agent_activated(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4462 static void pri_cc_fsm_ptmp_agent_activated(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4463 {
4464 switch (event) {
4465 case CC_EVENT_RECALL:
4466 pri_cc_act_send_error_recall(ctrl, cc_record, ROSE_ERROR_CCBS_NotReadyForCall);
4467 pri_cc_act_set_call_to_hangup(ctrl, cc_record, call);
4468 break;
4469 case CC_EVENT_B_FREE:
4470 pri_cc_act_send_ccbs_b_free(ctrl, cc_record);
4471 break;
4472 case CC_EVENT_REMOTE_USER_FREE:
4473 switch (cc_record->party_a_status) {
4474 case CC_PARTY_A_AVAILABILITY_INVALID:
4475 if (!pri_cc_get_t_ccbs1_status(cc_record)) {
4476 pri_cc_act_reset_raw_a_status(ctrl, cc_record);
4477 pri_cc_act_send_ccbs_status_request(ctrl, cc_record);
4478 //pri_cc_act_start_t_ccbs1(ctrl, cc_record);
4479 }
4480 cc_record->state = CC_STATE_B_AVAILABLE;
4481 break;
4482 case CC_PARTY_A_AVAILABILITY_BUSY:
4483 pri_cc_act_pass_up_a_status_indirect(ctrl, cc_record);
4484 pri_cc_act_send_ccbs_b_free(ctrl, cc_record);
4485 if (!pri_cc_get_t_ccbs1_status(cc_record)) {
4486 pri_cc_act_reset_raw_a_status(ctrl, cc_record);
4487 pri_cc_act_send_ccbs_status_request(ctrl, cc_record);
4488 //pri_cc_act_start_t_ccbs1(ctrl, cc_record);
4489 }
4490 cc_record->state = CC_STATE_SUSPENDED;
4491 break;
4492 case CC_PARTY_A_AVAILABILITY_FREE:
4493 //pri_cc_act_pass_up_a_status_indirect(ctrl, cc_record);
4494 pri_cc_act_send_remote_user_free(ctrl, cc_record);
4495 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4496 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4497 pri_cc_act_start_t_recall(ctrl, cc_record);
4498 cc_record->state = CC_STATE_WAIT_CALLBACK;
4499 break;
4500 default:
4501 break;
4502 }
4503 break;
4504 case CC_EVENT_A_STATUS:
4505 if (pri_cc_get_t_ccbs1_status(cc_record)) {
4506 pri_cc_act_pass_up_status_rsp_a_indirect(ctrl, cc_record);
4507 } else {
4508 pri_cc_act_reset_a_status(ctrl, cc_record);
4509 pri_cc_act_reset_raw_a_status(ctrl, cc_record);
4510 pri_cc_act_send_ccbs_status_request(ctrl, cc_record);
4511 //pri_cc_act_start_t_ccbs1(ctrl, cc_record);
4512 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4513 pri_cc_act_start_extended_t_ccbs1(ctrl, cc_record);
4514 }
4515 break;
4516 case CC_EVENT_A_FREE:
4517 pri_cc_act_raw_status_count_reset(ctrl, cc_record);
4518 pri_cc_act_set_raw_a_status_free(ctrl, cc_record);
4519 pri_cc_act_promote_raw_a_status(ctrl, cc_record);
4520 pri_cc_act_pass_up_a_status(ctrl, cc_record);
4521 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4522 break;
4523 case CC_EVENT_A_BUSY:
4524 pri_cc_act_add_raw_a_status_busy(ctrl, cc_record);
4525 pri_cc_act_pass_up_status_rsp_a(ctrl, cc_record);
4526 break;
4527 case CC_EVENT_TIMEOUT_T_CCBS1:
4528 pri_cc_act_promote_raw_a_status(ctrl, cc_record);
4529 if (cc_record->party_a_status != CC_PARTY_A_AVAILABILITY_INVALID) {
4530 /* Only received User A busy. */
4531 pri_cc_act_raw_status_count_reset(ctrl, cc_record);
4532 } else {
4533 /* Did not get any responses. */
4534 pri_cc_act_raw_status_count_increment(ctrl, cc_record);
4535 if (cc_record->fsm.ptmp.party_a_status_count >= RAW_STATUS_COUNT_MAX) {
4536 /* User A no longer present. */
4537 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4538 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4539 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4540 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4541 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4542 pri_cc_act_set_self_destruct(ctrl, cc_record);
4543 cc_record->state = CC_STATE_IDLE;
4544 }
4545 }
4546 break;
4547 case CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1:
4548 pri_cc_act_reset_a_status(ctrl, cc_record);
4549 pri_cc_act_raw_status_count_reset(ctrl, cc_record);
4550 break;
4551 case CC_EVENT_TIMEOUT_T_SUPERVISION:
4552 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4553 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 1 /* t-CCBS2-timeout */);
4554 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4555 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4556 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4557 pri_cc_act_set_self_destruct(ctrl, cc_record);
4558 cc_record->state = CC_STATE_IDLE;
4559 break;
4560 case CC_EVENT_LINK_CANCEL:
4561 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4562 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4563 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4564 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4565 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4566 pri_cc_act_set_self_destruct(ctrl, cc_record);
4567 cc_record->state = CC_STATE_IDLE;
4568 break;
4569 case CC_EVENT_CANCEL:
4570 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4571 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4572 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4573 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4574 pri_cc_act_set_self_destruct(ctrl, cc_record);
4575 cc_record->state = CC_STATE_IDLE;
4576 break;
4577 default:
4578 break;
4579 }
4580 }
4581
4582 /*!
4583 * \internal
4584 * \brief CC FSM PTMP agent CC_STATE_B_AVAILABLE.
4585 *
4586 * \param ctrl D channel controller.
4587 * \param call Q.931 call leg.
4588 * \param cc_record Call completion record to process event.
4589 * \param event Event to process.
4590 *
4591 * \return Nothing
4592 */
pri_cc_fsm_ptmp_agent_b_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4593 static void pri_cc_fsm_ptmp_agent_b_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4594 {
4595 switch (event) {
4596 case CC_EVENT_RECALL:
4597 pri_cc_act_send_error_recall(ctrl, cc_record, ROSE_ERROR_CCBS_NotReadyForCall);
4598 pri_cc_act_set_call_to_hangup(ctrl, cc_record, call);
4599 break;
4600 case CC_EVENT_A_STATUS:
4601 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4602 pri_cc_act_start_extended_t_ccbs1(ctrl, cc_record);
4603 pri_cc_act_pass_up_status_rsp_a_indirect(ctrl, cc_record);
4604 break;
4605 case CC_EVENT_A_FREE:
4606 pri_cc_act_send_remote_user_free(ctrl, cc_record);
4607 pri_cc_act_set_raw_a_status_free(ctrl, cc_record);
4608 //pri_cc_act_promote_raw_a_status(ctrl, cc_record);
4609 //pri_cc_act_pass_up_a_status(ctrl, cc_record);
4610 if (cc_record->fsm.ptmp.extended_t_ccbs1) {
4611 pri_cc_act_pass_up_status_rsp_a(ctrl, cc_record);
4612 }
4613 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4614 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4615 pri_cc_act_start_t_recall(ctrl, cc_record);
4616 cc_record->state = CC_STATE_WAIT_CALLBACK;
4617 break;
4618 case CC_EVENT_A_BUSY:
4619 pri_cc_act_add_raw_a_status_busy(ctrl, cc_record);
4620 if (cc_record->fsm.ptmp.extended_t_ccbs1) {
4621 pri_cc_act_pass_up_status_rsp_a(ctrl, cc_record);
4622 }
4623 break;
4624 case CC_EVENT_TIMEOUT_T_CCBS1:
4625 if (cc_record->fsm.ptmp.party_a_status_acc != CC_PARTY_A_AVAILABILITY_INVALID) {
4626 /* Only received User A busy. */
4627 pri_cc_act_raw_status_count_reset(ctrl, cc_record);
4628 pri_cc_act_send_ccbs_b_free(ctrl, cc_record);
4629 pri_cc_act_promote_raw_a_status(ctrl, cc_record);
4630 pri_cc_act_pass_up_a_status(ctrl, cc_record);
4631 /* Optimization due to flattening. */
4632 //if (!pri_cc_get_t_ccbs1_status(cc_record))
4633 {
4634 pri_cc_act_reset_raw_a_status(ctrl, cc_record);
4635 pri_cc_act_send_ccbs_status_request(ctrl, cc_record);
4636 //pri_cc_act_start_t_ccbs1(ctrl, cc_record);
4637 }
4638 cc_record->state = CC_STATE_SUSPENDED;
4639 } else {
4640 /* Did not get any responses. */
4641 pri_cc_act_raw_status_count_increment(ctrl, cc_record);
4642 if (cc_record->fsm.ptmp.party_a_status_count >= RAW_STATUS_COUNT_MAX) {
4643 /* User A no longer present. */
4644 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4645 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4646 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4647 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4648 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4649 pri_cc_act_set_self_destruct(ctrl, cc_record);
4650 cc_record->state = CC_STATE_IDLE;
4651 break;
4652 }
4653 //pri_cc_act_reset_raw_a_status(ctrl, cc_record);
4654 pri_cc_act_send_ccbs_status_request(ctrl, cc_record);
4655 //pri_cc_act_start_t_ccbs1(ctrl, cc_record);
4656 }
4657 break;
4658 case CC_EVENT_TIMEOUT_T_SUPERVISION:
4659 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4660 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 1 /* t-CCBS2-timeout */);
4661 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4662 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4663 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4664 pri_cc_act_set_self_destruct(ctrl, cc_record);
4665 cc_record->state = CC_STATE_IDLE;
4666 break;
4667 case CC_EVENT_LINK_CANCEL:
4668 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4669 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4670 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4671 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4672 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4673 pri_cc_act_set_self_destruct(ctrl, cc_record);
4674 cc_record->state = CC_STATE_IDLE;
4675 break;
4676 case CC_EVENT_CANCEL:
4677 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4678 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4679 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4680 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4681 pri_cc_act_set_self_destruct(ctrl, cc_record);
4682 cc_record->state = CC_STATE_IDLE;
4683 break;
4684 default:
4685 break;
4686 }
4687 }
4688
4689 /*!
4690 * \internal
4691 * \brief CC FSM PTMP agent CC_STATE_SUSPENDED.
4692 *
4693 * \param ctrl D channel controller.
4694 * \param call Q.931 call leg.
4695 * \param cc_record Call completion record to process event.
4696 * \param event Event to process.
4697 *
4698 * \return Nothing
4699 */
pri_cc_fsm_ptmp_agent_suspended(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4700 static void pri_cc_fsm_ptmp_agent_suspended(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4701 {
4702 switch (event) {
4703 case CC_EVENT_RECALL:
4704 pri_cc_act_send_error_recall(ctrl, cc_record, ROSE_ERROR_CCBS_NotReadyForCall);
4705 pri_cc_act_set_call_to_hangup(ctrl, cc_record, call);
4706 break;
4707 case CC_EVENT_A_STATUS:
4708 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4709 pri_cc_act_start_extended_t_ccbs1(ctrl, cc_record);
4710 pri_cc_act_pass_up_status_rsp_a_indirect(ctrl, cc_record);
4711 break;
4712 case CC_EVENT_A_FREE:
4713 pri_cc_act_set_raw_a_status_free(ctrl, cc_record);
4714 pri_cc_act_promote_raw_a_status(ctrl, cc_record);
4715 pri_cc_act_pass_up_a_status(ctrl, cc_record);
4716 if (cc_record->fsm.ptmp.extended_t_ccbs1) {
4717 pri_cc_act_pass_up_status_rsp_a(ctrl, cc_record);
4718 }
4719 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4720 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4721 pri_cc_act_reset_a_status(ctrl, cc_record);
4722 pri_cc_act_raw_status_count_reset(ctrl, cc_record);
4723 cc_record->state = CC_STATE_ACTIVATED;
4724 break;
4725 case CC_EVENT_A_BUSY:
4726 pri_cc_act_add_raw_a_status_busy(ctrl, cc_record);
4727 if (cc_record->fsm.ptmp.extended_t_ccbs1) {
4728 pri_cc_act_pass_up_status_rsp_a(ctrl, cc_record);
4729 }
4730 break;
4731 case CC_EVENT_TIMEOUT_T_CCBS1:
4732 if (cc_record->fsm.ptmp.party_a_status_acc != CC_PARTY_A_AVAILABILITY_INVALID) {
4733 /* Only received User A busy. */
4734 pri_cc_act_raw_status_count_reset(ctrl, cc_record);
4735 } else {
4736 /* Did not get any responses. */
4737 pri_cc_act_raw_status_count_increment(ctrl, cc_record);
4738 if (cc_record->fsm.ptmp.party_a_status_count >= RAW_STATUS_COUNT_MAX) {
4739 /* User A no longer present. */
4740 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4741 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4742 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4743 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4744 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4745 pri_cc_act_set_self_destruct(ctrl, cc_record);
4746 cc_record->state = CC_STATE_IDLE;
4747 break;
4748 }
4749 }
4750 pri_cc_act_reset_raw_a_status(ctrl, cc_record);
4751 pri_cc_act_send_ccbs_status_request(ctrl, cc_record);
4752 //pri_cc_act_start_t_ccbs1(ctrl, cc_record);
4753 break;
4754 case CC_EVENT_TIMEOUT_T_SUPERVISION:
4755 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4756 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 1 /* t-CCBS2-timeout */);
4757 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4758 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4759 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4760 pri_cc_act_set_self_destruct(ctrl, cc_record);
4761 cc_record->state = CC_STATE_IDLE;
4762 break;
4763 case CC_EVENT_LINK_CANCEL:
4764 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4765 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4766 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4767 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4768 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4769 pri_cc_act_set_self_destruct(ctrl, cc_record);
4770 cc_record->state = CC_STATE_IDLE;
4771 break;
4772 case CC_EVENT_CANCEL:
4773 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4774 pri_cc_act_stop_t_ccbs1(ctrl, cc_record);
4775 pri_cc_act_stop_extended_t_ccbs1(ctrl, cc_record);
4776 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4777 pri_cc_act_set_self_destruct(ctrl, cc_record);
4778 cc_record->state = CC_STATE_IDLE;
4779 break;
4780 default:
4781 break;
4782 }
4783 }
4784
4785 /*!
4786 * \internal
4787 * \brief CC FSM PTMP agent CC_STATE_WAIT_CALLBACK.
4788 *
4789 * \param ctrl D channel controller.
4790 * \param call Q.931 call leg.
4791 * \param cc_record Call completion record to process event.
4792 * \param event Event to process.
4793 *
4794 * \return Nothing
4795 */
pri_cc_fsm_ptmp_agent_wait_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4796 static void pri_cc_fsm_ptmp_agent_wait_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4797 {
4798 switch (event) {
4799 case CC_EVENT_TIMEOUT_T_RECALL:
4800 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4801 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 2 /* t-CCBS3-timeout */);
4802 pri_cc_act_stop_t_recall(ctrl, cc_record);
4803 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4804 pri_cc_act_set_self_destruct(ctrl, cc_record);
4805 cc_record->state = CC_STATE_IDLE;
4806 break;
4807 case CC_EVENT_STOP_ALERTING:
4808 /*
4809 * If an earlier link can send us this event then we
4810 * really should be configured for globalRecall like
4811 * the earlier link.
4812 */
4813 if (cc_record->option.recall_mode == 0 /* globalRecall */) {
4814 pri_cc_act_send_ccbs_stop_alerting(ctrl, cc_record);
4815 }
4816 pri_cc_act_stop_t_recall(ctrl, cc_record);
4817 pri_cc_act_reset_a_status(ctrl, cc_record);
4818 pri_cc_act_raw_status_count_reset(ctrl, cc_record);
4819 cc_record->state = CC_STATE_ACTIVATED;
4820 break;
4821 case CC_EVENT_RECALL:
4822 pri_cc_act_pass_up_cc_call(ctrl, cc_record);
4823 pri_cc_act_set_original_call_parameters(ctrl, call, cc_record);
4824 if (cc_record->option.recall_mode == 0 /* globalRecall */) {
4825 pri_cc_act_send_ccbs_stop_alerting(ctrl, cc_record);
4826 }
4827 pri_cc_act_stop_t_recall(ctrl, cc_record);
4828 cc_record->state = CC_STATE_CALLBACK;
4829 break;
4830 case CC_EVENT_A_STATUS:
4831 pri_cc_act_set_raw_a_status_free(ctrl, cc_record);
4832 pri_cc_act_pass_up_status_rsp_a_indirect(ctrl, cc_record);
4833 break;
4834 case CC_EVENT_TIMEOUT_T_SUPERVISION:
4835 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4836 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 1 /* t-CCBS2-timeout */);
4837 pri_cc_act_stop_t_recall(ctrl, cc_record);
4838 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4839 pri_cc_act_set_self_destruct(ctrl, cc_record);
4840 cc_record->state = CC_STATE_IDLE;
4841 break;
4842 case CC_EVENT_LINK_CANCEL:
4843 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4844 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4845 pri_cc_act_stop_t_recall(ctrl, cc_record);
4846 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4847 pri_cc_act_set_self_destruct(ctrl, cc_record);
4848 cc_record->state = CC_STATE_IDLE;
4849 break;
4850 case CC_EVENT_CANCEL:
4851 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4852 pri_cc_act_stop_t_recall(ctrl, cc_record);
4853 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4854 pri_cc_act_set_self_destruct(ctrl, cc_record);
4855 cc_record->state = CC_STATE_IDLE;
4856 break;
4857 default:
4858 break;
4859 }
4860 }
4861
4862 /*!
4863 * \internal
4864 * \brief CC FSM PTMP agent CC_STATE_CALLBACK.
4865 *
4866 * \param ctrl D channel controller.
4867 * \param call Q.931 call leg.
4868 * \param cc_record Call completion record to process event.
4869 * \param event Event to process.
4870 *
4871 * \return Nothing
4872 */
pri_cc_fsm_ptmp_agent_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4873 static void pri_cc_fsm_ptmp_agent_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4874 {
4875 switch (event) {
4876 case CC_EVENT_RECALL:
4877 pri_cc_act_send_error_recall(ctrl, cc_record, ROSE_ERROR_CCBS_AlreadyAccepted);
4878 pri_cc_act_set_call_to_hangup(ctrl, cc_record, call);
4879 break;
4880 case CC_EVENT_A_STATUS:
4881 pri_cc_act_set_raw_a_status_free(ctrl, cc_record);
4882 pri_cc_act_pass_up_status_rsp_a_indirect(ctrl, cc_record);
4883 break;
4884 case CC_EVENT_TIMEOUT_T_SUPERVISION:
4885 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4886 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 1 /* t-CCBS2-timeout */);
4887 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4888 pri_cc_act_set_self_destruct(ctrl, cc_record);
4889 cc_record->state = CC_STATE_IDLE;
4890 break;
4891 case CC_EVENT_LINK_CANCEL:
4892 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4893 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4894 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4895 pri_cc_act_set_self_destruct(ctrl, cc_record);
4896 cc_record->state = CC_STATE_IDLE;
4897 break;
4898 case CC_EVENT_CANCEL:
4899 pri_cc_act_send_ccbs_erase(ctrl, cc_record, 0 /* normal-unspecified */);
4900 pri_cc_act_stop_t_supervision(ctrl, cc_record);
4901 pri_cc_act_set_self_destruct(ctrl, cc_record);
4902 cc_record->state = CC_STATE_IDLE;
4903 break;
4904 default:
4905 break;
4906 }
4907 }
4908
4909 /*!
4910 * \internal
4911 * \brief CC FSM PTMP monitor CC_STATE_IDLE.
4912 *
4913 * \param ctrl D channel controller.
4914 * \param call Q.931 call leg.
4915 * \param cc_record Call completion record to process event.
4916 * \param event Event to process.
4917 *
4918 * \return Nothing
4919 */
pri_cc_fsm_ptmp_monitor_idle(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4920 static void pri_cc_fsm_ptmp_monitor_idle(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4921 {
4922 switch (event) {
4923 case CC_EVENT_AVAILABLE:
4924 /*
4925 * Before event is posted:
4926 * Received CallInfoRetain
4927 * Created cc_record
4928 * Saved CallLinkageID
4929 */
4930 pri_cc_act_pass_up_cc_available(ctrl, cc_record);
4931 cc_record->state = CC_STATE_AVAILABLE;
4932 break;
4933 case CC_EVENT_CANCEL:
4934 pri_cc_act_set_self_destruct(ctrl, cc_record);
4935 break;
4936 default:
4937 break;
4938 }
4939 }
4940
4941 /*!
4942 * \internal
4943 * \brief CC FSM PTMP monitor CC_STATE_AVAILABLE.
4944 *
4945 * \param ctrl D channel controller.
4946 * \param call Q.931 call leg.
4947 * \param cc_record Call completion record to process event.
4948 * \param event Event to process.
4949 *
4950 * \return Nothing
4951 */
pri_cc_fsm_ptmp_monitor_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4952 static void pri_cc_fsm_ptmp_monitor_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4953 {
4954 /*
4955 * The upper layer is responsible for canceling the CC available
4956 * offering as a safeguard in case the network cable is disconnected.
4957 * The timer should be set much longer than the network T_RETENTION
4958 * timer so normally the CC records will be cleaned up by network
4959 * activity.
4960 */
4961 switch (event) {
4962 case CC_EVENT_CC_REQUEST:
4963 /* cc_record->is_ccnr is set before event posted. */
4964 pri_cc_act_queue_cc_request(ctrl, cc_record, call);
4965 //pri_cc_act_start_t_activate(ctrl, cc_record);
4966 cc_record->state = CC_STATE_REQUESTED;
4967 break;
4968 case CC_EVENT_TIMEOUT_T_RETENTION:
4969 /*
4970 * Received EraseCallLinkageID
4971 * T_RETENTION expired on the network side so we will pretend
4972 * that it expired on our side.
4973 */
4974 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
4975 pri_cc_act_set_self_destruct(ctrl, cc_record);
4976 cc_record->state = CC_STATE_IDLE;
4977 break;
4978 case CC_EVENT_CANCEL:
4979 pri_cc_act_set_self_destruct(ctrl, cc_record);
4980 cc_record->state = CC_STATE_IDLE;
4981 break;
4982 default:
4983 break;
4984 }
4985 }
4986
4987 /*!
4988 * \internal
4989 * \brief CC FSM PTMP monitor CC_STATE_REQUESTED.
4990 *
4991 * \param ctrl D channel controller.
4992 * \param call Q.931 call leg.
4993 * \param cc_record Call completion record to process event.
4994 * \param event Event to process.
4995 *
4996 * \return Nothing
4997 */
pri_cc_fsm_ptmp_monitor_req(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)4998 static void pri_cc_fsm_ptmp_monitor_req(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
4999 {
5000 switch (event) {
5001 case CC_EVENT_CC_REQUEST_ACCEPT:
5002 /*
5003 * Before event is posted:
5004 * Received CCBSRequest/CCNRRequest response
5005 * Saved CCBSReference
5006 */
5007 pri_cc_act_release_link_id(ctrl, cc_record);
5008 pri_cc_act_pass_up_cc_req_rsp_success(ctrl, cc_record);
5009 pri_cc_act_stop_t_activate(ctrl, cc_record);
5010 /*
5011 * Start T_CCBS2 or T_CCNR2 depending upon CC mode.
5012 * For PTMP TE mode these timers are not defined. However,
5013 * we will use them anyway to protect our resources from leaks
5014 * caused by the network cable being disconnected. These
5015 * timers should be set much longer than the network
5016 * so normally the CC records will be cleaned up by network
5017 * activity.
5018 */
5019 pri_cc_act_start_t_supervision(ctrl, cc_record);
5020 cc_record->state = CC_STATE_ACTIVATED;
5021 break;
5022 case CC_EVENT_CC_REQUEST_FAIL:
5023 pri_cc_act_pass_up_cc_req_rsp_fail(ctrl, cc_record);
5024 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5025 pri_cc_act_stop_t_activate(ctrl, cc_record);
5026 pri_cc_act_set_self_destruct(ctrl, cc_record);
5027 cc_record->state = CC_STATE_IDLE;
5028 break;
5029 case CC_EVENT_TIMEOUT_T_ACTIVATE:
5030 pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
5031 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5032 pri_cc_act_stop_t_activate(ctrl, cc_record);
5033 pri_cc_act_set_self_destruct(ctrl, cc_record);
5034 cc_record->state = CC_STATE_IDLE;
5035 break;
5036 case CC_EVENT_LINK_CANCEL:
5037 /* Received CCBSErase */
5038 /* Claim it was a timeout */
5039 pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
5040 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5041 pri_cc_act_stop_t_activate(ctrl, cc_record);
5042 pri_cc_act_set_self_destruct(ctrl, cc_record);
5043 cc_record->state = CC_STATE_IDLE;
5044 break;
5045 case CC_EVENT_CANCEL:
5046 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
5047 break;
5048 default:
5049 break;
5050 }
5051 }
5052
5053 /*!
5054 * \internal
5055 * \brief CC FSM PTMP monitor CC_STATE_WAIT_DESTRUCTION.
5056 *
5057 * \param ctrl D channel controller.
5058 * \param call Q.931 call leg.
5059 * \param cc_record Call completion record to process event.
5060 * \param event Event to process.
5061 *
5062 * \return Nothing
5063 */
pri_cc_fsm_ptmp_monitor_wait_destruction(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5064 static void pri_cc_fsm_ptmp_monitor_wait_destruction(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5065 {
5066 /* We were in the middle of a cc-request when we were asked to cancel. */
5067 switch (event) {
5068 case CC_EVENT_CC_REQUEST_ACCEPT:
5069 /*
5070 * Before event is posted:
5071 * Received CCBSRequest/CCNRRequest response
5072 * Saved CCBSReference
5073 */
5074 pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
5075 pri_cc_act_stop_t_activate(ctrl, cc_record);
5076 pri_cc_act_set_self_destruct(ctrl, cc_record);
5077 cc_record->state = CC_STATE_IDLE;
5078 break;
5079 case CC_EVENT_CC_REQUEST_FAIL:
5080 pri_cc_act_stop_t_activate(ctrl, cc_record);
5081 pri_cc_act_set_self_destruct(ctrl, cc_record);
5082 cc_record->state = CC_STATE_IDLE;
5083 break;
5084 case CC_EVENT_TIMEOUT_T_ACTIVATE:
5085 pri_cc_act_stop_t_activate(ctrl, cc_record);
5086 pri_cc_act_set_self_destruct(ctrl, cc_record);
5087 cc_record->state = CC_STATE_IDLE;
5088 break;
5089 case CC_EVENT_LINK_CANCEL:
5090 /* Received CCBSErase */
5091 pri_cc_act_stop_t_activate(ctrl, cc_record);
5092 pri_cc_act_set_self_destruct(ctrl, cc_record);
5093 cc_record->state = CC_STATE_IDLE;
5094 break;
5095 default:
5096 break;
5097 }
5098 }
5099
5100 /*!
5101 * \internal
5102 * \brief CC FSM PTMP monitor CC_STATE_ACTIVATED.
5103 *
5104 * \param ctrl D channel controller.
5105 * \param call Q.931 call leg.
5106 * \param cc_record Call completion record to process event.
5107 * \param event Event to process.
5108 *
5109 * \return Nothing
5110 */
pri_cc_fsm_ptmp_monitor_activated(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5111 static void pri_cc_fsm_ptmp_monitor_activated(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5112 {
5113 switch (event) {
5114 case CC_EVENT_B_FREE:
5115 /* Received CCBSBFree */
5116 pri_cc_act_pass_up_b_free(ctrl, cc_record);
5117 break;
5118 case CC_EVENT_REMOTE_USER_FREE:
5119 /* Received CCBSRemoteUserFree */
5120 pri_cc_act_pass_up_remote_user_free(ctrl, cc_record);
5121 cc_record->state = CC_STATE_WAIT_CALLBACK;
5122 break;
5123 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5124 pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
5125 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5126 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5127 pri_cc_act_set_self_destruct(ctrl, cc_record);
5128 cc_record->state = CC_STATE_IDLE;
5129 break;
5130 case CC_EVENT_LINK_CANCEL:
5131 /* Received CCBSErase */
5132 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5133 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5134 pri_cc_act_set_self_destruct(ctrl, cc_record);
5135 cc_record->state = CC_STATE_IDLE;
5136 break;
5137 case CC_EVENT_CANCEL:
5138 pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
5139 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5140 pri_cc_act_set_self_destruct(ctrl, cc_record);
5141 cc_record->state = CC_STATE_IDLE;
5142 break;
5143 default:
5144 break;
5145 }
5146 }
5147
5148 /*!
5149 * \internal
5150 * \brief CC FSM PTMP monitor CC_STATE_WAIT_CALLBACK.
5151 *
5152 * \param ctrl D channel controller.
5153 * \param call Q.931 call leg.
5154 * \param cc_record Call completion record to process event.
5155 * \param event Event to process.
5156 *
5157 * \return Nothing
5158 */
pri_cc_fsm_ptmp_monitor_wait_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5159 static void pri_cc_fsm_ptmp_monitor_wait_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5160 {
5161 switch (event) {
5162 case CC_EVENT_STOP_ALERTING:
5163 pri_cc_act_pass_up_stop_alerting(ctrl, cc_record);
5164 cc_record->state = CC_STATE_ACTIVATED;
5165 break;
5166 case CC_EVENT_RECALL:
5167 /* The original call parameters have already been set. */
5168 pri_cc_act_queue_setup_recall(ctrl, cc_record, call);
5169 cc_record->state = CC_STATE_CALLBACK;
5170 break;
5171 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5172 pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
5173 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5174 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5175 pri_cc_act_set_self_destruct(ctrl, cc_record);
5176 cc_record->state = CC_STATE_IDLE;
5177 break;
5178 case CC_EVENT_LINK_CANCEL:
5179 /* Received CCBSErase */
5180 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5181 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5182 pri_cc_act_set_self_destruct(ctrl, cc_record);
5183 cc_record->state = CC_STATE_IDLE;
5184 break;
5185 case CC_EVENT_CANCEL:
5186 pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
5187 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5188 pri_cc_act_set_self_destruct(ctrl, cc_record);
5189 cc_record->state = CC_STATE_IDLE;
5190 break;
5191 default:
5192 break;
5193 }
5194 }
5195
5196 /*!
5197 * \internal
5198 * \brief CC FSM PTMP monitor CC_STATE_CALLBACK.
5199 *
5200 * \param ctrl D channel controller.
5201 * \param call Q.931 call leg.
5202 * \param cc_record Call completion record to process event.
5203 * \param event Event to process.
5204 *
5205 * \return Nothing
5206 */
pri_cc_fsm_ptmp_monitor_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5207 static void pri_cc_fsm_ptmp_monitor_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5208 {
5209 /*
5210 * We are waiting for the CC records to be torn down because
5211 * CC is complete.
5212 * This state is mainly to block CC_EVENT_STOP_ALERTING since
5213 * we are the one doing the CC recall so we do not need to stop
5214 * alerting.
5215 */
5216 switch (event) {
5217 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5218 pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
5219 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5220 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5221 pri_cc_act_set_self_destruct(ctrl, cc_record);
5222 cc_record->state = CC_STATE_IDLE;
5223 break;
5224 case CC_EVENT_LINK_CANCEL:
5225 /* Received CCBSErase */
5226 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5227 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5228 pri_cc_act_set_self_destruct(ctrl, cc_record);
5229 cc_record->state = CC_STATE_IDLE;
5230 break;
5231 case CC_EVENT_CANCEL:
5232 pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
5233 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5234 pri_cc_act_set_self_destruct(ctrl, cc_record);
5235 cc_record->state = CC_STATE_IDLE;
5236 break;
5237 default:
5238 break;
5239 }
5240 }
5241
5242 /*!
5243 * \internal
5244 * \brief CC FSM PTP agent CC_STATE_IDLE.
5245 *
5246 * \param ctrl D channel controller.
5247 * \param call Q.931 call leg.
5248 * \param cc_record Call completion record to process event.
5249 * \param event Event to process.
5250 *
5251 * \return Nothing
5252 */
pri_cc_fsm_ptp_agent_idle(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5253 static void pri_cc_fsm_ptp_agent_idle(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5254 {
5255 switch (event) {
5256 case CC_EVENT_AVAILABLE:
5257 cc_record->state = CC_STATE_PENDING_AVAILABLE;
5258 break;
5259 case CC_EVENT_CANCEL:
5260 pri_cc_act_set_self_destruct(ctrl, cc_record);
5261 break;
5262 default:
5263 break;
5264 }
5265 }
5266
5267 /*!
5268 * \internal
5269 * \brief CC FSM PTP agent CC_STATE_PENDING_AVAILABLE.
5270 *
5271 * \param ctrl D channel controller.
5272 * \param call Q.931 call leg.
5273 * \param cc_record Call completion record to process event.
5274 * \param event Event to process.
5275 *
5276 * \return Nothing
5277 */
pri_cc_fsm_ptp_agent_pend_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5278 static void pri_cc_fsm_ptp_agent_pend_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5279 {
5280 switch (event) {
5281 case CC_EVENT_MSG_ALERTING:
5282 pri_cc_act_send_cc_available(ctrl, cc_record, call, Q931_ALERTING);
5283 cc_record->state = CC_STATE_AVAILABLE;
5284 break;
5285 case CC_EVENT_MSG_DISCONNECT:
5286 pri_cc_act_send_cc_available(ctrl, cc_record, call, Q931_DISCONNECT);
5287 cc_record->state = CC_STATE_AVAILABLE;
5288 break;
5289 case CC_EVENT_INTERNAL_CLEARING:
5290 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5291 pri_cc_act_set_self_destruct(ctrl, cc_record);
5292 cc_record->state = CC_STATE_IDLE;
5293 break;
5294 case CC_EVENT_CANCEL:
5295 pri_cc_act_set_self_destruct(ctrl, cc_record);
5296 cc_record->state = CC_STATE_IDLE;
5297 break;
5298 default:
5299 break;
5300 }
5301 }
5302
5303 /*!
5304 * \internal
5305 * \brief CC FSM PTP agent CC_STATE_AVAILABLE.
5306 *
5307 * \param ctrl D channel controller.
5308 * \param call Q.931 call leg.
5309 * \param cc_record Call completion record to process event.
5310 * \param event Event to process.
5311 *
5312 * \return Nothing
5313 */
pri_cc_fsm_ptp_agent_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5314 static void pri_cc_fsm_ptp_agent_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5315 {
5316 /*
5317 * For PTP mode the T_RETENTION timer is not defined. However,
5318 * we will use it anyway in this state to protect our resources
5319 * from leaks caused by user A not requesting CC. This timer
5320 * should be set much longer than the PTMP network link to
5321 * allow for variations in user A's CC offer timer.
5322 */
5323 switch (event) {
5324 case CC_EVENT_MSG_RELEASE:
5325 case CC_EVENT_MSG_RELEASE_COMPLETE:
5326 pri_cc_act_stop_t_retention(ctrl, cc_record);
5327 pri_cc_act_start_t_retention(ctrl, cc_record);
5328 break;
5329 case CC_EVENT_CC_REQUEST:
5330 pri_cc_act_pass_up_cc_request(ctrl, cc_record);
5331 pri_cc_act_stop_t_retention(ctrl, cc_record);
5332 cc_record->state = CC_STATE_REQUESTED;
5333 break;
5334 case CC_EVENT_INTERNAL_CLEARING:
5335 pri_cc_act_stop_t_retention(ctrl, cc_record);
5336 pri_cc_act_start_t_retention(ctrl, cc_record);
5337 break;
5338 case CC_EVENT_TIMEOUT_T_RETENTION:
5339 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5340 pri_cc_act_stop_t_retention(ctrl, cc_record);
5341 pri_cc_act_set_self_destruct(ctrl, cc_record);
5342 cc_record->state = CC_STATE_IDLE;
5343 break;
5344 case CC_EVENT_CANCEL:
5345 pri_cc_act_stop_t_retention(ctrl, cc_record);
5346 pri_cc_act_set_self_destruct(ctrl, cc_record);
5347 cc_record->state = CC_STATE_IDLE;
5348 break;
5349 default:
5350 break;
5351 }
5352 }
5353
5354 /*!
5355 * \internal
5356 * \brief CC FSM PTP agent CC_STATE_REQUESTED.
5357 *
5358 * \param ctrl D channel controller.
5359 * \param call Q.931 call leg.
5360 * \param cc_record Call completion record to process event.
5361 * \param event Event to process.
5362 *
5363 * \return Nothing
5364 */
pri_cc_fsm_ptp_agent_req(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5365 static void pri_cc_fsm_ptp_agent_req(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5366 {
5367 switch (event) {
5368 case CC_EVENT_CC_REQUEST_ACCEPT:
5369 /* Start T_CCBS5/T_CCNR5 depending upon CC mode. */
5370 pri_cc_act_start_t_supervision(ctrl, cc_record);
5371 pri_cc_act_reset_a_status(ctrl, cc_record);
5372 cc_record->state = CC_STATE_ACTIVATED;
5373 break;
5374 case CC_EVENT_SIGNALING_GONE:
5375 /* Signaling link cleared. */
5376 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5377 pri_cc_act_set_self_destruct(ctrl, cc_record);
5378 cc_record->state = CC_STATE_IDLE;
5379 break;
5380 case CC_EVENT_CANCEL:
5381 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5382 pri_cc_act_set_self_destruct(ctrl, cc_record);
5383 cc_record->state = CC_STATE_IDLE;
5384 break;
5385 default:
5386 break;
5387 }
5388 }
5389
5390 /*!
5391 * \internal
5392 * \brief CC FSM PTP agent CC_STATE_ACTIVATED.
5393 *
5394 * \param ctrl D channel controller.
5395 * \param call Q.931 call leg.
5396 * \param cc_record Call completion record to process event.
5397 * \param event Event to process.
5398 *
5399 * \return Nothing
5400 */
pri_cc_fsm_ptp_agent_activated(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5401 static void pri_cc_fsm_ptp_agent_activated(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5402 {
5403 switch (event) {
5404 case CC_EVENT_REMOTE_USER_FREE:
5405 pri_cc_act_pass_up_a_status_indirect(ctrl, cc_record);
5406 if (cc_record->party_a_status == CC_PARTY_A_AVAILABILITY_BUSY) {
5407 cc_record->state = CC_STATE_SUSPENDED;
5408 } else {
5409 pri_cc_act_send_remote_user_free(ctrl, cc_record);
5410 cc_record->state = CC_STATE_WAIT_CALLBACK;
5411 }
5412 break;
5413 case CC_EVENT_SUSPEND:
5414 /* Received CCBS_T_Suspend */
5415 pri_cc_act_set_a_status_busy(ctrl, cc_record);
5416 break;
5417 case CC_EVENT_RESUME:
5418 /* Received CCBS_T_Resume */
5419 pri_cc_act_reset_a_status(ctrl, cc_record);
5420 break;
5421 case CC_EVENT_RECALL:
5422 /* Received CCBS_T_Call */
5423 pri_cc_act_pass_up_cc_call(ctrl, cc_record);
5424 pri_cc_act_set_original_call_parameters(ctrl, call, cc_record);
5425 break;
5426 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5427 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5428 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5429 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5430 pri_cc_act_set_self_destruct(ctrl, cc_record);
5431 cc_record->state = CC_STATE_IDLE;
5432 break;
5433 case CC_EVENT_SIGNALING_GONE:
5434 /* Signaling link cleared. */
5435 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5436 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5437 pri_cc_act_set_self_destruct(ctrl, cc_record);
5438 cc_record->state = CC_STATE_IDLE;
5439 break;
5440 case CC_EVENT_CANCEL:
5441 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5442 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5443 pri_cc_act_set_self_destruct(ctrl, cc_record);
5444 cc_record->state = CC_STATE_IDLE;
5445 break;
5446 default:
5447 break;
5448 }
5449 }
5450
5451 /*!
5452 * \internal
5453 * \brief CC FSM PTP agent CC_STATE_WAIT_CALLBACK.
5454 *
5455 * \param ctrl D channel controller.
5456 * \param call Q.931 call leg.
5457 * \param cc_record Call completion record to process event.
5458 * \param event Event to process.
5459 *
5460 * \return Nothing
5461 */
pri_cc_fsm_ptp_agent_wait_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5462 static void pri_cc_fsm_ptp_agent_wait_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5463 {
5464 switch (event) {
5465 case CC_EVENT_SUSPEND:
5466 /* Received CCBS_T_Suspend */
5467 pri_cc_act_set_a_status_busy(ctrl, cc_record);
5468 pri_cc_act_pass_up_a_status(ctrl, cc_record);
5469 cc_record->state = CC_STATE_SUSPENDED;
5470 break;
5471 case CC_EVENT_RECALL:
5472 /* Received CCBS_T_Call */
5473 pri_cc_act_pass_up_cc_call(ctrl, cc_record);
5474 pri_cc_act_set_original_call_parameters(ctrl, call, cc_record);
5475 break;
5476 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5477 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5478 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5479 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5480 pri_cc_act_set_self_destruct(ctrl, cc_record);
5481 cc_record->state = CC_STATE_IDLE;
5482 break;
5483 case CC_EVENT_SIGNALING_GONE:
5484 /* Signaling link cleared. */
5485 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5486 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5487 pri_cc_act_set_self_destruct(ctrl, cc_record);
5488 cc_record->state = CC_STATE_IDLE;
5489 break;
5490 case CC_EVENT_CANCEL:
5491 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5492 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5493 pri_cc_act_set_self_destruct(ctrl, cc_record);
5494 cc_record->state = CC_STATE_IDLE;
5495 break;
5496 default:
5497 break;
5498 }
5499 }
5500
5501 /*!
5502 * \internal
5503 * \brief CC FSM PTP agent CC_STATE_SUSPENDED.
5504 *
5505 * \param ctrl D channel controller.
5506 * \param call Q.931 call leg.
5507 * \param cc_record Call completion record to process event.
5508 * \param event Event to process.
5509 *
5510 * \return Nothing
5511 */
pri_cc_fsm_ptp_agent_suspended(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5512 static void pri_cc_fsm_ptp_agent_suspended(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5513 {
5514 switch (event) {
5515 case CC_EVENT_RESUME:
5516 /* Received CCBS_T_Resume */
5517 pri_cc_act_set_a_status_free(ctrl, cc_record);
5518 pri_cc_act_pass_up_a_status(ctrl, cc_record);
5519 pri_cc_act_reset_a_status(ctrl, cc_record);
5520 cc_record->state = CC_STATE_ACTIVATED;
5521 break;
5522 case CC_EVENT_RECALL:
5523 /* Received CCBS_T_Call */
5524 pri_cc_act_pass_up_cc_call(ctrl, cc_record);
5525 pri_cc_act_set_original_call_parameters(ctrl, call, cc_record);
5526 break;
5527 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5528 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5529 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5530 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5531 pri_cc_act_set_self_destruct(ctrl, cc_record);
5532 cc_record->state = CC_STATE_IDLE;
5533 break;
5534 case CC_EVENT_SIGNALING_GONE:
5535 /* Signaling link cleared. */
5536 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5537 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5538 pri_cc_act_set_self_destruct(ctrl, cc_record);
5539 cc_record->state = CC_STATE_IDLE;
5540 break;
5541 case CC_EVENT_CANCEL:
5542 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5543 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5544 pri_cc_act_set_self_destruct(ctrl, cc_record);
5545 cc_record->state = CC_STATE_IDLE;
5546 break;
5547 default:
5548 break;
5549 }
5550 }
5551
5552 /*!
5553 * \internal
5554 * \brief CC FSM PTP monitor CC_STATE_IDLE.
5555 *
5556 * \param ctrl D channel controller.
5557 * \param call Q.931 call leg.
5558 * \param cc_record Call completion record to process event.
5559 * \param event Event to process.
5560 *
5561 * \return Nothing
5562 */
pri_cc_fsm_ptp_monitor_idle(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5563 static void pri_cc_fsm_ptp_monitor_idle(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5564 {
5565 switch (event) {
5566 case CC_EVENT_AVAILABLE:
5567 /* Received CCBS-T-Aailable */
5568 pri_cc_act_pass_up_cc_available(ctrl, cc_record);
5569 cc_record->state = CC_STATE_AVAILABLE;
5570 break;
5571 case CC_EVENT_CANCEL:
5572 pri_cc_act_set_self_destruct(ctrl, cc_record);
5573 break;
5574 default:
5575 break;
5576 }
5577 }
5578
5579 /*!
5580 * \internal
5581 * \brief CC FSM PTP monitor CC_STATE_AVAILABLE.
5582 *
5583 * \param ctrl D channel controller.
5584 * \param call Q.931 call leg.
5585 * \param cc_record Call completion record to process event.
5586 * \param event Event to process.
5587 *
5588 * \return Nothing
5589 */
pri_cc_fsm_ptp_monitor_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5590 static void pri_cc_fsm_ptp_monitor_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5591 {
5592 /* The upper layer is responsible for canceling the CC available offering. */
5593 switch (event) {
5594 case CC_EVENT_CC_REQUEST:
5595 /*
5596 * Before event is posted:
5597 * cc_record->is_ccnr is set.
5598 * The signaling connection call record is created.
5599 */
5600 pri_cc_act_queue_cc_request(ctrl, cc_record, call);
5601 /*
5602 * For PTP mode the T_ACTIVATE timer is not defined. However,
5603 * we will use it to protect our resources from leaks caused
5604 * by the network cable being disconnected.
5605 * This timer should be set longer than normal so the
5606 * CC records will normally be cleaned up by network activity.
5607 */
5608 //pri_cc_act_start_t_activate(ctrl, cc_record);
5609 cc_record->state = CC_STATE_REQUESTED;
5610 break;
5611 case CC_EVENT_CANCEL:
5612 pri_cc_act_set_self_destruct(ctrl, cc_record);
5613 cc_record->state = CC_STATE_IDLE;
5614 break;
5615 default:
5616 break;
5617 }
5618 }
5619
5620 /*!
5621 * \internal
5622 * \brief CC FSM PTP monitor CC_STATE_REQUESTED.
5623 *
5624 * \param ctrl D channel controller.
5625 * \param call Q.931 call leg.
5626 * \param cc_record Call completion record to process event.
5627 * \param event Event to process.
5628 *
5629 * \return Nothing
5630 */
pri_cc_fsm_ptp_monitor_req(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5631 static void pri_cc_fsm_ptp_monitor_req(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5632 {
5633 switch (event) {
5634 case CC_EVENT_CC_REQUEST_ACCEPT:
5635 /*
5636 * Received CCBS-T-Request/CCNR-T-Request response
5637 * Before event is posted:
5638 * Negotiated CC retention setting saved
5639 */
5640 pri_cc_act_pass_up_cc_req_rsp_success(ctrl, cc_record);
5641 pri_cc_act_stop_t_activate(ctrl, cc_record);
5642 /* Start T_CCBS6/T_CCNR6 depending upon CC mode. */
5643 pri_cc_act_start_t_supervision(ctrl, cc_record);
5644 pri_cc_act_reset_a_status(ctrl, cc_record);
5645 cc_record->state = CC_STATE_ACTIVATED;
5646 break;
5647 case CC_EVENT_CC_REQUEST_FAIL:
5648 pri_cc_act_pass_up_cc_req_rsp_fail(ctrl, cc_record);
5649 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5650 /*
5651 * If this request fail comes in with the RELEASE_COMPLETE
5652 * message then the post action will never get a chance to
5653 * run. It will be aborted because the CC_EVENT_SIGNALING_GONE
5654 * will be processed first.
5655 */
5656 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
5657 pri_cc_act_stop_t_activate(ctrl, cc_record);
5658 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
5659 break;
5660 case CC_EVENT_TIMEOUT_T_ACTIVATE:
5661 pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
5662 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5663 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5664 pri_cc_act_stop_t_activate(ctrl, cc_record);
5665 pri_cc_act_set_self_destruct(ctrl, cc_record);
5666 cc_record->state = CC_STATE_IDLE;
5667 break;
5668 case CC_EVENT_SIGNALING_GONE:
5669 /* Claim it was a timeout */
5670 pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
5671 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5672 pri_cc_act_stop_t_activate(ctrl, cc_record);
5673 pri_cc_act_set_self_destruct(ctrl, cc_record);
5674 cc_record->state = CC_STATE_IDLE;
5675 break;
5676 case CC_EVENT_CANCEL:
5677 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5678 pri_cc_act_stop_t_activate(ctrl, cc_record);
5679 pri_cc_act_set_self_destruct(ctrl, cc_record);
5680 cc_record->state = CC_STATE_IDLE;
5681 break;
5682 default:
5683 break;
5684 }
5685 }
5686
5687 /*!
5688 * \internal
5689 * \brief CC FSM PTP monitor CC_STATE_WAIT_DESTRUCTION.
5690 *
5691 * \param ctrl D channel controller.
5692 * \param call Q.931 call leg.
5693 * \param cc_record Call completion record to process event.
5694 * \param event Event to process.
5695 *
5696 * \return Nothing
5697 */
pri_cc_fsm_ptp_monitor_wait_destruction(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5698 static void pri_cc_fsm_ptp_monitor_wait_destruction(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5699 {
5700 /*
5701 * Delayed disconnect of the signaling link to allow subcmd events
5702 * from the signaling link to be passed up.
5703 */
5704 switch (event) {
5705 case CC_EVENT_SIGNALING_GONE:
5706 /* Signaling link cleared. */
5707 pri_cc_act_set_self_destruct(ctrl, cc_record);
5708 cc_record->state = CC_STATE_IDLE;
5709 break;
5710 case CC_EVENT_HANGUP_SIGNALING:
5711 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5712 pri_cc_act_set_self_destruct(ctrl, cc_record);
5713 cc_record->state = CC_STATE_IDLE;
5714 break;
5715 case CC_EVENT_CANCEL:
5716 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5717 pri_cc_act_set_self_destruct(ctrl, cc_record);
5718 cc_record->state = CC_STATE_IDLE;
5719 break;
5720 default:
5721 break;
5722 }
5723 }
5724
5725 /*!
5726 * \internal
5727 * \brief CC FSM PTP monitor CC_STATE_ACTIVATED.
5728 *
5729 * \param ctrl D channel controller.
5730 * \param call Q.931 call leg.
5731 * \param cc_record Call completion record to process event.
5732 * \param event Event to process.
5733 *
5734 * \return Nothing
5735 */
pri_cc_fsm_ptp_monitor_activated(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5736 static void pri_cc_fsm_ptp_monitor_activated(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5737 {
5738 switch (event) {
5739 case CC_EVENT_REMOTE_USER_FREE:
5740 /* Received CCBS_T_RemoteUserFree */
5741 pri_cc_act_pass_up_remote_user_free(ctrl, cc_record);
5742 if (cc_record->party_a_status == CC_PARTY_A_AVAILABILITY_BUSY) {
5743 pri_cc_act_send_cc_suspend(ctrl, cc_record);
5744 cc_record->state = CC_STATE_SUSPENDED;
5745 } else {
5746 cc_record->state = CC_STATE_WAIT_CALLBACK;
5747 }
5748 break;
5749 case CC_EVENT_SUSPEND:
5750 pri_cc_act_set_a_status_busy(ctrl, cc_record);
5751 break;
5752 case CC_EVENT_RESUME:
5753 pri_cc_act_reset_a_status(ctrl, cc_record);
5754 break;
5755 case CC_EVENT_RECALL:
5756 /* The original call parameters have already been set. */
5757 pri_cc_act_queue_setup_recall(ctrl, cc_record, call);
5758 break;
5759 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5760 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5761 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5762 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5763 pri_cc_act_set_self_destruct(ctrl, cc_record);
5764 cc_record->state = CC_STATE_IDLE;
5765 break;
5766 case CC_EVENT_SIGNALING_GONE:
5767 /* Signaling link cleared. */
5768 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5769 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5770 pri_cc_act_set_self_destruct(ctrl, cc_record);
5771 cc_record->state = CC_STATE_IDLE;
5772 break;
5773 case CC_EVENT_CANCEL:
5774 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5775 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5776 pri_cc_act_set_self_destruct(ctrl, cc_record);
5777 cc_record->state = CC_STATE_IDLE;
5778 break;
5779 default:
5780 break;
5781 }
5782 }
5783
5784 /*!
5785 * \internal
5786 * \brief CC FSM PTP monitor CC_STATE_WAIT_CALLBACK.
5787 *
5788 * \param ctrl D channel controller.
5789 * \param call Q.931 call leg.
5790 * \param cc_record Call completion record to process event.
5791 * \param event Event to process.
5792 *
5793 * \return Nothing
5794 */
pri_cc_fsm_ptp_monitor_wait_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5795 static void pri_cc_fsm_ptp_monitor_wait_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5796 {
5797 switch (event) {
5798 case CC_EVENT_SUSPEND:
5799 pri_cc_act_send_cc_suspend(ctrl, cc_record);
5800 cc_record->state = CC_STATE_SUSPENDED;
5801 break;
5802 case CC_EVENT_RECALL:
5803 /* The original call parameters have already been set. */
5804 pri_cc_act_queue_setup_recall(ctrl, cc_record, call);
5805 break;
5806 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5807 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5808 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5809 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5810 pri_cc_act_set_self_destruct(ctrl, cc_record);
5811 cc_record->state = CC_STATE_IDLE;
5812 break;
5813 case CC_EVENT_SIGNALING_GONE:
5814 /* Signaling link cleared. */
5815 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5816 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5817 pri_cc_act_set_self_destruct(ctrl, cc_record);
5818 cc_record->state = CC_STATE_IDLE;
5819 break;
5820 case CC_EVENT_CANCEL:
5821 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5822 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5823 pri_cc_act_set_self_destruct(ctrl, cc_record);
5824 cc_record->state = CC_STATE_IDLE;
5825 break;
5826 default:
5827 break;
5828 }
5829 }
5830
5831 /*!
5832 * \internal
5833 * \brief CC FSM PTP monitor CC_STATE_SUSPENDED.
5834 *
5835 * \param ctrl D channel controller.
5836 * \param call Q.931 call leg.
5837 * \param cc_record Call completion record to process event.
5838 * \param event Event to process.
5839 *
5840 * \return Nothing
5841 */
pri_cc_fsm_ptp_monitor_suspended(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5842 static void pri_cc_fsm_ptp_monitor_suspended(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5843 {
5844 switch (event) {
5845 case CC_EVENT_RESUME:
5846 pri_cc_act_send_cc_resume(ctrl, cc_record);
5847 pri_cc_act_reset_a_status(ctrl, cc_record);
5848 cc_record->state = CC_STATE_ACTIVATED;
5849 break;
5850 case CC_EVENT_RECALL:
5851 /* The original call parameters have already been set. */
5852 pri_cc_act_queue_setup_recall(ctrl, cc_record, call);
5853 break;
5854 case CC_EVENT_TIMEOUT_T_SUPERVISION:
5855 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5856 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5857 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5858 pri_cc_act_set_self_destruct(ctrl, cc_record);
5859 cc_record->state = CC_STATE_IDLE;
5860 break;
5861 case CC_EVENT_SIGNALING_GONE:
5862 /* Signaling link cleared. */
5863 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5864 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5865 pri_cc_act_set_self_destruct(ctrl, cc_record);
5866 cc_record->state = CC_STATE_IDLE;
5867 break;
5868 case CC_EVENT_CANCEL:
5869 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5870 pri_cc_act_stop_t_supervision(ctrl, cc_record);
5871 pri_cc_act_set_self_destruct(ctrl, cc_record);
5872 cc_record->state = CC_STATE_IDLE;
5873 break;
5874 default:
5875 break;
5876 }
5877 }
5878
5879 /*!
5880 * \internal
5881 * \brief CC FSM Q.SIG agent CC_STATE_IDLE.
5882 *
5883 * \param ctrl D channel controller.
5884 * \param call Q.931 call leg.
5885 * \param cc_record Call completion record to process event.
5886 * \param event Event to process.
5887 *
5888 * \return Nothing
5889 */
pri_cc_fsm_qsig_agent_idle(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5890 static void pri_cc_fsm_qsig_agent_idle(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5891 {
5892 switch (event) {
5893 case CC_EVENT_AVAILABLE:
5894 cc_record->state = CC_STATE_AVAILABLE;
5895 break;
5896 case CC_EVENT_CANCEL:
5897 pri_cc_act_set_self_destruct(ctrl, cc_record);
5898 break;
5899 default:
5900 break;
5901 }
5902 }
5903
5904 /*!
5905 * \internal
5906 * \brief CC FSM Q.SIG agent CC_STATE_AVAILABLE.
5907 *
5908 * \param ctrl D channel controller.
5909 * \param call Q.931 call leg.
5910 * \param cc_record Call completion record to process event.
5911 * \param event Event to process.
5912 *
5913 * \return Nothing
5914 */
pri_cc_fsm_qsig_agent_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5915 static void pri_cc_fsm_qsig_agent_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5916 {
5917 /*
5918 * For Q.SIG mode the T_RETENTION timer is not defined. However,
5919 * we will use it anyway in this state to protect our resources
5920 * from leaks caused by user A not requesting CC. This timer
5921 * should be set much longer than the PTMP network link to
5922 * allow for variations in user A's CC offer timer.
5923 */
5924 switch (event) {
5925 case CC_EVENT_MSG_RELEASE:
5926 case CC_EVENT_MSG_RELEASE_COMPLETE:
5927 pri_cc_act_stop_t_retention(ctrl, cc_record);
5928 pri_cc_act_start_t_retention(ctrl, cc_record);
5929 break;
5930 case CC_EVENT_CC_REQUEST:
5931 pri_cc_act_pass_up_cc_request(ctrl, cc_record);
5932 /* Send Q931_CALL_PROCEEDING message on signaling link. */
5933 pri_cc_act_send_call_proceeding(ctrl, cc_record);
5934 pri_cc_act_stop_t_retention(ctrl, cc_record);
5935 cc_record->state = CC_STATE_REQUESTED;
5936 break;
5937 case CC_EVENT_INTERNAL_CLEARING:
5938 pri_cc_act_stop_t_retention(ctrl, cc_record);
5939 pri_cc_act_start_t_retention(ctrl, cc_record);
5940 break;
5941 case CC_EVENT_TIMEOUT_T_RETENTION:
5942 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5943 pri_cc_act_stop_t_retention(ctrl, cc_record);
5944 pri_cc_act_set_self_destruct(ctrl, cc_record);
5945 cc_record->state = CC_STATE_IDLE;
5946 break;
5947 case CC_EVENT_CANCEL:
5948 pri_cc_act_stop_t_retention(ctrl, cc_record);
5949 pri_cc_act_set_self_destruct(ctrl, cc_record);
5950 cc_record->state = CC_STATE_IDLE;
5951 break;
5952 default:
5953 break;
5954 }
5955 }
5956
5957 /*!
5958 * \internal
5959 * \brief CC FSM Q.SIG agent CC_STATE_REQUESTED.
5960 *
5961 * \param ctrl D channel controller.
5962 * \param call Q.931 call leg.
5963 * \param cc_record Call completion record to process event.
5964 * \param event Event to process.
5965 *
5966 * \return Nothing
5967 */
pri_cc_fsm_qsig_agent_req(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)5968 static void pri_cc_fsm_qsig_agent_req(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
5969 {
5970 switch (event) {
5971 case CC_EVENT_CC_REQUEST_ACCEPT:
5972 /* Start QSIG_CCBS_T2/QSIG_CCNR_T2 depending upon CC mode. */
5973 pri_cc_act_start_t_supervision(ctrl, cc_record);
5974 cc_record->state = CC_STATE_ACTIVATED;
5975 break;
5976 case CC_EVENT_SIGNALING_GONE:
5977 /* Signaling link cleared. */
5978 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
5979 pri_cc_act_set_self_destruct(ctrl, cc_record);
5980 cc_record->state = CC_STATE_IDLE;
5981 break;
5982 case CC_EVENT_CANCEL:
5983 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
5984 pri_cc_act_set_self_destruct(ctrl, cc_record);
5985 cc_record->state = CC_STATE_IDLE;
5986 break;
5987 default:
5988 break;
5989 }
5990 }
5991
5992 /*!
5993 * \internal
5994 * \brief CC FSM Q.SIG agent CC_STATE_WAIT_DESTRUCTION.
5995 *
5996 * \param ctrl D channel controller.
5997 * \param call Q.931 call leg.
5998 * \param cc_record Call completion record to process event.
5999 * \param event Event to process.
6000 *
6001 * \return Nothing
6002 */
pri_cc_fsm_qsig_agent_wait_destruction(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6003 static void pri_cc_fsm_qsig_agent_wait_destruction(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6004 {
6005 /*
6006 * Delayed disconnect of the signaling link to allow subcmd events
6007 * from the signaling link to be passed up.
6008 */
6009 switch (event) {
6010 case CC_EVENT_SIGNALING_GONE:
6011 /* Signaling link cleared. */
6012 pri_cc_act_set_self_destruct(ctrl, cc_record);
6013 cc_record->state = CC_STATE_IDLE;
6014 break;
6015 case CC_EVENT_HANGUP_SIGNALING:
6016 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
6017 pri_cc_act_set_self_destruct(ctrl, cc_record);
6018 cc_record->state = CC_STATE_IDLE;
6019 break;
6020 default:
6021 break;
6022 }
6023 }
6024
6025 /*!
6026 * \internal
6027 * \brief CC FSM Q.SIG agent CC_STATE_ACTIVATED.
6028 *
6029 * \param ctrl D channel controller.
6030 * \param call Q.931 call leg.
6031 * \param cc_record Call completion record to process event.
6032 * \param event Event to process.
6033 *
6034 * \return Nothing
6035 */
pri_cc_fsm_qsig_agent_activated(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6036 static void pri_cc_fsm_qsig_agent_activated(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6037 {
6038 switch (event) {
6039 case CC_EVENT_REMOTE_USER_FREE:
6040 /* Send ccExecPossible in FACILITY or SETUP. */
6041 pri_cc_act_send_remote_user_free(ctrl, cc_record);
6042 cc_record->state = CC_STATE_WAIT_CALLBACK;
6043 break;
6044 case CC_EVENT_TIMEOUT_T_SUPERVISION:
6045 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6046 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6047 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6048 pri_cc_act_set_self_destruct(ctrl, cc_record);
6049 cc_record->state = CC_STATE_IDLE;
6050 break;
6051 case CC_EVENT_SIGNALING_GONE:
6052 /* Signaling link cleared. */
6053 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6054 break;
6055 case CC_EVENT_LINK_CANCEL:
6056 /* Received ccCancel */
6057 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6058 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6059 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6060 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6061 break;
6062 case CC_EVENT_CANCEL:
6063 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6064 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6065 pri_cc_act_set_self_destruct(ctrl, cc_record);
6066 cc_record->state = CC_STATE_IDLE;
6067 break;
6068 default:
6069 break;
6070 }
6071 }
6072
6073 /*!
6074 * \internal
6075 * \brief CC FSM Q.SIG agent CC_STATE_WAIT_CALLBACK.
6076 *
6077 * \param ctrl D channel controller.
6078 * \param call Q.931 call leg.
6079 * \param cc_record Call completion record to process event.
6080 * \param event Event to process.
6081 *
6082 * \return Nothing
6083 */
pri_cc_fsm_qsig_agent_wait_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6084 static void pri_cc_fsm_qsig_agent_wait_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6085 {
6086 switch (event) {
6087 case CC_EVENT_SUSPEND:
6088 /* Received ccSuspend */
6089 pri_cc_act_set_a_status_busy(ctrl, cc_record);
6090 pri_cc_act_pass_up_a_status(ctrl, cc_record);
6091 cc_record->state = CC_STATE_SUSPENDED;
6092 break;
6093 case CC_EVENT_RECALL:
6094 /* Received ccRingout */
6095 pri_cc_act_pass_up_cc_call(ctrl, cc_record);
6096 pri_cc_act_set_original_call_parameters(ctrl, call, cc_record);
6097 break;
6098 case CC_EVENT_TIMEOUT_T_SUPERVISION:
6099 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6100 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6101 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6102 pri_cc_act_set_self_destruct(ctrl, cc_record);
6103 cc_record->state = CC_STATE_IDLE;
6104 break;
6105 case CC_EVENT_SIGNALING_GONE:
6106 /* Signaling link cleared. */
6107 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6108 break;
6109 case CC_EVENT_LINK_CANCEL:
6110 /* Received ccCancel */
6111 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6112 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6113 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6114 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6115 break;
6116 case CC_EVENT_CANCEL:
6117 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6118 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6119 pri_cc_act_set_self_destruct(ctrl, cc_record);
6120 cc_record->state = CC_STATE_IDLE;
6121 break;
6122 default:
6123 break;
6124 }
6125 }
6126
6127 /*!
6128 * \internal
6129 * \brief CC FSM Q.SIG agent CC_STATE_SUSPENDED.
6130 *
6131 * \param ctrl D channel controller.
6132 * \param call Q.931 call leg.
6133 * \param cc_record Call completion record to process event.
6134 * \param event Event to process.
6135 *
6136 * \return Nothing
6137 */
pri_cc_fsm_qsig_agent_suspended(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6138 static void pri_cc_fsm_qsig_agent_suspended(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6139 {
6140 switch (event) {
6141 case CC_EVENT_RESUME:
6142 /* Received ccResume */
6143 pri_cc_act_set_a_status_free(ctrl, cc_record);
6144 pri_cc_act_pass_up_a_status(ctrl, cc_record);
6145 cc_record->state = CC_STATE_ACTIVATED;
6146 break;
6147 case CC_EVENT_TIMEOUT_T_SUPERVISION:
6148 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6149 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6150 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6151 pri_cc_act_set_self_destruct(ctrl, cc_record);
6152 cc_record->state = CC_STATE_IDLE;
6153 break;
6154 case CC_EVENT_SIGNALING_GONE:
6155 /* Signaling link cleared. */
6156 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6157 break;
6158 case CC_EVENT_LINK_CANCEL:
6159 /* Received ccCancel */
6160 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6161 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6162 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6163 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6164 break;
6165 case CC_EVENT_CANCEL:
6166 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6167 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6168 pri_cc_act_set_self_destruct(ctrl, cc_record);
6169 cc_record->state = CC_STATE_IDLE;
6170 break;
6171 default:
6172 break;
6173 }
6174 }
6175
6176 /*!
6177 * \internal
6178 * \brief CC FSM Q.SIG monitor CC_STATE_IDLE.
6179 *
6180 * \param ctrl D channel controller.
6181 * \param call Q.931 call leg.
6182 * \param cc_record Call completion record to process event.
6183 * \param event Event to process.
6184 *
6185 * \return Nothing
6186 */
pri_cc_fsm_qsig_monitor_idle(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6187 static void pri_cc_fsm_qsig_monitor_idle(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6188 {
6189 switch (event) {
6190 case CC_EVENT_AVAILABLE:
6191 /*
6192 * LibPRI will determine if CC will be offered based upon
6193 * if it is even possible.
6194 * Essentially:
6195 * 1) The call must not have been redirected in this link's
6196 * setup.
6197 * 2) Received an ALERTING or received a
6198 * DISCONNECT(busy/congestion).
6199 */
6200 pri_cc_act_pass_up_cc_available(ctrl, cc_record);
6201 cc_record->state = CC_STATE_AVAILABLE;
6202 break;
6203 case CC_EVENT_CANCEL:
6204 pri_cc_act_set_self_destruct(ctrl, cc_record);
6205 break;
6206 default:
6207 break;
6208 }
6209 }
6210
6211 /*!
6212 * \internal
6213 * \brief CC FSM Q.SIG monitor CC_STATE_AVAILABLE.
6214 *
6215 * \param ctrl D channel controller.
6216 * \param call Q.931 call leg.
6217 * \param cc_record Call completion record to process event.
6218 * \param event Event to process.
6219 *
6220 * \return Nothing
6221 */
pri_cc_fsm_qsig_monitor_avail(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6222 static void pri_cc_fsm_qsig_monitor_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6223 {
6224 /* The upper layer is responsible for canceling the CC available offering. */
6225 switch (event) {
6226 case CC_EVENT_CC_REQUEST:
6227 /*
6228 * Before event is posted:
6229 * cc_record->is_ccnr is set.
6230 * The signaling connection call record is created.
6231 */
6232 pri_cc_act_queue_cc_request(ctrl, cc_record, call);
6233 /* Start QSIG_CC_T1. */
6234 //pri_cc_act_start_t_activate(ctrl, cc_record);
6235 cc_record->state = CC_STATE_REQUESTED;
6236 break;
6237 case CC_EVENT_CANCEL:
6238 pri_cc_act_set_self_destruct(ctrl, cc_record);
6239 cc_record->state = CC_STATE_IDLE;
6240 break;
6241 default:
6242 break;
6243 }
6244 }
6245
6246 /*!
6247 * \internal
6248 * \brief CC FSM Q.SIG monitor CC_STATE_REQUESTED.
6249 *
6250 * \param ctrl D channel controller.
6251 * \param call Q.931 call leg.
6252 * \param cc_record Call completion record to process event.
6253 * \param event Event to process.
6254 *
6255 * \return Nothing
6256 */
pri_cc_fsm_qsig_monitor_req(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6257 static void pri_cc_fsm_qsig_monitor_req(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6258 {
6259 switch (event) {
6260 case CC_EVENT_CC_REQUEST_ACCEPT:
6261 /*
6262 * Received ccbsRequest/ccnrRequest response
6263 * Before event is posted:
6264 * Negotiated CC retention setting saved
6265 * Negotiated signaling link retention setting saved
6266 */
6267 pri_cc_act_stop_t_activate(ctrl, cc_record);
6268 if (cc_record->fsm.qsig.msgtype == Q931_RELEASE) {
6269 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6270 if (cc_record->option.retain_signaling_link) {
6271 /*
6272 * The far end did not honor the
6273 * signaling link retention requirement.
6274 * ECMA-186 Section 6.5.2.2.1
6275 */
6276 pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
6277 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6278 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6279 pri_cc_act_set_self_destruct(ctrl, cc_record);
6280 cc_record->state = CC_STATE_IDLE;
6281 break;
6282 }
6283 }
6284 pri_cc_act_pass_up_cc_req_rsp_success(ctrl, cc_record);
6285 /* Start QSIG_CCBS_T2/QSIG_CCNR_T2 depending upon CC mode. */
6286 pri_cc_act_start_t_supervision(ctrl, cc_record);
6287 pri_cc_act_reset_a_status(ctrl, cc_record);
6288 cc_record->state = CC_STATE_ACTIVATED;
6289 break;
6290 case CC_EVENT_CC_REQUEST_FAIL:
6291 pri_cc_act_stop_t_activate(ctrl, cc_record);
6292 pri_cc_act_pass_up_cc_req_rsp_fail(ctrl, cc_record);
6293 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6294 /*
6295 * If this request fail comes in with the RELEASE message
6296 * then the post action will never get a chance to run.
6297 * It will be aborted because the CC_EVENT_SIGNALING_GONE
6298 * will be processed first.
6299 */
6300 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6301 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6302 break;
6303 case CC_EVENT_TIMEOUT_T_ACTIVATE:
6304 pri_cc_act_stop_t_activate(ctrl, cc_record);
6305 pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
6306 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6307 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
6308 pri_cc_act_set_self_destruct(ctrl, cc_record);
6309 cc_record->state = CC_STATE_IDLE;
6310 break;
6311 case CC_EVENT_SIGNALING_GONE:
6312 pri_cc_act_stop_t_activate(ctrl, cc_record);
6313 /* Claim it was a timeout */
6314 pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
6315 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6316 pri_cc_act_set_self_destruct(ctrl, cc_record);
6317 cc_record->state = CC_STATE_IDLE;
6318 break;
6319 case CC_EVENT_CANCEL:
6320 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6321 break;
6322 default:
6323 break;
6324 }
6325 }
6326
6327 /*!
6328 * \internal
6329 * \brief CC FSM Q.SIG monitor CC_STATE_WAIT_DESTRUCTION.
6330 *
6331 * \param ctrl D channel controller.
6332 * \param call Q.931 call leg.
6333 * \param cc_record Call completion record to process event.
6334 * \param event Event to process.
6335 *
6336 * \return Nothing
6337 */
pri_cc_fsm_qsig_monitor_wait_destruction(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6338 static void pri_cc_fsm_qsig_monitor_wait_destruction(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6339 {
6340 /*
6341 * Delayed disconnect of the signaling link to allow subcmd events
6342 * from the signaling link to be passed up.
6343 */
6344 switch (event) {
6345 case CC_EVENT_CC_REQUEST_ACCEPT:
6346 /*
6347 * Received ccbsRequest/ccnrRequest response
6348 * Before event is posted:
6349 * Negotiated CC retention setting saved
6350 * Negotiated signaling link retention setting saved
6351 */
6352 pri_cc_act_stop_t_activate(ctrl, cc_record);
6353 if (cc_record->fsm.qsig.msgtype == Q931_RELEASE) {
6354 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6355 }
6356 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6357 pri_cc_act_set_self_destruct(ctrl, cc_record);
6358 cc_record->state = CC_STATE_IDLE;
6359 break;
6360 case CC_EVENT_CC_REQUEST_FAIL:
6361 pri_cc_act_stop_t_activate(ctrl, cc_record);
6362 /*
6363 * If this request fail comes in with the RELEASE message
6364 * then the post action will never get a chance to run.
6365 * It will be aborted because the CC_EVENT_SIGNALING_GONE
6366 * will be processed first.
6367 */
6368 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6369 break;
6370 case CC_EVENT_TIMEOUT_T_ACTIVATE:
6371 pri_cc_act_stop_t_activate(ctrl, cc_record);
6372 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
6373 pri_cc_act_set_self_destruct(ctrl, cc_record);
6374 cc_record->state = CC_STATE_IDLE;
6375 break;
6376 case CC_EVENT_SIGNALING_GONE:
6377 /* Signaling link cleared. */
6378 pri_cc_act_stop_t_activate(ctrl, cc_record);
6379 pri_cc_act_set_self_destruct(ctrl, cc_record);
6380 cc_record->state = CC_STATE_IDLE;
6381 break;
6382 case CC_EVENT_HANGUP_SIGNALING:
6383 //pri_cc_act_stop_t_activate(ctrl, cc_record);
6384 pri_cc_act_hangup_signaling_link(ctrl, cc_record);
6385 pri_cc_act_set_self_destruct(ctrl, cc_record);
6386 cc_record->state = CC_STATE_IDLE;
6387 break;
6388 default:
6389 break;
6390 }
6391 }
6392
6393 /*!
6394 * \internal
6395 * \brief CC FSM Q.SIG monitor CC_STATE_ACTIVATED.
6396 *
6397 * \param ctrl D channel controller.
6398 * \param call Q.931 call leg.
6399 * \param cc_record Call completion record to process event.
6400 * \param event Event to process.
6401 *
6402 * \return Nothing
6403 */
pri_cc_fsm_qsig_monitor_activated(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6404 static void pri_cc_fsm_qsig_monitor_activated(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6405 {
6406 switch (event) {
6407 case CC_EVENT_REMOTE_USER_FREE:
6408 /* Received ccExecPossible */
6409 pri_cc_act_pass_up_remote_user_free(ctrl, cc_record);
6410 /*
6411 * ECMA-186 Section 6.5.2.1.7
6412 * Implied switch to retain-signaling-link.
6413 */
6414 pri_cc_act_set_retain_signaling_link(ctrl, cc_record);
6415 if (cc_record->fsm.qsig.msgtype == Q931_SETUP) {
6416 /* Send Q931_CALL_PROCEEDING message on signaling link. */
6417 pri_cc_act_send_call_proceeding(ctrl, cc_record);
6418 }
6419 if (cc_record->party_a_status == CC_PARTY_A_AVAILABILITY_BUSY) {
6420 /*
6421 * The ccSuspend will be sent in a FACILITY or CONNECT
6422 * message depending upon the CIS call state.
6423 */
6424 pri_cc_act_send_cc_suspend(ctrl, cc_record);
6425 cc_record->state = CC_STATE_SUSPENDED;
6426 } else {
6427 /* Start QSIG_CC_T3 */
6428 pri_cc_act_start_t_recall(ctrl, cc_record);
6429 cc_record->state = CC_STATE_WAIT_CALLBACK;
6430 }
6431 break;
6432 case CC_EVENT_SUSPEND:
6433 pri_cc_act_set_a_status_busy(ctrl, cc_record);
6434 break;
6435 case CC_EVENT_RESUME:
6436 pri_cc_act_reset_a_status(ctrl, cc_record);
6437 break;
6438 case CC_EVENT_TIMEOUT_T_SUPERVISION:
6439 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6440 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6441 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6442 pri_cc_act_set_self_destruct(ctrl, cc_record);
6443 cc_record->state = CC_STATE_IDLE;
6444 break;
6445 case CC_EVENT_SIGNALING_GONE:
6446 /* Signaling link cleared. */
6447 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6448 break;
6449 case CC_EVENT_LINK_CANCEL:
6450 /* Received ccCancel */
6451 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6452 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6453 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6454 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6455 break;
6456 case CC_EVENT_CANCEL:
6457 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6458 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6459 pri_cc_act_set_self_destruct(ctrl, cc_record);
6460 cc_record->state = CC_STATE_IDLE;
6461 break;
6462 default:
6463 break;
6464 }
6465 }
6466
6467 /*!
6468 * \internal
6469 * \brief CC FSM Q.SIG monitor CC_STATE_WAIT_CALLBACK.
6470 *
6471 * \param ctrl D channel controller.
6472 * \param call Q.931 call leg.
6473 * \param cc_record Call completion record to process event.
6474 * \param event Event to process.
6475 *
6476 * \return Nothing
6477 */
pri_cc_fsm_qsig_monitor_wait_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6478 static void pri_cc_fsm_qsig_monitor_wait_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6479 {
6480 switch (event) {
6481 case CC_EVENT_RECALL:
6482 /* The original call parameters have already been set. */
6483 pri_cc_act_queue_setup_recall(ctrl, cc_record, call);
6484 pri_cc_act_stop_t_recall(ctrl, cc_record);
6485 cc_record->state = CC_STATE_CALLBACK;
6486 break;
6487 case CC_EVENT_SUSPEND:
6488 pri_cc_act_stop_t_recall(ctrl, cc_record);
6489 /*
6490 * The ccSuspend will be sent in a FACILITY or CONNECT
6491 * message depending upon the CIS call state.
6492 */
6493 pri_cc_act_send_cc_suspend(ctrl, cc_record);
6494 cc_record->state = CC_STATE_SUSPENDED;
6495 break;
6496 case CC_EVENT_TIMEOUT_T_RECALL:
6497 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6498 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6499 pri_cc_act_stop_t_recall(ctrl, cc_record);
6500 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6501 pri_cc_act_set_self_destruct(ctrl, cc_record);
6502 cc_record->state = CC_STATE_IDLE;
6503 break;
6504 case CC_EVENT_TIMEOUT_T_SUPERVISION:
6505 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6506 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6507 pri_cc_act_stop_t_recall(ctrl, cc_record);
6508 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6509 pri_cc_act_set_self_destruct(ctrl, cc_record);
6510 cc_record->state = CC_STATE_IDLE;
6511 break;
6512 case CC_EVENT_SIGNALING_GONE:
6513 /* Signaling link cleared. */
6514 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6515 break;
6516 case CC_EVENT_LINK_CANCEL:
6517 /* Received ccCancel */
6518 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6519 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6520 pri_cc_act_stop_t_recall(ctrl, cc_record);
6521 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6522 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6523 break;
6524 case CC_EVENT_CANCEL:
6525 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6526 pri_cc_act_stop_t_recall(ctrl, cc_record);
6527 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6528 pri_cc_act_set_self_destruct(ctrl, cc_record);
6529 cc_record->state = CC_STATE_IDLE;
6530 break;
6531 default:
6532 break;
6533 }
6534 }
6535
6536 /*!
6537 * \internal
6538 * \brief CC FSM Q.SIG monitor CC_STATE_CALLBACK.
6539 *
6540 * \param ctrl D channel controller.
6541 * \param call Q.931 call leg.
6542 * \param cc_record Call completion record to process event.
6543 * \param event Event to process.
6544 *
6545 * \return Nothing
6546 */
pri_cc_fsm_qsig_monitor_callback(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6547 static void pri_cc_fsm_qsig_monitor_callback(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6548 {
6549 switch (event) {
6550 case CC_EVENT_TIMEOUT_T_SUPERVISION:
6551 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6552 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6553 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6554 pri_cc_act_set_self_destruct(ctrl, cc_record);
6555 cc_record->state = CC_STATE_IDLE;
6556 break;
6557 case CC_EVENT_SIGNALING_GONE:
6558 /* Signaling link cleared. */
6559 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6560 break;
6561 case CC_EVENT_LINK_CANCEL:
6562 /* Received ccCancel */
6563 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6564 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6565 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6566 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6567 break;
6568 case CC_EVENT_CANCEL:
6569 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6570 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6571 pri_cc_act_set_self_destruct(ctrl, cc_record);
6572 cc_record->state = CC_STATE_IDLE;
6573 break;
6574 default:
6575 break;
6576 }
6577 }
6578
6579 /*!
6580 * \internal
6581 * \brief CC FSM Q.SIG monitor CC_STATE_SUSPENDED.
6582 *
6583 * \param ctrl D channel controller.
6584 * \param call Q.931 call leg.
6585 * \param cc_record Call completion record to process event.
6586 * \param event Event to process.
6587 *
6588 * \return Nothing
6589 */
pri_cc_fsm_qsig_monitor_suspended(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6590 static void pri_cc_fsm_qsig_monitor_suspended(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6591 {
6592 switch (event) {
6593 case CC_EVENT_RESUME:
6594 pri_cc_act_send_cc_resume(ctrl, cc_record);
6595 pri_cc_act_reset_a_status(ctrl, cc_record);
6596 cc_record->state = CC_STATE_ACTIVATED;
6597 break;
6598 case CC_EVENT_TIMEOUT_T_SUPERVISION:
6599 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6600 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6601 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6602 pri_cc_act_set_self_destruct(ctrl, cc_record);
6603 cc_record->state = CC_STATE_IDLE;
6604 break;
6605 case CC_EVENT_SIGNALING_GONE:
6606 /* Signaling link cleared. */
6607 pri_cc_act_disassociate_signaling_link(ctrl, cc_record);
6608 break;
6609 case CC_EVENT_LINK_CANCEL:
6610 /* Received ccCancel */
6611 pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
6612 pri_cc_act_post_hangup_signaling(ctrl, cc_record);
6613 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6614 cc_record->state = CC_STATE_WAIT_DESTRUCTION;
6615 break;
6616 case CC_EVENT_CANCEL:
6617 pri_cc_act_send_cc_cancel(ctrl, cc_record);
6618 pri_cc_act_stop_t_supervision(ctrl, cc_record);
6619 pri_cc_act_set_self_destruct(ctrl, cc_record);
6620 cc_record->state = CC_STATE_IDLE;
6621 break;
6622 default:
6623 break;
6624 }
6625 }
6626
6627 /*!
6628 * \internal
6629 * \brief CC FSM state function type.
6630 *
6631 * \param ctrl D channel controller.
6632 * \param call Q.931 call leg.
6633 * \param cc_record Call completion record to process event.
6634 * \param event Event to process.
6635 *
6636 * \return Nothing
6637 */
6638 typedef void (*pri_cc_fsm_state)(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event);
6639
6640 /*! CC FSM PTMP agent state table. */
6641 static const pri_cc_fsm_state pri_cc_fsm_ptmp_agent[CC_STATE_NUM] = {
6642 /* *INDENT-OFF* */
6643 [CC_STATE_IDLE] = pri_cc_fsm_ptmp_agent_idle,
6644 [CC_STATE_PENDING_AVAILABLE] = pri_cc_fsm_ptmp_agent_pend_avail,
6645 [CC_STATE_AVAILABLE] = pri_cc_fsm_ptmp_agent_avail,
6646 [CC_STATE_REQUESTED] = pri_cc_fsm_ptmp_agent_req,
6647 [CC_STATE_ACTIVATED] = pri_cc_fsm_ptmp_agent_activated,
6648 [CC_STATE_B_AVAILABLE] = pri_cc_fsm_ptmp_agent_b_avail,
6649 [CC_STATE_SUSPENDED] = pri_cc_fsm_ptmp_agent_suspended,
6650 [CC_STATE_WAIT_CALLBACK] = pri_cc_fsm_ptmp_agent_wait_callback,
6651 [CC_STATE_CALLBACK] = pri_cc_fsm_ptmp_agent_callback,
6652 /* *INDENT-ON* */
6653 };
6654
6655 /*! CC FSM PTMP monitor state table. */
6656 static const pri_cc_fsm_state pri_cc_fsm_ptmp_monitor[CC_STATE_NUM] = {
6657 /* *INDENT-OFF* */
6658 [CC_STATE_IDLE] = pri_cc_fsm_ptmp_monitor_idle,
6659 [CC_STATE_AVAILABLE] = pri_cc_fsm_ptmp_monitor_avail,
6660 [CC_STATE_REQUESTED] = pri_cc_fsm_ptmp_monitor_req,
6661 [CC_STATE_WAIT_DESTRUCTION] = pri_cc_fsm_ptmp_monitor_wait_destruction,
6662 [CC_STATE_ACTIVATED] = pri_cc_fsm_ptmp_monitor_activated,
6663 [CC_STATE_WAIT_CALLBACK] = pri_cc_fsm_ptmp_monitor_wait_callback,
6664 [CC_STATE_CALLBACK] = pri_cc_fsm_ptmp_monitor_callback,
6665 /* *INDENT-ON* */
6666 };
6667
6668 /*! CC FSM PTP agent state table. */
6669 static const pri_cc_fsm_state pri_cc_fsm_ptp_agent[CC_STATE_NUM] = {
6670 /* *INDENT-OFF* */
6671 [CC_STATE_IDLE] = pri_cc_fsm_ptp_agent_idle,
6672 [CC_STATE_PENDING_AVAILABLE] = pri_cc_fsm_ptp_agent_pend_avail,
6673 [CC_STATE_AVAILABLE] = pri_cc_fsm_ptp_agent_avail,
6674 [CC_STATE_REQUESTED] = pri_cc_fsm_ptp_agent_req,
6675 [CC_STATE_ACTIVATED] = pri_cc_fsm_ptp_agent_activated,
6676 [CC_STATE_WAIT_CALLBACK] = pri_cc_fsm_ptp_agent_wait_callback,
6677 [CC_STATE_SUSPENDED] = pri_cc_fsm_ptp_agent_suspended,
6678 /* *INDENT-ON* */
6679 };
6680
6681 /*! CC FSM PTP monitor state table. */
6682 static const pri_cc_fsm_state pri_cc_fsm_ptp_monitor[CC_STATE_NUM] = {
6683 /* *INDENT-OFF* */
6684 [CC_STATE_IDLE] = pri_cc_fsm_ptp_monitor_idle,
6685 [CC_STATE_AVAILABLE] = pri_cc_fsm_ptp_monitor_avail,
6686 [CC_STATE_REQUESTED] = pri_cc_fsm_ptp_monitor_req,
6687 [CC_STATE_WAIT_DESTRUCTION] = pri_cc_fsm_ptp_monitor_wait_destruction,
6688 [CC_STATE_ACTIVATED] = pri_cc_fsm_ptp_monitor_activated,
6689 [CC_STATE_WAIT_CALLBACK] = pri_cc_fsm_ptp_monitor_wait_callback,
6690 [CC_STATE_SUSPENDED] = pri_cc_fsm_ptp_monitor_suspended,
6691 /* *INDENT-ON* */
6692 };
6693
6694 /*! CC FSM Q.SIG agent state table. */
6695 static const pri_cc_fsm_state pri_cc_fsm_qsig_agent[CC_STATE_NUM] = {
6696 /* *INDENT-OFF* */
6697 [CC_STATE_IDLE] = pri_cc_fsm_qsig_agent_idle,
6698 [CC_STATE_AVAILABLE] = pri_cc_fsm_qsig_agent_avail,
6699 [CC_STATE_REQUESTED] = pri_cc_fsm_qsig_agent_req,
6700 [CC_STATE_WAIT_DESTRUCTION] = pri_cc_fsm_qsig_agent_wait_destruction,
6701 [CC_STATE_ACTIVATED] = pri_cc_fsm_qsig_agent_activated,
6702 [CC_STATE_WAIT_CALLBACK] = pri_cc_fsm_qsig_agent_wait_callback,
6703 [CC_STATE_SUSPENDED] = pri_cc_fsm_qsig_agent_suspended,
6704 /* *INDENT-ON* */
6705 };
6706
6707 /*! CC FSM Q.SIG monitor state table. */
6708 static const pri_cc_fsm_state pri_cc_fsm_qsig_monitor[CC_STATE_NUM] = {
6709 /* *INDENT-OFF* */
6710 [CC_STATE_IDLE] = pri_cc_fsm_qsig_monitor_idle,
6711 [CC_STATE_AVAILABLE] = pri_cc_fsm_qsig_monitor_avail,
6712 [CC_STATE_REQUESTED] = pri_cc_fsm_qsig_monitor_req,
6713 [CC_STATE_WAIT_DESTRUCTION] = pri_cc_fsm_qsig_monitor_wait_destruction,
6714 [CC_STATE_ACTIVATED] = pri_cc_fsm_qsig_monitor_activated,
6715 [CC_STATE_WAIT_CALLBACK] = pri_cc_fsm_qsig_monitor_wait_callback,
6716 [CC_STATE_CALLBACK] = pri_cc_fsm_qsig_monitor_callback,
6717 [CC_STATE_SUSPENDED] = pri_cc_fsm_qsig_monitor_suspended,
6718 /* *INDENT-ON* */
6719 };
6720
6721 /*!
6722 * \brief Send an event to the cc state machine.
6723 *
6724 * \param ctrl D channel controller.
6725 * \param call Q.931 call leg.
6726 * (May be NULL if it is supposed to be the signaling connection
6727 * for Q.SIG or PTP and it is not established yet.)
6728 * \param cc_record Call completion record to process event.
6729 * \param event Event to process.
6730 *
6731 * \retval nonzero if cc record destroyed because FSM completed.
6732 */
pri_cc_event(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,enum CC_EVENTS event)6733 int pri_cc_event(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
6734 {
6735 const pri_cc_fsm_state *cc_fsm;
6736 enum CC_STATES orig_state;
6737
6738 switch (ctrl->switchtype) {
6739 case PRI_SWITCH_QSIG:
6740 if (cc_record->is_agent) {
6741 cc_fsm = pri_cc_fsm_qsig_agent;
6742 } else {
6743 cc_fsm = pri_cc_fsm_qsig_monitor;
6744 }
6745 break;
6746 case PRI_SWITCH_EUROISDN_E1:
6747 case PRI_SWITCH_EUROISDN_T1:
6748 if (PTMP_MODE(ctrl)) {
6749 if (cc_record->is_agent) {
6750 cc_fsm = pri_cc_fsm_ptmp_agent;
6751 } else {
6752 cc_fsm = pri_cc_fsm_ptmp_monitor;
6753 }
6754 } else {
6755 if (cc_record->is_agent) {
6756 cc_fsm = pri_cc_fsm_ptp_agent;
6757 } else {
6758 cc_fsm = pri_cc_fsm_ptp_monitor;
6759 }
6760 }
6761 break;
6762 default:
6763 /* CC not supported on this switch type. */
6764 cc_fsm = NULL;
6765 break;
6766 }
6767
6768 if (!cc_fsm) {
6769 /* No FSM available. */
6770 pri_cc_delete_record(ctrl, cc_record);
6771 return 1;
6772 }
6773 orig_state = cc_record->state;
6774 if (ctrl->debug & PRI_DEBUG_CC) {
6775 pri_message(ctrl, "%ld CC-Event: %s in state %s\n", cc_record->record_id,
6776 pri_cc_fsm_event_str(event), pri_cc_fsm_state_str(orig_state));
6777 }
6778 if (orig_state < CC_STATE_IDLE || CC_STATE_NUM <= orig_state || !cc_fsm[orig_state]) {
6779 /* Programming error: State not implemented. */
6780 pri_error(ctrl, "!! CC state not implemented: %s(%d)\n",
6781 pri_cc_fsm_state_str(orig_state), orig_state);
6782 return 0;
6783 }
6784 /* Execute the state. */
6785 cc_fsm[orig_state](ctrl, call, cc_record, event);
6786 if (ctrl->debug & PRI_DEBUG_CC) {
6787 pri_message(ctrl, "%ld CC-Next-State: %s\n", cc_record->record_id,
6788 (orig_state == cc_record->state)
6789 ? "$" : pri_cc_fsm_state_str(cc_record->state));
6790 }
6791 if (cc_record->fsm_complete) {
6792 pri_cc_delete_record(ctrl, cc_record);
6793 return 1;
6794 } else {
6795 return 0;
6796 }
6797 }
6798
6799 /*!
6800 * \brief Indicate to the far end that CCBS/CCNR is available.
6801 *
6802 * \param ctrl D channel controller.
6803 * \param call Q.931 call leg.
6804 *
6805 * \details
6806 * The CC available indication will go out with the next
6807 * DISCONNECT(busy/congested)/ALERTING message.
6808 *
6809 * \retval cc_id on success for subsequent reference.
6810 * \retval -1 on error.
6811 */
pri_cc_available(struct pri * ctrl,q931_call * call)6812 long pri_cc_available(struct pri *ctrl, q931_call *call)
6813 {
6814 struct pri_cc_record *cc_record;
6815 long cc_id;
6816
6817 if (!ctrl || !pri_is_call_valid(ctrl, call)) {
6818 return -1;
6819 }
6820 if (call->cc.record) {
6821 /* This call is already associated with call completion. */
6822 return -1;
6823 }
6824
6825 cc_record = NULL;
6826
6827 switch (ctrl->switchtype) {
6828 case PRI_SWITCH_QSIG:
6829 cc_record = pri_cc_new_record(ctrl, call);
6830 if (!cc_record) {
6831 break;
6832 }
6833
6834 /*
6835 * Q.SIG has no message to send when CC is available.
6836 * Q.SIG assumes CC is always available and is denied when
6837 * requested if CC is not possible or allowed.
6838 */
6839 cc_record->original_call = call;
6840 cc_record->is_agent = 1;
6841 break;
6842 case PRI_SWITCH_EUROISDN_E1:
6843 case PRI_SWITCH_EUROISDN_T1:
6844 if (PTMP_MODE(ctrl)) {
6845 int linkage_id;
6846
6847 if (!BRI_NT_PTMP(ctrl)) {
6848 /*
6849 * No CC agent protocol defined for this mode.
6850 * i.e., A device acting like a phone cannot be a CC agent.
6851 */
6852 break;
6853 }
6854
6855 linkage_id = pri_cc_new_linkage_id(ctrl);
6856 if (linkage_id == CC_PTMP_INVALID_ID) {
6857 break;
6858 }
6859 cc_record = pri_cc_new_record(ctrl, call);
6860 if (!cc_record) {
6861 break;
6862 }
6863 cc_record->call_linkage_id = linkage_id;
6864 cc_record->signaling = ctrl->link.dummy_call;
6865 } else {
6866 cc_record = pri_cc_new_record(ctrl, call);
6867 if (!cc_record) {
6868 break;
6869 }
6870 }
6871 cc_record->original_call = call;
6872 cc_record->is_agent = 1;
6873 break;
6874 default:
6875 break;
6876 }
6877
6878 call->cc.record = cc_record;
6879 if (cc_record && !pri_cc_event(ctrl, call, cc_record, CC_EVENT_AVAILABLE)) {
6880 cc_id = cc_record->record_id;
6881 } else {
6882 cc_id = -1;
6883 }
6884 return cc_id;
6885 }
6886
6887 /*!
6888 * \brief Determine if CC is available for Q.SIG outgoing call.
6889 *
6890 * \param ctrl D channel controller.
6891 * \param call Q.931 call leg.
6892 *
6893 * \return Nothing
6894 */
pri_cc_qsig_determine_available(struct pri * ctrl,q931_call * call)6895 void pri_cc_qsig_determine_available(struct pri *ctrl, q931_call *call)
6896 {
6897 struct pri_cc_record *cc_record;
6898
6899 if (!call->cc.originated || call->cc.initially_redirected) {
6900 /*
6901 * The call is not suitable for us to consider CC:
6902 * The call was not originated by us.
6903 * The call was originally redirected.
6904 */
6905 return;
6906 }
6907
6908 if (!ctrl->cc_support) {
6909 /*
6910 * Blocking the cc-available event effectively
6911 * disables call completion for outgoing calls.
6912 */
6913 return;
6914 }
6915 if (call->cc.record) {
6916 /* Already made available. */
6917 return;
6918 }
6919 cc_record = pri_cc_new_record(ctrl, call);
6920 if (!cc_record) {
6921 return;
6922 }
6923 cc_record->original_call = call;
6924 call->cc.record = cc_record;
6925 pri_cc_event(ctrl, call, cc_record, CC_EVENT_AVAILABLE);
6926 }
6927
6928 /*!
6929 * \brief Request to activate CC.
6930 *
6931 * \param ctrl D channel controller.
6932 * \param cc_id CC record ID to activate.
6933 * \param mode Which CC mode to use CCBS(0)/CCNR(1)
6934 *
6935 * \note
6936 * Will always get a reply from libpri. libpri will start a timer to guarantee
6937 * that a reply will be passed back to the upper layer.
6938 * \note
6939 * If you cancel with pri_cc_cancel() you are indicating that you do not need
6940 * the request reply and the cc_id will no longer be valid anyway.
6941 * \note
6942 * Allow for the possibility that the reply may come in before this
6943 * function returns.
6944 *
6945 * \retval 0 on success.
6946 * \retval -1 on error.
6947 */
pri_cc_req(struct pri * ctrl,long cc_id,int mode)6948 int pri_cc_req(struct pri *ctrl, long cc_id, int mode)
6949 {
6950 struct pri_sr req;
6951 q931_call *call;
6952 struct pri_cc_record *cc_record;
6953
6954 if (!ctrl) {
6955 return -1;
6956 }
6957 cc_record = pri_cc_find_by_id(ctrl, cc_id);
6958 if (!cc_record) {
6959 return -1;
6960 }
6961 if (cc_record->is_agent || cc_record->state != CC_STATE_AVAILABLE) {
6962 /* CC is an agent or already requested. */
6963 return -1;
6964 }
6965
6966 /* Set the requested CC mode. */
6967 cc_record->is_ccnr = mode ? 1 : 0;
6968
6969 switch (ctrl->switchtype) {
6970 case PRI_SWITCH_QSIG:
6971 if (cc_record->signaling) {
6972 /* We should not have a signaling link at this point. */
6973 return -1;
6974 }
6975 call = q931_new_call(ctrl);
6976 if (!call) {
6977 return -1;
6978 }
6979
6980 /* Link the new call as the signaling link. */
6981 cc_record->signaling = call;
6982 call->cc.record = cc_record;
6983
6984 if (pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST)) {
6985 /* Should not happen. */
6986 q931_destroycall(ctrl, call);
6987 break;
6988 }
6989
6990 pri_sr_init(&req);
6991 req.caller = cc_record->party_a;
6992 req.called = cc_record->party_b;
6993 //req.cis_auto_disconnect = 0;
6994 req.cis_call = 1;
6995 if (q931_setup(ctrl, call, &req)) {
6996 /* Should not happen. */
6997 q931_destroycall(ctrl, call);
6998 return -1;
6999 }
7000 break;
7001 case PRI_SWITCH_EUROISDN_E1:
7002 case PRI_SWITCH_EUROISDN_T1:
7003 if (PTMP_MODE(ctrl)) {
7004 /* ETSI PTMP */
7005 if (pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_CC_REQUEST)) {
7006 /* Should not happen. */
7007 break;
7008 }
7009 q931_facility(ctrl, cc_record->signaling);
7010 break;
7011 }
7012
7013 /* ETSI PTP */
7014 if (cc_record->signaling) {
7015 /* We should not have a signaling link at this point. */
7016 return -1;
7017 }
7018 call = q931_new_call(ctrl);
7019 if (!call) {
7020 return -1;
7021 }
7022
7023 cc_record->signaling = call;
7024 call->cc.record = cc_record;
7025 if (pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST)) {
7026 /* Should not happen. */
7027 q931_destroycall(ctrl, call);
7028 break;
7029 }
7030
7031 if (q931_register(ctrl, call)) {
7032 /* Should not happen. */
7033 q931_destroycall(ctrl, call);
7034 return -1;
7035 }
7036 break;
7037 default:
7038 return -1;
7039 }
7040
7041 return 0;
7042 }
7043
7044 /*!
7045 * \internal
7046 * \brief Encode a PTMP cc-request reply message.
7047 *
7048 * \param ctrl D channel controller for diagnostic messages or global options.
7049 * \param pos Starting position to encode the facility ie contents.
7050 * \param end End of facility ie contents encoding data buffer.
7051 * \param operation CCBS/CCNR operation code.
7052 * \param invoke_id Invoke id to put in error message response.
7053 * \param recall_mode Configured PTMP recall mode.
7054 * \param reference_id Active CC reference id.
7055 *
7056 * \retval Start of the next ASN.1 component to encode on success.
7057 * \retval NULL on error.
7058 */
enc_cc_etsi_ptmp_req_rsp(struct pri * ctrl,unsigned char * pos,unsigned char * end,enum rose_operation operation,int invoke_id,int recall_mode,int reference_id)7059 static unsigned char *enc_cc_etsi_ptmp_req_rsp(struct pri *ctrl, unsigned char *pos,
7060 unsigned char *end, enum rose_operation operation, int invoke_id, int recall_mode,
7061 int reference_id)
7062 {
7063 struct rose_msg_result msg;
7064
7065 pos = facility_encode_header(ctrl, pos, end, NULL);
7066 if (!pos) {
7067 return NULL;
7068 }
7069
7070 memset(&msg, 0, sizeof(msg));
7071 msg.invoke_id = invoke_id;
7072 msg.operation = operation;
7073
7074 /* CCBS/CCNR reply */
7075 msg.args.etsi.CCBSRequest.recall_mode = recall_mode;
7076 msg.args.etsi.CCBSRequest.ccbs_reference = reference_id;
7077
7078 pos = rose_encode_result(ctrl, pos, end, &msg);
7079
7080 return pos;
7081 }
7082
7083 /*!
7084 * \internal
7085 * \brief Encode and queue PTMP a cc-request reply message.
7086 *
7087 * \param ctrl D channel controller.
7088 * \param call Q.931 call leg.
7089 * \param msgtype Q.931 message type to put facility ie in.
7090 * \param operation CCBS/CCNR operation code.
7091 * \param invoke_id Invoke id to put in error message response.
7092 * \param recall_mode Configured PTMP recall mode.
7093 * \param reference_id Active CC reference id.
7094 *
7095 * \retval 0 on success.
7096 * \retval -1 on error.
7097 */
rose_cc_etsi_ptmp_req_rsp_encode(struct pri * ctrl,q931_call * call,int msgtype,enum rose_operation operation,int invoke_id,int recall_mode,int reference_id)7098 static int rose_cc_etsi_ptmp_req_rsp_encode(struct pri *ctrl, q931_call *call, int msgtype, enum rose_operation operation, int invoke_id, int recall_mode, int reference_id)
7099 {
7100 unsigned char buffer[256];
7101 unsigned char *end;
7102
7103 end = enc_cc_etsi_ptmp_req_rsp(ctrl, buffer, buffer + sizeof(buffer), operation,
7104 invoke_id, recall_mode, reference_id);
7105 if (!end) {
7106 return -1;
7107 }
7108
7109 return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
7110 }
7111
7112 /*!
7113 * \internal
7114 * \brief Send the CC activation request result PTMP.
7115 *
7116 * \param ctrl D channel controller.
7117 * \param call Q.931 call leg.
7118 * \param operation CCBS/CCNR operation code.
7119 * \param invoke_id Invoke id to put in error message response.
7120 * \param recall_mode Configured PTMP recall mode.
7121 * \param reference_id Active CC reference id.
7122 *
7123 * \retval 0 on success.
7124 * \retval -1 on error.
7125 */
send_cc_etsi_ptmp_req_rsp(struct pri * ctrl,q931_call * call,enum rose_operation operation,int invoke_id,int recall_mode,int reference_id)7126 static int send_cc_etsi_ptmp_req_rsp(struct pri *ctrl, q931_call *call, enum rose_operation operation, int invoke_id, int recall_mode, int reference_id)
7127 {
7128 if (rose_cc_etsi_ptmp_req_rsp_encode(ctrl, call, Q931_FACILITY, operation, invoke_id,
7129 recall_mode, reference_id)
7130 || q931_facility(ctrl, call)) {
7131 pri_message(ctrl, "Could not schedule CC request result message.\n");
7132 return -1;
7133 }
7134
7135 return 0;
7136 }
7137
7138 /*!
7139 * \internal
7140 * \brief Response to an incoming CC activation request PTMP.
7141 *
7142 * \param ctrl D channel controller.
7143 * \param cc_record Call completion record to process event.
7144 * \param status success(0)/timeout(1)/
7145 * short_term_denial(2)/long_term_denial(3)/not_subscribed(4)/queue_full(5)
7146 *
7147 * \retval 0 on success.
7148 * \retval -1 on error.
7149 */
pri_cc_req_rsp_ptmp(struct pri * ctrl,struct pri_cc_record * cc_record,int status)7150 static int pri_cc_req_rsp_ptmp(struct pri *ctrl, struct pri_cc_record *cc_record, int status)
7151 {
7152 int fail;
7153
7154 switch (cc_record->response.invoke_operation) {
7155 case ROSE_ETSI_CCBSRequest:
7156 case ROSE_ETSI_CCNRRequest:
7157 break;
7158 default:
7159 /* We no longer know how to send the response. Should not happen. */
7160 return -1;
7161 }
7162
7163 fail = 0;
7164 if (status) {
7165 enum rose_error_code code;
7166
7167 switch (status) {
7168 default:
7169 case 1:/* timeout */
7170 case 2:/* short_term_denial */
7171 code = ROSE_ERROR_CCBS_ShortTermDenial;
7172 break;
7173 case 3:/* long_term_denial */
7174 code = ROSE_ERROR_CCBS_LongTermDenial;
7175 break;
7176 case 4:/* not_subscribed */
7177 code = ROSE_ERROR_Gen_NotSubscribed;
7178 break;
7179 case 5:/* queue_full */
7180 code = ROSE_ERROR_CCBS_OutgoingCCBSQueueFull;
7181 break;
7182 }
7183 send_facility_error(ctrl, cc_record->response.signaling,
7184 cc_record->response.invoke_id, code);
7185 pri_cc_event(ctrl, cc_record->response.signaling, cc_record,
7186 CC_EVENT_CANCEL);
7187 } else {
7188 /* Successful CC activation. */
7189 if (send_cc_etsi_ptmp_req_rsp(ctrl, cc_record->response.signaling,
7190 cc_record->response.invoke_operation, cc_record->response.invoke_id,
7191 cc_record->option.recall_mode, cc_record->ccbs_reference_id)) {
7192 fail = -1;
7193 }
7194 pri_cc_event(ctrl, cc_record->response.signaling, cc_record,
7195 CC_EVENT_CC_REQUEST_ACCEPT);
7196 }
7197 return fail;
7198 }
7199
7200 /*!
7201 * \internal
7202 * \brief Encode a PTP cc-request reply message.
7203 *
7204 * \param ctrl D channel controller for diagnostic messages or global options.
7205 * \param pos Starting position to encode the facility ie contents.
7206 * \param end End of facility ie contents encoding data buffer.
7207 * \param cc_record Call completion record to process event.
7208 *
7209 * \retval Start of the next ASN.1 component to encode on success.
7210 * \retval NULL on error.
7211 */
enc_cc_etsi_ptp_req_rsp(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)7212 static unsigned char *enc_cc_etsi_ptp_req_rsp(struct pri *ctrl, unsigned char *pos,
7213 unsigned char *end, struct pri_cc_record *cc_record)
7214 {
7215 struct rose_msg_result msg;
7216
7217 pos = facility_encode_header(ctrl, pos, end, NULL);
7218 if (!pos) {
7219 return NULL;
7220 }
7221
7222 memset(&msg, 0, sizeof(msg));
7223 msg.invoke_id = cc_record->response.invoke_id;
7224 msg.operation = cc_record->response.invoke_operation;
7225
7226 /* CCBS/CCNR reply */
7227 //msg.args.etsi.CCBS_T_Request.retention_supported = 0;
7228
7229 pos = rose_encode_result(ctrl, pos, end, &msg);
7230
7231 return pos;
7232 }
7233
7234 /*!
7235 * \internal
7236 * \brief Encode and queue PTP a cc-request reply message.
7237 *
7238 * \param ctrl D channel controller.
7239 * \param call Q.931 call leg.
7240 * \param cc_record Call completion record to process event.
7241 *
7242 * \retval 0 on success.
7243 * \retval -1 on error.
7244 */
rose_cc_etsi_ptp_req_rsp_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)7245 static int rose_cc_etsi_ptp_req_rsp_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
7246 {
7247 unsigned char buffer[256];
7248 unsigned char *end;
7249
7250 end = enc_cc_etsi_ptp_req_rsp(ctrl, buffer, buffer + sizeof(buffer), cc_record);
7251 if (!end) {
7252 return -1;
7253 }
7254
7255 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
7256 }
7257
7258 /*!
7259 * \internal
7260 * \brief Send the CC activation request result PTP.
7261 *
7262 * \param ctrl D channel controller.
7263 * \param cc_record Call completion record to process event.
7264 *
7265 * \retval 0 on success.
7266 * \retval -1 on error.
7267 */
send_cc_etsi_ptp_req_rsp(struct pri * ctrl,struct pri_cc_record * cc_record)7268 static int send_cc_etsi_ptp_req_rsp(struct pri *ctrl, struct pri_cc_record *cc_record)
7269 {
7270 if (rose_cc_etsi_ptp_req_rsp_encode(ctrl, cc_record->signaling, cc_record)
7271 || q931_facility(ctrl, cc_record->signaling)) {
7272 pri_message(ctrl, "Could not schedule CC request result message.\n");
7273 return -1;
7274 }
7275
7276 return 0;
7277 }
7278
7279 /*!
7280 * \internal
7281 * \brief Response to an incoming CC activation request PTP.
7282 *
7283 * \param ctrl D channel controller.
7284 * \param cc_record Call completion record to process event.
7285 * \param status success(0)/timeout(1)/
7286 * short_term_denial(2)/long_term_denial(3)/not_subscribed(4)/queue_full(5)
7287 *
7288 * \retval 0 on success.
7289 * \retval -1 on error.
7290 */
pri_cc_req_rsp_ptp(struct pri * ctrl,struct pri_cc_record * cc_record,int status)7291 static int pri_cc_req_rsp_ptp(struct pri *ctrl, struct pri_cc_record *cc_record, int status)
7292 {
7293 int fail;
7294
7295 switch (cc_record->response.invoke_operation) {
7296 case ROSE_ETSI_CCBS_T_Request:
7297 case ROSE_ETSI_CCNR_T_Request:
7298 break;
7299 default:
7300 /* We no longer know how to send the response. Should not happen. */
7301 return -1;
7302 }
7303 if (!cc_record->signaling) {
7304 return -1;
7305 }
7306
7307 fail = 0;
7308 if (status) {
7309 enum rose_error_code code;
7310
7311 switch (status) {
7312 default:
7313 case 1:/* timeout */
7314 case 5:/* queue_full */
7315 case 2:/* short_term_denial */
7316 code = ROSE_ERROR_CCBS_T_ShortTermDenial;
7317 break;
7318 case 3:/* long_term_denial */
7319 code = ROSE_ERROR_CCBS_T_LongTermDenial;
7320 break;
7321 case 4:/* not_subscribed */
7322 code = ROSE_ERROR_Gen_NotSubscribed;
7323 break;
7324 }
7325 rose_error_msg_encode(ctrl, cc_record->signaling, Q931_ANY_MESSAGE,
7326 cc_record->response.invoke_id, code);
7327 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_CANCEL);
7328 } else {
7329 /* Successful CC activation. */
7330 if (send_cc_etsi_ptp_req_rsp(ctrl, cc_record)) {
7331 fail = -1;
7332 }
7333 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_CC_REQUEST_ACCEPT);
7334 }
7335 return fail;
7336 }
7337
7338 /*!
7339 * \internal
7340 * \brief Encode a Q.SIG cc-request reply message.
7341 *
7342 * \param ctrl D channel controller for diagnostic messages or global options.
7343 * \param pos Starting position to encode the facility ie contents.
7344 * \param end End of facility ie contents encoding data buffer.
7345 * \param cc_record Call completion record to process event.
7346 *
7347 * \retval Start of the next ASN.1 component to encode on success.
7348 * \retval NULL on error.
7349 */
enc_cc_qsig_req_rsp(struct pri * ctrl,unsigned char * pos,unsigned char * end,struct pri_cc_record * cc_record)7350 static unsigned char *enc_cc_qsig_req_rsp(struct pri *ctrl, unsigned char *pos,
7351 unsigned char *end, struct pri_cc_record *cc_record)
7352 {
7353 struct fac_extension_header header;
7354 struct rose_msg_result msg;
7355
7356 memset(&header, 0, sizeof(header));
7357 header.nfe_present = 1;
7358 header.nfe.source_entity = 0; /* endPINX */
7359 header.nfe.destination_entity = 0; /* endPINX */
7360 header.interpretation_present = 1;
7361 header.interpretation = 0; /* discardAnyUnrecognisedInvokePdu */
7362 pos = facility_encode_header(ctrl, pos, end, &header);
7363 if (!pos) {
7364 return NULL;
7365 }
7366
7367 memset(&msg, 0, sizeof(msg));
7368 msg.invoke_id = cc_record->response.invoke_id;
7369 msg.operation = cc_record->response.invoke_operation;
7370
7371 /* CCBS/CCNR reply */
7372
7373 /* We do not support ccPathReserve */
7374 msg.args.qsig.CcbsRequest.no_path_reservation = 1;
7375 //msg.args.qsig.CcbsRequest.retain_service = 0;
7376
7377 pos = rose_encode_result(ctrl, pos, end, &msg);
7378
7379 return pos;
7380 }
7381
7382 /*!
7383 * \internal
7384 * \brief Encode and queue Q.SIG a cc-request reply message.
7385 *
7386 * \param ctrl D channel controller.
7387 * \param call Q.931 call leg.
7388 * \param cc_record Call completion record to process event.
7389 *
7390 * \retval 0 on success.
7391 * \retval -1 on error.
7392 */
rose_cc_qsig_req_rsp_encode(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record)7393 static int rose_cc_qsig_req_rsp_encode(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
7394 {
7395 unsigned char buffer[256];
7396 unsigned char *end;
7397
7398 end = enc_cc_qsig_req_rsp(ctrl, buffer, buffer + sizeof(buffer), cc_record);
7399 if (!end) {
7400 return -1;
7401 }
7402
7403 return pri_call_apdu_queue(call, Q931_ANY_MESSAGE, buffer, end - buffer, NULL);
7404 }
7405
7406 /*!
7407 * \internal
7408 * \brief Send the CC activation request result Q.SIG.
7409 *
7410 * \param ctrl D channel controller.
7411 * \param cc_record Call completion record to process event.
7412 *
7413 * \retval 0 on success.
7414 * \retval -1 on error.
7415 */
send_cc_qsig_req_rsp(struct pri * ctrl,struct pri_cc_record * cc_record)7416 static int send_cc_qsig_req_rsp(struct pri *ctrl, struct pri_cc_record *cc_record)
7417 {
7418 struct q931_call *call;
7419 int retval;
7420
7421 /* The cc-request response goes out on either a CONNECT or RELEASE message. */
7422 call = cc_record->signaling;
7423 retval = rose_cc_qsig_req_rsp_encode(ctrl, call, cc_record);
7424 if (!retval) {
7425 if (cc_record->option.retain_signaling_link) {
7426 retval = q931_connect(ctrl, call, 0, 0);
7427 } else {
7428 pri_cc_disassociate_signaling_link(cc_record);
7429 retval = pri_hangup(ctrl, call, -1);
7430 }
7431 }
7432 if (retval) {
7433 pri_message(ctrl, "Could not schedule CC request result message.\n");
7434 return -1;
7435 }
7436
7437 return 0;
7438 }
7439
7440 /*!
7441 * \internal
7442 * \brief Response to an incoming CC activation request Q.SIG.
7443 *
7444 * \param ctrl D channel controller.
7445 * \param cc_record Call completion record to process event.
7446 * \param status success(0)/timeout(1)/
7447 * short_term_denial(2)/long_term_denial(3)/not_subscribed(4)/queue_full(5)
7448 *
7449 * \retval 0 on success.
7450 * \retval -1 on error.
7451 */
pri_cc_req_rsp_qsig(struct pri * ctrl,struct pri_cc_record * cc_record,int status)7452 static int pri_cc_req_rsp_qsig(struct pri *ctrl, struct pri_cc_record *cc_record, int status)
7453 {
7454 int fail;
7455
7456 switch (cc_record->response.invoke_operation) {
7457 case ROSE_QSIG_CcbsRequest:
7458 case ROSE_QSIG_CcnrRequest:
7459 break;
7460 default:
7461 /* We no longer know how to send the response. Should not happen. */
7462 return -1;
7463 }
7464 if (!cc_record->signaling) {
7465 return -1;
7466 }
7467
7468 fail = 0;
7469 if (status) {
7470 enum rose_error_code code;
7471
7472 switch (status) {
7473 default:
7474 case 1:/* timeout */
7475 case 5:/* queue_full */
7476 case 2:/* short_term_denial */
7477 code = ROSE_ERROR_QSIG_ShortTermRejection;
7478 break;
7479 case 4:/* not_subscribed */
7480 case 3:/* long_term_denial */
7481 code = ROSE_ERROR_QSIG_LongTermRejection;
7482 break;
7483 }
7484 rose_error_msg_encode(ctrl, cc_record->signaling, Q931_ANY_MESSAGE,
7485 cc_record->response.invoke_id, code);
7486 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_CANCEL);
7487 } else {
7488 /* Successful CC activation. */
7489 if (send_cc_qsig_req_rsp(ctrl, cc_record)) {
7490 fail = -1;
7491 }
7492 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_CC_REQUEST_ACCEPT);
7493 }
7494 return fail;
7495 }
7496
7497 /*!
7498 * \brief Response to an incoming CC activation request.
7499 *
7500 * \param ctrl D channel controller.
7501 * \param cc_id CC record ID to activate.
7502 * \param status success(0)/timeout(1)/
7503 * short_term_denial(2)/long_term_denial(3)/not_subscribed(4)/queue_full(5)
7504 *
7505 * \note
7506 * If the given status was failure, then the cc_id is no longer valid.
7507 * \note
7508 * The caller should cancel CC if error is returned.
7509 *
7510 * \retval 0 on success.
7511 * \retval -1 on error.
7512 */
pri_cc_req_rsp(struct pri * ctrl,long cc_id,int status)7513 int pri_cc_req_rsp(struct pri *ctrl, long cc_id, int status)
7514 {
7515 struct pri_cc_record *cc_record;
7516 int fail;
7517
7518 if (!ctrl) {
7519 return -1;
7520 }
7521 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7522 if (!cc_record) {
7523 return -1;
7524 }
7525 if (!cc_record->is_agent) {
7526 /* CC is a monitor and does not send this response event. */
7527 return -1;
7528 }
7529
7530 fail = -1;
7531 switch (ctrl->switchtype) {
7532 case PRI_SWITCH_QSIG:
7533 if (!pri_cc_req_rsp_qsig(ctrl, cc_record, status)) {
7534 fail = 0;
7535 }
7536 break;
7537 case PRI_SWITCH_EUROISDN_E1:
7538 case PRI_SWITCH_EUROISDN_T1:
7539 if (PTMP_MODE(ctrl)) {
7540 if (!pri_cc_req_rsp_ptmp(ctrl, cc_record, status)) {
7541 fail = 0;
7542 }
7543 } else {
7544 if (!pri_cc_req_rsp_ptp(ctrl, cc_record, status)) {
7545 fail = 0;
7546 }
7547 }
7548 break;
7549 default:
7550 break;
7551 }
7552 return fail;
7553 }
7554
7555 /*!
7556 * \brief Indicate that the remote user (Party B) is free to call.
7557 * The upper layer considers Party A is free.
7558 *
7559 * \param ctrl D channel controller.
7560 * \param cc_id CC record ID to activate.
7561 *
7562 * \return Nothing
7563 */
pri_cc_remote_user_free(struct pri * ctrl,long cc_id)7564 void pri_cc_remote_user_free(struct pri *ctrl, long cc_id)
7565 {
7566 struct pri_cc_record *cc_record;
7567
7568 if (!ctrl) {
7569 return;
7570 }
7571 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7572 if (!cc_record) {
7573 return;
7574 }
7575 if (!cc_record->is_agent) {
7576 /* CC is a monitor and does not send this event. */
7577 return;
7578 }
7579
7580 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_REMOTE_USER_FREE);
7581 }
7582
7583 /*!
7584 * \brief Indicate that the remote user (Party B) is free to call.
7585 * However, the upper layer considers Party A is busy.
7586 *
7587 * \details
7588 * Party B is free, but Party A is considered busy for some reason.
7589 * This is mainly due to the upper layer experiencing congestion.
7590 * The upper layer will be monitoring Party A until it considers
7591 * Party A free again.
7592 *
7593 * \param ctrl D channel controller.
7594 * \param cc_id CC record ID to activate.
7595 *
7596 * \return Nothing
7597 */
pri_cc_b_free(struct pri * ctrl,long cc_id)7598 void pri_cc_b_free(struct pri *ctrl, long cc_id)
7599 {
7600 struct pri_cc_record *cc_record;
7601
7602 if (!ctrl) {
7603 return;
7604 }
7605 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7606 if (!cc_record) {
7607 return;
7608 }
7609 if (!cc_record->is_agent) {
7610 /* CC is a monitor and does not send this event. */
7611 return;
7612 }
7613
7614 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_B_FREE);
7615 }
7616
7617 /*!
7618 * \brief Indicate that some other Party A has responed to the CC recall.
7619 *
7620 * \param ctrl D channel controller.
7621 * \param cc_id CC record ID to activate.
7622 *
7623 * \return Nothing
7624 */
pri_cc_stop_alerting(struct pri * ctrl,long cc_id)7625 void pri_cc_stop_alerting(struct pri *ctrl, long cc_id)
7626 {
7627 struct pri_cc_record *cc_record;
7628
7629 if (!ctrl) {
7630 return;
7631 }
7632 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7633 if (!cc_record) {
7634 return;
7635 }
7636 if (!cc_record->is_agent) {
7637 /* CC is a monitor and does not send this event. */
7638 return;
7639 }
7640
7641 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_STOP_ALERTING);
7642 }
7643
7644 /*!
7645 * \brief Poll/Ping for the status of CC party A.
7646 *
7647 * \param ctrl D channel controller.
7648 * \param cc_id CC record ID to activate.
7649 *
7650 * \note
7651 * There could be zero, one, or more PRI_SUBCMD_CC_STATUS_REQ_RSP responses to
7652 * the status request depending upon how many endpoints respond to the request.
7653 * \note
7654 * This is expected to be called only if there are two PTMP links between
7655 * party A and the network. (e.g., A --> * --> PSTN)
7656 *
7657 * \return Nothing
7658 */
pri_cc_status_req(struct pri * ctrl,long cc_id)7659 void pri_cc_status_req(struct pri *ctrl, long cc_id)
7660 {
7661 struct pri_cc_record *cc_record;
7662
7663 if (!ctrl) {
7664 return;
7665 }
7666 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7667 if (!cc_record) {
7668 return;
7669 }
7670 if (!cc_record->is_agent) {
7671 /* CC is a monitor and does not send this event. */
7672 return;
7673 }
7674
7675 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_A_STATUS);
7676 }
7677
7678 /*!
7679 * \internal
7680 * \brief Encode and queue an CCBSStatusRequest result message.
7681 *
7682 * \param ctrl D channel controller for diagnostic messages or global options.
7683 * \param call Call leg from which to encode CCBSStatusRequest.
7684 * \param cc_record Call completion record to process event.
7685 * \param is_free TRUE if the Party A status is available.
7686 *
7687 * \retval 0 on success.
7688 * \retval -1 on error.
7689 */
rose_ccbs_status_request_rsp(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,int is_free)7690 static int rose_ccbs_status_request_rsp(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, int is_free)
7691 {
7692 unsigned char buffer[256];
7693 unsigned char *end;
7694
7695 end =
7696 enc_etsi_ptmp_ccbs_status_request_rsp(ctrl, buffer, buffer + sizeof(buffer),
7697 cc_record, is_free);
7698 if (!end) {
7699 return -1;
7700 }
7701
7702 return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
7703 }
7704
7705 /*!
7706 * \internal
7707 * \brief Encode and send an CCBSStatusRequest result message.
7708 *
7709 * \param ctrl D channel controller for diagnostic messages or global options.
7710 * \param call Call leg from which to encode CCBSStatusRequest.
7711 * \param cc_record Call completion record to process event.
7712 * \param is_free TRUE if the Party A status is available.
7713 *
7714 * \retval 0 on success.
7715 * \retval -1 on error.
7716 */
send_ccbs_status_request_rsp(struct pri * ctrl,q931_call * call,struct pri_cc_record * cc_record,int is_free)7717 static int send_ccbs_status_request_rsp(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, int is_free)
7718 {
7719 if (rose_ccbs_status_request_rsp(ctrl, call, cc_record, is_free)
7720 || q931_facility(ctrl, call)) {
7721 pri_message(ctrl,
7722 "Could not schedule facility message for CCBSStatusRequest result.\n");
7723 return -1;
7724 }
7725
7726 return 0;
7727 }
7728
7729 /*!
7730 * \brief Update the busy status of CC party A.
7731 *
7732 * \param ctrl D channel controller.
7733 * \param cc_id CC record ID to activate.
7734 * \param status Updated party A status free(0)/busy(1)
7735 *
7736 * \note
7737 * This is expected to be called only if there are two PTMP links between
7738 * party A and the network. (e.g., A --> * --> PSTN)
7739 *
7740 * \return Nothing
7741 */
pri_cc_status_req_rsp(struct pri * ctrl,long cc_id,int status)7742 void pri_cc_status_req_rsp(struct pri *ctrl, long cc_id, int status)
7743 {
7744 struct pri_cc_record *cc_record;
7745
7746 if (!ctrl) {
7747 return;
7748 }
7749 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7750 if (!cc_record) {
7751 return;
7752 }
7753 if (cc_record->is_agent) {
7754 /* CC is an agent and does not send this response event. */
7755 return;
7756 }
7757
7758 switch (ctrl->switchtype) {
7759 case PRI_SWITCH_QSIG:
7760 /* Does not apply. */
7761 break;
7762 case PRI_SWITCH_EUROISDN_E1:
7763 case PRI_SWITCH_EUROISDN_T1:
7764 if (PTMP_MODE(ctrl)) {
7765 if (cc_record->response.invoke_operation != ROSE_ETSI_CCBSStatusRequest) {
7766 /* We no longer know how to send the response. */
7767 break;
7768 }
7769 send_ccbs_status_request_rsp(ctrl, cc_record->signaling, cc_record,
7770 status ? 0 /* busy */ : 1 /* free */);
7771 }
7772 break;
7773 default:
7774 break;
7775 }
7776 }
7777
7778 /*!
7779 * \brief Update the busy status of CC party A.
7780 *
7781 * \param ctrl D channel controller.
7782 * \param cc_id CC record ID to activate.
7783 * \param status Updated party A status free(0)/busy(1)
7784 *
7785 * \note
7786 * Party A status is used to suspend/resume monitoring party B.
7787 *
7788 * \return Nothing
7789 */
pri_cc_status(struct pri * ctrl,long cc_id,int status)7790 void pri_cc_status(struct pri *ctrl, long cc_id, int status)
7791 {
7792 struct pri_cc_record *cc_record;
7793
7794 if (!ctrl) {
7795 return;
7796 }
7797 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7798 if (!cc_record) {
7799 return;
7800 }
7801 if (cc_record->is_agent) {
7802 /* CC is an agent and does not send this event. */
7803 return;
7804 }
7805
7806 pri_cc_event(ctrl, cc_record->signaling, cc_record,
7807 status ? CC_EVENT_SUSPEND : CC_EVENT_RESUME);
7808 }
7809
7810 /*!
7811 * \brief Initiate the CC callback call.
7812 *
7813 * \param ctrl D channel controller.
7814 * \param cc_id CC record ID to activate.
7815 * \param call Q.931 call leg.
7816 * \param req SETUP request parameters. Parameters saved by CC will override.
7817 *
7818 * \retval 0 on success.
7819 * \retval -1 on error.
7820 */
pri_cc_call(struct pri * ctrl,long cc_id,q931_call * call,struct pri_sr * req)7821 int pri_cc_call(struct pri *ctrl, long cc_id, q931_call *call, struct pri_sr *req)
7822 {
7823 struct pri_cc_record *cc_record;
7824
7825 if (!ctrl || !pri_is_call_valid(ctrl, call) || !req) {
7826 return -1;
7827 }
7828 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7829 if (!cc_record) {
7830 return -1;
7831 }
7832 if (cc_record->is_agent) {
7833 /* CC is an agent and does not initiate callbacks. */
7834 return -1;
7835 }
7836
7837 /* Override parameters for sending recall. */
7838 req->caller = cc_record->party_a;
7839 req->called = cc_record->party_b;
7840 req->transmode = cc_record->bc.transcapability;
7841 req->userl1 = cc_record->bc.userl1;
7842
7843 /*
7844 * The caller is allowed to send different user-user information.
7845 *
7846 * It makes no sense for the caller to supply redirecting information
7847 * but we'll allow it to pass anyway.
7848 */
7849 //q931_party_redirecting_init(&req->redirecting);
7850
7851 /* Add switch specific recall APDU to call. */
7852 pri_cc_event(ctrl, call, cc_record, CC_EVENT_RECALL);
7853
7854 if (q931_setup(ctrl, call, req)) {
7855 return -1;
7856 }
7857 return 0;
7858 }
7859
7860 /*!
7861 * \brief Unsolicited indication that CC is cancelled.
7862 *
7863 * \param ctrl D channel controller.
7864 * \param cc_id CC record ID to deactivate.
7865 *
7866 * \return Nothing. The cc_id is no longer valid.
7867 */
pri_cc_cancel(struct pri * ctrl,long cc_id)7868 void pri_cc_cancel(struct pri *ctrl, long cc_id)
7869 {
7870 struct pri_cc_record *cc_record;
7871
7872 if (!ctrl) {
7873 return;
7874 }
7875 cc_record = pri_cc_find_by_id(ctrl, cc_id);
7876 if (!cc_record) {
7877 return;
7878 }
7879 pri_cc_event(ctrl, cc_record->signaling, cc_record, CC_EVENT_CANCEL);
7880 }
7881
7882 /* ------------------------------------------------------------------- */
7883 /* end pri_cc.c */
7884