2 * Copyright (c) 1996-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * Author: Hartmut Brandt <harti@freebsd.org>
29 * $Begemot: libunimsg/netnatm/sig/sig_coord.c,v 1.12 2004/08/05 07:11:01 brandt Exp $
34 #include <netnatm/unimsg.h>
35 #include <netnatm/saal/sscfudef.h>
36 #include <netnatm/msg/unistruct.h>
37 #include <netnatm/msg/unimsglib.h>
38 #include <netnatm/sig/uni.h>
40 #include <netnatm/sig/unipriv.h>
41 #include <netnatm/sig/unimkmsg.h>
43 #define STR(S) [S] = #S
44 static const char *const cunames[] = {
51 #define DEF_PRIV_SIG(NAME, FROM) [SIG##NAME] = "SIG"#NAME,
52 static const char *const coord_sigs[] = {
57 static void sig_all_calls(struct uni *, u_int sig);
58 static void set_custat(struct uni *, enum cu_stat);
60 static void input_dummy(struct uni *uni, struct uni_msg *m, struct uni_all *u);
61 static void input_global(struct uni *uni, struct uni_msg *m, struct uni_all *u);
62 static void input_unknown(struct uni *uni, struct uni_msg *m, struct uni_all *u);
63 static void input_cobi(struct call *c, struct uni_msg *m, struct uni_all *u);
64 static void input_call(struct call *c, struct uni_msg *m, struct uni_all *u);
66 TIMER_FUNC_UNI(t309, t309_func)
69 * All those 'bogus signal' printouts are not specified in the SDLs.
74 * SAAL-ESTABLISH.indication
76 * This means either a resynchronisation or error-recovery or
77 * an incoming SSCOP connection.
80 coord_saal_establish_indication(struct uni *uni)
82 switch (uni->custat) {
84 case CU_STAT0: /* Q.2931:Coord-U 4/10 */
85 case CU_STAT3: /* Q.2931:Coord-U 5/10 */
86 sig_all_calls(uni, SIGC_LINK_ESTABLISH_indication);
87 set_custat(uni, CU_STAT3);
92 VERBOSE0(uni, UNI_FAC_COORD,
93 "signal saal_establish.indication in CU%u", uni->custat);
97 ASSERT(0, ("CU_STAT*"));
102 * SAAL-ESTABLISH.confirm
105 coord_saal_establish_confirm(struct uni *uni)
107 switch (uni->custat) {
111 VERBOSE0(uni, UNI_FAC_COORD,
112 "signal saal_establish.confirm in CU%u", uni->custat);
117 * Q.2931:Co-ord-U 4/10
119 TIMER_STOP_UNI(uni, t309);
120 sig_all_calls(uni, SIGC_LINK_ESTABLISH_confirm);
121 uni->funcs->uni_output(uni, uni->arg,
122 UNIAPI_LINK_ESTABLISH_confirm, 0, NULL);
123 set_custat(uni, CU_STAT3);
128 * Q.2931:Coord-U 5/10
130 sig_all_calls(uni, SIGC_LINK_ESTABLISH_confirm);
131 uni->funcs->uni_output(uni, uni->arg,
132 UNIAPI_LINK_ESTABLISH_confirm, 0, NULL);
136 ASSERT(0, ("CU_STAT*"));
141 * SAAL-RELEASE.confirm
144 coord_saal_release_confirm(struct uni *uni)
146 switch (uni->custat) {
151 VERBOSE0(uni, UNI_FAC_COORD,
152 "signal saal_release.confirm in CU%u", uni->custat);
157 * Q.2931:Coord-U 5/10
159 uni->funcs->uni_output(uni, uni->arg,
160 UNIAPI_LINK_RELEASE_confirm, 0, NULL);
161 set_custat(uni, CU_STAT0);
165 ASSERT(0, ("CU_STAT*"));
173 coord_saal_release_indication(struct uni *uni)
175 switch (uni->custat) {
179 VERBOSE0(uni, UNI_FAC_COORD,
180 "signal saal_release.indication in CU%u", uni->custat);
186 * Q.2931:Coord-U 4/10
187 * Q.2931:Coord-U 5/10
189 sig_all_calls(uni, SIGC_LINK_RELEASE_indication);
190 set_custat(uni, CU_STAT0);
194 ASSERT(0, ("CU_STAT*"));
199 * Link-establish.request from USER. This can also come from
200 * a call instance. In this case 'cookie' is zero.
203 coord_link_establish_request(struct uni *uni, uint32_t cookie)
205 switch (uni->custat) {
209 * Q.2931:Coord-U 4/10
211 uni->funcs->saal_output(uni, uni->arg,
212 SAAL_ESTABLISH_request, NULL);
213 if (!TIMER_ISACT(uni, t309))
214 TIMER_START_UNI(uni, t309, uni->timer309);
215 set_custat(uni, CU_STAT1);
217 uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
222 * Q.2931:Coord-U 4/10
223 * This is probably missing from the delay field.
225 uni_delenq_coord(uni, SIGO_LINK_ESTABLISH_request,
230 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0);
232 VERBOSE0(uni, UNI_FAC_COORD,
233 "signal link-establish.request in CU%u",
239 * Q.2931:Coord-U 5/10
241 uni->funcs->uni_output(uni, uni->arg,
242 UNIAPI_LINK_ESTABLISH_confirm, 0, NULL);
243 uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
247 ASSERT(0, ("CU_STAT*"));
252 * Link-release.request from user
255 coord_link_release_request(struct uni *uni, u_int cookie)
257 switch (uni->custat) {
262 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0);
267 * Q.2931:Coord-U 5/10
269 uni->funcs->saal_output(uni, uni->arg,
270 SAAL_RELEASE_request, NULL);
271 set_custat(uni, CU_STAT2);
272 uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
276 ASSERT(0, ("CU_STAT*"));
281 * T309 timeout signal
284 coord_t309(struct uni *uni)
286 switch (uni->custat) {
291 * Q.2931:Coord-U 4/10
293 sig_all_calls(uni, SIGC_LINK_ESTABLISH_ERROR_indication);
294 set_custat(uni, CU_STAT0);
295 /* this is not in the SDLs, but how will the call control
296 * know, that starting the LINK has failed otherwise? */
297 uni->funcs->uni_output(uni, uni->arg,
298 UNIAPI_LINK_RELEASE_confirm, 0, NULL);
303 VERBOSE0(uni, UNI_FAC_COORD,
304 "signal T309 in CU%u", uni->custat);
308 ASSERT(0, ("CU_STAT*"));
316 coord_saal_data_indication(struct uni *uni, struct uni_msg *m)
321 memset(&uni->cause, 0, sizeof(uni->cause));
322 if ((u = UNI_ALLOC()) == NULL) {
326 if (uni_decode_head(m, u, &uni->cx)) {
327 VERBOSE(uni, UNI_FAC_COORD, 2, "bogus message - ignored");
332 if (u->u.hdr.cref.cref == CREF_DUMMY) {
334 input_dummy(uni, m, u);
336 VERBOSE(uni, UNI_FAC_COORD, 2, "dummy cref - ignored");
343 if (u->u.hdr.cref.cref == CREF_GLOBAL)
344 input_global(uni, m, u);
345 else if ((c = uni_find_call(uni, &u->u.hdr.cref)) == NULL)
346 input_unknown(uni, m, u);
347 else if (c->type == CALL_COBI)
354 * Message with global call reference
356 * Q.2931:Coord-U (X) 7/10
359 input_global(struct uni *uni, struct uni_msg *m, struct uni_all *u)
361 VERBOSE(uni, UNI_FAC_COORD, 2, "GLOB MTYPE = %x", u->mtype);
367 * Q.2931:Coord-U 7/10
371 uni_respond_status(uni, &u->u.hdr.cref,
372 u->u.hdr.cref.flag ? uni->glob_start : uni->glob_respond,
377 if (u->u.hdr.cref.flag) {
379 * Q.2931:Coord-U 7/10 (5.6.3.2h)
381 uni_respond_status(uni, &u->u.hdr.cref,
382 uni->glob_start, UNI_CAUSE_CREF_INV);
385 uni_enq_resp(uni, SIGR_RESTART, 0, m, u);
388 case UNI_RESTART_ACK:
389 if (!u->u.hdr.cref.flag) {
391 * Q.2931:Coord-U 7/10 (5.6.3.2h)
392 * Note, that the SDL diagram contains an error.
393 * The error with the 'YES' label should go to the
396 uni_respond_status(uni, &u->u.hdr.cref,
397 uni->glob_respond, UNI_CAUSE_CREF_INV);
400 uni_enq_start(uni, SIGS_RESTART_ACK, 0, m, u);
404 if (u->u.hdr.cref.flag)
405 uni_enq_start(uni, SIGS_STATUS, 0, m, u);
407 uni_enq_resp(uni, SIGR_STATUS, 0, m, u);
415 * Q.2931:Coord-U 8/10
417 * Message for an unknown call reference
420 input_unknown(struct uni *uni, struct uni_msg *m, struct uni_all *u)
422 struct uni_all *resp;
424 u_int cause = UNI_CAUSE_CREF_INV;
426 VERBOSE(uni, UNI_FAC_COORD, 2, "UNKNOWN MTYPE = %x", u->mtype);
432 * This message type is entirly unknown
434 * 5.6.4 and 5.7.1 are only when the call is not in the
435 * NULL state. This means, 5.6.3.2a takes over.
440 if (u->u.hdr.cref.flag)
445 if ((c = uni_create_call(uni, u->u.hdr.cref.cref, 0, 0)) != NULL) {
446 uni_enq_call(c, SIGC_SETUP, 0, m, u);
451 case UNI_RELEASE_COMPL:
461 * The SDLs don't use the verify procedure and don't
462 * handle the case of an invalid callstate - we
463 * ignore the message, if the callstate is not good.
465 (void)uni_decode_body(m, u, &uni->cx);
466 if (!IE_ISGOOD(u->u.status.callstate))
468 if (u->u.status.callstate.state == UNI_CALLSTATE_U0)
470 cause = UNI_CAUSE_MSG_INCOMP;
474 if ((resp = UNI_ALLOC()) == NULL)
477 (void)uni_decode_body(m, u, &uni->cx);
478 MK_MSG_RESP(resp, UNI_STATUS, &u->u.hdr.cref);
479 MK_IE_CALLSTATE(resp->u.status.callstate, UNI_CALLSTATE_U0);
480 MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER,
483 if (IE_ISGOOD(u->u.status_enq.epref)) {
484 /* reflect epref as required by L3MU_PO */
485 resp->u.status.epref = u->u.status_enq.epref;
486 MK_IE_EPREF(resp->u.status.epref,
487 u->u.status_enq.epref.epref,
488 !u->u.status_enq.epref.flag);
489 MK_IE_EPSTATE(resp->u.status.epstate, UNI_EPSTATE_NULL);
492 (void)uni_send_output(resp, uni);
498 if (u->u.hdr.cref.flag)
500 * 5.6.3.2c (probably)
503 if ((c = uni_create_call(uni, u->u.hdr.cref.cref, 0, 0)) != NULL) {
504 uni_enq_call(c, SIGC_COBISETUP, 0, m, u);
513 * Respond with a RELEASE COMPLETE
515 if ((resp = UNI_ALLOC()) == NULL)
518 MK_MSG_RESP(resp, UNI_RELEASE_COMPL, &u->u.hdr.cref);
519 MK_IE_CAUSE(resp->u.release_compl.cause[0], UNI_CAUSE_LOC_USER, cause);
520 if (uni_diag(cause, UNI_CODING_ITU) == UNI_DIAG_MTYPE)
521 ADD_CAUSE_MTYPE(resp->u.release_compl.cause[0], u->mtype);
523 (void)uni_send_output(resp, uni);
533 input_cobi(struct call *c __unused, struct uni_msg *m, struct uni_all *u)
541 input_dummy(struct uni *uni __unused, struct uni_msg *m, struct uni_all *u)
549 input_call(struct call *c, struct uni_msg *m, struct uni_all *u)
551 VERBOSE(c->uni, UNI_FAC_COORD, 2, "CALL MTYPE = %x %d/%s",
552 u->mtype, c->cref, c->mine ? "mine":"his");
563 uni_enq_call(c, SIGC_CALL_PROC, 0, m, u);
567 uni_enq_call(c, SIGC_ALERTING, 0, m, u);
571 uni_enq_call(c, SIGC_RELEASE, 0, m, u);
574 case UNI_RELEASE_COMPL:
575 uni_enq_call(c, SIGC_RELEASE_COMPL, 0, m, u);
579 uni_enq_call(c, SIGC_CONNECT, 0, m, u);
582 case UNI_CONNECT_ACK:
583 uni_enq_call(c, SIGC_CONNECT_ACK, 0, m, u);
587 uni_enq_call(c, SIGC_NOTIFY, 0, m, u);
591 uni_enq_call(c, SIGC_STATUS, 0, m, u);
595 uni_enq_call(c, SIGC_STATUS_ENQ, 0, m, u);
599 uni_enq_call(c, SIGC_ADD_PARTY, 0, m, u);
602 case UNI_PARTY_ALERTING:
603 uni_enq_call(c, SIGC_PARTY_ALERTING, 0, m, u);
606 case UNI_ADD_PARTY_ACK:
607 uni_enq_call(c, SIGC_ADD_PARTY_ACK, 0, m, u);
610 case UNI_ADD_PARTY_REJ:
611 uni_enq_call(c, SIGC_ADD_PARTY_REJ, 0, m, u);
615 uni_enq_call(c, SIGC_DROP_PARTY, 0, m, u);
618 case UNI_DROP_PARTY_ACK:
619 uni_enq_call(c, SIGC_DROP_PARTY_ACK, 0, m, u);
623 uni_enq_call(c, SIGC_UNKNOWN, 0, m, u);
632 * This macro tries to implement the delaying behaviour for
633 * message from the API when we are in the Awaiting-Establish state.
634 * In this state, the message is delayed. If we drop back to CU 0,
635 * everything gets unqueued and errors are returned for all that stuff.
636 * If we progess to CUSTAT2 we process the requests.
638 #define COMMON_DELAY(SIG, COOKIE) \
639 if (uni->custat == CU_STAT0 || uni->custat == CU_STAT2) {\
640 uniapi_uni_error(uni, UNIAPI_ERROR_BADCU, \
644 if (uni->custat == CU_STAT1) { \
645 uni_delenq_coord(uni, SIG, COOKIE, msg); \
650 * Signal handler of the coordinator
653 uni_sig_coord(struct uni *uni, enum coord_sig sig, uint32_t cookie,
658 if (sig >= SIGO_END) {
659 VERBOSE(uni, UNI_FAC_ERR, 1, "Signal %d outside of range to "
662 uni_msg_destroy(msg);
666 VERBOSE(uni, UNI_FAC_COORD, 1, "Signal %s in state %s",
667 coord_sigs[sig], cunames[uni->custat]);
674 case SIGO_DATA: /* delayed output */
675 if (uni->custat == CU_STAT0 || uni->custat == CU_STAT1)
677 if (uni->custat == CU_STAT1)
678 uni_delenq_coord(uni, SIGO_DATA, cookie, msg);/* ??? */
680 uni->funcs->saal_output(uni, uni->arg,
681 SAAL_DATA_request, msg);
688 case SIGO_SAAL_ESTABLISH_indication:
689 coord_saal_establish_indication(uni);
692 case SIGO_SAAL_ESTABLISH_confirm:
693 coord_saal_establish_confirm(uni);
696 case SIGO_SAAL_RELEASE_confirm:
697 coord_saal_release_confirm(uni);
700 case SIGO_SAAL_RELEASE_indication:
701 coord_saal_release_indication(uni);
704 case SIGO_SAAL_DATA_indication:
705 coord_saal_data_indication(uni, msg);
709 case SIGO_SAAL_UDATA_indication:
710 VERBOSE0(uni, UNI_FAC_ERR, "SAAL_UDATA_indication");
716 case SIGO_LINK_ESTABLISH_request:
717 coord_link_establish_request(uni, cookie);
720 case SIGO_LINK_RELEASE_request:
721 coord_link_release_request(uni, cookie);
724 case SIGO_RESET_request:
725 uni_enq_start(uni, SIGS_RESET_request, cookie, msg, NULL);
727 if (uni->custat == CU_STAT0) {
728 uni->funcs->saal_output(uni, uni->arg,
729 SAAL_ESTABLISH_request, NULL);
730 if (!TIMER_ISACT(uni, t309))
731 TIMER_START_UNI(uni, t309, uni->timer309);
732 set_custat(uni, CU_STAT1);
736 case SIGO_RESET_ERROR_response:
737 COMMON_DELAY(SIGO_RESET_ERROR_response, cookie);
738 uni_enq_resp(uni, SIGR_RESET_ERROR_response, cookie, msg, NULL);
742 case SIGO_RESET_response:
743 COMMON_DELAY(SIGO_RESET_response, cookie);
744 uni_enq_resp(uni, SIGR_RESET_response, cookie, msg, NULL);
748 case SIGO_SETUP_request:
749 if ((c = uni_create_new_call(uni, cookie)) != NULL) {
750 uni_enq_call(c, SIGC_SETUP_request, cookie, msg, NULL);
752 if (uni->custat == CU_STAT0) {
753 uni->funcs->saal_output(uni, uni->arg,
754 SAAL_ESTABLISH_request, NULL);
755 if (!TIMER_ISACT(uni, t309))
756 TIMER_START_UNI(uni, t309, uni->timer309);
757 set_custat(uni, CU_STAT1);
760 uniapi_uni_error(uni, UNIAPI_ERROR_NOMEM, cookie,
765 case SIGO_PROCEEDING_request:
767 struct uniapi_proceeding_request *arg =
768 uni_msg_rptr(msg, struct uniapi_proceeding_request *);
770 COMMON_DELAY(SIGO_PROCEEDING_request, cookie);
771 if ((c = uni_find_call(uni, &arg->call_proc.hdr.cref)) != NULL) {
772 uni_enq_call(c, SIGC_PROCEEDING_request, cookie, msg, NULL);
775 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
781 case SIGO_ALERTING_request:
783 struct uniapi_alerting_request *arg =
784 uni_msg_rptr(msg, struct uniapi_alerting_request *);
786 COMMON_DELAY(SIGO_ALERTING_request, cookie);
787 if ((c = uni_find_call(uni, &arg->alerting.hdr.cref)) != NULL) {
788 uni_enq_call(c, SIGC_ALERTING_request, cookie, msg, NULL);
791 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
797 case SIGO_SETUP_response:
799 struct uniapi_setup_response *arg =
800 uni_msg_rptr(msg, struct uniapi_setup_response *);
802 COMMON_DELAY(SIGO_SETUP_response, cookie);
803 if ((c = uni_find_call(uni, &arg->connect.hdr.cref)) != NULL) {
804 uni_enq_call(c, SIGC_SETUP_response, cookie, msg, NULL);
807 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
813 case SIGO_SETUP_COMPLETE_request:
815 struct uniapi_setup_complete_request *arg =
816 uni_msg_rptr(msg, struct uniapi_setup_complete_request *);
818 COMMON_DELAY(SIGO_SETUP_COMPLETE_request, cookie);
819 if ((c = uni_find_call(uni, &arg->connect_ack.hdr.cref)) != NULL) {
820 uni_enq_call(c, SIGC_SETUP_COMPLETE_request,
824 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
830 case SIGO_RELEASE_request:
832 struct uniapi_release_request *arg =
833 uni_msg_rptr(msg, struct uniapi_release_request *);
835 COMMON_DELAY(SIGO_RELEASE_request, cookie);
836 if ((c = uni_find_call(uni, &arg->release.hdr.cref)) != NULL) {
837 uni_enq_call(c, SIGC_RELEASE_request, cookie, msg, NULL);
840 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
846 case SIGO_RELEASE_response:
848 struct uniapi_release_response *arg =
849 uni_msg_rptr(msg, struct uniapi_release_response *);
851 COMMON_DELAY(SIGO_RELEASE_response, cookie);
852 if ((c = uni_find_call(uni, &arg->release_compl.hdr.cref)) != NULL) {
853 uni_enq_call(c, SIGC_RELEASE_response, cookie, msg, NULL);
856 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
862 case SIGO_NOTIFY_request:
864 struct uniapi_notify_request *arg =
865 uni_msg_rptr(msg, struct uniapi_notify_request *);
867 COMMON_DELAY(SIGO_NOTIFY_request, cookie);
868 if ((c = uni_find_call(uni, &arg->notify.hdr.cref)) != NULL) {
869 uni_enq_call(c, SIGC_NOTIFY_request, cookie, msg, NULL);
872 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
878 case SIGO_STATUS_ENQUIRY_request:
880 struct uniapi_status_enquiry_request *arg =
881 uni_msg_rptr(msg, struct uniapi_status_enquiry_request *);
883 COMMON_DELAY(SIGO_STATUS_ENQUIRY_request, cookie);
884 if ((c = uni_find_call(uni, &arg->cref)) != NULL) {
885 uni_enq_call(c, SIGC_STATUS_ENQUIRY_request, cookie, msg, NULL);
888 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
894 case SIGO_ADD_PARTY_request:
896 struct uniapi_add_party_request *arg =
897 uni_msg_rptr(msg, struct uniapi_add_party_request *);
899 COMMON_DELAY(SIGO_ADD_PARTY_request, cookie);
900 if ((c = uni_find_call(uni, &arg->add.hdr.cref)) != NULL) {
901 if (c->type != CALL_ROOT) {
902 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
906 uni_enq_call(c, SIGC_ADD_PARTY_request, cookie, msg, NULL);
909 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
915 case SIGO_PARTY_ALERTING_request:
917 struct uniapi_party_alerting_request *arg =
918 uni_msg_rptr(msg, struct uniapi_party_alerting_request *);
920 COMMON_DELAY(SIGO_PARTY_ALERTING_request, cookie);
921 if ((c = uni_find_call(uni, &arg->alert.hdr.cref)) != NULL) {
922 if (c->type != CALL_LEAF) {
923 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
927 uni_enq_call(c, SIGC_PARTY_ALERTING_request, cookie, msg, NULL);
930 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
936 case SIGO_ADD_PARTY_ACK_request:
938 struct uniapi_add_party_ack_request *arg =
939 uni_msg_rptr(msg, struct uniapi_add_party_ack_request *);
941 COMMON_DELAY(SIGO_ADD_PARTY_ACK_request, cookie);
942 if ((c = uni_find_call(uni, &arg->ack.hdr.cref)) != NULL) {
943 if (c->type != CALL_LEAF) {
944 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
948 uni_enq_call(c, SIGC_ADD_PARTY_ACK_request, cookie, msg, NULL);
951 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
957 case SIGO_ADD_PARTY_REJ_request:
959 struct uniapi_add_party_rej_request *arg =
960 uni_msg_rptr(msg, struct uniapi_add_party_rej_request *);
962 COMMON_DELAY(SIGO_ADD_PARTY_REJ_request, cookie);
963 if ((c = uni_find_call(uni, &arg->rej.hdr.cref)) != NULL) {
964 if (c->type != CALL_LEAF) {
965 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
969 uni_enq_call(c, SIGC_ADD_PARTY_REJ_request, cookie, msg, NULL);
972 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
978 case SIGO_DROP_PARTY_request:
980 struct uniapi_drop_party_request *arg =
981 uni_msg_rptr(msg, struct uniapi_drop_party_request *);
983 COMMON_DELAY(SIGO_DROP_PARTY_request, cookie);
984 if ((c = uni_find_call(uni, &arg->drop.hdr.cref)) != NULL) {
985 if (c->type != CALL_ROOT && c->type != CALL_LEAF) {
986 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
990 uni_enq_call(c, SIGC_DROP_PARTY_request, cookie, msg, NULL);
993 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
999 case SIGO_DROP_PARTY_ACK_request:
1001 struct uniapi_drop_party_ack_request *arg =
1002 uni_msg_rptr(msg, struct uniapi_drop_party_ack_request *);
1004 COMMON_DELAY(SIGO_DROP_PARTY_ACK_request, cookie);
1005 if ((c = uni_find_call(uni, &arg->ack.hdr.cref)) != NULL) {
1006 if (c->type != CALL_ROOT && c->type != CALL_LEAF) {
1007 uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE,
1011 uni_enq_call(c, SIGC_DROP_PARTY_ACK_request, cookie, msg, NULL);
1014 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
1020 case SIGO_ABORT_CALL_request:
1022 struct uniapi_abort_call_request *arg =
1023 uni_msg_rptr(msg, struct uniapi_abort_call_request *);
1025 if ((c = uni_find_call(uni, &arg->cref)) != NULL) {
1026 uni_enq_call(c, SIGC_ABORT_CALL_request, cookie, NULL, NULL);
1028 uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie,
1037 case SIGO_CALL_DESTROYED:
1038 uni->funcs->uni_output(uni, uni->arg,
1039 UNIAPI_CALL_DESTROYED, 0, msg);
1046 case SIGO_RESET_indication:
1047 uni->funcs->uni_output(uni, uni->arg,
1048 UNIAPI_RESET_indication, 0, msg);
1061 uni_msg_destroy(msg);
1065 * Send a signal to all call instances
1068 sig_all_calls(struct uni *uni, u_int sig)
1072 TAILQ_FOREACH(call, &uni->calls, link)
1073 uni_enq_call(call, sig, 0, NULL, NULL);
1077 * Set a new coordinator state - this moves all delayed coordinator
1078 * signals from the delayed queue to the signal queue.
1081 cufilt(struct sig *s, void *arg __unused)
1083 return (s->type == SIG_COORD);
1087 set_custat(struct uni *uni, enum cu_stat nstate)
1089 if (uni->custat != nstate) {
1090 uni->custat = nstate;
1091 uni_undel(uni, cufilt, NULL);
1096 * T309 timeout function
1099 t309_func(struct uni *uni)
1101 uni_enq_coord(uni, SIGO_T309, 0, NULL);
1105 * Respond with a status message
1108 uni_respond_status(struct uni *uni, struct uni_cref *cref,
1109 enum uni_callstate cs, enum uni_cause c1)
1111 struct uni_all *resp;
1113 if ((resp = UNI_ALLOC()) == NULL)
1116 MK_MSG_RESP(resp, UNI_STATUS, cref);
1117 MK_IE_CALLSTATE(resp->u.status.callstate, cs);
1118 MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER, c1);
1120 (void)uni_send_output(resp, uni);
1126 * Respond with a status message
1129 uni_respond_status_mtype(struct uni *uni, struct uni_cref *cref,
1130 enum uni_callstate cs, enum uni_cause c1, u_int mtype)
1132 struct uni_all *resp;
1134 if((resp = UNI_ALLOC()) == NULL)
1137 MK_MSG_RESP(resp, UNI_STATUS, cref);
1138 MK_IE_CALLSTATE(resp->u.status.callstate, cs);
1139 MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER, c1);
1140 ADD_CAUSE_MTYPE(resp->u.status.cause, mtype);
1142 (void)uni_send_output(resp, uni);
1148 * Send a message. If we are in CUSTAT1, delay the message if we
1149 * are in CUSTAT3 send it, else drop it.
1152 uni_send_output(struct uni_all *u, struct uni *uni)
1157 if (uni->custat == CU_STAT0 || uni->custat == CU_STAT2)
1160 m = uni_msg_alloc(1024);
1161 if ((err = uni_encode(m, u, &uni->cx)) != 0) {
1162 VERBOSE0(uni, UNI_FAC_ERR, "uni_encode failed: %08x", err);
1166 if (uni->custat == CU_STAT1)
1167 uni_delenq_coord(uni, SIGO_DATA, 0, m);
1169 uni->funcs->saal_output(uni, uni->arg, SAAL_DATA_request, m);