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_party.c,v 1.18 2004/08/05 07:11:01 brandt Exp $ 30122205Sharti * 31122205Sharti * Party instance handling 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#include <netnatm/sig/unimsgcpy.h> 43122205Sharti 44122205Shartistatic void drop_partyE(struct party *p); 45122205Shartistatic int epstate_compat(struct party *, enum uni_epstate); 46122205Sharti 47133492Sharti#define DEF_PRIV_SIG(NAME, FROM) [SIG##NAME] = "SIG"#NAME, 48122205Shartistatic const char *const party_sigs[] = { 49122205Sharti DEF_PARTY_SIGS 50122205Sharti}; 51122205Sharti#undef DEF_PRIV_SIG 52122205Sharti 53122205ShartiTIMER_FUNC_PARTY(t397, t397_func) 54122205ShartiTIMER_FUNC_PARTY(t398, t398_func) 55122205ShartiTIMER_FUNC_PARTY(t399, t399_func) 56122205Sharti 57122205Shartistatic __inline void 58122205Shartiset_party_state(struct party *p, enum uni_epstate state) 59122205Sharti{ 60122205Sharti if (p->state != state) { 61122205Sharti VERBOSE(p->call->uni, UNI_FAC_CALL, 1, 62122205Sharti "party %u/%u %u/%u PU%u -> PU%u", 63122205Sharti p->call->cref, p->call->mine, 64122205Sharti p->epref, p->flags & PARTY_MINE, p->state, state); 65122205Sharti p->state = state; 66122205Sharti } 67122205Sharti} 68122205Sharti 69122205Sharti/* 70122205Sharti * Create a party with a given endpoint reference. 71122205Sharti * No check is done, that a party with this epref does not alreay exist. 72122205Sharti */ 73122205Shartistruct party * 74131826Shartiuni_create_partyx(struct call *c, u_int epref, u_int mine, uint32_t cookie) 75122205Sharti{ 76122205Sharti struct party *p; 77122205Sharti struct uni_msg *api; 78122205Sharti struct uniapi_party_created *ind; 79122205Sharti 80122205Sharti mine = (mine ? PARTY_MINE : 0); 81122205Sharti 82122205Sharti if ((p = PARTY_ALLOC()) == NULL) 83122205Sharti return (NULL); 84122205Sharti 85122205Sharti if ((ind = ALLOC_API(struct uniapi_party_created, api)) == NULL) { 86122205Sharti PARTY_FREE(p); 87122205Sharti return (NULL); 88122205Sharti } 89122205Sharti 90122205Sharti ind->cref.cref = c->cref; 91122205Sharti ind->cref.flag = c->mine; 92122205Sharti MK_IE_EPREF(ind->epref, epref, mine); 93122205Sharti ind->epref.h.act = UNI_IEACT_DEFAULT; 94122205Sharti 95122205Sharti p->call = c; 96122205Sharti p->epref = epref; 97122205Sharti p->flags = mine; 98122205Sharti p->state = UNI_EPSTATE_NULL;; 99122205Sharti 100122205Sharti TIMER_INIT_PARTY(p, t397); 101122205Sharti TIMER_INIT_PARTY(p, t398); 102122205Sharti TIMER_INIT_PARTY(p, t399); 103122205Sharti 104122205Sharti TAILQ_INSERT_HEAD(&c->parties, p, link); 105122205Sharti 106122205Sharti c->uni->funcs->uni_output(c->uni, c->uni->arg, 107122205Sharti UNIAPI_PARTY_CREATED, cookie, api); 108122205Sharti 109122205Sharti VERBOSE(c->uni, UNI_FAC_CALL, 1, "created party %u/%s %u/%s", 110122205Sharti p->call->cref, p->call->mine ? "mine" : "his", 111122205Sharti p->epref, (p->flags & PARTY_MINE) ? "mine" : "his"); 112122205Sharti 113122205Sharti return (p); 114122205Sharti 115122205Sharti} 116122205Sharti 117122205Shartistruct party * 118122205Shartiuni_create_party(struct call *c, struct uni_ie_epref *epref) 119122205Sharti{ 120122205Sharti return (uni_create_partyx(c, epref->epref, epref->flag, 0)); 121122205Sharti} 122122205Sharti 123122205Shartistruct party * 124122205Shartiuni_find_party(struct call *c, struct uni_ie_epref *epref) 125122205Sharti{ 126122205Sharti struct party *p; 127122205Sharti 128122205Sharti TAILQ_FOREACH(p, &c->parties, link) 129122205Sharti if (p->epref == epref->epref && 130122205Sharti (!(p->flags & PARTY_MINE) == !epref->flag)) 131122205Sharti return (p); 132122205Sharti return (NULL); 133122205Sharti} 134122205Shartistruct party * 135122205Shartiuni_find_partyx(struct call *c, u_int epref, u_int mine) 136122205Sharti{ 137122205Sharti struct party *p; 138122205Sharti 139122205Sharti TAILQ_FOREACH(p, &c->parties, link) 140122205Sharti if (p->epref == epref && (!(p->flags & PARTY_MINE) == !mine)) 141122205Sharti return (p); 142122205Sharti return (NULL); 143122205Sharti} 144122205Sharti 145122205Sharti/* 146122205Sharti * Destroy a party. 147122205Sharti * This function is assumed to remove the party from the parent's call 148122205Sharti * party list. 149122205Sharti */ 150122205Shartivoid 151122205Shartiuni_destroy_party(struct party *p, int really) 152122205Sharti{ 153122205Sharti struct uni_msg *api; 154122205Sharti struct uniapi_party_destroyed *ind; 155122205Sharti 156122205Sharti TIMER_DESTROY_PARTY(p, t397); 157122205Sharti TIMER_DESTROY_PARTY(p, t398); 158122205Sharti TIMER_DESTROY_PARTY(p, t399); 159122205Sharti 160122205Sharti TAILQ_REMOVE(&p->call->parties, p, link); 161122205Sharti 162122205Sharti uni_delsig(p->call->uni, SIG_PARTY, p->call, p); 163122205Sharti 164122205Sharti if (!really) { 165122205Sharti ind = ALLOC_API(struct uniapi_party_destroyed, api); 166122205Sharti if (ind != NULL) { 167122205Sharti ind->cref.cref = p->call->cref; 168122205Sharti ind->cref.flag = p->call->mine; 169122205Sharti ind->epref.epref = p->epref; 170122205Sharti ind->epref.flag = p->flags & PARTY_MINE; 171122205Sharti ind->epref.h.act = UNI_IEACT_DEFAULT; 172122205Sharti IE_SETPRESENT(ind->epref); 173122205Sharti 174122205Sharti uni_enq_call(p->call, SIGC_PARTY_DESTROYED, 0, api, NULL); 175122205Sharti } 176122205Sharti 177122205Sharti uni_enq_party(p, SIGP_PARTY_DELETE, 0, NULL, NULL); 178122205Sharti return; 179122205Sharti } 180122205Sharti PARTY_FREE(p); 181122205Sharti} 182122205Sharti 183122205Sharti/* 184122205Sharti * Count number of parties in active states. 185122205Sharti * If the argument is 0 only ACTIVE parties are counter 186122205Sharti * If the argument is 1 only parties in establishing states are counted 187122205Sharti * If the argument is 2 both are counted. 188122205Sharti */ 189122205Shartiu_int 190122205Shartiuni_party_act_count(struct call *c, int kind) 191122205Sharti{ 192122205Sharti struct party *p; 193122205Sharti u_int cnt; 194122205Sharti 195122205Sharti cnt = 0; 196122205Sharti TAILQ_FOREACH(p, &c->parties, link) { 197122205Sharti switch (p->state) { 198122205Sharti 199122205Sharti case UNI_EPSTATE_ACTIVE: 200122205Sharti if (kind == 0 || kind == 2) 201122205Sharti cnt++; 202122205Sharti break; 203122205Sharti 204122205Sharti case UNI_EPSTATE_ALERT_RCVD: 205122205Sharti case UNI_EPSTATE_ADD_INIT: 206122205Sharti case UNI_EPSTATE_ALERT_DLVD: 207122205Sharti case UNI_EPSTATE_ADD_RCVD: 208122205Sharti if (kind == 1 || kind == 2) 209122205Sharti cnt++; 210122205Sharti break; 211122205Sharti 212122205Sharti default: 213122205Sharti break; 214122205Sharti } 215122205Sharti } 216122205Sharti return (cnt); 217122205Sharti} 218122205Sharti 219122205Shartistatic void 220122205Shartistop_all_party_timers(struct party *p) 221122205Sharti{ 222122205Sharti TIMER_STOP_PARTY(p, t397); 223122205Sharti TIMER_STOP_PARTY(p, t398); 224122205Sharti TIMER_STOP_PARTY(p, t399); 225122205Sharti} 226122205Sharti/************************************************************/ 227122205Sharti 228122205Sharti/* 229122205Sharti * Add-party.request 230122205Sharti * 231122205Sharti * Q.2971:Party-control-U 3 (PU0) 232122205Sharti * Q.2971:Party-control-N 3 (PN0) 233122205Sharti */ 234122205Shartistatic void 235131826Shartipun0_add_party_request(struct party *p, struct uni_msg *api, uint32_t cookie) 236122205Sharti{ 237122205Sharti struct uni_all *add; 238122205Sharti struct uniapi_add_party_request *req = 239122205Sharti uni_msg_rptr(api, struct uniapi_add_party_request *); 240122205Sharti 241122205Sharti if ((add = UNI_ALLOC()) == NULL) { 242122205Sharti uni_msg_destroy(api); 243122205Sharti uniapi_party_error(p, UNIAPI_ERROR_NOMEM, cookie); 244122205Sharti return; 245122205Sharti } 246122205Sharti 247122205Sharti add->u.add_party = req->add; 248122205Sharti MK_MSG_ORIG(add, UNI_ADD_PARTY, p->call->cref, !p->call->mine); 249122205Sharti uni_send_output(add, p->call->uni); 250122205Sharti UNI_FREE(add); 251122205Sharti 252122205Sharti TIMER_START_PARTY(p, t399, p->call->uni->timer399); 253122205Sharti 254122205Sharti set_party_state(p, UNI_EPSTATE_ADD_INIT); 255122205Sharti 256122205Sharti uni_msg_destroy(api); 257122205Sharti uniapi_party_error(p, UNIAPI_OK, cookie); 258122205Sharti} 259122205Sharti 260122205Sharti/* 261122205Sharti * Add-party-ack.request 262122205Sharti * 263122205Sharti * Q.2971:Party-Control-U 6 PU2 264122205Sharti * Q.2971:Party-Control-U 7 PU3 265122205Sharti * Q.2971:Party-Control-N 6 PN2 266122205Sharti * Q.2971:Party-Control-N 7 PN3 267122205Sharti */ 268122205Shartistatic void 269131826Shartipunx_add_party_ack_request(struct party *p, struct uni_msg *m, uint32_t cookie) 270122205Sharti{ 271122205Sharti struct uni_all *ack; 272122205Sharti struct uniapi_add_party_ack_request *req = 273122205Sharti uni_msg_rptr(m, struct uniapi_add_party_ack_request *); 274122205Sharti 275122205Sharti if ((ack = UNI_ALLOC()) == NULL) { 276122205Sharti uniapi_party_error(p, UNIAPI_ERROR_NOMEM, cookie); 277122205Sharti uni_msg_destroy(m); 278122205Sharti return; 279122205Sharti } 280122205Sharti ack->u.add_party_ack = req->ack; 281122205Sharti MK_MSG_ORIG(ack, UNI_ADD_PARTY_ACK, p->call->cref, !p->call->mine); 282122205Sharti uni_send_output(ack, p->call->uni); 283122205Sharti UNI_FREE(ack); 284122205Sharti 285122205Sharti set_party_state(p, UNI_EPSTATE_ACTIVE); 286122205Sharti 287122205Sharti uni_msg_destroy(m); 288122205Sharti uniapi_party_error(p, UNIAPI_OK, cookie); 289122205Sharti} 290122205Sharti 291122205Sharti/* 292122205Sharti * Add-party-rej.request 293122205Sharti * 294122205Sharti * Q.2971:Party-Control-U 6 PU2 295122205Sharti * Q.2971:Party-Control-N 6 PN2 296122205Sharti */ 297122205Shartistatic void 298131826Shartipun2_add_party_rej_request(struct party *p, struct uni_msg *m, uint32_t cookie) 299122205Sharti{ 300122205Sharti struct uni_all *rej; 301122205Sharti struct uniapi_add_party_rej_request *req = 302122205Sharti uni_msg_rptr(m, struct uniapi_add_party_rej_request *); 303122205Sharti 304122205Sharti if ((rej = UNI_ALLOC()) == NULL) { 305122205Sharti uniapi_party_error(p, UNIAPI_ERROR_NOMEM, cookie); 306122205Sharti uni_msg_destroy(m); 307122205Sharti return; 308122205Sharti } 309122205Sharti 310122205Sharti stop_all_party_timers(p); 311122205Sharti 312122205Sharti rej->u.add_party_rej = req->rej; 313122205Sharti MK_MSG_ORIG(rej, UNI_ADD_PARTY_REJ, p->call->cref, !p->call->mine); 314122205Sharti uni_enq_call(p->call, SIGC_SEND_ADD_PARTY_REJ, cookie, NULL, rej); 315122205Sharti 316122205Sharti uni_msg_destroy(m); 317122205Sharti p->state = UNI_EPSTATE_NULL; 318122205Sharti uniapi_party_error(p, UNIAPI_OK, cookie); 319122205Sharti 320122205Sharti uni_destroy_party(p, 0); 321122205Sharti} 322122205Sharti 323122205Sharti/* 324122205Sharti * ADD PARTY in PU0, PN0 325122205Sharti * 326122205Sharti * Q.2971:Party-Control-U 3/14 PU0 327122205Sharti */ 328122205Shartistatic void 329122205Shartipun0_add_party(struct party *p, struct uni_msg *m, struct uni_all *u) 330122205Sharti{ 331122205Sharti struct uniapi_add_party_indication *ind; 332122205Sharti struct uni_msg *api; 333122205Sharti 334122205Sharti ind = ALLOC_API(struct uniapi_add_party_indication, api); 335122205Sharti if (ind != NULL) { 336122205Sharti ind->add.hdr = u->u.hdr; 337122205Sharti copy_msg_add_party(&u->u.add_party, &ind->add); 338122205Sharti p->call->uni->funcs->uni_output(p->call->uni, p->call->uni->arg, 339122205Sharti UNIAPI_ADD_PARTY_indication, 0, api); 340122205Sharti } 341122205Sharti set_party_state(p, UNI_EPSTATE_ADD_RCVD); 342122205Sharti 343122205Sharti uni_msg_destroy(m); 344122205Sharti UNI_FREE(u); 345122205Sharti} 346122205Sharti 347122205Sharti/* 348122205Sharti * PARTY-ALERTING.request 349122205Sharti * 350122205Sharti * Q.2971:Party-Control-U 6 (PU2) 351122205Sharti * Q.2971:Party-Control-N 6 (PN2) 352122205Sharti */ 353122205Shartistatic void 354122205Shartipun2_party_alerting_request(struct party *p, struct uni_msg *api, 355131826Sharti uint32_t cookie) 356122205Sharti{ 357122205Sharti struct uni_all *alert; 358122205Sharti struct uniapi_party_alerting_request *req = 359122205Sharti uni_msg_rptr(api, struct uniapi_party_alerting_request *); 360122205Sharti 361122205Sharti if ((alert = UNI_ALLOC()) == NULL) { 362122205Sharti uniapi_party_error(p, UNIAPI_ERROR_NOMEM, cookie); 363122205Sharti uni_msg_destroy(api); 364122205Sharti return; 365122205Sharti } 366122205Sharti alert->u.party_alerting = req->alert; 367122205Sharti MK_MSG_ORIG(alert, UNI_PARTY_ALERTING, 368122205Sharti p->call->cref, !p->call->mine); 369122205Sharti uni_send_output(alert, p->call->uni); 370122205Sharti UNI_FREE(alert); 371122205Sharti 372122205Sharti set_party_state(p, UNI_EPSTATE_ALERT_DLVD); 373122205Sharti 374122205Sharti uni_msg_destroy(api); 375122205Sharti uniapi_party_error(p, UNIAPI_OK, cookie); 376122205Sharti} 377122205Sharti 378122205Sharti/* 379122205Sharti * PARTY-ALERTING in state PU1/PN1 380122205Sharti * 381122205Sharti * Q.2971:Party-Control-U 14 382122205Sharti * Q.2971:Party-Control-N 5 383122205Sharti */ 384122205Shartistatic void 385122205Shartipun1_party_alerting(struct party *p, struct uni_msg *m, struct uni_all *u) 386122205Sharti{ 387122205Sharti struct uniapi_party_alerting_indication *ind; 388122205Sharti struct uni_msg *api; 389122205Sharti 390122205Sharti ind = ALLOC_API(struct uniapi_party_alerting_indication, api); 391122205Sharti if (ind == NULL) { 392122205Sharti uni_msg_destroy(m); 393122205Sharti UNI_FREE(u); 394122205Sharti return; 395122205Sharti } 396122205Sharti TIMER_STOP_PARTY(p, t399); 397122205Sharti 398122205Sharti ind->alert.hdr = u->u.hdr; 399122205Sharti copy_msg_party_alerting(&u->u.party_alerting, &ind->alert); 400122205Sharti 401122205Sharti p->call->uni->funcs->uni_output(p->call->uni, p->call->uni->arg, 402122205Sharti UNIAPI_PARTY_ALERTING_indication, 0, api); 403122205Sharti 404122205Sharti TIMER_START_PARTY(p, t397, p->call->uni->timer397); 405122205Sharti 406122205Sharti uni_msg_destroy(m); 407122205Sharti UNI_FREE(u); 408122205Sharti 409122205Sharti set_party_state(p, UNI_EPSTATE_ALERT_RCVD); 410122205Sharti} 411122205Sharti 412122205Sharti/* 413122205Sharti * ADD-PARTY-ACK 414122205Sharti * 415122205Sharti * Q.2971:Party-Control-U 4 (PU1) 416122205Sharti * Q.2971:Party-Control-U 7 (PU4) 417122205Sharti * Q.2971:Party-Control-N 4 (PN1) 418122205Sharti * Q.2971:Party-Control-N 7 (PN4) 419122205Sharti */ 420122205Shartistatic void 421122205Shartipun1pun4_add_party_ack(struct party *p, struct uni_msg *m, struct uni_all *u) 422122205Sharti{ 423122205Sharti struct uniapi_add_party_ack_indication *ind; 424122205Sharti struct uni_msg *api; 425122205Sharti 426122205Sharti ind = ALLOC_API(struct uniapi_add_party_ack_indication, api); 427122205Sharti if (ind == NULL) { 428122205Sharti uni_msg_destroy(m); 429122205Sharti UNI_FREE(u); 430122205Sharti return; 431122205Sharti } 432122205Sharti 433122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT) 434122205Sharti TIMER_STOP_PARTY(p, t399); 435122205Sharti else 436122205Sharti TIMER_STOP_PARTY(p, t397); 437122205Sharti 438122205Sharti ind->ack.hdr = u->u.hdr; 439122205Sharti copy_msg_add_party_ack(&u->u.add_party_ack, &ind->ack); 440122205Sharti 441122205Sharti p->call->uni->funcs->uni_output(p->call->uni, p->call->uni->arg, 442122205Sharti UNIAPI_ADD_PARTY_ACK_indication, 0, api); 443122205Sharti 444122205Sharti uni_msg_destroy(m); 445122205Sharti UNI_FREE(u); 446122205Sharti 447122205Sharti set_party_state(p, UNI_EPSTATE_ACTIVE); 448122205Sharti} 449122205Sharti 450122205Sharti/* 451122205Sharti * ADD-PARTY-REJECT 452122205Sharti * 453122205Sharti * Q.2971:Party-Control-U 4 (PU1) 454122205Sharti * Q.2971:Party-Control-N 4 (PN1) 455122205Sharti */ 456122205Shartistatic void 457122205Shartipun1_add_party_rej(struct party *p, struct uni_msg *m, struct uni_all *u) 458122205Sharti{ 459122205Sharti struct uniapi_add_party_rej_indication *ind; 460122205Sharti struct uni_msg *api; 461122205Sharti 462122205Sharti ind = ALLOC_API(struct uniapi_add_party_rej_indication, api); 463122205Sharti if (ind == NULL) { 464122205Sharti uni_msg_destroy(m); 465122205Sharti UNI_FREE(u); 466122205Sharti return; 467122205Sharti } 468122205Sharti 469122205Sharti TIMER_STOP_PARTY(p, t399); 470122205Sharti 471122205Sharti ind->rej.hdr = u->u.hdr; 472122205Sharti copy_msg_add_party_rej(&u->u.add_party_rej, &ind->rej); 473122205Sharti uni_enq_call(p->call, SIGC_ADD_PARTY_REJ_indication, 0, api, NULL); 474122205Sharti 475122205Sharti uni_destroy_party(p, 0); 476122205Sharti 477122205Sharti uni_msg_destroy(m); 478122205Sharti UNI_FREE(u); 479122205Sharti} 480122205Sharti 481122205Sharti/* 482122205Sharti * ADD-PARTY-REJECT 483122205Sharti * 484122205Sharti * Q.2971:Party-Control-U 10 (PU5) 485122205Sharti * Q.2971:Party-Control-N 10 (PN5) 486122205Sharti */ 487122205Shartistatic void 488122205Shartipun5_add_party_rej(struct party *p, struct uni_msg *m, struct uni_all *u) 489122205Sharti{ 490122205Sharti struct uniapi_drop_party_ack_indication *ind; 491122205Sharti struct uni_msg *api; 492122205Sharti 493122205Sharti ind = ALLOC_API(struct uniapi_drop_party_ack_indication, api); 494122205Sharti if (ind == NULL) { 495122205Sharti uni_msg_destroy(m); 496122205Sharti UNI_FREE(u); 497122205Sharti return; 498122205Sharti } 499122205Sharti 500122205Sharti ind->drop.hdr = u->u.hdr; 501122205Sharti COPY_FROM_ADD_REJ(u, &ind->drop); 502122205Sharti if (IE_ISGOOD(u->u.add_party_rej.crankback)) 503122205Sharti ind->crankback = u->u.add_party_rej.crankback; 504122205Sharti uni_enq_call(p->call, SIGC_DROP_PARTY_ACK_indication, 0, api, NULL); 505122205Sharti 506122205Sharti TIMER_STOP_PARTY(p, t398); 507122205Sharti 508122205Sharti uni_destroy_party(p, 0); 509122205Sharti 510122205Sharti uni_msg_destroy(m); 511122205Sharti UNI_FREE(u); 512122205Sharti} 513122205Sharti 514122205Sharti/* 515122205Sharti * DROP-PARTY-ACKNOWLEDGE 516122205Sharti * 517122205Sharti * Q.2971:Party-Control-U 8 518122205Sharti * Q.2971:Party-Control-N 8 519122205Sharti * 520122205Sharti * Message already verified in Call-Control! 521122205Sharti */ 522122205Shartistatic void 523122205Shartipunx_drop_party_ack(struct party *p, struct uni_msg *m, struct uni_all *u) 524122205Sharti{ 525122205Sharti struct uniapi_drop_party_ack_indication *ind; 526122205Sharti struct uni_msg *api; 527122205Sharti 528122205Sharti stop_all_party_timers(p); 529122205Sharti 530122205Sharti ind = ALLOC_API(struct uniapi_drop_party_ack_indication, api); 531122205Sharti if (ind != NULL) { 532122205Sharti ind->drop.hdr = u->u.hdr; 533122205Sharti COPY_FROM_DROP_ACK(u, &ind->drop); 534122205Sharti uni_enq_call(p->call, SIGC_DROP_PARTY_ACK_indication, 535122205Sharti 0, api, NULL); 536122205Sharti } 537122205Sharti 538122205Sharti uni_destroy_party(p, 0); 539122205Sharti 540122205Sharti uni_msg_destroy(m); 541122205Sharti UNI_FREE(u); 542122205Sharti} 543122205Sharti 544122205Sharti/* 545122205Sharti * DROP PARTY message in any state except PU5/PN5 546122205Sharti * 547122205Sharti * Q.2971:Party-Control-U 9 548122205Sharti * Q.2971:Party-Control-N 9 549122205Sharti */ 550122205Shartistatic void 551122205Shartipunx_drop_party(struct party *p, struct uni_msg *m, struct uni_all *u) 552122205Sharti{ 553122205Sharti struct uniapi_drop_party_indication *ind; 554122205Sharti struct uni_msg *api; 555122205Sharti 556122205Sharti ind = ALLOC_API(struct uniapi_drop_party_indication, api); 557122205Sharti if (ind == NULL) { 558122205Sharti uni_msg_destroy(m); 559122205Sharti UNI_FREE(u); 560122205Sharti return; 561122205Sharti } 562122205Sharti 563122205Sharti ind->drop.hdr = u->u.hdr; 564122205Sharti copy_msg_drop_party(&u->u.drop_party, &ind->drop); 565122205Sharti 566122205Sharti /* need the cause even if it is bad */ 567122205Sharti if (IE_ISERROR(u->u.drop_party.cause)) 568122205Sharti ind->drop.cause = u->u.drop_party.cause; 569122205Sharti 570122205Sharti ind->my_cause = p->call->uni->cause; 571122205Sharti 572122205Sharti uni_enq_call(p->call, SIGC_DROP_PARTY_indication, 0, api, NULL); 573122205Sharti 574122205Sharti TIMER_STOP_PARTY(p, t397); 575122205Sharti TIMER_STOP_PARTY(p, t399); 576122205Sharti 577122205Sharti uni_msg_destroy(m); 578122205Sharti UNI_FREE(u); 579122205Sharti 580122205Sharti set_party_state(p, UNI_EPSTATE_DROP_RCVD); 581122205Sharti} 582122205Sharti 583122205Sharti/* 584122205Sharti * DROP PARTY message in state PU5/PN5 585122205Sharti * 586122205Sharti * Q.2971:Party-Control-U 10 587122205Sharti * Q.2971:Party-Control-N 10 588122205Sharti */ 589122205Shartistatic void 590122205Shartipun5_drop_party(struct party *p, struct uni_msg *m, struct uni_all *u) 591122205Sharti{ 592122205Sharti struct uniapi_drop_party_ack_indication *ind; 593122205Sharti struct uni_msg *api; 594122205Sharti 595122205Sharti ind = ALLOC_API(struct uniapi_drop_party_ack_indication, api); 596122205Sharti if (ind == NULL) { 597122205Sharti uni_msg_destroy(m); 598122205Sharti UNI_FREE(u); 599122205Sharti return; 600122205Sharti } 601122205Sharti 602122205Sharti ind->drop.hdr = u->u.hdr; 603122205Sharti copy_msg_drop_party(&u->u.drop_party, &ind->drop); 604122205Sharti 605122205Sharti /* need the cause even if it is bad */ 606122205Sharti if (IE_ISERROR(u->u.drop_party.cause)) 607122205Sharti ind->drop.cause = u->u.drop_party.cause; 608122205Sharti 609122205Sharti uni_enq_call(p->call, SIGC_DROP_PARTY_ACK_indication, 0, api, NULL); 610122205Sharti 611122205Sharti TIMER_STOP_PARTY(p, t398); 612122205Sharti 613122205Sharti uni_msg_destroy(m); 614122205Sharti UNI_FREE(u); 615122205Sharti 616122205Sharti set_party_state(p, UNI_EPSTATE_DROP_RCVD); 617122205Sharti 618122205Sharti uni_destroy_party(p, 0); 619122205Sharti} 620122205Sharti 621122205Sharti/************************************************************/ 622122205Sharti 623122205Sharti/* 624122205Sharti * T399 625122205Sharti * 626122205Sharti * Q.2971:Party-Control-U 4 (PU1) 627122205Sharti * Q.2971:Party-Control-N 4 (PN1) 628122205Sharti */ 629122205Shartistatic void 630122205Shartipun1_t399(struct party *p) 631122205Sharti{ 632122205Sharti if (p->call->uni->proto == UNIPROTO_UNI40N) { 633122205Sharti MK_IE_CAUSE(p->call->uni->cause, UNI_CAUSE_LOC_USER, 634122205Sharti UNI_CAUSE_NO_RESPONSE); 635122205Sharti } else { 636122205Sharti MK_IE_CAUSE(p->call->uni->cause, UNI_CAUSE_LOC_USER, 637122205Sharti UNI_CAUSE_RECOVER); 638122205Sharti ADD_CAUSE_TIMER(p->call->uni->cause, "399"); 639122205Sharti } 640122205Sharti 641122205Sharti drop_partyE(p); 642122205Sharti} 643122205Sharti 644122205Sharti/* 645122205Sharti * T398 646122205Sharti * 647122205Sharti * Q.2971:Party-Control-U 10 (PU5) 648122205Sharti * Q.2971:Party-Control-N 10 (PN5) 649122205Sharti */ 650122205Shartistatic void 651122205Shartipun5_t398(struct party *p) 652122205Sharti{ 653122205Sharti struct uniapi_drop_party_ack_indication *ind; 654122205Sharti struct uni_all *drop; 655122205Sharti struct uni_msg *api; 656122205Sharti 657122205Sharti MK_IE_CAUSE(p->call->uni->cause, 658122205Sharti UNI_CAUSE_LOC_USER, UNI_CAUSE_RECOVER); 659122205Sharti ADD_CAUSE_TIMER(p->call->uni->cause, "398"); 660122205Sharti /* 661122205Sharti * Send indication to API 662122205Sharti */ 663122205Sharti ind = ALLOC_API(struct uniapi_drop_party_ack_indication, api); 664122205Sharti if (ind != NULL) { 665122205Sharti ind->drop.hdr.cref.cref = p->call->cref; 666122205Sharti ind->drop.hdr.cref.flag = p->call->mine; 667122205Sharti ind->drop.hdr.act = UNI_MSGACT_DEFAULT; 668122205Sharti MK_IE_EPREF(ind->drop.epref, p->epref, p->flags & PARTY_MINE); 669122205Sharti ind->drop.cause = p->call->uni->cause; 670122205Sharti uni_enq_call(p->call, SIGC_DROP_PARTY_ACK_indication, 671122205Sharti 0, api, NULL); 672122205Sharti } 673122205Sharti 674122205Sharti /* 675122205Sharti * Send DROP PARTY ACK 676122205Sharti */ 677122205Sharti if ((drop = UNI_ALLOC()) != NULL) { 678122205Sharti MK_MSG_ORIG(drop, UNI_DROP_PARTY_ACK, 679122205Sharti p->call->cref, !p->call->mine); 680122205Sharti MK_IE_EPREF(drop->u.drop_party_ack.epref, 681122205Sharti p->epref, !(p->flags & PARTY_MINE)); 682122205Sharti drop->u.drop_party_ack.cause = p->call->uni->cause; 683122205Sharti uni_enq_call(p->call, SIGC_SEND_DROP_PARTY_ACK, 0, NULL, drop); 684122205Sharti } 685122205Sharti 686122205Sharti uni_destroy_party(p, 0); 687122205Sharti} 688122205Sharti 689122205Sharti/* 690122205Sharti * T397 691122205Sharti * 692122205Sharti * Q.2971:Party-Control-U 7 (PU4) 693122205Sharti * Q.2971:Party-Control-N 7 (PN4) 694122205Sharti */ 695122205Shartistatic void 696122205Shartipun4_t397(struct party *p) 697122205Sharti{ 698122205Sharti MK_IE_CAUSE(p->call->uni->cause, UNI_CAUSE_LOC_USER, 699122205Sharti UNI_CAUSE_RECOVER); 700122205Sharti ADD_CAUSE_TIMER(p->call->uni->cause, "397"); 701122205Sharti 702122205Sharti drop_partyE(p); 703122205Sharti} 704122205Sharti 705122205Sharti/************************************************************/ 706122205Sharti 707122205Sharti/* 708122205Sharti * Drop a party because of an error condition. 709122205Sharti * This is label E on page Party-Control-U 8/14. 710122205Sharti * 711122205Sharti * It is assumed, that the caller has constructed the cause in 712122205Sharti * p->call->uni->cause. 713122205Sharti */ 714122205Shartistatic void 715122205Shartidrop_partyE(struct party *p) 716122205Sharti{ 717122205Sharti struct uni_msg *api; 718122205Sharti struct uniapi_drop_party_indication *ind; 719122205Sharti struct uni_all *drop; 720122205Sharti 721122205Sharti /* 722122205Sharti * Send indication to API 723122205Sharti */ 724122205Sharti if ((ind = ALLOC_API(struct uniapi_drop_party_indication, api)) != NULL) { 725122205Sharti ind->drop.hdr.cref.cref = p->call->cref; 726122205Sharti ind->drop.hdr.cref.flag = p->call->mine; 727122205Sharti ind->drop.hdr.act = UNI_MSGACT_DEFAULT; 728122205Sharti MK_IE_EPREF(ind->drop.epref, p->epref, p->flags & PARTY_MINE); 729122205Sharti ind->drop.cause = p->call->uni->cause; 730122205Sharti uni_enq_call(p->call, SIGC_DROP_PARTY_indication, 0, api, NULL); 731122205Sharti } 732122205Sharti TIMER_STOP_PARTY(p, t399); 733122205Sharti TIMER_STOP_PARTY(p, t397); 734122205Sharti TIMER_START_PARTY(p, t398, p->call->uni->timer398); 735122205Sharti 736122205Sharti if ((drop = UNI_ALLOC()) != NULL) { 737122205Sharti drop->u.drop_party.cause = p->call->uni->cause; 738122205Sharti MK_MSG_ORIG(drop, UNI_DROP_PARTY, p->call->cref, !p->call->mine); 739122205Sharti MK_IE_EPREF(drop->u.drop_party.epref, p->epref, 740122205Sharti !(p->flags & PARTY_MINE)); 741122205Sharti uni_enq_call(p->call, SIGC_SEND_DROP_PARTY, 0, NULL, drop); 742122205Sharti } 743122205Sharti 744122205Sharti set_party_state(p, UNI_EPSTATE_DROP_INIT); 745122205Sharti} 746122205Sharti 747122205Sharti/* 748122205Sharti * Drop party request in Px1, Px3, Px4 or Px7 749122205Sharti * 750122205Sharti * Q.2971:Party-Control-U 8 751122205Sharti * Q.2971:Party-Control-N 8 752122205Sharti */ 753122205Shartistatic void 754131826Shartipunx_drop_party_request(struct party *p, struct uni_msg *api, uint32_t cookie) 755122205Sharti{ 756122205Sharti struct uniapi_drop_party_request *req = 757122205Sharti uni_msg_rptr(api, struct uniapi_drop_party_request *); 758122205Sharti struct uni_all *drop; 759122205Sharti 760122205Sharti if ((drop = UNI_ALLOC()) == NULL) { 761122205Sharti uniapi_party_error(p, UNIAPI_ERROR_NOMEM, cookie); 762122205Sharti uni_msg_destroy(api); 763122205Sharti return; 764122205Sharti } 765122205Sharti 766122205Sharti TIMER_STOP_PARTY(p, t399); 767122205Sharti TIMER_STOP_PARTY(p, t397); 768122205Sharti TIMER_START_PARTY(p, t398, p->call->uni->timer398); 769122205Sharti 770122205Sharti drop->u.drop_party = req->drop; 771122205Sharti MK_MSG_ORIG(drop, UNI_DROP_PARTY, p->call->cref, !p->call->mine); 772122205Sharti uni_enq_call(p->call, SIGC_SEND_DROP_PARTY, cookie, NULL, drop); 773122205Sharti 774122205Sharti set_party_state(p, UNI_EPSTATE_DROP_INIT); 775122205Sharti 776122205Sharti uni_msg_destroy(api); 777122205Sharti uniapi_party_error(p, UNIAPI_OK, cookie); 778122205Sharti} 779122205Sharti 780122205Sharti/* 781122205Sharti * Drop-party-ack.request in Px6 782122205Sharti * 783122205Sharti * Q.2971:Party-Control-U 9 784122205Sharti * Q.2971:Party-Control-N 9 785122205Sharti */ 786122205Shartistatic void 787131826Shartipun6_drop_party_ack_request(struct party *p, struct uni_msg *api, uint32_t cookie) 788122205Sharti{ 789122205Sharti struct uniapi_drop_party_ack_request *req = 790122205Sharti uni_msg_rptr(api, struct uniapi_drop_party_ack_request *); 791122205Sharti struct uni_all *ack; 792122205Sharti 793122205Sharti if ((ack = UNI_ALLOC()) == NULL) { 794122205Sharti uni_msg_destroy(api); 795122205Sharti uniapi_party_error(p, UNIAPI_ERROR_NOMEM, cookie); 796122205Sharti return; 797122205Sharti } 798122205Sharti ack->u.drop_party_ack = req->ack; 799122205Sharti MK_MSG_ORIG(ack, UNI_DROP_PARTY_ACK, p->call->cref, !p->call->mine); 800122205Sharti uni_enq_call(p->call, SIGC_SEND_DROP_PARTY_ACK, cookie, NULL, ack); 801122205Sharti 802122205Sharti stop_all_party_timers(p); 803122205Sharti 804122205Sharti uni_msg_destroy(api); 805122205Sharti uniapi_party_error(p, UNIAPI_OK, cookie); 806122205Sharti 807122205Sharti uni_destroy_party(p, 0); 808122205Sharti} 809122205Sharti/************************************************************/ 810122205Sharti/* 811122205Sharti * Party status enquiry request from API or call-control 812122205Sharti * 813122205Sharti * Q.2971:Party-Control-U 12 814122205Sharti * Q.2971:Party-Control-N 12 815122205Sharti */ 816122205Shartistatic void 817131826Shartipunx_status_enquiry_request(struct party *p, uint32_t cookie) 818122205Sharti{ 819122205Sharti struct uni_all *enq; 820122205Sharti 821122205Sharti if((enq = UNI_ALLOC()) == NULL) { 822122205Sharti uniapi_party_error(p, UNIAPI_ERROR_NOMEM, cookie); 823122205Sharti return; 824122205Sharti } 825122205Sharti MK_IE_EPREF(enq->u.status_enq.epref, p->epref, 826122205Sharti !(p->flags & PARTY_MINE)); 827122205Sharti MK_MSG_ORIG(enq, UNI_STATUS_ENQ, p->call->cref, !p->call->mine); 828122205Sharti uni_enq_call(p->call, SIGC_SEND_STATUS_ENQ, cookie, NULL, enq); 829122205Sharti 830122205Sharti uniapi_party_error(p, UNIAPI_OK, cookie); 831122205Sharti} 832122205Sharti 833122205Sharti/* 834122205Sharti * STATUS in any state except PU5/PN5 835122205Sharti * 836122205Sharti * Q.2971:Party-Control-U 12 837122205Sharti * Q.2971:Party-Control-N 12 838122205Sharti */ 839122205Shartistatic void 840122205Shartipunx_status(struct party *p, struct uni_msg *m, struct uni_all *u) 841122205Sharti{ 842122205Sharti struct uniapi_drop_party_ack_indication *ind; 843122205Sharti struct uni_msg *api; 844122205Sharti 845122205Sharti if (u->u.status.epstate.state == UNI_EPSTATE_NULL) { 846122205Sharti /* should not happend */ 847122205Sharti ind = ALLOC_API(struct uniapi_drop_party_ack_indication, api); 848122205Sharti if (ind != NULL) { 849122205Sharti ind->drop.hdr = u->u.hdr; 850122205Sharti ind->drop.cause = u->u.status.cause; 851122205Sharti ind->drop.epref = u->u.status.epref; 852122205Sharti uni_enq_call(p->call, SIGC_DROP_PARTY_ACK_indication, 853122205Sharti 0, api, NULL); 854122205Sharti } 855122205Sharti stop_all_party_timers(p); 856122205Sharti 857122205Sharti uni_destroy_party(p, 0); 858122205Sharti } else { 859122205Sharti if (epstate_compat(p, u->u.status.epstate.state)) { 860122205Sharti if(u->u.status.cause.cause == UNI_CAUSE_MANDAT || 861122205Sharti u->u.status.cause.cause == UNI_CAUSE_MTYPE_NIMPL || 862122205Sharti u->u.status.cause.cause == UNI_CAUSE_IE_NIMPL || 863122205Sharti u->u.status.cause.cause == UNI_CAUSE_IE_INV) { 864122205Sharti MK_IE_CAUSE(p->call->uni->cause, 865122205Sharti UNI_CAUSE_LOC_USER, 866122205Sharti UNI_CAUSE_UNSPEC); 867122205Sharti drop_partyE(p); 868122205Sharti } 869122205Sharti } else { 870122205Sharti MK_IE_CAUSE(p->call->uni->cause, 871122205Sharti UNI_CAUSE_LOC_USER, 872122205Sharti UNI_CAUSE_MSG_INCOMP); 873122205Sharti drop_partyE(p); 874122205Sharti } 875122205Sharti } 876122205Sharti 877122205Sharti uni_msg_destroy(m); 878122205Sharti UNI_FREE(u); 879122205Sharti} 880122205Sharti 881122205Sharti/* 882122205Sharti * STATUS in PU5/PN5 883122205Sharti * 884122205Sharti * Q.2971:Party-Control-U 10 885122205Sharti * Q.2971:Party-Control-N 10 886122205Sharti */ 887122205Shartistatic void 888122205Shartipun5_status(struct party *p, struct uni_msg *m, struct uni_all *u) 889122205Sharti{ 890122205Sharti struct uniapi_drop_party_ack_indication *ind; 891122205Sharti struct uni_msg *api; 892122205Sharti 893122205Sharti if (u->u.status.epstate.state == UNI_EPSTATE_NULL) { 894122205Sharti ind = ALLOC_API(struct uniapi_drop_party_ack_indication, api); 895122205Sharti if (ind != NULL) { 896122205Sharti ind->drop.hdr = u->u.hdr; 897122205Sharti ind->drop.cause = u->u.status.cause; 898122205Sharti ind->drop.epref = u->u.status.epref; 899122205Sharti uni_enq_call(p->call, SIGC_DROP_PARTY_ACK_indication, 900122205Sharti 0, api, NULL); 901122205Sharti } 902122205Sharti TIMER_STOP_PARTY(p, t398); 903122205Sharti 904122205Sharti uni_destroy_party(p, 0); 905122205Sharti } 906122205Sharti 907122205Sharti uni_msg_destroy(m); 908122205Sharti UNI_FREE(u); 909122205Sharti} 910122205Sharti 911122205Sharti/************************************************************/ 912122205Sharti 913122205Shartivoid 914131826Shartiuni_sig_party(struct party *p, enum party_sig sig, uint32_t cookie, 915122205Sharti struct uni_msg *msg, struct uni_all *u) 916122205Sharti{ 917122205Sharti if (sig >= SIGP_END) { 918122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 919122205Sharti "Signal %d outside of range to Party-Control", sig); 920122205Sharti if (msg) 921122205Sharti uni_msg_destroy(msg); 922122205Sharti if (u) 923122205Sharti UNI_FREE(u); 924122205Sharti return; 925122205Sharti } 926122205Sharti VERBOSE(p->call->uni, UNI_FAC_CALL, 1, 927122205Sharti "Signal %s in state %u of party %u/%s (call %u/%s in state %s)" 928122205Sharti "; cookie %u", party_sigs[sig], p->state, p->epref, 929122205Sharti (p->flags & PARTY_MINE) ? "mine" : "his", p->call->cref, 930122205Sharti p->call->mine ? "mine" : "his", callstates[p->call->cstate].name, 931122205Sharti cookie); 932122205Sharti 933122205Sharti switch (sig) { 934122205Sharti 935122205Sharti case SIGP_PARTY_DELETE: 936122205Sharti PARTY_FREE(p); 937122205Sharti break; 938122205Sharti 939122205Sharti /* 940122205Sharti * Messages 941122205Sharti */ 942122205Sharti case SIGP_SETUP: 943122205Sharti if (p->state == UNI_EPSTATE_NULL) { 944122205Sharti /* Q.2971:Call-Control-U 3/13 */ 945122205Sharti /* Q.2971:Call-Control-N 3/13 */ 946122205Sharti set_party_state(p, UNI_EPSTATE_ADD_RCVD); 947122205Sharti break; 948122205Sharti } 949122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 950122205Sharti "SETUP in ps=%u", p->state); 951122205Sharti break; 952122205Sharti 953122205Sharti case SIGP_ALERTING: 954122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT) { 955122205Sharti /* Q.2971:Call-Control-U 14 */ 956122205Sharti /* Q.2971:Call-Control-N 5 */ 957122205Sharti TIMER_START_PARTY(p, t397, p->call->uni->timer397); 958122205Sharti set_party_state(p, UNI_EPSTATE_ALERT_RCVD); 959122205Sharti break; 960122205Sharti } 961122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 962122205Sharti "ALERTING in ps=%u", p->state); 963122205Sharti break; 964122205Sharti 965122205Sharti case SIGP_CONNECT: 966122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT) { 967122205Sharti /* Q.2971:Call-Control-U 4/13 */ 968122205Sharti TIMER_STOP_PARTY(p, t399); 969122205Sharti set_party_state(p, UNI_EPSTATE_ACTIVE); 970122205Sharti break; 971122205Sharti } 972122205Sharti if (p->state == UNI_EPSTATE_ALERT_RCVD) { 973122205Sharti /* Q.2971:Call-Control-U 7/13 */ 974122205Sharti TIMER_STOP_PARTY(p, t397); 975122205Sharti set_party_state(p, UNI_EPSTATE_ACTIVE); 976122205Sharti break; 977122205Sharti } 978122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 979122205Sharti "CONNECT in ps=%u", p->state); 980122205Sharti break; 981122205Sharti 982122205Sharti case SIGP_CONNECT_ACK: 983122205Sharti if (p->state == UNI_EPSTATE_ADD_RCVD || 984122205Sharti p->state == UNI_EPSTATE_ALERT_DLVD) { 985122205Sharti /* Q.2971:Call-Control-U 6/13 */ 986122205Sharti /* Q.2971:Call-Control-U 7/13 */ 987122205Sharti p->flags &= ~PARTY_CONNECT; 988122205Sharti set_party_state(p, UNI_EPSTATE_ACTIVE); 989122205Sharti break; 990122205Sharti } 991122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 992122205Sharti "CONNECT in ps=%u", p->state); 993122205Sharti break; 994122205Sharti 995122205Sharti case SIGP_RELEASE: 996122205Sharti if (p->state == UNI_EPSTATE_DROP_INIT) { 997122205Sharti /* Q.2971:Party-Control-U 10/14 */ 998122205Sharti /* Q.2971:Party-Control-N 10/14 */ 999122205Sharti TIMER_STOP_PARTY(p, t398); 1000122205Sharti uni_destroy_party(p, 0); 1001122205Sharti break; 1002122205Sharti } 1003122205Sharti /* Q.2971:Party-Control-U 11/14 */ 1004122205Sharti /* Q.2971:Party-Control-N 11/14 */ 1005122205Sharti TIMER_STOP_PARTY(p, t397); 1006122205Sharti TIMER_STOP_PARTY(p, t399); 1007122205Sharti uni_destroy_party(p, 0); 1008122205Sharti break; 1009122205Sharti 1010122205Sharti case SIGP_RELEASE_COMPL: 1011122205Sharti /* Q.2971:Party-Control-U 11/14 */ 1012122205Sharti /* Q.2971:Party-Control-N 11/14 */ 1013122205Sharti stop_all_party_timers(p); 1014122205Sharti uni_destroy_party(p, 0); 1015122205Sharti break; 1016122205Sharti 1017122205Sharti case SIGP_RELEASE_confirm: 1018122205Sharti /* not in the SDLs */ 1019122205Sharti stop_all_party_timers(p); 1020122205Sharti uni_destroy_party(p, 0); 1021122205Sharti break; 1022122205Sharti 1023122205Sharti case SIGP_RELEASE_request: 1024122205Sharti if (p->state == UNI_EPSTATE_DROP_INIT) { 1025122205Sharti /* Q.2971:Party-Control-U 10 */ 1026122205Sharti /* Q.2971:Party-Control-N 10 */ 1027122205Sharti uni_destroy_party(p, 0); 1028122205Sharti break; 1029122205Sharti } 1030122205Sharti /* Q.2971:Party-Control-U 11 */ 1031122205Sharti /* Q.2971:Party-Control-N 11 */ 1032122205Sharti TIMER_STOP_PARTY(p, t397); 1033122205Sharti TIMER_STOP_PARTY(p, t399); 1034122205Sharti uni_destroy_party(p, 0); 1035122205Sharti break; 1036122205Sharti 1037122205Sharti case SIGP_RELEASE_response: 1038122205Sharti /* Q.2971:Party-Control-U 11 */ 1039122205Sharti /* Q.2971:Party-Control-N 11 */ 1040122205Sharti stop_all_party_timers(p); 1041122205Sharti uni_destroy_party(p, 0); 1042122205Sharti break; 1043122205Sharti 1044122205Sharti case SIGP_ADD_PARTY: 1045122205Sharti if (p->state == UNI_EPSTATE_NULL) { 1046122205Sharti /* Q.2971:Party-Control-U 3 PU0 */ 1047122205Sharti /* Q.2971:Party-Control-N 3 PN0 */ 1048122205Sharti pun0_add_party(p, msg, u); 1049122205Sharti break; 1050122205Sharti } 1051122205Sharti if (p->state == UNI_EPSTATE_ADD_RCVD) { 1052122205Sharti /* Q.2971:Party-Control-U 6 PU2 */ 1053122205Sharti /* Q.2971:Party-Control-N 6 PN2 */ 1054122205Sharti uni_msg_destroy(msg); 1055122205Sharti UNI_FREE(u); 1056122205Sharti break; 1057122205Sharti } 1058122205Sharti uni_bad_message(p->call, u, UNI_CAUSE_MSG_INCOMP, 1059122205Sharti &u->u.add_party.epref, p->state); 1060122205Sharti uni_msg_destroy(msg); 1061122205Sharti UNI_FREE(u); 1062122205Sharti break; 1063122205Sharti 1064122205Sharti case SIGP_PARTY_ALERTING: 1065122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT) { 1066122205Sharti /* Q.2971:Party-Control-U 14 */ 1067122205Sharti /* Q.2971:Party-Control-N 5 */ 1068122205Sharti pun1_party_alerting(p, msg, u); 1069122205Sharti break; 1070122205Sharti } 1071122205Sharti uni_bad_message(p->call, u, UNI_CAUSE_MSG_INCOMP, 1072122205Sharti &u->u.party_alerting.epref, p->state); 1073122205Sharti uni_msg_destroy(msg); 1074122205Sharti UNI_FREE(u); 1075122205Sharti break; 1076122205Sharti 1077122205Sharti case SIGP_ADD_PARTY_ACK: 1078122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT || 1079122205Sharti p->state == UNI_EPSTATE_ALERT_RCVD) { 1080122205Sharti /* Q.2971:Party-Control-U 4 (PU1) */ 1081122205Sharti /* Q.2971:Party-Control-U 7 (PU4) */ 1082122205Sharti /* Q.2971:Party-Control-N 4 (PN1) */ 1083122205Sharti /* Q.2971:Party-Control-N 7 (PN4) */ 1084122205Sharti pun1pun4_add_party_ack(p, msg, u); 1085122205Sharti break; 1086122205Sharti } 1087122205Sharti uni_bad_message(p->call, u, UNI_CAUSE_MSG_INCOMP, 1088122205Sharti &u->u.add_party_ack.epref, p->state); 1089122205Sharti uni_msg_destroy(msg); 1090122205Sharti UNI_FREE(u); 1091122205Sharti break; 1092122205Sharti 1093122205Sharti case SIGP_ADD_PARTY_REJ: 1094122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT) { 1095122205Sharti /* Q.2971:Party-Control-U 4 (PU1) */ 1096122205Sharti /* Q.2971:Party-Control-N 4 (PN1) */ 1097122205Sharti pun1_add_party_rej(p, msg, u); 1098122205Sharti break; 1099122205Sharti } 1100122205Sharti if (p->state == UNI_EPSTATE_DROP_INIT) { 1101122205Sharti /* Q.2971:Party-Control-U 10 (PU5) */ 1102122205Sharti /* Q.2971:Party-Control-N 10 (PN5) */ 1103122205Sharti pun5_add_party_rej(p, msg, u); 1104122205Sharti break; 1105122205Sharti } 1106122205Sharti uni_bad_message(p->call, u, UNI_CAUSE_MSG_INCOMP, 1107122205Sharti &u->u.add_party_rej.epref, p->state); 1108122205Sharti uni_msg_destroy(msg); 1109122205Sharti UNI_FREE(u); 1110122205Sharti break; 1111122205Sharti 1112122205Sharti case SIGP_DROP_PARTY_ACK: 1113122205Sharti /* Q.2971:Party-Control-U 8 */ 1114122205Sharti /* Q.2971:Party-Control-N 8 */ 1115122205Sharti punx_drop_party_ack(p, msg, u); 1116122205Sharti break; 1117122205Sharti 1118122205Sharti case SIGP_DROP_PARTY: 1119122205Sharti if (p->state == UNI_EPSTATE_DROP_INIT) 1120122205Sharti /* Q.2971:Party-Control-U 10 */ 1121122205Sharti /* Q.2971:Party-Control-N 10 */ 1122122205Sharti pun5_drop_party(p, msg, u); 1123122205Sharti else 1124122205Sharti /* Q.2971:Party-Control-U 9 */ 1125122205Sharti /* Q.2971:Party-Control-N 9 */ 1126122205Sharti punx_drop_party(p, msg, u); 1127122205Sharti break; 1128122205Sharti 1129122205Sharti case SIGP_STATUS: 1130122205Sharti if (p->state == UNI_EPSTATE_DROP_INIT) 1131122205Sharti /* Q.2971:Party-Control-U 10 */ 1132122205Sharti /* Q.2971:Party-Control-N 10 */ 1133122205Sharti pun5_status(p, msg, u); 1134122205Sharti else 1135122205Sharti /* Q.2971:Party-Control-U 12 */ 1136122205Sharti /* Q.2971:Party-Control-N 12 */ 1137122205Sharti punx_status(p, msg, u); 1138122205Sharti break; 1139122205Sharti 1140122205Sharti /* 1141122205Sharti * User 1142122205Sharti */ 1143122205Sharti case SIGP_SETUP_request: 1144122205Sharti if (p->state == UNI_EPSTATE_NULL) { 1145122205Sharti /* Q.2971:Party-Control-U 3 */ 1146122205Sharti /* Q.2971:Party-Control-N 3 */ 1147122205Sharti set_party_state(p, UNI_EPSTATE_ADD_INIT); 1148122205Sharti break; 1149122205Sharti } 1150122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1151122205Sharti "SETUP.request in ps=%u", p->state); 1152122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1153122205Sharti break; 1154122205Sharti 1155122205Sharti case SIGP_SETUP_response: 1156122205Sharti if (p->state == UNI_EPSTATE_ADD_RCVD || 1157122205Sharti p->state == UNI_EPSTATE_ALERT_DLVD) { 1158122205Sharti /* Q.2971:Party-Control-N 6 (PN2) */ 1159122205Sharti /* Q.2971:Party-Control-N 7 (PN3) */ 1160122205Sharti set_party_state(p, UNI_EPSTATE_ACTIVE); 1161122205Sharti break; 1162122205Sharti } 1163122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1164122205Sharti "SETUP.response in ps=%u", p->state); 1165122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1166122205Sharti break; 1167122205Sharti 1168122205Sharti case SIGP_SETUP_COMPL_request: 1169122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT) { 1170122205Sharti /* Q.2971:Party-Control-N 4 */ 1171122205Sharti TIMER_STOP_PARTY(p, t399); 1172122205Sharti set_party_state(p, UNI_EPSTATE_ACTIVE); 1173122205Sharti break; 1174122205Sharti } 1175122205Sharti if (p->state == UNI_EPSTATE_ALERT_RCVD) { 1176122205Sharti /* Q.2971:Party-Control-N 7 */ 1177122205Sharti TIMER_STOP_PARTY(p, t397); 1178122205Sharti set_party_state(p, UNI_EPSTATE_ACTIVE); 1179122205Sharti break; 1180122205Sharti } 1181122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1182122205Sharti "SETUP_COMPL.request in ps=%u", p->state); 1183122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1184122205Sharti break; 1185122205Sharti 1186122205Sharti case SIGP_ADD_PARTY_request: 1187122205Sharti if (p->state == UNI_EPSTATE_NULL) { 1188122205Sharti /* Q.2971:Party-control-U 3 (PU0) */ 1189122205Sharti /* Q.2971:Party-control-N 3 (PN0) */ 1190122205Sharti pun0_add_party_request(p, msg, cookie); 1191122205Sharti break; 1192122205Sharti } 1193122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1194122205Sharti "Add-party.request in ps=%u", p->state); 1195122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1196122205Sharti uni_msg_destroy(msg); 1197122205Sharti break; 1198122205Sharti 1199122205Sharti case SIGP_ALERTING_request: 1200122205Sharti /* Q.2971:Party-Control-U 6 (PU2) */ 1201122205Sharti /* Q.2971:Party-Control-N 6 (PN2) */ 1202122205Sharti set_party_state(p, UNI_EPSTATE_ALERT_DLVD); 1203122205Sharti break; 1204122205Sharti 1205122205Sharti case SIGP_PARTY_ALERTING_request: 1206122205Sharti if (p->state == UNI_EPSTATE_ADD_RCVD) { 1207122205Sharti /* Q.2971:Party-Control-U 6 (PU2) */ 1208122205Sharti /* Q.2971:Party-Control-N 6 (PN2) */ 1209122205Sharti pun2_party_alerting_request(p, msg, cookie); 1210122205Sharti break; 1211122205Sharti } 1212122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1213122205Sharti "Party-alerting.request in ps=%u", p->state); 1214122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1215122205Sharti uni_msg_destroy(msg); 1216122205Sharti break; 1217122205Sharti 1218122205Sharti case SIGP_ADD_PARTY_ACK_request: 1219122205Sharti if (p->state == UNI_EPSTATE_ADD_RCVD || 1220122205Sharti p->state == UNI_EPSTATE_ALERT_DLVD) { 1221122205Sharti /* Q.2971:Party-Control-U 6 PU2 */ 1222122205Sharti /* Q.2971:Party-Control-U 7 PU3 */ 1223122205Sharti /* Q.2971:Party-Control-N 6 PN2 */ 1224122205Sharti /* Q.2971:Party-Control-N 7 PN3 */ 1225122205Sharti punx_add_party_ack_request(p, msg, cookie); 1226122205Sharti break; 1227122205Sharti } 1228122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1229122205Sharti "Add-party-ack.request in ps=%u", p->state); 1230122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1231122205Sharti uni_msg_destroy(msg); 1232122205Sharti break; 1233122205Sharti 1234122205Sharti case SIGP_ADD_PARTY_REJ_request: 1235122205Sharti if (p->state == UNI_EPSTATE_ADD_RCVD) { 1236122205Sharti /* Q.2971:Party-Control-U 6 PU2 */ 1237122205Sharti /* Q.2971:Party-Control-N 6 PN2 */ 1238122205Sharti pun2_add_party_rej_request(p, msg, cookie); 1239122205Sharti break; 1240122205Sharti } 1241122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1242122205Sharti "Add-party-rej.request in ps=%u", p->state); 1243122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1244122205Sharti uni_msg_destroy(msg); 1245122205Sharti break; 1246122205Sharti 1247122205Sharti case SIGP_DROP_PARTY_request: 1248122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT || 1249122205Sharti p->state == UNI_EPSTATE_ALERT_DLVD || 1250122205Sharti p->state == UNI_EPSTATE_ALERT_RCVD || 1251122205Sharti p->state == UNI_EPSTATE_ACTIVE) { 1252122205Sharti /* Q.2971:Party-Control-U 8 */ 1253122205Sharti /* Q.2971:Party-Control-N 8 */ 1254122205Sharti punx_drop_party_request(p, msg, cookie); 1255122205Sharti break; 1256122205Sharti } 1257122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1258122205Sharti "Drop-party.request in ps=%u", p->state); 1259122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1260122205Sharti uni_msg_destroy(msg); 1261122205Sharti break; 1262122205Sharti 1263122205Sharti case SIGP_DROP_PARTY_ACK_request: 1264122205Sharti if (p->state == UNI_EPSTATE_DROP_RCVD) { 1265122205Sharti /* Q.2971:Party-Control-U 9 */ 1266122205Sharti /* Q.2971:Party-Control-N 9 */ 1267122205Sharti pun6_drop_party_ack_request(p, msg, cookie); 1268122205Sharti break; 1269122205Sharti } 1270122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1271122205Sharti "Drop-party-ack.request in ps=%u", p->state); 1272122205Sharti uniapi_party_error(p, UNIAPI_ERROR_BAD_EPSTATE, cookie); 1273122205Sharti uni_msg_destroy(msg); 1274122205Sharti break; 1275122205Sharti 1276122205Sharti case SIGP_STATUS_ENQUIRY_request: 1277122205Sharti /* Q.2971:Party-Control-U 12 */ 1278122205Sharti /* Q.2971:Party-Control-N 12 */ 1279122205Sharti punx_status_enquiry_request(p, cookie); 1280122205Sharti break; 1281122205Sharti 1282122205Sharti /* 1283122205Sharti * Timers 1284122205Sharti */ 1285122205Sharti case SIGP_T397: 1286122205Sharti if (p->state == UNI_EPSTATE_ALERT_RCVD) { 1287122205Sharti /* Q.2971:Party-Control-U 7 (PU4) */ 1288122205Sharti /* Q.2971:Party-Control-N 7 (PN4) */ 1289122205Sharti pun4_t397(p); 1290122205Sharti break; 1291122205Sharti } 1292122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1293122205Sharti "T397 in ps=%u", p->state); 1294122205Sharti break; 1295122205Sharti 1296122205Sharti case SIGP_T398: 1297122205Sharti if (p->state == UNI_EPSTATE_DROP_INIT) { 1298122205Sharti /* Q.2971:Party-Control-U 10 (PU5) */ 1299122205Sharti /* Q.2971:Party-Control-N 10 (PN5) */ 1300122205Sharti pun5_t398(p); 1301122205Sharti break; 1302122205Sharti } 1303122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1304122205Sharti "T398 in ps=%u", p->state); 1305122205Sharti break; 1306122205Sharti 1307122205Sharti case SIGP_T399: 1308122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT) { 1309122205Sharti /* Q.2971:Party-Control-U 4 (PU1) */ 1310122205Sharti /* Q.2971:Party-Control-N 4 (PN1) */ 1311122205Sharti pun1_t399(p); 1312122205Sharti break; 1313122205Sharti } 1314122205Sharti VERBOSE(p->call->uni, UNI_FAC_ERR, 1, 1315122205Sharti "T399 in ps=%u", p->state); 1316122205Sharti break; 1317122205Sharti 1318122205Sharti case SIGP_END: 1319122205Sharti break; 1320122205Sharti } 1321122205Sharti} 1322122205Sharti 1323122205Shartistatic void 1324122205Shartit397_func(struct party *p) 1325122205Sharti{ 1326122205Sharti uni_enq_party(p, SIGP_T397, 0, NULL, NULL); 1327122205Sharti} 1328122205Shartistatic void 1329122205Shartit398_func(struct party *p) 1330122205Sharti{ 1331122205Sharti uni_enq_party(p, SIGP_T398, 0, NULL, NULL); 1332122205Sharti} 1333122205Shartistatic void 1334122205Shartit399_func(struct party *p) 1335122205Sharti{ 1336122205Sharti uni_enq_party(p, SIGP_T399, 0, NULL, NULL); 1337122205Sharti} 1338122205Sharti 1339122205Shartistatic int 1340122205Shartiepstate_compat(struct party *p, enum uni_epstate state) 1341122205Sharti{ 1342122205Sharti if (p->state == UNI_EPSTATE_ADD_INIT || 1343122205Sharti p->state == UNI_EPSTATE_ALERT_RCVD) 1344122205Sharti if (state == UNI_EPSTATE_ADD_INIT || 1345122205Sharti state == UNI_EPSTATE_ALERT_RCVD) 1346122205Sharti return (0); 1347122205Sharti if (p->state == UNI_EPSTATE_ADD_RCVD || 1348122205Sharti p->state == UNI_EPSTATE_ALERT_DLVD) 1349122205Sharti if (state == UNI_EPSTATE_ADD_RCVD || 1350122205Sharti state == UNI_EPSTATE_ALERT_DLVD) 1351122205Sharti return (0); 1352122205Sharti return (1); 1353122205Sharti} 1354