/*
 *
 Copyright (c) Eicon Networks, 2002.
 *
 This source file is supplied for the use with
 Eicon Networks range of DIVA Server Adapters.
 *
 Eicon File Revision :    2.1
 *
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 *
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 See the GNU General Public License for more details.
 *
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */





#include "platform.h"
#include "di_defs.h"
#include "pc.h"
#include "capi20.h"
#include "divacapi.h"
#include "mdm_msg.h"
#include "divasync.h"



#define FILE_ "MESSAGE.C"
#define dprintf









/*------------------------------------------------------------------*/
/* This is options supported for all adapters that are server by    */
/* XDI driver. Allo it is not necessary to ask it from every adapter*/
/* and it is not necessary to save it separate for every adapter    */
/* Macrose defined here have only local meaning                     */
/*------------------------------------------------------------------*/
static dword diva_xdi_extended_features = 0;

#define DIVA_CAPI_USE_CMA                 0x00000001
#define DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR  0x00000002
#define DIVA_CAPI_XDI_PROVIDES_NO_CANCEL  0x00000004
#define DIVA_CAPI_XDI_PROVIDES_RX_DMA     0x00000008

/*
  CAPI can request to process all return codes self only if:
  protocol code supports this && xdi supports this
*/
#define DIVA_CAPI_SUPPORTS_NO_CANCEL(__a__)   (((__a__)->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) && ((__a__)->manufacturer_features & MANUFACTURER_FEATURE_OK_FC_LABEL) && (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_NO_CANCEL))

/*------------------------------------------------------------------*/
/* local function prototypes                                        */
/*------------------------------------------------------------------*/

static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci);
static void set_group_ind_mask(PLCI *plci);
static void clear_group_ind_mask_bit(PLCI *plci, word b);
static byte test_group_ind_mask_bit(PLCI *plci, word b);
void AutomaticLaw(DIVA_CAPI_ADAPTER *);
word CapiRelease(word);
word CapiRegister(word);
word api_put(APPL *, CAPI_MSG *);
static word api_parse(byte *, word, byte *, API_PARSE *);
static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out);
static void api_load_msg(API_SAVE *in, API_PARSE *out);

word api_remove_start(void);
void api_remove_complete(void);

static void plci_remove(PLCI *);
static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER *a);
static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER *, IDI_SYNC_REQ *);

void callback(ENTITY *);

static void control_rc(PLCI *, byte, byte, byte, byte, byte);
static void data_rc(PLCI *, byte);
static void data_ack(PLCI *, byte);
static void sig_ind(PLCI *);
static void SendInfo(PLCI *, dword, byte **, byte);
static void SendSetupInfo(APPL *, PLCI *, dword, byte **, byte);
static void SendSSExtInd(APPL *, PLCI *plci, dword Id, byte **parms);

static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms);

static void nl_ind(PLCI *);

static byte connect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte connect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte connect_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte disconnect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte disconnect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte listen_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte info_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte info_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte alert_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte facility_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte facility_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte connect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte connect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte connect_b3_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte disconnect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte disconnect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte data_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte data_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte reset_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte reset_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte connect_b3_t90_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte select_b_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte manufacturer_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
static byte manufacturer_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);

static word get_plci(DIVA_CAPI_ADAPTER *);
static void add_p(PLCI *, byte, byte *);
static void add_s(PLCI *plci, byte code, API_PARSE *p);
static void add_ss(PLCI *plci, byte code, API_PARSE *p);
static void add_ie(PLCI *plci, byte code, byte *p, word p_length);
static void add_d(PLCI *, word, byte *);
static void add_ai(PLCI *, API_PARSE *);
static word add_b1(PLCI *, API_PARSE *, word, word);
static word add_b23(PLCI *, API_PARSE *);
static word add_modem_b23(PLCI *plci, API_PARSE *bp_parms);
static void sig_req(PLCI *, byte, byte);
static void nl_req_ncci(PLCI *, byte, byte);
static void send_req(PLCI *);
static void send_data(PLCI *);
static word plci_remove_check(PLCI *);
static void listen_check(DIVA_CAPI_ADAPTER *);
static byte AddInfo(byte **, byte **, byte *, byte *);
static byte getChannel(API_PARSE *);
static void IndParse(PLCI *, word *, byte **, byte);
static byte ie_compare(byte *, byte *);
static word find_cip(DIVA_CAPI_ADAPTER *, byte *, byte *);
static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *, word);

/*
  XON protocol helpers
*/
static void channel_flow_control_remove(PLCI *plci);
static void channel_x_off(PLCI *plci, byte ch, byte flag);
static void channel_x_on(PLCI *plci, byte ch);
static void channel_request_xon(PLCI *plci, byte ch);
static void channel_xmit_xon(PLCI *plci);
static int channel_can_xon(PLCI *plci, byte ch);
static void channel_xmit_extended_xon(PLCI *plci);

static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type, dword info_mask, byte setupParse);
static word AdvCodecSupport(DIVA_CAPI_ADAPTER *, PLCI *, APPL *, byte);
static void CodecIdCheck(DIVA_CAPI_ADAPTER *, PLCI *);
static void SetVoiceChannel(PLCI *, byte *, DIVA_CAPI_ADAPTER *);
static void VoiceChannelOff(PLCI *plci);
static void adv_voice_write_coefs(PLCI *plci, word write_command);
static void adv_voice_clear_config(PLCI *plci);

static word get_b1_facilities(PLCI *plci, byte b1_resource);
static byte add_b1_facilities(PLCI *plci, byte b1_resource, word b1_facilities);
static void adjust_b1_facilities(PLCI *plci, byte new_b1_resource, word new_b1_facilities);
static word adjust_b_process(dword Id, PLCI *plci, byte Rc);
static void adjust_b1_resource(dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command);
static void adjust_b_restore(dword Id, PLCI *plci, byte Rc);
static void reset_b3_command(dword Id, PLCI *plci, byte Rc);
static void select_b_command(dword Id, PLCI *plci, byte Rc);
static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc);
static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc);
static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc);
static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc);
static void fax_disconnect_command(dword Id, PLCI *plci, byte Rc);
static void hold_save_command(dword Id, PLCI *plci, byte Rc);
static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc);
static void init_b1_config(PLCI *plci);
static void clear_b1_config(PLCI *plci);

static void dtmf_command(dword Id, PLCI *plci, byte Rc);
static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
static void dtmf_confirmation(dword Id, PLCI *plci);
static void dtmf_indication(dword Id, PLCI *plci, byte *msg, word length);
static void dtmf_parameter_write(PLCI *plci);


static void mixer_set_bchannel_id_esc(PLCI *plci, byte bchannel_id);
static void mixer_set_bchannel_id(PLCI *plci, byte *chi);
static void mixer_clear_config(PLCI *plci);
static void mixer_notify_update(PLCI *plci, byte others);
static void mixer_command(dword Id, PLCI *plci, byte Rc);
static byte mixer_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
static void mixer_indication_coefs_set(dword Id, PLCI *plci);
static void mixer_indication_xconnect_from(dword Id, PLCI *plci, byte *msg, word length);
static void mixer_indication_xconnect_to(dword Id, PLCI *plci, byte *msg, word length);
static void mixer_remove(PLCI *plci);


static void ec_command(dword Id, PLCI *plci, byte Rc);
static byte ec_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
static void ec_indication(dword Id, PLCI *plci, byte *msg, word length);


static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc);
static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc);


static int diva_get_dma_descriptor(PLCI *plci, dword *dma_magic);
static void diva_free_dma_descriptor(PLCI *plci, int nr);

/*------------------------------------------------------------------*/
/* external function prototypes                                     */
/*------------------------------------------------------------------*/

extern byte MapController(byte);
extern byte UnMapController(byte);
#define MapId(Id)(((Id) & 0xffffff00L) | MapController((byte)(Id)))
#define UnMapId(Id)(((Id) & 0xffffff00L) | UnMapController((byte)(Id)))

void sendf(APPL *, word, dword, word, byte *, ...);
void *TransmitBufferSet(APPL *appl, dword ref);
void *TransmitBufferGet(APPL *appl, void *p);
void TransmitBufferFree(APPL *appl, void *p);
void *ReceiveBufferGet(APPL *appl, int Num);

int fax_head_line_time(char *buffer);


/*------------------------------------------------------------------*/
/* Global data definitions                                          */
/*------------------------------------------------------------------*/
extern byte max_adapter;
extern byte max_appl;
extern DIVA_CAPI_ADAPTER *adapter;
extern APPL *application;







static byte remove_started = false;
static PLCI dummy_plci;


static struct _ftable {
	word command;
	byte *format;
	byte (*function)(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
} ftable[] = {
	{_DATA_B3_R,                          "dwww",         data_b3_req},
	{_DATA_B3_I | RESPONSE,               "w",            data_b3_res},
	{_INFO_R,                             "ss",           info_req},
	{_INFO_I | RESPONSE,                  "",             info_res},
	{_CONNECT_R,                          "wsssssssss",   connect_req},
	{_CONNECT_I | RESPONSE,               "wsssss",       connect_res},
	{_CONNECT_ACTIVE_I | RESPONSE,        "",             connect_a_res},
	{_DISCONNECT_R,                       "s",            disconnect_req},
	{_DISCONNECT_I | RESPONSE,            "",             disconnect_res},
	{_LISTEN_R,                           "dddss",        listen_req},
	{_ALERT_R,                            "s",            alert_req},
	{_FACILITY_R,                         "ws",           facility_req},
	{_FACILITY_I | RESPONSE,              "ws",           facility_res},
	{_CONNECT_B3_R,                       "s",            connect_b3_req},
	{_CONNECT_B3_I | RESPONSE,            "ws",           connect_b3_res},
	{_CONNECT_B3_ACTIVE_I | RESPONSE,     "",             connect_b3_a_res},
	{_DISCONNECT_B3_R,                    "s",            disconnect_b3_req},
	{_DISCONNECT_B3_I | RESPONSE,         "",             disconnect_b3_res},
	{_RESET_B3_R,                         "s",            reset_b3_req},
	{_RESET_B3_I | RESPONSE,              "",             reset_b3_res},
	{_CONNECT_B3_T90_ACTIVE_I | RESPONSE, "ws",           connect_b3_t90_a_res},
	{_CONNECT_B3_T90_ACTIVE_I | RESPONSE, "",             connect_b3_t90_a_res},
	{_SELECT_B_REQ,                       "s",            select_b_req},
	{_MANUFACTURER_R,                     "dws",          manufacturer_req},
	{_MANUFACTURER_I | RESPONSE,          "dws",          manufacturer_res},
	{_MANUFACTURER_I | RESPONSE,          "",             manufacturer_res}
};

static byte *cip_bc[29][2] = {
	{ "",                     ""                     }, /* 0 */
	{ "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 1 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 2 */
	{ "\x02\x89\x90",         "\x02\x89\x90"         }, /* 3 */
	{ "\x03\x90\x90\xa3",     "\x03\x90\x90\xa2"     }, /* 4 */
	{ "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 5 */
	{ "\x02\x98\x90",         "\x02\x98\x90"         }, /* 6 */
	{ "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */
	{ "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */
	{ "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 9 */
	{ "",                     ""                     }, /* 10 */
	{ "",                     ""                     }, /* 11 */
	{ "",                     ""                     }, /* 12 */
	{ "",                     ""                     }, /* 13 */
	{ "",                     ""                     }, /* 14 */
	{ "",                     ""                     }, /* 15 */

	{ "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 16 */
	{ "\x03\x90\x90\xa3",     "\x03\x90\x90\xa2"     }, /* 17 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 18 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 19 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 20 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 21 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 22 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 23 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 24 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 25 */
	{ "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 26 */
	{ "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 27 */
	{ "\x02\x88\x90",         "\x02\x88\x90"         }  /* 28 */
};

static byte *cip_hlc[29] = {
	"",                           /* 0 */
	"",                           /* 1 */
	"",                           /* 2 */
	"",                           /* 3 */
	"",                           /* 4 */
	"",                           /* 5 */
	"",                           /* 6 */
	"",                           /* 7 */
	"",                           /* 8 */
	"",                           /* 9 */
	"",                           /* 10 */
	"",                           /* 11 */
	"",                           /* 12 */
	"",                           /* 13 */
	"",                           /* 14 */
	"",                           /* 15 */

	"\x02\x91\x81",               /* 16 */
	"\x02\x91\x84",               /* 17 */
	"\x02\x91\xa1",               /* 18 */
	"\x02\x91\xa4",               /* 19 */
	"\x02\x91\xa8",               /* 20 */
	"\x02\x91\xb1",               /* 21 */
	"\x02\x91\xb2",               /* 22 */
	"\x02\x91\xb5",               /* 23 */
	"\x02\x91\xb8",               /* 24 */
	"\x02\x91\xc1",               /* 25 */
	"\x02\x91\x81",               /* 26 */
	"\x03\x91\xe0\x01",           /* 27 */
	"\x03\x91\xe0\x02"            /* 28 */
};

/*------------------------------------------------------------------*/

#define V120_HEADER_LENGTH 1
#define V120_HEADER_EXTEND_BIT  0x80
#define V120_HEADER_BREAK_BIT   0x40
#define V120_HEADER_C1_BIT      0x04
#define V120_HEADER_C2_BIT      0x08
#define V120_HEADER_FLUSH_COND  (V120_HEADER_BREAK_BIT | V120_HEADER_C1_BIT | V120_HEADER_C2_BIT)

static byte v120_default_header[] =
{

	0x83                          /*  Ext, BR , res, res, C2 , C1 , B  , F   */

};

static byte v120_break_header[] =
{

	0xc3 | V120_HEADER_BREAK_BIT  /*  Ext, BR , res, res, C2 , C1 , B  , F   */

};


/*------------------------------------------------------------------*/
/* API_PUT function                                                 */
/*------------------------------------------------------------------*/

word api_put(APPL *appl, CAPI_MSG *msg)
{
	word i, j, k, l, n;
	word ret;
	byte c;
	byte controller;
	DIVA_CAPI_ADAPTER *a;
	PLCI *plci;
	NCCI *ncci_ptr;
	word ncci;
	CAPI_MSG *m;
	API_PARSE msg_parms[MAX_MSG_PARMS + 1];

	if (msg->header.length < sizeof(msg->header) ||
	    msg->header.length > MAX_MSG_SIZE) {
		dbug(1, dprintf("bad len"));
		return _BAD_MSG;
	}

	controller = (byte)((msg->header.controller & 0x7f) - 1);

	/* controller starts with 0 up to (max_adapter - 1) */
	if (controller >= max_adapter)
	{
		dbug(1, dprintf("invalid ctrl"));
		return _BAD_MSG;
	}

	a = &adapter[controller];
	plci = NULL;
	if ((msg->header.plci != 0) && (msg->header.plci <= a->max_plci) && !a->adapter_disabled)
	{
		dbug(1, dprintf("plci=%x", msg->header.plci));
		plci = &a->plci[msg->header.plci - 1];
		ncci = GET_WORD(&msg->header.ncci);
		if (plci->Id
		    && (plci->appl
			|| (plci->State == INC_CON_PENDING)
			|| (plci->State == INC_CON_ALERT)
			|| (msg->header.command == (_DISCONNECT_I | RESPONSE)))
		    && ((ncci == 0)
			|| (msg->header.command == (_DISCONNECT_B3_I | RESPONSE))
			|| ((ncci < MAX_NCCI + 1) && (a->ncci_plci[ncci] == plci->Id))))
		{
			i = plci->msg_in_read_pos;
			j = plci->msg_in_write_pos;
			if (j >= i)
			{
				if (j + msg->header.length + MSG_IN_OVERHEAD <= MSG_IN_QUEUE_SIZE)
					i += MSG_IN_QUEUE_SIZE - j;
				else
					j = 0;
			}
			else
			{

				n = (((CAPI_MSG *)(plci->msg_in_queue))->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc;

				if (i > MSG_IN_QUEUE_SIZE - n)
					i = MSG_IN_QUEUE_SIZE - n + 1;
				i -= j;
			}

			if (i <= ((msg->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc))

			{
				dbug(0, dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d",
						msg->header.length, plci->msg_in_write_pos,
						plci->msg_in_read_pos, plci->msg_in_wrap_pos, i));

				return _QUEUE_FULL;
			}
			c = false;
			if ((((byte *) msg) < ((byte *)(plci->msg_in_queue)))
			    || (((byte *) msg) >= ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
			{
				if (plci->msg_in_write_pos != plci->msg_in_read_pos)
					c = true;
			}
			if (msg->header.command == _DATA_B3_R)
			{
				if (msg->header.length < 20)
				{
					dbug(1, dprintf("DATA_B3 REQ wrong length %d", msg->header.length));
					return _BAD_MSG;
				}
				ncci_ptr = &(a->ncci[ncci]);
				n = ncci_ptr->data_pending;
				l = ncci_ptr->data_ack_pending;
				k = plci->msg_in_read_pos;
				while (k != plci->msg_in_write_pos)
				{
					if (k == plci->msg_in_wrap_pos)
						k = 0;
					if ((((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.command == _DATA_B3_R)
					    && (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.ncci == ncci))
					{
						n++;
						if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->info.data_b3_req.Flags & 0x0004)
							l++;
					}

					k += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.length +
					      MSG_IN_OVERHEAD + 3) & 0xfffc;

				}
				if ((n >= MAX_DATA_B3) || (l >= MAX_DATA_ACK))
				{
					dbug(0, dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d",
							ncci_ptr->data_pending, n, ncci_ptr->data_ack_pending, l));

					return _QUEUE_FULL;
				}
				if (plci->req_in || plci->internal_command)
				{
					if ((((byte *) msg) >= ((byte *)(plci->msg_in_queue)))
					    && (((byte *) msg) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
					{
						dbug(0, dprintf("Q-FULL3(requeue)"));

						return _QUEUE_FULL;
					}
					c = true;
				}
			}
			else
			{
				if (plci->req_in || plci->internal_command)
					c = true;
				else
				{
					plci->command = msg->header.command;
					plci->number = msg->header.number;
				}
			}
			if (c)
			{
				dbug(1, dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d",
						msg->header.command, plci->req_in, plci->internal_command,
						msg->header.length, plci->msg_in_write_pos,
						plci->msg_in_read_pos, plci->msg_in_wrap_pos, i));
				if (j == 0)
					plci->msg_in_wrap_pos = plci->msg_in_write_pos;
				m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]);
				for (i = 0; i < msg->header.length; i++)
					((byte *)(plci->msg_in_queue))[j++] = ((byte *) msg)[i];
				if (m->header.command == _DATA_B3_R)
				{

					m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet(appl, m->info.data_b3_req.Data));

				}

				j = (j + 3) & 0xfffc;

				*((APPL **)(&((byte *)(plci->msg_in_queue))[j])) = appl;
				plci->msg_in_write_pos = j + MSG_IN_OVERHEAD;
				return 0;
			}
		}
		else
		{
			plci = NULL;
		}
	}
	dbug(1, dprintf("com=%x", msg->header.command));

	for (j = 0; j < MAX_MSG_PARMS + 1; j++) msg_parms[j].length = 0;
	for (i = 0, ret = _BAD_MSG; i < ARRAY_SIZE(ftable); i++) {

		if (ftable[i].command == msg->header.command) {
			/* break loop if the message is correct, otherwise continue scan  */
			/* (for example: CONNECT_B3_T90_ACT_RES has two specifications)   */
			if (!api_parse(msg->info.b, (word)(msg->header.length - 12), ftable[i].format, msg_parms)) {
				ret = 0;
				break;
			}
			for (j = 0; j < MAX_MSG_PARMS + 1; j++) msg_parms[j].length = 0;
		}
	}
	if (ret) {
		dbug(1, dprintf("BAD_MSG"));
		if (plci) plci->command = 0;
		return ret;
	}


	c = ftable[i].function(GET_DWORD(&msg->header.controller),
			       msg->header.number,
			       a,
			       plci,
			       appl,
			       msg_parms);

	channel_xmit_extended_xon(plci);

	if (c == 1) send_req(plci);
	if (c == 2 && plci) plci->req_in = plci->req_in_start = plci->req_out = 0;
	if (plci && !plci->req_in) plci->command = 0;
	return 0;
}


/*------------------------------------------------------------------*/
/* api_parse function, check the format of api messages             */
/*------------------------------------------------------------------*/

static word api_parse(byte *msg, word length, byte *format, API_PARSE *parms)
{
	word i;
	word p;

	for (i = 0, p = 0; format[i]; i++) {
		if (parms)
		{
			parms[i].info = &msg[p];
		}
		switch (format[i]) {
		case 'b':
			p += 1;
			break;
		case 'w':
			p += 2;
			break;
		case 'd':
			p += 4;
			break;
		case 's':
			if (msg[p] == 0xff) {
				parms[i].info += 2;
				parms[i].length = msg[p + 1] + (msg[p + 2] << 8);
				p += (parms[i].length + 3);
			}
			else {
				parms[i].length = msg[p];
				p += (parms[i].length + 1);
			}
			break;
		}

		if (p > length) return true;
	}
	if (parms) parms[i].info = NULL;
	return false;
}

static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out)
{
	word i, j, n = 0;
	byte *p;

	p = out->info;
	for (i = 0; format[i] != '\0'; i++)
	{
		out->parms[i].info = p;
		out->parms[i].length = in[i].length;
		switch (format[i])
		{
		case 'b':
			n = 1;
			break;
		case 'w':
			n = 2;
			break;
		case 'd':
			n = 4;
			break;
		case 's':
			n = in[i].length + 1;
			break;
		}
		for (j = 0; j < n; j++)
			*(p++) = in[i].info[j];
	}
	out->parms[i].info = NULL;
	out->parms[i].length = 0;
}

static void api_load_msg(API_SAVE *in, API_PARSE *out)
{
	word i;

	i = 0;
	do
	{
		out[i].info = in->parms[i].info;
		out[i].length = in->parms[i].length;
	} while (in->parms[i++].info);
}


/*------------------------------------------------------------------*/
/* CAPI remove function                                             */
/*------------------------------------------------------------------*/

word api_remove_start(void)
{
	word i;
	word j;

	if (!remove_started) {
		remove_started = true;
		for (i = 0; i < max_adapter; i++) {
			if (adapter[i].request) {
				for (j = 0; j < adapter[i].max_plci; j++) {
					if (adapter[i].plci[j].Sig.Id) plci_remove(&adapter[i].plci[j]);
				}
			}
		}
		return 1;
	}
	else {
		for (i = 0; i < max_adapter; i++) {
			if (adapter[i].request) {
				for (j = 0; j < adapter[i].max_plci; j++) {
					if (adapter[i].plci[j].Sig.Id) return 1;
				}
			}
		}
	}
	api_remove_complete();
	return 0;
}


/*------------------------------------------------------------------*/
/* internal command queue                                           */
/*------------------------------------------------------------------*/

static void init_internal_command_queue(PLCI *plci)
{
	word i;

	dbug(1, dprintf("%s,%d: init_internal_command_queue",
			(char *)(FILE_), __LINE__));

	plci->internal_command = 0;
	for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS; i++)
		plci->internal_command_queue[i] = NULL;
}


static void start_internal_command(dword Id, PLCI *plci, t_std_internal_command command_function)
{
	word i;

	dbug(1, dprintf("[%06lx] %s,%d: start_internal_command",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	if (plci->internal_command == 0)
	{
		plci->internal_command_queue[0] = command_function;
		(*command_function)(Id, plci, OK);
	}
	else
	{
		i = 1;
		while (plci->internal_command_queue[i] != NULL)
			i++;
		plci->internal_command_queue[i] = command_function;
	}
}


static void next_internal_command(dword Id, PLCI *plci)
{
	word i;

	dbug(1, dprintf("[%06lx] %s,%d: next_internal_command",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	plci->internal_command = 0;
	plci->internal_command_queue[0] = NULL;
	while (plci->internal_command_queue[1] != NULL)
	{
		for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS - 1; i++)
			plci->internal_command_queue[i] = plci->internal_command_queue[i + 1];
		plci->internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS - 1] = NULL;
		(*(plci->internal_command_queue[0]))(Id, plci, OK);
		if (plci->internal_command != 0)
			return;
		plci->internal_command_queue[0] = NULL;
	}
}


/*------------------------------------------------------------------*/
/* NCCI allocate/remove function                                    */
/*------------------------------------------------------------------*/

static dword ncci_mapping_bug = 0;

static word get_ncci(PLCI *plci, byte ch, word force_ncci)
{
	DIVA_CAPI_ADAPTER *a;
	word ncci, i, j, k;

	a = plci->adapter;
	if (!ch || a->ch_ncci[ch])
	{
		ncci_mapping_bug++;
		dbug(1, dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x",
				ncci_mapping_bug, ch, force_ncci, a->ncci_ch[a->ch_ncci[ch]], a->ch_ncci[ch]));
		ncci = ch;
	}
	else
	{
		if (force_ncci)
			ncci = force_ncci;
		else
		{
			if ((ch < MAX_NCCI + 1) && !a->ncci_ch[ch])
				ncci = ch;
			else
			{
				ncci = 1;
				while ((ncci < MAX_NCCI + 1) && a->ncci_ch[ncci])
					ncci++;
				if (ncci == MAX_NCCI + 1)
				{
					ncci_mapping_bug++;
					i = 1;
					do
					{
						j = 1;
						while ((j < MAX_NCCI + 1) && (a->ncci_ch[j] != i))
							j++;
						k = j;
						if (j < MAX_NCCI + 1)
						{
							do
							{
								j++;
							} while ((j < MAX_NCCI + 1) && (a->ncci_ch[j] != i));
						}
					} while ((i < MAX_NL_CHANNEL + 1) && (j < MAX_NCCI + 1));
					if (i < MAX_NL_CHANNEL + 1)
					{
						dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x",
								ncci_mapping_bug, ch, force_ncci, i, k, j));
					}
					else
					{
						dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x",
								ncci_mapping_bug, ch, force_ncci));
					}
					ncci = ch;
				}
			}
			a->ncci_plci[ncci] = plci->Id;
			a->ncci_state[ncci] = IDLE;
			if (!plci->ncci_ring_list)
				plci->ncci_ring_list = ncci;
			else
				a->ncci_next[ncci] = a->ncci_next[plci->ncci_ring_list];
			a->ncci_next[plci->ncci_ring_list] = (byte) ncci;
		}
		a->ncci_ch[ncci] = ch;
		a->ch_ncci[ch] = (byte) ncci;
		dbug(1, dprintf("NCCI mapping established %ld %02x %02x %02x-%02x",
				ncci_mapping_bug, ch, force_ncci, ch, ncci));
	}
	return (ncci);
}


static void ncci_free_receive_buffers(PLCI *plci, word ncci)
{
	DIVA_CAPI_ADAPTER *a;
	APPL *appl;
	word i, ncci_code;
	dword Id;

	a = plci->adapter;
	Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
	if (ncci)
	{
		if (a->ncci_plci[ncci] == plci->Id)
		{
			if (!plci->appl)
			{
				ncci_mapping_bug++;
				dbug(1, dprintf("NCCI mapping appl expected %ld %08lx",
						ncci_mapping_bug, Id));
			}
			else
			{
				appl = plci->appl;
				ncci_code = ncci | (((word) a->Id) << 8);
				for (i = 0; i < appl->MaxBuffer; i++)
				{
					if ((appl->DataNCCI[i] == ncci_code)
					    && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
					{
						appl->DataNCCI[i] = 0;
					}
				}
			}
		}
	}
	else
	{
		for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
		{
			if (a->ncci_plci[ncci] == plci->Id)
			{
				if (!plci->appl)
				{
					ncci_mapping_bug++;
					dbug(1, dprintf("NCCI mapping no appl %ld %08lx",
							ncci_mapping_bug, Id));
				}
				else
				{
					appl = plci->appl;
					ncci_code = ncci | (((word) a->Id) << 8);
					for (i = 0; i < appl->MaxBuffer; i++)
					{
						if ((appl->DataNCCI[i] == ncci_code)
						    && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
						{
							appl->DataNCCI[i] = 0;
						}
					}
				}
			}
		}
	}
}


static void cleanup_ncci_data(PLCI *plci, word ncci)
{
	NCCI *ncci_ptr;

	if (ncci && (plci->adapter->ncci_plci[ncci] == plci->Id))
	{
		ncci_ptr = &(plci->adapter->ncci[ncci]);
		if (plci->appl)
		{
			while (ncci_ptr->data_pending != 0)
			{
				if (!plci->data_sent || (ncci_ptr->DBuffer[ncci_ptr->data_out].P != plci->data_sent_ptr))
					TransmitBufferFree(plci->appl, ncci_ptr->DBuffer[ncci_ptr->data_out].P);
				(ncci_ptr->data_out)++;
				if (ncci_ptr->data_out == MAX_DATA_B3)
					ncci_ptr->data_out = 0;
				(ncci_ptr->data_pending)--;
			}
		}
		ncci_ptr->data_out = 0;
		ncci_ptr->data_pending = 0;
		ncci_ptr->data_ack_out = 0;
		ncci_ptr->data_ack_pending = 0;
	}
}


static void ncci_remove(PLCI *plci, word ncci, byte preserve_ncci)
{
	DIVA_CAPI_ADAPTER *a;
	dword Id;
	word i;

	a = plci->adapter;
	Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
	if (!preserve_ncci)
		ncci_free_receive_buffers(plci, ncci);
	if (ncci)
	{
		if (a->ncci_plci[ncci] != plci->Id)
		{
			ncci_mapping_bug++;
			dbug(1, dprintf("NCCI mapping doesn't exist %ld %08lx %02x",
					ncci_mapping_bug, Id, preserve_ncci));
		}
		else
		{
			cleanup_ncci_data(plci, ncci);
			dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
					ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci));
			a->ch_ncci[a->ncci_ch[ncci]] = 0;
			if (!preserve_ncci)
			{
				a->ncci_ch[ncci] = 0;
				a->ncci_plci[ncci] = 0;
				a->ncci_state[ncci] = IDLE;
				i = plci->ncci_ring_list;
				while ((i != 0) && (a->ncci_next[i] != plci->ncci_ring_list) && (a->ncci_next[i] != ncci))
					i = a->ncci_next[i];
				if ((i != 0) && (a->ncci_next[i] == ncci))
				{
					if (i == ncci)
						plci->ncci_ring_list = 0;
					else if (plci->ncci_ring_list == ncci)
						plci->ncci_ring_list = i;
					a->ncci_next[i] = a->ncci_next[ncci];
				}
				a->ncci_next[ncci] = 0;
			}
		}
	}
	else
	{
		for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
		{
			if (a->ncci_plci[ncci] == plci->Id)
			{
				cleanup_ncci_data(plci, ncci);
				dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
						ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci));
				a->ch_ncci[a->ncci_ch[ncci]] = 0;
				if (!preserve_ncci)
				{
					a->ncci_ch[ncci] = 0;
					a->ncci_plci[ncci] = 0;
					a->ncci_state[ncci] = IDLE;
					a->ncci_next[ncci] = 0;
				}
			}
		}
		if (!preserve_ncci)
			plci->ncci_ring_list = 0;
	}
}


/*------------------------------------------------------------------*/
/* PLCI remove function                                             */
/*------------------------------------------------------------------*/

static void plci_free_msg_in_queue(PLCI *plci)
{
	word i;

	if (plci->appl)
	{
		i = plci->msg_in_read_pos;
		while (i != plci->msg_in_write_pos)
		{
			if (i == plci->msg_in_wrap_pos)
				i = 0;
			if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.command == _DATA_B3_R)
			{

				TransmitBufferFree(plci->appl,
						   (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));

			}

			i += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.length +
			      MSG_IN_OVERHEAD + 3) & 0xfffc;

		}
	}
	plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
	plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
	plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
}


static void plci_remove(PLCI *plci)
{

	if (!plci) {
		dbug(1, dprintf("plci_remove(no plci)"));
		return;
	}
	init_internal_command_queue(plci);
	dbug(1, dprintf("plci_remove(%x,tel=%x)", plci->Id, plci->tel));
	if (plci_remove_check(plci))
	{
		return;
	}
	if (plci->Sig.Id == 0xff)
	{
		dbug(1, dprintf("D-channel X.25 plci->NL.Id:%0x", plci->NL.Id));
		if (plci->NL.Id && !plci->nl_remove_id)
		{
			nl_req_ncci(plci, REMOVE, 0);
			send_req(plci);
		}
	}
	else
	{
		if (!plci->sig_remove_id
		    && (plci->Sig.Id
			|| (plci->req_in != plci->req_out)
			|| (plci->nl_req || plci->sig_req)))
		{
			sig_req(plci, HANGUP, 0);
			send_req(plci);
		}
	}
	ncci_remove(plci, 0, false);
	plci_free_msg_in_queue(plci);

	plci->channels = 0;
	plci->appl = NULL;
	if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT))
		plci->State = OUTG_DIS_PENDING;
}

/*------------------------------------------------------------------*/
/* Application Group function helpers                               */
/*------------------------------------------------------------------*/

static void set_group_ind_mask(PLCI *plci)
{
	word i;

	for (i = 0; i < C_IND_MASK_DWORDS; i++)
		plci->group_optimization_mask_table[i] = 0xffffffffL;
}

static void clear_group_ind_mask_bit(PLCI *plci, word b)
{
	plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
}

static byte test_group_ind_mask_bit(PLCI *plci, word b)
{
	return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
}

/*------------------------------------------------------------------*/
/* c_ind_mask operations for arbitrary MAX_APPL                     */
/*------------------------------------------------------------------*/

static void clear_c_ind_mask(PLCI *plci)
{
	word i;

	for (i = 0; i < C_IND_MASK_DWORDS; i++)
		plci->c_ind_mask_table[i] = 0;
}

static byte c_ind_mask_empty(PLCI *plci)
{
	word i;

	i = 0;
	while ((i < C_IND_MASK_DWORDS) && (plci->c_ind_mask_table[i] == 0))
		i++;
	return (i == C_IND_MASK_DWORDS);
}

static void set_c_ind_mask_bit(PLCI *plci, word b)
{
	plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f));
}

static void clear_c_ind_mask_bit(PLCI *plci, word b)
{
	plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
}

static byte test_c_ind_mask_bit(PLCI *plci, word b)
{
	return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
}

static void dump_c_ind_mask(PLCI *plci)
{
	static char hex_digit_table[0x10] =
		{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
	word i, j, k;
	dword d;
	char *p;
	char buf[40];

	for (i = 0; i < C_IND_MASK_DWORDS; i += 4)
	{
		p = buf + 36;
		*p = '\0';
		for (j = 0; j < 4; j++)
		{
			if (i + j < C_IND_MASK_DWORDS)
			{
				d = plci->c_ind_mask_table[i + j];
				for (k = 0; k < 8; k++)
				{
					*(--p) = hex_digit_table[d & 0xf];
					d >>= 4;
				}
			}
			else if (i != 0)
			{
				for (k = 0; k < 8; k++)
					*(--p) = ' ';
			}
			*(--p) = ' ';
		}
		dbug(1, dprintf("c_ind_mask =%s", (char *) p));
	}
}





#define dump_plcis(a)



/*------------------------------------------------------------------*/
/* translation function for each message                            */
/*------------------------------------------------------------------*/

static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word ch;
	word i;
	word Info;
	byte LinkLayer;
	API_PARSE *ai;
	API_PARSE *bp;
	API_PARSE ai_parms[5];
	word channel = 0;
	dword ch_mask;
	byte m;
	static byte esc_chi[35] = {0x02, 0x18, 0x01};
	static byte lli[2] = {0x01, 0x00};
	byte noCh = 0;
	word dir = 0;
	byte *p_chi = "";

	for (i = 0; i < 5; i++) ai_parms[i].length = 0;

	dbug(1, dprintf("connect_req(%d)", parms->length));
	Info = _WRONG_IDENTIFIER;
	if (a)
	{
		if (a->adapter_disabled)
		{
			dbug(1, dprintf("adapter disabled"));
			Id = ((word)1 << 8) | a->Id;
			sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
			sendf(appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR);
			return false;
		}
		Info = _OUT_OF_PLCI;
		if ((i = get_plci(a)))
		{
			Info = 0;
			plci = &a->plci[i - 1];
			plci->appl = appl;
			plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
			/* check 'external controller' bit for codec support */
			if (Id & EXT_CONTROLLER)
			{
				if (AdvCodecSupport(a, plci, appl, 0))
				{
					plci->Id = 0;
					sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER);
					return 2;
				}
			}
			ai = &parms[9];
			bp = &parms[5];
			ch = 0;
			if (bp->length)LinkLayer = bp->info[3];
			else LinkLayer = 0;
			if (ai->length)
			{
				ch = 0xffff;
				if (!api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
				{
					ch = 0;
					if (ai_parms[0].length)
					{
						ch = GET_WORD(ai_parms[0].info + 1);
						if (ch > 4) ch = 0; /* safety -> ignore ChannelID */
						if (ch == 4) /* explizit CHI in message */
						{
							/* check length of B-CH struct */
							if ((ai_parms[0].info)[3] >= 1)
							{
								if ((ai_parms[0].info)[4] == CHI)
								{
									p_chi = &((ai_parms[0].info)[5]);
								}
								else
								{
									p_chi = &((ai_parms[0].info)[3]);
								}
								if (p_chi[0] > 35) /* check length of channel ID */
								{
									Info = _WRONG_MESSAGE_FORMAT;
								}
							}
							else Info = _WRONG_MESSAGE_FORMAT;
						}

						if (ch == 3 && ai_parms[0].length >= 7 && ai_parms[0].length <= 36)
						{
							dir = GET_WORD(ai_parms[0].info + 3);
							ch_mask = 0;
							m = 0x3f;
							for (i = 0; i + 5 <= ai_parms[0].length; i++)
							{
								if (ai_parms[0].info[i + 5] != 0)
								{
									if ((ai_parms[0].info[i + 5] | m) != 0xff)
										Info = _WRONG_MESSAGE_FORMAT;
									else
									{
										if (ch_mask == 0)
											channel = i;
										ch_mask |= 1L << i;
									}
								}
								m = 0;
							}
							if (ch_mask == 0)
								Info = _WRONG_MESSAGE_FORMAT;
							if (!Info)
							{
								if ((ai_parms[0].length == 36) || (ch_mask != ((dword)(1L << channel))))
								{
									esc_chi[0] = (byte)(ai_parms[0].length - 2);
									for (i = 0; i + 5 <= ai_parms[0].length; i++)
										esc_chi[i + 3] = ai_parms[0].info[i + 5];
								}
								else
									esc_chi[0] = 2;
								esc_chi[2] = (byte)channel;
								plci->b_channel = (byte)channel; /* not correct for ETSI ch 17..31 */
								add_p(plci, LLI, lli);
								add_p(plci, ESC, esc_chi);
								plci->State = LOCAL_CONNECT;
								if (!dir) plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;     /* dir 0=DTE, 1=DCE */
							}
						}
					}
				}
				else  Info = _WRONG_MESSAGE_FORMAT;
			}

			dbug(1, dprintf("ch=%x,dir=%x,p_ch=%d", ch, dir, channel));
			plci->command = _CONNECT_R;
			plci->number = Number;
			/* x.31 or D-ch free SAPI in LinkLayer? */
			if (ch == 1 && LinkLayer != 3 && LinkLayer != 12) noCh = true;
			if ((ch == 0 || ch == 2 || noCh || ch == 3 || ch == 4) && !Info)
			{
				/* B-channel used for B3 connections (ch==0), or no B channel    */
				/* is used (ch==2) or perm. connection (3) is used  do a CALL    */
				if (noCh) Info = add_b1(plci, &parms[5], 2, 0);    /* no resource    */
				else     Info = add_b1(plci, &parms[5], ch, 0);
				add_s(plci, OAD, &parms[2]);
				add_s(plci, OSA, &parms[4]);
				add_s(plci, BC, &parms[6]);
				add_s(plci, LLC, &parms[7]);
				add_s(plci, HLC, &parms[8]);
				if (a->Info_Mask[appl->Id - 1] & 0x200)
				{
					/* early B3 connect (CIP mask bit 9) no release after a disc */
					add_p(plci, LLI, "\x01\x01");
				}
				if (GET_WORD(parms[0].info) < 29) {
					add_p(plci, BC, cip_bc[GET_WORD(parms[0].info)][a->u_law]);
					add_p(plci, HLC, cip_hlc[GET_WORD(parms[0].info)]);
				}
				add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
				sig_req(plci, ASSIGN, DSIG_ID);
			}
			else if (ch == 1) {

				/* D-Channel used for B3 connections */
				plci->Sig.Id = 0xff;
				Info = 0;
			}

			if (!Info && ch != 2 && !noCh) {
				Info = add_b23(plci, &parms[5]);
				if (!Info) {
					if (!(plci->tel && !plci->adv_nl))nl_req_ncci(plci, ASSIGN, 0);
				}
			}

			if (!Info)
			{
				if (ch == 0 || ch == 2 || ch == 3 || noCh || ch == 4)
				{
					if (plci->spoofed_msg == SPOOFING_REQUIRED)
					{
						api_save_msg(parms, "wsssssssss", &plci->saved_msg);
						plci->spoofed_msg = CALL_REQ;
						plci->internal_command = BLOCK_PLCI;
						plci->command = 0;
						dbug(1, dprintf("Spoof"));
						send_req(plci);
						return false;
					}
					if (ch == 4)add_p(plci, CHI, p_chi);
					add_s(plci, CPN, &parms[1]);
					add_s(plci, DSA, &parms[3]);
					if (noCh) add_p(plci, ESC, "\x02\x18\xfd");  /* D-channel, no B-L3 */
					add_ai(plci, &parms[9]);
					if (!dir)sig_req(plci, CALL_REQ, 0);
					else
					{
						plci->command = PERM_LIST_REQ;
						plci->appl = appl;
						sig_req(plci, LISTEN_REQ, 0);
						send_req(plci);
						return false;
					}
				}
				send_req(plci);
				return false;
			}
			plci->Id = 0;
		}
	}
	sendf(appl,
	      _CONNECT_R | CONFIRM,
	      Id,
	      Number,
	      "w", Info);
	return 2;
}

static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word i, Info;
	word Reject;
	static byte cau_t[] = {0, 0, 0x90, 0x91, 0xac, 0x9d, 0x86, 0xd8, 0x9b};
	static byte esc_t[] = {0x03, 0x08, 0x00, 0x00};
	API_PARSE *ai;
	API_PARSE ai_parms[5];
	word ch = 0;

	if (!plci) {
		dbug(1, dprintf("connect_res(no plci)"));
		return 0;  /* no plci, no send */
	}

	dbug(1, dprintf("connect_res(State=0x%x)", plci->State));
	for (i = 0; i < 5; i++) ai_parms[i].length = 0;
	ai = &parms[5];
	dbug(1, dprintf("ai->length=%d", ai->length));

	if (ai->length)
	{
		if (!api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
		{
			dbug(1, dprintf("ai_parms[0].length=%d/0x%x", ai_parms[0].length, GET_WORD(ai_parms[0].info + 1)));
			ch = 0;
			if (ai_parms[0].length)
			{
				ch = GET_WORD(ai_parms[0].info + 1);
				dbug(1, dprintf("BCH-I=0x%x", ch));
			}
		}
	}

	if (plci->State == INC_CON_CONNECTED_ALERT)
	{
		dbug(1, dprintf("Connected Alert Call_Res"));
		if (a->Info_Mask[appl->Id - 1] & 0x200)
		{
			/* early B3 connect (CIP mask bit 9) no release after a disc */
			add_p(plci, LLI, "\x01\x01");
		}
		add_s(plci, CONN_NR, &parms[2]);
		add_s(plci, LLC, &parms[4]);
		add_ai(plci, &parms[5]);
		plci->State = INC_CON_ACCEPT;
		sig_req(plci, CALL_RES, 0);
		return 1;
	}
	else if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT) {
		clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
		dump_c_ind_mask(plci);
		Reject = GET_WORD(parms[0].info);
		dbug(1, dprintf("Reject=0x%x", Reject));
		if (Reject)
		{
			if (c_ind_mask_empty(plci))
			{
				if ((Reject & 0xff00) == 0x3400)
				{
					esc_t[2] = ((byte)(Reject & 0x00ff)) | 0x80;
					add_p(plci, ESC, esc_t);
					add_ai(plci, &parms[5]);
					sig_req(plci, REJECT, 0);
				}
				else if (Reject == 1 || Reject >= 9)
				{
					add_ai(plci, &parms[5]);
					sig_req(plci, HANGUP, 0);
				}
				else
				{
					esc_t[2] = cau_t[(Reject&0x000f)];
					add_p(plci, ESC, esc_t);
					add_ai(plci, &parms[5]);
					sig_req(plci, REJECT, 0);
				}
				plci->appl = appl;
			}
			else
			{
				sendf(appl, _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
			}
		}
		else {
			plci->appl = appl;
			if (Id & EXT_CONTROLLER) {
				if (AdvCodecSupport(a, plci, appl, 0)) {
					dbug(1, dprintf("connect_res(error from AdvCodecSupport)"));
					sig_req(plci, HANGUP, 0);
					return 1;
				}
				if (plci->tel == ADV_VOICE && a->AdvCodecPLCI)
				{
					Info = add_b23(plci, &parms[1]);
					if (Info)
					{
						dbug(1, dprintf("connect_res(error from add_b23)"));
						sig_req(plci, HANGUP, 0);
						return 1;
					}
					if (plci->adv_nl)
					{
						nl_req_ncci(plci, ASSIGN, 0);
					}
				}
			}
			else
			{
				plci->tel = 0;
				if (ch != 2)
				{
					Info = add_b23(plci, &parms[1]);
					if (Info)
					{
						dbug(1, dprintf("connect_res(error from add_b23 2)"));
						sig_req(plci, HANGUP, 0);
						return 1;
					}
				}
				nl_req_ncci(plci, ASSIGN, 0);
			}

			if (plci->spoofed_msg == SPOOFING_REQUIRED)
			{
				api_save_msg(parms, "wsssss", &plci->saved_msg);
				plci->spoofed_msg = CALL_RES;
				plci->internal_command = BLOCK_PLCI;
				plci->command = 0;
				dbug(1, dprintf("Spoof"));
			}
			else
			{
				add_b1(plci, &parms[1], ch, plci->B1_facilities);
				if (a->Info_Mask[appl->Id - 1] & 0x200)
				{
					/* early B3 connect (CIP mask bit 9) no release after a disc */
					add_p(plci, LLI, "\x01\x01");
				}
				add_s(plci, CONN_NR, &parms[2]);
				add_s(plci, LLC, &parms[4]);
				add_ai(plci, &parms[5]);
				plci->State = INC_CON_ACCEPT;
				sig_req(plci, CALL_RES, 0);
			}

			for (i = 0; i < max_appl; i++) {
				if (test_c_ind_mask_bit(plci, i)) {
					sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
				}
			}
		}
	}
	return 1;
}

static byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			  PLCI *plci, APPL *appl, API_PARSE *msg)
{
	dbug(1, dprintf("connect_a_res"));
	return false;
}

static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			   PLCI *plci, APPL *appl, API_PARSE *msg)
{
	word Info;
	word i;

	dbug(1, dprintf("disconnect_req"));

	Info = _WRONG_IDENTIFIER;

	if (plci)
	{
		if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT)
		{
			clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
			plci->appl = appl;
			for (i = 0; i < max_appl; i++)
			{
				if (test_c_ind_mask_bit(plci, i))
					sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
			}
			plci->State = OUTG_DIS_PENDING;
		}
		if (plci->Sig.Id && plci->appl)
		{
			Info = 0;
			if (plci->Sig.Id != 0xff)
			{
				if (plci->State != INC_DIS_PENDING)
				{
					add_ai(plci, &msg[0]);
					sig_req(plci, HANGUP, 0);
					plci->State = OUTG_DIS_PENDING;
					return 1;
				}
			}
			else
			{
				if (plci->NL.Id && !plci->nl_remove_id)
				{
					mixer_remove(plci);
					nl_req_ncci(plci, REMOVE, 0);
					sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", 0);
					sendf(appl, _DISCONNECT_I, Id, 0, "w", 0);
					plci->State = INC_DIS_PENDING;
				}
				return 1;
			}
		}
	}

	if (!appl)  return false;
	sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", Info);
	return false;
}

static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			   PLCI *plci, APPL *appl, API_PARSE *msg)
{
	dbug(1, dprintf("disconnect_res"));
	if (plci)
	{
		/* clear ind mask bit, just in case of collsion of          */
		/* DISCONNECT_IND and CONNECT_RES                           */
		clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
		ncci_free_receive_buffers(plci, 0);
		if (plci_remove_check(plci))
		{
			return 0;
		}
		if (plci->State == INC_DIS_PENDING
		    || plci->State == SUSPENDING) {
			if (c_ind_mask_empty(plci)) {
				if (plci->State != SUSPENDING) plci->State = IDLE;
				dbug(1, dprintf("chs=%d", plci->channels));
				if (!plci->channels) {
					plci_remove(plci);
				}
			}
		}
	}
	return 0;
}

static byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
		       PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word Info;
	byte i;

	dbug(1, dprintf("listen_req(Appl=0x%x)", appl->Id));

	Info = _WRONG_IDENTIFIER;
	if (a) {
		Info = 0;
		a->Info_Mask[appl->Id - 1] = GET_DWORD(parms[0].info);
		a->CIP_Mask[appl->Id - 1] = GET_DWORD(parms[1].info);
		dbug(1, dprintf("CIP_MASK=0x%lx", GET_DWORD(parms[1].info)));
		if (a->Info_Mask[appl->Id - 1] & 0x200) { /* early B3 connect provides */
			a->Info_Mask[appl->Id - 1] |=  0x10;   /* call progression infos    */
		}

		/* check if external controller listen and switch listen on or off*/
		if (Id&EXT_CONTROLLER && GET_DWORD(parms[1].info)) {
			if (a->profile.Global_Options & ON_BOARD_CODEC) {
				dummy_plci.State = IDLE;
				a->codec_listen[appl->Id - 1] = &dummy_plci;
				a->TelOAD[0] = (byte)(parms[3].length);
				for (i = 1; parms[3].length >= i && i < 22; i++) {
					a->TelOAD[i] = parms[3].info[i];
				}
				a->TelOAD[i] = 0;
				a->TelOSA[0] = (byte)(parms[4].length);
				for (i = 1; parms[4].length >= i && i < 22; i++) {
					a->TelOSA[i] = parms[4].info[i];
				}
				a->TelOSA[i] = 0;
			}
			else Info = 0x2002; /* wrong controller, codec not supported */
		}
		else{               /* clear listen */
			a->codec_listen[appl->Id - 1] = (PLCI *)0;
		}
	}
	sendf(appl,
	      _LISTEN_R | CONFIRM,
	      Id,
	      Number,
	      "w", Info);

	if (a) listen_check(a);
	return false;
}

static byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
		     PLCI *plci, APPL *appl, API_PARSE *msg)
{
	word i;
	API_PARSE *ai;
	PLCI *rc_plci = NULL;
	API_PARSE ai_parms[5];
	word Info = 0;

	dbug(1, dprintf("info_req"));
	for (i = 0; i < 5; i++) ai_parms[i].length = 0;

	ai = &msg[1];

	if (ai->length)
	{
		if (api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
		{
			dbug(1, dprintf("AddInfo wrong"));
			Info = _WRONG_MESSAGE_FORMAT;
		}
	}
	if (!a) Info = _WRONG_STATE;

	if (!Info && plci)
	{                /* no fac, with CPN, or KEY */
		rc_plci = plci;
		if (!ai_parms[3].length && plci->State && (msg[0].length || ai_parms[1].length))
		{
			/* overlap sending option */
			dbug(1, dprintf("OvlSnd"));
			add_s(plci, CPN, &msg[0]);
			add_s(plci, KEY, &ai_parms[1]);
			sig_req(plci, INFO_REQ, 0);
			send_req(plci);
			return false;
		}

		if (plci->State && ai_parms[2].length)
		{
			/* User_Info option */
			dbug(1, dprintf("UUI"));
			add_s(plci, UUI, &ai_parms[2]);
			sig_req(plci, USER_DATA, 0);
		}
		else if (plci->State && ai_parms[3].length)
		{
			/* Facility option */
			dbug(1, dprintf("FAC"));
			add_s(plci, CPN, &msg[0]);
			add_ai(plci, &msg[1]);
			sig_req(plci, FACILITY_REQ, 0);
		}
		else
		{
			Info = _WRONG_STATE;
		}
	}
	else if ((ai_parms[1].length || ai_parms[2].length || ai_parms[3].length) && !Info)
	{
		/* NCR_Facility option -> send UUI and Keypad too */
		dbug(1, dprintf("NCR_FAC"));
		if ((i = get_plci(a)))
		{
			rc_plci = &a->plci[i - 1];
			appl->NullCREnable = true;
			rc_plci->internal_command = C_NCR_FAC_REQ;
			rc_plci->appl = appl;
			add_p(rc_plci, CAI, "\x01\x80");
			add_p(rc_plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
			sig_req(rc_plci, ASSIGN, DSIG_ID);
			send_req(rc_plci);
		}
		else
		{
			Info = _OUT_OF_PLCI;
		}

		if (!Info)
		{
			add_s(rc_plci, CPN, &msg[0]);
			add_ai(rc_plci, &msg[1]);
			sig_req(rc_plci, NCR_FACILITY, 0);
			send_req(rc_plci);
			return false;
			/* for application controlled supplementary services    */
		}
	}

	if (!rc_plci)
	{
		Info = _WRONG_MESSAGE_FORMAT;
	}

	if (!Info)
	{
		send_req(rc_plci);
	}
	else
	{  /* appl is not assigned to a PLCI or error condition */
		dbug(1, dprintf("localInfoCon"));
		sendf(appl,
		      _INFO_R | CONFIRM,
		      Id,
		      Number,
		      "w", Info);
	}
	return false;
}

static byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
		     PLCI *plci, APPL *appl, API_PARSE *msg)
{
	dbug(1, dprintf("info_res"));
	return false;
}

static byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
		      PLCI *plci, APPL *appl, API_PARSE *msg)
{
	word Info;
	byte ret;

	dbug(1, dprintf("alert_req"));

	Info = _WRONG_IDENTIFIER;
	ret = false;
	if (plci) {
		Info = _ALERT_IGNORED;
		if (plci->State != INC_CON_ALERT) {
			Info = _WRONG_STATE;
			if (plci->State == INC_CON_PENDING) {
				Info = 0;
				plci->State = INC_CON_ALERT;
				add_ai(plci, &msg[0]);
				sig_req(plci, CALL_ALERT, 0);
				ret = 1;
			}
		}
	}
	sendf(appl,
	      _ALERT_R | CONFIRM,
	      Id,
	      Number,
	      "w", Info);
	return ret;
}

static byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			 PLCI *plci, APPL *appl, API_PARSE *msg)
{
	word Info = 0;
	word i    = 0;

	word selector;
	word SSreq;
	long relatedPLCIvalue;
	DIVA_CAPI_ADAPTER *relatedadapter;
	byte *SSparms  = "";
	byte RCparms[]  = "\x05\x00\x00\x02\x00\x00";
	byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
	API_PARSE *parms;
	API_PARSE ss_parms[11];
	PLCI *rplci;
	byte cai[15];
	dword d;
	API_PARSE dummy;

	dbug(1, dprintf("facility_req"));
	for (i = 0; i < 9; i++) ss_parms[i].length = 0;

	parms = &msg[1];

	if (!a)
	{
		dbug(1, dprintf("wrong Ctrl"));
		Info = _WRONG_IDENTIFIER;
	}

	selector = GET_WORD(msg[0].info);

	if (!Info)
	{
		switch (selector)
		{
		case SELECTOR_HANDSET:
			Info = AdvCodecSupport(a, plci, appl, HOOK_SUPPORT);
			break;

		case SELECTOR_SU_SERV:
			if (!msg[1].length)
			{
				Info = _WRONG_MESSAGE_FORMAT;
				break;
			}
			SSreq = GET_WORD(&(msg[1].info[1]));
			PUT_WORD(&RCparms[1], SSreq);
			SSparms = RCparms;
			switch (SSreq)
			{
			case S_GET_SUPPORTED_SERVICES:
				if ((i = get_plci(a)))
				{
					rplci = &a->plci[i - 1];
					rplci->appl = appl;
					add_p(rplci, CAI, "\x01\x80");
					add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
					sig_req(rplci, ASSIGN, DSIG_ID);
					send_req(rplci);
				}
				else
				{
					PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
					SSparms = (byte *)SSstruct;
					break;
				}
				rplci->internal_command = GETSERV_REQ_PEND;
				rplci->number = Number;
				rplci->appl = appl;
				sig_req(rplci, S_SUPPORTED, 0);
				send_req(rplci);
				return false;
				break;

			case S_LISTEN:
				if (parms->length == 7)
				{
					if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
					{
						dbug(1, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
						break;
					}
				}
				else
				{
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				a->Notification_Mask[appl->Id - 1] = GET_DWORD(ss_parms[2].info);
				if (a->Notification_Mask[appl->Id - 1] & SMASK_MWI) /* MWI active? */
				{
					if ((i = get_plci(a)))
					{
						rplci = &a->plci[i - 1];
						rplci->appl = appl;
						add_p(rplci, CAI, "\x01\x80");
						add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
						sig_req(rplci, ASSIGN, DSIG_ID);
						send_req(rplci);
					}
					else
					{
						break;
					}
					rplci->internal_command = GET_MWI_STATE;
					rplci->number = Number;
					sig_req(rplci, MWI_POLL, 0);
					send_req(rplci);
				}
				break;

			case S_HOLD:
				api_parse(&parms->info[1], (word)parms->length, "ws", ss_parms);
				if (plci && plci->State && plci->SuppState == IDLE)
				{
					plci->SuppState = HOLD_REQUEST;
					plci->command = C_HOLD_REQ;
					add_s(plci, CAI, &ss_parms[1]);
					sig_req(plci, CALL_HOLD, 0);
					send_req(plci);
					return false;
				}
				else Info = 0x3010;                    /* wrong state           */
				break;
			case S_RETRIEVE:
				if (plci && plci->State && plci->SuppState == CALL_HELD)
				{
					if (Id & EXT_CONTROLLER)
					{
						if (AdvCodecSupport(a, plci, appl, 0))
						{
							Info = 0x3010;                    /* wrong state           */
							break;
						}
					}
					else plci->tel = 0;

					plci->SuppState = RETRIEVE_REQUEST;
					plci->command = C_RETRIEVE_REQ;
					if (plci->spoofed_msg == SPOOFING_REQUIRED)
					{
						plci->spoofed_msg = CALL_RETRIEVE;
						plci->internal_command = BLOCK_PLCI;
						plci->command = 0;
						dbug(1, dprintf("Spoof"));
						return false;
					}
					else
					{
						sig_req(plci, CALL_RETRIEVE, 0);
						send_req(plci);
						return false;
					}
				}
				else Info = 0x3010;                    /* wrong state           */
				break;
			case S_SUSPEND:
				if (parms->length)
				{
					if (api_parse(&parms->info[1], (word)parms->length, "wbs", ss_parms))
					{
						dbug(1, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
						break;
					}
				}
				if (plci && plci->State)
				{
					add_s(plci, CAI, &ss_parms[2]);
					plci->command = SUSPEND_REQ;
					sig_req(plci, SUSPEND, 0);
					plci->State = SUSPENDING;
					send_req(plci);
				}
				else Info = 0x3010;                    /* wrong state           */
				break;

			case S_RESUME:
				if (!(i = get_plci(a)))
				{
					Info = _OUT_OF_PLCI;
					break;
				}
				rplci = &a->plci[i - 1];
				rplci->appl = appl;
				rplci->number = Number;
				rplci->tel = 0;
				rplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
				/* check 'external controller' bit for codec support */
				if (Id & EXT_CONTROLLER)
				{
					if (AdvCodecSupport(a, rplci, appl, 0))
					{
						rplci->Id = 0;
						Info = 0x300A;
						break;
					}
				}
				if (parms->length)
				{
					if (api_parse(&parms->info[1], (word)parms->length, "wbs", ss_parms))
					{
						dbug(1, dprintf("format wrong"));
						rplci->Id = 0;
						Info = _WRONG_MESSAGE_FORMAT;
						break;
					}
				}
				dummy.length = 0;
				dummy.info = "\x00";
				add_b1(rplci, &dummy, 0, 0);
				if (a->Info_Mask[appl->Id - 1] & 0x200)
				{
					/* early B3 connect (CIP mask bit 9) no release after a disc */
					add_p(rplci, LLI, "\x01\x01");
				}
				add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
				sig_req(rplci, ASSIGN, DSIG_ID);
				send_req(rplci);
				add_s(rplci, CAI, &ss_parms[2]);
				rplci->command = RESUME_REQ;
				sig_req(rplci, RESUME, 0);
				rplci->State = RESUMING;
				send_req(rplci);
				break;

			case S_CONF_BEGIN: /* Request */
			case S_CONF_DROP:
			case S_CONF_ISOLATE:
			case S_CONF_REATTACH:
				if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
				{
					dbug(1, dprintf("format wrong"));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				if (plci && plci->State && ((plci->SuppState == IDLE) || (plci->SuppState == CALL_HELD)))
				{
					d = GET_DWORD(ss_parms[2].info);
					if (d >= 0x80)
					{
						dbug(1, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
						break;
					}
					plci->ptyState = (byte)SSreq;
					plci->command = 0;
					cai[0] = 2;
					switch (SSreq)
					{
					case S_CONF_BEGIN:
						cai[1] = CONF_BEGIN;
						plci->internal_command = CONF_BEGIN_REQ_PEND;
						break;
					case S_CONF_DROP:
						cai[1] = CONF_DROP;
						plci->internal_command = CONF_DROP_REQ_PEND;
						break;
					case S_CONF_ISOLATE:
						cai[1] = CONF_ISOLATE;
						plci->internal_command = CONF_ISOLATE_REQ_PEND;
						break;
					case S_CONF_REATTACH:
						cai[1] = CONF_REATTACH;
						plci->internal_command = CONF_REATTACH_REQ_PEND;
						break;
					}
					cai[2] = (byte)d; /* Conference Size resp. PartyId */
					add_p(plci, CAI, cai);
					sig_req(plci, S_SERVICE, 0);
					send_req(plci);
					return false;
				}
				else Info = 0x3010;                    /* wrong state           */
				break;

			case S_ECT:
			case S_3PTY_BEGIN:
			case S_3PTY_END:
			case S_CONF_ADD:
				if (parms->length == 7)
				{
					if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
					{
						dbug(1, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
						break;
					}
				}
				else if (parms->length == 8) /* workaround for the T-View-S */
				{
					if (api_parse(&parms->info[1], (word)parms->length, "wbdb", ss_parms))
					{
						dbug(1, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
						break;
					}
				}
				else
				{
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				if (!msg[1].length)
				{
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				if (!plci)
				{
					Info = _WRONG_IDENTIFIER;
					break;
				}
				relatedPLCIvalue = GET_DWORD(ss_parms[2].info);
				relatedPLCIvalue &= 0x0000FFFF;
				dbug(1, dprintf("PTY/ECT/addCONF,relPLCI=%lx", relatedPLCIvalue));
				/* controller starts with 0 up to (max_adapter - 1) */
				if (((relatedPLCIvalue & 0x7f) == 0)
				    || (MapController((byte)(relatedPLCIvalue & 0x7f)) == 0)
				    || (MapController((byte)(relatedPLCIvalue & 0x7f)) > max_adapter))
				{
					if (SSreq == S_3PTY_END)
					{
						dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI"));
						rplci = plci;
					}
					else
					{
						Info = 0x3010;                    /* wrong state           */
						break;
					}
				}
				else
				{
					relatedadapter = &adapter[MapController((byte)(relatedPLCIvalue & 0x7f)) - 1];
					relatedPLCIvalue >>= 8;
					/* find PLCI PTR*/
					for (i = 0, rplci = NULL; i < relatedadapter->max_plci; i++)
					{
						if (relatedadapter->plci[i].Id == (byte)relatedPLCIvalue)
						{
							rplci = &relatedadapter->plci[i];
						}
					}
					if (!rplci || !relatedPLCIvalue)
					{
						if (SSreq == S_3PTY_END)
						{
							dbug(1, dprintf("use 2nd PLCI=PLCI"));
							rplci = plci;
						}
						else
						{
							Info = 0x3010;                    /* wrong state           */
							break;
						}
					}
				}
/*
  dbug(1, dprintf("rplci:%x", rplci));
  dbug(1, dprintf("plci:%x", plci));
  dbug(1, dprintf("rplci->ptyState:%x", rplci->ptyState));
  dbug(1, dprintf("plci->ptyState:%x", plci->ptyState));
  dbug(1, dprintf("SSreq:%x", SSreq));
  dbug(1, dprintf("rplci->internal_command:%x", rplci->internal_command));
  dbug(1, dprintf("rplci->appl:%x", rplci->appl));
  dbug(1, dprintf("rplci->Id:%x", rplci->Id));
*/
				/* send PTY/ECT req, cannot check all states because of US stuff */
				if (!rplci->internal_command && rplci->appl)
				{
					plci->command = 0;
					rplci->relatedPTYPLCI = plci;
					plci->relatedPTYPLCI = rplci;
					rplci->ptyState = (byte)SSreq;
					if (SSreq == S_ECT)
					{
						rplci->internal_command = ECT_REQ_PEND;
						cai[1] = ECT_EXECUTE;

						rplci->vswitchstate = 0;
						rplci->vsprot = 0;
						rplci->vsprotdialect = 0;
						plci->vswitchstate = 0;
						plci->vsprot = 0;
						plci->vsprotdialect = 0;

					}
					else if (SSreq == S_CONF_ADD)
					{
						rplci->internal_command = CONF_ADD_REQ_PEND;
						cai[1] = CONF_ADD;
					}
					else
					{
						rplci->internal_command = PTY_REQ_PEND;
						cai[1] = (byte)(SSreq - 3);
					}
					rplci->number = Number;
					if (plci != rplci) /* explicit invocation */
					{
						cai[0] = 2;
						cai[2] = plci->Sig.Id;
						dbug(1, dprintf("explicit invocation"));
					}
					else
					{
						dbug(1, dprintf("implicit invocation"));
						cai[0] = 1;
					}
					add_p(rplci, CAI, cai);
					sig_req(rplci, S_SERVICE, 0);
					send_req(rplci);
					return false;
				}
				else
				{
					dbug(0, dprintf("Wrong line"));
					Info = 0x3010;                    /* wrong state           */
					break;
				}
				break;

			case S_CALL_DEFLECTION:
				if (api_parse(&parms->info[1], (word)parms->length, "wbwss", ss_parms))
				{
					dbug(1, dprintf("format wrong"));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				if (!plci)
				{
					Info = _WRONG_IDENTIFIER;
					break;
				}
				/* reuse unused screening indicator */
				ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0]));
				plci->command = 0;
				plci->internal_command = CD_REQ_PEND;
				appl->CDEnable = true;
				cai[0] = 1;
				cai[1] = CALL_DEFLECTION;
				add_p(plci, CAI, cai);
				add_p(plci, CPN, ss_parms[3].info);
				sig_req(plci, S_SERVICE, 0);
				send_req(plci);
				return false;
				break;

			case S_CALL_FORWARDING_START:
				if (api_parse(&parms->info[1], (word)parms->length, "wbdwwsss", ss_parms))
				{
					dbug(1, dprintf("format wrong"));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}

				if ((i = get_plci(a)))
				{
					rplci = &a->plci[i - 1];
					rplci->appl = appl;
					add_p(rplci, CAI, "\x01\x80");
					add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
					sig_req(rplci, ASSIGN, DSIG_ID);
					send_req(rplci);
				}
				else
				{
					Info = _OUT_OF_PLCI;
					break;
				}

				/* reuse unused screening indicator */
				rplci->internal_command = CF_START_PEND;
				rplci->appl = appl;
				rplci->number = Number;
				appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
				cai[0] = 2;
				cai[1] = 0x70 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
				cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */
				add_p(rplci, CAI, cai);
				add_p(rplci, OAD, ss_parms[5].info);
				add_p(rplci, CPN, ss_parms[6].info);
				sig_req(rplci, S_SERVICE, 0);
				send_req(rplci);
				return false;
				break;

			case S_INTERROGATE_DIVERSION:
			case S_INTERROGATE_NUMBERS:
			case S_CALL_FORWARDING_STOP:
			case S_CCBS_REQUEST:
			case S_CCBS_DEACTIVATE:
			case S_CCBS_INTERROGATE:
				switch (SSreq)
				{
				case S_INTERROGATE_NUMBERS:
					if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
					{
						dbug(0, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
					}
					break;
				case S_CCBS_REQUEST:
				case S_CCBS_DEACTIVATE:
					if (api_parse(&parms->info[1], (word)parms->length, "wbdw", ss_parms))
					{
						dbug(0, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
					}
					break;
				case S_CCBS_INTERROGATE:
					if (api_parse(&parms->info[1], (word)parms->length, "wbdws", ss_parms))
					{
						dbug(0, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
					}
					break;
				default:
					if (api_parse(&parms->info[1], (word)parms->length, "wbdwws", ss_parms))
					{
						dbug(0, dprintf("format wrong"));
						Info = _WRONG_MESSAGE_FORMAT;
						break;
					}
					break;
				}

				if (Info) break;
				if ((i = get_plci(a)))
				{
					rplci = &a->plci[i - 1];
					switch (SSreq)
					{
					case S_INTERROGATE_DIVERSION: /* use cai with S_SERVICE below */
						cai[1] = 0x60 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
						rplci->internal_command = INTERR_DIVERSION_REQ_PEND; /* move to rplci if assigned */
						break;
					case S_INTERROGATE_NUMBERS: /* use cai with S_SERVICE below */
						cai[1] = DIVERSION_INTERROGATE_NUM; /* Function */
						rplci->internal_command = INTERR_NUMBERS_REQ_PEND; /* move to rplci if assigned */
						break;
					case S_CALL_FORWARDING_STOP:
						rplci->internal_command = CF_STOP_PEND;
						cai[1] = 0x80 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
						break;
					case S_CCBS_REQUEST:
						cai[1] = CCBS_REQUEST;
						rplci->internal_command = CCBS_REQUEST_REQ_PEND;
						break;
					case S_CCBS_DEACTIVATE:
						cai[1] = CCBS_DEACTIVATE;
						rplci->internal_command = CCBS_DEACTIVATE_REQ_PEND;
						break;
					case S_CCBS_INTERROGATE:
						cai[1] = CCBS_INTERROGATE;
						rplci->internal_command = CCBS_INTERROGATE_REQ_PEND;
						break;
					default:
						cai[1] = 0;
						break;
					}
					rplci->appl = appl;
					rplci->number = Number;
					add_p(rplci, CAI, "\x01\x80");
					add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
					sig_req(rplci, ASSIGN, DSIG_ID);
					send_req(rplci);
				}
				else
				{
					Info = _OUT_OF_PLCI;
					break;
				}

				appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
				switch (SSreq)
				{
				case S_INTERROGATE_NUMBERS:
					cai[0] = 1;
					add_p(rplci, CAI, cai);
					break;
				case S_CCBS_REQUEST:
				case S_CCBS_DEACTIVATE:
					cai[0] = 3;
					PUT_WORD(&cai[2], GET_WORD(&(ss_parms[3].info[0])));
					add_p(rplci, CAI, cai);
					break;
				case S_CCBS_INTERROGATE:
					cai[0] = 3;
					PUT_WORD(&cai[2], GET_WORD(&(ss_parms[3].info[0])));
					add_p(rplci, CAI, cai);
					add_p(rplci, OAD, ss_parms[4].info);
					break;
				default:
					cai[0] = 2;
					cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */
					add_p(rplci, CAI, cai);
					add_p(rplci, OAD, ss_parms[5].info);
					break;
				}

				sig_req(rplci, S_SERVICE, 0);
				send_req(rplci);
				return false;
				break;

			case S_MWI_ACTIVATE:
				if (api_parse(&parms->info[1], (word)parms->length, "wbwdwwwssss", ss_parms))
				{
					dbug(1, dprintf("format wrong"));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				if (!plci)
				{
					if ((i = get_plci(a)))
					{
						rplci = &a->plci[i - 1];
						rplci->appl = appl;
						rplci->cr_enquiry = true;
						add_p(rplci, CAI, "\x01\x80");
						add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
						sig_req(rplci, ASSIGN, DSIG_ID);
						send_req(rplci);
					}
					else
					{
						Info = _OUT_OF_PLCI;
						break;
					}
				}
				else
				{
					rplci = plci;
					rplci->cr_enquiry = false;
				}

				rplci->command = 0;
				rplci->internal_command = MWI_ACTIVATE_REQ_PEND;
				rplci->appl = appl;
				rplci->number = Number;

				cai[0] = 13;
				cai[1] = ACTIVATION_MWI; /* Function */
				PUT_WORD(&cai[2], GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */
				PUT_DWORD(&cai[4], GET_DWORD(&(ss_parms[3].info[0]))); /* Number of Messages */
				PUT_WORD(&cai[8], GET_WORD(&(ss_parms[4].info[0]))); /* Message Status */
				PUT_WORD(&cai[10], GET_WORD(&(ss_parms[5].info[0]))); /* Message Reference */
				PUT_WORD(&cai[12], GET_WORD(&(ss_parms[6].info[0]))); /* Invocation Mode */
				add_p(rplci, CAI, cai);
				add_p(rplci, CPN, ss_parms[7].info); /* Receiving User Number */
				add_p(rplci, OAD, ss_parms[8].info); /* Controlling User Number */
				add_p(rplci, OSA, ss_parms[9].info); /* Controlling User Provided Number */
				add_p(rplci, UID, ss_parms[10].info); /* Time */
				sig_req(rplci, S_SERVICE, 0);
				send_req(rplci);
				return false;

			case S_MWI_DEACTIVATE:
				if (api_parse(&parms->info[1], (word)parms->length, "wbwwss", ss_parms))
				{
					dbug(1, dprintf("format wrong"));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				if (!plci)
				{
					if ((i = get_plci(a)))
					{
						rplci = &a->plci[i - 1];
						rplci->appl = appl;
						rplci->cr_enquiry = true;
						add_p(rplci, CAI, "\x01\x80");
						add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
						sig_req(rplci, ASSIGN, DSIG_ID);
						send_req(rplci);
					}
					else
					{
						Info = _OUT_OF_PLCI;
						break;
					}
				}
				else
				{
					rplci = plci;
					rplci->cr_enquiry = false;
				}

				rplci->command = 0;
				rplci->internal_command = MWI_DEACTIVATE_REQ_PEND;
				rplci->appl = appl;
				rplci->number = Number;

				cai[0] = 5;
				cai[1] = DEACTIVATION_MWI; /* Function */
				PUT_WORD(&cai[2], GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */
				PUT_WORD(&cai[4], GET_WORD(&(ss_parms[3].info[0]))); /* Invocation Mode */
				add_p(rplci, CAI, cai);
				add_p(rplci, CPN, ss_parms[4].info); /* Receiving User Number */
				add_p(rplci, OAD, ss_parms[5].info); /* Controlling User Number */
				sig_req(rplci, S_SERVICE, 0);
				send_req(rplci);
				return false;

			default:
				Info = 0x300E;  /* not supported */
				break;
			}
			break; /* case SELECTOR_SU_SERV: end */


		case SELECTOR_DTMF:
			return (dtmf_request(Id, Number, a, plci, appl, msg));



		case SELECTOR_LINE_INTERCONNECT:
			return (mixer_request(Id, Number, a, plci, appl, msg));



		case PRIV_SELECTOR_ECHO_CANCELLER:
			appl->appl_flags |= APPL_FLAG_PRIV_EC_SPEC;
			return (ec_request(Id, Number, a, plci, appl, msg));

		case SELECTOR_ECHO_CANCELLER:
			appl->appl_flags &= ~APPL_FLAG_PRIV_EC_SPEC;
			return (ec_request(Id, Number, a, plci, appl, msg));


		case SELECTOR_V42BIS:
		default:
			Info = _FACILITY_NOT_SUPPORTED;
			break;
		} /* end of switch (selector) */
	}

	dbug(1, dprintf("SendFacRc"));
	sendf(appl,
	      _FACILITY_R | CONFIRM,
	      Id,
	      Number,
	      "wws", Info, selector, SSparms);
	return false;
}

static byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			 PLCI *plci, APPL *appl, API_PARSE *msg)
{
	dbug(1, dprintf("facility_res"));
	return false;
}

static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			   PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word Info = 0;
	byte req;
	byte len;
	word w;
	word fax_control_bits, fax_feature_bits, fax_info_change;
	API_PARSE *ncpi;
	byte pvc[2];

	API_PARSE fax_parms[9];
	word i;


	dbug(1, dprintf("connect_b3_req"));
	if (plci)
	{
		if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING)
		    || (plci->State == INC_DIS_PENDING) || (plci->SuppState != IDLE))
		{
			Info = _WRONG_STATE;
		}
		else
		{
			/* local reply if assign unsuccessful
			   or B3 protocol allows only one layer 3 connection
			   and already connected
			   or B2 protocol not any LAPD
			   and connect_b3_req contradicts originate/answer direction */
			if (!plci->NL.Id
			    || (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))
				&& ((plci->channels != 0)
				    || (((plci->B2_prot != B2_SDLC) && (plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL))
					&& ((plci->call_dir & CALL_DIR_ANSWER) && !(plci->call_dir & CALL_DIR_FORCE_OUTG_NL))))))
			{
				dbug(1, dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x",
						plci->channels, plci->NL.Id, plci->call_dir, plci->SuppState));
				Info = _WRONG_STATE;
				sendf(appl,
				      _CONNECT_B3_R | CONFIRM,
				      Id,
				      Number,
				      "w", Info);
				return false;
			}
			plci->requested_options_conn = 0;

			req = N_CONNECT;
			ncpi = &parms[0];
			if (plci->B3_prot == 2 || plci->B3_prot == 3)
			{
				if (ncpi->length > 2)
				{
					/* check for PVC */
					if (ncpi->info[2] || ncpi->info[3])
					{
						pvc[0] = ncpi->info[3];
						pvc[1] = ncpi->info[2];
						add_d(plci, 2, pvc);
						req = N_RESET;
					}
					else
					{
						if (ncpi->info[1] & 1) req = N_CONNECT | N_D_BIT;
						add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
					}
				}
			}
			else if (plci->B3_prot == 5)
			{
				if (plci->NL.Id && !plci->nl_remove_id)
				{
					fax_control_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low);
					fax_feature_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low);
					if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS)
					    || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS))
					{
						len = offsetof(T30_INFO, universal_6);
						fax_info_change = false;
						if (ncpi->length >= 4)
						{
							w = GET_WORD(&ncpi->info[3]);
							if ((w & 0x0001) != ((word)(((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & 0x0001)))
							{
								((T30_INFO *)(plci->fax_connect_info_buffer))->resolution =
									(byte)((((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & ~T30_RESOLUTION_R8_0770_OR_200) |
									       ((w & 0x0001) ? T30_RESOLUTION_R8_0770_OR_200 : 0));
								fax_info_change = true;
							}
							fax_control_bits &= ~(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
							if (w & 0x0002)  /* Fax-polling request */
								fax_control_bits |= T30_CONTROL_BIT_REQUEST_POLLING;
							if ((w & 0x0004) /* Request to send / poll another document */
							    && (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS))
							{
								fax_control_bits |= T30_CONTROL_BIT_MORE_DOCUMENTS;
							}
							if (ncpi->length >= 6)
							{
								w = GET_WORD(&ncpi->info[5]);
								if (((byte) w) != ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format)
								{
									((T30_INFO *)(plci->fax_connect_info_buffer))->data_format = (byte) w;
									fax_info_change = true;
								}

								if ((a->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
								    && (GET_WORD(&ncpi->info[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */
								{
									plci->requested_options_conn |= (1L << PRIVATE_FAX_SUB_SEP_PWD);
								}
								if ((a->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
								    && (GET_WORD(&ncpi->info[5]) & 0x4000)) /* Private non-standard facilities enable */
								{
									plci->requested_options_conn |= (1L << PRIVATE_FAX_NONSTANDARD);
								}
								fax_control_bits &= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_SEL_POLLING |
										      T30_CONTROL_BIT_ACCEPT_PASSWORD);
								if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
								    & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
								{
									if (api_parse(&ncpi->info[1], ncpi->length, "wwwwsss", fax_parms))
										Info = _WRONG_MESSAGE_FORMAT;
									else
									{
										if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
										    & (1L << PRIVATE_FAX_SUB_SEP_PWD))
										{
											fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD;
											if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING)
												fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
										}
										w = fax_parms[4].length;
										if (w > 20)
											w = 20;
										((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = (byte) w;
										for (i = 0; i < w; i++)
											((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1 + i];
										((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
										len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
										w = fax_parms[5].length;
										if (w > 20)
											w = 20;
										plci->fax_connect_info_buffer[len++] = (byte) w;
										for (i = 0; i < w; i++)
											plci->fax_connect_info_buffer[len++] = fax_parms[5].info[1 + i];
										w = fax_parms[6].length;
										if (w > 20)
											w = 20;
										plci->fax_connect_info_buffer[len++] = (byte) w;
										for (i = 0; i < w; i++)
											plci->fax_connect_info_buffer[len++] = fax_parms[6].info[1 + i];
										if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
										    & (1L << PRIVATE_FAX_NONSTANDARD))
										{
											if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
											{
												dbug(1, dprintf("non-standard facilities info missing or wrong format"));
												plci->fax_connect_info_buffer[len++] = 0;
											}
											else
											{
												if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
													plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
												plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
												for (i = 0; i < fax_parms[7].length; i++)
													plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
											}
										}
									}
								}
								else
								{
									len = offsetof(T30_INFO, universal_6);
								}
								fax_info_change = true;

							}
							if (fax_control_bits != GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low))
							{
								PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits);
								fax_info_change = true;
							}
						}
						if (Info == GOOD)
						{
							plci->fax_connect_info_length = len;
							if (fax_info_change)
							{
								if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
								{
									start_internal_command(Id, plci, fax_connect_info_command);
									return false;
								}
								else
								{
									start_internal_command(Id, plci, fax_adjust_b23_command);
									return false;
								}
							}
						}
					}
					else  Info = _WRONG_STATE;
				}
				else  Info = _WRONG_STATE;
			}

			else if (plci->B3_prot == B3_RTP)
			{
				plci->internal_req_buffer[0] = ncpi->length + 1;
				plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE;
				for (w = 0; w < ncpi->length; w++)
					plci->internal_req_buffer[2 + w] = ncpi->info[1 + w];
				start_internal_command(Id, plci, rtp_connect_b3_req_command);
				return false;
			}

			if (!Info)
			{
				nl_req_ncci(plci, req, 0);
				return 1;
			}
		}
	}
	else Info = _WRONG_IDENTIFIER;

	sendf(appl,
	      _CONNECT_B3_R | CONFIRM,
	      Id,
	      Number,
	      "w", Info);
	return false;
}

static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			   PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word ncci;
	API_PARSE *ncpi;
	byte req;

	word w;


	API_PARSE fax_parms[9];
	word i;
	byte len;


	dbug(1, dprintf("connect_b3_res"));

	ncci = (word)(Id >> 16);
	if (plci && ncci) {
		if (a->ncci_state[ncci] == INC_CON_PENDING) {
			if (GET_WORD(&parms[0].info[0]) != 0)
			{
				a->ncci_state[ncci] = OUTG_REJ_PENDING;
				channel_request_xon(plci, a->ncci_ch[ncci]);
				channel_xmit_xon(plci);
				cleanup_ncci_data(plci, ncci);
				nl_req_ncci(plci, N_DISC, (byte)ncci);
				return 1;
			}
			a->ncci_state[ncci] = INC_ACT_PENDING;

			req = N_CONNECT_ACK;
			ncpi = &parms[1];
			if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
			{

				if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
				    & (1L << PRIVATE_FAX_NONSTANDARD))
				{
					if (((plci->B3_prot == 4) || (plci->B3_prot == 5))
					    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
					    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
					{
						len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
						if (plci->fax_connect_info_length < len)
						{
							((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
							((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
						}
						if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
						{
							dbug(1, dprintf("non-standard facilities info missing or wrong format"));
						}
						else
						{
							if (plci->fax_connect_info_length <= len)
								plci->fax_connect_info_buffer[len] = 0;
							len += 1 + plci->fax_connect_info_buffer[len];
							if (plci->fax_connect_info_length <= len)
								plci->fax_connect_info_buffer[len] = 0;
							len += 1 + plci->fax_connect_info_buffer[len];
							if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
								plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
							plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
							for (i = 0; i < fax_parms[7].length; i++)
								plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
						}
						plci->fax_connect_info_length = len;
						((T30_INFO *)(plci->fax_connect_info_buffer))->code = 0;
						start_internal_command(Id, plci, fax_connect_ack_command);
						return false;
					}
				}

				nl_req_ncci(plci, req, (byte)ncci);
				if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
				    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
				{
					if (plci->B3_prot == 4)
						sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
					else
						sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
					plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
				}
			}

			else if (plci->B3_prot == B3_RTP)
			{
				plci->internal_req_buffer[0] = ncpi->length + 1;
				plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE;
				for (w = 0; w < ncpi->length; w++)
					plci->internal_req_buffer[2 + w] = ncpi->info[1+w];
				start_internal_command(Id, plci, rtp_connect_b3_res_command);
				return false;
			}

			else
			{
				if (ncpi->length > 2) {
					if (ncpi->info[1] & 1) req = N_CONNECT_ACK | N_D_BIT;
					add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
				}
				nl_req_ncci(plci, req, (byte)ncci);
				sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
				if (plci->adjust_b_restore)
				{
					plci->adjust_b_restore = false;
					start_internal_command(Id, plci, adjust_b_restore);
				}
			}
			return 1;
		}
	}
	return false;
}

static byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			     PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word ncci;

	ncci = (word)(Id >> 16);
	dbug(1, dprintf("connect_b3_a_res(ncci=0x%x)", ncci));

	if (plci && ncci && (plci->State != IDLE) && (plci->State != INC_DIS_PENDING)
	    && (plci->State != OUTG_DIS_PENDING))
	{
		if (a->ncci_state[ncci] == INC_ACT_PENDING) {
			a->ncci_state[ncci] = CONNECTED;
			if (plci->State != INC_CON_CONNECTED_ALERT) plci->State = CONNECTED;
			channel_request_xon(plci, a->ncci_ch[ncci]);
			channel_xmit_xon(plci);
		}
	}
	return false;
}

static byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			      PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word Info;
	word ncci;
	API_PARSE *ncpi;

	dbug(1, dprintf("disconnect_b3_req"));

	Info = _WRONG_IDENTIFIER;
	ncci = (word)(Id >> 16);
	if (plci && ncci)
	{
		Info = _WRONG_STATE;
		if ((a->ncci_state[ncci] == CONNECTED)
		    || (a->ncci_state[ncci] == OUTG_CON_PENDING)
		    || (a->ncci_state[ncci] == INC_CON_PENDING)
		    || (a->ncci_state[ncci] == INC_ACT_PENDING))
		{
			a->ncci_state[ncci] = OUTG_DIS_PENDING;
			channel_request_xon(plci, a->ncci_ch[ncci]);
			channel_xmit_xon(plci);

			if (a->ncci[ncci].data_pending
			    && ((plci->B3_prot == B3_TRANSPARENT)
				|| (plci->B3_prot == B3_T30)
				|| (plci->B3_prot == B3_T30_WITH_EXTENSIONS)))
			{
				plci->send_disc = (byte)ncci;
				plci->command = 0;
				return false;
			}
			else
			{
				cleanup_ncci_data(plci, ncci);

				if (plci->B3_prot == 2 || plci->B3_prot == 3)
				{
					ncpi = &parms[0];
					if (ncpi->length > 3)
					{
						add_d(plci, (word)(ncpi->length - 3), (byte *)&(ncpi->info[4]));
					}
				}
				nl_req_ncci(plci, N_DISC, (byte)ncci);
			}
			return 1;
		}
	}
	sendf(appl,
	      _DISCONNECT_B3_R | CONFIRM,
	      Id,
	      Number,
	      "w", Info);
	return false;
}

static byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			      PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word ncci;
	word i;

	ncci = (word)(Id >> 16);
	dbug(1, dprintf("disconnect_b3_res(ncci=0x%x", ncci));
	if (plci && ncci) {
		plci->requested_options_conn = 0;
		plci->fax_connect_info_length = 0;
		plci->ncpi_state = 0x00;
		if (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))
		    && ((plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL)))
		{
			plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
		}
		for (i = 0; i < MAX_CHANNELS_PER_PLCI && plci->inc_dis_ncci_table[i] != (byte)ncci; i++);
		if (i < MAX_CHANNELS_PER_PLCI) {
			if (plci->channels)plci->channels--;
			for (; i < MAX_CHANNELS_PER_PLCI - 1; i++) plci->inc_dis_ncci_table[i] = plci->inc_dis_ncci_table[i + 1];
			plci->inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI - 1] = 0;

			ncci_free_receive_buffers(plci, ncci);

			if ((plci->State == IDLE || plci->State == SUSPENDING) && !plci->channels) {
				if (plci->State == SUSPENDING) {
					sendf(plci->appl,
					      _FACILITY_I,
					      Id & 0xffffL,
					      0,
					      "ws", (word)3, "\x03\x04\x00\x00");
					sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
				}
				plci_remove(plci);
				plci->State = IDLE;
			}
		}
		else
		{
			if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
			    && ((plci->B3_prot == 4) || (plci->B3_prot == 5))
			    && (a->ncci_state[ncci] == INC_DIS_PENDING))
			{
				ncci_free_receive_buffers(plci, ncci);

				nl_req_ncci(plci, N_EDATA, (byte)ncci);

				plci->adapter->ncci_state[ncci] = IDLE;
				start_internal_command(Id, plci, fax_disconnect_command);
				return 1;
			}
		}
	}
	return false;
}

static byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			PLCI *plci, APPL *appl, API_PARSE *parms)
{
	NCCI *ncci_ptr;
	DATA_B3_DESC *data;
	word Info;
	word ncci;
	word i;

	dbug(1, dprintf("data_b3_req"));

	Info = _WRONG_IDENTIFIER;
	ncci = (word)(Id >> 16);
	dbug(1, dprintf("ncci=0x%x, plci=0x%x", ncci, plci));

	if (plci && ncci)
	{
		Info = _WRONG_STATE;
		if ((a->ncci_state[ncci] == CONNECTED)
		    || (a->ncci_state[ncci] == INC_ACT_PENDING))
		{
			/* queue data */
			ncci_ptr = &(a->ncci[ncci]);
			i = ncci_ptr->data_out + ncci_ptr->data_pending;
			if (i >= MAX_DATA_B3)
				i -= MAX_DATA_B3;
			data = &(ncci_ptr->DBuffer[i]);
			data->Number = Number;
			if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue)))
			    && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
			{

				data->P = (byte *)(long)(*((dword *)(parms[0].info)));

			}
			else
				data->P = TransmitBufferSet(appl, *(dword *)parms[0].info);
			data->Length = GET_WORD(parms[1].info);
			data->Handle = GET_WORD(parms[2].info);
			data->Flags = GET_WORD(parms[3].info);
			(ncci_ptr->data_pending)++;

			/* check for delivery confirmation */
			if (data->Flags & 0x0004)
			{
				i = ncci_ptr->data_ack_out + ncci_ptr->data_ack_pending;
				if (i >= MAX_DATA_ACK)
					i -= MAX_DATA_ACK;
				ncci_ptr->DataAck[i].Number = data->Number;
				ncci_ptr->DataAck[i].Handle = data->Handle;
				(ncci_ptr->data_ack_pending)++;
			}

			send_data(plci);
			return false;
		}
	}
	if (appl)
	{
		if (plci)
		{
			if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue)))
			    && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
			{

				TransmitBufferFree(appl, (byte *)(long)(*((dword *)(parms[0].info))));

			}
		}
		sendf(appl,
		      _DATA_B3_R | CONFIRM,
		      Id,
		      Number,
		      "ww", GET_WORD(parms[2].info), Info);
	}
	return false;
}

static byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word n;
	word ncci;
	word NCCIcode;

	dbug(1, dprintf("data_b3_res"));

	ncci = (word)(Id >> 16);
	if (plci && ncci) {
		n = GET_WORD(parms[0].info);
		dbug(1, dprintf("free(%d)", n));
		NCCIcode = ncci | (((word) a->Id) << 8);
		if (n < appl->MaxBuffer &&
		    appl->DataNCCI[n] == NCCIcode &&
		    (byte)(appl->DataFlags[n] >> 8) == plci->Id) {
			dbug(1, dprintf("found"));
			appl->DataNCCI[n] = 0;

			if (channel_can_xon(plci, a->ncci_ch[ncci])) {
				channel_request_xon(plci, a->ncci_ch[ncci]);
			}
			channel_xmit_xon(plci);

			if (appl->DataFlags[n] & 4) {
				nl_req_ncci(plci, N_DATA_ACK, (byte)ncci);
				return 1;
			}
		}
	}
	return false;
}

static byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			 PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word Info;
	word ncci;

	dbug(1, dprintf("reset_b3_req"));

	Info = _WRONG_IDENTIFIER;
	ncci = (word)(Id >> 16);
	if (plci && ncci)
	{
		Info = _WRONG_STATE;
		switch (plci->B3_prot)
		{
		case B3_ISO8208:
		case B3_X25_DCE:
			if (a->ncci_state[ncci] == CONNECTED)
			{
				nl_req_ncci(plci, N_RESET, (byte)ncci);
				send_req(plci);
				Info = GOOD;
			}
			break;
		case B3_TRANSPARENT:
			if (a->ncci_state[ncci] == CONNECTED)
			{
				start_internal_command(Id, plci, reset_b3_command);
				Info = GOOD;
			}
			break;
		}
	}
	/* reset_b3 must result in a reset_b3_con & reset_b3_Ind */
	sendf(appl,
	      _RESET_B3_R | CONFIRM,
	      Id,
	      Number,
	      "w", Info);
	return false;
}

static byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			 PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word ncci;

	dbug(1, dprintf("reset_b3_res"));

	ncci = (word)(Id >> 16);
	if (plci && ncci) {
		switch (plci->B3_prot)
		{
		case B3_ISO8208:
		case B3_X25_DCE:
			if (a->ncci_state[ncci] == INC_RES_PENDING)
			{
				a->ncci_state[ncci] = CONNECTED;
				nl_req_ncci(plci, N_RESET_ACK, (byte)ncci);
				return true;
			}
			break;
		}
	}
	return false;
}

static byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
				 PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word ncci;
	API_PARSE *ncpi;
	byte req;

	dbug(1, dprintf("connect_b3_t90_a_res"));

	ncci = (word)(Id >> 16);
	if (plci && ncci) {
		if (a->ncci_state[ncci] == INC_ACT_PENDING) {
			a->ncci_state[ncci] = CONNECTED;
		}
		else if (a->ncci_state[ncci] == INC_CON_PENDING) {
			a->ncci_state[ncci] = CONNECTED;

			req = N_CONNECT_ACK;

			/* parms[0]==0 for CAPI original message definition! */
			if (parms[0].info) {
				ncpi = &parms[1];
				if (ncpi->length > 2) {
					if (ncpi->info[1] & 1) req = N_CONNECT_ACK | N_D_BIT;
					add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
				}
			}
			nl_req_ncci(plci, req, (byte)ncci);
			return 1;
		}
	}
	return false;
}


static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			 PLCI *plci, APPL *appl, API_PARSE *msg)
{
	word Info = 0;
	word i;
	byte tel;
	API_PARSE bp_parms[7];

	if (!plci || !msg)
	{
		Info = _WRONG_IDENTIFIER;
	}
	else
	{
		dbug(1, dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x",
				msg->length, plci->Id, plci->tel, plci->NL.Id, plci->appl, plci->SuppState));
		dbug(1, dprintf("PlciState=0x%x", plci->State));
		for (i = 0; i < 7; i++) bp_parms[i].length = 0;

		/* check if no channel is open, no B3 connected only */
		if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) || (plci->State == INC_DIS_PENDING)
		    || (plci->SuppState != IDLE) || plci->channels || plci->nl_remove_id)
		{
			Info = _WRONG_STATE;
		}
		/* check message format and fill bp_parms pointer */
		else if (msg->length && api_parse(&msg->info[1], (word)msg->length, "wwwsss", bp_parms))
		{
			Info = _WRONG_MESSAGE_FORMAT;
		}
		else
		{
			if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT)) /* send alert tone inband to the network, */
			{                                                                  /* e.g. Qsig or RBS or Cornet-N or xess PRI */
				if (Id & EXT_CONTROLLER)
				{
					sendf(appl, _SELECT_B_REQ | CONFIRM, Id, Number, "w", 0x2002); /* wrong controller */
					return 0;
				}
				plci->State = INC_CON_CONNECTED_ALERT;
				plci->appl = appl;
				clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
				dump_c_ind_mask(plci);
				for (i = 0; i < max_appl; i++) /* disconnect the other appls */
				{                         /* its quasi a connect        */
					if (test_c_ind_mask_bit(plci, i))
						sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
				}
			}

			api_save_msg(msg, "s", &plci->saved_msg);
			tel = plci->tel;
			if (Id & EXT_CONTROLLER)
			{
				if (tel) /* external controller in use by this PLCI */
				{
					if (a->AdvSignalAppl && a->AdvSignalAppl != appl)
					{
						dbug(1, dprintf("Ext_Ctrl in use 1"));
						Info = _WRONG_STATE;
					}
				}
				else  /* external controller NOT in use by this PLCI ? */
				{
					if (a->AdvSignalPLCI)
					{
						dbug(1, dprintf("Ext_Ctrl in use 2"));
						Info = _WRONG_STATE;
					}
					else /* activate the codec */
					{
						dbug(1, dprintf("Ext_Ctrl start"));
						if (AdvCodecSupport(a, plci, appl, 0))
						{
							dbug(1, dprintf("Error in codec procedures"));
							Info = _WRONG_STATE;
						}
						else if (plci->spoofed_msg == SPOOFING_REQUIRED) /* wait until codec is active */
						{
							plci->spoofed_msg = AWAITING_SELECT_B;
							plci->internal_command = BLOCK_PLCI; /* lock other commands */
							plci->command = 0;
							dbug(1, dprintf("continue if codec loaded"));
							return false;
						}
					}
				}
			}
			else /* external controller bit is OFF */
			{
				if (tel) /* external controller in use, need to switch off */
				{
					if (a->AdvSignalAppl == appl)
					{
						CodecIdCheck(a, plci);
						plci->tel = 0;
						plci->adv_nl = 0;
						dbug(1, dprintf("Ext_Ctrl disable"));
					}
					else
					{
						dbug(1, dprintf("Ext_Ctrl not requested"));
					}
				}
			}
			if (!Info)
			{
				if (plci->call_dir & CALL_DIR_OUT)
					plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
				else if (plci->call_dir & CALL_DIR_IN)
					plci->call_dir = CALL_DIR_IN | CALL_DIR_ANSWER;
				start_internal_command(Id, plci, select_b_command);
				return false;
			}
		}
	}
	sendf(appl, _SELECT_B_REQ | CONFIRM, Id, Number, "w", Info);
	return false;
}

static byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			     PLCI *plci, APPL *appl, API_PARSE *parms)
{
	word command;
	word i;
	word ncci;
	API_PARSE *m;
	API_PARSE m_parms[5];
	word codec;
	byte req;
	byte ch;
	byte dir;
	static byte chi[2] = {0x01, 0x00};
	static byte lli[2] = {0x01, 0x00};
	static byte codec_cai[2] = {0x01, 0x01};
	static byte null_msg = {0};
	static API_PARSE null_parms = { 0, &null_msg };
	PLCI *v_plci;
	word Info = 0;

	dbug(1, dprintf("manufacturer_req"));
	for (i = 0; i < 5; i++) m_parms[i].length = 0;

	if (GET_DWORD(parms[0].info) != _DI_MANU_ID) {
		Info = _WRONG_MESSAGE_FORMAT;
	}
	command = GET_WORD(parms[1].info);
	m = &parms[2];
	if (!Info)
	{
		switch (command) {
		case _DI_ASSIGN_PLCI:
			if (api_parse(&m->info[1], (word)m->length, "wbbs", m_parms)) {
				Info = _WRONG_MESSAGE_FORMAT;
				break;
			}
			codec = GET_WORD(m_parms[0].info);
			ch = m_parms[1].info[0];
			dir = m_parms[2].info[0];
			if ((i = get_plci(a))) {
				plci = &a->plci[i - 1];
				plci->appl = appl;
				plci->command = _MANUFACTURER_R;
				plci->m_command = command;
				plci->number = Number;
				plci->State = LOCAL_CONNECT;
				Id = (((word)plci->Id << 8) | plci->adapter->Id | 0x80);
				dbug(1, dprintf("ManCMD,plci=0x%x", Id));

				if ((ch == 1 || ch == 2) && (dir <= 2)) {
					chi[1] = (byte)(0x80 | ch);
					lli[1] = 0;
					plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
					switch (codec)
					{
					case 0:
						Info = add_b1(plci, &m_parms[3], 0, 0);
						break;
					case 1:
						add_p(plci, CAI, codec_cai);
						break;
						/* manual 'swich on' to the codec support without signalling */
						/* first 'assign plci' with this function, then use */
					case 2:
						if (AdvCodecSupport(a, plci, appl, 0)) {
							Info = _RESOURCE_ERROR;
						}
						else {
							Info = add_b1(plci, &null_parms, 0, B1_FACILITY_LOCAL);
							lli[1] = 0x10; /* local call codec stream */
						}
						break;
					}

					plci->State = LOCAL_CONNECT;
					plci->manufacturer = true;
					plci->command = _MANUFACTURER_R;
					plci->m_command = command;
					plci->number = Number;

					if (!Info)
					{
						add_p(plci, LLI, lli);
						add_p(plci, CHI, chi);
						add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
						sig_req(plci, ASSIGN, DSIG_ID);

						if (!codec)
						{
							Info = add_b23(plci, &m_parms[3]);
							if (!Info)
							{
								nl_req_ncci(plci, ASSIGN, 0);
								send_req(plci);
							}
						}
						if (!Info)
						{
							dbug(1, dprintf("dir=0x%x,spoof=0x%x", dir, plci->spoofed_msg));
							if (plci->spoofed_msg == SPOOFING_REQUIRED)
							{
								api_save_msg(m_parms, "wbbs", &plci->saved_msg);
								plci->spoofed_msg = AWAITING_MANUF_CON;
								plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
								plci->command = 0;
								send_req(plci);
								return false;
							}
							if (dir == 1) {
								sig_req(plci, CALL_REQ, 0);
							}
							else if (!dir) {
								sig_req(plci, LISTEN_REQ, 0);
							}
							send_req(plci);
						}
						else
						{
							sendf(appl,
							      _MANUFACTURER_R | CONFIRM,
							      Id,
							      Number,
							      "dww", _DI_MANU_ID, command, Info);
							return 2;
						}
					}
				}
			}
			else  Info = _OUT_OF_PLCI;
			break;

		case _DI_IDI_CTRL:
			if (!plci)
			{
				Info = _WRONG_IDENTIFIER;
				break;
			}
			if (api_parse(&m->info[1], (word)m->length, "bs", m_parms)) {
				Info = _WRONG_MESSAGE_FORMAT;
				break;
			}
			req = m_parms[0].info[0];
			plci->command = _MANUFACTURER_R;
			plci->m_command = command;
			plci->number = Number;
			if (req == CALL_REQ)
			{
				plci->b_channel = getChannel(&m_parms[1]);
				mixer_set_bchannel_id_esc(plci, plci->b_channel);
				if (plci->spoofed_msg == SPOOFING_REQUIRED)
				{
					plci->spoofed_msg = CALL_REQ | AWAITING_MANUF_CON;
					plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
					plci->command = 0;
					break;
				}
			}
			else if (req == LAW_REQ)
			{
				plci->cr_enquiry = true;
			}
			add_ss(plci, FTY, &m_parms[1]);
			sig_req(plci, req, 0);
			send_req(plci);
			if (req == HANGUP)
			{
				if (plci->NL.Id && !plci->nl_remove_id)
				{
					if (plci->channels)
					{
						for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
						{
							if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED))
							{
								a->ncci_state[ncci] = OUTG_DIS_PENDING;
								cleanup_ncci_data(plci, ncci);
								nl_req_ncci(plci, N_DISC, (byte)ncci);
							}
						}
					}
					mixer_remove(plci);
					nl_req_ncci(plci, REMOVE, 0);
					send_req(plci);
				}
			}
			break;

		case _DI_SIG_CTRL:
			/* signalling control for loop activation B-channel */
			if (!plci)
			{
				Info = _WRONG_IDENTIFIER;
				break;
			}
			if (m->length) {
				plci->command = _MANUFACTURER_R;
				plci->number = Number;
				add_ss(plci, FTY, m);
				sig_req(plci, SIG_CTRL, 0);
				send_req(plci);
			}
			else Info = _WRONG_MESSAGE_FORMAT;
			break;

		case _DI_RXT_CTRL:
			/* activation control for receiver/transmitter B-channel */
			if (!plci)
			{
				Info = _WRONG_IDENTIFIER;
				break;
			}
			if (m->length) {
				plci->command = _MANUFACTURER_R;
				plci->number = Number;
				add_ss(plci, FTY, m);
				sig_req(plci, DSP_CTRL, 0);
				send_req(plci);
			}
			else Info = _WRONG_MESSAGE_FORMAT;
			break;

		case _DI_ADV_CODEC:
		case _DI_DSP_CTRL:
			/* TEL_CTRL commands to support non standard adjustments: */
			/* Ring on/off, Handset micro volume, external micro vol. */
			/* handset+external speaker volume, receiver+transm. gain,*/
			/* handsfree on (hookinfo off), set mixer command         */

			if (command == _DI_ADV_CODEC)
			{
				if (!a->AdvCodecPLCI) {
					Info = _WRONG_STATE;
					break;
				}
				v_plci = a->AdvCodecPLCI;
			}
			else
			{
				if (plci
				    && (m->length >= 3)
				    && (m->info[1] == 0x1c)
				    && (m->info[2] >= 1))
				{
					if (m->info[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS)
					{
						if ((plci->tel != ADV_VOICE) || (plci != a->AdvSignalPLCI))
						{
							Info = _WRONG_STATE;
							break;
						}
						a->adv_voice_coef_length = m->info[2] - 1;
						if (a->adv_voice_coef_length > m->length - 3)
							a->adv_voice_coef_length = (byte)(m->length - 3);
						if (a->adv_voice_coef_length > ADV_VOICE_COEF_BUFFER_SIZE)
							a->adv_voice_coef_length = ADV_VOICE_COEF_BUFFER_SIZE;
						for (i = 0; i < a->adv_voice_coef_length; i++)
							a->adv_voice_coef_buffer[i] = m->info[4 + i];
						if (plci->B1_facilities & B1_FACILITY_VOICE)
							adv_voice_write_coefs(plci, ADV_VOICE_WRITE_UPDATE);
						break;
					}
					else if (m->info[3] == DSP_CTRL_SET_DTMF_PARAMETERS)
					{
						if (!(a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_PARAMETERS))
						{
							Info = _FACILITY_NOT_SUPPORTED;
							break;
						}

						plci->dtmf_parameter_length = m->info[2] - 1;
						if (plci->dtmf_parameter_length > m->length - 3)
							plci->dtmf_parameter_length = (byte)(m->length - 3);
						if (plci->dtmf_parameter_length > DTMF_PARAMETER_BUFFER_SIZE)
							plci->dtmf_parameter_length = DTMF_PARAMETER_BUFFER_SIZE;
						for (i = 0; i < plci->dtmf_parameter_length; i++)
							plci->dtmf_parameter_buffer[i] = m->info[4 + i];
						if (plci->B1_facilities & B1_FACILITY_DTMFR)
							dtmf_parameter_write(plci);
						break;

					}
				}
				v_plci = plci;
			}

			if (!v_plci)
			{
				Info = _WRONG_IDENTIFIER;
				break;
			}
			if (m->length) {
				add_ss(v_plci, FTY, m);
				sig_req(v_plci, TEL_CTRL, 0);
				send_req(v_plci);
			}
			else Info = _WRONG_MESSAGE_FORMAT;

			break;

		case _DI_OPTIONS_REQUEST:
			if (api_parse(&m->info[1], (word)m->length, "d", m_parms)) {
				Info = _WRONG_MESSAGE_FORMAT;
				break;
			}
			if (GET_DWORD(m_parms[0].info) & ~a->man_profile.private_options)
			{
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			a->requested_options_table[appl->Id - 1] = GET_DWORD(m_parms[0].info);
			break;



		default:
			Info = _WRONG_MESSAGE_FORMAT;
			break;
		}
	}

	sendf(appl,
	      _MANUFACTURER_R | CONFIRM,
	      Id,
	      Number,
	      "dww", _DI_MANU_ID, command, Info);
	return false;
}


static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
			     PLCI *plci, APPL *appl, API_PARSE *msg)
{
	word indication;

	API_PARSE m_parms[3];
	API_PARSE *ncpi;
	API_PARSE fax_parms[9];
	word i;
	byte len;


	dbug(1, dprintf("manufacturer_res"));

	if ((msg[0].length == 0)
	    || (msg[1].length == 0)
	    || (GET_DWORD(msg[0].info) != _DI_MANU_ID))
	{
		return false;
	}
	indication = GET_WORD(msg[1].info);
	switch (indication)
	{

	case _DI_NEGOTIATE_B3:
		if (!plci)
			break;
		if (((plci->B3_prot != 4) && (plci->B3_prot != 5))
		    || !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
		{
			dbug(1, dprintf("wrong state for NEGOTIATE_B3 parameters"));
			break;
		}
		if (api_parse(&msg[2].info[1], msg[2].length, "ws", m_parms))
		{
			dbug(1, dprintf("wrong format in NEGOTIATE_B3 parameters"));
			break;
		}
		ncpi = &m_parms[1];
		len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
		if (plci->fax_connect_info_length < len)
		{
			((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
			((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
		}
		if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
		{
			dbug(1, dprintf("non-standard facilities info missing or wrong format"));
		}
		else
		{
			if (plci->fax_connect_info_length <= len)
				plci->fax_connect_info_buffer[len] = 0;
			len += 1 + plci->fax_connect_info_buffer[len];
			if (plci->fax_connect_info_length <= len)
				plci->fax_connect_info_buffer[len] = 0;
			len += 1 + plci->fax_connect_info_buffer[len];
			if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
				plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
			plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
			for (i = 0; i < fax_parms[7].length; i++)
				plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
		}
		plci->fax_connect_info_length = len;
		plci->fax_edata_ack_length = plci->fax_connect_info_length;
		start_internal_command(Id, plci, fax_edata_ack_command);
		break;

	}
	return false;
}

/*------------------------------------------------------------------*/
/* IDI callback function                                            */
/*------------------------------------------------------------------*/

void callback(ENTITY *e)
{
	DIVA_CAPI_ADAPTER *a;
	APPL *appl;
	PLCI *plci;
	CAPI_MSG *m;
	word i, j;
	byte rc;
	byte ch;
	byte req;
	byte global_req;
	int no_cancel_rc;

	dbug(1, dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)",
			(e->user[0] + 1) & 0x7fff, e->Id, e->Req, e->Rc, e->Ind));

	a = &(adapter[(byte)e->user[0]]);
	plci = &(a->plci[e->user[1]]);
	no_cancel_rc = DIVA_CAPI_SUPPORTS_NO_CANCEL(a);

	/*
	  If new protocol code and new XDI is used then CAPI should work
	  fully in accordance with IDI cpec an look on callback field instead
	  of Rc field for return codes.
	*/
	if (((e->complete == 0xff) && no_cancel_rc) ||
	    (e->Rc && !no_cancel_rc)) {
		rc = e->Rc;
		ch = e->RcCh;
		req = e->Req;
		e->Rc = 0;

		if (e->user[0] & 0x8000)
		{
			/*
			  If REMOVE request was sent then we have to wait until
			  return code with Id set to zero arrives.
			  All other return codes should be ignored.
			*/
			if (req == REMOVE)
			{
				if (e->Id)
				{
					dbug(1, dprintf("cancel RC in REMOVE state"));
					return;
				}
				channel_flow_control_remove(plci);
				for (i = 0; i < 256; i++)
				{
					if (a->FlowControlIdTable[i] == plci->nl_remove_id)
						a->FlowControlIdTable[i] = 0;
				}
				plci->nl_remove_id = 0;
				if (plci->rx_dma_descriptor > 0) {
					diva_free_dma_descriptor(plci, plci->rx_dma_descriptor - 1);
					plci->rx_dma_descriptor = 0;
				}
			}
			if (rc == OK_FC)
			{
				a->FlowControlIdTable[ch] = e->Id;
				a->FlowControlSkipTable[ch] = 0;

				a->ch_flow_control[ch] |= N_OK_FC_PENDING;
				a->ch_flow_plci[ch] = plci->Id;
				plci->nl_req = 0;
			}
			else
			{
				/*
				  Cancel return codes self, if feature was requested
				*/
				if (no_cancel_rc && (a->FlowControlIdTable[ch] == e->Id) && e->Id) {
					a->FlowControlIdTable[ch] = 0;
					if ((rc == OK) && a->FlowControlSkipTable[ch]) {
						dbug(3, dprintf("XDI CAPI: RC cancelled Id:0x02, Ch:%02x", e->Id, ch));
						return;
					}
				}

				if (a->ch_flow_control[ch] & N_OK_FC_PENDING)
				{
					a->ch_flow_control[ch] &= ~N_OK_FC_PENDING;
					if (ch == e->ReqCh)
						plci->nl_req = 0;
				}
				else
					plci->nl_req = 0;
			}
			if (plci->nl_req)
				control_rc(plci, 0, rc, ch, 0, true);
			else
			{
				if (req == N_XON)
				{
					channel_x_on(plci, ch);
					if (plci->internal_command)
						control_rc(plci, req, rc, ch, 0, true);
				}
				else
				{
					if (plci->nl_global_req)
					{
						global_req = plci->nl_global_req;
						plci->nl_global_req = 0;
						if (rc != ASSIGN_OK) {
							e->Id = 0;
							if (plci->rx_dma_descriptor > 0) {
								diva_free_dma_descriptor(plci, plci->rx_dma_descriptor - 1);
								plci->rx_dma_descriptor = 0;
							}
						}
						channel_xmit_xon(plci);
						control_rc(plci, 0, rc, ch, global_req, true);
					}
					else if (plci->data_sent)
					{
						channel_xmit_xon(plci);
						plci->data_sent = false;
						plci->NL.XNum = 1;
						data_rc(plci, ch);
						if (plci->internal_command)
							control_rc(plci, req, rc, ch, 0, true);
					}
					else
					{
						channel_xmit_xon(plci);
						control_rc(plci, req, rc, ch, 0, true);
					}
				}
			}
		}
		else
		{
			/*
			  If REMOVE request was sent then we have to wait until
			  return code with Id set to zero arrives.
			  All other return codes should be ignored.
			*/
			if (req == REMOVE)
			{
				if (e->Id)
				{
					dbug(1, dprintf("cancel RC in REMOVE state"));
					return;
				}
				plci->sig_remove_id = 0;
			}
			plci->sig_req = 0;
			if (plci->sig_global_req)
			{
				global_req = plci->sig_global_req;
				plci->sig_global_req = 0;
				if (rc != ASSIGN_OK)
					e->Id = 0;
				channel_xmit_xon(plci);
				control_rc(plci, 0, rc, ch, global_req, false);
			}
			else
			{
				channel_xmit_xon(plci);
				control_rc(plci, req, rc, ch, 0, false);
			}
		}
		/*
		  Again: in accordance with IDI spec Rc and Ind can't be delivered in the
		  same callback. Also if new XDI and protocol code used then jump
		  direct to finish.
		*/
		if (no_cancel_rc) {
			channel_xmit_xon(plci);
			goto capi_callback_suffix;
		}
	}

	channel_xmit_xon(plci);

	if (e->Ind) {
		if (e->user[0] & 0x8000) {
			byte Ind = e->Ind & 0x0f;
			byte Ch = e->IndCh;
			if (((Ind == N_DISC) || (Ind == N_DISC_ACK)) &&
			    (a->ch_flow_plci[Ch] == plci->Id)) {
				if (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK) {
					dbug(3, dprintf("XDI CAPI: I: pending N-XON Ch:%02x", Ch));
				}
				a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
			}
			nl_ind(plci);
			if ((e->RNR != 1) &&
			    (a->ch_flow_plci[Ch] == plci->Id) &&
			    (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK)) {
				a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
				dbug(3, dprintf("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch));
			}
		} else {
			sig_ind(plci);
		}
		e->Ind = 0;
	}

capi_callback_suffix:

	while (!plci->req_in
	       && !plci->internal_command
	       && (plci->msg_in_write_pos != plci->msg_in_read_pos))
	{
		j = (plci->msg_in_read_pos == plci->msg_in_wrap_pos) ? 0 : plci->msg_in_read_pos;

		i = (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]))->header.length + 3) & 0xfffc;

		m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]);
		appl = *((APPL **)(&((byte *)(plci->msg_in_queue))[j + i]));
		dbug(1, dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d",
				m->header.command, plci->msg_in_write_pos, plci->msg_in_read_pos, plci->msg_in_wrap_pos));
		if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
		{
			plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
			plci->msg_in_read_pos = i + MSG_IN_OVERHEAD;
		}
		else
		{
			plci->msg_in_read_pos = j + i + MSG_IN_OVERHEAD;
		}
		if (plci->msg_in_read_pos == plci->msg_in_write_pos)
		{
			plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
			plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
		}
		else if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
		{
			plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
			plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
		}
		i = api_put(appl, m);
		if (i != 0)
		{
			if (m->header.command == _DATA_B3_R)

				TransmitBufferFree(appl, (byte *)(long)(m->info.data_b3_req.Data));

			dbug(1, dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command));
			break;
		}

		if (plci->li_notify_update)
		{
			plci->li_notify_update = false;
			mixer_notify_update(plci, false);
		}

	}
	send_data(plci);
	send_req(plci);
}


static void control_rc(PLCI *plci, byte req, byte rc, byte ch, byte global_req,
		       byte nl_rc)
{
	dword Id;
	dword rId;
	word Number;
	word Info = 0;
	word i;
	word ncci;
	DIVA_CAPI_ADAPTER *a;
	APPL *appl;
	PLCI *rplci;
	byte SSparms[] = "\x05\x00\x00\x02\x00\x00";
	byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";

	if (!plci) {
		dbug(0, dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc));
		return;
	}
	dbug(1, dprintf("req0_in/out=%d/%d", plci->req_in, plci->req_out));
	if (plci->req_in != plci->req_out)
	{
		if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK))
		{
			dbug(1, dprintf("req_1return"));
			return;
		}
		/* cancel outstanding request on the PLCI after SIG ASSIGN failure */
	}
	plci->req_in = plci->req_in_start = plci->req_out = 0;
	dbug(1, dprintf("control_rc"));

	appl = plci->appl;
	a = plci->adapter;
	ncci = a->ch_ncci[ch];
	if (appl)
	{
		Id = (((dword)(ncci ? ncci : ch)) << 16) | ((word)plci->Id << 8) | a->Id;
		if (plci->tel && plci->SuppState != CALL_HELD) Id |= EXT_CONTROLLER;
		Number = plci->number;
		dbug(1, dprintf("Contr_RC-Id=%08lx,plci=%x,tel=%x, entity=0x%x, command=0x%x, int_command=0x%x", Id, plci->Id, plci->tel, plci->Sig.Id, plci->command, plci->internal_command));
		dbug(1, dprintf("channels=0x%x", plci->channels));
		if (plci_remove_check(plci))
			return;
		if (req == REMOVE && rc == ASSIGN_OK)
		{
			sig_req(plci, HANGUP, 0);
			sig_req(plci, REMOVE, 0);
			send_req(plci);
		}
		if (plci->command)
		{
			switch (plci->command)
			{
			case C_HOLD_REQ:
				dbug(1, dprintf("HoldRC=0x%x", rc));
				SSparms[1] = (byte)S_HOLD;
				if (rc != OK)
				{
					plci->SuppState = IDLE;
					Info = 0x2001;
				}
				sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", Info, 3, SSparms);
				break;

			case C_RETRIEVE_REQ:
				dbug(1, dprintf("RetrieveRC=0x%x", rc));
				SSparms[1] = (byte)S_RETRIEVE;
				if (rc != OK)
				{
					plci->SuppState = CALL_HELD;
					Info = 0x2001;
				}
				sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", Info, 3, SSparms);
				break;

			case _INFO_R:
				dbug(1, dprintf("InfoRC=0x%x", rc));
				if (rc != OK) Info = _WRONG_STATE;
				sendf(appl, _INFO_R | CONFIRM, Id, Number, "w", Info);
				break;

			case _CONNECT_R:
				dbug(1, dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x", req, rc, global_req, nl_rc));
				if (plci->State == INC_DIS_PENDING)
					break;
				if (plci->Sig.Id != 0xff)
				{
					if (((global_req == ASSIGN) && (rc != ASSIGN_OK))
					    || (!nl_rc && (req == CALL_REQ) && (rc != OK)))
					{
						dbug(1, dprintf("No more IDs/Call_Req failed"));
						sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
						plci_remove(plci);
						plci->State = IDLE;
						break;
					}
					if (plci->State != LOCAL_CONNECT) plci->State = OUTG_CON_PENDING;
					sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
				}
				else /* D-ch activation */
				{
					if (rc != ASSIGN_OK)
					{
						dbug(1, dprintf("No more IDs/X.25 Call_Req failed"));
						sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
						plci_remove(plci);
						plci->State = IDLE;
						break;
					}
					sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
					sendf(plci->appl, _CONNECT_ACTIVE_I, Id, 0, "sss", "", "", "");
					plci->State = INC_ACT_PENDING;
				}
				break;

			case _CONNECT_I | RESPONSE:
				if (plci->State != INC_DIS_PENDING)
					plci->State = INC_CON_ACCEPT;
				break;

			case _DISCONNECT_R:
				if (plci->State == INC_DIS_PENDING)
					break;
				if (plci->Sig.Id != 0xff)
				{
					plci->State = OUTG_DIS_PENDING;
					sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", 0);
				}
				break;

			case SUSPEND_REQ:
				break;

			case RESUME_REQ:
				break;

			case _CONNECT_B3_R:
				if (rc != OK)
				{
					sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER);
					break;
				}
				ncci = get_ncci(plci, ch, 0);
				Id = (Id & 0xffff) | (((dword) ncci) << 16);
				plci->channels++;
				if (req == N_RESET)
				{
					a->ncci_state[ncci] = INC_ACT_PENDING;
					sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
					sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
				}
				else
				{
					a->ncci_state[ncci] = OUTG_CON_PENDING;
					sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
				}
				break;

			case _CONNECT_B3_I | RESPONSE:
				break;

			case _RESET_B3_R:
/*        sendf(appl, _RESET_B3_R | CONFIRM, Id, Number, "w", 0);*/
				break;

			case _DISCONNECT_B3_R:
				sendf(appl, _DISCONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
				break;

			case _MANUFACTURER_R:
				break;

			case PERM_LIST_REQ:
				if (rc != OK)
				{
					Info = _WRONG_IDENTIFIER;
					sendf(plci->appl, _CONNECT_R | CONFIRM, Id, Number, "w", Info);
					plci_remove(plci);
				}
				else
					sendf(plci->appl, _CONNECT_R | CONFIRM, Id, Number, "w", Info);
				break;

			default:
				break;
			}
			plci->command = 0;
		}
		else if (plci->internal_command)
		{
			switch (plci->internal_command)
			{
			case BLOCK_PLCI:
				return;

			case GET_MWI_STATE:
				if (rc == OK) /* command supported, wait for indication */
				{
					return;
				}
				plci_remove(plci);
				break;

				/* Get Supported Services */
			case GETSERV_REQ_PEND:
				if (rc == OK) /* command supported, wait for indication */
				{
					break;
				}
				PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
				sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", 0, 3, SSstruct);
				plci_remove(plci);
				break;

			case INTERR_DIVERSION_REQ_PEND:      /* Interrogate Parameters        */
			case INTERR_NUMBERS_REQ_PEND:
			case CF_START_PEND:                  /* Call Forwarding Start pending */
			case CF_STOP_PEND:                   /* Call Forwarding Stop pending  */
			case CCBS_REQUEST_REQ_PEND:
			case CCBS_DEACTIVATE_REQ_PEND:
			case CCBS_INTERROGATE_REQ_PEND:
				switch (plci->internal_command)
				{
				case INTERR_DIVERSION_REQ_PEND:
					SSparms[1] = S_INTERROGATE_DIVERSION;
					break;
				case INTERR_NUMBERS_REQ_PEND:
					SSparms[1] = S_INTERROGATE_NUMBERS;
					break;
				case CF_START_PEND:
					SSparms[1] = S_CALL_FORWARDING_START;
					break;
				case CF_STOP_PEND:
					SSparms[1] = S_CALL_FORWARDING_STOP;
					break;
				case CCBS_REQUEST_REQ_PEND:
					SSparms[1] = S_CCBS_REQUEST;
					break;
				case CCBS_DEACTIVATE_REQ_PEND:
					SSparms[1] = S_CCBS_DEACTIVATE;
					break;
				case CCBS_INTERROGATE_REQ_PEND:
					SSparms[1] = S_CCBS_INTERROGATE;
					break;
				}
				if (global_req == ASSIGN)
				{
					dbug(1, dprintf("AssignDiversion_RC=0x%x/0x%x", req, rc));
					return;
				}
				if (!plci->appl) break;
				if (rc == ISDN_GUARD_REJ)
				{
					Info = _CAPI_GUARD_ERROR;
				}
				else if (rc != OK)
				{
					Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED;
				}
				sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0x7,
				      plci->number, "wws", Info, (word)3, SSparms);
				if (Info) plci_remove(plci);
				break;

				/* 3pty conference pending */
			case PTY_REQ_PEND:
				if (!plci->relatedPTYPLCI) break;
				rplci = plci->relatedPTYPLCI;
				SSparms[1] = plci->ptyState;
				rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
				if (rplci->tel) rId |= EXT_CONTROLLER;
				if (rc != OK)
				{
					Info = 0x300E; /* not supported */
					plci->relatedPTYPLCI = NULL;
					plci->ptyState = 0;
				}
				sendf(rplci->appl,
				      _FACILITY_R | CONFIRM,
				      rId,
				      plci->number,
				      "wws", Info, (word)3, SSparms);
				break;

				/* Explicit Call Transfer pending */
			case ECT_REQ_PEND:
				dbug(1, dprintf("ECT_RC=0x%x/0x%x", req, rc));
				if (!plci->relatedPTYPLCI) break;
				rplci = plci->relatedPTYPLCI;
				SSparms[1] = S_ECT;
				rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
				if (rplci->tel) rId |= EXT_CONTROLLER;
				if (rc != OK)
				{
					Info = 0x300E; /* not supported */
					plci->relatedPTYPLCI = NULL;
					plci->ptyState = 0;
				}
				sendf(rplci->appl,
				      _FACILITY_R | CONFIRM,
				      rId,
				      plci->number,
				      "wws", Info, (word)3, SSparms);
				break;

			case _MANUFACTURER_R:
				dbug(1, dprintf("_Manufacturer_R=0x%x/0x%x", req, rc));
				if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
				{
					dbug(1, dprintf("No more IDs"));
					sendf(appl, _MANUFACTURER_R | CONFIRM, Id, Number, "dww", _DI_MANU_ID, _MANUFACTURER_R, _OUT_OF_PLCI);
					plci_remove(plci);  /* after codec init, internal codec commands pending */
				}
				break;

			case _CONNECT_R:
				dbug(1, dprintf("_Connect_R=0x%x/0x%x", req, rc));
				if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
				{
					dbug(1, dprintf("No more IDs"));
					sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
					plci_remove(plci);  /* after codec init, internal codec commands pending */
				}
				break;

			case PERM_COD_HOOK:                     /* finished with Hook_Ind */
				return;

			case PERM_COD_CALL:
				dbug(1, dprintf("***Codec Connect_Pending A, Rc = 0x%x", rc));
				plci->internal_command = PERM_COD_CONN_PEND;
				return;

			case PERM_COD_ASSIGN:
				dbug(1, dprintf("***Codec Assign A, Rc = 0x%x", rc));
				if (rc != ASSIGN_OK) break;
				sig_req(plci, CALL_REQ, 0);
				send_req(plci);
				plci->internal_command = PERM_COD_CALL;
				return;

				/* Null Call Reference Request pending */
			case C_NCR_FAC_REQ:
				dbug(1, dprintf("NCR_FAC=0x%x/0x%x", req, rc));
				if (global_req == ASSIGN)
				{
					if (rc == ASSIGN_OK)
					{
						return;
					}
					else
					{
						sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", _WRONG_STATE);
						appl->NullCREnable = false;
						plci_remove(plci);
					}
				}
				else if (req == NCR_FACILITY)
				{
					if (rc == OK)
					{
						sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", 0);
					}
					else
					{
						sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", _WRONG_STATE);
						appl->NullCREnable = false;
					}
					plci_remove(plci);
				}
				break;

			case HOOK_ON_REQ:
				if (plci->channels)
				{
					if (a->ncci_state[ncci] == CONNECTED)
					{
						a->ncci_state[ncci] = OUTG_DIS_PENDING;
						cleanup_ncci_data(plci, ncci);
						nl_req_ncci(plci, N_DISC, (byte)ncci);
					}
					break;
				}
				break;

			case HOOK_OFF_REQ:
				if (plci->State == INC_DIS_PENDING)
					break;
				sig_req(plci, CALL_REQ, 0);
				send_req(plci);
				plci->State = OUTG_CON_PENDING;
				break;


			case MWI_ACTIVATE_REQ_PEND:
			case MWI_DEACTIVATE_REQ_PEND:
				if (global_req == ASSIGN && rc == ASSIGN_OK)
				{
					dbug(1, dprintf("MWI_REQ assigned"));
					return;
				}
				else if (rc != OK)
				{
					if (rc == WRONG_IE)
					{
						Info = 0x2007; /* Illegal message parameter coding */
						dbug(1, dprintf("MWI_REQ invalid parameter"));
					}
					else
					{
						Info = 0x300B; /* not supported */
						dbug(1, dprintf("MWI_REQ not supported"));
					}
					/* 0x3010: Request not allowed in this state */
					PUT_WORD(&SSparms[4], 0x300E); /* SS not supported */

				}
				if (plci->internal_command == MWI_ACTIVATE_REQ_PEND)
				{
					PUT_WORD(&SSparms[1], S_MWI_ACTIVATE);
				}
				else PUT_WORD(&SSparms[1], S_MWI_DEACTIVATE);

				if (plci->cr_enquiry)
				{
					sendf(plci->appl,
					      _FACILITY_R | CONFIRM,
					      Id & 0xf,
					      plci->number,
					      "wws", Info, (word)3, SSparms);
					if (rc != OK) plci_remove(plci);
				}
				else
				{
					sendf(plci->appl,
					      _FACILITY_R | CONFIRM,
					      Id,
					      plci->number,
					      "wws", Info, (word)3, SSparms);
				}
				break;

			case CONF_BEGIN_REQ_PEND:
			case CONF_ADD_REQ_PEND:
			case CONF_SPLIT_REQ_PEND:
			case CONF_DROP_REQ_PEND:
			case CONF_ISOLATE_REQ_PEND:
			case CONF_REATTACH_REQ_PEND:
				dbug(1, dprintf("CONF_RC=0x%x/0x%x", req, rc));
				if ((plci->internal_command == CONF_ADD_REQ_PEND) && (!plci->relatedPTYPLCI)) break;
				rplci = plci;
				rId = Id;
				switch (plci->internal_command)
				{
				case CONF_BEGIN_REQ_PEND:
					SSparms[1] = S_CONF_BEGIN;
					break;
				case CONF_ADD_REQ_PEND:
					SSparms[1] = S_CONF_ADD;
					rplci = plci->relatedPTYPLCI;
					rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
					break;
				case CONF_SPLIT_REQ_PEND:
					SSparms[1] = S_CONF_SPLIT;
					break;
				case CONF_DROP_REQ_PEND:
					SSparms[1] = S_CONF_DROP;
					break;
				case CONF_ISOLATE_REQ_PEND:
					SSparms[1] = S_CONF_ISOLATE;
					break;
				case CONF_REATTACH_REQ_PEND:
					SSparms[1] = S_CONF_REATTACH;
					break;
				}

				if (rc != OK)
				{
					Info = 0x300E; /* not supported */
					plci->relatedPTYPLCI = NULL;
					plci->ptyState = 0;
				}
				sendf(rplci->appl,
				      _FACILITY_R | CONFIRM,
				      rId,
				      plci->number,
				      "wws", Info, (word)3, SSparms);
				break;

			case VSWITCH_REQ_PEND:
				if (rc != OK)
				{
					if (plci->relatedPTYPLCI)
					{
						plci->relatedPTYPLCI->vswitchstate = 0;
						plci->relatedPTYPLCI->vsprot = 0;
						plci->relatedPTYPLCI->vsprotdialect = 0;
					}
					plci->vswitchstate = 0;
					plci->vsprot = 0;
					plci->vsprotdialect = 0;
				}
				else
				{
					if (plci->relatedPTYPLCI &&
					    plci->vswitchstate == 1 &&
					    plci->relatedPTYPLCI->vswitchstate == 3) /* join complete */
						plci->vswitchstate = 3;
				}
				break;

				/* Call Deflection Request pending (SSCT) */
			case CD_REQ_PEND:
				SSparms[1] = S_CALL_DEFLECTION;
				if (rc != OK)
				{
					Info = 0x300E; /* not supported */
					plci->appl->CDEnable = 0;
				}
				sendf(plci->appl, _FACILITY_R | CONFIRM, Id,
				      plci->number, "wws", Info, (word)3, SSparms);
				break;

			case RTP_CONNECT_B3_REQ_COMMAND_2:
				if (rc == OK)
				{
					ncci = get_ncci(plci, ch, 0);
					Id = (Id & 0xffff) | (((dword) ncci) << 16);
					plci->channels++;
					a->ncci_state[ncci] = OUTG_CON_PENDING;
				}

			default:
				if (plci->internal_command_queue[0])
				{
					(*(plci->internal_command_queue[0]))(Id, plci, rc);
					if (plci->internal_command)
						return;
				}
				break;
			}
			next_internal_command(Id, plci);
		}
	}
	else /* appl==0 */
	{
		Id = ((word)plci->Id << 8) | plci->adapter->Id;
		if (plci->tel) Id |= EXT_CONTROLLER;

		switch (plci->internal_command)
		{
		case BLOCK_PLCI:
			return;

		case START_L1_SIG_ASSIGN_PEND:
		case REM_L1_SIG_ASSIGN_PEND:
			if (global_req == ASSIGN)
			{
				break;
			}
			else
			{
				dbug(1, dprintf("***L1 Req rem PLCI"));
				plci->internal_command = 0;
				sig_req(plci, REMOVE, 0);
				send_req(plci);
			}
			break;

			/* Call Deflection Request pending, just no appl ptr assigned */
		case CD_REQ_PEND:
			SSparms[1] = S_CALL_DEFLECTION;
			if (rc != OK)
			{
				Info = 0x300E; /* not supported */
			}
			for (i = 0; i < max_appl; i++)
			{
				if (application[i].CDEnable)
				{
					if (!application[i].Id) application[i].CDEnable = 0;
					else
					{
						sendf(&application[i], _FACILITY_R | CONFIRM, Id,
						      plci->number, "wws", Info, (word)3, SSparms);
						if (Info) application[i].CDEnable = 0;
					}
				}
			}
			plci->internal_command = 0;
			break;

		case PERM_COD_HOOK:                   /* finished with Hook_Ind */
			return;

		case PERM_COD_CALL:
			plci->internal_command = PERM_COD_CONN_PEND;
			dbug(1, dprintf("***Codec Connect_Pending, Rc = 0x%x", rc));
			return;

		case PERM_COD_ASSIGN:
			dbug(1, dprintf("***Codec Assign, Rc = 0x%x", rc));
			plci->internal_command = 0;
			if (rc != ASSIGN_OK) break;
			plci->internal_command = PERM_COD_CALL;
			sig_req(plci, CALL_REQ, 0);
			send_req(plci);
			return;

		case LISTEN_SIG_ASSIGN_PEND:
			if (rc == ASSIGN_OK)
			{
				plci->internal_command = 0;
				dbug(1, dprintf("ListenCheck, new SIG_ID = 0x%x", plci->Sig.Id));
				add_p(plci, ESC, "\x02\x18\x00");             /* support call waiting */
				sig_req(plci, INDICATE_REQ, 0);
				send_req(plci);
			}
			else
			{
				dbug(1, dprintf("ListenCheck failed (assignRc=0x%x)", rc));
				a->listen_active--;
				plci_remove(plci);
				plci->State = IDLE;
			}
			break;

		case USELAW_REQ:
			if (global_req == ASSIGN)
			{
				if (rc == ASSIGN_OK)
				{
					sig_req(plci, LAW_REQ, 0);
					send_req(plci);
					dbug(1, dprintf("Auto-Law assigned"));
				}
				else
				{
					dbug(1, dprintf("Auto-Law assign failed"));
					a->automatic_law = 3;
					plci->internal_command = 0;
					a->automatic_lawPLCI = NULL;
				}
				break;
			}
			else if (req == LAW_REQ && rc == OK)
			{
				dbug(1, dprintf("Auto-Law initiated"));
				a->automatic_law = 2;
				plci->internal_command = 0;
			}
			else
			{
				dbug(1, dprintf("Auto-Law not supported"));
				a->automatic_law = 3;
				plci->internal_command = 0;
				sig_req(plci, REMOVE, 0);
				send_req(plci);
				a->automatic_lawPLCI = NULL;
			}
			break;
		}
		plci_remove_check(plci);
	}
}

static void data_rc(PLCI *plci, byte ch)
{
	dword Id;
	DIVA_CAPI_ADAPTER *a;
	NCCI *ncci_ptr;
	DATA_B3_DESC *data;
	word ncci;

	if (plci->appl)
	{
		TransmitBufferFree(plci->appl, plci->data_sent_ptr);
		a = plci->adapter;
		ncci = a->ch_ncci[ch];
		if (ncci && (a->ncci_plci[ncci] == plci->Id))
		{
			ncci_ptr = &(a->ncci[ncci]);
			dbug(1, dprintf("data_out=%d, data_pending=%d", ncci_ptr->data_out, ncci_ptr->data_pending));
			if (ncci_ptr->data_pending)
			{
				data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
				if (!(data->Flags & 4) && a->ncci_state[ncci])
				{
					Id = (((dword)ncci) << 16) | ((word)plci->Id << 8) | a->Id;
					if (plci->tel) Id |= EXT_CONTROLLER;
					sendf(plci->appl, _DATA_B3_R | CONFIRM, Id, data->Number,
					      "ww", data->Handle, 0);
				}
				(ncci_ptr->data_out)++;
				if (ncci_ptr->data_out == MAX_DATA_B3)
					ncci_ptr->data_out = 0;
				(ncci_ptr->data_pending)--;
			}
		}
	}
}

static void data_ack(PLCI *plci, byte ch)
{
	dword Id;
	DIVA_CAPI_ADAPTER *a;
	NCCI *ncci_ptr;
	word ncci;

	a = plci->adapter;
	ncci = a->ch_ncci[ch];
	ncci_ptr = &(a->ncci[ncci]);
	if (ncci_ptr->data_ack_pending)
	{
		if (a->ncci_state[ncci] && (a->ncci_plci[ncci] == plci->Id))
		{
			Id = (((dword)ncci) << 16) | ((word)plci->Id << 8) | a->Id;
			if (plci->tel) Id |= EXT_CONTROLLER;
			sendf(plci->appl, _DATA_B3_R | CONFIRM, Id, ncci_ptr->DataAck[ncci_ptr->data_ack_out].Number,
			      "ww", ncci_ptr->DataAck[ncci_ptr->data_ack_out].Handle, 0);
		}
		(ncci_ptr->data_ack_out)++;
		if (ncci_ptr->data_ack_out == MAX_DATA_ACK)
			ncci_ptr->data_ack_out = 0;
		(ncci_ptr->data_ack_pending)--;
	}
}

static void sig_ind(PLCI *plci)
{
	dword x_Id;
	dword Id;
	dword rId;
	word i;
	word cip;
	dword cip_mask;
	byte *ie;
	DIVA_CAPI_ADAPTER *a;
	API_PARSE saved_parms[MAX_MSG_PARMS + 1];
#define MAXPARMSIDS 31
	byte *parms[MAXPARMSIDS];
	byte *add_i[4];
	byte *multi_fac_parms[MAX_MULTI_IE];
	byte *multi_pi_parms[MAX_MULTI_IE];
	byte *multi_ssext_parms[MAX_MULTI_IE];
	byte *multi_CiPN_parms[MAX_MULTI_IE];

	byte *multi_vswitch_parms[MAX_MULTI_IE];

	byte ai_len;
	byte *esc_chi = "";
	byte *esc_law = "";
	byte *pty_cai = "";
	byte *esc_cr  = "";
	byte *esc_profile = "";

	byte facility[256];
	PLCI *tplci = NULL;
	byte chi[] = "\x02\x18\x01";
	byte voice_cai[]  = "\x06\x14\x00\x00\x00\x00\x08";
	byte resume_cau[] = "\x05\x05\x00\x02\x00\x00";
	/* ESC_MSGTYPE must be the last but one message, a new IE has to be */
	/* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */
	/* SMSG is situated at the end because its 0 (for compatibility reasons */
	/* (see Info_Mask Bit 4, first IE. then the message type)           */
	word parms_id[] =
		{MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA,
		 UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW,
		 RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR,
		 CST, ESC_PROFILE, 0xff, ESC_MSGTYPE, SMSG};
	/* 14 FTY repl by ESC_CHI */
	/* 18 PI  repl by ESC_LAW */
	/* removed OAD changed to 0xff for future use, OAD is multiIE now */
	word multi_fac_id[] = {1, FTY};
	word multi_pi_id[]  = {1, PI};
	word multi_CiPN_id[]  = {1, OAD};
	word multi_ssext_id[]  = {1, ESC_SSEXT};

	word multi_vswitch_id[]  = {1, ESC_VSWITCH};

	byte *cau;
	word ncci;
	byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
	byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
	byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
	byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00";
	byte force_mt_info = false;
	byte dir;
	dword d;
	word w;

	a = plci->adapter;
	Id = ((word)plci->Id << 8) | a->Id;
	PUT_WORD(&SS_Ind[4], 0x0000);

	if (plci->sig_remove_id)
	{
		plci->Sig.RNR = 2; /* discard */
		dbug(1, dprintf("SIG discard while remove pending"));
		return;
	}
	if (plci->tel && plci->SuppState != CALL_HELD) Id |= EXT_CONTROLLER;
	dbug(1, dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d",
			Id, plci->Id, plci->tel, plci->State, plci->channels, plci->hangup_flow_ctrl_timer));
	if (plci->Sig.Ind == CALL_HOLD_ACK && plci->channels)
	{
		plci->Sig.RNR = 1;
		return;
	}
	if (plci->Sig.Ind == HANGUP && plci->channels)
	{
		plci->Sig.RNR = 1;
		plci->hangup_flow_ctrl_timer++;
		/* recover the network layer after timeout */
		if (plci->hangup_flow_ctrl_timer == 100)
		{
			dbug(1, dprintf("Exceptional disc"));
			plci->Sig.RNR = 0;
			plci->hangup_flow_ctrl_timer = 0;
			for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
			{
				if (a->ncci_plci[ncci] == plci->Id)
				{
					cleanup_ncci_data(plci, ncci);
					if (plci->channels)plci->channels--;
					if (plci->appl)
						sendf(plci->appl, _DISCONNECT_B3_I, (((dword) ncci) << 16) | Id, 0, "ws", 0, "");
				}
			}
			if (plci->appl)
				sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
			plci_remove(plci);
			plci->State = IDLE;
		}
		return;
	}

	/* do first parse the info with no OAD in, because OAD will be converted */
	/* first the multiple facility IE, then mult. progress ind.              */
	/* then the parameters for the info_ind + conn_ind                       */
	IndParse(plci, multi_fac_id, multi_fac_parms, MAX_MULTI_IE);
	IndParse(plci, multi_pi_id, multi_pi_parms, MAX_MULTI_IE);
	IndParse(plci, multi_ssext_id, multi_ssext_parms, MAX_MULTI_IE);

	IndParse(plci, multi_vswitch_id, multi_vswitch_parms, MAX_MULTI_IE);

	IndParse(plci, parms_id, parms, 0);
	IndParse(plci, multi_CiPN_id, multi_CiPN_parms, MAX_MULTI_IE);
	esc_chi  = parms[14];
	esc_law  = parms[18];
	pty_cai  = parms[24];
	esc_cr   = parms[25];
	esc_profile = parms[27];
	if (esc_cr[0] && plci)
	{
		if (plci->cr_enquiry && plci->appl)
		{
			plci->cr_enquiry = false;
			/* d = MANU_ID            */
			/* w = m_command          */
			/* b = total length       */
			/* b = indication type    */
			/* b = length of all IEs  */
			/* b = IE1                */
			/* S = IE1 length + cont. */
			/* b = IE2                */
			/* S = IE2 length + cont. */
			sendf(plci->appl,
			      _MANUFACTURER_I,
			      Id,
			      0,
			      "dwbbbbSbS", _DI_MANU_ID, plci->m_command,
			      2 + 1 + 1 + esc_cr[0] + 1 + 1 + esc_law[0], plci->Sig.Ind, 1 + 1 + esc_cr[0] + 1 + 1 + esc_law[0], ESC, esc_cr, ESC, esc_law);
		}
	}
	/* create the additional info structure                                  */
	add_i[1] = parms[15]; /* KEY of additional info */
	add_i[2] = parms[11]; /* UUI of additional info */
	ai_len = AddInfo(add_i, multi_fac_parms, esc_chi, facility);

	/* the ESC_LAW indicates if u-Law or a-Law is actually used by the card  */
	/* indication returns by the card if requested by the function           */
	/* AutomaticLaw() after driver init                                      */
	if (a->automatic_law < 4)
	{
		if (esc_law[0]) {
			if (esc_law[2]) {
				dbug(0, dprintf("u-Law selected"));
				a->u_law = 1;
			}
			else {
				dbug(0, dprintf("a-Law selected"));
				a->u_law = 0;
			}
			a->automatic_law = 4;
			if (plci == a->automatic_lawPLCI) {
				plci->internal_command = 0;
				sig_req(plci, REMOVE, 0);
				send_req(plci);
				a->automatic_lawPLCI = NULL;
			}
		}
		if (esc_profile[0])
		{
			dbug(1, dprintf("[%06x] CardProfile: %lx %lx %lx %lx %lx",
					UnMapController(a->Id), GET_DWORD(&esc_profile[6]),
					GET_DWORD(&esc_profile[10]), GET_DWORD(&esc_profile[14]),
					GET_DWORD(&esc_profile[18]), GET_DWORD(&esc_profile[46])));

			a->profile.Global_Options &= 0x000000ffL;
			a->profile.B1_Protocols &= 0x000003ffL;
			a->profile.B2_Protocols &= 0x00001fdfL;
			a->profile.B3_Protocols &= 0x000000b7L;

			a->profile.Global_Options &= GET_DWORD(&esc_profile[6]) |
				GL_BCHANNEL_OPERATION_SUPPORTED;
			a->profile.B1_Protocols &= GET_DWORD(&esc_profile[10]);
			a->profile.B2_Protocols &= GET_DWORD(&esc_profile[14]);
			a->profile.B3_Protocols &= GET_DWORD(&esc_profile[18]);
			a->manufacturer_features = GET_DWORD(&esc_profile[46]);
			a->man_profile.private_options = 0;

			if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER)
			{
				a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER;
				a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED;
			}


			if (a->manufacturer_features & MANUFACTURER_FEATURE_RTP)
				a->man_profile.private_options |= 1L << PRIVATE_RTP;
			a->man_profile.rtp_primary_payloads = GET_DWORD(&esc_profile[50]);
			a->man_profile.rtp_additional_payloads = GET_DWORD(&esc_profile[54]);


			if (a->manufacturer_features & MANUFACTURER_FEATURE_T38)
				a->man_profile.private_options |= 1L << PRIVATE_T38;


			if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD)
				a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;


			if (a->manufacturer_features & MANUFACTURER_FEATURE_V18)
				a->man_profile.private_options |= 1L << PRIVATE_V18;


			if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE)
				a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE;


			if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS)
				a->man_profile.private_options |= 1L << PRIVATE_PIAFS;


			if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
				a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS;


			if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN)
				a->man_profile.private_options |= 1L << PRIVATE_VOWN;


			if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD)
				a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD;

		}
		else
		{
			a->profile.Global_Options &= 0x0000007fL;
			a->profile.B1_Protocols &= 0x000003dfL;
			a->profile.B2_Protocols &= 0x00001adfL;
			a->profile.B3_Protocols &= 0x000000b7L;
			a->manufacturer_features &= MANUFACTURER_FEATURE_HARDDTMF;
		}
		if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF |
						MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
		{
			a->profile.Global_Options |= GL_DTMF_SUPPORTED;
		}
		a->manufacturer_features &= ~MANUFACTURER_FEATURE_OOB_CHANNEL;
		dbug(1, dprintf("[%06x] Profile: %lx %lx %lx %lx %lx",
				UnMapController(a->Id), a->profile.Global_Options,
				a->profile.B1_Protocols, a->profile.B2_Protocols,
				a->profile.B3_Protocols, a->manufacturer_features));
	}
	/* codec plci for the handset/hook state support is just an internal id  */
	if (plci != a->AdvCodecPLCI)
	{
		force_mt_info = SendMultiIE(plci, Id, multi_fac_parms, FTY, 0x20, 0);
		force_mt_info |= SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, 0);
		SendSSExtInd(NULL, plci, Id, multi_ssext_parms);
		SendInfo(plci, Id, parms, force_mt_info);

		VSwitchReqInd(plci, Id, multi_vswitch_parms);

	}

	/* switch the codec to the b-channel                                     */
	if (esc_chi[0] && plci && !plci->SuppState) {
		plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
		mixer_set_bchannel_id_esc(plci, plci->b_channel);
		dbug(1, dprintf("storeChannel=0x%x", plci->b_channel));
		if (plci->tel == ADV_VOICE && plci->appl) {
			SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
		}
	}

	if (plci->appl) plci->appl->Number++;

	switch (plci->Sig.Ind) {
		/* Response to Get_Supported_Services request */
	case S_SUPPORTED:
		dbug(1, dprintf("S_Supported"));
		if (!plci->appl) break;
		if (pty_cai[0] == 4)
		{
			PUT_DWORD(&CF_Ind[6], GET_DWORD(&pty_cai[1]));
		}
		else
		{
			PUT_DWORD(&CF_Ind[6], MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE);
		}
		PUT_WORD(&CF_Ind[1], 0);
		PUT_WORD(&CF_Ind[4], 0);
		sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0x7, plci->number, "wws", 0, 3, CF_Ind);
		plci_remove(plci);
		break;

		/* Supplementary Service rejected */
	case S_SERVICE_REJ:
		dbug(1, dprintf("S_Reject=0x%x", pty_cai[5]));
		if (!pty_cai[0]) break;
		switch (pty_cai[5])
		{
		case ECT_EXECUTE:
		case THREE_PTY_END:
		case THREE_PTY_BEGIN:
			if (!plci->relatedPTYPLCI) break;
			tplci = plci->relatedPTYPLCI;
			rId = ((word)tplci->Id << 8) | tplci->adapter->Id;
			if (tplci->tel) rId |= EXT_CONTROLLER;
			if (pty_cai[5] == ECT_EXECUTE)
			{
				PUT_WORD(&SS_Ind[1], S_ECT);

				plci->vswitchstate = 0;
				plci->relatedPTYPLCI->vswitchstate = 0;

			}
			else
			{
				PUT_WORD(&SS_Ind[1], pty_cai[5] + 3);
			}
			if (pty_cai[2] != 0xff)
			{
				PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
			}
			else
			{
				PUT_WORD(&SS_Ind[4], 0x300E);
			}
			plci->relatedPTYPLCI = NULL;
			plci->ptyState = 0;
			sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);
			break;

		case CALL_DEFLECTION:
			if (pty_cai[2] != 0xff)
			{
				PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
			}
			else
			{
				PUT_WORD(&SS_Ind[4], 0x300E);
			}
			PUT_WORD(&SS_Ind[1], pty_cai[5]);
			for (i = 0; i < max_appl; i++)
			{
				if (application[i].CDEnable)
				{
					if (application[i].Id) sendf(&application[i], _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
					application[i].CDEnable = false;
				}
			}
			break;

		case DEACTIVATION_DIVERSION:
		case ACTIVATION_DIVERSION:
		case DIVERSION_INTERROGATE_CFU:
		case DIVERSION_INTERROGATE_CFB:
		case DIVERSION_INTERROGATE_CFNR:
		case DIVERSION_INTERROGATE_NUM:
		case CCBS_REQUEST:
		case CCBS_DEACTIVATE:
		case CCBS_INTERROGATE:
			if (!plci->appl) break;
			if (pty_cai[2] != 0xff)
			{
				PUT_WORD(&Interr_Err_Ind[4], 0x3600 | (word)pty_cai[2]);
			}
			else
			{
				PUT_WORD(&Interr_Err_Ind[4], 0x300E);
			}
			switch (pty_cai[5])
			{
			case DEACTIVATION_DIVERSION:
				dbug(1, dprintf("Deact_Div"));
				Interr_Err_Ind[0] = 0x9;
				Interr_Err_Ind[3] = 0x6;
				PUT_WORD(&Interr_Err_Ind[1], S_CALL_FORWARDING_STOP);
				break;
			case ACTIVATION_DIVERSION:
				dbug(1, dprintf("Act_Div"));
				Interr_Err_Ind[0] = 0x9;
				Interr_Err_Ind[3] = 0x6;
				PUT_WORD(&Interr_Err_Ind[1], S_CALL_FORWARDING_START);
				break;
			case DIVERSION_INTERROGATE_CFU:
			case DIVERSION_INTERROGATE_CFB:
			case DIVERSION_INTERROGATE_CFNR:
				dbug(1, dprintf("Interr_Div"));
				Interr_Err_Ind[0] = 0xa;
				Interr_Err_Ind[3] = 0x7;
				PUT_WORD(&Interr_Err_Ind[1], S_INTERROGATE_DIVERSION);
				break;
			case DIVERSION_INTERROGATE_NUM:
				dbug(1, dprintf("Interr_Num"));
				Interr_Err_Ind[0] = 0xa;
				Interr_Err_Ind[3] = 0x7;
				PUT_WORD(&Interr_Err_Ind[1], S_INTERROGATE_NUMBERS);
				break;
			case CCBS_REQUEST:
				dbug(1, dprintf("CCBS Request"));
				Interr_Err_Ind[0] = 0xd;
				Interr_Err_Ind[3] = 0xa;
				PUT_WORD(&Interr_Err_Ind[1], S_CCBS_REQUEST);
				break;
			case CCBS_DEACTIVATE:
				dbug(1, dprintf("CCBS Deactivate"));
				Interr_Err_Ind[0] = 0x9;
				Interr_Err_Ind[3] = 0x6;
				PUT_WORD(&Interr_Err_Ind[1], S_CCBS_DEACTIVATE);
				break;
			case CCBS_INTERROGATE:
				dbug(1, dprintf("CCBS Interrogate"));
				Interr_Err_Ind[0] = 0xb;
				Interr_Err_Ind[3] = 0x8;
				PUT_WORD(&Interr_Err_Ind[1], S_CCBS_INTERROGATE);
				break;
			}
			PUT_DWORD(&Interr_Err_Ind[6], plci->appl->S_Handle);
			sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "ws", 3, Interr_Err_Ind);
			plci_remove(plci);
			break;
		case ACTIVATION_MWI:
		case DEACTIVATION_MWI:
			if (pty_cai[5] == ACTIVATION_MWI)
			{
				PUT_WORD(&SS_Ind[1], S_MWI_ACTIVATE);
			}
			else PUT_WORD(&SS_Ind[1], S_MWI_DEACTIVATE);

			if (pty_cai[2] != 0xff)
			{
				PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
			}
			else
			{
				PUT_WORD(&SS_Ind[4], 0x300E);
			}

			if (plci->cr_enquiry)
			{
				sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "ws", 3, SS_Ind);
				plci_remove(plci);
			}
			else
			{
				sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
			}
			break;
		case CONF_ADD: /* ERROR */
		case CONF_BEGIN:
		case CONF_DROP:
		case CONF_ISOLATE:
		case CONF_REATTACH:
			CONF_Ind[0] = 9;
			CONF_Ind[3] = 6;
			switch (pty_cai[5])
			{
			case CONF_BEGIN:
				PUT_WORD(&CONF_Ind[1], S_CONF_BEGIN);
				plci->ptyState = 0;
				break;
			case CONF_DROP:
				CONF_Ind[0] = 5;
				CONF_Ind[3] = 2;
				PUT_WORD(&CONF_Ind[1], S_CONF_DROP);
				plci->ptyState = CONNECTED;
				break;
			case CONF_ISOLATE:
				CONF_Ind[0] = 5;
				CONF_Ind[3] = 2;
				PUT_WORD(&CONF_Ind[1], S_CONF_ISOLATE);
				plci->ptyState = CONNECTED;
				break;
			case CONF_REATTACH:
				CONF_Ind[0] = 5;
				CONF_Ind[3] = 2;
				PUT_WORD(&CONF_Ind[1], S_CONF_REATTACH);
				plci->ptyState = CONNECTED;
				break;
			case CONF_ADD:
				PUT_WORD(&CONF_Ind[1], S_CONF_ADD);
				plci->relatedPTYPLCI = NULL;
				tplci = plci->relatedPTYPLCI;
				if (tplci) tplci->ptyState = CONNECTED;
				plci->ptyState = CONNECTED;
				break;
			}

			if (pty_cai[2] != 0xff)
			{
				PUT_WORD(&CONF_Ind[4], 0x3600 | (word)pty_cai[2]);
			}
			else
			{
				PUT_WORD(&CONF_Ind[4], 0x3303); /* Time-out: network did not respond
								  within the required time */
			}

			PUT_DWORD(&CONF_Ind[6], 0x0);
			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
			break;
		}
		break;

		/* Supplementary Service indicates success */
	case S_SERVICE:
		dbug(1, dprintf("Service_Ind"));
		PUT_WORD(&CF_Ind[4], 0);
		switch (pty_cai[5])
		{
		case THREE_PTY_END:
		case THREE_PTY_BEGIN:
		case ECT_EXECUTE:
			if (!plci->relatedPTYPLCI) break;
			tplci = plci->relatedPTYPLCI;
			rId = ((word)tplci->Id << 8) | tplci->adapter->Id;
			if (tplci->tel) rId |= EXT_CONTROLLER;
			if (pty_cai[5] == ECT_EXECUTE)
			{
				PUT_WORD(&SS_Ind[1], S_ECT);

				if (plci->vswitchstate != 3)
				{

					plci->ptyState = IDLE;
					plci->relatedPTYPLCI = NULL;
					plci->ptyState = 0;

				}

				dbug(1, dprintf("ECT OK"));
				sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);



			}
			else
			{
				switch (plci->ptyState)
				{
				case S_3PTY_BEGIN:
					plci->ptyState = CONNECTED;
					dbug(1, dprintf("3PTY ON"));
					break;

				case S_3PTY_END:
					plci->ptyState = IDLE;
					plci->relatedPTYPLCI = NULL;
					plci->ptyState = 0;
					dbug(1, dprintf("3PTY OFF"));
					break;
				}
				PUT_WORD(&SS_Ind[1], pty_cai[5] + 3);
				sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);
			}
			break;

		case CALL_DEFLECTION:
			PUT_WORD(&SS_Ind[1], pty_cai[5]);
			for (i = 0; i < max_appl; i++)
			{
				if (application[i].CDEnable)
				{
					if (application[i].Id) sendf(&application[i], _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
					application[i].CDEnable = false;
				}
			}
			break;

		case DEACTIVATION_DIVERSION:
		case ACTIVATION_DIVERSION:
			if (!plci->appl) break;
			PUT_WORD(&CF_Ind[1], pty_cai[5] + 2);
			PUT_DWORD(&CF_Ind[6], plci->appl->S_Handle);
			sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "ws", 3, CF_Ind);
			plci_remove(plci);
			break;

		case DIVERSION_INTERROGATE_CFU:
		case DIVERSION_INTERROGATE_CFB:
		case DIVERSION_INTERROGATE_CFNR:
		case DIVERSION_INTERROGATE_NUM:
		case CCBS_REQUEST:
		case CCBS_DEACTIVATE:
		case CCBS_INTERROGATE:
			if (!plci->appl) break;
			switch (pty_cai[5])
			{
			case DIVERSION_INTERROGATE_CFU:
			case DIVERSION_INTERROGATE_CFB:
			case DIVERSION_INTERROGATE_CFNR:
				dbug(1, dprintf("Interr_Div"));
				PUT_WORD(&pty_cai[1], S_INTERROGATE_DIVERSION);
				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
				break;
			case DIVERSION_INTERROGATE_NUM:
				dbug(1, dprintf("Interr_Num"));
				PUT_WORD(&pty_cai[1], S_INTERROGATE_NUMBERS);
				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
				break;
			case CCBS_REQUEST:
				dbug(1, dprintf("CCBS Request"));
				PUT_WORD(&pty_cai[1], S_CCBS_REQUEST);
				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
				break;
			case CCBS_DEACTIVATE:
				dbug(1, dprintf("CCBS Deactivate"));
				PUT_WORD(&pty_cai[1], S_CCBS_DEACTIVATE);
				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
				break;
			case CCBS_INTERROGATE:
				dbug(1, dprintf("CCBS Interrogate"));
				PUT_WORD(&pty_cai[1], S_CCBS_INTERROGATE);
				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
				break;
			}
			PUT_WORD(&pty_cai[4], 0); /* Supplementary Service Reason */
			PUT_DWORD(&pty_cai[6], plci->appl->S_Handle);
			sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "wS", 3, pty_cai);
			plci_remove(plci);
			break;

		case ACTIVATION_MWI:
		case DEACTIVATION_MWI:
			if (pty_cai[5] == ACTIVATION_MWI)
			{
				PUT_WORD(&SS_Ind[1], S_MWI_ACTIVATE);
			}
			else PUT_WORD(&SS_Ind[1], S_MWI_DEACTIVATE);
			if (plci->cr_enquiry)
			{
				sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "ws", 3, SS_Ind);
				plci_remove(plci);
			}
			else
			{
				sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
			}
			break;
		case MWI_INDICATION:
			if (pty_cai[0] >= 0x12)
			{
				PUT_WORD(&pty_cai[3], S_MWI_INDICATE);
				pty_cai[2] = pty_cai[0] - 2; /* len Parameter */
				pty_cai[5] = pty_cai[0] - 5; /* Supplementary Service-specific parameter len */
				if (plci->appl && (a->Notification_Mask[plci->appl->Id - 1] & SMASK_MWI))
				{
					if (plci->internal_command == GET_MWI_STATE) /* result on Message Waiting Listen */
					{
						sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "wS", 3, &pty_cai[2]);
						plci_remove(plci);
						return;
					}
					else sendf(plci->appl, _FACILITY_I, Id, 0, "wS", 3, &pty_cai[2]);
					pty_cai[0] = 0;
				}
				else
				{
					for (i = 0; i < max_appl; i++)
					{
						if (a->Notification_Mask[i]&SMASK_MWI)
						{
							sendf(&application[i], _FACILITY_I, Id & 0x7, 0, "wS", 3, &pty_cai[2]);
							pty_cai[0] = 0;
						}
					}
				}

				if (!pty_cai[0])
				{ /* acknowledge */
					facility[2] = 0; /* returncode */
				}
				else facility[2] = 0xff;
			}
			else
			{
				/* reject */
				facility[2] = 0xff; /* returncode */
			}
			facility[0] = 2;
			facility[1] = MWI_RESPONSE; /* Function */
			add_p(plci, CAI, facility);
			add_p(plci, ESC, multi_ssext_parms[0]); /* remembered parameter -> only one possible */
			sig_req(plci, S_SERVICE, 0);
			send_req(plci);
			plci->command = 0;
			next_internal_command(Id, plci);
			break;
		case CONF_ADD: /* OK */
		case CONF_BEGIN:
		case CONF_DROP:
		case CONF_ISOLATE:
		case CONF_REATTACH:
		case CONF_PARTYDISC:
			CONF_Ind[0] = 9;
			CONF_Ind[3] = 6;
			switch (pty_cai[5])
			{
			case CONF_BEGIN:
				PUT_WORD(&CONF_Ind[1], S_CONF_BEGIN);
				if (pty_cai[0] == 6)
				{
					d = pty_cai[6];
					PUT_DWORD(&CONF_Ind[6], d); /* PartyID */
				}
				else
				{
					PUT_DWORD(&CONF_Ind[6], 0x0);
				}
				break;
			case CONF_ISOLATE:
				PUT_WORD(&CONF_Ind[1], S_CONF_ISOLATE);
				CONF_Ind[0] = 5;
				CONF_Ind[3] = 2;
				break;
			case CONF_REATTACH:
				PUT_WORD(&CONF_Ind[1], S_CONF_REATTACH);
				CONF_Ind[0] = 5;
				CONF_Ind[3] = 2;
				break;
			case CONF_DROP:
				PUT_WORD(&CONF_Ind[1], S_CONF_DROP);
				CONF_Ind[0] = 5;
				CONF_Ind[3] = 2;
				break;
			case CONF_ADD:
				PUT_WORD(&CONF_Ind[1], S_CONF_ADD);
				d = pty_cai[6];
				PUT_DWORD(&CONF_Ind[6], d); /* PartyID */
				tplci = plci->relatedPTYPLCI;
				if (tplci) tplci->ptyState = CONNECTED;
				break;
			case CONF_PARTYDISC:
				CONF_Ind[0] = 7;
				CONF_Ind[3] = 4;
				PUT_WORD(&CONF_Ind[1], S_CONF_PARTYDISC);
				d = pty_cai[6];
				PUT_DWORD(&CONF_Ind[4], d); /* PartyID */
				break;
			}
			plci->ptyState = CONNECTED;
			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
			break;
		case CCBS_INFO_RETAIN:
		case CCBS_ERASECALLLINKAGEID:
		case CCBS_STOP_ALERTING:
			CONF_Ind[0] = 5;
			CONF_Ind[3] = 2;
			switch (pty_cai[5])
			{
			case CCBS_INFO_RETAIN:
				PUT_WORD(&CONF_Ind[1], S_CCBS_INFO_RETAIN);
				break;
			case CCBS_STOP_ALERTING:
				PUT_WORD(&CONF_Ind[1], S_CCBS_STOP_ALERTING);
				break;
			case CCBS_ERASECALLLINKAGEID:
				PUT_WORD(&CONF_Ind[1], S_CCBS_ERASECALLLINKAGEID);
				CONF_Ind[0] = 7;
				CONF_Ind[3] = 4;
				CONF_Ind[6] = 0;
				CONF_Ind[7] = 0;
				break;
			}
			w = pty_cai[6];
			PUT_WORD(&CONF_Ind[4], w); /* PartyID */

			if (plci->appl && (a->Notification_Mask[plci->appl->Id - 1] & SMASK_CCBS))
			{
				sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
			}
			else
			{
				for (i = 0; i < max_appl; i++)
					if (a->Notification_Mask[i] & SMASK_CCBS)
						sendf(&application[i], _FACILITY_I, Id & 0x7, 0, "ws", 3, CONF_Ind);
			}
			break;
		}
		break;
	case CALL_HOLD_REJ:
		cau = parms[7];
		if (cau)
		{
			i = _L3_CAUSE | cau[2];
			if (cau[2] == 0) i = 0x3603;
		}
		else
		{
			i = 0x3603;
		}
		PUT_WORD(&SS_Ind[1], S_HOLD);
		PUT_WORD(&SS_Ind[4], i);
		if (plci->SuppState == HOLD_REQUEST)
		{
			plci->SuppState = IDLE;
			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
		}
		break;

	case CALL_HOLD_ACK:
		if (plci->SuppState == HOLD_REQUEST)
		{
			plci->SuppState = CALL_HELD;
			CodecIdCheck(a, plci);
			start_internal_command(Id, plci, hold_save_command);
		}
		break;

	case CALL_RETRIEVE_REJ:
		cau = parms[7];
		if (cau)
		{
			i = _L3_CAUSE | cau[2];
			if (cau[2] == 0) i = 0x3603;
		}
		else
		{
			i = 0x3603;
		}
		PUT_WORD(&SS_Ind[1], S_RETRIEVE);
		PUT_WORD(&SS_Ind[4], i);
		if (plci->SuppState == RETRIEVE_REQUEST)
		{
			plci->SuppState = CALL_HELD;
			CodecIdCheck(a, plci);
			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
		}
		break;

	case CALL_RETRIEVE_ACK:
		PUT_WORD(&SS_Ind[1], S_RETRIEVE);
		if (plci->SuppState == RETRIEVE_REQUEST)
		{
			plci->SuppState = IDLE;
			plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
			plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
			if (plci->tel)
			{
				mixer_set_bchannel_id_esc(plci, plci->b_channel);
				dbug(1, dprintf("RetrChannel=0x%x", plci->b_channel));
				SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
				if (plci->B2_prot == B2_TRANSPARENT && plci->B3_prot == B3_TRANSPARENT)
				{
					dbug(1, dprintf("Get B-ch"));
					start_internal_command(Id, plci, retrieve_restore_command);
				}
				else
					sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
			}
			else
				start_internal_command(Id, plci, retrieve_restore_command);
		}
		break;

	case INDICATE_IND:
		if (plci->State != LISTENING) {
			sig_req(plci, HANGUP, 0);
			send_req(plci);
			break;
		}
		cip = find_cip(a, parms[4], parms[6]);
		cip_mask = 1L << cip;
		dbug(1, dprintf("cip=%d,cip_mask=%lx", cip, cip_mask));
		clear_c_ind_mask(plci);
		if (!remove_started && !a->adapter_disabled)
		{
			set_c_ind_mask_bit(plci, MAX_APPL);
			group_optimization(a, plci);
			for (i = 0; i < max_appl; i++) {
				if (application[i].Id
				    && (a->CIP_Mask[i] & 1 || a->CIP_Mask[i] & cip_mask)
				    && CPN_filter_ok(parms[0], a, i)
				    && test_group_ind_mask_bit(plci, i)) {
					dbug(1, dprintf("storedcip_mask[%d]=0x%lx", i, a->CIP_Mask[i]));
					set_c_ind_mask_bit(plci, i);
					dump_c_ind_mask(plci);
					plci->State = INC_CON_PENDING;
					plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) |
						CALL_DIR_IN | CALL_DIR_ANSWER;
					if (esc_chi[0]) {
						plci->b_channel = esc_chi[esc_chi[0]] & 0x1f;
						mixer_set_bchannel_id_esc(plci, plci->b_channel);
					}
					/* if a listen on the ext controller is done, check if hook states */
					/* are supported or if just a on board codec must be activated     */
					if (a->codec_listen[i] && !a->AdvSignalPLCI) {
						if (a->profile.Global_Options & HANDSET)
							plci->tel = ADV_VOICE;
						else if (a->profile.Global_Options & ON_BOARD_CODEC)
							plci->tel = CODEC;
						if (plci->tel) Id |= EXT_CONTROLLER;
						a->codec_listen[i] = plci;
					}

					sendf(&application[i], _CONNECT_I, Id, 0,
					      "wSSSSSSSbSSSSS", cip,    /* CIP                 */
					      parms[0],    /* CalledPartyNumber   */
					      multi_CiPN_parms[0],    /* CallingPartyNumber  */
					      parms[2],    /* CalledPartySubad    */
					      parms[3],    /* CallingPartySubad   */
					      parms[4],    /* BearerCapability    */
					      parms[5],    /* LowLC               */
					      parms[6],    /* HighLC              */
					      ai_len,      /* nested struct add_i */
					      add_i[0],    /* B channel info    */
					      add_i[1],    /* keypad facility   */
					      add_i[2],    /* user user data    */
					      add_i[3],    /* nested facility   */
					      multi_CiPN_parms[1]    /* second CiPN(SCR)   */
						);
					SendSSExtInd(&application[i],
						     plci,
						     Id,
						     multi_ssext_parms);
					SendSetupInfo(&application[i],
						      plci,
						      Id,
						      parms,
						      SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, true));
				}
			}
			clear_c_ind_mask_bit(plci, MAX_APPL);
			dump_c_ind_mask(plci);
		}
		if (c_ind_mask_empty(plci)) {
			sig_req(plci, HANGUP, 0);
			send_req(plci);
			plci->State = IDLE;
		}
		plci->notifiedcall = 0;
		a->listen_active--;
		listen_check(a);
		break;

	case CALL_PEND_NOTIFY:
		plci->notifiedcall = 1;
		listen_check(a);
		break;

	case CALL_IND:
	case CALL_CON:
		if (plci->State == ADVANCED_VOICE_SIG || plci->State == ADVANCED_VOICE_NOSIG)
		{
			if (plci->internal_command == PERM_COD_CONN_PEND)
			{
				if (plci->State == ADVANCED_VOICE_NOSIG)
				{
					dbug(1, dprintf("***Codec OK"));
					if (a->AdvSignalPLCI)
					{
						tplci = a->AdvSignalPLCI;
						if (tplci->spoofed_msg)
						{
							dbug(1, dprintf("***Spoofed Msg(0x%x)", tplci->spoofed_msg));
							tplci->command = 0;
							tplci->internal_command = 0;
							x_Id = ((word)tplci->Id << 8) | tplci->adapter->Id | 0x80;
							switch (tplci->spoofed_msg)
							{
							case CALL_RES:
								tplci->command = _CONNECT_I | RESPONSE;
								api_load_msg(&tplci->saved_msg, saved_parms);
								add_b1(tplci, &saved_parms[1], 0, tplci->B1_facilities);
								if (tplci->adapter->Info_Mask[tplci->appl->Id - 1] & 0x200)
								{
									/* early B3 connect (CIP mask bit 9) no release after a disc */
									add_p(tplci, LLI, "\x01\x01");
								}
								add_s(tplci, CONN_NR, &saved_parms[2]);
								add_s(tplci, LLC, &saved_parms[4]);
								add_ai(tplci, &saved_parms[5]);
								tplci->State = INC_CON_ACCEPT;
								sig_req(tplci, CALL_RES, 0);
								send_req(tplci);
								break;

							case AWAITING_SELECT_B:
								dbug(1, dprintf("Select_B continue"));
								start_internal_command(x_Id, tplci, select_b_command);
								break;

							case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */
								if (!tplci->Sig.Id)
								{
									dbug(1, dprintf("No SigID!"));
									sendf(tplci->appl, _MANUFACTURER_R | CONFIRM, x_Id, tplci->number, "dww", _DI_MANU_ID, _MANUFACTURER_R, _OUT_OF_PLCI);
									plci_remove(tplci);
									break;
								}
								tplci->command = _MANUFACTURER_R;
								api_load_msg(&tplci->saved_msg, saved_parms);
								dir = saved_parms[2].info[0];
								if (dir == 1) {
									sig_req(tplci, CALL_REQ, 0);
								}
								else if (!dir) {
									sig_req(tplci, LISTEN_REQ, 0);
								}
								send_req(tplci);
								sendf(tplci->appl, _MANUFACTURER_R | CONFIRM, x_Id, tplci->number, "dww", _DI_MANU_ID, _MANUFACTURER_R, 0);
								break;

							case (CALL_REQ | AWAITING_MANUF_CON):
								sig_req(tplci, CALL_REQ, 0);
								send_req(tplci);
								break;

							case CALL_REQ:
								if (!tplci->Sig.Id)
								{
									dbug(1, dprintf("No SigID!"));
									sendf(tplci->appl, _CONNECT_R | CONFIRM, tplci->adapter->Id, 0, "w", _OUT_OF_PLCI);
									plci_remove(tplci);
									break;
								}
								tplci->command = _CONNECT_R;
								api_load_msg(&tplci->saved_msg, saved_parms);
								add_s(tplci, CPN, &saved_parms[1]);
								add_s(tplci, DSA, &saved_parms[3]);
								add_ai(tplci, &saved_parms[9]);
								sig_req(tplci, CALL_REQ, 0);
								send_req(tplci);
								break;

							case CALL_RETRIEVE:
								tplci->command = C_RETRIEVE_REQ;
								sig_req(tplci, CALL_RETRIEVE, 0);
								send_req(tplci);
								break;
							}
							tplci->spoofed_msg = 0;
							if (tplci->internal_command == 0)
								next_internal_command(x_Id, tplci);
						}
					}
					next_internal_command(Id, plci);
					break;
				}
				dbug(1, dprintf("***Codec Hook Init Req"));
				plci->internal_command = PERM_COD_HOOK;
				add_p(plci, FTY, "\x01\x09");             /* Get Hook State*/
				sig_req(plci, TEL_CTRL, 0);
				send_req(plci);
			}
		}
		else if (plci->command != _MANUFACTURER_R  /* old style permanent connect */
			 && plci->State != INC_ACT_PENDING)
		{
			mixer_set_bchannel_id_esc(plci, plci->b_channel);
			if (plci->tel == ADV_VOICE && plci->SuppState == IDLE) /* with permanent codec switch on immediately */
			{
				chi[2] = plci->b_channel;
				SetVoiceChannel(a->AdvCodecPLCI, chi, a);
			}
			sendf(plci->appl, _CONNECT_ACTIVE_I, Id, 0, "Sss", parms[21], "", "");
			plci->State = INC_ACT_PENDING;
		}
		break;

	case TEL_CTRL:
		ie = multi_fac_parms[0]; /* inspect the facility hook indications */
		if (plci->State == ADVANCED_VOICE_SIG && ie[0]) {
			switch (ie[1] & 0x91) {
			case 0x80:   /* hook off */
			case 0x81:
				if (plci->internal_command == PERM_COD_HOOK)
				{
					dbug(1, dprintf("init:hook_off"));
					plci->hook_state = ie[1];
					next_internal_command(Id, plci);
					break;
				}
				else /* ignore doubled hook indications */
				{
					if (((plci->hook_state) & 0xf0) == 0x80)
					{
						dbug(1, dprintf("ignore hook"));
						break;
					}
					plci->hook_state = ie[1]&0x91;
				}
				/* check for incoming call pending */
				/* and signal '+'.Appl must decide */
				/* with connect_res if call must   */
				/* accepted or not                 */
				for (i = 0, tplci = NULL; i < max_appl; i++) {
					if (a->codec_listen[i]
					    && (a->codec_listen[i]->State == INC_CON_PENDING
						|| a->codec_listen[i]->State == INC_CON_ALERT)) {
						tplci = a->codec_listen[i];
						tplci->appl = &application[i];
					}
				}
				/* no incoming call, do outgoing call */
				/* and signal '+' if outg. setup   */
				if (!a->AdvSignalPLCI && !tplci) {
					if ((i = get_plci(a))) {
						a->AdvSignalPLCI = &a->plci[i - 1];
						tplci = a->AdvSignalPLCI;
						tplci->tel  = ADV_VOICE;
						PUT_WORD(&voice_cai[5], a->AdvSignalAppl->MaxDataLength);
						if (a->Info_Mask[a->AdvSignalAppl->Id - 1] & 0x200) {
							/* early B3 connect (CIP mask bit 9) no release after a disc */
							add_p(tplci, LLI, "\x01\x01");
						}
						add_p(tplci, CAI, voice_cai);
						add_p(tplci, OAD, a->TelOAD);
						add_p(tplci, OSA, a->TelOSA);
						add_p(tplci, SHIFT | 6, NULL);
						add_p(tplci, SIN, "\x02\x01\x00");
						add_p(tplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
						sig_req(tplci, ASSIGN, DSIG_ID);
						a->AdvSignalPLCI->internal_command = HOOK_OFF_REQ;
						a->AdvSignalPLCI->command = 0;
						tplci->appl = a->AdvSignalAppl;
						tplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
						send_req(tplci);
					}

				}

				if (!tplci) break;
				Id = ((word)tplci->Id << 8) | a->Id;
				Id |= EXT_CONTROLLER;
				sendf(tplci->appl,
				      _FACILITY_I,
				      Id,
				      0,
				      "ws", (word)0, "\x01+");
				break;

			case 0x90:   /* hook on  */
			case 0x91:
				if (plci->internal_command == PERM_COD_HOOK)
				{
					dbug(1, dprintf("init:hook_on"));
					plci->hook_state = ie[1] & 0x91;
					next_internal_command(Id, plci);
					break;
				}
				else /* ignore doubled hook indications */
				{
					if (((plci->hook_state) & 0xf0) == 0x90) break;
					plci->hook_state = ie[1] & 0x91;
				}
				/* hangup the adv. voice call and signal '-' to the appl */
				if (a->AdvSignalPLCI) {
					Id = ((word)a->AdvSignalPLCI->Id << 8) | a->Id;
					if (plci->tel) Id |= EXT_CONTROLLER;
					sendf(a->AdvSignalAppl,
					      _FACILITY_I,
					      Id,
					      0,
					      "ws", (word)0, "\x01-");
					a->AdvSignalPLCI->internal_command = HOOK_ON_REQ;
					a->AdvSignalPLCI->command = 0;
					sig_req(a->AdvSignalPLCI, HANGUP, 0);
					send_req(a->AdvSignalPLCI);
				}
				break;
			}
		}
		break;

	case RESUME:
		clear_c_ind_mask_bit(plci, (word)(plci->appl->Id - 1));
		PUT_WORD(&resume_cau[4], GOOD);
		sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau);
		break;

	case SUSPEND:
		clear_c_ind_mask(plci);

		if (plci->NL.Id && !plci->nl_remove_id) {
			mixer_remove(plci);
			nl_req_ncci(plci, REMOVE, 0);
		}
		if (!plci->sig_remove_id) {
			plci->internal_command = 0;
			sig_req(plci, REMOVE, 0);
		}
		send_req(plci);
		if (!plci->channels) {
			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, "\x05\x04\x00\x02\x00\x00");
			sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
		}
		break;

	case SUSPEND_REJ:
		break;

	case HANGUP:
		plci->hangup_flow_ctrl_timer = 0;
		if (plci->manufacturer && plci->State == LOCAL_CONNECT) break;
		cau = parms[7];
		if (cau) {
			i = _L3_CAUSE | cau[2];
			if (cau[2] == 0) i = 0;
			else if (cau[2] == 8) i = _L1_ERROR;
			else if (cau[2] == 9 || cau[2] == 10) i = _L2_ERROR;
			else if (cau[2] == 5) i = _CAPI_GUARD_ERROR;
		}
		else {
			i = _L3_ERROR;
		}

		if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT)
		{
			for (i = 0; i < max_appl; i++)
			{
				if (test_c_ind_mask_bit(plci, i))
					sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
			}
		}
		else
		{
			clear_c_ind_mask(plci);
		}
		if (!plci->appl)
		{
			if (plci->State == LISTENING)
			{
				plci->notifiedcall = 0;
				a->listen_active--;
			}
			plci->State = INC_DIS_PENDING;
			if (c_ind_mask_empty(plci))
			{
				plci->State = IDLE;
				if (plci->NL.Id && !plci->nl_remove_id)
				{
					mixer_remove(plci);
					nl_req_ncci(plci, REMOVE, 0);
				}
				if (!plci->sig_remove_id)
				{
					plci->internal_command = 0;
					sig_req(plci, REMOVE, 0);
				}
				send_req(plci);
			}
		}
		else
		{
			/* collision of DISCONNECT or CONNECT_RES with HANGUP can   */
			/* result in a second HANGUP! Don't generate another        */
			/* DISCONNECT                                               */
			if (plci->State != IDLE && plci->State != INC_DIS_PENDING)
			{
				if (plci->State == RESUMING)
				{
					PUT_WORD(&resume_cau[4], i);
					sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau);
				}
				plci->State = INC_DIS_PENDING;
				sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", i);
			}
		}
		break;

	case SSEXT_IND:
		SendSSExtInd(NULL, plci, Id, multi_ssext_parms);
		break;

	case VSWITCH_REQ:
		VSwitchReqInd(plci, Id, multi_vswitch_parms);
		break;
	case VSWITCH_IND:
		if (plci->relatedPTYPLCI &&
		    plci->vswitchstate == 3 &&
		    plci->relatedPTYPLCI->vswitchstate == 3 &&
		    parms[MAXPARMSIDS - 1][0])
		{
			add_p(plci->relatedPTYPLCI, SMSG, parms[MAXPARMSIDS - 1]);
			sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
			send_req(plci->relatedPTYPLCI);
		}
		else VSwitchReqInd(plci, Id, multi_vswitch_parms);
		break;

	}
}


static void SendSetupInfo(APPL *appl, PLCI *plci, dword Id, byte **parms, byte Info_Sent_Flag)
{
	word i;
	byte *ie;
	word Info_Number;
	byte *Info_Element;
	word Info_Mask = 0;

	dbug(1, dprintf("SetupInfo"));

	for (i = 0; i < MAXPARMSIDS; i++) {
		ie = parms[i];
		Info_Number = 0;
		Info_Element = ie;
		if (ie[0]) {
			switch (i) {
			case 0:
				dbug(1, dprintf("CPN "));
				Info_Number = 0x0070;
				Info_Mask = 0x80;
				Info_Sent_Flag = true;
				break;
			case 8:  /* display      */
				dbug(1, dprintf("display(%d)", i));
				Info_Number = 0x0028;
				Info_Mask = 0x04;
				Info_Sent_Flag = true;
				break;
			case 16: /* Channel Id */
				dbug(1, dprintf("CHI"));
				Info_Number = 0x0018;
				Info_Mask = 0x100;
				Info_Sent_Flag = true;
				mixer_set_bchannel_id(plci, Info_Element);
				break;
			case 19: /* Redirected Number */
				dbug(1, dprintf("RDN"));
				Info_Number = 0x0074;
				Info_Mask = 0x400;
				Info_Sent_Flag = true;
				break;
			case 20: /* Redirected Number extended */
				dbug(1, dprintf("RDX"));
				Info_Number = 0x0073;
				Info_Mask = 0x400;
				Info_Sent_Flag = true;
				break;
			case 22: /* Redirecing Number  */
				dbug(1, dprintf("RIN"));
				Info_Number = 0x0076;
				Info_Mask = 0x400;
				Info_Sent_Flag = true;
				break;
			default:
				Info_Number = 0;
				break;
			}
		}

		if (i == MAXPARMSIDS - 2) { /* to indicate the message type "Setup" */
			Info_Number = 0x8000 | 5;
			Info_Mask = 0x10;
			Info_Element = "";
		}

		if (Info_Sent_Flag && Info_Number) {
			if (plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask) {
				sendf(appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
			}
		}
	}
}


static void SendInfo(PLCI *plci, dword Id, byte **parms, byte iesent)
{
	word i;
	word j;
	word k;
	byte *ie;
	word Info_Number;
	byte *Info_Element;
	word Info_Mask = 0;
	static byte charges[5] = {4, 0, 0, 0, 0};
	static byte cause[] = {0x02, 0x80, 0x00};
	APPL *appl;

	dbug(1, dprintf("InfoParse "));

	if (
		!plci->appl
		&& !plci->State
		&& plci->Sig.Ind != NCR_FACILITY
		)
	{
		dbug(1, dprintf("NoParse "));
		return;
	}
	cause[2] = 0;
	for (i = 0; i < MAXPARMSIDS; i++) {
		ie = parms[i];
		Info_Number = 0;
		Info_Element = ie;
		if (ie[0]) {
			switch (i) {
			case 0:
				dbug(1, dprintf("CPN "));
				Info_Number = 0x0070;
				Info_Mask   = 0x80;
				break;
			case 7: /* ESC_CAU */
				dbug(1, dprintf("cau(0x%x)", ie[2]));
				Info_Number = 0x0008;
				Info_Mask = 0x00;
				cause[2] = ie[2];
				Info_Element = NULL;
				break;
			case 8:  /* display      */
				dbug(1, dprintf("display(%d)", i));
				Info_Number = 0x0028;
				Info_Mask = 0x04;
				break;
			case 9:  /* Date display */
				dbug(1, dprintf("date(%d)", i));
				Info_Number = 0x0029;
				Info_Mask = 0x02;
				break;
			case 10: /* charges */
				for (j = 0; j < 4; j++) charges[1 + j] = 0;
				for (j = 0; j < ie[0] && !(ie[1 + j] & 0x80); j++);
				for (k = 1, j++; j < ie[0] && k <= 4; j++, k++) charges[k] = ie[1 + j];
				Info_Number = 0x4000;
				Info_Mask = 0x40;
				Info_Element = charges;
				break;
			case 11: /* user user info */
				dbug(1, dprintf("uui"));
				Info_Number = 0x007E;
				Info_Mask = 0x08;
				break;
			case 12: /* congestion receiver ready */
				dbug(1, dprintf("clRDY"));
				Info_Number = 0x00B0;
				Info_Mask = 0x08;
				Info_Element = "";
				break;
			case 13: /* congestion receiver not ready */
				dbug(1, dprintf("clNRDY"));
				Info_Number = 0x00BF;
				Info_Mask = 0x08;
				Info_Element = "";
				break;
			case 15: /* Keypad Facility */
				dbug(1, dprintf("KEY"));
				Info_Number = 0x002C;
				Info_Mask = 0x20;
				break;
			case 16: /* Channel Id */
				dbug(1, dprintf("CHI"));
				Info_Number = 0x0018;
				Info_Mask = 0x100;
				mixer_set_bchannel_id(plci, Info_Element);
				break;
			case 17: /* if no 1tr6 cause, send full cause, else esc_cause */
				dbug(1, dprintf("q9cau(0x%x)", ie[2]));
				if (!cause[2] || cause[2] < 0x80) break;  /* eg. layer 1 error */
				Info_Number = 0x0008;
				Info_Mask = 0x01;
				if (cause[2] != ie[2]) Info_Element = cause;
				break;
			case 19: /* Redirected Number */
				dbug(1, dprintf("RDN"));
				Info_Number = 0x0074;
				Info_Mask = 0x400;
				break;
			case 22: /* Redirecing Number  */
				dbug(1, dprintf("RIN"));
				Info_Number = 0x0076;
				Info_Mask = 0x400;
				break;
			case 23: /* Notification Indicator  */
				dbug(1, dprintf("NI"));
				Info_Number = (word)NI;
				Info_Mask = 0x210;
				break;
			case 26: /* Call State  */
				dbug(1, dprintf("CST"));
				Info_Number = (word)CST;
				Info_Mask = 0x01; /* do with cause i.e. for now */
				break;
			case MAXPARMSIDS - 2:  /* Escape Message Type, must be the last indication */
				dbug(1, dprintf("ESC/MT[0x%x]", ie[3]));
				Info_Number = 0x8000 | ie[3];
				if (iesent) Info_Mask = 0xffff;
				else  Info_Mask = 0x10;
				Info_Element = "";
				break;
			default:
				Info_Number  = 0;
				Info_Mask    = 0;
				Info_Element = "";
				break;
			}
		}

		if (plci->Sig.Ind == NCR_FACILITY)           /* check controller broadcast */
		{
			for (j = 0; j < max_appl; j++)
			{
				appl = &application[j];
				if (Info_Number
				    && appl->Id
				    && plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask)
				{
					dbug(1, dprintf("NCR_Ind"));
					iesent = true;
					sendf(&application[j], _INFO_I, Id & 0x0f, 0, "wS", Info_Number, Info_Element);
				}
			}
		}
		else if (!plci->appl)
		{ /* overlap receiving broadcast */
			if (Info_Number == CPN
			    || Info_Number == KEY
			    || Info_Number == NI
			    || Info_Number == DSP
			    || Info_Number == UUI)
			{
				for (j = 0; j < max_appl; j++)
				{
					if (test_c_ind_mask_bit(plci, j))
					{
						dbug(1, dprintf("Ovl_Ind"));
						iesent = true;
						sendf(&application[j], _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
					}
				}
			}
		}               /* all other signalling states */
		else if (Info_Number
			 && plci->adapter->Info_Mask[plci->appl->Id - 1] & Info_Mask)
		{
			dbug(1, dprintf("Std_Ind"));
			iesent = true;
			sendf(plci->appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
		}
	}
}


static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type,
			dword info_mask, byte setupParse)
{
	word i;
	word j;
	byte *ie;
	word Info_Number;
	byte *Info_Element;
	APPL *appl;
	word Info_Mask = 0;
	byte iesent = 0;

	if (
		!plci->appl
		&& !plci->State
		&& plci->Sig.Ind != NCR_FACILITY
		&& !setupParse
		)
	{
		dbug(1, dprintf("NoM-IEParse "));
		return 0;
	}
	dbug(1, dprintf("M-IEParse "));

	for (i = 0; i < MAX_MULTI_IE; i++)
	{
		ie = parms[i];
		Info_Number = 0;
		Info_Element = ie;
		if (ie[0])
		{
			dbug(1, dprintf("[Ind0x%x]:IE=0x%x", plci->Sig.Ind, ie_type));
			Info_Number = (word)ie_type;
			Info_Mask = (word)info_mask;
		}

		if (plci->Sig.Ind == NCR_FACILITY)           /* check controller broadcast */
		{
			for (j = 0; j < max_appl; j++)
			{
				appl = &application[j];
				if (Info_Number
				    && appl->Id
				    && plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask)
				{
					iesent = true;
					dbug(1, dprintf("Mlt_NCR_Ind"));
					sendf(&application[j], _INFO_I, Id & 0x0f, 0, "wS", Info_Number, Info_Element);
				}
			}
		}
		else if (!plci->appl && Info_Number)
		{                                        /* overlap receiving broadcast */
			for (j = 0; j < max_appl; j++)
			{
				if (test_c_ind_mask_bit(plci, j))
				{
					iesent = true;
					dbug(1, dprintf("Mlt_Ovl_Ind"));
					sendf(&application[j] , _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
				}
			}
		}                                        /* all other signalling states */
		else if (Info_Number
			 && plci->adapter->Info_Mask[plci->appl->Id - 1] & Info_Mask)
		{
			iesent = true;
			dbug(1, dprintf("Mlt_Std_Ind"));
			sendf(plci->appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
		}
	}
	return iesent;
}

static void SendSSExtInd(APPL *appl, PLCI *plci, dword Id, byte **parms)
{
	word i;
	/* Format of multi_ssext_parms[i][]:
	   0 byte length
	   1 byte SSEXTIE
	   2 byte SSEXT_REQ/SSEXT_IND
	   3 byte length
	   4 word SSExtCommand
	   6... Params
	*/
	if (
		plci
		&& plci->State
		&& plci->Sig.Ind != NCR_FACILITY
		)
		for (i = 0; i < MAX_MULTI_IE; i++)
		{
			if (parms[i][0] < 6) continue;
			if (parms[i][2] == SSEXT_REQ) continue;

			if (appl)
			{
				parms[i][0] = 0; /* kill it */
				sendf(appl, _MANUFACTURER_I,
				      Id,
				      0,
				      "dwS",
				      _DI_MANU_ID,
				      _DI_SSEXT_CTRL,
				      &parms[i][3]);
			}
			else if (plci->appl)
			{
				parms[i][0] = 0; /* kill it */
				sendf(plci->appl, _MANUFACTURER_I,
				      Id,
				      0,
				      "dwS",
				      _DI_MANU_ID,
				      _DI_SSEXT_CTRL,
				      &parms[i][3]);
			}
		}
};

static void nl_ind(PLCI *plci)
{
	byte ch;
	word ncci;
	dword Id;
	DIVA_CAPI_ADAPTER *a;
	word NCCIcode;
	APPL *APPLptr;
	word count;
	word Num;
	word i, ncpi_state;
	byte len, ncci_state;
	word msg;
	word info = 0;
	word fax_feature_bits;
	byte fax_send_edata_ack;
	static byte v120_header_buffer[2 + 3];
	static word fax_info[] = {
		0,                     /* T30_SUCCESS                        */
		_FAX_NO_CONNECTION,    /* T30_ERR_NO_DIS_RECEIVED            */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_NO_RESPONSE        */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_RESPONSE          */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TOO_MANY_REPEATS           */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_UNEXPECTED_MESSAGE         */
		_FAX_REMOTE_ABORT,     /* T30_ERR_UNEXPECTED_DCN             */
		_FAX_LOCAL_ABORT,      /* T30_ERR_DTC_UNSUPPORTED            */
		_FAX_TRAINING_ERROR,   /* T30_ERR_ALL_RATES_FAILED           */
		_FAX_TRAINING_ERROR,   /* T30_ERR_TOO_MANY_TRAINS            */
		_FAX_PARAMETER_ERROR,  /* T30_ERR_RECEIVE_CORRUPTED          */
		_FAX_REMOTE_ABORT,     /* T30_ERR_UNEXPECTED_DISC            */
		_FAX_LOCAL_ABORT,      /* T30_ERR_APPLICATION_DISC           */
		_FAX_REMOTE_REJECT,    /* T30_ERR_INCOMPATIBLE_DIS           */
		_FAX_LOCAL_ABORT,      /* T30_ERR_INCOMPATIBLE_DCS           */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_NO_COMMAND         */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_COMMAND           */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG   */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG  */
		_FAX_NO_CONNECTION,    /* T30_ERR_NOT_IDENTIFIED             */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_SUPERVISORY_TIMEOUT        */
		_FAX_PARAMETER_ERROR,  /* T30_ERR_TOO_LONG_SCAN_LINE         */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS    */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR    */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_FTT     */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_EOM     */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_MPS     */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCN_AFTER_MCF     */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCN_AFTER_RTN     */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_CFR               */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_EOP     */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_EOM     */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_MPS     */
		0x331d,                /* T30_ERR_SUB_SEP_UNSUPPORTED        */
		0x331e,                /* T30_ERR_PWD_UNSUPPORTED            */
		0x331f,                /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED    */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_INVALID_COMMAND_FRAME      */
		_FAX_PARAMETER_ERROR,  /* T30_ERR_UNSUPPORTED_PAGE_CODING    */
		_FAX_PARAMETER_ERROR,  /* T30_ERR_INVALID_PAGE_CODING        */
		_FAX_REMOTE_REJECT,    /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG   */
		_FAX_LOCAL_ABORT,      /* T30_ERR_TIMEOUT_FROM_APPLICATION   */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_TRAINING_TIMEOUT    */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_UNEXPECTED_V21      */
		_FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_PRIMARY_CTS_ON      */
		_FAX_LOCAL_ABORT,      /* T30_ERR_V34FAX_TURNAROUND_POLLING  */
		_FAX_LOCAL_ABORT       /* T30_ERR_V34FAX_V8_INCOMPATIBILITY  */
	};

	byte dtmf_code_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE + 1];


	static word rtp_info[] = {
		GOOD,                  /* RTP_SUCCESS                       */
		0x3600                 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE    */
	};

	static dword udata_forwarding_table[0x100 / sizeof(dword)] =
		{
			0x0020301e, 0x00000000, 0x00000000, 0x00000000,
			0x00000000, 0x00000000, 0x00000000, 0x00000000
		};

	ch = plci->NL.IndCh;
	a = plci->adapter;
	ncci = a->ch_ncci[ch];
	Id = (((dword)(ncci ? ncci : ch)) << 16) | (((word) plci->Id) << 8) | a->Id;
	if (plci->tel) Id |= EXT_CONTROLLER;
	APPLptr = plci->appl;
	dbug(1, dprintf("NL_IND-Id(NL:0x%x)=0x%08lx,plci=%x,tel=%x,state=0x%x,ch=0x%x,chs=%d,Ind=%x",
			plci->NL.Id, Id, plci->Id, plci->tel, plci->State, ch, plci->channels, plci->NL.Ind & 0x0f));

	/* in the case if no connect_active_Ind was sent to the appl we wait for */

	if (plci->nl_remove_id)
	{
		plci->NL.RNR = 2; /* discard */
		dbug(1, dprintf("NL discard while remove pending"));
		return;
	}
	if ((plci->NL.Ind & 0x0f) == N_CONNECT)
	{
		if (plci->State == INC_DIS_PENDING
		    || plci->State == OUTG_DIS_PENDING
		    || plci->State == IDLE)
		{
			plci->NL.RNR = 2; /* discard */
			dbug(1, dprintf("discard n_connect"));
			return;
		}
		if (plci->State < INC_ACT_PENDING)
		{
			plci->NL.RNR = 1; /* flow control */
			channel_x_off(plci, ch, N_XON_CONNECT_IND);
			return;
		}
	}

	if (!APPLptr)                         /* no application or invalid data */
	{                                    /* while reloading the DSP        */
		dbug(1, dprintf("discard1"));
		plci->NL.RNR = 2;
		return;
	}

	if (((plci->NL.Ind & 0x0f) == N_UDATA)
	    && (((plci->B2_prot != B2_SDLC) && ((plci->B1_resource == 17) || (plci->B1_resource == 18)))
		|| (plci->B2_prot == 7)
		|| (plci->B3_prot == 7)))
	{
		plci->ncpi_buffer[0] = 0;

		ncpi_state = plci->ncpi_state;
		if (plci->NL.complete == 1)
		{
			byte *data = &plci->NL.RBuffer->P[0];

			if ((plci->NL.RBuffer->length >= 12)
			    && ((*data == DSP_UDATA_INDICATION_DCD_ON)
				|| (*data == DSP_UDATA_INDICATION_CTS_ON)))
			{
				word conn_opt, ncpi_opt = 0x00;
/*      HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */

				if (*data == DSP_UDATA_INDICATION_DCD_ON)
					plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED;
				if (*data == DSP_UDATA_INDICATION_CTS_ON)
					plci->ncpi_state |= NCPI_MDM_CTS_ON_RECEIVED;

				data++;    /* indication code */
				data += 2; /* timestamp */
				if ((*data == DSP_CONNECTED_NORM_V18) || (*data == DSP_CONNECTED_NORM_VOWN))
					ncpi_state &= ~(NCPI_MDM_DCD_ON_RECEIVED | NCPI_MDM_CTS_ON_RECEIVED);
				data++;    /* connected norm */
				conn_opt = GET_WORD(data);
				data += 2; /* connected options */

				PUT_WORD(&(plci->ncpi_buffer[1]), (word)(GET_DWORD(data) & 0x0000FFFF));

				if (conn_opt & DSP_CONNECTED_OPTION_MASK_V42)
				{
					ncpi_opt |= MDM_NCPI_ECM_V42;
				}
				else if (conn_opt & DSP_CONNECTED_OPTION_MASK_MNP)
				{
					ncpi_opt |= MDM_NCPI_ECM_MNP;
				}
				else
				{
					ncpi_opt |= MDM_NCPI_TRANSPARENT;
				}
				if (conn_opt & DSP_CONNECTED_OPTION_MASK_COMPRESSION)
				{
					ncpi_opt |= MDM_NCPI_COMPRESSED;
				}
				PUT_WORD(&(plci->ncpi_buffer[3]), ncpi_opt);
				plci->ncpi_buffer[0] = 4;

				plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND | NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
			}
		}
		if (plci->B3_prot == 7)
		{
			if (((a->ncci_state[ncci] == INC_ACT_PENDING) || (a->ncci_state[ncci] == OUTG_CON_PENDING))
			    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
			    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
			{
				a->ncci_state[ncci] = INC_ACT_PENDING;
				sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
				plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
			}
		}

		if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
		      & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
		    || !(ncpi_state & NCPI_MDM_DCD_ON_RECEIVED)
		    || !(ncpi_state & NCPI_MDM_CTS_ON_RECEIVED))

		{
			plci->NL.RNR = 2;
			return;
		}
	}

	if (plci->NL.complete == 2)
	{
		if (((plci->NL.Ind & 0x0f) == N_UDATA)
		    && !(udata_forwarding_table[plci->RData[0].P[0] >> 5] & (1L << (plci->RData[0].P[0] & 0x1f))))
		{
			switch (plci->RData[0].P[0])
			{

			case DTMF_UDATA_INDICATION_FAX_CALLING_TONE:
				if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG)
					sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", SELECTOR_DTMF, "\x01X");
				break;
			case DTMF_UDATA_INDICATION_ANSWER_TONE:
				if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG)
					sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", SELECTOR_DTMF, "\x01Y");
				break;
			case DTMF_UDATA_INDICATION_DIGITS_RECEIVED:
				dtmf_indication(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
				break;
			case DTMF_UDATA_INDICATION_DIGITS_SENT:
				dtmf_confirmation(Id, plci);
				break;


			case UDATA_INDICATION_MIXER_TAP_DATA:
				capidtmf_recv_process_block(&(plci->capidtmf_state), plci->RData[0].P + 1, (word)(plci->RData[0].PLength - 1));
				i = capidtmf_indication(&(plci->capidtmf_state), dtmf_code_buffer + 1);
				if (i != 0)
				{
					dtmf_code_buffer[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED;
					dtmf_indication(Id, plci, dtmf_code_buffer, (word)(i + 1));
				}
				break;


			case UDATA_INDICATION_MIXER_COEFS_SET:
				mixer_indication_coefs_set(Id, plci);
				break;
			case UDATA_INDICATION_XCONNECT_FROM:
				mixer_indication_xconnect_from(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
				break;
			case UDATA_INDICATION_XCONNECT_TO:
				mixer_indication_xconnect_to(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
				break;


			case LEC_UDATA_INDICATION_DISABLE_DETECT:
				ec_indication(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
				break;



			default:
				break;
			}
		}
		else
		{
			if ((plci->RData[0].PLength != 0)
			    && ((plci->B2_prot == B2_V120_ASYNC)
				|| (plci->B2_prot == B2_V120_ASYNC_V42BIS)
				|| (plci->B2_prot == B2_V120_BIT_TRANSPARENT)))
			{

				sendf(plci->appl, _DATA_B3_I, Id, 0,
				      "dwww",
				      plci->RData[1].P,
				      (plci->NL.RNum < 2) ? 0 : plci->RData[1].PLength,
				      plci->RNum,
				      plci->RFlags);

			}
			else
			{

				sendf(plci->appl, _DATA_B3_I, Id, 0,
				      "dwww",
				      plci->RData[0].P,
				      plci->RData[0].PLength,
				      plci->RNum,
				      plci->RFlags);

			}
		}
		return;
	}

	fax_feature_bits = 0;
	if ((plci->NL.Ind & 0x0f) == N_CONNECT ||
	    (plci->NL.Ind & 0x0f) == N_CONNECT_ACK ||
	    (plci->NL.Ind & 0x0f) == N_DISC ||
	    (plci->NL.Ind & 0x0f) == N_EDATA ||
	    (plci->NL.Ind & 0x0f) == N_DISC_ACK)
	{
		info = 0;
		plci->ncpi_buffer[0] = 0;
		switch (plci->B3_prot) {
		case  0: /*XPARENT*/
		case  1: /*T.90 NL*/
			break;    /* no network control protocol info - jfr */
		case  2: /*ISO8202*/
		case  3: /*X25 DCE*/
			for (i = 0; i < plci->NL.RLength; i++) plci->ncpi_buffer[4 + i] = plci->NL.RBuffer->P[i];
			plci->ncpi_buffer[0] = (byte)(i + 3);
			plci->ncpi_buffer[1] = (byte)(plci->NL.Ind & N_D_BIT ? 1 : 0);
			plci->ncpi_buffer[2] = 0;
			plci->ncpi_buffer[3] = 0;
			break;
		case  4: /*T.30 - FAX*/
		case  5: /*T.30 - FAX*/
			if (plci->NL.RLength >= sizeof(T30_INFO))
			{
				dbug(1, dprintf("FaxStatus %04x", ((T30_INFO *)plci->NL.RBuffer->P)->code));
				len = 9;
				PUT_WORD(&(plci->ncpi_buffer[1]), ((T30_INFO *)plci->NL.RBuffer->P)->rate_div_2400 * 2400);
				fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low);
				i = (((T30_INFO *)plci->NL.RBuffer->P)->resolution & T30_RESOLUTION_R8_0770_OR_200) ? 0x0001 : 0x0000;
				if (plci->B3_prot == 5)
				{
					if (!(fax_feature_bits & T30_FEATURE_BIT_ECM))
						i |= 0x8000; /* This is not an ECM connection */
					if (fax_feature_bits & T30_FEATURE_BIT_T6_CODING)
						i |= 0x4000; /* This is a connection with MMR compression */
					if (fax_feature_bits & T30_FEATURE_BIT_2D_CODING)
						i |= 0x2000; /* This is a connection with MR compression */
					if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
						i |= 0x0004; /* More documents */
					if (fax_feature_bits & T30_FEATURE_BIT_POLLING)
						i |= 0x0002; /* Fax-polling indication */
				}
				dbug(1, dprintf("FAX Options %04x %04x", fax_feature_bits, i));
				PUT_WORD(&(plci->ncpi_buffer[3]), i);
				PUT_WORD(&(plci->ncpi_buffer[5]), ((T30_INFO *)plci->NL.RBuffer->P)->data_format);
				plci->ncpi_buffer[7] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_low;
				plci->ncpi_buffer[8] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_high;
				plci->ncpi_buffer[len] = 0;
				if (((T30_INFO *)plci->NL.RBuffer->P)->station_id_len)
				{
					plci->ncpi_buffer[len] = 20;
					for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
						plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i];
				}
				if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
				{
					if (((T30_INFO *)plci->NL.RBuffer->P)->code < ARRAY_SIZE(fax_info))
						info = fax_info[((T30_INFO *)plci->NL.RBuffer->P)->code];
					else
						info = _FAX_PROTOCOL_ERROR;
				}

				if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
				    & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
				{
					i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
					while (i < plci->NL.RBuffer->length)
						plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
				}

				plci->ncpi_buffer[0] = len;
				fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low);
				PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low, fax_feature_bits);

				plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND;
				if (((plci->NL.Ind & 0x0f) == N_CONNECT_ACK)
				    || (((plci->NL.Ind & 0x0f) == N_CONNECT)
					&& (fax_feature_bits & T30_FEATURE_BIT_POLLING))
				    || (((plci->NL.Ind & 0x0f) == N_EDATA)
					&& ((((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_TRAIN_OK)
					    || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS)
					    || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DTC))))
				{
					plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT;
				}
				if (((plci->NL.Ind & 0x0f) == N_DISC)
				    || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)
				    || (((plci->NL.Ind & 0x0f) == N_EDATA)
					&& (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_EOP_CAPI)))
				{
					plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
				}
			}
			break;

		case B3_RTP:
			if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
			{
				if (plci->NL.RLength != 0)
				{
					info = rtp_info[plci->NL.RBuffer->P[0]];
					plci->ncpi_buffer[0] = plci->NL.RLength - 1;
					for (i = 1; i < plci->NL.RLength; i++)
						plci->ncpi_buffer[i] = plci->NL.RBuffer->P[i];
				}
			}
			break;

		}
		plci->NL.RNR = 2;
	}
	switch (plci->NL.Ind & 0x0f) {
	case N_EDATA:
		if ((plci->B3_prot == 4) || (plci->B3_prot == 5))
		{
			dbug(1, dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci, a->ncci_state[ncci],
					((T30_INFO *)plci->NL.RBuffer->P)->code));
			fax_send_edata_ack = (((T30_INFO *)(plci->fax_connect_info_buffer))->operating_mode == T30_OPERATING_MODE_CAPI_NEG);

			if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
			    && (plci->nsf_control_bits & (T30_NSF_CONTROL_BIT_NEGOTIATE_IND | T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
			    && (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS)
			    && (a->ncci_state[ncci] == OUTG_CON_PENDING)
			    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
			    && !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
			{
				((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code;
				sendf(plci->appl, _MANUFACTURER_I, Id, 0, "dwbS", _DI_MANU_ID, _DI_NEGOTIATE_B3,
				      (byte)(plci->ncpi_buffer[0] + 1), plci->ncpi_buffer);
				plci->ncpi_state |= NCPI_NEGOTIATE_B3_SENT;
				if (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)
					fax_send_edata_ack = false;
			}

			if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
			{
				switch (((T30_INFO *)plci->NL.RBuffer->P)->code)
				{
				case EDATA_T30_DIS:
					if ((a->ncci_state[ncci] == OUTG_CON_PENDING)
					    && !(GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) & T30_CONTROL_BIT_REQUEST_POLLING)
					    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
					    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
					{
						a->ncci_state[ncci] = INC_ACT_PENDING;
						if (plci->B3_prot == 4)
							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
						else
							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
						plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
					}
					break;

				case EDATA_T30_TRAIN_OK:
					if ((a->ncci_state[ncci] == INC_ACT_PENDING)
					    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
					    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
					{
						if (plci->B3_prot == 4)
							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
						else
							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
						plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
					}
					break;

				case EDATA_T30_EOP_CAPI:
					if (a->ncci_state[ncci] == CONNECTED)
					{
						sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", GOOD, plci->ncpi_buffer);
						a->ncci_state[ncci] = INC_DIS_PENDING;
						plci->ncpi_state = 0;
						fax_send_edata_ack = false;
					}
					break;
				}
			}
			else
			{
				switch (((T30_INFO *)plci->NL.RBuffer->P)->code)
				{
				case EDATA_T30_TRAIN_OK:
					if ((a->ncci_state[ncci] == INC_ACT_PENDING)
					    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
					    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
					{
						if (plci->B3_prot == 4)
							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
						else
							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
						plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
					}
					break;
				}
			}
			if (fax_send_edata_ack)
			{
				((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code;
				plci->fax_edata_ack_length = 1;
				start_internal_command(Id, plci, fax_edata_ack_command);
			}
		}
		else
		{
			dbug(1, dprintf("EDATA ncci=0x%x state=%d", ncci, a->ncci_state[ncci]));
		}
		break;
	case N_CONNECT:
		if (!a->ch_ncci[ch])
		{
			ncci = get_ncci(plci, ch, 0);
			Id = (Id & 0xffff) | (((dword) ncci) << 16);
		}
		dbug(1, dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d",
				ch, a->ncci_state[ncci], a->ncci_plci[ncci], plci->Id, plci->State));

		msg = _CONNECT_B3_I;
		if (a->ncci_state[ncci] == IDLE)
			plci->channels++;
		else if (plci->B3_prot == 1)
			msg = _CONNECT_B3_T90_ACTIVE_I;

		a->ncci_state[ncci] = INC_CON_PENDING;
		if (plci->B3_prot == 4)
			sendf(plci->appl, msg, Id, 0, "s", "");
		else
			sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
		break;
	case N_CONNECT_ACK:
		dbug(1, dprintf("N_connect_Ack"));
		if (plci->internal_command_queue[0]
		    && ((plci->adjust_b_state == ADJUST_B_CONNECT_2)
			|| (plci->adjust_b_state == ADJUST_B_CONNECT_3)
			|| (plci->adjust_b_state == ADJUST_B_CONNECT_4)))
		{
			(*(plci->internal_command_queue[0]))(Id, plci, 0);
			if (!plci->internal_command)
				next_internal_command(Id, plci);
			break;
		}
		msg = _CONNECT_B3_ACTIVE_I;
		if (plci->B3_prot == 1)
		{
			if (a->ncci_state[ncci] != OUTG_CON_PENDING)
				msg = _CONNECT_B3_T90_ACTIVE_I;
			a->ncci_state[ncci] = INC_ACT_PENDING;
			sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
		}
		else if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
		{
			if ((a->ncci_state[ncci] == OUTG_CON_PENDING)
			    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
			    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
			{
				a->ncci_state[ncci] = INC_ACT_PENDING;
				if (plci->B3_prot == 4)
					sendf(plci->appl, msg, Id, 0, "s", "");
				else
					sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
				plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
			}
		}
		else
		{
			a->ncci_state[ncci] = INC_ACT_PENDING;
			sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
		}
		if (plci->adjust_b_restore)
		{
			plci->adjust_b_restore = false;
			start_internal_command(Id, plci, adjust_b_restore);
		}
		break;
	case N_DISC:
	case N_DISC_ACK:
		if (plci->internal_command_queue[0]
		    && ((plci->internal_command == FAX_DISCONNECT_COMMAND_1)
			|| (plci->internal_command == FAX_DISCONNECT_COMMAND_2)
			|| (plci->internal_command == FAX_DISCONNECT_COMMAND_3)))
		{
			(*(plci->internal_command_queue[0]))(Id, plci, 0);
			if (!plci->internal_command)
				next_internal_command(Id, plci);
		}
		ncci_state = a->ncci_state[ncci];
		ncci_remove(plci, ncci, false);

		/* with N_DISC or N_DISC_ACK the IDI frees the respective   */
		/* channel, so we cannot store the state in ncci_state! The */
		/* information which channel we received a N_DISC is thus   */
		/* stored in the inc_dis_ncci_table buffer.                 */
		for (i = 0; plci->inc_dis_ncci_table[i]; i++);
		plci->inc_dis_ncci_table[i] = (byte) ncci;

		/* need a connect_b3_ind before a disconnect_b3_ind with FAX */
		if (!plci->channels
		    && (plci->B1_resource == 16)
		    && (plci->State <= CONNECTED))
		{
			len = 9;
			i = ((T30_INFO *)plci->fax_connect_info_buffer)->rate_div_2400 * 2400;
			PUT_WORD(&plci->ncpi_buffer[1], i);
			PUT_WORD(&plci->ncpi_buffer[3], 0);
			i = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format;
			PUT_WORD(&plci->ncpi_buffer[5], i);
			PUT_WORD(&plci->ncpi_buffer[7], 0);
			plci->ncpi_buffer[len] = 0;
			plci->ncpi_buffer[0] = len;
			if (plci->B3_prot == 4)
				sendf(plci->appl, _CONNECT_B3_I, Id, 0, "s", "");
			else
			{

				if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
				    & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
				{
					plci->ncpi_buffer[++len] = 0;
					plci->ncpi_buffer[++len] = 0;
					plci->ncpi_buffer[++len] = 0;
					plci->ncpi_buffer[0] = len;
				}

				sendf(plci->appl, _CONNECT_B3_I, Id, 0, "S", plci->ncpi_buffer);
			}
			sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", info, plci->ncpi_buffer);
			plci->ncpi_state = 0;
			sig_req(plci, HANGUP, 0);
			send_req(plci);
			plci->State = OUTG_DIS_PENDING;
			/* disc here */
		}
		else if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
			 && ((plci->B3_prot == 4) || (plci->B3_prot == 5))
			 && ((ncci_state == INC_DIS_PENDING) || (ncci_state == IDLE)))
		{
			if (ncci_state == IDLE)
			{
				if (plci->channels)
					plci->channels--;
				if ((plci->State == IDLE || plci->State == SUSPENDING) && !plci->channels) {
					if (plci->State == SUSPENDING) {
						sendf(plci->appl,
						      _FACILITY_I,
						      Id & 0xffffL,
						      0,
						      "ws", (word)3, "\x03\x04\x00\x00");
						sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
					}
					plci_remove(plci);
					plci->State = IDLE;
				}
			}
		}
		else if (plci->channels)
		{
			sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", info, plci->ncpi_buffer);
			plci->ncpi_state = 0;
			if ((ncci_state == OUTG_REJ_PENDING)
			    && ((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)))
			{
				sig_req(plci, HANGUP, 0);
				send_req(plci);
				plci->State = OUTG_DIS_PENDING;
			}
		}
		break;
	case N_RESET:
		a->ncci_state[ncci] = INC_RES_PENDING;
		sendf(plci->appl, _RESET_B3_I, Id, 0, "S", plci->ncpi_buffer);
		break;
	case N_RESET_ACK:
		a->ncci_state[ncci] = CONNECTED;
		sendf(plci->appl, _RESET_B3_I, Id, 0, "S", plci->ncpi_buffer);
		break;

	case N_UDATA:
		if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f))))
		{
			plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3);
			plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE;
			plci->NL.R = plci->RData;
			plci->NL.RNum = 1;
			return;
		}
	case N_BDATA:
	case N_DATA:
		if (((a->ncci_state[ncci] != CONNECTED) && (plci->B2_prot == 1)) /* transparent */
		    || (a->ncci_state[ncci] == IDLE)
		    || (a->ncci_state[ncci] == INC_DIS_PENDING))
		{
			plci->NL.RNR = 2;
			break;
		}
		if ((a->ncci_state[ncci] != CONNECTED)
		    && (a->ncci_state[ncci] != OUTG_DIS_PENDING)
		    && (a->ncci_state[ncci] != OUTG_REJ_PENDING))
		{
			dbug(1, dprintf("flow control"));
			plci->NL.RNR = 1; /* flow control  */
			channel_x_off(plci, ch, 0);
			break;
		}

		NCCIcode = ncci | (((word)a->Id) << 8);

		/* count all buffers within the Application pool    */
		/* belonging to the same NCCI. If this is below the */
		/* number of buffers available per NCCI we accept   */
		/* this packet, otherwise we reject it              */
		count = 0;
		Num = 0xffff;
		for (i = 0; i < APPLptr->MaxBuffer; i++) {
			if (NCCIcode == APPLptr->DataNCCI[i]) count++;
			if (!APPLptr->DataNCCI[i] && Num == 0xffff) Num = i;
		}

		if (count >= APPLptr->MaxNCCIData || Num == 0xffff)
		{
			dbug(3, dprintf("Flow-Control"));
			plci->NL.RNR = 1;
			if (++(APPLptr->NCCIDataFlowCtrlTimer) >=
			    (word)((a->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) ? 40 : 2000))
			{
				plci->NL.RNR = 2;
				dbug(3, dprintf("DiscardData"));
			} else {
				channel_x_off(plci, ch, 0);
			}
			break;
		}
		else
		{
			APPLptr->NCCIDataFlowCtrlTimer = 0;
		}

		plci->RData[0].P = ReceiveBufferGet(APPLptr, Num);
		if (!plci->RData[0].P) {
			plci->NL.RNR = 1;
			channel_x_off(plci, ch, 0);
			break;
		}

		APPLptr->DataNCCI[Num] = NCCIcode;
		APPLptr->DataFlags[Num] = (plci->Id << 8) | (plci->NL.Ind >> 4);
		dbug(3, dprintf("Buffer(%d), Max = %d", Num, APPLptr->MaxBuffer));

		plci->RNum = Num;
		plci->RFlags = plci->NL.Ind >> 4;
		plci->RData[0].PLength = APPLptr->MaxDataLength;
		plci->NL.R = plci->RData;
		if ((plci->NL.RLength != 0)
		    && ((plci->B2_prot == B2_V120_ASYNC)
			|| (plci->B2_prot == B2_V120_ASYNC_V42BIS)
			|| (plci->B2_prot == B2_V120_BIT_TRANSPARENT)))
		{
			plci->RData[1].P = plci->RData[0].P;
			plci->RData[1].PLength = plci->RData[0].PLength;
			plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3);
			if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1))
				plci->RData[0].PLength = 1;
			else
				plci->RData[0].PLength = 2;
			if (plci->NL.RBuffer->P[0] & V120_HEADER_BREAK_BIT)
				plci->RFlags |= 0x0010;
			if (plci->NL.RBuffer->P[0] & (V120_HEADER_C1_BIT | V120_HEADER_C2_BIT))
				plci->RFlags |= 0x8000;
			plci->NL.RNum = 2;
		}
		else
		{
			if ((plci->NL.Ind & 0x0f) == N_UDATA)
				plci->RFlags |= 0x0010;

			else if ((plci->B3_prot == B3_RTP) && ((plci->NL.Ind & 0x0f) == N_BDATA))
				plci->RFlags |= 0x0001;

			plci->NL.RNum = 1;
		}
		break;
	case N_DATA_ACK:
		data_ack(plci, ch);
		break;
	default:
		plci->NL.RNR = 2;
		break;
	}
}

/*------------------------------------------------------------------*/
/* find a free PLCI */
/*------------------------------------------------------------------*/

static word get_plci(DIVA_CAPI_ADAPTER *a)
{
	word i, j;
	PLCI *plci;

	dump_plcis(a);
	for (i = 0; i < a->max_plci && a->plci[i].Id; i++);
	if (i == a->max_plci) {
		dbug(1, dprintf("get_plci: out of PLCIs"));
		return 0;
	}
	plci = &a->plci[i];
	plci->Id = (byte)(i + 1);

	plci->Sig.Id = 0;
	plci->NL.Id = 0;
	plci->sig_req = 0;
	plci->nl_req = 0;

	plci->appl = NULL;
	plci->relatedPTYPLCI = NULL;
	plci->State = IDLE;
	plci->SuppState = IDLE;
	plci->channels = 0;
	plci->tel = 0;
	plci->B1_resource = 0;
	plci->B2_prot = 0;
	plci->B3_prot = 0;

	plci->command = 0;
	plci->m_command = 0;
	init_internal_command_queue(plci);
	plci->number = 0;
	plci->req_in_start = 0;
	plci->req_in = 0;
	plci->req_out = 0;
	plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
	plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
	plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;

	plci->data_sent = false;
	plci->send_disc = 0;
	plci->sig_global_req = 0;
	plci->sig_remove_id = 0;
	plci->nl_global_req = 0;
	plci->nl_remove_id = 0;
	plci->adv_nl = 0;
	plci->manufacturer = false;
	plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
	plci->spoofed_msg = 0;
	plci->ptyState = 0;
	plci->cr_enquiry = false;
	plci->hangup_flow_ctrl_timer = 0;

	plci->ncci_ring_list = 0;
	for (j = 0; j < MAX_CHANNELS_PER_PLCI; j++) plci->inc_dis_ncci_table[j] = 0;
	clear_c_ind_mask(plci);
	set_group_ind_mask(plci);
	plci->fax_connect_info_length = 0;
	plci->nsf_control_bits = 0;
	plci->ncpi_state = 0x00;
	plci->ncpi_buffer[0] = 0;

	plci->requested_options_conn = 0;
	plci->requested_options = 0;
	plci->notifiedcall = 0;
	plci->vswitchstate = 0;
	plci->vsprot = 0;
	plci->vsprotdialect = 0;
	init_b1_config(plci);
	dbug(1, dprintf("get_plci(%x)", plci->Id));
	return i + 1;
}

/*------------------------------------------------------------------*/
/* put a parameter in the parameter buffer                          */
/*------------------------------------------------------------------*/

static void add_p(PLCI *plci, byte code, byte *p)
{
	word p_length;

	p_length = 0;
	if (p) p_length = p[0];
	add_ie(plci, code, p, p_length);
}

/*------------------------------------------------------------------*/
/* put a structure in the parameter buffer                          */
/*------------------------------------------------------------------*/
static void add_s(PLCI *plci, byte code, API_PARSE *p)
{
	if (p) add_ie(plci, code, p->info, (word)p->length);
}

/*------------------------------------------------------------------*/
/* put multiple structures in the parameter buffer                  */
/*------------------------------------------------------------------*/
static void add_ss(PLCI *plci, byte code, API_PARSE *p)
{
	byte i;

	if (p) {
		dbug(1, dprintf("add_ss(%x,len=%d)", code, p->length));
		for (i = 2; i < (byte)p->length; i += p->info[i] + 2) {
			dbug(1, dprintf("add_ss_ie(%x,len=%d)", p->info[i - 1], p->info[i]));
			add_ie(plci, p->info[i - 1], (byte *)&(p->info[i]), (word)p->info[i]);
		}
	}
}

/*------------------------------------------------------------------*/
/* return the channel number sent by the application in a esc_chi   */
/*------------------------------------------------------------------*/
static byte getChannel(API_PARSE *p)
{
	byte i;

	if (p) {
		for (i = 2; i < (byte)p->length; i += p->info[i] + 2) {
			if (p->info[i] == 2) {
				if (p->info[i - 1] == ESC && p->info[i + 1] == CHI) return (p->info[i + 2]);
			}
		}
	}
	return 0;
}


/*------------------------------------------------------------------*/
/* put an information element in the parameter buffer               */
/*------------------------------------------------------------------*/

static void add_ie(PLCI *plci, byte code, byte *p, word p_length)
{
	word i;

	if (!(code & 0x80) && !p_length) return;

	if (plci->req_in == plci->req_in_start) {
		plci->req_in += 2;
	}
	else {
		plci->req_in--;
	}
	plci->RBuffer[plci->req_in++] = code;

	if (p) {
		plci->RBuffer[plci->req_in++] = (byte)p_length;
		for (i = 0; i < p_length; i++) plci->RBuffer[plci->req_in++] = p[1 + i];
	}

	plci->RBuffer[plci->req_in++] = 0;
}

/*------------------------------------------------------------------*/
/* put a unstructured data into the buffer                          */
/*------------------------------------------------------------------*/

static void add_d(PLCI *plci, word length, byte *p)
{
	word i;

	if (plci->req_in == plci->req_in_start) {
		plci->req_in += 2;
	}
	else {
		plci->req_in--;
	}
	for (i = 0; i < length; i++) plci->RBuffer[plci->req_in++] = p[i];
}

/*------------------------------------------------------------------*/
/* put parameters from the Additional Info parameter in the         */
/* parameter buffer                                                 */
/*------------------------------------------------------------------*/

static void add_ai(PLCI *plci, API_PARSE *ai)
{
	word i;
	API_PARSE ai_parms[5];

	for (i = 0; i < 5; i++) ai_parms[i].length = 0;

	if (!ai->length)
		return;
	if (api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
		return;

	add_s(plci, KEY, &ai_parms[1]);
	add_s(plci, UUI, &ai_parms[2]);
	add_ss(plci, FTY, &ai_parms[3]);
}

/*------------------------------------------------------------------*/
/* put parameter for b1 protocol in the parameter buffer            */
/*------------------------------------------------------------------*/

static word add_b1(PLCI *plci, API_PARSE *bp, word b_channel_info,
		   word b1_facilities)
{
	API_PARSE bp_parms[8];
	API_PARSE mdm_cfg[9];
	API_PARSE global_config[2];
	byte cai[256];
	byte resource[] = {5, 9, 13, 12, 16, 39, 9, 17, 17, 18};
	byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08";
	word i;

	API_PARSE mdm_cfg_v18[4];
	word j, n, w;
	dword d;


	for (i = 0; i < 8; i++) bp_parms[i].length = 0;
	for (i = 0; i < 2; i++) global_config[i].length = 0;

	dbug(1, dprintf("add_b1"));
	api_save_msg(bp, "s", &plci->B_protocol);

	if (b_channel_info == 2) {
		plci->B1_resource = 0;
		adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
		add_p(plci, CAI, "\x01\x00");
		dbug(1, dprintf("Cai=1,0 (no resource)"));
		return 0;
	}

	if (plci->tel == CODEC_PERMANENT) return 0;
	else if (plci->tel == CODEC) {
		plci->B1_resource = 1;
		adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
		add_p(plci, CAI, "\x01\x01");
		dbug(1, dprintf("Cai=1,1 (Codec)"));
		return 0;
	}
	else if (plci->tel == ADV_VOICE) {
		plci->B1_resource = add_b1_facilities(plci, 9, (word)(b1_facilities | B1_FACILITY_VOICE));
		adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities | B1_FACILITY_VOICE));
		voice_cai[1] = plci->B1_resource;
		PUT_WORD(&voice_cai[5], plci->appl->MaxDataLength);
		add_p(plci, CAI, voice_cai);
		dbug(1, dprintf("Cai=1,0x%x (AdvVoice)", voice_cai[1]));
		return 0;
	}
	plci->call_dir &= ~(CALL_DIR_ORIGINATE | CALL_DIR_ANSWER);
	if (plci->call_dir & CALL_DIR_OUT)
		plci->call_dir |= CALL_DIR_ORIGINATE;
	else if (plci->call_dir & CALL_DIR_IN)
		plci->call_dir |= CALL_DIR_ANSWER;

	if (!bp->length) {
		plci->B1_resource = 0x5;
		adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
		add_p(plci, CAI, "\x01\x05");
		return 0;
	}

	dbug(1, dprintf("b_prot_len=%d", (word)bp->length));
	if (bp->length > 256) return _WRONG_MESSAGE_FORMAT;
	if (api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
	{
		bp_parms[6].length = 0;
		if (api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
		{
			dbug(1, dprintf("b-form.!"));
			return _WRONG_MESSAGE_FORMAT;
		}
	}
	else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
	{
		dbug(1, dprintf("b-form.!"));
		return _WRONG_MESSAGE_FORMAT;
	}

	if (bp_parms[6].length)
	{
		if (api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
		{
			return _WRONG_MESSAGE_FORMAT;
		}
		switch (GET_WORD(global_config[0].info))
		{
		case 1:
			plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
			break;
		case 2:
			plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
			break;
		}
	}
	dbug(1, dprintf("call_dir=%04x", plci->call_dir));


	if ((GET_WORD(bp_parms[0].info) == B1_RTP)
	    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
	{
		plci->B1_resource = add_b1_facilities(plci, 31, (word)(b1_facilities & ~B1_FACILITY_VOICE));
		adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
		cai[1] = plci->B1_resource;
		cai[2] = 0;
		cai[3] = 0;
		cai[4] = 0;
		PUT_WORD(&cai[5], plci->appl->MaxDataLength);
		for (i = 0; i < bp_parms[3].length; i++)
			cai[7 + i] = bp_parms[3].info[1 + i];
		cai[0] = 6 + bp_parms[3].length;
		add_p(plci, CAI, cai);
		return 0;
	}


	if ((GET_WORD(bp_parms[0].info) == B1_PIAFS)
	    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))
	{
		plci->B1_resource = add_b1_facilities(plci, 35/* PIAFS HARDWARE FACILITY */, (word)(b1_facilities & ~B1_FACILITY_VOICE));
		adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
		cai[1] = plci->B1_resource;
		cai[2] = 0;
		cai[3] = 0;
		cai[4] = 0;
		PUT_WORD(&cai[5], plci->appl->MaxDataLength);
		cai[0] = 6;
		add_p(plci, CAI, cai);
		return 0;
	}


	if ((GET_WORD(bp_parms[0].info) >= 32)
	    || (!((1L << GET_WORD(bp_parms[0].info)) & plci->adapter->profile.B1_Protocols)
		&& ((GET_WORD(bp_parms[0].info) != 3)
		    || !((1L << B1_HDLC) & plci->adapter->profile.B1_Protocols)
		    || ((bp_parms[3].length != 0) && (GET_WORD(&bp_parms[3].info[1]) != 0) && (GET_WORD(&bp_parms[3].info[1]) != 56000)))))
	{
		return _B1_NOT_SUPPORTED;
	}
	plci->B1_resource = add_b1_facilities(plci, resource[GET_WORD(bp_parms[0].info)],
					      (word)(b1_facilities & ~B1_FACILITY_VOICE));
	adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
	cai[0] = 6;
	cai[1] = plci->B1_resource;
	for (i = 2; i < sizeof(cai); i++) cai[i] = 0;

	if ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
	    || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
	    || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC))
	{ /* B1 - modem */
		for (i = 0; i < 7; i++) mdm_cfg[i].length = 0;

		if (bp_parms[3].length)
		{
			if (api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwww", mdm_cfg))
			{
				return (_WRONG_MESSAGE_FORMAT);
			}

			cai[2] = 0; /* Bit rate for adaptation */

			dbug(1, dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg[0].info)));

			PUT_WORD(&cai[13], 0);                          /* Min Tx speed */
			PUT_WORD(&cai[15], GET_WORD(mdm_cfg[0].info)); /* Max Tx speed */
			PUT_WORD(&cai[17], 0);                          /* Min Rx speed */
			PUT_WORD(&cai[19], GET_WORD(mdm_cfg[0].info)); /* Max Rx speed */

			cai[3] = 0; /* Async framing parameters */
			switch (GET_WORD(mdm_cfg[2].info))
			{       /* Parity     */
			case 1: /* odd parity */
				cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
				dbug(1, dprintf("MDM: odd parity"));
				break;

			case 2: /* even parity */
				cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
				dbug(1, dprintf("MDM: even parity"));
				break;

			default:
				dbug(1, dprintf("MDM: no parity"));
				break;
			}

			switch (GET_WORD(mdm_cfg[3].info))
			{       /* stop bits   */
			case 1: /* 2 stop bits */
				cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
				dbug(1, dprintf("MDM: 2 stop bits"));
				break;

			default:
				dbug(1, dprintf("MDM: 1 stop bit"));
				break;
			}

			switch (GET_WORD(mdm_cfg[1].info))
			{     /* char length */
			case 5:
				cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
				dbug(1, dprintf("MDM: 5 bits"));
				break;

			case 6:
				cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
				dbug(1, dprintf("MDM: 6 bits"));
				break;

			case 7:
				cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
				dbug(1, dprintf("MDM: 7 bits"));
				break;

			default:
				dbug(1, dprintf("MDM: 8 bits"));
				break;
			}

			cai[7] = 0; /* Line taking options */
			cai[8] = 0; /* Modulation negotiation options */
			cai[9] = 0; /* Modulation options */

			if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0))
			{
				cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION;
				dbug(1, dprintf("MDM: Reverse direction"));
			}

			if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN)
			{
				cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN;
				dbug(1, dprintf("MDM: Disable retrain"));
			}

			if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE)
			{
				cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE;
				dbug(1, dprintf("MDM: Disable ring tone"));
			}

			if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_GUARD_1800)
			{
				cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ;
				dbug(1, dprintf("MDM: 1800 guard tone"));
			}
			else if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_GUARD_550)
			{
				cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ;
				dbug(1, dprintf("MDM: 550 guard tone"));
			}

			if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100)
			{
				cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100;
				dbug(1, dprintf("MDM: V100"));
			}
			else if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS)
			{
				cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS;
				dbug(1, dprintf("MDM: IN CLASS"));
			}
			else if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED)
			{
				cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED;
				dbug(1, dprintf("MDM: DISABLED"));
			}
			cai[0] = 20;

			if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18))
			    && (GET_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */
			{
				plci->requested_options |= 1L << PRIVATE_V18;
			}
			if (GET_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */
				plci->requested_options |= 1L << PRIVATE_VOWN;

			if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
			    & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
			{
				if (!api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwwws", mdm_cfg))
				{
					i = 27;
					if (mdm_cfg[6].length >= 4)
					{
						d = GET_DWORD(&mdm_cfg[6].info[1]);
						cai[7] |= (byte) d;          /* line taking options */
						cai[9] |= (byte)(d >> 8);    /* modulation options */
						cai[++i] = (byte)(d >> 16);  /* vown modulation options */
						cai[++i] = (byte)(d >> 24);
						if (mdm_cfg[6].length >= 8)
						{
							d = GET_DWORD(&mdm_cfg[6].info[5]);
							cai[10] |= (byte) d;        /* disabled modulations mask */
							cai[11] |= (byte)(d >> 8);
							if (mdm_cfg[6].length >= 12)
							{
								d = GET_DWORD(&mdm_cfg[6].info[9]);
								cai[12] = (byte) d;          /* enabled modulations mask */
								cai[++i] = (byte)(d >> 8);   /* vown enabled modulations */
								cai[++i] = (byte)(d >> 16);
								cai[++i] = (byte)(d >> 24);
								cai[++i] = 0;
								if (mdm_cfg[6].length >= 14)
								{
									w = GET_WORD(&mdm_cfg[6].info[13]);
									if (w != 0)
										PUT_WORD(&cai[13], w);  /* min tx speed */
									if (mdm_cfg[6].length >= 16)
									{
										w = GET_WORD(&mdm_cfg[6].info[15]);
										if (w != 0)
											PUT_WORD(&cai[15], w);  /* max tx speed */
										if (mdm_cfg[6].length >= 18)
										{
											w = GET_WORD(&mdm_cfg[6].info[17]);
											if (w != 0)
												PUT_WORD(&cai[17], w);  /* min rx speed */
											if (mdm_cfg[6].length >= 20)
											{
												w = GET_WORD(&mdm_cfg[6].info[19]);
												if (w != 0)
													PUT_WORD(&cai[19], w);  /* max rx speed */
												if (mdm_cfg[6].length >= 22)
												{
													w = GET_WORD(&mdm_cfg[6].info[21]);
													cai[23] = (byte)(-((short) w));  /* transmit level */
													if (mdm_cfg[6].length >= 24)
													{
														w = GET_WORD(&mdm_cfg[6].info[23]);
														cai[22] |= (byte) w;        /* info options mask */
														cai[21] |= (byte)(w >> 8);  /* disabled symbol rates */
													}
												}
											}
										}
									}
								}
							}
						}
					}
					cai[27] = i - 27;
					i++;
					if (!api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwwwss", mdm_cfg))
					{
						if (!api_parse(&mdm_cfg[7].info[1], (word)mdm_cfg[7].length, "sss", mdm_cfg_v18))
						{
							for (n = 0; n < 3; n++)
							{
								cai[i] = (byte)(mdm_cfg_v18[n].length);
								for (j = 1; j < ((word)(cai[i] + 1)); j++)
									cai[i + j] = mdm_cfg_v18[n].info[j];
								i += cai[i] + 1;
							}
						}
					}
					cai[0] = (byte)(i - 1);
				}
			}

		}
	}
	if (GET_WORD(bp_parms[0].info) == 2 ||                         /* V.110 async */
	    GET_WORD(bp_parms[0].info) == 3)                           /* V.110 sync */
	{
		if (bp_parms[3].length) {
			dbug(1, dprintf("V.110,%d", GET_WORD(&bp_parms[3].info[1])));
			switch (GET_WORD(&bp_parms[3].info[1])) {                 /* Rate */
			case 0:
			case 56000:
				if (GET_WORD(bp_parms[0].info) == 3) {                  /* V.110 sync 56k */
					dbug(1, dprintf("56k sync HSCX"));
					cai[1] = 8;
					cai[2] = 0;
					cai[3] = 0;
				}
				else if (GET_WORD(bp_parms[0].info) == 2) {
					dbug(1, dprintf("56k async DSP"));
					cai[2] = 9;
				}
				break;
			case 50:     cai[2] = 1;  break;
			case 75:     cai[2] = 1;  break;
			case 110:    cai[2] = 1;  break;
			case 150:    cai[2] = 1;  break;
			case 200:    cai[2] = 1;  break;
			case 300:    cai[2] = 1;  break;
			case 600:    cai[2] = 1;  break;
			case 1200:   cai[2] = 2;  break;
			case 2400:   cai[2] = 3;  break;
			case 4800:   cai[2] = 4;  break;
			case 7200:   cai[2] = 10; break;
			case 9600:   cai[2] = 5;  break;
			case 12000:  cai[2] = 13; break;
			case 24000:  cai[2] = 0;  break;
			case 14400:  cai[2] = 11; break;
			case 19200:  cai[2] = 6;  break;
			case 28800:  cai[2] = 12; break;
			case 38400:  cai[2] = 7;  break;
			case 48000:  cai[2] = 8;  break;
			case 76:     cai[2] = 15; break;  /* 75/1200     */
			case 1201:   cai[2] = 14; break;  /* 1200/75     */
			case 56001:  cai[2] = 9;  break;  /* V.110 56000 */

			default:
				return _B1_PARM_NOT_SUPPORTED;
			}
			cai[3] = 0;
			if (cai[1] == 13)                                        /* v.110 async */
			{
				if (bp_parms[3].length >= 8)
				{
					switch (GET_WORD(&bp_parms[3].info[3]))
					{       /* char length */
					case 5:
						cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
						break;
					case 6:
						cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
						break;
					case 7:
						cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
						break;
					}
					switch (GET_WORD(&bp_parms[3].info[5]))
					{       /* Parity     */
					case 1: /* odd parity */
						cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
						break;
					case 2: /* even parity */
						cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
						break;
					}
					switch (GET_WORD(&bp_parms[3].info[7]))
					{       /* stop bits   */
					case 1: /* 2 stop bits */
						cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
						break;
					}
				}
			}
		}
		else if (cai[1] == 8 || GET_WORD(bp_parms[0].info) == 3) {
			dbug(1, dprintf("V.110 default 56k sync"));
			cai[1] = 8;
			cai[2] = 0;
			cai[3] = 0;
		}
		else {
			dbug(1, dprintf("V.110 default 9600 async"));
			cai[2] = 5;
		}
	}
	PUT_WORD(&cai[5], plci->appl->MaxDataLength);
	dbug(1, dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6]));
/* HexDump ("CAI", sizeof(cai), &cai[0]); */

	add_p(plci, CAI, cai);
	return 0;
}

/*------------------------------------------------------------------*/
/* put parameter for b2 and B3  protocol in the parameter buffer    */
/*------------------------------------------------------------------*/

static word add_b23(PLCI *plci, API_PARSE *bp)
{
	word i, fax_control_bits;
	byte pos, len;
	byte SAPI = 0x40;  /* default SAPI 16 for x.31 */
	API_PARSE bp_parms[8];
	API_PARSE *b1_config;
	API_PARSE *b2_config;
	API_PARSE b2_config_parms[8];
	API_PARSE *b3_config;
	API_PARSE b3_config_parms[6];
	API_PARSE global_config[2];

	static byte llc[3] = {2,0,0};
	static byte dlc[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	static byte nlc[256];
	static byte lli[12] = {1,1};

	const byte llc2_out[] = {1,2,4,6,2,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6};
	const byte llc2_in[]  = {1,3,4,6,3,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6};

	const byte llc3[] = {4,3,2,2,6,6,0};
	const byte header[] = {0,2,3,3,0,0,0};

	for (i = 0; i < 8; i++) bp_parms[i].length = 0;
	for (i = 0; i < 6; i++) b2_config_parms[i].length = 0;
	for (i = 0; i < 5; i++) b3_config_parms[i].length = 0;

	lli[0] = 1;
	lli[1] = 1;
	if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
		lli[1] |= 2;
	if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
		lli[1] |= 4;

	if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
		lli[1] |= 0x10;
		if (plci->rx_dma_descriptor <= 0) {
			plci->rx_dma_descriptor = diva_get_dma_descriptor(plci, &plci->rx_dma_magic);
			if (plci->rx_dma_descriptor >= 0)
				plci->rx_dma_descriptor++;
		}
		if (plci->rx_dma_descriptor > 0) {
			lli[0] = 6;
			lli[1] |= 0x40;
			lli[2] = (byte)(plci->rx_dma_descriptor - 1);
			lli[3] = (byte)plci->rx_dma_magic;
			lli[4] = (byte)(plci->rx_dma_magic >>  8);
			lli[5] = (byte)(plci->rx_dma_magic >> 16);
			lli[6] = (byte)(plci->rx_dma_magic >> 24);
		}
	}

	if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
		lli[1] |= 0x20;
	}

	dbug(1, dprintf("add_b23"));
	api_save_msg(bp, "s", &plci->B_protocol);

	if (!bp->length && plci->tel)
	{
		plci->adv_nl = true;
		dbug(1, dprintf("Default adv.Nl"));
		add_p(plci, LLI, lli);
		plci->B2_prot = 1 /*XPARENT*/;
		plci->B3_prot = 0 /*XPARENT*/;
		llc[1] = 2;
		llc[2] = 4;
		add_p(plci, LLC, llc);
		dlc[0] = 2;
		PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
		add_p(plci, DLC, dlc);
		return 0;
	}

	if (!bp->length) /*default*/
	{
		dbug(1, dprintf("ret default"));
		add_p(plci, LLI, lli);
		plci->B2_prot = 0 /*X.75   */;
		plci->B3_prot = 0 /*XPARENT*/;
		llc[1] = 1;
		llc[2] = 4;
		add_p(plci, LLC, llc);
		dlc[0] = 2;
		PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
		add_p(plci, DLC, dlc);
		return 0;
	}
	dbug(1, dprintf("b_prot_len=%d", (word)bp->length));
	if ((word)bp->length > 256)    return _WRONG_MESSAGE_FORMAT;

	if (api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
	{
		bp_parms[6].length = 0;
		if (api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
		{
			dbug(1, dprintf("b-form.!"));
			return _WRONG_MESSAGE_FORMAT;
		}
	}
	else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
	{
		dbug(1, dprintf("b-form.!"));
		return _WRONG_MESSAGE_FORMAT;
	}

	if (plci->tel == ADV_VOICE) /* transparent B on advanced voice */
	{
		if (GET_WORD(bp_parms[1].info) != 1
		    || GET_WORD(bp_parms[2].info) != 0) return _B2_NOT_SUPPORTED;
		plci->adv_nl = true;
	}
	else if (plci->tel) return _B2_NOT_SUPPORTED;


	if ((GET_WORD(bp_parms[1].info) == B2_RTP)
	    && (GET_WORD(bp_parms[2].info) == B3_RTP)
	    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
	{
		add_p(plci, LLI, lli);
		plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
		plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
		llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? 14 : 13;
		llc[2] = 4;
		add_p(plci, LLC, llc);
		dlc[0] = 2;
		PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
		dlc[3] = 3; /* Addr A */
		dlc[4] = 1; /* Addr B */
		dlc[5] = 7; /* modulo mode */
		dlc[6] = 7; /* window size */
		dlc[7] = 0; /* XID len Lo  */
		dlc[8] = 0; /* XID len Hi  */
		for (i = 0; i < bp_parms[4].length; i++)
			dlc[9 + i] = bp_parms[4].info[1 + i];
		dlc[0] = (byte)(8 + bp_parms[4].length);
		add_p(plci, DLC, dlc);
		for (i = 0; i < bp_parms[5].length; i++)
			nlc[1 + i] = bp_parms[5].info[1 + i];
		nlc[0] = (byte)(bp_parms[5].length);
		add_p(plci, NLC, nlc);
		return 0;
	}



	if ((GET_WORD(bp_parms[1].info) >= 32)
	    || (!((1L << GET_WORD(bp_parms[1].info)) & plci->adapter->profile.B2_Protocols)
		&& ((GET_WORD(bp_parms[1].info) != B2_PIAFS)
		    || !(plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))))

	{
		return _B2_NOT_SUPPORTED;
	}
	if ((GET_WORD(bp_parms[2].info) >= 32)
	    || !((1L << GET_WORD(bp_parms[2].info)) & plci->adapter->profile.B3_Protocols))
	{
		return _B3_NOT_SUPPORTED;
	}
	if ((GET_WORD(bp_parms[1].info) != B2_SDLC)
	    && ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
		|| (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
		|| (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC)))
	{
		return (add_modem_b23(plci, bp_parms));
	}

	add_p(plci, LLI, lli);

	plci->B2_prot = (byte)GET_WORD(bp_parms[1].info);
	plci->B3_prot = (byte)GET_WORD(bp_parms[2].info);
	if (plci->B2_prot == 12) SAPI = 0; /* default SAPI D-channel */

	if (bp_parms[6].length)
	{
		if (api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
		{
			return _WRONG_MESSAGE_FORMAT;
		}
		switch (GET_WORD(global_config[0].info))
		{
		case 1:
			plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
			break;
		case 2:
			plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
			break;
		}
	}
	dbug(1, dprintf("call_dir=%04x", plci->call_dir));


	if (plci->B2_prot == B2_PIAFS)
		llc[1] = PIAFS_CRC;
	else
/* IMPLEMENT_PIAFS */
	{
		llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ?
			llc2_out[GET_WORD(bp_parms[1].info)] : llc2_in[GET_WORD(bp_parms[1].info)];
	}
	llc[2] = llc3[GET_WORD(bp_parms[2].info)];

	add_p(plci, LLC, llc);

	dlc[0] = 2;
	PUT_WORD(&dlc[1], plci->appl->MaxDataLength +
		 header[GET_WORD(bp_parms[2].info)]);

	b1_config = &bp_parms[3];
	nlc[0] = 0;
	if (plci->B3_prot == 4
	    || plci->B3_prot == 5)
	{
		for (i = 0; i < sizeof(T30_INFO); i++) nlc[i] = 0;
		nlc[0] = sizeof(T30_INFO);
		if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
			((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI;
		((T30_INFO *)&nlc[1])->rate_div_2400 = 0xff;
		if (b1_config->length >= 2)
		{
			((T30_INFO *)&nlc[1])->rate_div_2400 = (byte)(GET_WORD(&b1_config->info[1]) / 2400);
		}
	}
	b2_config = &bp_parms[4];


	if (llc[1] == PIAFS_CRC)
	{
		if (plci->B3_prot != B3_TRANSPARENT)
		{
			return _B_STACK_NOT_SUPPORTED;
		}
		if (b2_config->length && api_parse(&b2_config->info[1], (word)b2_config->length, "bwww", b2_config_parms)) {
			return _WRONG_MESSAGE_FORMAT;
		}
		PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
		dlc[3] = 0; /* Addr A */
		dlc[4] = 0; /* Addr B */
		dlc[5] = 0; /* modulo mode */
		dlc[6] = 0; /* window size */
		if (b2_config->length >= 7) {
			dlc[7] = 7;
			dlc[8] = 0;
			dlc[9] = b2_config_parms[0].info[0]; /* PIAFS protocol Speed configuration */
			dlc[10] = b2_config_parms[1].info[0]; /* V.42bis P0 */
			dlc[11] = b2_config_parms[1].info[1]; /* V.42bis P0 */
			dlc[12] = b2_config_parms[2].info[0]; /* V.42bis P1 */
			dlc[13] = b2_config_parms[2].info[1]; /* V.42bis P1 */
			dlc[14] = b2_config_parms[3].info[0]; /* V.42bis P2 */
			dlc[15] = b2_config_parms[3].info[1]; /* V.42bis P2 */
			dlc[0] = 15;
			if (b2_config->length >= 8) { /* PIAFS control abilities */
				dlc[7] = 10;
				dlc[16] = 2; /* Length of PIAFS extension */
				dlc[17] = PIAFS_UDATA_ABILITIES; /* control (UDATA) ability */
				dlc[18] = b2_config_parms[4].info[0]; /* value */
				dlc[0] = 18;
			}
		}
		else /* default values, 64K, variable, no compression */
		{
			dlc[7] = 7;
			dlc[8] = 0;
			dlc[9] = 0x03; /* PIAFS protocol Speed configuration */
			dlc[10] = 0x03; /* V.42bis P0 */
			dlc[11] = 0;    /* V.42bis P0 */
			dlc[12] = 0;    /* V.42bis P1 */
			dlc[13] = 0;    /* V.42bis P1 */
			dlc[14] = 0;    /* V.42bis P2 */
			dlc[15] = 0;    /* V.42bis P2 */
			dlc[0] = 15;
		}
		add_p(plci, DLC, dlc);
	}
	else

		if ((llc[1] == V120_L2) || (llc[1] == V120_V42BIS))
		{
			if (plci->B3_prot != B3_TRANSPARENT)
				return _B_STACK_NOT_SUPPORTED;

			dlc[0] = 6;
			PUT_WORD(&dlc[1], GET_WORD(&dlc[1]) + 2);
			dlc[3] = 0x08;
			dlc[4] = 0x01;
			dlc[5] = 127;
			dlc[6] = 7;
			if (b2_config->length != 0)
			{
				if ((llc[1] == V120_V42BIS) && api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) {
					return _WRONG_MESSAGE_FORMAT;
				}
				dlc[3] = (byte)((b2_config->info[2] << 3) | ((b2_config->info[1] >> 5) & 0x04));
				dlc[4] = (byte)((b2_config->info[1] << 1) | 0x01);
				if (b2_config->info[3] != 128)
				{
					dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
					return _B2_PARM_NOT_SUPPORTED;
				}
				dlc[5] = (byte)(b2_config->info[3] - 1);
				dlc[6] = b2_config->info[4];
				if (llc[1] == V120_V42BIS) {
					if (b2_config->length >= 10) {
						dlc[7] = 6;
						dlc[8] = 0;
						dlc[9] = b2_config_parms[4].info[0];
						dlc[10] = b2_config_parms[4].info[1];
						dlc[11] = b2_config_parms[5].info[0];
						dlc[12] = b2_config_parms[5].info[1];
						dlc[13] = b2_config_parms[6].info[0];
						dlc[14] = b2_config_parms[6].info[1];
						dlc[0] = 14;
						dbug(1, dprintf("b2_config_parms[4].info[0] [1]:  %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1]));
						dbug(1, dprintf("b2_config_parms[5].info[0] [1]:  %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1]));
						dbug(1, dprintf("b2_config_parms[6].info[0] [1]:  %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1]));
					}
					else {
						dlc[6] = 14;
					}
				}
			}
		}
		else
		{
			if (b2_config->length)
			{
				dbug(1, dprintf("B2-Config"));
				if (llc[1] == X75_V42BIS) {
					if (api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms))
					{
						return _WRONG_MESSAGE_FORMAT;
					}
				}
				else {
					if (api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbs", b2_config_parms))
					{
						return _WRONG_MESSAGE_FORMAT;
					}
				}
				/* if B2 Protocol is LAPD, b2_config structure is different */
				if (llc[1] == 6)
				{
					dlc[0] = 4;
					if (b2_config->length >= 1) dlc[2] = b2_config->info[1];      /* TEI */
					else dlc[2] = 0x01;
					if ((b2_config->length >= 2) && (plci->B2_prot == 12))
					{
						SAPI = b2_config->info[2];    /* SAPI */
					}
					dlc[1] = SAPI;
					if ((b2_config->length >= 3) && (b2_config->info[3] == 128))
					{
						dlc[3] = 127;      /* Mode */
					}
					else
					{
						dlc[3] = 7;        /* Mode */
					}

					if (b2_config->length >= 4) dlc[4] = b2_config->info[4];      /* Window */
					else dlc[4] = 1;
					dbug(1, dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
					if (b2_config->length > 5) return _B2_PARM_NOT_SUPPORTED;
				}
				else
				{
					dlc[0] = (byte)(b2_config_parms[4].length + 6);
					dlc[3] = b2_config->info[1];
					dlc[4] = b2_config->info[2];
					if (b2_config->info[3] != 8 && b2_config->info[3] != 128) {
						dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
						return _B2_PARM_NOT_SUPPORTED;
					}

					dlc[5] = (byte)(b2_config->info[3] - 1);
					dlc[6] = b2_config->info[4];
					if (dlc[6] > dlc[5]) {
						dbug(1, dprintf("2D-dlc= %x %x %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4], dlc[5], dlc[6]));
						return _B2_PARM_NOT_SUPPORTED;
					}

					if (llc[1] == X75_V42BIS) {
						if (b2_config->length >= 10) {
							dlc[7] = 6;
							dlc[8] = 0;
							dlc[9] = b2_config_parms[4].info[0];
							dlc[10] = b2_config_parms[4].info[1];
							dlc[11] = b2_config_parms[5].info[0];
							dlc[12] = b2_config_parms[5].info[1];
							dlc[13] = b2_config_parms[6].info[0];
							dlc[14] = b2_config_parms[6].info[1];
							dlc[0] = 14;
							dbug(1, dprintf("b2_config_parms[4].info[0] [1]:  %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1]));
							dbug(1, dprintf("b2_config_parms[5].info[0] [1]:  %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1]));
							dbug(1, dprintf("b2_config_parms[6].info[0] [1]:  %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1]));
						}
						else {
							dlc[6] = 14;
						}

					}
					else {
						PUT_WORD(&dlc[7], (word)b2_config_parms[4].length);
						for (i = 0; i < b2_config_parms[4].length; i++)
							dlc[11 + i] = b2_config_parms[4].info[1 + i];
					}
				}
			}
		}
	add_p(plci, DLC, dlc);

	b3_config = &bp_parms[5];
	if (b3_config->length)
	{
		if (plci->B3_prot == 4
		    || plci->B3_prot == 5)
		{
			if (api_parse(&b3_config->info[1], (word)b3_config->length, "wwss", b3_config_parms))
			{
				return _WRONG_MESSAGE_FORMAT;
			}
			i = GET_WORD((byte *)(b3_config_parms[0].info));
			((T30_INFO *)&nlc[1])->resolution = (byte)(((i & 0x0001) ||
								    ((plci->B3_prot == 4) && (((byte)(GET_WORD((byte *)b3_config_parms[1].info))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200 : 0);
			((T30_INFO *)&nlc[1])->data_format = (byte)(GET_WORD((byte *)b3_config_parms[1].info));
			fax_control_bits = T30_CONTROL_BIT_ALL_FEATURES;
			if ((((T30_INFO *)&nlc[1])->rate_div_2400 != 0) && (((T30_INFO *)&nlc[1])->rate_div_2400 <= 6))
				fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_V34FAX;
			if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
			{

				if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
				    & (1L << PRIVATE_FAX_PAPER_FORMATS))
				{
					((T30_INFO *)&nlc[1])->resolution |= T30_RESOLUTION_R8_1540 |
						T30_RESOLUTION_R16_1540_OR_400 | T30_RESOLUTION_300_300 |
						T30_RESOLUTION_INCH_BASED | T30_RESOLUTION_METRIC_BASED;
				}

				((T30_INFO *)&nlc[1])->recording_properties =
					T30_RECORDING_WIDTH_ISO_A3 |
					(T30_RECORDING_LENGTH_UNLIMITED << 2) |
					(T30_MIN_SCANLINE_TIME_00_00_00 << 4);
			}
			if (plci->B3_prot == 5)
			{
				if (i & 0x0002) /* Accept incoming fax-polling requests */
					fax_control_bits |= T30_CONTROL_BIT_ACCEPT_POLLING;
				if (i & 0x2000) /* Do not use MR compression */
					fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_2D_CODING;
				if (i & 0x4000) /* Do not use MMR compression */
					fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_T6_CODING;
				if (i & 0x8000) /* Do not use ECM */
					fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_ECM;
				if (plci->fax_connect_info_length != 0)
				{
					((T30_INFO *)&nlc[1])->resolution = ((T30_INFO *)plci->fax_connect_info_buffer)->resolution;
					((T30_INFO *)&nlc[1])->data_format = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format;
					((T30_INFO *)&nlc[1])->recording_properties = ((T30_INFO *)plci->fax_connect_info_buffer)->recording_properties;
					fax_control_bits |= GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) &
						(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
				}
			}
			/* copy station id to NLC */
			for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
			{
				if (i < b3_config_parms[2].length)
				{
					((T30_INFO *)&nlc[1])->station_id[i] = ((byte *)b3_config_parms[2].info)[1 + i];
				}
				else
				{
					((T30_INFO *)&nlc[1])->station_id[i] = ' ';
				}
			}
			((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
			/* copy head line to NLC */
			if (b3_config_parms[3].length)
			{

				pos = (byte)(fax_head_line_time(&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
				if (pos != 0)
				{
					if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
						pos = 0;
					else
					{
						nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
						nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
						len = (byte)b3_config_parms[2].length;
						if (len > 20)
							len = 20;
						if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
						{
							for (i = 0; i < len; i++)
								nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[2].info)[1 + i];
							nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
							nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
						}
					}
				}

				len = (byte)b3_config_parms[3].length;
				if (len > CAPI_MAX_HEAD_LINE_SPACE - pos)
					len = (byte)(CAPI_MAX_HEAD_LINE_SPACE - pos);
				((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
				nlc[0] += (byte)(pos + len);
				for (i = 0; i < len; i++)
					nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] =  ((byte *)b3_config_parms[3].info)[1 + i];
			} else
				((T30_INFO *)&nlc[1])->head_line_len = 0;

			plci->nsf_control_bits = 0;
			if (plci->B3_prot == 5)
			{
				if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
				    && (GET_WORD((byte *)b3_config_parms[1].info) & 0x8000)) /* Private SUB/SEP/PWD enable */
				{
					plci->requested_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
				}
				if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
				    && (GET_WORD((byte *)b3_config_parms[1].info) & 0x4000)) /* Private non-standard facilities enable */
				{
					plci->requested_options |= 1L << PRIVATE_FAX_NONSTANDARD;
				}
				if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
				    & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
				{
					if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
					    & (1L << PRIVATE_FAX_SUB_SEP_PWD))
					{
						fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD;
						if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING)
							fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
					}
					len = nlc[0];
					pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
					if (pos < plci->fax_connect_info_length)
					{
						for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
							nlc[++len] = plci->fax_connect_info_buffer[pos++];
					}
					else
						nlc[++len] = 0;
					if (pos < plci->fax_connect_info_length)
					{
						for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
							nlc[++len] = plci->fax_connect_info_buffer[pos++];
					}
					else
						nlc[++len] = 0;
					if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
					    & (1L << PRIVATE_FAX_NONSTANDARD))
					{
						if ((pos < plci->fax_connect_info_length) && (plci->fax_connect_info_buffer[pos] != 0))
						{
							if ((plci->fax_connect_info_buffer[pos] >= 3) && (plci->fax_connect_info_buffer[pos + 1] >= 2))
								plci->nsf_control_bits = GET_WORD(&plci->fax_connect_info_buffer[pos + 2]);
							for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
								nlc[++len] = plci->fax_connect_info_buffer[pos++];
						}
						else
						{
							if (api_parse(&b3_config->info[1], (word)b3_config->length, "wwsss", b3_config_parms))
							{
								dbug(1, dprintf("non-standard facilities info missing or wrong format"));
								nlc[++len] = 0;
							}
							else
							{
								if ((b3_config_parms[4].length >= 3) && (b3_config_parms[4].info[1] >= 2))
									plci->nsf_control_bits = GET_WORD(&b3_config_parms[4].info[2]);
								nlc[++len] = (byte)(b3_config_parms[4].length);
								for (i = 0; i < b3_config_parms[4].length; i++)
									nlc[++len] = b3_config_parms[4].info[1 + i];
							}
						}
					}
					nlc[0] = len;
					if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
					    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
					{
						((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI_NEG;
					}
				}
			}

			PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
			len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
			for (i = 0; i < len; i++)
				plci->fax_connect_info_buffer[i] = nlc[1 + i];
			((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0;
			i += ((T30_INFO *)&nlc[1])->head_line_len;
			while (i < nlc[0])
				plci->fax_connect_info_buffer[len++] = nlc[++i];
			plci->fax_connect_info_length = len;
		}
		else
		{
			nlc[0] = 14;
			if (b3_config->length != 16)
				return _B3_PARM_NOT_SUPPORTED;
			for (i = 0; i < 12; i++) nlc[1 + i] = b3_config->info[1 + i];
			if (GET_WORD(&b3_config->info[13]) != 8 && GET_WORD(&b3_config->info[13]) != 128)
				return _B3_PARM_NOT_SUPPORTED;
			nlc[13] = b3_config->info[13];
			if (GET_WORD(&b3_config->info[15]) >= nlc[13])
				return _B3_PARM_NOT_SUPPORTED;
			nlc[14] = b3_config->info[15];
		}
	}
	else
	{
		if (plci->B3_prot == 4
		    || plci->B3_prot == 5 /*T.30 - FAX*/) return _B3_PARM_NOT_SUPPORTED;
	}
	add_p(plci, NLC, nlc);
	return 0;
}

/*----------------------------------------------------------------*/
/*      make the same as add_b23, but only for the modem related  */
/*      L2 and L3 B-Chan protocol.                                */
/*                                                                */
/*      Enabled L2 and L3 Configurations:                         */
/*        If L1 == Modem all negotiation                          */
/*          only L2 == Modem with full negotiation is allowed     */
/*        If L1 == Modem async or sync                            */
/*          only L2 == Transparent is allowed                     */
/*        L3 == Modem or L3 == Transparent are allowed            */
/*      B2 Configuration for modem:                               */
/*          word : enable/disable compression, bitoptions         */
/*      B3 Configuration for modem:                               */
/*          empty                                                 */
/*----------------------------------------------------------------*/
static word add_modem_b23(PLCI *plci, API_PARSE *bp_parms)
{
	static byte lli[12] = {1,1};
	static byte llc[3] = {2,0,0};
	static byte dlc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	API_PARSE mdm_config[2];
	word i;
	word b2_config = 0;

	for (i = 0; i < 2; i++) mdm_config[i].length = 0;
	for (i = 0; i < sizeof(dlc); i++) dlc[i] = 0;

	if (((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
	     && (GET_WORD(bp_parms[1].info) != B2_MODEM_EC_COMPRESSION))
	    || ((GET_WORD(bp_parms[0].info) != B1_MODEM_ALL_NEGOTIATE)
		&& (GET_WORD(bp_parms[1].info) != B2_TRANSPARENT)))
	{
		return (_B_STACK_NOT_SUPPORTED);
	}
	if ((GET_WORD(bp_parms[2].info) != B3_MODEM)
	    && (GET_WORD(bp_parms[2].info) != B3_TRANSPARENT))
	{
		return (_B_STACK_NOT_SUPPORTED);
	}

	plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
	plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);

	if ((GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) && bp_parms[4].length)
	{
		if (api_parse(&bp_parms[4].info[1],
			      (word)bp_parms[4].length, "w",
			      mdm_config))
		{
			return (_WRONG_MESSAGE_FORMAT);
		}
		b2_config = GET_WORD(mdm_config[0].info);
	}

	/* OK, L2 is modem */

	lli[0] = 1;
	lli[1] = 1;
	if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
		lli[1] |= 2;
	if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
		lli[1] |= 4;

	if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
		lli[1] |= 0x10;
		if (plci->rx_dma_descriptor <= 0) {
			plci->rx_dma_descriptor = diva_get_dma_descriptor(plci, &plci->rx_dma_magic);
			if (plci->rx_dma_descriptor >= 0)
				plci->rx_dma_descriptor++;
		}
		if (plci->rx_dma_descriptor > 0) {
			lli[1] |= 0x40;
			lli[0] = 6;
			lli[2] = (byte)(plci->rx_dma_descriptor - 1);
			lli[3] = (byte)plci->rx_dma_magic;
			lli[4] = (byte)(plci->rx_dma_magic >>  8);
			lli[5] = (byte)(plci->rx_dma_magic >> 16);
			lli[6] = (byte)(plci->rx_dma_magic >> 24);
		}
	}

	if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
		lli[1] |= 0x20;
	}

	llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ?
		/*V42*/ 10 : /*V42_IN*/ 9;
	llc[2] = 4;                      /* pass L3 always transparent */
	add_p(plci, LLI, lli);
	add_p(plci, LLC, llc);
	i =  1;
	PUT_WORD(&dlc[i], plci->appl->MaxDataLength);
	i += 2;
	if (GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION)
	{
		if (bp_parms[4].length)
		{
			dbug(1, dprintf("MDM b2_config=%02x", b2_config));
			dlc[i++] = 3; /* Addr A */
			dlc[i++] = 1; /* Addr B */
			dlc[i++] = 7; /* modulo mode */
			dlc[i++] = 7; /* window size */
			dlc[i++] = 0; /* XID len Lo  */
			dlc[i++] = 0; /* XID len Hi  */

			if (b2_config & MDM_B2_DISABLE_V42bis)
			{
				dlc[i] |= DLC_MODEMPROT_DISABLE_V42_V42BIS;
			}
			if (b2_config & MDM_B2_DISABLE_MNP)
			{
				dlc[i] |= DLC_MODEMPROT_DISABLE_MNP_MNP5;
			}
			if (b2_config & MDM_B2_DISABLE_TRANS)
			{
				dlc[i] |= DLC_MODEMPROT_REQUIRE_PROTOCOL;
			}
			if (b2_config & MDM_B2_DISABLE_V42)
			{
				dlc[i] |= DLC_MODEMPROT_DISABLE_V42_DETECT;
			}
			if (b2_config & MDM_B2_DISABLE_COMP)
			{
				dlc[i] |= DLC_MODEMPROT_DISABLE_COMPRESSION;
			}
			i++;
		}
	}
	else
	{
		dlc[i++] = 3; /* Addr A */
		dlc[i++] = 1; /* Addr B */
		dlc[i++] = 7; /* modulo mode */
		dlc[i++] = 7; /* window size */
		dlc[i++] = 0; /* XID len Lo  */
		dlc[i++] = 0; /* XID len Hi  */
		dlc[i++] = DLC_MODEMPROT_DISABLE_V42_V42BIS |
			DLC_MODEMPROT_DISABLE_MNP_MNP5 |
			DLC_MODEMPROT_DISABLE_V42_DETECT |
			DLC_MODEMPROT_DISABLE_COMPRESSION;
	}
	dlc[0] = (byte)(i - 1);
/* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
	add_p(plci, DLC, dlc);
	return (0);
}


/*------------------------------------------------------------------*/
/* send a request for the signaling entity                          */
/*------------------------------------------------------------------*/

static void sig_req(PLCI *plci, byte req, byte Id)
{
	if (!plci) return;
	if (plci->adapter->adapter_disabled) return;
	dbug(1, dprintf("sig_req(%x)", req));
	if (req == REMOVE)
		plci->sig_remove_id = plci->Sig.Id;
	if (plci->req_in == plci->req_in_start) {
		plci->req_in += 2;
		plci->RBuffer[plci->req_in++] = 0;
	}
	PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start - 2);
	plci->RBuffer[plci->req_in++] = Id;   /* sig/nl flag */
	plci->RBuffer[plci->req_in++] = req;  /* request */
	plci->RBuffer[plci->req_in++] = 0;    /* channel */
	plci->req_in_start = plci->req_in;
}

/*------------------------------------------------------------------*/
/* send a request for the network layer entity                      */
/*------------------------------------------------------------------*/

static void nl_req_ncci(PLCI *plci, byte req, byte ncci)
{
	if (!plci) return;
	if (plci->adapter->adapter_disabled) return;
	dbug(1, dprintf("nl_req %02x %02x %02x", plci->Id, req, ncci));
	if (req == REMOVE)
	{
		plci->nl_remove_id = plci->NL.Id;
		ncci_remove(plci, 0, (byte)(ncci != 0));
		ncci = 0;
	}
	if (plci->req_in == plci->req_in_start) {
		plci->req_in += 2;
		plci->RBuffer[plci->req_in++] = 0;
	}
	PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start - 2);
	plci->RBuffer[plci->req_in++] = 1;    /* sig/nl flag */
	plci->RBuffer[plci->req_in++] = req;  /* request */
	plci->RBuffer[plci->req_in++] = plci->adapter->ncci_ch[ncci];   /* channel */
	plci->req_in_start = plci->req_in;
}

static void send_req(PLCI *plci)
{
	ENTITY *e;
	word l;
/*  word i; */

	if (!plci) return;
	if (plci->adapter->adapter_disabled) return;
	channel_xmit_xon(plci);

	/* if nothing to do, return */
	if (plci->req_in == plci->req_out) return;
	dbug(1, dprintf("send_req(in=%d,out=%d)", plci->req_in, plci->req_out));

	if (plci->nl_req || plci->sig_req) return;

	l = GET_WORD(&plci->RBuffer[plci->req_out]);
	plci->req_out += 2;
	plci->XData[0].P = &plci->RBuffer[plci->req_out];
	plci->req_out += l;
	if (plci->RBuffer[plci->req_out] == 1)
	{
		e = &plci->NL;
		plci->req_out++;
		e->Req = plci->nl_req = plci->RBuffer[plci->req_out++];
		e->ReqCh = plci->RBuffer[plci->req_out++];
		if (!(e->Id & 0x1f))
		{
			e->Id = NL_ID;
			plci->RBuffer[plci->req_out - 4] = CAI;
			plci->RBuffer[plci->req_out - 3] = 1;
			plci->RBuffer[plci->req_out - 2] = (plci->Sig.Id == 0xff) ? 0 : plci->Sig.Id;
			plci->RBuffer[plci->req_out - 1] = 0;
			l += 3;
			plci->nl_global_req = plci->nl_req;
		}
		dbug(1, dprintf("%x:NLREQ(%x:%x:%x)", plci->adapter->Id, e->Id, e->Req, e->ReqCh));
	}
	else
	{
		e = &plci->Sig;
		if (plci->RBuffer[plci->req_out])
			e->Id = plci->RBuffer[plci->req_out];
		plci->req_out++;
		e->Req = plci->sig_req = plci->RBuffer[plci->req_out++];
		e->ReqCh = plci->RBuffer[plci->req_out++];
		if (!(e->Id & 0x1f))
			plci->sig_global_req = plci->sig_req;
		dbug(1, dprintf("%x:SIGREQ(%x:%x:%x)", plci->adapter->Id, e->Id, e->Req, e->ReqCh));
	}
	plci->XData[0].PLength = l;
	e->X = plci->XData;
	plci->adapter->request(e);
	dbug(1, dprintf("send_ok"));
}

static void send_data(PLCI *plci)
{
	DIVA_CAPI_ADAPTER *a;
	DATA_B3_DESC *data;
	NCCI   *ncci_ptr;
	word ncci;

	if (!plci->nl_req && plci->ncci_ring_list)
	{
		a = plci->adapter;
		ncci = plci->ncci_ring_list;
		do
		{
			ncci = a->ncci_next[ncci];
			ncci_ptr = &(a->ncci[ncci]);
			if (!(a->ncci_ch[ncci]
			      && (a->ch_flow_control[a->ncci_ch[ncci]] & N_OK_FC_PENDING)))
			{
				if (ncci_ptr->data_pending)
				{
					if ((a->ncci_state[ncci] == CONNECTED)
					    || (a->ncci_state[ncci] == INC_ACT_PENDING)
					    || (plci->send_disc == ncci))
					{
						data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
						if ((plci->B2_prot == B2_V120_ASYNC)
						    || (plci->B2_prot == B2_V120_ASYNC_V42BIS)
						    || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))
						{
							plci->NData[1].P = TransmitBufferGet(plci->appl, data->P);
							plci->NData[1].PLength = data->Length;
							if (data->Flags & 0x10)
								plci->NData[0].P = v120_break_header;
							else
								plci->NData[0].P = v120_default_header;
							plci->NData[0].PLength = 1;
							plci->NL.XNum = 2;
							plci->NL.Req = plci->nl_req = (byte)((data->Flags & 0x07) << 4 | N_DATA);
						}
						else
						{
							plci->NData[0].P = TransmitBufferGet(plci->appl, data->P);
							plci->NData[0].PLength = data->Length;
							if (data->Flags & 0x10)
								plci->NL.Req = plci->nl_req = (byte)N_UDATA;

							else if ((plci->B3_prot == B3_RTP) && (data->Flags & 0x01))
								plci->NL.Req = plci->nl_req = (byte)N_BDATA;

							else
								plci->NL.Req = plci->nl_req = (byte)((data->Flags & 0x07) << 4 | N_DATA);
						}
						plci->NL.X = plci->NData;
						plci->NL.ReqCh = a->ncci_ch[ncci];
						dbug(1, dprintf("%x:DREQ(%x:%x)", a->Id, plci->NL.Id, plci->NL.Req));
						plci->data_sent = true;
						plci->data_sent_ptr = data->P;
						a->request(&plci->NL);
					}
					else {
						cleanup_ncci_data(plci, ncci);
					}
				}
				else if (plci->send_disc == ncci)
				{
					/* dprintf("N_DISC"); */
					plci->NData[0].PLength = 0;
					plci->NL.ReqCh = a->ncci_ch[ncci];
					plci->NL.Req = plci->nl_req = N_DISC;
					a->request(&plci->NL);
					plci->command = _DISCONNECT_B3_R;
					plci->send_disc = 0;
				}
			}
		} while (!plci->nl_req && (ncci != plci->ncci_ring_list));
		plci->ncci_ring_list = ncci;
	}
}

static void listen_check(DIVA_CAPI_ADAPTER *a)
{
	word i, j;
	PLCI *plci;
	byte activnotifiedcalls = 0;

	dbug(1, dprintf("listen_check(%d,%d)", a->listen_active, a->max_listen));
	if (!remove_started && !a->adapter_disabled)
	{
		for (i = 0; i < a->max_plci; i++)
		{
			plci = &(a->plci[i]);
			if (plci->notifiedcall) activnotifiedcalls++;
		}
		dbug(1, dprintf("listen_check(%d)", activnotifiedcalls));

		for (i = a->listen_active; i < ((word)(a->max_listen + activnotifiedcalls)); i++) {
			if ((j = get_plci(a))) {
				a->listen_active++;
				plci = &a->plci[j - 1];
				plci->State = LISTENING;

				add_p(plci, OAD, "\x01\xfd");

				add_p(plci, KEY, "\x04\x43\x41\x32\x30");

				add_p(plci, CAI, "\x01\xc0");
				add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
				add_p(plci, LLI, "\x01\xc4");                  /* support Dummy CR FAC + MWI + SpoofNotify */
				add_p(plci, SHIFT | 6, NULL);
				add_p(plci, SIN, "\x02\x00\x00");
				plci->internal_command = LISTEN_SIG_ASSIGN_PEND;     /* do indicate_req if OK  */
				sig_req(plci, ASSIGN, DSIG_ID);
				send_req(plci);
			}
		}
	}
}

/*------------------------------------------------------------------*/
/* functions for all parameters sent in INDs                        */
/*------------------------------------------------------------------*/

static void IndParse(PLCI *plci, word *parms_id, byte **parms, byte multiIEsize)
{
	word ploc;            /* points to current location within packet */
	byte w;
	byte wlen;
	byte codeset, lock;
	byte *in;
	word i;
	word code;
	word mIEindex = 0;
	ploc = 0;
	codeset = 0;
	lock = 0;

	in = plci->Sig.RBuffer->P;
	for (i = 0; i < parms_id[0]; i++)   /* multiIE parms_id contains just the 1st */
	{                            /* element but parms array is larger      */
		parms[i] = (byte *)"";
	}
	for (i = 0; i < multiIEsize; i++)
	{
		parms[i] = (byte *)"";
	}

	while (ploc < plci->Sig.RBuffer->length - 1) {

		/* read information element id and length                   */
		w = in[ploc];

		if (w & 0x80) {
/*    w &=0xf0; removed, cannot detect congestion levels */
/*    upper 4 bit masked with w==SHIFT now               */
			wlen = 0;
		}
		else {
			wlen = (byte)(in[ploc + 1] + 1);
		}
		/* check if length valid (not exceeding end of packet)      */
		if ((ploc + wlen) > 270) return;
		if (lock & 0x80) lock &= 0x7f;
		else codeset = lock;

		if ((w & 0xf0) == SHIFT) {
			codeset = in[ploc];
			if (!(codeset & 0x08)) lock = (byte)(codeset & 7);
			codeset &= 7;
			lock |= 0x80;
		}
		else {
			if (w == ESC && wlen >= 3) code = in[ploc + 2] | 0x800;
			else code = w;
			code |= (codeset << 8);

			for (i = 1; i < parms_id[0] + 1 && parms_id[i] != code; i++);

			if (i < parms_id[0] + 1) {
				if (!multiIEsize) { /* with multiIEs use next field index,          */
					mIEindex = i - 1;    /* with normal IEs use same index like parms_id */
				}

				parms[mIEindex] = &in[ploc + 1];
				dbug(1, dprintf("mIE[%d]=0x%x", *parms[mIEindex], in[ploc]));
				if (parms_id[i] == OAD
				    || parms_id[i] == CONN_NR
				    || parms_id[i] == CAD) {
					if (in[ploc + 2] & 0x80) {
						in[ploc + 0] = (byte)(in[ploc + 1] + 1);
						in[ploc + 1] = (byte)(in[ploc + 2] & 0x7f);
						in[ploc + 2] = 0x80;
						parms[mIEindex] = &in[ploc];
					}
				}
				mIEindex++;       /* effects multiIEs only */
			}
		}

		ploc += (wlen + 1);
	}
	return;
}

/*------------------------------------------------------------------*/
/* try to match a cip from received BC and HLC                      */
/*------------------------------------------------------------------*/

static byte ie_compare(byte *ie1, byte *ie2)
{
	word i;
	if (!ie1 || !ie2) return false;
	if (!ie1[0]) return false;
	for (i = 0; i < (word)(ie1[0] + 1); i++) if (ie1[i] != ie2[i]) return false;
	return true;
}

static word find_cip(DIVA_CAPI_ADAPTER *a, byte *bc, byte *hlc)
{
	word i;
	word j;

	for (i = 9; i && !ie_compare(bc, cip_bc[i][a->u_law]); i--);

	for (j = 16; j < 29 &&
		     (!ie_compare(bc, cip_bc[j][a->u_law]) || !ie_compare(hlc, cip_hlc[j])); j++);
	if (j == 29) return i;
	return j;
}


static byte AddInfo(byte **add_i,
		    byte **fty_i,
		    byte *esc_chi,
		    byte *facility)
{
	byte i;
	byte j;
	byte k;
	byte flen;
	byte len = 0;
	/* facility is a nested structure */
	/* FTY can be more than once      */

	if (esc_chi[0] && !(esc_chi[esc_chi[0]] & 0x7f))
	{
		add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */
	}

	else
	{
		add_i[0] = (byte *)"";
	}
	if (!fty_i[0][0])
	{
		add_i[3] = (byte *)"";
	}
	else
	{    /* facility array found  */
		for (i = 0, j = 1; i < MAX_MULTI_IE && fty_i[i][0]; i++)
		{
			dbug(1, dprintf("AddIFac[%d]", fty_i[i][0]));
			len += fty_i[i][0];
			len += 2;
			flen = fty_i[i][0];
			facility[j++] = 0x1c; /* copy fac IE */
			for (k = 0; k <= flen; k++, j++)
			{
				facility[j] = fty_i[i][k];
/*      dbug(1, dprintf("%x ",facility[j])); */
			}
		}
		facility[0] = len;
		add_i[3] = facility;
	}
/*  dbug(1, dprintf("FacArrLen=%d ",len)); */
	len = add_i[0][0] + add_i[1][0] + add_i[2][0] + add_i[3][0];
	len += 4;                          /* calculate length of all */
	return (len);
}

/*------------------------------------------------------------------*/
/* voice and codec features                                         */
/*------------------------------------------------------------------*/

static void SetVoiceChannel(PLCI *plci, byte *chi, DIVA_CAPI_ADAPTER *a)
{
	byte voice_chi[] = "\x02\x18\x01";
	byte channel;

	channel = chi[chi[0]] & 0x3;
	dbug(1, dprintf("ExtDevON(Ch=0x%x)", channel));
	voice_chi[2] = (channel) ? channel : 1;
	add_p(plci, FTY, "\x02\x01\x07");             /* B On, default on 1 */
	add_p(plci, ESC, voice_chi);                  /* Channel */
	sig_req(plci, TEL_CTRL, 0);
	send_req(plci);
	if (a->AdvSignalPLCI)
	{
		adv_voice_write_coefs(a->AdvSignalPLCI, ADV_VOICE_WRITE_ACTIVATION);
	}
}

static void VoiceChannelOff(PLCI *plci)
{
	dbug(1, dprintf("ExtDevOFF"));
	add_p(plci, FTY, "\x02\x01\x08");             /* B Off */
	sig_req(plci, TEL_CTRL, 0);
	send_req(plci);
	if (plci->adapter->AdvSignalPLCI)
	{
		adv_voice_clear_config(plci->adapter->AdvSignalPLCI);
	}
}


static word AdvCodecSupport(DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl,
			    byte hook_listen)
{
	word j;
	PLCI *splci;

	/* check if hardware supports handset with hook states (adv.codec) */
	/* or if just a on board codec is supported                        */
	/* the advanced codec plci is just for internal use                */

	/* diva Pro with on-board codec:                                   */
	if (a->profile.Global_Options & HANDSET)
	{
		/* new call, but hook states are already signalled */
		if (a->AdvCodecFLAG)
		{
			if (a->AdvSignalAppl != appl || a->AdvSignalPLCI)
			{
				dbug(1, dprintf("AdvSigPlci=0x%x", a->AdvSignalPLCI));
				return 0x2001; /* codec in use by another application */
			}
			if (plci != NULL)
			{
				a->AdvSignalPLCI = plci;
				plci->tel = ADV_VOICE;
			}
			return 0;                      /* adv codec still used */
		}
		if ((j = get_plci(a)))
		{
			splci = &a->plci[j - 1];
			splci->tel = CODEC_PERMANENT;
			/* hook_listen indicates if a facility_req with handset/hook support */
			/* was sent. Otherwise if just a call on an external device was made */
			/* the codec will be used but the hook info will be discarded (just  */
			/* the external controller is in use                                 */
			if (hook_listen) splci->State = ADVANCED_VOICE_SIG;
			else
			{
				splci->State = ADVANCED_VOICE_NOSIG;
				if (plci)
				{
					plci->spoofed_msg = SPOOFING_REQUIRED;
				}
				/* indicate D-ch connect if  */
			}                                        /* codec is connected OK     */
			if (plci != NULL)
			{
				a->AdvSignalPLCI = plci;
				plci->tel = ADV_VOICE;
			}
			a->AdvSignalAppl = appl;
			a->AdvCodecFLAG = true;
			a->AdvCodecPLCI = splci;
			add_p(splci, CAI, "\x01\x15");
			add_p(splci, LLI, "\x01\x00");
			add_p(splci, ESC, "\x02\x18\x00");
			add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
			splci->internal_command = PERM_COD_ASSIGN;
			dbug(1, dprintf("Codec Assign"));
			sig_req(splci, ASSIGN, DSIG_ID);
			send_req(splci);
		}
		else
		{
			return 0x2001; /* wrong state, no more plcis */
		}
	}
	else if (a->profile.Global_Options & ON_BOARD_CODEC)
	{
		if (hook_listen) return 0x300B;               /* Facility not supported */
		/* no hook with SCOM      */
		if (plci != NULL) plci->tel = CODEC;
		dbug(1, dprintf("S/SCOM codec"));
		/* first time we use the scom-s codec we must shut down the internal   */
		/* handset application of the card. This can be done by an assign with */
		/* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/
		if (!a->scom_appl_disable) {
			if ((j = get_plci(a))) {
				splci = &a->plci[j - 1];
				add_p(splci, CAI, "\x01\x80");
				add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
				sig_req(splci, ASSIGN, 0xC0);  /* 0xc0 is the TEL_ID */
				send_req(splci);
				a->scom_appl_disable = true;
			}
			else{
				return 0x2001; /* wrong state, no more plcis */
			}
		}
	}
	else return 0x300B;               /* Facility not supported */

	return 0;
}


static void CodecIdCheck(DIVA_CAPI_ADAPTER *a, PLCI *plci)
{

	dbug(1, dprintf("CodecIdCheck"));

	if (a->AdvSignalPLCI == plci)
	{
		dbug(1, dprintf("PLCI owns codec"));
		VoiceChannelOff(a->AdvCodecPLCI);
		if (a->AdvCodecPLCI->State == ADVANCED_VOICE_NOSIG)
		{
			dbug(1, dprintf("remove temp codec PLCI"));
			plci_remove(a->AdvCodecPLCI);
			a->AdvCodecFLAG  = 0;
			a->AdvCodecPLCI  = NULL;
			a->AdvSignalAppl = NULL;
		}
		a->AdvSignalPLCI = NULL;
	}
}

/* -------------------------------------------------------------------
   Ask for physical address of card on PCI bus
   ------------------------------------------------------------------- */
static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER *a,
				       IDI_SYNC_REQ *preq) {
	a->sdram_bar = 0;
	if (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR) {
		ENTITY *e = (ENTITY *)preq;

		e->user[0] = a->Id - 1;
		preq->xdi_sdram_bar.info.bar    = 0;
		preq->xdi_sdram_bar.Req         = 0;
		preq->xdi_sdram_bar.Rc           = IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR;

		(*(a->request))(e);

		a->sdram_bar = preq->xdi_sdram_bar.info.bar;
		dbug(3, dprintf("A(%d) SDRAM BAR = %08x", a->Id, a->sdram_bar));
	}
}

/* -------------------------------------------------------------------
   Ask XDI about extended features
   ------------------------------------------------------------------- */
static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER *a) {
	IDI_SYNC_REQ *preq;
	char buffer[((sizeof(preq->xdi_extended_features) + 4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features) + 4) : sizeof(ENTITY)];

	char features[4];
	preq = (IDI_SYNC_REQ *)&buffer[0];

	if (!diva_xdi_extended_features) {
		ENTITY *e = (ENTITY *)preq;
		diva_xdi_extended_features |= 0x80000000;

		e->user[0] = a->Id - 1;
		preq->xdi_extended_features.Req = 0;
		preq->xdi_extended_features.Rc  = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;
		preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);
		preq->xdi_extended_features.info.features = &features[0];

		(*(a->request))(e);

		if (features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) {
			/*
			  Check features located in the byte '0'
			*/
			if (features[0] & DIVA_XDI_EXTENDED_FEATURE_CMA) {
				diva_xdi_extended_features |= DIVA_CAPI_USE_CMA;
			}
			if (features[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA) {
				diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_RX_DMA;
				dbug(1, dprintf("XDI provides RxDMA"));
			}
			if (features[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR) {
				diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR;
			}
			if (features[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC) {
				diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL;
				dbug(3, dprintf("XDI provides NO_CANCEL_RC feature"));
			}

		}
	}

	diva_ask_for_xdi_sdram_bar(a, preq);
}

/*------------------------------------------------------------------*/
/* automatic law                                                    */
/*------------------------------------------------------------------*/
/* called from OS specific part after init time to get the Law              */
/* a-law (Euro) and u-law (us,japan) use different BCs in the Setup message */
void AutomaticLaw(DIVA_CAPI_ADAPTER *a)
{
	word j;
	PLCI *splci;

	if (a->automatic_law) {
		return;
	}
	if ((j = get_plci(a))) {
		diva_get_extended_adapter_features(a);
		splci = &a->plci[j - 1];
		a->automatic_lawPLCI = splci;
		a->automatic_law = 1;
		add_p(splci, CAI, "\x01\x80");
		add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
		splci->internal_command = USELAW_REQ;
		splci->command = 0;
		splci->number = 0;
		sig_req(splci, ASSIGN, DSIG_ID);
		send_req(splci);
	}
}

/* called from OS specific part if an application sends an Capi20Release */
word CapiRelease(word Id)
{
	word i, j, appls_found;
	PLCI *plci;
	APPL   *this;
	DIVA_CAPI_ADAPTER *a;

	if (!Id)
	{
		dbug(0, dprintf("A: CapiRelease(Id==0)"));
		return (_WRONG_APPL_ID);
	}

	this = &application[Id - 1];               /* get application pointer */

	for (i = 0, appls_found = 0; i < max_appl; i++)
	{
		if (application[i].Id)       /* an application has been found        */
		{
			appls_found++;
		}
	}

	for (i = 0; i < max_adapter; i++)             /* scan all adapters...    */
	{
		a = &adapter[i];
		if (a->request)
		{
			a->Info_Mask[Id - 1] = 0;
			a->CIP_Mask[Id - 1] = 0;
			a->Notification_Mask[Id - 1] = 0;
			a->codec_listen[Id - 1] = NULL;
			a->requested_options_table[Id - 1] = 0;
			for (j = 0; j < a->max_plci; j++)           /* and all PLCIs connected */
			{                                      /* with this application   */
				plci = &a->plci[j];
				if (plci->Id)                         /* if plci owns no application */
				{                                    /* it may be not jet connected */
					if (plci->State == INC_CON_PENDING
					    || plci->State == INC_CON_ALERT)
					{
						if (test_c_ind_mask_bit(plci, (word)(Id - 1)))
						{
							clear_c_ind_mask_bit(plci, (word)(Id - 1));
							if (c_ind_mask_empty(plci))
							{
								sig_req(plci, HANGUP, 0);
								send_req(plci);
								plci->State = OUTG_DIS_PENDING;
							}
						}
					}
					if (test_c_ind_mask_bit(plci, (word)(Id - 1)))
					{
						clear_c_ind_mask_bit(plci, (word)(Id - 1));
						if (c_ind_mask_empty(plci))
						{
							if (!plci->appl)
							{
								plci_remove(plci);
								plci->State = IDLE;
							}
						}
					}
					if (plci->appl == this)
					{
						plci->appl = NULL;
						plci_remove(plci);
						plci->State = IDLE;
					}
				}
			}
			listen_check(a);

			if (a->flag_dynamic_l1_down)
			{
				if (appls_found == 1)            /* last application does a capi release */
				{
					if ((j = get_plci(a)))
					{
						plci = &a->plci[j - 1];
						plci->command = 0;
						add_p(plci, OAD, "\x01\xfd");
						add_p(plci, CAI, "\x01\x80");
						add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
						add_p(plci, SHIFT | 6, NULL);
						add_p(plci, SIN, "\x02\x00\x00");
						plci->internal_command = REM_L1_SIG_ASSIGN_PEND;
						sig_req(plci, ASSIGN, DSIG_ID);
						add_p(plci, FTY, "\x02\xff\x06"); /* l1 down */
						sig_req(plci, SIG_CTRL, 0);
						send_req(plci);
					}
				}
			}
			if (a->AdvSignalAppl == this)
			{
				this->NullCREnable = false;
				if (a->AdvCodecPLCI)
				{
					plci_remove(a->AdvCodecPLCI);
					a->AdvCodecPLCI->tel = 0;
					a->AdvCodecPLCI->adv_nl = 0;
				}
				a->AdvSignalAppl = NULL;
				a->AdvSignalPLCI = NULL;
				a->AdvCodecFLAG = 0;
				a->AdvCodecPLCI = NULL;
			}
		}
	}

	this->Id = 0;

	return GOOD;
}

static word plci_remove_check(PLCI *plci)
{
	if (!plci) return true;
	if (!plci->NL.Id && c_ind_mask_empty(plci))
	{
		if (plci->Sig.Id == 0xff)
			plci->Sig.Id = 0;
		if (!plci->Sig.Id)
		{
			dbug(1, dprintf("plci_remove_complete(%x)", plci->Id));
			dbug(1, dprintf("tel=0x%x,Sig=0x%x", plci->tel, plci->Sig.Id));
			if (plci->Id)
			{
				CodecIdCheck(plci->adapter, plci);
				clear_b1_config(plci);
				ncci_remove(plci, 0, false);
				plci_free_msg_in_queue(plci);
				channel_flow_control_remove(plci);
				plci->Id = 0;
				plci->State = IDLE;
				plci->channels = 0;
				plci->appl = NULL;
				plci->notifiedcall = 0;
			}
			listen_check(plci->adapter);
			return true;
		}
	}
	return false;
}


/*------------------------------------------------------------------*/

static byte plci_nl_busy(PLCI *plci)
{
	/* only applicable for non-multiplexed protocols */
	return (plci->nl_req
		|| (plci->ncci_ring_list
		    && plci->adapter->ncci_ch[plci->ncci_ring_list]
		    && (plci->adapter->ch_flow_control[plci->adapter->ncci_ch[plci->ncci_ring_list]] & N_OK_FC_PENDING)));
}


/*------------------------------------------------------------------*/
/* DTMF facilities                                                  */
/*------------------------------------------------------------------*/


static struct
{
	byte send_mask;
	byte listen_mask;
	byte character;
	byte code;
} dtmf_digit_map[] =
{
	{ 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK },
	{ 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR },
	{ 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0 },
	{ 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1 },
	{ 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2 },
	{ 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3 },
	{ 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4 },
	{ 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5 },
	{ 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6 },
	{ 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7 },
	{ 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8 },
	{ 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9 },
	{ 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A },
	{ 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B },
	{ 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C },
	{ 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D },
	{ 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A },
	{ 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B },
	{ 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C },
	{ 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D },

	{ 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE },
	{ 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE },
	{ 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE },
	{ 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE },
	{ 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE },
	{ 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE },
	{ 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE },
	{ 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE },
	{ 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE },
	{ 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE },
	{ 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE },
	{ 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE },
	{ 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE },
	{ 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE },
	{ 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE },
	{ 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE },
	{ 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE },
	{ 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE },
	{ 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE },
	{ 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE },
	{ 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE },
	{ 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE },
	{ 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE },
	{ 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL },
	{ 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE },
	{ 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE },
	{ 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE },
	{ 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE },
	{ 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE },
	{ 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE },
	{ 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE },
	{ 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE },
	{ 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE },
	{ 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS },
	{ 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID },
	{ 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH },
	{ 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390 },
	{ 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1 },
	{ 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2 },
	{ 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3 },
	{ 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4 },
	{ 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5 },
	{ 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6 },
	{ 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7 },
	{ 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8 },
	{ 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9 },
	{ 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0 },
	{ 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1 },
	{ 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2 },
	{ 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP },
	{ 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1 },
	{ 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST },

};

#define DTMF_DIGIT_MAP_ENTRIES ARRAY_SIZE(dtmf_digit_map)


static void dtmf_enable_receiver(PLCI *plci, byte enable_mask)
{
	word min_digit_duration, min_gap_duration;

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_enable_receiver %02x",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__, enable_mask));

	if (enable_mask != 0)
	{
		min_digit_duration = (plci->dtmf_rec_pulse_ms == 0) ? 40 : plci->dtmf_rec_pulse_ms;
		min_gap_duration = (plci->dtmf_rec_pause_ms == 0) ? 40 : plci->dtmf_rec_pause_ms;
		plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER;
		PUT_WORD(&plci->internal_req_buffer[1], min_digit_duration);
		PUT_WORD(&plci->internal_req_buffer[3], min_gap_duration);
		plci->NData[0].PLength = 5;

		PUT_WORD(&plci->internal_req_buffer[5], INTERNAL_IND_BUFFER_SIZE);
		plci->NData[0].PLength += 2;
		capidtmf_recv_enable(&(plci->capidtmf_state), min_digit_duration, min_gap_duration);

	}
	else
	{
		plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER;
		plci->NData[0].PLength = 1;

		capidtmf_recv_disable(&(plci->capidtmf_state));

	}
	plci->NData[0].P = plci->internal_req_buffer;
	plci->NL.X = plci->NData;
	plci->NL.ReqCh = 0;
	plci->NL.Req = plci->nl_req = (byte) N_UDATA;
	plci->adapter->request(&plci->NL);
}


static void dtmf_send_digits(PLCI *plci, byte *digit_buffer, word digit_count)
{
	word w, i;

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_digits %d",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__, digit_count));

	plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_SEND_DIGITS;
	w = (plci->dtmf_send_pulse_ms == 0) ? 40 : plci->dtmf_send_pulse_ms;
	PUT_WORD(&plci->internal_req_buffer[1], w);
	w = (plci->dtmf_send_pause_ms == 0) ? 40 : plci->dtmf_send_pause_ms;
	PUT_WORD(&plci->internal_req_buffer[3], w);
	for (i = 0; i < digit_count; i++)
	{
		w = 0;
		while ((w < DTMF_DIGIT_MAP_ENTRIES)
		       && (digit_buffer[i] != dtmf_digit_map[w].character))
		{
			w++;
		}
		plci->internal_req_buffer[5 + i] = (w < DTMF_DIGIT_MAP_ENTRIES) ?
			dtmf_digit_map[w].code : DTMF_DIGIT_TONE_CODE_STAR;
	}
	plci->NData[0].PLength = 5 + digit_count;
	plci->NData[0].P = plci->internal_req_buffer;
	plci->NL.X = plci->NData;
	plci->NL.ReqCh = 0;
	plci->NL.Req = plci->nl_req = (byte) N_UDATA;
	plci->adapter->request(&plci->NL);
}


static void dtmf_rec_clear_config(PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_rec_clear_config",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	plci->dtmf_rec_active = 0;
	plci->dtmf_rec_pulse_ms = 0;
	plci->dtmf_rec_pause_ms = 0;

	capidtmf_init(&(plci->capidtmf_state), plci->adapter->u_law);

}


static void dtmf_send_clear_config(PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_clear_config",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	plci->dtmf_send_requests = 0;
	plci->dtmf_send_pulse_ms = 0;
	plci->dtmf_send_pause_ms = 0;
}


static void dtmf_prepare_switch(dword Id, PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_prepare_switch",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	while (plci->dtmf_send_requests != 0)
		dtmf_confirmation(Id, plci);
}


static word dtmf_save_config(dword Id, PLCI *plci, byte Rc)
{

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_save_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	return (GOOD);
}


static word dtmf_restore_config(dword Id, PLCI *plci, byte Rc)
{
	word Info;

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_restore_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	Info = GOOD;
	if (plci->B1_facilities & B1_FACILITY_DTMFR)
	{
		switch (plci->adjust_b_state)
		{
		case ADJUST_B_RESTORE_DTMF_1:
			plci->internal_command = plci->adjust_b_command;
			if (plci_nl_busy(plci))
			{
				plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
				break;
			}
			dtmf_enable_receiver(plci, plci->dtmf_rec_active);
			plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_2;
			break;
		case ADJUST_B_RESTORE_DTMF_2:
			if ((Rc != OK) && (Rc != OK_FC))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Reenable DTMF receiver failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				Info = _WRONG_STATE;
				break;
			}
			break;
		}
	}
	return (Info);
}


static void dtmf_command(dword Id, PLCI *plci, byte Rc)
{
	word internal_command, Info;
	byte mask;
	byte result[4];

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
			plci->dtmf_cmd, plci->dtmf_rec_pulse_ms, plci->dtmf_rec_pause_ms,
			plci->dtmf_send_pulse_ms, plci->dtmf_send_pause_ms));

	Info = GOOD;
	result[0] = 2;
	PUT_WORD(&result[1], DTMF_SUCCESS);
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	mask = 0x01;
	switch (plci->dtmf_cmd)
	{

	case DTMF_LISTEN_TONE_START:
		mask <<= 1;
	case DTMF_LISTEN_MF_START:
		mask <<= 1;

	case DTMF_LISTEN_START:
		switch (internal_command)
		{
		default:
			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
								  B1_FACILITY_DTMFR), DTMF_COMMAND_1);
		case DTMF_COMMAND_1:
			if (adjust_b_process(Id, plci, Rc) != GOOD)
			{
				dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			if (plci->internal_command)
				return;
		case DTMF_COMMAND_2:
			if (plci_nl_busy(plci))
			{
				plci->internal_command = DTMF_COMMAND_2;
				return;
			}
			plci->internal_command = DTMF_COMMAND_3;
			dtmf_enable_receiver(plci, (byte)(plci->dtmf_rec_active | mask));
			return;
		case DTMF_COMMAND_3:
			if ((Rc != OK) && (Rc != OK_FC))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Enable DTMF receiver failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}

			plci->tone_last_indication_code = DTMF_SIGNAL_NO_TONE;

			plci->dtmf_rec_active |= mask;
			break;
		}
		break;


	case DTMF_LISTEN_TONE_STOP:
		mask <<= 1;
	case DTMF_LISTEN_MF_STOP:
		mask <<= 1;

	case DTMF_LISTEN_STOP:
		switch (internal_command)
		{
		default:
			plci->dtmf_rec_active &= ~mask;
			if (plci->dtmf_rec_active)
				break;
/*
  case DTMF_COMMAND_1:
  if (plci->dtmf_rec_active)
  {
  if (plci_nl_busy (plci))
  {
  plci->internal_command = DTMF_COMMAND_1;
  return;
  }
  plci->dtmf_rec_active &= ~mask;
  plci->internal_command = DTMF_COMMAND_2;
  dtmf_enable_receiver (plci, false);
  return;
  }
  Rc = OK;
  case DTMF_COMMAND_2:
  if ((Rc != OK) && (Rc != OK_FC))
  {
  dbug (1, dprintf("[%06lx] %s,%d: Disable DTMF receiver failed %02x",
  UnMapId (Id), (char far *)(FILE_), __LINE__, Rc));
  Info = _FACILITY_NOT_SUPPORTED;
  break;
  }
*/
			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
								  ~(B1_FACILITY_DTMFX | B1_FACILITY_DTMFR)), DTMF_COMMAND_3);
		case DTMF_COMMAND_3:
			if (adjust_b_process(Id, plci, Rc) != GOOD)
			{
				dbug(1, dprintf("[%06lx] %s,%d: Unload DTMF failed",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			if (plci->internal_command)
				return;
			break;
		}
		break;


	case DTMF_SEND_TONE:
		mask <<= 1;
	case DTMF_SEND_MF:
		mask <<= 1;

	case DTMF_DIGITS_SEND:
		switch (internal_command)
		{
		default:
			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
								  ((plci->dtmf_parameter_length != 0) ? B1_FACILITY_DTMFX | B1_FACILITY_DTMFR : B1_FACILITY_DTMFX)),
					   DTMF_COMMAND_1);
		case DTMF_COMMAND_1:
			if (adjust_b_process(Id, plci, Rc) != GOOD)
			{
				dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			if (plci->internal_command)
				return;
		case DTMF_COMMAND_2:
			if (plci_nl_busy(plci))
			{
				plci->internal_command = DTMF_COMMAND_2;
				return;
			}
			plci->dtmf_msg_number_queue[(plci->dtmf_send_requests)++] = plci->number;
			plci->internal_command = DTMF_COMMAND_3;
			dtmf_send_digits(plci, &plci->saved_msg.parms[3].info[1], plci->saved_msg.parms[3].length);
			return;
		case DTMF_COMMAND_3:
			if ((Rc != OK) && (Rc != OK_FC))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Send DTMF digits failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				if (plci->dtmf_send_requests != 0)
					(plci->dtmf_send_requests)--;
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			return;
		}
		break;
	}
	sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
	      "wws", Info, SELECTOR_DTMF, result);
}


static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL   *appl, API_PARSE *msg)
{
	word Info;
	word i, j;
	byte mask;
	API_PARSE dtmf_parms[5];
	byte result[40];

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_request",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	Info = GOOD;
	result[0] = 2;
	PUT_WORD(&result[1], DTMF_SUCCESS);
	if (!(a->profile.Global_Options & GL_DTMF_SUPPORTED))
	{
		dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		Info = _FACILITY_NOT_SUPPORTED;
	}
	else if (api_parse(&msg[1].info[1], msg[1].length, "w", dtmf_parms))
	{
		dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		Info = _WRONG_MESSAGE_FORMAT;
	}

	else if ((GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
		 || (GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_SEND_CODES))
	{
		if (!((a->requested_options_table[appl->Id - 1])
		      & (1L << PRIVATE_DTMF_TONE)))
		{
			dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
					UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
			PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
		}
		else
		{
			for (i = 0; i < 32; i++)
				result[4 + i] = 0;
			if (GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
			{
				for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
				{
					if (dtmf_digit_map[i].listen_mask != 0)
						result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7));
				}
			}
			else
			{
				for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
				{
					if (dtmf_digit_map[i].send_mask != 0)
						result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7));
				}
			}
			result[0] = 3 + 32;
			result[3] = 32;
		}
	}

	else if (plci == NULL)
	{
		dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		Info = _WRONG_IDENTIFIER;
	}
	else
	{
		if (!plci->State
		    || !plci->NL.Id || plci->nl_remove_id)
		{
			dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
					UnMapId(Id), (char *)(FILE_), __LINE__));
			Info = _WRONG_STATE;
		}
		else
		{
			plci->command = 0;
			plci->dtmf_cmd = GET_WORD(dtmf_parms[0].info);
			mask = 0x01;
			switch (plci->dtmf_cmd)
			{

			case DTMF_LISTEN_TONE_START:
			case DTMF_LISTEN_TONE_STOP:
				mask <<= 1;
			case DTMF_LISTEN_MF_START:
			case DTMF_LISTEN_MF_STOP:
				mask <<= 1;
				if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1])
				      & (1L << PRIVATE_DTMF_TONE)))
				{
					dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
							UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
					PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
					break;
				}

			case DTMF_LISTEN_START:
			case DTMF_LISTEN_STOP:
				if (!(a->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF)
				    && !(a->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
				{
					dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _FACILITY_NOT_SUPPORTED;
					break;
				}
				if (mask & DTMF_LISTEN_ACTIVE_FLAG)
				{
					if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
					{
						plci->dtmf_rec_pulse_ms = 0;
						plci->dtmf_rec_pause_ms = 0;
					}
					else
					{
						plci->dtmf_rec_pulse_ms = GET_WORD(dtmf_parms[1].info);
						plci->dtmf_rec_pause_ms = GET_WORD(dtmf_parms[2].info);
					}
				}
				start_internal_command(Id, plci, dtmf_command);
				return (false);


			case DTMF_SEND_TONE:
				mask <<= 1;
			case DTMF_SEND_MF:
				mask <<= 1;
				if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1])
				      & (1L << PRIVATE_DTMF_TONE)))
				{
					dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
							UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
					PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
					break;
				}

			case DTMF_DIGITS_SEND:
				if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				if (mask & DTMF_LISTEN_ACTIVE_FLAG)
				{
					plci->dtmf_send_pulse_ms = GET_WORD(dtmf_parms[1].info);
					plci->dtmf_send_pause_ms = GET_WORD(dtmf_parms[2].info);
				}
				i = 0;
				j = 0;
				while ((i < dtmf_parms[3].length) && (j < DTMF_DIGIT_MAP_ENTRIES))
				{
					j = 0;
					while ((j < DTMF_DIGIT_MAP_ENTRIES)
					       && ((dtmf_parms[3].info[i + 1] != dtmf_digit_map[j].character)
						   || ((dtmf_digit_map[j].send_mask & mask) == 0)))
					{
						j++;
					}
					i++;
				}
				if (j == DTMF_DIGIT_MAP_ENTRIES)
				{
					dbug(1, dprintf("[%06lx] %s,%d: Incorrect DTMF digit %02x",
							UnMapId(Id), (char *)(FILE_), __LINE__, dtmf_parms[3].info[i]));
					PUT_WORD(&result[1], DTMF_INCORRECT_DIGIT);
					break;
				}
				if (plci->dtmf_send_requests >= ARRAY_SIZE(plci->dtmf_msg_number_queue))
				{
					dbug(1, dprintf("[%06lx] %s,%d: DTMF request overrun",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_STATE;
					break;
				}
				api_save_msg(dtmf_parms, "wwws", &plci->saved_msg);
				start_internal_command(Id, plci, dtmf_command);
				return (false);

			default:
				dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
						UnMapId(Id), (char *)(FILE_), __LINE__, plci->dtmf_cmd));
				PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
			}
		}
	}
	sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
	      "wws", Info, SELECTOR_DTMF, result);
	return (false);
}


static void dtmf_confirmation(dword Id, PLCI *plci)
{
	word i;
	byte result[4];

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_confirmation",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	result[0] = 2;
	PUT_WORD(&result[1], DTMF_SUCCESS);
	if (plci->dtmf_send_requests != 0)
	{
		sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->dtmf_msg_number_queue[0],
		      "wws", GOOD, SELECTOR_DTMF, result);
		(plci->dtmf_send_requests)--;
		for (i = 0; i < plci->dtmf_send_requests; i++)
			plci->dtmf_msg_number_queue[i] = plci->dtmf_msg_number_queue[i + 1];
	}
}


static void dtmf_indication(dword Id, PLCI *plci, byte *msg, word length)
{
	word i, j, n;

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_indication",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	n = 0;
	for (i = 1; i < length; i++)
	{
		j = 0;
		while ((j < DTMF_DIGIT_MAP_ENTRIES)
		       && ((msg[i] != dtmf_digit_map[j].code)
			   || ((dtmf_digit_map[j].listen_mask & plci->dtmf_rec_active) == 0)))
		{
			j++;
		}
		if (j < DTMF_DIGIT_MAP_ENTRIES)
		{

			if ((dtmf_digit_map[j].listen_mask & DTMF_TONE_LISTEN_ACTIVE_FLAG)
			    && (plci->tone_last_indication_code == DTMF_SIGNAL_NO_TONE)
			    && (dtmf_digit_map[j].character != DTMF_SIGNAL_UNIDENTIFIED_TONE))
			{
				if (n + 1 == i)
				{
					for (i = length; i > n + 1; i--)
						msg[i] = msg[i - 1];
					length++;
					i++;
				}
				msg[++n] = DTMF_SIGNAL_UNIDENTIFIED_TONE;
			}
			plci->tone_last_indication_code = dtmf_digit_map[j].character;

			msg[++n] = dtmf_digit_map[j].character;
		}
	}
	if (n != 0)
	{
		msg[0] = (byte) n;
		sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "wS", SELECTOR_DTMF, msg);
	}
}


/*------------------------------------------------------------------*/
/* DTMF parameters                                                  */
/*------------------------------------------------------------------*/

static void dtmf_parameter_write(PLCI *plci)
{
	word i;
	byte parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE + 2];

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_write",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	parameter_buffer[0] = plci->dtmf_parameter_length + 1;
	parameter_buffer[1] = DSP_CTRL_SET_DTMF_PARAMETERS;
	for (i = 0; i < plci->dtmf_parameter_length; i++)
		parameter_buffer[2 + i] = plci->dtmf_parameter_buffer[i];
	add_p(plci, FTY, parameter_buffer);
	sig_req(plci, TEL_CTRL, 0);
	send_req(plci);
}


static void dtmf_parameter_clear_config(PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_clear_config",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	plci->dtmf_parameter_length = 0;
}


static void dtmf_parameter_prepare_switch(dword Id, PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_prepare_switch",
			UnMapId(Id), (char *)(FILE_), __LINE__));

}


static word dtmf_parameter_save_config(dword Id, PLCI *plci, byte Rc)
{

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	return (GOOD);
}


static word dtmf_parameter_restore_config(dword Id, PLCI *plci, byte Rc)
{
	word Info;

	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	Info = GOOD;
	if ((plci->B1_facilities & B1_FACILITY_DTMFR)
	    && (plci->dtmf_parameter_length != 0))
	{
		switch (plci->adjust_b_state)
		{
		case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
			plci->internal_command = plci->adjust_b_command;
			if (plci->sig_req)
			{
				plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
				break;
			}
			dtmf_parameter_write(plci);
			plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_2;
			break;
		case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
			if ((Rc != OK) && (Rc != OK_FC))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Restore DTMF parameters failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				Info = _WRONG_STATE;
				break;
			}
			break;
		}
	}
	return (Info);
}


/*------------------------------------------------------------------*/
/* Line interconnect facilities                                     */
/*------------------------------------------------------------------*/


LI_CONFIG   *li_config_table;
word li_total_channels;


/*------------------------------------------------------------------*/
/* translate a CHI information element to a channel number          */
/* returns 0xff - any channel                                       */
/*         0xfe - chi wrong coding                                  */
/*         0xfd - D-channel                                         */
/*         0x00 - no channel                                        */
/*         else channel number / PRI: timeslot                      */
/* if channels is provided we accept more than one channel.         */
/*------------------------------------------------------------------*/

static byte chi_to_channel(byte *chi, dword *pchannelmap)
{
	int p;
	int i;
	dword map;
	byte excl;
	byte ofs;
	byte ch;

	if (pchannelmap) *pchannelmap = 0;
	if (!chi[0]) return 0xff;
	excl = 0;

	if (chi[1] & 0x20) {
		if (chi[0] == 1 && chi[1] == 0xac) return 0xfd; /* exclusive d-channel */
		for (i = 1; i < chi[0] && !(chi[i] & 0x80); i++);
		if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
		if ((chi[1] | 0xc8) != 0xe9) return 0xfe;
		if (chi[1] & 0x08) excl = 0x40;

		/* int. id present */
		if (chi[1] & 0x40) {
			p = i + 1;
			for (i = p; i < chi[0] && !(chi[i] & 0x80); i++);
			if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
		}

		/* coding standard, Number/Map, Channel Type */
		p = i + 1;
		for (i = p; i < chi[0] && !(chi[i] & 0x80); i++);
		if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
		if ((chi[p] | 0xd0) != 0xd3) return 0xfe;

		/* Number/Map */
		if (chi[p] & 0x10) {

			/* map */
			if ((chi[0] - p) == 4) ofs = 0;
			else if ((chi[0] - p) == 3) ofs = 1;
			else return 0xfe;
			ch = 0;
			map = 0;
			for (i = 0; i < 4 && p < chi[0]; i++) {
				p++;
				ch += 8;
				map <<= 8;
				if (chi[p]) {
					for (ch = 0; !(chi[p] & (1 << ch)); ch++);
					map |= chi[p];
				}
			}
			ch += ofs;
			map <<= ofs;
		}
		else {

			/* number */
			p = i + 1;
			ch = chi[p] & 0x3f;
			if (pchannelmap) {
				if ((byte)(chi[0] - p) > 30) return 0xfe;
				map = 0;
				for (i = p; i <= chi[0]; i++) {
					if ((chi[i] & 0x7f) > 31) return 0xfe;
					map |= (1L << (chi[i] & 0x7f));
				}
			}
			else {
				if (p != chi[0]) return 0xfe;
				if (ch > 31) return 0xfe;
				map = (1L << ch);
			}
			if (chi[p] & 0x40) return 0xfe;
		}
		if (pchannelmap) *pchannelmap = map;
		else if (map != ((dword)(1L << ch))) return 0xfe;
		return (byte)(excl | ch);
	}
	else {  /* not PRI */
		for (i = 1; i < chi[0] && !(chi[i] & 0x80); i++);
		if (i != chi[0] || !(chi[i] & 0x80)) return 0xfe;
		if (chi[1] & 0x08) excl = 0x40;

		switch (chi[1] | 0x98) {
		case 0x98: return 0;
		case 0x99:
			if (pchannelmap) *pchannelmap = 2;
			return excl | 1;
		case 0x9a:
			if (pchannelmap) *pchannelmap = 4;
			return excl | 2;
		case 0x9b: return 0xff;
		case 0x9c: return 0xfd; /* d-ch */
		default: return 0xfe;
		}
	}
}


static void mixer_set_bchannel_id_esc(PLCI *plci, byte bchannel_id)
{
	DIVA_CAPI_ADAPTER *a;
	PLCI *splci;
	byte old_id;

	a = plci->adapter;
	old_id = plci->li_bchannel_id;
	if (a->li_pri)
	{
		if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
			li_config_table[a->li_base + (old_id - 1)].plci = NULL;
		plci->li_bchannel_id = (bchannel_id & 0x1f) + 1;
		if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
			li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
	}
	else
	{
		if (((bchannel_id & 0x03) == 1) || ((bchannel_id & 0x03) == 2))
		{
			if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
				li_config_table[a->li_base + (old_id - 1)].plci = NULL;
			plci->li_bchannel_id = bchannel_id & 0x03;
			if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE))
			{
				splci = a->AdvSignalPLCI;
				if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
				{
					if ((splci->li_bchannel_id != 0)
					    && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
					{
						li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
					}
					splci->li_bchannel_id = 3 - plci->li_bchannel_id;
					li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci;
					dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d",
							(dword)((splci->Id << 8) | UnMapController(splci->adapter->Id)),
							(char *)(FILE_), __LINE__, splci->li_bchannel_id));
				}
			}
			if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
				li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
		}
	}
	if ((old_id == 0) && (plci->li_bchannel_id != 0)
	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
	{
		mixer_clear_config(plci);
	}
	dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__, bchannel_id, plci->li_bchannel_id));
}


static void mixer_set_bchannel_id(PLCI *plci, byte *chi)
{
	DIVA_CAPI_ADAPTER *a;
	PLCI *splci;
	byte ch, old_id;

	a = plci->adapter;
	old_id = plci->li_bchannel_id;
	ch = chi_to_channel(chi, NULL);
	if (!(ch & 0x80))
	{
		if (a->li_pri)
		{
			if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
				li_config_table[a->li_base + (old_id - 1)].plci = NULL;
			plci->li_bchannel_id = (ch & 0x1f) + 1;
			if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
				li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
		}
		else
		{
			if (((ch & 0x1f) == 1) || ((ch & 0x1f) == 2))
			{
				if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
					li_config_table[a->li_base + (old_id - 1)].plci = NULL;
				plci->li_bchannel_id = ch & 0x1f;
				if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE))
				{
					splci = a->AdvSignalPLCI;
					if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
					{
						if ((splci->li_bchannel_id != 0)
						    && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
						{
							li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
						}
						splci->li_bchannel_id = 3 - plci->li_bchannel_id;
						li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci;
						dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
								(dword)((splci->Id << 8) | UnMapController(splci->adapter->Id)),
								(char *)(FILE_), __LINE__, splci->li_bchannel_id));
					}
				}
				if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
					li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
			}
		}
	}
	if ((old_id == 0) && (plci->li_bchannel_id != 0)
	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
	{
		mixer_clear_config(plci);
	}
	dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__, ch, plci->li_bchannel_id));
}


#define MIXER_MAX_DUMP_CHANNELS 34

static void mixer_calculate_coefs(DIVA_CAPI_ADAPTER *a)
{
	static char hex_digit_table[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
	word n, i, j;
	char *p;
	char hex_line[2 * MIXER_MAX_DUMP_CHANNELS + MIXER_MAX_DUMP_CHANNELS / 8 + 4];

	dbug(1, dprintf("[%06lx] %s,%d: mixer_calculate_coefs",
			(dword)(UnMapController(a->Id)), (char *)(FILE_), __LINE__));

	for (i = 0; i < li_total_channels; i++)
	{
		li_config_table[i].channel &= LI_CHANNEL_ADDRESSES_SET;
		if (li_config_table[i].chflags != 0)
			li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
		else
		{
			for (j = 0; j < li_total_channels; j++)
			{
				if (((li_config_table[i].flag_table[j]) != 0)
				    || ((li_config_table[j].flag_table[i]) != 0))
				{
					li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
				}
				if (((li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) != 0)
				    || ((li_config_table[j].flag_table[i] & LI_FLAG_CONFERENCE) != 0))
				{
					li_config_table[i].channel |= LI_CHANNEL_CONFERENCE;
				}
			}
		}
	}
	for (i = 0; i < li_total_channels; i++)
	{
		for (j = 0; j < li_total_channels; j++)
		{
			li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC);
			if (li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE)
				li_config_table[i].coef_table[j] |= LI_COEF_CH_CH;
		}
	}
	for (n = 0; n < li_total_channels; n++)
	{
		if (li_config_table[n].channel & LI_CHANNEL_CONFERENCE)
		{
			for (i = 0; i < li_total_channels; i++)
			{
				if (li_config_table[i].channel & LI_CHANNEL_CONFERENCE)
				{
					for (j = 0; j < li_total_channels; j++)
					{
						li_config_table[i].coef_table[j] |=
							li_config_table[i].coef_table[n] & li_config_table[n].coef_table[j];
					}
				}
			}
		}
	}
	for (i = 0; i < li_total_channels; i++)
	{
		if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
		{
			li_config_table[i].coef_table[i] &= ~LI_COEF_CH_CH;
			for (j = 0; j < li_total_channels; j++)
			{
				if (li_config_table[i].coef_table[j] & LI_COEF_CH_CH)
					li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE;
			}
			if (li_config_table[i].flag_table[i] & LI_FLAG_CONFERENCE)
				li_config_table[i].coef_table[i] |= LI_COEF_CH_CH;
		}
	}
	for (i = 0; i < li_total_channels; i++)
	{
		if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
		{
			for (j = 0; j < li_total_channels; j++)
			{
				if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
					li_config_table[i].coef_table[j] |= LI_COEF_CH_CH;
				if (li_config_table[i].flag_table[j] & LI_FLAG_MONITOR)
					li_config_table[i].coef_table[j] |= LI_COEF_CH_PC;
				if (li_config_table[i].flag_table[j] & LI_FLAG_MIX)
					li_config_table[i].coef_table[j] |= LI_COEF_PC_CH;
				if (li_config_table[i].flag_table[j] & LI_FLAG_PCCONNECT)
					li_config_table[i].coef_table[j] |= LI_COEF_PC_PC;
			}
			if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
			{
				for (j = 0; j < li_total_channels; j++)
				{
					if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
					{
						li_config_table[i].coef_table[j] |= LI_COEF_CH_PC;
						if (li_config_table[j].chflags & LI_CHFLAG_MIX)
							li_config_table[i].coef_table[j] |= LI_COEF_PC_CH | LI_COEF_PC_PC;
					}
				}
			}
			if (li_config_table[i].chflags & LI_CHFLAG_MIX)
			{
				for (j = 0; j < li_total_channels; j++)
				{
					if (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT)
						li_config_table[j].coef_table[i] |= LI_COEF_PC_CH;
				}
			}
			if (li_config_table[i].chflags & LI_CHFLAG_LOOP)
			{
				for (j = 0; j < li_total_channels; j++)
				{
					if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
					{
						for (n = 0; n < li_total_channels; n++)
						{
							if (li_config_table[n].flag_table[i] & LI_FLAG_INTERCONNECT)
							{
								li_config_table[n].coef_table[j] |= LI_COEF_CH_CH;
								if (li_config_table[j].chflags & LI_CHFLAG_MIX)
								{
									li_config_table[n].coef_table[j] |= LI_COEF_PC_CH;
									if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
										li_config_table[n].coef_table[j] |= LI_COEF_CH_PC | LI_COEF_PC_PC;
								}
								else if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
									li_config_table[n].coef_table[j] |= LI_COEF_CH_PC;
							}
						}
					}
				}
			}
		}
	}
	for (i = 0; i < li_total_channels; i++)
	{
		if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
		{
			if (li_config_table[i].chflags & (LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP))
				li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
			if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
				li_config_table[i].channel |= LI_CHANNEL_RX_DATA;
			if (li_config_table[i].chflags & LI_CHFLAG_MIX)
				li_config_table[i].channel |= LI_CHANNEL_TX_DATA;
			for (j = 0; j < li_total_channels; j++)
			{
				if ((li_config_table[i].flag_table[j] &
				     (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_MONITOR))
				    || (li_config_table[j].flag_table[i] &
					(LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX)))
				{
					li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
				}
				if (li_config_table[i].flag_table[j] & (LI_FLAG_PCCONNECT | LI_FLAG_MONITOR))
					li_config_table[i].channel |= LI_CHANNEL_RX_DATA;
				if (li_config_table[j].flag_table[i] & (LI_FLAG_PCCONNECT | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX))
					li_config_table[i].channel |= LI_CHANNEL_TX_DATA;
			}
			if (!(li_config_table[i].channel & LI_CHANNEL_ACTIVE))
			{
				li_config_table[i].coef_table[i] |= LI_COEF_PC_CH | LI_COEF_CH_PC;
				li_config_table[i].channel |= LI_CHANNEL_TX_DATA | LI_CHANNEL_RX_DATA;
			}
		}
	}
	for (i = 0; i < li_total_channels; i++)
	{
		if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
		{
			j = 0;
			while ((j < li_total_channels) && !(li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT))
				j++;
			if (j < li_total_channels)
			{
				for (j = 0; j < li_total_channels; j++)
				{
					li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_PC_CH);
					if (li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT)
						li_config_table[i].coef_table[j] |= LI_COEF_PC_CH;
				}
			}
		}
	}
	n = li_total_channels;
	if (n > MIXER_MAX_DUMP_CHANNELS)
		n = MIXER_MAX_DUMP_CHANNELS;
	p = hex_line;
	for (j = 0; j < n; j++)
	{
		if ((j & 0x7) == 0)
			*(p++) = ' ';
		*(p++) = hex_digit_table[li_config_table[j].curchnl >> 4];
		*(p++) = hex_digit_table[li_config_table[j].curchnl & 0xf];
	}
	*p = '\0';
	dbug(1, dprintf("[%06lx] CURRENT %s",
			(dword)(UnMapController(a->Id)), (char *)hex_line));
	p = hex_line;
	for (j = 0; j < n; j++)
	{
		if ((j & 0x7) == 0)
			*(p++) = ' ';
		*(p++) = hex_digit_table[li_config_table[j].channel >> 4];
		*(p++) = hex_digit_table[li_config_table[j].channel & 0xf];
	}
	*p = '\0';
	dbug(1, dprintf("[%06lx] CHANNEL %s",
			(dword)(UnMapController(a->Id)), (char *)hex_line));
	p = hex_line;
	for (j = 0; j < n; j++)
	{
		if ((j & 0x7) == 0)
			*(p++) = ' ';
		*(p++) = hex_digit_table[li_config_table[j].chflags >> 4];
		*(p++) = hex_digit_table[li_config_table[j].chflags & 0xf];
	}
	*p = '\0';
	dbug(1, dprintf("[%06lx] CHFLAG  %s",
			(dword)(UnMapController(a->Id)), (char *)hex_line));
	for (i = 0; i < n; i++)
	{
		p = hex_line;
		for (j = 0; j < n; j++)
		{
			if ((j & 0x7) == 0)
				*(p++) = ' ';
			*(p++) = hex_digit_table[li_config_table[i].flag_table[j] >> 4];
			*(p++) = hex_digit_table[li_config_table[i].flag_table[j] & 0xf];
		}
		*p = '\0';
		dbug(1, dprintf("[%06lx] FLAG[%02x]%s",
				(dword)(UnMapController(a->Id)), i, (char *)hex_line));
	}
	for (i = 0; i < n; i++)
	{
		p = hex_line;
		for (j = 0; j < n; j++)
		{
			if ((j & 0x7) == 0)
				*(p++) = ' ';
			*(p++) = hex_digit_table[li_config_table[i].coef_table[j] >> 4];
			*(p++) = hex_digit_table[li_config_table[i].coef_table[j] & 0xf];
		}
		*p = '\0';
		dbug(1, dprintf("[%06lx] COEF[%02x]%s",
				(dword)(UnMapController(a->Id)), i, (char *)hex_line));
	}
}


static struct
{
	byte mask;
	byte line_flags;
} mixer_write_prog_pri[] =
{
	{ LI_COEF_CH_CH, 0 },
	{ LI_COEF_CH_PC, MIXER_COEF_LINE_TO_PC_FLAG },
	{ LI_COEF_PC_CH, MIXER_COEF_LINE_FROM_PC_FLAG },
	{ LI_COEF_PC_PC, MIXER_COEF_LINE_TO_PC_FLAG | MIXER_COEF_LINE_FROM_PC_FLAG }
};

static struct
{
	byte from_ch;
	byte to_ch;
	byte mask;
	byte xconnect_override;
} mixer_write_prog_bri[] =
{
	{ 0, 0, LI_COEF_CH_CH, 0x01 },  /* B      to B      */
	{ 1, 0, LI_COEF_CH_CH, 0x01 },  /* Alt B  to B      */
	{ 0, 0, LI_COEF_PC_CH, 0x80 },  /* PC     to B      */
	{ 1, 0, LI_COEF_PC_CH, 0x01 },  /* Alt PC to B      */
	{ 2, 0, LI_COEF_CH_CH, 0x00 },  /* IC     to B      */
	{ 3, 0, LI_COEF_CH_CH, 0x00 },  /* Alt IC to B      */
	{ 0, 0, LI_COEF_CH_PC, 0x80 },  /* B      to PC     */
	{ 1, 0, LI_COEF_CH_PC, 0x01 },  /* Alt B  to PC     */
	{ 0, 0, LI_COEF_PC_PC, 0x01 },  /* PC     to PC     */
	{ 1, 0, LI_COEF_PC_PC, 0x01 },  /* Alt PC to PC     */
	{ 2, 0, LI_COEF_CH_PC, 0x00 },  /* IC     to PC     */
	{ 3, 0, LI_COEF_CH_PC, 0x00 },  /* Alt IC to PC     */
	{ 0, 2, LI_COEF_CH_CH, 0x00 },  /* B      to IC     */
	{ 1, 2, LI_COEF_CH_CH, 0x00 },  /* Alt B  to IC     */
	{ 0, 2, LI_COEF_PC_CH, 0x00 },  /* PC     to IC     */
	{ 1, 2, LI_COEF_PC_CH, 0x00 },  /* Alt PC to IC     */
	{ 2, 2, LI_COEF_CH_CH, 0x00 },  /* IC     to IC     */
	{ 3, 2, LI_COEF_CH_CH, 0x00 },  /* Alt IC to IC     */
	{ 1, 1, LI_COEF_CH_CH, 0x01 },  /* Alt B  to Alt B  */
	{ 0, 1, LI_COEF_CH_CH, 0x01 },  /* B      to Alt B  */
	{ 1, 1, LI_COEF_PC_CH, 0x80 },  /* Alt PC to Alt B  */
	{ 0, 1, LI_COEF_PC_CH, 0x01 },  /* PC     to Alt B  */
	{ 3, 1, LI_COEF_CH_CH, 0x00 },  /* Alt IC to Alt B  */
	{ 2, 1, LI_COEF_CH_CH, 0x00 },  /* IC     to Alt B  */
	{ 1, 1, LI_COEF_CH_PC, 0x80 },  /* Alt B  to Alt PC */
	{ 0, 1, LI_COEF_CH_PC, 0x01 },  /* B      to Alt PC */
	{ 1, 1, LI_COEF_PC_PC, 0x01 },  /* Alt PC to Alt PC */
	{ 0, 1, LI_COEF_PC_PC, 0x01 },  /* PC     to Alt PC */
	{ 3, 1, LI_COEF_CH_PC, 0x00 },  /* Alt IC to Alt PC */
	{ 2, 1, LI_COEF_CH_PC, 0x00 },  /* IC     to Alt PC */
	{ 1, 3, LI_COEF_CH_CH, 0x00 },  /* Alt B  to Alt IC */
	{ 0, 3, LI_COEF_CH_CH, 0x00 },  /* B      to Alt IC */
	{ 1, 3, LI_COEF_PC_CH, 0x00 },  /* Alt PC to Alt IC */
	{ 0, 3, LI_COEF_PC_CH, 0x00 },  /* PC     to Alt IC */
	{ 3, 3, LI_COEF_CH_CH, 0x00 },  /* Alt IC to Alt IC */
	{ 2, 3, LI_COEF_CH_CH, 0x00 }   /* IC     to Alt IC */
};

static byte mixer_swapped_index_bri[] =
{
	18,  /* B      to B      */
	19,  /* Alt B  to B      */
	20,  /* PC     to B      */
	21,  /* Alt PC to B      */
	22,  /* IC     to B      */
	23,  /* Alt IC to B      */
	24,  /* B      to PC     */
	25,  /* Alt B  to PC     */
	26,  /* PC     to PC     */
	27,  /* Alt PC to PC     */
	28,  /* IC     to PC     */
	29,  /* Alt IC to PC     */
	30,  /* B      to IC     */
	31,  /* Alt B  to IC     */
	32,  /* PC     to IC     */
	33,  /* Alt PC to IC     */
	34,  /* IC     to IC     */
	35,  /* Alt IC to IC     */
	0,   /* Alt B  to Alt B  */
	1,   /* B      to Alt B  */
	2,   /* Alt PC to Alt B  */
	3,   /* PC     to Alt B  */
	4,   /* Alt IC to Alt B  */
	5,   /* IC     to Alt B  */
	6,   /* Alt B  to Alt PC */
	7,   /* B      to Alt PC */
	8,   /* Alt PC to Alt PC */
	9,   /* PC     to Alt PC */
	10,  /* Alt IC to Alt PC */
	11,  /* IC     to Alt PC */
	12,  /* Alt B  to Alt IC */
	13,  /* B      to Alt IC */
	14,  /* Alt PC to Alt IC */
	15,  /* PC     to Alt IC */
	16,  /* Alt IC to Alt IC */
	17   /* IC     to Alt IC */
};

static struct
{
	byte mask;
	byte from_pc;
	byte to_pc;
} xconnect_write_prog[] =
{
	{ LI_COEF_CH_CH, false, false },
	{ LI_COEF_CH_PC, false, true },
	{ LI_COEF_PC_CH, true, false },
	{ LI_COEF_PC_PC, true, true }
};


static void xconnect_query_addresses(PLCI *plci)
{
	DIVA_CAPI_ADAPTER *a;
	word w, ch;
	byte *p;

	dbug(1, dprintf("[%06lx] %s,%d: xconnect_query_addresses",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	a = plci->adapter;
	if (a->li_pri && ((plci->li_bchannel_id == 0)
			  || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)))
	{
		dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out",
				(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
				(char *)(FILE_), __LINE__));
		return;
	}
	p = plci->internal_req_buffer;
	ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
	*(p++) = UDATA_REQUEST_XCONNECT_FROM;
	w = ch;
	*(p++) = (byte) w;
	*(p++) = (byte)(w >> 8);
	w = ch | XCONNECT_CHANNEL_PORT_PC;
	*(p++) = (byte) w;
	*(p++) = (byte)(w >> 8);
	plci->NData[0].P = plci->internal_req_buffer;
	plci->NData[0].PLength = p - plci->internal_req_buffer;
	plci->NL.X = plci->NData;
	plci->NL.ReqCh = 0;
	plci->NL.Req = plci->nl_req = (byte) N_UDATA;
	plci->adapter->request(&plci->NL);
}


static void xconnect_write_coefs(PLCI *plci, word internal_command)
{

	dbug(1, dprintf("[%06lx] %s,%d: xconnect_write_coefs %04x",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__, internal_command));

	plci->li_write_command = internal_command;
	plci->li_write_channel = 0;
}


static byte xconnect_write_coefs_process(dword Id, PLCI *plci, byte Rc)
{
	DIVA_CAPI_ADAPTER *a;
	word w, n, i, j, r, s, to_ch;
	dword d;
	byte *p;
	struct xconnect_transfer_address_s   *transfer_address;
	byte ch_map[MIXER_CHANNELS_BRI];

	dbug(1, dprintf("[%06x] %s,%d: xconnect_write_coefs_process %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->li_write_channel));

	a = plci->adapter;
	if ((plci->li_bchannel_id == 0)
	    || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
	{
		dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		return (true);
	}
	i = a->li_base + (plci->li_bchannel_id - 1);
	j = plci->li_write_channel;
	p = plci->internal_req_buffer;
	if (j != 0)
	{
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: LI write coefs failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			return (false);
		}
	}
	if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
	{
		r = 0;
		s = 0;
		if (j < li_total_channels)
		{
			if (li_config_table[i].channel & LI_CHANNEL_ADDRESSES_SET)
			{
				s = ((li_config_table[i].send_b.card_address.low | li_config_table[i].send_b.card_address.high) ?
				     (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_PC | LI_COEF_PC_PC)) &
					((li_config_table[i].send_pc.card_address.low | li_config_table[i].send_pc.card_address.high) ?
					 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_PC_CH));
			}
			r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
			while ((j < li_total_channels)
			       && ((r == 0)
				   || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET))
				   || (!li_config_table[j].adapter->li_pri
				       && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI))
				   || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low)
					|| (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high))
				       && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)
					   || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)))
				   || ((li_config_table[j].adapter->li_base != a->li_base)
				       && !(r & s &
					    ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
					     (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
					    ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
					     (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC))))))
			{
				j++;
				if (j < li_total_channels)
					r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
			}
		}
		if (j < li_total_channels)
		{
			plci->internal_command = plci->li_write_command;
			if (plci_nl_busy(plci))
				return (true);
			to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
			*(p++) = UDATA_REQUEST_XCONNECT_TO;
			do
			{
				if (li_config_table[j].adapter->li_base != a->li_base)
				{
					r &= s &
						((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
						 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
						((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
						 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC));
				}
				n = 0;
				do
				{
					if (r & xconnect_write_prog[n].mask)
					{
						if (xconnect_write_prog[n].from_pc)
							transfer_address = &(li_config_table[j].send_pc);
						else
							transfer_address = &(li_config_table[j].send_b);
						d = transfer_address->card_address.low;
						*(p++) = (byte) d;
						*(p++) = (byte)(d >> 8);
						*(p++) = (byte)(d >> 16);
						*(p++) = (byte)(d >> 24);
						d = transfer_address->card_address.high;
						*(p++) = (byte) d;
						*(p++) = (byte)(d >> 8);
						*(p++) = (byte)(d >> 16);
						*(p++) = (byte)(d >> 24);
						d = transfer_address->offset;
						*(p++) = (byte) d;
						*(p++) = (byte)(d >> 8);
						*(p++) = (byte)(d >> 16);
						*(p++) = (byte)(d >> 24);
						w = xconnect_write_prog[n].to_pc ? to_ch | XCONNECT_CHANNEL_PORT_PC : to_ch;
						*(p++) = (byte) w;
						*(p++) = (byte)(w >> 8);
						w = ((li_config_table[i].coef_table[j] & xconnect_write_prog[n].mask) == 0) ? 0x01 :
							(li_config_table[i].adapter->u_law ?
							 (li_config_table[j].adapter->u_law ? 0x80 : 0x86) :
							 (li_config_table[j].adapter->u_law ? 0x7a : 0x80));
						*(p++) = (byte) w;
						*(p++) = (byte) 0;
						li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4;
					}
					n++;
				} while ((n < ARRAY_SIZE(xconnect_write_prog))
					 && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
				if (n == ARRAY_SIZE(xconnect_write_prog))
				{
					do
					{
						j++;
						if (j < li_total_channels)
							r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
					} while ((j < li_total_channels)
						 && ((r == 0)
						     || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET))
						     || (!li_config_table[j].adapter->li_pri
							 && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI))
						     || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low)
							  || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high))
							 && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)
							     || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)))
						     || ((li_config_table[j].adapter->li_base != a->li_base)
							 && !(r & s &
							      ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
							       (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
							      ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
							       (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC))))));
				}
			} while ((j < li_total_channels)
				 && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
		}
		else if (j == li_total_channels)
		{
			plci->internal_command = plci->li_write_command;
			if (plci_nl_busy(plci))
				return (true);
			if (a->li_pri)
			{
				*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
				w = 0;
				if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
					w |= MIXER_FEATURE_ENABLE_TX_DATA;
				if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
					w |= MIXER_FEATURE_ENABLE_RX_DATA;
				*(p++) = (byte) w;
				*(p++) = (byte)(w >> 8);
			}
			else
			{
				*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
				w = 0;
				if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
				    && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
				{
					w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
				}
				if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
					w |= MIXER_FEATURE_ENABLE_TX_DATA;
				if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
					w |= MIXER_FEATURE_ENABLE_RX_DATA;
				*(p++) = (byte) w;
				*(p++) = (byte)(w >> 8);
				for (j = 0; j < sizeof(ch_map); j += 2)
				{
					if (plci->li_bchannel_id == 2)
					{
						ch_map[j] = (byte)(j + 1);
						ch_map[j + 1] = (byte) j;
					}
					else
					{
						ch_map[j] = (byte) j;
						ch_map[j + 1] = (byte)(j + 1);
					}
				}
				for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
				{
					i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
					j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
					if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
					{
						*p = (mixer_write_prog_bri[n].xconnect_override != 0) ?
							mixer_write_prog_bri[n].xconnect_override :
							((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
						if ((i >= a->li_base + MIXER_BCHANNELS_BRI) || (j >= a->li_base + MIXER_BCHANNELS_BRI))
						{
							w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
							li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
						}
					}
					else
					{
						*p = 0x00;
						if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
						{
							w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n];
							if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length)
								*p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w];
						}
					}
					p++;
				}
			}
			j = li_total_channels + 1;
		}
	}
	else
	{
		if (j <= li_total_channels)
		{
			plci->internal_command = plci->li_write_command;
			if (plci_nl_busy(plci))
				return (true);
			if (j < a->li_base)
				j = a->li_base;
			if (a->li_pri)
			{
				*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
				w = 0;
				if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
					w |= MIXER_FEATURE_ENABLE_TX_DATA;
				if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
					w |= MIXER_FEATURE_ENABLE_RX_DATA;
				*(p++) = (byte) w;
				*(p++) = (byte)(w >> 8);
				for (n = 0; n < ARRAY_SIZE(mixer_write_prog_pri); n++)
				{
					*(p++) = (byte)((plci->li_bchannel_id - 1) | mixer_write_prog_pri[n].line_flags);
					for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
					{
						w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
						if (w & mixer_write_prog_pri[n].mask)
						{
							*(p++) = (li_config_table[i].coef_table[j] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01;
							li_config_table[i].coef_table[j] ^= mixer_write_prog_pri[n].mask << 4;
						}
						else
							*(p++) = 0x00;
					}
					*(p++) = (byte)((plci->li_bchannel_id - 1) | MIXER_COEF_LINE_ROW_FLAG | mixer_write_prog_pri[n].line_flags);
					for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
					{
						w = ((li_config_table[j].coef_table[i] & 0xf) ^ (li_config_table[j].coef_table[i] >> 4));
						if (w & mixer_write_prog_pri[n].mask)
						{
							*(p++) = (li_config_table[j].coef_table[i] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01;
							li_config_table[j].coef_table[i] ^= mixer_write_prog_pri[n].mask << 4;
						}
						else
							*(p++) = 0x00;
					}
				}
			}
			else
			{
				*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
				w = 0;
				if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
				    && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
				{
					w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
				}
				if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
					w |= MIXER_FEATURE_ENABLE_TX_DATA;
				if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
					w |= MIXER_FEATURE_ENABLE_RX_DATA;
				*(p++) = (byte) w;
				*(p++) = (byte)(w >> 8);
				for (j = 0; j < sizeof(ch_map); j += 2)
				{
					if (plci->li_bchannel_id == 2)
					{
						ch_map[j] = (byte)(j + 1);
						ch_map[j + 1] = (byte) j;
					}
					else
					{
						ch_map[j] = (byte) j;
						ch_map[j + 1] = (byte)(j + 1);
					}
				}
				for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
				{
					i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
					j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
					if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
					{
						*p = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
						w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
						li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
					}
					else
					{
						*p = 0x00;
						if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
						{
							w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n];
							if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length)
								*p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w];
						}
					}
					p++;
				}
			}
			j = li_total_channels + 1;
		}
	}
	plci->li_write_channel = j;
	if (p != plci->internal_req_buffer)
	{
		plci->NData[0].P = plci->internal_req_buffer;
		plci->NData[0].PLength = p - plci->internal_req_buffer;
		plci->NL.X = plci->NData;
		plci->NL.ReqCh = 0;
		plci->NL.Req = plci->nl_req = (byte) N_UDATA;
		plci->adapter->request(&plci->NL);
	}
	return (true);
}


static void mixer_notify_update(PLCI *plci, byte others)
{
	DIVA_CAPI_ADAPTER *a;
	word i, w;
	PLCI *notify_plci;
	byte msg[sizeof(CAPI_MSG_HEADER) + 6];

	dbug(1, dprintf("[%06lx] %s,%d: mixer_notify_update %d",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__, others));

	a = plci->adapter;
	if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
	{
		if (others)
			plci->li_notify_update = true;
		i = 0;
		do
		{
			notify_plci = NULL;
			if (others)
			{
				while ((i < li_total_channels) && (li_config_table[i].plci == NULL))
					i++;
				if (i < li_total_channels)
					notify_plci = li_config_table[i++].plci;
			}
			else
			{
				if ((plci->li_bchannel_id != 0)
				    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
				{
					notify_plci = plci;
				}
			}
			if ((notify_plci != NULL)
			    && !notify_plci->li_notify_update
			    && (notify_plci->appl != NULL)
			    && (notify_plci->State)
			    && notify_plci->NL.Id && !notify_plci->nl_remove_id)
			{
				notify_plci->li_notify_update = true;
				((CAPI_MSG *) msg)->header.length = 18;
				((CAPI_MSG *) msg)->header.appl_id = notify_plci->appl->Id;
				((CAPI_MSG *) msg)->header.command = _FACILITY_R;
				((CAPI_MSG *) msg)->header.number = 0;
				((CAPI_MSG *) msg)->header.controller = notify_plci->adapter->Id;
				((CAPI_MSG *) msg)->header.plci = notify_plci->Id;
				((CAPI_MSG *) msg)->header.ncci = 0;
				((CAPI_MSG *) msg)->info.facility_req.Selector = SELECTOR_LINE_INTERCONNECT;
				((CAPI_MSG *) msg)->info.facility_req.structs[0] = 3;
				PUT_WORD(&(((CAPI_MSG *) msg)->info.facility_req.structs[1]), LI_REQ_SILENT_UPDATE);
				((CAPI_MSG *) msg)->info.facility_req.structs[3] = 0;
				w = api_put(notify_plci->appl, (CAPI_MSG *) msg);
				if (w != _QUEUE_FULL)
				{
					if (w != 0)
					{
						dbug(1, dprintf("[%06lx] %s,%d: Interconnect notify failed %06x %d",
								(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
								(char *)(FILE_), __LINE__,
								(dword)((notify_plci->Id << 8) | UnMapController(notify_plci->adapter->Id)), w));
					}
					notify_plci->li_notify_update = false;
				}
			}
		} while (others && (notify_plci != NULL));
		if (others)
			plci->li_notify_update = false;
	}
}


static void mixer_clear_config(PLCI *plci)
{
	DIVA_CAPI_ADAPTER *a;
	word i, j;

	dbug(1, dprintf("[%06lx] %s,%d: mixer_clear_config",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	plci->li_notify_update = false;
	plci->li_plci_b_write_pos = 0;
	plci->li_plci_b_read_pos = 0;
	plci->li_plci_b_req_pos = 0;
	a = plci->adapter;
	if ((plci->li_bchannel_id != 0)
	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
	{
		i = a->li_base + (plci->li_bchannel_id - 1);
		li_config_table[i].curchnl = 0;
		li_config_table[i].channel = 0;
		li_config_table[i].chflags = 0;
		for (j = 0; j < li_total_channels; j++)
		{
			li_config_table[j].flag_table[i] = 0;
			li_config_table[i].flag_table[j] = 0;
			li_config_table[i].coef_table[j] = 0;
			li_config_table[j].coef_table[i] = 0;
		}
		if (!a->li_pri)
		{
			li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
			if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
			{
				i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
				li_config_table[i].curchnl = 0;
				li_config_table[i].channel = 0;
				li_config_table[i].chflags = 0;
				for (j = 0; j < li_total_channels; j++)
				{
					li_config_table[i].flag_table[j] = 0;
					li_config_table[j].flag_table[i] = 0;
					li_config_table[i].coef_table[j] = 0;
					li_config_table[j].coef_table[i] = 0;
				}
				if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
				{
					i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
					li_config_table[i].curchnl = 0;
					li_config_table[i].channel = 0;
					li_config_table[i].chflags = 0;
					for (j = 0; j < li_total_channels; j++)
					{
						li_config_table[i].flag_table[j] = 0;
						li_config_table[j].flag_table[i] = 0;
						li_config_table[i].coef_table[j] = 0;
						li_config_table[j].coef_table[i] = 0;
					}
				}
			}
		}
	}
}


static void mixer_prepare_switch(dword Id, PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: mixer_prepare_switch",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	do
	{
		mixer_indication_coefs_set(Id, plci);
	} while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
}


static word mixer_save_config(dword Id, PLCI *plci, byte Rc)
{
	DIVA_CAPI_ADAPTER *a;
	word i, j;

	dbug(1, dprintf("[%06lx] %s,%d: mixer_save_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	a = plci->adapter;
	if ((plci->li_bchannel_id != 0)
	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
	{
		i = a->li_base + (plci->li_bchannel_id - 1);
		for (j = 0; j < li_total_channels; j++)
		{
			li_config_table[i].coef_table[j] &= 0xf;
			li_config_table[j].coef_table[i] &= 0xf;
		}
		if (!a->li_pri)
			li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
	}
	return (GOOD);
}


static word mixer_restore_config(dword Id, PLCI *plci, byte Rc)
{
	DIVA_CAPI_ADAPTER *a;
	word Info;

	dbug(1, dprintf("[%06lx] %s,%d: mixer_restore_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	Info = GOOD;
	a = plci->adapter;
	if ((plci->B1_facilities & B1_FACILITY_MIXER)
	    && (plci->li_bchannel_id != 0)
	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
	{
		switch (plci->adjust_b_state)
		{
		case ADJUST_B_RESTORE_MIXER_1:
			if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
			{
				plci->internal_command = plci->adjust_b_command;
				if (plci_nl_busy(plci))
				{
					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
					break;
				}
				xconnect_query_addresses(plci);
				plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_2;
				break;
			}
			plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
			Rc = OK;
		case ADJUST_B_RESTORE_MIXER_2:
		case ADJUST_B_RESTORE_MIXER_3:
		case ADJUST_B_RESTORE_MIXER_4:
			if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Adjust B query addresses failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				Info = _WRONG_STATE;
				break;
			}
			if (Rc == OK)
			{
				if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_3;
				else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4)
					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
			}
			else if (Rc == 0)
			{
				if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_4;
				else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3)
					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
			}
			if (plci->adjust_b_state != ADJUST_B_RESTORE_MIXER_5)
			{
				plci->internal_command = plci->adjust_b_command;
				break;
			}
		case ADJUST_B_RESTORE_MIXER_5:
			xconnect_write_coefs(plci, plci->adjust_b_command);
			plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_6;
			Rc = OK;
		case ADJUST_B_RESTORE_MIXER_6:
			if (!xconnect_write_coefs_process(Id, plci, Rc))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			if (plci->internal_command)
				break;
			plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_7;
		case ADJUST_B_RESTORE_MIXER_7:
			break;
		}
	}
	return (Info);
}


static void mixer_command(dword Id, PLCI *plci, byte Rc)
{
	DIVA_CAPI_ADAPTER *a;
	word i, internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: mixer_command %02x %04x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
			plci->li_cmd));

	a = plci->adapter;
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (plci->li_cmd)
	{
	case LI_REQ_CONNECT:
	case LI_REQ_DISCONNECT:
	case LI_REQ_SILENT_UPDATE:
		switch (internal_command)
		{
		default:
			if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
			{
				adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
									  B1_FACILITY_MIXER), MIXER_COMMAND_1);
			}
		case MIXER_COMMAND_1:
			if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
			{
				if (adjust_b_process(Id, plci, Rc) != GOOD)
				{
					dbug(1, dprintf("[%06lx] %s,%d: Load mixer failed",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					break;
				}
				if (plci->internal_command)
					return;
			}
			plci->li_plci_b_req_pos = plci->li_plci_b_write_pos;
			if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED)
			    || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER)
				&& (add_b1_facilities(plci, plci->B1_resource, (word)(plci->B1_facilities &
										      ~B1_FACILITY_MIXER)) == plci->B1_resource)))
			{
				xconnect_write_coefs(plci, MIXER_COMMAND_2);
			}
			else
			{
				do
				{
					mixer_indication_coefs_set(Id, plci);
				} while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
			}
		case MIXER_COMMAND_2:
			if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED)
			    || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER)
				&& (add_b1_facilities(plci, plci->B1_resource, (word)(plci->B1_facilities &
										      ~B1_FACILITY_MIXER)) == plci->B1_resource)))
			{
				if (!xconnect_write_coefs_process(Id, plci, Rc))
				{
					dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					if (plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
					{
						do
						{
							plci->li_plci_b_write_pos = (plci->li_plci_b_write_pos == 0) ?
								LI_PLCI_B_QUEUE_ENTRIES - 1 : plci->li_plci_b_write_pos - 1;
							i = (plci->li_plci_b_write_pos == 0) ?
								LI_PLCI_B_QUEUE_ENTRIES - 1 : plci->li_plci_b_write_pos - 1;
						} while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
							 && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG));
					}
					break;
				}
				if (plci->internal_command)
					return;
			}
			if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
			{
				adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
									  ~B1_FACILITY_MIXER), MIXER_COMMAND_3);
			}
		case MIXER_COMMAND_3:
			if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
			{
				if (adjust_b_process(Id, plci, Rc) != GOOD)
				{
					dbug(1, dprintf("[%06lx] %s,%d: Unload mixer failed",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					break;
				}
				if (plci->internal_command)
					return;
			}
			break;
		}
		break;
	}
	if ((plci->li_bchannel_id == 0)
	    || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
	{
		dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out %d",
				UnMapId(Id), (char *)(FILE_), __LINE__, (int)(plci->li_bchannel_id)));
	}
	else
	{
		i = a->li_base + (plci->li_bchannel_id - 1);
		li_config_table[i].curchnl = plci->li_channel_bits;
		if (!a->li_pri && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
		{
			i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
			li_config_table[i].curchnl = plci->li_channel_bits;
			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
			{
				i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
				li_config_table[i].curchnl = plci->li_channel_bits;
			}
		}
	}
}


static void li_update_connect(dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci,
			      dword plci_b_id, byte connect, dword li_flags)
{
	word i, ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
	PLCI *plci_b;
	DIVA_CAPI_ADAPTER *a_b;

	a_b = &(adapter[MapController((byte)(plci_b_id & 0x7f)) - 1]);
	plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]);
	ch_a = a->li_base + (plci->li_bchannel_id - 1);
	if (!a->li_pri && (plci->tel == ADV_VOICE)
	    && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER))
	{
		ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE;
		ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
			a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v;
	}
	else
	{
		ch_a_v = ch_a;
		ch_a_s = ch_a;
	}
	ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1);
	if (!a_b->li_pri && (plci_b->tel == ADV_VOICE)
	    && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER))
	{
		ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE;
		ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
			a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v;
	}
	else
	{
		ch_b_v = ch_b;
		ch_b_s = ch_b;
	}
	if (connect)
	{
		li_config_table[ch_a].flag_table[ch_a_v] &= ~LI_FLAG_MONITOR;
		li_config_table[ch_a].flag_table[ch_a_s] &= ~LI_FLAG_MONITOR;
		li_config_table[ch_a_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
		li_config_table[ch_a_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
	}
	li_config_table[ch_a].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR;
	li_config_table[ch_a].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR;
	li_config_table[ch_b_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
	li_config_table[ch_b_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
	if (ch_a_v == ch_b_v)
	{
		li_config_table[ch_a_v].flag_table[ch_b_v] &= ~LI_FLAG_CONFERENCE;
		li_config_table[ch_a_s].flag_table[ch_b_s] &= ~LI_FLAG_CONFERENCE;
	}
	else
	{
		if (li_config_table[ch_a_v].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
		{
			for (i = 0; i < li_total_channels; i++)
			{
				if (i != ch_a_v)
					li_config_table[ch_a_v].flag_table[i] &= ~LI_FLAG_CONFERENCE;
			}
		}
		if (li_config_table[ch_a_s].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
		{
			for (i = 0; i < li_total_channels; i++)
			{
				if (i != ch_a_s)
					li_config_table[ch_a_s].flag_table[i] &= ~LI_FLAG_CONFERENCE;
			}
		}
		if (li_config_table[ch_b_v].flag_table[ch_a_v] & LI_FLAG_CONFERENCE)
		{
			for (i = 0; i < li_total_channels; i++)
			{
				if (i != ch_a_v)
					li_config_table[i].flag_table[ch_a_v] &= ~LI_FLAG_CONFERENCE;
			}
		}
		if (li_config_table[ch_b_v].flag_table[ch_a_s] & LI_FLAG_CONFERENCE)
		{
			for (i = 0; i < li_total_channels; i++)
			{
				if (i != ch_a_s)
					li_config_table[i].flag_table[ch_a_s] &= ~LI_FLAG_CONFERENCE;
			}
		}
	}
	if (li_flags & LI_FLAG_CONFERENCE_A_B)
	{
		li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
	}
	if (li_flags & LI_FLAG_CONFERENCE_B_A)
	{
		li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
	}
	if (li_flags & LI_FLAG_MONITOR_A)
	{
		li_config_table[ch_a].flag_table[ch_a_v] |= LI_FLAG_MONITOR;
		li_config_table[ch_a].flag_table[ch_a_s] |= LI_FLAG_MONITOR;
	}
	if (li_flags & LI_FLAG_MONITOR_B)
	{
		li_config_table[ch_a].flag_table[ch_b_v] |= LI_FLAG_MONITOR;
		li_config_table[ch_a].flag_table[ch_b_s] |= LI_FLAG_MONITOR;
	}
	if (li_flags & LI_FLAG_ANNOUNCEMENT_A)
	{
		li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
		li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
	}
	if (li_flags & LI_FLAG_ANNOUNCEMENT_B)
	{
		li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
		li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
	}
	if (li_flags & LI_FLAG_MIX_A)
	{
		li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_MIX;
		li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_MIX;
	}
	if (li_flags & LI_FLAG_MIX_B)
	{
		li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_MIX;
		li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_MIX;
	}
	if (ch_a_v != ch_a_s)
	{
		li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
	}
	if (ch_b_v != ch_b_s)
	{
		li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
	}
}


static void li2_update_connect(dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci,
			       dword plci_b_id, byte connect, dword li_flags)
{
	word ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
	PLCI *plci_b;
	DIVA_CAPI_ADAPTER *a_b;

	a_b = &(adapter[MapController((byte)(plci_b_id & 0x7f)) - 1]);
	plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]);
	ch_a = a->li_base + (plci->li_bchannel_id - 1);
	if (!a->li_pri && (plci->tel == ADV_VOICE)
	    && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER))
	{
		ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE;
		ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
			a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v;
	}
	else
	{
		ch_a_v = ch_a;
		ch_a_s = ch_a;
	}
	ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1);
	if (!a_b->li_pri && (plci_b->tel == ADV_VOICE)
	    && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER))
	{
		ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE;
		ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
			a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v;
	}
	else
	{
		ch_b_v = ch_b;
		ch_b_s = ch_b;
	}
	if (connect)
	{
		li_config_table[ch_b].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR;
		li_config_table[ch_b].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR;
		li_config_table[ch_b_v].flag_table[ch_b] &= ~LI_FLAG_MIX;
		li_config_table[ch_b_s].flag_table[ch_b] &= ~LI_FLAG_MIX;
		li_config_table[ch_b].flag_table[ch_b] &= ~LI_FLAG_PCCONNECT;
		li_config_table[ch_b].chflags &= ~(LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP);
	}
	li_config_table[ch_b_v].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
	li_config_table[ch_b_s].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
	li_config_table[ch_b_v].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
	li_config_table[ch_b_s].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
	li_config_table[ch_a_v].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
	li_config_table[ch_a_v].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
	li_config_table[ch_a_s].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
	li_config_table[ch_a_s].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
	if (li_flags & LI2_FLAG_INTERCONNECT_A_B)
	{
		li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT;
	}
	if (li_flags & LI2_FLAG_INTERCONNECT_B_A)
	{
		li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
	}
	if (li_flags & LI2_FLAG_MONITOR_B)
	{
		li_config_table[ch_b].flag_table[ch_b_v] |= LI_FLAG_MONITOR;
		li_config_table[ch_b].flag_table[ch_b_s] |= LI_FLAG_MONITOR;
	}
	if (li_flags & LI2_FLAG_MIX_B)
	{
		li_config_table[ch_b_v].flag_table[ch_b] |= LI_FLAG_MIX;
		li_config_table[ch_b_s].flag_table[ch_b] |= LI_FLAG_MIX;
	}
	if (li_flags & LI2_FLAG_MONITOR_X)
		li_config_table[ch_b].chflags |= LI_CHFLAG_MONITOR;
	if (li_flags & LI2_FLAG_MIX_X)
		li_config_table[ch_b].chflags |= LI_CHFLAG_MIX;
	if (li_flags & LI2_FLAG_LOOP_B)
	{
		li_config_table[ch_b_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
		li_config_table[ch_b_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
	}
	if (li_flags & LI2_FLAG_LOOP_PC)
		li_config_table[ch_b].flag_table[ch_b] |= LI_FLAG_PCCONNECT;
	if (li_flags & LI2_FLAG_LOOP_X)
		li_config_table[ch_b].chflags |= LI_CHFLAG_LOOP;
	if (li_flags & LI2_FLAG_PCCONNECT_A_B)
		li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_PCCONNECT;
	if (li_flags & LI2_FLAG_PCCONNECT_B_A)
		li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_PCCONNECT;
	if (ch_a_v != ch_a_s)
	{
		li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
	}
	if (ch_b_v != ch_b_s)
	{
		li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
		li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
	}
}


static word li_check_main_plci(dword Id, PLCI *plci)
{
	if (plci == NULL)
	{
		dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		return (_WRONG_IDENTIFIER);
	}
	if (!plci->State
	    || !plci->NL.Id || plci->nl_remove_id
	    || (plci->li_bchannel_id == 0))
	{
		dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		return (_WRONG_STATE);
	}
	li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = plci;
	return (GOOD);
}


static PLCI *li_check_plci_b(dword Id, PLCI *plci,
			     dword plci_b_id, word plci_b_write_pos, byte *p_result)
{
	byte ctlr_b;
	PLCI *plci_b;

	if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
	     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
		return (NULL);
	}
	ctlr_b = 0;
	if ((plci_b_id & 0x7f) != 0)
	{
		ctlr_b = MapController((byte)(plci_b_id & 0x7f));
		if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
			ctlr_b = 0;
	}
	if ((ctlr_b == 0)
	    || (((plci_b_id >> 8) & 0xff) == 0)
	    || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx",
				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
		PUT_WORD(p_result, _WRONG_IDENTIFIER);
		return (NULL);
	}
	plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
	if (!plci_b->State
	    || !plci_b->NL.Id || plci_b->nl_remove_id
	    || (plci_b->li_bchannel_id == 0))
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx",
				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
		PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
		return (NULL);
	}
	li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci = plci_b;
	if (((byte)(plci_b_id & ~EXT_CONTROLLER)) !=
	    ((byte)(UnMapController(plci->adapter->Id) & ~EXT_CONTROLLER))
	    && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
		|| !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)))
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx",
				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
		PUT_WORD(p_result, _WRONG_IDENTIFIER);
		return (NULL);
	}
	if (!(get_b1_facilities(plci_b, add_b1_facilities(plci_b, plci_b->B1_resource,
							  (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER))
	{
		dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d",
				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b->B1_resource));
		PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
		return (NULL);
	}
	return (plci_b);
}


static PLCI *li2_check_plci_b(dword Id, PLCI *plci,
			      dword plci_b_id, word plci_b_write_pos, byte *p_result)
{
	byte ctlr_b;
	PLCI *plci_b;

	if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
	     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		PUT_WORD(p_result, _WRONG_STATE);
		return (NULL);
	}
	ctlr_b = 0;
	if ((plci_b_id & 0x7f) != 0)
	{
		ctlr_b = MapController((byte)(plci_b_id & 0x7f));
		if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
			ctlr_b = 0;
	}
	if ((ctlr_b == 0)
	    || (((plci_b_id >> 8) & 0xff) == 0)
	    || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx",
				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
		PUT_WORD(p_result, _WRONG_IDENTIFIER);
		return (NULL);
	}
	plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
	if (!plci_b->State
	    || !plci_b->NL.Id || plci_b->nl_remove_id
	    || (plci_b->li_bchannel_id == 0)
	    || (li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci != plci_b))
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx",
				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
		PUT_WORD(p_result, _WRONG_STATE);
		return (NULL);
	}
	if (((byte)(plci_b_id & ~EXT_CONTROLLER)) !=
	    ((byte)(UnMapController(plci->adapter->Id) & ~EXT_CONTROLLER))
	    && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
		|| !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)))
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx",
				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
		PUT_WORD(p_result, _WRONG_IDENTIFIER);
		return (NULL);
	}
	if (!(get_b1_facilities(plci_b, add_b1_facilities(plci_b, plci_b->B1_resource,
							  (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER))
	{
		dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d",
				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b->B1_resource));
		PUT_WORD(p_result, _WRONG_STATE);
		return (NULL);
	}
	return (plci_b);
}


static byte mixer_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL   *appl, API_PARSE *msg)
{
	word Info;
	word i;
	dword d, li_flags, plci_b_id;
	PLCI *plci_b;
	API_PARSE li_parms[3];
	API_PARSE li_req_parms[3];
	API_PARSE li_participant_struct[2];
	API_PARSE li_participant_parms[3];
	word participant_parms_pos;
	byte result_buffer[32];
	byte *result;
	word result_pos;
	word plci_b_write_pos;

	dbug(1, dprintf("[%06lx] %s,%d: mixer_request",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	Info = GOOD;
	result = result_buffer;
	result_buffer[0] = 0;
	if (!(a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED))
	{
		dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		Info = _FACILITY_NOT_SUPPORTED;
	}
	else if (api_parse(&msg[1].info[1], msg[1].length, "ws", li_parms))
	{
		dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		Info = _WRONG_MESSAGE_FORMAT;
	}
	else
	{
		result_buffer[0] = 3;
		PUT_WORD(&result_buffer[1], GET_WORD(li_parms[0].info));
		result_buffer[3] = 0;
		switch (GET_WORD(li_parms[0].info))
		{
		case LI_GET_SUPPORTED_SERVICES:
			if (appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
			{
				result_buffer[0] = 17;
				result_buffer[3] = 14;
				PUT_WORD(&result_buffer[4], GOOD);
				d = 0;
				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_CH)
					d |= LI_CONFERENCING_SUPPORTED;
				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC)
					d |= LI_MONITORING_SUPPORTED;
				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH)
					d |= LI_ANNOUNCEMENTS_SUPPORTED | LI_MIXING_SUPPORTED;
				if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
					d |= LI_CROSS_CONTROLLER_SUPPORTED;
				PUT_DWORD(&result_buffer[6], d);
				if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
				{
					d = 0;
					for (i = 0; i < li_total_channels; i++)
					{
						if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
						    && (li_config_table[i].adapter->li_pri
							|| (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI)))
						{
							d++;
						}
					}
				}
				else
				{
					d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
				}
				PUT_DWORD(&result_buffer[10], d / 2);
				PUT_DWORD(&result_buffer[14], d);
			}
			else
			{
				result_buffer[0] = 25;
				result_buffer[3] = 22;
				PUT_WORD(&result_buffer[4], GOOD);
				d = LI2_ASYMMETRIC_SUPPORTED | LI2_B_LOOPING_SUPPORTED | LI2_X_LOOPING_SUPPORTED;
				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC)
					d |= LI2_MONITORING_SUPPORTED | LI2_REMOTE_MONITORING_SUPPORTED;
				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH)
					d |= LI2_MIXING_SUPPORTED | LI2_REMOTE_MIXING_SUPPORTED;
				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_PC)
					d |= LI2_PC_LOOPING_SUPPORTED;
				if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
					d |= LI2_CROSS_CONTROLLER_SUPPORTED;
				PUT_DWORD(&result_buffer[6], d);
				d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
				PUT_DWORD(&result_buffer[10], d / 2);
				PUT_DWORD(&result_buffer[14], d - 1);
				if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
				{
					d = 0;
					for (i = 0; i < li_total_channels; i++)
					{
						if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
						    && (li_config_table[i].adapter->li_pri
							|| (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI)))
						{
							d++;
						}
					}
				}
				PUT_DWORD(&result_buffer[18], d / 2);
				PUT_DWORD(&result_buffer[22], d - 1);
			}
			break;

		case LI_REQ_CONNECT:
			if (li_parms[1].length == 8)
			{
				appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC;
				if (api_parse(&li_parms[1].info[1], li_parms[1].length, "dd", li_req_parms))
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				plci_b_id = GET_DWORD(li_req_parms[0].info) & 0xffff;
				li_flags = GET_DWORD(li_req_parms[1].info);
				Info = li_check_main_plci(Id, plci);
				result_buffer[0] = 9;
				result_buffer[3] = 6;
				PUT_DWORD(&result_buffer[4], plci_b_id);
				PUT_WORD(&result_buffer[8], GOOD);
				if (Info != GOOD)
					break;
				result = plci->saved_msg.info;
				for (i = 0; i <= result_buffer[0]; i++)
					result[i] = result_buffer[i];
				plci_b_write_pos = plci->li_plci_b_write_pos;
				plci_b = li_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
				if (plci_b == NULL)
					break;
				li_update_connect(Id, a, plci, plci_b_id, true, li_flags);
				plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_LAST_FLAG;
				plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
				plci->li_plci_b_write_pos = plci_b_write_pos;
			}
			else
			{
				appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC;
				if (api_parse(&li_parms[1].info[1], li_parms[1].length, "ds", li_req_parms))
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				li_flags = GET_DWORD(li_req_parms[0].info) & ~(LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A);
				Info = li_check_main_plci(Id, plci);
				result_buffer[0] = 7;
				result_buffer[3] = 4;
				PUT_WORD(&result_buffer[4], Info);
				result_buffer[6] = 0;
				if (Info != GOOD)
					break;
				result = plci->saved_msg.info;
				for (i = 0; i <= result_buffer[0]; i++)
					result[i] = result_buffer[i];
				plci_b_write_pos = plci->li_plci_b_write_pos;
				participant_parms_pos = 0;
				result_pos = 7;
				li2_update_connect(Id, a, plci, UnMapId(Id), true, li_flags);
				while (participant_parms_pos < li_req_parms[1].length)
				{
					result[result_pos] = 6;
					result_pos += 7;
					PUT_DWORD(&result[result_pos - 6], 0);
					PUT_WORD(&result[result_pos - 2], GOOD);
					if (api_parse(&li_req_parms[1].info[1 + participant_parms_pos],
						      (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct))
					{
						dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
								UnMapId(Id), (char *)(FILE_), __LINE__));
						PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
						break;
					}
					if (api_parse(&li_participant_struct[0].info[1],
						      li_participant_struct[0].length, "dd", li_participant_parms))
					{
						dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
								UnMapId(Id), (char *)(FILE_), __LINE__));
						PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
						break;
					}
					plci_b_id = GET_DWORD(li_participant_parms[0].info) & 0xffff;
					li_flags = GET_DWORD(li_participant_parms[1].info);
					PUT_DWORD(&result[result_pos - 6], plci_b_id);
					if (sizeof(result) - result_pos < 7)
					{
						dbug(1, dprintf("[%06lx] %s,%d: LI result overrun",
								UnMapId(Id), (char *)(FILE_), __LINE__));
						PUT_WORD(&result[result_pos - 2], _WRONG_STATE);
						break;
					}
					plci_b = li2_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
					if (plci_b != NULL)
					{
						li2_update_connect(Id, a, plci, plci_b_id, true, li_flags);
						plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id |
							((li_flags & (LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A |
								      LI2_FLAG_PCCONNECT_A_B | LI2_FLAG_PCCONNECT_B_A)) ? 0 : LI_PLCI_B_DISC_FLAG);
						plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
					}
					participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
								       (&li_req_parms[1].info[1]));
				}
				result[0] = (byte)(result_pos - 1);
				result[3] = (byte)(result_pos - 4);
				result[6] = (byte)(result_pos - 7);
				i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
				if ((plci_b_write_pos == plci->li_plci_b_read_pos)
				    || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
				{
					plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
					plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
				}
				else
					plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
				plci->li_plci_b_write_pos = plci_b_write_pos;
			}
			mixer_calculate_coefs(a);
			plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
			mixer_notify_update(plci, true);
			sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
			      "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
			plci->command = 0;
			plci->li_cmd = GET_WORD(li_parms[0].info);
			start_internal_command(Id, plci, mixer_command);
			return (false);

		case LI_REQ_DISCONNECT:
			if (li_parms[1].length == 4)
			{
				appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC;
				if (api_parse(&li_parms[1].info[1], li_parms[1].length, "d", li_req_parms))
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				plci_b_id = GET_DWORD(li_req_parms[0].info) & 0xffff;
				Info = li_check_main_plci(Id, plci);
				result_buffer[0] = 9;
				result_buffer[3] = 6;
				PUT_DWORD(&result_buffer[4], GET_DWORD(li_req_parms[0].info));
				PUT_WORD(&result_buffer[8], GOOD);
				if (Info != GOOD)
					break;
				result = plci->saved_msg.info;
				for (i = 0; i <= result_buffer[0]; i++)
					result[i] = result_buffer[i];
				plci_b_write_pos = plci->li_plci_b_write_pos;
				plci_b = li_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
				if (plci_b == NULL)
					break;
				li_update_connect(Id, a, plci, plci_b_id, false, 0);
				plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG | LI_PLCI_B_LAST_FLAG;
				plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
				plci->li_plci_b_write_pos = plci_b_write_pos;
			}
			else
			{
				appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC;
				if (api_parse(&li_parms[1].info[1], li_parms[1].length, "s", li_req_parms))
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_MESSAGE_FORMAT;
					break;
				}
				Info = li_check_main_plci(Id, plci);
				result_buffer[0] = 7;
				result_buffer[3] = 4;
				PUT_WORD(&result_buffer[4], Info);
				result_buffer[6] = 0;
				if (Info != GOOD)
					break;
				result = plci->saved_msg.info;
				for (i = 0; i <= result_buffer[0]; i++)
					result[i] = result_buffer[i];
				plci_b_write_pos = plci->li_plci_b_write_pos;
				participant_parms_pos = 0;
				result_pos = 7;
				while (participant_parms_pos < li_req_parms[0].length)
				{
					result[result_pos] = 6;
					result_pos += 7;
					PUT_DWORD(&result[result_pos - 6], 0);
					PUT_WORD(&result[result_pos - 2], GOOD);
					if (api_parse(&li_req_parms[0].info[1 + participant_parms_pos],
						      (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct))
					{
						dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
								UnMapId(Id), (char *)(FILE_), __LINE__));
						PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
						break;
					}
					if (api_parse(&li_participant_struct[0].info[1],
						      li_participant_struct[0].length, "d", li_participant_parms))
					{
						dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
								UnMapId(Id), (char *)(FILE_), __LINE__));
						PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
						break;
					}
					plci_b_id = GET_DWORD(li_participant_parms[0].info) & 0xffff;
					PUT_DWORD(&result[result_pos - 6], plci_b_id);
					if (sizeof(result) - result_pos < 7)
					{
						dbug(1, dprintf("[%06lx] %s,%d: LI result overrun",
								UnMapId(Id), (char *)(FILE_), __LINE__));
						PUT_WORD(&result[result_pos - 2], _WRONG_STATE);
						break;
					}
					plci_b = li2_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
					if (plci_b != NULL)
					{
						li2_update_connect(Id, a, plci, plci_b_id, false, 0);
						plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
						plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
					}
					participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
								       (&li_req_parms[0].info[1]));
				}
				result[0] = (byte)(result_pos - 1);
				result[3] = (byte)(result_pos - 4);
				result[6] = (byte)(result_pos - 7);
				i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
				if ((plci_b_write_pos == plci->li_plci_b_read_pos)
				    || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
				{
					plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
					plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
				}
				else
					plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
				plci->li_plci_b_write_pos = plci_b_write_pos;
			}
			mixer_calculate_coefs(a);
			plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
			mixer_notify_update(plci, true);
			sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
			      "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
			plci->command = 0;
			plci->li_cmd = GET_WORD(li_parms[0].info);
			start_internal_command(Id, plci, mixer_command);
			return (false);

		case LI_REQ_SILENT_UPDATE:
			if (!plci || !plci->State
			    || !plci->NL.Id || plci->nl_remove_id
			    || (plci->li_bchannel_id == 0)
			    || (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci != plci))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				return (false);
			}
			plci_b_write_pos = plci->li_plci_b_write_pos;
			if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
			     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
			{
				dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				return (false);
			}
			i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
			if ((plci_b_write_pos == plci->li_plci_b_read_pos)
			    || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
			{
				plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
				plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
			}
			else
				plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
			plci->li_plci_b_write_pos = plci_b_write_pos;
			plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
			plci->command = 0;
			plci->li_cmd = GET_WORD(li_parms[0].info);
			start_internal_command(Id, plci, mixer_command);
			return (false);

		default:
			dbug(1, dprintf("[%06lx] %s,%d: LI unknown request %04x",
					UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(li_parms[0].info)));
			Info = _FACILITY_NOT_SUPPORTED;
		}
	}
	sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
	      "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
	return (false);
}


static void mixer_indication_coefs_set(dword Id, PLCI *plci)
{
	dword d;
	byte result[12];

	dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_coefs_set",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
	{
		do
		{
			d = plci->li_plci_b_queue[plci->li_plci_b_read_pos];
			if (!(d & LI_PLCI_B_SKIP_FLAG))
			{
				if (plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
				{
					if (d & LI_PLCI_B_DISC_FLAG)
					{
						result[0] = 5;
						PUT_WORD(&result[1], LI_IND_DISCONNECT);
						result[3] = 2;
						PUT_WORD(&result[4], _LI_USER_INITIATED);
					}
					else
					{
						result[0] = 7;
						PUT_WORD(&result[1], LI_IND_CONNECT_ACTIVE);
						result[3] = 4;
						PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
					}
				}
				else
				{
					if (d & LI_PLCI_B_DISC_FLAG)
					{
						result[0] = 9;
						PUT_WORD(&result[1], LI_IND_DISCONNECT);
						result[3] = 6;
						PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
						PUT_WORD(&result[8], _LI_USER_INITIATED);
					}
					else
					{
						result[0] = 7;
						PUT_WORD(&result[1], LI_IND_CONNECT_ACTIVE);
						result[3] = 4;
						PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
					}
				}
				sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,
				      "ws", SELECTOR_LINE_INTERCONNECT, result);
			}
			plci->li_plci_b_read_pos = (plci->li_plci_b_read_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ?
				0 : plci->li_plci_b_read_pos + 1;
		} while (!(d & LI_PLCI_B_LAST_FLAG) && (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos));
	}
}


static void mixer_indication_xconnect_from(dword Id, PLCI *plci, byte *msg, word length)
{
	word i, j, ch;
	struct xconnect_transfer_address_s s,   *p;
	DIVA_CAPI_ADAPTER *a;

	dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_from %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, (int)length));

	a = plci->adapter;
	i = 1;
	for (i = 1; i < length; i += 16)
	{
		s.card_address.low = msg[i] | (msg[i + 1] << 8) | (((dword)(msg[i + 2])) << 16) | (((dword)(msg[i + 3])) << 24);
		s.card_address.high = msg[i + 4] | (msg[i + 5] << 8) | (((dword)(msg[i + 6])) << 16) | (((dword)(msg[i + 7])) << 24);
		s.offset = msg[i + 8] | (msg[i + 9] << 8) | (((dword)(msg[i + 10])) << 16) | (((dword)(msg[i + 11])) << 24);
		ch = msg[i + 12] | (msg[i + 13] << 8);
		j = ch & XCONNECT_CHANNEL_NUMBER_MASK;
		if (!a->li_pri && (plci->li_bchannel_id == 2))
			j = 1 - j;
		j += a->li_base;
		if (ch & XCONNECT_CHANNEL_PORT_PC)
			p = &(li_config_table[j].send_pc);
		else
			p = &(li_config_table[j].send_b);
		p->card_address.low = s.card_address.low;
		p->card_address.high = s.card_address.high;
		p->offset = s.offset;
		li_config_table[j].channel |= LI_CHANNEL_ADDRESSES_SET;
	}
	if (plci->internal_command_queue[0]
	    && ((plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
		|| (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3)
		|| (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4)))
	{
		(*(plci->internal_command_queue[0]))(Id, plci, 0);
		if (!plci->internal_command)
			next_internal_command(Id, plci);
	}
	mixer_notify_update(plci, true);
}


static void mixer_indication_xconnect_to(dword Id, PLCI *plci, byte *msg, word length)
{

	dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_to %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, (int) length));

}


static byte mixer_notify_source_removed(PLCI *plci, dword plci_b_id)
{
	word plci_b_write_pos;

	plci_b_write_pos = plci->li_plci_b_write_pos;
	if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
	     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 1)
	{
		dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
				(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
				(char *)(FILE_), __LINE__));
		return (false);
	}
	plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
	plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
	plci->li_plci_b_write_pos = plci_b_write_pos;
	return (true);
}


static void mixer_remove(PLCI *plci)
{
	DIVA_CAPI_ADAPTER *a;
	PLCI *notify_plci;
	dword plci_b_id;
	word i, j;

	dbug(1, dprintf("[%06lx] %s,%d: mixer_remove",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	a = plci->adapter;
	plci_b_id = (plci->Id << 8) | UnMapController(plci->adapter->Id);
	if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
	{
		if ((plci->li_bchannel_id != 0)
		    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
		{
			i = a->li_base + (plci->li_bchannel_id - 1);
			if ((li_config_table[i].curchnl | li_config_table[i].channel) & LI_CHANNEL_INVOLVED)
			{
				for (j = 0; j < li_total_channels; j++)
				{
					if ((li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
					    || (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT))
					{
						notify_plci = li_config_table[j].plci;
						if ((notify_plci != NULL)
						    && (notify_plci != plci)
						    && (notify_plci->appl != NULL)
						    && !(notify_plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
						    && (notify_plci->State)
						    && notify_plci->NL.Id && !notify_plci->nl_remove_id)
						{
							mixer_notify_source_removed(notify_plci, plci_b_id);
						}
					}
				}
				mixer_clear_config(plci);
				mixer_calculate_coefs(a);
				mixer_notify_update(plci, true);
			}
			li_config_table[i].plci = NULL;
			plci->li_bchannel_id = 0;
		}
	}
}


/*------------------------------------------------------------------*/
/* Echo canceller facilities                                        */
/*------------------------------------------------------------------*/


static void ec_write_parameters(PLCI *plci)
{
	word w;
	byte parameter_buffer[6];

	dbug(1, dprintf("[%06lx] %s,%d: ec_write_parameters",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	parameter_buffer[0] = 5;
	parameter_buffer[1] = DSP_CTRL_SET_LEC_PARAMETERS;
	PUT_WORD(&parameter_buffer[2], plci->ec_idi_options);
	plci->ec_idi_options &= ~LEC_RESET_COEFFICIENTS;
	w = (plci->ec_tail_length == 0) ? 128 : plci->ec_tail_length;
	PUT_WORD(&parameter_buffer[4], w);
	add_p(plci, FTY, parameter_buffer);
	sig_req(plci, TEL_CTRL, 0);
	send_req(plci);
}


static void ec_clear_config(PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: ec_clear_config",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
		LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING;
	plci->ec_tail_length = 0;
}


static void ec_prepare_switch(dword Id, PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: ec_prepare_switch",
			UnMapId(Id), (char *)(FILE_), __LINE__));

}


static word ec_save_config(dword Id, PLCI *plci, byte Rc)
{

	dbug(1, dprintf("[%06lx] %s,%d: ec_save_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	return (GOOD);
}


static word ec_restore_config(dword Id, PLCI *plci, byte Rc)
{
	word Info;

	dbug(1, dprintf("[%06lx] %s,%d: ec_restore_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	Info = GOOD;
	if (plci->B1_facilities & B1_FACILITY_EC)
	{
		switch (plci->adjust_b_state)
		{
		case ADJUST_B_RESTORE_EC_1:
			plci->internal_command = plci->adjust_b_command;
			if (plci->sig_req)
			{
				plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
				break;
			}
			ec_write_parameters(plci);
			plci->adjust_b_state = ADJUST_B_RESTORE_EC_2;
			break;
		case ADJUST_B_RESTORE_EC_2:
			if ((Rc != OK) && (Rc != OK_FC))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Restore EC failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				Info = _WRONG_STATE;
				break;
			}
			break;
		}
	}
	return (Info);
}


static void ec_command(dword Id, PLCI *plci, byte Rc)
{
	word internal_command, Info;
	byte result[8];

	dbug(1, dprintf("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
			plci->ec_cmd, plci->ec_idi_options, plci->ec_tail_length));

	Info = GOOD;
	if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
	{
		result[0] = 2;
		PUT_WORD(&result[1], EC_SUCCESS);
	}
	else
	{
		result[0] = 5;
		PUT_WORD(&result[1], plci->ec_cmd);
		result[3] = 2;
		PUT_WORD(&result[4], GOOD);
	}
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (plci->ec_cmd)
	{
	case EC_ENABLE_OPERATION:
	case EC_FREEZE_COEFFICIENTS:
	case EC_RESUME_COEFFICIENT_UPDATE:
	case EC_RESET_COEFFICIENTS:
		switch (internal_command)
		{
		default:
			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
								  B1_FACILITY_EC), EC_COMMAND_1);
		case EC_COMMAND_1:
			if (adjust_b_process(Id, plci, Rc) != GOOD)
			{
				dbug(1, dprintf("[%06lx] %s,%d: Load EC failed",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			if (plci->internal_command)
				return;
		case EC_COMMAND_2:
			if (plci->sig_req)
			{
				plci->internal_command = EC_COMMAND_2;
				return;
			}
			plci->internal_command = EC_COMMAND_3;
			ec_write_parameters(plci);
			return;
		case EC_COMMAND_3:
			if ((Rc != OK) && (Rc != OK_FC))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Enable EC failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			break;
		}
		break;

	case EC_DISABLE_OPERATION:
		switch (internal_command)
		{
		default:
		case EC_COMMAND_1:
			if (plci->B1_facilities & B1_FACILITY_EC)
			{
				if (plci->sig_req)
				{
					plci->internal_command = EC_COMMAND_1;
					return;
				}
				plci->internal_command = EC_COMMAND_2;
				ec_write_parameters(plci);
				return;
			}
			Rc = OK;
		case EC_COMMAND_2:
			if ((Rc != OK) && (Rc != OK_FC))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Disable EC failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
								  ~B1_FACILITY_EC), EC_COMMAND_3);
		case EC_COMMAND_3:
			if (adjust_b_process(Id, plci, Rc) != GOOD)
			{
				dbug(1, dprintf("[%06lx] %s,%d: Unload EC failed",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				Info = _FACILITY_NOT_SUPPORTED;
				break;
			}
			if (plci->internal_command)
				return;
			break;
		}
		break;
	}
	sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
	      "wws", Info, (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
	      PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
}


static byte ec_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL   *appl, API_PARSE *msg)
{
	word Info;
	word opt;
	API_PARSE ec_parms[3];
	byte result[16];

	dbug(1, dprintf("[%06lx] %s,%d: ec_request",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	Info = GOOD;
	result[0] = 0;
	if (!(a->man_profile.private_options & (1L << PRIVATE_ECHO_CANCELLER)))
	{
		dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
				UnMapId(Id), (char *)(FILE_), __LINE__));
		Info = _FACILITY_NOT_SUPPORTED;
	}
	else
	{
		if (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
		{
			if (api_parse(&msg[1].info[1], msg[1].length, "w", ec_parms))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				Info = _WRONG_MESSAGE_FORMAT;
			}
			else
			{
				if (plci == NULL)
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_IDENTIFIER;
				}
				else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_STATE;
				}
				else
				{
					plci->command = 0;
					plci->ec_cmd = GET_WORD(ec_parms[0].info);
					plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
					result[0] = 2;
					PUT_WORD(&result[1], EC_SUCCESS);
					if (msg[1].length >= 4)
					{
						opt = GET_WORD(&ec_parms[0].info[2]);
						plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING |
									  LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS);
						if (!(opt & EC_DISABLE_NON_LINEAR_PROCESSING))
							plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING;
						if (opt & EC_DETECT_DISABLE_TONE)
							plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR;
						if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS))
							plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS;
						if (msg[1].length >= 6)
						{
							plci->ec_tail_length = GET_WORD(&ec_parms[0].info[4]);
						}
					}
					switch (plci->ec_cmd)
					{
					case EC_ENABLE_OPERATION:
						plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
						start_internal_command(Id, plci, ec_command);
						return (false);

					case EC_DISABLE_OPERATION:
						plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
							LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
							LEC_RESET_COEFFICIENTS;
						start_internal_command(Id, plci, ec_command);
						return (false);

					case EC_FREEZE_COEFFICIENTS:
						plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS;
						start_internal_command(Id, plci, ec_command);
						return (false);

					case EC_RESUME_COEFFICIENT_UPDATE:
						plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
						start_internal_command(Id, plci, ec_command);
						return (false);

					case EC_RESET_COEFFICIENTS:
						plci->ec_idi_options |= LEC_RESET_COEFFICIENTS;
						start_internal_command(Id, plci, ec_command);
						return (false);

					default:
						dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x",
								UnMapId(Id), (char *)(FILE_), __LINE__, plci->ec_cmd));
						PUT_WORD(&result[1], EC_UNSUPPORTED_OPERATION);
					}
				}
			}
		}
		else
		{
			if (api_parse(&msg[1].info[1], msg[1].length, "ws", ec_parms))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
						UnMapId(Id), (char *)(FILE_), __LINE__));
				Info = _WRONG_MESSAGE_FORMAT;
			}
			else
			{
				if (GET_WORD(ec_parms[0].info) == EC_GET_SUPPORTED_SERVICES)
				{
					result[0] = 11;
					PUT_WORD(&result[1], EC_GET_SUPPORTED_SERVICES);
					result[3] = 8;
					PUT_WORD(&result[4], GOOD);
					PUT_WORD(&result[6], 0x0007);
					PUT_WORD(&result[8], LEC_MAX_SUPPORTED_TAIL_LENGTH);
					PUT_WORD(&result[10], 0);
				}
				else if (plci == NULL)
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_IDENTIFIER;
				}
				else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
				{
					dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
							UnMapId(Id), (char *)(FILE_), __LINE__));
					Info = _WRONG_STATE;
				}
				else
				{
					plci->command = 0;
					plci->ec_cmd = GET_WORD(ec_parms[0].info);
					plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
					result[0] = 5;
					PUT_WORD(&result[1], plci->ec_cmd);
					result[3] = 2;
					PUT_WORD(&result[4], GOOD);
					plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING |
								  LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS);
					plci->ec_tail_length = 0;
					if (ec_parms[1].length >= 2)
					{
						opt = GET_WORD(&ec_parms[1].info[1]);
						if (opt & EC_ENABLE_NON_LINEAR_PROCESSING)
							plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING;
						if (opt & EC_DETECT_DISABLE_TONE)
							plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR;
						if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS))
							plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS;
						if (ec_parms[1].length >= 4)
						{
							plci->ec_tail_length = GET_WORD(&ec_parms[1].info[3]);
						}
					}
					switch (plci->ec_cmd)
					{
					case EC_ENABLE_OPERATION:
						plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
						start_internal_command(Id, plci, ec_command);
						return (false);

					case EC_DISABLE_OPERATION:
						plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
							LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
							LEC_RESET_COEFFICIENTS;
						start_internal_command(Id, plci, ec_command);
						return (false);

					default:
						dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x",
								UnMapId(Id), (char *)(FILE_), __LINE__, plci->ec_cmd));
						PUT_WORD(&result[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP);
					}
				}
			}
		}
	}
	sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
	      "wws", Info, (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
	      PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
	return (false);
}


static void ec_indication(dword Id, PLCI *plci, byte *msg, word length)
{
	byte result[8];

	dbug(1, dprintf("[%06lx] %s,%d: ec_indication",
			UnMapId(Id), (char *)(FILE_), __LINE__));

	if (!(plci->ec_idi_options & LEC_MANUAL_DISABLE))
	{
		if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
		{
			result[0] = 2;
			PUT_WORD(&result[1], 0);
			switch (msg[1])
			{
			case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
				PUT_WORD(&result[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
				break;
			case LEC_DISABLE_TYPE_REVERSED_2100HZ:
				PUT_WORD(&result[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
				break;
			case LEC_DISABLE_RELEASED:
				PUT_WORD(&result[1], EC_BYPASS_RELEASED);
				break;
			}
		}
		else
		{
			result[0] = 5;
			PUT_WORD(&result[1], EC_BYPASS_INDICATION);
			result[3] = 2;
			PUT_WORD(&result[4], 0);
			switch (msg[1])
			{
			case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
				PUT_WORD(&result[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
				break;
			case LEC_DISABLE_TYPE_REVERSED_2100HZ:
				PUT_WORD(&result[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
				break;
			case LEC_DISABLE_RELEASED:
				PUT_WORD(&result[4], EC_BYPASS_RELEASED);
				break;
			}
		}
		sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
		      PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
	}
}



/*------------------------------------------------------------------*/
/* Advanced voice                                                   */
/*------------------------------------------------------------------*/

static void adv_voice_write_coefs(PLCI *plci, word write_command)
{
	DIVA_CAPI_ADAPTER *a;
	word i;
	byte *p;

	word w, n, j, k;
	byte ch_map[MIXER_CHANNELS_BRI];

	byte coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE + 2];

	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_write_coefs %d",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__, write_command));

	a = plci->adapter;
	p = coef_buffer + 1;
	*(p++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS;
	i = 0;
	while (i + sizeof(word) <= a->adv_voice_coef_length)
	{
		PUT_WORD(p, GET_WORD(a->adv_voice_coef_buffer + i));
		p += 2;
		i += 2;
	}
	while (i < ADV_VOICE_OLD_COEF_COUNT * sizeof(word))
	{
		PUT_WORD(p, 0x8000);
		p += 2;
		i += 2;
	}

	if (!a->li_pri && (plci->li_bchannel_id == 0))
	{
		if ((li_config_table[a->li_base].plci == NULL) && (li_config_table[a->li_base + 1].plci != NULL))
		{
			plci->li_bchannel_id = 1;
			li_config_table[a->li_base].plci = plci;
			dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
					(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
					(char *)(FILE_), __LINE__, plci->li_bchannel_id));
		}
		else if ((li_config_table[a->li_base].plci != NULL) && (li_config_table[a->li_base + 1].plci == NULL))
		{
			plci->li_bchannel_id = 2;
			li_config_table[a->li_base + 1].plci = plci;
			dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
					(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
					(char *)(FILE_), __LINE__, plci->li_bchannel_id));
		}
	}
	if (!a->li_pri && (plci->li_bchannel_id != 0)
	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
	{
		i = a->li_base + (plci->li_bchannel_id - 1);
		switch (write_command)
		{
		case ADV_VOICE_WRITE_ACTIVATION:
			j = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
			k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
			if (!(plci->B1_facilities & B1_FACILITY_MIXER))
			{
				li_config_table[j].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX;
				li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR;
			}
			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
			{
				li_config_table[k].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX;
				li_config_table[i].flag_table[k] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR;
				li_config_table[k].flag_table[j] |= LI_FLAG_CONFERENCE;
				li_config_table[j].flag_table[k] |= LI_FLAG_CONFERENCE;
			}
			mixer_calculate_coefs(a);
			li_config_table[i].curchnl = li_config_table[i].channel;
			li_config_table[j].curchnl = li_config_table[j].channel;
			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
				li_config_table[k].curchnl = li_config_table[k].channel;
			break;

		case ADV_VOICE_WRITE_DEACTIVATION:
			for (j = 0; j < li_total_channels; j++)
			{
				li_config_table[i].flag_table[j] = 0;
				li_config_table[j].flag_table[i] = 0;
			}
			k = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
			for (j = 0; j < li_total_channels; j++)
			{
				li_config_table[k].flag_table[j] = 0;
				li_config_table[j].flag_table[k] = 0;
			}
			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
			{
				k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
				for (j = 0; j < li_total_channels; j++)
				{
					li_config_table[k].flag_table[j] = 0;
					li_config_table[j].flag_table[k] = 0;
				}
			}
			mixer_calculate_coefs(a);
			break;
		}
		if (plci->B1_facilities & B1_FACILITY_MIXER)
		{
			w = 0;
			if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)
				w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
			if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
				w |= MIXER_FEATURE_ENABLE_TX_DATA;
			if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
				w |= MIXER_FEATURE_ENABLE_RX_DATA;
			*(p++) = (byte) w;
			*(p++) = (byte)(w >> 8);
			for (j = 0; j < sizeof(ch_map); j += 2)
			{
				ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1));
				ch_map[j + 1] = (byte)(j + (2 - plci->li_bchannel_id));
			}
			for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
			{
				i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
				j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
				if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
				{
					*(p++) = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
					w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
					li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
				}
				else
				{
					*(p++) = (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n < a->adv_voice_coef_length) ?
						a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n] : 0x00;
				}
			}
		}
		else
		{
			for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
				*(p++) = a->adv_voice_coef_buffer[i];
		}
	}
	else

	{
		for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
			*(p++) = a->adv_voice_coef_buffer[i];
	}
	coef_buffer[0] = (p - coef_buffer) - 1;
	add_p(plci, FTY, coef_buffer);
	sig_req(plci, TEL_CTRL, 0);
	send_req(plci);
}


static void adv_voice_clear_config(PLCI *plci)
{
	DIVA_CAPI_ADAPTER *a;

	word i, j;


	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_clear_config",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	a = plci->adapter;
	if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
	{
		a->adv_voice_coef_length = 0;

		if (!a->li_pri && (plci->li_bchannel_id != 0)
		    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
		{
			i = a->li_base + (plci->li_bchannel_id - 1);
			li_config_table[i].curchnl = 0;
			li_config_table[i].channel = 0;
			li_config_table[i].chflags = 0;
			for (j = 0; j < li_total_channels; j++)
			{
				li_config_table[i].flag_table[j] = 0;
				li_config_table[j].flag_table[i] = 0;
				li_config_table[i].coef_table[j] = 0;
				li_config_table[j].coef_table[i] = 0;
			}
			li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
			i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
			li_config_table[i].curchnl = 0;
			li_config_table[i].channel = 0;
			li_config_table[i].chflags = 0;
			for (j = 0; j < li_total_channels; j++)
			{
				li_config_table[i].flag_table[j] = 0;
				li_config_table[j].flag_table[i] = 0;
				li_config_table[i].coef_table[j] = 0;
				li_config_table[j].coef_table[i] = 0;
			}
			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
			{
				i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
				li_config_table[i].curchnl = 0;
				li_config_table[i].channel = 0;
				li_config_table[i].chflags = 0;
				for (j = 0; j < li_total_channels; j++)
				{
					li_config_table[i].flag_table[j] = 0;
					li_config_table[j].flag_table[i] = 0;
					li_config_table[i].coef_table[j] = 0;
					li_config_table[j].coef_table[i] = 0;
				}
			}
		}

	}
}


static void adv_voice_prepare_switch(dword Id, PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_prepare_switch",
			UnMapId(Id), (char *)(FILE_), __LINE__));

}


static word adv_voice_save_config(dword Id, PLCI *plci, byte Rc)
{

	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_save_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	return (GOOD);
}


static word adv_voice_restore_config(dword Id, PLCI *plci, byte Rc)
{
	DIVA_CAPI_ADAPTER *a;
	word Info;

	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_restore_config %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	Info = GOOD;
	a = plci->adapter;
	if ((plci->B1_facilities & B1_FACILITY_VOICE)
	    && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
	{
		switch (plci->adjust_b_state)
		{
		case ADJUST_B_RESTORE_VOICE_1:
			plci->internal_command = plci->adjust_b_command;
			if (plci->sig_req)
			{
				plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
				break;
			}
			adv_voice_write_coefs(plci, ADV_VOICE_WRITE_UPDATE);
			plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_2;
			break;
		case ADJUST_B_RESTORE_VOICE_2:
			if ((Rc != OK) && (Rc != OK_FC))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Restore voice config failed %02x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
				Info = _WRONG_STATE;
				break;
			}
			break;
		}
	}
	return (Info);
}




/*------------------------------------------------------------------*/
/* B1 resource switching                                            */
/*------------------------------------------------------------------*/

static byte b1_facilities_table[] =
{
	0x00,  /* 0  No bchannel resources      */
	0x00,  /* 1  Codec (automatic law)      */
	0x00,  /* 2  Codec (A-law)              */
	0x00,  /* 3  Codec (y-law)              */
	0x00,  /* 4  HDLC for X.21              */
	0x00,  /* 5  HDLC                       */
	0x00,  /* 6  External Device 0          */
	0x00,  /* 7  External Device 1          */
	0x00,  /* 8  HDLC 56k                   */
	0x00,  /* 9  Transparent                */
	0x00,  /* 10 Loopback to network        */
	0x00,  /* 11 Test pattern to net        */
	0x00,  /* 12 Rate adaptation sync       */
	0x00,  /* 13 Rate adaptation async      */
	0x00,  /* 14 R-Interface                */
	0x00,  /* 15 HDLC 128k leased line      */
	0x00,  /* 16 FAX                        */
	0x00,  /* 17 Modem async                */
	0x00,  /* 18 Modem sync HDLC            */
	0x00,  /* 19 V.110 async HDLC           */
	0x12,  /* 20 Adv voice (Trans,mixer)    */
	0x00,  /* 21 Codec connected to IC      */
	0x0c,  /* 22 Trans,DTMF                 */
	0x1e,  /* 23 Trans,DTMF+mixer           */
	0x1f,  /* 24 Trans,DTMF+mixer+local     */
	0x13,  /* 25 Trans,mixer+local          */
	0x12,  /* 26 HDLC,mixer                 */
	0x12,  /* 27 HDLC 56k,mixer             */
	0x2c,  /* 28 Trans,LEC+DTMF             */
	0x3e,  /* 29 Trans,LEC+DTMF+mixer       */
	0x3f,  /* 30 Trans,LEC+DTMF+mixer+local */
	0x2c,  /* 31 RTP,LEC+DTMF               */
	0x3e,  /* 32 RTP,LEC+DTMF+mixer         */
	0x3f,  /* 33 RTP,LEC+DTMF+mixer+local   */
	0x00,  /* 34 Signaling task             */
	0x00,  /* 35 PIAFS                      */
	0x0c,  /* 36 Trans,DTMF+TONE            */
	0x1e,  /* 37 Trans,DTMF+TONE+mixer      */
	0x1f   /* 38 Trans,DTMF+TONE+mixer+local*/
};


static word get_b1_facilities(PLCI *plci, byte b1_resource)
{
	word b1_facilities;

	b1_facilities = b1_facilities_table[b1_resource];
	if ((b1_resource == 9) || (b1_resource == 20) || (b1_resource == 25))
	{

		if (!(((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE))
		      || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id - 1] & (1L << PRIVATE_DTMF_TONE)))))

		{
			if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND)
				b1_facilities |= B1_FACILITY_DTMFX;
			if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)
				b1_facilities |= B1_FACILITY_DTMFR;
		}
	}
	if ((b1_resource == 17) || (b1_resource == 18))
	{
		if (plci->adapter->manufacturer_features & (MANUFACTURER_FEATURE_V18 | MANUFACTURER_FEATURE_VOWN))
			b1_facilities |= B1_FACILITY_DTMFX | B1_FACILITY_DTMFR;
	}
/*
  dbug (1, dprintf("[%06lx] %s,%d: get_b1_facilities %d %04x",
  (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
  (char far *)(FILE_), __LINE__, b1_resource, b1_facilites));
*/
	return (b1_facilities);
}


static byte add_b1_facilities(PLCI *plci, byte b1_resource, word b1_facilities)
{
	byte b;

	switch (b1_resource)
	{
	case 5:
	case 26:
		if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
			b = 26;
		else
			b = 5;
		break;

	case 8:
	case 27:
		if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
			b = 27;
		else
			b = 8;
		break;

	case 9:
	case 20:
	case 22:
	case 23:
	case 24:
	case 25:
	case 28:
	case 29:
	case 30:
	case 36:
	case 37:
	case 38:
		if (b1_facilities & B1_FACILITY_EC)
		{
			if (b1_facilities & B1_FACILITY_LOCAL)
				b = 30;
			else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
				b = 29;
			else
				b = 28;
		}

		else if ((b1_facilities & (B1_FACILITY_DTMFX | B1_FACILITY_DTMFR | B1_FACILITY_MIXER))
			 && (((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE))
			     || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id - 1] & (1L << PRIVATE_DTMF_TONE)))))
		{
			if (b1_facilities & B1_FACILITY_LOCAL)
				b = 38;
			else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
				b = 37;
			else
				b = 36;
		}

		else if (((plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF)
			  && !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
			 || ((b1_facilities & B1_FACILITY_DTMFR)
			     && ((b1_facilities & B1_FACILITY_MIXER)
				 || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)))
			 || ((b1_facilities & B1_FACILITY_DTMFX)
			     && ((b1_facilities & B1_FACILITY_MIXER)
				 || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND))))
		{
			if (b1_facilities & B1_FACILITY_LOCAL)
				b = 24;
			else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
				b = 23;
			else
				b = 22;
		}
		else
		{
			if (b1_facilities & B1_FACILITY_LOCAL)
				b = 25;
			else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
				b = 20;
			else
				b = 9;
		}
		break;

	case 31:
	case 32:
	case 33:
		if (b1_facilities & B1_FACILITY_LOCAL)
			b = 33;
		else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
			b = 32;
		else
			b = 31;
		break;

	default:
		b = b1_resource;
	}
	dbug(1, dprintf("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__,
			b1_resource, b1_facilities, b, get_b1_facilities(plci, b)));
	return (b);
}


static void adjust_b1_facilities(PLCI *plci, byte new_b1_resource, word new_b1_facilities)
{
	word removed_facilities;

	dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__, new_b1_resource, new_b1_facilities,
			new_b1_facilities & get_b1_facilities(plci, new_b1_resource)));

	new_b1_facilities &= get_b1_facilities(plci, new_b1_resource);
	removed_facilities = plci->B1_facilities & ~new_b1_facilities;

	if (removed_facilities & B1_FACILITY_EC)
		ec_clear_config(plci);


	if (removed_facilities & B1_FACILITY_DTMFR)
	{
		dtmf_rec_clear_config(plci);
		dtmf_parameter_clear_config(plci);
	}
	if (removed_facilities & B1_FACILITY_DTMFX)
		dtmf_send_clear_config(plci);


	if (removed_facilities & B1_FACILITY_MIXER)
		mixer_clear_config(plci);

	if (removed_facilities & B1_FACILITY_VOICE)
		adv_voice_clear_config(plci);
	plci->B1_facilities = new_b1_facilities;
}


static void adjust_b_clear(PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: adjust_b_clear",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	plci->adjust_b_restore = false;
}


static word adjust_b_process(dword Id, PLCI *plci, byte Rc)
{
	word Info;
	byte b1_resource;
	NCCI *ncci_ptr;
	API_PARSE bp[2];

	dbug(1, dprintf("[%06lx] %s,%d: adjust_b_process %02x %d",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));

	Info = GOOD;
	switch (plci->adjust_b_state)
	{
	case ADJUST_B_START:
		if ((plci->adjust_b_parms_msg == NULL)
		    && (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1)
		    && ((plci->adjust_b_mode & ~(ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 |
						 ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_RESTORE)) == 0))
		{
			b1_resource = (plci->adjust_b_mode == ADJUST_B_MODE_NO_RESOURCE) ?
				0 : add_b1_facilities(plci, plci->B1_resource, plci->adjust_b_facilities);
			if (b1_resource == plci->B1_resource)
			{
				adjust_b1_facilities(plci, b1_resource, plci->adjust_b_facilities);
				break;
			}
			if (plci->adjust_b_facilities & ~get_b1_facilities(plci, b1_resource))
			{
				dbug(1, dprintf("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x",
						UnMapId(Id), (char *)(FILE_), __LINE__,
						plci->B1_resource, b1_resource, plci->adjust_b_facilities));
				Info = _WRONG_STATE;
				break;
			}
		}
		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
		{

			mixer_prepare_switch(Id, plci);


			dtmf_prepare_switch(Id, plci);
			dtmf_parameter_prepare_switch(Id, plci);


			ec_prepare_switch(Id, plci);

			adv_voice_prepare_switch(Id, plci);
		}
		plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1;
		Rc = OK;
	case ADJUST_B_SAVE_MIXER_1:
		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
		{

			Info = mixer_save_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;

		}
		plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1;
		Rc = OK;
	case ADJUST_B_SAVE_DTMF_1:
		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
		{

			Info = dtmf_save_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;

		}
		plci->adjust_b_state = ADJUST_B_REMOVE_L23_1;
	case ADJUST_B_REMOVE_L23_1:
		if ((plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
		    && plci->NL.Id && !plci->nl_remove_id)
		{
			plci->internal_command = plci->adjust_b_command;
			if (plci->adjust_b_ncci != 0)
			{
				ncci_ptr = &(plci->adapter->ncci[plci->adjust_b_ncci]);
				while (ncci_ptr->data_pending)
				{
					plci->data_sent_ptr = ncci_ptr->DBuffer[ncci_ptr->data_out].P;
					data_rc(plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
				}
				while (ncci_ptr->data_ack_pending)
					data_ack(plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
			}
			nl_req_ncci(plci, REMOVE,
				    (byte)((plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) ? plci->adjust_b_ncci : 0));
			send_req(plci);
			plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
			break;
		}
		plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
		Rc = OK;
	case ADJUST_B_REMOVE_L23_2:
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: Adjust B remove failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			Info = _WRONG_STATE;
			break;
		}
		if (plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
		{
			if (plci_nl_busy(plci))
			{
				plci->internal_command = plci->adjust_b_command;
				break;
			}
		}
		plci->adjust_b_state = ADJUST_B_SAVE_EC_1;
		Rc = OK;
	case ADJUST_B_SAVE_EC_1:
		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
		{

			Info = ec_save_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;

		}
		plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1;
		Rc = OK;
	case ADJUST_B_SAVE_DTMF_PARAMETER_1:
		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
		{

			Info = dtmf_parameter_save_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;

		}
		plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1;
		Rc = OK;
	case ADJUST_B_SAVE_VOICE_1:
		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
		{
			Info = adv_voice_save_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;
		}
		plci->adjust_b_state = ADJUST_B_SWITCH_L1_1;
	case ADJUST_B_SWITCH_L1_1:
		if (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1)
		{
			if (plci->sig_req)
			{
				plci->internal_command = plci->adjust_b_command;
				break;
			}
			if (plci->adjust_b_parms_msg != NULL)
				api_load_msg(plci->adjust_b_parms_msg, bp);
			else
				api_load_msg(&plci->B_protocol, bp);
			Info = add_b1(plci, bp,
				      (word)((plci->adjust_b_mode & ADJUST_B_MODE_NO_RESOURCE) ? 2 : 0),
				      plci->adjust_b_facilities);
			if (Info != GOOD)
			{
				dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x",
						UnMapId(Id), (char *)(FILE_), __LINE__,
						plci->B1_resource, plci->adjust_b_facilities));
				break;
			}
			plci->internal_command = plci->adjust_b_command;
			sig_req(plci, RESOURCES, 0);
			send_req(plci);
			plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
			break;
		}
		plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
		Rc = OK;
	case ADJUST_B_SWITCH_L1_2:
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x",
					UnMapId(Id), (char *)(FILE_), __LINE__,
					Rc, plci->B1_resource, plci->adjust_b_facilities));
			Info = _WRONG_STATE;
			break;
		}
		plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
		Rc = OK;
	case ADJUST_B_RESTORE_VOICE_1:
	case ADJUST_B_RESTORE_VOICE_2:
		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
		{
			Info = adv_voice_restore_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;
		}
		plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
		Rc = OK;
	case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
	case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
		{

			Info = dtmf_parameter_restore_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;

		}
		plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
		Rc = OK;
	case ADJUST_B_RESTORE_EC_1:
	case ADJUST_B_RESTORE_EC_2:
		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
		{

			Info = ec_restore_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;

		}
		plci->adjust_b_state = ADJUST_B_ASSIGN_L23_1;
	case ADJUST_B_ASSIGN_L23_1:
		if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
		{
			if (plci_nl_busy(plci))
			{
				plci->internal_command = plci->adjust_b_command;
				break;
			}
			if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
				plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
			if (plci->adjust_b_parms_msg != NULL)
				api_load_msg(plci->adjust_b_parms_msg, bp);
			else
				api_load_msg(&plci->B_protocol, bp);
			Info = add_b23(plci, bp);
			if (Info != GOOD)
			{
				dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x",
						UnMapId(Id), (char *)(FILE_), __LINE__, Info));
				break;
			}
			plci->internal_command = plci->adjust_b_command;
			nl_req_ncci(plci, ASSIGN, 0);
			send_req(plci);
			plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
			break;
		}
		plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
		Rc = ASSIGN_OK;
	case ADJUST_B_ASSIGN_L23_2:
		if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK))
		{
			dbug(1, dprintf("[%06lx] %s,%d: Adjust B assign failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			Info = _WRONG_STATE;
			break;
		}
		if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
		{
			if (Rc != ASSIGN_OK)
			{
				plci->internal_command = plci->adjust_b_command;
				break;
			}
		}
		if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT)
		{
			plci->adjust_b_restore = true;
			break;
		}
		plci->adjust_b_state = ADJUST_B_CONNECT_1;
	case ADJUST_B_CONNECT_1:
		if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
		{
			plci->internal_command = plci->adjust_b_command;
			if (plci_nl_busy(plci))
				break;
			nl_req_ncci(plci, N_CONNECT, 0);
			send_req(plci);
			plci->adjust_b_state = ADJUST_B_CONNECT_2;
			break;
		}
		plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
		Rc = OK;
	case ADJUST_B_CONNECT_2:
	case ADJUST_B_CONNECT_3:
	case ADJUST_B_CONNECT_4:
		if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
		{
			dbug(1, dprintf("[%06lx] %s,%d: Adjust B connect failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			Info = _WRONG_STATE;
			break;
		}
		if (Rc == OK)
		{
			if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
			{
				get_ncci(plci, (byte)(Id >> 16), plci->adjust_b_ncci);
				Id = (Id & 0xffff) | (((dword)(plci->adjust_b_ncci)) << 16);
			}
			if (plci->adjust_b_state == ADJUST_B_CONNECT_2)
				plci->adjust_b_state = ADJUST_B_CONNECT_3;
			else if (plci->adjust_b_state == ADJUST_B_CONNECT_4)
				plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
		}
		else if (Rc == 0)
		{
			if (plci->adjust_b_state == ADJUST_B_CONNECT_2)
				plci->adjust_b_state = ADJUST_B_CONNECT_4;
			else if (plci->adjust_b_state == ADJUST_B_CONNECT_3)
				plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
		}
		if (plci->adjust_b_state != ADJUST_B_RESTORE_DTMF_1)
		{
			plci->internal_command = plci->adjust_b_command;
			break;
		}
		Rc = OK;
	case ADJUST_B_RESTORE_DTMF_1:
	case ADJUST_B_RESTORE_DTMF_2:
		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
		{

			Info = dtmf_restore_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;

		}
		plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
		Rc = OK;
	case ADJUST_B_RESTORE_MIXER_1:
	case ADJUST_B_RESTORE_MIXER_2:
	case ADJUST_B_RESTORE_MIXER_3:
	case ADJUST_B_RESTORE_MIXER_4:
	case ADJUST_B_RESTORE_MIXER_5:
	case ADJUST_B_RESTORE_MIXER_6:
	case ADJUST_B_RESTORE_MIXER_7:
		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
		{

			Info = mixer_restore_config(Id, plci, Rc);
			if ((Info != GOOD) || plci->internal_command)
				break;

		}
		plci->adjust_b_state = ADJUST_B_END;
	case ADJUST_B_END:
		break;
	}
	return (Info);
}


static void adjust_b1_resource(dword Id, PLCI *plci, API_SAVE   *bp_msg, word b1_facilities, word internal_command)
{

	dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_resource %d %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__,
			plci->B1_resource, b1_facilities));

	plci->adjust_b_parms_msg = bp_msg;
	plci->adjust_b_facilities = b1_facilities;
	plci->adjust_b_command = internal_command;
	plci->adjust_b_ncci = (word)(Id >> 16);
	if ((bp_msg == NULL) && (plci->B1_resource == 0))
		plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_SWITCH_L1;
	else
		plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | ADJUST_B_MODE_RESTORE;
	plci->adjust_b_state = ADJUST_B_START;
	dbug(1, dprintf("[%06lx] %s,%d: Adjust B1 resource %d %04x...",
			UnMapId(Id), (char *)(FILE_), __LINE__,
			plci->B1_resource, b1_facilities));
}


static void adjust_b_restore(dword Id, PLCI *plci, byte Rc)
{
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: adjust_b_restore %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
		if (plci->req_in != 0)
		{
			plci->internal_command = ADJUST_B_RESTORE_1;
			break;
		}
		Rc = OK;
	case ADJUST_B_RESTORE_1:
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: Adjust B enqueued failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
		}
		plci->adjust_b_parms_msg = NULL;
		plci->adjust_b_facilities = plci->B1_facilities;
		plci->adjust_b_command = ADJUST_B_RESTORE_2;
		plci->adjust_b_ncci = (word)(Id >> 16);
		plci->adjust_b_mode = ADJUST_B_MODE_RESTORE;
		plci->adjust_b_state = ADJUST_B_START;
		dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore...",
				UnMapId(Id), (char *)(FILE_), __LINE__));
	case ADJUST_B_RESTORE_2:
		if (adjust_b_process(Id, plci, Rc) != GOOD)
		{
			dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore failed",
					UnMapId(Id), (char *)(FILE_), __LINE__));
		}
		if (plci->internal_command)
			break;
		break;
	}
}


static void reset_b3_command(dword Id, PLCI *plci, byte Rc)
{
	word Info;
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: reset_b3_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	Info = GOOD;
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
		plci->adjust_b_parms_msg = NULL;
		plci->adjust_b_facilities = plci->B1_facilities;
		plci->adjust_b_command = RESET_B3_COMMAND_1;
		plci->adjust_b_ncci = (word)(Id >> 16);
		plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_CONNECT;
		plci->adjust_b_state = ADJUST_B_START;
		dbug(1, dprintf("[%06lx] %s,%d: Reset B3...",
				UnMapId(Id), (char *)(FILE_), __LINE__));
	case RESET_B3_COMMAND_1:
		Info = adjust_b_process(Id, plci, Rc);
		if (Info != GOOD)
		{
			dbug(1, dprintf("[%06lx] %s,%d: Reset failed",
					UnMapId(Id), (char *)(FILE_), __LINE__));
			break;
		}
		if (plci->internal_command)
			return;
		break;
	}
/*  sendf (plci->appl, _RESET_B3_R | CONFIRM, Id, plci->number, "w", Info);*/
	sendf(plci->appl, _RESET_B3_I, Id, 0, "s", "");
}


static void select_b_command(dword Id, PLCI *plci, byte Rc)
{
	word Info;
	word internal_command;
	byte esc_chi[3];

	dbug(1, dprintf("[%06lx] %s,%d: select_b_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	Info = GOOD;
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
		plci->adjust_b_parms_msg = &plci->saved_msg;
		if ((plci->tel == ADV_VOICE) && (plci == plci->adapter->AdvSignalPLCI))
			plci->adjust_b_facilities = plci->B1_facilities | B1_FACILITY_VOICE;
		else
			plci->adjust_b_facilities = plci->B1_facilities & ~B1_FACILITY_VOICE;
		plci->adjust_b_command = SELECT_B_COMMAND_1;
		plci->adjust_b_ncci = (word)(Id >> 16);
		if (plci->saved_msg.parms[0].length == 0)
		{
			plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 |
				ADJUST_B_MODE_NO_RESOURCE;
		}
		else
		{
			plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 |
				ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE;
		}
		plci->adjust_b_state = ADJUST_B_START;
		dbug(1, dprintf("[%06lx] %s,%d: Select B protocol...",
				UnMapId(Id), (char *)(FILE_), __LINE__));
	case SELECT_B_COMMAND_1:
		Info = adjust_b_process(Id, plci, Rc);
		if (Info != GOOD)
		{
			dbug(1, dprintf("[%06lx] %s,%d: Select B protocol failed",
					UnMapId(Id), (char *)(FILE_), __LINE__));
			break;
		}
		if (plci->internal_command)
			return;
		if (plci->tel == ADV_VOICE)
		{
			esc_chi[0] = 0x02;
			esc_chi[1] = 0x18;
			esc_chi[2] = plci->b_channel;
			SetVoiceChannel(plci->adapter->AdvCodecPLCI, esc_chi, plci->adapter);
		}
		break;
	}
	sendf(plci->appl, _SELECT_B_REQ | CONFIRM, Id, plci->number, "w", Info);
}


static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc)
{
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
	case FAX_CONNECT_ACK_COMMAND_1:
		if (plci_nl_busy(plci))
		{
			plci->internal_command = FAX_CONNECT_ACK_COMMAND_1;
			return;
		}
		plci->internal_command = FAX_CONNECT_ACK_COMMAND_2;
		plci->NData[0].P = plci->fax_connect_info_buffer;
		plci->NData[0].PLength = plci->fax_connect_info_length;
		plci->NL.X = plci->NData;
		plci->NL.ReqCh = 0;
		plci->NL.Req = plci->nl_req = (byte) N_CONNECT_ACK;
		plci->adapter->request(&plci->NL);
		return;
	case FAX_CONNECT_ACK_COMMAND_2:
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			break;
		}
	}
	if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
	    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
	{
		if (plci->B3_prot == 4)
			sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
		else
			sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
		plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
	}
}


static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc)
{
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
	case FAX_EDATA_ACK_COMMAND_1:
		if (plci_nl_busy(plci))
		{
			plci->internal_command = FAX_EDATA_ACK_COMMAND_1;
			return;
		}
		plci->internal_command = FAX_EDATA_ACK_COMMAND_2;
		plci->NData[0].P = plci->fax_connect_info_buffer;
		plci->NData[0].PLength = plci->fax_edata_ack_length;
		plci->NL.X = plci->NData;
		plci->NL.ReqCh = 0;
		plci->NL.Req = plci->nl_req = (byte) N_EDATA;
		plci->adapter->request(&plci->NL);
		return;
	case FAX_EDATA_ACK_COMMAND_2:
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			break;
		}
	}
}


static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc)
{
	word Info;
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: fax_connect_info_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	Info = GOOD;
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
	case FAX_CONNECT_INFO_COMMAND_1:
		if (plci_nl_busy(plci))
		{
			plci->internal_command = FAX_CONNECT_INFO_COMMAND_1;
			return;
		}
		plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
		plci->NData[0].P = plci->fax_connect_info_buffer;
		plci->NData[0].PLength = plci->fax_connect_info_length;
		plci->NL.X = plci->NData;
		plci->NL.ReqCh = 0;
		plci->NL.Req = plci->nl_req = (byte) N_EDATA;
		plci->adapter->request(&plci->NL);
		return;
	case FAX_CONNECT_INFO_COMMAND_2:
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: FAX setting connect info failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			Info = _WRONG_STATE;
			break;
		}
		if (plci_nl_busy(plci))
		{
			plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
			return;
		}
		plci->command = _CONNECT_B3_R;
		nl_req_ncci(plci, N_CONNECT, 0);
		send_req(plci);
		return;
	}
	sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
}


static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc)
{
	word Info;
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	Info = GOOD;
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
		plci->adjust_b_parms_msg = NULL;
		plci->adjust_b_facilities = plci->B1_facilities;
		plci->adjust_b_command = FAX_ADJUST_B23_COMMAND_1;
		plci->adjust_b_ncci = (word)(Id >> 16);
		plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23;
		plci->adjust_b_state = ADJUST_B_START;
		dbug(1, dprintf("[%06lx] %s,%d: FAX adjust B23...",
				UnMapId(Id), (char *)(FILE_), __LINE__));
	case FAX_ADJUST_B23_COMMAND_1:
		Info = adjust_b_process(Id, plci, Rc);
		if (Info != GOOD)
		{
			dbug(1, dprintf("[%06lx] %s,%d: FAX adjust failed",
					UnMapId(Id), (char *)(FILE_), __LINE__));
			break;
		}
		if (plci->internal_command)
			return;
	case FAX_ADJUST_B23_COMMAND_2:
		if (plci_nl_busy(plci))
		{
			plci->internal_command = FAX_ADJUST_B23_COMMAND_2;
			return;
		}
		plci->command = _CONNECT_B3_R;
		nl_req_ncci(plci, N_CONNECT, 0);
		send_req(plci);
		return;
	}
	sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
}


static void fax_disconnect_command(dword Id, PLCI *plci, byte Rc)
{
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: fax_disconnect_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
		plci->internal_command = FAX_DISCONNECT_COMMAND_1;
		return;
	case FAX_DISCONNECT_COMMAND_1:
	case FAX_DISCONNECT_COMMAND_2:
	case FAX_DISCONNECT_COMMAND_3:
		if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
		{
			dbug(1, dprintf("[%06lx] %s,%d: FAX disconnect EDATA failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			break;
		}
		if (Rc == OK)
		{
			if ((internal_command == FAX_DISCONNECT_COMMAND_1)
			    || (internal_command == FAX_DISCONNECT_COMMAND_2))
			{
				plci->internal_command = FAX_DISCONNECT_COMMAND_2;
			}
		}
		else if (Rc == 0)
		{
			if (internal_command == FAX_DISCONNECT_COMMAND_1)
				plci->internal_command = FAX_DISCONNECT_COMMAND_3;
		}
		return;
	}
}



static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc)
{
	word Info;
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	Info = GOOD;
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
	case RTP_CONNECT_B3_REQ_COMMAND_1:
		if (plci_nl_busy(plci))
		{
			plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_1;
			return;
		}
		plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
		nl_req_ncci(plci, N_CONNECT, 0);
		send_req(plci);
		return;
	case RTP_CONNECT_B3_REQ_COMMAND_2:
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect info failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			Info = _WRONG_STATE;
			break;
		}
		if (plci_nl_busy(plci))
		{
			plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
			return;
		}
		plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_3;
		plci->NData[0].PLength = plci->internal_req_buffer[0];
		plci->NData[0].P = plci->internal_req_buffer + 1;
		plci->NL.X = plci->NData;
		plci->NL.ReqCh = 0;
		plci->NL.Req = plci->nl_req = (byte) N_UDATA;
		plci->adapter->request(&plci->NL);
		break;
	case RTP_CONNECT_B3_REQ_COMMAND_3:
		return;
	}
	sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
}


static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc)
{
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
	case RTP_CONNECT_B3_RES_COMMAND_1:
		if (plci_nl_busy(plci))
		{
			plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_1;
			return;
		}
		plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
		nl_req_ncci(plci, N_CONNECT_ACK, (byte)(Id >> 16));
		send_req(plci);
		return;
	case RTP_CONNECT_B3_RES_COMMAND_2:
		if ((Rc != OK) && (Rc != OK_FC))
		{
			dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
			break;
		}
		if (plci_nl_busy(plci))
		{
			plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
			return;
		}
		sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
		plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_3;
		plci->NData[0].PLength = plci->internal_req_buffer[0];
		plci->NData[0].P = plci->internal_req_buffer + 1;
		plci->NL.X = plci->NData;
		plci->NL.ReqCh = 0;
		plci->NL.Req = plci->nl_req = (byte) N_UDATA;
		plci->adapter->request(&plci->NL);
		return;
	case RTP_CONNECT_B3_RES_COMMAND_3:
		return;
	}
}



static void hold_save_command(dword Id, PLCI *plci, byte Rc)
{
	byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
	word Info;
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: hold_save_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	Info = GOOD;
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		if (!plci->NL.Id)
			break;
		plci->command = 0;
		plci->adjust_b_parms_msg = NULL;
		plci->adjust_b_facilities = plci->B1_facilities;
		plci->adjust_b_command = HOLD_SAVE_COMMAND_1;
		plci->adjust_b_ncci = (word)(Id >> 16);
		plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23;
		plci->adjust_b_state = ADJUST_B_START;
		dbug(1, dprintf("[%06lx] %s,%d: HOLD save...",
				UnMapId(Id), (char *)(FILE_), __LINE__));
	case HOLD_SAVE_COMMAND_1:
		Info = adjust_b_process(Id, plci, Rc);
		if (Info != GOOD)
		{
			dbug(1, dprintf("[%06lx] %s,%d: HOLD save failed",
					UnMapId(Id), (char *)(FILE_), __LINE__));
			break;
		}
		if (plci->internal_command)
			return;
	}
	sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
}


static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc)
{
	byte SS_Ind[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/
	word Info;
	word internal_command;

	dbug(1, dprintf("[%06lx] %s,%d: retrieve_restore_command %02x %04x",
			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));

	Info = GOOD;
	internal_command = plci->internal_command;
	plci->internal_command = 0;
	switch (internal_command)
	{
	default:
		plci->command = 0;
		plci->adjust_b_parms_msg = NULL;
		plci->adjust_b_facilities = plci->B1_facilities;
		plci->adjust_b_command = RETRIEVE_RESTORE_COMMAND_1;
		plci->adjust_b_ncci = (word)(Id >> 16);
		plci->adjust_b_mode = ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE;
		plci->adjust_b_state = ADJUST_B_START;
		dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore...",
				UnMapId(Id), (char *)(FILE_), __LINE__));
	case RETRIEVE_RESTORE_COMMAND_1:
		Info = adjust_b_process(Id, plci, Rc);
		if (Info != GOOD)
		{
			dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore failed",
					UnMapId(Id), (char *)(FILE_), __LINE__));
			break;
		}
		if (plci->internal_command)
			return;
	}
	sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
}


static void init_b1_config(PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: init_b1_config",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	plci->B1_resource = 0;
	plci->B1_facilities = 0;

	plci->li_bchannel_id = 0;
	mixer_clear_config(plci);


	ec_clear_config(plci);


	dtmf_rec_clear_config(plci);
	dtmf_send_clear_config(plci);
	dtmf_parameter_clear_config(plci);

	adv_voice_clear_config(plci);
	adjust_b_clear(plci);
}


static void clear_b1_config(PLCI *plci)
{

	dbug(1, dprintf("[%06lx] %s,%d: clear_b1_config",
			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
			(char *)(FILE_), __LINE__));

	adv_voice_clear_config(plci);
	adjust_b_clear(plci);

	ec_clear_config(plci);


	dtmf_rec_clear_config(plci);
	dtmf_send_clear_config(plci);
	dtmf_parameter_clear_config(plci);


	if ((plci->li_bchannel_id != 0)
	    && (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci == plci))
	{
		mixer_clear_config(plci);
		li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = NULL;
		plci->li_bchannel_id = 0;
	}

	plci->B1_resource = 0;
	plci->B1_facilities = 0;
}


/* -----------------------------------------------------------------
   XON protocol local helpers
   ----------------------------------------------------------------- */
static void channel_flow_control_remove(PLCI *plci) {
	DIVA_CAPI_ADAPTER *a = plci->adapter;
	word i;
	for (i = 1; i < MAX_NL_CHANNEL + 1; i++) {
		if (a->ch_flow_plci[i] == plci->Id) {
			a->ch_flow_plci[i] = 0;
			a->ch_flow_control[i] = 0;
		}
	}
}

static void channel_x_on(PLCI *plci, byte ch) {
	DIVA_CAPI_ADAPTER *a = plci->adapter;
	if (a->ch_flow_control[ch] & N_XON_SENT) {
		a->ch_flow_control[ch] &= ~N_XON_SENT;
	}
}

static void channel_x_off(PLCI *plci, byte ch, byte flag) {
	DIVA_CAPI_ADAPTER *a = plci->adapter;
	if ((a->ch_flow_control[ch] & N_RX_FLOW_CONTROL_MASK) == 0) {
		a->ch_flow_control[ch] |= (N_CH_XOFF | flag);
		a->ch_flow_plci[ch] = plci->Id;
		a->ch_flow_control_pending++;
	}
}

static void channel_request_xon(PLCI *plci, byte ch) {
	DIVA_CAPI_ADAPTER *a = plci->adapter;

	if (a->ch_flow_control[ch] & N_CH_XOFF) {
		a->ch_flow_control[ch] |= N_XON_REQ;
		a->ch_flow_control[ch] &= ~N_CH_XOFF;
		a->ch_flow_control[ch] &= ~N_XON_CONNECT_IND;
	}
}

static void channel_xmit_extended_xon(PLCI *plci) {
	DIVA_CAPI_ADAPTER *a;
	int max_ch = ARRAY_SIZE(a->ch_flow_control);
	int i, one_requested = 0;

	if ((!plci) || (!plci->Id) || ((a = plci->adapter) == NULL)) {
		return;
	}

	for (i = 0; i < max_ch; i++) {
		if ((a->ch_flow_control[i] & N_CH_XOFF) &&
		    (a->ch_flow_control[i] & N_XON_CONNECT_IND) &&
		    (plci->Id == a->ch_flow_plci[i])) {
			channel_request_xon(plci, (byte)i);
			one_requested = 1;
		}
	}

	if (one_requested) {
		channel_xmit_xon(plci);
	}
}

/*
  Try to xmit next X_ON
*/
static int find_channel_with_pending_x_on(DIVA_CAPI_ADAPTER *a, PLCI *plci) {
	int max_ch = ARRAY_SIZE(a->ch_flow_control);
	int i;

	if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) {
		return (0);
	}

	if (a->last_flow_control_ch >= max_ch) {
		a->last_flow_control_ch = 1;
	}
	for (i = a->last_flow_control_ch; i < max_ch; i++) {
		if ((a->ch_flow_control[i] & N_XON_REQ) &&
		    (plci->Id == a->ch_flow_plci[i])) {
			a->last_flow_control_ch = i + 1;
			return (i);
		}
	}

	for (i = 1; i < a->last_flow_control_ch; i++) {
		if ((a->ch_flow_control[i] & N_XON_REQ) &&
		    (plci->Id == a->ch_flow_plci[i])) {
			a->last_flow_control_ch = i + 1;
			return (i);
		}
	}

	return (0);
}

static void channel_xmit_xon(PLCI *plci) {
	DIVA_CAPI_ADAPTER *a = plci->adapter;
	byte ch;

	if (plci->nl_req || !plci->NL.Id || plci->nl_remove_id) {
		return;
	}
	if ((ch = (byte)find_channel_with_pending_x_on(a, plci)) == 0) {
		return;
	}
	a->ch_flow_control[ch] &= ~N_XON_REQ;
	a->ch_flow_control[ch] |= N_XON_SENT;

	plci->NL.Req = plci->nl_req = (byte)N_XON;
	plci->NL.ReqCh         = ch;
	plci->NL.X             = plci->NData;
	plci->NL.XNum          = 1;
	plci->NData[0].P       = &plci->RBuffer[0];
	plci->NData[0].PLength = 0;

	plci->adapter->request(&plci->NL);
}

static int channel_can_xon(PLCI *plci, byte ch) {
	APPL *APPLptr;
	DIVA_CAPI_ADAPTER *a;
	word NCCIcode;
	dword count;
	word Num;
	word i;

	APPLptr = plci->appl;
	a = plci->adapter;

	if (!APPLptr)
		return (0);

	NCCIcode = a->ch_ncci[ch] | (((word) a->Id) << 8);

	/* count all buffers within the Application pool    */
	/* belonging to the same NCCI. XON if a first is    */
	/* used.                                            */
	count = 0;
	Num = 0xffff;
	for (i = 0; i < APPLptr->MaxBuffer; i++) {
		if (NCCIcode == APPLptr->DataNCCI[i]) count++;
		if (!APPLptr->DataNCCI[i] && Num == 0xffff) Num = i;
	}
	if ((count > 2) || (Num == 0xffff)) {
		return (0);
	}
	return (1);
}


/*------------------------------------------------------------------*/

static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *a, word offset)
{
	return 1;
}



/**********************************************************************************/
/* function groups the listening applications according to the CIP mask and the   */
/* Info_Mask. Each group gets just one Connect_Ind. Some application manufacturer */
/* are not multi-instance capable, so they start e.g. 30 applications what causes */
/* big problems on application level (one call, 30 Connect_Ind, ect). The         */
/* function must be enabled by setting "a->group_optimization_enabled" from the   */
/* OS specific part (per adapter).                                                */
/**********************************************************************************/
static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci)
{
	word i, j, k, busy, group_found;
	dword info_mask_group[MAX_CIP_TYPES];
	dword cip_mask_group[MAX_CIP_TYPES];
	word appl_number_group_type[MAX_APPL];
	PLCI *auxplci;

	set_group_ind_mask(plci); /* all APPLs within this inc. call are allowed to dial in */

	if (!a->group_optimization_enabled)
	{
		dbug(1, dprintf("No group optimization"));
		return;
	}

	dbug(1, dprintf("Group optimization = 0x%x...", a->group_optimization_enabled));

	for (i = 0; i < MAX_CIP_TYPES; i++)
	{
		info_mask_group[i] = 0;
		cip_mask_group[i] = 0;
	}
	for (i = 0; i < MAX_APPL; i++)
	{
		appl_number_group_type[i] = 0;
	}
	for (i = 0; i < max_appl; i++) /* check if any multi instance capable application is present */
	{  /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */
		if (application[i].Id && (application[i].MaxNCCI) > 1 && (a->CIP_Mask[i]) && (a->group_optimization_enabled == 1))
		{
			dbug(1, dprintf("Multi-Instance capable, no optimization required"));
			return; /* allow good application unfiltered access */
		}
	}
	for (i = 0; i < max_appl; i++) /* Build CIP Groups */
	{
		if (application[i].Id && a->CIP_Mask[i])
		{
			for (k = 0, busy = false; k < a->max_plci; k++)
			{
				if (a->plci[k].Id)
				{
					auxplci = &a->plci[k];
					if (auxplci->appl == &application[i]) /* application has a busy PLCI */
					{
						busy = true;
						dbug(1, dprintf("Appl 0x%x is busy", i + 1));
					}
					else if (test_c_ind_mask_bit(auxplci, i)) /* application has an incoming call pending */
					{
						busy = true;
						dbug(1, dprintf("Appl 0x%x has inc. call pending", i + 1));
					}
				}
			}

			for (j = 0, group_found = 0; j <= (MAX_CIP_TYPES) && !busy && !group_found; j++)     /* build groups with free applications only */
			{
				if (j == MAX_CIP_TYPES)       /* all groups are in use but group still not found */
				{                           /* the MAX_CIP_TYPES group enables all calls because of field overflow */
					appl_number_group_type[i] = MAX_CIP_TYPES;
					group_found = true;
					dbug(1, dprintf("Field overflow appl 0x%x", i + 1));
				}
				else if ((info_mask_group[j] == a->CIP_Mask[i]) && (cip_mask_group[j] == a->Info_Mask[i]))
				{                                      /* is group already present ?                  */
					appl_number_group_type[i] = j | 0x80;  /* store the group number for each application */
					group_found = true;
					dbug(1, dprintf("Group 0x%x found with appl 0x%x, CIP=0x%lx", appl_number_group_type[i], i + 1, info_mask_group[j]));
				}
				else if (!info_mask_group[j])
				{                                      /* establish a new group                       */
					appl_number_group_type[i] = j | 0x80;  /* store the group number for each application */
					info_mask_group[j] = a->CIP_Mask[i]; /* store the new CIP mask for the new group    */
					cip_mask_group[j] = a->Info_Mask[i]; /* store the new Info_Mask for this new group  */
					group_found = true;
					dbug(1, dprintf("New Group 0x%x established with appl 0x%x, CIP=0x%lx", appl_number_group_type[i], i + 1, info_mask_group[j]));
				}
			}
		}
	}

	for (i = 0; i < max_appl; i++) /* Build group_optimization_mask_table */
	{
		if (appl_number_group_type[i]) /* application is free, has listens and is member of a group */
		{
			if (appl_number_group_type[i] == MAX_CIP_TYPES)
			{
				dbug(1, dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled", appl_number_group_type[i], i + 1));
			}
			else
			{
				dbug(1, dprintf("Group 0x%x, valid appl = 0x%x", appl_number_group_type[i], i + 1));
				for (j = i + 1; j < max_appl; j++)   /* search other group members and mark them as busy        */
				{
					if (appl_number_group_type[i] == appl_number_group_type[j])
					{
						dbug(1, dprintf("Appl 0x%x is member of group 0x%x, no call", j + 1, appl_number_group_type[j]));
						clear_group_ind_mask_bit(plci, j);           /* disable call on other group members */
						appl_number_group_type[j] = 0;       /* remove disabled group member from group list */
					}
				}
			}
		}
		else                                                 /* application should not get a call */
		{
			clear_group_ind_mask_bit(plci, i);
		}
	}

}



/* OS notifies the driver about a application Capi_Register */
word CapiRegister(word id)
{
	word i, j, appls_found;

	PLCI *plci;
	DIVA_CAPI_ADAPTER *a;

	for (i = 0, appls_found = 0; i < max_appl; i++)
	{
		if (application[i].Id && (application[i].Id != id))
		{
			appls_found++;                       /* an application has been found */
		}
	}

	if (appls_found) return true;
	for (i = 0; i < max_adapter; i++)                   /* scan all adapters...    */
	{
		a = &adapter[i];
		if (a->request)
		{
			if (a->flag_dynamic_l1_down)  /* remove adapter from L1 tristate (Huntgroup) */
			{
				if (!appls_found)           /* first application does a capi register   */
				{
					if ((j = get_plci(a)))                    /* activate L1 of all adapters */
					{
						plci = &a->plci[j - 1];
						plci->command = 0;
						add_p(plci, OAD, "\x01\xfd");
						add_p(plci, CAI, "\x01\x80");
						add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
						add_p(plci, SHIFT | 6, NULL);
						add_p(plci, SIN, "\x02\x00\x00");
						plci->internal_command = START_L1_SIG_ASSIGN_PEND;
						sig_req(plci, ASSIGN, DSIG_ID);
						add_p(plci, FTY, "\x02\xff\x07"); /* l1 start */
						sig_req(plci, SIG_CTRL, 0);
						send_req(plci);
					}
				}
			}
		}
	}
	return false;
}

/*------------------------------------------------------------------*/

/* Functions for virtual Switching e.g. Transfer by join, Conference */

static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms)
{
	word i;
	/* Format of vswitch_t:
	   0 byte length
	   1 byte VSWITCHIE
	   2 byte VSWITCH_REQ/VSWITCH_IND
	   3 byte reserved
	   4 word VSwitchcommand
	   6 word returnerror
	   8... Params
	*/
	if (!plci ||
	    !plci->appl ||
	    !plci->State ||
	    plci->Sig.Ind == NCR_FACILITY
		)
		return;

	for (i = 0; i < MAX_MULTI_IE; i++)
	{
		if (!parms[i][0]) continue;
		if (parms[i][0] < 7)
		{
			parms[i][0] = 0; /* kill it */
			continue;
		}
		dbug(1, dprintf("VSwitchReqInd(%d)", parms[i][4]));
		switch (parms[i][4])
		{
		case VSJOIN:
			if (!plci->relatedPTYPLCI ||
			    (plci->ptyState != S_ECT && plci->relatedPTYPLCI->ptyState != S_ECT))
			{ /* Error */
				break;
			}
			/* remember all necessary informations */
			if (parms[i][0] != 11 || parms[i][8] != 3) /* Length Test */
			{
				break;
			}
			if (parms[i][2] == VSWITCH_IND && parms[i][9] == 1)
			{   /* first indication after ECT-Request on Consultation Call */
				plci->vswitchstate = parms[i][9];
				parms[i][9] = 2; /* State */
				/* now ask first Call to join */
			}
			else if (parms[i][2] == VSWITCH_REQ && parms[i][9] == 3)
			{ /* Answer of VSWITCH_REQ from first Call */
				plci->vswitchstate = parms[i][9];
				/* tell consultation call to join
				   and the protocol capabilities of the first call */
			}
			else
			{ /* Error */
				break;
			}
			plci->vsprot = parms[i][10]; /* protocol */
			plci->vsprotdialect = parms[i][11]; /* protocoldialect */
			/* send join request to related PLCI */
			parms[i][1] = VSWITCHIE;
			parms[i][2] = VSWITCH_REQ;

			plci->relatedPTYPLCI->command = 0;
			plci->relatedPTYPLCI->internal_command = VSWITCH_REQ_PEND;
			add_p(plci->relatedPTYPLCI, ESC, &parms[i][0]);
			sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
			send_req(plci->relatedPTYPLCI);
			break;
		case VSTRANSPORT:
		default:
			if (plci->relatedPTYPLCI &&
			    plci->vswitchstate == 3 &&
			    plci->relatedPTYPLCI->vswitchstate == 3)
			{
				add_p(plci->relatedPTYPLCI, ESC, &parms[i][0]);
				sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
				send_req(plci->relatedPTYPLCI);
			}
			break;
		}
		parms[i][0] = 0; /* kill it */
	}
}


/*------------------------------------------------------------------*/

static int diva_get_dma_descriptor(PLCI *plci, dword   *dma_magic) {
	ENTITY e;
	IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;

	if (!(diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_RX_DMA)) {
		return (-1);
	}

	pReq->xdi_dma_descriptor_operation.Req = 0;
	pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;

	pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;
	pReq->xdi_dma_descriptor_operation.info.descriptor_number  = -1;
	pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
	pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;

	e.user[0] = plci->adapter->Id - 1;
	plci->adapter->request((ENTITY *)pReq);

	if (!pReq->xdi_dma_descriptor_operation.info.operation &&
	    (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&
	    pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {
		*dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;
		dbug(3, dprintf("dma_alloc, a:%d (%d-%08x)",
				plci->adapter->Id,
				pReq->xdi_dma_descriptor_operation.info.descriptor_number,
				*dma_magic));
		return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
	} else {
		dbug(1, dprintf("dma_alloc failed"));
		return (-1);
	}
}

static void diva_free_dma_descriptor(PLCI *plci, int nr) {
	ENTITY e;
	IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;

	if (nr < 0) {
		return;
	}

	pReq->xdi_dma_descriptor_operation.Req = 0;
	pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;

	pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;
	pReq->xdi_dma_descriptor_operation.info.descriptor_number  = nr;
	pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
	pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;

	e.user[0] = plci->adapter->Id - 1;
	plci->adapter->request((ENTITY *)pReq);

	if (!pReq->xdi_dma_descriptor_operation.info.operation) {
		dbug(1, dprintf("dma_free(%d)", nr));
	} else {
		dbug(1, dprintf("dma_free failed (%d)", nr));
	}
}

/*------------------------------------------------------------------*/
