1122205Sharti/* 2122205Sharti * Copyright (c) 1996-2003 3122205Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4122205Sharti * All rights reserved. 5122205Sharti * 6122205Sharti * Redistribution and use in source and binary forms, with or without 7122205Sharti * modification, are permitted provided that the following conditions 8122205Sharti * are met: 9122205Sharti * 1. Redistributions of source code must retain the above copyright 10122205Sharti * notice, this list of conditions and the following disclaimer. 11122205Sharti * 2. Redistributions in binary form must reproduce the above copyright 12122205Sharti * notice, this list of conditions and the following disclaimer in the 13122205Sharti * documentation and/or other materials provided with the distribution. 14122205Sharti * 15122205Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16122205Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17122205Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18122205Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19122205Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20122205Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21122205Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22122205Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23122205Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24122205Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25122205Sharti * SUCH DAMAGE. 26122205Sharti * 27122205Sharti * Author: Hartmut Brandt <harti@freebsd.org> 28122205Sharti * 29133492Sharti * $Begemot: libunimsg/netnatm/sig/sig_coord.c,v 1.12 2004/08/05 07:11:01 brandt Exp $ 30122205Sharti * 31122205Sharti * Coordinator 32122205Sharti */ 33122205Sharti 34122205Sharti#include <netnatm/unimsg.h> 35122205Sharti#include <netnatm/saal/sscfudef.h> 36122205Sharti#include <netnatm/msg/unistruct.h> 37122205Sharti#include <netnatm/msg/unimsglib.h> 38122205Sharti#include <netnatm/sig/uni.h> 39122205Sharti 40122205Sharti#include <netnatm/sig/unipriv.h> 41122205Sharti#include <netnatm/sig/unimkmsg.h> 42122205Sharti 43133492Sharti#define STR(S) [S] = #S 44122205Shartistatic const char *const cunames[] = { 45122205Sharti STR(CU_STAT0), 46122205Sharti STR(CU_STAT1), 47122205Sharti STR(CU_STAT2), 48122205Sharti STR(CU_STAT3), 49122205Sharti}; 50122205Sharti 51133492Sharti#define DEF_PRIV_SIG(NAME, FROM) [SIG##NAME] = "SIG"#NAME, 52122205Shartistatic const char *const coord_sigs[] = { 53122205Sharti DEF_COORD_SIGS 54122205Sharti}; 55122205Sharti#undef DEF_PRIV_SIG 56122205Sharti 57122205Shartistatic void sig_all_calls(struct uni *, u_int sig); 58122205Shartistatic void set_custat(struct uni *, enum cu_stat); 59122205Sharti 60122205Shartistatic void input_dummy(struct uni *uni, struct uni_msg *m, struct uni_all *u); 61122205Shartistatic void input_global(struct uni *uni, struct uni_msg *m, struct uni_all *u); 62122205Shartistatic void input_unknown(struct uni *uni, struct uni_msg *m, struct uni_all *u); 63122205Shartistatic void input_cobi(struct call *c, struct uni_msg *m, struct uni_all *u); 64122205Shartistatic void input_call(struct call *c, struct uni_msg *m, struct uni_all *u); 65122205Sharti 66122205ShartiTIMER_FUNC_UNI(t309, t309_func) 67122205Sharti 68122205Sharti/* 69122205Sharti * All those 'bogus signal' printouts are not specified in the SDLs. 70122205Sharti */ 71122205Sharti 72122205Sharti 73122205Sharti/* 74122205Sharti * SAAL-ESTABLISH.indication 75122205Sharti * 76122205Sharti * This means either a resynchronisation or error-recovery or 77122205Sharti * an incoming SSCOP connection. 78122205Sharti */ 79122205Shartistatic void 80122205Sharticoord_saal_establish_indication(struct uni *uni) 81122205Sharti{ 82122205Sharti switch (uni->custat) { 83122205Sharti 84122205Sharti case CU_STAT0: /* Q.2931:Coord-U 4/10 */ 85122205Sharti case CU_STAT3: /* Q.2931:Coord-U 5/10 */ 86122205Sharti sig_all_calls(uni, SIGC_LINK_ESTABLISH_indication); 87122205Sharti set_custat(uni, CU_STAT3); 88122205Sharti break; 89122205Sharti 90122205Sharti case CU_STAT1: 91122205Sharti case CU_STAT2: 92122205Sharti VERBOSE0(uni, UNI_FAC_COORD, 93122205Sharti "signal saal_establish.indication in CU%u", uni->custat); 94122205Sharti break; 95122205Sharti 96122205Sharti default: 97122205Sharti ASSERT(0, ("CU_STAT*")); 98122205Sharti } 99122205Sharti} 100122205Sharti 101122205Sharti/* 102122205Sharti * SAAL-ESTABLISH.confirm 103122205Sharti */ 104122205Shartistatic void 105122205Sharticoord_saal_establish_confirm(struct uni *uni) 106122205Sharti{ 107122205Sharti switch (uni->custat) { 108122205Sharti 109122205Sharti case CU_STAT0: 110122205Sharti case CU_STAT2: 111122205Sharti VERBOSE0(uni, UNI_FAC_COORD, 112122205Sharti "signal saal_establish.confirm in CU%u", uni->custat); 113122205Sharti break; 114122205Sharti 115122205Sharti case CU_STAT1: 116122205Sharti /* 117122205Sharti * Q.2931:Co-ord-U 4/10 118122205Sharti */ 119122205Sharti TIMER_STOP_UNI(uni, t309); 120122205Sharti sig_all_calls(uni, SIGC_LINK_ESTABLISH_confirm); 121122205Sharti uni->funcs->uni_output(uni, uni->arg, 122122205Sharti UNIAPI_LINK_ESTABLISH_confirm, 0, NULL); 123122205Sharti set_custat(uni, CU_STAT3); 124122205Sharti break; 125122205Sharti 126122205Sharti case CU_STAT3: 127122205Sharti /* 128122205Sharti * Q.2931:Coord-U 5/10 129122205Sharti */ 130122205Sharti sig_all_calls(uni, SIGC_LINK_ESTABLISH_confirm); 131122205Sharti uni->funcs->uni_output(uni, uni->arg, 132122205Sharti UNIAPI_LINK_ESTABLISH_confirm, 0, NULL); 133122205Sharti break; 134122205Sharti 135122205Sharti default: 136122205Sharti ASSERT(0, ("CU_STAT*")); 137122205Sharti } 138122205Sharti} 139122205Sharti 140122205Sharti/* 141122205Sharti * SAAL-RELEASE.confirm 142122205Sharti */ 143122205Shartistatic void 144122205Sharticoord_saal_release_confirm(struct uni *uni) 145122205Sharti{ 146122205Sharti switch (uni->custat) { 147122205Sharti 148122205Sharti case CU_STAT0: 149122205Sharti case CU_STAT1: 150122205Sharti case CU_STAT3: 151122205Sharti VERBOSE0(uni, UNI_FAC_COORD, 152122205Sharti "signal saal_release.confirm in CU%u", uni->custat); 153122205Sharti break; 154122205Sharti 155122205Sharti case CU_STAT2: 156122205Sharti /* 157122205Sharti * Q.2931:Coord-U 5/10 158122205Sharti */ 159122205Sharti uni->funcs->uni_output(uni, uni->arg, 160122205Sharti UNIAPI_LINK_RELEASE_confirm, 0, NULL); 161122205Sharti set_custat(uni, CU_STAT0); 162122205Sharti break; 163122205Sharti 164122205Sharti default: 165122205Sharti ASSERT(0, ("CU_STAT*")); 166122205Sharti } 167122205Sharti} 168122205Sharti 169122205Sharti/* 170122205Sharti * SAAL failure. 171122205Sharti */ 172122205Shartistatic void 173122205Sharticoord_saal_release_indication(struct uni *uni) 174122205Sharti{ 175122205Sharti switch (uni->custat) { 176122205Sharti 177122205Sharti case CU_STAT0: 178122205Sharti case CU_STAT2: 179122205Sharti VERBOSE0(uni, UNI_FAC_COORD, 180122205Sharti "signal saal_release.indication in CU%u", uni->custat); 181122205Sharti break; 182122205Sharti 183122205Sharti case CU_STAT1: 184122205Sharti case CU_STAT3: 185122205Sharti /* 186122205Sharti * Q.2931:Coord-U 4/10 187122205Sharti * Q.2931:Coord-U 5/10 188122205Sharti */ 189122205Sharti sig_all_calls(uni, SIGC_LINK_RELEASE_indication); 190122205Sharti set_custat(uni, CU_STAT0); 191122205Sharti break; 192122205Sharti 193122205Sharti default: 194122205Sharti ASSERT(0, ("CU_STAT*")); 195122205Sharti } 196122205Sharti} 197122205Sharti 198122205Sharti/* 199122205Sharti * Link-establish.request from USER. This can also come from 200122205Sharti * a call instance. In this case 'cookie' is zero. 201122205Sharti */ 202122205Shartistatic void 203131826Sharticoord_link_establish_request(struct uni *uni, uint32_t cookie) 204122205Sharti{ 205122205Sharti switch (uni->custat) { 206122205Sharti 207122205Sharti case CU_STAT0: 208122205Sharti /* 209122205Sharti * Q.2931:Coord-U 4/10 210122205Sharti */ 211122205Sharti uni->funcs->saal_output(uni, uni->arg, 212122205Sharti SAAL_ESTABLISH_request, NULL); 213122205Sharti if (!TIMER_ISACT(uni, t309)) 214122205Sharti TIMER_START_UNI(uni, t309, uni->timer309); 215122205Sharti set_custat(uni, CU_STAT1); 216122205Sharti if (cookie) 217122205Sharti uniapi_uni_error(uni, UNIAPI_OK, cookie, 0); 218122205Sharti break; 219122205Sharti 220122205Sharti case CU_STAT1: 221122205Sharti /* 222122205Sharti * Q.2931:Coord-U 4/10 223122205Sharti * This is probably missing from the delay field. 224122205Sharti */ 225122205Sharti uni_delenq_coord(uni, SIGO_LINK_ESTABLISH_request, 226122205Sharti cookie, NULL); 227122205Sharti break; 228122205Sharti 229122205Sharti case CU_STAT2: 230122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0); 231122205Sharti if (cookie == 0) 232122205Sharti VERBOSE0(uni, UNI_FAC_COORD, 233122205Sharti "signal link-establish.request in CU%u", 234122205Sharti uni->custat); 235122205Sharti break; 236122205Sharti 237122205Sharti case CU_STAT3: 238122205Sharti /* 239122205Sharti * Q.2931:Coord-U 5/10 240122205Sharti */ 241122205Sharti uni->funcs->uni_output(uni, uni->arg, 242122205Sharti UNIAPI_LINK_ESTABLISH_confirm, 0, NULL); 243122205Sharti uniapi_uni_error(uni, UNIAPI_OK, cookie, 0); 244122205Sharti break; 245122205Sharti 246122205Sharti default: 247122205Sharti ASSERT(0, ("CU_STAT*")); 248122205Sharti } 249122205Sharti} 250122205Sharti 251122205Sharti/* 252122205Sharti * Link-release.request from user 253122205Sharti */ 254122205Shartistatic void 255122205Sharticoord_link_release_request(struct uni *uni, u_int cookie) 256122205Sharti{ 257122205Sharti switch (uni->custat) { 258122205Sharti 259122205Sharti case CU_STAT0: 260122205Sharti case CU_STAT1: 261122205Sharti case CU_STAT2: 262122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0); 263122205Sharti break; 264122205Sharti 265122205Sharti case CU_STAT3: 266122205Sharti /* 267122205Sharti * Q.2931:Coord-U 5/10 268122205Sharti */ 269122205Sharti uni->funcs->saal_output(uni, uni->arg, 270122205Sharti SAAL_RELEASE_request, NULL); 271122205Sharti set_custat(uni, CU_STAT2); 272122205Sharti uniapi_uni_error(uni, UNIAPI_OK, cookie, 0); 273122205Sharti break; 274122205Sharti 275122205Sharti default: 276122205Sharti ASSERT(0, ("CU_STAT*")); 277122205Sharti } 278122205Sharti} 279122205Sharti 280122205Sharti/* 281122205Sharti * T309 timeout signal 282122205Sharti */ 283122205Shartistatic void 284122205Sharticoord_t309(struct uni *uni) 285122205Sharti{ 286122205Sharti switch (uni->custat) { 287122205Sharti 288122205Sharti case CU_STAT0: 289122205Sharti case CU_STAT1: 290122205Sharti /* 291122205Sharti * Q.2931:Coord-U 4/10 292122205Sharti */ 293122205Sharti sig_all_calls(uni, SIGC_LINK_ESTABLISH_ERROR_indication); 294122205Sharti set_custat(uni, CU_STAT0); 295122205Sharti /* this is not in the SDLs, but how will the call control 296122205Sharti * know, that starting the LINK has failed otherwise? */ 297122205Sharti uni->funcs->uni_output(uni, uni->arg, 298122205Sharti UNIAPI_LINK_RELEASE_confirm, 0, NULL); 299122205Sharti break; 300122205Sharti 301122205Sharti case CU_STAT2: 302122205Sharti case CU_STAT3: 303122205Sharti VERBOSE0(uni, UNI_FAC_COORD, 304122205Sharti "signal T309 in CU%u", uni->custat); 305122205Sharti break; 306122205Sharti 307122205Sharti default: 308122205Sharti ASSERT(0, ("CU_STAT*")); 309122205Sharti } 310122205Sharti} 311122205Sharti 312122205Sharti/* 313122205Sharti * Message from SAAL 314122205Sharti */ 315122205Shartistatic void 316122205Sharticoord_saal_data_indication(struct uni *uni, struct uni_msg *m) 317122205Sharti{ 318122205Sharti struct uni_all *u; 319122205Sharti struct call *c; 320122205Sharti 321122205Sharti memset(&uni->cause, 0, sizeof(uni->cause)); 322122205Sharti if ((u = UNI_ALLOC()) == NULL) { 323122205Sharti uni_msg_destroy(m); 324122205Sharti return; 325122205Sharti } 326122205Sharti if (uni_decode_head(m, u, &uni->cx)) { 327122205Sharti VERBOSE(uni, UNI_FAC_COORD, 2, "bogus message - ignored"); 328122205Sharti uni_msg_destroy(m); 329122205Sharti UNI_FREE(u); 330122205Sharti return; 331122205Sharti } 332122205Sharti if (u->u.hdr.cref.cref == CREF_DUMMY) { 333122205Sharti if (uni->cx.q2932) { 334122205Sharti input_dummy(uni, m, u); 335122205Sharti } else { 336122205Sharti VERBOSE(uni, UNI_FAC_COORD, 2, "dummy cref - ignored"); 337122205Sharti UNI_FREE(u); 338122205Sharti uni_msg_destroy(m); 339122205Sharti } 340122205Sharti return; 341122205Sharti } 342122205Sharti 343122205Sharti if (u->u.hdr.cref.cref == CREF_GLOBAL) 344122205Sharti input_global(uni, m, u); 345122205Sharti else if ((c = uni_find_call(uni, &u->u.hdr.cref)) == NULL) 346122205Sharti input_unknown(uni, m, u); 347122205Sharti else if (c->type == CALL_COBI) 348122205Sharti input_cobi(c, m, u); 349122205Sharti else 350122205Sharti input_call(c, m, u); 351122205Sharti} 352122205Sharti 353122205Sharti/* 354122205Sharti * Message with global call reference 355122205Sharti * 356122205Sharti * Q.2931:Coord-U (X) 7/10 357122205Sharti */ 358122205Shartistatic void 359122205Shartiinput_global(struct uni *uni, struct uni_msg *m, struct uni_all *u) 360122205Sharti{ 361122205Sharti VERBOSE(uni, UNI_FAC_COORD, 2, "GLOB MTYPE = %x", u->mtype); 362122205Sharti 363122205Sharti switch (u->mtype) { 364122205Sharti 365122205Sharti default: 366122205Sharti /* 367122205Sharti * Q.2931:Coord-U 7/10 368122205Sharti * Q.2931: 5.6.3.2e 369122205Sharti * Amd4: 29e 370122205Sharti */ 371122205Sharti uni_respond_status(uni, &u->u.hdr.cref, 372122205Sharti u->u.hdr.cref.flag ? uni->glob_start : uni->glob_respond, 373122205Sharti UNI_CAUSE_CREF_INV); 374122205Sharti break; 375122205Sharti 376122205Sharti case UNI_RESTART: 377122205Sharti if (u->u.hdr.cref.flag) { 378122205Sharti /* 379122205Sharti * Q.2931:Coord-U 7/10 (5.6.3.2h) 380122205Sharti */ 381122205Sharti uni_respond_status(uni, &u->u.hdr.cref, 382122205Sharti uni->glob_start, UNI_CAUSE_CREF_INV); 383122205Sharti break; 384122205Sharti } 385122205Sharti uni_enq_resp(uni, SIGR_RESTART, 0, m, u); 386122205Sharti return; 387122205Sharti 388122205Sharti case UNI_RESTART_ACK: 389122205Sharti if (!u->u.hdr.cref.flag) { 390122205Sharti /* 391122205Sharti * Q.2931:Coord-U 7/10 (5.6.3.2h) 392122205Sharti * Note, that the SDL diagram contains an error. 393122205Sharti * The error with the 'YES' label should go to the 394122205Sharti * box below 'OTHER'. 395122205Sharti */ 396122205Sharti uni_respond_status(uni, &u->u.hdr.cref, 397122205Sharti uni->glob_respond, UNI_CAUSE_CREF_INV); 398122205Sharti break; 399122205Sharti } 400122205Sharti uni_enq_start(uni, SIGS_RESTART_ACK, 0, m, u); 401122205Sharti return; 402122205Sharti 403122205Sharti case UNI_STATUS: 404122205Sharti if (u->u.hdr.cref.flag) 405122205Sharti uni_enq_start(uni, SIGS_STATUS, 0, m, u); 406122205Sharti else 407122205Sharti uni_enq_resp(uni, SIGR_STATUS, 0, m, u); 408122205Sharti return; 409122205Sharti } 410122205Sharti uni_msg_destroy(m); 411122205Sharti UNI_FREE(u); 412122205Sharti} 413122205Sharti 414122205Sharti/* 415122205Sharti * Q.2931:Coord-U 8/10 416122205Sharti * 417122205Sharti * Message for an unknown call reference 418122205Sharti */ 419122205Shartistatic void 420122205Shartiinput_unknown(struct uni *uni, struct uni_msg *m, struct uni_all *u) 421122205Sharti{ 422122205Sharti struct uni_all *resp; 423122205Sharti struct call *c; 424122205Sharti u_int cause = UNI_CAUSE_CREF_INV; 425122205Sharti 426122205Sharti VERBOSE(uni, UNI_FAC_COORD, 2, "UNKNOWN MTYPE = %x", u->mtype); 427122205Sharti 428122205Sharti switch (u->mtype) { 429122205Sharti 430122205Sharti default: 431122205Sharti /* 432122205Sharti * This message type is entirly unknown 433122205Sharti * 434122205Sharti * 5.6.4 and 5.7.1 are only when the call is not in the 435122205Sharti * NULL state. This means, 5.6.3.2a takes over. 436122205Sharti */ 437122205Sharti break; 438122205Sharti 439122205Sharti case UNI_SETUP: 440122205Sharti if (u->u.hdr.cref.flag) 441122205Sharti /* 442122205Sharti * 5.6.3.2c 443122205Sharti */ 444122205Sharti goto drop; 445122205Sharti if ((c = uni_create_call(uni, u->u.hdr.cref.cref, 0, 0)) != NULL) { 446122205Sharti uni_enq_call(c, SIGC_SETUP, 0, m, u); 447122205Sharti return; 448122205Sharti } 449122205Sharti goto drop; 450122205Sharti 451122205Sharti case UNI_RELEASE_COMPL: 452122205Sharti /* 453122205Sharti * 5.6.3.2c 454122205Sharti */ 455122205Sharti goto drop; 456122205Sharti 457122205Sharti case UNI_STATUS: 458122205Sharti /* 459122205Sharti * 5.6.12 460122205Sharti * 461122205Sharti * The SDLs don't use the verify procedure and don't 462122205Sharti * handle the case of an invalid callstate - we 463122205Sharti * ignore the message, if the callstate is not good. 464122205Sharti */ 465122205Sharti (void)uni_decode_body(m, u, &uni->cx); 466122205Sharti if (!IE_ISGOOD(u->u.status.callstate)) 467122205Sharti goto drop; 468122205Sharti if (u->u.status.callstate.state == UNI_CALLSTATE_U0) 469122205Sharti goto drop; 470122205Sharti cause = UNI_CAUSE_MSG_INCOMP; 471122205Sharti break; 472122205Sharti 473122205Sharti case UNI_STATUS_ENQ: 474122205Sharti if ((resp = UNI_ALLOC()) == NULL) 475122205Sharti goto drop; 476122205Sharti 477122205Sharti (void)uni_decode_body(m, u, &uni->cx); 478122205Sharti MK_MSG_RESP(resp, UNI_STATUS, &u->u.hdr.cref); 479122205Sharti MK_IE_CALLSTATE(resp->u.status.callstate, UNI_CALLSTATE_U0); 480122205Sharti MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER, 481122205Sharti UNI_CAUSE_STATUS); 482122205Sharti 483122205Sharti if (IE_ISGOOD(u->u.status_enq.epref)) { 484122205Sharti /* reflect epref as required by L3MU_PO */ 485122205Sharti resp->u.status.epref = u->u.status_enq.epref; 486122205Sharti MK_IE_EPREF(resp->u.status.epref, 487122205Sharti u->u.status_enq.epref.epref, 488122205Sharti !u->u.status_enq.epref.flag); 489122205Sharti MK_IE_EPSTATE(resp->u.status.epstate, UNI_EPSTATE_NULL); 490122205Sharti } 491122205Sharti 492122205Sharti (void)uni_send_output(resp, uni); 493122205Sharti 494122205Sharti UNI_FREE(resp); 495122205Sharti goto drop; 496122205Sharti 497122205Sharti case UNI_COBISETUP: 498122205Sharti if (u->u.hdr.cref.flag) 499122205Sharti /* 500122205Sharti * 5.6.3.2c (probably) 501122205Sharti */ 502122205Sharti goto drop; 503122205Sharti if ((c = uni_create_call(uni, u->u.hdr.cref.cref, 0, 0)) != NULL) { 504122205Sharti uni_enq_call(c, SIGC_COBISETUP, 0, m, u); 505122205Sharti return; 506122205Sharti } 507122205Sharti goto drop; 508122205Sharti } 509122205Sharti 510122205Sharti /* 511122205Sharti * 5.6.3.2a) 512122205Sharti * 513122205Sharti * Respond with a RELEASE COMPLETE 514122205Sharti */ 515122205Sharti if ((resp = UNI_ALLOC()) == NULL) 516122205Sharti goto drop; 517122205Sharti 518122205Sharti MK_MSG_RESP(resp, UNI_RELEASE_COMPL, &u->u.hdr.cref); 519122205Sharti MK_IE_CAUSE(resp->u.release_compl.cause[0], UNI_CAUSE_LOC_USER, cause); 520122205Sharti if (uni_diag(cause, UNI_CODING_ITU) == UNI_DIAG_MTYPE) 521122205Sharti ADD_CAUSE_MTYPE(resp->u.release_compl.cause[0], u->mtype); 522122205Sharti 523122205Sharti (void)uni_send_output(resp, uni); 524122205Sharti 525122205Sharti UNI_FREE(resp); 526122205Sharti 527122205Sharti drop: 528122205Sharti UNI_FREE(u); 529122205Sharti uni_msg_destroy(m); 530122205Sharti} 531122205Sharti 532122205Shartistatic void 533122205Shartiinput_cobi(struct call *c __unused, struct uni_msg *m, struct uni_all *u) 534122205Sharti{ 535122205Sharti /* XXX */ 536122205Sharti UNI_FREE(u); 537122205Sharti uni_msg_destroy(m); 538122205Sharti} 539122205Sharti 540122205Shartistatic void 541122205Shartiinput_dummy(struct uni *uni __unused, struct uni_msg *m, struct uni_all *u) 542122205Sharti{ 543122205Sharti /* XXX */ 544122205Sharti UNI_FREE(u); 545122205Sharti uni_msg_destroy(m); 546122205Sharti} 547122205Sharti 548122205Shartistatic void 549122205Shartiinput_call(struct call *c, struct uni_msg *m, struct uni_all *u) 550122205Sharti{ 551122205Sharti VERBOSE(c->uni, UNI_FAC_COORD, 2, "CALL MTYPE = %x %d/%s", 552122205Sharti u->mtype, c->cref, c->mine ? "mine":"his"); 553122205Sharti 554122205Sharti switch (u->mtype) { 555122205Sharti 556122205Sharti case UNI_SETUP: 557122205Sharti /* 558122205Sharti * Ignored 559122205Sharti */ 560122205Sharti break; 561122205Sharti 562122205Sharti case UNI_CALL_PROC: 563122205Sharti uni_enq_call(c, SIGC_CALL_PROC, 0, m, u); 564122205Sharti return; 565122205Sharti 566122205Sharti case UNI_ALERTING: 567122205Sharti uni_enq_call(c, SIGC_ALERTING, 0, m, u); 568122205Sharti return; 569122205Sharti 570122205Sharti case UNI_RELEASE: 571122205Sharti uni_enq_call(c, SIGC_RELEASE, 0, m, u); 572122205Sharti return; 573122205Sharti 574122205Sharti case UNI_RELEASE_COMPL: 575122205Sharti uni_enq_call(c, SIGC_RELEASE_COMPL, 0, m, u); 576122205Sharti return; 577122205Sharti 578122205Sharti case UNI_CONNECT: 579122205Sharti uni_enq_call(c, SIGC_CONNECT, 0, m, u); 580122205Sharti return; 581122205Sharti 582122205Sharti case UNI_CONNECT_ACK: 583122205Sharti uni_enq_call(c, SIGC_CONNECT_ACK, 0, m, u); 584122205Sharti return; 585122205Sharti 586122205Sharti case UNI_NOTIFY: 587122205Sharti uni_enq_call(c, SIGC_NOTIFY, 0, m, u); 588122205Sharti return; 589122205Sharti 590122205Sharti case UNI_STATUS: 591122205Sharti uni_enq_call(c, SIGC_STATUS, 0, m, u); 592122205Sharti return; 593122205Sharti 594122205Sharti case UNI_STATUS_ENQ: 595122205Sharti uni_enq_call(c, SIGC_STATUS_ENQ, 0, m, u); 596122205Sharti return; 597122205Sharti 598122205Sharti case UNI_ADD_PARTY: 599122205Sharti uni_enq_call(c, SIGC_ADD_PARTY, 0, m, u); 600122205Sharti return; 601122205Sharti 602122205Sharti case UNI_PARTY_ALERTING: 603122205Sharti uni_enq_call(c, SIGC_PARTY_ALERTING, 0, m, u); 604122205Sharti return; 605122205Sharti 606122205Sharti case UNI_ADD_PARTY_ACK: 607122205Sharti uni_enq_call(c, SIGC_ADD_PARTY_ACK, 0, m, u); 608122205Sharti return; 609122205Sharti 610122205Sharti case UNI_ADD_PARTY_REJ: 611122205Sharti uni_enq_call(c, SIGC_ADD_PARTY_REJ, 0, m, u); 612122205Sharti return; 613122205Sharti 614122205Sharti case UNI_DROP_PARTY: 615122205Sharti uni_enq_call(c, SIGC_DROP_PARTY, 0, m, u); 616122205Sharti return; 617122205Sharti 618122205Sharti case UNI_DROP_PARTY_ACK: 619122205Sharti uni_enq_call(c, SIGC_DROP_PARTY_ACK, 0, m, u); 620122205Sharti return; 621122205Sharti 622122205Sharti default: 623122205Sharti uni_enq_call(c, SIGC_UNKNOWN, 0, m, u); 624122205Sharti return; 625122205Sharti } 626122205Sharti UNI_FREE(u); 627122205Sharti uni_msg_destroy(m); 628122205Sharti} 629122205Sharti 630122205Sharti 631122205Sharti/* 632122205Sharti * This macro tries to implement the delaying behaviour for 633122205Sharti * message from the API when we are in the Awaiting-Establish state. 634122205Sharti * In this state, the message is delayed. If we drop back to CU 0, 635122205Sharti * everything gets unqueued and errors are returned for all that stuff. 636122205Sharti * If we progess to CUSTAT2 we process the requests. 637122205Sharti */ 638122205Sharti#define COMMON_DELAY(SIG, COOKIE) \ 639122205Sharti if (uni->custat == CU_STAT0 || uni->custat == CU_STAT2) {\ 640122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BADCU, \ 641122205Sharti COOKIE, 0); \ 642122205Sharti break; \ 643122205Sharti } \ 644122205Sharti if (uni->custat == CU_STAT1) { \ 645122205Sharti uni_delenq_coord(uni, SIG, COOKIE, msg); \ 646122205Sharti break; \ 647122205Sharti } 648122205Sharti 649122205Sharti/* 650122205Sharti * Signal handler of the coordinator 651122205Sharti */ 652122205Shartivoid 653131826Shartiuni_sig_coord(struct uni *uni, enum coord_sig sig, uint32_t cookie, 654122205Sharti struct uni_msg *msg) 655122205Sharti{ 656122205Sharti struct call *c; 657122205Sharti 658122205Sharti if (sig >= SIGO_END) { 659122205Sharti VERBOSE(uni, UNI_FAC_ERR, 1, "Signal %d outside of range to " 660122205Sharti "Coord", sig); 661122205Sharti if (msg) 662122205Sharti uni_msg_destroy(msg); 663122205Sharti return; 664122205Sharti } 665122205Sharti 666122205Sharti VERBOSE(uni, UNI_FAC_COORD, 1, "Signal %s in state %s", 667122205Sharti coord_sigs[sig], cunames[uni->custat]); 668122205Sharti 669122205Sharti switch (sig) { 670122205Sharti 671122205Sharti case SIGO_END: 672122205Sharti break; 673122205Sharti 674122205Sharti case SIGO_DATA: /* delayed output */ 675122205Sharti if (uni->custat == CU_STAT0 || uni->custat == CU_STAT1) 676122205Sharti break; /* drop */ 677122205Sharti if (uni->custat == CU_STAT1) 678122205Sharti uni_delenq_coord(uni, SIGO_DATA, cookie, msg);/* ??? */ 679122205Sharti else 680122205Sharti uni->funcs->saal_output(uni, uni->arg, 681122205Sharti SAAL_DATA_request, msg); 682122205Sharti msg = NULL; 683122205Sharti break; 684122205Sharti 685122205Sharti /* 686122205Sharti * SAAL signals 687122205Sharti */ 688122205Sharti case SIGO_SAAL_ESTABLISH_indication: 689122205Sharti coord_saal_establish_indication(uni); 690122205Sharti break; 691122205Sharti 692122205Sharti case SIGO_SAAL_ESTABLISH_confirm: 693122205Sharti coord_saal_establish_confirm(uni); 694122205Sharti break; 695122205Sharti 696122205Sharti case SIGO_SAAL_RELEASE_confirm: 697122205Sharti coord_saal_release_confirm(uni); 698122205Sharti break; 699122205Sharti 700122205Sharti case SIGO_SAAL_RELEASE_indication: 701122205Sharti coord_saal_release_indication(uni); 702122205Sharti break; 703122205Sharti 704122205Sharti case SIGO_SAAL_DATA_indication: 705122205Sharti coord_saal_data_indication(uni, msg); 706122205Sharti msg = NULL; 707122205Sharti break; 708122205Sharti 709122205Sharti case SIGO_SAAL_UDATA_indication: 710122205Sharti VERBOSE0(uni, UNI_FAC_ERR, "SAAL_UDATA_indication"); 711122205Sharti break; 712122205Sharti 713122205Sharti /* 714122205Sharti * Signals from USER 715122205Sharti */ 716122205Sharti case SIGO_LINK_ESTABLISH_request: 717122205Sharti coord_link_establish_request(uni, cookie); 718122205Sharti break; 719122205Sharti 720122205Sharti case SIGO_LINK_RELEASE_request: 721122205Sharti coord_link_release_request(uni, cookie); 722122205Sharti break; 723122205Sharti 724122205Sharti case SIGO_RESET_request: 725122205Sharti uni_enq_start(uni, SIGS_RESET_request, cookie, msg, NULL); 726122205Sharti msg = NULL; 727122205Sharti if (uni->custat == CU_STAT0) { 728122205Sharti uni->funcs->saal_output(uni, uni->arg, 729122205Sharti SAAL_ESTABLISH_request, NULL); 730122205Sharti if (!TIMER_ISACT(uni, t309)) 731122205Sharti TIMER_START_UNI(uni, t309, uni->timer309); 732122205Sharti set_custat(uni, CU_STAT1); 733122205Sharti } 734122205Sharti break; 735122205Sharti 736122205Sharti case SIGO_RESET_ERROR_response: 737122205Sharti COMMON_DELAY(SIGO_RESET_ERROR_response, cookie); 738122205Sharti uni_enq_resp(uni, SIGR_RESET_ERROR_response, cookie, msg, NULL); 739122205Sharti msg = NULL; 740122205Sharti break; 741122205Sharti 742122205Sharti case SIGO_RESET_response: 743122205Sharti COMMON_DELAY(SIGO_RESET_response, cookie); 744122205Sharti uni_enq_resp(uni, SIGR_RESET_response, cookie, msg, NULL); 745122205Sharti msg = NULL; 746122205Sharti break; 747122205Sharti 748122205Sharti case SIGO_SETUP_request: 749122205Sharti if ((c = uni_create_new_call(uni, cookie)) != NULL) { 750122205Sharti uni_enq_call(c, SIGC_SETUP_request, cookie, msg, NULL); 751122205Sharti msg = NULL; 752122205Sharti if (uni->custat == CU_STAT0) { 753122205Sharti uni->funcs->saal_output(uni, uni->arg, 754122205Sharti SAAL_ESTABLISH_request, NULL); 755122205Sharti if (!TIMER_ISACT(uni, t309)) 756122205Sharti TIMER_START_UNI(uni, t309, uni->timer309); 757122205Sharti set_custat(uni, CU_STAT1); 758122205Sharti } 759122205Sharti } else { 760122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_NOMEM, cookie, 761122205Sharti UNI_CALLSTATE_U0); 762122205Sharti } 763122205Sharti break; 764122205Sharti 765122205Sharti case SIGO_PROCEEDING_request: 766122205Sharti { 767122205Sharti struct uniapi_proceeding_request *arg = 768122205Sharti uni_msg_rptr(msg, struct uniapi_proceeding_request *); 769122205Sharti 770122205Sharti COMMON_DELAY(SIGO_PROCEEDING_request, cookie); 771122205Sharti if ((c = uni_find_call(uni, &arg->call_proc.hdr.cref)) != NULL) { 772122205Sharti uni_enq_call(c, SIGC_PROCEEDING_request, cookie, msg, NULL); 773122205Sharti msg = NULL; 774122205Sharti } else { 775122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 776122205Sharti UNI_CALLSTATE_U0); 777122205Sharti } 778122205Sharti break; 779122205Sharti } 780122205Sharti 781122205Sharti case SIGO_ALERTING_request: 782122205Sharti { 783122205Sharti struct uniapi_alerting_request *arg = 784122205Sharti uni_msg_rptr(msg, struct uniapi_alerting_request *); 785122205Sharti 786122205Sharti COMMON_DELAY(SIGO_ALERTING_request, cookie); 787122205Sharti if ((c = uni_find_call(uni, &arg->alerting.hdr.cref)) != NULL) { 788122205Sharti uni_enq_call(c, SIGC_ALERTING_request, cookie, msg, NULL); 789122205Sharti msg = NULL; 790122205Sharti } else { 791122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 792122205Sharti UNI_CALLSTATE_U0); 793122205Sharti } 794122205Sharti break; 795122205Sharti } 796122205Sharti 797122205Sharti case SIGO_SETUP_response: 798122205Sharti { 799122205Sharti struct uniapi_setup_response *arg = 800122205Sharti uni_msg_rptr(msg, struct uniapi_setup_response *); 801122205Sharti 802122205Sharti COMMON_DELAY(SIGO_SETUP_response, cookie); 803122205Sharti if ((c = uni_find_call(uni, &arg->connect.hdr.cref)) != NULL) { 804122205Sharti uni_enq_call(c, SIGC_SETUP_response, cookie, msg, NULL); 805122205Sharti msg = NULL; 806122205Sharti } else { 807122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 808122205Sharti UNI_CALLSTATE_U0); 809122205Sharti } 810122205Sharti break; 811122205Sharti } 812122205Sharti 813122205Sharti case SIGO_SETUP_COMPLETE_request: 814122205Sharti { 815122205Sharti struct uniapi_setup_complete_request *arg = 816122205Sharti uni_msg_rptr(msg, struct uniapi_setup_complete_request *); 817122205Sharti 818122205Sharti COMMON_DELAY(SIGO_SETUP_COMPLETE_request, cookie); 819122205Sharti if ((c = uni_find_call(uni, &arg->connect_ack.hdr.cref)) != NULL) { 820122205Sharti uni_enq_call(c, SIGC_SETUP_COMPLETE_request, 821122205Sharti cookie, msg, NULL); 822122205Sharti msg = NULL; 823122205Sharti } else { 824122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 825122205Sharti UNI_CALLSTATE_U0); 826122205Sharti } 827122205Sharti break; 828122205Sharti } 829122205Sharti 830122205Sharti case SIGO_RELEASE_request: 831122205Sharti { 832122205Sharti struct uniapi_release_request *arg = 833122205Sharti uni_msg_rptr(msg, struct uniapi_release_request *); 834122205Sharti 835122205Sharti COMMON_DELAY(SIGO_RELEASE_request, cookie); 836122205Sharti if ((c = uni_find_call(uni, &arg->release.hdr.cref)) != NULL) { 837122205Sharti uni_enq_call(c, SIGC_RELEASE_request, cookie, msg, NULL); 838122205Sharti msg = NULL; 839122205Sharti } else { 840122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 841122205Sharti UNI_CALLSTATE_U0); 842122205Sharti } 843122205Sharti break; 844122205Sharti } 845122205Sharti 846122205Sharti case SIGO_RELEASE_response: 847122205Sharti { 848122205Sharti struct uniapi_release_response *arg = 849122205Sharti uni_msg_rptr(msg, struct uniapi_release_response *); 850122205Sharti 851122205Sharti COMMON_DELAY(SIGO_RELEASE_response, cookie); 852122205Sharti if ((c = uni_find_call(uni, &arg->release_compl.hdr.cref)) != NULL) { 853122205Sharti uni_enq_call(c, SIGC_RELEASE_response, cookie, msg, NULL); 854122205Sharti msg = NULL; 855122205Sharti } else { 856122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 857122205Sharti UNI_CALLSTATE_U0); 858122205Sharti } 859122205Sharti break; 860122205Sharti } 861122205Sharti 862122205Sharti case SIGO_NOTIFY_request: 863122205Sharti { 864122205Sharti struct uniapi_notify_request *arg = 865122205Sharti uni_msg_rptr(msg, struct uniapi_notify_request *); 866122205Sharti 867122205Sharti COMMON_DELAY(SIGO_NOTIFY_request, cookie); 868122205Sharti if ((c = uni_find_call(uni, &arg->notify.hdr.cref)) != NULL) { 869122205Sharti uni_enq_call(c, SIGC_NOTIFY_request, cookie, msg, NULL); 870122205Sharti msg = NULL; 871122205Sharti } else { 872122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 873122205Sharti UNI_CALLSTATE_U0); 874122205Sharti } 875122205Sharti break; 876122205Sharti } 877122205Sharti 878122205Sharti case SIGO_STATUS_ENQUIRY_request: 879122205Sharti { 880122205Sharti struct uniapi_status_enquiry_request *arg = 881122205Sharti uni_msg_rptr(msg, struct uniapi_status_enquiry_request *); 882122205Sharti 883122205Sharti COMMON_DELAY(SIGO_STATUS_ENQUIRY_request, cookie); 884122205Sharti if ((c = uni_find_call(uni, &arg->cref)) != NULL) { 885122205Sharti uni_enq_call(c, SIGC_STATUS_ENQUIRY_request, cookie, msg, NULL); 886122205Sharti msg = NULL; 887122205Sharti } else { 888122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 889122205Sharti UNI_CALLSTATE_U0); 890122205Sharti } 891122205Sharti break; 892122205Sharti } 893122205Sharti 894122205Sharti case SIGO_ADD_PARTY_request: 895122205Sharti { 896122205Sharti struct uniapi_add_party_request *arg = 897122205Sharti uni_msg_rptr(msg, struct uniapi_add_party_request *); 898122205Sharti 899122205Sharti COMMON_DELAY(SIGO_ADD_PARTY_request, cookie); 900122205Sharti if ((c = uni_find_call(uni, &arg->add.hdr.cref)) != NULL) { 901122205Sharti if (c->type != CALL_ROOT) { 902122205Sharti uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE, 903122205Sharti cookie); 904122205Sharti break; 905122205Sharti } 906122205Sharti uni_enq_call(c, SIGC_ADD_PARTY_request, cookie, msg, NULL); 907122205Sharti msg = NULL; 908122205Sharti } else { 909122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 910122205Sharti UNI_CALLSTATE_U0); 911122205Sharti } 912122205Sharti break; 913122205Sharti } 914122205Sharti 915122205Sharti case SIGO_PARTY_ALERTING_request: 916122205Sharti { 917122205Sharti struct uniapi_party_alerting_request *arg = 918122205Sharti uni_msg_rptr(msg, struct uniapi_party_alerting_request *); 919122205Sharti 920122205Sharti COMMON_DELAY(SIGO_PARTY_ALERTING_request, cookie); 921122205Sharti if ((c = uni_find_call(uni, &arg->alert.hdr.cref)) != NULL) { 922122205Sharti if (c->type != CALL_LEAF) { 923122205Sharti uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE, 924122205Sharti cookie); 925122205Sharti break; 926122205Sharti } 927122205Sharti uni_enq_call(c, SIGC_PARTY_ALERTING_request, cookie, msg, NULL); 928122205Sharti msg = NULL; 929122205Sharti } else { 930122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 931122205Sharti UNI_CALLSTATE_U0); 932122205Sharti } 933122205Sharti break; 934122205Sharti } 935122205Sharti 936122205Sharti case SIGO_ADD_PARTY_ACK_request: 937122205Sharti { 938122205Sharti struct uniapi_add_party_ack_request *arg = 939122205Sharti uni_msg_rptr(msg, struct uniapi_add_party_ack_request *); 940122205Sharti 941122205Sharti COMMON_DELAY(SIGO_ADD_PARTY_ACK_request, cookie); 942122205Sharti if ((c = uni_find_call(uni, &arg->ack.hdr.cref)) != NULL) { 943122205Sharti if (c->type != CALL_LEAF) { 944122205Sharti uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE, 945122205Sharti cookie); 946122205Sharti break; 947122205Sharti } 948122205Sharti uni_enq_call(c, SIGC_ADD_PARTY_ACK_request, cookie, msg, NULL); 949122205Sharti msg = NULL; 950122205Sharti } else { 951122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 952122205Sharti UNI_CALLSTATE_U0); 953122205Sharti } 954122205Sharti break; 955122205Sharti } 956122205Sharti 957122205Sharti case SIGO_ADD_PARTY_REJ_request: 958122205Sharti { 959122205Sharti struct uniapi_add_party_rej_request *arg = 960122205Sharti uni_msg_rptr(msg, struct uniapi_add_party_rej_request *); 961122205Sharti 962122205Sharti COMMON_DELAY(SIGO_ADD_PARTY_REJ_request, cookie); 963122205Sharti if ((c = uni_find_call(uni, &arg->rej.hdr.cref)) != NULL) { 964122205Sharti if (c->type != CALL_LEAF) { 965122205Sharti uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE, 966122205Sharti cookie); 967122205Sharti break; 968122205Sharti } 969122205Sharti uni_enq_call(c, SIGC_ADD_PARTY_REJ_request, cookie, msg, NULL); 970122205Sharti msg = NULL; 971122205Sharti } else { 972122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 973122205Sharti UNI_CALLSTATE_U0); 974122205Sharti } 975122205Sharti break; 976122205Sharti } 977122205Sharti 978122205Sharti case SIGO_DROP_PARTY_request: 979122205Sharti { 980122205Sharti struct uniapi_drop_party_request *arg = 981122205Sharti uni_msg_rptr(msg, struct uniapi_drop_party_request *); 982122205Sharti 983122205Sharti COMMON_DELAY(SIGO_DROP_PARTY_request, cookie); 984122205Sharti if ((c = uni_find_call(uni, &arg->drop.hdr.cref)) != NULL) { 985122205Sharti if (c->type != CALL_ROOT && c->type != CALL_LEAF) { 986122205Sharti uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE, 987122205Sharti cookie); 988122205Sharti break; 989122205Sharti } 990122205Sharti uni_enq_call(c, SIGC_DROP_PARTY_request, cookie, msg, NULL); 991122205Sharti msg = NULL; 992122205Sharti } else { 993122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 994122205Sharti UNI_CALLSTATE_U0); 995122205Sharti } 996122205Sharti break; 997122205Sharti } 998122205Sharti 999122205Sharti case SIGO_DROP_PARTY_ACK_request: 1000122205Sharti { 1001122205Sharti struct uniapi_drop_party_ack_request *arg = 1002122205Sharti uni_msg_rptr(msg, struct uniapi_drop_party_ack_request *); 1003122205Sharti 1004122205Sharti COMMON_DELAY(SIGO_DROP_PARTY_ACK_request, cookie); 1005122205Sharti if ((c = uni_find_call(uni, &arg->ack.hdr.cref)) != NULL) { 1006122205Sharti if (c->type != CALL_ROOT && c->type != CALL_LEAF) { 1007122205Sharti uniapi_call_error(c, UNIAPI_ERROR_BAD_CTYPE, 1008122205Sharti cookie); 1009122205Sharti break; 1010122205Sharti } 1011122205Sharti uni_enq_call(c, SIGC_DROP_PARTY_ACK_request, cookie, msg, NULL); 1012122205Sharti msg = NULL; 1013122205Sharti } else { 1014122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 1015122205Sharti UNI_CALLSTATE_U0); 1016122205Sharti } 1017122205Sharti break; 1018122205Sharti } 1019122205Sharti 1020122205Sharti case SIGO_ABORT_CALL_request: 1021122205Sharti { 1022122205Sharti struct uniapi_abort_call_request *arg = 1023122205Sharti uni_msg_rptr(msg, struct uniapi_abort_call_request *); 1024122205Sharti 1025122205Sharti if ((c = uni_find_call(uni, &arg->cref)) != NULL) { 1026122205Sharti uni_enq_call(c, SIGC_ABORT_CALL_request, cookie, NULL, NULL); 1027122205Sharti } else { 1028122205Sharti uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALL, cookie, 1029122205Sharti UNI_CALLSTATE_U0); 1030122205Sharti } 1031122205Sharti break; 1032122205Sharti } 1033122205Sharti 1034122205Sharti /* 1035122205Sharti * Call-Control 1036122205Sharti */ 1037122205Sharti case SIGO_CALL_DESTROYED: 1038122205Sharti uni->funcs->uni_output(uni, uni->arg, 1039122205Sharti UNIAPI_CALL_DESTROYED, 0, msg); 1040122205Sharti msg = NULL; 1041122205Sharti break; 1042122205Sharti 1043122205Sharti /* 1044122205Sharti * ResetRespond 1045122205Sharti */ 1046122205Sharti case SIGO_RESET_indication: 1047122205Sharti uni->funcs->uni_output(uni, uni->arg, 1048122205Sharti UNIAPI_RESET_indication, 0, msg); 1049122205Sharti msg = NULL; 1050122205Sharti break; 1051122205Sharti 1052122205Sharti /* 1053122205Sharti * Timeouts 1054122205Sharti */ 1055122205Sharti case SIGO_T309: 1056122205Sharti coord_t309(uni); 1057122205Sharti break; 1058122205Sharti 1059122205Sharti } 1060122205Sharti if (msg != NULL) 1061122205Sharti uni_msg_destroy(msg); 1062122205Sharti} 1063122205Sharti 1064122205Sharti/* 1065122205Sharti * Send a signal to all call instances 1066122205Sharti */ 1067122205Shartistatic void 1068122205Shartisig_all_calls(struct uni *uni, u_int sig) 1069122205Sharti{ 1070122205Sharti struct call *call; 1071122205Sharti 1072122205Sharti TAILQ_FOREACH(call, &uni->calls, link) 1073122205Sharti uni_enq_call(call, sig, 0, NULL, NULL); 1074122205Sharti} 1075122205Sharti 1076122205Sharti/* 1077122205Sharti * Set a new coordinator state - this moves all delayed coordinator 1078122205Sharti * signals from the delayed queue to the signal queue. 1079122205Sharti */ 1080122205Shartistatic int 1081122205Sharticufilt(struct sig *s, void *arg __unused) 1082122205Sharti{ 1083122205Sharti return (s->type == SIG_COORD); 1084122205Sharti} 1085122205Sharti 1086122205Shartistatic void 1087122205Shartiset_custat(struct uni *uni, enum cu_stat nstate) 1088122205Sharti{ 1089122205Sharti if (uni->custat != nstate) { 1090122205Sharti uni->custat = nstate; 1091122205Sharti uni_undel(uni, cufilt, NULL); 1092122205Sharti } 1093122205Sharti} 1094122205Sharti 1095122205Sharti/* 1096122205Sharti * T309 timeout function 1097122205Sharti */ 1098122205Shartistatic void 1099122205Shartit309_func(struct uni *uni) 1100122205Sharti{ 1101122205Sharti uni_enq_coord(uni, SIGO_T309, 0, NULL); 1102122205Sharti} 1103122205Sharti 1104122205Sharti/* 1105122205Sharti * Respond with a status message 1106122205Sharti */ 1107122205Shartivoid 1108122205Shartiuni_respond_status(struct uni *uni, struct uni_cref *cref, 1109122205Sharti enum uni_callstate cs, enum uni_cause c1) 1110122205Sharti{ 1111122205Sharti struct uni_all *resp; 1112122205Sharti 1113122205Sharti if ((resp = UNI_ALLOC()) == NULL) 1114122205Sharti return; 1115122205Sharti 1116122205Sharti MK_MSG_RESP(resp, UNI_STATUS, cref); 1117122205Sharti MK_IE_CALLSTATE(resp->u.status.callstate, cs); 1118122205Sharti MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER, c1); 1119122205Sharti 1120122205Sharti (void)uni_send_output(resp, uni); 1121122205Sharti 1122122205Sharti UNI_FREE(resp); 1123122205Sharti} 1124122205Sharti 1125122205Sharti/* 1126122205Sharti * Respond with a status message 1127122205Sharti */ 1128122205Shartivoid 1129122205Shartiuni_respond_status_mtype(struct uni *uni, struct uni_cref *cref, 1130122205Sharti enum uni_callstate cs, enum uni_cause c1, u_int mtype) 1131122205Sharti{ 1132122205Sharti struct uni_all *resp; 1133122205Sharti 1134122205Sharti if((resp = UNI_ALLOC()) == NULL) 1135122205Sharti return; 1136122205Sharti 1137122205Sharti MK_MSG_RESP(resp, UNI_STATUS, cref); 1138122205Sharti MK_IE_CALLSTATE(resp->u.status.callstate, cs); 1139122205Sharti MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER, c1); 1140122205Sharti ADD_CAUSE_MTYPE(resp->u.status.cause, mtype); 1141122205Sharti 1142122205Sharti (void)uni_send_output(resp, uni); 1143122205Sharti 1144122205Sharti UNI_FREE(resp); 1145122205Sharti} 1146122205Sharti 1147122205Sharti/* 1148122205Sharti * Send a message. If we are in CUSTAT1, delay the message if we 1149122205Sharti * are in CUSTAT3 send it, else drop it. 1150122205Sharti */ 1151122205Shartiint 1152122205Shartiuni_send_output(struct uni_all *u, struct uni *uni) 1153122205Sharti{ 1154122205Sharti struct uni_msg *m; 1155122205Sharti int err; 1156122205Sharti 1157122205Sharti if (uni->custat == CU_STAT0 || uni->custat == CU_STAT2) 1158122205Sharti return (0); 1159122205Sharti 1160122205Sharti m = uni_msg_alloc(1024); 1161122205Sharti if ((err = uni_encode(m, u, &uni->cx)) != 0) { 1162122205Sharti VERBOSE0(uni, UNI_FAC_ERR, "uni_encode failed: %08x", err); 1163122205Sharti uni_msg_destroy(m); 1164122205Sharti return (-1); 1165122205Sharti } 1166122205Sharti if (uni->custat == CU_STAT1) 1167122205Sharti uni_delenq_coord(uni, SIGO_DATA, 0, m); 1168122205Sharti else 1169122205Sharti uni->funcs->saal_output(uni, uni->arg, SAAL_DATA_request, m); 1170122205Sharti return (0); 1171122205Sharti} 1172