/*
 *
 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 *, const 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)
{
	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_asc_lo(d);
					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)           */
	static const 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 */
	static const word multi_fac_id[] = {1, FTY};
	static const word multi_pi_id[]  = {1, PI};
	static const word multi_CiPN_id[]  = {1, OAD};
	static const word multi_ssext_id[]  = {1, ESC_SSEXT};

	static const 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, const 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)
{
	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_byte_pack(p, li_config_table[j].curchnl);
	}
	*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_byte_pack(p, li_config_table[j].channel);
	}
	*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_byte_pack(p, li_config_table[j].chflags);
	}
	*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_byte_pack(p, li_config_table[i].flag_table[j]);
		}
		*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_byte_pack(p, li_config_table[i].coef_table[j]);
		}
		*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;
				((CAPI_MSG *) msg)->info.facility_req.structs[1] = LI_REQ_SILENT_UPDATE & 0xff;
				((CAPI_MSG *) msg)->info.facility_req.structs[2] = LI_REQ_SILENT_UPDATE >> 8;
				((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));
	}
}

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