diff options
Diffstat (limited to 'drivers/isdn/hardware/eicon/message.c')
-rw-r--r-- | drivers/isdn/hardware/eicon/message.c | 14954 |
1 files changed, 0 insertions, 14954 deletions
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c deleted file mode 100644 index def7992a38e6..000000000000 --- a/drivers/isdn/hardware/eicon/message.c +++ /dev/null @@ -1,14954 +0,0 @@ -/* - * - 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 <linux/bitmap.h> - -#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); -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)); |