1 /*
2  * Copyright (c) 2003-2004
3  *	Hartmut Brandt
4  *	All rights reserved.
5  *
6  * Copyright (c) 2001-2002
7  *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
8  *	All rights reserved.
9  *
10  * Author: Harti Brandt <[email protected]>
11  *
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:
15  *
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.
21  *
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.
33  *
34  * $Begemot: libunimsg/netnatm/api/cc_user.c,v 1.3 2004/07/16 18:46:55 brandt Exp $
35  *
36  * ATM API as defined per af-saa-0108
37  *
38  * User side (upper half)
39  */
40 
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>
49 
50 /*
51 * This file handles messages to a USER.
52 */
53 static const char *stab[] = {
54 #define DEF(N) [N] = #N,
55 	USER_STATES
56 #undef DEF
57 };
58 
59 const char *
cc_user_state2str(u_int s)60 cc_user_state2str(u_int s)
61 {
62 	if (s >= sizeof(stab) / sizeof(stab[0]) || stab[s] == NULL)
63 		return ("?");
64 	return (stab[s]);
65 }
66 
67 static __inline void
set_state(struct ccuser * user,enum user_state ns)68 set_state(struct ccuser *user, enum user_state ns)
69 {
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]);
74 		user->state = ns;
75 	}
76 }
77 
78 static __inline void
cc_user_send(struct ccuser * user,u_int op,void * arg,size_t len)79 cc_user_send(struct ccuser *user, u_int op, void *arg, size_t len)
80 {
81 	user->cc->funcs->send_user(user, user->uarg, op, arg, len);
82 }
83 
84 static __inline void
cc_user_ok(struct ccuser * user,u_int data,void * arg,size_t len)85 cc_user_ok(struct ccuser *user, u_int data, void *arg, size_t len)
86 {
87 	user->cc->funcs->respond_user(user, user->uarg,
88 	    ATMERR_OK, data, arg, len);
89 }
90 
91 static __inline void
cc_user_err(struct ccuser * user,int err)92 cc_user_err(struct ccuser *user, int err)
93 {
94 	user->cc->funcs->respond_user(user, user->uarg,
95 	    err, ATMRESP_NONE, NULL, 0);
96 }
97 
98 
99 /**********************************************************************
100 *
101 * INSTANCE MANAGEMENT
102 */
103 /*
104 * New endpoint created
105 */
106 struct ccuser *
cc_user_create(struct ccdata * cc,void * uarg,const char * name)107 cc_user_create(struct ccdata *cc, void *uarg, const char *name)
108 {
109 	struct ccuser *user;
110 
111 	user = CCZALLOC(sizeof(*user));
112 	if (user == NULL)
113 		return (NULL);
114 
115 	user->cc = cc;
116 	user->state = USER_NULL;
117 	user->uarg = uarg;
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);
122 
123 	if (user->cc->log & CCLOG_USER_INST)
124 		cc_user_log(user, "created with name '%s'", name);
125 
126 	return (user);
127 }
128 
129 /*
130  * Reset a user instance
131  */
132 static void
cc_user_reset(struct ccuser * user)133 cc_user_reset(struct ccuser *user)
134 {
135 
136 	CCASSERT(TAILQ_EMPTY(&user->connq), ("connq not empty"));
137 
138 	if (user->sap != NULL) {
139 		CCFREE(user->sap);
140 		user->sap = NULL;
141 	}
142 
143 	if (user->accepted != NULL) {
144 		user->accepted->acceptor = NULL;
145 		user->accepted = NULL;
146 	}
147 	user->config = USER_P2P;
148 	user->queue_act = 0;
149 	user->queue_max = 0;
150 	user->aborted = 0;
151 
152 	set_state(user, USER_NULL);
153 
154 	cc_user_sig_flush(user);
155 }
156 
157 static void
cc_user_abort(struct ccuser * user,const struct uni_ie_cause * cause)158 cc_user_abort(struct ccuser *user, const struct uni_ie_cause *cause)
159 {
160 	struct ccconn *conn;
161 
162 	/*
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.
169 	 *
170 	 * First bring user into a state that the connections
171 	 * are not dispatched back to it.
172 	 */
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));
177 			if (cause != NULL)
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);
182 		}
183 	}
184 
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);
189 	}
190 
191 	cc_user_reset(user);
192 }
193 
194 /*
195  * Application has closed this endpoint. Clean up all user resources and
196  * abort all connections. This can be called in any state.
197  */
198 void
cc_user_destroy(struct ccuser * user)199 cc_user_destroy(struct ccuser *user)
200 {
201 
202 	if (user->cc->log & CCLOG_USER_INST)
203 		cc_user_log(user, "destroy '%s'", user->name);
204 
205 	cc_user_abort(user, NULL);
206 
207 	if (user->sap != NULL)
208 		CCFREE(user->sap);
209 
210 	cc_user_sig_flush(user);
211 
212 	LIST_REMOVE(user, node_link);
213 	CCFREE(user);
214 }
215 
216 /**********************************************************************
217  *
218  * OUTGOING CALLS
219  */
220 /*
221  * Return true when the calling address of the connection matches the address.
222  */
223 static int
addr_matches(const struct ccaddr * addr,const struct ccconn * conn)224 addr_matches(const struct ccaddr *addr, const struct ccconn *conn)
225 {
226 
227 	if (!IE_ISPRESENT(conn->calling))
228 		return (0);
229 
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);
235 }
236 
237 /*
238  * Check if the user's SAP (given he is in the right state) and
239  * the given SAP overlap
240  */
241 static int
check_overlap(struct ccuser * user,struct uni_sap * sap)242 check_overlap(struct ccuser *user, struct uni_sap *sap)
243 {
244 	return ((user->state == USER_IN_PREPARING ||
245 	    user->state == USER_IN_WAITING) &&
246 	    unisve_overlap_sap(user->sap, sap));
247 }
248 
249 /*
250  * Send arrival notification to user
251  */
252 static void
do_arrival(struct ccuser * user)253 do_arrival(struct ccuser *user)
254 {
255 	struct ccconn *conn;
256 
257 	user->aborted = 0;
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);
262 	}
263 }
264 
265 /**********************************************************************
266  *
267  * ATTRIBUTES
268  */
269 /*
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).
273  */
274 static struct ccconn *
cc_query_check(struct ccuser * user)275 cc_query_check(struct ccuser *user)
276 {
277 
278 	switch (user->state) {
279 
280 	  case USER_OUT_PREPARING:
281 	  case USER_IN_ARRIVED:
282 	  case USER_ACTIVE:
283 		return (TAILQ_FIRST(&user->connq));
284 
285 	  case USER_NULL:
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.
290 		 */
291 		if (user->accepted != NULL &&
292 		    user->accepted->state == CONN_IN_WAIT_ACCEPT_OK)
293 			return (user->accepted);
294 		/* FALLTHRU */
295 
296 	  default:
297 		return (NULL);
298 	}
299 }
300 
301 /*
302  * Query attributes
303  */
304 static void
cc_attr_query(struct ccuser * user,struct ccconn * conn,uint32_t * attr,u_int count)305 cc_attr_query(struct ccuser *user, struct ccconn *conn,
306     uint32_t *attr, u_int count)
307 {
308 	void *val, *ptr;
309 	size_t total, len;
310 	u_int i;
311 	uint32_t *atab;
312 
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++) {
316 		len = 0;
317 		switch ((enum atm_attribute)attr[i]) {
318 
319 		  case ATM_ATTR_NONE:
320 			break;
321 
322 		  case ATM_ATTR_BLLI_SELECTOR:
323 			len = sizeof(uint32_t);
324 			break;
325 
326 		  case ATM_ATTR_BLLI:
327 			len = sizeof(struct uni_ie_blli);
328 			break;
329 
330 		  case ATM_ATTR_BEARER:
331 			len = sizeof(struct uni_ie_bearer);
332 			break;
333 
334 		  case ATM_ATTR_TRAFFIC:
335 			len = sizeof(struct uni_ie_traffic);
336 			break;
337 
338 		  case ATM_ATTR_QOS:
339 			len = sizeof(struct uni_ie_qos);
340 			break;
341 
342 		  case ATM_ATTR_EXQOS:
343 			len = sizeof(struct uni_ie_exqos);
344 			break;
345 
346 		  case ATM_ATTR_CALLED:
347 			len = sizeof(struct uni_ie_called);
348 			break;
349 
350 		  case ATM_ATTR_CALLEDSUB:
351 			len = sizeof(struct uni_ie_calledsub);
352 			break;
353 
354 		  case ATM_ATTR_CALLING:
355 			len = sizeof(struct uni_ie_calling);
356 			break;
357 
358 		  case ATM_ATTR_CALLINGSUB:
359 			len = sizeof(struct uni_ie_callingsub);
360 			break;
361 
362 		  case ATM_ATTR_AAL:
363 			len = sizeof(struct uni_ie_aal);
364 			break;
365 
366 		  case ATM_ATTR_EPREF:
367 			len = sizeof(struct uni_ie_epref);
368 			break;
369 
370 		  case ATM_ATTR_CONNED:
371 			len = sizeof(struct uni_ie_conned);
372 			break;
373 
374 		  case ATM_ATTR_CONNEDSUB:
375 			len = sizeof(struct uni_ie_connedsub);
376 			break;
377 
378 		  case ATM_ATTR_EETD:
379 			len = sizeof(struct uni_ie_eetd);
380 			break;
381 
382 		  case ATM_ATTR_ABRSETUP:
383 			len = sizeof(struct uni_ie_abrsetup);
384 			break;
385 
386 		  case ATM_ATTR_ABRADD:
387 			len = sizeof(struct uni_ie_abradd);
388 			break;
389 
390 		  case ATM_ATTR_CONNID:
391 			len = sizeof(struct uni_ie_connid);
392 			break;
393 
394 		  case ATM_ATTR_MDCR:
395 			len = sizeof(struct uni_ie_mdcr);
396 			break;
397 		}
398 		if (len == 0) {
399 			cc_user_err(user, ATMERR_BAD_ATTR);
400 			return;
401 		}
402 		total += len;
403 	}
404 
405 	/* allocate buffer */
406 	val = CCMALLOC(total);
407 	if (val == NULL)
408 		return;
409 
410 	atab = val;
411 	atab[0] = count;
412 
413 	/* fill */
414 	ptr = (u_char *)val + (sizeof(uint32_t) + count * sizeof(uint32_t));
415 	for (i = 0; i < count; i++) {
416 		len = 0;
417 		atab[i + 1] = attr[i];
418 		switch (attr[i]) {
419 
420 		  case ATM_ATTR_NONE:
421 			break;
422 
423 		  case ATM_ATTR_BLLI_SELECTOR:
424 			len = sizeof(uint32_t);
425 			memcpy(ptr, &conn->blli_selector, len);
426 			break;
427 
428 		  case ATM_ATTR_BLLI:
429 			/* in A6 the blli_selector may be 0 when
430 			 * there was no blli in the SETUP.
431 			 */
432 			len = sizeof(struct uni_ie_blli);
433 			if (conn->blli_selector == 0)
434 				memset(ptr, 0, len);
435 			else
436 				memcpy(ptr, &conn->blli[conn->blli_selector -
437 				    1], len);
438 			break;
439 
440 		  case ATM_ATTR_BEARER:
441 			len = sizeof(struct uni_ie_bearer);
442 			memcpy(ptr, &conn->bearer, len);
443 			break;
444 
445 		  case ATM_ATTR_TRAFFIC:
446 			len = sizeof(struct uni_ie_traffic);
447 			memcpy(ptr, &conn->traffic, len);
448 			break;
449 
450 		  case ATM_ATTR_QOS:
451 			len = sizeof(struct uni_ie_qos);
452 			memcpy(ptr, &conn->qos, len);
453 			break;
454 
455 		  case ATM_ATTR_EXQOS:
456 			len = sizeof(struct uni_ie_exqos);
457 			memcpy(ptr, &conn->exqos, len);
458 			break;
459 
460 		  case ATM_ATTR_CALLED:
461 			len = sizeof(struct uni_ie_called);
462 			memcpy(ptr, &conn->called, len);
463 			break;
464 
465 		  case ATM_ATTR_CALLEDSUB:
466 			len = sizeof(struct uni_ie_calledsub);
467 			memcpy(ptr, &conn->calledsub, len);
468 			break;
469 
470 		  case ATM_ATTR_CALLING:
471 			len = sizeof(struct uni_ie_calling);
472 			memcpy(ptr, &conn->calling, len);
473 			break;
474 
475 		  case ATM_ATTR_CALLINGSUB:
476 			len = sizeof(struct uni_ie_callingsub);
477 			memcpy(ptr, &conn->callingsub, len);
478 			break;
479 
480 		  case ATM_ATTR_AAL:
481 			len = sizeof(struct uni_ie_aal);
482 			memcpy(ptr, &conn->aal, len);
483 			break;
484 
485 		  case ATM_ATTR_EPREF:
486 			len = sizeof(struct uni_ie_epref);
487 			memcpy(ptr, &conn->epref, len);
488 			break;
489 
490 		  case ATM_ATTR_CONNED:
491 			len = sizeof(struct uni_ie_conned);
492 			memcpy(ptr, &conn->conned, len);
493 			break;
494 
495 		  case ATM_ATTR_CONNEDSUB:
496 			len = sizeof(struct uni_ie_connedsub);
497 			memcpy(ptr, &conn->connedsub, len);
498 			break;
499 
500 		  case ATM_ATTR_EETD:
501 			len = sizeof(struct uni_ie_eetd);
502 			memcpy(ptr, &conn->eetd, len);
503 			break;
504 
505 		  case ATM_ATTR_ABRSETUP:
506 			len = sizeof(struct uni_ie_abrsetup);
507 			memcpy(ptr, &conn->abrsetup, len);
508 			break;
509 
510 		  case ATM_ATTR_ABRADD:
511 			len = sizeof(struct uni_ie_abradd);
512 			memcpy(ptr, &conn->abradd, len);
513 			break;
514 
515 		  case ATM_ATTR_CONNID:
516 			len = sizeof(struct uni_ie_connid);
517 			memcpy(ptr, &conn->connid, len);
518 			break;
519 
520 		  case ATM_ATTR_MDCR:
521 			len = sizeof(struct uni_ie_mdcr);
522 			memcpy(ptr, &conn->mdcr, len);
523 			break;
524 		}
525 		ptr = (u_char *)ptr + len;
526 	}
527 
528 	cc_user_ok(user, ATMRESP_ATTRS, val, total);
529 
530 	CCFREE(val);
531 }
532 
533 /*
534  * Check whether the state is ok and return the connection
535  */
536 static struct ccconn *
cc_set_check(struct ccuser * user)537 cc_set_check(struct ccuser *user)
538 {
539 	switch(user->state) {
540 
541 	  case USER_OUT_PREPARING:
542 	  case USER_IN_ARRIVED:
543 		return (TAILQ_FIRST(&user->connq));
544 
545 	  default:
546 		return (NULL);
547 	}
548 }
549 
550 /*
551  * Set connection attribute(s)
552  */
553 static void
cc_attr_set(struct ccuser * user,struct ccconn * conn,uint32_t * attr,u_int count,u_char * val,size_t vallen)554 cc_attr_set(struct ccuser *user, struct ccconn *conn, uint32_t *attr,
555     u_int count, u_char *val, size_t vallen)
556 {
557 	size_t total, len;
558 	u_int i;
559 	u_char *ptr;
560 
561 	/* determine the length of the total attribute buffer */
562 	total = 0;
563 	ptr = val;
564 	for (i = 0; i < count; i++) {
565 		len = 0;
566 		switch ((enum atm_attribute)attr[i]) {
567 
568 		  case ATM_ATTR_NONE:
569 			break;
570 
571 		  case ATM_ATTR_BLLI_SELECTOR:
572 		    {
573 			uint32_t sel;
574 
575 			if (conn->state != CONN_OUT_PREPARING)
576 				goto rdonly;
577 			memcpy(&sel, ptr, sizeof(sel));
578 			if (sel == 0 || sel > UNI_NUM_IE_BLLI)
579 				goto bad_val;
580 			len = sizeof(uint32_t);
581 			break;
582 		    }
583 
584 		  case ATM_ATTR_BLLI:
585 			len = sizeof(struct uni_ie_blli);
586 			break;
587 
588 		  case ATM_ATTR_BEARER:
589 			if (conn->state != CONN_OUT_PREPARING)
590 				goto rdonly;
591 			len = sizeof(struct uni_ie_bearer);
592 			break;
593 
594 		  case ATM_ATTR_TRAFFIC:
595 			len = sizeof(struct uni_ie_traffic);
596 			break;
597 
598 		  case ATM_ATTR_QOS:
599 			if (conn->state != CONN_OUT_PREPARING)
600 				goto rdonly;
601 			len = sizeof(struct uni_ie_qos);
602 			break;
603 
604 		  case ATM_ATTR_EXQOS:
605 			len = sizeof(struct uni_ie_exqos);
606 			break;
607 
608 		  case ATM_ATTR_CALLED:
609 			goto rdonly;
610 
611 		  case ATM_ATTR_CALLEDSUB:
612 			if (conn->state != CONN_OUT_PREPARING)
613 				goto rdonly;
614 			len = sizeof(struct uni_ie_calledsub);
615 			break;
616 
617 		  case ATM_ATTR_CALLING:
618 			if (conn->state != CONN_OUT_PREPARING)
619 				goto rdonly;
620 			len = sizeof(struct uni_ie_calling);
621 			break;
622 
623 		  case ATM_ATTR_CALLINGSUB:
624 			if (conn->state != CONN_OUT_PREPARING)
625 				goto rdonly;
626 			len = sizeof(struct uni_ie_callingsub);
627 			break;
628 
629 		  case ATM_ATTR_AAL:
630 			len = sizeof(struct uni_ie_aal);
631 			break;
632 
633 		  case ATM_ATTR_EPREF:
634 			goto rdonly;
635 
636 		  case ATM_ATTR_CONNED:
637 			goto rdonly;
638 
639 		  case ATM_ATTR_CONNEDSUB:
640 			goto rdonly;
641 
642 		  case ATM_ATTR_EETD:
643 			len = sizeof(struct uni_ie_eetd);
644 			break;
645 
646 		  case ATM_ATTR_ABRSETUP:
647 			len = sizeof(struct uni_ie_abrsetup);
648 			break;
649 
650 		  case ATM_ATTR_ABRADD:
651 			len = sizeof(struct uni_ie_abradd);
652 			break;
653 
654 		  case ATM_ATTR_CONNID:
655 			len = sizeof(struct uni_ie_connid);
656 			break;
657 
658 		  case ATM_ATTR_MDCR:
659 			if (conn->state != CONN_OUT_PREPARING)
660 				goto rdonly;
661 			len = sizeof(struct uni_ie_mdcr);
662 			break;
663 		}
664 		if (len == 0) {
665 			cc_user_err(user, ATMERR_BAD_ATTR);
666 			return;
667 		}
668 		total += len;
669 		ptr += len;
670 	}
671 
672 	/* check the length */
673 	if (vallen != total) {
674 		cc_user_err(user, ATMERR_BAD_ARGS);
675 		return;
676 	}
677 
678 	ptr = val;
679 	for (i = 0; i < count; i++) {
680 		len = 0;
681 		switch ((enum atm_attribute)attr[i]) {
682 
683 		  case ATM_ATTR_NONE:
684 			break;
685 
686 		  case ATM_ATTR_BLLI_SELECTOR:
687 		    {
688 			uint32_t sel;
689 
690 			memcpy(&sel, ptr, sizeof(sel));
691 			conn->blli_selector = sel;
692 			len = sizeof(uint32_t);
693 			break;
694 		    }
695 
696 		  case ATM_ATTR_BLLI:
697 			len = sizeof(struct uni_ie_blli);
698 			memcpy(&conn->blli[conn->blli_selector - 1], ptr, len);
699 			conn->dirty_attr |= CCDIRTY_BLLI;
700 			break;
701 
702 		  case ATM_ATTR_BEARER:
703 			len = sizeof(struct uni_ie_bearer);
704 			memcpy(&conn->bearer, ptr, len);
705 			break;
706 
707 		  case ATM_ATTR_TRAFFIC:
708 			len = sizeof(struct uni_ie_traffic);
709 			memcpy(&conn->traffic, ptr, len);
710 			conn->dirty_attr |= CCDIRTY_TRAFFIC;
711 			break;
712 
713 		  case ATM_ATTR_QOS:
714 			len = sizeof(struct uni_ie_qos);
715 			memcpy(&conn->qos, ptr, len);
716 			break;
717 
718 		  case ATM_ATTR_EXQOS:
719 			len = sizeof(struct uni_ie_exqos);
720 			memcpy(&conn->exqos, ptr, len);
721 			conn->dirty_attr |= CCDIRTY_EXQOS;
722 			break;
723 
724 		  case ATM_ATTR_CALLED:
725 			len = sizeof(struct uni_ie_called);
726 			break;
727 
728 		  case ATM_ATTR_CALLEDSUB:
729 			len = sizeof(struct uni_ie_calledsub);
730 			memcpy(&conn->calledsub, ptr, len);
731 			break;
732 
733 		  case ATM_ATTR_CALLING:
734 			len = sizeof(struct uni_ie_calling);
735 			memcpy(&conn->calling, ptr, len);
736 			break;
737 
738 		  case ATM_ATTR_CALLINGSUB:
739 			len = sizeof(struct uni_ie_callingsub);
740 			memcpy(&conn->callingsub, ptr, len);
741 			break;
742 
743 		  case ATM_ATTR_AAL:
744 			len = sizeof(struct uni_ie_aal);
745 			memcpy(&conn->aal, ptr, len);
746 			conn->dirty_attr |= CCDIRTY_AAL;
747 			break;
748 
749 		  case ATM_ATTR_EPREF:
750 			len = sizeof(struct uni_ie_epref);
751 			break;
752 
753 		  case ATM_ATTR_CONNED:
754 			len = sizeof(struct uni_ie_conned);
755 			break;
756 
757 		  case ATM_ATTR_CONNEDSUB:
758 			len = sizeof(struct uni_ie_connedsub);
759 			break;
760 
761 		  case ATM_ATTR_EETD:
762 			len = sizeof(struct uni_ie_eetd);
763 			memcpy(&conn->eetd, ptr, len);
764 			conn->dirty_attr |= CCDIRTY_EETD;
765 			break;
766 
767 		  case ATM_ATTR_ABRSETUP:
768 			len = sizeof(struct uni_ie_abrsetup);
769 			memcpy(&conn->abrsetup, ptr, len);
770 			conn->dirty_attr |= CCDIRTY_ABRSETUP;
771 			break;
772 
773 		  case ATM_ATTR_ABRADD:
774 			len = sizeof(struct uni_ie_abradd);
775 			memcpy(&conn->abradd, ptr, len);
776 			conn->dirty_attr |= CCDIRTY_ABRADD;
777 			break;
778 
779 		  case ATM_ATTR_CONNID:
780 			len = sizeof(struct uni_ie_connid);
781 			memcpy(&conn->connid, ptr, len);
782 			conn->dirty_attr |= CCDIRTY_CONNID;
783 			break;
784 
785 		  case ATM_ATTR_MDCR:
786 			len = sizeof(struct uni_ie_mdcr);
787 			memcpy(&conn->mdcr, ptr, len);
788 			break;
789 		}
790 		ptr += len;
791 	}
792 
793 	cc_user_ok(user, ATMRESP_NONE, NULL, 0);
794 	return;
795 
796   bad_val:
797 	cc_user_err(user, ATMERR_BAD_VALUE);
798 	return;
799 
800   rdonly:
801 	cc_user_err(user, ATMERR_RDONLY);
802 	return;
803 }
804 
805 #ifdef CCATM_DEBUG
806 static const char *op_names[] = {
807 #define	S(OP)	[ATMOP_##OP] = #OP
808 	S(RESP),
809 	S(ABORT_CONNECTION),
810 	S(ACCEPT_INCOMING_CALL),
811 	S(ADD_PARTY),
812 	S(ADD_PARTY_REJECT),
813 	S(ADD_PARTY_SUCCESS),
814 	S(ARRIVAL_OF_INCOMING_CALL),
815 	S(CALL_RELEASE),
816 	S(CONNECT_OUTGOING_CALL),
817 	S(DROP_PARTY),
818 	S(GET_LOCAL_PORT_INFO),
819 	S(P2MP_CALL_ACTIVE),
820 	S(P2P_CALL_ACTIVE),
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),
829 	S(QUERY_STATE),
830 #undef S
831 };
832 #endif
833 
834 /*
835  * Signal from user - map this to our internal signals and queue
836  * the mapped signal.
837  */
838 int
cc_user_signal(struct ccuser * user,enum atmop sig,struct uni_msg * msg)839 cc_user_signal(struct ccuser *user, enum atmop sig, struct uni_msg *msg)
840 {
841 	size_t len = uni_msg_len(msg);
842 	int err = EINVAL;
843 
844 	if (user->cc->log & CCLOG_USER_SIG)
845 		cc_user_log(user, "signal %s to user", op_names[sig]);
846 
847 	if ((u_int)sig > ATMOP_QUERY_STATE)
848 		goto bad_signal;
849 
850 	switch (sig) {
851 
852 	  case ATMOP_ABORT_CONNECTION:
853 		if (len != sizeof(struct atm_abort_connection))
854 			goto bad_len;
855 		err = cc_user_sig_msg(user, USER_SIG_ABORT_CONNECTION, msg);
856 		break;
857 
858 	  case ATMOP_ACCEPT_INCOMING_CALL:
859 		if (len != sizeof(struct atm_accept_incoming_call))
860 			goto bad_len;
861 		err = cc_user_sig_msg(user, USER_SIG_ACCEPT_INCOMING, msg);
862 		break;
863 
864 	  case ATMOP_ADD_PARTY:
865 		if (len != sizeof(struct atm_add_party))
866 			goto bad_len;
867 		err = cc_user_sig_msg(user, USER_SIG_ADD_PARTY, msg);
868 		break;
869 
870 	  case ATMOP_CALL_RELEASE:
871 		if (len != sizeof(struct atm_call_release))
872 			goto bad_len;
873 		err = cc_user_sig_msg(user, USER_SIG_CALL_RELEASE, msg);
874 		break;
875 
876 	  case ATMOP_CONNECT_OUTGOING_CALL:
877 		if (len != sizeof(struct atm_connect_outgoing_call))
878 			goto bad_len;
879 		err = cc_user_sig_msg(user, USER_SIG_CONNECT_OUTGOING, msg);
880 		break;
881 
882 	  case ATMOP_DROP_PARTY:
883 		if (len != sizeof(struct atm_drop_party))
884 			goto bad_len;
885 		err = cc_user_sig_msg(user, USER_SIG_DROP_PARTY, msg);
886 		break;
887 
888 	  case ATMOP_GET_LOCAL_PORT_INFO:
889 		if (len != sizeof(struct atm_get_local_port_info))
890 			goto bad_len;
891 		err = cc_user_sig_msg(user, USER_SIG_GET_LOCAL_PORT_INFO, msg);
892 		break;
893 
894 	  case ATMOP_PREPARE_INCOMING_CALL:
895 		if (len != sizeof(struct atm_prepare_incoming_call))
896 			goto bad_len;
897 		err = cc_user_sig_msg(user, USER_SIG_PREPARE_INCOMING, msg);
898 		break;
899 
900 	  case ATMOP_PREPARE_OUTGOING_CALL:
901 		if (len != 0)
902 			goto bad_len;
903 		uni_msg_destroy(msg);
904 		err = cc_user_sig(user, USER_SIG_PREPARE_OUTGOING, NULL, 0);
905 		break;
906 
907 	  case ATMOP_QUERY_CONNECTION_ATTRIBUTES:
908 		if (len != sizeof(struct atm_query_connection_attributes))
909 			goto bad_len;
910 		err = cc_user_sig_msg(user, USER_SIG_QUERY_ATTR, msg);
911 		break;
912 
913 	  case ATMOP_REJECT_INCOMING_CALL:
914 		if (len != sizeof(struct atm_reject_incoming_call))
915 			goto bad_len;
916 		err = cc_user_sig_msg(user, USER_SIG_REJECT_INCOMING, msg);
917 		break;
918 
919 	  case ATMOP_SET_CONNECTION_ATTRIBUTES:
920 		if (len < sizeof(struct atm_set_connection_attributes))
921 			goto bad_len;
922 		err = cc_user_sig_msg(user, USER_SIG_SET_ATTR, msg);
923 		break;
924 
925 	  case ATMOP_WAIT_ON_INCOMING_CALL:
926 		if (len != 0)
927 			goto bad_len;
928 		uni_msg_destroy(msg);
929 		err = cc_user_sig(user, USER_SIG_WAIT_ON_INCOMING, NULL, 0);
930 		break;
931 
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 *
937 		    sizeof(uint32_t))
938 			goto bad_len;
939 		err = cc_user_sig_msg(user, USER_SIG_QUERY_ATTR_X, msg);
940 		break;
941 
942 	  case ATMOP_SET_CONNECTION_ATTRIBUTES_X:
943 		if (len < sizeof(struct atm_set_connection_attributes_x))
944 			goto bad_len;
945 		err = cc_user_sig_msg(user, USER_SIG_SET_ATTR_X, msg);
946 		break;
947 
948 	  case ATMOP_QUERY_STATE:
949 		if (len != 0)
950 			goto bad_len;
951 		uni_msg_destroy(msg);
952 		err = cc_user_sig(user, USER_SIG_QUERY_STATE, NULL, 0);
953 		break;
954 
955 	  case ATMOP_RESP:
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:
961 	  bad_signal:
962 		/* bad signal */
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);
967 		break;
968 	}
969 	return (err);
970 
971   bad_len:
972 	/* bad argument length */
973 	if (user->cc->log & CCLOG_USER_SIG)
974 		cc_user_log(user, "signal %s had bad len=%zu",
975 		    op_names[sig], len);
976 	cc_user_err(user, ATMERR_BAD_ARGS);
977 	uni_msg_destroy(msg);
978 	return (EINVAL);
979 }
980 
981 /*
982  * Send active signal to user
983  */
984 static void
cc_user_active(struct ccuser * user)985 cc_user_active(struct ccuser *user)
986 {
987 	struct ccconn *conn = TAILQ_FIRST(&user->connq);
988 
989 	set_state(user, USER_ACTIVE);
990 	if (conn->bearer.cfg == UNI_BEARER_P2P) {
991 		struct atm_p2p_call_active *act;
992 
993 		user->config = USER_P2P;
994 		act = CCZALLOC(sizeof(*act));
995 		if (act == NULL)
996 			return;
997 		act->connid = conn->connid;
998 		cc_user_send(user, ATMOP_P2P_CALL_ACTIVE, act, sizeof(*act));
999 		CCFREE(act);
1000 	} else {
1001 		struct atm_p2mp_call_active *act;
1002 
1003 		user->config = USER_ROOT;
1004 		act = CCZALLOC(sizeof(*act));
1005 		if (act == NULL)
1006 			return;
1007 		act->connid = conn->connid;
1008 		cc_user_send(user, ATMOP_P2MP_CALL_ACTIVE, act, sizeof(*act));
1009 		CCFREE(act);
1010 	}
1011 }
1012 
1013 /*
1014 * Handle a signal to this user
1015 */
1016 void
cc_user_sig_handle(struct ccuser * user,enum user_sig sig,void * arg,u_int arg2)1017 cc_user_sig_handle(struct ccuser *user, enum user_sig sig,
1018     void *arg, u_int arg2)
1019 {
1020 
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]);
1024 
1025 	switch (sig) {
1026 
1027 
1028 	  case USER_SIG_PREPARE_OUTGOING:
1029 	    {
1030 		/*
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
1035 		 * to connect.
1036 		 */
1037 		struct ccconn *conn;
1038 
1039 		if (user->state != USER_NULL) {
1040 			cc_user_err(user, ATMERR_BAD_STATE);
1041 			goto bad_state;
1042 		}
1043 		conn = cc_conn_create(user->cc);
1044 		if (conn == NULL) {
1045 			cc_user_err(user, ATMERR_NOMEM);
1046 			return;
1047 		}
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);
1052 
1053 		cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1054 		return;
1055 	    }
1056 
1057 
1058 	  case USER_SIG_CONNECT_OUTGOING:
1059 	    {
1060 		/*
1061 		 * Request to connect that call
1062 		 *
1063 		 * Here we assign the connection to a port.
1064 		 */
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);
1072 
1073 		if (user->state != USER_OUT_PREPARING) {
1074 			uni_msg_destroy(msg);
1075 			cc_user_err(user, ATMERR_BAD_STATE);
1076 			goto bad_state;
1077 		}
1078 		if (!IE_ISPRESENT(req->called)) {
1079 			uni_msg_destroy(msg);
1080 			cc_user_err(user, ATMERR_BAD_ARGS);
1081 			return;
1082 		}
1083 		CCASSERT(conn->port == NULL, ("connection still on port"));
1084 
1085 		if (TAILQ_EMPTY(&priv->port_list)) {
1086 			/*
1087 			 * We have no ports - reject
1088 			 */
1089 			uni_msg_destroy(msg);
1090 			cc_user_err(user, ATMERR_BAD_PORT);
1091 			return;
1092 		}
1093 
1094 		/*
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.
1099 		 */
1100 		TAILQ_FOREACH(port, &priv->port_list, node_link)
1101 			TAILQ_FOREACH(addr, &port->addr_list, port_link)
1102 				if (addr_matches(addr, conn))
1103 					break;
1104 
1105 		if (port == NULL)
1106 			port = TAILQ_FIRST(&priv->port_list);
1107 
1108 		cc_conn_ins_port(conn, port);
1109 		conn->called = req->called;
1110 		uni_msg_destroy(msg);
1111 
1112 		/*
1113 		 * Now move the state
1114 		 */
1115 		set_state(user, USER_OUT_WAIT_OK);
1116 		cc_conn_sig(conn, CONN_SIG_CONNECT_OUTGOING, NULL);
1117 
1118 		return;
1119 	    }
1120 
1121 
1122 	  case USER_SIG_CONNECT_OUTGOING_ERR:
1123 		switch (user->state) {
1124 
1125 		  case USER_OUT_WAIT_OK:
1126 			set_state(user, USER_OUT_PREPARING);
1127 			cc_user_err(user, arg2);
1128 			break;
1129 
1130 		  case USER_REL_WAIT_CONN:
1131 		    {
1132 			struct ccconn *conn;
1133 
1134 			conn = TAILQ_FIRST(&user->connq);
1135 			if (conn != NULL) {
1136 				cc_disconnect_from_user(conn);
1137 				cc_conn_destroy(conn);
1138 			}
1139 
1140 			cc_user_reset(user);
1141 			cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1142 			break;
1143 		    }
1144 
1145 		  default:
1146 			goto bad_state;
1147 		}
1148 		return;
1149 
1150 
1151 	  case USER_SIG_CONNECT_OUTGOING_OK:
1152 		switch (user->state) {
1153 
1154 		  case USER_OUT_WAIT_OK:
1155 			set_state(user, USER_OUT_WAIT_CONF);
1156 			cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1157 			break;
1158 
1159 		  case USER_REL_WAIT_CONN:
1160 			set_state(user, USER_REL_WAIT_SCONF);
1161 			break;
1162 
1163 		  default:
1164 			goto bad_state;
1165 		}
1166 		return;
1167 
1168 
1169 	  case USER_SIG_SETUP_CONFIRM:
1170 		/*
1171 		 * SETUP.confirm from UNI stack.
1172 		 */
1173 		switch (user->state) {
1174 
1175 		  case USER_OUT_WAIT_CONF:
1176 			cc_user_active(user);
1177 			break;
1178 
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);
1184 			break;
1185 
1186 		  default:
1187 			goto bad_state;
1188 		}
1189 		return;
1190 
1191 
1192 	  case USER_SIG_PREPARE_INCOMING:
1193 	    {
1194 		struct uni_msg *msg = arg;
1195 		struct ccuser *ptr;
1196 		struct atm_prepare_incoming_call *prep = uni_msg_rptr(msg,
1197 		    struct atm_prepare_incoming_call *);
1198 
1199 		if (user->state != USER_NULL) {
1200 			uni_msg_destroy(msg);
1201 			cc_user_err(user, ATMERR_BAD_STATE);
1202 			goto bad_state;
1203 		}
1204 
1205 		/*
1206 		 * Check the SAP
1207 		 */
1208 		if (unisve_check_sap(&prep->sap) != UNISVE_OK) {
1209 			uni_msg_destroy(msg);
1210 			cc_user_err(user, ATMERR_BAD_SAP);
1211 			return;
1212 		}
1213 
1214 		/*
1215 		 * Loop through all incoming calls and check whether there
1216 		 * is an overlap in SAP space.
1217 		 */
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);
1222 				return;
1223 			}
1224 		}
1225 
1226 		/*
1227 		 * Save info and set state
1228 		 */
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);
1233 			return;
1234 		}
1235 		*user->sap = prep->sap;
1236 		user->queue_max = prep->queue_size;
1237 		user->queue_act = 0;
1238 		uni_msg_destroy(msg);
1239 
1240 		set_state(user, USER_IN_PREPARING);
1241 		cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1242 
1243 		return;
1244 	    }
1245 
1246 
1247 	  case USER_SIG_WAIT_ON_INCOMING:
1248 		if (user->state != USER_IN_PREPARING) {
1249 			cc_user_err(user, ATMERR_BAD_STATE);
1250 			goto bad_state;
1251 		}
1252 
1253 		set_state(user, USER_IN_WAITING);
1254 		cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1255 		return;
1256 
1257 
1258 	  case USER_SIG_SETUP_IND:
1259 		/*
1260 		 * New connection queued up in the queue. If this is the
1261 		 * first one, inform the application of the arrival.
1262 		 */
1263 		switch (user->state) {
1264 
1265 		  case USER_IN_WAITING:
1266 			do_arrival(user);
1267 			break;
1268 
1269 		  case USER_IN_ARRIVED:
1270 		  case USER_IN_WAIT_REJ:
1271 		  case USER_IN_WAIT_ACC:
1272 			break;
1273 
1274 		  default:
1275 			goto bad_state;
1276 		}
1277 		return;
1278 
1279 
1280 	  case USER_SIG_REJECT_INCOMING:
1281 	     {
1282 		/*
1283 		 * User rejects call. This is done on the OLD user
1284 		 * (i.e. the one sending the arrival).
1285 		 */
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);
1290 
1291 		if (user->state != USER_IN_ARRIVED) {
1292 			uni_msg_destroy(msg);
1293 			cc_user_err(user, ATMERR_BAD_STATE);
1294 			goto bad_state;
1295 		}
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);
1302 
1303 			set_state(user, USER_IN_WAITING);
1304 			do_arrival(user);
1305 			return;
1306 		}
1307 		conn->cause[0] = rej->cause;
1308 		memset(&conn->cause[1], 0, sizeof(conn->cause[1]));
1309 		uni_msg_destroy(msg);
1310 
1311 		set_state(user, USER_IN_WAIT_REJ);
1312 		cc_conn_sig(conn, CONN_SIG_REJECT, NULL);
1313 
1314 		return;
1315 	    }
1316 
1317 
1318 	  case USER_SIG_REJECT_OK:
1319 		if (user->state != USER_IN_WAIT_REJ)
1320 			goto bad_state;
1321 		cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1322 
1323 		set_state(user, USER_IN_WAITING);
1324 		do_arrival(user);
1325 		return;
1326 
1327 
1328 	  case USER_SIG_REJECT_ERR:
1329 		if (user->state != USER_IN_WAIT_REJ)
1330 			goto bad_state;
1331 		cc_user_err(user, arg2);
1332 
1333 		if (arg == NULL)
1334 			set_state(user, USER_IN_ARRIVED);
1335 		else {
1336 			set_state(user, USER_IN_WAITING);
1337 			do_arrival(user);
1338 		}
1339 		return;
1340 
1341 
1342 	  case USER_SIG_ACCEPT_INCOMING:
1343 	    {
1344 		/*
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
1347 		 * new endpoint.
1348 		 */
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;
1353 
1354 		if (user->state != USER_IN_ARRIVED) {
1355 			uni_msg_destroy(msg);
1356 			cc_user_err(user, ATMERR_BAD_STATE);
1357 			return;
1358 		}
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);
1365 
1366 			set_state(user, USER_IN_WAITING);
1367 			do_arrival(user);
1368 			return;
1369 		}
1370 		acc->newep[sizeof(acc->newep) - 1] = '\0';
1371 
1372 		LIST_FOREACH(newep, &user->cc->user_list, node_link)
1373 			if (strcmp(acc->newep, newep->name) == 0)
1374 				break;
1375 		uni_msg_destroy(msg);
1376 
1377 		if (newep == NULL) {
1378 			cc_user_err(user, ATMERR_BAD_ENDPOINT);
1379 			return;
1380 		}
1381 
1382 		if (newep->state != USER_NULL || newep->accepted != NULL) {
1383 			cc_user_err(user, ATMERR_BAD_STATE);
1384 			return;
1385 		}
1386 
1387 		set_state(user, USER_IN_WAIT_ACC);
1388 		cc_conn_sig(TAILQ_FIRST(&user->connq), CONN_SIG_ACCEPT, newep);
1389 
1390 		return;
1391 	    }
1392 
1393 
1394 	  case USER_SIG_ACCEPT_OK:
1395 		if (user->state != USER_IN_WAIT_ACC)
1396 			goto bad_state;
1397 		cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1398 
1399 		set_state(user, USER_IN_WAITING);
1400 		do_arrival(user);
1401 		return;
1402 
1403 
1404 	  case USER_SIG_ACCEPT_ERR:
1405 		if (user->state != USER_IN_WAIT_ACC)
1406 			goto bad_state;
1407 		cc_user_err(user, arg2);
1408 
1409 		if (arg == NULL) {
1410 			/* arg used as flag! */
1411 			set_state(user, USER_IN_ARRIVED);
1412 		} else {
1413 			set_state(user, USER_IN_WAITING);
1414 			do_arrival(user);
1415 		}
1416 		return;
1417 
1418 
1419 	  case USER_SIG_ACCEPTING:
1420 		if (user->state != USER_NULL)
1421 			goto bad_state;
1422 		set_state(user, USER_IN_ACCEPTING);
1423 		return;
1424 
1425 
1426 	  case USER_SIG_SETUP_COMPL:
1427 	    {
1428 		struct ccconn *conn = TAILQ_FIRST(&user->connq);
1429 
1430 		if (user->state != USER_IN_ACCEPTING)
1431 			goto bad_state;
1432 
1433 		user->state = USER_ACTIVE;
1434 		if (conn->bearer.cfg == UNI_BEARER_P2P) {
1435 			struct atm_p2p_call_active *act;
1436 
1437 			user->config = USER_P2P;
1438 			act = CCZALLOC(sizeof(*act));
1439 			if (act == NULL)
1440 				return;
1441 			act->connid = conn->connid;
1442 			cc_user_send(user, ATMOP_P2P_CALL_ACTIVE,
1443 			    act, sizeof(*act));
1444 			CCFREE(act);
1445 		} else {
1446 			struct atm_p2mp_call_active *act;
1447 
1448 			user->config = USER_LEAF;
1449 			act = CCZALLOC(sizeof(*act));
1450 			if (act == NULL)
1451 				return;
1452 			act->connid = conn->connid;
1453 			cc_user_send(user, ATMOP_P2MP_CALL_ACTIVE,
1454 			    act, sizeof(*act));
1455 			CCFREE(act);
1456 		}
1457 		return;
1458 	    }
1459 
1460 
1461 	  case USER_SIG_CALL_RELEASE:
1462 	    {
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;
1467 
1468 		conn = TAILQ_FIRST(&user->connq);
1469 		switch (user->state) {
1470 
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);
1476 			break;
1477 
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);
1483 			break;
1484 
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);
1490 			break;
1491 
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);
1497 			break;
1498 
1499 		  default:
1500 			uni_msg_destroy(msg);
1501 			cc_user_err(user, ATMERR_BAD_STATE);
1502 			goto bad_state;
1503 		}
1504 		uni_msg_destroy(msg);
1505 		return;
1506 	    }
1507 
1508 
1509 	  case USER_SIG_RELEASE_CONFIRM:
1510 	    {
1511 		struct atm_call_release *ind;
1512 
1513 		switch (user->state) {
1514 
1515 		  case USER_OUT_WAIT_CONF:	/* U3/A3 */
1516 		  case USER_ACTIVE:		/* U4/A8,A9,A10 */
1517 			cc_user_reset(user);
1518 			break;
1519 
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);
1526 			return;
1527 
1528 		  case USER_IN_ACCEPTING:	/* U11/A7 */
1529 			cc_user_reset(user);
1530 			break;
1531 
1532 		  default:
1533 			goto bad_state;
1534 		}
1535 
1536 		ind = CCZALLOC(sizeof(*ind));
1537 		if (ind == NULL)
1538 			return;
1539 		memcpy(ind->cause, user->cause, sizeof(ind->cause));
1540 		cc_user_send(user, ATMOP_CALL_RELEASE, ind, sizeof(*ind));
1541 		CCFREE(ind);
1542 		return;
1543 	    }
1544 
1545 
1546 	  case USER_SIG_RELEASE_ERR:
1547 		switch (user->state) {
1548 
1549 		  case USER_REL_WAIT:		/* U5/A8,A9,A10 */
1550 			set_state(user, USER_ACTIVE);
1551 			cc_user_err(user, ATM_MKUNIERR(arg2));
1552 			break;
1553 
1554 		  case USER_REL_WAIT_CONF:	/* U14/A3 */
1555 			cc_user_err(user, ATM_MKUNIERR(arg2));
1556 			cc_user_active(user);
1557 			break;
1558 
1559 		  case USER_REL_WAIT_SCOMP:	/* U12/A7 */
1560 			set_state(user, USER_IN_ACCEPTING);
1561 			cc_user_err(user, ATM_MKUNIERR(arg2));
1562 			break;
1563 
1564 		  default:
1565 			goto bad_state;
1566 		}
1567 		return;
1568 
1569 
1570 	  case USER_SIG_ADD_PARTY:
1571 	    {
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;
1576 
1577 		if (user->state != USER_ACTIVE || user->config != USER_ROOT) {
1578 			uni_msg_destroy(msg);
1579 			cc_user_err(user, ATMERR_BAD_STATE);
1580 			return;
1581 		}
1582 
1583 		if (add->leaf_ident == 0 || add->leaf_ident >= 32786) {
1584 			uni_msg_destroy(msg);
1585 			cc_user_err(user, ATMERR_BAD_LEAF_IDENT);
1586 			return;
1587 		}
1588 
1589 		conn = TAILQ_FIRST(&user->connq);
1590 		conn->called = add->called;
1591 
1592 		cc_conn_sig(conn, CONN_SIG_ADD_PARTY,
1593 		    (void *)(uintptr_t)add->leaf_ident);
1594 
1595 		uni_msg_destroy(msg);
1596 		return;
1597 	    }
1598 
1599 
1600 	  case USER_SIG_ADD_PARTY_ERR:
1601 		if (user->state != USER_ACTIVE)
1602 			goto bad_state;
1603 		cc_user_err(user, arg2);
1604 		return;
1605 
1606 
1607 	  case USER_SIG_ADD_PARTY_OK:
1608 		if (user->state != USER_ACTIVE)
1609 			goto bad_state;
1610 		cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1611 		return;
1612 
1613 
1614 	  case USER_SIG_ADD_PARTY_ACK:
1615 	    {
1616 		u_int leaf_ident = arg2;
1617 		struct atm_add_party_success *succ;
1618 
1619 		if (user->state != USER_ACTIVE)
1620 			goto bad_state;
1621 
1622 		succ = CCZALLOC(sizeof(*succ));
1623 		if (succ == NULL)
1624 			return;
1625 
1626 		succ->leaf_ident = leaf_ident;
1627 		cc_user_send(user, ATMOP_ADD_PARTY_SUCCESS,
1628 		    succ, sizeof(*succ));
1629 
1630 		CCFREE(succ);
1631 		return;
1632 	    }
1633 
1634 
1635 	  case USER_SIG_ADD_PARTY_REJ:
1636 	    {
1637 		u_int leaf_ident = arg2;
1638 		struct atm_add_party_reject *reject;
1639 
1640 		if (user->state != USER_ACTIVE)
1641 			goto bad_state;
1642 
1643 		reject = CCZALLOC(sizeof(*reject));
1644 		if (reject == NULL)
1645 			return;
1646 
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));
1651 
1652 		CCFREE(reject);
1653 		return;
1654 	    }
1655 
1656 
1657 	  case USER_SIG_DROP_PARTY:
1658 	    {
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;
1663 
1664 		if (user->state != USER_ACTIVE || user->config != USER_ROOT) {
1665 			uni_msg_destroy(msg);
1666 			cc_user_err(user, ATMERR_BAD_STATE);
1667 			return;
1668 		}
1669 
1670 		if (drop->leaf_ident >= 32786) {
1671 			uni_msg_destroy(msg);
1672 			cc_user_err(user, ATMERR_BAD_LEAF_IDENT);
1673 			return;
1674 		}
1675 
1676 		conn = TAILQ_FIRST(&user->connq);
1677 		conn->cause[0] = drop->cause;
1678 		memset(&conn->cause[1], 0, sizeof(conn->cause[1]));
1679 
1680 		cc_conn_sig(conn, CONN_SIG_DROP_PARTY,
1681 		    (void *)(uintptr_t)drop->leaf_ident);
1682 
1683 		uni_msg_destroy(msg);
1684 		return;
1685 	    }
1686 
1687 
1688 	  case USER_SIG_DROP_PARTY_ERR:
1689 		if (user->state != USER_ACTIVE)
1690 			goto bad_state;
1691 		cc_user_err(user, arg2);
1692 		return;
1693 
1694 
1695 	  case USER_SIG_DROP_PARTY_OK:
1696 		if (user->state != USER_ACTIVE)
1697 			goto bad_state;
1698 		cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1699 		return;
1700 
1701 
1702 	  case USER_SIG_DROP_PARTY_IND:
1703 	    {
1704 		u_int leaf_ident = arg2;
1705 		struct atm_drop_party *drop;
1706 
1707 		if (user->state != USER_ACTIVE)
1708 			goto bad_state;
1709 
1710 		drop = CCZALLOC(sizeof(*drop));
1711 		if (drop == NULL)
1712 			return;
1713 
1714 		drop->leaf_ident = leaf_ident;
1715 		drop->cause = user->cause[0];
1716 		cc_user_send(user, ATMOP_DROP_PARTY, drop, sizeof(*drop));
1717 
1718 		CCFREE(drop);
1719 		return;
1720 	    }
1721 
1722 
1723 	  case USER_SIG_QUERY_ATTR:
1724 	    {
1725 		struct uni_msg *msg = arg;
1726 		struct atm_query_connection_attributes *req;
1727 		struct ccconn *conn;
1728 
1729 		if (user->aborted) {
1730 			cc_user_err(user, ATMERR_PREVIOUSLY_ABORTED);
1731 			uni_msg_destroy(msg);
1732 			return;
1733 		}
1734 		conn = cc_query_check(user);
1735 		if (conn == NULL) {
1736 			cc_user_err(user, ATMERR_BAD_STATE);
1737 			uni_msg_destroy(msg);
1738 			return;
1739 		}
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);
1744 		return;
1745 	    }
1746 
1747 	  case USER_SIG_QUERY_ATTR_X:
1748 	    {
1749 		struct uni_msg *msg = arg;
1750 		struct atm_query_connection_attributes_x *req;
1751 		struct ccconn *conn;
1752 
1753 		conn = cc_query_check(user);
1754 		if (conn == NULL) {
1755 			cc_user_err(user, ATMERR_BAD_STATE);
1756 			uni_msg_destroy(msg);
1757 			return;
1758 		}
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);
1763 		return;
1764 	    }
1765 
1766 	  case USER_SIG_SET_ATTR:
1767 	    {
1768 		struct uni_msg *msg = arg;
1769 		struct atm_set_connection_attributes *req;
1770 		struct ccconn *conn;
1771 
1772 		if (user->aborted) {
1773 			cc_user_err(user, ATMERR_PREVIOUSLY_ABORTED);
1774 			uni_msg_destroy(msg);
1775 			return;
1776 		}
1777 		conn = cc_set_check(user);
1778 		if (conn == NULL) {
1779 			cc_user_err(user, ATMERR_BAD_STATE);
1780 			uni_msg_destroy(msg);
1781 			return;
1782 		}
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);
1787 		return;
1788 	    }
1789 
1790 	  case USER_SIG_SET_ATTR_X:
1791 	    {
1792 		struct uni_msg *msg = arg;
1793 		struct atm_set_connection_attributes_x *req;
1794 		struct ccconn *conn;
1795 
1796 		conn = cc_set_check(user);
1797 		if (conn == NULL) {
1798 			cc_user_err(user, ATMERR_BAD_STATE);
1799 			uni_msg_destroy(msg);
1800 			return;
1801 		}
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]),
1806 		    uni_msg_len(msg) -
1807 		    offsetof(struct atm_set_connection_attributes_x, attr) -
1808 		    req->count * sizeof(req->attr[0]));
1809 		uni_msg_destroy(msg);
1810 		return;
1811 	    }
1812 
1813 	  case USER_SIG_QUERY_STATE:
1814 	    {
1815 		struct atm_epstate state;
1816 
1817 		strcpy(state.name, user->name);
1818 		switch (user->state) {
1819 
1820 		  case USER_NULL:
1821 			if (user->accepted != NULL)
1822 				state.state = ATM_A7;
1823 			else
1824 				state.state = ATM_A1;
1825 			break;
1826 
1827 		  case USER_OUT_PREPARING:
1828 			state.state = ATM_A2;
1829 			break;
1830 
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;
1837 			break;
1838 
1839 		  case USER_ACTIVE:
1840 		  case USER_REL_WAIT:
1841 			switch (user->config) {
1842 
1843 			  case USER_P2P:
1844 				state.state = ATM_A8;
1845 				break;
1846 
1847 			  case USER_ROOT:
1848 				state.state = ATM_A9;
1849 				break;
1850 
1851 			  case USER_LEAF:
1852 				state.state = ATM_A10;
1853 				break;
1854 			}
1855 			break;
1856 
1857 		  case USER_IN_PREPARING:
1858 			state.state = ATM_A4;
1859 			break;
1860 
1861 		  case USER_IN_WAITING:
1862 			state.state = ATM_A5;
1863 			break;
1864 
1865 		  case USER_IN_ARRIVED:
1866 		  case USER_IN_WAIT_REJ:
1867 		  case USER_IN_WAIT_ACC:
1868 			state.state = ATM_A6;
1869 			break;
1870 
1871 		  case USER_IN_ACCEPTING:
1872 		  case USER_REL_WAIT_SCOMP:
1873 			state.state = ATM_A7;
1874 			break;
1875 		}
1876 		cc_user_ok(user, ATMRESP_STATE, &state, sizeof(state));
1877 		return;
1878 	    }
1879 
1880 	  case USER_SIG_GET_LOCAL_PORT_INFO:
1881 	    {
1882 		struct uni_msg *msg = arg;
1883 		struct atm_port_list *list;
1884 		size_t list_len;
1885 
1886 		list = cc_get_local_port_info(user->cc,
1887 		    uni_msg_rptr(msg, struct atm_get_local_port_info *)->port,
1888 		    &list_len);
1889 		uni_msg_destroy(msg);
1890 		if (list == NULL) {
1891 			cc_user_err(user, ATMERR_NOMEM);
1892 			return;
1893 		}
1894 		cc_user_ok(user, ATMRESP_PORTS, list, list_len);
1895 		CCFREE(list);
1896 		return;
1897 	    }
1898 
1899 	  case USER_SIG_ABORT_CONNECTION:
1900 	    {
1901 		struct uni_msg *msg = arg;
1902 		struct atm_abort_connection *abo = uni_msg_rptr(msg,
1903 		    struct atm_abort_connection *);
1904 
1905 		cc_user_abort(user, &abo->cause);
1906 		uni_msg_destroy(msg);
1907 		cc_user_ok(user, ATMRESP_NONE, NULL, 0);
1908 		return;
1909 	    }
1910 
1911 	}
1912 	if (user->cc->log & CCLOG_USER_SIG)
1913 		cc_user_log(user, "bad signal=%u in state=%u",
1914 		    sig, user->state);
1915 	return;
1916 
1917   bad_state:
1918 	if (user->cc->log & CCLOG_USER_SIG)
1919 		cc_user_log(user, "bad state=%u for signal=%u",
1920 		    user->state, sig);
1921 	return;
1922 }
1923