]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/ngatm/netnatm/api/cc_user.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / contrib / ngatm / netnatm / api / cc_user.c
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 <harti@freebsd.org>
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 *
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
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
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
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
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 *
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
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
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
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
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
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
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 *
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
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 *
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
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
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
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
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 }