2 * Copyright (c) 2003-2004
6 * Copyright (c) 2001-2002
7 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
10 * Author: Harti Brandt <harti@freebsd.org>
12 * Redistribution of this software and documentation and use in source and
13 * binary forms, with or without modification, are permitted provided that
14 * the following conditions are met:
16 * 1. Redistributions of source code or documentation must retain the above
17 * copyright notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
22 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE AUTHOR
23 * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
25 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
26 * THE AUTHOR OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
29 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * $Begemot: libunimsg/netnatm/api/cc_user.c,v 1.3 2004/07/16 18:46:55 brandt Exp $
36 * ATM API as defined per af-saa-0108
38 * User side (upper half)
41 #include <netnatm/unimsg.h>
42 #include <netnatm/msg/unistruct.h>
43 #include <netnatm/msg/unimsglib.h>
44 #include <netnatm/api/unisap.h>
45 #include <netnatm/sig/unidef.h>
46 #include <netnatm/api/atmapi.h>
47 #include <netnatm/api/ccatm.h>
48 #include <netnatm/api/ccpriv.h>
51 * This file handles messages to a USER.
53 static const char *stab[] = {
54 #define DEF(N) [N] = #N,
60 cc_user_state2str(u_int s)
62 if (s >= sizeof(stab) / sizeof(stab[0]) || stab[s] == NULL)
68 set_state(struct ccuser *user, enum user_state ns)
70 if (user->state != ns) {
71 if (user->cc->log & CCLOG_USER_STATE)
72 cc_user_log(user, "%s -> %s",
73 stab[user->state], stab[ns]);
79 cc_user_send(struct ccuser *user, u_int op, void *arg, size_t len)
81 user->cc->funcs->send_user(user, user->uarg, op, arg, len);
85 cc_user_ok(struct ccuser *user, u_int data, void *arg, size_t len)
87 user->cc->funcs->respond_user(user, user->uarg,
88 ATMERR_OK, data, arg, len);
92 cc_user_err(struct ccuser *user, int err)
94 user->cc->funcs->respond_user(user, user->uarg,
95 err, ATMRESP_NONE, NULL, 0);
99 /**********************************************************************
101 * INSTANCE MANAGEMENT
104 * New endpoint created
107 cc_user_create(struct ccdata *cc, void *uarg, const char *name)
111 user = CCZALLOC(sizeof(*user));
116 user->state = USER_NULL;
118 strncpy(user->name, name, sizeof(user->name));
119 user->name[sizeof(user->name) - 1] = '\0';
120 TAILQ_INIT(&user->connq);
121 LIST_INSERT_HEAD(&cc->user_list, user, node_link);
123 if (user->cc->log & CCLOG_USER_INST)
124 cc_user_log(user, "created with name '%s'", name);
130 * Reset a user instance
133 cc_user_reset(struct ccuser *user)
136 CCASSERT(TAILQ_EMPTY(&user->connq), ("connq not empty"));
138 if (user->sap != NULL) {
143 if (user->accepted != NULL) {
144 user->accepted->acceptor = NULL;
145 user->accepted = NULL;
147 user->config = USER_P2P;
152 set_state(user, USER_NULL);
154 cc_user_sig_flush(user);
158 cc_user_abort(struct ccuser *user, const struct uni_ie_cause *cause)
163 * Although the standard state that 'all connections
164 * associated with this endpoint are aborted' we only
165 * have to abort the head one, because in state A6
166 * (call present) the endpoint is only associated to the
167 * head connection - the others are 'somewhere else' and
168 * need to be redispatched.
170 * First bring user into a state that the connections
171 * are not dispatched back to it.
173 set_state(user, USER_NULL);
174 if (!user->aborted) {
175 if ((conn = TAILQ_FIRST(&user->connq)) != NULL) {
176 memset(conn->cause, 0, sizeof(conn->cause));
178 conn->cause[0] = *cause;
179 cc_conn_reset_acceptor(conn);
180 cc_disconnect_from_user(conn);
181 cc_conn_sig(conn, CONN_SIG_USER_ABORT, NULL);
185 while ((conn = TAILQ_FIRST(&user->connq)) != NULL) {
186 /* these should be in C21 */
187 cc_disconnect_from_user(conn);
188 cc_conn_dispatch(conn);
195 * Application has closed this endpoint. Clean up all user resources and
196 * abort all connections. This can be called in any state.
199 cc_user_destroy(struct ccuser *user)
202 if (user->cc->log & CCLOG_USER_INST)
203 cc_user_log(user, "destroy '%s'", user->name);
205 cc_user_abort(user, NULL);
207 if (user->sap != NULL)
210 cc_user_sig_flush(user);
212 LIST_REMOVE(user, node_link);
216 /**********************************************************************
221 * Return true when the calling address of the connection matches the address.
224 addr_matches(const struct ccaddr *addr, const struct ccconn *conn)
227 if (!IE_ISPRESENT(conn->calling))
230 return (addr->addr.type == conn->calling.addr.type &&
231 addr->addr.plan == conn->calling.addr.plan &&
232 addr->addr.len == conn->calling.addr.len &&
233 memcmp(addr->addr.addr, conn->calling.addr.addr,
234 addr->addr.len) == 0);
238 * Check if the user's SAP (given he is in the right state) and
239 * the given SAP overlap
242 check_overlap(struct ccuser *user, struct uni_sap *sap)
244 return ((user->state == USER_IN_PREPARING ||
245 user->state == USER_IN_WAITING) &&
246 unisve_overlap_sap(user->sap, sap));
250 * Send arrival notification to user
253 do_arrival(struct ccuser *user)
258 if ((conn = TAILQ_FIRST(&user->connq)) != NULL) {
259 set_state(user, USER_IN_ARRIVED);
260 cc_user_send(user, ATMOP_ARRIVAL_OF_INCOMING_CALL, NULL, 0);
261 cc_conn_sig(conn, CONN_SIG_ARRIVAL, NULL);
265 /**********************************************************************
270 * Query an attribute. This is possible only in some states: preparation
271 * of an outgoing call, after an incoming call was offered to the application
272 * and in the three active states (P2P, P2PLeaf, P2PRoot).
274 static struct ccconn *
275 cc_query_check(struct ccuser *user)
278 switch (user->state) {
280 case USER_OUT_PREPARING:
281 case USER_IN_ARRIVED:
283 return (TAILQ_FIRST(&user->connq));
286 /* if we are waiting for the SETUP_confirm, we are in
287 * the NULL state still (we are the new endpoint), but
288 * have a connection in 'accepted' that is in the
289 * CONN_IN_WAIT_ACCEPT_OK state.
291 if (user->accepted != NULL &&
292 user->accepted->state == CONN_IN_WAIT_ACCEPT_OK)
293 return (user->accepted);
305 cc_attr_query(struct ccuser *user, struct ccconn *conn,
306 uint32_t *attr, u_int count)
313 /* determine the length of the total attribute buffer */
314 total = sizeof(uint32_t) + count * sizeof(uint32_t);
315 for (i = 0; i < count; i++) {
317 switch ((enum atm_attribute)attr[i]) {
322 case ATM_ATTR_BLLI_SELECTOR:
323 len = sizeof(uint32_t);
327 len = sizeof(struct uni_ie_blli);
330 case ATM_ATTR_BEARER:
331 len = sizeof(struct uni_ie_bearer);
334 case ATM_ATTR_TRAFFIC:
335 len = sizeof(struct uni_ie_traffic);
339 len = sizeof(struct uni_ie_qos);
343 len = sizeof(struct uni_ie_exqos);
346 case ATM_ATTR_CALLED:
347 len = sizeof(struct uni_ie_called);
350 case ATM_ATTR_CALLEDSUB:
351 len = sizeof(struct uni_ie_calledsub);
354 case ATM_ATTR_CALLING:
355 len = sizeof(struct uni_ie_calling);
358 case ATM_ATTR_CALLINGSUB:
359 len = sizeof(struct uni_ie_callingsub);
363 len = sizeof(struct uni_ie_aal);
367 len = sizeof(struct uni_ie_epref);
370 case ATM_ATTR_CONNED:
371 len = sizeof(struct uni_ie_conned);
374 case ATM_ATTR_CONNEDSUB:
375 len = sizeof(struct uni_ie_connedsub);
379 len = sizeof(struct uni_ie_eetd);
382 case ATM_ATTR_ABRSETUP:
383 len = sizeof(struct uni_ie_abrsetup);
386 case ATM_ATTR_ABRADD:
387 len = sizeof(struct uni_ie_abradd);
390 case ATM_ATTR_CONNID:
391 len = sizeof(struct uni_ie_connid);
395 len = sizeof(struct uni_ie_mdcr);
399 cc_user_err(user, ATMERR_BAD_ATTR);
405 /* allocate buffer */
406 val = CCMALLOC(total);
414 ptr = (u_char *)val + (sizeof(uint32_t) + count * sizeof(uint32_t));
415 for (i = 0; i < count; i++) {
417 atab[i + 1] = attr[i];
423 case ATM_ATTR_BLLI_SELECTOR:
424 len = sizeof(uint32_t);
425 memcpy(ptr, &conn->blli_selector, len);
429 /* in A6 the blli_selector may be 0 when
430 * there was no blli in the SETUP.
432 len = sizeof(struct uni_ie_blli);
433 if (conn->blli_selector == 0)
436 memcpy(ptr, &conn->blli[conn->blli_selector -
440 case ATM_ATTR_BEARER:
441 len = sizeof(struct uni_ie_bearer);
442 memcpy(ptr, &conn->bearer, len);
445 case ATM_ATTR_TRAFFIC:
446 len = sizeof(struct uni_ie_traffic);
447 memcpy(ptr, &conn->traffic, len);
451 len = sizeof(struct uni_ie_qos);
452 memcpy(ptr, &conn->qos, len);
456 len = sizeof(struct uni_ie_exqos);
457 memcpy(ptr, &conn->exqos, len);
460 case ATM_ATTR_CALLED:
461 len = sizeof(struct uni_ie_called);
462 memcpy(ptr, &conn->called, len);
465 case ATM_ATTR_CALLEDSUB:
466 len = sizeof(struct uni_ie_calledsub);
467 memcpy(ptr, &conn->calledsub, len);
470 case ATM_ATTR_CALLING:
471 len = sizeof(struct uni_ie_calling);
472 memcpy(ptr, &conn->calling, len);
475 case ATM_ATTR_CALLINGSUB:
476 len = sizeof(struct uni_ie_callingsub);
477 memcpy(ptr, &conn->callingsub, len);
481 len = sizeof(struct uni_ie_aal);
482 memcpy(ptr, &conn->aal, len);
486 len = sizeof(struct uni_ie_epref);
487 memcpy(ptr, &conn->epref, len);
490 case ATM_ATTR_CONNED:
491 len = sizeof(struct uni_ie_conned);
492 memcpy(ptr, &conn->conned, len);
495 case ATM_ATTR_CONNEDSUB:
496 len = sizeof(struct uni_ie_connedsub);
497 memcpy(ptr, &conn->connedsub, len);
501 len = sizeof(struct uni_ie_eetd);
502 memcpy(ptr, &conn->eetd, len);
505 case ATM_ATTR_ABRSETUP:
506 len = sizeof(struct uni_ie_abrsetup);
507 memcpy(ptr, &conn->abrsetup, len);
510 case ATM_ATTR_ABRADD:
511 len = sizeof(struct uni_ie_abradd);
512 memcpy(ptr, &conn->abradd, len);
515 case ATM_ATTR_CONNID:
516 len = sizeof(struct uni_ie_connid);
517 memcpy(ptr, &conn->connid, len);
521 len = sizeof(struct uni_ie_mdcr);
522 memcpy(ptr, &conn->mdcr, len);
525 ptr = (u_char *)ptr + len;
528 cc_user_ok(user, ATMRESP_ATTRS, val, total);
534 * Check whether the state is ok and return the connection
536 static struct ccconn *
537 cc_set_check(struct ccuser *user)
539 switch(user->state) {
541 case USER_OUT_PREPARING:
542 case USER_IN_ARRIVED:
543 return (TAILQ_FIRST(&user->connq));
551 * Set connection attribute(s)
554 cc_attr_set(struct ccuser *user, struct ccconn *conn, uint32_t *attr,
555 u_int count, u_char *val, size_t vallen)
561 /* determine the length of the total attribute buffer */
564 for (i = 0; i < count; i++) {
566 switch ((enum atm_attribute)attr[i]) {
571 case ATM_ATTR_BLLI_SELECTOR:
575 if (conn->state != CONN_OUT_PREPARING)
577 memcpy(&sel, ptr, sizeof(sel));
578 if (sel == 0 || sel > UNI_NUM_IE_BLLI)
580 len = sizeof(uint32_t);
585 len = sizeof(struct uni_ie_blli);
588 case ATM_ATTR_BEARER:
589 if (conn->state != CONN_OUT_PREPARING)
591 len = sizeof(struct uni_ie_bearer);
594 case ATM_ATTR_TRAFFIC:
595 len = sizeof(struct uni_ie_traffic);
599 if (conn->state != CONN_OUT_PREPARING)
601 len = sizeof(struct uni_ie_qos);
605 len = sizeof(struct uni_ie_exqos);
608 case ATM_ATTR_CALLED:
611 case ATM_ATTR_CALLEDSUB:
612 if (conn->state != CONN_OUT_PREPARING)
614 len = sizeof(struct uni_ie_calledsub);
617 case ATM_ATTR_CALLING:
618 if (conn->state != CONN_OUT_PREPARING)
620 len = sizeof(struct uni_ie_calling);
623 case ATM_ATTR_CALLINGSUB:
624 if (conn->state != CONN_OUT_PREPARING)
626 len = sizeof(struct uni_ie_callingsub);
630 len = sizeof(struct uni_ie_aal);
636 case ATM_ATTR_CONNED:
639 case ATM_ATTR_CONNEDSUB:
643 len = sizeof(struct uni_ie_eetd);
646 case ATM_ATTR_ABRSETUP:
647 len = sizeof(struct uni_ie_abrsetup);
650 case ATM_ATTR_ABRADD:
651 len = sizeof(struct uni_ie_abradd);
654 case ATM_ATTR_CONNID:
655 len = sizeof(struct uni_ie_connid);
659 if (conn->state != CONN_OUT_PREPARING)
661 len = sizeof(struct uni_ie_mdcr);
665 cc_user_err(user, ATMERR_BAD_ATTR);
672 /* check the length */
673 if (vallen != total) {
674 cc_user_err(user, ATMERR_BAD_ARGS);
679 for (i = 0; i < count; i++) {
681 switch ((enum atm_attribute)attr[i]) {
686 case ATM_ATTR_BLLI_SELECTOR:
690 memcpy(&sel, ptr, sizeof(sel));
691 conn->blli_selector = sel;
692 len = sizeof(uint32_t);
697 len = sizeof(struct uni_ie_blli);
698 memcpy(&conn->blli[conn->blli_selector - 1], ptr, len);
699 conn->dirty_attr |= CCDIRTY_BLLI;
702 case ATM_ATTR_BEARER:
703 len = sizeof(struct uni_ie_bearer);
704 memcpy(&conn->bearer, ptr, len);
707 case ATM_ATTR_TRAFFIC:
708 len = sizeof(struct uni_ie_traffic);
709 memcpy(&conn->traffic, ptr, len);
710 conn->dirty_attr |= CCDIRTY_TRAFFIC;
714 len = sizeof(struct uni_ie_qos);
715 memcpy(&conn->qos, ptr, len);
719 len = sizeof(struct uni_ie_exqos);
720 memcpy(&conn->exqos, ptr, len);
721 conn->dirty_attr |= CCDIRTY_EXQOS;
724 case ATM_ATTR_CALLED:
725 len = sizeof(struct uni_ie_called);
728 case ATM_ATTR_CALLEDSUB:
729 len = sizeof(struct uni_ie_calledsub);
730 memcpy(&conn->calledsub, ptr, len);
733 case ATM_ATTR_CALLING:
734 len = sizeof(struct uni_ie_calling);
735 memcpy(&conn->calling, ptr, len);
738 case ATM_ATTR_CALLINGSUB:
739 len = sizeof(struct uni_ie_callingsub);
740 memcpy(&conn->callingsub, ptr, len);
744 len = sizeof(struct uni_ie_aal);
745 memcpy(&conn->aal, ptr, len);
746 conn->dirty_attr |= CCDIRTY_AAL;
750 len = sizeof(struct uni_ie_epref);
753 case ATM_ATTR_CONNED:
754 len = sizeof(struct uni_ie_conned);
757 case ATM_ATTR_CONNEDSUB:
758 len = sizeof(struct uni_ie_connedsub);
762 len = sizeof(struct uni_ie_eetd);
763 memcpy(&conn->eetd, ptr, len);
764 conn->dirty_attr |= CCDIRTY_EETD;
767 case ATM_ATTR_ABRSETUP:
768 len = sizeof(struct uni_ie_abrsetup);
769 memcpy(&conn->abrsetup, ptr, len);
770 conn->dirty_attr |= CCDIRTY_ABRSETUP;
773 case ATM_ATTR_ABRADD:
774 len = sizeof(struct uni_ie_abradd);
775 memcpy(&conn->abradd, ptr, len);
776 conn->dirty_attr |= CCDIRTY_ABRADD;
779 case ATM_ATTR_CONNID:
780 len = sizeof(struct uni_ie_connid);
781 memcpy(&conn->connid, ptr, len);
782 conn->dirty_attr |= CCDIRTY_CONNID;
786 len = sizeof(struct uni_ie_mdcr);
787 memcpy(&conn->mdcr, ptr, len);
793 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
797 cc_user_err(user, ATMERR_BAD_VALUE);
801 cc_user_err(user, ATMERR_RDONLY);
806 static const char *op_names[] = {
807 #define S(OP) [ATMOP_##OP] = #OP
810 S(ACCEPT_INCOMING_CALL),
813 S(ADD_PARTY_SUCCESS),
814 S(ARRIVAL_OF_INCOMING_CALL),
816 S(CONNECT_OUTGOING_CALL),
818 S(GET_LOCAL_PORT_INFO),
821 S(PREPARE_INCOMING_CALL),
822 S(PREPARE_OUTGOING_CALL),
823 S(QUERY_CONNECTION_ATTRIBUTES),
824 S(REJECT_INCOMING_CALL),
825 S(SET_CONNECTION_ATTRIBUTES),
826 S(WAIT_ON_INCOMING_CALL),
827 S(SET_CONNECTION_ATTRIBUTES_X),
828 S(QUERY_CONNECTION_ATTRIBUTES_X),
835 * Signal from user - map this to our internal signals and queue
839 cc_user_signal(struct ccuser *user, enum atmop sig, struct uni_msg *msg)
841 size_t len = uni_msg_len(msg);
844 if (user->cc->log & CCLOG_USER_SIG)
845 cc_user_log(user, "signal %s to user", op_names[sig]);
847 if ((u_int)sig > ATMOP_QUERY_STATE)
852 case ATMOP_ABORT_CONNECTION:
853 if (len != sizeof(struct atm_abort_connection))
855 err = cc_user_sig_msg(user, USER_SIG_ABORT_CONNECTION, msg);
858 case ATMOP_ACCEPT_INCOMING_CALL:
859 if (len != sizeof(struct atm_accept_incoming_call))
861 err = cc_user_sig_msg(user, USER_SIG_ACCEPT_INCOMING, msg);
864 case ATMOP_ADD_PARTY:
865 if (len != sizeof(struct atm_add_party))
867 err = cc_user_sig_msg(user, USER_SIG_ADD_PARTY, msg);
870 case ATMOP_CALL_RELEASE:
871 if (len != sizeof(struct atm_call_release))
873 err = cc_user_sig_msg(user, USER_SIG_CALL_RELEASE, msg);
876 case ATMOP_CONNECT_OUTGOING_CALL:
877 if (len != sizeof(struct atm_connect_outgoing_call))
879 err = cc_user_sig_msg(user, USER_SIG_CONNECT_OUTGOING, msg);
882 case ATMOP_DROP_PARTY:
883 if (len != sizeof(struct atm_drop_party))
885 err = cc_user_sig_msg(user, USER_SIG_DROP_PARTY, msg);
888 case ATMOP_GET_LOCAL_PORT_INFO:
889 if (len != sizeof(struct atm_get_local_port_info))
891 err = cc_user_sig_msg(user, USER_SIG_GET_LOCAL_PORT_INFO, msg);
894 case ATMOP_PREPARE_INCOMING_CALL:
895 if (len != sizeof(struct atm_prepare_incoming_call))
897 err = cc_user_sig_msg(user, USER_SIG_PREPARE_INCOMING, msg);
900 case ATMOP_PREPARE_OUTGOING_CALL:
903 uni_msg_destroy(msg);
904 err = cc_user_sig(user, USER_SIG_PREPARE_OUTGOING, NULL, 0);
907 case ATMOP_QUERY_CONNECTION_ATTRIBUTES:
908 if (len != sizeof(struct atm_query_connection_attributes))
910 err = cc_user_sig_msg(user, USER_SIG_QUERY_ATTR, msg);
913 case ATMOP_REJECT_INCOMING_CALL:
914 if (len != sizeof(struct atm_reject_incoming_call))
916 err = cc_user_sig_msg(user, USER_SIG_REJECT_INCOMING, msg);
919 case ATMOP_SET_CONNECTION_ATTRIBUTES:
920 if (len < sizeof(struct atm_set_connection_attributes))
922 err = cc_user_sig_msg(user, USER_SIG_SET_ATTR, msg);
925 case ATMOP_WAIT_ON_INCOMING_CALL:
928 uni_msg_destroy(msg);
929 err = cc_user_sig(user, USER_SIG_WAIT_ON_INCOMING, NULL, 0);
932 case ATMOP_QUERY_CONNECTION_ATTRIBUTES_X:
933 if (len < sizeof(struct atm_set_connection_attributes_x) ||
934 len != offsetof(struct atm_set_connection_attributes_x,
935 attr) + uni_msg_rptr(msg,
936 struct atm_set_connection_attributes_x *)->count *
939 err = cc_user_sig_msg(user, USER_SIG_QUERY_ATTR_X, msg);
942 case ATMOP_SET_CONNECTION_ATTRIBUTES_X:
943 if (len < sizeof(struct atm_set_connection_attributes_x))
945 err = cc_user_sig_msg(user, USER_SIG_SET_ATTR_X, msg);
948 case ATMOP_QUERY_STATE:
951 uni_msg_destroy(msg);
952 err = cc_user_sig(user, USER_SIG_QUERY_STATE, NULL, 0);
956 case ATMOP_ADD_PARTY_REJECT:
957 case ATMOP_ADD_PARTY_SUCCESS:
958 case ATMOP_ARRIVAL_OF_INCOMING_CALL:
959 case ATMOP_P2MP_CALL_ACTIVE:
960 case ATMOP_P2P_CALL_ACTIVE:
963 if (user->cc->log & CCLOG_USER_SIG)
964 cc_user_log(user, "bad signal %u", sig);
965 cc_user_err(user, ATMERR_BAD_OP);
966 uni_msg_destroy(msg);
972 /* bad argument length */
973 if (user->cc->log & CCLOG_USER_SIG)
974 cc_user_log(user, "signal %s had bad len=%zu",
976 cc_user_err(user, ATMERR_BAD_ARGS);
977 uni_msg_destroy(msg);
982 * Send active signal to user
985 cc_user_active(struct ccuser *user)
987 struct ccconn *conn = TAILQ_FIRST(&user->connq);
989 set_state(user, USER_ACTIVE);
990 if (conn->bearer.cfg == UNI_BEARER_P2P) {
991 struct atm_p2p_call_active *act;
993 user->config = USER_P2P;
994 act = CCZALLOC(sizeof(*act));
997 act->connid = conn->connid;
998 cc_user_send(user, ATMOP_P2P_CALL_ACTIVE, act, sizeof(*act));
1001 struct atm_p2mp_call_active *act;
1003 user->config = USER_ROOT;
1004 act = CCZALLOC(sizeof(*act));
1007 act->connid = conn->connid;
1008 cc_user_send(user, ATMOP_P2MP_CALL_ACTIVE, act, sizeof(*act));
1014 * Handle a signal to this user
1017 cc_user_sig_handle(struct ccuser *user, enum user_sig sig,
1018 void *arg, u_int arg2)
1021 if (user->cc->log & CCLOG_USER_SIG)
1022 cc_user_log(user, "signal %s to user state %s",
1023 cc_user_sigtab[sig], stab[user->state]);
1028 case USER_SIG_PREPARE_OUTGOING:
1031 * Here we create a connection for the call we soon will make.
1032 * We put this call on the list of orphaned connections,
1033 * because we don't know yet, which port will get the
1034 * connection. It is assigned, when the user issues the call
1037 struct ccconn *conn;
1039 if (user->state != USER_NULL) {
1040 cc_user_err(user, ATMERR_BAD_STATE);
1043 conn = cc_conn_create(user->cc);
1045 cc_user_err(user, ATMERR_NOMEM);
1048 set_state(user, USER_OUT_PREPARING);
1049 cc_conn_set_state(conn, CONN_OUT_PREPARING);
1050 conn->blli_selector = 1;
1051 cc_connect_to_user(conn, user);
1053 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1058 case USER_SIG_CONNECT_OUTGOING:
1061 * Request to connect that call
1063 * Here we assign the connection to a port.
1065 struct uni_msg *msg = arg;
1066 struct atm_connect_outgoing_call *req = uni_msg_rptr(msg,
1067 struct atm_connect_outgoing_call *);
1068 struct ccdata *priv = user->cc;
1069 struct ccport *port;
1070 struct ccaddr *addr;
1071 struct ccconn *conn = TAILQ_FIRST(&user->connq);
1073 if (user->state != USER_OUT_PREPARING) {
1074 uni_msg_destroy(msg);
1075 cc_user_err(user, ATMERR_BAD_STATE);
1078 if (!IE_ISPRESENT(req->called)) {
1079 uni_msg_destroy(msg);
1080 cc_user_err(user, ATMERR_BAD_ARGS);
1083 CCASSERT(conn->port == NULL, ("connection still on port"));
1085 if (TAILQ_EMPTY(&priv->port_list)) {
1087 * We have no ports - reject
1089 uni_msg_destroy(msg);
1090 cc_user_err(user, ATMERR_BAD_PORT);
1095 * Find the correct port
1096 * Routing of outgoing calls goes to the lowest numbered port
1097 * with a matching address or, if no address match is found to
1098 * the lowest numbered port.
1100 TAILQ_FOREACH(port, &priv->port_list, node_link)
1101 TAILQ_FOREACH(addr, &port->addr_list, port_link)
1102 if (addr_matches(addr, conn))
1106 port = TAILQ_FIRST(&priv->port_list);
1108 cc_conn_ins_port(conn, port);
1109 conn->called = req->called;
1110 uni_msg_destroy(msg);
1113 * Now move the state
1115 set_state(user, USER_OUT_WAIT_OK);
1116 cc_conn_sig(conn, CONN_SIG_CONNECT_OUTGOING, NULL);
1122 case USER_SIG_CONNECT_OUTGOING_ERR:
1123 switch (user->state) {
1125 case USER_OUT_WAIT_OK:
1126 set_state(user, USER_OUT_PREPARING);
1127 cc_user_err(user, arg2);
1130 case USER_REL_WAIT_CONN:
1132 struct ccconn *conn;
1134 conn = TAILQ_FIRST(&user->connq);
1136 cc_disconnect_from_user(conn);
1137 cc_conn_destroy(conn);
1140 cc_user_reset(user);
1141 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1151 case USER_SIG_CONNECT_OUTGOING_OK:
1152 switch (user->state) {
1154 case USER_OUT_WAIT_OK:
1155 set_state(user, USER_OUT_WAIT_CONF);
1156 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1159 case USER_REL_WAIT_CONN:
1160 set_state(user, USER_REL_WAIT_SCONF);
1169 case USER_SIG_SETUP_CONFIRM:
1171 * SETUP.confirm from UNI stack.
1173 switch (user->state) {
1175 case USER_OUT_WAIT_CONF:
1176 cc_user_active(user);
1179 case USER_REL_WAIT_SCONF:
1180 /* now try to release */
1181 set_state(user, USER_REL_WAIT_CONF);
1182 cc_conn_sig(TAILQ_FIRST(&user->connq),
1183 CONN_SIG_RELEASE, NULL);
1192 case USER_SIG_PREPARE_INCOMING:
1194 struct uni_msg *msg = arg;
1196 struct atm_prepare_incoming_call *prep = uni_msg_rptr(msg,
1197 struct atm_prepare_incoming_call *);
1199 if (user->state != USER_NULL) {
1200 uni_msg_destroy(msg);
1201 cc_user_err(user, ATMERR_BAD_STATE);
1208 if (unisve_check_sap(&prep->sap) != UNISVE_OK) {
1209 uni_msg_destroy(msg);
1210 cc_user_err(user, ATMERR_BAD_SAP);
1215 * Loop through all incoming calls and check whether there
1216 * is an overlap in SAP space.
1218 LIST_FOREACH(ptr, &user->cc->user_list, node_link) {
1219 if (check_overlap(ptr, &prep->sap)) {
1220 uni_msg_destroy(msg);
1221 cc_user_err(user, ATMERR_OVERLAP);
1227 * Save info and set state
1229 user->sap = CCZALLOC(sizeof(struct uni_sap));
1230 if (user->sap == NULL) {
1231 uni_msg_destroy(msg);
1232 cc_user_err(user, ATMERR_NOMEM);
1235 *user->sap = prep->sap;
1236 user->queue_max = prep->queue_size;
1237 user->queue_act = 0;
1238 uni_msg_destroy(msg);
1240 set_state(user, USER_IN_PREPARING);
1241 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1247 case USER_SIG_WAIT_ON_INCOMING:
1248 if (user->state != USER_IN_PREPARING) {
1249 cc_user_err(user, ATMERR_BAD_STATE);
1253 set_state(user, USER_IN_WAITING);
1254 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1258 case USER_SIG_SETUP_IND:
1260 * New connection queued up in the queue. If this is the
1261 * first one, inform the application of the arrival.
1263 switch (user->state) {
1265 case USER_IN_WAITING:
1269 case USER_IN_ARRIVED:
1270 case USER_IN_WAIT_REJ:
1271 case USER_IN_WAIT_ACC:
1280 case USER_SIG_REJECT_INCOMING:
1283 * User rejects call. This is done on the OLD user
1284 * (i.e. the one sending the arrival).
1286 struct uni_msg *msg = arg;
1287 struct atm_reject_incoming_call *rej = uni_msg_rptr(msg,
1288 struct atm_reject_incoming_call *);
1289 struct ccconn *conn = TAILQ_FIRST(&user->connq);
1291 if (user->state != USER_IN_ARRIVED) {
1292 uni_msg_destroy(msg);
1293 cc_user_err(user, ATMERR_BAD_STATE);
1296 if (user->aborted) {
1297 /* connection has disappeared. Send an ok
1298 * to the user and lock whether there is another
1299 * connection at this endpoint */
1300 uni_msg_destroy(msg);
1301 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1303 set_state(user, USER_IN_WAITING);
1307 conn->cause[0] = rej->cause;
1308 memset(&conn->cause[1], 0, sizeof(conn->cause[1]));
1309 uni_msg_destroy(msg);
1311 set_state(user, USER_IN_WAIT_REJ);
1312 cc_conn_sig(conn, CONN_SIG_REJECT, NULL);
1318 case USER_SIG_REJECT_OK:
1319 if (user->state != USER_IN_WAIT_REJ)
1321 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1323 set_state(user, USER_IN_WAITING);
1328 case USER_SIG_REJECT_ERR:
1329 if (user->state != USER_IN_WAIT_REJ)
1331 cc_user_err(user, arg2);
1334 set_state(user, USER_IN_ARRIVED);
1336 set_state(user, USER_IN_WAITING);
1342 case USER_SIG_ACCEPT_INCOMING:
1345 * User accepts call. This is done on the OLD user (i.e. the one
1346 * sending the arrival), the message contains a pointer to the
1349 struct uni_msg *msg = arg;
1350 struct atm_accept_incoming_call *acc =
1351 uni_msg_rptr(msg, struct atm_accept_incoming_call *);
1352 struct ccuser *newep;
1354 if (user->state != USER_IN_ARRIVED) {
1355 uni_msg_destroy(msg);
1356 cc_user_err(user, ATMERR_BAD_STATE);
1359 if (user->aborted) {
1360 /* connection has disappeared. Send an error
1361 * to the user and lock whether there is another
1362 * connection at this endpoint */
1363 uni_msg_destroy(msg);
1364 cc_user_err(user, ATMERR_PREVIOUSLY_ABORTED);
1366 set_state(user, USER_IN_WAITING);
1370 acc->newep[sizeof(acc->newep) - 1] = '\0';
1372 LIST_FOREACH(newep, &user->cc->user_list, node_link)
1373 if (strcmp(acc->newep, newep->name) == 0)
1375 uni_msg_destroy(msg);
1377 if (newep == NULL) {
1378 cc_user_err(user, ATMERR_BAD_ENDPOINT);
1382 if (newep->state != USER_NULL || newep->accepted != NULL) {
1383 cc_user_err(user, ATMERR_BAD_STATE);
1387 set_state(user, USER_IN_WAIT_ACC);
1388 cc_conn_sig(TAILQ_FIRST(&user->connq), CONN_SIG_ACCEPT, newep);
1394 case USER_SIG_ACCEPT_OK:
1395 if (user->state != USER_IN_WAIT_ACC)
1397 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1399 set_state(user, USER_IN_WAITING);
1404 case USER_SIG_ACCEPT_ERR:
1405 if (user->state != USER_IN_WAIT_ACC)
1407 cc_user_err(user, arg2);
1410 /* arg used as flag! */
1411 set_state(user, USER_IN_ARRIVED);
1413 set_state(user, USER_IN_WAITING);
1419 case USER_SIG_ACCEPTING:
1420 if (user->state != USER_NULL)
1422 set_state(user, USER_IN_ACCEPTING);
1426 case USER_SIG_SETUP_COMPL:
1428 struct ccconn *conn = TAILQ_FIRST(&user->connq);
1430 if (user->state != USER_IN_ACCEPTING)
1433 user->state = USER_ACTIVE;
1434 if (conn->bearer.cfg == UNI_BEARER_P2P) {
1435 struct atm_p2p_call_active *act;
1437 user->config = USER_P2P;
1438 act = CCZALLOC(sizeof(*act));
1441 act->connid = conn->connid;
1442 cc_user_send(user, ATMOP_P2P_CALL_ACTIVE,
1446 struct atm_p2mp_call_active *act;
1448 user->config = USER_LEAF;
1449 act = CCZALLOC(sizeof(*act));
1452 act->connid = conn->connid;
1453 cc_user_send(user, ATMOP_P2MP_CALL_ACTIVE,
1461 case USER_SIG_CALL_RELEASE:
1463 struct uni_msg *msg = arg;
1464 struct atm_call_release *api = uni_msg_rptr(msg,
1465 struct atm_call_release *);
1466 struct ccconn *conn;
1468 conn = TAILQ_FIRST(&user->connq);
1469 switch (user->state) {
1471 case USER_OUT_WAIT_OK: /* U2/A3 */
1472 /* wait for CONN_OK first */
1473 conn->cause[0] = api->cause[0];
1474 conn->cause[1] = api->cause[1];
1475 set_state(user, USER_REL_WAIT_CONN);
1478 case USER_OUT_WAIT_CONF: /* U3/A3 */
1479 /* wait for SETUP.confirm first */
1480 conn->cause[0] = api->cause[0];
1481 conn->cause[1] = api->cause[1];
1482 set_state(user, USER_REL_WAIT_SCONF);
1485 case USER_IN_ACCEPTING: /* U11/A7 */
1486 conn->cause[0] = api->cause[0];
1487 conn->cause[1] = api->cause[1];
1488 set_state(user, USER_REL_WAIT_SCOMP);
1489 cc_conn_sig(conn, CONN_SIG_RELEASE, NULL);
1492 case USER_ACTIVE: /* U4/A8,A9,A10 */
1493 conn->cause[0] = api->cause[0];
1494 conn->cause[1] = api->cause[1];
1495 set_state(user, USER_REL_WAIT);
1496 cc_conn_sig(conn, CONN_SIG_RELEASE, NULL);
1500 uni_msg_destroy(msg);
1501 cc_user_err(user, ATMERR_BAD_STATE);
1504 uni_msg_destroy(msg);
1509 case USER_SIG_RELEASE_CONFIRM:
1511 struct atm_call_release *ind;
1513 switch (user->state) {
1515 case USER_OUT_WAIT_CONF: /* U3/A3 */
1516 case USER_ACTIVE: /* U4/A8,A9,A10 */
1517 cc_user_reset(user);
1520 case USER_REL_WAIT: /* U5 /A8,A9,A10 */
1521 case USER_REL_WAIT_SCOMP: /* U12/A7 */
1522 case USER_REL_WAIT_SCONF: /* U13/A3 */
1523 case USER_REL_WAIT_CONF: /* U14/A3 */
1524 cc_user_reset(user);
1525 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1528 case USER_IN_ACCEPTING: /* U11/A7 */
1529 cc_user_reset(user);
1536 ind = CCZALLOC(sizeof(*ind));
1539 memcpy(ind->cause, user->cause, sizeof(ind->cause));
1540 cc_user_send(user, ATMOP_CALL_RELEASE, ind, sizeof(*ind));
1546 case USER_SIG_RELEASE_ERR:
1547 switch (user->state) {
1549 case USER_REL_WAIT: /* U5/A8,A9,A10 */
1550 set_state(user, USER_ACTIVE);
1551 cc_user_err(user, ATM_MKUNIERR(arg2));
1554 case USER_REL_WAIT_CONF: /* U14/A3 */
1555 cc_user_err(user, ATM_MKUNIERR(arg2));
1556 cc_user_active(user);
1559 case USER_REL_WAIT_SCOMP: /* U12/A7 */
1560 set_state(user, USER_IN_ACCEPTING);
1561 cc_user_err(user, ATM_MKUNIERR(arg2));
1570 case USER_SIG_ADD_PARTY:
1572 struct uni_msg *msg = arg;
1573 struct atm_add_party *add = uni_msg_rptr(msg,
1574 struct atm_add_party *);
1575 struct ccconn *conn;
1577 if (user->state != USER_ACTIVE || user->config != USER_ROOT) {
1578 uni_msg_destroy(msg);
1579 cc_user_err(user, ATMERR_BAD_STATE);
1583 if (add->leaf_ident == 0 || add->leaf_ident >= 32786) {
1584 uni_msg_destroy(msg);
1585 cc_user_err(user, ATMERR_BAD_LEAF_IDENT);
1589 conn = TAILQ_FIRST(&user->connq);
1590 conn->called = add->called;
1592 cc_conn_sig(conn, CONN_SIG_ADD_PARTY,
1593 (void *)(uintptr_t)add->leaf_ident);
1595 uni_msg_destroy(msg);
1600 case USER_SIG_ADD_PARTY_ERR:
1601 if (user->state != USER_ACTIVE)
1603 cc_user_err(user, arg2);
1607 case USER_SIG_ADD_PARTY_OK:
1608 if (user->state != USER_ACTIVE)
1610 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1614 case USER_SIG_ADD_PARTY_ACK:
1616 u_int leaf_ident = arg2;
1617 struct atm_add_party_success *succ;
1619 if (user->state != USER_ACTIVE)
1622 succ = CCZALLOC(sizeof(*succ));
1626 succ->leaf_ident = leaf_ident;
1627 cc_user_send(user, ATMOP_ADD_PARTY_SUCCESS,
1628 succ, sizeof(*succ));
1635 case USER_SIG_ADD_PARTY_REJ:
1637 u_int leaf_ident = arg2;
1638 struct atm_add_party_reject *reject;
1640 if (user->state != USER_ACTIVE)
1643 reject = CCZALLOC(sizeof(*reject));
1647 reject->leaf_ident = leaf_ident;
1648 reject->cause = user->cause[0];
1649 cc_user_send(user, ATMOP_ADD_PARTY_REJECT,
1650 reject, sizeof(*reject));
1657 case USER_SIG_DROP_PARTY:
1659 struct uni_msg *msg = arg;
1660 struct atm_drop_party *drop = uni_msg_rptr(msg,
1661 struct atm_drop_party *);
1662 struct ccconn *conn;
1664 if (user->state != USER_ACTIVE || user->config != USER_ROOT) {
1665 uni_msg_destroy(msg);
1666 cc_user_err(user, ATMERR_BAD_STATE);
1670 if (drop->leaf_ident >= 32786) {
1671 uni_msg_destroy(msg);
1672 cc_user_err(user, ATMERR_BAD_LEAF_IDENT);
1676 conn = TAILQ_FIRST(&user->connq);
1677 conn->cause[0] = drop->cause;
1678 memset(&conn->cause[1], 0, sizeof(conn->cause[1]));
1680 cc_conn_sig(conn, CONN_SIG_DROP_PARTY,
1681 (void *)(uintptr_t)drop->leaf_ident);
1683 uni_msg_destroy(msg);
1688 case USER_SIG_DROP_PARTY_ERR:
1689 if (user->state != USER_ACTIVE)
1691 cc_user_err(user, arg2);
1695 case USER_SIG_DROP_PARTY_OK:
1696 if (user->state != USER_ACTIVE)
1698 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1702 case USER_SIG_DROP_PARTY_IND:
1704 u_int leaf_ident = arg2;
1705 struct atm_drop_party *drop;
1707 if (user->state != USER_ACTIVE)
1710 drop = CCZALLOC(sizeof(*drop));
1714 drop->leaf_ident = leaf_ident;
1715 drop->cause = user->cause[0];
1716 cc_user_send(user, ATMOP_DROP_PARTY, drop, sizeof(*drop));
1723 case USER_SIG_QUERY_ATTR:
1725 struct uni_msg *msg = arg;
1726 struct atm_query_connection_attributes *req;
1727 struct ccconn *conn;
1729 if (user->aborted) {
1730 cc_user_err(user, ATMERR_PREVIOUSLY_ABORTED);
1731 uni_msg_destroy(msg);
1734 conn = cc_query_check(user);
1736 cc_user_err(user, ATMERR_BAD_STATE);
1737 uni_msg_destroy(msg);
1740 req = uni_msg_rptr(msg,
1741 struct atm_query_connection_attributes *);
1742 cc_attr_query(user, conn, &req->attr, 1);
1743 uni_msg_destroy(msg);
1747 case USER_SIG_QUERY_ATTR_X:
1749 struct uni_msg *msg = arg;
1750 struct atm_query_connection_attributes_x *req;
1751 struct ccconn *conn;
1753 conn = cc_query_check(user);
1755 cc_user_err(user, ATMERR_BAD_STATE);
1756 uni_msg_destroy(msg);
1759 req = uni_msg_rptr(msg,
1760 struct atm_query_connection_attributes_x *);
1761 cc_attr_query(user, conn, req->attr, req->count);
1762 uni_msg_destroy(msg);
1766 case USER_SIG_SET_ATTR:
1768 struct uni_msg *msg = arg;
1769 struct atm_set_connection_attributes *req;
1770 struct ccconn *conn;
1772 if (user->aborted) {
1773 cc_user_err(user, ATMERR_PREVIOUSLY_ABORTED);
1774 uni_msg_destroy(msg);
1777 conn = cc_set_check(user);
1779 cc_user_err(user, ATMERR_BAD_STATE);
1780 uni_msg_destroy(msg);
1783 req = uni_msg_rptr(msg, struct atm_set_connection_attributes *);
1784 cc_attr_set(user, conn, &req->attr, 1, (u_char *)(req + 1),
1785 uni_msg_len(msg) - sizeof(*req));
1786 uni_msg_destroy(msg);
1790 case USER_SIG_SET_ATTR_X:
1792 struct uni_msg *msg = arg;
1793 struct atm_set_connection_attributes_x *req;
1794 struct ccconn *conn;
1796 conn = cc_set_check(user);
1798 cc_user_err(user, ATMERR_BAD_STATE);
1799 uni_msg_destroy(msg);
1802 req = uni_msg_rptr(msg,
1803 struct atm_set_connection_attributes_x *);
1804 cc_attr_set(user, conn, req->attr, req->count,
1805 (u_char *)req->attr + req->count * sizeof(req->attr[0]),
1807 offsetof(struct atm_set_connection_attributes_x, attr) -
1808 req->count * sizeof(req->attr[0]));
1809 uni_msg_destroy(msg);
1813 case USER_SIG_QUERY_STATE:
1815 struct atm_epstate state;
1817 strcpy(state.name, user->name);
1818 switch (user->state) {
1821 if (user->accepted != NULL)
1822 state.state = ATM_A7;
1824 state.state = ATM_A1;
1827 case USER_OUT_PREPARING:
1828 state.state = ATM_A2;
1831 case USER_OUT_WAIT_OK:
1832 case USER_OUT_WAIT_CONF:
1833 case USER_REL_WAIT_SCONF:
1834 case USER_REL_WAIT_CONF:
1835 case USER_REL_WAIT_CONN:
1836 state.state = ATM_A3;
1841 switch (user->config) {
1844 state.state = ATM_A8;
1848 state.state = ATM_A9;
1852 state.state = ATM_A10;
1857 case USER_IN_PREPARING:
1858 state.state = ATM_A4;
1861 case USER_IN_WAITING:
1862 state.state = ATM_A5;
1865 case USER_IN_ARRIVED:
1866 case USER_IN_WAIT_REJ:
1867 case USER_IN_WAIT_ACC:
1868 state.state = ATM_A6;
1871 case USER_IN_ACCEPTING:
1872 case USER_REL_WAIT_SCOMP:
1873 state.state = ATM_A7;
1876 cc_user_ok(user, ATMRESP_STATE, &state, sizeof(state));
1880 case USER_SIG_GET_LOCAL_PORT_INFO:
1882 struct uni_msg *msg = arg;
1883 struct atm_port_list *list;
1886 list = cc_get_local_port_info(user->cc,
1887 uni_msg_rptr(msg, struct atm_get_local_port_info *)->port,
1889 uni_msg_destroy(msg);
1891 cc_user_err(user, ATMERR_NOMEM);
1894 cc_user_ok(user, ATMRESP_PORTS, list, list_len);
1899 case USER_SIG_ABORT_CONNECTION:
1901 struct uni_msg *msg = arg;
1902 struct atm_abort_connection *abo = uni_msg_rptr(msg,
1903 struct atm_abort_connection *);
1905 cc_user_abort(user, &abo->cause);
1906 uni_msg_destroy(msg);
1907 cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1912 if (user->cc->log & CCLOG_USER_SIG)
1913 cc_user_log(user, "bad signal=%u in state=%u",
1918 if (user->cc->log & CCLOG_USER_SIG)
1919 cc_user_log(user, "bad state=%u for signal=%u",