1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-26 11:47:31 +00:00

Virgin import of signaling layer of NgATM shared kernel/user part 0.91

This commit is contained in:
Hartmut Brandt 2003-11-07 08:46:22 +00:00
parent 0b6c80c996
commit 22e2dd6a2d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor-sys/ngatm/dist/; revision=122205
14 changed files with 10928 additions and 0 deletions

View File

@ -0,0 +1,80 @@
#
# Copyright (c) 2001-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Hartmut Brandt <harti@freebsd.org>
#
# $Begemot: libunimsg/atm/sig/genmsgcpyc.awk,v 1.3 2003/09/19 12:03:33 hbb Exp $
#
# Generate copy functions for messages
#
function begin() {
}
function first_entry() {
print "/* This file was created automatically"
print " * Source file: " id
print " * $FreeBSD$"
print " */"
print ""
print "#include <netnatm/msg/unistruct.h>"
print "#include <netnatm/sig/unimsgcpy.h>"
}
function end() {
}
function start_message() {
}
function end_message() {
print ""
print "void"
print "copy_msg_" msg "(struct uni_" msg " *src, struct uni_" msg " *dst)"
print "{"
for(i = 0; i < cnt; i++) {
if(ienum[i] != "-") {
print "\tu_int s, d;"
print ""
break
}
}
for(i = 0; i < cnt; i++) {
ie = iename[i]
if(ierep[i]) {
print "\tif(IE_ISGOOD(src->" ie "_repeat))"
print "\t\tdst->" ie "_repeat = src->" ie "_repeat;"
}
if(ienum[i] != "-") {
print "\tfor(s = d = 0; s < "ienum[i]"; s++)"
print "\t\tif(IE_ISGOOD(src->"ie"[s]))"
print "\t\t\tdst->"ie"[d++] = src->"ie"[s];"
} else {
print "\tif(IE_ISGOOD(src->"ie"))"
print "\t\tdst->"ie" = src->"ie";"
}
}
print "}"
}

View File

@ -0,0 +1,55 @@
#
# Copyright (c) 2001-2003
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Hartmut Brandt <harti@freebsd.org>
#
# $Begemot: libunimsg/atm/sig/genmsgcpyh.awk,v 1.3 2003/09/19 12:03:33 hbb Exp $
#
# Generate copy functions for messages
#
function begin() {
}
function first_entry() {
print "/* This file was created automatically"
print " * Source file: " id
print " * $FreeBSD$"
print " */"
print ""
}
function end() {
}
function start_message() {
}
function end_message() {
print ""
print "void"
print "copy_msg_" msg "(struct uni_" msg " *src, struct uni_" msg " *dst);"
print ""
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,622 @@
/*
* Copyright (c) 2002-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
* Kendy Kutzner <kutzner@fokus.fraunhofer.de>
*
* $Begemot: libunimsg/atm/sig/sig_print.c,v 1.4 2003/09/19 12:03:34 hbb Exp $
*/
#include <sys/types.h>
#ifdef _KERNEL
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/libkern.h>
#include <machine/stdarg.h>
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#endif
#include <netnatm/saal/sscfu.h>
#include <netnatm/msg/uni_hdr.h>
#include <netnatm/msg/unistruct.h>
#include <netnatm/msg/unimsglib.h>
#include <netnatm/msg/uniprint.h>
#include <netnatm/sig/uni.h>
#include <netnatm/sig/unisig.h>
#include <netnatm/sig/unidef.h>
const char *
uni_strerr(u_int err)
{
static const char *const errstr[] = {
#define DEF(NAME, VAL, STR) [UNIAPI_##NAME] STR,
UNIAPI_DEF_ERRORS(DEF)
#undef DEF
};
static char buf[100];
if (err >= sizeof(errstr)/sizeof(errstr[0]) || errstr[err] == NULL) {
sprintf(buf, "Unknown error %u", err);
return (buf);
}
return (errstr[err]);
}
#define D(M) [M] #M
static const char *const msgs[] = {
D(UNIAPI_ERROR),
D(UNIAPI_CALL_CREATED),
D(UNIAPI_CALL_DESTROYED),
D(UNIAPI_PARTY_CREATED),
D(UNIAPI_PARTY_DESTROYED),
D(UNIAPI_LINK_ESTABLISH_request),
D(UNIAPI_LINK_ESTABLISH_confirm),
D(UNIAPI_LINK_RELEASE_request),
D(UNIAPI_LINK_RELEASE_confirm),
D(UNIAPI_RESET_request),
D(UNIAPI_RESET_confirm),
D(UNIAPI_RESET_indication),
D(UNIAPI_RESET_ERROR_indication),
D(UNIAPI_RESET_response),
D(UNIAPI_RESET_ERROR_response),
D(UNIAPI_RESET_STATUS_indication),
D(UNIAPI_SETUP_request),
D(UNIAPI_SETUP_indication),
D(UNIAPI_SETUP_response),
D(UNIAPI_SETUP_confirm),
D(UNIAPI_SETUP_COMPLETE_indication),
D(UNIAPI_SETUP_COMPLETE_request),
D(UNIAPI_ALERTING_request),
D(UNIAPI_ALERTING_indication),
D(UNIAPI_PROCEEDING_request),
D(UNIAPI_PROCEEDING_indication),
D(UNIAPI_RELEASE_request),
D(UNIAPI_RELEASE_indication),
D(UNIAPI_RELEASE_response),
D(UNIAPI_RELEASE_confirm),
D(UNIAPI_NOTIFY_request),
D(UNIAPI_NOTIFY_indication),
D(UNIAPI_STATUS_indication),
D(UNIAPI_STATUS_ENQUIRY_request),
D(UNIAPI_ADD_PARTY_request),
D(UNIAPI_ADD_PARTY_indication),
D(UNIAPI_PARTY_ALERTING_request),
D(UNIAPI_PARTY_ALERTING_indication),
D(UNIAPI_ADD_PARTY_ACK_request),
D(UNIAPI_ADD_PARTY_ACK_indication),
D(UNIAPI_ADD_PARTY_REJ_request),
D(UNIAPI_ADD_PARTY_REJ_indication),
D(UNIAPI_DROP_PARTY_request),
D(UNIAPI_DROP_PARTY_indication),
D(UNIAPI_DROP_PARTY_ACK_request),
D(UNIAPI_DROP_PARTY_ACK_indication),
D(UNIAPI_ABORT_CALL_request),
};
#undef D
void
uni_print_api(char *buf, size_t bufsiz, u_int type, u_int cookie,
const void *msg, struct unicx *cx)
{
int old_dont_init = cx->dont_init;
uni_print_init(buf, bufsiz, cx);
cx->dont_init = 1;
if (type >= sizeof(msgs) / sizeof(msgs[0]) || msgs[type] == NULL) {
uni_print_flag("UNIAPI_UNKNOWN", cx);
uni_print_entry(cx, "sig", "%u", type);
uni_print_entry(cx, "cookie", "%u", cookie);
goto out;
}
uni_print_flag(msgs[type], cx);
uni_print_entry(cx, "cookie", "%u", cookie);
cx->indent++;
switch (type) {
case UNIAPI_ERROR:
{
const struct uniapi_error *api = msg;
uni_print_eol(cx);
uni_print_entry(cx, "reason", "%s", uni_strerr(api->reason));
uni_print_entry(cx, "state", "U%u", api->state);
break;
}
case UNIAPI_CALL_CREATED:
{
const struct uniapi_call_created *api = msg;
uni_print_cref(NULL, 0, &api->cref, cx);
break;
}
case UNIAPI_CALL_DESTROYED:
{
const struct uniapi_call_destroyed *api = msg;
uni_print_cref(NULL, 0, &api->cref, cx);
break;
}
case UNIAPI_PARTY_CREATED:
{
const struct uniapi_party_created *api = msg;
uni_print_cref(NULL, 0, &api->cref, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_EPREF,
(const union uni_ieall *)&api->epref, cx);
break;
}
case UNIAPI_PARTY_DESTROYED:
{
const struct uniapi_party_destroyed *api = msg;
uni_print_cref(NULL, 0, &api->cref, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_EPREF,
(const union uni_ieall *)&api->epref, cx);
break;
}
case UNIAPI_LINK_ESTABLISH_request:
case UNIAPI_LINK_ESTABLISH_confirm:
case UNIAPI_LINK_RELEASE_request:
case UNIAPI_LINK_RELEASE_confirm:
break;
case UNIAPI_RESET_request:
{
const struct uniapi_reset_request *api = msg;
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_RESTART,
(const union uni_ieall *)&api->restart, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CONNID,
(const union uni_ieall *)&api->restart, cx);
break;
}
case UNIAPI_RESET_confirm:
{
const struct uniapi_reset_confirm *api = msg;
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_RESTART,
(const union uni_ieall *)&api->restart, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CONNID,
(const union uni_ieall *)&api->restart, cx);
break;
}
case UNIAPI_RESET_indication:
{
const struct uniapi_reset_indication *api = msg;
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_RESTART,
(const union uni_ieall *)&api->restart, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CONNID,
(const union uni_ieall *)&api->restart, cx);
break;
}
case UNIAPI_RESET_ERROR_indication:
{
const struct uniapi_reset_error_indication *api = msg;
static const struct uni_print_tbl reason[] = {
#define DEF(NAME, VALUE, STR) { STR, VALUE },
UNIAPI_DEF_RESET_ERRORS(DEF)
#undef DEF
{ NULL, 0 }
};
static const struct uni_print_tbl source[] = {
{ "start", 0 },
{ "respond", 1 },
{ NULL, 0 }
};
uni_print_eol(cx);
uni_print_tbl("source", api->source, source, cx);
uni_print_tbl("reason", api->reason, reason, cx);
break;
}
case UNIAPI_RESET_response:
{
const struct uniapi_reset_response *api = msg;
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_RESTART,
(const union uni_ieall *)&api->restart, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CONNID,
(const union uni_ieall *)&api->restart, cx);
break;
}
case UNIAPI_RESET_ERROR_response:
{
const struct uniapi_reset_error_response *api = msg;
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CAUSE,
(const union uni_ieall *)&api->cause, cx);
break;
}
case UNIAPI_RESET_STATUS_indication:
{
const struct uniapi_reset_status_indication *api = msg;
uni_print_cref(NULL, 0, &api->cref, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CALLSTATE,
(const union uni_ieall *)&api->callstate, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CAUSE,
(const union uni_ieall *)&api->cause, cx);
break;
}
case UNIAPI_SETUP_request:
{
const struct uniapi_setup_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_SETUP,
(const union uni_msgall *)&api->setup, cx);
break;
}
case UNIAPI_SETUP_indication:
{
const struct uniapi_setup_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_SETUP,
(const union uni_msgall *)&api->setup, cx);
break;
}
case UNIAPI_SETUP_response:
{
const struct uniapi_setup_response *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_CONNECT,
(const union uni_msgall *)&api->connect, cx);
break;
}
case UNIAPI_SETUP_confirm:
{
const struct uniapi_setup_confirm *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_CONNECT,
(const union uni_msgall *)&api->connect, cx);
break;
}
case UNIAPI_SETUP_COMPLETE_indication:
{
const struct uniapi_setup_complete_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_CONNECT_ACK,
(const union uni_msgall *)&api->connect_ack, cx);
break;
}
case UNIAPI_SETUP_COMPLETE_request:
{
const struct uniapi_setup_complete_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_CONNECT_ACK,
(const union uni_msgall *)&api->connect_ack, cx);
break;
}
case UNIAPI_ALERTING_request:
{
const struct uniapi_alerting_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_ALERTING,
(const union uni_msgall *)&api->alerting, cx);
break;
}
case UNIAPI_ALERTING_indication:
{
const struct uniapi_alerting_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_ALERTING,
(const union uni_msgall *)&api->alerting, cx);
break;
}
case UNIAPI_PROCEEDING_request:
{
const struct uniapi_proceeding_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_CALL_PROC,
(const union uni_msgall *)&api->call_proc, cx);
break;
}
case UNIAPI_PROCEEDING_indication:
{
const struct uniapi_proceeding_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_CALL_PROC,
(const union uni_msgall *)&api->call_proc, cx);
break;
}
case UNIAPI_RELEASE_request:
{
const struct uniapi_release_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_RELEASE,
(const union uni_msgall *)&api->release, cx);
break;
}
case UNIAPI_RELEASE_indication:
{
const struct uniapi_release_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_RELEASE,
(const union uni_msgall *)&api->release, cx);
break;
}
case UNIAPI_RELEASE_response:
{
const struct uniapi_release_response *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_RELEASE_COMPL,
(const union uni_msgall *)&api->release_compl, cx);
break;
}
case UNIAPI_RELEASE_confirm:
{
const struct uniapi_release_confirm *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_RELEASE,
(const union uni_msgall *)&api->release, cx);
break;
}
case UNIAPI_NOTIFY_request:
{
const struct uniapi_notify_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_NOTIFY,
(const union uni_msgall *)&api->notify, cx);
break;
}
case UNIAPI_NOTIFY_indication:
{
const struct uniapi_notify_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_NOTIFY,
(const union uni_msgall *)&api->notify, cx);
break;
}
case UNIAPI_STATUS_indication:
{
const struct uniapi_status_indication *api = msg;
uni_print_cref(NULL, 0, &api->cref, cx);
uni_print_eol(cx);
uni_print_entry(cx, "my_state", "U%u", api->my_state);
uni_print_entry(cx, "my_cause", "%s",
uni_ie_cause2str(UNI_CODING_ITU, api->my_cause));
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CALLSTATE,
(const union uni_ieall *)&api->his_state, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CAUSE,
(const union uni_ieall *)&api->his_cause, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_EPREF,
(const union uni_ieall *)&api->epref, cx);
break;
}
case UNIAPI_STATUS_ENQUIRY_request:
{
const struct uniapi_status_enquiry_request *api = msg;
uni_print_cref(NULL, 0, &api->cref, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_EPREF,
(const union uni_ieall *)&api->epref, cx);
break;
}
case UNIAPI_ADD_PARTY_request:
{
const struct uniapi_add_party_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_ADD_PARTY,
(const union uni_msgall *)&api->add, cx);
break;
}
case UNIAPI_ADD_PARTY_indication:
{
const struct uniapi_add_party_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_ADD_PARTY,
(const union uni_msgall *)&api->add, cx);
break;
}
case UNIAPI_PARTY_ALERTING_request:
{
const struct uniapi_party_alerting_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_PARTY_ALERTING,
(const union uni_msgall *)&api->alert, cx);
break;
}
case UNIAPI_PARTY_ALERTING_indication:
{
const struct uniapi_party_alerting_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_PARTY_ALERTING,
(const union uni_msgall *)&api->alert, cx);
break;
}
case UNIAPI_ADD_PARTY_ACK_request:
{
const struct uniapi_add_party_ack_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_ADD_PARTY_ACK,
(const union uni_msgall *)&api->ack, cx);
break;
}
case UNIAPI_ADD_PARTY_ACK_indication:
{
const struct uniapi_add_party_ack_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_ADD_PARTY_ACK,
(const union uni_msgall *)&api->ack, cx);
break;
}
case UNIAPI_ADD_PARTY_REJ_request:
{
const struct uniapi_add_party_rej_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_ADD_PARTY_REJ,
(const union uni_msgall *)&api->rej, cx);
break;
}
case UNIAPI_ADD_PARTY_REJ_indication:
{
const struct uniapi_add_party_rej_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_ADD_PARTY_REJ,
(const union uni_msgall *)&api->rej, cx);
break;
}
case UNIAPI_DROP_PARTY_request:
{
const struct uniapi_drop_party_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_DROP_PARTY,
(const union uni_msgall *)&api->drop, cx);
break;
}
case UNIAPI_DROP_PARTY_indication:
{
const struct uniapi_drop_party_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_DROP_PARTY,
(const union uni_msgall *)&api->drop, cx);
break;
}
case UNIAPI_DROP_PARTY_ACK_request:
{
const struct uniapi_drop_party_ack_request *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_DROP_PARTY_ACK,
(const union uni_msgall *)&api->ack, cx);
break;
}
case UNIAPI_DROP_PARTY_ACK_indication:
{
const struct uniapi_drop_party_ack_indication *api = msg;
uni_print_eol(cx);
uni_print_msg(NULL, 0, UNI_DROP_PARTY,
(const union uni_msgall *)&api->drop, cx);
uni_print_eol(cx);
uni_print_ie(NULL, 0, UNI_IE_CRANKBACK,
(const union uni_ieall *)&api->crankback, cx);
break;
}
case UNIAPI_ABORT_CALL_request:
{
const struct uniapi_abort_call_request *api = msg;
uni_print_cref(NULL, 0, &api->cref, cx);
break;
}
}
out:
cx->dont_init = old_dont_init;
}

View File

@ -0,0 +1,824 @@
/*
* Copyright (c) 1996-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/atm/sig/sig_reset.c,v 1.5 2003/09/24 10:27:50 hbb Exp $
*
* Reset-start and reset-respond
*/
#include <netnatm/unimsg.h>
#include <netnatm/saal/sscfudef.h>
#include <netnatm/msg/unistruct.h>
#include <netnatm/msg/unimsglib.h>
#include <netnatm/sig/uni.h>
#include <netnatm/sig/unipriv.h>
#include <netnatm/sig/unimkmsg.h>
static void response_restart(struct uni *, struct uni_msg *, struct uni_all *);
static void response_status(struct uni *, struct uni_msg *, struct uni_all *);
static void response_t317(struct uni *);
static void response_error(struct uni *, struct uniapi_reset_error_response *, u_int32_t cookie);
static void response_response(struct uni *, struct uniapi_reset_response *, u_int32_t);
static void start_request(struct uni *, struct uniapi_reset_request *, u_int32_t);
static void start_t316(struct uni *);
static void start_restart_ack(struct uni *, struct uni_msg *, struct uni_all *);
static void start_status(struct uni *, struct uni_msg *, struct uni_all *);
static int restart_forward(struct uni *, const struct uni_all *);
#define DEF_PRIV_SIG(NAME, FROM) [SIG##NAME] "SIG"#NAME,
static const char *const start_sigs[] = {
DEF_START_SIGS
};
#undef DEF_PRIV_SIG
#define DEF_PRIV_SIG(NAME, FROM) [SIG##NAME] "SIG"#NAME,
static const char *const respond_sigs[] = {
DEF_RESPOND_SIGS
};
#undef DEF_PRIV_SIG
TIMER_FUNC_UNI(t317, t317_func)
TIMER_FUNC_UNI(t316, t316_func)
/*
* Reset-Start process.
*/
void
uni_sig_start(struct uni *uni, u_int sig, u_int32_t cookie,
struct uni_msg *m, struct uni_all *u)
{
if (sig >= SIGS_END) {
VERBOSE(uni, UNI_FAC_ERR, 1, "Signal %d outside of range to "
"Reset-Start", sig);
if (m)
uni_msg_destroy(m);
if (u)
UNI_FREE(u);
return;
}
VERBOSE(uni, UNI_FAC_RESTART, 1,
"Signal %s in state %u of Reset-Start; cookie %u",
start_sigs[sig], uni->glob_start, cookie);
switch (sig) {
/*
* User requests
*/
case SIGS_RESET_request:
start_request(uni,
uni_msg_rptr(m, struct uniapi_reset_request *), cookie);
uni_msg_destroy(m);
break;
/*
* Timers
*/
case SIGS_T316:
start_t316(uni);
break;
/*
* SAAL
*/
case SIGS_RESTART_ACK:
start_restart_ack(uni, m, u);
uni_msg_destroy(m);
UNI_FREE(u);
break;
case SIGS_STATUS:
start_status(uni, m, u);
uni_msg_destroy(m);
UNI_FREE(u);
break;
case SIGS_END:
break;
}
}
/*
* Reset-request from USER.
*
* Q.2931:Reset-Start 1/2
*/
static void
start_request(struct uni *uni, struct uniapi_reset_request *req, u_int32_t cookie)
{
struct uni_all *resp;
int err;
if (uni->glob_start != UNI_CALLSTATE_REST0) {
uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0);
return;
}
if ((resp = UNI_ALLOC()) == NULL) {
uniapi_uni_error(uni, UNIAPI_ERROR_NOMEM, cookie, 0);
return;
}
MK_MSG_ORIG(resp, UNI_RESTART, 0, 0);
resp->u.restart.restart = req->restart;
resp->u.restart.connid = req->connid;
if (restart_forward(uni, resp))
return;
uni->connid_start = req->connid;
uni->restart_start = req->restart;
if ((err = uni_send_output(resp, uni)) != 0)
uniapi_uni_error(uni, UNIAPI_ERROR_ENCODING, cookie, 0);
UNI_FREE(resp);
if (err)
return;
uni->cnt316 = 0;
TIMER_START_UNI(uni, t316, uni->timer316);
uni->glob_start = UNI_CALLSTATE_REST1;
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Start state := 1");
uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
}
/*
* T316 timeout function
*/
static void
t316_func(struct uni *uni)
{
uni_enq_start(uni, SIGS_T316, 0, NULL, NULL);
}
/*
* Q.2931:Reset-Start 1/2
*/
static void
start_t316(struct uni *uni)
{
if (uni->glob_start != UNI_CALLSTATE_REST1) {
VERBOSE0(uni, UNI_FAC_ERR, "T316 in state %d",
uni->glob_start);
return;
}
if (++uni->cnt316 == uni->init316) {
struct uni_msg *app;
struct uniapi_reset_error_indication *resp;
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Start error");
resp = ALLOC_API(struct uniapi_reset_error_indication, app);
if (resp != NULL) {
resp->source = 0;
resp->reason = UNIAPI_RESET_ERROR_NO_RESPONSE,
uni->funcs->uni_output(uni, uni->arg,
UNIAPI_RESET_ERROR_indication, 0, app);
}
uni->glob_start = UNI_CALLSTATE_REST0;
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Start state := 0");
} else {
struct uni_all *resp;
if ((resp = UNI_ALLOC()) == NULL)
return;
MK_MSG_ORIG(resp, UNI_RESTART, 0, 0);
resp->u.restart.restart = uni->restart_start;
resp->u.restart.connid = uni->connid_start;
(void)uni_send_output(resp, uni);
UNI_FREE(resp);
TIMER_START_UNI(uni, t316, uni->timer316);
}
}
/*
* Got RESTART_ACK.
*/
static void
start_restart_ack(struct uni *uni, struct uni_msg *m, struct uni_all *u)
{
enum uni_callstate new_state;
struct uniapi_reset_confirm *conf;
struct uni_msg *app;
if (uni->glob_start == UNI_CALLSTATE_REST0) {
uni_respond_status_mtype(uni, &u->u.hdr.cref, uni->glob_start,
UNI_CAUSE_MSG_INCOMP, UNI_RESTART_ACK);
return;
}
if (uni->glob_start != UNI_CALLSTATE_REST1) {
ASSERT(0, ("bad global call state in Reset-Start"));
return;
}
/*
* If body decoding fails, this is because IEs are wrong.
*/
(void)uni_decode_body(m, u, &uni->cx);
MANDATE_IE(uni, u->u.restart_ack.restart, UNI_IE_RESTART);
if (IE_ISGOOD(u->u.restart_ack.restart)) {
/*
* Q.2931: 5.5.2.2
*/
if (u->u.restart_ack.restart.rclass == UNI_RESTART_ALL &&
IE_ISGOOD(u->u.restart_ack.connid)) {
UNI_SAVE_IERR(&uni->cx, UNI_IE_CONNID,
u->u.restart_ack.connid.h.act,
UNI_IERR_UNK);
} else if ((u->u.restart_ack.restart.rclass == UNI_RESTART_PATH ||
u->u.restart_ack.restart.rclass == UNI_RESTART_CHANNEL)) {
MANDATE_IE(uni, u->u.restart_ack.connid, UNI_IE_CONNID);
}
}
/*
* Compare the information elements now, because
* we may need the new callstate for the status message
* below.
*/
new_state = UNI_CALLSTATE_REST1;
if (IE_ISGOOD(u->u.restart_ack.restart) &&
IE_ISGOOD(uni->restart_start) &&
u->u.restart_ack.restart.rclass == uni->restart_start.rclass &&
!IE_ISGOOD(u->u.restart_ack.connid) == !IE_ISGOOD(uni->connid_start) &&
(!IE_ISGOOD(uni->connid_start) ||
(u->u.restart_ack.connid.vpci == uni->connid_start.vpci &&
u->u.restart_ack.connid.vci == uni->connid_start.vci)))
new_state = UNI_CALLSTATE_REST0;
switch (uni_verify(uni, u->u.hdr.act)) {
case VFY_RAIM:
case VFY_RAI:
uni_respond_status_verify(uni, &u->u.hdr.cref,
UNI_CALLSTATE_REST1, NULL, 0);
case VFY_I:
return;
case VFY_CLR:
uni->glob_start = UNI_CALLSTATE_REST0;
VERBOSE(uni, UNI_FAC_RESTART, 1,
"Reset-Start state := 0");
return;
case VFY_RAP:
case VFY_RAPU:
uni_respond_status_verify(uni, &u->u.hdr.cref,
new_state, NULL, 0);
case VFY_OK:
break;
}
if (new_state == UNI_CALLSTATE_REST1)
/*
* Q.2931: 5.5.1.2/2
*/
return;
/*
* Build restart.confirm signal for application
*/
if (!IE_ISGOOD(u->u.restart_ack.connid))
u->u.restart.connid.h.present = 0;
if ((conf = ALLOC_API(struct uniapi_reset_confirm, app)) == NULL)
return;
conf->restart = u->u.restart.restart;
conf->connid = u->u.restart.connid;
TIMER_STOP_UNI(uni, t316);
uni->funcs->uni_output(uni, uni->arg, UNIAPI_RESET_confirm, 0, app);
uni->glob_start = UNI_CALLSTATE_REST0;
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Start state := 0");
}
/*
* Reset-Start got a STATUS message.
*
* Q.2931: Reset-Start 2/2
*
* In Q.2931 only CALLSTATE_REST1 is allowed, this seems silly and to contradict
* 5.6.12. So allow it in any state.
*
* The following states are considered compatible:
*
* Sender Receiver(we)
* ------ --------
* Rest0 Rest0 this is the normal state OK!
* Rest2 Rest0 this may be the result of no answer from the API
* on the remote end and the us finally timing out. ERROR!
* Rest2 Rest1 this is normal. OK!
* Rest0 Rest1 RESTART_ACK was probably lost. OK!
*
* All others are wrong.
*/
static void
start_status(struct uni *uni, struct uni_msg *m, struct uni_all *u)
{
(void)uni_decode_body(m, u, &uni->cx);
MANDATE_IE(uni, u->u.status.callstate, UNI_IE_CALLSTATE);
MANDATE_IE(uni, u->u.status.cause, UNI_IE_CAUSE);
switch (uni_verify(uni, u->u.hdr.act)) {
case VFY_CLR:
uni->glob_start = UNI_CALLSTATE_REST0;
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Start state := 0");
return;
case VFY_RAIM:
case VFY_RAI:
case VFY_RAP:
case VFY_RAPU:
uni_respond_status_verify(uni, &u->u.hdr.cref, uni->glob_start,
NULL, 0);
case VFY_I:
case VFY_OK:
break;
}
if (!IE_ISGOOD(u->u.status.callstate)) {
/*
* As a result of the strange handling above, we must
* process a STATUS with an invalid or missing callstate!
*/
return;
}
if ((u->u.status.callstate.state == UNI_CALLSTATE_REST0 &&
uni->glob_start == UNI_CALLSTATE_REST0) ||
(u->u.status.callstate.state == UNI_CALLSTATE_REST0 &&
uni->glob_start == UNI_CALLSTATE_REST1) ||
(u->u.status.callstate.state == UNI_CALLSTATE_REST2 &&
uni->glob_start == UNI_CALLSTATE_REST1)) {
/*
* Implementation dependend procedure:
* Inform the API
*/
struct uniapi_reset_status_indication *resp;
struct uni_msg *app;
resp = ALLOC_API(struct uniapi_reset_status_indication, app);
if (resp == NULL)
return;
resp->cref = u->u.hdr.cref;
resp->callstate = u->u.status.callstate;
if (IE_ISGOOD(u->u.status.cause))
resp->cause = u->u.status.cause;
uni->funcs->uni_output(uni, uni->arg,
UNIAPI_RESET_STATUS_indication, 0, app);
} else {
struct uniapi_reset_error_indication *resp;
struct uni_msg *app;
resp = ALLOC_API(struct uniapi_reset_error_indication, app);
if (resp != NULL) {
resp->source = 0;
resp->reason = UNIAPI_RESET_ERROR_PEER_INCOMP_STATE,
uni->funcs->uni_output(uni, uni->arg,
UNIAPI_RESET_ERROR_indication, 0, app);
}
}
}
/************************************************************/
/*
* Reset-Respond process.
*/
void
uni_sig_respond(struct uni *uni, u_int sig, u_int32_t cookie,
struct uni_msg *m, struct uni_all *u)
{
if (sig >= SIGR_END) {
VERBOSE(uni, UNI_FAC_ERR, 1, "Signal %d outside of range to "
"Reset-Respond", sig);
if (m)
uni_msg_destroy(m);
if (u)
UNI_FREE(u);
return;
}
VERBOSE(uni, UNI_FAC_RESTART, 1,
"Signal %s in state %u of Reset-Respond; cookie %u",
respond_sigs[sig], uni->glob_respond, cookie);
switch (sig) {
/*
* SAAL
*/
case SIGR_RESTART:
response_restart(uni, m, u);
uni_msg_destroy(m);
UNI_FREE(u);
break;
case SIGR_STATUS:
response_status(uni, m, u);
uni_msg_destroy(m);
UNI_FREE(u);
break;
/*
* User
*/
case SIGR_RESET_ERROR_response:
response_error(uni,
uni_msg_rptr(m, struct uniapi_reset_error_response *),
cookie);
uni_msg_destroy(m);
break;
case SIGR_RESET_response:
response_response(uni,
uni_msg_rptr(m, struct uniapi_reset_response *), cookie);
uni_msg_destroy(m);
break;
/*
* Timers
*/
case SIGR_T317:
response_t317(uni);
return;
case SIGR_END:
break;
}
}
/*
* Send a RELEASE_COMPLETE to all affected calls as per
* F.2.3(3)
*/
static int
restart_forward(struct uni *uni, const struct uni_all *u)
{
struct call *c;
struct uni_all *resp;
if ((resp = UNI_ALLOC()) == NULL)
return (-1);
TAILQ_FOREACH(c, &uni->calls, link) {
if (u->u.restart.restart.rclass == UNI_RESTART_ALL ||
(IE_ISPRESENT(c->connid) &&
u->u.restart.connid.vpci == c->connid.vpci &&
(u->u.restart.restart.rclass == UNI_RESTART_PATH ||
u->u.restart.connid.vci == c->connid.vci))) {
MK_MSG_ORIG(resp, UNI_RELEASE_COMPL, c->cref, c->mine);
uni_release_compl(c, resp);
}
}
UNI_FREE(resp);
return (0);
}
/*
* Respond process got a restart message.
* Doesn't free the messages.
*/
static void
response_restart(struct uni *uni, struct uni_msg *m, struct uni_all *u)
{
struct uni_msg *app;
struct uniapi_reset_indication *ind;
if (uni->glob_respond == UNI_CALLSTATE_REST0) {
/*
* If body decoding fails, this is because IEs are wrong.
*/
(void)uni_decode_body(m, u, &uni->cx);
MANDATE_IE(uni, u->u.restart.restart, UNI_IE_RESTART);
if (IE_ISGOOD(u->u.restart.restart)) {
/*
* Q.2931: 5.5.2.2
*/
if (u->u.restart.restart.rclass == UNI_RESTART_ALL &&
IE_ISGOOD(u->u.restart.connid)) {
UNI_SAVE_IERR(&uni->cx, UNI_IE_CONNID,
u->u.restart.connid.h.act,
UNI_IERR_UNK);
} else if ((u->u.restart.restart.rclass == UNI_RESTART_PATH ||
u->u.restart.restart.rclass == UNI_RESTART_CHANNEL)) {
MANDATE_IE(uni, u->u.restart.connid, UNI_IE_CONNID);
}
}
switch (uni_verify(uni, u->u.hdr.act)) {
case VFY_RAIM:
case VFY_RAI:
uni_respond_status_verify(uni, &u->u.hdr.cref,
UNI_CALLSTATE_REST0, NULL, 0);
case VFY_CLR:
case VFY_I:
return;
case VFY_RAP:
case VFY_RAPU:
uni_respond_status_verify(uni, &u->u.hdr.cref,
UNI_CALLSTATE_REST2, NULL, 0);
case VFY_OK:
break;
}
if (!IE_ISGOOD(u->u.restart.connid))
u->u.restart.connid.h.present = 0;
/*
* Send a RELEASE_COMPLETE to all affected calls as per
* F.2.3(3)
*/
if (restart_forward(uni, u))
return;
/*
* Build restart signal for application
*/
if ((ind = ALLOC_API(struct uniapi_reset_indication, app)) == NULL)
return;
ind->restart = u->u.restart.restart;
ind->connid = u->u.restart.connid;
uni_enq_coord(uni, SIGO_RESET_indication, 0, app);
TIMER_START_UNI(uni, t317, uni->timer317);
uni->glob_respond = UNI_CALLSTATE_REST2;
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Respond state := 2");
} else if (uni->glob_respond == UNI_CALLSTATE_REST2) {
/*
* No need to decode the message. It is unexpected in this
* state so return a status.
*/
uni_respond_status_mtype(uni, &u->u.hdr.cref, uni->glob_respond,
UNI_CAUSE_MSG_INCOMP, UNI_RESTART);
} else
ASSERT(0, ("bad global call state in responder"));
}
static void
response_t317(struct uni *uni)
{
struct uniapi_reset_error_indication *resp;
struct uni_msg *app;
if (uni->glob_respond != UNI_CALLSTATE_REST2) {
VERBOSE0(uni, UNI_FAC_ERR, "T317 in state %d",
uni->glob_respond);
return;
}
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Respond error");
if ((resp = ALLOC_API(struct uniapi_reset_error_indication, app)) != NULL) {
resp->source = 1;
resp->reason = UNIAPI_RESET_ERROR_NO_CONFIRM;
uni->funcs->uni_output(uni, uni->arg,
UNIAPI_RESET_ERROR_indication, 0, app);
}
uni->glob_respond = UNI_CALLSTATE_REST0;
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Respond state := 0");
}
/*
* Error response from USER
*/
static void
response_error(struct uni *uni, struct uniapi_reset_error_response *c,
u_int32_t cookie)
{
struct uni_all *resp;
if (uni->glob_respond != UNI_CALLSTATE_REST2) {
uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0);
return;
}
if ((resp = UNI_ALLOC()) == NULL) {
uniapi_uni_error(uni, UNIAPI_ERROR_NOMEM, cookie, 0);
return;
}
MK_MSG_ORIG(resp, UNI_STATUS, 0, 1);
MK_IE_CALLSTATE(resp->u.status.callstate, UNI_CALLSTATE_REST2);
if (IE_ISGOOD(c->cause))
resp->u.status.cause = c->cause;
else {
MK_IE_CAUSE(resp->u.status.cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_CHANNEL_NEX);
if (IE_ISGOOD(uni->connid_respond))
ADD_CAUSE_CHANNID(resp->u.status.cause,
uni->connid_respond.vpci,
uni->connid_respond.vci);
}
if (uni_send_output(resp, uni) != 0) {
uniapi_uni_error(uni, UNIAPI_ERROR_ENCODING, cookie, 0);
UNI_FREE(resp);
return;
}
uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
}
/*
* Reset-response from user.
*/
static void
response_response(struct uni *uni, struct uniapi_reset_response *arg,
u_int32_t cookie)
{
struct uni_all *resp;
if (uni->glob_respond != UNI_CALLSTATE_REST2) {
uniapi_uni_error(uni, UNIAPI_ERROR_BAD_CALLSTATE, cookie, 0);
return;
}
if (!IE_ISGOOD(arg->restart)) {
uniapi_uni_error(uni, UNIAPI_ERROR_MISSING_IE, cookie, 0);
return;
}
if ((resp = UNI_ALLOC()) == NULL) {
uniapi_uni_error(uni, UNIAPI_ERROR_NOMEM, cookie, 0);
return;
}
TIMER_STOP_UNI(uni, t317);
MK_MSG_ORIG(resp, UNI_RESTART_ACK, 0, 1);
resp->u.restart.restart = arg->restart;
if (IE_ISGOOD(arg->connid))
resp->u.restart.connid = arg->connid;
if (uni_send_output(resp, uni) != 0) {
uniapi_uni_error(uni, UNIAPI_ERROR_ENCODING, cookie, 0);
UNI_FREE(resp);
return;
}
UNI_FREE(resp);
uni->glob_respond = UNI_CALLSTATE_REST0;
VERBOSE(uni, UNI_FAC_RESTART, 1, "Reset-Respond state := 0");
uniapi_uni_error(uni, UNIAPI_OK, cookie, 0);
}
/*
* Reset-Response got a STATUS message.
*
* Q.2931: Reset-Response 2/2
*
* In Q.2931 only CALLSTATE_REST2 is allowed, this seems silly and to contradict
* 5.6.12. So allow it in any state.
*
* The following states are considered compatible:
*
* Sender Receiver
* ------ --------
* Rest0 Rest0 this is the normal state OK!
* Rest0 Rest2 this may be the result of no answer from the API
* and the Sender finally timing out. ERROR!
* Rest1 Rest2 this is normal. OK!
* Rest1 Rest0 RESTART_ACK was probably lost. OK!
*
* All others are wrong.
*/
static void
response_status(struct uni *uni, struct uni_msg *m, struct uni_all *u)
{
(void)uni_decode_body(m, u, &uni->cx);
MANDATE_IE(uni, u->u.status.callstate, UNI_IE_CALLSTATE);
MANDATE_IE(uni, u->u.status.cause, UNI_IE_CAUSE);
switch (uni_verify(uni, u->u.hdr.act)) {
case VFY_CLR:
if (uni->proto == UNIPROTO_UNI40U) {
uni->glob_respond = UNI_CALLSTATE_REST0;
VERBOSE(uni, UNI_FAC_RESTART, 1,
"Reset-Respond state := 0");
return;
}
break;
case VFY_RAIM:
case VFY_RAI:
case VFY_RAP:
case VFY_RAPU:
uni_respond_status_verify(uni, &u->u.hdr.cref,
uni->glob_respond, NULL, 0);
case VFY_I:
case VFY_OK:
break;
}
if (!IE_ISGOOD(u->u.status.callstate)) {
/*
* As a result of the strange handling above, we must
* process a STATUS with an invalid or missing callstate!
*/
return;
}
if ((u->u.status.callstate.state == UNI_CALLSTATE_REST0 &&
uni->glob_respond == UNI_CALLSTATE_REST0) ||
(u->u.status.callstate.state == UNI_CALLSTATE_REST1 &&
uni->glob_respond == UNI_CALLSTATE_REST0) ||
(u->u.status.callstate.state == UNI_CALLSTATE_REST1 &&
uni->glob_respond == UNI_CALLSTATE_REST2)) {
/*
* Implementation dependend procedure:
* Inform the API
*/
struct uniapi_reset_status_indication *resp;
struct uni_msg *app;
resp = ALLOC_API(struct uniapi_reset_status_indication, app);
if (resp == NULL)
return;
resp->cref = u->u.hdr.cref;
resp->callstate = u->u.status.callstate;
if (IE_ISGOOD(u->u.status.cause))
resp->cause = u->u.status.cause;
uni->funcs->uni_output(uni, uni->arg,
UNIAPI_RESET_STATUS_indication, 0, app);
} else {
struct uniapi_reset_error_indication *resp;
struct uni_msg *app;
resp = ALLOC_API(struct uniapi_reset_error_indication, app);
if (resp != NULL) {
resp->source = 1;
resp->reason = UNIAPI_RESET_ERROR_PEER_INCOMP_STATE,
uni->funcs->uni_output(uni, uni->arg,
UNIAPI_RESET_ERROR_indication, 0, app);
}
}
}
/*
* T317 timeout function
*/
static void
t317_func(struct uni *uni)
{
uni_enq_resp(uni, SIGR_T317, 0, NULL, NULL);
}

View File

@ -0,0 +1,749 @@
/*
* Copyright (c) 1996-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/atm/sig/sig_uni.c,v 1.4 2003/09/24 10:27:50 hbb Exp $
*
* Instance handling
*/
#include <netnatm/unimsg.h>
#include <netnatm/saal/sscopdef.h>
#include <netnatm/saal/sscfudef.h>
#include <netnatm/msg/unistruct.h>
#include <netnatm/msg/unimsglib.h>
#include <netnatm/sig/uni.h>
#include <netnatm/sig/unisig.h>
#include <netnatm/sig/unipriv.h>
#ifdef UNICORE
UNICORE
#endif
#define STR(S) [S] #S
static const char *custat_names[] = {
STR(CU_STAT0),
STR(CU_STAT1),
STR(CU_STAT2),
STR(CU_STAT3),
};
static const char *globstat_names[] = {
STR(UNI_CALLSTATE_REST0),
STR(UNI_CALLSTATE_REST1),
STR(UNI_CALLSTATE_REST2),
};
static const char *sig_names[] = {
STR(UNIAPI_ERROR),
STR(UNIAPI_CALL_CREATED),
STR(UNIAPI_CALL_DESTROYED),
STR(UNIAPI_PARTY_CREATED),
STR(UNIAPI_PARTY_DESTROYED),
STR(UNIAPI_LINK_ESTABLISH_request),
STR(UNIAPI_LINK_ESTABLISH_confirm),
STR(UNIAPI_LINK_RELEASE_request),
STR(UNIAPI_LINK_RELEASE_confirm),
STR(UNIAPI_RESET_request),
STR(UNIAPI_RESET_confirm),
STR(UNIAPI_RESET_indication),
STR(UNIAPI_RESET_ERROR_indication),
STR(UNIAPI_RESET_response),
STR(UNIAPI_RESET_ERROR_response),
STR(UNIAPI_RESET_STATUS_indication),
STR(UNIAPI_SETUP_request),
STR(UNIAPI_SETUP_indication),
STR(UNIAPI_SETUP_response),
STR(UNIAPI_SETUP_confirm),
STR(UNIAPI_SETUP_COMPLETE_indication),
STR(UNIAPI_SETUP_COMPLETE_request),
STR(UNIAPI_ALERTING_request),
STR(UNIAPI_ALERTING_indication),
STR(UNIAPI_PROCEEDING_request),
STR(UNIAPI_PROCEEDING_indication),
STR(UNIAPI_RELEASE_request),
STR(UNIAPI_RELEASE_indication),
STR(UNIAPI_RELEASE_response),
STR(UNIAPI_RELEASE_confirm),
STR(UNIAPI_NOTIFY_request),
STR(UNIAPI_NOTIFY_indication),
STR(UNIAPI_STATUS_indication),
STR(UNIAPI_STATUS_ENQUIRY_request),
STR(UNIAPI_ADD_PARTY_request),
STR(UNIAPI_ADD_PARTY_indication),
STR(UNIAPI_PARTY_ALERTING_request),
STR(UNIAPI_PARTY_ALERTING_indication),
STR(UNIAPI_ADD_PARTY_ACK_request),
STR(UNIAPI_ADD_PARTY_ACK_indication),
STR(UNIAPI_ADD_PARTY_REJ_request),
STR(UNIAPI_ADD_PARTY_REJ_indication),
STR(UNIAPI_DROP_PARTY_request),
STR(UNIAPI_DROP_PARTY_indication),
STR(UNIAPI_DROP_PARTY_ACK_request),
STR(UNIAPI_DROP_PARTY_ACK_indication),
STR(UNIAPI_ABORT_CALL_request),
};
static const char *verb_names[] = {
# define UNI_DEBUG_DEFINE(D) [UNI_FAC_##D] #D,
UNI_DEBUG_FACILITIES
# undef UNI_DEBUG_DEFINE
};
const char *
uni_facname(enum uni_verb fac)
{
static char buf[40];
if (fac >= UNI_MAXFACILITY) {
sprintf(buf, "FAC%u", fac);
return (buf);
}
return (verb_names[fac]);
}
const char *
uni_signame(enum uni_sig sig)
{
static char buf[40];
if (sig >= UNIAPI_MAXSIG) {
sprintf(buf, "UNIAPI_SIG%u", sig);
return (buf);
}
return (sig_names[sig]);
}
struct unicx *
uni_context(struct uni *uni)
{
return (&uni->cx);
}
static void
uni_init(struct uni *uni)
{
uni->working = 0;
uni->cref_alloc = 12;
uni->custat = CU_STAT0;
uni->glob_start = UNI_CALLSTATE_REST0;
uni->glob_respond = UNI_CALLSTATE_REST0;
}
static void
uni_stop(struct uni *uni)
{
struct call *c;
while ((c = TAILQ_FIRST(&uni->calls)) != NULL) {
TAILQ_REMOVE(&uni->calls, c, link);
uni_destroy_call(c, 1);
}
SIGQ_CLEAR(&uni->workq);
SIGQ_CLEAR(&uni->delq);
}
/*
* INSTANCE HANDLING
*/
struct uni *
uni_create(void *arg, const struct uni_funcs *funcs)
{
struct uni *uni;
if ((uni = INS_ALLOC()) == NULL)
return (NULL);
uni_init(uni);
uni->funcs = funcs;
uni->arg = arg;
uni->proto = UNIPROTO_UNI40U;
uni->sb_tb = 0;
TAILQ_INIT(&uni->workq);
TAILQ_INIT(&uni->delq);
TIMER_INIT_UNI(uni, t309);
uni->timer309 = UNI_T309_DEFAULT;
TAILQ_INIT(&uni->calls);
uni_initcx(&uni->cx);
TIMER_INIT_UNI(uni, t317);
TIMER_INIT_UNI(uni, t316);
uni->timer301 = UNI_T301_DEFAULT;
uni->init303 = UNI_T303_CNT_DEFAULT;
uni->timer303 = UNI_T303_DEFAULT;
uni->init308 = UNI_T308_CNT_DEFAULT;
uni->timer308 = UNI_T308_DEFAULT;
uni->timer310 = UNI_T310U_DEFAULT;
uni->timer313 = UNI_T313_DEFAULT;
uni->init316 = UNI_T316_CNT_DEFAULT;
uni->timer316 = UNI_T316_DEFAULT;
uni->timer317 = UNI_T317_DEFAULT;
uni->timer322 = UNI_T322_DEFAULT;
uni->init322 = UNI_T322_CNT_DEFAULT;
uni->timer397 = UNI_T397_DEFAULT;
uni->timer398 = UNI_T398_DEFAULT;
uni->timer399 = UNI_T399U_DEFAULT;
return (uni);
}
void
uni_destroy(struct uni *uni)
{
uni_stop(uni);
TIMER_DESTROY_UNI(uni, t309);
TIMER_DESTROY_UNI(uni, t316);
TIMER_DESTROY_UNI(uni, t317);
INS_FREE(uni);
}
void
uni_reset(struct uni *uni)
{
uni_stop(uni);
uni_init(uni);
}
/*
* DISPATCH SSCOP SIGNAL
*/
void
uni_saal_input(struct uni *uni, enum saal_sig sig, struct uni_msg *m)
{
switch (sig) {
case SAAL_ESTABLISH_indication:
if (m != NULL)
uni_msg_destroy(m);
uni_enq_coord(uni, SIGO_SAAL_ESTABLISH_indication, 0, NULL);
break;
case SAAL_ESTABLISH_confirm:
if (m != NULL)
uni_msg_destroy(m);
uni_enq_coord(uni, SIGO_SAAL_ESTABLISH_confirm, 0, NULL);
break;
case SAAL_RELEASE_confirm:
if (m != NULL)
uni_msg_destroy(m);
uni_enq_coord(uni, SIGO_SAAL_RELEASE_confirm, 0, NULL);
break;
case SAAL_RELEASE_indication:
if (m != NULL)
uni_msg_destroy(m);
uni_enq_coord(uni, SIGO_SAAL_RELEASE_indication, 0, NULL);
break;
case SAAL_DATA_indication:
uni_enq_coord(uni, SIGO_SAAL_DATA_indication, 0, m);
break;
case SAAL_UDATA_indication:
uni_enq_coord(uni, SIGO_SAAL_UDATA_indication, 0, m);
break;
default:
VERBOSE(uni, UNI_FAC_ERR, 1, "bogus saal signal %u", sig);
if (m != NULL)
uni_msg_destroy(m);
break;
}
}
static struct {
const char *name;
enum uni_sig sig;
size_t arglen;
u_int coord_sig;
u_int proto;
#define UNIU 0x01
#define UNIN 0x02
#define PNNI 0x04
} maptab[] = {
{ "LINK-ESTABLISH.request", UNIAPI_LINK_ESTABLISH_request,
0,
SIGO_LINK_ESTABLISH_request, UNIU | UNIN },
{ "LINK-RELEASE.request", UNIAPI_LINK_RELEASE_request,
0,
SIGO_LINK_RELEASE_request, UNIU | UNIN },
{ "RESET.request", UNIAPI_RESET_request,
sizeof(struct uniapi_reset_request),
SIGO_RESET_request, UNIU | UNIN },
{ "RESET-ERROR.response", UNIAPI_RESET_ERROR_response,
sizeof(struct uniapi_reset_error_response),
SIGO_RESET_ERROR_response, UNIU | UNIN },
{ "RESET.response", UNIAPI_RESET_response,
sizeof(struct uniapi_reset_response),
SIGO_RESET_response, UNIU | UNIN },
{ "SETUP.request", UNIAPI_SETUP_request,
sizeof(struct uniapi_setup_request),
SIGO_SETUP_request, UNIU | UNIN },
{ "SETUP.response", UNIAPI_SETUP_response,
sizeof(struct uniapi_setup_response),
SIGO_SETUP_response, UNIU | UNIN },
{ "SETUP-COMPLETE.request", UNIAPI_SETUP_COMPLETE_request,
sizeof(struct uniapi_setup_complete_request),
SIGO_SETUP_COMPLETE_request, UNIN },
{ "PROCEEDING.request", UNIAPI_PROCEEDING_request,
sizeof(struct uniapi_proceeding_request),
SIGO_PROCEEDING_request, UNIU | UNIN },
{ "ALERTING.request", UNIAPI_ALERTING_request,
sizeof(struct uniapi_alerting_request),
SIGO_ALERTING_request, UNIU | UNIN },
{ "RELEASE.request", UNIAPI_RELEASE_request,
sizeof(struct uniapi_release_request),
SIGO_RELEASE_request, UNIU | UNIN },
{ "RELEASE.response", UNIAPI_RELEASE_response,
sizeof(struct uniapi_release_response),
SIGO_RELEASE_response, UNIU | UNIN },
{ "NOTIFY.request", UNIAPI_NOTIFY_request,
sizeof(struct uniapi_notify_request),
SIGO_NOTIFY_request, UNIU | UNIN },
{ "STATUS-ENQUIRY.request", UNIAPI_STATUS_ENQUIRY_request,
sizeof(struct uniapi_status_enquiry_request),
SIGO_STATUS_ENQUIRY_request, UNIU | UNIN },
{ "ADD-PARTY.request", UNIAPI_ADD_PARTY_request,
sizeof(struct uniapi_add_party_request),
SIGO_ADD_PARTY_request, UNIU | UNIN },
{ "ADD-PARTY-ACK.request", UNIAPI_ADD_PARTY_ACK_request,
sizeof(struct uniapi_add_party_ack_request),
SIGO_ADD_PARTY_ACK_request, UNIU | UNIN },
{ "ADD-PARTY-REJ.request", UNIAPI_ADD_PARTY_REJ_request,
sizeof(struct uniapi_add_party_rej_request),
SIGO_ADD_PARTY_REJ_request, UNIU | UNIN },
{ "PARTY-ALERTING.request", UNIAPI_PARTY_ALERTING_request,
sizeof(struct uniapi_party_alerting_request),
SIGO_PARTY_ALERTING_request, UNIU | UNIN },
{ "DROP-PARTY.request", UNIAPI_DROP_PARTY_request,
sizeof(struct uniapi_drop_party_request),
SIGO_DROP_PARTY_request, UNIU | UNIN },
{ "DROP-PARTY-ACK.request", UNIAPI_DROP_PARTY_ACK_request,
sizeof(struct uniapi_drop_party_ack_request),
SIGO_DROP_PARTY_ACK_request, UNIU | UNIN },
{ "ABORT-CALL.request", UNIAPI_ABORT_CALL_request,
sizeof(struct uniapi_abort_call_request),
SIGO_ABORT_CALL_request, UNIU | UNIN },
{ NULL, 0, 0, 0, 0 }
};
void
uni_uni_input(struct uni *uni, enum uni_sig sig, u_int32_t cookie,
struct uni_msg *m)
{
u_int i;
for (i = 0; maptab[i].name != NULL; i++) {
if (maptab[i].sig == sig) {
if (uni->proto == UNIPROTO_UNI40U) {
if (!(maptab[i].proto & UNIU))
uniapi_uni_error(uni,
UNIAPI_ERROR_BAD_SIGNAL, cookie, 0);
} else if(uni->proto == UNIPROTO_UNI40N) {
if (!(maptab[i].proto & UNIN))
uniapi_uni_error(uni,
UNIAPI_ERROR_BAD_SIGNAL, cookie, 0);
} else if(uni->proto == UNIPROTO_PNNI10) {
if (!(maptab[i].proto & PNNI))
uniapi_uni_error(uni,
UNIAPI_ERROR_BAD_SIGNAL, cookie, 0);
} else {
uniapi_uni_error(uni,
UNIAPI_ERROR_BAD_SIGNAL, cookie, 0);
}
if (uni_msg_len(m) != maptab[i].arglen) {
VERBOSE(uni, UNI_FAC_ERR, 1, "bogus data in %s"
" (expecting %zu, got %zu)", maptab[i].name,
maptab[i].arglen, uni_msg_len(m));
uni_msg_destroy(m);
uniapi_uni_error(uni, UNIAPI_ERROR_BAD_ARG,
cookie, 0);
return;
}
if (maptab[i].arglen == 0) {
uni_msg_destroy(m);
m = NULL;
}
VERBOSE(uni, UNI_FAC_API, 1, "got signal %s - "
"delivering to Coord", maptab[i].name);
uni_enq_coord(uni, maptab[i].coord_sig, cookie, m);
return;
}
}
VERBOSE(uni, UNI_FAC_ERR, 1, "bogus uni signal %u", sig);
uni_msg_destroy(m);
uniapi_uni_error(uni, UNIAPI_ERROR_BAD_SIGNAL, cookie, 0);
}
#undef UNIU
#undef UNIN
#undef PNNI
/**************************************************************/
void
uni_work(struct uni *uni)
{
struct sig *s;
if (uni->working)
return;
uni->working = 1;
while ((s = TAILQ_FIRST(&uni->workq)) != NULL) {
TAILQ_REMOVE(&uni->workq, s, link);
switch (s->type) {
case SIG_COORD:
uni_sig_coord(uni, s->sig, s->cookie, s->msg);
break;
case SIG_RESET_START:
uni_sig_start(uni, s->sig, s->cookie, s->msg, s->u);
break;
case SIG_RESET_RESP:
uni_sig_respond(uni, s->sig, s->cookie, s->msg, s->u);
break;
case SIG_CALL:
uni_sig_call(s->call, s->sig, s->cookie, s->msg, s->u);
break;
case SIG_PARTY:
uni_sig_party(s->party, s->sig, s->cookie, s->msg, s->u);
break;
default:
ASSERT(0, ("bad signal type"));
}
SIG_FREE(s);
}
uni->working = 0;
}
/*
* Enqueue a signal in the working queue
*/
void
uni_enq_sig(struct uni *uni, u_int type, struct call *call,
struct party *party, u_int32_t sig, u_int32_t cookie,
struct uni_msg *msg, struct uni_all *u)
{
struct sig *s;
if ((s = SIG_ALLOC()) != NULL) {
s->type = type;
s->sig = sig;
s->cookie = cookie;
s->msg = msg;
s->call = call;
s->party = party;
s->u = u;
TAILQ_INSERT_TAIL(&uni->workq, s, link);
}
}
/*
* Enqueue a signal in the delayed queue
*/
void
uni_delenq_sig(struct uni *uni, u_int type, struct call *call,
struct party *party, u_int32_t sig, u_int32_t cookie,
struct uni_msg *msg, struct uni_all *u)
{
struct sig *s;
if ((s = SIG_ALLOC()) != NULL) {
s->type = type;
s->sig = sig;
s->cookie = cookie;
s->msg = msg;
s->call = call;
s->party = party;
s->u = u;
TAILQ_INSERT_TAIL(&uni->delq, s, link);
}
}
/**************************************************************/
void
uniapi_uni_error(struct uni *uni, u_int32_t reason, u_int32_t cookie,
u_int32_t state)
{
struct uni_msg *resp;
struct uniapi_error *err;
if (cookie == 0)
return;
resp = uni_msg_alloc(sizeof(struct uniapi_error));
err = uni_msg_wptr(resp, struct uniapi_error *);
resp->b_wptr += sizeof(struct uniapi_error);
err->reason = reason;
err->state = state;
uni->funcs->uni_output(uni, uni->arg, UNIAPI_ERROR, cookie, resp);
}
void
uniapi_call_error(struct call *c, u_int32_t reason, u_int32_t cookie)
{
uniapi_uni_error(c->uni, reason, cookie, callstates[c->cstate].ext);
}
void
uniapi_party_error(struct party *p, u_int32_t reason, u_int32_t cookie)
{
uniapi_uni_error(p->call->uni, reason, cookie,
callstates[p->call->cstate].ext);
}
/**************************************************************/
void
uni_status(struct uni *uni, void *arg)
{
uni->funcs->status(uni, uni->arg, arg,
"working: %s\n", uni->working ? "yes" : "no");
uni->funcs->status(uni, uni->arg, arg,
"work queue: %sempty\n", TAILQ_EMPTY(&uni->workq)? "" : "not ");
uni->funcs->status(uni, uni->arg, arg,
"delayed work queue: %sempty\n",
TAILQ_EMPTY(&uni->delq)? "" : "not ");
uni->funcs->status(uni, uni->arg, arg,
"coordinator: %s\n", custat_names[uni->custat]);
uni->funcs->status(uni, uni->arg, arg,
"reset-start: %s\n", globstat_names[uni->glob_start]);
uni->funcs->status(uni, uni->arg, arg,
"reset-respond: %s\n", globstat_names[uni->glob_respond]);
}
void
uni_undel(struct uni *uni, int (*filter)(struct sig *, void *), void *arg)
{
struct sigqueue newq;
struct sig *s, *s1;
if (TAILQ_EMPTY(&uni->delq))
return;
TAILQ_INIT(&newq);
s = TAILQ_FIRST(&uni->delq);
while (s != NULL) {
s1 = TAILQ_NEXT(s, link);
if ((*filter)(s, arg)) {
TAILQ_REMOVE(&uni->delq, s, link);
TAILQ_INSERT_TAIL(&uni->workq, s, link);
}
s = s1;
}
}
void
uni_delsig(struct uni *uni, u_int type, struct call *c, struct party *p)
{
struct sig *s, *s1;
s = TAILQ_FIRST(&uni->workq);
while (s != NULL) {
s1 = TAILQ_NEXT(s, link);
if ((type == SIG_CALL && s->type == SIG_CALL &&
s->call == c) ||
(type == SIG_PARTY && s->type == SIG_PARTY &&
s->call == c && s->party == p)) {
TAILQ_REMOVE(&uni->workq, s, link);
if (s->msg)
uni_msg_destroy(s->msg);
if (s->u)
UNI_FREE(s->u);
SIG_FREE(s);
}
s = s1;
}
s = TAILQ_FIRST(&uni->delq);
while (s != NULL) {
s1 = TAILQ_NEXT(s, link);
if ((type == SIG_CALL && s->type == SIG_CALL &&
s->call == c) ||
(type == SIG_PARTY && s->type == SIG_PARTY &&
s->call == c && s->party == p)) {
TAILQ_REMOVE(&uni->delq, s, link);
if (s->msg)
uni_msg_destroy(s->msg);
if (s->u)
UNI_FREE(s->u);
SIG_FREE(s); \
}
s = s1;
}
}
/**************************************************************/
void
uni_get_config(const struct uni *uni, struct uni_config *config)
{
config->proto = uni->proto;
config->popt = 0;
if (uni->cx.q2932)
config->popt |= UNIPROTO_GFP;
config->option = 0;
if (uni->cx.git_hard)
config->option |= UNIOPT_GIT_HARD;
if (uni->cx.bearer_hard)
config->option |= UNIOPT_BEARER_HARD;
if (uni->cx.cause_hard)
config->option |= UNIOPT_CAUSE_HARD;
if (uni->sb_tb)
config->popt |= UNIPROTO_SB_TB;
config->timer301 = uni->timer301;
config->timer303 = uni->timer303;
config->init303 = uni->init303;
config->timer308 = uni->timer308;
config->init308 = uni->init308;
config->timer309 = uni->timer309;
config->timer310 = uni->timer310;
config->timer313 = uni->timer313;
config->timer316 = uni->timer316;
config->init316 = uni->init316;
config->timer317 = uni->timer317;
config->timer322 = uni->timer322;
config->init322 = uni->init322;
config->timer397 = uni->timer397;
config->timer398 = uni->timer398;
config->timer399 = uni->timer399;
}
void
uni_set_config(struct uni *uni, const struct uni_config *config,
u_int32_t *mask, u_int32_t *popt_mask, u_int32_t *opt_mask)
{
int idle;
idle = TAILQ_EMPTY(&uni->calls) &&
TAILQ_EMPTY(&uni->workq) &&
TAILQ_EMPTY(&uni->delq);
if ((*mask & UNICFG_PROTO) && idle) {
switch (config->proto) {
case UNIPROTO_UNI40U:
case UNIPROTO_UNI40N:
/* case UNIPROTO_PNNI10: XXX */
uni->proto = config->proto;
*mask &= ~UNICFG_PROTO;
break;
}
}
if (*popt_mask & UNIPROTO_GFP) {
if (config->popt & UNIPROTO_GFP) {
uni->cx.q2932 = 1;
*popt_mask &= ~UNIPROTO_GFP;
} else {
if (!uni->cx.q2932 || idle) {
uni->cx.q2932 = 0;
*popt_mask &= ~UNIPROTO_GFP;
}
}
}
if (*popt_mask & UNIPROTO_SB_TB) {
uni->sb_tb = ((config->popt & UNIPROTO_SB_TB) != 0);
*popt_mask &= ~UNIPROTO_SB_TB;
}
if (*opt_mask & UNIOPT_GIT_HARD) {
uni->cx.git_hard = ((config->option & UNIOPT_GIT_HARD) != 0);
*opt_mask &= ~UNIOPT_GIT_HARD;
}
if (*opt_mask & UNIOPT_BEARER_HARD) {
uni->cx.bearer_hard = ((config->option & UNIOPT_BEARER_HARD) != 0);
*opt_mask &= ~UNIOPT_BEARER_HARD;
}
if (*opt_mask & UNIOPT_CAUSE_HARD) {
uni->cx.cause_hard = ((config->option & UNIOPT_CAUSE_HARD) != 0);
*opt_mask &= ~UNIOPT_CAUSE_HARD;
}
#define SET_TIMER(NAME,name) \
if (*mask & UNICFG_##NAME) { \
uni->name = config->name; \
*mask &= ~UNICFG_##NAME; \
}
SET_TIMER(TIMER301, timer301);
SET_TIMER(TIMER303, timer303);
SET_TIMER(INIT303, init303);
SET_TIMER(TIMER308, timer308);
SET_TIMER(INIT308, init308);
SET_TIMER(TIMER309, timer309);
SET_TIMER(TIMER310, timer310);
SET_TIMER(TIMER313, timer313);
SET_TIMER(TIMER316, timer316);
SET_TIMER(INIT316, init316);
SET_TIMER(TIMER317, timer317);
SET_TIMER(TIMER322, timer322);
SET_TIMER(INIT322, init322);
SET_TIMER(TIMER397, timer397);
SET_TIMER(TIMER398, timer398);
SET_TIMER(TIMER399, timer399);
#undef SET_TIMER
}
void
uni_set_debug(struct uni *uni, enum uni_verb fac, u_int level)
{
uni->debug[fac] = level;
}
u_int
uni_get_debug(const struct uni *uni, enum uni_verb fac)
{
return (uni->debug[fac]);
}
u_int
uni_getcustate(const struct uni *uni)
{
return (uni->custat);
}

View File

@ -0,0 +1,442 @@
/*
* Copyright (c) 2001-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/atm/sig/sig_verify.c,v 1.16 2003/10/10 14:37:28 hbb Exp $
*
* Message verification with explicit action indicators.
*/
#include <netnatm/unimsg.h>
#include <netnatm/saal/sscfudef.h>
#include <netnatm/msg/unistruct.h>
#include <netnatm/msg/unimsglib.h>
#include <netnatm/sig/uni.h>
#include <netnatm/sig/unipriv.h>
#include <netnatm/sig/unimkmsg.h>
void
uni_mandate_ie(struct uni *uni, enum uni_ietype ie)
{
struct uni_ierr *e;
FOREACH_ERR(e, uni)
if (e->ie == ie) {
e->man = 1;
return;
}
if (UNI_SAVE_IERR(&uni->cx, ie, UNI_IEACT_DEFAULT, UNI_IERR_MIS))
uni->cx.err[uni->cx.errcnt - 1].man = 1;
}
/*
* This special handling is required for ADD PARTY, PARTY ALERTING and
* ADD PARTY ACKNOWLEDGE by Q.2971 9.5.3.2.1.
* It means, that the EPREF should be handled as mandatory only if
* no other IEs have explicit action indicators.
*/
void
uni_mandate_epref(struct uni *uni, struct uni_ie_epref *epref)
{
struct uni_ierr *e;
int maxact;
if (!IE_ISPRESENT(*epref)) {
/*
* 9.5.3.2.1 -- missing endpoint reference
*/
/*
* a) if any unrecognized or IE with error has a CLEAR
* action indicator, this takes precedence.
* b) if any unrecognized or IE with error has a
* discard message and report action indicator, this takes
* precedence.
* c) if any unrecognized or IE with error has a
* discard message action indicator, this takes
* precedence.
*
* In any of these cases we must remove the EPREF IE
* if it has CLEAR, otherwise the CLEAR would take over.
*/
maxact = -1;
FOREACH_ERR(e, uni) {
if (e->ie == UNI_IE_EPREF)
continue;
if (e->act == UNI_IEACT_CLEAR)
maxact = UNI_IEACT_CLEAR;
else if (e->act == UNI_IEACT_MSG_REPORT) {
if (maxact == -1 && maxact != UNI_IEACT_CLEAR)
maxact = UNI_IEACT_MSG_REPORT;
} else if (e->act == UNI_IEACT_MSG_IGNORE) {
if (maxact == -1)
maxact = UNI_IEACT_MSG_IGNORE;
}
}
if (maxact != -1) {
/* ok, second pass to remove UNI_IE_EPREF */
FOREACH_ERR(e, uni)
if (e->ie == UNI_IE_EPREF) {
memmove(e, e + 1,
(uni->cx.errcnt - (e - uni->cx.err)
- 1) * sizeof(uni->cx.err[0]));
uni->cx.errcnt--;
break;
}
return;
}
/*
* d) if nothing of the above, the IE is mandatory
*/
uni_mandate_ie(uni, UNI_IE_EPREF);
return;
}
if (IE_ISGOOD(*epref))
return;
/*
* It has an error obviously
* 9.5.3.2.2
*
* It turns out, that Q.2931 handling just does the right thing
* if we don't mandate the IE.
*/
return;
}
/*
* Look, what to do with this message. We assume, that the message itself is
* recognized.
*
* This is rather complicated. We must use the information provided in the
* fields of the context, because IEs with length errors may not be set
* altogether.
*/
enum verify
uni_verify(struct uni *uni, enum uni_msgact msgact)
{
struct uni_ierr *e1;
if (uni->debug[UNI_FAC_VERIFY] >= 2) {
FOREACH_ERR(e1, uni) {
VERBOSE(uni, UNI_FAC_VERIFY, 2, "ie=%02x err=%u man=%d"
" act=%u", e1->ie, e1->err, e1->man, e1->act);
}
}
/*
* Look for missing mandatory IEs. The action indicator is ignored
* according to 5.6.7.1. If IEs are missing the action is to
* ignore the message and report status for all messages except
* RELEASE, RELEASE_COMPLETE and SETUP. Because we must differentiate
* this RAI from other RAIs in this case, use another return code.
* Note, that mandatory IEs with errors are not handled here.
*/
FOREACH_ERR(e1, uni) {
if (e1->err == UNI_IERR_MIS) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_MANDAT);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAIM");
return (VFY_RAIM);
}
}
/*
* When any IE with error specifies a CLR action indicator, this
* takes precedence obviously. There are two cases here:
* unrecognized IEs and IEs with error. So we look through the
* error array twice and send only one STATUS. Unrecognized will
* take precedence.
*
* 5.7.2a)
*/
FOREACH_ERR(e1, uni) {
if (e1->act == UNI_IEACT_CLEAR && e1->err == UNI_IERR_UNK) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_IE_NIMPL);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "CLR1");
return (VFY_CLR);
}
}
FOREACH_ERR(e1, uni) {
if (e1->act == UNI_IEACT_CLEAR &&
(e1->err == UNI_IERR_LEN || e1->err == UNI_IERR_BAD ||
e1->err == UNI_IERR_ACC)) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_IE_INV);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "CLR2");
return (VFY_CLR);
}
}
/*
* Now check, whether anybody wants to explicitly ignore the message
* and report status.
*
* 5.7.2a)
*/
FOREACH_ERR(e1, uni) {
if (e1->act == UNI_IEACT_MSG_REPORT && e1->err == UNI_IERR_UNK) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_IE_NIMPL);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAI");
return (VFY_RAI);
}
}
FOREACH_ERR(e1, uni) {
if (e1->act == UNI_IEACT_MSG_REPORT &&
(e1->err == UNI_IERR_LEN || e1->err == UNI_IERR_BAD ||
e1->err == UNI_IERR_ACC)) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_IE_INV);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAI");
return (VFY_RAI);
}
}
/*
* Now look whether some IE wants to explicitely ignore the message
* without any report.
*/
FOREACH_ERR(e1, uni) {
if (e1->act == UNI_IEACT_MSG_IGNORE) {
VERBOSE(uni, UNI_FAC_VERIFY, 1, "I1");
return (VFY_I);
}
}
/*
* At this point we have left only
* mandatory and non-mandatory IEs with error that want the IE to be
* ignored or ignored with report or defaulted.
* Because a mandatory IE with errors lead to
* the message beeing ignored, we make this of higher
* precedence, than the rest.
*/
FOREACH_ERR(e1, uni) {
if (e1->man) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_MANDAT);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAI");
return (VFY_RAI);
}
}
/*
* Now look for ignoring the IE and reporting. This takes precedence
* over simply ignoring it. We also collect defaulted (non-mandatory)
* IEs.
*
* 5.7.2d) and 5.6.8.1
*/
FOREACH_ERR(e1, uni) {
if ((e1->act == UNI_IEACT_DEFAULT ||
e1->act == UNI_IEACT_REPORT)
&& e1->err != UNI_IERR_UNK) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_IE_INV);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAP");
return (VFY_RAP);
}
}
FOREACH_ERR(e1, uni) {
if ((e1->act == UNI_IEACT_DEFAULT ||
e1->act == UNI_IEACT_REPORT)
&& e1->err == UNI_IERR_UNK) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_IE_NIMPL);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAPU");
return (VFY_RAPU);
}
}
/*
* This leaves us with IEs, that want to be ignored. Among these may
* be mandatory IEs. If we have an mandatory IEs here in the error
* array, then the message wil not contain enough information and
* must be handled according to 5.8 as either in 5.6.7.1 (this
* means, that mandatory IEs cannot really be ignored) or 5.7.1.
*/
FOREACH_ERR(e1, uni) {
if (e1->man) {
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_MANDAT);
if (msgact == UNI_MSGACT_CLEAR) {
VERBOSE(uni, UNI_FAC_VERIFY, 1, "CLR3");
return (VFY_CLR);
}
if (msgact == UNI_MSGACT_IGNORE) {
VERBOSE(uni, UNI_FAC_VERIFY, 1, "I2");
return (VFY_I);
}
VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAI");
return (VFY_RAI);
}
}
/*
* Now only non-mandatory IEs are left, that want to be explicitely
* ignored.
*/
if (uni->cx.errcnt != 0)
MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
UNI_CAUSE_IE_INV);
VERBOSE(uni, UNI_FAC_VERIFY, 1, "OK");
return (VFY_OK);
}
/*
* Collect the IE identifiers for some of the known cause codes.
*/
void
uni_vfy_collect_ies(struct uni *uni)
{
struct uni_ierr *e;
#define STUFF_IE(IE) \
uni->cause.u.ie.ie[uni->cause.u.ie.len++] = (IE); \
if (uni->cause.u.ie.len == UNI_CAUSE_IE_N) \
break;
uni->cause.u.ie.len = 0;
if (uni->cause.cause == UNI_CAUSE_MANDAT) {
FOREACH_ERR(e, uni) {
if (e->err == UNI_IERR_MIS || e->man != 0) {
STUFF_IE(e->ie);
}
}
} else if (uni->cause.cause == UNI_CAUSE_IE_NIMPL) {
FOREACH_ERR(e, uni) {
if (e->err == UNI_IERR_UNK) {
STUFF_IE(e->ie);
}
}
} else if (uni->cause.cause == UNI_CAUSE_IE_INV) {
FOREACH_ERR(e, uni) {
if (e->err == UNI_IERR_LEN ||
e->err == UNI_IERR_BAD ||
e->err == UNI_IERR_ACC) {
STUFF_IE(e->ie);
}
}
} else
return;
if (uni->cause.u.ie.len != 0)
uni->cause.h.present |= UNI_CAUSE_IE_P;
}
void
uni_respond_status_verify(struct uni *uni, struct uni_cref *cref,
enum uni_callstate cs, struct uni_ie_epref *epref,
enum uni_epstate ps)
{
struct uni_all *resp;
if ((resp = UNI_ALLOC()) == NULL)
return;
uni_vfy_collect_ies(uni);
MK_MSG_RESP(resp, UNI_STATUS, cref);
MK_IE_CALLSTATE(resp->u.status.callstate, cs);
resp->u.status.cause = uni->cause;
if (epref && IE_ISGOOD(*epref)) {
MK_IE_EPREF(resp->u.status.epref, epref->epref, !epref->flag);
MK_IE_EPSTATE(resp->u.status.epstate, ps);
}
uni_send_output(resp, uni);
UNI_FREE(resp);
}
/*
* Handling of Q.2971 9.5.8.1:
*/
void
uni_vfy_remove_unknown(struct uni *uni)
{
struct uni_ierr *e1, *e0;
int flag = 0;
FOREACH_ERR(e1, uni) {
if (e1->err == UNI_IERR_UNK) {
if (e1->act == UNI_IEACT_CLEAR ||
e1->act == UNI_IEACT_MSG_IGNORE ||
e1->act == UNI_IEACT_MSG_REPORT)
return;
if (e1->act == UNI_IEACT_REPORT ||
e1->act == UNI_IEACT_DEFAULT)
flag = 1;
}
}
if (flag)
return;
e0 = e1 = uni->cx.err;
while (e1 < uni->cx.err + uni->cx.errcnt) {
if (e1->err != UNI_IERR_UNK) {
if (e0 != e1)
*e0 = *e1;
e0++;
}
e1++;
}
uni->cx.errcnt = e0 - uni->cx.err;
}
/*
* Handling for ADD_PARTY_REJ and DROP_PARTY_ACK with bad cause
*/
void
uni_vfy_remove_cause(struct uni *uni)
{
struct uni_ierr *e1, *e0;
e0 = e1 = uni->cx.err;
while (e1 < uni->cx.err + uni->cx.errcnt) {
if (e1->ie != UNI_IE_CAUSE) {
if (e0 != e1)
*e0 = *e1;
e0++;
}
e1++;
}
uni->cx.errcnt = e0 - uni->cx.err;
}

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2001-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/atm/sig/uni.h,v 1.3 2003/09/19 12:03:34 hbb Exp $
*
* Public UNI interface
*/
#ifndef _NETNATM_SIG_UNI_H_
#define _NETNATM_SIG_UNI_H_
#include <netnatm/sig/unidef.h>
struct uni;
/* functions to be supplied by the user */
struct uni_funcs {
/* output to the upper layer */
void (*uni_output)(struct uni *, void *, enum uni_sig,
u_int32_t, struct uni_msg *);
/* output to the SAAL */
void (*saal_output)(struct uni *, void *, enum saal_sig,
struct uni_msg *);
/* verbosity */
void (*verbose)(struct uni *, void *, enum uni_verb,
const char *, ...) __printflike(4, 5);
/* function to 'print' status */
void (*status)(struct uni *, void *, void *,
const char *, ...) __printflike(4, 5);
#ifndef _KERNEL
/* start a timer */
void *(*start_timer)(struct uni *, void *, u_int,
void (*)(void *), void *);
/* stop a timer */
void (*stop_timer)(struct uni *, void *, void *);
#endif
};
/* create a UNI instance */
struct uni *uni_create(void *, const struct uni_funcs *);
/* destroy a UNI instance, free all resources */
void uni_destroy(struct uni *);
/* generate a status report */
void uni_status(struct uni *, void *);
/* get current instance configuration */
void uni_get_config(const struct uni *, struct uni_config *);
/* set new instance configuration */
void uni_set_config(struct uni *, const struct uni_config *,
u_int32_t *, u_int32_t *, u_int32_t *);
/* input from the SAAL to the instance */
void uni_saal_input(struct uni *, enum saal_sig, struct uni_msg *);
/* input from the upper layer to the instance */
void uni_uni_input(struct uni *, enum uni_sig, u_int32_t, struct uni_msg *);
/* do work on pending signals */
void uni_work(struct uni *);
/* set debuging level */
void uni_set_debug(struct uni *, enum uni_verb, u_int level);
u_int uni_get_debug(const struct uni *, enum uni_verb);
/* reset a UNI instance */
void uni_reset(struct uni *);
/* states */
u_int uni_getcustate(const struct uni *);
/* return a reference to the coding/decoding context */
struct unicx *uni_context(struct uni *);
#endif

View File

@ -0,0 +1,474 @@
/*
* Copyright (c) 1996-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/atm/sig/unidef.h,v 1.6 2003/09/19 12:03:34 hbb Exp $
*
* UNI public definitions.
*/
#ifndef _ATM_SIG_UNIDEF_H_
#define _ATM_SIG_UNIDEF_H_
/*
* Debug facilities
*/
#define UNI_DEBUG_FACILITIES \
UNI_DEBUG_DEFINE(TIMEOUT) \
UNI_DEBUG_DEFINE(RESTART) \
UNI_DEBUG_DEFINE(SAAL) \
UNI_DEBUG_DEFINE(PARSE) \
UNI_DEBUG_DEFINE(CALL) \
UNI_DEBUG_DEFINE(WARN) \
UNI_DEBUG_DEFINE(COORD) \
UNI_DEBUG_DEFINE(API) \
UNI_DEBUG_DEFINE(MSG) \
UNI_DEBUG_DEFINE(ERR) \
UNI_DEBUG_DEFINE(VERIFY) \
enum uni_verb {
#define UNI_DEBUG_DEFINE(D) UNI_FAC_##D,
UNI_DEBUG_FACILITIES
#undef UNI_DEBUG_DEFINE
UNI_MAXFACILITY,
};
/*
* Default timer values and repeat counts
*/
#define UNI_T301_DEFAULT 180000
#define UNI_T303_DEFAULT 4000
#define UNI_T303_CNT_DEFAULT 2
#define UNI_T308_DEFAULT 30000
#define UNI_T308_CNT_DEFAULT 2
#define UNI_T309_DEFAULT 10000
#define UNI_T310U_DEFAULT 30000
#define UNI_T310N_DEFAULT 10000
#define UNI_T313_DEFAULT 4000
#define UNI_T316_DEFAULT 120000
#define UNI_T316_CNT_DEFAULT 2
#define UNI_T317_DEFAULT 90000
#define UNI_T322_DEFAULT 4000
#define UNI_T322_CNT_DEFAULT 2
#define UNI_T397_DEFAULT UNI_T301_DEFAULT
#define UNI_T398_DEFAULT 4000
#define UNI_T399U_DEFAULT (UNI_T303_DEFAULT + UNI_T310U_DEFAULT)
#define UNI_T399N_DEFAULT (UNI_T303_DEFAULT + UNI_T310N_DEFAULT)
/*
* Protocol support
*/
enum uni_proto {
UNIPROTO_UNI40U, /* UNI4.0 user side */
UNIPROTO_UNI40N, /* UNI4.0 network side */
UNIPROTO_PNNI10, /* PNNI1.0 */
};
enum uni_popt {
UNIPROTO_GFP = 0x0001, /* enable GFP */
UNIPROTO_SB_TB = 0x0002, /* Coincident Sb-Tb/Tb */
UNIPROTO_ALLMASK = 0x0003,
};
/*
* Other options
*/
enum uni_option {
UNIOPT_GIT_HARD = 0x0001, /* harder check of GIT IE */
UNIOPT_BEARER_HARD = 0x0002, /* harder check of BEARER IE */
UNIOPT_CAUSE_HARD = 0x0004, /* harder check of CAUSE IE */
UNIOPT_ALLMASK = 0x0007,
};
/*
* UNI configuration
*/
struct uni_config {
u_int32_t proto; /* which protocol */
u_int32_t popt; /* protocol option */
u_int32_t option; /* other options */
u_int32_t timer301; /* T301 */
u_int32_t timer303; /* T303 */
u_int32_t init303; /* T303 retransmission count */
u_int32_t timer308; /* T308 */
u_int32_t init308; /* T308 retransmission count */
u_int32_t timer309; /* T309 */
u_int32_t timer310; /* T310 */
u_int32_t timer313; /* T313 */
u_int32_t timer316; /* T316 */
u_int32_t init316; /* T316 retransmission count */
u_int32_t timer317; /* T317 */
u_int32_t timer322; /* T322 */
u_int32_t init322; /* T322 retransmission count */
u_int32_t timer397; /* T397 */
u_int32_t timer398; /* T398 */
u_int32_t timer399; /* T399 */
};
enum uni_config_mask {
UNICFG_PROTO = 0x00000001,
UNICFG_TIMER301 = 0x00000002,
UNICFG_TIMER303 = 0x00000004,
UNICFG_INIT303 = 0x00000008,
UNICFG_TIMER308 = 0x00000010,
UNICFG_INIT308 = 0x00000020,
UNICFG_TIMER309 = 0x00000040,
UNICFG_TIMER310 = 0x00000080,
UNICFG_TIMER313 = 0x00000100,
UNICFG_TIMER316 = 0x00000200,
UNICFG_INIT316 = 0x00000400,
UNICFG_TIMER317 = 0x00000800,
UNICFG_TIMER322 = 0x00001000,
UNICFG_INIT322 = 0x00002000,
UNICFG_TIMER397 = 0x00004000,
UNICFG_TIMER398 = 0x00008000,
UNICFG_TIMER399 = 0x00010000,
UNICFG_ALLMASK = 0x0001ffff,
};
/*
* API signals
*/
enum uni_sig {
UNIAPI_ERROR = 0, /* UNI -> API */
UNIAPI_CALL_CREATED = 1, /* UNI -> API */
UNIAPI_CALL_DESTROYED = 2, /* UNI -> API */
UNIAPI_PARTY_CREATED = 3, /* UNI -> API */
UNIAPI_PARTY_DESTROYED = 4, /* UNI -> API */
UNIAPI_LINK_ESTABLISH_request = 5, /* API -> UNI */
UNIAPI_LINK_ESTABLISH_confirm = 6, /* UNI -> API */
UNIAPI_LINK_RELEASE_request = 7, /* API -> UNI */
UNIAPI_LINK_RELEASE_confirm = 8, /* UNI -> API */
UNIAPI_RESET_request = 9, /* API -> UNI */
UNIAPI_RESET_confirm = 10, /* UNI -> API */
UNIAPI_RESET_indication = 11, /* UNI -> API */
UNIAPI_RESET_ERROR_indication = 12, /* UNI -> API */
UNIAPI_RESET_response = 13, /* API -> UNI */
UNIAPI_RESET_ERROR_response = 14, /* API -> UNI */
UNIAPI_RESET_STATUS_indication = 15, /* UNI -> API */
UNIAPI_SETUP_request = 16, /* API -> UNI */
UNIAPI_SETUP_indication = 17, /* UNI -> API */
UNIAPI_SETUP_response = 18, /* API -> UNI */
UNIAPI_SETUP_confirm = 19, /* UNI -> API */
UNIAPI_SETUP_COMPLETE_indication= 20, /* U-UNI -> API */
UNIAPI_SETUP_COMPLETE_request = 46, /* API -> N-UNI */
UNIAPI_ALERTING_request = 21, /* API -> UNI */
UNIAPI_ALERTING_indication = 22, /* UNI -> API */
UNIAPI_PROCEEDING_request = 23, /* API -> UNI */
UNIAPI_PROCEEDING_indication = 24, /* UNI -> API */
UNIAPI_RELEASE_request = 25, /* API -> UNI */
UNIAPI_RELEASE_indication = 26, /* UNI -> API */
UNIAPI_RELEASE_response = 27, /* API -> UNI */
UNIAPI_RELEASE_confirm = 28, /* UNI -> API */
UNIAPI_NOTIFY_request = 29, /* API -> UNI */
UNIAPI_NOTIFY_indication = 30, /* UNI -> API */
UNIAPI_STATUS_indication = 31, /* UNI -> API */
UNIAPI_STATUS_ENQUIRY_request = 32, /* API -> UNI */
UNIAPI_ADD_PARTY_request = 33, /* API -> UNI */
UNIAPI_ADD_PARTY_indication = 34, /* UNI -> API */
UNIAPI_PARTY_ALERTING_request = 35, /* API -> UNI */
UNIAPI_PARTY_ALERTING_indication= 36, /* UNI -> API */
UNIAPI_ADD_PARTY_ACK_request = 37, /* API -> UNI */
UNIAPI_ADD_PARTY_ACK_indication = 38, /* UNI -> API */
UNIAPI_ADD_PARTY_REJ_request = 39, /* API -> UNI */
UNIAPI_ADD_PARTY_REJ_indication = 40, /* UNI -> API */
UNIAPI_DROP_PARTY_request = 41, /* API -> UNI */
UNIAPI_DROP_PARTY_indication = 42, /* UNI -> API */
UNIAPI_DROP_PARTY_ACK_request = 43, /* API -> UNI */
UNIAPI_DROP_PARTY_ACK_indication= 44, /* UNI -> API */
UNIAPI_ABORT_CALL_request = 45, /* API -> UNI */
UNIAPI_MAXSIG = 47
};
struct uniapi_error {
u_int32_t reason;
u_int32_t state;
};
/* keep this in sync with atmapi.h:enum atmerr */
#define UNIAPI_DEF_ERRORS(MACRO) \
MACRO(OK, 0, "no error") \
MACRO(ERROR_BAD_SIGNAL, 1, "unknown signal") \
MACRO(ERROR_BADCU, 2, "signal in bad co-ordinator state") \
MACRO(ERROR_BAD_CALLSTATE, 3, "signal in bad call state") \
MACRO(ERROR_BAD_EPSTATE, 4, "signal in bad endpoint state") \
MACRO(ERROR_BAD_ARG, 5, "bad argument") \
MACRO(ERROR_BAD_CALL, 6, "unknown call reference") \
MACRO(ERROR_BAD_PARTY, 7, "unknown party") \
MACRO(ERROR_BAD_CTYPE, 8, "bad type of call for signal") \
MACRO(ERROR_BAD_IE, 9, "bad information element") \
MACRO(ERROR_EPREF_INUSE, 10, "endpoint reference already in use") \
MACRO(ERROR_MISSING_IE, 11, "missing information element") \
MACRO(ERROR_ENCODING, 12, "error during message encoding") \
MACRO(ERROR_NOMEM, 13, "out of memory") \
MACRO(ERROR_BUSY, 14, "status enquiry busy")
enum {
#define DEF(NAME, VAL, STR) UNIAPI_##NAME = VAL,
UNIAPI_DEF_ERRORS(DEF)
#undef DEF
};
struct uniapi_call_created {
struct uni_cref cref;
};
struct uniapi_call_destroyed {
struct uni_cref cref;
};
struct uniapi_party_created {
struct uni_cref cref;
struct uni_ie_epref epref;
};
struct uniapi_party_destroyed {
struct uni_cref cref;
struct uni_ie_epref epref;
};
struct uniapi_abort_call_request {
struct uni_cref cref;
};
struct uniapi_reset_request {
struct uni_ie_restart restart;
struct uni_ie_connid connid;
};
struct uniapi_reset_confirm {
struct uni_ie_restart restart;
struct uni_ie_connid connid;
};
struct uniapi_reset_indication {
struct uni_ie_restart restart;
struct uni_ie_connid connid;
};
struct uniapi_reset_error_indication {
u_int32_t source; /* 0 - start, 1 - response */
u_int32_t reason;
};
#define UNIAPI_DEF_RESET_ERRORS(MACRO) \
MACRO(UNIAPI_RESET_ERROR_NO_CONFIRM, 0, \
"no confirmation") \
MACRO(UNIAPI_RESET_ERROR_NO_RESPONSE, 1, \
"no response") \
MACRO(UNIAPI_RESET_ERROR_PEER_INCOMP_STATE, 2, \
"incompatible state")
enum {
#define DEF(NAME, VALUE, STR) NAME = VALUE,
UNIAPI_DEF_RESET_ERRORS(DEF)
#undef DEF
};
struct uniapi_reset_response {
struct uni_ie_restart restart;
struct uni_ie_connid connid;
};
struct uniapi_reset_error_response {
struct uni_ie_cause cause;
};
struct uniapi_reset_status_indication {
struct uni_cref cref; /* STATUS message CREF */
struct uni_ie_callstate callstate;
struct uni_ie_cause cause;
};
struct uniapi_setup_request {
struct uni_setup setup;
};
struct uniapi_setup_indication {
struct uni_setup setup;
};
struct uniapi_setup_response {
struct uni_connect connect;
};
struct uniapi_setup_confirm {
struct uni_connect connect;
};
struct uniapi_setup_complete_indication {
struct uni_connect_ack connect_ack;
};
struct uniapi_setup_complete_request {
struct uni_connect_ack connect_ack;
};
struct uniapi_alerting_request {
struct uni_alerting alerting;
};
struct uniapi_alerting_indication {
struct uni_alerting alerting;
};
struct uniapi_proceeding_request {
struct uni_call_proc call_proc;
};
struct uniapi_proceeding_indication {
struct uni_call_proc call_proc;
};
struct uniapi_release_request {
struct uni_release release;
};
struct uniapi_release_indication {
struct uni_release release;
};
struct uniapi_release_response {
struct uni_release_compl release_compl;
};
/*
* A release confirm can come from a RELEASE COMPLETE or a RELEASE.
* Because the IEs in a RELEASE COMPLETE are a subset of a RELEASE,
* use the RELEASE here.
*/
struct uniapi_release_confirm {
struct uni_release release;
};
struct uniapi_notify_request {
struct uni_notify notify;
};
struct uniapi_notify_indication {
struct uni_notify notify;
};
struct uniapi_status_indication {
struct uni_cref cref;
enum uni_callstate my_state;
enum uni_cause my_cause;
struct uni_ie_callstate his_state;
struct uni_ie_cause his_cause;
struct uni_ie_epref epref;
struct uni_ie_epstate epstate;
};
struct uniapi_status_enquiry_request {
struct uni_cref cref;
struct uni_ie_epref epref;
};
struct uniapi_add_party_request {
struct uni_add_party add;
};
struct uniapi_add_party_indication {
struct uni_add_party add;
};
struct uniapi_party_alerting_request {
struct uni_party_alerting alert;
};
struct uniapi_party_alerting_indication {
struct uni_party_alerting alert;
};
struct uniapi_add_party_ack_request {
struct uni_add_party_ack ack;
};
struct uniapi_add_party_ack_indication {
struct uni_add_party_ack ack;
};
struct uniapi_add_party_rej_request {
struct uni_add_party_rej rej;
};
struct uniapi_add_party_rej_indication {
struct uni_add_party_rej rej;
};
struct uniapi_drop_party_request {
struct uni_drop_party drop;
};
struct uniapi_drop_party_indication {
struct uni_drop_party drop;
struct uni_ie_cause my_cause;
};
struct uniapi_drop_party_ack_request {
struct uni_drop_party_ack ack;
};
struct uniapi_drop_party_ack_indication {
struct uni_drop_party drop;
struct uni_ie_crankback crankback;
};
union uniapi_all {
struct uniapi_error error;
struct uniapi_call_created call_created;
struct uniapi_call_destroyed call_destroyed;
struct uniapi_party_created party_created;
struct uniapi_party_destroyed party_destroyed;
struct uniapi_abort_call_request abort_call_request;
struct uniapi_reset_request reset_request;
struct uniapi_reset_confirm reset_confirm;
struct uniapi_reset_indication reset_indication;
struct uniapi_reset_error_indication reset_error_indication;
struct uniapi_reset_response reset_response;
struct uniapi_reset_error_response reset_error_response;
struct uniapi_reset_status_indication reset_status_indication;
struct uniapi_setup_request setup_request;
struct uniapi_setup_indication setup_indication;
struct uniapi_setup_response setup_response;
struct uniapi_setup_confirm setup_confirm;
struct uniapi_setup_complete_indication setup_complete_indication;
struct uniapi_setup_complete_request setup_complete_request;
struct uniapi_alerting_request alerting_request;
struct uniapi_alerting_indication alerting_indication;
struct uniapi_proceeding_request proceeding_request;
struct uniapi_proceeding_indication proceeding_indication;
struct uniapi_release_request release_request;
struct uniapi_release_indication release_indication;
struct uniapi_release_response release_response;
struct uniapi_release_confirm release_confirm;
struct uniapi_notify_request notify_request;
struct uniapi_notify_indication notify_indication;
struct uniapi_status_indication status_indication;
struct uniapi_status_enquiry_request status_enquiry_request;
struct uniapi_add_party_request add_party_request;
struct uniapi_add_party_indication add_party_indication;
struct uniapi_party_alerting_request party_alerting_request;
struct uniapi_party_alerting_indication party_alerting_indication;
struct uniapi_add_party_ack_request add_party_ack_request;
struct uniapi_add_party_ack_indication add_party_ack_indication;
struct uniapi_add_party_rej_request add_party_rej_request;
struct uniapi_add_party_rej_indication add_party_rej_indication;
struct uniapi_drop_party_request drop_party_request;
struct uniapi_drop_party_indication drop_party_indication;
struct uniapi_drop_party_ack_request drop_party_ack_request;
struct uniapi_drop_party_ack_indication drop_party_ack_indication;
};
#endif

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2001-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/atm/sig/unimkmsg.h,v 1.4 2003/09/19 12:03:34 hbb Exp $
*
* Macros to make messages.
*/
#define MK_MSG_ORIG(MSG,TYPE,CREF,FLAG) \
do { \
(MSG)->mtype = (TYPE); \
(MSG)->u.hdr.cref.cref = (CREF); \
(MSG)->u.hdr.cref.flag = (FLAG); \
(MSG)->u.hdr.act = UNI_MSGACT_DEFAULT; \
} while(0)
#define MK_MSG_RESP(MSG,TYPE,CREF) \
do { \
(MSG)->mtype = (TYPE); \
(MSG)->u.hdr.cref.cref = (CREF)->cref; \
(MSG)->u.hdr.cref.flag = !(CREF)->flag; \
(MSG)->u.hdr.act = UNI_MSGACT_DEFAULT; \
} while(0)
#define MK_IE_CALLSTATE(IE,CS) \
do { \
(IE).h.present = 0; \
IE_SETPRESENT(IE); \
(IE).h.coding = UNI_CODING_ITU; \
(IE).h.act = UNI_IEACT_DEFAULT; \
(IE).state = CS; \
} while(0)
#define MK_IE_EPREF(IE,EPREF,FLAG) \
do { \
(IE).h.present = 0; \
IE_SETPRESENT(IE); \
(IE).h.coding = UNI_CODING_ITU; \
(IE).h.act = UNI_IEACT_DEFAULT; \
(IE).epref = EPREF; \
(IE).flag = FLAG; \
} while(0)
#define MK_IE_EPSTATE(IE,STATE) \
do { \
(IE).h.present = 0; \
IE_SETPRESENT(IE); \
(IE).h.coding = UNI_CODING_ITU; \
(IE).h.act = UNI_IEACT_DEFAULT; \
(IE).state = STATE; \
} while(0)
#define MK_IE_CAUSE(IE,LOC,CAUSE) \
do { \
(IE).h.present = 0; \
IE_SETPRESENT(IE); \
(IE).h.coding = UNI_CODING_ITU; \
(IE).h.act = UNI_IEACT_DEFAULT; \
(IE).loc = LOC; \
(IE).cause = CAUSE; \
} while(0)
#define ADD_CAUSE_MTYPE(IE,MTYPE) \
do { \
(IE).h.present |= UNI_CAUSE_MTYPE_P; \
(IE).u.mtype = MTYPE; \
} while(0)
#define ADD_CAUSE_CHANNID(IE,VPI,VCI) \
do { \
(IE).h.present |= UNI_CAUSE_VPCI_P; \
(IE).u.vpci.vpci = VPI; \
(IE).u.vpci.vci = VCI; \
} while(0)
#define ADD_CAUSE_TIMER(IE,TIMER) \
do { \
(IE).h.present |= UNI_CAUSE_TIMER_P; \
(IE).u.timer[0] = (TIMER)[0]; \
(IE).u.timer[1] = (TIMER)[1]; \
(IE).u.timer[2] = (TIMER)[2]; \
} while(0)
/************************************************************/
#define COPY_FROM_RELEASE_COMPL(U,DEST) \
do { \
u_int _i, _j; \
\
for(_i = _j = 0; _i < 2; _i++) \
if(IE_ISGOOD((U)->u.release_compl.cause[_i])) \
(DEST)->cause[_j++] = \
(U)->u.release_compl.cause[_i]; \
for(_i = _j = 0; _i < UNI_NUM_IE_GIT; _i++) \
if(IE_ISGOOD((U)->u.release_compl.git[_i])) \
(DEST)->git[_j++] = \
(U)->u.release_compl.git[_i]; \
if(IE_ISGOOD((U)->u.release_compl.uu)) \
(DEST)->uu = (U)->u.release_compl.uu; \
if(IE_ISGOOD((U)->u.release_compl.crankback)) \
(DEST)->crankback = (U)->u.release_compl.crankback; \
} while(0)
#define COPY_FROM_DROP_ACK(U,DEST) \
do { \
u_int _i, _j; \
\
if(IE_ISGOOD((U)->u.drop_party_ack.epref)) \
(DEST)->epref = (U)->u.drop_party_ack.epref; \
if(IE_ISGOOD((U)->u.drop_party_ack.cause)) \
(DEST)->cause = (U)->u.drop_party_ack.cause; \
if(IE_ISGOOD((U)->u.drop_party_ack.uu)) \
(DEST)->uu = (U)->u.drop_party_ack.uu; \
for(_i = _j = 0; _i < UNI_NUM_IE_GIT; _i++) \
if(IE_ISGOOD((U)->u.drop_party_ack.git[_i])) \
(DEST)->git[_j++] = \
(U)->u.drop_party_ack.git[_i]; \
} while(0)
#define COPY_FROM_ADD_REJ(U,DEST) \
do { \
u_int _i, _j; \
\
if(IE_ISGOOD((U)->u.add_party_rej.epref)) \
(DEST)->epref = (U)->u.add_party_rej.epref; \
if(IE_ISGOOD((U)->u.add_party_rej.cause)) \
(DEST)->cause = (U)->u.add_party_rej.cause; \
if(IE_ISGOOD((U)->u.add_party_rej.uu)) \
(DEST)->uu = (U)->u.add_party_rej.uu; \
for(_i = _j = 0; _i < UNI_NUM_IE_GIT; _i++) \
if(IE_ISGOOD((U)->u.add_party_rej.git[_i])) \
(DEST)->git[_j++] = \
(U)->u.add_party_rej.git[_i]; \
} while(0)

View File

@ -0,0 +1,544 @@
/*
* Copyright (c) 1996-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/atm/sig/unipriv.h,v 1.5 2003/09/24 10:27:50 hbb Exp $
*
* Private UNI stuff.
*/
#ifndef unipriv_h
#define unipriv_h
#ifdef _KERNEL
#ifdef __FreeBSD__
#include <netgraph/atm/uni/ng_uni_cust.h>
#endif
#else
#include "unicust.h"
#endif
struct call;
struct party;
enum cu_stat {
CU_STAT0, /* AAL connection released */
CU_STAT1, /* awaiting establish */
CU_STAT2, /* awaiting release */
CU_STAT3, /* AAL connection established */
};
/*
* Internal Signals
*/
#define DEF_COORD_SIGS \
DEF_PRIV_SIG(O_SAAL_ESTABLISH_indication, SAAL) \
DEF_PRIV_SIG(O_SAAL_ESTABLISH_confirm, SAAL) \
DEF_PRIV_SIG(O_SAAL_RELEASE_indication, SAAL) \
DEF_PRIV_SIG(O_SAAL_RELEASE_confirm, SAAL) \
DEF_PRIV_SIG(O_SAAL_DATA_indication, SAAL) \
DEF_PRIV_SIG(O_SAAL_UDATA_indication, SAAL) \
DEF_PRIV_SIG(O_T309, Coord) \
DEF_PRIV_SIG(O_DATA, Coord) \
DEF_PRIV_SIG(O_LINK_ESTABLISH_request, API) \
DEF_PRIV_SIG(O_LINK_RELEASE_request, API) \
DEF_PRIV_SIG(O_RESET_request, API) \
DEF_PRIV_SIG(O_RESET_response, API) \
DEF_PRIV_SIG(O_RESET_ERROR_response, API) \
DEF_PRIV_SIG(O_SETUP_request, API) \
DEF_PRIV_SIG(O_SETUP_response, API) \
DEF_PRIV_SIG(O_SETUP_COMPLETE_request, API) \
DEF_PRIV_SIG(O_PROCEEDING_request, API) \
DEF_PRIV_SIG(O_ALERTING_request, API) \
DEF_PRIV_SIG(O_RELEASE_request, API) \
DEF_PRIV_SIG(O_RELEASE_response, API) \
DEF_PRIV_SIG(O_NOTIFY_request, API) \
DEF_PRIV_SIG(O_STATUS_ENQUIRY_request, API) \
DEF_PRIV_SIG(O_ADD_PARTY_request, API) \
DEF_PRIV_SIG(O_PARTY_ALERTING_request, API) \
DEF_PRIV_SIG(O_ADD_PARTY_ACK_request, API) \
DEF_PRIV_SIG(O_ADD_PARTY_REJ_request, API) \
DEF_PRIV_SIG(O_DROP_PARTY_request, API) \
DEF_PRIV_SIG(O_DROP_PARTY_ACK_request, API) \
DEF_PRIV_SIG(O_ABORT_CALL_request, API) \
DEF_PRIV_SIG(O_CALL_DESTROYED, CallControl) \
DEF_PRIV_SIG(O_RESET_indication, ResetRespond) \
DEF_PRIV_SIG(O_END, Coord)
#define DEF_RESPOND_SIGS \
DEF_PRIV_SIG(R_RESTART, Coord) \
DEF_PRIV_SIG(R_STATUS, Coord) \
DEF_PRIV_SIG(R_RESET_response, Coord) \
DEF_PRIV_SIG(R_RESET_ERROR_response, Coord) \
DEF_PRIV_SIG(R_T317, ResetRespond) \
DEF_PRIV_SIG(R_END, ResetRespond)
#define DEF_START_SIGS \
DEF_PRIV_SIG(S_RESTART_ACK, Coord) \
DEF_PRIV_SIG(S_STATUS, Coord) \
DEF_PRIV_SIG(S_RESET_request, Coord) \
DEF_PRIV_SIG(S_T316, ResetStart) \
DEF_PRIV_SIG(S_END, ResetStart)
#define DEF_CALL_SIGS \
DEF_PRIV_SIG(C_LINK_ESTABLISH_confirm, Coord) \
DEF_PRIV_SIG(C_LINK_ESTABLISH_indication, Coord) \
DEF_PRIV_SIG(C_LINK_ESTABLISH_ERROR_indication,Coord) \
DEF_PRIV_SIG(C_LINK_RELEASE_indication, Coord) \
DEF_PRIV_SIG(C_SETUP_request, Coord) \
DEF_PRIV_SIG(C_SETUP_response, Coord) \
DEF_PRIV_SIG(C_SETUP_COMPLETE_request, Coord) \
DEF_PRIV_SIG(C_PROCEEDING_request, Coord) \
DEF_PRIV_SIG(C_ALERTING_request, Coord) \
DEF_PRIV_SIG(C_RELEASE_request, Coord) \
DEF_PRIV_SIG(C_RELEASE_response, Coord) \
DEF_PRIV_SIG(C_NOTIFY_request, Coord) \
DEF_PRIV_SIG(C_STATUS_ENQUIRY_request, Coord) \
DEF_PRIV_SIG(C_ADD_PARTY_request, Coord) \
DEF_PRIV_SIG(C_PARTY_ALERTING_request, Coord) \
DEF_PRIV_SIG(C_ADD_PARTY_ACK_request, Coord) \
DEF_PRIV_SIG(C_ADD_PARTY_REJ_request, Coord) \
DEF_PRIV_SIG(C_DROP_PARTY_request, Coord) \
DEF_PRIV_SIG(C_DROP_PARTY_ACK_request, Coord) \
DEF_PRIV_SIG(C_ABORT_CALL_request, Coord) \
DEF_PRIV_SIG(C_UNKNOWN, Coord) \
DEF_PRIV_SIG(C_SETUP, Coord) \
DEF_PRIV_SIG(C_CALL_PROC, Coord) \
DEF_PRIV_SIG(C_ALERTING, Coord) \
DEF_PRIV_SIG(C_CONNECT, Coord) \
DEF_PRIV_SIG(C_CONNECT_ACK, Coord) \
DEF_PRIV_SIG(C_RELEASE, Coord) \
DEF_PRIV_SIG(C_RELEASE_COMPL, Coord) \
DEF_PRIV_SIG(C_COBISETUP, Coord) \
DEF_PRIV_SIG(C_NOTIFY, Coord) \
DEF_PRIV_SIG(C_STATUS, Coord) \
DEF_PRIV_SIG(C_STATUS_ENQ, Coord) \
DEF_PRIV_SIG(C_ADD_PARTY, Coord) \
DEF_PRIV_SIG(C_PARTY_ALERTING, Coord) \
DEF_PRIV_SIG(C_ADD_PARTY_ACK, Coord) \
DEF_PRIV_SIG(C_ADD_PARTY_REJ, Coord) \
DEF_PRIV_SIG(C_DROP_PARTY, Coord) \
DEF_PRIV_SIG(C_DROP_PARTY_ACK, Coord) \
DEF_PRIV_SIG(C_CALL_DELETE, CallControl) \
DEF_PRIV_SIG(C_T301, CallControl) \
DEF_PRIV_SIG(C_T303, CallControl) \
DEF_PRIV_SIG(C_T308, CallControl) \
DEF_PRIV_SIG(C_T310, CallControl) \
DEF_PRIV_SIG(C_T313, CallControl) \
DEF_PRIV_SIG(C_T322, CallControl) \
DEF_PRIV_SIG(C_DROP_PARTY_indication, PartyControl) \
DEF_PRIV_SIG(C_SEND_DROP_PARTY, PartyControl) \
DEF_PRIV_SIG(C_DROP_PARTY_ACK_indication, PartyControl) \
DEF_PRIV_SIG(C_SEND_DROP_PARTY_ACK, PartyControl) \
DEF_PRIV_SIG(C_ADD_PARTY_REJ_indication, PartyControl) \
DEF_PRIV_SIG(C_SEND_ADD_PARTY_REJ, PartyControl) \
DEF_PRIV_SIG(C_SEND_STATUS_ENQ, PartyControl) \
DEF_PRIV_SIG(C_PARTY_DESTROYED, PartyControl) \
DEF_PRIV_SIG(C_END, CallControl)
#define DEF_PARTY_SIGS \
DEF_PRIV_SIG(P_SETUP, CallControl) \
DEF_PRIV_SIG(P_ALERTING, CallControl) \
DEF_PRIV_SIG(P_CONNECT, CallControl) \
DEF_PRIV_SIG(P_CONNECT_ACK, CallControl) \
DEF_PRIV_SIG(P_RELEASE, CallControl) \
DEF_PRIV_SIG(P_RELEASE_COMPL, CallControl) \
DEF_PRIV_SIG(P_STATUS, CallControl) \
DEF_PRIV_SIG(P_ADD_PARTY, CallControl) \
DEF_PRIV_SIG(P_PARTY_ALERTING, CallControl) \
DEF_PRIV_SIG(P_ADD_PARTY_ACK, CallControl) \
DEF_PRIV_SIG(P_ADD_PARTY_REJ, CallControl) \
DEF_PRIV_SIG(P_DROP_PARTY, CallControl) \
DEF_PRIV_SIG(P_DROP_PARTY_ACK, CallControl) \
DEF_PRIV_SIG(P_SETUP_request, CallControl) \
DEF_PRIV_SIG(P_SETUP_response, CallControl) \
DEF_PRIV_SIG(P_SETUP_COMPL_request, CallControl) \
DEF_PRIV_SIG(P_ALERTING_request, CallControl) \
DEF_PRIV_SIG(P_RELEASE_request, CallControl) \
DEF_PRIV_SIG(P_RELEASE_response, CallControl) \
DEF_PRIV_SIG(P_RELEASE_confirm, CallControl) \
DEF_PRIV_SIG(P_STATUS_ENQUIRY_request, CallControl) \
DEF_PRIV_SIG(P_ADD_PARTY_request, CallControl) \
DEF_PRIV_SIG(P_PARTY_ALERTING_request, CallControl) \
DEF_PRIV_SIG(P_ADD_PARTY_ACK_request, CallControl) \
DEF_PRIV_SIG(P_ADD_PARTY_REJ_request, CallControl) \
DEF_PRIV_SIG(P_DROP_PARTY_request, CallControl) \
DEF_PRIV_SIG(P_DROP_PARTY_ACK_request, CallControl) \
DEF_PRIV_SIG(P_PARTY_DELETE, PartyControl) \
DEF_PRIV_SIG(P_T397, PartyControl) \
DEF_PRIV_SIG(P_T398, PartyControl) \
DEF_PRIV_SIG(P_T399, PartyControl) \
DEF_PRIV_SIG(P_END, PartyControl)
#define DEF_PRIV_SIG(NAME, FROM) SIG##NAME,
enum coord_sig {
DEF_COORD_SIGS
};
enum respond_sig {
DEF_RESPOND_SIGS
};
enum start_sig {
DEF_START_SIGS
};
enum call_sig {
DEF_CALL_SIGS
};
enum party_sig {
DEF_PARTY_SIGS
};
#undef DEF_PRIV_SIG
/*************************************************************
*
* SIGNALS and SIGNAL QUEUES
*/
enum {
SIG_COORD,
SIG_RESET_START,
SIG_RESET_RESP,
SIG_CALL,
SIG_PARTY,
};
struct sig {
TAILQ_ENTRY(sig) link;
u_int type; /* one of the above */
struct call *call; /* call to send to */
struct party *party; /* party to send to */
u_int32_t sig; /* the signal */
u_int32_t cookie; /* user cookie */
struct uni_msg *msg; /* attached message */
struct uni_all *u; /* dito */
};
TAILQ_HEAD(sigqueue, sig);
#define SIGQ_CLEAR(Q) \
do { \
struct sig *s; \
while(!TAILQ_EMPTY(Q)) { \
s = TAILQ_FIRST(Q); \
TAILQ_REMOVE(Q, s, link); \
if(s->msg) uni_msg_destroy(s->msg); \
if(s->u) UNI_FREE(s->u); \
SIG_FREE(s); \
} \
} while(0)
void uni_sig_party(struct party *, enum party_sig, u_int32_t cookie,
struct uni_msg *, struct uni_all *);
void uni_sig_call(struct call *, enum call_sig, u_int32_t cookie,
struct uni_msg *, struct uni_all *);
void uni_sig_coord(struct uni *, enum coord_sig, u_int32_t cookie,
struct uni_msg *);
void uni_sig_start(struct uni *, enum start_sig, u_int32_t cookie,
struct uni_msg *, struct uni_all *);
void uni_sig_respond(struct uni *, enum respond_sig, u_int32_t cookie,
struct uni_msg *, struct uni_all *);
/*************************************************************
*
* CALL INSTANCES
*/
struct party {
struct call *call;
TAILQ_ENTRY(party) link;
u_int epref; /* endpoint reference */
u_int flags; /* flags */
enum uni_epstate state; /* party state */
struct uni_timer t397; /* T397 */
struct uni_timer t398; /* T398 */
struct uni_timer t399; /* T399 */
};
#define PARTY_MINE 0x0001 /* must be 1 */
#define PARTY_CONNECT 0x0002 /* connect request from this party */
TAILQ_HEAD(partyqueue, party);
void uni_destroy_party(struct party *, int);
struct party *uni_find_party(struct call *, struct uni_ie_epref *);
struct party *uni_find_partyx(struct call *, u_int epref, u_int mine);
struct party *uni_create_party(struct call *, struct uni_ie_epref *);
struct party *uni_create_partyx(struct call *, u_int epref, u_int mine, u_int32_t cookie);
u_int uni_party_act_count(struct call *, int);
enum call_type {
CALL_NULL, /* not known yet */
CALL_P2P, /* normal point-to-point call */
CALL_COBI, /* Q.2932.1 COBI call */
CALL_ROOT, /* point-to-multipoint root */
CALL_LEAF, /* point-to-multipoint leaf */
};
enum call_state {
CALLST_NULL,
CALLST_U1, CALLST_U3, CALLST_U4, CALLST_U6, CALLST_U7, CALLST_U8,
CALLST_U9, CALLST_U10, CALLST_U11, CALLST_U12,
CALLST_N1, CALLST_N3, CALLST_N4, CALLST_N6, CALLST_N7, CALLST_N8,
CALLST_N9, CALLST_N10, CALLST_N11, CALLST_N12
};
struct call {
TAILQ_ENTRY(call) link; /* link between calls */
struct uni *uni; /* backpointer to owning UNI */
u_int cref; /* call reference value or lij seqno */
u_int mine; /* if TRUE this is my call */
enum call_type type; /* what call is it */
enum call_state cstate; /* the state of the call */
struct uni_ie_connid connid; /* the connection ID */
struct uni_setup msg_setup; /* retransmission */
struct uni_release msg_release; /* retransmission */
struct uni_ie_epref stat_epref; /* retransmission */
struct partyqueue parties;
u_int se_active; /* status enquiry active */
u_int epref_alloc;
struct uni_timer t308; /* T303 */
u_int cnt308;
struct uni_timer t303; /* T303 */
u_int cnt303;
struct uni_timer t301; /* T301 */
struct uni_timer t310; /* T310 */
struct uni_timer t313; /* T313 */
struct uni_timer t322; /* T322 */
u_int cnt322;
};
TAILQ_HEAD(callqueue, call);
struct call *uni_find_call(struct uni *, struct uni_cref *);
struct call *uni_find_callx(struct uni *, u_int cref, u_int mine);
struct call *uni_create_call(struct uni *, u_int cref, u_int mine,
u_int32_t cookie);
struct call *uni_create_new_call(struct uni *, u_int32_t cookie);
void uni_destroy_call(struct call *, int);
void uni_bad_message(struct call *, struct uni_all *, u_int,
struct uni_ie_epref *, int);
extern const struct callstates {
const char *name;
enum uni_callstate ext;
} callstates[];
/*************************************************************
*
* UNI INSTANCE
*/
struct uni {
void *arg; /* user arg */
const struct uni_funcs *funcs;
enum uni_proto proto; /* protocol */
struct unicx cx; /* decoding/coding context */
int sb_tb : 1; /* Sb-Tb/Tb point */
struct sigqueue workq; /* work queue */
struct sigqueue delq; /* delayed signal queue */
int working;
u_int32_t cref_alloc;
enum cu_stat custat; /* coordinator state */
struct uni_timer t309;
u_int timer309;
enum uni_callstate glob_start;
enum uni_callstate glob_respond;
struct uni_timer t316;
struct uni_timer t317;
struct uni_ie_connid connid_start;
struct uni_ie_connid connid_respond;
u_int cnt316;
struct uni_ie_restart restart_start;
struct callqueue calls;
struct uni_ie_cause cause; /* working area for verify */
/* tuneable parameters */
u_int timer301;
u_int init303;
u_int timer303;
u_int init308;
u_int timer308;
u_int timer310;
u_int timer313;
u_int init316;
u_int timer316;
u_int timer317;
u_int timer322;
u_int init322;
u_int timer397;
u_int timer398;
u_int timer399;
u_int debug[UNI_MAXFACILITY];
};
void uniapi_uni_error(struct uni *uni, u_int32_t reason, u_int32_t cookie,
u_int32_t state);
void uniapi_call_error(struct call *c, u_int32_t reason, u_int32_t cookie);
void uniapi_party_error(struct party *p, u_int32_t reason, u_int32_t cookie);
/*************************************************************
*
* INLINE FUNCTIONS
*/
/* Enqueue a signal in the working queue */
void uni_enq_sig(struct uni *, u_int, struct call *, struct party *,
uint32_t, uint32_t, struct uni_msg *, struct uni_all *);
/* Enqueue a signal in the delayed queue */
void uni_delenq_sig(struct uni *, u_int, struct call *, struct party *,
uint32_t, uint32_t, struct uni_msg *, struct uni_all *);
/* Enqueue a signal to the coordinator */
#define uni_enq_coord(UNI, SIG, COOKIE, MSG) do { \
uni_enq_sig((UNI), SIG_COORD, NULL, NULL, \
(SIG), (COOKIE), (MSG), NULL); \
} while (0)
/* Enqueue a delayed signal to the coordinator */
#define uni_delenq_coord(UNI, SIG, COOKIE, MSG) do { \
uni_delenq_sig((UNI), SIG_COORD, NULL, NULL, \
(SIG), (COOKIE), (MSG), NULL); \
} while (0)
/* Enqueue a signal to a call */
#define uni_enq_call(CALL, SIG, COOKIE, MSG, U) do { \
uni_enq_sig((CALL)->uni, SIG_CALL, (CALL), NULL, \
(SIG), (COOKIE), (MSG), (U)); \
} while (0)
/* Enqueue a signal to a party */
#define uni_enq_party(PARTY, SIG, COOKIE, MSG, U) do { \
uni_enq_sig((PARTY)->call->uni, SIG_PARTY, (PARTY)->call, \
(PARTY), (SIG), (COOKIE), (MSG), (U)); \
} while (0)
/* Enqueue a signal to RESET-START */
#define uni_enq_start(UNI, SIG, COOKIE, MSG, U) do { \
uni_enq_sig((UNI), SIG_RESET_START, NULL, NULL, \
(SIG), (COOKIE), (MSG), (U)); \
} while (0)
/* Enqueue a signal to RESET-RESPOND */
#define uni_enq_resp(UNI, SIG, COOKIE, MSG, U) do { \
uni_enq_sig((UNI), SIG_RESET_RESP, NULL, NULL, \
(SIG), (COOKIE), (MSG), (U)); \
} while (0)
int uni_send_output(struct uni_all *u, struct uni *uni);
void uni_undel(struct uni *, int (*)(struct sig *, void *), void *);
void uni_delsig(struct uni *, u_int, struct call *, struct party *);
void uni_release_compl(struct call *, struct uni_all *);
/*************************************************************/
/*
* Message verification.
*/
#define MANDATE_IE(UNI,MSG,IE) \
do { \
if (!IE_ISGOOD(MSG)) \
uni_mandate_ie(UNI, IE); \
} while(0)
enum verify {
VFY_OK, /* ok */
VFY_RAP, /* report and proceed */
VFY_RAPU, /* report and proceed becuase of unknown IEs */
VFY_I, /* ignore */
VFY_CLR, /* clear call */
VFY_RAI, /* report and ignore */
VFY_RAIM, /* report and ignore because if mandat. IE miss */
};
void uni_mandate_ie(struct uni *, enum uni_ietype);
void uni_mandate_epref(struct uni *, struct uni_ie_epref *);
enum verify uni_verify(struct uni *, enum uni_msgact);
void uni_respond_status_verify(struct uni *, struct uni_cref *,
enum uni_callstate, struct uni_ie_epref *, enum uni_epstate);
void uni_vfy_remove_unknown(struct uni *);
void uni_vfy_remove_cause(struct uni *);
void uni_vfy_collect_ies(struct uni *);
void uni_respond_status(struct uni *uni, struct uni_cref *cref,
enum uni_callstate cs, enum uni_cause c1);
void uni_respond_status_mtype(struct uni *uni, struct uni_cref *cref,
enum uni_callstate cs, enum uni_cause c1, u_int mtype);
#define FOREACH_ERR(E, UNI) \
for ((E) = (UNI)->cx.err; (E) < (UNI)->cx.err + (UNI)->cx.errcnt; (E)++)
#define ALLOC_API(TYPE,API) \
({ \
TYPE *_tmp = NULL; \
\
if(((API) = uni_msg_alloc(sizeof(TYPE))) != NULL) { \
_tmp = uni_msg_wptr((API), TYPE *); \
(API)->b_wptr += sizeof(TYPE); \
memset(_tmp, 0, sizeof(TYPE)); \
} \
_tmp; \
})
#define VERBOSE(UNI, FAC, LEVEL, FMT, ARGS...) do { \
if ((UNI)->debug[(FAC)] >= (LEVEL)) { \
(UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC), \
FMT , ## ARGS); \
} \
} while(0)
#define VERBOSE0(UNI, FAC, FMT, ARGS...) do { \
(UNI)->funcs->verbose((UNI), (UNI)->arg, (FAC), FMT , \
## ARGS); \
} while(0)
#define TIMER_INIT_UNI(U,T) _TIMER_INIT(U,T)
#define TIMER_INIT_CALL(C,T) _TIMER_INIT(C,T)
#define TIMER_INIT_PARTY(P,T) _TIMER_INIT(P,T)
#define TIMER_DESTROY_UNI(U,T) _TIMER_DESTROY(U, (U)->T)
#define TIMER_DESTROY_CALL(C,T) _TIMER_DESTROY((C)->uni, (C)->T)
#define TIMER_DESTROY_PARTY(P,T) _TIMER_DESTROY((P)->call->uni, (P)->T)
#define TIMER_STOP_UNI(U,T) _TIMER_STOP(U, (U)->T)
#define TIMER_STOP_CALL(C,T) _TIMER_STOP((C)->uni, (C)->T)
#define TIMER_STOP_PARTY(P,T) _TIMER_STOP((P)->call->uni, (P)->T)
#define TIMER_START_UNI(U,T,N) _TIMER_START(U, U, (U)->T, N, _##T##_func)
#define TIMER_START_CALL(C,T,N) _TIMER_START(C->uni, C, (C)->T, N, _##T##_func)
#define TIMER_START_PARTY(P,T,N) _TIMER_START(P->call->uni, P, (P)->T, N, _##T##_func)
#endif

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2001-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Hartmut Brandt <harti@freebsd.org>
*
* $Begemot: libunimsg/atm/sig/unisig.h,v 1.3 2003/09/19 12:03:34 hbb Exp $
*
* Utility functions for signalling stuff
*/
#ifndef _NETNATM_SIG_UNISIG_H_
#define _NETNATM_SIG_UNISIG_H_
#include <netnatm/sig/unidef.h>
/* names */
const char *uni_signame(enum uni_sig);
const char *uni_facname(enum uni_verb);
/* return a string for the error code */
const char *uni_strerr(u_int _err);
/* format an API message */
void uni_print_api(char *_buf, size_t _bufsiz, u_int _type, u_int _cookie,
const void *_msg, struct unicx *_cx);
#endif