]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/ngatm/netnatm/sig/unipriv.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / ngatm / netnatm / sig / unipriv.h
1 /*
2  * Copyright (c) 1996-2003
3  *      Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4  *      All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * Author: Hartmut Brandt <harti@freebsd.org>
28  *
29  * $Begemot: libunimsg/netnatm/sig/unipriv.h,v 1.17 2004/07/08 08:22:25 brandt Exp $
30  *
31  * Private UNI stuff.
32  */
33 #ifndef unipriv_h
34 #define unipriv_h
35
36 #ifdef _KERNEL
37 #ifdef __FreeBSD__
38 #include <netgraph/atm/uni/ng_uni_cust.h>
39 #endif
40 #else
41 #include "unicust.h"
42 #endif
43
44 struct call;
45 struct party;
46
47 enum cu_stat {
48         CU_STAT0,       /* AAL connection released */
49         CU_STAT1,       /* awaiting establish */
50         CU_STAT2,       /* awaiting release */
51         CU_STAT3,       /* AAL connection established */
52 };
53
54 /*
55  * Internal Signals
56  */
57 #define DEF_COORD_SIGS                                          \
58   DEF_PRIV_SIG(O_SAAL_ESTABLISH_indication,     SAAL)           \
59   DEF_PRIV_SIG(O_SAAL_ESTABLISH_confirm,        SAAL)           \
60   DEF_PRIV_SIG(O_SAAL_RELEASE_indication,       SAAL)           \
61   DEF_PRIV_SIG(O_SAAL_RELEASE_confirm,          SAAL)           \
62   DEF_PRIV_SIG(O_SAAL_DATA_indication,          SAAL)           \
63   DEF_PRIV_SIG(O_SAAL_UDATA_indication,         SAAL)           \
64   DEF_PRIV_SIG(O_T309,                          Coord)          \
65   DEF_PRIV_SIG(O_DATA,                          Coord)          \
66   DEF_PRIV_SIG(O_LINK_ESTABLISH_request,        API)            \
67   DEF_PRIV_SIG(O_LINK_RELEASE_request,          API)            \
68   DEF_PRIV_SIG(O_RESET_request,                 API)            \
69   DEF_PRIV_SIG(O_RESET_response,                API)            \
70   DEF_PRIV_SIG(O_RESET_ERROR_response,          API)            \
71   DEF_PRIV_SIG(O_SETUP_request,                 API)            \
72   DEF_PRIV_SIG(O_SETUP_response,                API)            \
73   DEF_PRIV_SIG(O_SETUP_COMPLETE_request,        API)            \
74   DEF_PRIV_SIG(O_PROCEEDING_request,            API)            \
75   DEF_PRIV_SIG(O_ALERTING_request,              API)            \
76   DEF_PRIV_SIG(O_RELEASE_request,               API)            \
77   DEF_PRIV_SIG(O_RELEASE_response,              API)            \
78   DEF_PRIV_SIG(O_NOTIFY_request,                API)            \
79   DEF_PRIV_SIG(O_STATUS_ENQUIRY_request,        API)            \
80   DEF_PRIV_SIG(O_ADD_PARTY_request,             API)            \
81   DEF_PRIV_SIG(O_PARTY_ALERTING_request,        API)            \
82   DEF_PRIV_SIG(O_ADD_PARTY_ACK_request,         API)            \
83   DEF_PRIV_SIG(O_ADD_PARTY_REJ_request,         API)            \
84   DEF_PRIV_SIG(O_DROP_PARTY_request,            API)            \
85   DEF_PRIV_SIG(O_DROP_PARTY_ACK_request,        API)            \
86   DEF_PRIV_SIG(O_ABORT_CALL_request,            API)            \
87   DEF_PRIV_SIG(O_CALL_DESTROYED,                CallControl)    \
88   DEF_PRIV_SIG(O_RESET_indication,              ResetRespond)   \
89   DEF_PRIV_SIG(O_END,                           Coord)
90
91 #define DEF_RESPOND_SIGS                                        \
92   DEF_PRIV_SIG(R_RESTART,                       Coord)          \
93   DEF_PRIV_SIG(R_STATUS,                        Coord)          \
94   DEF_PRIV_SIG(R_RESET_response,                Coord)          \
95   DEF_PRIV_SIG(R_RESET_ERROR_response,          Coord)          \
96   DEF_PRIV_SIG(R_T317,                          ResetRespond)   \
97   DEF_PRIV_SIG(R_END,                           ResetRespond)
98
99 #define DEF_START_SIGS                                          \
100   DEF_PRIV_SIG(S_RESTART_ACK,                   Coord)          \
101   DEF_PRIV_SIG(S_STATUS,                        Coord)          \
102   DEF_PRIV_SIG(S_RESET_request,                 Coord)          \
103   DEF_PRIV_SIG(S_T316,                          ResetStart)     \
104   DEF_PRIV_SIG(S_END,                           ResetStart)
105
106 #define DEF_CALL_SIGS                                           \
107   DEF_PRIV_SIG(C_LINK_ESTABLISH_confirm,        Coord)          \
108   DEF_PRIV_SIG(C_LINK_ESTABLISH_indication,     Coord)          \
109   DEF_PRIV_SIG(C_LINK_ESTABLISH_ERROR_indication,Coord)         \
110   DEF_PRIV_SIG(C_LINK_RELEASE_indication,       Coord)          \
111   DEF_PRIV_SIG(C_SETUP_request,                 Coord)          \
112   DEF_PRIV_SIG(C_SETUP_response,                Coord)          \
113   DEF_PRIV_SIG(C_SETUP_COMPLETE_request,        Coord)          \
114   DEF_PRIV_SIG(C_PROCEEDING_request,            Coord)          \
115   DEF_PRIV_SIG(C_ALERTING_request,              Coord)          \
116   DEF_PRIV_SIG(C_RELEASE_request,               Coord)          \
117   DEF_PRIV_SIG(C_RELEASE_response,              Coord)          \
118   DEF_PRIV_SIG(C_NOTIFY_request,                Coord)          \
119   DEF_PRIV_SIG(C_STATUS_ENQUIRY_request,        Coord)          \
120   DEF_PRIV_SIG(C_ADD_PARTY_request,             Coord)          \
121   DEF_PRIV_SIG(C_PARTY_ALERTING_request,        Coord)          \
122   DEF_PRIV_SIG(C_ADD_PARTY_ACK_request,         Coord)          \
123   DEF_PRIV_SIG(C_ADD_PARTY_REJ_request,         Coord)          \
124   DEF_PRIV_SIG(C_DROP_PARTY_request,            Coord)          \
125   DEF_PRIV_SIG(C_DROP_PARTY_ACK_request,        Coord)          \
126   DEF_PRIV_SIG(C_ABORT_CALL_request,            Coord)          \
127   DEF_PRIV_SIG(C_UNKNOWN,                       Coord)          \
128   DEF_PRIV_SIG(C_SETUP,                         Coord)          \
129   DEF_PRIV_SIG(C_CALL_PROC,                     Coord)          \
130   DEF_PRIV_SIG(C_ALERTING,                      Coord)          \
131   DEF_PRIV_SIG(C_CONNECT,                       Coord)          \
132   DEF_PRIV_SIG(C_CONNECT_ACK,                   Coord)          \
133   DEF_PRIV_SIG(C_RELEASE,                       Coord)          \
134   DEF_PRIV_SIG(C_RELEASE_COMPL,                 Coord)          \
135   DEF_PRIV_SIG(C_COBISETUP,                     Coord)          \
136   DEF_PRIV_SIG(C_NOTIFY,                        Coord)          \
137   DEF_PRIV_SIG(C_STATUS,                        Coord)          \
138   DEF_PRIV_SIG(C_STATUS_ENQ,                    Coord)          \
139   DEF_PRIV_SIG(C_ADD_PARTY,                     Coord)          \
140   DEF_PRIV_SIG(C_PARTY_ALERTING,                Coord)          \
141   DEF_PRIV_SIG(C_ADD_PARTY_ACK,                 Coord)          \
142   DEF_PRIV_SIG(C_ADD_PARTY_REJ,                 Coord)          \
143   DEF_PRIV_SIG(C_DROP_PARTY,                    Coord)          \
144   DEF_PRIV_SIG(C_DROP_PARTY_ACK,                Coord)          \
145   DEF_PRIV_SIG(C_CALL_DELETE,                   CallControl)    \
146   DEF_PRIV_SIG(C_T301,                          CallControl)    \
147   DEF_PRIV_SIG(C_T303,                          CallControl)    \
148   DEF_PRIV_SIG(C_T308,                          CallControl)    \
149   DEF_PRIV_SIG(C_T310,                          CallControl)    \
150   DEF_PRIV_SIG(C_T313,                          CallControl)    \
151   DEF_PRIV_SIG(C_T322,                          CallControl)    \
152   DEF_PRIV_SIG(C_DROP_PARTY_indication,         PartyControl)   \
153   DEF_PRIV_SIG(C_SEND_DROP_PARTY,               PartyControl)   \
154   DEF_PRIV_SIG(C_DROP_PARTY_ACK_indication,     PartyControl)   \
155   DEF_PRIV_SIG(C_SEND_DROP_PARTY_ACK,           PartyControl)   \
156   DEF_PRIV_SIG(C_ADD_PARTY_REJ_indication,      PartyControl)   \
157   DEF_PRIV_SIG(C_SEND_ADD_PARTY_REJ,            PartyControl)   \
158   DEF_PRIV_SIG(C_SEND_STATUS_ENQ,               PartyControl)   \
159   DEF_PRIV_SIG(C_PARTY_DESTROYED,               PartyControl)   \
160   DEF_PRIV_SIG(C_END,                           CallControl)
161
162 #define DEF_PARTY_SIGS                                                  \
163   DEF_PRIV_SIG(P_SETUP,                         CallControl)            \
164   DEF_PRIV_SIG(P_ALERTING,                      CallControl)            \
165   DEF_PRIV_SIG(P_CONNECT,                       CallControl)            \
166   DEF_PRIV_SIG(P_CONNECT_ACK,                   CallControl)            \
167   DEF_PRIV_SIG(P_RELEASE,                       CallControl)            \
168   DEF_PRIV_SIG(P_RELEASE_COMPL,                 CallControl)            \
169   DEF_PRIV_SIG(P_STATUS,                        CallControl)            \
170   DEF_PRIV_SIG(P_ADD_PARTY,                     CallControl)            \
171   DEF_PRIV_SIG(P_PARTY_ALERTING,                CallControl)            \
172   DEF_PRIV_SIG(P_ADD_PARTY_ACK,                 CallControl)            \
173   DEF_PRIV_SIG(P_ADD_PARTY_REJ,                 CallControl)            \
174   DEF_PRIV_SIG(P_DROP_PARTY,                    CallControl)            \
175   DEF_PRIV_SIG(P_DROP_PARTY_ACK,                CallControl)            \
176   DEF_PRIV_SIG(P_SETUP_request,                 CallControl)            \
177   DEF_PRIV_SIG(P_SETUP_response,                CallControl)            \
178   DEF_PRIV_SIG(P_SETUP_COMPL_request,           CallControl)            \
179   DEF_PRIV_SIG(P_ALERTING_request,              CallControl)            \
180   DEF_PRIV_SIG(P_RELEASE_request,               CallControl)            \
181   DEF_PRIV_SIG(P_RELEASE_response,              CallControl)            \
182   DEF_PRIV_SIG(P_RELEASE_confirm,               CallControl)            \
183   DEF_PRIV_SIG(P_STATUS_ENQUIRY_request,        CallControl)            \
184   DEF_PRIV_SIG(P_ADD_PARTY_request,             CallControl)            \
185   DEF_PRIV_SIG(P_PARTY_ALERTING_request,        CallControl)            \
186   DEF_PRIV_SIG(P_ADD_PARTY_ACK_request,         CallControl)            \
187   DEF_PRIV_SIG(P_ADD_PARTY_REJ_request,         CallControl)            \
188   DEF_PRIV_SIG(P_DROP_PARTY_request,            CallControl)            \
189   DEF_PRIV_SIG(P_DROP_PARTY_ACK_request,        CallControl)            \
190   DEF_PRIV_SIG(P_PARTY_DELETE,                  PartyControl)           \
191   DEF_PRIV_SIG(P_T397,                          PartyControl)           \
192   DEF_PRIV_SIG(P_T398,                          PartyControl)           \
193   DEF_PRIV_SIG(P_T399,                          PartyControl)           \
194   DEF_PRIV_SIG(P_END,                           PartyControl)
195
196
197 #define DEF_PRIV_SIG(NAME, FROM)        SIG##NAME,
198 enum coord_sig {
199         DEF_COORD_SIGS
200 };
201 enum respond_sig {
202         DEF_RESPOND_SIGS
203 };
204 enum start_sig {
205         DEF_START_SIGS
206 };
207 enum call_sig {
208         DEF_CALL_SIGS
209 };
210 enum party_sig {
211         DEF_PARTY_SIGS
212 };
213 #undef DEF_PRIV_SIG
214
215 /*************************************************************
216  *
217  * SIGNALS and SIGNAL QUEUES
218  */
219 enum {
220         SIG_COORD,
221         SIG_RESET_START,
222         SIG_RESET_RESP,
223         SIG_CALL,
224         SIG_PARTY,
225 };
226
227 struct sig {
228         TAILQ_ENTRY(sig) link;
229         u_int           type;   /* one of the above */
230         struct call     *call;  /* call to send to */
231         struct party    *party; /* party to send to */
232         uint32_t        sig;    /* the signal */
233         uint32_t        cookie; /* user cookie */
234         struct uni_msg  *msg;   /* attached message */
235         struct uni_all  *u;     /* dito */
236 };
237 TAILQ_HEAD(sigqueue, sig);
238
239 #define SIGQ_CLEAR(Q)                                                   \
240     do {                                                                \
241         struct sig *s;                                                  \
242         while(!TAILQ_EMPTY(Q)) {                                        \
243                 s = TAILQ_FIRST(Q);                                     \
244                 TAILQ_REMOVE(Q, s, link);                               \
245                 if(s->msg) uni_msg_destroy(s->msg);                     \
246                 if(s->u) UNI_FREE(s->u);                                \
247                 SIG_FREE(s);                                            \
248         }                                                               \
249     } while(0)
250
251 void uni_sig_party(struct party *, enum party_sig, uint32_t cookie,
252     struct uni_msg *, struct uni_all *);
253 void uni_sig_call(struct call *, enum call_sig, uint32_t cookie,
254     struct uni_msg *, struct uni_all *);
255 void uni_sig_coord(struct uni *, enum coord_sig, uint32_t cookie,
256     struct uni_msg *);
257 void uni_sig_start(struct uni *, enum start_sig, uint32_t cookie,
258     struct uni_msg *, struct uni_all *);
259 void uni_sig_respond(struct uni *, enum respond_sig, uint32_t cookie,
260     struct uni_msg *, struct uni_all *);
261
262 /*************************************************************
263  *
264  * CALL INSTANCES
265  */
266 struct party {
267         struct call             *call;
268         TAILQ_ENTRY(party)      link;
269         u_int                   epref;  /* endpoint reference */
270         u_int                   flags;  /* flags */
271         enum uni_epstate        state;  /* party state */
272
273         struct uni_timer        t397;   /* T397 */
274         struct uni_timer        t398;   /* T398 */
275         struct uni_timer        t399;   /* T399 */
276 };
277 #define PARTY_MINE      0x0001          /* must be 1 */
278 #define PARTY_CONNECT   0x0002          /* connect request from this party */
279
280 TAILQ_HEAD(partyqueue, party);
281
282 void uni_destroy_party(struct party *, int);
283 struct party *uni_find_party(struct call *, struct uni_ie_epref *);
284 struct party *uni_find_partyx(struct call *, u_int epref, u_int mine);
285 struct party *uni_create_party(struct call *, struct uni_ie_epref *);
286 struct party *uni_create_partyx(struct call *, u_int epref, u_int mine,
287     uint32_t cookie);
288 u_int uni_party_act_count(struct call *, int);
289
290 enum call_type {
291         CALL_NULL,      /* not known yet */
292         CALL_P2P,       /* normal point-to-point call */
293         CALL_COBI,      /* Q.2932.1 COBI call */
294         CALL_ROOT,      /* point-to-multipoint root */
295         CALL_LEAF,      /* point-to-multipoint leaf */
296 };
297
298 enum call_state {
299         CALLST_NULL,
300         CALLST_U1, CALLST_U3, CALLST_U4, CALLST_U6, CALLST_U7, CALLST_U8,
301         CALLST_U9, CALLST_U10, CALLST_U11, CALLST_U12,
302         CALLST_N1, CALLST_N3, CALLST_N4, CALLST_N6, CALLST_N7, CALLST_N8,
303         CALLST_N9, CALLST_N10, CALLST_N11, CALLST_N12
304 };
305
306 struct call {
307         TAILQ_ENTRY(call)       link;   /* link between calls */
308         struct uni              *uni;   /* backpointer to owning UNI */
309         u_int                   cref;   /* call reference value or lij seqno */
310         u_int                   mine;   /* if TRUE this is my call */
311         enum call_type          type;   /* what call is it */
312         enum call_state         cstate; /* the state of the call */
313         struct uni_ie_connid    connid; /* the connection ID */
314         struct uni_setup        msg_setup;      /* retransmission */
315         struct uni_release      msg_release;    /* retransmission */
316         struct uni_ie_epref     stat_epref;     /* retransmission */
317         struct partyqueue       parties;
318         u_int                   se_active;      /* status enquiry active */
319         u_int                   epref_alloc;
320
321         struct uni_timer        t308;   /* T303 */
322         u_int                   cnt308;
323
324         struct uni_timer        t303;   /* T303 */
325         u_int                   cnt303;
326
327         struct uni_timer        t301;   /* T301 */
328         struct uni_timer        t310;   /* T310 */
329         struct uni_timer        t313;   /* T313 */
330
331         struct uni_timer        t322;   /* T322 */
332         u_int                   cnt322;
333 };
334
335 TAILQ_HEAD(callqueue, call);
336
337 struct call *uni_find_call(struct uni *, struct uni_cref *);
338 struct call *uni_find_callx(struct uni *, u_int cref, u_int mine);
339 struct call *uni_create_call(struct uni *, u_int cref, u_int mine,
340         uint32_t cookie);
341 struct call *uni_create_new_call(struct uni *, uint32_t cookie);
342 void uni_destroy_call(struct call *, int);
343
344 void uni_bad_message(struct call *, struct uni_all *, u_int,
345     struct uni_ie_epref *, int);
346
347 extern const struct callstates {
348         const char *name;
349         enum uni_callstate ext;
350 } callstates[];
351
352 /*************************************************************
353  *
354  * UNI INSTANCE
355  */
356 struct uni {
357         void                    *arg;   /* user arg */
358         const struct uni_funcs  *funcs;
359
360         enum uni_proto          proto;  /* protocol */
361         struct unicx            cx;     /* decoding/coding context */
362         int                     sb_tb : 1;      /* Sb-Tb/Tb point */
363
364         struct sigqueue         workq;  /* work queue */
365         struct sigqueue         delq;   /* delayed signal queue */
366         int                     working;
367
368         uint32_t                cref_alloc;
369
370         enum cu_stat            custat; /* coordinator state */
371         struct uni_timer        t309;
372         u_int                   timer309;
373
374         enum uni_callstate      glob_start;
375         enum uni_callstate      glob_respond;
376         struct uni_timer        t316;
377         struct uni_timer        t317;
378         struct uni_ie_connid    connid_start;
379         struct uni_ie_connid    connid_respond;
380         u_int                   cnt316;
381         struct uni_ie_restart   restart_start;
382
383         struct callqueue        calls;
384
385         struct uni_ie_cause     cause;  /* working area for verify */
386
387         /* tuneable parameters */
388         u_int                   timer301;
389         u_int                   init303;
390         u_int                   timer303;
391         u_int                   init308;
392         u_int                   timer308;
393         u_int                   timer310;
394         u_int                   timer313;
395         u_int                   init316;
396         u_int                   timer316;
397         u_int                   timer317;
398         u_int                   timer322;
399         u_int                   init322;
400         u_int                   timer397;
401         u_int                   timer398;
402         u_int                   timer399;
403
404         u_int                   debug[UNI_MAXFACILITY];
405 };
406
407 void uniapi_uni_error(struct uni *uni, uint32_t reason, uint32_t cookie,
408         uint32_t state);
409 void uniapi_call_error(struct call *c, uint32_t reason, uint32_t cookie);
410 void uniapi_party_error(struct party *p, uint32_t reason, uint32_t cookie);
411
412 /*************************************************************
413  *
414  * INLINE FUNCTIONS
415  */
416
417 /* Enqueue a signal in the working queue */
418 void uni_enq_sig(struct uni *, u_int, struct call *, struct party *,
419     uint32_t, uint32_t, struct uni_msg *, struct uni_all *);
420
421 /* Enqueue a signal in the delayed queue */
422 void uni_delenq_sig(struct uni *, u_int, struct call *, struct party *,
423     uint32_t, uint32_t, struct uni_msg *, struct uni_all *);
424
425 /* Enqueue a signal to the coordinator */
426 #define uni_enq_coord(UNI, SIG, COOKIE, MSG) do {                       \
427         uni_enq_sig((UNI), SIG_COORD, NULL, NULL,                       \
428             (SIG), (COOKIE), (MSG), NULL);                              \
429     } while (0)
430
431 /* Enqueue a delayed signal to the coordinator */
432 #define uni_delenq_coord(UNI, SIG, COOKIE, MSG) do {                    \
433         uni_delenq_sig((UNI), SIG_COORD, NULL, NULL,                    \
434             (SIG), (COOKIE), (MSG), NULL);                              \
435     } while (0)
436
437 /* Enqueue a signal to a call */
438 #define uni_enq_call(CALL, SIG, COOKIE, MSG, U) do {                    \
439         uni_enq_sig((CALL)->uni, SIG_CALL, (CALL), NULL,                \
440             (SIG), (COOKIE), (MSG), (U));                               \
441     } while (0)
442
443 /* Enqueue a signal to a party */
444 #define uni_enq_party(PARTY, SIG, COOKIE, MSG, U) do {                  \
445         uni_enq_sig((PARTY)->call->uni, SIG_PARTY, (PARTY)->call,       \
446             (PARTY), (SIG), (COOKIE), (MSG), (U));                      \
447     } while (0)
448
449 /* Enqueue a signal to RESET-START */
450 #define uni_enq_start(UNI, SIG, COOKIE, MSG, U) do {                    \
451         uni_enq_sig((UNI), SIG_RESET_START, NULL, NULL,                 \
452             (SIG), (COOKIE), (MSG), (U));                               \
453     } while (0)
454
455 /* Enqueue a signal to RESET-RESPOND */
456 #define uni_enq_resp(UNI, SIG, COOKIE, MSG, U) do {                     \
457         uni_enq_sig((UNI), SIG_RESET_RESP, NULL, NULL,                  \
458             (SIG), (COOKIE), (MSG), (U));                               \
459     } while (0)
460
461 int uni_send_output(struct uni_all *u, struct uni *uni);
462 void uni_undel(struct uni *, int (*)(struct sig *, void *), void *);
463 void uni_delsig(struct uni *, u_int, struct call *, struct party *);
464
465 void uni_release_compl(struct call *, struct uni_all *);
466
467 /*************************************************************/
468 /*
469  * Message verification.
470  */
471 #define MANDATE_IE(UNI,MSG,IE)                                          \
472     do {                                                                \
473         if (!IE_ISGOOD(MSG))                                            \
474                 uni_mandate_ie(UNI, IE);                                \
475     } while(0)
476
477 enum verify {
478         VFY_OK,         /* ok */
479         VFY_RAP,        /* report and proceed */
480         VFY_RAPU,       /* report and proceed becuase of unknown IEs */
481         VFY_I,          /* ignore */
482         VFY_CLR,        /* clear call */
483         VFY_RAI,        /* report and ignore */
484         VFY_RAIM,       /* report and ignore because if mandat. IE miss */
485 };
486
487 void uni_mandate_ie(struct uni *, enum uni_ietype);
488 void uni_mandate_epref(struct uni *, struct uni_ie_epref *);
489 enum verify uni_verify(struct uni *, enum uni_msgact);
490 void uni_respond_status_verify(struct uni *, struct uni_cref *,
491         enum uni_callstate, struct uni_ie_epref *, enum uni_epstate);
492 void uni_vfy_remove_unknown(struct uni *);
493 void uni_vfy_remove_cause(struct uni *);
494 void uni_vfy_collect_ies(struct uni *);
495
496
497 void uni_respond_status(struct uni *uni, struct uni_cref *cref,
498     enum uni_callstate cs, enum uni_cause c1);
499 void uni_respond_status_mtype(struct uni *uni, struct uni_cref *cref,
500     enum uni_callstate cs, enum uni_cause c1, u_int mtype);
501
502 #define FOREACH_ERR(E, UNI) \
503         for ((E) = (UNI)->cx.err; (E) < (UNI)->cx.err + (UNI)->cx.errcnt; (E)++)
504
505 #define ALLOC_API(TYPE,API)                                     \
506     ({                                                          \
507         TYPE *_tmp = NULL;                                      \
508                                                                 \
509         if(((API) = uni_msg_alloc(sizeof(TYPE))) != NULL) {     \
510                 _tmp = uni_msg_wptr((API), TYPE *);             \
511                 (API)->b_wptr += sizeof(TYPE);                  \
512                 memset(_tmp, 0, sizeof(TYPE));                  \
513         }                                                       \
514         _tmp;                                                   \
515     })
516
517 #if defined(__GNUC__) && __GNUC__ < 3
518
519 #define VERBOSE(UNI, FAC, LEVEL, ARGS...) do {                  \
520         if ((UNI)->debug[(FAC)] >= (LEVEL)) {                   \
521                 (UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC) ,\
522                    ## ARGS);                                    \
523         }                                                       \
524     } while(0)
525
526 #define VERBOSE0(UNI, FAC, ARGS...) do {                        \
527         (UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC) ,        \
528             ## ARGS);                                           \
529     } while(0)
530
531 #else
532
533 #define VERBOSE(UNI, FAC, LEVEL, ...) do {                      \
534         if ((UNI)->debug[(FAC)] >= (LEVEL)) {                   \
535                 (UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC), \
536                     __VA_ARGS__);                               \
537         }                                                       \
538     } while(0)
539
540 #define VERBOSE0(UNI, FAC, ...) do {                            \
541         (UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC),         \
542             __VA_ARGS__);                                       \
543     } while(0)
544
545 #endif
546
547 #define TIMER_INIT_UNI(U,T)     _TIMER_INIT(U,T)
548 #define TIMER_INIT_CALL(C,T)    _TIMER_INIT(C,T)
549 #define TIMER_INIT_PARTY(P,T)   _TIMER_INIT(P,T)
550
551 #define TIMER_DESTROY_UNI(U,T)          _TIMER_DESTROY(U, (U)->T)
552 #define TIMER_DESTROY_CALL(C,T)         _TIMER_DESTROY((C)->uni, (C)->T)
553 #define TIMER_DESTROY_PARTY(P,T)        _TIMER_DESTROY((P)->call->uni, (P)->T)
554
555 #define TIMER_STOP_UNI(U,T)     _TIMER_STOP(U, (U)->T)
556 #define TIMER_STOP_CALL(C,T)    _TIMER_STOP((C)->uni, (C)->T)
557 #define TIMER_STOP_PARTY(P,T)   _TIMER_STOP((P)->call->uni, (P)->T)
558
559 #define TIMER_START_UNI(U,T,N) _TIMER_START(U, U, (U)->T, N, _##T##_func)
560 #define TIMER_START_CALL(C,T,N) _TIMER_START(C->uni, C, (C)->T, N, _##T##_func)
561 #define TIMER_START_PARTY(P,T,N) _TIMER_START(P->call->uni, P, (P)->T, N, _##T##_func)
562
563 #endif