mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-25 11:37:56 +00:00
8419ef9a1e
clang compile this files. Approved by: ed (mentor) Silence from: harti (maintainer?)
750 lines
19 KiB
C
750 lines
19 KiB
C
/*
|
|
* 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/netnatm/sig/sig_uni.c,v 1.11 2004/08/05 07:11:03 brandt 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, uint32_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, uint32_t sig, uint32_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, uint32_t sig, uint32_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, uint32_t reason, uint32_t cookie,
|
|
uint32_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, uint32_t reason, uint32_t cookie)
|
|
{
|
|
uniapi_uni_error(c->uni, reason, cookie, callstates[c->cstate].ext);
|
|
}
|
|
void
|
|
uniapi_party_error(struct party *p, uint32_t reason, uint32_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,
|
|
uint32_t *mask, uint32_t *popt_mask, uint32_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);
|
|
}
|