| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 |  | 
 | 2 | /* | 
 | 3 |  * | 
 | 4 |   Copyright (c) Eicon Networks, 2002. | 
 | 5 |  * | 
 | 6 |   This source file is supplied for the use with | 
 | 7 |   Eicon Networks range of DIVA Server Adapters. | 
 | 8 |  * | 
 | 9 |   Eicon File Revision :    2.1 | 
 | 10 |  * | 
 | 11 |   This program is free software; you can redistribute it and/or modify | 
 | 12 |   it under the terms of the GNU General Public License as published by | 
 | 13 |   the Free Software Foundation; either version 2, or (at your option) | 
 | 14 |   any later version. | 
 | 15 |  * | 
 | 16 |   This program is distributed in the hope that it will be useful, | 
 | 17 |   but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY | 
 | 18 |   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
 | 19 |   See the GNU General Public License for more details. | 
 | 20 |  * | 
 | 21 |   You should have received a copy of the GNU General Public License | 
 | 22 |   along with this program; if not, write to the Free Software | 
 | 23 |   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
 | 24 |  * | 
 | 25 |  */ | 
 | 26 |  | 
 | 27 |  | 
 | 28 |  | 
 | 29 |  | 
 | 30 |  | 
 | 31 | #include "platform.h" | 
 | 32 | #include "di_defs.h" | 
 | 33 | #include "pc.h" | 
 | 34 | #include "capi20.h" | 
 | 35 | #include "divacapi.h" | 
 | 36 | #include "mdm_msg.h" | 
 | 37 | #include "divasync.h" | 
 | 38 |  | 
 | 39 |  | 
 | 40 |  | 
 | 41 | #define FILE_ "MESSAGE.C" | 
 | 42 | #define dprintf | 
 | 43 |  | 
 | 44 |  | 
 | 45 |  | 
 | 46 |  | 
 | 47 |  | 
 | 48 |  | 
 | 49 |  | 
 | 50 |  | 
 | 51 |  | 
 | 52 | /*------------------------------------------------------------------*/ | 
 | 53 | /* This is options supported for all adapters that are server by    */ | 
 | 54 | /* XDI driver. Allo it is not necessary to ask it from every adapter*/ | 
 | 55 | /* and it is not necessary to save it separate for every adapter    */ | 
 | 56 | /* Macrose defined here have only local meaning                     */ | 
 | 57 | /*------------------------------------------------------------------*/ | 
 | 58 | static dword diva_xdi_extended_features = 0; | 
 | 59 |  | 
 | 60 | #define DIVA_CAPI_USE_CMA                 0x00000001 | 
 | 61 | #define DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR  0x00000002 | 
 | 62 | #define DIVA_CAPI_XDI_PROVIDES_NO_CANCEL  0x00000004 | 
 | 63 | #define DIVA_CAPI_XDI_PROVIDES_RX_DMA     0x00000008 | 
 | 64 |  | 
 | 65 | /* | 
 | 66 |   CAPI can request to process all return codes self only if: | 
 | 67 |   protocol code supports this && xdi supports this | 
 | 68 |  */ | 
 | 69 | #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)) | 
 | 70 |  | 
 | 71 | /*------------------------------------------------------------------*/ | 
 | 72 | /* local function prototypes                                        */ | 
 | 73 | /*------------------------------------------------------------------*/ | 
 | 74 |  | 
 | 75 | static void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci); | 
 | 76 | static void set_group_ind_mask (PLCI   *plci); | 
 | 77 | static void clear_group_ind_mask_bit (PLCI   *plci, word b); | 
 | 78 | static byte test_group_ind_mask_bit (PLCI   *plci, word b); | 
 | 79 | void AutomaticLaw(DIVA_CAPI_ADAPTER   *); | 
 | 80 | word CapiRelease(word); | 
 | 81 | word CapiRegister(word); | 
 | 82 | word api_put(APPL   *, CAPI_MSG   *); | 
 | 83 | static word api_parse(byte   *, word, byte *, API_PARSE *); | 
 | 84 | static void api_save_msg(API_PARSE   *in, byte *format, API_SAVE   *out); | 
 | 85 | static void api_load_msg(API_SAVE   *in, API_PARSE   *out); | 
 | 86 |  | 
 | 87 | word api_remove_start(void); | 
 | 88 | void api_remove_complete(void); | 
 | 89 |  | 
 | 90 | static void plci_remove(PLCI   *); | 
 | 91 | static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER  * a); | 
 | 92 | static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER  *, IDI_SYNC_REQ  *); | 
 | 93 |  | 
 | 94 | void   callback(ENTITY   *); | 
 | 95 |  | 
 | 96 | static void control_rc(PLCI   *, byte, byte, byte, byte, byte); | 
 | 97 | static void data_rc(PLCI   *, byte); | 
 | 98 | static void data_ack(PLCI   *, byte); | 
 | 99 | static void sig_ind(PLCI   *); | 
 | 100 | static void SendInfo(PLCI   *, dword, byte   * *, byte); | 
 | 101 | static void SendSetupInfo(APPL   *, PLCI   *, dword, byte   * *, byte); | 
 | 102 | static void SendSSExtInd(APPL   *, PLCI   * plci, dword Id, byte   * * parms); | 
 | 103 |  | 
 | 104 | static void VSwitchReqInd(PLCI   *plci, dword Id, byte   **parms); | 
 | 105 |  | 
 | 106 | static void nl_ind(PLCI   *); | 
 | 107 |  | 
 | 108 | static byte connect_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 109 | static byte connect_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 110 | static byte connect_a_res(dword,word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 111 | static byte disconnect_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 112 | static byte disconnect_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 113 | static byte listen_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 114 | static byte info_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 115 | static byte info_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 116 | static byte alert_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 117 | static byte facility_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 118 | static byte facility_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 119 | static byte connect_b3_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 120 | static byte connect_b3_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 121 | static byte connect_b3_a_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 122 | static byte disconnect_b3_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 123 | static byte disconnect_b3_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 124 | static byte data_b3_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 125 | static byte data_b3_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 126 | static byte reset_b3_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 127 | static byte reset_b3_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 128 | static byte connect_b3_t90_a_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 129 | static byte select_b_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 130 | static byte manufacturer_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 131 | static byte manufacturer_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 132 |  | 
 | 133 | static word get_plci(DIVA_CAPI_ADAPTER   *); | 
 | 134 | static void add_p(PLCI   *, byte, byte   *); | 
 | 135 | static void add_s(PLCI   * plci, byte code, API_PARSE * p); | 
 | 136 | static void add_ss(PLCI   * plci, byte code, API_PARSE * p); | 
 | 137 | static void add_ie(PLCI   * plci, byte code, byte   * p, word p_length); | 
 | 138 | static void add_d(PLCI   *, word, byte   *); | 
 | 139 | static void add_ai(PLCI   *, API_PARSE *); | 
 | 140 | static word add_b1(PLCI   *, API_PARSE *, word, word); | 
 | 141 | static word add_b23(PLCI   *, API_PARSE *); | 
 | 142 | static word add_modem_b23 (PLCI  * plci, API_PARSE* bp_parms); | 
 | 143 | static void sig_req(PLCI   *, byte, byte); | 
 | 144 | static void nl_req_ncci(PLCI   *, byte, byte); | 
 | 145 | static void send_req(PLCI   *); | 
 | 146 | static void send_data(PLCI   *); | 
 | 147 | static word plci_remove_check(PLCI   *); | 
 | 148 | static void listen_check(DIVA_CAPI_ADAPTER   *); | 
 | 149 | static byte AddInfo(byte   **, byte   **, byte   *, byte *); | 
 | 150 | static byte getChannel(API_PARSE *); | 
 | 151 | static void IndParse(PLCI   *, word *, byte   **, byte); | 
 | 152 | static byte ie_compare(byte   *, byte *); | 
 | 153 | static word find_cip(DIVA_CAPI_ADAPTER   *, byte   *, byte   *); | 
 | 154 | static word CPN_filter_ok(byte   *cpn,DIVA_CAPI_ADAPTER   *,word); | 
 | 155 |  | 
 | 156 | /* | 
 | 157 |   XON protocol helpers | 
 | 158 |   */ | 
 | 159 | static void channel_flow_control_remove (PLCI   * plci); | 
 | 160 | static void channel_x_off (PLCI   * plci, byte ch, byte flag); | 
 | 161 | static void channel_x_on (PLCI   * plci, byte ch); | 
 | 162 | static void channel_request_xon (PLCI   * plci, byte ch); | 
 | 163 | static void channel_xmit_xon (PLCI   * plci); | 
 | 164 | static int channel_can_xon (PLCI   * plci, byte ch); | 
 | 165 | static void channel_xmit_extended_xon (PLCI   * plci); | 
 | 166 |  | 
 | 167 | static byte SendMultiIE(PLCI   * plci, dword Id, byte   * * parms, byte ie_type, dword info_mask, byte setupParse); | 
 | 168 | static word AdvCodecSupport(DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, byte); | 
 | 169 | static void CodecIdCheck(DIVA_CAPI_ADAPTER   *, PLCI   *); | 
 | 170 | static void SetVoiceChannel(PLCI   *, byte   *, DIVA_CAPI_ADAPTER   * ); | 
 | 171 | static void VoiceChannelOff(PLCI   *plci); | 
 | 172 | static void adv_voice_write_coefs (PLCI   *plci, word write_command); | 
 | 173 | static void adv_voice_clear_config (PLCI   *plci); | 
 | 174 |  | 
 | 175 | static word get_b1_facilities (PLCI   * plci, byte b1_resource); | 
 | 176 | static byte add_b1_facilities (PLCI   * plci, byte b1_resource, word b1_facilities); | 
 | 177 | static void adjust_b1_facilities (PLCI   *plci, byte new_b1_resource, word new_b1_facilities); | 
 | 178 | static word adjust_b_process (dword Id, PLCI   *plci, byte Rc); | 
 | 179 | static void adjust_b1_resource (dword Id, PLCI   *plci, API_SAVE   *bp_msg, word b1_facilities, word internal_command); | 
 | 180 | static void adjust_b_restore (dword Id, PLCI   *plci, byte Rc); | 
 | 181 | static void reset_b3_command (dword Id, PLCI   *plci, byte Rc); | 
 | 182 | static void select_b_command (dword Id, PLCI   *plci, byte Rc); | 
 | 183 | static void fax_connect_ack_command (dword Id, PLCI   *plci, byte Rc); | 
 | 184 | static void fax_edata_ack_command (dword Id, PLCI   *plci, byte Rc); | 
 | 185 | static void fax_connect_info_command (dword Id, PLCI   *plci, byte Rc); | 
 | 186 | static void fax_adjust_b23_command (dword Id, PLCI   *plci, byte Rc); | 
 | 187 | static void fax_disconnect_command (dword Id, PLCI   *plci, byte Rc); | 
 | 188 | static void hold_save_command (dword Id, PLCI   *plci, byte Rc); | 
 | 189 | static void retrieve_restore_command (dword Id, PLCI   *plci, byte Rc); | 
 | 190 | static void init_b1_config (PLCI   *plci); | 
 | 191 | static void clear_b1_config (PLCI   *plci); | 
 | 192 |  | 
 | 193 | static void dtmf_command (dword Id, PLCI   *plci, byte Rc); | 
 | 194 | static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg); | 
 | 195 | static void dtmf_confirmation (dword Id, PLCI   *plci); | 
 | 196 | static void dtmf_indication (dword Id, PLCI   *plci, byte   *msg, word length); | 
 | 197 | static void dtmf_parameter_write (PLCI   *plci); | 
 | 198 |  | 
 | 199 |  | 
 | 200 | static void mixer_set_bchannel_id_esc (PLCI   *plci, byte bchannel_id); | 
 | 201 | static void mixer_set_bchannel_id (PLCI   *plci, byte   *chi); | 
 | 202 | static void mixer_clear_config (PLCI   *plci); | 
 | 203 | static void mixer_notify_update (PLCI   *plci, byte others); | 
 | 204 | static void mixer_command (dword Id, PLCI   *plci, byte Rc); | 
 | 205 | static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg); | 
 | 206 | static void mixer_indication_coefs_set (dword Id, PLCI   *plci); | 
 | 207 | static void mixer_indication_xconnect_from (dword Id, PLCI   *plci, byte   *msg, word length); | 
 | 208 | static void mixer_indication_xconnect_to (dword Id, PLCI   *plci, byte   *msg, word length); | 
 | 209 | static void mixer_remove (PLCI   *plci); | 
 | 210 |  | 
 | 211 |  | 
 | 212 | static void ec_command (dword Id, PLCI   *plci, byte Rc); | 
 | 213 | static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg); | 
 | 214 | static void ec_indication (dword Id, PLCI   *plci, byte   *msg, word length); | 
 | 215 |  | 
 | 216 |  | 
 | 217 | static void rtp_connect_b3_req_command (dword Id, PLCI   *plci, byte Rc); | 
 | 218 | static void rtp_connect_b3_res_command (dword Id, PLCI   *plci, byte Rc); | 
 | 219 |  | 
 | 220 |  | 
 | 221 | static int  diva_get_dma_descriptor  (PLCI   *plci, dword   *dma_magic); | 
 | 222 | static void diva_free_dma_descriptor (PLCI   *plci, int nr); | 
 | 223 |  | 
 | 224 | /*------------------------------------------------------------------*/ | 
 | 225 | /* external function prototypes                                     */ | 
 | 226 | /*------------------------------------------------------------------*/ | 
 | 227 |  | 
 | 228 | extern byte MapController (byte); | 
 | 229 | extern byte UnMapController (byte); | 
 | 230 | #define MapId(Id) (((Id) & 0xffffff00L) | MapController ((byte)(Id))) | 
 | 231 | #define UnMapId(Id) (((Id) & 0xffffff00L) | UnMapController ((byte)(Id))) | 
 | 232 |  | 
 | 233 | void   sendf(APPL   *, word, dword, word, byte *, ...); | 
 | 234 | void   * TransmitBufferSet(APPL   * appl, dword ref); | 
 | 235 | void   * TransmitBufferGet(APPL   * appl, void   * p); | 
 | 236 | void TransmitBufferFree(APPL   * appl, void   * p); | 
 | 237 | void   * ReceiveBufferGet(APPL   * appl, int Num); | 
 | 238 |  | 
 | 239 | int fax_head_line_time (char *buffer); | 
 | 240 |  | 
 | 241 |  | 
 | 242 | /*------------------------------------------------------------------*/ | 
 | 243 | /* Global data definitions                                          */ | 
 | 244 | /*------------------------------------------------------------------*/ | 
 | 245 | extern byte max_adapter; | 
 | 246 | extern byte max_appl; | 
 | 247 | extern DIVA_CAPI_ADAPTER   * adapter; | 
 | 248 | extern APPL   * application; | 
 | 249 |  | 
 | 250 |  | 
 | 251 |  | 
 | 252 |  | 
 | 253 |  | 
 | 254 |  | 
 | 255 |  | 
 | 256 | static byte remove_started = FALSE; | 
 | 257 | static PLCI dummy_plci; | 
 | 258 |  | 
 | 259 |  | 
 | 260 | static struct _ftable { | 
 | 261 |   word command; | 
 | 262 |   byte * format; | 
 | 263 |   byte (* function)(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *); | 
 | 264 | } ftable[] = { | 
 | 265 |   {_DATA_B3_R,                          "dwww",         data_b3_req}, | 
 | 266 |   {_DATA_B3_I|RESPONSE,                 "w",            data_b3_res}, | 
 | 267 |   {_INFO_R,                             "ss",           info_req}, | 
 | 268 |   {_INFO_I|RESPONSE,                    "",             info_res}, | 
 | 269 |   {_CONNECT_R,                          "wsssssssss",   connect_req}, | 
 | 270 |   {_CONNECT_I|RESPONSE,                 "wsssss",       connect_res}, | 
 | 271 |   {_CONNECT_ACTIVE_I|RESPONSE,          "",             connect_a_res}, | 
 | 272 |   {_DISCONNECT_R,                       "s",            disconnect_req}, | 
 | 273 |   {_DISCONNECT_I|RESPONSE,              "",             disconnect_res}, | 
 | 274 |   {_LISTEN_R,                           "dddss",        listen_req}, | 
 | 275 |   {_ALERT_R,                            "s",            alert_req}, | 
 | 276 |   {_FACILITY_R,                         "ws",           facility_req}, | 
 | 277 |   {_FACILITY_I|RESPONSE,                "ws",           facility_res}, | 
 | 278 |   {_CONNECT_B3_R,                       "s",            connect_b3_req}, | 
 | 279 |   {_CONNECT_B3_I|RESPONSE,              "ws",           connect_b3_res}, | 
 | 280 |   {_CONNECT_B3_ACTIVE_I|RESPONSE,       "",             connect_b3_a_res}, | 
 | 281 |   {_DISCONNECT_B3_R,                    "s",            disconnect_b3_req}, | 
 | 282 |   {_DISCONNECT_B3_I|RESPONSE,           "",             disconnect_b3_res}, | 
 | 283 |   {_RESET_B3_R,                         "s",            reset_b3_req}, | 
 | 284 |   {_RESET_B3_I|RESPONSE,                "",             reset_b3_res}, | 
 | 285 |   {_CONNECT_B3_T90_ACTIVE_I|RESPONSE,   "ws",           connect_b3_t90_a_res}, | 
 | 286 |   {_CONNECT_B3_T90_ACTIVE_I|RESPONSE,   "",             connect_b3_t90_a_res}, | 
 | 287 |   {_SELECT_B_REQ,                       "s",            select_b_req}, | 
 | 288 |   {_MANUFACTURER_R,                     "dws",          manufacturer_req}, | 
 | 289 |   {_MANUFACTURER_I|RESPONSE,            "dws",          manufacturer_res}, | 
 | 290 |   {_MANUFACTURER_I|RESPONSE,            "",             manufacturer_res} | 
 | 291 | }; | 
 | 292 |  | 
 | 293 | static byte * cip_bc[29][2] = { | 
 | 294 |   { "",                     ""                     }, /* 0 */ | 
 | 295 |   { "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 1 */ | 
 | 296 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 2 */ | 
 | 297 |   { "\x02\x89\x90",         "\x02\x89\x90"         }, /* 3 */ | 
 | 298 |   { "\x03\x90\x90\xa3",     "\x03\x90\x90\xa2"     }, /* 4 */ | 
 | 299 |   { "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 5 */ | 
 | 300 |   { "\x02\x98\x90",         "\x02\x98\x90"         }, /* 6 */ | 
 | 301 |   { "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */ | 
 | 302 |   { "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */ | 
 | 303 |   { "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 9 */ | 
 | 304 |   { "",                     ""                     }, /* 10 */ | 
 | 305 |   { "",                     ""                     }, /* 11 */ | 
 | 306 |   { "",                     ""                     }, /* 12 */ | 
 | 307 |   { "",                     ""                     }, /* 13 */ | 
 | 308 |   { "",                     ""                     }, /* 14 */ | 
 | 309 |   { "",                     ""                     }, /* 15 */ | 
 | 310 |  | 
 | 311 |   { "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 16 */ | 
 | 312 |   { "\x03\x90\x90\xa3",     "\x03\x90\x90\xa2"     }, /* 17 */ | 
 | 313 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 18 */ | 
 | 314 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 19 */ | 
 | 315 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 20 */ | 
 | 316 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 21 */ | 
 | 317 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 22 */ | 
 | 318 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 23 */ | 
 | 319 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 24 */ | 
 | 320 |   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 25 */ | 
 | 321 |   { "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 26 */ | 
 | 322 |   { "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 27 */ | 
 | 323 |   { "\x02\x88\x90",         "\x02\x88\x90"         }  /* 28 */ | 
 | 324 | }; | 
 | 325 |  | 
 | 326 | static byte * cip_hlc[29] = { | 
 | 327 |   "",                           /* 0 */ | 
 | 328 |   "",                           /* 1 */ | 
 | 329 |   "",                           /* 2 */ | 
 | 330 |   "",                           /* 3 */ | 
 | 331 |   "",                           /* 4 */ | 
 | 332 |   "",                           /* 5 */ | 
 | 333 |   "",                           /* 6 */ | 
 | 334 |   "",                           /* 7 */ | 
 | 335 |   "",                           /* 8 */ | 
 | 336 |   "",                           /* 9 */ | 
 | 337 |   "",                           /* 10 */ | 
 | 338 |   "",                           /* 11 */ | 
 | 339 |   "",                           /* 12 */ | 
 | 340 |   "",                           /* 13 */ | 
 | 341 |   "",                           /* 14 */ | 
 | 342 |   "",                           /* 15 */ | 
 | 343 |  | 
 | 344 |   "\x02\x91\x81",               /* 16 */ | 
 | 345 |   "\x02\x91\x84",               /* 17 */ | 
 | 346 |   "\x02\x91\xa1",               /* 18 */ | 
 | 347 |   "\x02\x91\xa4",               /* 19 */ | 
 | 348 |   "\x02\x91\xa8",               /* 20 */ | 
 | 349 |   "\x02\x91\xb1",               /* 21 */ | 
 | 350 |   "\x02\x91\xb2",               /* 22 */ | 
 | 351 |   "\x02\x91\xb5",               /* 23 */ | 
 | 352 |   "\x02\x91\xb8",               /* 24 */ | 
 | 353 |   "\x02\x91\xc1",               /* 25 */ | 
 | 354 |   "\x02\x91\x81",               /* 26 */ | 
 | 355 |   "\x03\x91\xe0\x01",           /* 27 */ | 
 | 356 |   "\x03\x91\xe0\x02"            /* 28 */ | 
 | 357 | }; | 
 | 358 |  | 
 | 359 | /*------------------------------------------------------------------*/ | 
 | 360 |  | 
 | 361 | #define V120_HEADER_LENGTH 1 | 
 | 362 | #define V120_HEADER_EXTEND_BIT  0x80 | 
 | 363 | #define V120_HEADER_BREAK_BIT   0x40 | 
 | 364 | #define V120_HEADER_C1_BIT      0x04 | 
 | 365 | #define V120_HEADER_C2_BIT      0x08 | 
 | 366 | #define V120_HEADER_FLUSH_COND  (V120_HEADER_BREAK_BIT | V120_HEADER_C1_BIT | V120_HEADER_C2_BIT) | 
 | 367 |  | 
 | 368 | static byte v120_default_header[] = | 
 | 369 | { | 
 | 370 |  | 
 | 371 |   0x83                          /*  Ext, BR , res, res, C2 , C1 , B  , F   */ | 
 | 372 |  | 
 | 373 | }; | 
 | 374 |  | 
 | 375 | static byte v120_break_header[] = | 
 | 376 | { | 
 | 377 |  | 
 | 378 |   0xc3 | V120_HEADER_BREAK_BIT  /*  Ext, BR , res, res, C2 , C1 , B  , F   */ | 
 | 379 |  | 
 | 380 | }; | 
 | 381 |  | 
 | 382 |  | 
 | 383 | /*------------------------------------------------------------------*/ | 
 | 384 | /* API_PUT function                                                 */ | 
 | 385 | /*------------------------------------------------------------------*/ | 
 | 386 |  | 
 | 387 | word api_put(APPL   * appl, CAPI_MSG   * msg) | 
 | 388 | { | 
 | 389 |   word i, j, k, l, n; | 
 | 390 |   word ret; | 
 | 391 |   byte c; | 
 | 392 |   byte controller; | 
 | 393 |   DIVA_CAPI_ADAPTER   * a; | 
 | 394 |   PLCI   * plci; | 
 | 395 |   NCCI   * ncci_ptr; | 
 | 396 |   word ncci; | 
 | 397 |   CAPI_MSG   *m; | 
 | 398 |     API_PARSE msg_parms[MAX_MSG_PARMS+1]; | 
 | 399 |  | 
 | 400 |   if (msg->header.length < sizeof (msg->header) || | 
 | 401 |       msg->header.length > MAX_MSG_SIZE) { | 
 | 402 |     dbug(1,dprintf("bad len")); | 
 | 403 |     return _BAD_MSG; | 
 | 404 |   } | 
 | 405 |  | 
 | 406 |   controller = (byte)((msg->header.controller &0x7f)-1); | 
 | 407 |  | 
 | 408 |   /* controller starts with 0 up to (max_adapter - 1) */ | 
 | 409 |   if ( controller >= max_adapter ) | 
 | 410 |   { | 
 | 411 |     dbug(1,dprintf("invalid ctrl")); | 
 | 412 |     return _BAD_MSG; | 
 | 413 |   } | 
 | 414 |    | 
 | 415 |   a = &adapter[controller]; | 
 | 416 |   plci = NULL; | 
 | 417 |   if ((msg->header.plci != 0) && (msg->header.plci <= a->max_plci) && !a->adapter_disabled) | 
 | 418 |   { | 
 | 419 |     dbug(1,dprintf("plci=%x",msg->header.plci)); | 
 | 420 |     plci = &a->plci[msg->header.plci-1]; | 
 | 421 |     ncci = GET_WORD(&msg->header.ncci); | 
 | 422 |     if (plci->Id | 
 | 423 |      && (plci->appl | 
 | 424 |       || (plci->State == INC_CON_PENDING) | 
 | 425 |       || (plci->State == INC_CON_ALERT) | 
 | 426 |       || (msg->header.command == (_DISCONNECT_I|RESPONSE))) | 
 | 427 |      && ((ncci == 0) | 
 | 428 |       || (msg->header.command == (_DISCONNECT_B3_I|RESPONSE)) | 
 | 429 |       || ((ncci < MAX_NCCI+1) && (a->ncci_plci[ncci] == plci->Id)))) | 
 | 430 |     { | 
 | 431 |       i = plci->msg_in_read_pos; | 
 | 432 |       j = plci->msg_in_write_pos; | 
 | 433 |       if (j >= i) | 
 | 434 |       { | 
 | 435 |         if (j + msg->header.length + MSG_IN_OVERHEAD <= MSG_IN_QUEUE_SIZE) | 
 | 436 |           i += MSG_IN_QUEUE_SIZE - j; | 
 | 437 |         else | 
 | 438 |           j = 0; | 
 | 439 |       } | 
 | 440 |       else | 
 | 441 |       { | 
 | 442 |  | 
 | 443 |         n = (((CAPI_MSG   *)(plci->msg_in_queue))->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc; | 
 | 444 |  | 
 | 445 |         if (i > MSG_IN_QUEUE_SIZE - n) | 
 | 446 |           i = MSG_IN_QUEUE_SIZE - n + 1; | 
 | 447 |         i -= j; | 
 | 448 |       } | 
 | 449 |  | 
 | 450 |       if (i <= ((msg->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc)) | 
 | 451 |  | 
 | 452 |       { | 
 | 453 |         dbug(0,dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d", | 
 | 454 |           msg->header.length, plci->msg_in_write_pos, | 
 | 455 |           plci->msg_in_read_pos, plci->msg_in_wrap_pos, i)); | 
 | 456 |  | 
 | 457 |         return _QUEUE_FULL; | 
 | 458 |       } | 
 | 459 |       c = FALSE; | 
 | 460 |       if ((((byte   *) msg) < ((byte   *)(plci->msg_in_queue))) | 
 | 461 |        || (((byte   *) msg) >= ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) | 
 | 462 |       { | 
 | 463 |         if (plci->msg_in_write_pos != plci->msg_in_read_pos) | 
 | 464 |           c = TRUE; | 
 | 465 |       } | 
 | 466 |       if (msg->header.command == _DATA_B3_R) | 
 | 467 |       { | 
 | 468 |         if (msg->header.length < 20) | 
 | 469 |         { | 
 | 470 |           dbug(1,dprintf("DATA_B3 REQ wrong length %d", msg->header.length)); | 
 | 471 |           return _BAD_MSG; | 
 | 472 |         } | 
 | 473 |         ncci_ptr = &(a->ncci[ncci]); | 
 | 474 |         n = ncci_ptr->data_pending; | 
 | 475 |         l = ncci_ptr->data_ack_pending; | 
 | 476 |         k = plci->msg_in_read_pos; | 
 | 477 |         while (k != plci->msg_in_write_pos) | 
 | 478 |         { | 
 | 479 |           if (k == plci->msg_in_wrap_pos) | 
 | 480 |             k = 0; | 
 | 481 |           if ((((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[k]))->header.command == _DATA_B3_R) | 
 | 482 |            && (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[k]))->header.ncci == ncci)) | 
 | 483 |           { | 
 | 484 |             n++; | 
 | 485 |             if (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[k]))->info.data_b3_req.Flags & 0x0004) | 
 | 486 |               l++; | 
 | 487 |           } | 
 | 488 |  | 
 | 489 |           k += (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[k]))->header.length + | 
 | 490 |             MSG_IN_OVERHEAD + 3) & 0xfffc; | 
 | 491 |  | 
 | 492 |         } | 
 | 493 |         if ((n >= MAX_DATA_B3) || (l >= MAX_DATA_ACK)) | 
 | 494 |         { | 
 | 495 |           dbug(0,dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d", | 
 | 496 |                           ncci_ptr->data_pending, n, ncci_ptr->data_ack_pending, l)); | 
 | 497 |  | 
 | 498 |           return _QUEUE_FULL; | 
 | 499 |         } | 
 | 500 |         if (plci->req_in || plci->internal_command) | 
 | 501 |         { | 
 | 502 |           if ((((byte   *) msg) >= ((byte   *)(plci->msg_in_queue))) | 
 | 503 |            && (((byte   *) msg) < ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) | 
 | 504 |           { | 
 | 505 |             dbug(0,dprintf("Q-FULL3(requeue)")); | 
 | 506 |  | 
 | 507 |             return _QUEUE_FULL; | 
 | 508 |           } | 
 | 509 |           c = TRUE; | 
 | 510 |         } | 
 | 511 |       } | 
 | 512 |       else | 
 | 513 |       { | 
 | 514 |         if (plci->req_in || plci->internal_command) | 
 | 515 |           c = TRUE; | 
 | 516 |         else | 
 | 517 |         { | 
 | 518 |           plci->command = msg->header.command; | 
 | 519 |           plci->number = msg->header.number; | 
 | 520 |         } | 
 | 521 |       } | 
 | 522 |       if (c) | 
 | 523 |       { | 
 | 524 |         dbug(1,dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d", | 
 | 525 |           msg->header.command, plci->req_in, plci->internal_command, | 
 | 526 |           msg->header.length, plci->msg_in_write_pos, | 
 | 527 |           plci->msg_in_read_pos, plci->msg_in_wrap_pos, i)); | 
 | 528 |         if (j == 0) | 
 | 529 |           plci->msg_in_wrap_pos = plci->msg_in_write_pos; | 
 | 530 |         m = (CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[j]); | 
 | 531 |         for (i = 0; i < msg->header.length; i++) | 
 | 532 |           ((byte   *)(plci->msg_in_queue))[j++] = ((byte   *) msg)[i]; | 
 | 533 |         if (m->header.command == _DATA_B3_R) | 
 | 534 |         { | 
 | 535 |  | 
 | 536 |           m->info.data_b3_req.Data = (dword)(TransmitBufferSet (appl, m->info.data_b3_req.Data)); | 
 | 537 |  | 
 | 538 |         } | 
 | 539 |  | 
 | 540 |         j = (j + 3) & 0xfffc; | 
 | 541 |  | 
 | 542 |         *((APPL   *   *)(&((byte   *)(plci->msg_in_queue))[j])) = appl; | 
 | 543 |         plci->msg_in_write_pos = j + MSG_IN_OVERHEAD; | 
 | 544 |         return 0; | 
 | 545 |       } | 
 | 546 |     } | 
 | 547 |     else | 
 | 548 |     { | 
 | 549 |       plci = NULL; | 
 | 550 |     } | 
 | 551 |   } | 
 | 552 |   dbug(1,dprintf("com=%x",msg->header.command)); | 
 | 553 |  | 
 | 554 |   for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0; | 
 | 555 |   for(i=0, ret = _BAD_MSG; | 
 | 556 |       i<(sizeof(ftable)/sizeof(struct _ftable)); | 
 | 557 |       i++) { | 
 | 558 |  | 
 | 559 |     if(ftable[i].command==msg->header.command) { | 
 | 560 |       /* break loop if the message is correct, otherwise continue scan  */ | 
 | 561 |       /* (for example: CONNECT_B3_T90_ACT_RES has two specifications)   */ | 
 | 562 |       if(!api_parse(msg->info.b,(word)(msg->header.length-12),ftable[i].format,msg_parms)) { | 
 | 563 |         ret = 0; | 
 | 564 |         break; | 
 | 565 |       } | 
 | 566 |       for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0; | 
 | 567 |     } | 
 | 568 |   } | 
 | 569 |   if(ret) { | 
 | 570 |     dbug(1,dprintf("BAD_MSG")); | 
 | 571 |     if(plci) plci->command = 0; | 
 | 572 |     return ret; | 
 | 573 |   } | 
 | 574 |  | 
 | 575 |  | 
 | 576 |   c = ftable[i].function(GET_DWORD(&msg->header.controller), | 
 | 577 |                          msg->header.number, | 
 | 578 |                          a, | 
 | 579 |                          plci, | 
 | 580 |                          appl, | 
 | 581 |                          msg_parms); | 
 | 582 |  | 
 | 583 |   channel_xmit_extended_xon (plci); | 
 | 584 |  | 
 | 585 |   if(c==1) send_req(plci); | 
 | 586 |   if(c==2 && plci) plci->req_in = plci->req_in_start = plci->req_out = 0; | 
 | 587 |   if(plci && !plci->req_in) plci->command = 0; | 
 | 588 |   return 0; | 
 | 589 | } | 
 | 590 |  | 
 | 591 |  | 
 | 592 | /*------------------------------------------------------------------*/ | 
 | 593 | /* api_parse function, check the format of api messages             */ | 
 | 594 | /*------------------------------------------------------------------*/ | 
 | 595 |  | 
 | 596 | word api_parse(byte   * msg, word length, byte * format, API_PARSE * parms) | 
 | 597 | { | 
 | 598 |   word i; | 
 | 599 |   word p; | 
 | 600 |  | 
 | 601 |   for(i=0,p=0; format[i]; i++) { | 
 | 602 |     if(parms) | 
 | 603 |     { | 
 | 604 |       parms[i].info = &msg[p]; | 
 | 605 |     } | 
 | 606 |     switch(format[i]) { | 
 | 607 |     case 'b': | 
 | 608 |       p +=1; | 
 | 609 |       break; | 
 | 610 |     case 'w': | 
 | 611 |       p +=2; | 
 | 612 |       break; | 
 | 613 |     case 'd': | 
 | 614 |       p +=4; | 
 | 615 |       break; | 
 | 616 |     case 's': | 
 | 617 |       if(msg[p]==0xff) { | 
 | 618 |         parms[i].info +=2; | 
 | 619 |         parms[i].length = msg[p+1] + (msg[p+2]<<8); | 
 | 620 |         p +=(parms[i].length +3); | 
 | 621 |       } | 
 | 622 |       else { | 
 | 623 |         parms[i].length = msg[p]; | 
 | 624 |         p +=(parms[i].length +1); | 
 | 625 |       } | 
 | 626 |       break; | 
 | 627 |     } | 
 | 628 |  | 
 | 629 |     if(p>length) return TRUE; | 
 | 630 |   } | 
 | 631 |   if(parms) parms[i].info = NULL; | 
 | 632 |   return FALSE; | 
 | 633 | } | 
 | 634 |  | 
 | 635 | void api_save_msg(API_PARSE   *in, byte *format, API_SAVE   *out) | 
 | 636 | { | 
 | 637 |   word i, j, n = 0; | 
 | 638 |   byte   *p; | 
 | 639 |  | 
 | 640 |   p = out->info; | 
 | 641 |   for (i = 0; format[i] != '\0'; i++) | 
 | 642 |   { | 
 | 643 |     out->parms[i].info = p; | 
 | 644 |     out->parms[i].length = in[i].length; | 
 | 645 |     switch (format[i]) | 
 | 646 |     { | 
 | 647 |     case 'b': | 
 | 648 |       n = 1; | 
 | 649 |       break; | 
 | 650 |     case 'w': | 
 | 651 |       n = 2; | 
 | 652 |       break; | 
 | 653 |     case 'd': | 
 | 654 |       n = 4; | 
 | 655 |       break; | 
 | 656 |     case 's': | 
 | 657 |       n = in[i].length + 1; | 
 | 658 |       break; | 
 | 659 |     } | 
 | 660 |     for (j = 0; j < n; j++) | 
 | 661 |       *(p++) = in[i].info[j]; | 
 | 662 |   } | 
 | 663 |   out->parms[i].info = NULL; | 
 | 664 |   out->parms[i].length = 0; | 
 | 665 | } | 
 | 666 |  | 
 | 667 | void api_load_msg(API_SAVE   *in, API_PARSE   *out) | 
 | 668 | { | 
 | 669 |   word i; | 
 | 670 |  | 
 | 671 |   i = 0; | 
 | 672 |   do | 
 | 673 |   { | 
 | 674 |     out[i].info = in->parms[i].info; | 
 | 675 |     out[i].length = in->parms[i].length; | 
 | 676 |   } while (in->parms[i++].info); | 
 | 677 | } | 
 | 678 |  | 
 | 679 |  | 
 | 680 | /*------------------------------------------------------------------*/ | 
 | 681 | /* CAPI remove function                                             */ | 
 | 682 | /*------------------------------------------------------------------*/ | 
 | 683 |  | 
 | 684 | word api_remove_start(void) | 
 | 685 | { | 
 | 686 |   word i; | 
 | 687 |   word j; | 
 | 688 |  | 
 | 689 |   if(!remove_started) { | 
 | 690 |     remove_started = TRUE; | 
 | 691 |     for(i=0;i<max_adapter;i++) { | 
 | 692 |       if(adapter[i].request) { | 
 | 693 |         for(j=0;j<adapter[i].max_plci;j++) { | 
 | 694 |           if(adapter[i].plci[j].Sig.Id) plci_remove(&adapter[i].plci[j]); | 
 | 695 |         } | 
 | 696 |       } | 
 | 697 |     } | 
 | 698 |     return 1; | 
 | 699 |   } | 
 | 700 |   else { | 
 | 701 |     for(i=0;i<max_adapter;i++) { | 
 | 702 |       if(adapter[i].request) { | 
 | 703 |         for(j=0;j<adapter[i].max_plci;j++) { | 
 | 704 |           if(adapter[i].plci[j].Sig.Id) return 1; | 
 | 705 |         } | 
 | 706 |       } | 
 | 707 |     } | 
 | 708 |   } | 
 | 709 |   api_remove_complete(); | 
 | 710 |   return 0; | 
 | 711 | } | 
 | 712 |  | 
 | 713 |  | 
 | 714 | /*------------------------------------------------------------------*/ | 
 | 715 | /* internal command queue                                           */ | 
 | 716 | /*------------------------------------------------------------------*/ | 
 | 717 |  | 
 | 718 | static void init_internal_command_queue (PLCI   *plci) | 
 | 719 | { | 
 | 720 |   word i; | 
 | 721 |  | 
 | 722 |   dbug (1, dprintf ("%s,%d: init_internal_command_queue", | 
 | 723 |     (char   *)(FILE_), __LINE__)); | 
 | 724 |  | 
 | 725 |   plci->internal_command = 0; | 
 | 726 |   for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS; i++) | 
 | 727 |     plci->internal_command_queue[i] = NULL; | 
 | 728 | } | 
 | 729 |  | 
 | 730 |  | 
 | 731 | static void start_internal_command (dword Id, PLCI   *plci, t_std_internal_command command_function) | 
 | 732 | { | 
 | 733 |   word i; | 
 | 734 |  | 
 | 735 |   dbug (1, dprintf ("[%06lx] %s,%d: start_internal_command", | 
 | 736 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 737 |  | 
 | 738 |   if (plci->internal_command == 0) | 
 | 739 |   { | 
 | 740 |     plci->internal_command_queue[0] = command_function; | 
 | 741 |     (* command_function)(Id, plci, OK); | 
 | 742 |   } | 
 | 743 |   else | 
 | 744 |   { | 
 | 745 |     i = 1; | 
 | 746 |     while (plci->internal_command_queue[i] != 0) | 
 | 747 |       i++; | 
 | 748 |     plci->internal_command_queue[i] = command_function; | 
 | 749 |   } | 
 | 750 | } | 
 | 751 |  | 
 | 752 |  | 
 | 753 | static void next_internal_command (dword Id, PLCI   *plci) | 
 | 754 | { | 
 | 755 |   word i; | 
 | 756 |  | 
 | 757 |   dbug (1, dprintf ("[%06lx] %s,%d: next_internal_command", | 
 | 758 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 759 |  | 
 | 760 |   plci->internal_command = 0; | 
 | 761 |   plci->internal_command_queue[0] = NULL; | 
 | 762 |   while (plci->internal_command_queue[1] != 0) | 
 | 763 |   { | 
 | 764 |     for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS - 1; i++) | 
 | 765 |       plci->internal_command_queue[i] = plci->internal_command_queue[i+1]; | 
 | 766 |     plci->internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS - 1] = NULL; | 
 | 767 |     (*(plci->internal_command_queue[0]))(Id, plci, OK); | 
 | 768 |     if (plci->internal_command != 0) | 
 | 769 |       return; | 
 | 770 |     plci->internal_command_queue[0] = NULL; | 
 | 771 |   } | 
 | 772 | } | 
 | 773 |  | 
 | 774 |  | 
 | 775 | /*------------------------------------------------------------------*/ | 
 | 776 | /* NCCI allocate/remove function                                    */ | 
 | 777 | /*------------------------------------------------------------------*/ | 
 | 778 |  | 
 | 779 | static dword ncci_mapping_bug = 0; | 
 | 780 |  | 
 | 781 | static word get_ncci (PLCI   *plci, byte ch, word force_ncci) | 
 | 782 | { | 
 | 783 |   DIVA_CAPI_ADAPTER   *a; | 
 | 784 |   word ncci, i, j, k; | 
 | 785 |  | 
 | 786 |   a = plci->adapter; | 
 | 787 |   if (!ch || a->ch_ncci[ch]) | 
 | 788 |   { | 
 | 789 |     ncci_mapping_bug++; | 
 | 790 |     dbug(1,dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x", | 
 | 791 |       ncci_mapping_bug, ch, force_ncci, a->ncci_ch[a->ch_ncci[ch]], a->ch_ncci[ch])); | 
 | 792 |     ncci = ch; | 
 | 793 |   } | 
 | 794 |   else | 
 | 795 |   { | 
 | 796 |     if (force_ncci) | 
 | 797 |       ncci = force_ncci; | 
 | 798 |     else | 
 | 799 |     { | 
 | 800 |       if ((ch < MAX_NCCI+1) && !a->ncci_ch[ch]) | 
 | 801 |         ncci = ch; | 
 | 802 |       else | 
 | 803 |       { | 
 | 804 |         ncci = 1; | 
 | 805 |         while ((ncci < MAX_NCCI+1) && a->ncci_ch[ncci]) | 
 | 806 |           ncci++; | 
 | 807 |         if (ncci == MAX_NCCI+1) | 
 | 808 |         { | 
 | 809 |           ncci_mapping_bug++; | 
 | 810 |           i = 1; | 
 | 811 |           do | 
 | 812 |           { | 
 | 813 |             j = 1; | 
 | 814 |             while ((j < MAX_NCCI+1) && (a->ncci_ch[j] != i)) | 
 | 815 |               j++; | 
 | 816 |             k = j; | 
 | 817 |             if (j < MAX_NCCI+1) | 
 | 818 |             { | 
 | 819 |               do | 
 | 820 |               { | 
 | 821 |                 j++; | 
 | 822 |               } while ((j < MAX_NCCI+1) && (a->ncci_ch[j] != i)); | 
 | 823 |             } | 
 | 824 |           } while ((i < MAX_NL_CHANNEL+1) && (j < MAX_NCCI+1)); | 
 | 825 |           if (i < MAX_NL_CHANNEL+1) | 
 | 826 |           { | 
 | 827 |             dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x", | 
 | 828 |               ncci_mapping_bug, ch, force_ncci, i, k, j)); | 
 | 829 |           } | 
 | 830 |           else | 
 | 831 |           { | 
 | 832 |             dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x", | 
 | 833 |               ncci_mapping_bug, ch, force_ncci)); | 
 | 834 |           } | 
 | 835 |           ncci = ch; | 
 | 836 |         } | 
 | 837 |       } | 
 | 838 |       a->ncci_plci[ncci] = plci->Id; | 
 | 839 |       a->ncci_state[ncci] = IDLE; | 
 | 840 |       if (!plci->ncci_ring_list) | 
 | 841 |         plci->ncci_ring_list = ncci; | 
 | 842 |       else | 
 | 843 |         a->ncci_next[ncci] = a->ncci_next[plci->ncci_ring_list]; | 
 | 844 |       a->ncci_next[plci->ncci_ring_list] = (byte) ncci; | 
 | 845 |     } | 
 | 846 |     a->ncci_ch[ncci] = ch; | 
 | 847 |     a->ch_ncci[ch] = (byte) ncci; | 
 | 848 |     dbug(1,dprintf("NCCI mapping established %ld %02x %02x %02x-%02x", | 
 | 849 |       ncci_mapping_bug, ch, force_ncci, ch, ncci)); | 
 | 850 |   } | 
 | 851 |   return (ncci); | 
 | 852 | } | 
 | 853 |  | 
 | 854 |  | 
 | 855 | static void ncci_free_receive_buffers (PLCI   *plci, word ncci) | 
 | 856 | { | 
 | 857 |   DIVA_CAPI_ADAPTER   *a; | 
 | 858 |   APPL   *appl; | 
 | 859 |   word i, ncci_code; | 
 | 860 |   dword Id; | 
 | 861 |  | 
 | 862 |   a = plci->adapter; | 
 | 863 |   Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id; | 
 | 864 |   if (ncci) | 
 | 865 |   { | 
 | 866 |     if (a->ncci_plci[ncci] == plci->Id) | 
 | 867 |     { | 
 | 868 |       if (!plci->appl) | 
 | 869 |       { | 
 | 870 |         ncci_mapping_bug++; | 
 | 871 |         dbug(1,dprintf("NCCI mapping appl expected %ld %08lx", | 
 | 872 |           ncci_mapping_bug, Id)); | 
 | 873 |       } | 
 | 874 |       else | 
 | 875 |       { | 
 | 876 |         appl = plci->appl; | 
 | 877 |         ncci_code = ncci | (((word) a->Id) << 8); | 
 | 878 |         for (i = 0; i < appl->MaxBuffer; i++) | 
 | 879 |         { | 
 | 880 |           if ((appl->DataNCCI[i] == ncci_code) | 
 | 881 |            && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id)) | 
 | 882 |           { | 
 | 883 |             appl->DataNCCI[i] = 0; | 
 | 884 |           } | 
 | 885 |         } | 
 | 886 |       } | 
 | 887 |     } | 
 | 888 |   } | 
 | 889 |   else | 
 | 890 |   { | 
 | 891 |     for (ncci = 1; ncci < MAX_NCCI+1; ncci++) | 
 | 892 |     { | 
 | 893 |       if (a->ncci_plci[ncci] == plci->Id) | 
 | 894 |       { | 
 | 895 |         if (!plci->appl) | 
 | 896 |         { | 
 | 897 |           ncci_mapping_bug++; | 
 | 898 |           dbug(1,dprintf("NCCI mapping no appl %ld %08lx", | 
 | 899 |             ncci_mapping_bug, Id)); | 
 | 900 |         } | 
 | 901 |         else | 
 | 902 |         { | 
 | 903 |           appl = plci->appl; | 
 | 904 |           ncci_code = ncci | (((word) a->Id) << 8); | 
 | 905 |           for (i = 0; i < appl->MaxBuffer; i++) | 
 | 906 |           { | 
 | 907 |             if ((appl->DataNCCI[i] == ncci_code) | 
 | 908 |              && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id)) | 
 | 909 |             { | 
 | 910 |               appl->DataNCCI[i] = 0; | 
 | 911 |             } | 
 | 912 |           } | 
 | 913 |         } | 
 | 914 |       } | 
 | 915 |     } | 
 | 916 |   } | 
 | 917 | } | 
 | 918 |  | 
 | 919 |  | 
 | 920 | static void cleanup_ncci_data (PLCI   *plci, word ncci) | 
 | 921 | { | 
 | 922 |   NCCI   *ncci_ptr; | 
 | 923 |  | 
 | 924 |   if (ncci && (plci->adapter->ncci_plci[ncci] == plci->Id)) | 
 | 925 |   { | 
 | 926 |     ncci_ptr = &(plci->adapter->ncci[ncci]); | 
 | 927 |     if (plci->appl) | 
 | 928 |     { | 
 | 929 |       while (ncci_ptr->data_pending != 0) | 
 | 930 |       { | 
 | 931 |         if (!plci->data_sent || (ncci_ptr->DBuffer[ncci_ptr->data_out].P != plci->data_sent_ptr)) | 
 | 932 |           TransmitBufferFree (plci->appl, ncci_ptr->DBuffer[ncci_ptr->data_out].P); | 
 | 933 |         (ncci_ptr->data_out)++; | 
 | 934 |         if (ncci_ptr->data_out == MAX_DATA_B3) | 
 | 935 |           ncci_ptr->data_out = 0; | 
 | 936 |         (ncci_ptr->data_pending)--; | 
 | 937 |       } | 
 | 938 |     } | 
 | 939 |     ncci_ptr->data_out = 0; | 
 | 940 |     ncci_ptr->data_pending = 0; | 
 | 941 |     ncci_ptr->data_ack_out = 0; | 
 | 942 |     ncci_ptr->data_ack_pending = 0; | 
 | 943 |   } | 
 | 944 | } | 
 | 945 |  | 
 | 946 |  | 
 | 947 | static void ncci_remove (PLCI   *plci, word ncci, byte preserve_ncci) | 
 | 948 | { | 
 | 949 |   DIVA_CAPI_ADAPTER   *a; | 
 | 950 |   dword Id; | 
 | 951 |   word i; | 
 | 952 |  | 
 | 953 |   a = plci->adapter; | 
 | 954 |   Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id; | 
 | 955 |   if (!preserve_ncci) | 
 | 956 |     ncci_free_receive_buffers (plci, ncci); | 
 | 957 |   if (ncci) | 
 | 958 |   { | 
 | 959 |     if (a->ncci_plci[ncci] != plci->Id) | 
 | 960 |     { | 
 | 961 |       ncci_mapping_bug++; | 
 | 962 |       dbug(1,dprintf("NCCI mapping doesn't exist %ld %08lx %02x", | 
 | 963 |         ncci_mapping_bug, Id, preserve_ncci)); | 
 | 964 |     } | 
 | 965 |     else | 
 | 966 |     { | 
 | 967 |       cleanup_ncci_data (plci, ncci); | 
 | 968 |       dbug(1,dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x", | 
 | 969 |         ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci)); | 
 | 970 |       a->ch_ncci[a->ncci_ch[ncci]] = 0; | 
 | 971 |       if (!preserve_ncci) | 
 | 972 |       { | 
 | 973 |         a->ncci_ch[ncci] = 0; | 
 | 974 |         a->ncci_plci[ncci] = 0; | 
 | 975 |         a->ncci_state[ncci] = IDLE; | 
 | 976 |         i = plci->ncci_ring_list; | 
 | 977 |         while ((i != 0) && (a->ncci_next[i] != plci->ncci_ring_list) && (a->ncci_next[i] != ncci)) | 
 | 978 |           i = a->ncci_next[i]; | 
 | 979 |         if ((i != 0) && (a->ncci_next[i] == ncci)) | 
 | 980 |         { | 
 | 981 |           if (i == ncci) | 
 | 982 |             plci->ncci_ring_list = 0; | 
 | 983 |           else if (plci->ncci_ring_list == ncci) | 
 | 984 |             plci->ncci_ring_list = i; | 
 | 985 |           a->ncci_next[i] = a->ncci_next[ncci]; | 
 | 986 |         } | 
 | 987 |         a->ncci_next[ncci] = 0; | 
 | 988 |       } | 
 | 989 |     } | 
 | 990 |   } | 
 | 991 |   else | 
 | 992 |   { | 
 | 993 |     for (ncci = 1; ncci < MAX_NCCI+1; ncci++) | 
 | 994 |     { | 
 | 995 |       if (a->ncci_plci[ncci] == plci->Id) | 
 | 996 |       { | 
 | 997 |         cleanup_ncci_data (plci, ncci); | 
 | 998 |         dbug(1,dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x", | 
 | 999 |           ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci)); | 
 | 1000 |         a->ch_ncci[a->ncci_ch[ncci]] = 0; | 
 | 1001 |         if (!preserve_ncci) | 
 | 1002 |         { | 
 | 1003 |           a->ncci_ch[ncci] = 0; | 
 | 1004 |           a->ncci_plci[ncci] = 0; | 
 | 1005 |           a->ncci_state[ncci] = IDLE; | 
 | 1006 |           a->ncci_next[ncci] = 0; | 
 | 1007 |         } | 
 | 1008 |       } | 
 | 1009 |     } | 
 | 1010 |     if (!preserve_ncci) | 
 | 1011 |       plci->ncci_ring_list = 0; | 
 | 1012 |   } | 
 | 1013 | } | 
 | 1014 |  | 
 | 1015 |  | 
 | 1016 | /*------------------------------------------------------------------*/ | 
 | 1017 | /* PLCI remove function                                             */ | 
 | 1018 | /*------------------------------------------------------------------*/ | 
 | 1019 |  | 
 | 1020 | static void plci_free_msg_in_queue (PLCI   *plci) | 
 | 1021 | { | 
 | 1022 |   word i; | 
 | 1023 |  | 
 | 1024 |   if (plci->appl) | 
 | 1025 |   { | 
 | 1026 |     i = plci->msg_in_read_pos; | 
 | 1027 |     while (i != plci->msg_in_write_pos) | 
 | 1028 |     { | 
 | 1029 |       if (i == plci->msg_in_wrap_pos) | 
 | 1030 |         i = 0; | 
 | 1031 |       if (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[i]))->header.command == _DATA_B3_R) | 
 | 1032 |       { | 
 | 1033 |  | 
 | 1034 |         TransmitBufferFree (plci->appl, | 
 | 1035 |           (byte   *)(((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data)); | 
 | 1036 |  | 
 | 1037 |       } | 
 | 1038 |  | 
 | 1039 |       i += (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[i]))->header.length + | 
 | 1040 |         MSG_IN_OVERHEAD + 3) & 0xfffc; | 
 | 1041 |  | 
 | 1042 |     } | 
 | 1043 |   } | 
 | 1044 |   plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; | 
 | 1045 |   plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; | 
 | 1046 |   plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; | 
 | 1047 | } | 
 | 1048 |  | 
 | 1049 |  | 
 | 1050 | static void plci_remove(PLCI   * plci) | 
 | 1051 | { | 
 | 1052 |  | 
 | 1053 |   if(!plci) { | 
 | 1054 |     dbug(1,dprintf("plci_remove(no plci)")); | 
 | 1055 |     return; | 
 | 1056 |   } | 
 | 1057 |   init_internal_command_queue (plci); | 
 | 1058 |   dbug(1,dprintf("plci_remove(%x,tel=%x)",plci->Id,plci->tel)); | 
 | 1059 |   if(plci_remove_check(plci)) | 
 | 1060 |   { | 
 | 1061 |     return; | 
 | 1062 |   } | 
 | 1063 |   if (plci->Sig.Id == 0xff) | 
 | 1064 |   { | 
 | 1065 |     dbug(1,dprintf("D-channel X.25 plci->NL.Id:%0x", plci->NL.Id)); | 
 | 1066 |     if (plci->NL.Id && !plci->nl_remove_id) | 
 | 1067 |     { | 
 | 1068 |       nl_req_ncci(plci,REMOVE,0); | 
 | 1069 |       send_req(plci); | 
 | 1070 |     } | 
 | 1071 |   } | 
 | 1072 |   else | 
 | 1073 |   { | 
 | 1074 |     if (!plci->sig_remove_id | 
 | 1075 |      && (plci->Sig.Id | 
 | 1076 |       || (plci->req_in!=plci->req_out) | 
 | 1077 |       || (plci->nl_req || plci->sig_req))) | 
 | 1078 |     { | 
 | 1079 |       sig_req(plci,HANGUP,0); | 
 | 1080 |       send_req(plci); | 
 | 1081 |     } | 
 | 1082 |   } | 
 | 1083 |   ncci_remove (plci, 0, FALSE); | 
 | 1084 |   plci_free_msg_in_queue (plci); | 
 | 1085 |  | 
 | 1086 |   plci->channels = 0; | 
 | 1087 |   plci->appl = NULL; | 
 | 1088 |   if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT)) | 
 | 1089 |     plci->State = OUTG_DIS_PENDING; | 
 | 1090 | } | 
 | 1091 |  | 
 | 1092 | /*------------------------------------------------------------------*/ | 
 | 1093 | /* Application Group function helpers                               */ | 
 | 1094 | /*------------------------------------------------------------------*/ | 
 | 1095 |  | 
 | 1096 | static void set_group_ind_mask (PLCI   *plci) | 
 | 1097 | { | 
 | 1098 |   word i; | 
 | 1099 |  | 
 | 1100 |   for (i = 0; i < C_IND_MASK_DWORDS; i++) | 
 | 1101 |     plci->group_optimization_mask_table[i] = 0xffffffffL; | 
 | 1102 | } | 
 | 1103 |  | 
 | 1104 | static void clear_group_ind_mask_bit (PLCI   *plci, word b) | 
 | 1105 | { | 
 | 1106 |   plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f)); | 
 | 1107 | } | 
 | 1108 |  | 
 | 1109 | static byte test_group_ind_mask_bit (PLCI   *plci, word b) | 
 | 1110 | { | 
 | 1111 |   return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0); | 
 | 1112 | } | 
 | 1113 |  | 
 | 1114 | /*------------------------------------------------------------------*/ | 
 | 1115 | /* c_ind_mask operations for arbitrary MAX_APPL                     */ | 
 | 1116 | /*------------------------------------------------------------------*/ | 
 | 1117 |  | 
 | 1118 | static void clear_c_ind_mask (PLCI   *plci) | 
 | 1119 | { | 
 | 1120 |   word i; | 
 | 1121 |  | 
 | 1122 |   for (i = 0; i < C_IND_MASK_DWORDS; i++) | 
 | 1123 |     plci->c_ind_mask_table[i] = 0; | 
 | 1124 | } | 
 | 1125 |  | 
 | 1126 | static byte c_ind_mask_empty (PLCI   *plci) | 
 | 1127 | { | 
 | 1128 |   word i; | 
 | 1129 |  | 
 | 1130 |   i = 0; | 
 | 1131 |   while ((i < C_IND_MASK_DWORDS) && (plci->c_ind_mask_table[i] == 0)) | 
 | 1132 |     i++; | 
 | 1133 |   return (i == C_IND_MASK_DWORDS); | 
 | 1134 | } | 
 | 1135 |  | 
 | 1136 | static void set_c_ind_mask_bit (PLCI   *plci, word b) | 
 | 1137 | { | 
 | 1138 |   plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f)); | 
 | 1139 | } | 
 | 1140 |  | 
 | 1141 | static void clear_c_ind_mask_bit (PLCI   *plci, word b) | 
 | 1142 | { | 
 | 1143 |   plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f)); | 
 | 1144 | } | 
 | 1145 |  | 
 | 1146 | static byte test_c_ind_mask_bit (PLCI   *plci, word b) | 
 | 1147 | { | 
 | 1148 |   return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0); | 
 | 1149 | } | 
 | 1150 |  | 
 | 1151 | static void dump_c_ind_mask (PLCI   *plci) | 
 | 1152 | { | 
 | 1153 | static char hex_digit_table[0x10] = | 
 | 1154 |   {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; | 
 | 1155 |   word i, j, k; | 
 | 1156 |   dword d; | 
 | 1157 |     char *p; | 
 | 1158 |     char buf[40]; | 
 | 1159 |  | 
 | 1160 |   for (i = 0; i < C_IND_MASK_DWORDS; i += 4) | 
 | 1161 |   { | 
 | 1162 |     p = buf + 36; | 
 | 1163 |     *p = '\0'; | 
 | 1164 |     for (j = 0; j < 4; j++) | 
 | 1165 |     { | 
 | 1166 |       if (i+j < C_IND_MASK_DWORDS) | 
 | 1167 |       { | 
 | 1168 |         d = plci->c_ind_mask_table[i+j]; | 
 | 1169 |         for (k = 0; k < 8; k++) | 
 | 1170 |         { | 
 | 1171 |           *(--p) = hex_digit_table[d & 0xf]; | 
 | 1172 |           d >>= 4; | 
 | 1173 |         } | 
 | 1174 |       } | 
 | 1175 |       else if (i != 0) | 
 | 1176 |       { | 
 | 1177 |         for (k = 0; k < 8; k++) | 
 | 1178 |           *(--p) = ' '; | 
 | 1179 |       } | 
 | 1180 |       *(--p) = ' '; | 
 | 1181 |     } | 
 | 1182 |     dbug(1,dprintf ("c_ind_mask =%s", (char   *) p)); | 
 | 1183 |   } | 
 | 1184 | } | 
 | 1185 |  | 
 | 1186 |  | 
 | 1187 |  | 
 | 1188 |  | 
 | 1189 |  | 
 | 1190 | #define dump_plcis(a) | 
 | 1191 |  | 
 | 1192 |  | 
 | 1193 |  | 
 | 1194 | /*------------------------------------------------------------------*/ | 
 | 1195 | /* translation function for each message                            */ | 
 | 1196 | /*------------------------------------------------------------------*/ | 
 | 1197 |  | 
 | 1198 | byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 1199 | { | 
 | 1200 |   word ch; | 
 | 1201 |   word i; | 
 | 1202 |   word Info; | 
 | 1203 |   word CIP; | 
 | 1204 |   byte LinkLayer; | 
 | 1205 |   API_PARSE * ai; | 
 | 1206 |   API_PARSE * bp; | 
 | 1207 |     API_PARSE ai_parms[5]; | 
 | 1208 |   word channel = 0; | 
 | 1209 |   dword ch_mask; | 
 | 1210 |   byte m; | 
 | 1211 |   static byte esc_chi[35] = {0x02,0x18,0x01}; | 
 | 1212 |   static byte lli[2] = {0x01,0x00}; | 
 | 1213 |   byte noCh = 0; | 
 | 1214 |   word dir = 0; | 
 | 1215 |   byte   *p_chi = ""; | 
 | 1216 |  | 
 | 1217 |   for(i=0;i<5;i++) ai_parms[i].length = 0; | 
 | 1218 |  | 
 | 1219 |   dbug(1,dprintf("connect_req(%d)",parms->length)); | 
 | 1220 |   Info = _WRONG_IDENTIFIER; | 
 | 1221 |   if(a) | 
 | 1222 |   { | 
 | 1223 |     if(a->adapter_disabled) | 
 | 1224 |     { | 
 | 1225 |       dbug(1,dprintf("adapter disabled")); | 
 | 1226 |       Id = ((word)1<<8)|a->Id; | 
 | 1227 |       sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0); | 
 | 1228 |       sendf(appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR); | 
 | 1229 |       return FALSE; | 
 | 1230 |     } | 
 | 1231 |     Info = _OUT_OF_PLCI; | 
 | 1232 |     if((i=get_plci(a))) | 
 | 1233 |     { | 
 | 1234 |       Info = 0; | 
 | 1235 |       plci = &a->plci[i-1]; | 
 | 1236 |       plci->appl = appl; | 
 | 1237 |       plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; | 
 | 1238 |       /* check 'external controller' bit for codec support */ | 
 | 1239 |       if(Id & EXT_CONTROLLER) | 
 | 1240 |       { | 
 | 1241 |         if(AdvCodecSupport(a, plci, appl, 0) ) | 
 | 1242 |         { | 
 | 1243 |           plci->Id = 0; | 
 | 1244 |           sendf(appl, _CONNECT_R|CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER); | 
 | 1245 |           return 2; | 
 | 1246 |         } | 
 | 1247 |       } | 
 | 1248 |       ai = &parms[9]; | 
 | 1249 |       bp = &parms[5]; | 
 | 1250 |       ch = 0; | 
 | 1251 |       if(bp->length)LinkLayer = bp->info[3]; | 
 | 1252 |       else LinkLayer = 0; | 
 | 1253 |       if(ai->length) | 
 | 1254 |       { | 
 | 1255 |         ch=0xffff; | 
 | 1256 |         if(!api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms)) | 
 | 1257 |         { | 
 | 1258 |           ch = 0; | 
 | 1259 |           if(ai_parms[0].length) | 
 | 1260 |           { | 
 | 1261 |             ch = GET_WORD(ai_parms[0].info+1); | 
 | 1262 |             if(ch>4) ch=0; /* safety -> ignore ChannelID */ | 
 | 1263 |             if(ch==4) /* explizit CHI in message */ | 
 | 1264 |             { | 
 | 1265 |               /* check length of B-CH struct */ | 
 | 1266 |               if((ai_parms[0].info)[3]>=1) | 
 | 1267 |               { | 
 | 1268 |                 if((ai_parms[0].info)[4]==CHI) | 
 | 1269 |                 { | 
 | 1270 |                   p_chi = &((ai_parms[0].info)[5]); | 
 | 1271 |                 } | 
 | 1272 |                 else | 
 | 1273 |                 { | 
 | 1274 |                   p_chi = &((ai_parms[0].info)[3]); | 
 | 1275 |                 } | 
 | 1276 |                 if(p_chi[0]>35) /* check length of channel ID */ | 
 | 1277 |                 { | 
 | 1278 |                   Info = _WRONG_MESSAGE_FORMAT;     | 
 | 1279 |                 } | 
 | 1280 |               } | 
 | 1281 |               else Info = _WRONG_MESSAGE_FORMAT;     | 
 | 1282 |             } | 
 | 1283 |  | 
 | 1284 |             if(ch==3 && ai_parms[0].length>=7 && ai_parms[0].length<=36) | 
 | 1285 |             { | 
 | 1286 |               dir = GET_WORD(ai_parms[0].info+3); | 
 | 1287 |               ch_mask = 0; | 
 | 1288 |               m = 0x3f; | 
 | 1289 |               for(i=0; i+5<=ai_parms[0].length; i++) | 
 | 1290 |               { | 
 | 1291 |                 if(ai_parms[0].info[i+5]!=0) | 
 | 1292 |                 { | 
 | 1293 |                   if((ai_parms[0].info[i+5] | m) != 0xff) | 
 | 1294 |                     Info = _WRONG_MESSAGE_FORMAT; | 
 | 1295 |                   else | 
 | 1296 |                   { | 
 | 1297 |                     if (ch_mask == 0) | 
 | 1298 |                       channel = i; | 
 | 1299 |                     ch_mask |= 1L << i; | 
 | 1300 |                   } | 
 | 1301 |                 } | 
 | 1302 |                 m = 0; | 
 | 1303 |               } | 
 | 1304 |               if (ch_mask == 0) | 
 | 1305 |                 Info = _WRONG_MESSAGE_FORMAT; | 
 | 1306 |               if (!Info) | 
 | 1307 |               { | 
 | 1308 |                 if ((ai_parms[0].length == 36) || (ch_mask != ((dword)(1L << channel)))) | 
 | 1309 |                 { | 
 | 1310 |                   esc_chi[0] = (byte)(ai_parms[0].length - 2); | 
 | 1311 |                   for(i=0; i+5<=ai_parms[0].length; i++) | 
 | 1312 |                     esc_chi[i+3] = ai_parms[0].info[i+5]; | 
 | 1313 |                 } | 
 | 1314 |                 else | 
 | 1315 |                   esc_chi[0] = 2; | 
 | 1316 |                 esc_chi[2] = (byte)channel; | 
 | 1317 |                 plci->b_channel = (byte)channel; /* not correct for ETSI ch 17..31 */ | 
 | 1318 |                 add_p(plci,LLI,lli); | 
 | 1319 |                 add_p(plci,ESC,esc_chi); | 
 | 1320 |                 plci->State = LOCAL_CONNECT; | 
 | 1321 |                 if(!dir) plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;     /* dir 0=DTE, 1=DCE */ | 
 | 1322 |               } | 
 | 1323 |             } | 
 | 1324 |           } | 
 | 1325 |         } | 
 | 1326 |         else  Info = _WRONG_MESSAGE_FORMAT; | 
 | 1327 |       } | 
 | 1328 |  | 
 | 1329 |       dbug(1,dprintf("ch=%x,dir=%x,p_ch=%d",ch,dir,channel)); | 
 | 1330 |       plci->command = _CONNECT_R; | 
 | 1331 |       plci->number = Number; | 
 | 1332 |       /* x.31 or D-ch free SAPI in LinkLayer? */ | 
 | 1333 |       if(ch==1 && LinkLayer!=3 && LinkLayer!=12) noCh = TRUE; | 
 | 1334 |       if((ch==0 || ch==2 || noCh || ch==3 || ch==4) && !Info) | 
 | 1335 |       { | 
 | 1336 |         /* B-channel used for B3 connections (ch==0), or no B channel    */ | 
 | 1337 |         /* is used (ch==2) or perm. connection (3) is used  do a CALL    */ | 
 | 1338 |         if(noCh) Info = add_b1(plci,&parms[5],2,0);    /* no resource    */ | 
 | 1339 |         else     Info = add_b1(plci,&parms[5],ch,0);  | 
 | 1340 |         add_s(plci,OAD,&parms[2]); | 
 | 1341 |         add_s(plci,OSA,&parms[4]); | 
 | 1342 |         add_s(plci,BC,&parms[6]); | 
 | 1343 |         add_s(plci,LLC,&parms[7]); | 
 | 1344 |         add_s(plci,HLC,&parms[8]); | 
 | 1345 |         CIP = GET_WORD(parms[0].info); | 
 | 1346 |         if (a->Info_Mask[appl->Id-1] & 0x200) | 
 | 1347 |         { | 
 | 1348 |           /* early B3 connect (CIP mask bit 9) no release after a disc */ | 
 | 1349 |           add_p(plci,LLI,"\x01\x01"); | 
 | 1350 |         } | 
 | 1351 |         if(GET_WORD(parms[0].info)<29) { | 
 | 1352 |           add_p(plci,BC,cip_bc[GET_WORD(parms[0].info)][a->u_law]); | 
 | 1353 |           add_p(plci,HLC,cip_hlc[GET_WORD(parms[0].info)]); | 
 | 1354 |         } | 
 | 1355 |         add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 1356 |         sig_req(plci,ASSIGN,DSIG_ID); | 
 | 1357 |       } | 
 | 1358 |       else if(ch==1) { | 
 | 1359 |  | 
 | 1360 |         /* D-Channel used for B3 connections */ | 
 | 1361 |         plci->Sig.Id = 0xff; | 
 | 1362 |         Info = 0; | 
 | 1363 |       } | 
 | 1364 |  | 
 | 1365 |       if(!Info && ch!=2 && !noCh ) { | 
 | 1366 |         Info = add_b23(plci,&parms[5]); | 
 | 1367 |         if(!Info) { | 
 | 1368 |           if(!(plci->tel && !plci->adv_nl))nl_req_ncci(plci,ASSIGN,0); | 
 | 1369 |         } | 
 | 1370 |       } | 
 | 1371 |  | 
 | 1372 |       if(!Info) | 
 | 1373 |       { | 
 | 1374 |         if(ch==0 || ch==2 || ch==3 || noCh || ch==4) | 
 | 1375 |         { | 
 | 1376 |           if(plci->spoofed_msg==SPOOFING_REQUIRED) | 
 | 1377 |           { | 
 | 1378 |             api_save_msg(parms, "wsssssssss", &plci->saved_msg); | 
 | 1379 |             plci->spoofed_msg = CALL_REQ; | 
 | 1380 |             plci->internal_command = BLOCK_PLCI; | 
 | 1381 |             plci->command = 0; | 
 | 1382 |             dbug(1,dprintf("Spoof")); | 
 | 1383 |             send_req(plci); | 
 | 1384 |             return FALSE; | 
 | 1385 |           } | 
 | 1386 |           if(ch==4)add_p(plci,CHI,p_chi); | 
 | 1387 |           add_s(plci,CPN,&parms[1]); | 
 | 1388 |           add_s(plci,DSA,&parms[3]); | 
 | 1389 |           if(noCh) add_p(plci,ESC,"\x02\x18\xfd");  /* D-channel, no B-L3 */ | 
 | 1390 |           add_ai(plci,&parms[9]); | 
 | 1391 |           if(!dir)sig_req(plci,CALL_REQ,0); | 
 | 1392 |           else | 
 | 1393 |           { | 
 | 1394 |             plci->command = PERM_LIST_REQ; | 
 | 1395 |             plci->appl = appl; | 
 | 1396 |             sig_req(plci,LISTEN_REQ,0); | 
 | 1397 |             send_req(plci); | 
 | 1398 |             return FALSE; | 
 | 1399 |           } | 
 | 1400 |         } | 
 | 1401 |         send_req(plci); | 
 | 1402 |         return FALSE; | 
 | 1403 |       } | 
 | 1404 |       plci->Id = 0; | 
 | 1405 |     } | 
 | 1406 |   } | 
 | 1407 |   sendf(appl, | 
 | 1408 |         _CONNECT_R|CONFIRM, | 
 | 1409 |         Id, | 
 | 1410 |         Number, | 
 | 1411 |         "w",Info); | 
 | 1412 |   return 2; | 
 | 1413 | } | 
 | 1414 |  | 
 | 1415 | byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 1416 | { | 
 | 1417 |   word i, Info; | 
 | 1418 |   word Reject; | 
 | 1419 |   static byte cau_t[] = {0,0,0x90,0x91,0xac,0x9d,0x86,0xd8,0x9b}; | 
 | 1420 |   static byte esc_t[] = {0x03,0x08,0x00,0x00}; | 
 | 1421 |   API_PARSE * ai; | 
 | 1422 |     API_PARSE ai_parms[5]; | 
 | 1423 |   word ch=0; | 
 | 1424 |  | 
 | 1425 |   if(!plci) { | 
 | 1426 |     dbug(1,dprintf("connect_res(no plci)")); | 
 | 1427 |     return 0;  /* no plci, no send */ | 
 | 1428 |   } | 
 | 1429 |  | 
 | 1430 |   dbug(1,dprintf("connect_res(State=0x%x)",plci->State)); | 
 | 1431 |   for(i=0;i<5;i++) ai_parms[i].length = 0; | 
 | 1432 |   ai = &parms[5]; | 
 | 1433 |   dbug(1,dprintf("ai->length=%d",ai->length)); | 
 | 1434 |  | 
 | 1435 |   if(ai->length) | 
 | 1436 |   { | 
 | 1437 |     if(!api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms)) | 
 | 1438 |     { | 
 | 1439 |       dbug(1,dprintf("ai_parms[0].length=%d/0x%x",ai_parms[0].length,GET_WORD(ai_parms[0].info+1))); | 
 | 1440 |       ch = 0; | 
 | 1441 |       if(ai_parms[0].length) | 
 | 1442 |       { | 
 | 1443 |         ch = GET_WORD(ai_parms[0].info+1); | 
 | 1444 |         dbug(1,dprintf("BCH-I=0x%x",ch)); | 
 | 1445 |       } | 
 | 1446 |     } | 
 | 1447 |   } | 
 | 1448 |  | 
 | 1449 |   if(plci->State==INC_CON_CONNECTED_ALERT) | 
 | 1450 |   { | 
 | 1451 |     dbug(1,dprintf("Connected Alert Call_Res")); | 
 | 1452 |     if (a->Info_Mask[appl->Id-1] & 0x200) | 
 | 1453 |     { | 
 | 1454 |     /* early B3 connect (CIP mask bit 9) no release after a disc */ | 
 | 1455 |       add_p(plci,LLI,"\x01\x01"); | 
 | 1456 |     } | 
 | 1457 |     add_s(plci, CONN_NR, &parms[2]); | 
 | 1458 |     add_s(plci, LLC, &parms[4]); | 
 | 1459 |     add_ai(plci, &parms[5]); | 
 | 1460 |     plci->State = INC_CON_ACCEPT; | 
 | 1461 |     sig_req(plci, CALL_RES,0); | 
 | 1462 |     return 1; | 
 | 1463 |   } | 
 | 1464 |   else if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT) { | 
 | 1465 |     clear_c_ind_mask_bit (plci, (word)(appl->Id-1)); | 
 | 1466 |     dump_c_ind_mask (plci); | 
 | 1467 |     Reject = GET_WORD(parms[0].info); | 
 | 1468 |     dbug(1,dprintf("Reject=0x%x",Reject)); | 
 | 1469 |     if(Reject)  | 
 | 1470 |     { | 
 | 1471 |       if(c_ind_mask_empty (plci))  | 
 | 1472 |       { | 
 | 1473 |         if((Reject&0xff00)==0x3400)  | 
 | 1474 |         { | 
 | 1475 |           esc_t[2] = ((byte)(Reject&0x00ff)) | 0x80; | 
 | 1476 |           add_p(plci,ESC,esc_t); | 
 | 1477 |           add_ai(plci, &parms[5]); | 
 | 1478 |           sig_req(plci,REJECT,0); | 
 | 1479 |         }       | 
 | 1480 |         else if(Reject==1 || Reject>9)  | 
 | 1481 |         { | 
 | 1482 |           add_ai(plci, &parms[5]); | 
 | 1483 |           sig_req(plci,HANGUP,0); | 
 | 1484 |         } | 
 | 1485 |         else  | 
 | 1486 |         { | 
 | 1487 |           esc_t[2] = cau_t[(Reject&0x000f)]; | 
 | 1488 |           add_p(plci,ESC,esc_t); | 
 | 1489 |           add_ai(plci, &parms[5]); | 
 | 1490 |           sig_req(plci,REJECT,0); | 
 | 1491 |         } | 
 | 1492 |         plci->appl = appl; | 
 | 1493 |       } | 
 | 1494 |       else  | 
 | 1495 |       { | 
 | 1496 |         sendf(appl, _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); | 
 | 1497 |       } | 
 | 1498 |     } | 
 | 1499 |     else { | 
 | 1500 |       plci->appl = appl; | 
 | 1501 |       if(Id & EXT_CONTROLLER){ | 
 | 1502 |         if(AdvCodecSupport(a, plci, appl, 0)){ | 
 | 1503 |           dbug(1,dprintf("connect_res(error from AdvCodecSupport)")); | 
 | 1504 |           sig_req(plci,HANGUP,0); | 
 | 1505 |           return 1; | 
 | 1506 |         } | 
 | 1507 |         if(plci->tel == ADV_VOICE && a->AdvCodecPLCI) | 
 | 1508 |         { | 
 | 1509 |           Info = add_b23(plci, &parms[1]); | 
 | 1510 |           if (Info) | 
 | 1511 |           { | 
 | 1512 |             dbug(1,dprintf("connect_res(error from add_b23)")); | 
 | 1513 |             sig_req(plci,HANGUP,0); | 
 | 1514 |             return 1; | 
 | 1515 |           } | 
 | 1516 |           if(plci->adv_nl) | 
 | 1517 |           { | 
 | 1518 |             nl_req_ncci(plci, ASSIGN, 0); | 
 | 1519 |           } | 
 | 1520 |         } | 
 | 1521 |       } | 
 | 1522 |       else | 
 | 1523 |       { | 
 | 1524 |         plci->tel = 0; | 
 | 1525 |         if(ch!=2) | 
 | 1526 |         { | 
 | 1527 |           Info = add_b23(plci, &parms[1]); | 
 | 1528 |           if (Info) | 
 | 1529 |           { | 
 | 1530 |             dbug(1,dprintf("connect_res(error from add_b23 2)")); | 
 | 1531 |             sig_req(plci,HANGUP,0); | 
 | 1532 |             return 1; | 
 | 1533 |           } | 
 | 1534 |         } | 
 | 1535 |         nl_req_ncci(plci, ASSIGN, 0); | 
 | 1536 |       } | 
 | 1537 |  | 
 | 1538 |       if(plci->spoofed_msg==SPOOFING_REQUIRED) | 
 | 1539 |       { | 
 | 1540 |         api_save_msg(parms, "wsssss", &plci->saved_msg); | 
 | 1541 |         plci->spoofed_msg = CALL_RES; | 
 | 1542 |         plci->internal_command = BLOCK_PLCI; | 
 | 1543 |         plci->command = 0; | 
 | 1544 |         dbug(1,dprintf("Spoof")); | 
 | 1545 |       } | 
 | 1546 |       else | 
 | 1547 |       { | 
 | 1548 |         add_b1 (plci, &parms[1], ch, plci->B1_facilities); | 
 | 1549 |         if (a->Info_Mask[appl->Id-1] & 0x200) | 
 | 1550 |         { | 
 | 1551 |           /* early B3 connect (CIP mask bit 9) no release after a disc */ | 
 | 1552 |           add_p(plci,LLI,"\x01\x01"); | 
 | 1553 |         } | 
 | 1554 |         add_s(plci, CONN_NR, &parms[2]); | 
 | 1555 |         add_s(plci, LLC, &parms[4]); | 
 | 1556 |         add_ai(plci, &parms[5]); | 
 | 1557 |         plci->State = INC_CON_ACCEPT; | 
 | 1558 |         sig_req(plci, CALL_RES,0); | 
 | 1559 |       } | 
 | 1560 |  | 
 | 1561 |       for(i=0; i<max_appl; i++) { | 
 | 1562 |         if(test_c_ind_mask_bit (plci, i)) { | 
 | 1563 |           sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); | 
 | 1564 |         } | 
 | 1565 |       } | 
 | 1566 |     } | 
 | 1567 |   } | 
 | 1568 |   return 1; | 
 | 1569 | } | 
 | 1570 |  | 
 | 1571 | byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 1572 | { | 
 | 1573 |   dbug(1,dprintf("connect_a_res")); | 
 | 1574 |   return FALSE; | 
 | 1575 | } | 
 | 1576 |  | 
 | 1577 | byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 1578 | { | 
 | 1579 |   word Info; | 
 | 1580 |   word i; | 
 | 1581 |  | 
 | 1582 |   dbug(1,dprintf("disconnect_req")); | 
 | 1583 |  | 
 | 1584 |   Info = _WRONG_IDENTIFIER; | 
 | 1585 |  | 
 | 1586 |   if(plci) | 
 | 1587 |   { | 
 | 1588 |     if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT) | 
 | 1589 |     { | 
 | 1590 |       clear_c_ind_mask_bit (plci, (word)(appl->Id-1)); | 
 | 1591 |       plci->appl = appl; | 
 | 1592 |       for(i=0; i<max_appl; i++) | 
 | 1593 |       { | 
 | 1594 |         if(test_c_ind_mask_bit (plci, i)) | 
 | 1595 |           sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0); | 
 | 1596 |       } | 
 | 1597 |       plci->State = OUTG_DIS_PENDING; | 
 | 1598 |     } | 
 | 1599 |     if(plci->Sig.Id && plci->appl) | 
 | 1600 |     { | 
 | 1601 |       Info = 0; | 
 | 1602 |         if(plci->Sig.Id!=0xff) | 
 | 1603 |         { | 
 | 1604 |           if(plci->State!=INC_DIS_PENDING) | 
 | 1605 |           { | 
 | 1606 |             add_ai(plci, &msg[0]); | 
 | 1607 |             sig_req(plci,HANGUP,0); | 
 | 1608 |             plci->State = OUTG_DIS_PENDING; | 
 | 1609 |             return 1; | 
 | 1610 |           } | 
 | 1611 |         } | 
 | 1612 |         else | 
 | 1613 |         { | 
 | 1614 |           if (plci->NL.Id && !plci->nl_remove_id) | 
 | 1615 |           { | 
 | 1616 |             mixer_remove (plci); | 
 | 1617 |             nl_req_ncci(plci,REMOVE,0); | 
 | 1618 |           sendf(appl,_DISCONNECT_R|CONFIRM,Id,Number,"w",0); | 
 | 1619 |           sendf(appl, _DISCONNECT_I, Id, 0, "w", 0); | 
 | 1620 |           plci->State = INC_DIS_PENDING; | 
 | 1621 |           } | 
 | 1622 |           return 1; | 
 | 1623 |         } | 
 | 1624 |       } | 
 | 1625 |     } | 
 | 1626 |  | 
 | 1627 |   if(!appl)  return FALSE; | 
 | 1628 |   sendf(appl, _DISCONNECT_R|CONFIRM, Id, Number, "w",Info); | 
 | 1629 |   return FALSE; | 
 | 1630 | } | 
 | 1631 |  | 
 | 1632 | byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 1633 | { | 
 | 1634 |   dbug(1,dprintf("disconnect_res")); | 
 | 1635 |   if(plci) | 
 | 1636 |   { | 
 | 1637 |         /* clear ind mask bit, just in case of collsion of          */ | 
 | 1638 |         /* DISCONNECT_IND and CONNECT_RES                           */ | 
 | 1639 |     clear_c_ind_mask_bit (plci, (word)(appl->Id-1)); | 
 | 1640 |     ncci_free_receive_buffers (plci, 0); | 
 | 1641 |     if(plci_remove_check(plci)) | 
 | 1642 |     { | 
 | 1643 |       return 0; | 
 | 1644 |     } | 
 | 1645 |     if(plci->State==INC_DIS_PENDING | 
 | 1646 |     || plci->State==SUSPENDING) { | 
 | 1647 |       if(c_ind_mask_empty (plci)) { | 
 | 1648 |         if(plci->State!=SUSPENDING)plci->State = IDLE; | 
 | 1649 |         dbug(1,dprintf("chs=%d",plci->channels)); | 
 | 1650 |         if(!plci->channels) { | 
 | 1651 |           plci_remove(plci); | 
 | 1652 |         } | 
 | 1653 |       } | 
 | 1654 |     } | 
 | 1655 |   } | 
 | 1656 |   return 0; | 
 | 1657 | } | 
 | 1658 |  | 
 | 1659 | byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 1660 | { | 
 | 1661 |   word Info; | 
 | 1662 |   byte i; | 
 | 1663 |  | 
 | 1664 |   dbug(1,dprintf("listen_req(Appl=0x%x)",appl->Id)); | 
 | 1665 |  | 
 | 1666 |   Info = _WRONG_IDENTIFIER; | 
 | 1667 |   if(a) { | 
 | 1668 |     Info = 0; | 
 | 1669 |     a->Info_Mask[appl->Id-1] = GET_DWORD(parms[0].info); | 
 | 1670 |     a->CIP_Mask[appl->Id-1] = GET_DWORD(parms[1].info); | 
 | 1671 |     dbug(1,dprintf("CIP_MASK=0x%lx",GET_DWORD(parms[1].info))); | 
 | 1672 |     if (a->Info_Mask[appl->Id-1] & 0x200){ /* early B3 connect provides */ | 
 | 1673 |       a->Info_Mask[appl->Id-1] |=  0x10;   /* call progression infos    */ | 
 | 1674 |     } | 
 | 1675 |  | 
 | 1676 |     /* check if external controller listen and switch listen on or off*/ | 
 | 1677 |     if(Id&EXT_CONTROLLER && GET_DWORD(parms[1].info)){ | 
 | 1678 |       if(a->profile.Global_Options & ON_BOARD_CODEC) { | 
 | 1679 |         dummy_plci.State = IDLE; | 
 | 1680 |         a->codec_listen[appl->Id-1] = &dummy_plci; | 
 | 1681 |         a->TelOAD[0] = (byte)(parms[3].length); | 
 | 1682 |         for(i=1;parms[3].length>=i && i<22;i++) { | 
 | 1683 |           a->TelOAD[i] = parms[3].info[i]; | 
 | 1684 |         } | 
 | 1685 |         a->TelOAD[i] = 0; | 
 | 1686 |         a->TelOSA[0] = (byte)(parms[4].length); | 
 | 1687 |         for(i=1;parms[4].length>=i && i<22;i++) { | 
 | 1688 |           a->TelOSA[i] = parms[4].info[i]; | 
 | 1689 |         } | 
 | 1690 |         a->TelOSA[i] = 0; | 
 | 1691 |       } | 
 | 1692 |       else Info = 0x2002; /* wrong controller, codec not supported */ | 
 | 1693 |     } | 
 | 1694 |     else{               /* clear listen */ | 
 | 1695 |       a->codec_listen[appl->Id-1] = (PLCI   *)0; | 
 | 1696 |     } | 
 | 1697 |   } | 
 | 1698 |   sendf(appl, | 
 | 1699 |         _LISTEN_R|CONFIRM, | 
 | 1700 |         Id, | 
 | 1701 |         Number, | 
 | 1702 |         "w",Info); | 
 | 1703 |  | 
 | 1704 |   if (a) listen_check(a); | 
 | 1705 |   return FALSE; | 
 | 1706 | } | 
 | 1707 |  | 
 | 1708 | byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 1709 | { | 
 | 1710 |   word i; | 
 | 1711 |   API_PARSE * ai; | 
 | 1712 |   PLCI   * rc_plci = NULL; | 
 | 1713 |     API_PARSE ai_parms[5]; | 
 | 1714 |   word Info = 0; | 
 | 1715 |  | 
 | 1716 |   dbug(1,dprintf("info_req")); | 
 | 1717 |   for(i=0;i<5;i++) ai_parms[i].length = 0; | 
 | 1718 |  | 
 | 1719 |   ai = &msg[1]; | 
 | 1720 |  | 
 | 1721 |   if(ai->length) | 
 | 1722 |   { | 
 | 1723 |     if(api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms)) | 
 | 1724 |     { | 
 | 1725 |       dbug(1,dprintf("AddInfo wrong")); | 
 | 1726 |       Info = _WRONG_MESSAGE_FORMAT; | 
 | 1727 |     } | 
 | 1728 |   } | 
 | 1729 |   if(!a) Info = _WRONG_STATE; | 
 | 1730 |  | 
 | 1731 |   if(!Info && plci) | 
 | 1732 |   {                /* no fac, with CPN, or KEY */ | 
 | 1733 |     rc_plci = plci; | 
 | 1734 |     if(!ai_parms[3].length && plci->State && (msg[0].length || ai_parms[1].length) ) | 
 | 1735 |     { | 
 | 1736 |       /* overlap sending option */ | 
 | 1737 |       dbug(1,dprintf("OvlSnd")); | 
 | 1738 |       add_s(plci,CPN,&msg[0]); | 
 | 1739 |       add_s(plci,KEY,&ai_parms[1]); | 
 | 1740 |       sig_req(plci,INFO_REQ,0); | 
 | 1741 |       send_req(plci); | 
 | 1742 |       return FALSE; | 
 | 1743 |     } | 
 | 1744 |  | 
 | 1745 |     if(plci->State && ai_parms[2].length) | 
 | 1746 |     { | 
 | 1747 |       /* User_Info option */ | 
 | 1748 |       dbug(1,dprintf("UUI")); | 
 | 1749 |       add_s(plci,UUI,&ai_parms[2]); | 
 | 1750 |       sig_req(plci,USER_DATA,0); | 
 | 1751 |     } | 
 | 1752 |     else if(plci->State && ai_parms[3].length) | 
 | 1753 |     { | 
 | 1754 |       /* Facility option */ | 
 | 1755 |       dbug(1,dprintf("FAC")); | 
 | 1756 |       add_s(plci,CPN,&msg[0]); | 
 | 1757 |       add_ai(plci, &msg[1]); | 
 | 1758 |       sig_req(plci,FACILITY_REQ,0); | 
 | 1759 |     } | 
 | 1760 |     else | 
 | 1761 |     { | 
 | 1762 |       Info = _WRONG_STATE; | 
 | 1763 |     } | 
 | 1764 |   } | 
 | 1765 |   else if((ai_parms[1].length || ai_parms[2].length || ai_parms[3].length) && !Info) | 
 | 1766 |   { | 
 | 1767 |     /* NCR_Facility option -> send UUI and Keypad too */ | 
 | 1768 |     dbug(1,dprintf("NCR_FAC")); | 
 | 1769 |     if((i=get_plci(a))) | 
 | 1770 |     { | 
 | 1771 |       rc_plci = &a->plci[i-1]; | 
 | 1772 |       appl->NullCREnable  = TRUE; | 
 | 1773 |       rc_plci->internal_command = C_NCR_FAC_REQ; | 
 | 1774 |       rc_plci->appl = appl; | 
 | 1775 |       add_p(rc_plci,CAI,"\x01\x80"); | 
 | 1776 |       add_p(rc_plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 1777 |       sig_req(rc_plci,ASSIGN,DSIG_ID); | 
 | 1778 |       send_req(rc_plci); | 
 | 1779 |     } | 
 | 1780 |     else | 
 | 1781 |     { | 
 | 1782 |       Info = _OUT_OF_PLCI; | 
 | 1783 |     } | 
 | 1784 |  | 
 | 1785 |     if(!Info) | 
 | 1786 |     { | 
 | 1787 |       add_s(rc_plci,CPN,&msg[0]); | 
 | 1788 |       add_ai(rc_plci, &msg[1]); | 
 | 1789 |       sig_req(rc_plci,NCR_FACILITY,0); | 
 | 1790 |       send_req(rc_plci); | 
 | 1791 |       return FALSE; | 
 | 1792 |      /* for application controlled supplementary services    */ | 
 | 1793 |     } | 
 | 1794 |   } | 
 | 1795 |  | 
 | 1796 |   if (!rc_plci) | 
 | 1797 |   { | 
 | 1798 |     Info = _WRONG_MESSAGE_FORMAT; | 
 | 1799 |   } | 
 | 1800 |  | 
 | 1801 |   if(!Info) | 
 | 1802 |   { | 
 | 1803 |     send_req(rc_plci); | 
 | 1804 |   } | 
 | 1805 |   else | 
 | 1806 |   {  /* appl is not assigned to a PLCI or error condition */ | 
 | 1807 |     dbug(1,dprintf("localInfoCon")); | 
 | 1808 |     sendf(appl, | 
 | 1809 |           _INFO_R|CONFIRM, | 
 | 1810 |           Id, | 
 | 1811 |           Number, | 
 | 1812 |           "w",Info); | 
 | 1813 |   } | 
 | 1814 |   return FALSE; | 
 | 1815 | } | 
 | 1816 |  | 
 | 1817 | byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 1818 | { | 
 | 1819 |   dbug(1,dprintf("info_res")); | 
 | 1820 |   return FALSE; | 
 | 1821 | } | 
 | 1822 |  | 
 | 1823 | byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 1824 | { | 
 | 1825 |   word Info; | 
 | 1826 |   byte ret; | 
 | 1827 |  | 
 | 1828 |   dbug(1,dprintf("alert_req")); | 
 | 1829 |  | 
 | 1830 |   Info = _WRONG_IDENTIFIER; | 
 | 1831 |   ret = FALSE; | 
 | 1832 |   if(plci) { | 
 | 1833 |     Info = _ALERT_IGNORED; | 
 | 1834 |     if(plci->State!=INC_CON_ALERT) { | 
 | 1835 |       Info = _WRONG_STATE; | 
 | 1836 |       if(plci->State==INC_CON_PENDING) { | 
 | 1837 |         Info = 0; | 
 | 1838 |         plci->State=INC_CON_ALERT; | 
 | 1839 |         add_ai(plci, &msg[0]); | 
 | 1840 |         sig_req(plci,CALL_ALERT,0); | 
 | 1841 |         ret = 1; | 
 | 1842 |       } | 
 | 1843 |     } | 
 | 1844 |   } | 
 | 1845 |   sendf(appl, | 
 | 1846 |         _ALERT_R|CONFIRM, | 
 | 1847 |         Id, | 
 | 1848 |         Number, | 
 | 1849 |         "w",Info); | 
 | 1850 |   return ret; | 
 | 1851 | } | 
 | 1852 |  | 
 | 1853 | byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 1854 | { | 
 | 1855 |   word Info = 0; | 
 | 1856 |   word i    = 0; | 
 | 1857 |  | 
 | 1858 |   word selector; | 
 | 1859 |   word SSreq; | 
 | 1860 |   long relatedPLCIvalue; | 
 | 1861 |   DIVA_CAPI_ADAPTER   * relatedadapter; | 
 | 1862 |   byte * SSparms  = ""; | 
 | 1863 |     byte RCparms[]  = "\x05\x00\x00\x02\x00\x00"; | 
 | 1864 |     byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00"; | 
 | 1865 |   API_PARSE * parms; | 
 | 1866 |     API_PARSE ss_parms[11]; | 
 | 1867 |   PLCI   *rplci; | 
 | 1868 |     byte cai[15]; | 
 | 1869 |   dword d; | 
 | 1870 |     API_PARSE dummy; | 
 | 1871 |  | 
 | 1872 |   dbug(1,dprintf("facility_req")); | 
 | 1873 |   for(i=0;i<9;i++) ss_parms[i].length = 0; | 
 | 1874 |  | 
 | 1875 |   parms = &msg[1]; | 
 | 1876 |  | 
 | 1877 |   if(!a) | 
 | 1878 |   { | 
 | 1879 |     dbug(1,dprintf("wrong Ctrl")); | 
 | 1880 |     Info = _WRONG_IDENTIFIER; | 
 | 1881 |   } | 
 | 1882 |  | 
 | 1883 |   selector = GET_WORD(msg[0].info); | 
 | 1884 |  | 
 | 1885 |   if(!Info) | 
 | 1886 |   { | 
 | 1887 |     switch(selector) | 
 | 1888 |     { | 
 | 1889 |       case SELECTOR_HANDSET: | 
 | 1890 |         Info = AdvCodecSupport(a, plci, appl, HOOK_SUPPORT); | 
 | 1891 |         break; | 
 | 1892 |  | 
 | 1893 |       case SELECTOR_SU_SERV: | 
 | 1894 |         if(!msg[1].length) | 
 | 1895 |         { | 
 | 1896 |           Info = _WRONG_MESSAGE_FORMAT; | 
 | 1897 |           break; | 
 | 1898 |         } | 
 | 1899 |         SSreq = GET_WORD(&(msg[1].info[1])); | 
 | 1900 |         PUT_WORD(&RCparms[1],SSreq); | 
 | 1901 |         SSparms = RCparms; | 
 | 1902 |         switch(SSreq) | 
 | 1903 |         { | 
 | 1904 |           case S_GET_SUPPORTED_SERVICES: | 
 | 1905 |             if((i=get_plci(a))) | 
 | 1906 |             { | 
 | 1907 |               rplci = &a->plci[i-1]; | 
 | 1908 |               rplci->appl = appl; | 
 | 1909 |               add_p(rplci,CAI,"\x01\x80"); | 
 | 1910 |               add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 1911 |               sig_req(rplci,ASSIGN,DSIG_ID); | 
 | 1912 |               send_req(rplci); | 
 | 1913 |             } | 
 | 1914 |             else | 
 | 1915 |             { | 
 | 1916 |               PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY); | 
 | 1917 |               SSparms = (byte *)SSstruct; | 
 | 1918 |               break; | 
 | 1919 |             } | 
 | 1920 |             rplci->internal_command = GETSERV_REQ_PEND; | 
 | 1921 |             rplci->number = Number; | 
 | 1922 |             rplci->appl = appl; | 
 | 1923 |             sig_req(rplci,S_SUPPORTED,0); | 
 | 1924 |             send_req(rplci); | 
 | 1925 |             return FALSE; | 
 | 1926 |             break; | 
 | 1927 |  | 
 | 1928 |           case S_LISTEN: | 
 | 1929 |             if(parms->length==7) | 
 | 1930 |             { | 
 | 1931 |               if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms)) | 
 | 1932 |               { | 
 | 1933 |                 dbug(1,dprintf("format wrong")); | 
 | 1934 |                 Info = _WRONG_MESSAGE_FORMAT; | 
 | 1935 |                 break; | 
 | 1936 |               } | 
 | 1937 |             } | 
 | 1938 |             else | 
 | 1939 |             { | 
 | 1940 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 1941 |               break; | 
 | 1942 |             } | 
 | 1943 |             a->Notification_Mask[appl->Id-1] = GET_DWORD(ss_parms[2].info); | 
 | 1944 |             if(a->Notification_Mask[appl->Id-1] & SMASK_MWI) /* MWI active? */ | 
 | 1945 |             { | 
 | 1946 |               if((i=get_plci(a))) | 
 | 1947 |               { | 
 | 1948 |                 rplci = &a->plci[i-1]; | 
 | 1949 |                 rplci->appl = appl; | 
 | 1950 |                 add_p(rplci,CAI,"\x01\x80"); | 
 | 1951 |                 add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 1952 |                 sig_req(rplci,ASSIGN,DSIG_ID); | 
 | 1953 |                 send_req(rplci); | 
 | 1954 |               } | 
 | 1955 |               else | 
 | 1956 |               { | 
 | 1957 |                 break; | 
 | 1958 |               } | 
 | 1959 |               rplci->internal_command = GET_MWI_STATE; | 
 | 1960 |               rplci->number = Number; | 
 | 1961 |               sig_req(rplci,MWI_POLL,0); | 
 | 1962 |               send_req(rplci); | 
 | 1963 |             } | 
 | 1964 |             break; | 
 | 1965 |  | 
 | 1966 |           case S_HOLD: | 
 | 1967 |             api_parse(&parms->info[1],(word)parms->length,"ws",ss_parms); | 
 | 1968 |             if(plci && plci->State && plci->SuppState==IDLE) | 
 | 1969 |             { | 
 | 1970 |               plci->SuppState = HOLD_REQUEST; | 
 | 1971 |               plci->command = C_HOLD_REQ; | 
 | 1972 |               add_s(plci,CAI,&ss_parms[1]); | 
 | 1973 |               sig_req(plci,CALL_HOLD,0); | 
 | 1974 |               send_req(plci); | 
 | 1975 |               return FALSE; | 
 | 1976 |             } | 
 | 1977 |             else Info = 0x3010;                    /* wrong state           */ | 
 | 1978 |             break; | 
 | 1979 |           case S_RETRIEVE: | 
 | 1980 |             if(plci && plci->State && plci->SuppState==CALL_HELD) | 
 | 1981 |             { | 
 | 1982 |               if(Id & EXT_CONTROLLER) | 
 | 1983 |               { | 
 | 1984 |                 if(AdvCodecSupport(a, plci, appl, 0)) | 
 | 1985 |                 { | 
 | 1986 |                   Info = 0x3010;                    /* wrong state           */ | 
 | 1987 |                   break; | 
 | 1988 |                 } | 
 | 1989 |               } | 
 | 1990 |               else plci->tel = 0; | 
 | 1991 |  | 
 | 1992 |               plci->SuppState = RETRIEVE_REQUEST; | 
 | 1993 |               plci->command = C_RETRIEVE_REQ; | 
 | 1994 |               if(plci->spoofed_msg==SPOOFING_REQUIRED) | 
 | 1995 |               { | 
 | 1996 |                 plci->spoofed_msg = CALL_RETRIEVE; | 
 | 1997 |                 plci->internal_command = BLOCK_PLCI; | 
 | 1998 |                 plci->command = 0; | 
 | 1999 |                 dbug(1,dprintf("Spoof")); | 
 | 2000 |                 return FALSE; | 
 | 2001 |               } | 
 | 2002 |               else | 
 | 2003 |               { | 
 | 2004 |                 sig_req(plci,CALL_RETRIEVE,0); | 
 | 2005 |                 send_req(plci); | 
 | 2006 |                 return FALSE; | 
 | 2007 |               } | 
 | 2008 |             } | 
 | 2009 |             else Info = 0x3010;                    /* wrong state           */ | 
 | 2010 |             break; | 
 | 2011 |           case S_SUSPEND: | 
 | 2012 |             if(parms->length) | 
 | 2013 |             { | 
 | 2014 |               if(api_parse(&parms->info[1],(word)parms->length,"wbs",ss_parms)) | 
 | 2015 |               { | 
 | 2016 |                 dbug(1,dprintf("format wrong")); | 
 | 2017 |                 Info = _WRONG_MESSAGE_FORMAT; | 
 | 2018 |                 break; | 
 | 2019 |               } | 
 | 2020 |             } | 
 | 2021 |             if(plci && plci->State) | 
 | 2022 |             { | 
 | 2023 |               add_s(plci,CAI,&ss_parms[2]); | 
 | 2024 |               plci->command = SUSPEND_REQ; | 
 | 2025 |               sig_req(plci,SUSPEND,0); | 
 | 2026 |               plci->State = SUSPENDING; | 
 | 2027 |               send_req(plci); | 
 | 2028 |             } | 
 | 2029 |             else Info = 0x3010;                    /* wrong state           */ | 
 | 2030 |             break; | 
 | 2031 |  | 
 | 2032 |           case S_RESUME: | 
 | 2033 |             if(!(i=get_plci(a)) ) | 
 | 2034 |             { | 
 | 2035 |               Info = _OUT_OF_PLCI; | 
 | 2036 |               break; | 
 | 2037 |             } | 
 | 2038 |             rplci = &a->plci[i-1]; | 
 | 2039 |             rplci->appl = appl; | 
 | 2040 |             rplci->number = Number; | 
 | 2041 |             rplci->tel = 0; | 
 | 2042 |             rplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; | 
 | 2043 |             /* check 'external controller' bit for codec support */ | 
 | 2044 |             if(Id & EXT_CONTROLLER) | 
 | 2045 |             { | 
 | 2046 |               if(AdvCodecSupport(a, rplci, appl, 0) ) | 
 | 2047 |               { | 
 | 2048 |                 rplci->Id = 0; | 
 | 2049 |                 Info = 0x300A; | 
 | 2050 |                 break; | 
 | 2051 |               } | 
 | 2052 |             } | 
 | 2053 |             if(parms->length) | 
 | 2054 |             { | 
 | 2055 |               if(api_parse(&parms->info[1],(word)parms->length,"wbs",ss_parms)) | 
 | 2056 |               { | 
 | 2057 |                 dbug(1,dprintf("format wrong")); | 
 | 2058 |                 rplci->Id = 0; | 
 | 2059 |                 Info = _WRONG_MESSAGE_FORMAT; | 
 | 2060 |                 break; | 
 | 2061 |               } | 
 | 2062 |             } | 
 | 2063 |             dummy.length = 0; | 
 | 2064 |             dummy.info = "\x00"; | 
 | 2065 |             add_b1(rplci, &dummy, 0, 0); | 
 | 2066 |             if (a->Info_Mask[appl->Id-1] & 0x200) | 
 | 2067 |             { | 
 | 2068 |               /* early B3 connect (CIP mask bit 9) no release after a disc */ | 
 | 2069 |               add_p(rplci,LLI,"\x01\x01"); | 
 | 2070 |             } | 
 | 2071 |             add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 2072 |             sig_req(rplci,ASSIGN,DSIG_ID); | 
 | 2073 |             send_req(rplci); | 
 | 2074 |             add_s(rplci,CAI,&ss_parms[2]); | 
 | 2075 |             rplci->command = RESUME_REQ; | 
 | 2076 |             sig_req(rplci,RESUME,0); | 
 | 2077 |             rplci->State = RESUMING; | 
 | 2078 |             send_req(rplci); | 
 | 2079 |             break; | 
 | 2080 |  | 
 | 2081 |           case S_CONF_BEGIN: /* Request */ | 
 | 2082 |           case S_CONF_DROP: | 
 | 2083 |           case S_CONF_ISOLATE: | 
 | 2084 |           case S_CONF_REATTACH: | 
 | 2085 |             if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms)) | 
 | 2086 |             { | 
 | 2087 |               dbug(1,dprintf("format wrong")); | 
 | 2088 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 2089 |               break; | 
 | 2090 |             } | 
 | 2091 |             if(plci && plci->State && ((plci->SuppState==IDLE)||(plci->SuppState==CALL_HELD))) | 
 | 2092 |             { | 
 | 2093 |               d = GET_DWORD(ss_parms[2].info);      | 
 | 2094 |               if(d>=0x80) | 
 | 2095 |               { | 
 | 2096 |                 dbug(1,dprintf("format wrong")); | 
 | 2097 |                 Info = _WRONG_MESSAGE_FORMAT; | 
 | 2098 |                 break; | 
 | 2099 |               } | 
 | 2100 |               plci->ptyState = (byte)SSreq; | 
 | 2101 |               plci->command = 0; | 
 | 2102 |               cai[0] = 2; | 
 | 2103 |               switch(SSreq) | 
 | 2104 |               { | 
 | 2105 |               case S_CONF_BEGIN: | 
 | 2106 |                   cai[1] = CONF_BEGIN; | 
 | 2107 |                   plci->internal_command = CONF_BEGIN_REQ_PEND; | 
 | 2108 |                   break; | 
 | 2109 |               case S_CONF_DROP: | 
 | 2110 |                   cai[1] = CONF_DROP; | 
 | 2111 |                   plci->internal_command = CONF_DROP_REQ_PEND; | 
 | 2112 |                   break; | 
 | 2113 |               case S_CONF_ISOLATE: | 
 | 2114 |                   cai[1] = CONF_ISOLATE; | 
 | 2115 |                   plci->internal_command = CONF_ISOLATE_REQ_PEND; | 
 | 2116 |                   break; | 
 | 2117 |               case S_CONF_REATTACH: | 
 | 2118 |                   cai[1] = CONF_REATTACH; | 
 | 2119 |                   plci->internal_command = CONF_REATTACH_REQ_PEND; | 
 | 2120 |                   break; | 
 | 2121 |               } | 
 | 2122 |               cai[2] = (byte)d; /* Conference Size resp. PartyId */ | 
 | 2123 |               add_p(plci,CAI,cai); | 
 | 2124 |               sig_req(plci,S_SERVICE,0); | 
 | 2125 |               send_req(plci); | 
 | 2126 |               return FALSE; | 
 | 2127 |             } | 
 | 2128 |             else Info = 0x3010;                    /* wrong state           */ | 
 | 2129 |             break; | 
 | 2130 |  | 
 | 2131 |           case S_ECT: | 
 | 2132 |           case S_3PTY_BEGIN: | 
 | 2133 |           case S_3PTY_END: | 
 | 2134 |           case S_CONF_ADD: | 
 | 2135 |             if(parms->length==7) | 
 | 2136 |             { | 
 | 2137 |               if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms)) | 
 | 2138 |               { | 
 | 2139 |                 dbug(1,dprintf("format wrong")); | 
 | 2140 |                 Info = _WRONG_MESSAGE_FORMAT; | 
 | 2141 |                 break; | 
 | 2142 |               } | 
 | 2143 |             } | 
 | 2144 |             else if(parms->length==8) /* workaround for the T-View-S */ | 
 | 2145 |             { | 
 | 2146 |               if(api_parse(&parms->info[1],(word)parms->length,"wbdb",ss_parms)) | 
 | 2147 |               { | 
 | 2148 |                 dbug(1,dprintf("format wrong")); | 
 | 2149 |                 Info = _WRONG_MESSAGE_FORMAT; | 
 | 2150 |                 break; | 
 | 2151 |               } | 
 | 2152 |             } | 
 | 2153 |             else | 
 | 2154 |             { | 
 | 2155 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 2156 |               break; | 
 | 2157 |             } | 
 | 2158 |             if(!msg[1].length) | 
 | 2159 |             { | 
 | 2160 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 2161 |               break; | 
 | 2162 |             } | 
 | 2163 |             if (!plci) | 
 | 2164 |             { | 
 | 2165 |               Info = _WRONG_IDENTIFIER; | 
 | 2166 |               break; | 
 | 2167 |             } | 
 | 2168 |             relatedPLCIvalue = GET_DWORD(ss_parms[2].info); | 
 | 2169 |             relatedPLCIvalue &= 0x0000FFFF; | 
 | 2170 |             dbug(1,dprintf("PTY/ECT/addCONF,relPLCI=%lx",relatedPLCIvalue)); | 
 | 2171 |             /* controller starts with 0 up to (max_adapter - 1) */ | 
 | 2172 |             if (((relatedPLCIvalue & 0x7f) == 0) | 
 | 2173 |              || (MapController ((byte)(relatedPLCIvalue & 0x7f)) == 0) | 
 | 2174 |              || (MapController ((byte)(relatedPLCIvalue & 0x7f)) > max_adapter)) | 
 | 2175 |             { | 
 | 2176 |               if(SSreq==S_3PTY_END) | 
 | 2177 |               { | 
 | 2178 |                 dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI")); | 
 | 2179 |                 rplci = plci; | 
 | 2180 |               } | 
 | 2181 |               else | 
 | 2182 |               { | 
 | 2183 |                 Info = 0x3010;                    /* wrong state           */ | 
 | 2184 |                 break; | 
 | 2185 |               } | 
 | 2186 |             } | 
 | 2187 |             else | 
 | 2188 |             {   | 
 | 2189 |               relatedadapter = &adapter[MapController ((byte)(relatedPLCIvalue & 0x7f))-1]; | 
 | 2190 |               relatedPLCIvalue >>=8; | 
 | 2191 |               /* find PLCI PTR*/ | 
 | 2192 |               for(i=0,rplci=NULL;i<relatedadapter->max_plci;i++) | 
 | 2193 |               { | 
 | 2194 |                 if(relatedadapter->plci[i].Id == (byte)relatedPLCIvalue) | 
 | 2195 |                 { | 
 | 2196 |                   rplci = &relatedadapter->plci[i]; | 
 | 2197 |                 } | 
 | 2198 |               } | 
 | 2199 |               if(!rplci || !relatedPLCIvalue) | 
 | 2200 |               { | 
 | 2201 |                 if(SSreq==S_3PTY_END) | 
 | 2202 |                 { | 
 | 2203 |                   dbug(1, dprintf("use 2nd PLCI=PLCI")); | 
 | 2204 |                   rplci = plci; | 
 | 2205 |                 } | 
 | 2206 |                 else | 
 | 2207 |                 { | 
 | 2208 |                   Info = 0x3010;                    /* wrong state           */ | 
 | 2209 |                   break; | 
 | 2210 |                 } | 
 | 2211 |               } | 
 | 2212 |             } | 
 | 2213 | /* | 
 | 2214 |             dbug(1,dprintf("rplci:%x",rplci)); | 
 | 2215 |             dbug(1,dprintf("plci:%x",plci)); | 
 | 2216 |             dbug(1,dprintf("rplci->ptyState:%x",rplci->ptyState)); | 
 | 2217 |             dbug(1,dprintf("plci->ptyState:%x",plci->ptyState)); | 
 | 2218 |             dbug(1,dprintf("SSreq:%x",SSreq)); | 
 | 2219 |             dbug(1,dprintf("rplci->internal_command:%x",rplci->internal_command)); | 
 | 2220 |             dbug(1,dprintf("rplci->appl:%x",rplci->appl)); | 
 | 2221 |             dbug(1,dprintf("rplci->Id:%x",rplci->Id)); | 
 | 2222 | */ | 
 | 2223 |             /* send PTY/ECT req, cannot check all states because of US stuff */ | 
 | 2224 |             if( !rplci->internal_command && rplci->appl ) | 
 | 2225 |             { | 
 | 2226 |               plci->command = 0; | 
 | 2227 |               rplci->relatedPTYPLCI = plci; | 
 | 2228 |               plci->relatedPTYPLCI = rplci; | 
 | 2229 |               rplci->ptyState = (byte)SSreq; | 
 | 2230 |               if(SSreq==S_ECT) | 
 | 2231 |               { | 
 | 2232 |                 rplci->internal_command = ECT_REQ_PEND; | 
 | 2233 |                 cai[1] = ECT_EXECUTE; | 
 | 2234 |  | 
 | 2235 |                 rplci->vswitchstate=0; | 
 | 2236 |                 rplci->vsprot=0; | 
 | 2237 |                 rplci->vsprotdialect=0; | 
 | 2238 |                 plci->vswitchstate=0; | 
 | 2239 |                 plci->vsprot=0; | 
 | 2240 |                 plci->vsprotdialect=0; | 
 | 2241 |  | 
 | 2242 |               } | 
 | 2243 |               else if(SSreq==S_CONF_ADD) | 
 | 2244 |               { | 
 | 2245 |                 rplci->internal_command = CONF_ADD_REQ_PEND; | 
 | 2246 |                 cai[1] = CONF_ADD; | 
 | 2247 |               } | 
 | 2248 |               else | 
 | 2249 |               { | 
 | 2250 |                 rplci->internal_command = PTY_REQ_PEND; | 
 | 2251 |                 cai[1] = (byte)(SSreq-3); | 
 | 2252 |               } | 
 | 2253 |               rplci->number = Number; | 
 | 2254 |               if(plci!=rplci) /* explicit invocation */ | 
 | 2255 |               { | 
 | 2256 |                 cai[0] = 2; | 
 | 2257 |                 cai[2] = plci->Sig.Id; | 
 | 2258 |                 dbug(1,dprintf("explicit invocation")); | 
 | 2259 |               } | 
 | 2260 |               else | 
 | 2261 |               { | 
 | 2262 |                 dbug(1,dprintf("implicit invocation")); | 
 | 2263 |                 cai[0] = 1; | 
 | 2264 |               } | 
 | 2265 |               add_p(rplci,CAI,cai); | 
 | 2266 |               sig_req(rplci,S_SERVICE,0); | 
 | 2267 |               send_req(rplci); | 
 | 2268 |               return FALSE; | 
 | 2269 |             } | 
 | 2270 |             else | 
 | 2271 |             { | 
 | 2272 |               dbug(0,dprintf("Wrong line")); | 
 | 2273 |               Info = 0x3010;                    /* wrong state           */ | 
 | 2274 |               break; | 
 | 2275 |             } | 
 | 2276 |             break; | 
 | 2277 |  | 
 | 2278 |           case S_CALL_DEFLECTION: | 
 | 2279 |             if(api_parse(&parms->info[1],(word)parms->length,"wbwss",ss_parms)) | 
 | 2280 |             { | 
 | 2281 |               dbug(1,dprintf("format wrong")); | 
 | 2282 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 2283 |               break; | 
 | 2284 |             } | 
 | 2285 |             if (!plci) | 
 | 2286 |             { | 
 | 2287 |               Info = _WRONG_IDENTIFIER; | 
 | 2288 |               break; | 
 | 2289 |             } | 
 | 2290 |             /* reuse unused screening indicator */ | 
 | 2291 |             ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0])); | 
 | 2292 |             plci->command = 0; | 
 | 2293 |             plci->internal_command = CD_REQ_PEND; | 
 | 2294 |             appl->CDEnable = TRUE; | 
 | 2295 |             cai[0] = 1; | 
 | 2296 |             cai[1] = CALL_DEFLECTION; | 
 | 2297 |             add_p(plci,CAI,cai); | 
 | 2298 |             add_p(plci,CPN,ss_parms[3].info); | 
 | 2299 |             sig_req(plci,S_SERVICE,0); | 
 | 2300 |             send_req(plci); | 
 | 2301 |             return FALSE; | 
 | 2302 |             break; | 
 | 2303 |  | 
 | 2304 |           case S_CALL_FORWARDING_START: | 
 | 2305 |             if(api_parse(&parms->info[1],(word)parms->length,"wbdwwsss",ss_parms)) | 
 | 2306 |             { | 
 | 2307 |               dbug(1,dprintf("format wrong")); | 
 | 2308 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 2309 |               break; | 
 | 2310 |             } | 
 | 2311 |  | 
 | 2312 |             if((i=get_plci(a))) | 
 | 2313 |             { | 
 | 2314 |               rplci = &a->plci[i-1]; | 
 | 2315 |               rplci->appl = appl; | 
 | 2316 |               add_p(rplci,CAI,"\x01\x80"); | 
 | 2317 |               add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 2318 |               sig_req(rplci,ASSIGN,DSIG_ID); | 
 | 2319 |               send_req(rplci); | 
 | 2320 |             } | 
 | 2321 |             else | 
 | 2322 |             { | 
 | 2323 |               Info = _OUT_OF_PLCI; | 
 | 2324 |               break; | 
 | 2325 |             } | 
 | 2326 |  | 
 | 2327 |             /* reuse unused screening indicator */ | 
 | 2328 |             rplci->internal_command = CF_START_PEND; | 
 | 2329 |             rplci->appl = appl; | 
 | 2330 |             rplci->number = Number; | 
 | 2331 |             appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0])); | 
 | 2332 |             cai[0] = 2; | 
 | 2333 |             cai[1] = 0x70|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ | 
 | 2334 |             cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */ | 
 | 2335 |             add_p(rplci,CAI,cai); | 
 | 2336 |             add_p(rplci,OAD,ss_parms[5].info); | 
 | 2337 |             add_p(rplci,CPN,ss_parms[6].info); | 
 | 2338 |             sig_req(rplci,S_SERVICE,0); | 
 | 2339 |             send_req(rplci); | 
 | 2340 |             return FALSE; | 
 | 2341 |             break; | 
 | 2342 |  | 
 | 2343 |           case S_INTERROGATE_DIVERSION: | 
 | 2344 |           case S_INTERROGATE_NUMBERS: | 
 | 2345 |           case S_CALL_FORWARDING_STOP: | 
 | 2346 |           case S_CCBS_REQUEST: | 
 | 2347 |           case S_CCBS_DEACTIVATE: | 
 | 2348 |           case S_CCBS_INTERROGATE: | 
 | 2349 |             switch(SSreq) | 
 | 2350 |             { | 
 | 2351 |             case S_INTERROGATE_NUMBERS: | 
 | 2352 |                 if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms)) | 
 | 2353 |                 { | 
 | 2354 |                   dbug(0,dprintf("format wrong")); | 
 | 2355 |                   Info = _WRONG_MESSAGE_FORMAT; | 
 | 2356 |                 } | 
 | 2357 |                 break; | 
 | 2358 |             case S_CCBS_REQUEST: | 
 | 2359 |             case S_CCBS_DEACTIVATE: | 
 | 2360 |                 if(api_parse(&parms->info[1],(word)parms->length,"wbdw",ss_parms)) | 
 | 2361 |                 { | 
 | 2362 |                   dbug(0,dprintf("format wrong")); | 
 | 2363 |                   Info = _WRONG_MESSAGE_FORMAT; | 
 | 2364 |                 } | 
 | 2365 |                 break; | 
 | 2366 |             case S_CCBS_INTERROGATE: | 
 | 2367 |                 if(api_parse(&parms->info[1],(word)parms->length,"wbdws",ss_parms)) | 
 | 2368 |                 { | 
 | 2369 |                   dbug(0,dprintf("format wrong")); | 
 | 2370 |                   Info = _WRONG_MESSAGE_FORMAT; | 
 | 2371 |                 } | 
 | 2372 |                 break; | 
 | 2373 |             default: | 
 | 2374 |             if(api_parse(&parms->info[1],(word)parms->length,"wbdwws",ss_parms)) | 
 | 2375 |             { | 
 | 2376 |               dbug(0,dprintf("format wrong")); | 
 | 2377 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 2378 |               break; | 
 | 2379 |             } | 
 | 2380 |                 break; | 
 | 2381 |             } | 
 | 2382 |  | 
 | 2383 |             if(Info) break; | 
 | 2384 |             if((i=get_plci(a))) | 
 | 2385 |             { | 
 | 2386 |               rplci = &a->plci[i-1]; | 
 | 2387 |               switch(SSreq) | 
 | 2388 |               { | 
 | 2389 |                 case S_INTERROGATE_DIVERSION: /* use cai with S_SERVICE below */ | 
 | 2390 |                   cai[1] = 0x60|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ | 
 | 2391 |                   rplci->internal_command = INTERR_DIVERSION_REQ_PEND; /* move to rplci if assigned */ | 
 | 2392 |                   break; | 
 | 2393 |                 case S_INTERROGATE_NUMBERS: /* use cai with S_SERVICE below */ | 
 | 2394 |                   cai[1] = DIVERSION_INTERROGATE_NUM; /* Function */ | 
 | 2395 |                   rplci->internal_command = INTERR_NUMBERS_REQ_PEND; /* move to rplci if assigned */ | 
 | 2396 |                   break; | 
 | 2397 |                 case S_CALL_FORWARDING_STOP: | 
 | 2398 |                   rplci->internal_command = CF_STOP_PEND; | 
 | 2399 |                   cai[1] = 0x80|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ | 
 | 2400 |                   break; | 
 | 2401 |                 case S_CCBS_REQUEST: | 
 | 2402 |                   cai[1] = CCBS_REQUEST; | 
 | 2403 |                   rplci->internal_command = CCBS_REQUEST_REQ_PEND; | 
 | 2404 |                   break; | 
 | 2405 |                 case S_CCBS_DEACTIVATE: | 
 | 2406 |                   cai[1] = CCBS_DEACTIVATE; | 
 | 2407 |                   rplci->internal_command = CCBS_DEACTIVATE_REQ_PEND; | 
 | 2408 |                   break; | 
 | 2409 |                 case S_CCBS_INTERROGATE: | 
 | 2410 |                   cai[1] = CCBS_INTERROGATE; | 
 | 2411 |                   rplci->internal_command = CCBS_INTERROGATE_REQ_PEND; | 
 | 2412 |                   break; | 
 | 2413 |                 default: | 
 | 2414 |                   cai[1] = 0; | 
 | 2415 |                 break; | 
 | 2416 |               } | 
 | 2417 |               rplci->appl = appl; | 
 | 2418 |               rplci->number = Number; | 
 | 2419 |               add_p(rplci,CAI,"\x01\x80"); | 
 | 2420 |               add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 2421 |               sig_req(rplci,ASSIGN,DSIG_ID); | 
 | 2422 |               send_req(rplci); | 
 | 2423 |             } | 
 | 2424 |             else | 
 | 2425 |             { | 
 | 2426 |               Info = _OUT_OF_PLCI; | 
 | 2427 |               break; | 
 | 2428 |             } | 
 | 2429 |  | 
 | 2430 |             appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0])); | 
 | 2431 |             switch(SSreq) | 
 | 2432 |             { | 
 | 2433 |             case S_INTERROGATE_NUMBERS: | 
 | 2434 |                 cai[0] = 1; | 
 | 2435 |                 add_p(rplci,CAI,cai); | 
 | 2436 |                 break; | 
 | 2437 |             case S_CCBS_REQUEST: | 
 | 2438 |             case S_CCBS_DEACTIVATE: | 
 | 2439 |                 cai[0] = 3; | 
 | 2440 |                 PUT_WORD(&cai[2],GET_WORD(&(ss_parms[3].info[0]))); | 
 | 2441 |                 add_p(rplci,CAI,cai); | 
 | 2442 |                 break; | 
 | 2443 |             case S_CCBS_INTERROGATE: | 
 | 2444 |                 cai[0] = 3; | 
 | 2445 |                 PUT_WORD(&cai[2],GET_WORD(&(ss_parms[3].info[0]))); | 
 | 2446 |                 add_p(rplci,CAI,cai); | 
 | 2447 |                 add_p(rplci,OAD,ss_parms[4].info); | 
 | 2448 |                 break; | 
 | 2449 |             default: | 
 | 2450 |             cai[0] = 2; | 
 | 2451 |             cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */ | 
 | 2452 |             add_p(rplci,CAI,cai); | 
 | 2453 |             add_p(rplci,OAD,ss_parms[5].info); | 
 | 2454 |                 break; | 
 | 2455 |             } | 
 | 2456 |                          | 
 | 2457 |             sig_req(rplci,S_SERVICE,0); | 
 | 2458 |             send_req(rplci); | 
 | 2459 |             return FALSE; | 
 | 2460 |             break; | 
 | 2461 |  | 
 | 2462 |           case S_MWI_ACTIVATE: | 
 | 2463 |             if(api_parse(&parms->info[1],(word)parms->length,"wbwdwwwssss",ss_parms)) | 
 | 2464 |             { | 
 | 2465 |               dbug(1,dprintf("format wrong")); | 
 | 2466 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 2467 |               break; | 
 | 2468 |             } | 
 | 2469 |             if(!plci) | 
 | 2470 |             {                                | 
 | 2471 |               if((i=get_plci(a))) | 
 | 2472 |               { | 
 | 2473 |                 rplci = &a->plci[i-1]; | 
 | 2474 |                 rplci->appl = appl; | 
 | 2475 |                 rplci->cr_enquiry=TRUE; | 
 | 2476 |                 add_p(rplci,CAI,"\x01\x80"); | 
 | 2477 |                 add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 2478 |                 sig_req(rplci,ASSIGN,DSIG_ID); | 
 | 2479 |                 send_req(rplci); | 
 | 2480 |               } | 
 | 2481 |               else | 
 | 2482 |               { | 
 | 2483 |                 Info = _OUT_OF_PLCI; | 
 | 2484 |                 break; | 
 | 2485 |               } | 
 | 2486 |             } | 
 | 2487 |             else | 
 | 2488 |             { | 
 | 2489 |               rplci = plci; | 
 | 2490 |               rplci->cr_enquiry=FALSE; | 
 | 2491 |             } | 
 | 2492 |  | 
 | 2493 |             rplci->command = 0; | 
 | 2494 |             rplci->internal_command = MWI_ACTIVATE_REQ_PEND; | 
 | 2495 |             rplci->appl = appl; | 
 | 2496 |             rplci->number = Number; | 
 | 2497 |  | 
 | 2498 |             cai[0] = 13; | 
 | 2499 |             cai[1] = ACTIVATION_MWI; /* Function */ | 
 | 2500 |             PUT_WORD(&cai[2],GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */ | 
 | 2501 |             PUT_DWORD(&cai[4],GET_DWORD(&(ss_parms[3].info[0]))); /* Number of Messages */ | 
 | 2502 |             PUT_WORD(&cai[8],GET_WORD(&(ss_parms[4].info[0]))); /* Message Status */ | 
 | 2503 |             PUT_WORD(&cai[10],GET_WORD(&(ss_parms[5].info[0]))); /* Message Reference */ | 
 | 2504 |             PUT_WORD(&cai[12],GET_WORD(&(ss_parms[6].info[0]))); /* Invocation Mode */ | 
 | 2505 |             add_p(rplci,CAI,cai); | 
 | 2506 |             add_p(rplci,CPN,ss_parms[7].info); /* Receiving User Number */ | 
 | 2507 |             add_p(rplci,OAD,ss_parms[8].info); /* Controlling User Number */ | 
 | 2508 |             add_p(rplci,OSA,ss_parms[9].info); /* Controlling User Provided Number */ | 
 | 2509 |             add_p(rplci,UID,ss_parms[10].info); /* Time */ | 
 | 2510 |             sig_req(rplci,S_SERVICE,0); | 
 | 2511 |             send_req(rplci); | 
 | 2512 |             return FALSE; | 
 | 2513 |  | 
 | 2514 |           case S_MWI_DEACTIVATE: | 
 | 2515 |             if(api_parse(&parms->info[1],(word)parms->length,"wbwwss",ss_parms)) | 
 | 2516 |             { | 
 | 2517 |               dbug(1,dprintf("format wrong")); | 
 | 2518 |               Info = _WRONG_MESSAGE_FORMAT; | 
 | 2519 |               break; | 
 | 2520 |             } | 
 | 2521 |             if(!plci) | 
 | 2522 |             {                                | 
 | 2523 |               if((i=get_plci(a))) | 
 | 2524 |               { | 
 | 2525 |                 rplci = &a->plci[i-1]; | 
 | 2526 |                 rplci->appl = appl; | 
 | 2527 |                 rplci->cr_enquiry=TRUE; | 
 | 2528 |                 add_p(rplci,CAI,"\x01\x80"); | 
 | 2529 |                 add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 2530 |                 sig_req(rplci,ASSIGN,DSIG_ID); | 
 | 2531 |                 send_req(rplci); | 
 | 2532 |               } | 
 | 2533 |               else | 
 | 2534 |               { | 
 | 2535 |                 Info = _OUT_OF_PLCI; | 
 | 2536 |                 break; | 
 | 2537 |               } | 
 | 2538 |             } | 
 | 2539 |             else | 
 | 2540 |             { | 
 | 2541 |               rplci = plci; | 
 | 2542 |               rplci->cr_enquiry=FALSE; | 
 | 2543 |             } | 
 | 2544 |  | 
 | 2545 |             rplci->command = 0; | 
 | 2546 |             rplci->internal_command = MWI_DEACTIVATE_REQ_PEND; | 
 | 2547 |             rplci->appl = appl; | 
 | 2548 |             rplci->number = Number; | 
 | 2549 |  | 
 | 2550 |             cai[0] = 5; | 
 | 2551 |             cai[1] = DEACTIVATION_MWI; /* Function */ | 
 | 2552 |             PUT_WORD(&cai[2],GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */ | 
 | 2553 |             PUT_WORD(&cai[4],GET_WORD(&(ss_parms[3].info[0]))); /* Invocation Mode */ | 
 | 2554 |             add_p(rplci,CAI,cai); | 
 | 2555 |             add_p(rplci,CPN,ss_parms[4].info); /* Receiving User Number */ | 
 | 2556 |             add_p(rplci,OAD,ss_parms[5].info); /* Controlling User Number */ | 
 | 2557 |             sig_req(rplci,S_SERVICE,0); | 
 | 2558 |             send_req(rplci); | 
 | 2559 |             return FALSE; | 
 | 2560 |  | 
 | 2561 |           default: | 
 | 2562 |             Info = 0x300E;  /* not supported */ | 
 | 2563 |             break; | 
 | 2564 |         } | 
 | 2565 |         break; /* case SELECTOR_SU_SERV: end */ | 
 | 2566 |  | 
 | 2567 |  | 
 | 2568 |       case SELECTOR_DTMF: | 
 | 2569 |         return (dtmf_request (Id, Number, a, plci, appl, msg)); | 
 | 2570 |  | 
 | 2571 |  | 
 | 2572 |  | 
 | 2573 |       case SELECTOR_LINE_INTERCONNECT: | 
 | 2574 |         return (mixer_request (Id, Number, a, plci, appl, msg)); | 
 | 2575 |  | 
 | 2576 |  | 
 | 2577 |  | 
 | 2578 |       case PRIV_SELECTOR_ECHO_CANCELLER: | 
 | 2579 |         appl->appl_flags |= APPL_FLAG_PRIV_EC_SPEC; | 
 | 2580 |         return (ec_request (Id, Number, a, plci, appl, msg)); | 
 | 2581 |  | 
 | 2582 |       case SELECTOR_ECHO_CANCELLER: | 
 | 2583 |         appl->appl_flags &= ~APPL_FLAG_PRIV_EC_SPEC; | 
 | 2584 |         return (ec_request (Id, Number, a, plci, appl, msg)); | 
 | 2585 |  | 
 | 2586 |  | 
 | 2587 |       case SELECTOR_V42BIS: | 
 | 2588 |       default: | 
 | 2589 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 2590 |         break; | 
 | 2591 |     } /* end of switch(selector) */ | 
 | 2592 |   } | 
 | 2593 |  | 
 | 2594 |   dbug(1,dprintf("SendFacRc")); | 
 | 2595 |   sendf(appl, | 
 | 2596 |         _FACILITY_R|CONFIRM, | 
 | 2597 |         Id, | 
 | 2598 |         Number, | 
 | 2599 |         "wws",Info,selector,SSparms); | 
 | 2600 |   return FALSE; | 
 | 2601 | } | 
 | 2602 |  | 
 | 2603 | byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 2604 | { | 
 | 2605 |   dbug(1,dprintf("facility_res")); | 
 | 2606 |   return FALSE; | 
 | 2607 | } | 
 | 2608 |  | 
 | 2609 | byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 2610 | { | 
 | 2611 |   word Info = 0; | 
 | 2612 |   byte req; | 
 | 2613 |   byte len; | 
 | 2614 |   word w; | 
 | 2615 |   word fax_control_bits, fax_feature_bits, fax_info_change; | 
 | 2616 |   API_PARSE * ncpi; | 
 | 2617 |     byte pvc[2]; | 
 | 2618 |  | 
 | 2619 |     API_PARSE fax_parms[9]; | 
 | 2620 |   word i; | 
 | 2621 |  | 
 | 2622 |  | 
 | 2623 |   dbug(1,dprintf("connect_b3_req")); | 
 | 2624 |   if(plci) | 
 | 2625 |   { | 
 | 2626 |     if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) | 
 | 2627 |      || (plci->State == INC_DIS_PENDING) || (plci->SuppState != IDLE)) | 
 | 2628 |     { | 
 | 2629 |       Info = _WRONG_STATE; | 
 | 2630 |     } | 
 | 2631 |     else | 
 | 2632 |     { | 
 | 2633 |       /* local reply if assign unsuccessfull | 
 | 2634 |          or B3 protocol allows only one layer 3 connection | 
 | 2635 |            and already connected | 
 | 2636 |              or B2 protocol not any LAPD | 
 | 2637 |                and connect_b3_req contradicts originate/answer direction */ | 
 | 2638 |       if (!plci->NL.Id | 
 | 2639 |        || (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)) | 
 | 2640 |         && ((plci->channels != 0) | 
 | 2641 |          || (((plci->B2_prot != B2_SDLC) && (plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL)) | 
 | 2642 |           && ((plci->call_dir & CALL_DIR_ANSWER) && !(plci->call_dir & CALL_DIR_FORCE_OUTG_NL)))))) | 
 | 2643 |       { | 
 | 2644 |         dbug(1,dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x", | 
 | 2645 |                        plci->channels,plci->NL.Id,plci->call_dir,plci->SuppState)); | 
 | 2646 |         Info = _WRONG_STATE; | 
 | 2647 |         sendf(appl,                                                         | 
 | 2648 |               _CONNECT_B3_R|CONFIRM, | 
 | 2649 |               Id, | 
 | 2650 |               Number, | 
 | 2651 |               "w",Info); | 
 | 2652 |         return FALSE; | 
 | 2653 |       } | 
 | 2654 |       plci->requested_options_conn = 0; | 
 | 2655 |  | 
 | 2656 |       req = N_CONNECT; | 
 | 2657 |       ncpi = &parms[0]; | 
 | 2658 |       if(plci->B3_prot==2 || plci->B3_prot==3) | 
 | 2659 |       { | 
 | 2660 |         if(ncpi->length>2) | 
 | 2661 |         { | 
 | 2662 |           /* check for PVC */ | 
 | 2663 |           if(ncpi->info[2] || ncpi->info[3]) | 
 | 2664 |           { | 
 | 2665 |             pvc[0] = ncpi->info[3]; | 
 | 2666 |             pvc[1] = ncpi->info[2]; | 
 | 2667 |             add_d(plci,2,pvc); | 
 | 2668 |             req = N_RESET; | 
 | 2669 |           } | 
 | 2670 |           else | 
 | 2671 |           { | 
 | 2672 |             if(ncpi->info[1] &1) req = N_CONNECT | N_D_BIT; | 
 | 2673 |             add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]); | 
 | 2674 |           } | 
 | 2675 |         } | 
 | 2676 |       } | 
 | 2677 |       else if(plci->B3_prot==5) | 
 | 2678 |       { | 
 | 2679 |         if (plci->NL.Id && !plci->nl_remove_id) | 
 | 2680 |         { | 
 | 2681 |           fax_control_bits = GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low); | 
 | 2682 |           fax_feature_bits = GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->feature_bits_low); | 
 | 2683 |           if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS) | 
 | 2684 |            || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)) | 
 | 2685 |           { | 
 | 2686 |             len = (byte)(&(((T30_INFO *) 0)->universal_6)); | 
 | 2687 |             fax_info_change = FALSE; | 
 | 2688 |             if (ncpi->length >= 4) | 
 | 2689 |             { | 
 | 2690 |               w = GET_WORD(&ncpi->info[3]); | 
 | 2691 |               if ((w & 0x0001) != ((word)(((T30_INFO   *)(plci->fax_connect_info_buffer))->resolution & 0x0001))) | 
 | 2692 |               { | 
 | 2693 |                 ((T30_INFO   *)(plci->fax_connect_info_buffer))->resolution = | 
 | 2694 |                   (byte)((((T30_INFO   *)(plci->fax_connect_info_buffer))->resolution & ~T30_RESOLUTION_R8_0770_OR_200) | | 
 | 2695 |                   ((w & 0x0001) ? T30_RESOLUTION_R8_0770_OR_200 : 0)); | 
 | 2696 |                 fax_info_change = TRUE; | 
 | 2697 |               } | 
 | 2698 |               fax_control_bits &= ~(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS); | 
 | 2699 |               if (w & 0x0002)  /* Fax-polling request */ | 
 | 2700 |                 fax_control_bits |= T30_CONTROL_BIT_REQUEST_POLLING; | 
 | 2701 |               if ((w & 0x0004) /* Request to send / poll another document */ | 
 | 2702 |                && (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS)) | 
 | 2703 |               { | 
 | 2704 |                 fax_control_bits |= T30_CONTROL_BIT_MORE_DOCUMENTS; | 
 | 2705 |               } | 
 | 2706 |               if (ncpi->length >= 6) | 
 | 2707 |               { | 
 | 2708 |                 w = GET_WORD(&ncpi->info[5]); | 
 | 2709 |                 if (((byte) w) != ((T30_INFO   *)(plci->fax_connect_info_buffer))->data_format) | 
 | 2710 |                 { | 
 | 2711 |                   ((T30_INFO   *)(plci->fax_connect_info_buffer))->data_format = (byte) w; | 
 | 2712 |                   fax_info_change = TRUE; | 
 | 2713 |                 } | 
 | 2714 |  | 
 | 2715 |                 if ((a->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD)) | 
 | 2716 |                  && (GET_WORD(&ncpi->info[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */ | 
 | 2717 |                 { | 
 | 2718 |                   plci->requested_options_conn |= (1L << PRIVATE_FAX_SUB_SEP_PWD); | 
 | 2719 |                 } | 
 | 2720 |                 if ((a->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD)) | 
 | 2721 |                  && (GET_WORD(&ncpi->info[5]) & 0x4000)) /* Private non-standard facilities enable */ | 
 | 2722 |                 { | 
 | 2723 |                   plci->requested_options_conn |= (1L << PRIVATE_FAX_NONSTANDARD); | 
 | 2724 |                 } | 
 | 2725 |                 fax_control_bits &= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_SEL_POLLING | | 
 | 2726 |                   T30_CONTROL_BIT_ACCEPT_PASSWORD); | 
 | 2727 |                 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1]) | 
 | 2728 |                   & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) | 
 | 2729 |                 { | 
 | 2730 |                   if (api_parse (&ncpi->info[1], ncpi->length, "wwwwsss", fax_parms)) | 
 | 2731 |                     Info = _WRONG_MESSAGE_FORMAT; | 
 | 2732 |                   else | 
 | 2733 |                   { | 
 | 2734 |                     if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1]) | 
 | 2735 |                       & (1L << PRIVATE_FAX_SUB_SEP_PWD)) | 
 | 2736 |       { | 
 | 2737 |                     fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD; | 
 | 2738 |                     if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING) | 
 | 2739 |                       fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; | 
 | 2740 |       } | 
 | 2741 |                     w = fax_parms[4].length; | 
 | 2742 |                     if (w > 20) | 
 | 2743 |                       w = 20; | 
 | 2744 |                     ((T30_INFO   *)(plci->fax_connect_info_buffer))->station_id_len = (byte) w; | 
 | 2745 |                     for (i = 0; i < w; i++) | 
 | 2746 |                       ((T30_INFO   *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i]; | 
 | 2747 |                     ((T30_INFO   *)(plci->fax_connect_info_buffer))->head_line_len = 0; | 
 | 2748 |                     len = (byte)(((T30_INFO *) 0)->station_id + 20); | 
 | 2749 |                     w = fax_parms[5].length; | 
 | 2750 |                     if (w > 20) | 
 | 2751 |                       w = 20; | 
 | 2752 |                     plci->fax_connect_info_buffer[len++] = (byte) w; | 
 | 2753 |                     for (i = 0; i < w; i++) | 
 | 2754 |                       plci->fax_connect_info_buffer[len++] = fax_parms[5].info[1+i]; | 
 | 2755 |                     w = fax_parms[6].length; | 
 | 2756 |                     if (w > 20) | 
 | 2757 |                       w = 20; | 
 | 2758 |                     plci->fax_connect_info_buffer[len++] = (byte) w; | 
 | 2759 |                     for (i = 0; i < w; i++) | 
 | 2760 |                       plci->fax_connect_info_buffer[len++] = fax_parms[6].info[1+i]; | 
 | 2761 |                     if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1]) | 
 | 2762 |                       & (1L << PRIVATE_FAX_NONSTANDARD)) | 
 | 2763 |       { | 
 | 2764 |                       if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) | 
 | 2765 |         { | 
 | 2766 |                         dbug(1,dprintf("non-standard facilities info missing or wrong format")); | 
 | 2767 |                         plci->fax_connect_info_buffer[len++] = 0; | 
 | 2768 |         } | 
 | 2769 |                       else | 
 | 2770 |                       { | 
 | 2771 |           if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) | 
 | 2772 |             plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); | 
 | 2773 |    plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); | 
 | 2774 |           for (i = 0; i < fax_parms[7].length; i++) | 
 | 2775 |      plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i]; | 
 | 2776 |                       } | 
 | 2777 |                     } | 
 | 2778 |                   } | 
 | 2779 |                 } | 
 | 2780 |                 else | 
 | 2781 |                 { | 
 | 2782 |                   len = (byte)(&(((T30_INFO *) 0)->universal_6)); | 
 | 2783 |                 } | 
 | 2784 |                 fax_info_change = TRUE; | 
 | 2785 |  | 
 | 2786 |               } | 
 | 2787 |               if (fax_control_bits != GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low)) | 
 | 2788 |               { | 
 | 2789 |                 PUT_WORD (&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits); | 
 | 2790 |                 fax_info_change = TRUE; | 
 | 2791 |               } | 
 | 2792 |             } | 
 | 2793 |             if (Info == GOOD) | 
 | 2794 |             { | 
 | 2795 |               plci->fax_connect_info_length = len; | 
 | 2796 |               if (fax_info_change) | 
 | 2797 |               { | 
 | 2798 |                 if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS) | 
 | 2799 |                 { | 
 | 2800 |                   start_internal_command (Id, plci, fax_connect_info_command); | 
 | 2801 |                   return FALSE; | 
 | 2802 |                 } | 
 | 2803 |                 else | 
 | 2804 |                 { | 
 | 2805 |                   start_internal_command (Id, plci, fax_adjust_b23_command); | 
 | 2806 |                   return FALSE; | 
 | 2807 |                 } | 
 | 2808 |               } | 
 | 2809 |             } | 
 | 2810 |           } | 
 | 2811 |           else  Info = _WRONG_STATE; | 
 | 2812 |         } | 
 | 2813 |         else  Info = _WRONG_STATE; | 
 | 2814 |       } | 
 | 2815 |  | 
 | 2816 |       else if (plci->B3_prot == B3_RTP) | 
 | 2817 |       { | 
 | 2818 |         plci->internal_req_buffer[0] = ncpi->length + 1; | 
 | 2819 |         plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE; | 
 | 2820 |         for (w = 0; w < ncpi->length; w++) | 
 | 2821 |           plci->internal_req_buffer[2+w] = ncpi->info[1+w]; | 
 | 2822 |         start_internal_command (Id, plci, rtp_connect_b3_req_command); | 
 | 2823 |         return FALSE; | 
 | 2824 |       } | 
 | 2825 |  | 
 | 2826 |       if(!Info) | 
 | 2827 |       { | 
 | 2828 |         nl_req_ncci(plci,req,0); | 
 | 2829 |         return 1; | 
 | 2830 |       } | 
 | 2831 |     } | 
 | 2832 |   } | 
 | 2833 |   else Info = _WRONG_IDENTIFIER; | 
 | 2834 |  | 
 | 2835 |   sendf(appl, | 
 | 2836 |         _CONNECT_B3_R|CONFIRM, | 
 | 2837 |         Id, | 
 | 2838 |         Number, | 
 | 2839 |         "w",Info); | 
 | 2840 |   return FALSE; | 
 | 2841 | } | 
 | 2842 |  | 
 | 2843 | byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 2844 | { | 
 | 2845 |   word ncci; | 
 | 2846 |   API_PARSE * ncpi; | 
 | 2847 |   byte req; | 
 | 2848 |  | 
 | 2849 |   word w; | 
 | 2850 |  | 
 | 2851 |  | 
 | 2852 |     API_PARSE fax_parms[9]; | 
 | 2853 |   word i; | 
 | 2854 |   byte len; | 
 | 2855 |  | 
 | 2856 |  | 
 | 2857 |   dbug(1,dprintf("connect_b3_res")); | 
 | 2858 |  | 
 | 2859 |   ncci = (word)(Id>>16); | 
 | 2860 |   if(plci && ncci) { | 
 | 2861 |     if(a->ncci_state[ncci]==INC_CON_PENDING) { | 
 | 2862 |       if (GET_WORD (&parms[0].info[0]) != 0) | 
 | 2863 |       { | 
 | 2864 |         a->ncci_state[ncci] = OUTG_REJ_PENDING; | 
 | 2865 |         channel_request_xon (plci, a->ncci_ch[ncci]); | 
 | 2866 |         channel_xmit_xon (plci); | 
 | 2867 |         cleanup_ncci_data (plci, ncci); | 
 | 2868 |         nl_req_ncci(plci,N_DISC,(byte)ncci); | 
 | 2869 |         return 1; | 
 | 2870 |       } | 
 | 2871 |       a->ncci_state[ncci] = INC_ACT_PENDING; | 
 | 2872 |  | 
 | 2873 |       req = N_CONNECT_ACK; | 
 | 2874 |       ncpi = &parms[1]; | 
 | 2875 |       if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7)) | 
 | 2876 |       { | 
 | 2877 |  | 
 | 2878 |         if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) | 
 | 2879 |           & (1L << PRIVATE_FAX_NONSTANDARD)) | 
 | 2880 |  { | 
 | 2881 |    if (((plci->B3_prot == 4) || (plci->B3_prot == 5)) | 
 | 2882 |     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) | 
 | 2883 |     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) | 
 | 2884 |    { | 
 | 2885 |             len = ((byte)(((T30_INFO *) 0)->station_id + 20)); | 
 | 2886 |             if (plci->fax_connect_info_length < len) | 
 | 2887 |             { | 
 | 2888 |               ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; | 
 | 2889 |               ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; | 
 | 2890 |             } | 
 | 2891 |             if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) | 
 | 2892 |             { | 
 | 2893 |               dbug(1,dprintf("non-standard facilities info missing or wrong format")); | 
 | 2894 |             } | 
 | 2895 |             else | 
 | 2896 |             { | 
 | 2897 |               if (plci->fax_connect_info_length <= len) | 
 | 2898 |                 plci->fax_connect_info_buffer[len] = 0; | 
 | 2899 |               len += 1 + plci->fax_connect_info_buffer[len]; | 
 | 2900 |               if (plci->fax_connect_info_length <= len) | 
 | 2901 |                 plci->fax_connect_info_buffer[len] = 0; | 
 | 2902 |               len += 1 + plci->fax_connect_info_buffer[len]; | 
 | 2903 |               if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) | 
 | 2904 |                 plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); | 
 | 2905 |               plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); | 
 | 2906 |               for (i = 0; i < fax_parms[7].length; i++) | 
 | 2907 |                 plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i]; | 
 | 2908 |             } | 
 | 2909 |             plci->fax_connect_info_length = len; | 
 | 2910 |             ((T30_INFO *)(plci->fax_connect_info_buffer))->code = 0; | 
 | 2911 |             start_internal_command (Id, plci, fax_connect_ack_command); | 
 | 2912 |      return FALSE; | 
 | 2913 |           } | 
 | 2914 |         } | 
 | 2915 |  | 
 | 2916 |         nl_req_ncci(plci,req,(byte)ncci); | 
 | 2917 |         if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) | 
 | 2918 |          && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) | 
 | 2919 |         { | 
 | 2920 |           if (plci->B3_prot == 4) | 
 | 2921 |             sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); | 
 | 2922 |           else | 
 | 2923 |             sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); | 
 | 2924 |           plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; | 
 | 2925 |         } | 
 | 2926 |       } | 
 | 2927 |  | 
 | 2928 |       else if (plci->B3_prot == B3_RTP) | 
 | 2929 |       { | 
 | 2930 |         plci->internal_req_buffer[0] = ncpi->length + 1; | 
 | 2931 |         plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE; | 
 | 2932 |         for (w = 0; w < ncpi->length; w++) | 
 | 2933 |           plci->internal_req_buffer[2+w] = ncpi->info[1+w]; | 
 | 2934 |         start_internal_command (Id, plci, rtp_connect_b3_res_command); | 
 | 2935 |         return FALSE; | 
 | 2936 |       } | 
 | 2937 |  | 
 | 2938 |       else | 
 | 2939 |       { | 
 | 2940 |         if(ncpi->length>2) { | 
 | 2941 |           if(ncpi->info[1] &1) req = N_CONNECT_ACK | N_D_BIT; | 
 | 2942 |           add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]); | 
 | 2943 |         } | 
 | 2944 |         nl_req_ncci(plci,req,(byte)ncci); | 
 | 2945 |         sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); | 
 | 2946 |         if (plci->adjust_b_restore) | 
 | 2947 |         { | 
 | 2948 |           plci->adjust_b_restore = FALSE; | 
 | 2949 |           start_internal_command (Id, plci, adjust_b_restore); | 
 | 2950 |         } | 
 | 2951 |       } | 
 | 2952 |       return 1; | 
 | 2953 |     } | 
 | 2954 |   } | 
 | 2955 |   return FALSE; | 
 | 2956 | } | 
 | 2957 |  | 
 | 2958 | byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 2959 | { | 
 | 2960 |   word ncci; | 
 | 2961 |  | 
 | 2962 |   ncci = (word)(Id>>16); | 
 | 2963 |   dbug(1,dprintf("connect_b3_a_res(ncci=0x%x)",ncci)); | 
 | 2964 |  | 
 | 2965 |   if (plci && ncci && (plci->State != IDLE) && (plci->State != INC_DIS_PENDING) | 
 | 2966 |    && (plci->State != OUTG_DIS_PENDING)) | 
 | 2967 |   { | 
 | 2968 |     if(a->ncci_state[ncci]==INC_ACT_PENDING) { | 
 | 2969 |       a->ncci_state[ncci] = CONNECTED; | 
 | 2970 |       if(plci->State!=INC_CON_CONNECTED_ALERT) plci->State = CONNECTED; | 
 | 2971 |       channel_request_xon (plci, a->ncci_ch[ncci]); | 
 | 2972 |       channel_xmit_xon (plci); | 
 | 2973 |     } | 
 | 2974 |   } | 
 | 2975 |   return FALSE; | 
 | 2976 | } | 
 | 2977 |  | 
 | 2978 | byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 2979 | { | 
 | 2980 |   word Info; | 
 | 2981 |   word ncci; | 
 | 2982 |   API_PARSE * ncpi; | 
 | 2983 |  | 
 | 2984 |   dbug(1,dprintf("disconnect_b3_req")); | 
 | 2985 |  | 
 | 2986 |   Info = _WRONG_IDENTIFIER; | 
 | 2987 |   ncci = (word)(Id>>16); | 
 | 2988 |   if (plci && ncci) | 
 | 2989 |   { | 
 | 2990 |     Info = _WRONG_STATE; | 
 | 2991 |     if ((a->ncci_state[ncci] == CONNECTED) | 
 | 2992 |      || (a->ncci_state[ncci] == OUTG_CON_PENDING) | 
 | 2993 |      || (a->ncci_state[ncci] == INC_CON_PENDING) | 
 | 2994 |      || (a->ncci_state[ncci] == INC_ACT_PENDING)) | 
 | 2995 |     { | 
 | 2996 |       a->ncci_state[ncci] = OUTG_DIS_PENDING; | 
 | 2997 |       channel_request_xon (plci, a->ncci_ch[ncci]); | 
 | 2998 |       channel_xmit_xon (plci); | 
 | 2999 |  | 
 | 3000 |       if (a->ncci[ncci].data_pending | 
 | 3001 |        && ((plci->B3_prot == B3_TRANSPARENT) | 
 | 3002 |         || (plci->B3_prot == B3_T30) | 
 | 3003 |         || (plci->B3_prot == B3_T30_WITH_EXTENSIONS))) | 
 | 3004 |       { | 
 | 3005 |         plci->send_disc = (byte)ncci; | 
 | 3006 |         plci->command = 0; | 
 | 3007 |         return FALSE; | 
 | 3008 |       } | 
 | 3009 |       else | 
 | 3010 |       { | 
 | 3011 |         cleanup_ncci_data (plci, ncci); | 
 | 3012 |  | 
 | 3013 |         if(plci->B3_prot==2 || plci->B3_prot==3) | 
 | 3014 |         { | 
 | 3015 |           ncpi = &parms[0]; | 
 | 3016 |           if(ncpi->length>3) | 
 | 3017 |           { | 
 | 3018 |             add_d(plci, (word)(ncpi->length - 3) ,(byte   *)&(ncpi->info[4])); | 
 | 3019 |           } | 
 | 3020 |         } | 
 | 3021 |         nl_req_ncci(plci,N_DISC,(byte)ncci); | 
 | 3022 |       } | 
 | 3023 |       return 1; | 
 | 3024 |     } | 
 | 3025 |   } | 
 | 3026 |   sendf(appl, | 
 | 3027 |         _DISCONNECT_B3_R|CONFIRM, | 
 | 3028 |         Id, | 
 | 3029 |         Number, | 
 | 3030 |         "w",Info); | 
 | 3031 |   return FALSE; | 
 | 3032 | } | 
 | 3033 |  | 
 | 3034 | byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 3035 | { | 
 | 3036 |   word ncci; | 
 | 3037 |   word i; | 
 | 3038 |  | 
 | 3039 |   ncci = (word)(Id>>16); | 
 | 3040 |   dbug(1,dprintf("disconnect_b3_res(ncci=0x%x",ncci)); | 
 | 3041 |   if(plci && ncci) { | 
 | 3042 |     plci->requested_options_conn = 0; | 
 | 3043 |     plci->fax_connect_info_length = 0; | 
 | 3044 |     plci->ncpi_state = 0x00; | 
 | 3045 |     if (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)) | 
 | 3046 |       && ((plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL))) | 
 | 3047 |     { | 
 | 3048 |       plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; | 
 | 3049 |     } | 
 | 3050 |     for(i=0; i<MAX_CHANNELS_PER_PLCI && plci->inc_dis_ncci_table[i]!=(byte)ncci; i++); | 
 | 3051 |     if(i<MAX_CHANNELS_PER_PLCI) { | 
 | 3052 |       if(plci->channels)plci->channels--; | 
 | 3053 |       for(; i<MAX_CHANNELS_PER_PLCI-1; i++) plci->inc_dis_ncci_table[i] = plci->inc_dis_ncci_table[i+1]; | 
 | 3054 |       plci->inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI-1] = 0; | 
 | 3055 |  | 
 | 3056 |       ncci_free_receive_buffers (plci, ncci); | 
 | 3057 |  | 
 | 3058 |       if((plci->State==IDLE || plci->State==SUSPENDING) && !plci->channels){ | 
 | 3059 |         if(plci->State == SUSPENDING){ | 
 | 3060 |           sendf(plci->appl, | 
 | 3061 |                 _FACILITY_I, | 
 | 3062 |                 Id & 0xffffL, | 
 | 3063 |                 0, | 
 | 3064 |                 "ws", (word)3, "\x03\x04\x00\x00"); | 
 | 3065 |           sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0); | 
 | 3066 |         } | 
 | 3067 |         plci_remove(plci); | 
 | 3068 |         plci->State=IDLE; | 
 | 3069 |       } | 
 | 3070 |     } | 
 | 3071 |     else | 
 | 3072 |     { | 
 | 3073 |       if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) | 
 | 3074 |        && ((plci->B3_prot == 4) || (plci->B3_prot == 5)) | 
 | 3075 |        && (a->ncci_state[ncci] == INC_DIS_PENDING)) | 
 | 3076 |       { | 
 | 3077 |         ncci_free_receive_buffers (plci, ncci); | 
 | 3078 |  | 
 | 3079 |         nl_req_ncci(plci,N_EDATA,(byte)ncci); | 
 | 3080 |  | 
 | 3081 |         plci->adapter->ncci_state[ncci] = IDLE; | 
 | 3082 |         start_internal_command (Id, plci, fax_disconnect_command); | 
 | 3083 |         return 1; | 
 | 3084 |       } | 
 | 3085 |     } | 
 | 3086 |   } | 
 | 3087 |   return FALSE; | 
 | 3088 | } | 
 | 3089 |  | 
 | 3090 | byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 3091 | { | 
 | 3092 |   NCCI   *ncci_ptr; | 
 | 3093 |   DATA_B3_DESC   *data; | 
 | 3094 |   word Info; | 
 | 3095 |   word ncci; | 
 | 3096 |   word i; | 
 | 3097 |  | 
 | 3098 |   dbug(1,dprintf("data_b3_req")); | 
 | 3099 |  | 
 | 3100 |   Info = _WRONG_IDENTIFIER; | 
 | 3101 |   ncci = (word)(Id>>16); | 
 | 3102 |   dbug(1,dprintf("ncci=0x%x, plci=0x%x",ncci,plci)); | 
 | 3103 |  | 
 | 3104 |   if (plci && ncci) | 
 | 3105 |   { | 
 | 3106 |     Info = _WRONG_STATE; | 
 | 3107 |     if ((a->ncci_state[ncci] == CONNECTED) | 
 | 3108 |      || (a->ncci_state[ncci] == INC_ACT_PENDING)) | 
 | 3109 |     { | 
 | 3110 |         /* queue data */ | 
 | 3111 |       ncci_ptr = &(a->ncci[ncci]); | 
 | 3112 |       i = ncci_ptr->data_out + ncci_ptr->data_pending; | 
 | 3113 |       if (i >= MAX_DATA_B3) | 
 | 3114 |         i -= MAX_DATA_B3; | 
 | 3115 |       data = &(ncci_ptr->DBuffer[i]); | 
 | 3116 |       data->Number = Number; | 
 | 3117 |       if ((((byte   *)(parms[0].info)) >= ((byte   *)(plci->msg_in_queue))) | 
 | 3118 |        && (((byte   *)(parms[0].info)) < ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) | 
 | 3119 |       { | 
 | 3120 |  | 
 | 3121 |         data->P = (byte   *)(*((dword   *)(parms[0].info))); | 
 | 3122 |  | 
 | 3123 |       } | 
 | 3124 |       else | 
 | 3125 |         data->P = TransmitBufferSet(appl,*(dword *)parms[0].info); | 
 | 3126 |       data->Length = GET_WORD(parms[1].info); | 
 | 3127 |       data->Handle = GET_WORD(parms[2].info); | 
 | 3128 |       data->Flags = GET_WORD(parms[3].info); | 
 | 3129 |       (ncci_ptr->data_pending)++; | 
 | 3130 |  | 
 | 3131 |         /* check for delivery confirmation */ | 
 | 3132 |       if (data->Flags & 0x0004) | 
 | 3133 |       { | 
 | 3134 |         i = ncci_ptr->data_ack_out + ncci_ptr->data_ack_pending; | 
 | 3135 |         if (i >= MAX_DATA_ACK) | 
 | 3136 |           i -= MAX_DATA_ACK; | 
 | 3137 |         ncci_ptr->DataAck[i].Number = data->Number; | 
 | 3138 |         ncci_ptr->DataAck[i].Handle = data->Handle; | 
 | 3139 |         (ncci_ptr->data_ack_pending)++; | 
 | 3140 |       } | 
 | 3141 |  | 
 | 3142 |       send_data(plci); | 
 | 3143 |       return FALSE; | 
 | 3144 |     } | 
 | 3145 |   } | 
 | 3146 |   if (appl) | 
 | 3147 |   { | 
 | 3148 |     if (plci) | 
 | 3149 |     { | 
 | 3150 |       if ((((byte   *)(parms[0].info)) >= ((byte   *)(plci->msg_in_queue))) | 
 | 3151 |        && (((byte   *)(parms[0].info)) < ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) | 
 | 3152 |       { | 
 | 3153 |  | 
 | 3154 |         TransmitBufferFree (appl, (byte   *)(*((dword   *)(parms[0].info)))); | 
 | 3155 |  | 
 | 3156 |       } | 
 | 3157 |     } | 
 | 3158 |     sendf(appl, | 
 | 3159 |           _DATA_B3_R|CONFIRM, | 
 | 3160 |           Id, | 
 | 3161 |           Number, | 
 | 3162 |           "ww",GET_WORD(parms[2].info),Info); | 
 | 3163 |   } | 
 | 3164 |   return FALSE; | 
 | 3165 | } | 
 | 3166 |  | 
 | 3167 | byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 3168 | { | 
 | 3169 |   word n; | 
 | 3170 |   word ncci; | 
 | 3171 |   word NCCIcode; | 
 | 3172 |  | 
 | 3173 |   dbug(1,dprintf("data_b3_res")); | 
 | 3174 |  | 
 | 3175 |   ncci = (word)(Id>>16); | 
 | 3176 |   if(plci && ncci) { | 
 | 3177 |     n = GET_WORD(parms[0].info); | 
 | 3178 |     dbug(1,dprintf("free(%d)",n)); | 
 | 3179 |     NCCIcode = ncci | (((word) a->Id) << 8); | 
 | 3180 |     if(n<appl->MaxBuffer && | 
 | 3181 |        appl->DataNCCI[n]==NCCIcode && | 
 | 3182 |        (byte)(appl->DataFlags[n]>>8)==plci->Id) { | 
 | 3183 |       dbug(1,dprintf("found")); | 
 | 3184 |       appl->DataNCCI[n] = 0; | 
 | 3185 |  | 
 | 3186 |       if (channel_can_xon (plci, a->ncci_ch[ncci])) { | 
 | 3187 |         channel_request_xon (plci, a->ncci_ch[ncci]); | 
 | 3188 |       } | 
 | 3189 |       channel_xmit_xon (plci); | 
 | 3190 |  | 
 | 3191 |       if(appl->DataFlags[n] &4) { | 
 | 3192 |         nl_req_ncci(plci,N_DATA_ACK,(byte)ncci); | 
 | 3193 |         return 1; | 
 | 3194 |       } | 
 | 3195 |     } | 
 | 3196 |   } | 
 | 3197 |   return FALSE; | 
 | 3198 | } | 
 | 3199 |  | 
 | 3200 | byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 3201 | { | 
 | 3202 |   word Info; | 
 | 3203 |   word ncci; | 
 | 3204 |  | 
 | 3205 |   dbug(1,dprintf("reset_b3_req")); | 
 | 3206 |  | 
 | 3207 |   Info = _WRONG_IDENTIFIER; | 
 | 3208 |   ncci = (word)(Id>>16); | 
 | 3209 |   if(plci && ncci) | 
 | 3210 |   { | 
 | 3211 |     Info = _WRONG_STATE; | 
 | 3212 |     switch (plci->B3_prot) | 
 | 3213 |     { | 
 | 3214 |     case B3_ISO8208: | 
 | 3215 |     case B3_X25_DCE: | 
 | 3216 |       if(a->ncci_state[ncci]==CONNECTED) | 
 | 3217 |       { | 
 | 3218 |         nl_req_ncci(plci,N_RESET,(byte)ncci); | 
 | 3219 |         send_req(plci); | 
 | 3220 |         Info = GOOD; | 
 | 3221 |       } | 
 | 3222 |       break; | 
 | 3223 |     case B3_TRANSPARENT: | 
 | 3224 |       if(a->ncci_state[ncci]==CONNECTED) | 
 | 3225 |       { | 
 | 3226 |         start_internal_command (Id, plci, reset_b3_command); | 
 | 3227 |         Info = GOOD; | 
 | 3228 |       } | 
 | 3229 |       break; | 
 | 3230 |     } | 
 | 3231 |   } | 
 | 3232 |   /* reset_b3 must result in a reset_b3_con & reset_b3_Ind */ | 
 | 3233 |   sendf(appl, | 
 | 3234 |         _RESET_B3_R|CONFIRM, | 
 | 3235 |         Id, | 
 | 3236 |         Number, | 
 | 3237 |         "w",Info); | 
 | 3238 |   return FALSE; | 
 | 3239 | } | 
 | 3240 |  | 
 | 3241 | byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 3242 | { | 
 | 3243 |   word ncci; | 
 | 3244 |  | 
 | 3245 |   dbug(1,dprintf("reset_b3_res")); | 
 | 3246 |  | 
 | 3247 |   ncci = (word)(Id>>16); | 
 | 3248 |   if(plci && ncci) { | 
 | 3249 |     switch (plci->B3_prot) | 
 | 3250 |     { | 
 | 3251 |     case B3_ISO8208: | 
 | 3252 |     case B3_X25_DCE: | 
 | 3253 |       if(a->ncci_state[ncci]==INC_RES_PENDING) | 
 | 3254 |       { | 
 | 3255 |         a->ncci_state[ncci] = CONNECTED; | 
 | 3256 |         nl_req_ncci(plci,N_RESET_ACK,(byte)ncci); | 
 | 3257 |         return TRUE; | 
 | 3258 |       } | 
 | 3259 |     break; | 
 | 3260 |     } | 
 | 3261 |   } | 
 | 3262 |   return FALSE; | 
 | 3263 | } | 
 | 3264 |  | 
 | 3265 | byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 3266 | { | 
 | 3267 |   word ncci; | 
 | 3268 |   API_PARSE * ncpi; | 
 | 3269 |   byte req; | 
 | 3270 |  | 
 | 3271 |   dbug(1,dprintf("connect_b3_t90_a_res")); | 
 | 3272 |  | 
 | 3273 |   ncci = (word)(Id>>16); | 
 | 3274 |   if(plci && ncci) { | 
 | 3275 |     if(a->ncci_state[ncci]==INC_ACT_PENDING) { | 
 | 3276 |       a->ncci_state[ncci] = CONNECTED; | 
 | 3277 |     } | 
 | 3278 |     else if(a->ncci_state[ncci]==INC_CON_PENDING) { | 
 | 3279 |       a->ncci_state[ncci] = CONNECTED; | 
 | 3280 |  | 
 | 3281 |       req = N_CONNECT_ACK; | 
 | 3282 |  | 
 | 3283 |         /* parms[0]==0 for CAPI original message definition! */ | 
 | 3284 |       if(parms[0].info) { | 
 | 3285 |         ncpi = &parms[1]; | 
 | 3286 |         if(ncpi->length>2) { | 
 | 3287 |           if(ncpi->info[1] &1) req = N_CONNECT_ACK | N_D_BIT; | 
 | 3288 |           add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]); | 
 | 3289 |         } | 
 | 3290 |       } | 
 | 3291 |       nl_req_ncci(plci,req,(byte)ncci); | 
 | 3292 |       return 1; | 
 | 3293 |     } | 
 | 3294 |   } | 
 | 3295 |   return FALSE; | 
 | 3296 | } | 
 | 3297 |  | 
 | 3298 |  | 
 | 3299 | byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 3300 | { | 
 | 3301 |   word Info=0; | 
 | 3302 |   word i; | 
 | 3303 |   byte tel; | 
 | 3304 |     API_PARSE bp_parms[7]; | 
 | 3305 |  | 
 | 3306 |   if(!plci || !msg) | 
 | 3307 |   { | 
 | 3308 |     Info = _WRONG_IDENTIFIER; | 
 | 3309 |   } | 
 | 3310 |   else | 
 | 3311 |   { | 
 | 3312 |     dbug(1,dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x", | 
 | 3313 |                    msg->length,plci->Id,plci->tel,plci->NL.Id,plci->appl,plci->SuppState)); | 
 | 3314 |     dbug(1,dprintf("PlciState=0x%x",plci->State)); | 
 | 3315 |     for(i=0;i<7;i++) bp_parms[i].length = 0; | 
 | 3316 |  | 
 | 3317 |     /* check if no channel is open, no B3 connected only */ | 
 | 3318 |     if((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) || (plci->State == INC_DIS_PENDING) | 
 | 3319 |      || (plci->SuppState != IDLE) || plci->channels || plci->nl_remove_id) | 
 | 3320 |     { | 
 | 3321 |       Info = _WRONG_STATE; | 
 | 3322 |     } | 
 | 3323 |     /* check message format and fill bp_parms pointer */ | 
 | 3324 |     else if(msg->length && api_parse(&msg->info[1], (word)msg->length, "wwwsss", bp_parms)) | 
 | 3325 |     { | 
 | 3326 |       Info = _WRONG_MESSAGE_FORMAT; | 
 | 3327 |     } | 
 | 3328 |     else | 
 | 3329 |     { | 
 | 3330 |       if((plci->State==INC_CON_PENDING) || (plci->State==INC_CON_ALERT)) /* send alert tone inband to the network, */ | 
 | 3331 |       {                                                                  /* e.g. Qsig or RBS or Cornet-N or xess PRI */ | 
 | 3332 |         if(Id & EXT_CONTROLLER) | 
 | 3333 |         { | 
 | 3334 |           sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", 0x2002); /* wrong controller */ | 
 | 3335 |           return 0; | 
 | 3336 |         } | 
 | 3337 |         plci->State=INC_CON_CONNECTED_ALERT; | 
 | 3338 |         plci->appl = appl; | 
 | 3339 |         clear_c_ind_mask_bit (plci, (word)(appl->Id-1)); | 
 | 3340 |         dump_c_ind_mask (plci); | 
 | 3341 |         for(i=0; i<max_appl; i++) /* disconnect the other appls */ | 
 | 3342 |         {                         /* its quasi a connect        */ | 
 | 3343 |           if(test_c_ind_mask_bit (plci, i)) | 
 | 3344 |             sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); | 
 | 3345 |         } | 
 | 3346 |       } | 
 | 3347 |  | 
 | 3348 |       api_save_msg(msg, "s", &plci->saved_msg); | 
 | 3349 |       tel = plci->tel; | 
 | 3350 |       if(Id & EXT_CONTROLLER) | 
 | 3351 |       { | 
 | 3352 |         if(tel) /* external controller in use by this PLCI */ | 
 | 3353 |         { | 
 | 3354 |           if(a->AdvSignalAppl && a->AdvSignalAppl!=appl) | 
 | 3355 |           { | 
 | 3356 |             dbug(1,dprintf("Ext_Ctrl in use 1")); | 
 | 3357 |             Info = _WRONG_STATE; | 
 | 3358 |           } | 
 | 3359 |         } | 
 | 3360 |         else  /* external controller NOT in use by this PLCI ? */ | 
 | 3361 |         { | 
 | 3362 |           if(a->AdvSignalPLCI) | 
 | 3363 |           { | 
 | 3364 |             dbug(1,dprintf("Ext_Ctrl in use 2")); | 
 | 3365 |             Info = _WRONG_STATE; | 
 | 3366 |           } | 
 | 3367 |           else /* activate the codec */ | 
 | 3368 |           { | 
 | 3369 |             dbug(1,dprintf("Ext_Ctrl start")); | 
 | 3370 |             if(AdvCodecSupport(a, plci, appl, 0) ) | 
 | 3371 |             { | 
 | 3372 |               dbug(1,dprintf("Error in codec procedures")); | 
 | 3373 |               Info = _WRONG_STATE; | 
 | 3374 |             } | 
 | 3375 |             else if(plci->spoofed_msg==SPOOFING_REQUIRED) /* wait until codec is active */ | 
 | 3376 |             { | 
 | 3377 |               plci->spoofed_msg = AWAITING_SELECT_B; | 
 | 3378 |               plci->internal_command = BLOCK_PLCI; /* lock other commands */ | 
 | 3379 |               plci->command = 0; | 
 | 3380 |               dbug(1,dprintf("continue if codec loaded")); | 
 | 3381 |               return FALSE; | 
 | 3382 |             } | 
 | 3383 |           } | 
 | 3384 |         } | 
 | 3385 |       } | 
 | 3386 |       else /* external controller bit is OFF */ | 
 | 3387 |       { | 
 | 3388 |         if(tel) /* external controller in use, need to switch off */ | 
 | 3389 |         { | 
 | 3390 |           if(a->AdvSignalAppl==appl) | 
 | 3391 |           { | 
 | 3392 |             CodecIdCheck(a, plci); | 
 | 3393 |             plci->tel = 0; | 
 | 3394 |             plci->adv_nl = 0; | 
 | 3395 |             dbug(1,dprintf("Ext_Ctrl disable")); | 
 | 3396 |           } | 
 | 3397 |           else | 
 | 3398 |           { | 
 | 3399 |             dbug(1,dprintf("Ext_Ctrl not requested")); | 
 | 3400 |           } | 
 | 3401 |         } | 
 | 3402 |       } | 
 | 3403 |       if (!Info) | 
 | 3404 |       { | 
 | 3405 |         if (plci->call_dir & CALL_DIR_OUT) | 
 | 3406 |           plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; | 
 | 3407 |         else if (plci->call_dir & CALL_DIR_IN) | 
 | 3408 |           plci->call_dir = CALL_DIR_IN | CALL_DIR_ANSWER; | 
 | 3409 |         start_internal_command (Id, plci, select_b_command); | 
 | 3410 |         return FALSE; | 
 | 3411 |       } | 
 | 3412 |     } | 
 | 3413 |   } | 
 | 3414 |   sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", Info); | 
 | 3415 |   return FALSE; | 
 | 3416 | } | 
 | 3417 |  | 
 | 3418 | byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms) | 
 | 3419 | { | 
 | 3420 |   word command; | 
 | 3421 |   word i; | 
 | 3422 |   word ncci; | 
 | 3423 |   API_PARSE * m; | 
 | 3424 |     API_PARSE m_parms[5]; | 
 | 3425 |   word codec; | 
 | 3426 |   byte req; | 
 | 3427 |   byte ch; | 
 | 3428 |   byte dir; | 
 | 3429 |   static byte chi[2] = {0x01,0x00}; | 
 | 3430 |   static byte lli[2] = {0x01,0x00}; | 
 | 3431 |   static byte codec_cai[2] = {0x01,0x01}; | 
 | 3432 |   static byte null_msg = {0}; | 
 | 3433 |   static API_PARSE null_parms = { 0, &null_msg }; | 
 | 3434 |   PLCI   * v_plci; | 
 | 3435 |   word Info=0; | 
 | 3436 |  | 
 | 3437 |   dbug(1,dprintf("manufacturer_req")); | 
 | 3438 |   for(i=0;i<5;i++) m_parms[i].length = 0; | 
 | 3439 |  | 
 | 3440 |   if(GET_DWORD(parms[0].info)!=_DI_MANU_ID) { | 
 | 3441 |     Info = _WRONG_MESSAGE_FORMAT; | 
 | 3442 |   } | 
 | 3443 |   command = GET_WORD(parms[1].info); | 
 | 3444 |   m = &parms[2]; | 
 | 3445 |   if (!Info) | 
 | 3446 |   { | 
 | 3447 |     switch(command) { | 
 | 3448 |     case _DI_ASSIGN_PLCI: | 
 | 3449 |       if(api_parse(&m->info[1],(word)m->length,"wbbs",m_parms)) { | 
 | 3450 |         Info = _WRONG_MESSAGE_FORMAT; | 
 | 3451 |         break; | 
 | 3452 |       } | 
 | 3453 |       codec = GET_WORD(m_parms[0].info); | 
 | 3454 |       ch = m_parms[1].info[0]; | 
 | 3455 |       dir = m_parms[2].info[0]; | 
 | 3456 |       if((i=get_plci(a))) { | 
 | 3457 |         plci = &a->plci[i-1]; | 
 | 3458 |         plci->appl = appl; | 
 | 3459 |         plci->command = _MANUFACTURER_R; | 
 | 3460 |         plci->m_command = command; | 
 | 3461 |         plci->number = Number; | 
 | 3462 |         plci->State = LOCAL_CONNECT; | 
 | 3463 |         Id = ( ((word)plci->Id<<8)|plci->adapter->Id|0x80); | 
 | 3464 |         dbug(1,dprintf("ManCMD,plci=0x%x",Id)); | 
 | 3465 |  | 
 | 3466 |         if((ch==1 || ch==2) && (dir<=2)) { | 
 | 3467 |           chi[1] = (byte)(0x80|ch); | 
 | 3468 |           lli[1] = 0; | 
 | 3469 |           plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; | 
 | 3470 |           switch(codec) | 
 | 3471 |           { | 
 | 3472 |           case 0: | 
 | 3473 |             Info = add_b1(plci,&m_parms[3],0,0); | 
 | 3474 |             break; | 
 | 3475 |           case 1: | 
 | 3476 |             add_p(plci,CAI,codec_cai); | 
 | 3477 |             break; | 
 | 3478 |           /* manual 'swich on' to the codec support without signalling */ | 
 | 3479 |           /* first 'assign plci' with this function, then use */ | 
 | 3480 |           case 2: | 
 | 3481 |             if(AdvCodecSupport(a, plci, appl, 0) ) { | 
 | 3482 |               Info = _RESOURCE_ERROR; | 
 | 3483 |             } | 
 | 3484 |             else { | 
 | 3485 |               Info = add_b1(plci,&null_parms,0,B1_FACILITY_LOCAL); | 
 | 3486 |               lli[1] = 0x10; /* local call codec stream */ | 
 | 3487 |             } | 
 | 3488 |             break; | 
 | 3489 |           } | 
 | 3490 |  | 
 | 3491 |           plci->State = LOCAL_CONNECT; | 
 | 3492 |           plci->manufacturer = TRUE; | 
 | 3493 |           plci->command = _MANUFACTURER_R; | 
 | 3494 |           plci->m_command = command; | 
 | 3495 |           plci->number = Number; | 
 | 3496 |  | 
 | 3497 |           if(!Info) | 
 | 3498 |           { | 
 | 3499 |             add_p(plci,LLI,lli); | 
 | 3500 |             add_p(plci,CHI,chi); | 
 | 3501 |             add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 3502 |             sig_req(plci,ASSIGN,DSIG_ID); | 
 | 3503 |  | 
 | 3504 |             if(!codec) | 
 | 3505 |             { | 
 | 3506 |               Info = add_b23(plci,&m_parms[3]); | 
 | 3507 |               if(!Info) | 
 | 3508 |               { | 
 | 3509 |                 nl_req_ncci(plci,ASSIGN,0); | 
 | 3510 |                 send_req(plci); | 
 | 3511 |               } | 
 | 3512 |             } | 
 | 3513 |             if(!Info) | 
 | 3514 |             { | 
 | 3515 |               dbug(1,dprintf("dir=0x%x,spoof=0x%x",dir,plci->spoofed_msg)); | 
 | 3516 |               if (plci->spoofed_msg==SPOOFING_REQUIRED) | 
 | 3517 |               { | 
 | 3518 |                 api_save_msg (m_parms, "wbbs", &plci->saved_msg); | 
 | 3519 |                 plci->spoofed_msg = AWAITING_MANUF_CON; | 
 | 3520 |                 plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */ | 
 | 3521 |                 plci->command = 0; | 
 | 3522 |                 send_req(plci); | 
 | 3523 |                 return FALSE; | 
 | 3524 |               } | 
 | 3525 |               if(dir==1) { | 
 | 3526 |                 sig_req(plci,CALL_REQ,0); | 
 | 3527 |               } | 
 | 3528 |               else if(!dir){ | 
 | 3529 |                 sig_req(plci,LISTEN_REQ,0); | 
 | 3530 |               } | 
 | 3531 |               send_req(plci); | 
 | 3532 |             } | 
 | 3533 |             else | 
 | 3534 |             { | 
 | 3535 |               sendf(appl, | 
 | 3536 |                     _MANUFACTURER_R|CONFIRM, | 
 | 3537 |                     Id, | 
 | 3538 |                     Number, | 
 | 3539 |                     "dww",_DI_MANU_ID,command,Info); | 
 | 3540 |               return 2; | 
 | 3541 |             } | 
 | 3542 |           } | 
 | 3543 |         } | 
 | 3544 |       } | 
 | 3545 |       else  Info = _OUT_OF_PLCI; | 
 | 3546 |       break; | 
 | 3547 |  | 
 | 3548 |     case _DI_IDI_CTRL: | 
 | 3549 |       if(!plci) | 
 | 3550 |       { | 
 | 3551 |         Info = _WRONG_IDENTIFIER; | 
 | 3552 |         break; | 
 | 3553 |       } | 
 | 3554 |       if(api_parse(&m->info[1],(word)m->length,"bs",m_parms)) { | 
 | 3555 |         Info = _WRONG_MESSAGE_FORMAT; | 
 | 3556 |         break; | 
 | 3557 |       } | 
 | 3558 |       req = m_parms[0].info[0]; | 
 | 3559 |       plci->command = _MANUFACTURER_R; | 
 | 3560 |       plci->m_command = command; | 
 | 3561 |       plci->number = Number; | 
 | 3562 |       if(req==CALL_REQ) | 
 | 3563 |       { | 
 | 3564 |         plci->b_channel = getChannel(&m_parms[1]); | 
 | 3565 |         mixer_set_bchannel_id_esc (plci, plci->b_channel); | 
 | 3566 |         if(plci->spoofed_msg==SPOOFING_REQUIRED) | 
 | 3567 |         { | 
 | 3568 |           plci->spoofed_msg = CALL_REQ | AWAITING_MANUF_CON; | 
 | 3569 |           plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */ | 
 | 3570 |           plci->command = 0; | 
 | 3571 |           break; | 
 | 3572 |         } | 
 | 3573 |       } | 
 | 3574 |       else if(req==LAW_REQ) | 
 | 3575 |       { | 
 | 3576 |         plci->cr_enquiry = TRUE; | 
 | 3577 |       } | 
 | 3578 |       add_ss(plci,FTY,&m_parms[1]); | 
 | 3579 |       sig_req(plci,req,0); | 
 | 3580 |       send_req(plci); | 
 | 3581 |       if(req==HANGUP) | 
 | 3582 |       {       | 
 | 3583 |         if (plci->NL.Id && !plci->nl_remove_id) | 
 | 3584 |         { | 
 | 3585 |           if (plci->channels) | 
 | 3586 |           { | 
 | 3587 |             for (ncci = 1; ncci < MAX_NCCI+1; ncci++) | 
 | 3588 |             { | 
 | 3589 |               if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED)) | 
 | 3590 |               { | 
 | 3591 |                 a->ncci_state[ncci] = OUTG_DIS_PENDING; | 
 | 3592 |                 cleanup_ncci_data (plci, ncci); | 
 | 3593 |                 nl_req_ncci(plci,N_DISC,(byte)ncci); | 
 | 3594 |               } | 
 | 3595 |             } | 
 | 3596 |           } | 
 | 3597 |           mixer_remove (plci); | 
 | 3598 |           nl_req_ncci(plci,REMOVE,0); | 
 | 3599 |           send_req(plci); | 
 | 3600 |         }   | 
 | 3601 |       } | 
 | 3602 |       break; | 
 | 3603 |  | 
 | 3604 |     case _DI_SIG_CTRL: | 
 | 3605 |     /* signalling control for loop activation B-channel */ | 
 | 3606 |       if(!plci) | 
 | 3607 |       { | 
 | 3608 |         Info = _WRONG_IDENTIFIER; | 
 | 3609 |         break; | 
 | 3610 |       } | 
 | 3611 |       if(m->length){ | 
 | 3612 |         plci->command = _MANUFACTURER_R; | 
 | 3613 |         plci->number = Number; | 
 | 3614 |         add_ss(plci,FTY,m); | 
 | 3615 |         sig_req(plci,SIG_CTRL,0); | 
 | 3616 |         send_req(plci); | 
 | 3617 |       } | 
 | 3618 |       else Info = _WRONG_MESSAGE_FORMAT; | 
 | 3619 |       break; | 
 | 3620 |  | 
 | 3621 |     case _DI_RXT_CTRL: | 
 | 3622 |     /* activation control for receiver/transmitter B-channel */ | 
 | 3623 |       if(!plci) | 
 | 3624 |       { | 
 | 3625 |         Info = _WRONG_IDENTIFIER; | 
 | 3626 |         break; | 
 | 3627 |       } | 
 | 3628 |       if(m->length){ | 
 | 3629 |         plci->command = _MANUFACTURER_R; | 
 | 3630 |         plci->number = Number; | 
 | 3631 |         add_ss(plci,FTY,m); | 
 | 3632 |         sig_req(plci,DSP_CTRL,0); | 
 | 3633 |         send_req(plci); | 
 | 3634 |       } | 
 | 3635 |       else Info = _WRONG_MESSAGE_FORMAT; | 
 | 3636 |       break; | 
 | 3637 |  | 
 | 3638 |     case _DI_ADV_CODEC: | 
 | 3639 |     case _DI_DSP_CTRL: | 
 | 3640 |       /* TEL_CTRL commands to support non standard adjustments: */ | 
 | 3641 |       /* Ring on/off, Handset micro volume, external micro vol. */ | 
 | 3642 |       /* handset+external speaker volume, receiver+transm. gain,*/ | 
 | 3643 |       /* handsfree on (hookinfo off), set mixer command         */ | 
 | 3644 |  | 
 | 3645 |       if(command == _DI_ADV_CODEC) | 
 | 3646 |       { | 
 | 3647 |         if(!a->AdvCodecPLCI) { | 
 | 3648 |           Info = _WRONG_STATE; | 
 | 3649 |           break; | 
 | 3650 |         } | 
 | 3651 |         v_plci = a->AdvCodecPLCI; | 
 | 3652 |       } | 
 | 3653 |       else | 
 | 3654 |       { | 
 | 3655 |         if (plci | 
 | 3656 |          && (m->length >= 3) | 
 | 3657 |          && (m->info[1] == 0x1c) | 
 | 3658 |          && (m->info[2] >= 1)) | 
 | 3659 |         { | 
 | 3660 |           if (m->info[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS) | 
 | 3661 |           { | 
 | 3662 |             if ((plci->tel != ADV_VOICE) || (plci != a->AdvSignalPLCI)) | 
 | 3663 |             { | 
 | 3664 |               Info = _WRONG_STATE; | 
 | 3665 |               break; | 
 | 3666 |             } | 
 | 3667 |             a->adv_voice_coef_length = m->info[2] - 1; | 
 | 3668 |             if (a->adv_voice_coef_length > m->length - 3) | 
 | 3669 |               a->adv_voice_coef_length = (byte)(m->length - 3); | 
 | 3670 |             if (a->adv_voice_coef_length > ADV_VOICE_COEF_BUFFER_SIZE) | 
 | 3671 |               a->adv_voice_coef_length = ADV_VOICE_COEF_BUFFER_SIZE; | 
 | 3672 |             for (i = 0; i < a->adv_voice_coef_length; i++) | 
 | 3673 |               a->adv_voice_coef_buffer[i] = m->info[4 + i]; | 
 | 3674 |             if (plci->B1_facilities & B1_FACILITY_VOICE) | 
 | 3675 |               adv_voice_write_coefs (plci, ADV_VOICE_WRITE_UPDATE); | 
 | 3676 |             break; | 
 | 3677 |           } | 
 | 3678 |           else if (m->info[3] == DSP_CTRL_SET_DTMF_PARAMETERS) | 
 | 3679 |           { | 
 | 3680 |             if (!(a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_PARAMETERS)) | 
 | 3681 |             { | 
 | 3682 |               Info = _FACILITY_NOT_SUPPORTED; | 
 | 3683 |               break; | 
 | 3684 |             } | 
 | 3685 |  | 
 | 3686 |             plci->dtmf_parameter_length = m->info[2] - 1; | 
 | 3687 |             if (plci->dtmf_parameter_length > m->length - 3) | 
 | 3688 |               plci->dtmf_parameter_length = (byte)(m->length - 3); | 
 | 3689 |             if (plci->dtmf_parameter_length > DTMF_PARAMETER_BUFFER_SIZE) | 
 | 3690 |               plci->dtmf_parameter_length = DTMF_PARAMETER_BUFFER_SIZE; | 
 | 3691 |             for (i = 0; i < plci->dtmf_parameter_length; i++) | 
 | 3692 |               plci->dtmf_parameter_buffer[i] = m->info[4+i]; | 
 | 3693 |             if (plci->B1_facilities & B1_FACILITY_DTMFR) | 
 | 3694 |               dtmf_parameter_write (plci); | 
 | 3695 |             break; | 
 | 3696 |  | 
 | 3697 |           } | 
 | 3698 |         } | 
 | 3699 |         v_plci = plci; | 
 | 3700 |       } | 
 | 3701 |  | 
 | 3702 |       if(!v_plci) | 
 | 3703 |       { | 
 | 3704 |         Info = _WRONG_IDENTIFIER; | 
 | 3705 |         break; | 
 | 3706 |       } | 
 | 3707 |       if(m->length){ | 
 | 3708 |         add_ss(v_plci,FTY,m); | 
 | 3709 |         sig_req(v_plci,TEL_CTRL,0); | 
 | 3710 |         send_req(v_plci); | 
 | 3711 |       } | 
 | 3712 |       else Info = _WRONG_MESSAGE_FORMAT; | 
 | 3713 |  | 
 | 3714 |       break; | 
 | 3715 |  | 
 | 3716 |     case _DI_OPTIONS_REQUEST: | 
 | 3717 |       if(api_parse(&m->info[1],(word)m->length,"d",m_parms)) { | 
 | 3718 |         Info = _WRONG_MESSAGE_FORMAT; | 
 | 3719 |         break; | 
 | 3720 |       } | 
 | 3721 |       if (GET_DWORD (m_parms[0].info) & ~a->man_profile.private_options) | 
 | 3722 |       { | 
 | 3723 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 3724 |         break; | 
 | 3725 |       } | 
 | 3726 |       a->requested_options_table[appl->Id-1] = GET_DWORD (m_parms[0].info); | 
 | 3727 |       break; | 
 | 3728 |  | 
 | 3729 |  | 
 | 3730 |  | 
 | 3731 |     default: | 
 | 3732 |       Info = _WRONG_MESSAGE_FORMAT; | 
 | 3733 |       break; | 
 | 3734 |     } | 
 | 3735 |   } | 
 | 3736 |  | 
 | 3737 |   sendf(appl, | 
 | 3738 |         _MANUFACTURER_R|CONFIRM, | 
 | 3739 |         Id, | 
 | 3740 |         Number, | 
 | 3741 |         "dww",_DI_MANU_ID,command,Info); | 
 | 3742 |   return FALSE; | 
 | 3743 | } | 
 | 3744 |  | 
 | 3745 |  | 
 | 3746 | byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg) | 
 | 3747 | { | 
 | 3748 |   word indication; | 
 | 3749 |  | 
 | 3750 |     API_PARSE m_parms[3]; | 
 | 3751 |   API_PARSE *ncpi; | 
 | 3752 |     API_PARSE fax_parms[9]; | 
 | 3753 |   word i; | 
 | 3754 |   byte len; | 
 | 3755 |  | 
 | 3756 |  | 
 | 3757 |   dbug(1,dprintf("manufacturer_res")); | 
 | 3758 |  | 
 | 3759 |   if ((msg[0].length == 0) | 
 | 3760 |    || (msg[1].length == 0) | 
 | 3761 |    || (GET_DWORD(msg[0].info)!=_DI_MANU_ID)) | 
 | 3762 |   { | 
 | 3763 |     return FALSE; | 
 | 3764 |   } | 
 | 3765 |   indication = GET_WORD(msg[1].info); | 
 | 3766 |   switch (indication) | 
 | 3767 |   { | 
 | 3768 |  | 
 | 3769 |   case _DI_NEGOTIATE_B3: | 
 | 3770 |     if(!plci) | 
 | 3771 |       break; | 
 | 3772 |     if (((plci->B3_prot != 4) && (plci->B3_prot != 5)) | 
 | 3773 |      || !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT)) | 
 | 3774 |     { | 
 | 3775 |       dbug(1,dprintf("wrong state for NEGOTIATE_B3 parameters")); | 
 | 3776 |       break; | 
 | 3777 |     } | 
 | 3778 |     if (api_parse (&msg[2].info[1], msg[2].length, "ws", m_parms)) | 
 | 3779 |     { | 
 | 3780 |       dbug(1,dprintf("wrong format in NEGOTIATE_B3 parameters")); | 
 | 3781 |       break; | 
 | 3782 |     } | 
 | 3783 |     ncpi = &m_parms[1]; | 
 | 3784 |     len = ((byte)(((T30_INFO *) 0)->station_id + 20)); | 
 | 3785 |     if (plci->fax_connect_info_length < len) | 
 | 3786 |     { | 
 | 3787 |       ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; | 
 | 3788 |       ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; | 
 | 3789 |     } | 
 | 3790 |     if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) | 
 | 3791 |     { | 
 | 3792 |       dbug(1,dprintf("non-standard facilities info missing or wrong format")); | 
 | 3793 |     } | 
 | 3794 |     else | 
 | 3795 |     { | 
 | 3796 |       if (plci->fax_connect_info_length <= len) | 
 | 3797 |         plci->fax_connect_info_buffer[len] = 0; | 
 | 3798 |       len += 1 + plci->fax_connect_info_buffer[len]; | 
 | 3799 |       if (plci->fax_connect_info_length <= len) | 
 | 3800 |         plci->fax_connect_info_buffer[len] = 0; | 
 | 3801 |       len += 1 + plci->fax_connect_info_buffer[len]; | 
 | 3802 |       if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) | 
 | 3803 |         plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); | 
 | 3804 |       plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); | 
 | 3805 |       for (i = 0; i < fax_parms[7].length; i++) | 
 | 3806 |         plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i]; | 
 | 3807 |     } | 
 | 3808 |     plci->fax_connect_info_length = len; | 
 | 3809 |     plci->fax_edata_ack_length = plci->fax_connect_info_length; | 
 | 3810 |     start_internal_command (Id, plci, fax_edata_ack_command); | 
 | 3811 |     break; | 
 | 3812 |  | 
 | 3813 |   } | 
 | 3814 |   return FALSE; | 
 | 3815 | } | 
 | 3816 |  | 
 | 3817 | /*------------------------------------------------------------------*/ | 
 | 3818 | /* IDI callback function                                            */ | 
 | 3819 | /*------------------------------------------------------------------*/ | 
 | 3820 |  | 
 | 3821 | void   callback(ENTITY   * e) | 
 | 3822 | { | 
 | 3823 |   DIVA_CAPI_ADAPTER   * a; | 
 | 3824 |   APPL   * appl; | 
 | 3825 |   PLCI   * plci; | 
 | 3826 |   CAPI_MSG   *m; | 
 | 3827 |   word i, j; | 
 | 3828 |   byte rc; | 
 | 3829 |   byte ch; | 
 | 3830 |   byte req; | 
 | 3831 |   byte global_req; | 
 | 3832 |   int no_cancel_rc; | 
 | 3833 |  | 
 | 3834 |   dbug(1,dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)", | 
 | 3835 |                  (e->user[0]+1)&0x7fff,e->Id,e->Req,e->Rc,e->Ind)); | 
 | 3836 |  | 
 | 3837 |   a = &(adapter[(byte)e->user[0]]); | 
 | 3838 |   plci = &(a->plci[e->user[1]]); | 
 | 3839 |   no_cancel_rc = DIVA_CAPI_SUPPORTS_NO_CANCEL(a); | 
 | 3840 |  | 
 | 3841 |   /* | 
 | 3842 |      If new protocol code and new XDI is used then CAPI should work | 
 | 3843 |      fully in accordance with IDI cpec an look on callback field instead | 
 | 3844 |      of Rc field for return codes. | 
 | 3845 |    */ | 
 | 3846 |   if (((e->complete == 0xff) && no_cancel_rc) || | 
 | 3847 |       (e->Rc && !no_cancel_rc)) { | 
 | 3848 |     rc = e->Rc; | 
 | 3849 |     ch = e->RcCh; | 
 | 3850 |     req = e->Req; | 
 | 3851 |     e->Rc = 0; | 
 | 3852 |  | 
 | 3853 |     if (e->user[0] & 0x8000) | 
 | 3854 |     { | 
 | 3855 |       /* | 
 | 3856 |          If REMOVE request was sent then we have to wait until | 
 | 3857 |          return code with Id set to zero arrives. | 
 | 3858 |          All other return codes should be ignored. | 
 | 3859 |          */ | 
 | 3860 |       if (req == REMOVE) | 
 | 3861 |       { | 
 | 3862 |         if (e->Id) | 
 | 3863 |         { | 
 | 3864 |           dbug(1,dprintf("cancel RC in REMOVE state")); | 
 | 3865 |           return; | 
 | 3866 |         } | 
 | 3867 |         channel_flow_control_remove (plci); | 
 | 3868 |         for (i = 0; i < 256; i++) | 
 | 3869 |         { | 
 | 3870 |           if (a->FlowControlIdTable[i] == plci->nl_remove_id) | 
 | 3871 |             a->FlowControlIdTable[i] = 0; | 
 | 3872 |         } | 
 | 3873 |         plci->nl_remove_id = 0; | 
 | 3874 |         if (plci->rx_dma_descriptor > 0) { | 
 | 3875 |           diva_free_dma_descriptor (plci, plci->rx_dma_descriptor - 1); | 
 | 3876 |           plci->rx_dma_descriptor = 0; | 
 | 3877 |         } | 
 | 3878 |       } | 
 | 3879 |       if (rc == OK_FC) | 
 | 3880 |       { | 
 | 3881 |         a->FlowControlIdTable[ch] = e->Id; | 
 | 3882 |         a->FlowControlSkipTable[ch] = 0; | 
 | 3883 |  | 
 | 3884 |         a->ch_flow_control[ch] |= N_OK_FC_PENDING; | 
 | 3885 |         a->ch_flow_plci[ch] = plci->Id; | 
 | 3886 |         plci->nl_req = 0; | 
 | 3887 |       } | 
 | 3888 |       else | 
 | 3889 |       { | 
 | 3890 |         /* | 
 | 3891 |           Cancel return codes self, if feature was requested | 
 | 3892 |           */ | 
 | 3893 |         if (no_cancel_rc && (a->FlowControlIdTable[ch] == e->Id) && e->Id) { | 
 | 3894 |           a->FlowControlIdTable[ch] = 0; | 
 | 3895 |           if ((rc == OK) && a->FlowControlSkipTable[ch]) { | 
 | 3896 |             dbug(3,dprintf ("XDI CAPI: RC cancelled Id:0x02, Ch:%02x",                              e->Id, ch)); | 
 | 3897 |             return; | 
 | 3898 |           } | 
 | 3899 |         } | 
 | 3900 |  | 
 | 3901 |         if (a->ch_flow_control[ch] & N_OK_FC_PENDING) | 
 | 3902 |         { | 
 | 3903 |           a->ch_flow_control[ch] &= ~N_OK_FC_PENDING; | 
 | 3904 |           if (ch == e->ReqCh) | 
 | 3905 |             plci->nl_req = 0; | 
 | 3906 |         } | 
 | 3907 |         else | 
 | 3908 |           plci->nl_req = 0; | 
 | 3909 |       } | 
 | 3910 |       if (plci->nl_req) | 
 | 3911 |         control_rc (plci, 0, rc, ch, 0, TRUE); | 
 | 3912 |       else | 
 | 3913 |       { | 
 | 3914 |         if (req == N_XON) | 
 | 3915 |         { | 
 | 3916 |           channel_x_on (plci, ch); | 
 | 3917 |           if (plci->internal_command) | 
 | 3918 |             control_rc (plci, req, rc, ch, 0, TRUE); | 
 | 3919 |         } | 
 | 3920 |         else | 
 | 3921 |         { | 
 | 3922 |           if (plci->nl_global_req) | 
 | 3923 |           { | 
 | 3924 |             global_req = plci->nl_global_req; | 
 | 3925 |             plci->nl_global_req = 0; | 
 | 3926 |             if (rc != ASSIGN_OK) { | 
 | 3927 |               e->Id = 0; | 
 | 3928 |               if (plci->rx_dma_descriptor > 0) { | 
 | 3929 |                 diva_free_dma_descriptor (plci, plci->rx_dma_descriptor - 1); | 
 | 3930 |                 plci->rx_dma_descriptor = 0; | 
 | 3931 |               } | 
 | 3932 |             } | 
 | 3933 |             channel_xmit_xon (plci); | 
 | 3934 |             control_rc (plci, 0, rc, ch, global_req, TRUE); | 
 | 3935 |           } | 
 | 3936 |           else if (plci->data_sent) | 
 | 3937 |           { | 
 | 3938 |             channel_xmit_xon (plci); | 
 | 3939 |             plci->data_sent = FALSE; | 
 | 3940 |             plci->NL.XNum = 1; | 
 | 3941 |             data_rc (plci, ch); | 
 | 3942 |             if (plci->internal_command) | 
 | 3943 |               control_rc (plci, req, rc, ch, 0, TRUE); | 
 | 3944 |           } | 
 | 3945 |           else | 
 | 3946 |           { | 
 | 3947 |             channel_xmit_xon (plci); | 
 | 3948 |             control_rc (plci, req, rc, ch, 0, TRUE); | 
 | 3949 |           } | 
 | 3950 |         } | 
 | 3951 |       } | 
 | 3952 |     } | 
 | 3953 |     else | 
 | 3954 |     { | 
 | 3955 |       /* | 
 | 3956 |          If REMOVE request was sent then we have to wait until | 
 | 3957 |          return code with Id set to zero arrives. | 
 | 3958 |          All other return codes should be ignored. | 
 | 3959 |          */ | 
 | 3960 |       if (req == REMOVE) | 
 | 3961 |       { | 
 | 3962 |         if (e->Id) | 
 | 3963 |         { | 
 | 3964 |           dbug(1,dprintf("cancel RC in REMOVE state")); | 
 | 3965 |           return; | 
 | 3966 |         } | 
 | 3967 |         plci->sig_remove_id = 0; | 
 | 3968 |       } | 
 | 3969 |       plci->sig_req = 0; | 
 | 3970 |       if (plci->sig_global_req) | 
 | 3971 |       { | 
 | 3972 |         global_req = plci->sig_global_req; | 
 | 3973 |         plci->sig_global_req = 0; | 
 | 3974 |         if (rc != ASSIGN_OK) | 
 | 3975 |           e->Id = 0; | 
 | 3976 |         channel_xmit_xon (plci); | 
 | 3977 |         control_rc (plci, 0, rc, ch, global_req, FALSE); | 
 | 3978 |       } | 
 | 3979 |       else | 
 | 3980 |       { | 
 | 3981 |         channel_xmit_xon (plci); | 
 | 3982 |         control_rc (plci, req, rc, ch, 0, FALSE); | 
 | 3983 |       } | 
 | 3984 |     } | 
 | 3985 |     /* | 
 | 3986 |       Again: in accordance with IDI spec Rc and Ind can't be delivered in the | 
 | 3987 |       same callback. Also if new XDI and protocol code used then jump | 
 | 3988 |       direct to finish. | 
 | 3989 |       */ | 
 | 3990 |     if (no_cancel_rc) { | 
 | 3991 |       channel_xmit_xon(plci); | 
 | 3992 |       goto capi_callback_suffix; | 
 | 3993 |     } | 
 | 3994 |   } | 
 | 3995 |  | 
 | 3996 |   channel_xmit_xon(plci); | 
 | 3997 |  | 
 | 3998 |   if (e->Ind) { | 
 | 3999 |     if (e->user[0] &0x8000) { | 
 | 4000 |       byte Ind = e->Ind & 0x0f; | 
 | 4001 |       byte Ch = e->IndCh; | 
 | 4002 |       if (((Ind==N_DISC) || (Ind==N_DISC_ACK)) && | 
 | 4003 |           (a->ch_flow_plci[Ch] == plci->Id)) { | 
 | 4004 |         if (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK) { | 
 | 4005 |           dbug(3,dprintf ("XDI CAPI: I: pending N-XON Ch:%02x", Ch)); | 
 | 4006 |         } | 
 | 4007 |         a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK; | 
 | 4008 |       } | 
 | 4009 |       nl_ind(plci); | 
 | 4010 |       if ((e->RNR != 1) && | 
 | 4011 |           (a->ch_flow_plci[Ch] == plci->Id) && | 
 | 4012 |           (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK)) { | 
 | 4013 |         a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK; | 
 | 4014 |         dbug(3,dprintf ("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch)); | 
 | 4015 |       } | 
 | 4016 |     } else { | 
 | 4017 |       sig_ind(plci); | 
 | 4018 |     } | 
 | 4019 |     e->Ind = 0; | 
 | 4020 |   } | 
 | 4021 |  | 
 | 4022 | capi_callback_suffix: | 
 | 4023 |  | 
 | 4024 |   while (!plci->req_in | 
 | 4025 |    && !plci->internal_command | 
 | 4026 |    && (plci->msg_in_write_pos != plci->msg_in_read_pos)) | 
 | 4027 |   { | 
 | 4028 |     j = (plci->msg_in_read_pos == plci->msg_in_wrap_pos) ? 0 : plci->msg_in_read_pos; | 
 | 4029 |  | 
 | 4030 |     i = (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[j]))->header.length + 3) & 0xfffc; | 
 | 4031 |  | 
 | 4032 |     m = (CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[j]); | 
 | 4033 |     appl = *((APPL   *   *)(&((byte   *)(plci->msg_in_queue))[j+i])); | 
 | 4034 |     dbug(1,dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d", | 
 | 4035 |       m->header.command, plci->msg_in_write_pos, plci->msg_in_read_pos, plci->msg_in_wrap_pos)); | 
 | 4036 |     if (plci->msg_in_read_pos == plci->msg_in_wrap_pos) | 
 | 4037 |     { | 
 | 4038 |       plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; | 
 | 4039 |       plci->msg_in_read_pos = i + MSG_IN_OVERHEAD; | 
 | 4040 |     } | 
 | 4041 |     else | 
 | 4042 |     { | 
 | 4043 |       plci->msg_in_read_pos = j + i + MSG_IN_OVERHEAD; | 
 | 4044 |     } | 
 | 4045 |     if (plci->msg_in_read_pos == plci->msg_in_write_pos) | 
 | 4046 |     { | 
 | 4047 |       plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; | 
 | 4048 |       plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; | 
 | 4049 |     } | 
 | 4050 |     else if (plci->msg_in_read_pos == plci->msg_in_wrap_pos) | 
 | 4051 |     { | 
 | 4052 |       plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; | 
 | 4053 |       plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; | 
 | 4054 |     } | 
 | 4055 |     i = api_put (appl, m); | 
 | 4056 |     if (i != 0) | 
 | 4057 |     { | 
 | 4058 |       if (m->header.command == _DATA_B3_R) | 
 | 4059 |  | 
 | 4060 |         TransmitBufferFree (appl, (byte   *)(m->info.data_b3_req.Data)); | 
 | 4061 |  | 
 | 4062 |       dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command)); | 
 | 4063 |       break; | 
 | 4064 |     } | 
 | 4065 |  | 
 | 4066 |     if (plci->li_notify_update) | 
 | 4067 |     { | 
 | 4068 |       plci->li_notify_update = FALSE; | 
 | 4069 |       mixer_notify_update (plci, FALSE); | 
 | 4070 |     } | 
 | 4071 |  | 
 | 4072 |   } | 
 | 4073 |   send_data(plci); | 
 | 4074 |   send_req(plci); | 
 | 4075 | } | 
 | 4076 |  | 
 | 4077 |  | 
 | 4078 | void control_rc(PLCI   * plci, byte req, byte rc, byte ch, byte global_req, byte nl_rc) | 
 | 4079 | { | 
 | 4080 |   dword Id; | 
 | 4081 |   dword rId; | 
 | 4082 |   word Number; | 
 | 4083 |   word Info=0; | 
 | 4084 |   word i; | 
 | 4085 |   word ncci; | 
 | 4086 |   DIVA_CAPI_ADAPTER   * a; | 
 | 4087 |   APPL   * appl; | 
 | 4088 |   PLCI   * rplci; | 
 | 4089 |     byte SSparms[]  = "\x05\x00\x00\x02\x00\x00"; | 
 | 4090 |     byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00"; | 
 | 4091 |  | 
 | 4092 |   if (!plci) { | 
 | 4093 |     dbug(0,dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc)); | 
 | 4094 |     return; | 
 | 4095 |   } | 
 | 4096 |   dbug(1,dprintf("req0_in/out=%d/%d",plci->req_in,plci->req_out)); | 
 | 4097 |   if(plci->req_in!=plci->req_out) | 
 | 4098 |   { | 
 | 4099 |     if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK)) | 
 | 4100 |     { | 
 | 4101 |       dbug(1,dprintf("req_1return")); | 
 | 4102 |       return; | 
 | 4103 |     } | 
 | 4104 |     /* cancel outstanding request on the PLCI after SIG ASSIGN failure */ | 
 | 4105 |   } | 
 | 4106 |   plci->req_in = plci->req_in_start = plci->req_out = 0; | 
 | 4107 |   dbug(1,dprintf("control_rc")); | 
 | 4108 |  | 
 | 4109 |   appl = plci->appl; | 
 | 4110 |   a = plci->adapter; | 
 | 4111 |   ncci = a->ch_ncci[ch]; | 
 | 4112 |   if(appl) | 
 | 4113 |   { | 
 | 4114 |     Id = (((dword)(ncci ? ncci : ch)) << 16) | ((word)plci->Id << 8) | a->Id; | 
 | 4115 |     if(plci->tel && plci->SuppState!=CALL_HELD) Id|=EXT_CONTROLLER; | 
 | 4116 |     Number = plci->number; | 
 | 4117 |     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)); | 
 | 4118 |     dbug(1,dprintf("channels=0x%x",plci->channels)); | 
 | 4119 |     if (plci_remove_check(plci)) | 
 | 4120 |       return; | 
 | 4121 |     if(req==REMOVE && rc==ASSIGN_OK) | 
 | 4122 |     { | 
 | 4123 |       sig_req(plci,HANGUP,0); | 
 | 4124 |       sig_req(plci,REMOVE,0); | 
 | 4125 |       send_req(plci); | 
 | 4126 |     } | 
 | 4127 |     if(plci->command) | 
 | 4128 |     { | 
 | 4129 |       switch(plci->command) | 
 | 4130 |       { | 
 | 4131 |       case C_HOLD_REQ: | 
 | 4132 |         dbug(1,dprintf("HoldRC=0x%x",rc)); | 
 | 4133 |         SSparms[1] = (byte)S_HOLD; | 
 | 4134 |         if(rc!=OK) | 
 | 4135 |         { | 
 | 4136 |           plci->SuppState = IDLE; | 
 | 4137 |           Info = 0x2001; | 
 | 4138 |         } | 
 | 4139 |         sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms); | 
 | 4140 |         break; | 
 | 4141 |  | 
 | 4142 |       case C_RETRIEVE_REQ: | 
 | 4143 |         dbug(1,dprintf("RetrieveRC=0x%x",rc)); | 
 | 4144 |         SSparms[1] = (byte)S_RETRIEVE; | 
 | 4145 |         if(rc!=OK) | 
 | 4146 |         { | 
 | 4147 |           plci->SuppState = CALL_HELD; | 
 | 4148 |           Info = 0x2001; | 
 | 4149 |         } | 
 | 4150 |         sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms); | 
 | 4151 |         break; | 
 | 4152 |  | 
 | 4153 |       case _INFO_R: | 
 | 4154 |         dbug(1,dprintf("InfoRC=0x%x",rc)); | 
 | 4155 |         if(rc!=OK) Info=_WRONG_STATE; | 
 | 4156 |         sendf(appl,_INFO_R|CONFIRM,Id,Number,"w",Info); | 
 | 4157 |         break; | 
 | 4158 |  | 
 | 4159 |       case _CONNECT_R: | 
 | 4160 |         dbug(1,dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x",req,rc,global_req,nl_rc)); | 
 | 4161 |         if (plci->State == INC_DIS_PENDING) | 
 | 4162 |           break; | 
 | 4163 |         if(plci->Sig.Id!=0xff) | 
 | 4164 |         { | 
 | 4165 |           if (((global_req == ASSIGN) && (rc != ASSIGN_OK)) | 
 | 4166 |            || (!nl_rc && (req == CALL_REQ) && (rc != OK))) | 
 | 4167 |           { | 
 | 4168 |             dbug(1,dprintf("No more IDs/Call_Req failed")); | 
 | 4169 |             sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI); | 
 | 4170 |             plci_remove(plci); | 
 | 4171 |             plci->State = IDLE; | 
 | 4172 |             break; | 
 | 4173 |           } | 
 | 4174 |           if(plci->State!=LOCAL_CONNECT)plci->State = OUTG_CON_PENDING; | 
 | 4175 |           sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0); | 
 | 4176 |         } | 
 | 4177 |         else /* D-ch activation */ | 
 | 4178 |         { | 
 | 4179 |           if (rc != ASSIGN_OK) | 
 | 4180 |           { | 
 | 4181 |             dbug(1,dprintf("No more IDs/X.25 Call_Req failed")); | 
 | 4182 |             sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI); | 
 | 4183 |             plci_remove(plci); | 
 | 4184 |             plci->State = IDLE; | 
 | 4185 |             break; | 
 | 4186 |           } | 
 | 4187 |           sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0); | 
 | 4188 |           sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"sss","","",""); | 
 | 4189 |           plci->State = INC_ACT_PENDING; | 
 | 4190 |         } | 
 | 4191 |         break; | 
 | 4192 |  | 
 | 4193 |       case _CONNECT_I|RESPONSE: | 
 | 4194 |         if (plci->State != INC_DIS_PENDING) | 
 | 4195 |           plci->State = INC_CON_ACCEPT; | 
 | 4196 |         break; | 
 | 4197 |  | 
 | 4198 |       case _DISCONNECT_R: | 
 | 4199 |         if (plci->State == INC_DIS_PENDING) | 
 | 4200 |           break; | 
 | 4201 |         if(plci->Sig.Id!=0xff) | 
 | 4202 |         { | 
 | 4203 |           plci->State = OUTG_DIS_PENDING; | 
 | 4204 |           sendf(appl,_DISCONNECT_R|CONFIRM,Id,Number,"w",0); | 
 | 4205 |         } | 
 | 4206 |         break; | 
 | 4207 |  | 
 | 4208 |       case SUSPEND_REQ: | 
 | 4209 |         break; | 
 | 4210 |  | 
 | 4211 |       case RESUME_REQ: | 
 | 4212 |         break; | 
 | 4213 |  | 
 | 4214 |       case _CONNECT_B3_R: | 
 | 4215 |         if(rc!=OK) | 
 | 4216 |         { | 
 | 4217 |           sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",_WRONG_IDENTIFIER); | 
 | 4218 |           break; | 
 | 4219 |         } | 
 | 4220 |         ncci = get_ncci (plci, ch, 0); | 
 | 4221 |         Id = (Id & 0xffff) | (((dword) ncci) << 16); | 
 | 4222 |         plci->channels++; | 
 | 4223 |         if(req==N_RESET) | 
 | 4224 |         { | 
 | 4225 |           a->ncci_state[ncci] = INC_ACT_PENDING; | 
 | 4226 |           sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0); | 
 | 4227 |           sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); | 
 | 4228 |         } | 
 | 4229 |         else | 
 | 4230 |         { | 
 | 4231 |           a->ncci_state[ncci] = OUTG_CON_PENDING; | 
 | 4232 |           sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0); | 
 | 4233 |         } | 
 | 4234 |         break; | 
 | 4235 |  | 
 | 4236 |       case _CONNECT_B3_I|RESPONSE: | 
 | 4237 |         break; | 
 | 4238 |  | 
 | 4239 |       case _RESET_B3_R: | 
 | 4240 | /*        sendf(appl,_RESET_B3_R|CONFIRM,Id,Number,"w",0);*/ | 
 | 4241 |         break; | 
 | 4242 |  | 
 | 4243 |       case _DISCONNECT_B3_R: | 
 | 4244 |         sendf(appl,_DISCONNECT_B3_R|CONFIRM,Id,Number,"w",0); | 
 | 4245 |         break; | 
 | 4246 |  | 
 | 4247 |       case _MANUFACTURER_R: | 
 | 4248 |         break; | 
 | 4249 |  | 
 | 4250 |       case PERM_LIST_REQ: | 
 | 4251 |         if(rc!=OK) | 
 | 4252 |         { | 
 | 4253 |           Info = _WRONG_IDENTIFIER; | 
 | 4254 |           sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info); | 
 | 4255 |           plci_remove(plci); | 
 | 4256 |         } | 
 | 4257 |         else | 
 | 4258 |           sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info); | 
 | 4259 |         break; | 
 | 4260 |  | 
 | 4261 |       default: | 
 | 4262 |         break; | 
 | 4263 |       } | 
 | 4264 |       plci->command = 0; | 
 | 4265 |     } | 
 | 4266 |     else if (plci->internal_command) | 
 | 4267 |     { | 
 | 4268 |       switch(plci->internal_command) | 
 | 4269 |       { | 
 | 4270 |       case BLOCK_PLCI: | 
 | 4271 |         return; | 
 | 4272 |  | 
 | 4273 |       case GET_MWI_STATE: | 
 | 4274 |         if(rc==OK) /* command supported, wait for indication */ | 
 | 4275 |         { | 
 | 4276 |           return; | 
 | 4277 |         } | 
 | 4278 |         plci_remove(plci); | 
 | 4279 |         break; | 
 | 4280 |  | 
 | 4281 |         /* Get Supported Services */ | 
 | 4282 |       case GETSERV_REQ_PEND: | 
 | 4283 |         if(rc==OK) /* command supported, wait for indication */ | 
 | 4284 |         { | 
 | 4285 |           break; | 
 | 4286 |         } | 
 | 4287 |         PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY); | 
 | 4288 |         sendf(appl, _FACILITY_R|CONFIRM, Id, Number, "wws",0,3,SSstruct); | 
 | 4289 |         plci_remove(plci); | 
 | 4290 |         break; | 
 | 4291 |  | 
 | 4292 |       case INTERR_DIVERSION_REQ_PEND:      /* Interrogate Parameters        */ | 
 | 4293 |       case INTERR_NUMBERS_REQ_PEND: | 
 | 4294 |       case CF_START_PEND:                  /* Call Forwarding Start pending */ | 
 | 4295 |       case CF_STOP_PEND:                   /* Call Forwarding Stop pending  */ | 
 | 4296 |       case CCBS_REQUEST_REQ_PEND: | 
 | 4297 |       case CCBS_DEACTIVATE_REQ_PEND: | 
 | 4298 |       case CCBS_INTERROGATE_REQ_PEND: | 
 | 4299 |         switch(plci->internal_command) | 
 | 4300 |         { | 
 | 4301 |           case INTERR_DIVERSION_REQ_PEND: | 
 | 4302 |             SSparms[1] = S_INTERROGATE_DIVERSION; | 
 | 4303 |             break; | 
 | 4304 |           case INTERR_NUMBERS_REQ_PEND: | 
 | 4305 |             SSparms[1] = S_INTERROGATE_NUMBERS; | 
 | 4306 |             break; | 
 | 4307 |           case CF_START_PEND: | 
 | 4308 |             SSparms[1] = S_CALL_FORWARDING_START; | 
 | 4309 |             break; | 
 | 4310 |           case CF_STOP_PEND: | 
 | 4311 |             SSparms[1] = S_CALL_FORWARDING_STOP; | 
 | 4312 |             break; | 
 | 4313 |           case CCBS_REQUEST_REQ_PEND: | 
 | 4314 |             SSparms[1] = S_CCBS_REQUEST; | 
 | 4315 |             break; | 
 | 4316 |           case CCBS_DEACTIVATE_REQ_PEND: | 
 | 4317 |             SSparms[1] = S_CCBS_DEACTIVATE; | 
 | 4318 |             break; | 
 | 4319 |           case CCBS_INTERROGATE_REQ_PEND: | 
 | 4320 |             SSparms[1] = S_CCBS_INTERROGATE; | 
 | 4321 |             break; | 
 | 4322 |         } | 
 | 4323 |         if(global_req==ASSIGN) | 
 | 4324 |         { | 
 | 4325 |           dbug(1,dprintf("AssignDiversion_RC=0x%x/0x%x",req,rc)); | 
 | 4326 |           return; | 
 | 4327 |         } | 
 | 4328 |         if(!plci->appl) break; | 
 | 4329 |         if(rc==ISDN_GUARD_REJ) | 
 | 4330 |         { | 
 | 4331 |           Info = _CAPI_GUARD_ERROR; | 
 | 4332 |         } | 
 | 4333 |         else if(rc!=OK) | 
 | 4334 |         { | 
 | 4335 |           Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED; | 
 | 4336 |         } | 
 | 4337 |         sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7, | 
 | 4338 |               plci->number,"wws",Info,(word)3,SSparms); | 
 | 4339 |         if(Info) plci_remove(plci); | 
 | 4340 |         break; | 
 | 4341 |  | 
 | 4342 |         /* 3pty conference pending */ | 
 | 4343 |       case PTY_REQ_PEND: | 
 | 4344 |         if(!plci->relatedPTYPLCI) break; | 
 | 4345 |         rplci = plci->relatedPTYPLCI; | 
 | 4346 |         SSparms[1] = plci->ptyState; | 
 | 4347 |         rId = ((word)rplci->Id<<8)|rplci->adapter->Id; | 
 | 4348 |         if(rplci->tel) rId|=EXT_CONTROLLER; | 
 | 4349 |         if(rc!=OK) | 
 | 4350 |         { | 
 | 4351 |           Info = 0x300E; /* not supported */ | 
 | 4352 |           plci->relatedPTYPLCI = NULL; | 
 | 4353 |           plci->ptyState = 0; | 
 | 4354 |         } | 
 | 4355 |         sendf(rplci->appl, | 
 | 4356 |               _FACILITY_R|CONFIRM, | 
 | 4357 |               rId, | 
 | 4358 |               plci->number, | 
 | 4359 |               "wws",Info,(word)3,SSparms); | 
 | 4360 |         break; | 
 | 4361 |  | 
 | 4362 |         /* Explicit Call Transfer pending */ | 
 | 4363 |       case ECT_REQ_PEND: | 
 | 4364 |         dbug(1,dprintf("ECT_RC=0x%x/0x%x",req,rc)); | 
 | 4365 |         if(!plci->relatedPTYPLCI) break; | 
 | 4366 |         rplci = plci->relatedPTYPLCI; | 
 | 4367 |         SSparms[1] = S_ECT; | 
 | 4368 |         rId = ((word)rplci->Id<<8)|rplci->adapter->Id; | 
 | 4369 |         if(rplci->tel) rId|=EXT_CONTROLLER; | 
 | 4370 |         if(rc!=OK) | 
 | 4371 |         { | 
 | 4372 |           Info = 0x300E; /* not supported */ | 
 | 4373 |           plci->relatedPTYPLCI = NULL; | 
 | 4374 |           plci->ptyState = 0; | 
 | 4375 |         } | 
 | 4376 |         sendf(rplci->appl, | 
 | 4377 |               _FACILITY_R|CONFIRM, | 
 | 4378 |               rId, | 
 | 4379 |               plci->number, | 
 | 4380 |               "wws",Info,(word)3,SSparms); | 
 | 4381 |         break; | 
 | 4382 |  | 
 | 4383 |       case _MANUFACTURER_R: | 
 | 4384 |         dbug(1,dprintf("_Manufacturer_R=0x%x/0x%x",req,rc)); | 
 | 4385 |         if ((global_req == ASSIGN) && (rc != ASSIGN_OK)) | 
 | 4386 |         { | 
 | 4387 |           dbug(1,dprintf("No more IDs")); | 
 | 4388 |           sendf(appl,_MANUFACTURER_R|CONFIRM,Id,Number,"dww",_DI_MANU_ID,_MANUFACTURER_R,_OUT_OF_PLCI); | 
 | 4389 |           plci_remove(plci);  /* after codec init, internal codec commands pending */ | 
 | 4390 |         } | 
 | 4391 |         break; | 
 | 4392 |  | 
 | 4393 |       case _CONNECT_R: | 
 | 4394 |         dbug(1,dprintf("_Connect_R=0x%x/0x%x",req,rc)); | 
 | 4395 |         if ((global_req == ASSIGN) && (rc != ASSIGN_OK)) | 
 | 4396 |         { | 
 | 4397 |           dbug(1,dprintf("No more IDs")); | 
 | 4398 |           sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI); | 
 | 4399 |           plci_remove(plci);  /* after codec init, internal codec commands pending */ | 
 | 4400 |         } | 
 | 4401 |         break; | 
 | 4402 |  | 
 | 4403 |       case PERM_COD_HOOK:                     /* finished with Hook_Ind */ | 
 | 4404 |         return; | 
 | 4405 |  | 
 | 4406 |       case PERM_COD_CALL: | 
 | 4407 |         dbug(1,dprintf("***Codec Connect_Pending A, Rc = 0x%x",rc)); | 
 | 4408 |         plci->internal_command = PERM_COD_CONN_PEND; | 
 | 4409 |         return; | 
 | 4410 |  | 
 | 4411 |       case PERM_COD_ASSIGN: | 
 | 4412 |         dbug(1,dprintf("***Codec Assign A, Rc = 0x%x",rc)); | 
 | 4413 |         if(rc!=ASSIGN_OK) break; | 
 | 4414 |         sig_req(plci,CALL_REQ,0); | 
 | 4415 |         send_req(plci); | 
 | 4416 |         plci->internal_command = PERM_COD_CALL; | 
 | 4417 |         return; | 
 | 4418 |  | 
 | 4419 |         /* Null Call Reference Request pending */ | 
 | 4420 |       case C_NCR_FAC_REQ: | 
 | 4421 |         dbug(1,dprintf("NCR_FAC=0x%x/0x%x",req,rc)); | 
 | 4422 |         if(global_req==ASSIGN) | 
 | 4423 |         { | 
 | 4424 |           if(rc==ASSIGN_OK) | 
 | 4425 |           { | 
 | 4426 |             return; | 
 | 4427 |           } | 
 | 4428 |           else | 
 | 4429 |           { | 
 | 4430 |             sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE); | 
 | 4431 |             appl->NullCREnable = FALSE; | 
 | 4432 |             plci_remove(plci); | 
 | 4433 |           } | 
 | 4434 |         } | 
 | 4435 |         else if(req==NCR_FACILITY) | 
 | 4436 |         { | 
 | 4437 |           if(rc==OK) | 
 | 4438 |           { | 
 | 4439 |             sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",0); | 
 | 4440 |           } | 
 | 4441 |           else | 
 | 4442 |           { | 
 | 4443 |             sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE); | 
 | 4444 |             appl->NullCREnable = FALSE; | 
 | 4445 |           } | 
 | 4446 |           plci_remove(plci); | 
 | 4447 |         } | 
 | 4448 |         break; | 
 | 4449 |  | 
 | 4450 |       case HOOK_ON_REQ: | 
 | 4451 |         if(plci->channels) | 
 | 4452 |         { | 
 | 4453 |           if(a->ncci_state[ncci]==CONNECTED) | 
 | 4454 |           { | 
 | 4455 |             a->ncci_state[ncci] = OUTG_DIS_PENDING; | 
 | 4456 |             cleanup_ncci_data (plci, ncci); | 
 | 4457 |             nl_req_ncci(plci,N_DISC,(byte)ncci); | 
 | 4458 |           } | 
 | 4459 |           break; | 
 | 4460 |         } | 
 | 4461 |         break; | 
 | 4462 |  | 
 | 4463 |       case HOOK_OFF_REQ: | 
 | 4464 |         if (plci->State == INC_DIS_PENDING) | 
 | 4465 |           break; | 
 | 4466 |         sig_req(plci,CALL_REQ,0); | 
 | 4467 |         send_req(plci); | 
 | 4468 |         plci->State=OUTG_CON_PENDING; | 
 | 4469 |         break; | 
 | 4470 |  | 
 | 4471 |  | 
 | 4472 |       case MWI_ACTIVATE_REQ_PEND: | 
 | 4473 |       case MWI_DEACTIVATE_REQ_PEND: | 
 | 4474 |         if(global_req == ASSIGN && rc==ASSIGN_OK) | 
 | 4475 |         { | 
 | 4476 |           dbug(1,dprintf("MWI_REQ assigned")); | 
 | 4477 |           return; | 
 | 4478 |         } | 
 | 4479 |         else if(rc!=OK) | 
 | 4480 |         {                  | 
 | 4481 |           if(rc==WRONG_IE) | 
 | 4482 |           { | 
 | 4483 |             Info = 0x2007; /* Illegal message parameter coding */ | 
 | 4484 |             dbug(1,dprintf("MWI_REQ invalid parameter")); | 
 | 4485 |           } | 
 | 4486 |           else | 
 | 4487 |           { | 
 | 4488 |             Info = 0x300B; /* not supported */                       | 
 | 4489 |             dbug(1,dprintf("MWI_REQ not supported")); | 
 | 4490 |           } | 
 | 4491 |           /* 0x3010: Request not allowed in this state */ | 
 | 4492 |           PUT_WORD(&SSparms[4],0x300E); /* SS not supported */ | 
 | 4493 |                      | 
 | 4494 |         } | 
 | 4495 |         if(plci->internal_command==MWI_ACTIVATE_REQ_PEND) | 
 | 4496 |         { | 
 | 4497 |           PUT_WORD(&SSparms[1],S_MWI_ACTIVATE); | 
 | 4498 |         } | 
 | 4499 |         else PUT_WORD(&SSparms[1],S_MWI_DEACTIVATE); | 
 | 4500 |  | 
 | 4501 |         if(plci->cr_enquiry) | 
 | 4502 |         { | 
 | 4503 |           sendf(plci->appl, | 
 | 4504 |                 _FACILITY_R|CONFIRM, | 
 | 4505 |                 Id&0xf, | 
 | 4506 |                 plci->number, | 
 | 4507 |                 "wws",Info,(word)3,SSparms); | 
 | 4508 |           if(rc!=OK) plci_remove(plci); | 
 | 4509 |         } | 
 | 4510 |         else | 
 | 4511 |         { | 
 | 4512 |           sendf(plci->appl, | 
 | 4513 |                 _FACILITY_R|CONFIRM, | 
 | 4514 |                 Id, | 
 | 4515 |                 plci->number, | 
 | 4516 |                 "wws",Info,(word)3,SSparms); | 
 | 4517 |         } | 
 | 4518 |         break; | 
 | 4519 |  | 
 | 4520 |       case CONF_BEGIN_REQ_PEND: | 
 | 4521 |       case CONF_ADD_REQ_PEND: | 
 | 4522 |       case CONF_SPLIT_REQ_PEND: | 
 | 4523 |       case CONF_DROP_REQ_PEND: | 
 | 4524 |       case CONF_ISOLATE_REQ_PEND: | 
 | 4525 |       case CONF_REATTACH_REQ_PEND: | 
 | 4526 |         dbug(1,dprintf("CONF_RC=0x%x/0x%x",req,rc)); | 
 | 4527 |         if((plci->internal_command==CONF_ADD_REQ_PEND)&&(!plci->relatedPTYPLCI)) break; | 
 | 4528 |         rplci = plci; | 
 | 4529 |         rId = Id; | 
 | 4530 |         switch(plci->internal_command) | 
 | 4531 |         { | 
 | 4532 |           case CONF_BEGIN_REQ_PEND: | 
 | 4533 |             SSparms[1] = S_CONF_BEGIN; | 
 | 4534 |             break; | 
 | 4535 |           case CONF_ADD_REQ_PEND: | 
 | 4536 |             SSparms[1] = S_CONF_ADD; | 
 | 4537 |             rplci = plci->relatedPTYPLCI; | 
 | 4538 |             rId = ((word)rplci->Id<<8)|rplci->adapter->Id; | 
 | 4539 |             break; | 
 | 4540 |           case CONF_SPLIT_REQ_PEND: | 
 | 4541 |             SSparms[1] = S_CONF_SPLIT; | 
 | 4542 |             break; | 
 | 4543 |           case CONF_DROP_REQ_PEND: | 
 | 4544 |             SSparms[1] = S_CONF_DROP; | 
 | 4545 |             break; | 
 | 4546 |           case CONF_ISOLATE_REQ_PEND: | 
 | 4547 |             SSparms[1] = S_CONF_ISOLATE; | 
 | 4548 |             break; | 
 | 4549 |           case CONF_REATTACH_REQ_PEND: | 
 | 4550 |             SSparms[1] = S_CONF_REATTACH; | 
 | 4551 |             break; | 
 | 4552 |         } | 
 | 4553 |          | 
 | 4554 |         if(rc!=OK) | 
 | 4555 |         { | 
 | 4556 |           Info = 0x300E; /* not supported */ | 
 | 4557 |           plci->relatedPTYPLCI = NULL; | 
 | 4558 |           plci->ptyState = 0; | 
 | 4559 |         } | 
 | 4560 |         sendf(rplci->appl, | 
 | 4561 |               _FACILITY_R|CONFIRM, | 
 | 4562 |               rId, | 
 | 4563 |               plci->number, | 
 | 4564 |               "wws",Info,(word)3,SSparms); | 
 | 4565 |         break; | 
 | 4566 |  | 
 | 4567 |       case VSWITCH_REQ_PEND: | 
 | 4568 |         if(rc!=OK) | 
 | 4569 |         { | 
 | 4570 |           if(plci->relatedPTYPLCI) | 
 | 4571 |           { | 
 | 4572 |             plci->relatedPTYPLCI->vswitchstate=0; | 
 | 4573 |             plci->relatedPTYPLCI->vsprot=0; | 
 | 4574 |             plci->relatedPTYPLCI->vsprotdialect=0;     | 
 | 4575 |           } | 
 | 4576 |           plci->vswitchstate=0; | 
 | 4577 |           plci->vsprot=0; | 
 | 4578 |           plci->vsprotdialect=0; | 
 | 4579 |         } | 
 | 4580 |         else | 
 | 4581 |         { | 
 | 4582 |           if(plci->relatedPTYPLCI && | 
 | 4583 |              plci->vswitchstate==1 && | 
 | 4584 |              plci->relatedPTYPLCI->vswitchstate==3) /* join complete */ | 
 | 4585 |             plci->vswitchstate=3; | 
 | 4586 |         } | 
 | 4587 |         break; | 
 | 4588 |  | 
 | 4589 |   /* Call Deflection Request pending (SSCT) */ | 
 | 4590 |       case CD_REQ_PEND: | 
 | 4591 |         SSparms[1] = S_CALL_DEFLECTION; | 
 | 4592 |         if(rc!=OK) | 
 | 4593 |         { | 
 | 4594 |           Info = 0x300E; /* not supported */ | 
 | 4595 |           plci->appl->CDEnable = 0; | 
 | 4596 |         }   | 
 | 4597 |         sendf(plci->appl,_FACILITY_R|CONFIRM,Id, | 
 | 4598 |           plci->number,"wws",Info,(word)3,SSparms); | 
 | 4599 |         break; | 
 | 4600 |  | 
 | 4601 |       case RTP_CONNECT_B3_REQ_COMMAND_2: | 
 | 4602 |         if (rc == OK) | 
 | 4603 |         { | 
 | 4604 |           ncci = get_ncci (plci, ch, 0); | 
 | 4605 |           Id = (Id & 0xffff) | (((dword) ncci) << 16); | 
 | 4606 |           plci->channels++; | 
 | 4607 |           a->ncci_state[ncci] = OUTG_CON_PENDING; | 
 | 4608 |         } | 
 | 4609 |  | 
 | 4610 |       default: | 
 | 4611 |         if (plci->internal_command_queue[0]) | 
 | 4612 |         { | 
 | 4613 |           (*(plci->internal_command_queue[0]))(Id, plci, rc); | 
 | 4614 |           if (plci->internal_command) | 
 | 4615 |             return; | 
 | 4616 |         } | 
 | 4617 |         break; | 
 | 4618 |       } | 
 | 4619 |       next_internal_command (Id, plci); | 
 | 4620 |     } | 
 | 4621 |   } | 
 | 4622 |   else /* appl==0 */ | 
 | 4623 |   { | 
 | 4624 |     Id = ((word)plci->Id<<8)|plci->adapter->Id; | 
 | 4625 |     if(plci->tel) Id|=EXT_CONTROLLER; | 
 | 4626 |  | 
 | 4627 |     switch(plci->internal_command) | 
 | 4628 |     { | 
 | 4629 |     case BLOCK_PLCI: | 
 | 4630 |       return; | 
 | 4631 |  | 
 | 4632 |     case START_L1_SIG_ASSIGN_PEND: | 
 | 4633 |     case REM_L1_SIG_ASSIGN_PEND: | 
 | 4634 |       if(global_req == ASSIGN) | 
 | 4635 |       { | 
 | 4636 |         break; | 
 | 4637 |       } | 
 | 4638 |       else | 
 | 4639 |       { | 
 | 4640 |         dbug(1,dprintf("***L1 Req rem PLCI")); | 
 | 4641 |         plci->internal_command = 0; | 
 | 4642 |         sig_req(plci,REMOVE,0); | 
 | 4643 |         send_req(plci); | 
 | 4644 |       } | 
 | 4645 |       break; | 
 | 4646 |  | 
 | 4647 |       /* Call Deflection Request pending, just no appl ptr assigned */ | 
 | 4648 |     case CD_REQ_PEND: | 
 | 4649 |       SSparms[1] = S_CALL_DEFLECTION; | 
 | 4650 |       if(rc!=OK) | 
 | 4651 |       { | 
 | 4652 |         Info = 0x300E; /* not supported */ | 
 | 4653 |       } | 
 | 4654 |       for(i=0; i<max_appl; i++) | 
 | 4655 |       { | 
 | 4656 |         if(application[i].CDEnable) | 
 | 4657 |         { | 
 | 4658 |           if(!application[i].Id) application[i].CDEnable = 0; | 
 | 4659 |           else | 
 | 4660 |           { | 
 | 4661 |             sendf(&application[i],_FACILITY_R|CONFIRM,Id, | 
 | 4662 |                   plci->number,"wws",Info,(word)3,SSparms); | 
 | 4663 |             if(Info) application[i].CDEnable = 0; | 
 | 4664 |           } | 
 | 4665 |         } | 
 | 4666 |       } | 
 | 4667 |       plci->internal_command = 0; | 
 | 4668 |       break; | 
 | 4669 |  | 
 | 4670 |     case PERM_COD_HOOK:                   /* finished with Hook_Ind */ | 
 | 4671 |       return; | 
 | 4672 |  | 
 | 4673 |     case PERM_COD_CALL: | 
 | 4674 |       plci->internal_command = PERM_COD_CONN_PEND; | 
 | 4675 |       dbug(1,dprintf("***Codec Connect_Pending, Rc = 0x%x",rc)); | 
 | 4676 |       return; | 
 | 4677 |  | 
 | 4678 |     case PERM_COD_ASSIGN: | 
 | 4679 |       dbug(1,dprintf("***Codec Assign, Rc = 0x%x",rc)); | 
 | 4680 |       plci->internal_command = 0; | 
 | 4681 |       if(rc!=ASSIGN_OK) break; | 
 | 4682 |       plci->internal_command = PERM_COD_CALL; | 
 | 4683 |       sig_req(plci,CALL_REQ,0); | 
 | 4684 |       send_req(plci); | 
 | 4685 |       return; | 
 | 4686 |  | 
 | 4687 |     case LISTEN_SIG_ASSIGN_PEND: | 
 | 4688 |       if(rc == ASSIGN_OK) | 
 | 4689 |       { | 
 | 4690 |         plci->internal_command = 0; | 
 | 4691 |         dbug(1,dprintf("ListenCheck, new SIG_ID = 0x%x",plci->Sig.Id)); | 
 | 4692 |         add_p(plci,ESC,"\x02\x18\x00");             /* support call waiting */ | 
 | 4693 |         sig_req(plci,INDICATE_REQ,0); | 
 | 4694 |         send_req(plci); | 
 | 4695 |       } | 
 | 4696 |       else | 
 | 4697 |       { | 
 | 4698 |         dbug(1,dprintf("ListenCheck failed (assignRc=0x%x)",rc)); | 
 | 4699 |         a->listen_active--; | 
 | 4700 |         plci_remove(plci); | 
 | 4701 |         plci->State = IDLE; | 
 | 4702 |       } | 
 | 4703 |       break; | 
 | 4704 |  | 
 | 4705 |     case USELAW_REQ: | 
 | 4706 |       if(global_req == ASSIGN) | 
 | 4707 |       { | 
 | 4708 |         if (rc==ASSIGN_OK) | 
 | 4709 |       { | 
 | 4710 |         sig_req(plci,LAW_REQ,0); | 
 | 4711 |         send_req(plci); | 
 | 4712 |         dbug(1,dprintf("Auto-Law assigned")); | 
 | 4713 |         } | 
 | 4714 |         else | 
 | 4715 |         { | 
 | 4716 |           dbug(1,dprintf("Auto-Law assign failed")); | 
 | 4717 |           a->automatic_law = 3; | 
 | 4718 |           plci->internal_command = 0; | 
 | 4719 |           a->automatic_lawPLCI = NULL; | 
 | 4720 |         } | 
 | 4721 |         break; | 
 | 4722 |       } | 
 | 4723 |       else if(req == LAW_REQ && rc==OK) | 
 | 4724 |       { | 
 | 4725 |         dbug(1,dprintf("Auto-Law initiated")); | 
 | 4726 |         a->automatic_law = 2; | 
 | 4727 |         plci->internal_command = 0; | 
 | 4728 |       } | 
 | 4729 |       else | 
 | 4730 |       { | 
 | 4731 |         dbug(1,dprintf("Auto-Law not supported")); | 
 | 4732 |         a->automatic_law = 3; | 
 | 4733 |         plci->internal_command = 0; | 
 | 4734 |         sig_req(plci,REMOVE,0); | 
 | 4735 |         send_req(plci); | 
 | 4736 |         a->automatic_lawPLCI = NULL; | 
 | 4737 |       } | 
 | 4738 |       break; | 
 | 4739 |     } | 
 | 4740 |     plci_remove_check(plci); | 
 | 4741 |   } | 
 | 4742 | } | 
 | 4743 |  | 
 | 4744 | void data_rc(PLCI   * plci, byte ch) | 
 | 4745 | { | 
 | 4746 |   dword Id; | 
 | 4747 |   DIVA_CAPI_ADAPTER   * a; | 
 | 4748 |   NCCI   *ncci_ptr; | 
 | 4749 |   DATA_B3_DESC   *data; | 
 | 4750 |   word ncci; | 
 | 4751 |  | 
 | 4752 |   if (plci->appl) | 
 | 4753 |   { | 
 | 4754 |     TransmitBufferFree (plci->appl, plci->data_sent_ptr); | 
 | 4755 |     a = plci->adapter; | 
 | 4756 |     ncci = a->ch_ncci[ch]; | 
 | 4757 |     if (ncci && (a->ncci_plci[ncci] == plci->Id)) | 
 | 4758 |     { | 
 | 4759 |       ncci_ptr = &(a->ncci[ncci]); | 
 | 4760 |       dbug(1,dprintf("data_out=%d, data_pending=%d",ncci_ptr->data_out,ncci_ptr->data_pending)); | 
 | 4761 |       if (ncci_ptr->data_pending) | 
 | 4762 |       { | 
 | 4763 |         data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]); | 
 | 4764 |         if (!(data->Flags &4) && a->ncci_state[ncci]) | 
 | 4765 |         { | 
 | 4766 |           Id = (((dword)ncci)<<16)|((word)plci->Id<<8)|a->Id; | 
 | 4767 |           if(plci->tel) Id|=EXT_CONTROLLER; | 
 | 4768 |           sendf(plci->appl,_DATA_B3_R|CONFIRM,Id,data->Number, | 
 | 4769 |                 "ww",data->Handle,0); | 
 | 4770 |         } | 
 | 4771 |         (ncci_ptr->data_out)++; | 
 | 4772 |         if (ncci_ptr->data_out == MAX_DATA_B3) | 
 | 4773 |           ncci_ptr->data_out = 0; | 
 | 4774 |         (ncci_ptr->data_pending)--; | 
 | 4775 |       } | 
 | 4776 |     } | 
 | 4777 |   } | 
 | 4778 | } | 
 | 4779 |  | 
 | 4780 | void data_ack(PLCI   * plci, byte ch) | 
 | 4781 | { | 
 | 4782 |   dword Id; | 
 | 4783 |   DIVA_CAPI_ADAPTER   * a; | 
 | 4784 |   NCCI   *ncci_ptr; | 
 | 4785 |   word ncci; | 
 | 4786 |  | 
 | 4787 |   a = plci->adapter; | 
 | 4788 |   ncci = a->ch_ncci[ch]; | 
 | 4789 |   ncci_ptr = &(a->ncci[ncci]); | 
 | 4790 |   if (ncci_ptr->data_ack_pending) | 
 | 4791 |   { | 
 | 4792 |     if (a->ncci_state[ncci] && (a->ncci_plci[ncci] == plci->Id)) | 
 | 4793 |     { | 
 | 4794 |       Id = (((dword)ncci)<<16)|((word)plci->Id<<8)|a->Id; | 
 | 4795 |       if(plci->tel) Id|=EXT_CONTROLLER; | 
 | 4796 |       sendf(plci->appl,_DATA_B3_R|CONFIRM,Id,ncci_ptr->DataAck[ncci_ptr->data_ack_out].Number, | 
 | 4797 |             "ww",ncci_ptr->DataAck[ncci_ptr->data_ack_out].Handle,0); | 
 | 4798 |     } | 
 | 4799 |     (ncci_ptr->data_ack_out)++; | 
 | 4800 |     if (ncci_ptr->data_ack_out == MAX_DATA_ACK) | 
 | 4801 |       ncci_ptr->data_ack_out = 0; | 
 | 4802 |     (ncci_ptr->data_ack_pending)--; | 
 | 4803 |   } | 
 | 4804 | } | 
 | 4805 |  | 
 | 4806 | void sig_ind(PLCI   * plci) | 
 | 4807 | { | 
 | 4808 |   dword x_Id; | 
 | 4809 |   dword Id; | 
 | 4810 |   dword rId; | 
 | 4811 |   word Number = 0; | 
 | 4812 |   word i; | 
 | 4813 |   word cip; | 
 | 4814 |   dword cip_mask; | 
 | 4815 |   byte   *ie; | 
 | 4816 |   DIVA_CAPI_ADAPTER   * a; | 
 | 4817 |     API_PARSE saved_parms[MAX_MSG_PARMS+1]; | 
 | 4818 | #define MAXPARMSIDS 31 | 
 | 4819 |     byte   * parms[MAXPARMSIDS]; | 
 | 4820 |     byte   * add_i[4]; | 
 | 4821 |     byte   * multi_fac_parms[MAX_MULTI_IE]; | 
 | 4822 |     byte   * multi_pi_parms [MAX_MULTI_IE]; | 
 | 4823 |     byte   * multi_ssext_parms [MAX_MULTI_IE]; | 
 | 4824 |     byte   * multi_CiPN_parms [MAX_MULTI_IE]; | 
 | 4825 |  | 
 | 4826 |     byte   * multi_vswitch_parms [MAX_MULTI_IE]; | 
 | 4827 |  | 
 | 4828 |   byte ai_len; | 
 | 4829 |     byte   *esc_chi = ""; | 
 | 4830 |     byte   *esc_law = ""; | 
 | 4831 |     byte   *pty_cai = ""; | 
 | 4832 |     byte   *esc_cr  = ""; | 
 | 4833 |     byte   *esc_profile = ""; | 
 | 4834 |  | 
 | 4835 |     byte facility[256]; | 
 | 4836 |   PLCI   * tplci = NULL; | 
 | 4837 |   byte chi[] = "\x02\x18\x01"; | 
 | 4838 |   byte voice_cai[]  = "\x06\x14\x00\x00\x00\x00\x08"; | 
 | 4839 |     byte resume_cau[] = "\x05\x05\x00\x02\x00\x00"; | 
 | 4840 |   /* ESC_MSGTYPE must be the last but one message, a new IE has to be */ | 
 | 4841 |   /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */ | 
 | 4842 |   /* SMSG is situated at the end because its 0 (for compatibility reasons */ | 
 | 4843 |   /* (see Info_Mask Bit 4, first IE. then the message type)           */ | 
 | 4844 |     word parms_id[] = | 
 | 4845 |          {MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA, | 
 | 4846 |           UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW, | 
 | 4847 |           RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR, | 
 | 4848 |           CST, ESC_PROFILE, 0xff, ESC_MSGTYPE, SMSG}; | 
 | 4849 |           /* 14 FTY repl by ESC_CHI */ | 
 | 4850 |           /* 18 PI  repl by ESC_LAW */ | 
 | 4851 |          /* removed OAD changed to 0xff for future use, OAD is multiIE now */ | 
 | 4852 |      word multi_fac_id[] = {1, FTY}; | 
 | 4853 |      word multi_pi_id[]  = {1, PI}; | 
 | 4854 |      word multi_CiPN_id[]  = {1, OAD}; | 
 | 4855 |      word multi_ssext_id[]  = {1, ESC_SSEXT}; | 
 | 4856 |  | 
 | 4857 |      word multi_vswitch_id[]  = {1, ESC_VSWITCH}; | 
 | 4858 |  | 
 | 4859 |   byte   * cau; | 
 | 4860 |   word ncci; | 
 | 4861 |     byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ | 
 | 4862 |     byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00"; | 
 | 4863 |     byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; | 
 | 4864 |     byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00"; | 
 | 4865 |   byte force_mt_info = FALSE; | 
 | 4866 |   byte dir; | 
 | 4867 |   dword d; | 
 | 4868 |   word w; | 
 | 4869 |  | 
 | 4870 |   a = plci->adapter; | 
 | 4871 |   Id = ((word)plci->Id<<8)|a->Id; | 
 | 4872 |   PUT_WORD(&SS_Ind[4],0x0000); | 
 | 4873 |  | 
 | 4874 |   if (plci->sig_remove_id) | 
 | 4875 |   { | 
 | 4876 |     plci->Sig.RNR = 2; /* discard */ | 
 | 4877 |     dbug(1,dprintf("SIG discard while remove pending")); | 
 | 4878 |     return; | 
 | 4879 |   } | 
 | 4880 |   if(plci->tel && plci->SuppState!=CALL_HELD) Id|=EXT_CONTROLLER; | 
 | 4881 |   dbug(1,dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d", | 
 | 4882 |     Id,plci->Id,plci->tel,plci->State,plci->channels,plci->hangup_flow_ctrl_timer)); | 
 | 4883 |   if(plci->Sig.Ind==CALL_HOLD_ACK && plci->channels) | 
 | 4884 |   { | 
 | 4885 |     plci->Sig.RNR = 1; | 
 | 4886 |     return; | 
 | 4887 |   } | 
 | 4888 |   if(plci->Sig.Ind==HANGUP && plci->channels) | 
 | 4889 |   { | 
 | 4890 |     plci->Sig.RNR = 1; | 
 | 4891 |     plci->hangup_flow_ctrl_timer++; | 
 | 4892 |     /* recover the network layer after timeout */ | 
 | 4893 |     if(plci->hangup_flow_ctrl_timer==100) | 
 | 4894 |     { | 
 | 4895 |       dbug(1,dprintf("Exceptional disc")); | 
 | 4896 |       plci->Sig.RNR = 0; | 
 | 4897 |       plci->hangup_flow_ctrl_timer = 0; | 
 | 4898 |       for (ncci = 1; ncci < MAX_NCCI+1; ncci++) | 
 | 4899 |       { | 
 | 4900 |         if (a->ncci_plci[ncci] == plci->Id) | 
 | 4901 |         { | 
 | 4902 |           cleanup_ncci_data (plci, ncci); | 
 | 4903 |           if(plci->channels)plci->channels--; | 
 | 4904 |           if (plci->appl) | 
 | 4905 |             sendf(plci->appl,_DISCONNECT_B3_I, (((dword) ncci) << 16) | Id,0,"ws",0,""); | 
 | 4906 |         } | 
 | 4907 |       } | 
 | 4908 |       if (plci->appl) | 
 | 4909 |         sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0); | 
 | 4910 |       plci_remove(plci); | 
 | 4911 |       plci->State=IDLE; | 
 | 4912 |     } | 
 | 4913 |     return; | 
 | 4914 |   } | 
 | 4915 |  | 
 | 4916 |   /* do first parse the info with no OAD in, because OAD will be converted */ | 
 | 4917 |   /* first the multiple facility IE, then mult. progress ind.              */ | 
 | 4918 |   /* then the parameters for the info_ind + conn_ind                       */ | 
 | 4919 |   IndParse(plci,multi_fac_id,multi_fac_parms,MAX_MULTI_IE); | 
 | 4920 |   IndParse(plci,multi_pi_id,multi_pi_parms,MAX_MULTI_IE); | 
 | 4921 |   IndParse(plci,multi_ssext_id,multi_ssext_parms,MAX_MULTI_IE); | 
 | 4922 |  | 
 | 4923 |   IndParse(plci,multi_vswitch_id,multi_vswitch_parms,MAX_MULTI_IE); | 
 | 4924 |  | 
 | 4925 |   IndParse(plci,parms_id,parms,0); | 
 | 4926 |   IndParse(plci,multi_CiPN_id,multi_CiPN_parms,MAX_MULTI_IE); | 
 | 4927 |   esc_chi  = parms[14]; | 
 | 4928 |   esc_law  = parms[18]; | 
 | 4929 |   pty_cai  = parms[24]; | 
 | 4930 |   esc_cr   = parms[25]; | 
 | 4931 |   esc_profile = parms[27]; | 
 | 4932 |   if(esc_cr[0] && plci) | 
 | 4933 |   { | 
 | 4934 |     if(plci->cr_enquiry && plci->appl) | 
 | 4935 |     { | 
 | 4936 |       plci->cr_enquiry = FALSE; | 
 | 4937 |       /* d = MANU_ID            */ | 
 | 4938 |       /* w = m_command          */ | 
 | 4939 |       /* b = total length       */ | 
 | 4940 |       /* b = indication type    */ | 
 | 4941 |       /* b = length of all IEs  */ | 
 | 4942 |       /* b = IE1                */ | 
 | 4943 |       /* S = IE1 length + cont. */ | 
 | 4944 |       /* b = IE2                */ | 
 | 4945 |       /* S = IE2 lenght + cont. */ | 
 | 4946 |       sendf(plci->appl, | 
 | 4947 |         _MANUFACTURER_I, | 
 | 4948 |         Id, | 
 | 4949 |         0, | 
 | 4950 |         "dwbbbbSbS",_DI_MANU_ID,plci->m_command, | 
 | 4951 |         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); | 
 | 4952 |     } | 
 | 4953 |   } | 
 | 4954 |   /* create the additional info structure                                  */ | 
 | 4955 |   add_i[1] = parms[15]; /* KEY of additional info */ | 
 | 4956 |   add_i[2] = parms[11]; /* UUI of additional info */ | 
 | 4957 |   ai_len = AddInfo(add_i,multi_fac_parms, esc_chi, facility); | 
 | 4958 |  | 
 | 4959 |   /* the ESC_LAW indicates if u-Law or a-Law is actually used by the card  */ | 
 | 4960 |   /* indication returns by the card if requested by the function           */ | 
 | 4961 |   /* AutomaticLaw() after driver init                                      */ | 
 | 4962 |   if (a->automatic_law<4) | 
 | 4963 |   { | 
 | 4964 |     if(esc_law[0]){ | 
 | 4965 |       if(esc_law[2]){ | 
 | 4966 |         dbug(0,dprintf("u-Law selected")); | 
 | 4967 |         a->u_law = 1; | 
 | 4968 |       } | 
 | 4969 |       else { | 
 | 4970 |         dbug(0,dprintf("a-Law selected")); | 
 | 4971 |         a->u_law = 0; | 
 | 4972 |       } | 
 | 4973 |       a->automatic_law = 4; | 
 | 4974 |       if(plci==a->automatic_lawPLCI) { | 
 | 4975 |         plci->internal_command = 0; | 
 | 4976 |         sig_req(plci,REMOVE,0); | 
 | 4977 |         send_req(plci); | 
 | 4978 |         a->automatic_lawPLCI = NULL; | 
 | 4979 |       } | 
 | 4980 |     } | 
 | 4981 |     if (esc_profile[0]) | 
 | 4982 |     { | 
 | 4983 |       dbug (1, dprintf ("[%06x] CardProfile: %lx %lx %lx %lx %lx", | 
 | 4984 |         UnMapController (a->Id), GET_DWORD (&esc_profile[6]), | 
 | 4985 |         GET_DWORD (&esc_profile[10]), GET_DWORD (&esc_profile[14]), | 
 | 4986 |         GET_DWORD (&esc_profile[18]), GET_DWORD (&esc_profile[46]))); | 
 | 4987 |  | 
 | 4988 |       a->profile.Global_Options &= 0x000000ffL; | 
 | 4989 |       a->profile.B1_Protocols &= 0x000003ffL; | 
 | 4990 |       a->profile.B2_Protocols &= 0x00001fdfL; | 
 | 4991 |       a->profile.B3_Protocols &= 0x000000b7L; | 
 | 4992 |  | 
 | 4993 |       a->profile.Global_Options &= GET_DWORD (&esc_profile[6]) | | 
 | 4994 |         GL_BCHANNEL_OPERATION_SUPPORTED; | 
 | 4995 |       a->profile.B1_Protocols &= GET_DWORD (&esc_profile[10]); | 
 | 4996 |       a->profile.B2_Protocols &= GET_DWORD (&esc_profile[14]); | 
 | 4997 |       a->profile.B3_Protocols &= GET_DWORD (&esc_profile[18]); | 
 | 4998 |       a->manufacturer_features = GET_DWORD (&esc_profile[46]); | 
 | 4999 |       a->man_profile.private_options = 0; | 
 | 5000 |  | 
 | 5001 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER) | 
 | 5002 |       { | 
 | 5003 |         a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER; | 
 | 5004 |         a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED; | 
 | 5005 |       } | 
 | 5006 |  | 
 | 5007 |  | 
 | 5008 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_RTP) | 
 | 5009 |         a->man_profile.private_options |= 1L << PRIVATE_RTP; | 
 | 5010 |       a->man_profile.rtp_primary_payloads = GET_DWORD (&esc_profile[50]); | 
 | 5011 |       a->man_profile.rtp_additional_payloads = GET_DWORD (&esc_profile[54]); | 
 | 5012 |  | 
 | 5013 |  | 
 | 5014 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_T38) | 
 | 5015 |         a->man_profile.private_options |= 1L << PRIVATE_T38; | 
 | 5016 |  | 
 | 5017 |  | 
 | 5018 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD) | 
 | 5019 |         a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD; | 
 | 5020 |  | 
 | 5021 |  | 
 | 5022 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_V18) | 
 | 5023 |         a->man_profile.private_options |= 1L << PRIVATE_V18; | 
 | 5024 |  | 
 | 5025 |  | 
 | 5026 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE) | 
 | 5027 |         a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE; | 
 | 5028 |  | 
 | 5029 |  | 
 | 5030 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS) | 
 | 5031 |         a->man_profile.private_options |= 1L << PRIVATE_PIAFS; | 
 | 5032 |  | 
 | 5033 |  | 
 | 5034 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) | 
 | 5035 |         a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS; | 
 | 5036 |  | 
 | 5037 |  | 
 | 5038 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN) | 
 | 5039 |         a->man_profile.private_options |= 1L << PRIVATE_VOWN; | 
 | 5040 |  | 
 | 5041 |  | 
 | 5042 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD) | 
 | 5043 |         a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD; | 
 | 5044 |  | 
 | 5045 |     } | 
 | 5046 |     else | 
 | 5047 |     { | 
 | 5048 |       a->profile.Global_Options &= 0x0000007fL; | 
 | 5049 |       a->profile.B1_Protocols &= 0x000003dfL; | 
 | 5050 |       a->profile.B2_Protocols &= 0x00001adfL; | 
 | 5051 |       a->profile.B3_Protocols &= 0x000000b7L; | 
 | 5052 |       a->manufacturer_features &= MANUFACTURER_FEATURE_HARDDTMF; | 
 | 5053 |     } | 
 | 5054 |     if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF | | 
 | 5055 |       MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) | 
 | 5056 |     { | 
 | 5057 |       a->profile.Global_Options |= GL_DTMF_SUPPORTED; | 
 | 5058 |     } | 
 | 5059 |     a->manufacturer_features &= ~MANUFACTURER_FEATURE_OOB_CHANNEL; | 
 | 5060 |     dbug (1, dprintf ("[%06x] Profile: %lx %lx %lx %lx %lx", | 
 | 5061 |       UnMapController (a->Id), a->profile.Global_Options, | 
 | 5062 |       a->profile.B1_Protocols, a->profile.B2_Protocols, | 
 | 5063 |       a->profile.B3_Protocols, a->manufacturer_features)); | 
 | 5064 |   } | 
 | 5065 |   /* codec plci for the handset/hook state support is just an internal id  */ | 
 | 5066 |   if(plci!=a->AdvCodecPLCI) | 
 | 5067 |   { | 
 | 5068 |     force_mt_info =  SendMultiIE(plci,Id,multi_fac_parms, FTY, 0x20, 0); | 
 | 5069 |     force_mt_info |= SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, 0); | 
 | 5070 |     SendSSExtInd(NULL,plci,Id,multi_ssext_parms); | 
 | 5071 |     SendInfo(plci,Id, parms, force_mt_info); | 
 | 5072 |  | 
 | 5073 |     VSwitchReqInd(plci,Id,multi_vswitch_parms); | 
 | 5074 |  | 
 | 5075 |   } | 
 | 5076 |  | 
 | 5077 |   /* switch the codec to the b-channel                                     */ | 
 | 5078 |   if(esc_chi[0] && plci && !plci->SuppState){ | 
 | 5079 |     plci->b_channel = esc_chi[esc_chi[0]]&0x1f; | 
 | 5080 |     mixer_set_bchannel_id_esc (plci, plci->b_channel); | 
 | 5081 |     dbug(1,dprintf("storeChannel=0x%x",plci->b_channel)); | 
 | 5082 |     if(plci->tel==ADV_VOICE && plci->appl) { | 
 | 5083 |       SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a); | 
 | 5084 |     } | 
 | 5085 |   } | 
 | 5086 |  | 
 | 5087 |   if(plci->appl) Number = plci->appl->Number++; | 
 | 5088 |  | 
 | 5089 |   switch(plci->Sig.Ind) { | 
 | 5090 |   /* Response to Get_Supported_Services request */ | 
 | 5091 |   case S_SUPPORTED: | 
 | 5092 |     dbug(1,dprintf("S_Supported")); | 
 | 5093 |     if(!plci->appl) break; | 
 | 5094 |     if(pty_cai[0]==4) | 
 | 5095 |     { | 
 | 5096 |       PUT_DWORD(&CF_Ind[6],GET_DWORD(&pty_cai[1]) ); | 
 | 5097 |     } | 
 | 5098 |     else | 
 | 5099 |     { | 
 | 5100 |       PUT_DWORD(&CF_Ind[6],MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE); | 
 | 5101 |     } | 
 | 5102 |     PUT_WORD (&CF_Ind[1], 0); | 
 | 5103 |     PUT_WORD (&CF_Ind[4], 0); | 
 | 5104 |     sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7,plci->number, "wws",0,3,CF_Ind); | 
 | 5105 |     plci_remove(plci); | 
 | 5106 |     break; | 
 | 5107 |                      | 
 | 5108 |   /* Supplementary Service rejected */ | 
 | 5109 |   case S_SERVICE_REJ: | 
 | 5110 |     dbug(1,dprintf("S_Reject=0x%x",pty_cai[5])); | 
 | 5111 |     if(!pty_cai[0]) break; | 
 | 5112 |     switch (pty_cai[5]) | 
 | 5113 |     { | 
 | 5114 |     case ECT_EXECUTE: | 
 | 5115 |     case THREE_PTY_END: | 
 | 5116 |     case THREE_PTY_BEGIN: | 
 | 5117 |       if(!plci->relatedPTYPLCI) break; | 
 | 5118 |       tplci = plci->relatedPTYPLCI; | 
 | 5119 |       rId = ( (word)tplci->Id<<8)|tplci->adapter->Id; | 
 | 5120 |       if(tplci->tel) rId|=EXT_CONTROLLER; | 
 | 5121 |       if(pty_cai[5]==ECT_EXECUTE) | 
 | 5122 |       { | 
 | 5123 |         PUT_WORD(&SS_Ind[1],S_ECT); | 
 | 5124 |  | 
 | 5125 |         plci->vswitchstate=0; | 
 | 5126 |         plci->relatedPTYPLCI->vswitchstate=0; | 
 | 5127 |  | 
 | 5128 |       } | 
 | 5129 |       else | 
 | 5130 |       { | 
 | 5131 |         PUT_WORD(&SS_Ind[1],pty_cai[5]+3); | 
 | 5132 |       } | 
 | 5133 |       if(pty_cai[2]!=0xff) | 
 | 5134 |       { | 
 | 5135 |         PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]); | 
 | 5136 |       } | 
 | 5137 |       else | 
 | 5138 |       { | 
 | 5139 |         PUT_WORD(&SS_Ind[4],0x300E); | 
 | 5140 |       } | 
 | 5141 |       plci->relatedPTYPLCI = NULL; | 
 | 5142 |       plci->ptyState = 0; | 
 | 5143 |       sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind); | 
 | 5144 |       break; | 
 | 5145 |  | 
 | 5146 |     case CALL_DEFLECTION: | 
 | 5147 |       if(pty_cai[2]!=0xff) | 
 | 5148 |       { | 
 | 5149 |         PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]); | 
 | 5150 |       } | 
 | 5151 |       else | 
 | 5152 |       { | 
 | 5153 |         PUT_WORD(&SS_Ind[4],0x300E); | 
 | 5154 |       } | 
 | 5155 |       PUT_WORD(&SS_Ind[1],pty_cai[5]); | 
 | 5156 |       for(i=0; i<max_appl; i++) | 
 | 5157 |       { | 
 | 5158 |         if(application[i].CDEnable) | 
 | 5159 |         { | 
 | 5160 |           if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind); | 
 | 5161 |           application[i].CDEnable = FALSE; | 
 | 5162 |         } | 
 | 5163 |       } | 
 | 5164 |       break; | 
 | 5165 |  | 
 | 5166 |     case DEACTIVATION_DIVERSION: | 
 | 5167 |     case ACTIVATION_DIVERSION: | 
 | 5168 |     case DIVERSION_INTERROGATE_CFU: | 
 | 5169 |     case DIVERSION_INTERROGATE_CFB: | 
 | 5170 |     case DIVERSION_INTERROGATE_CFNR: | 
 | 5171 |     case DIVERSION_INTERROGATE_NUM: | 
 | 5172 |     case CCBS_REQUEST: | 
 | 5173 |     case CCBS_DEACTIVATE: | 
 | 5174 |     case CCBS_INTERROGATE: | 
 | 5175 |       if(!plci->appl) break; | 
 | 5176 |       if(pty_cai[2]!=0xff) | 
 | 5177 |       { | 
 | 5178 |         PUT_WORD(&Interr_Err_Ind[4],0x3600|(word)pty_cai[2]); | 
 | 5179 |       } | 
 | 5180 |       else | 
 | 5181 |       { | 
 | 5182 |         PUT_WORD(&Interr_Err_Ind[4],0x300E); | 
 | 5183 |       } | 
 | 5184 |       switch (pty_cai[5]) | 
 | 5185 |       { | 
 | 5186 |         case DEACTIVATION_DIVERSION: | 
 | 5187 |           dbug(1,dprintf("Deact_Div")); | 
 | 5188 |           Interr_Err_Ind[0]=0x9; | 
 | 5189 |           Interr_Err_Ind[3]=0x6; | 
 | 5190 |           PUT_WORD(&Interr_Err_Ind[1],S_CALL_FORWARDING_STOP); | 
 | 5191 |           break; | 
 | 5192 |         case ACTIVATION_DIVERSION: | 
 | 5193 |           dbug(1,dprintf("Act_Div")); | 
 | 5194 |           Interr_Err_Ind[0]=0x9; | 
 | 5195 |           Interr_Err_Ind[3]=0x6; | 
 | 5196 |           PUT_WORD(&Interr_Err_Ind[1],S_CALL_FORWARDING_START); | 
 | 5197 |           break; | 
 | 5198 |         case DIVERSION_INTERROGATE_CFU: | 
 | 5199 |         case DIVERSION_INTERROGATE_CFB: | 
 | 5200 |         case DIVERSION_INTERROGATE_CFNR: | 
 | 5201 |           dbug(1,dprintf("Interr_Div")); | 
 | 5202 |           Interr_Err_Ind[0]=0xa; | 
 | 5203 |           Interr_Err_Ind[3]=0x7; | 
 | 5204 |           PUT_WORD(&Interr_Err_Ind[1],S_INTERROGATE_DIVERSION); | 
 | 5205 |           break; | 
 | 5206 |         case DIVERSION_INTERROGATE_NUM: | 
 | 5207 |           dbug(1,dprintf("Interr_Num")); | 
 | 5208 |           Interr_Err_Ind[0]=0xa; | 
 | 5209 |           Interr_Err_Ind[3]=0x7; | 
 | 5210 |           PUT_WORD(&Interr_Err_Ind[1],S_INTERROGATE_NUMBERS); | 
 | 5211 |           break; | 
 | 5212 |         case CCBS_REQUEST: | 
 | 5213 |           dbug(1,dprintf("CCBS Request")); | 
 | 5214 |           Interr_Err_Ind[0]=0xd; | 
 | 5215 |           Interr_Err_Ind[3]=0xa; | 
 | 5216 |           PUT_WORD(&Interr_Err_Ind[1],S_CCBS_REQUEST); | 
 | 5217 |           break; | 
 | 5218 |         case CCBS_DEACTIVATE: | 
 | 5219 |           dbug(1,dprintf("CCBS Deactivate")); | 
 | 5220 |           Interr_Err_Ind[0]=0x9; | 
 | 5221 |           Interr_Err_Ind[3]=0x6; | 
 | 5222 |           PUT_WORD(&Interr_Err_Ind[1],S_CCBS_DEACTIVATE); | 
 | 5223 |           break; | 
 | 5224 |         case CCBS_INTERROGATE: | 
 | 5225 |           dbug(1,dprintf("CCBS Interrogate")); | 
 | 5226 |           Interr_Err_Ind[0]=0xb; | 
 | 5227 |           Interr_Err_Ind[3]=0x8; | 
 | 5228 |           PUT_WORD(&Interr_Err_Ind[1],S_CCBS_INTERROGATE); | 
 | 5229 |           break; | 
 | 5230 |       } | 
 | 5231 |       PUT_DWORD(&Interr_Err_Ind[6],plci->appl->S_Handle); | 
 | 5232 |       sendf(plci->appl,_FACILITY_I,Id&0x7,0,"ws",3, Interr_Err_Ind); | 
 | 5233 |       plci_remove(plci); | 
 | 5234 |       break; | 
 | 5235 |     case ACTIVATION_MWI:       | 
 | 5236 |     case DEACTIVATION_MWI: | 
 | 5237 |       if(pty_cai[5]==ACTIVATION_MWI) | 
 | 5238 |       { | 
 | 5239 |         PUT_WORD(&SS_Ind[1],S_MWI_ACTIVATE); | 
 | 5240 |       } | 
 | 5241 |       else PUT_WORD(&SS_Ind[1],S_MWI_DEACTIVATE); | 
 | 5242 |        | 
 | 5243 |       if(pty_cai[2]!=0xff) | 
 | 5244 |       { | 
 | 5245 |         PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]); | 
 | 5246 |       } | 
 | 5247 |       else | 
 | 5248 |       { | 
 | 5249 |         PUT_WORD(&SS_Ind[4],0x300E); | 
 | 5250 |       } | 
 | 5251 |  | 
 | 5252 |       if(plci->cr_enquiry) | 
 | 5253 |       { | 
 | 5254 |         sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind); | 
 | 5255 |         plci_remove(plci); | 
 | 5256 |       } | 
 | 5257 |       else | 
 | 5258 |       { | 
 | 5259 |         sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); | 
 | 5260 |       } | 
 | 5261 |       break; | 
 | 5262 |     case CONF_ADD: /* ERROR */ | 
 | 5263 |     case CONF_BEGIN: | 
 | 5264 |     case CONF_DROP: | 
 | 5265 |     case CONF_ISOLATE: | 
 | 5266 |     case CONF_REATTACH: | 
 | 5267 |       CONF_Ind[0]=9; | 
 | 5268 |       CONF_Ind[3]=6;    | 
 | 5269 |       switch(pty_cai[5]) | 
 | 5270 |       { | 
 | 5271 |       case CONF_BEGIN: | 
 | 5272 |           PUT_WORD(&CONF_Ind[1],S_CONF_BEGIN); | 
 | 5273 |           plci->ptyState = 0; | 
 | 5274 |           break; | 
 | 5275 |       case CONF_DROP: | 
 | 5276 |           CONF_Ind[0]=5; | 
 | 5277 |           CONF_Ind[3]=2; | 
 | 5278 |           PUT_WORD(&CONF_Ind[1],S_CONF_DROP); | 
 | 5279 |           plci->ptyState = CONNECTED; | 
 | 5280 |           break; | 
 | 5281 |       case CONF_ISOLATE: | 
 | 5282 |           CONF_Ind[0]=5; | 
 | 5283 |           CONF_Ind[3]=2; | 
 | 5284 |           PUT_WORD(&CONF_Ind[1],S_CONF_ISOLATE); | 
 | 5285 |           plci->ptyState = CONNECTED; | 
 | 5286 |           break; | 
 | 5287 |       case CONF_REATTACH: | 
 | 5288 |           CONF_Ind[0]=5; | 
 | 5289 |           CONF_Ind[3]=2; | 
 | 5290 |           PUT_WORD(&CONF_Ind[1],S_CONF_REATTACH); | 
 | 5291 |           plci->ptyState = CONNECTED; | 
 | 5292 |           break; | 
 | 5293 |       case CONF_ADD: | 
 | 5294 |           PUT_WORD(&CONF_Ind[1],S_CONF_ADD); | 
 | 5295 |           plci->relatedPTYPLCI = NULL; | 
 | 5296 |           tplci=plci->relatedPTYPLCI; | 
 | 5297 |           if(tplci) tplci->ptyState = CONNECTED; | 
 | 5298 |           plci->ptyState = CONNECTED; | 
 | 5299 |           break; | 
 | 5300 |       } | 
 | 5301 |            | 
 | 5302 |       if(pty_cai[2]!=0xff) | 
 | 5303 |       { | 
 | 5304 |         PUT_WORD(&CONF_Ind[4],0x3600|(word)pty_cai[2]); | 
 | 5305 |       } | 
 | 5306 |       else | 
 | 5307 |       { | 
 | 5308 |         PUT_WORD(&CONF_Ind[4],0x3303); /* Time-out: network did not respond | 
 | 5309 |                                             within the required time */ | 
 | 5310 |       } | 
 | 5311 |  | 
 | 5312 |       PUT_DWORD(&CONF_Ind[6],0x0); | 
 | 5313 |       sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind); | 
 | 5314 |       break; | 
 | 5315 |     } | 
 | 5316 |     break; | 
 | 5317 |  | 
 | 5318 |   /* Supplementary Service indicates success */ | 
 | 5319 |   case S_SERVICE: | 
 | 5320 |     dbug(1,dprintf("Service_Ind")); | 
 | 5321 |     PUT_WORD (&CF_Ind[4], 0); | 
 | 5322 |     switch (pty_cai[5]) | 
 | 5323 |     { | 
 | 5324 |     case THREE_PTY_END: | 
 | 5325 |     case THREE_PTY_BEGIN: | 
 | 5326 |     case ECT_EXECUTE: | 
 | 5327 |       if(!plci->relatedPTYPLCI) break; | 
 | 5328 |       tplci = plci->relatedPTYPLCI; | 
 | 5329 |       rId = ( (word)tplci->Id<<8)|tplci->adapter->Id; | 
 | 5330 |       if(tplci->tel) rId|=EXT_CONTROLLER; | 
 | 5331 |       if(pty_cai[5]==ECT_EXECUTE) | 
 | 5332 |       { | 
 | 5333 |         PUT_WORD(&SS_Ind[1],S_ECT); | 
 | 5334 |  | 
 | 5335 |         if(plci->vswitchstate!=3) | 
 | 5336 |         { | 
 | 5337 |  | 
 | 5338 |         plci->ptyState = IDLE; | 
 | 5339 |         plci->relatedPTYPLCI = NULL; | 
 | 5340 |         plci->ptyState = 0; | 
 | 5341 |  | 
 | 5342 |         } | 
 | 5343 |  | 
 | 5344 |         dbug(1,dprintf("ECT OK")); | 
 | 5345 |         sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind); | 
 | 5346 |  | 
 | 5347 |  | 
 | 5348 |  | 
 | 5349 |       } | 
 | 5350 |       else | 
 | 5351 |       { | 
 | 5352 |         switch (plci->ptyState) | 
 | 5353 |         { | 
 | 5354 |         case S_3PTY_BEGIN: | 
 | 5355 |           plci->ptyState = CONNECTED; | 
 | 5356 |           dbug(1,dprintf("3PTY ON")); | 
 | 5357 |           break; | 
 | 5358 |  | 
 | 5359 |         case S_3PTY_END: | 
 | 5360 |           plci->ptyState = IDLE; | 
 | 5361 |           plci->relatedPTYPLCI = NULL; | 
 | 5362 |           plci->ptyState = 0; | 
 | 5363 |           dbug(1,dprintf("3PTY OFF")); | 
 | 5364 |           break; | 
 | 5365 |         } | 
 | 5366 |         PUT_WORD(&SS_Ind[1],pty_cai[5]+3); | 
 | 5367 |         sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind); | 
 | 5368 |       } | 
 | 5369 |       break; | 
 | 5370 |  | 
 | 5371 |     case CALL_DEFLECTION: | 
 | 5372 |       PUT_WORD(&SS_Ind[1],pty_cai[5]); | 
 | 5373 |       for(i=0; i<max_appl; i++) | 
 | 5374 |       { | 
 | 5375 |         if(application[i].CDEnable) | 
 | 5376 |         { | 
 | 5377 |           if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind); | 
 | 5378 |           application[i].CDEnable = FALSE; | 
 | 5379 |         } | 
 | 5380 |       } | 
 | 5381 |       break; | 
 | 5382 |  | 
 | 5383 |     case DEACTIVATION_DIVERSION: | 
 | 5384 |     case ACTIVATION_DIVERSION: | 
 | 5385 |       if(!plci->appl) break; | 
 | 5386 |       PUT_WORD(&CF_Ind[1],pty_cai[5]+2); | 
 | 5387 |       PUT_DWORD(&CF_Ind[6],plci->appl->S_Handle); | 
 | 5388 |       sendf(plci->appl,_FACILITY_I,Id&0x7,0,"ws",3, CF_Ind); | 
 | 5389 |       plci_remove(plci); | 
 | 5390 |       break; | 
 | 5391 |  | 
 | 5392 |     case DIVERSION_INTERROGATE_CFU: | 
 | 5393 |     case DIVERSION_INTERROGATE_CFB: | 
 | 5394 |     case DIVERSION_INTERROGATE_CFNR: | 
 | 5395 |     case DIVERSION_INTERROGATE_NUM: | 
 | 5396 |     case CCBS_REQUEST: | 
 | 5397 |     case CCBS_DEACTIVATE: | 
 | 5398 |     case CCBS_INTERROGATE: | 
 | 5399 |       if(!plci->appl) break; | 
 | 5400 |       switch (pty_cai[5]) | 
 | 5401 |       { | 
 | 5402 |         case DIVERSION_INTERROGATE_CFU: | 
 | 5403 |         case DIVERSION_INTERROGATE_CFB: | 
 | 5404 |         case DIVERSION_INTERROGATE_CFNR: | 
 | 5405 |           dbug(1,dprintf("Interr_Div")); | 
 | 5406 |           PUT_WORD(&pty_cai[1],S_INTERROGATE_DIVERSION); | 
 | 5407 |           pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ | 
 | 5408 |           break; | 
 | 5409 |         case DIVERSION_INTERROGATE_NUM: | 
 | 5410 |           dbug(1,dprintf("Interr_Num")); | 
 | 5411 |           PUT_WORD(&pty_cai[1],S_INTERROGATE_NUMBERS); | 
 | 5412 |           pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ | 
 | 5413 |           break; | 
 | 5414 |         case CCBS_REQUEST: | 
 | 5415 |           dbug(1,dprintf("CCBS Request")); | 
 | 5416 |           PUT_WORD(&pty_cai[1],S_CCBS_REQUEST); | 
 | 5417 |           pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ | 
 | 5418 |           break; | 
 | 5419 |         case CCBS_DEACTIVATE: | 
 | 5420 |           dbug(1,dprintf("CCBS Deactivate")); | 
 | 5421 |           PUT_WORD(&pty_cai[1],S_CCBS_DEACTIVATE); | 
 | 5422 |           pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ | 
 | 5423 |           break; | 
 | 5424 |         case CCBS_INTERROGATE: | 
 | 5425 |           dbug(1,dprintf("CCBS Interrogate")); | 
 | 5426 |           PUT_WORD(&pty_cai[1],S_CCBS_INTERROGATE); | 
 | 5427 |           pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ | 
 | 5428 |           break; | 
 | 5429 |       } | 
 | 5430 |       PUT_WORD(&pty_cai[4],0); /* Supplementary Service Reason */ | 
 | 5431 |       PUT_DWORD(&pty_cai[6],plci->appl->S_Handle); | 
 | 5432 |       sendf(plci->appl,_FACILITY_I,Id&0x7,0,"wS",3, pty_cai); | 
 | 5433 |       plci_remove(plci); | 
 | 5434 |       break; | 
 | 5435 |  | 
 | 5436 |     case ACTIVATION_MWI: | 
 | 5437 |     case DEACTIVATION_MWI: | 
 | 5438 |       if(pty_cai[5]==ACTIVATION_MWI) | 
 | 5439 |       { | 
 | 5440 |         PUT_WORD(&SS_Ind[1],S_MWI_ACTIVATE); | 
 | 5441 |       } | 
 | 5442 |       else PUT_WORD(&SS_Ind[1],S_MWI_DEACTIVATE); | 
 | 5443 |       if(plci->cr_enquiry) | 
 | 5444 |       { | 
 | 5445 |         sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind); | 
 | 5446 |         plci_remove(plci); | 
 | 5447 |       } | 
 | 5448 |       else | 
 | 5449 |       { | 
 | 5450 |         sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); | 
 | 5451 |       } | 
 | 5452 |       break; | 
 | 5453 |     case MWI_INDICATION: | 
 | 5454 |       if(pty_cai[0]>=0x12) | 
 | 5455 |       { | 
 | 5456 |         PUT_WORD(&pty_cai[3],S_MWI_INDICATE); | 
 | 5457 |         pty_cai[2]=pty_cai[0]-2; /* len Parameter */ | 
 | 5458 |         pty_cai[5]=pty_cai[0]-5; /* Supplementary Service-specific parameter len */ | 
 | 5459 |         if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_MWI)) | 
 | 5460 |         { | 
 | 5461 |           if(plci->internal_command==GET_MWI_STATE) /* result on Message Waiting Listen */ | 
 | 5462 |           { | 
 | 5463 |             sendf(plci->appl,_FACILITY_I,Id&0xf,0,"wS",3, &pty_cai[2]); | 
 | 5464 |             plci_remove(plci); | 
 | 5465 |             return; | 
 | 5466 |           } | 
 | 5467 |           else  sendf(plci->appl,_FACILITY_I,Id,0,"wS",3, &pty_cai[2]); | 
 | 5468 |           pty_cai[0]=0; | 
 | 5469 |         } | 
 | 5470 |         else | 
 | 5471 |         { | 
 | 5472 |           for(i=0; i<max_appl; i++) | 
 | 5473 |           {                      | 
 | 5474 |             if(a->Notification_Mask[i]&SMASK_MWI) | 
 | 5475 |             { | 
 | 5476 |               sendf(&application[i],_FACILITY_I,Id&0x7,0,"wS",3, &pty_cai[2]); | 
 | 5477 |               pty_cai[0]=0; | 
 | 5478 |             } | 
 | 5479 |           } | 
 | 5480 |         } | 
 | 5481 |  | 
 | 5482 |         if(!pty_cai[0]) | 
 | 5483 |         { /* acknowledge */ | 
 | 5484 |           facility[2]= 0; /* returncode */ | 
 | 5485 |         } | 
 | 5486 |         else facility[2]= 0xff; | 
 | 5487 |       } | 
 | 5488 |       else | 
 | 5489 |       { | 
 | 5490 |         /* reject */ | 
 | 5491 |         facility[2]= 0xff; /* returncode */ | 
 | 5492 |       } | 
 | 5493 |       facility[0]= 2; | 
 | 5494 |       facility[1]= MWI_RESPONSE; /* Function */ | 
 | 5495 |       add_p(plci,CAI,facility); | 
 | 5496 |       add_p(plci,ESC,multi_ssext_parms[0]); /* remembered parameter -> only one possible */ | 
 | 5497 |       sig_req(plci,S_SERVICE,0); | 
 | 5498 |       send_req(plci); | 
 | 5499 |       plci->command = 0; | 
 | 5500 |       next_internal_command (Id, plci); | 
 | 5501 |       break; | 
 | 5502 |     case CONF_ADD: /* OK */ | 
 | 5503 |     case CONF_BEGIN: | 
 | 5504 |     case CONF_DROP: | 
 | 5505 |     case CONF_ISOLATE: | 
 | 5506 |     case CONF_REATTACH: | 
 | 5507 |     case CONF_PARTYDISC: | 
 | 5508 |       CONF_Ind[0]=9; | 
 | 5509 |       CONF_Ind[3]=6; | 
 | 5510 |       switch(pty_cai[5]) | 
 | 5511 |       { | 
 | 5512 |       case CONF_BEGIN: | 
 | 5513 |           PUT_WORD(&CONF_Ind[1],S_CONF_BEGIN); | 
 | 5514 |           if(pty_cai[0]==6) | 
 | 5515 |           { | 
 | 5516 |               d=pty_cai[6]; | 
 | 5517 |               PUT_DWORD(&CONF_Ind[6],d); /* PartyID */ | 
 | 5518 |           } | 
 | 5519 |           else | 
 | 5520 |           { | 
 | 5521 |               PUT_DWORD(&CONF_Ind[6],0x0); | 
 | 5522 |           } | 
 | 5523 |           break; | 
 | 5524 |       case CONF_ISOLATE: | 
 | 5525 |           PUT_WORD(&CONF_Ind[1],S_CONF_ISOLATE); | 
 | 5526 |           CONF_Ind[0]=5; | 
 | 5527 |           CONF_Ind[3]=2; | 
 | 5528 |           break; | 
 | 5529 |       case CONF_REATTACH: | 
 | 5530 |           PUT_WORD(&CONF_Ind[1],S_CONF_REATTACH); | 
 | 5531 |           CONF_Ind[0]=5; | 
 | 5532 |           CONF_Ind[3]=2; | 
 | 5533 |           break; | 
 | 5534 |       case CONF_DROP: | 
 | 5535 |           PUT_WORD(&CONF_Ind[1],S_CONF_DROP); | 
 | 5536 |           CONF_Ind[0]=5; | 
 | 5537 |           CONF_Ind[3]=2; | 
 | 5538 |           break; | 
 | 5539 |       case CONF_ADD: | 
 | 5540 |           PUT_WORD(&CONF_Ind[1],S_CONF_ADD); | 
 | 5541 |           d=pty_cai[6]; | 
 | 5542 |           PUT_DWORD(&CONF_Ind[6],d); /* PartyID */ | 
 | 5543 |           tplci=plci->relatedPTYPLCI; | 
 | 5544 |           if(tplci) tplci->ptyState = CONNECTED; | 
 | 5545 |           break; | 
 | 5546 |       case CONF_PARTYDISC: | 
 | 5547 |           CONF_Ind[0]=7; | 
 | 5548 |           CONF_Ind[3]=4;           | 
 | 5549 |           PUT_WORD(&CONF_Ind[1],S_CONF_PARTYDISC); | 
 | 5550 |           d=pty_cai[6]; | 
 | 5551 |           PUT_DWORD(&CONF_Ind[4],d); /* PartyID */ | 
 | 5552 |           break; | 
 | 5553 |       } | 
 | 5554 |       plci->ptyState = CONNECTED; | 
 | 5555 |       sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind); | 
 | 5556 |       break; | 
 | 5557 |     case CCBS_INFO_RETAIN: | 
 | 5558 |     case CCBS_ERASECALLLINKAGEID: | 
 | 5559 |     case CCBS_STOP_ALERTING: | 
 | 5560 |       CONF_Ind[0]=5; | 
 | 5561 |       CONF_Ind[3]=2; | 
 | 5562 |       switch(pty_cai[5]) | 
 | 5563 |       { | 
 | 5564 |       case CCBS_INFO_RETAIN: | 
 | 5565 |         PUT_WORD(&CONF_Ind[1],S_CCBS_INFO_RETAIN); | 
 | 5566 |         break; | 
 | 5567 |       case CCBS_STOP_ALERTING: | 
 | 5568 |         PUT_WORD(&CONF_Ind[1],S_CCBS_STOP_ALERTING); | 
 | 5569 |     break; | 
 | 5570 |       case CCBS_ERASECALLLINKAGEID: | 
 | 5571 |         PUT_WORD(&CONF_Ind[1],S_CCBS_ERASECALLLINKAGEID); | 
 | 5572 |         CONF_Ind[0]=7; | 
 | 5573 |         CONF_Ind[3]=4; | 
 | 5574 |         CONF_Ind[6]=0; | 
 | 5575 |         CONF_Ind[7]=0; | 
 | 5576 |         break; | 
 | 5577 |       }       | 
 | 5578 |       w=pty_cai[6]; | 
 | 5579 |       PUT_WORD(&CONF_Ind[4],w); /* PartyID */ | 
 | 5580 |  | 
 | 5581 |       if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_CCBS)) | 
 | 5582 |       { | 
 | 5583 |         sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind); | 
 | 5584 |       } | 
 | 5585 |       else | 
 | 5586 |       { | 
 | 5587 |         for(i=0; i<max_appl; i++) | 
 | 5588 |             if(a->Notification_Mask[i]&SMASK_CCBS) | 
 | 5589 |                 sendf(&application[i],_FACILITY_I,Id&0x7,0,"ws",3, CONF_Ind); | 
 | 5590 |       } | 
 | 5591 |       break; | 
 | 5592 |     } | 
 | 5593 |     break; | 
 | 5594 |   case CALL_HOLD_REJ: | 
 | 5595 |     cau = parms[7]; | 
 | 5596 |     if(cau) | 
 | 5597 |     { | 
 | 5598 |       i = _L3_CAUSE | cau[2]; | 
 | 5599 |       if(cau[2]==0) i = 0x3603; | 
 | 5600 |     } | 
 | 5601 |     else | 
 | 5602 |     { | 
 | 5603 |       i = 0x3603; | 
 | 5604 |     } | 
 | 5605 |     PUT_WORD(&SS_Ind[1],S_HOLD); | 
 | 5606 |     PUT_WORD(&SS_Ind[4],i); | 
 | 5607 |     if(plci->SuppState == HOLD_REQUEST) | 
 | 5608 |     { | 
 | 5609 |       plci->SuppState = IDLE; | 
 | 5610 |       sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); | 
 | 5611 |     } | 
 | 5612 |     break; | 
 | 5613 |  | 
 | 5614 |   case CALL_HOLD_ACK: | 
 | 5615 |     if(plci->SuppState == HOLD_REQUEST) | 
 | 5616 |     { | 
 | 5617 |       plci->SuppState = CALL_HELD; | 
 | 5618 |       CodecIdCheck(a, plci); | 
 | 5619 |       start_internal_command (Id, plci, hold_save_command); | 
 | 5620 |     } | 
 | 5621 |     break; | 
 | 5622 |  | 
 | 5623 |   case CALL_RETRIEVE_REJ: | 
 | 5624 |     cau = parms[7]; | 
 | 5625 |     if(cau) | 
 | 5626 |     { | 
 | 5627 |       i = _L3_CAUSE | cau[2]; | 
 | 5628 |       if(cau[2]==0) i = 0x3603; | 
 | 5629 |     } | 
 | 5630 |     else | 
 | 5631 |     { | 
 | 5632 |       i = 0x3603; | 
 | 5633 |     } | 
 | 5634 |     PUT_WORD(&SS_Ind[1],S_RETRIEVE); | 
 | 5635 |     PUT_WORD(&SS_Ind[4],i); | 
 | 5636 |     if(plci->SuppState == RETRIEVE_REQUEST) | 
 | 5637 |     { | 
 | 5638 |       plci->SuppState = CALL_HELD; | 
 | 5639 |       CodecIdCheck(a, plci); | 
 | 5640 |       sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); | 
 | 5641 |     } | 
 | 5642 |     break; | 
 | 5643 |  | 
 | 5644 |   case CALL_RETRIEVE_ACK: | 
 | 5645 |     PUT_WORD(&SS_Ind[1],S_RETRIEVE); | 
 | 5646 |     if(plci->SuppState == RETRIEVE_REQUEST) | 
 | 5647 |     { | 
 | 5648 |       plci->SuppState = IDLE; | 
 | 5649 |       plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; | 
 | 5650 |       plci->b_channel = esc_chi[esc_chi[0]]&0x1f; | 
 | 5651 |       if(plci->tel) | 
 | 5652 |       { | 
 | 5653 |         mixer_set_bchannel_id_esc (plci, plci->b_channel); | 
 | 5654 |         dbug(1,dprintf("RetrChannel=0x%x",plci->b_channel)); | 
 | 5655 |         SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a); | 
 | 5656 |         if(plci->B2_prot==B2_TRANSPARENT && plci->B3_prot==B3_TRANSPARENT) | 
 | 5657 |         { | 
 | 5658 |           dbug(1,dprintf("Get B-ch")); | 
 | 5659 |           start_internal_command (Id, plci, retrieve_restore_command); | 
 | 5660 |         } | 
 | 5661 |         else | 
 | 5662 |           sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); | 
 | 5663 |       } | 
 | 5664 |       else | 
 | 5665 |         start_internal_command (Id, plci, retrieve_restore_command); | 
 | 5666 |     } | 
 | 5667 |     break; | 
 | 5668 |  | 
 | 5669 |   case INDICATE_IND: | 
 | 5670 |     if(plci->State != LISTENING) { | 
 | 5671 |       sig_req(plci,HANGUP,0); | 
 | 5672 |       send_req(plci); | 
 | 5673 |       break; | 
 | 5674 |     } | 
 | 5675 |     cip = find_cip(a,parms[4],parms[6]); | 
 | 5676 |     cip_mask = 1L<<cip; | 
 | 5677 |     dbug(1,dprintf("cip=%d,cip_mask=%lx",cip,cip_mask)); | 
 | 5678 |     clear_c_ind_mask (plci); | 
 | 5679 |     if (!remove_started && !a->adapter_disabled) | 
 | 5680 |     { | 
 | 5681 |       set_c_ind_mask_bit (plci, MAX_APPL); | 
 | 5682 |       group_optimization(a, plci); | 
 | 5683 |       for(i=0; i<max_appl; i++) { | 
 | 5684 |         if(application[i].Id | 
 | 5685 |         && (a->CIP_Mask[i]&1 || a->CIP_Mask[i]&cip_mask) | 
 | 5686 |         && CPN_filter_ok(parms[0],a,i) | 
 | 5687 |         && test_group_ind_mask_bit (plci, i) ) { | 
 | 5688 |           dbug(1,dprintf("storedcip_mask[%d]=0x%lx",i,a->CIP_Mask[i] )); | 
 | 5689 |           set_c_ind_mask_bit (plci, i); | 
 | 5690 |           dump_c_ind_mask (plci); | 
 | 5691 |           plci->State = INC_CON_PENDING; | 
 | 5692 |           plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) | | 
 | 5693 |             CALL_DIR_IN | CALL_DIR_ANSWER; | 
 | 5694 |           if(esc_chi[0]) { | 
 | 5695 |             plci->b_channel = esc_chi[esc_chi[0]]&0x1f; | 
 | 5696 |             mixer_set_bchannel_id_esc (plci, plci->b_channel); | 
 | 5697 |           } | 
 | 5698 |           /* if a listen on the ext controller is done, check if hook states */ | 
 | 5699 |           /* are supported or if just a on board codec must be activated     */ | 
 | 5700 |           if(a->codec_listen[i] && !a->AdvSignalPLCI) { | 
 | 5701 |             if(a->profile.Global_Options & HANDSET) | 
 | 5702 |               plci->tel = ADV_VOICE; | 
 | 5703 |             else if(a->profile.Global_Options & ON_BOARD_CODEC) | 
 | 5704 |               plci->tel = CODEC; | 
 | 5705 |             if(plci->tel) Id|=EXT_CONTROLLER; | 
 | 5706 |             a->codec_listen[i] = plci; | 
 | 5707 |           } | 
 | 5708 |  | 
 | 5709 |           sendf(&application[i],_CONNECT_I,Id,0, | 
 | 5710 |                 "wSSSSSSSbSSSSS", cip,    /* CIP                 */ | 
 | 5711 |                              parms[0],    /* CalledPartyNumber   */ | 
 | 5712 |                              multi_CiPN_parms[0],    /* CallingPartyNumber  */ | 
 | 5713 |                              parms[2],    /* CalledPartySubad    */ | 
 | 5714 |                              parms[3],    /* CallingPartySubad   */ | 
 | 5715 |                              parms[4],    /* BearerCapability    */ | 
 | 5716 |                              parms[5],    /* LowLC               */ | 
 | 5717 |                              parms[6],    /* HighLC              */ | 
 | 5718 |                              ai_len,      /* nested struct add_i */ | 
 | 5719 |                              add_i[0],    /* B channel info    */ | 
 | 5720 |                              add_i[1],    /* keypad facility   */ | 
 | 5721 |                              add_i[2],    /* user user data    */ | 
 | 5722 |                              add_i[3],    /* nested facility   */ | 
 | 5723 |                              multi_CiPN_parms[1]    /* second CiPN(SCR)   */ | 
 | 5724 |                              ); | 
 | 5725 |           SendSSExtInd(&application[i], | 
 | 5726 |                         plci, | 
 | 5727 |                         Id, | 
 | 5728 |                         multi_ssext_parms); | 
 | 5729 |           SendSetupInfo(&application[i], | 
 | 5730 |                         plci, | 
 | 5731 |                         Id, | 
 | 5732 |                         parms, | 
 | 5733 |                         SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, TRUE)); | 
 | 5734 |         } | 
 | 5735 |       } | 
 | 5736 |       clear_c_ind_mask_bit (plci, MAX_APPL); | 
 | 5737 |       dump_c_ind_mask (plci); | 
 | 5738 |     } | 
 | 5739 |     if(c_ind_mask_empty (plci)) { | 
 | 5740 |       sig_req(plci,HANGUP,0); | 
 | 5741 |       send_req(plci); | 
 | 5742 |       plci->State = IDLE; | 
 | 5743 |     } | 
 | 5744 |     plci->notifiedcall = 0; | 
 | 5745 |     a->listen_active--; | 
 | 5746 |     listen_check(a); | 
 | 5747 |     break; | 
 | 5748 |  | 
 | 5749 |   case CALL_PEND_NOTIFY: | 
 | 5750 |     plci->notifiedcall = 1; | 
 | 5751 |     listen_check(a); | 
 | 5752 |     break; | 
 | 5753 |  | 
 | 5754 |   case CALL_IND: | 
 | 5755 |   case CALL_CON: | 
 | 5756 |     if(plci->State==ADVANCED_VOICE_SIG || plci->State==ADVANCED_VOICE_NOSIG) | 
 | 5757 |     { | 
 | 5758 |       if(plci->internal_command==PERM_COD_CONN_PEND) | 
 | 5759 |       { | 
 | 5760 |         if(plci->State==ADVANCED_VOICE_NOSIG) | 
 | 5761 |         { | 
 | 5762 |           dbug(1,dprintf("***Codec OK")); | 
 | 5763 |           if(a->AdvSignalPLCI) | 
 | 5764 |           { | 
 | 5765 |             tplci = a->AdvSignalPLCI; | 
 | 5766 |             if(tplci->spoofed_msg) | 
 | 5767 |             { | 
 | 5768 |               dbug(1,dprintf("***Spoofed Msg(0x%x)",tplci->spoofed_msg)); | 
 | 5769 |               tplci->command = 0; | 
 | 5770 |               tplci->internal_command = 0; | 
 | 5771 |               x_Id = ((word)tplci->Id<<8)|tplci->adapter->Id | 0x80; | 
 | 5772 |               switch (tplci->spoofed_msg) | 
 | 5773 |               { | 
 | 5774 |               case CALL_RES: | 
 | 5775 |                 tplci->command = _CONNECT_I|RESPONSE; | 
 | 5776 |                 api_load_msg (&tplci->saved_msg, saved_parms); | 
 | 5777 |                 add_b1(tplci,&saved_parms[1],0,tplci->B1_facilities); | 
 | 5778 |                 if (tplci->adapter->Info_Mask[tplci->appl->Id-1] & 0x200) | 
 | 5779 |                 { | 
 | 5780 |                   /* early B3 connect (CIP mask bit 9) no release after a disc */ | 
 | 5781 |                   add_p(tplci,LLI,"\x01\x01"); | 
 | 5782 |                 } | 
 | 5783 |                 add_s(tplci, CONN_NR, &saved_parms[2]); | 
 | 5784 |                 add_s(tplci, LLC, &saved_parms[4]); | 
 | 5785 |                 add_ai(tplci, &saved_parms[5]); | 
 | 5786 |                 tplci->State = INC_CON_ACCEPT; | 
 | 5787 |                 sig_req(tplci, CALL_RES,0); | 
 | 5788 |                 send_req(tplci); | 
 | 5789 |                 break; | 
 | 5790 |  | 
 | 5791 |               case AWAITING_SELECT_B: | 
 | 5792 |                 dbug(1,dprintf("Select_B continue")); | 
 | 5793 |                 start_internal_command (x_Id, tplci, select_b_command); | 
 | 5794 |                 break; | 
 | 5795 |  | 
 | 5796 |               case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */ | 
 | 5797 |                 if(!tplci->Sig.Id) | 
 | 5798 |                 { | 
 | 5799 |                   dbug(1,dprintf("No SigID!")); | 
 | 5800 |                   sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,_OUT_OF_PLCI); | 
 | 5801 |                   plci_remove(tplci); | 
 | 5802 |                   break; | 
 | 5803 |                 } | 
 | 5804 |                 tplci->command = _MANUFACTURER_R; | 
 | 5805 |                 api_load_msg (&tplci->saved_msg, saved_parms); | 
 | 5806 |                 dir = saved_parms[2].info[0]; | 
 | 5807 |                 if(dir==1) { | 
 | 5808 |                   sig_req(tplci,CALL_REQ,0); | 
 | 5809 |                 } | 
 | 5810 |                 else if(!dir){ | 
 | 5811 |                   sig_req(tplci,LISTEN_REQ,0); | 
 | 5812 |                 } | 
 | 5813 |                 send_req(tplci); | 
 | 5814 |                 sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,0); | 
 | 5815 |                 break; | 
 | 5816 |  | 
 | 5817 |               case (CALL_REQ|AWAITING_MANUF_CON): | 
 | 5818 |                 sig_req(tplci,CALL_REQ,0); | 
 | 5819 |                 send_req(tplci); | 
 | 5820 |                 break; | 
 | 5821 |  | 
 | 5822 |               case CALL_REQ: | 
 | 5823 |                 if(!tplci->Sig.Id) | 
 | 5824 |                 { | 
 | 5825 |                   dbug(1,dprintf("No SigID!")); | 
 | 5826 |                   sendf(tplci->appl,_CONNECT_R|CONFIRM,tplci->adapter->Id,0,"w",_OUT_OF_PLCI); | 
 | 5827 |                   plci_remove(tplci); | 
 | 5828 |                   break; | 
 | 5829 |                 } | 
 | 5830 |                 tplci->command = _CONNECT_R; | 
 | 5831 |                 api_load_msg (&tplci->saved_msg, saved_parms); | 
 | 5832 |                 add_s(tplci,CPN,&saved_parms[1]); | 
 | 5833 |                 add_s(tplci,DSA,&saved_parms[3]); | 
 | 5834 |                 add_ai(tplci,&saved_parms[9]); | 
 | 5835 |                 sig_req(tplci,CALL_REQ,0); | 
 | 5836 |                 send_req(tplci); | 
 | 5837 |                 break; | 
 | 5838 |  | 
 | 5839 |               case CALL_RETRIEVE: | 
 | 5840 |                 tplci->command = C_RETRIEVE_REQ; | 
 | 5841 |                 sig_req(tplci,CALL_RETRIEVE,0); | 
 | 5842 |                 send_req(tplci); | 
 | 5843 |                 break; | 
 | 5844 |               } | 
 | 5845 |               tplci->spoofed_msg = 0; | 
 | 5846 |               if (tplci->internal_command == 0) | 
 | 5847 |                 next_internal_command (x_Id, tplci); | 
 | 5848 |             } | 
 | 5849 |           } | 
 | 5850 |           next_internal_command (Id, plci); | 
 | 5851 |           break; | 
 | 5852 |         } | 
 | 5853 |         dbug(1,dprintf("***Codec Hook Init Req")); | 
 | 5854 |         plci->internal_command = PERM_COD_HOOK; | 
 | 5855 |         add_p(plci,FTY,"\x01\x09");             /* Get Hook State*/ | 
 | 5856 |         sig_req(plci,TEL_CTRL,0); | 
 | 5857 |         send_req(plci); | 
 | 5858 |       } | 
 | 5859 |     } | 
 | 5860 |     else if(plci->command != _MANUFACTURER_R  /* old style permanent connect */ | 
 | 5861 |     && plci->State!=INC_ACT_PENDING) | 
 | 5862 |     { | 
 | 5863 |       mixer_set_bchannel_id_esc (plci, plci->b_channel); | 
 | 5864 |       if(plci->tel == ADV_VOICE && plci->SuppState == IDLE) /* with permanent codec switch on immediately */ | 
 | 5865 |       { | 
 | 5866 |         chi[2] = plci->b_channel; | 
 | 5867 |         SetVoiceChannel(a->AdvCodecPLCI, chi, a); | 
 | 5868 |       } | 
 | 5869 |       sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"Sss",parms[21],"",""); | 
 | 5870 |       plci->State = INC_ACT_PENDING; | 
 | 5871 |     } | 
 | 5872 |     break; | 
 | 5873 |  | 
 | 5874 |   case TEL_CTRL: | 
 | 5875 |     Number = 0; | 
 | 5876 |     ie = multi_fac_parms[0]; /* inspect the facility hook indications */ | 
 | 5877 |     if(plci->State==ADVANCED_VOICE_SIG && ie[0]){ | 
 | 5878 |       switch (ie[1]&0x91) { | 
 | 5879 |         case 0x80:   /* hook off */ | 
 | 5880 |         case 0x81: | 
 | 5881 |           if(plci->internal_command==PERM_COD_HOOK) | 
 | 5882 |           { | 
 | 5883 |             dbug(1,dprintf("init:hook_off")); | 
 | 5884 |             plci->hook_state = ie[1]; | 
 | 5885 |             next_internal_command (Id, plci); | 
 | 5886 |             break; | 
 | 5887 |           } | 
 | 5888 |           else /* ignore doubled hook indications */ | 
 | 5889 |           { | 
 | 5890 |             if( ((plci->hook_state)&0xf0)==0x80) | 
 | 5891 |             { | 
 | 5892 |               dbug(1,dprintf("ignore hook")); | 
 | 5893 |               break; | 
 | 5894 |             } | 
 | 5895 |             plci->hook_state = ie[1]&0x91; | 
 | 5896 |           } | 
 | 5897 |           /* check for incoming call pending */ | 
 | 5898 |           /* and signal '+'.Appl must decide */ | 
 | 5899 |           /* with connect_res if call must   */ | 
 | 5900 |           /* accepted or not                 */ | 
 | 5901 |           for(i=0, tplci=NULL;i<max_appl;i++){ | 
 | 5902 |             if(a->codec_listen[i] | 
 | 5903 |             && (a->codec_listen[i]->State==INC_CON_PENDING | 
 | 5904 |               ||a->codec_listen[i]->State==INC_CON_ALERT) ){ | 
 | 5905 |               tplci = a->codec_listen[i]; | 
 | 5906 |               tplci->appl = &application[i]; | 
 | 5907 |             } | 
 | 5908 |           } | 
 | 5909 |           /* no incoming call, do outgoing call */ | 
 | 5910 |           /* and signal '+' if outg. setup   */ | 
 | 5911 |           if(!a->AdvSignalPLCI && !tplci){ | 
 | 5912 |             if((i=get_plci(a))) { | 
 | 5913 |               a->AdvSignalPLCI = &a->plci[i-1]; | 
 | 5914 |               tplci = a->AdvSignalPLCI; | 
 | 5915 |               tplci->tel  = ADV_VOICE; | 
 | 5916 |               PUT_WORD(&voice_cai[5],a->AdvSignalAppl->MaxDataLength); | 
 | 5917 |               if (a->Info_Mask[a->AdvSignalAppl->Id-1] & 0x200){ | 
 | 5918 |                 /* early B3 connect (CIP mask bit 9) no release after a disc */ | 
 | 5919 |                 add_p(tplci,LLI,"\x01\x01"); | 
 | 5920 |               } | 
 | 5921 |               add_p(tplci, CAI, voice_cai); | 
 | 5922 |               add_p(tplci, OAD, a->TelOAD); | 
 | 5923 |               add_p(tplci, OSA, a->TelOSA); | 
 | 5924 |               add_p(tplci,SHIFT|6,NULL); | 
 | 5925 |               add_p(tplci,SIN,"\x02\x01\x00"); | 
 | 5926 |               add_p(tplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 5927 |               sig_req(tplci,ASSIGN,DSIG_ID); | 
 | 5928 |               a->AdvSignalPLCI->internal_command = HOOK_OFF_REQ; | 
 | 5929 |               a->AdvSignalPLCI->command = 0; | 
 | 5930 |               tplci->appl = a->AdvSignalAppl; | 
 | 5931 |               tplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; | 
 | 5932 |               send_req(tplci); | 
 | 5933 |             } | 
 | 5934 |  | 
 | 5935 |           } | 
 | 5936 |  | 
 | 5937 |           if(!tplci) break; | 
 | 5938 |           Id = ((word)tplci->Id<<8)|a->Id; | 
 | 5939 |           Id|=EXT_CONTROLLER; | 
 | 5940 |           sendf(tplci->appl, | 
 | 5941 |                 _FACILITY_I, | 
 | 5942 |                 Id, | 
 | 5943 |                 0, | 
 | 5944 |                 "ws", (word)0, "\x01+"); | 
 | 5945 |           break; | 
 | 5946 |  | 
 | 5947 |         case 0x90:   /* hook on  */ | 
 | 5948 |         case 0x91: | 
 | 5949 |           if(plci->internal_command==PERM_COD_HOOK) | 
 | 5950 |           { | 
 | 5951 |             dbug(1,dprintf("init:hook_on")); | 
 | 5952 |             plci->hook_state = ie[1]&0x91; | 
 | 5953 |             next_internal_command (Id, plci); | 
 | 5954 |             break; | 
 | 5955 |           } | 
 | 5956 |           else /* ignore doubled hook indications */ | 
 | 5957 |           { | 
 | 5958 |             if( ((plci->hook_state)&0xf0)==0x90) break; | 
 | 5959 |             plci->hook_state = ie[1]&0x91; | 
 | 5960 |           } | 
 | 5961 |           /* hangup the adv. voice call and signal '-' to the appl */ | 
 | 5962 |           if(a->AdvSignalPLCI) { | 
 | 5963 |             Id = ((word)a->AdvSignalPLCI->Id<<8)|a->Id; | 
 | 5964 |             if(plci->tel) Id|=EXT_CONTROLLER; | 
 | 5965 |             sendf(a->AdvSignalAppl, | 
 | 5966 |                   _FACILITY_I, | 
 | 5967 |                   Id, | 
 | 5968 |                   0, | 
 | 5969 |                   "ws", (word)0, "\x01-"); | 
 | 5970 |             a->AdvSignalPLCI->internal_command = HOOK_ON_REQ; | 
 | 5971 |             a->AdvSignalPLCI->command = 0; | 
 | 5972 |             sig_req(a->AdvSignalPLCI,HANGUP,0); | 
 | 5973 |             send_req(a->AdvSignalPLCI); | 
 | 5974 |           } | 
 | 5975 |           break; | 
 | 5976 |       } | 
 | 5977 |     } | 
 | 5978 |     break; | 
 | 5979 |  | 
 | 5980 |   case RESUME: | 
 | 5981 |     clear_c_ind_mask_bit (plci, (word)(plci->appl->Id-1)); | 
 | 5982 |     PUT_WORD(&resume_cau[4],GOOD); | 
 | 5983 |     sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau); | 
 | 5984 |     break; | 
 | 5985 |  | 
 | 5986 |   case SUSPEND: | 
 | 5987 |     clear_c_ind_mask (plci); | 
 | 5988 |  | 
 | 5989 |     if (plci->NL.Id && !plci->nl_remove_id) { | 
 | 5990 |       mixer_remove (plci); | 
 | 5991 |       nl_req_ncci(plci,REMOVE,0); | 
 | 5992 |     } | 
 | 5993 |     if (!plci->sig_remove_id) { | 
 | 5994 |       plci->internal_command = 0; | 
 | 5995 |       sig_req(plci,REMOVE,0); | 
 | 5996 |     } | 
 | 5997 |     send_req(plci); | 
 | 5998 |     if(!plci->channels) { | 
 | 5999 |       sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, "\x05\x04\x00\x02\x00\x00"); | 
 | 6000 |       sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0); | 
 | 6001 |     } | 
 | 6002 |     break; | 
 | 6003 |  | 
 | 6004 |   case SUSPEND_REJ: | 
 | 6005 |     break; | 
 | 6006 |  | 
 | 6007 |   case HANGUP: | 
 | 6008 |     plci->hangup_flow_ctrl_timer=0; | 
 | 6009 |     if(plci->manufacturer && plci->State==LOCAL_CONNECT) break; | 
 | 6010 |     cau = parms[7]; | 
 | 6011 |     if(cau) { | 
 | 6012 |       i = _L3_CAUSE | cau[2]; | 
 | 6013 |       if(cau[2]==0) i = 0; | 
 | 6014 |       else if(cau[2]==8) i = _L1_ERROR; | 
 | 6015 |       else if(cau[2]==9 || cau[2]==10) i = _L2_ERROR; | 
 | 6016 |       else if(cau[2]==5) i = _CAPI_GUARD_ERROR; | 
 | 6017 |     } | 
 | 6018 |     else { | 
 | 6019 |       i = _L3_ERROR; | 
 | 6020 |     } | 
 | 6021 |  | 
 | 6022 |     if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT) | 
 | 6023 |     { | 
 | 6024 |       for(i=0; i<max_appl; i++) | 
 | 6025 |       { | 
 | 6026 |         if(test_c_ind_mask_bit (plci, i)) | 
 | 6027 |           sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0); | 
 | 6028 |       } | 
 | 6029 |     } | 
 | 6030 |     else | 
 | 6031 |     { | 
 | 6032 |       clear_c_ind_mask (plci); | 
 | 6033 |     } | 
 | 6034 |     if(!plci->appl) | 
 | 6035 |     { | 
 | 6036 |       if (plci->State == LISTENING) | 
 | 6037 |       { | 
 | 6038 |         plci->notifiedcall=0; | 
 | 6039 |         a->listen_active--; | 
 | 6040 |       } | 
 | 6041 |       plci->State = INC_DIS_PENDING; | 
 | 6042 |       if(c_ind_mask_empty (plci)) | 
 | 6043 |       { | 
 | 6044 |         plci->State = IDLE; | 
 | 6045 |         if (plci->NL.Id && !plci->nl_remove_id) | 
 | 6046 |         { | 
 | 6047 |           mixer_remove (plci); | 
 | 6048 |           nl_req_ncci(plci,REMOVE,0); | 
 | 6049 |         } | 
 | 6050 |         if (!plci->sig_remove_id) | 
 | 6051 |         { | 
 | 6052 |           plci->internal_command = 0; | 
 | 6053 |           sig_req(plci,REMOVE,0); | 
 | 6054 |         } | 
 | 6055 |         send_req(plci); | 
 | 6056 |       } | 
 | 6057 |     } | 
 | 6058 |     else | 
 | 6059 |     { | 
 | 6060 |         /* collision of DISCONNECT or CONNECT_RES with HANGUP can   */ | 
 | 6061 |         /* result in a second HANGUP! Don't generate another        */ | 
 | 6062 |         /* DISCONNECT                                               */ | 
 | 6063 |       if(plci->State!=IDLE && plci->State!=INC_DIS_PENDING) | 
 | 6064 |       { | 
 | 6065 |         if(plci->State==RESUMING) | 
 | 6066 |         { | 
 | 6067 |           PUT_WORD(&resume_cau[4],i); | 
 | 6068 |           sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau); | 
 | 6069 |         } | 
 | 6070 |         plci->State = INC_DIS_PENDING; | 
 | 6071 |         sendf(plci->appl,_DISCONNECT_I,Id,0,"w",i); | 
 | 6072 |       } | 
 | 6073 |     } | 
 | 6074 |     break; | 
 | 6075 |  | 
 | 6076 |   case SSEXT_IND: | 
 | 6077 |     SendSSExtInd(NULL,plci,Id,multi_ssext_parms); | 
 | 6078 |     break; | 
 | 6079 |  | 
 | 6080 |   case VSWITCH_REQ: | 
 | 6081 |     VSwitchReqInd(plci,Id,multi_vswitch_parms); | 
 | 6082 |     break; | 
 | 6083 |   case VSWITCH_IND: | 
 | 6084 |  if(plci->relatedPTYPLCI && | 
 | 6085 |   plci->vswitchstate==3 && | 
 | 6086 |   plci->relatedPTYPLCI->vswitchstate==3 && | 
 | 6087 |   parms[MAXPARMSIDS-1][0]) | 
 | 6088 |  { | 
 | 6089 |   add_p(plci->relatedPTYPLCI,SMSG,parms[MAXPARMSIDS-1]); | 
 | 6090 |   sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0); | 
 | 6091 |   send_req(plci->relatedPTYPLCI); | 
 | 6092 |  } | 
 | 6093 |     else VSwitchReqInd(plci,Id,multi_vswitch_parms); | 
 | 6094 |     break; | 
 | 6095 |  | 
 | 6096 |   } | 
 | 6097 | } | 
 | 6098 |  | 
 | 6099 |  | 
 | 6100 | static void SendSetupInfo(APPL   * appl, PLCI   * plci, dword Id, byte   * * parms, byte Info_Sent_Flag) | 
 | 6101 | { | 
 | 6102 |   word i; | 
 | 6103 |   byte   * ie; | 
 | 6104 |   word Info_Number; | 
 | 6105 |   byte   * Info_Element; | 
 | 6106 |   word Info_Mask = 0; | 
 | 6107 |  | 
 | 6108 |   dbug(1,dprintf("SetupInfo")); | 
 | 6109 |  | 
 | 6110 |   for(i=0; i<MAXPARMSIDS; i++) { | 
 | 6111 |     ie = parms[i]; | 
 | 6112 |     Info_Number = 0; | 
 | 6113 |     Info_Element = ie; | 
 | 6114 |     if(ie[0]) { | 
 | 6115 |       switch(i) { | 
 | 6116 |       case 0: | 
 | 6117 |         dbug(1,dprintf("CPN ")); | 
 | 6118 |         Info_Number = 0x0070; | 
 | 6119 |         Info_Mask   = 0x80; | 
 | 6120 |         Info_Sent_Flag = TRUE; | 
 | 6121 |         break; | 
 | 6122 |       case 8:  /* display      */ | 
 | 6123 |         dbug(1,dprintf("display(%d)",i)); | 
 | 6124 |         Info_Number = 0x0028; | 
 | 6125 |         Info_Mask = 0x04; | 
 | 6126 |         Info_Sent_Flag = TRUE; | 
 | 6127 |         break; | 
 | 6128 |       case 16: /* Channel Id */ | 
 | 6129 |         dbug(1,dprintf("CHI")); | 
 | 6130 |         Info_Number = 0x0018; | 
 | 6131 |         Info_Mask = 0x100; | 
 | 6132 |         Info_Sent_Flag = TRUE; | 
 | 6133 |         mixer_set_bchannel_id (plci, Info_Element); | 
 | 6134 |         break; | 
 | 6135 |       case 19: /* Redirected Number */ | 
 | 6136 |         dbug(1,dprintf("RDN")); | 
 | 6137 |         Info_Number = 0x0074; | 
 | 6138 |         Info_Mask = 0x400; | 
 | 6139 |         Info_Sent_Flag = TRUE; | 
 | 6140 |         break; | 
 | 6141 |       case 20: /* Redirected Number extended */ | 
 | 6142 |         dbug(1,dprintf("RDX")); | 
 | 6143 |         Info_Number = 0x0073; | 
 | 6144 |         Info_Mask = 0x400; | 
 | 6145 |         Info_Sent_Flag = TRUE; | 
 | 6146 |         break; | 
 | 6147 |       case 22: /* Redirecing Number  */ | 
 | 6148 |         dbug(1,dprintf("RIN")); | 
 | 6149 |         Info_Number = 0x0076; | 
 | 6150 |         Info_Mask = 0x400; | 
 | 6151 |         Info_Sent_Flag = TRUE; | 
 | 6152 |         break; | 
 | 6153 |       default: | 
 | 6154 |         Info_Number = 0; | 
 | 6155 |         break; | 
 | 6156 |       } | 
 | 6157 |     } | 
 | 6158 |  | 
 | 6159 |     if(i==MAXPARMSIDS-2){ /* to indicate the message type "Setup" */ | 
 | 6160 |       Info_Number = 0x8000 |5; | 
 | 6161 |       Info_Mask = 0x10; | 
 | 6162 |       Info_Element = ""; | 
 | 6163 |     } | 
 | 6164 |  | 
 | 6165 |     if(Info_Sent_Flag && Info_Number){ | 
 | 6166 |       if(plci->adapter->Info_Mask[appl->Id-1] & Info_Mask) { | 
 | 6167 |         sendf(appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element); | 
 | 6168 |       } | 
 | 6169 |     } | 
 | 6170 |   } | 
 | 6171 | } | 
 | 6172 |  | 
 | 6173 |  | 
 | 6174 | void SendInfo(PLCI   * plci, dword Id, byte   * * parms, byte iesent) | 
 | 6175 | { | 
 | 6176 |   word i; | 
 | 6177 |   word j; | 
 | 6178 |   word k; | 
 | 6179 |   byte   * ie; | 
 | 6180 |   word Info_Number; | 
 | 6181 |   byte   * Info_Element; | 
 | 6182 |   word Info_Mask = 0; | 
 | 6183 |   static byte charges[5] = {4,0,0,0,0}; | 
 | 6184 |   static byte cause[] = {0x02,0x80,0x00}; | 
 | 6185 |   APPL   *appl; | 
 | 6186 |  | 
 | 6187 |   dbug(1,dprintf("InfoParse ")); | 
 | 6188 |  | 
 | 6189 |   if( | 
 | 6190 |         !plci->appl | 
 | 6191 |         && !plci->State | 
 | 6192 |         && plci->Sig.Ind!=NCR_FACILITY | 
 | 6193 |       ) | 
 | 6194 |   { | 
 | 6195 |     dbug(1,dprintf("NoParse ")); | 
 | 6196 |     return; | 
 | 6197 |   } | 
 | 6198 |   cause[2] = 0; | 
 | 6199 |   for(i=0; i<MAXPARMSIDS; i++) { | 
 | 6200 |     ie = parms[i]; | 
 | 6201 |     Info_Number = 0; | 
 | 6202 |     Info_Element = ie; | 
 | 6203 |     if(ie[0]) { | 
 | 6204 |       switch(i) { | 
 | 6205 |       case 0: | 
 | 6206 |         dbug(1,dprintf("CPN ")); | 
 | 6207 |         Info_Number = 0x0070; | 
 | 6208 |         Info_Mask   = 0x80; | 
 | 6209 |         break; | 
 | 6210 |       case 7: /* ESC_CAU */ | 
 | 6211 |         dbug(1,dprintf("cau(0x%x)",ie[2])); | 
 | 6212 |         Info_Number = 0x0008; | 
 | 6213 |         Info_Mask = 0x00; | 
 | 6214 |         cause[2] = ie[2]; | 
 | 6215 |         Info_Element = NULL; | 
 | 6216 |         break; | 
 | 6217 |       case 8:  /* display      */ | 
 | 6218 |         dbug(1,dprintf("display(%d)",i)); | 
 | 6219 |         Info_Number = 0x0028; | 
 | 6220 |         Info_Mask = 0x04; | 
 | 6221 |         break; | 
 | 6222 |       case 9:  /* Date display */ | 
 | 6223 |         dbug(1,dprintf("date(%d)",i)); | 
 | 6224 |         Info_Number = 0x0029; | 
 | 6225 |         Info_Mask = 0x02; | 
 | 6226 |         break; | 
 | 6227 |       case 10: /* charges */ | 
 | 6228 |         for(j=0;j<4;j++) charges[1+j] = 0; | 
 | 6229 |         for(j=0; j<ie[0] && !(ie[1+j]&0x80); j++); | 
 | 6230 |         for(k=1,j++; j<ie[0] && k<=4; j++,k++) charges[k] = ie[1+j]; | 
 | 6231 |         Info_Number = 0x4000; | 
 | 6232 |         Info_Mask = 0x40; | 
 | 6233 |         Info_Element = charges; | 
 | 6234 |         break; | 
 | 6235 |       case 11: /* user user info */ | 
 | 6236 |         dbug(1,dprintf("uui")); | 
 | 6237 |         Info_Number = 0x007E; | 
 | 6238 |         Info_Mask = 0x08; | 
 | 6239 |         break; | 
 | 6240 |       case 12: /* congestion receiver ready */ | 
 | 6241 |         dbug(1,dprintf("clRDY")); | 
 | 6242 |         Info_Number = 0x00B0; | 
 | 6243 |         Info_Mask = 0x08; | 
 | 6244 |         Info_Element = ""; | 
 | 6245 |         break; | 
 | 6246 |       case 13: /* congestion receiver not ready */ | 
 | 6247 |         dbug(1,dprintf("clNRDY")); | 
 | 6248 |         Info_Number = 0x00BF; | 
 | 6249 |         Info_Mask = 0x08; | 
 | 6250 |         Info_Element = ""; | 
 | 6251 |         break; | 
 | 6252 |       case 15: /* Keypad Facility */ | 
 | 6253 |         dbug(1,dprintf("KEY")); | 
 | 6254 |         Info_Number = 0x002C; | 
 | 6255 |         Info_Mask = 0x20; | 
 | 6256 |         break; | 
 | 6257 |       case 16: /* Channel Id */ | 
 | 6258 |         dbug(1,dprintf("CHI")); | 
 | 6259 |         Info_Number = 0x0018; | 
 | 6260 |         Info_Mask = 0x100; | 
 | 6261 |         mixer_set_bchannel_id (plci, Info_Element); | 
 | 6262 |         break; | 
 | 6263 |       case 17: /* if no 1tr6 cause, send full cause, else esc_cause */ | 
 | 6264 |         dbug(1,dprintf("q9cau(0x%x)",ie[2])); | 
 | 6265 |         if(!cause[2] || cause[2]<0x80) break;  /* eg. layer 1 error */ | 
 | 6266 |         Info_Number = 0x0008; | 
 | 6267 |         Info_Mask = 0x01; | 
 | 6268 |         if(cause[2] != ie[2]) Info_Element = cause; | 
 | 6269 |         break; | 
 | 6270 |       case 19: /* Redirected Number */ | 
 | 6271 |         dbug(1,dprintf("RDN")); | 
 | 6272 |         Info_Number = 0x0074; | 
 | 6273 |         Info_Mask = 0x400; | 
 | 6274 |         break; | 
 | 6275 |       case 22: /* Redirecing Number  */ | 
 | 6276 |         dbug(1,dprintf("RIN")); | 
 | 6277 |         Info_Number = 0x0076; | 
 | 6278 |         Info_Mask = 0x400; | 
 | 6279 |         break; | 
 | 6280 |       case 23: /* Notification Indicator  */ | 
 | 6281 |         dbug(1,dprintf("NI")); | 
 | 6282 |         Info_Number = (word)NI; | 
 | 6283 |         Info_Mask = 0x210; | 
 | 6284 |         break; | 
 | 6285 |       case 26: /* Call State  */ | 
 | 6286 |         dbug(1,dprintf("CST")); | 
 | 6287 |         Info_Number = (word)CST; | 
 | 6288 |         Info_Mask = 0x01; /* do with cause i.e. for now */ | 
 | 6289 |         break; | 
 | 6290 |       case MAXPARMSIDS-2:  /* Escape Message Type, must be the last indication */ | 
 | 6291 |         dbug(1,dprintf("ESC/MT[0x%x]",ie[3])); | 
 | 6292 |         Info_Number = 0x8000 |ie[3]; | 
 | 6293 |         if(iesent) Info_Mask = 0xffff; | 
 | 6294 |         else  Info_Mask = 0x10; | 
 | 6295 |         Info_Element = ""; | 
 | 6296 |         break; | 
 | 6297 |       default: | 
 | 6298 |         Info_Number  = 0; | 
 | 6299 |         Info_Mask    = 0; | 
 | 6300 |         Info_Element = ""; | 
 | 6301 |         break; | 
 | 6302 |       } | 
 | 6303 |     } | 
 | 6304 |  | 
 | 6305 |     if(plci->Sig.Ind==NCR_FACILITY)           /* check controller broadcast */ | 
 | 6306 |     { | 
 | 6307 |       for(j=0; j<max_appl; j++) | 
 | 6308 |       { | 
 | 6309 |         appl = &application[j]; | 
 | 6310 |         if(Info_Number | 
 | 6311 |         && appl->Id | 
 | 6312 |         && plci->adapter->Info_Mask[appl->Id-1] &Info_Mask) | 
 | 6313 |         { | 
 | 6314 |           dbug(1,dprintf("NCR_Ind")); | 
 | 6315 |           iesent=TRUE; | 
 | 6316 |           sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element); | 
 | 6317 |         } | 
 | 6318 |       } | 
 | 6319 |     } | 
 | 6320 |     else if(!plci->appl) | 
 | 6321 |     { /* overlap receiving broadcast */ | 
 | 6322 |       if(Info_Number==CPN | 
 | 6323 |       || Info_Number==KEY | 
 | 6324 |       || Info_Number==NI | 
 | 6325 |       || Info_Number==DSP | 
 | 6326 |       || Info_Number==UUI ) | 
 | 6327 |       { | 
 | 6328 |         for(j=0; j<max_appl; j++) | 
 | 6329 |         { | 
 | 6330 |           if(test_c_ind_mask_bit (plci, j)) | 
 | 6331 |           { | 
 | 6332 |             dbug(1,dprintf("Ovl_Ind")); | 
 | 6333 |             iesent=TRUE; | 
 | 6334 |             sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element); | 
 | 6335 |           } | 
 | 6336 |         } | 
 | 6337 |       } | 
 | 6338 |     }               /* all other signalling states */ | 
 | 6339 |     else if(Info_Number | 
 | 6340 |     && plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask) | 
 | 6341 |     { | 
 | 6342 |       dbug(1,dprintf("Std_Ind")); | 
 | 6343 |       iesent=TRUE; | 
 | 6344 |       sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element); | 
 | 6345 |     } | 
 | 6346 |   } | 
 | 6347 | } | 
 | 6348 |  | 
 | 6349 |  | 
 | 6350 | byte SendMultiIE(PLCI   * plci, dword Id, byte   * * parms, byte ie_type, dword info_mask, byte setupParse) | 
 | 6351 | { | 
 | 6352 |   word i; | 
 | 6353 |   word j; | 
 | 6354 |   byte   * ie; | 
 | 6355 |   word Info_Number; | 
 | 6356 |   byte   * Info_Element; | 
 | 6357 |   APPL   *appl; | 
 | 6358 |   word Info_Mask = 0; | 
 | 6359 |   byte iesent=0; | 
 | 6360 |  | 
 | 6361 |   if( | 
 | 6362 |       !plci->appl | 
 | 6363 |       && !plci->State | 
 | 6364 |       && plci->Sig.Ind!=NCR_FACILITY | 
 | 6365 |       && !setupParse | 
 | 6366 |       ) | 
 | 6367 |   { | 
 | 6368 |     dbug(1,dprintf("NoM-IEParse ")); | 
 | 6369 |     return 0; | 
 | 6370 |   } | 
 | 6371 |   dbug(1,dprintf("M-IEParse ")); | 
 | 6372 |  | 
 | 6373 |   for(i=0; i<MAX_MULTI_IE; i++) | 
 | 6374 |   { | 
 | 6375 |     ie = parms[i]; | 
 | 6376 |     Info_Number = 0; | 
 | 6377 |     Info_Element = ie; | 
 | 6378 |     if(ie[0]) | 
 | 6379 |     { | 
 | 6380 |       dbug(1,dprintf("[Ind0x%x]:IE=0x%x",plci->Sig.Ind,ie_type)); | 
 | 6381 |       Info_Number = (word)ie_type; | 
 | 6382 |       Info_Mask = (word)info_mask; | 
 | 6383 |     } | 
 | 6384 |  | 
 | 6385 |     if(plci->Sig.Ind==NCR_FACILITY)           /* check controller broadcast */ | 
 | 6386 |     { | 
 | 6387 |       for(j=0; j<max_appl; j++) | 
 | 6388 |       { | 
 | 6389 |         appl = &application[j]; | 
 | 6390 |         if(Info_Number | 
 | 6391 |         && appl->Id | 
 | 6392 |         && plci->adapter->Info_Mask[appl->Id-1] &Info_Mask) | 
 | 6393 |         { | 
 | 6394 |           iesent = TRUE; | 
 | 6395 |           dbug(1,dprintf("Mlt_NCR_Ind")); | 
 | 6396 |           sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element); | 
 | 6397 |         } | 
 | 6398 |       } | 
 | 6399 |     } | 
 | 6400 |     else if(!plci->appl && Info_Number) | 
 | 6401 |     {                                        /* overlap receiving broadcast */ | 
 | 6402 |       for(j=0; j<max_appl; j++) | 
 | 6403 |       { | 
 | 6404 |         if(test_c_ind_mask_bit (plci, j)) | 
 | 6405 |         { | 
 | 6406 |           iesent = TRUE; | 
 | 6407 |           dbug(1,dprintf("Mlt_Ovl_Ind")); | 
 | 6408 |           sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element); | 
 | 6409 |         } | 
 | 6410 |       } | 
 | 6411 |     }                                        /* all other signalling states */ | 
 | 6412 |     else if(Info_Number | 
 | 6413 |     && plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask) | 
 | 6414 |     { | 
 | 6415 |       iesent = TRUE; | 
 | 6416 |       dbug(1,dprintf("Mlt_Std_Ind")); | 
 | 6417 |       sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element); | 
 | 6418 |     } | 
 | 6419 |   } | 
 | 6420 |   return iesent; | 
 | 6421 | } | 
 | 6422 |  | 
 | 6423 | static void SendSSExtInd(APPL   * appl, PLCI   * plci, dword Id, byte   * * parms) | 
 | 6424 | { | 
 | 6425 |   word i; | 
 | 6426 |    /* Format of multi_ssext_parms[i][]: | 
 | 6427 |    0 byte length | 
 | 6428 |    1 byte SSEXTIE | 
 | 6429 |    2 byte SSEXT_REQ/SSEXT_IND | 
 | 6430 |    3 byte length | 
 | 6431 |    4 word SSExtCommand | 
 | 6432 |    6... Params | 
 | 6433 |    */ | 
 | 6434 |   if( | 
 | 6435 |    plci | 
 | 6436 |    && plci->State | 
 | 6437 |    && plci->Sig.Ind!=NCR_FACILITY | 
 | 6438 |     ) | 
 | 6439 |  for(i=0;i<MAX_MULTI_IE;i++) | 
 | 6440 |     { | 
 | 6441 |       if(parms[i][0]<6) continue; | 
 | 6442 |    if(parms[i][2]==SSEXT_REQ) continue; | 
 | 6443 |  | 
 | 6444 |    if(appl) | 
 | 6445 |    { | 
 | 6446 |     parms[i][0]=0; /* kill it */ | 
 | 6447 |     sendf(appl,_MANUFACTURER_I, | 
 | 6448 |     Id, | 
 | 6449 |     0, | 
 | 6450 |     "dwS", | 
 | 6451 |     _DI_MANU_ID, | 
 | 6452 |     _DI_SSEXT_CTRL, | 
 | 6453 |     &parms[i][3]); | 
 | 6454 |    } | 
 | 6455 |    else if(plci->appl) | 
 | 6456 |    { | 
 | 6457 |     parms[i][0]=0; /* kill it */ | 
 | 6458 |     sendf(plci->appl,_MANUFACTURER_I, | 
 | 6459 |     Id, | 
 | 6460 |     0, | 
 | 6461 |     "dwS", | 
 | 6462 |     _DI_MANU_ID, | 
 | 6463 |     _DI_SSEXT_CTRL, | 
 | 6464 |     &parms[i][3]); | 
 | 6465 |    } | 
 | 6466 |     } | 
 | 6467 | }; | 
 | 6468 |  | 
 | 6469 | void nl_ind(PLCI   * plci) | 
 | 6470 | { | 
 | 6471 |   byte ch; | 
 | 6472 |   word ncci; | 
 | 6473 |   dword Id; | 
 | 6474 |   DIVA_CAPI_ADAPTER   * a; | 
 | 6475 |   word NCCIcode; | 
 | 6476 |   APPL   * APPLptr; | 
 | 6477 |   word count; | 
 | 6478 |   word Num; | 
 | 6479 |   word i, ncpi_state; | 
 | 6480 |   byte len, ncci_state; | 
 | 6481 |   word msg; | 
 | 6482 |   word info = 0; | 
 | 6483 |   word fax_feature_bits; | 
 | 6484 |   byte fax_send_edata_ack; | 
 | 6485 |   static byte v120_header_buffer[2 + 3]; | 
 | 6486 |   static word fax_info[] = { | 
 | 6487 |     0,                     /* T30_SUCCESS                        */ | 
 | 6488 |     _FAX_NO_CONNECTION,    /* T30_ERR_NO_DIS_RECEIVED            */ | 
 | 6489 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_NO_RESPONSE        */ | 
 | 6490 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_RESPONSE          */ | 
 | 6491 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_TOO_MANY_REPEATS           */ | 
 | 6492 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_UNEXPECTED_MESSAGE         */ | 
 | 6493 |     _FAX_REMOTE_ABORT,     /* T30_ERR_UNEXPECTED_DCN             */ | 
 | 6494 |     _FAX_LOCAL_ABORT,      /* T30_ERR_DTC_UNSUPPORTED            */ | 
 | 6495 |     _FAX_TRAINING_ERROR,   /* T30_ERR_ALL_RATES_FAILED           */ | 
 | 6496 |     _FAX_TRAINING_ERROR,   /* T30_ERR_TOO_MANY_TRAINS            */ | 
 | 6497 |     _FAX_PARAMETER_ERROR,  /* T30_ERR_RECEIVE_CORRUPTED          */ | 
 | 6498 |     _FAX_REMOTE_ABORT,     /* T30_ERR_UNEXPECTED_DISC            */ | 
 | 6499 |     _FAX_LOCAL_ABORT,      /* T30_ERR_APPLICATION_DISC           */ | 
 | 6500 |     _FAX_REMOTE_REJECT,    /* T30_ERR_INCOMPATIBLE_DIS           */ | 
 | 6501 |     _FAX_LOCAL_ABORT,      /* T30_ERR_INCOMPATIBLE_DCS           */ | 
 | 6502 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_NO_COMMAND         */ | 
 | 6503 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_COMMAND           */ | 
 | 6504 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG   */ | 
 | 6505 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG  */ | 
 | 6506 |     _FAX_NO_CONNECTION,    /* T30_ERR_NOT_IDENTIFIED             */ | 
 | 6507 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_SUPERVISORY_TIMEOUT        */ | 
 | 6508 |     _FAX_PARAMETER_ERROR,  /* T30_ERR_TOO_LONG_SCAN_LINE         */ | 
 | 6509 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS    */ | 
 | 6510 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR    */ | 
 | 6511 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_FTT     */ | 
 | 6512 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_EOM     */ | 
 | 6513 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_MPS     */ | 
 | 6514 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCN_AFTER_MCF     */ | 
 | 6515 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCN_AFTER_RTN     */ | 
 | 6516 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_CFR               */ | 
 | 6517 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_EOP     */ | 
 | 6518 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_EOM     */ | 
 | 6519 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_MPS     */ | 
 | 6520 |     0x331d,                /* T30_ERR_SUB_SEP_UNSUPPORTED        */ | 
 | 6521 |     0x331e,                /* T30_ERR_PWD_UNSUPPORTED            */ | 
 | 6522 |     0x331f,                /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED    */ | 
 | 6523 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_INVALID_COMMAND_FRAME      */ | 
 | 6524 |     _FAX_PARAMETER_ERROR,  /* T30_ERR_UNSUPPORTED_PAGE_CODING    */ | 
 | 6525 |     _FAX_PARAMETER_ERROR,  /* T30_ERR_INVALID_PAGE_CODING        */ | 
 | 6526 |     _FAX_REMOTE_REJECT,    /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG   */ | 
 | 6527 |     _FAX_LOCAL_ABORT,      /* T30_ERR_TIMEOUT_FROM_APPLICATION   */ | 
 | 6528 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */ | 
 | 6529 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_TRAINING_TIMEOUT    */ | 
 | 6530 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_UNEXPECTED_V21      */ | 
 | 6531 |     _FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_PRIMARY_CTS_ON      */ | 
 | 6532 |     _FAX_LOCAL_ABORT,      /* T30_ERR_V34FAX_TURNAROUND_POLLING  */ | 
 | 6533 |     _FAX_LOCAL_ABORT       /* T30_ERR_V34FAX_V8_INCOMPATIBILITY  */ | 
 | 6534 |   }; | 
 | 6535 |  | 
 | 6536 |     byte dtmf_code_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE + 1]; | 
 | 6537 |  | 
 | 6538 |  | 
 | 6539 |   static word rtp_info[] = { | 
 | 6540 |     GOOD,                  /* RTP_SUCCESS                       */ | 
 | 6541 |     0x3600                 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE    */ | 
 | 6542 |   }; | 
 | 6543 |  | 
 | 6544 |   static dword udata_forwarding_table[0x100 / sizeof(dword)] = | 
 | 6545 |   { | 
 | 6546 |     0x0020301e, 0x00000000, 0x00000000, 0x00000000, | 
 | 6547 |     0x00000000, 0x00000000, 0x00000000, 0x00000000 | 
 | 6548 |   }; | 
 | 6549 |  | 
 | 6550 |   ch = plci->NL.IndCh; | 
 | 6551 |   a = plci->adapter; | 
 | 6552 |   ncci = a->ch_ncci[ch]; | 
 | 6553 |   Id = (((dword)(ncci ? ncci : ch)) << 16) | (((word) plci->Id) << 8) | a->Id; | 
 | 6554 |   if(plci->tel) Id|=EXT_CONTROLLER; | 
 | 6555 |   APPLptr = plci->appl; | 
 | 6556 |   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", | 
 | 6557 |     plci->NL.Id,Id,plci->Id,plci->tel,plci->State,ch,plci->channels,plci->NL.Ind &0x0f)); | 
 | 6558 |  | 
 | 6559 |   /* in the case if no connect_active_Ind was sent to the appl we wait for */ | 
 | 6560 |  | 
 | 6561 |   if (plci->nl_remove_id) | 
 | 6562 |   { | 
 | 6563 |     plci->NL.RNR = 2; /* discard */ | 
 | 6564 |     dbug(1,dprintf("NL discard while remove pending")); | 
 | 6565 |     return; | 
 | 6566 |   } | 
 | 6567 |   if((plci->NL.Ind &0x0f)==N_CONNECT) | 
 | 6568 |   { | 
 | 6569 |     if(plci->State==INC_DIS_PENDING | 
 | 6570 |     || plci->State==OUTG_DIS_PENDING | 
 | 6571 |     || plci->State==IDLE) | 
 | 6572 |     { | 
 | 6573 |       plci->NL.RNR = 2; /* discard */ | 
 | 6574 |       dbug(1,dprintf("discard n_connect")); | 
 | 6575 |       return; | 
 | 6576 |     } | 
 | 6577 |     if(plci->State < INC_ACT_PENDING) | 
 | 6578 |     { | 
 | 6579 |       plci->NL.RNR = 1; /* flow control */ | 
 | 6580 |       channel_x_off (plci, ch, N_XON_CONNECT_IND); | 
 | 6581 |       return; | 
 | 6582 |     } | 
 | 6583 |   } | 
 | 6584 |  | 
 | 6585 |   if(!APPLptr)                         /* no application or invalid data */ | 
 | 6586 |   {                                    /* while reloading the DSP        */ | 
 | 6587 |     dbug(1,dprintf("discard1")); | 
 | 6588 |     plci->NL.RNR = 2; | 
 | 6589 |     return; | 
 | 6590 |   } | 
 | 6591 |  | 
 | 6592 |   if (((plci->NL.Ind &0x0f) == N_UDATA) | 
 | 6593 |      && (((plci->B2_prot != B2_SDLC) && ((plci->B1_resource == 17) || (plci->B1_resource == 18))) | 
 | 6594 |         || (plci->B2_prot == 7) | 
 | 6595 |         || (plci->B3_prot == 7)) ) | 
 | 6596 |   { | 
 | 6597 |     plci->ncpi_buffer[0] = 0; | 
 | 6598 |  | 
 | 6599 |     ncpi_state = plci->ncpi_state; | 
 | 6600 |     if (plci->NL.complete == 1) | 
 | 6601 |     { | 
 | 6602 |       byte  * data = &plci->NL.RBuffer->P[0]; | 
 | 6603 |  | 
 | 6604 |       if ((plci->NL.RBuffer->length >= 12) | 
 | 6605 |         &&( (*data == DSP_UDATA_INDICATION_DCD_ON) | 
 | 6606 |           ||(*data == DSP_UDATA_INDICATION_CTS_ON)) ) | 
 | 6607 |       { | 
 | 6608 |         word conn_opt, ncpi_opt = 0x00; | 
 | 6609 | /*      HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */ | 
 | 6610 |  | 
 | 6611 |         if (*data == DSP_UDATA_INDICATION_DCD_ON) | 
 | 6612 |           plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED; | 
 | 6613 |         if (*data == DSP_UDATA_INDICATION_CTS_ON) | 
 | 6614 |           plci->ncpi_state |= NCPI_MDM_CTS_ON_RECEIVED; | 
 | 6615 |  | 
 | 6616 |         data++;    /* indication code */ | 
 | 6617 |         data += 2; /* timestamp */ | 
 | 6618 |         if ((*data == DSP_CONNECTED_NORM_V18) || (*data == DSP_CONNECTED_NORM_VOWN)) | 
 | 6619 |           ncpi_state &= ~(NCPI_MDM_DCD_ON_RECEIVED | NCPI_MDM_CTS_ON_RECEIVED); | 
 | 6620 |         data++;    /* connected norm */ | 
 | 6621 |         conn_opt = GET_WORD(data); | 
 | 6622 |         data += 2; /* connected options */ | 
 | 6623 |  | 
 | 6624 |         PUT_WORD (&(plci->ncpi_buffer[1]), (word)(GET_DWORD(data) & 0x0000FFFF)); | 
 | 6625 |  | 
 | 6626 |         if (conn_opt & DSP_CONNECTED_OPTION_MASK_V42) | 
 | 6627 |         { | 
 | 6628 |           ncpi_opt |= MDM_NCPI_ECM_V42; | 
 | 6629 |         } | 
 | 6630 |         else if (conn_opt & DSP_CONNECTED_OPTION_MASK_MNP) | 
 | 6631 |         { | 
 | 6632 |           ncpi_opt |= MDM_NCPI_ECM_MNP; | 
 | 6633 |         } | 
 | 6634 |         else | 
 | 6635 |         { | 
 | 6636 |           ncpi_opt |= MDM_NCPI_TRANSPARENT; | 
 | 6637 |         } | 
 | 6638 |         if (conn_opt & DSP_CONNECTED_OPTION_MASK_COMPRESSION) | 
 | 6639 |         { | 
 | 6640 |           ncpi_opt |= MDM_NCPI_COMPRESSED; | 
 | 6641 |         } | 
 | 6642 |         PUT_WORD (&(plci->ncpi_buffer[3]), ncpi_opt); | 
 | 6643 |         plci->ncpi_buffer[0] = 4; | 
 | 6644 |  | 
 | 6645 |         plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND | NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND; | 
 | 6646 |       } | 
 | 6647 |     } | 
 | 6648 |     if (plci->B3_prot == 7) | 
 | 6649 |     { | 
 | 6650 |       if (((a->ncci_state[ncci] == INC_ACT_PENDING) || (a->ncci_state[ncci] == OUTG_CON_PENDING)) | 
 | 6651 |        && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) | 
 | 6652 |        && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) | 
 | 6653 |       { | 
 | 6654 |         a->ncci_state[ncci] = INC_ACT_PENDING; | 
 | 6655 |         sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); | 
 | 6656 |         plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; | 
 | 6657 |       } | 
 | 6658 |     } | 
 | 6659 |  | 
 | 6660 |     if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) | 
 | 6661 |         & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN))) | 
 | 6662 |      || !(ncpi_state & NCPI_MDM_DCD_ON_RECEIVED) | 
 | 6663 |      || !(ncpi_state & NCPI_MDM_CTS_ON_RECEIVED)) | 
 | 6664 |  | 
 | 6665 |     { | 
 | 6666 |       plci->NL.RNR = 2; | 
 | 6667 |       return; | 
 | 6668 |     } | 
 | 6669 |   } | 
 | 6670 |  | 
 | 6671 |   if(plci->NL.complete == 2) | 
 | 6672 |     { | 
 | 6673 |     if (((plci->NL.Ind &0x0f) == N_UDATA) | 
 | 6674 |      && !(udata_forwarding_table[plci->RData[0].P[0] >> 5] & (1L << (plci->RData[0].P[0] & 0x1f)))) | 
 | 6675 |     { | 
 | 6676 |       switch(plci->RData[0].P[0]) | 
 | 6677 |       { | 
 | 6678 |  | 
 | 6679 |       case DTMF_UDATA_INDICATION_FAX_CALLING_TONE: | 
 | 6680 |         if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG) | 
 | 6681 |           sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,"ws", SELECTOR_DTMF, "\x01X"); | 
 | 6682 |         break; | 
 | 6683 |       case DTMF_UDATA_INDICATION_ANSWER_TONE: | 
 | 6684 |         if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG) | 
 | 6685 |           sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,"ws", SELECTOR_DTMF, "\x01Y"); | 
 | 6686 |         break; | 
 | 6687 |       case DTMF_UDATA_INDICATION_DIGITS_RECEIVED: | 
 | 6688 |         dtmf_indication (Id, plci, plci->RData[0].P, plci->RData[0].PLength); | 
 | 6689 |         break; | 
 | 6690 |       case DTMF_UDATA_INDICATION_DIGITS_SENT: | 
 | 6691 |         dtmf_confirmation (Id, plci); | 
 | 6692 |         break; | 
 | 6693 |  | 
 | 6694 |  | 
 | 6695 |       case UDATA_INDICATION_MIXER_TAP_DATA: | 
 | 6696 |         capidtmf_recv_process_block (&(plci->capidtmf_state), plci->RData[0].P + 1, (word)(plci->RData[0].PLength - 1)); | 
 | 6697 |  i = capidtmf_indication (&(plci->capidtmf_state), dtmf_code_buffer + 1); | 
 | 6698 |  if (i != 0) | 
 | 6699 |  { | 
 | 6700 |    dtmf_code_buffer[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED; | 
 | 6701 |           dtmf_indication (Id, plci, dtmf_code_buffer, (word)(i + 1)); | 
 | 6702 |  } | 
 | 6703 |         break; | 
 | 6704 |  | 
 | 6705 |  | 
 | 6706 |       case UDATA_INDICATION_MIXER_COEFS_SET: | 
 | 6707 |         mixer_indication_coefs_set (Id, plci); | 
 | 6708 |         break; | 
 | 6709 |       case UDATA_INDICATION_XCONNECT_FROM: | 
 | 6710 |         mixer_indication_xconnect_from (Id, plci, plci->RData[0].P, plci->RData[0].PLength); | 
 | 6711 |         break; | 
 | 6712 |       case UDATA_INDICATION_XCONNECT_TO: | 
 | 6713 |         mixer_indication_xconnect_to (Id, plci, plci->RData[0].P, plci->RData[0].PLength); | 
 | 6714 |         break; | 
 | 6715 |  | 
 | 6716 |  | 
 | 6717 |       case LEC_UDATA_INDICATION_DISABLE_DETECT: | 
 | 6718 |         ec_indication (Id, plci, plci->RData[0].P, plci->RData[0].PLength); | 
 | 6719 |         break; | 
 | 6720 |  | 
 | 6721 |  | 
 | 6722 |  | 
 | 6723 |       default: | 
 | 6724 |         break; | 
 | 6725 |       } | 
 | 6726 |     } | 
 | 6727 |     else | 
 | 6728 |   { | 
 | 6729 |       if ((plci->RData[0].PLength != 0) | 
 | 6730 |      && ((plci->B2_prot == B2_V120_ASYNC) | 
 | 6731 |       || (plci->B2_prot == B2_V120_ASYNC_V42BIS) | 
 | 6732 |       || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))) | 
 | 6733 |     { | 
 | 6734 |  | 
 | 6735 |       sendf(plci->appl,_DATA_B3_I,Id,0, | 
 | 6736 |             "dwww", | 
 | 6737 |             plci->RData[1].P, | 
 | 6738 |               (plci->NL.RNum < 2) ? 0 : plci->RData[1].PLength, | 
 | 6739 |             plci->RNum, | 
 | 6740 |             plci->RFlags); | 
 | 6741 |  | 
 | 6742 |     } | 
 | 6743 |     else | 
 | 6744 |     { | 
 | 6745 |  | 
 | 6746 |       sendf(plci->appl,_DATA_B3_I,Id,0, | 
 | 6747 |             "dwww", | 
 | 6748 |             plci->RData[0].P, | 
 | 6749 |             plci->RData[0].PLength, | 
 | 6750 |             plci->RNum, | 
 | 6751 |             plci->RFlags); | 
 | 6752 |  | 
 | 6753 |     } | 
 | 6754 |     } | 
 | 6755 |     return; | 
 | 6756 |   } | 
 | 6757 |  | 
 | 6758 |   fax_feature_bits = 0; | 
 | 6759 |   if((plci->NL.Ind &0x0f)==N_CONNECT || | 
 | 6760 |      (plci->NL.Ind &0x0f)==N_CONNECT_ACK || | 
 | 6761 |      (plci->NL.Ind &0x0f)==N_DISC || | 
 | 6762 |      (plci->NL.Ind &0x0f)==N_EDATA || | 
 | 6763 |      (plci->NL.Ind &0x0f)==N_DISC_ACK) | 
 | 6764 |   { | 
 | 6765 |     info = 0; | 
 | 6766 |     plci->ncpi_buffer[0] = 0; | 
 | 6767 |     switch (plci->B3_prot) { | 
 | 6768 |     case  0: /*XPARENT*/ | 
 | 6769 |     case  1: /*T.90 NL*/ | 
 | 6770 |       break;    /* no network control protocol info - jfr */ | 
 | 6771 |     case  2: /*ISO8202*/ | 
 | 6772 |     case  3: /*X25 DCE*/ | 
 | 6773 |       for(i=0; i<plci->NL.RLength; i++) plci->ncpi_buffer[4+i] = plci->NL.RBuffer->P[i]; | 
 | 6774 |       plci->ncpi_buffer[0] = (byte)(i+3); | 
 | 6775 |       plci->ncpi_buffer[1] = (byte)(plci->NL.Ind &N_D_BIT? 1:0); | 
 | 6776 |       plci->ncpi_buffer[2] = 0; | 
 | 6777 |       plci->ncpi_buffer[3] = 0; | 
 | 6778 |       break; | 
 | 6779 |     case  4: /*T.30 - FAX*/ | 
 | 6780 |     case  5: /*T.30 - FAX*/ | 
 | 6781 |       if(plci->NL.RLength>=sizeof(T30_INFO)) | 
 | 6782 |       { | 
 | 6783 |         dbug(1,dprintf("FaxStatus %04x", ((T30_INFO   *)plci->NL.RBuffer->P)->code)); | 
 | 6784 |         len = 9; | 
 | 6785 |         PUT_WORD(&(plci->ncpi_buffer[1]),((T30_INFO   *)plci->NL.RBuffer->P)->rate_div_2400 * 2400); | 
 | 6786 |         fax_feature_bits = GET_WORD(&((T30_INFO   *)plci->NL.RBuffer->P)->feature_bits_low); | 
 | 6787 |         i = (((T30_INFO   *)plci->NL.RBuffer->P)->resolution & T30_RESOLUTION_R8_0770_OR_200) ? 0x0001 : 0x0000; | 
 | 6788 |         if (plci->B3_prot == 5) | 
 | 6789 |         { | 
 | 6790 |           if (!(fax_feature_bits & T30_FEATURE_BIT_ECM)) | 
 | 6791 |             i |= 0x8000; /* This is not an ECM connection */ | 
 | 6792 |           if (fax_feature_bits & T30_FEATURE_BIT_T6_CODING) | 
 | 6793 |             i |= 0x4000; /* This is a connection with MMR compression */ | 
 | 6794 |           if (fax_feature_bits & T30_FEATURE_BIT_2D_CODING) | 
 | 6795 |             i |= 0x2000; /* This is a connection with MR compression */ | 
 | 6796 |           if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS) | 
 | 6797 |             i |= 0x0004; /* More documents */ | 
 | 6798 |           if (fax_feature_bits & T30_FEATURE_BIT_POLLING) | 
 | 6799 |             i |= 0x0002; /* Fax-polling indication */ | 
 | 6800 |         } | 
 | 6801 |         dbug(1,dprintf("FAX Options %04x %04x",fax_feature_bits,i)); | 
 | 6802 |         PUT_WORD(&(plci->ncpi_buffer[3]),i); | 
 | 6803 |         PUT_WORD(&(plci->ncpi_buffer[5]),((T30_INFO   *)plci->NL.RBuffer->P)->data_format); | 
 | 6804 |         plci->ncpi_buffer[7] = ((T30_INFO   *)plci->NL.RBuffer->P)->pages_low; | 
 | 6805 |         plci->ncpi_buffer[8] = ((T30_INFO   *)plci->NL.RBuffer->P)->pages_high; | 
 | 6806 |         plci->ncpi_buffer[len] = 0; | 
 | 6807 |         if(((T30_INFO   *)plci->NL.RBuffer->P)->station_id_len) | 
 | 6808 |         { | 
 | 6809 |           plci->ncpi_buffer[len] = 20; | 
 | 6810 |           for (i = 0; i < 20; i++) | 
 | 6811 |             plci->ncpi_buffer[++len] = ((T30_INFO   *)plci->NL.RBuffer->P)->station_id[i]; | 
 | 6812 |         } | 
 | 6813 |         if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) | 
 | 6814 |         { | 
 | 6815 |           if (((T30_INFO   *)plci->NL.RBuffer->P)->code < sizeof(fax_info) / sizeof(fax_info[0])) | 
 | 6816 |             info = fax_info[((T30_INFO   *)plci->NL.RBuffer->P)->code]; | 
 | 6817 |           else | 
 | 6818 |             info = _FAX_PROTOCOL_ERROR; | 
 | 6819 |         } | 
 | 6820 |  | 
 | 6821 |         if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) | 
 | 6822 |           & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) | 
 | 6823 |         { | 
 | 6824 |           i = ((word)(((T30_INFO *) 0)->station_id + 20)) + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len; | 
 | 6825 |           while (i < plci->NL.RBuffer->length) | 
 | 6826 |             plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++]; | 
 | 6827 |         } | 
 | 6828 |  | 
 | 6829 |         plci->ncpi_buffer[0] = len; | 
 | 6830 |         fax_feature_bits = GET_WORD(&((T30_INFO   *)plci->NL.RBuffer->P)->feature_bits_low); | 
 | 6831 |         PUT_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->feature_bits_low, fax_feature_bits); | 
 | 6832 |  | 
 | 6833 |         plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND; | 
 | 6834 |  if (((plci->NL.Ind &0x0f) == N_CONNECT_ACK) | 
 | 6835 |          || (((plci->NL.Ind &0x0f) == N_CONNECT) | 
 | 6836 |           && (fax_feature_bits & T30_FEATURE_BIT_POLLING)) | 
 | 6837 |          || (((plci->NL.Ind &0x0f) == N_EDATA) | 
 | 6838 |           && ((((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_TRAIN_OK) | 
 | 6839 |            || (((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS) | 
 | 6840 |            || (((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_DTC)))) | 
 | 6841 |  { | 
 | 6842 |           plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT; | 
 | 6843 |  } | 
 | 6844 |  if (((plci->NL.Ind &0x0f) == N_DISC) | 
 | 6845 |   || ((plci->NL.Ind &0x0f) == N_DISC_ACK) | 
 | 6846 |   || (((plci->NL.Ind &0x0f) == N_EDATA) | 
 | 6847 |    && (((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_EOP_CAPI))) | 
 | 6848 |  { | 
 | 6849 |           plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND; | 
 | 6850 |  } | 
 | 6851 |       } | 
 | 6852 |       break; | 
 | 6853 |  | 
 | 6854 |     case B3_RTP: | 
 | 6855 |       if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) | 
 | 6856 |       { | 
 | 6857 |         if (plci->NL.RLength != 0) | 
 | 6858 |         { | 
 | 6859 |           info = rtp_info[plci->NL.RBuffer->P[0]]; | 
 | 6860 |           plci->ncpi_buffer[0] = plci->NL.RLength - 1; | 
 | 6861 |           for (i = 1; i < plci->NL.RLength; i++) | 
 | 6862 |             plci->ncpi_buffer[i] = plci->NL.RBuffer->P[i]; | 
 | 6863 |         } | 
 | 6864 |       } | 
 | 6865 |       break; | 
 | 6866 |  | 
 | 6867 |     } | 
 | 6868 |     plci->NL.RNR = 2; | 
 | 6869 |   } | 
 | 6870 |   switch(plci->NL.Ind &0x0f) { | 
 | 6871 |   case N_EDATA: | 
 | 6872 |     if ((plci->B3_prot == 4) || (plci->B3_prot == 5)) | 
 | 6873 |     { | 
 | 6874 |       dbug(1,dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci, a->ncci_state[ncci], | 
 | 6875 |         ((T30_INFO   *)plci->NL.RBuffer->P)->code)); | 
 | 6876 |       fax_send_edata_ack = (((T30_INFO   *)(plci->fax_connect_info_buffer))->operating_mode == T30_OPERATING_MODE_CAPI_NEG); | 
 | 6877 |  | 
 | 6878 |       if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) | 
 | 6879 |        && (plci->nsf_control_bits & (T30_NSF_CONTROL_BIT_NEGOTIATE_IND | T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) | 
 | 6880 |        && (((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS) | 
 | 6881 |        && (a->ncci_state[ncci] == OUTG_CON_PENDING) | 
 | 6882 |        && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) | 
 | 6883 |        && !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT)) | 
 | 6884 |       { | 
 | 6885 |         ((T30_INFO   *)(plci->fax_connect_info_buffer))->code = ((T30_INFO   *)plci->NL.RBuffer->P)->code; | 
 | 6886 |         sendf(plci->appl,_MANUFACTURER_I,Id,0,"dwbS",_DI_MANU_ID,_DI_NEGOTIATE_B3, | 
 | 6887 |           (byte)(plci->ncpi_buffer[0] + 1), plci->ncpi_buffer); | 
 | 6888 |         plci->ncpi_state |= NCPI_NEGOTIATE_B3_SENT; | 
 | 6889 |  if (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP) | 
 | 6890 |    fax_send_edata_ack = FALSE; | 
 | 6891 |       } | 
 | 6892 |  | 
 | 6893 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) | 
 | 6894 |       { | 
 | 6895 |         switch (((T30_INFO   *)plci->NL.RBuffer->P)->code) | 
 | 6896 |         { | 
 | 6897 |         case EDATA_T30_DIS: | 
 | 6898 |           if ((a->ncci_state[ncci] == OUTG_CON_PENDING) | 
 | 6899 |            && !(GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low) & T30_CONTROL_BIT_REQUEST_POLLING) | 
 | 6900 |            && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) | 
 | 6901 |            && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) | 
 | 6902 |           { | 
 | 6903 |             a->ncci_state[ncci] = INC_ACT_PENDING; | 
 | 6904 |             if (plci->B3_prot == 4) | 
 | 6905 |               sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); | 
 | 6906 |             else | 
 | 6907 |               sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); | 
 | 6908 |             plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; | 
 | 6909 |           } | 
 | 6910 |           break; | 
 | 6911 |  | 
 | 6912 |         case EDATA_T30_TRAIN_OK: | 
 | 6913 |           if ((a->ncci_state[ncci] == INC_ACT_PENDING) | 
 | 6914 |            && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) | 
 | 6915 |            && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) | 
 | 6916 |           { | 
 | 6917 |             if (plci->B3_prot == 4) | 
 | 6918 |               sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); | 
 | 6919 |             else | 
 | 6920 |               sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); | 
 | 6921 |             plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; | 
 | 6922 |           } | 
 | 6923 |           break; | 
 | 6924 |  | 
 | 6925 |         case EDATA_T30_EOP_CAPI: | 
 | 6926 |           if (a->ncci_state[ncci] == CONNECTED) | 
 | 6927 |           { | 
 | 6928 |             sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",GOOD,plci->ncpi_buffer); | 
 | 6929 |             a->ncci_state[ncci] = INC_DIS_PENDING; | 
 | 6930 |             plci->ncpi_state = 0; | 
 | 6931 |      fax_send_edata_ack = FALSE; | 
 | 6932 |           } | 
 | 6933 |           break; | 
 | 6934 |         } | 
 | 6935 |       } | 
 | 6936 |       else | 
 | 6937 |       { | 
 | 6938 |         switch (((T30_INFO   *)plci->NL.RBuffer->P)->code) | 
 | 6939 |         { | 
 | 6940 |         case EDATA_T30_TRAIN_OK: | 
 | 6941 |           if ((a->ncci_state[ncci] == INC_ACT_PENDING) | 
 | 6942 |            && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) | 
 | 6943 |            && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) | 
 | 6944 |           { | 
 | 6945 |             if (plci->B3_prot == 4) | 
 | 6946 |               sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); | 
 | 6947 |             else | 
 | 6948 |               sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); | 
 | 6949 |             plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; | 
 | 6950 |           } | 
 | 6951 |           break; | 
 | 6952 |         } | 
 | 6953 |       } | 
 | 6954 |       if (fax_send_edata_ack) | 
 | 6955 |       { | 
 | 6956 |         ((T30_INFO   *)(plci->fax_connect_info_buffer))->code = ((T30_INFO   *)plci->NL.RBuffer->P)->code; | 
 | 6957 |  plci->fax_edata_ack_length = 1; | 
 | 6958 |         start_internal_command (Id, plci, fax_edata_ack_command); | 
 | 6959 |       } | 
 | 6960 |     } | 
 | 6961 |     else | 
 | 6962 |     { | 
 | 6963 |       dbug(1,dprintf("EDATA ncci=0x%x state=%d", ncci, a->ncci_state[ncci])); | 
 | 6964 |     } | 
 | 6965 |     break; | 
 | 6966 |   case N_CONNECT: | 
 | 6967 |     if (!a->ch_ncci[ch]) | 
 | 6968 |     { | 
 | 6969 |       ncci = get_ncci (plci, ch, 0); | 
 | 6970 |       Id = (Id & 0xffff) | (((dword) ncci) << 16); | 
 | 6971 |     } | 
 | 6972 |     dbug(1,dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d", | 
 | 6973 |       ch, a->ncci_state[ncci], a->ncci_plci[ncci], plci->Id, plci->State)); | 
 | 6974 |  | 
 | 6975 |     msg = _CONNECT_B3_I; | 
 | 6976 |     if (a->ncci_state[ncci] == IDLE) | 
 | 6977 |       plci->channels++; | 
 | 6978 |     else if (plci->B3_prot == 1) | 
 | 6979 |       msg = _CONNECT_B3_T90_ACTIVE_I; | 
 | 6980 |  | 
 | 6981 |     a->ncci_state[ncci] = INC_CON_PENDING; | 
 | 6982 |     if(plci->B3_prot == 4) | 
 | 6983 |       sendf(plci->appl,msg,Id,0,"s",""); | 
 | 6984 |     else | 
 | 6985 |       sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer); | 
 | 6986 |     break; | 
 | 6987 |   case N_CONNECT_ACK: | 
 | 6988 |     dbug(1,dprintf("N_connect_Ack")); | 
 | 6989 |     if (plci->internal_command_queue[0] | 
 | 6990 |      && ((plci->adjust_b_state == ADJUST_B_CONNECT_2) | 
 | 6991 |       || (plci->adjust_b_state == ADJUST_B_CONNECT_3) | 
 | 6992 |       || (plci->adjust_b_state == ADJUST_B_CONNECT_4))) | 
 | 6993 |     { | 
 | 6994 |       (*(plci->internal_command_queue[0]))(Id, plci, 0); | 
 | 6995 |       if (!plci->internal_command) | 
 | 6996 |         next_internal_command (Id, plci); | 
 | 6997 |       break; | 
 | 6998 |     } | 
 | 6999 |     msg = _CONNECT_B3_ACTIVE_I; | 
 | 7000 |     if (plci->B3_prot == 1) | 
 | 7001 |     { | 
 | 7002 |       if (a->ncci_state[ncci] != OUTG_CON_PENDING) | 
 | 7003 |         msg = _CONNECT_B3_T90_ACTIVE_I; | 
 | 7004 |       a->ncci_state[ncci] = INC_ACT_PENDING; | 
 | 7005 |       sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer); | 
 | 7006 |     } | 
 | 7007 |     else if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7)) | 
 | 7008 |     { | 
 | 7009 |       if ((a->ncci_state[ncci] == OUTG_CON_PENDING) | 
 | 7010 |        && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) | 
 | 7011 |        && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) | 
 | 7012 |       { | 
 | 7013 |         a->ncci_state[ncci] = INC_ACT_PENDING; | 
 | 7014 |         if (plci->B3_prot == 4) | 
 | 7015 |           sendf(plci->appl,msg,Id,0,"s",""); | 
 | 7016 |         else | 
 | 7017 |           sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer); | 
 | 7018 |         plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; | 
 | 7019 |       } | 
 | 7020 |     } | 
 | 7021 |     else | 
 | 7022 |     { | 
 | 7023 |       a->ncci_state[ncci] = INC_ACT_PENDING; | 
 | 7024 |       sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer); | 
 | 7025 |     } | 
 | 7026 |     if (plci->adjust_b_restore) | 
 | 7027 |     { | 
 | 7028 |       plci->adjust_b_restore = FALSE; | 
 | 7029 |       start_internal_command (Id, plci, adjust_b_restore); | 
 | 7030 |     } | 
 | 7031 |     break; | 
 | 7032 |   case N_DISC: | 
 | 7033 |   case N_DISC_ACK: | 
 | 7034 |     if (plci->internal_command_queue[0] | 
 | 7035 |      && ((plci->internal_command == FAX_DISCONNECT_COMMAND_1) | 
 | 7036 |       || (plci->internal_command == FAX_DISCONNECT_COMMAND_2) | 
 | 7037 |       || (plci->internal_command == FAX_DISCONNECT_COMMAND_3))) | 
 | 7038 |     { | 
 | 7039 |       (*(plci->internal_command_queue[0]))(Id, plci, 0); | 
 | 7040 |       if (!plci->internal_command) | 
 | 7041 |         next_internal_command (Id, plci); | 
 | 7042 |     } | 
 | 7043 |     ncci_state = a->ncci_state[ncci]; | 
 | 7044 |     ncci_remove (plci, ncci, FALSE); | 
 | 7045 |  | 
 | 7046 |         /* with N_DISC or N_DISC_ACK the IDI frees the respective   */ | 
 | 7047 |         /* channel, so we cannot store the state in ncci_state! The */ | 
 | 7048 |         /* information which channel we received a N_DISC is thus   */ | 
 | 7049 |         /* stored in the inc_dis_ncci_table buffer.                 */ | 
 | 7050 |     for(i=0; plci->inc_dis_ncci_table[i]; i++); | 
 | 7051 |     plci->inc_dis_ncci_table[i] = (byte) ncci; | 
 | 7052 |  | 
 | 7053 |       /* need a connect_b3_ind before a disconnect_b3_ind with FAX */ | 
 | 7054 |     if (!plci->channels | 
 | 7055 |      && (plci->B1_resource == 16) | 
 | 7056 |      && (plci->State <= CONNECTED)) | 
 | 7057 |     { | 
 | 7058 |       len = 9; | 
 | 7059 |       i = ((T30_INFO   *)plci->fax_connect_info_buffer)->rate_div_2400 * 2400; | 
 | 7060 |       PUT_WORD (&plci->ncpi_buffer[1], i); | 
 | 7061 |       PUT_WORD (&plci->ncpi_buffer[3], 0); | 
 | 7062 |       i = ((T30_INFO   *)plci->fax_connect_info_buffer)->data_format; | 
 | 7063 |       PUT_WORD (&plci->ncpi_buffer[5], i); | 
 | 7064 |       PUT_WORD (&plci->ncpi_buffer[7], 0); | 
 | 7065 |       plci->ncpi_buffer[len] = 0; | 
 | 7066 |       plci->ncpi_buffer[0] = len; | 
 | 7067 |       if(plci->B3_prot == 4) | 
 | 7068 |         sendf(plci->appl,_CONNECT_B3_I,Id,0,"s",""); | 
 | 7069 |       else | 
 | 7070 |       { | 
 | 7071 |  | 
 | 7072 |         if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) | 
 | 7073 |           & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) | 
 | 7074 |         { | 
 | 7075 |           plci->ncpi_buffer[++len] = 0; | 
 | 7076 |           plci->ncpi_buffer[++len] = 0; | 
 | 7077 |           plci->ncpi_buffer[++len] = 0; | 
 | 7078 |           plci->ncpi_buffer[0] = len; | 
 | 7079 |         } | 
 | 7080 |  | 
 | 7081 |         sendf(plci->appl,_CONNECT_B3_I,Id,0,"S",plci->ncpi_buffer); | 
 | 7082 |       } | 
 | 7083 |       sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",info,plci->ncpi_buffer); | 
 | 7084 |       plci->ncpi_state = 0; | 
 | 7085 |       sig_req(plci,HANGUP,0); | 
 | 7086 |       send_req(plci); | 
 | 7087 |       plci->State = OUTG_DIS_PENDING; | 
 | 7088 |       /* disc here */ | 
 | 7089 |     } | 
 | 7090 |     else if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) | 
 | 7091 |      && ((plci->B3_prot == 4) || (plci->B3_prot == 5)) | 
 | 7092 |      && ((ncci_state == INC_DIS_PENDING) || (ncci_state == IDLE))) | 
 | 7093 |     { | 
 | 7094 |       if (ncci_state == IDLE) | 
 | 7095 |       { | 
 | 7096 |         if (plci->channels) | 
 | 7097 |           plci->channels--; | 
 | 7098 |         if((plci->State==IDLE || plci->State==SUSPENDING) && !plci->channels){ | 
 | 7099 |           if(plci->State == SUSPENDING){ | 
 | 7100 |             sendf(plci->appl, | 
 | 7101 |                   _FACILITY_I, | 
 | 7102 |                   Id & 0xffffL, | 
 | 7103 |                   0, | 
 | 7104 |                   "ws", (word)3, "\x03\x04\x00\x00"); | 
 | 7105 |             sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0); | 
 | 7106 |           } | 
 | 7107 |           plci_remove(plci); | 
 | 7108 |           plci->State=IDLE; | 
 | 7109 |         } | 
 | 7110 |       } | 
 | 7111 |     } | 
 | 7112 |     else if (plci->channels) | 
 | 7113 |     { | 
 | 7114 |       sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",info,plci->ncpi_buffer); | 
 | 7115 |       plci->ncpi_state = 0; | 
 | 7116 |       if ((ncci_state == OUTG_REJ_PENDING) | 
 | 7117 |        && ((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))) | 
 | 7118 |       { | 
 | 7119 |         sig_req(plci,HANGUP,0); | 
 | 7120 |         send_req(plci); | 
 | 7121 |         plci->State = OUTG_DIS_PENDING; | 
 | 7122 |       } | 
 | 7123 |     } | 
 | 7124 |     break; | 
 | 7125 |   case N_RESET: | 
 | 7126 |     a->ncci_state[ncci] = INC_RES_PENDING; | 
 | 7127 |     sendf(plci->appl,_RESET_B3_I,Id,0,"S",plci->ncpi_buffer); | 
 | 7128 |     break; | 
 | 7129 |   case N_RESET_ACK: | 
 | 7130 |     a->ncci_state[ncci] = CONNECTED; | 
 | 7131 |     sendf(plci->appl,_RESET_B3_I,Id,0,"S",plci->ncpi_buffer); | 
 | 7132 |     break; | 
 | 7133 |  | 
 | 7134 |   case N_UDATA: | 
 | 7135 |     if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f)))) | 
 | 7136 |     { | 
 | 7137 |       plci->RData[0].P = plci->internal_ind_buffer + (-((int)(plci->internal_ind_buffer)) & 3); | 
 | 7138 |       plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE; | 
 | 7139 |       plci->NL.R = plci->RData; | 
 | 7140 |       plci->NL.RNum = 1; | 
 | 7141 |       return; | 
 | 7142 |     } | 
 | 7143 |   case N_BDATA: | 
 | 7144 |   case N_DATA: | 
 | 7145 |     if (((a->ncci_state[ncci] != CONNECTED) && (plci->B2_prot == 1)) /* transparent */ | 
 | 7146 |      || (a->ncci_state[ncci] == IDLE) | 
 | 7147 |      || (a->ncci_state[ncci] == INC_DIS_PENDING)) | 
 | 7148 |     { | 
 | 7149 |       plci->NL.RNR = 2; | 
 | 7150 |       break; | 
 | 7151 |     } | 
 | 7152 |     if ((a->ncci_state[ncci] != CONNECTED) | 
 | 7153 |      && (a->ncci_state[ncci] != OUTG_DIS_PENDING) | 
 | 7154 |      && (a->ncci_state[ncci] != OUTG_REJ_PENDING)) | 
 | 7155 |     { | 
 | 7156 |       dbug(1,dprintf("flow control")); | 
 | 7157 |       plci->NL.RNR = 1; /* flow control  */ | 
 | 7158 |       channel_x_off (plci, ch, 0); | 
 | 7159 |       break; | 
 | 7160 |     } | 
 | 7161 |  | 
 | 7162 |     NCCIcode = ncci | (((word)a->Id) << 8); | 
 | 7163 |  | 
 | 7164 |                 /* count all buffers within the Application pool    */ | 
 | 7165 |                 /* belonging to the same NCCI. If this is below the */ | 
 | 7166 |                 /* number of buffers available per NCCI we accept   */ | 
 | 7167 |                 /* this packet, otherwise we reject it              */ | 
 | 7168 |     count = 0; | 
 | 7169 |     Num = 0xffff; | 
 | 7170 |     for(i=0; i<APPLptr->MaxBuffer; i++) { | 
 | 7171 |       if(NCCIcode==APPLptr->DataNCCI[i]) count++; | 
 | 7172 |       if(!APPLptr->DataNCCI[i] && Num==0xffff) Num = i; | 
 | 7173 |     } | 
 | 7174 |  | 
 | 7175 |     if(count>=APPLptr->MaxNCCIData || Num==0xffff) | 
 | 7176 |     { | 
 | 7177 |       dbug(3,dprintf("Flow-Control")); | 
 | 7178 |       plci->NL.RNR = 1; | 
 | 7179 |       if( ++(APPLptr->NCCIDataFlowCtrlTimer)>= | 
 | 7180 |        (word)((a->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) ? 40 : 2000)) | 
 | 7181 |       { | 
 | 7182 |         plci->NL.RNR = 2; | 
 | 7183 |         dbug(3,dprintf("DiscardData")); | 
 | 7184 |       } else { | 
 | 7185 |         channel_x_off (plci, ch, 0); | 
 | 7186 |       } | 
 | 7187 |       break; | 
 | 7188 |     } | 
 | 7189 |     else | 
 | 7190 |     { | 
 | 7191 |       APPLptr->NCCIDataFlowCtrlTimer = 0; | 
 | 7192 |     } | 
 | 7193 |  | 
 | 7194 |     plci->RData[0].P = ReceiveBufferGet(APPLptr,Num); | 
 | 7195 |     if(!plci->RData[0].P) { | 
 | 7196 |       plci->NL.RNR = 1; | 
 | 7197 |       channel_x_off (plci, ch, 0); | 
 | 7198 |       break; | 
 | 7199 |     } | 
 | 7200 |  | 
 | 7201 |     APPLptr->DataNCCI[Num] = NCCIcode; | 
 | 7202 |     APPLptr->DataFlags[Num] = (plci->Id<<8) | (plci->NL.Ind>>4); | 
 | 7203 |     dbug(3,dprintf("Buffer(%d), Max = %d",Num,APPLptr->MaxBuffer)); | 
 | 7204 |  | 
 | 7205 |     plci->RNum = Num; | 
 | 7206 |     plci->RFlags = plci->NL.Ind>>4; | 
 | 7207 |     plci->RData[0].PLength = APPLptr->MaxDataLength; | 
 | 7208 |     plci->NL.R = plci->RData; | 
 | 7209 |     if ((plci->NL.RLength != 0) | 
 | 7210 |      && ((plci->B2_prot == B2_V120_ASYNC) | 
 | 7211 |       || (plci->B2_prot == B2_V120_ASYNC_V42BIS) | 
 | 7212 |       || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))) | 
 | 7213 |     { | 
 | 7214 |       plci->RData[1].P = plci->RData[0].P; | 
 | 7215 |       plci->RData[1].PLength = plci->RData[0].PLength; | 
 | 7216 |       plci->RData[0].P = v120_header_buffer + (-((int) v120_header_buffer) & 3); | 
 | 7217 |       if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1)) | 
 | 7218 |         plci->RData[0].PLength = 1; | 
 | 7219 |       else | 
 | 7220 |         plci->RData[0].PLength = 2; | 
 | 7221 |       if (plci->NL.RBuffer->P[0] & V120_HEADER_BREAK_BIT) | 
 | 7222 |         plci->RFlags |= 0x0010; | 
 | 7223 |       if (plci->NL.RBuffer->P[0] & (V120_HEADER_C1_BIT | V120_HEADER_C2_BIT)) | 
 | 7224 |         plci->RFlags |= 0x8000; | 
 | 7225 |       plci->NL.RNum = 2; | 
 | 7226 |     } | 
 | 7227 |     else | 
 | 7228 |     { | 
 | 7229 |       if((plci->NL.Ind &0x0f)==N_UDATA) | 
 | 7230 |         plci->RFlags |= 0x0010; | 
 | 7231 |  | 
 | 7232 |       else if ((plci->B3_prot == B3_RTP) && ((plci->NL.Ind & 0x0f) == N_BDATA)) | 
 | 7233 |         plci->RFlags |= 0x0001; | 
 | 7234 |  | 
 | 7235 |       plci->NL.RNum = 1; | 
 | 7236 |     } | 
 | 7237 |     break; | 
 | 7238 |   case N_DATA_ACK: | 
 | 7239 |     data_ack (plci, ch); | 
 | 7240 |     break; | 
 | 7241 |   default: | 
 | 7242 |     plci->NL.RNR = 2; | 
 | 7243 |     break; | 
 | 7244 |   } | 
 | 7245 | } | 
 | 7246 |  | 
 | 7247 | /*------------------------------------------------------------------*/ | 
 | 7248 | /* find a free PLCI                                                 */ | 
 | 7249 | /*------------------------------------------------------------------*/ | 
 | 7250 |  | 
 | 7251 | word get_plci(DIVA_CAPI_ADAPTER   * a) | 
 | 7252 | { | 
 | 7253 |   word i,j; | 
 | 7254 |   PLCI   * plci; | 
 | 7255 |  | 
 | 7256 |   dump_plcis (a); | 
 | 7257 |   for(i=0;i<a->max_plci && a->plci[i].Id;i++); | 
 | 7258 |   if(i==a->max_plci) { | 
 | 7259 |     dbug(1,dprintf("get_plci: out of PLCIs")); | 
 | 7260 |     return 0; | 
 | 7261 |   } | 
 | 7262 |   plci = &a->plci[i]; | 
 | 7263 |   plci->Id = (byte)(i+1); | 
 | 7264 |  | 
 | 7265 |   plci->Sig.Id = 0; | 
 | 7266 |   plci->NL.Id = 0; | 
 | 7267 |   plci->sig_req = 0; | 
 | 7268 |   plci->nl_req = 0; | 
 | 7269 |  | 
 | 7270 |   plci->appl = NULL; | 
 | 7271 |   plci->relatedPTYPLCI = NULL; | 
 | 7272 |   plci->State = IDLE; | 
 | 7273 |   plci->SuppState = IDLE; | 
 | 7274 |   plci->channels = 0; | 
 | 7275 |   plci->tel = 0; | 
 | 7276 |   plci->B1_resource = 0; | 
 | 7277 |   plci->B2_prot = 0; | 
 | 7278 |   plci->B3_prot = 0; | 
 | 7279 |  | 
 | 7280 |   plci->command = 0; | 
 | 7281 |   plci->m_command = 0; | 
 | 7282 |   init_internal_command_queue (plci); | 
 | 7283 |   plci->number = 0; | 
 | 7284 |   plci->req_in_start = 0; | 
 | 7285 |   plci->req_in = 0; | 
 | 7286 |   plci->req_out = 0; | 
 | 7287 |   plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; | 
 | 7288 |   plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; | 
 | 7289 |   plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; | 
 | 7290 |  | 
 | 7291 |   plci->data_sent = FALSE; | 
 | 7292 |   plci->send_disc = 0; | 
 | 7293 |   plci->sig_global_req = 0; | 
 | 7294 |   plci->sig_remove_id = 0; | 
 | 7295 |   plci->nl_global_req = 0; | 
 | 7296 |   plci->nl_remove_id = 0; | 
 | 7297 |   plci->adv_nl = 0; | 
 | 7298 |   plci->manufacturer = FALSE; | 
 | 7299 |   plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; | 
 | 7300 |   plci->spoofed_msg = 0; | 
 | 7301 |   plci->ptyState = 0; | 
 | 7302 |   plci->cr_enquiry = FALSE; | 
 | 7303 |   plci->hangup_flow_ctrl_timer = 0; | 
 | 7304 |  | 
 | 7305 |   plci->ncci_ring_list = 0; | 
 | 7306 |   for(j=0;j<MAX_CHANNELS_PER_PLCI;j++) plci->inc_dis_ncci_table[j] = 0; | 
 | 7307 |   clear_c_ind_mask (plci); | 
 | 7308 |   set_group_ind_mask (plci); | 
 | 7309 |   plci->fax_connect_info_length = 0; | 
 | 7310 |   plci->nsf_control_bits = 0; | 
 | 7311 |   plci->ncpi_state = 0x00; | 
 | 7312 |   plci->ncpi_buffer[0] = 0; | 
 | 7313 |  | 
 | 7314 |   plci->requested_options_conn = 0; | 
 | 7315 |   plci->requested_options = 0; | 
 | 7316 |   plci->notifiedcall = 0; | 
 | 7317 |   plci->vswitchstate = 0; | 
 | 7318 |   plci->vsprot = 0; | 
 | 7319 |   plci->vsprotdialect = 0; | 
 | 7320 |   init_b1_config (plci); | 
 | 7321 |   dbug(1,dprintf("get_plci(%x)",plci->Id)); | 
 | 7322 |   return i+1; | 
 | 7323 | } | 
 | 7324 |  | 
 | 7325 | /*------------------------------------------------------------------*/ | 
 | 7326 | /* put a parameter in the parameter buffer                          */ | 
 | 7327 | /*------------------------------------------------------------------*/ | 
 | 7328 |  | 
 | 7329 | static void add_p(PLCI   * plci, byte code, byte   * p) | 
 | 7330 | { | 
 | 7331 |   word p_length; | 
 | 7332 |  | 
 | 7333 |   p_length = 0; | 
 | 7334 |   if(p) p_length = p[0]; | 
 | 7335 |   add_ie(plci, code, p, p_length); | 
 | 7336 | } | 
 | 7337 |  | 
 | 7338 | /*------------------------------------------------------------------*/ | 
 | 7339 | /* put a structure in the parameter buffer                          */ | 
 | 7340 | /*------------------------------------------------------------------*/ | 
 | 7341 | static void add_s(PLCI   * plci, byte code, API_PARSE * p) | 
 | 7342 | { | 
 | 7343 |   if(p) add_ie(plci, code, p->info, (word)p->length); | 
 | 7344 | } | 
 | 7345 |  | 
 | 7346 | /*------------------------------------------------------------------*/ | 
 | 7347 | /* put multiple structures in the parameter buffer                  */ | 
 | 7348 | /*------------------------------------------------------------------*/ | 
 | 7349 | static void add_ss(PLCI   * plci, byte code, API_PARSE * p) | 
 | 7350 | { | 
 | 7351 |   byte i; | 
 | 7352 |  | 
 | 7353 |   if(p){ | 
 | 7354 |     dbug(1,dprintf("add_ss(%x,len=%d)",code,p->length)); | 
 | 7355 |     for(i=2;i<(byte)p->length;i+=p->info[i]+2){ | 
 | 7356 |       dbug(1,dprintf("add_ss_ie(%x,len=%d)",p->info[i-1],p->info[i])); | 
 | 7357 |       add_ie(plci, p->info[i-1], (byte   *)&(p->info[i]), (word)p->info[i]); | 
 | 7358 |     } | 
 | 7359 |   } | 
 | 7360 | } | 
 | 7361 |  | 
 | 7362 | /*------------------------------------------------------------------*/ | 
 | 7363 | /* return the channel number sent by the application in a esc_chi   */ | 
 | 7364 | /*------------------------------------------------------------------*/ | 
 | 7365 | static byte getChannel(API_PARSE * p) | 
 | 7366 | { | 
 | 7367 |   byte i; | 
 | 7368 |  | 
 | 7369 |   if(p){ | 
 | 7370 |     for(i=2;i<(byte)p->length;i+=p->info[i]+2){ | 
 | 7371 |       if(p->info[i]==2){ | 
 | 7372 |         if(p->info[i-1]==ESC && p->info[i+1]==CHI) return (p->info[i+2]); | 
 | 7373 |       } | 
 | 7374 |     } | 
 | 7375 |   } | 
 | 7376 |   return 0; | 
 | 7377 | } | 
 | 7378 |  | 
 | 7379 |  | 
 | 7380 | /*------------------------------------------------------------------*/ | 
 | 7381 | /* put an information element in the parameter buffer               */ | 
 | 7382 | /*------------------------------------------------------------------*/ | 
 | 7383 |  | 
 | 7384 | static void add_ie(PLCI   * plci, byte code, byte   * p, word p_length) | 
 | 7385 | { | 
 | 7386 |   word i; | 
 | 7387 |  | 
 | 7388 |   if(!(code &0x80) && !p_length) return; | 
 | 7389 |  | 
 | 7390 |   if(plci->req_in==plci->req_in_start) { | 
 | 7391 |     plci->req_in +=2; | 
 | 7392 |   } | 
 | 7393 |   else { | 
 | 7394 |     plci->req_in--; | 
 | 7395 |   } | 
 | 7396 |   plci->RBuffer[plci->req_in++] = code; | 
 | 7397 |  | 
 | 7398 |   if(p) { | 
 | 7399 |     plci->RBuffer[plci->req_in++] = (byte)p_length; | 
 | 7400 |     for(i=0;i<p_length;i++) plci->RBuffer[plci->req_in++] = p[1+i]; | 
 | 7401 |   } | 
 | 7402 |  | 
 | 7403 |   plci->RBuffer[plci->req_in++] = 0; | 
 | 7404 | } | 
 | 7405 |  | 
 | 7406 | /*------------------------------------------------------------------*/ | 
 | 7407 | /* put a unstructured data into the buffer                          */ | 
 | 7408 | /*------------------------------------------------------------------*/ | 
 | 7409 |  | 
 | 7410 | void add_d(PLCI   * plci, word length, byte   * p) | 
 | 7411 | { | 
 | 7412 |   word i; | 
 | 7413 |  | 
 | 7414 |   if(plci->req_in==plci->req_in_start) { | 
 | 7415 |     plci->req_in +=2; | 
 | 7416 |   } | 
 | 7417 |   else { | 
 | 7418 |     plci->req_in--; | 
 | 7419 |   } | 
 | 7420 |   for(i=0;i<length;i++) plci->RBuffer[plci->req_in++] = p[i]; | 
 | 7421 | } | 
 | 7422 |  | 
 | 7423 | /*------------------------------------------------------------------*/ | 
 | 7424 | /* put parameters from the Additional Info parameter in the         */ | 
 | 7425 | /* parameter buffer                                                 */ | 
 | 7426 | /*------------------------------------------------------------------*/ | 
 | 7427 |  | 
 | 7428 | void add_ai(PLCI   * plci, API_PARSE * ai) | 
 | 7429 | { | 
 | 7430 |   word i; | 
 | 7431 |     API_PARSE ai_parms[5]; | 
 | 7432 |  | 
 | 7433 |   for(i=0;i<5;i++) ai_parms[i].length = 0; | 
 | 7434 |  | 
 | 7435 |   if(!ai->length) | 
 | 7436 |     return; | 
 | 7437 |   if(api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms)) | 
 | 7438 |     return; | 
 | 7439 |  | 
 | 7440 |   add_s (plci,KEY,&ai_parms[1]); | 
 | 7441 |   add_s (plci,UUI,&ai_parms[2]); | 
 | 7442 |   add_ss(plci,FTY,&ai_parms[3]); | 
 | 7443 | } | 
 | 7444 |  | 
 | 7445 | /*------------------------------------------------------------------*/ | 
 | 7446 | /* put parameter for b1 protocol in the parameter buffer            */ | 
 | 7447 | /*------------------------------------------------------------------*/ | 
 | 7448 |  | 
 | 7449 | word add_b1(PLCI   * plci, API_PARSE * bp, word b_channel_info, word b1_facilities) | 
 | 7450 | { | 
 | 7451 |     API_PARSE bp_parms[8]; | 
 | 7452 |     API_PARSE mdm_cfg[9]; | 
 | 7453 |     API_PARSE global_config[2]; | 
 | 7454 |     byte cai[256]; | 
 | 7455 |   byte resource[] = {5,9,13,12,16,39,9,17,17,18}; | 
 | 7456 |   byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08"; | 
 | 7457 |   word i; | 
 | 7458 |  | 
 | 7459 |     API_PARSE mdm_cfg_v18[4]; | 
 | 7460 |   word j, n, w; | 
 | 7461 |   dword d; | 
 | 7462 |  | 
 | 7463 |  | 
 | 7464 |   for(i=0;i<8;i++) bp_parms[i].length = 0; | 
 | 7465 |   for(i=0;i<2;i++) global_config[i].length = 0; | 
 | 7466 |  | 
 | 7467 |   dbug(1,dprintf("add_b1")); | 
 | 7468 |   api_save_msg(bp, "s", &plci->B_protocol); | 
 | 7469 |  | 
 | 7470 |   if(b_channel_info==2){ | 
 | 7471 |     plci->B1_resource = 0; | 
 | 7472 |     adjust_b1_facilities (plci, plci->B1_resource, b1_facilities); | 
 | 7473 |     add_p(plci, CAI, "\x01\x00"); | 
 | 7474 |     dbug(1,dprintf("Cai=1,0 (no resource)")); | 
 | 7475 |     return 0; | 
 | 7476 |   } | 
 | 7477 |  | 
 | 7478 |   if(plci->tel == CODEC_PERMANENT) return 0; | 
 | 7479 |   else if(plci->tel == CODEC){ | 
 | 7480 |     plci->B1_resource = 1; | 
 | 7481 |     adjust_b1_facilities (plci, plci->B1_resource, b1_facilities); | 
 | 7482 |     add_p(plci, CAI, "\x01\x01"); | 
 | 7483 |     dbug(1,dprintf("Cai=1,1 (Codec)")); | 
 | 7484 |     return 0; | 
 | 7485 |   } | 
 | 7486 |   else if(plci->tel == ADV_VOICE){ | 
 | 7487 |     plci->B1_resource = add_b1_facilities (plci, 9, (word)(b1_facilities | B1_FACILITY_VOICE)); | 
 | 7488 |     adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities | B1_FACILITY_VOICE)); | 
 | 7489 |     voice_cai[1] = plci->B1_resource; | 
 | 7490 |     PUT_WORD (&voice_cai[5], plci->appl->MaxDataLength); | 
 | 7491 |     add_p(plci, CAI, voice_cai); | 
 | 7492 |     dbug(1,dprintf("Cai=1,0x%x (AdvVoice)",voice_cai[1])); | 
 | 7493 |     return 0; | 
 | 7494 |   } | 
 | 7495 |   plci->call_dir &= ~(CALL_DIR_ORIGINATE | CALL_DIR_ANSWER); | 
 | 7496 |   if (plci->call_dir & CALL_DIR_OUT) | 
 | 7497 |     plci->call_dir |= CALL_DIR_ORIGINATE; | 
 | 7498 |   else if (plci->call_dir & CALL_DIR_IN) | 
 | 7499 |     plci->call_dir |= CALL_DIR_ANSWER; | 
 | 7500 |  | 
 | 7501 |   if(!bp->length){ | 
 | 7502 |     plci->B1_resource = 0x5; | 
 | 7503 |     adjust_b1_facilities (plci, plci->B1_resource, b1_facilities); | 
 | 7504 |     add_p(plci, CAI, "\x01\x05"); | 
 | 7505 |     return 0; | 
 | 7506 |   } | 
 | 7507 |  | 
 | 7508 |   dbug(1,dprintf("b_prot_len=%d",(word)bp->length)); | 
 | 7509 |   if(bp->length>256) return _WRONG_MESSAGE_FORMAT; | 
 | 7510 |   if(api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms)) | 
 | 7511 |   { | 
 | 7512 |     bp_parms[6].length = 0; | 
 | 7513 |     if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms)) | 
 | 7514 |     { | 
 | 7515 |       dbug(1,dprintf("b-form.!")); | 
 | 7516 |       return _WRONG_MESSAGE_FORMAT; | 
 | 7517 |     } | 
 | 7518 |   } | 
 | 7519 |   else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms)) | 
 | 7520 |   { | 
 | 7521 |     dbug(1,dprintf("b-form.!")); | 
 | 7522 |     return _WRONG_MESSAGE_FORMAT; | 
 | 7523 |   } | 
 | 7524 |  | 
 | 7525 |   if(bp_parms[6].length) | 
 | 7526 |   { | 
 | 7527 |     if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config)) | 
 | 7528 |     { | 
 | 7529 |       return _WRONG_MESSAGE_FORMAT; | 
 | 7530 |     } | 
 | 7531 |     switch(GET_WORD(global_config[0].info)) | 
 | 7532 |     { | 
 | 7533 |     case 1: | 
 | 7534 |       plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE; | 
 | 7535 |       break; | 
 | 7536 |     case 2: | 
 | 7537 |       plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER; | 
 | 7538 |       break; | 
 | 7539 |     } | 
 | 7540 |   } | 
 | 7541 |   dbug(1,dprintf("call_dir=%04x", plci->call_dir)); | 
 | 7542 |  | 
 | 7543 |  | 
 | 7544 |   if ((GET_WORD(bp_parms[0].info) == B1_RTP) | 
 | 7545 |    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP))) | 
 | 7546 |   { | 
 | 7547 |     plci->B1_resource = add_b1_facilities (plci, 31, (word)(b1_facilities & ~B1_FACILITY_VOICE)); | 
 | 7548 |     adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); | 
 | 7549 |     cai[1] = plci->B1_resource; | 
 | 7550 |     cai[2] = 0; | 
 | 7551 |     cai[3] = 0; | 
 | 7552 |     cai[4] = 0; | 
 | 7553 |     PUT_WORD(&cai[5],plci->appl->MaxDataLength); | 
 | 7554 |     for (i = 0; i < bp_parms[3].length; i++) | 
 | 7555 |       cai[7+i] = bp_parms[3].info[1+i]; | 
 | 7556 |     cai[0] = 6 + bp_parms[3].length; | 
 | 7557 |     add_p(plci, CAI, cai); | 
 | 7558 |     return 0; | 
 | 7559 |   } | 
 | 7560 |  | 
 | 7561 |  | 
 | 7562 |   if ((GET_WORD(bp_parms[0].info) == B1_PIAFS) | 
 | 7563 |    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS))) | 
 | 7564 |   { | 
 | 7565 |     plci->B1_resource = add_b1_facilities (plci, 35/* PIAFS HARDWARE FACILITY */, (word)(b1_facilities & ~B1_FACILITY_VOICE)); | 
 | 7566 |     adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); | 
 | 7567 |     cai[1] = plci->B1_resource; | 
 | 7568 |     cai[2] = 0; | 
 | 7569 |     cai[3] = 0; | 
 | 7570 |     cai[4] = 0; | 
 | 7571 |     PUT_WORD(&cai[5],plci->appl->MaxDataLength); | 
 | 7572 |     cai[0] = 6; | 
 | 7573 |     add_p(plci, CAI, cai); | 
 | 7574 |     return 0; | 
 | 7575 |   } | 
 | 7576 |  | 
 | 7577 |  | 
 | 7578 |   if ((GET_WORD(bp_parms[0].info) >= 32) | 
 | 7579 |    || (!((1L << GET_WORD(bp_parms[0].info)) & plci->adapter->profile.B1_Protocols) | 
 | 7580 |     && ((GET_WORD(bp_parms[0].info) != 3) | 
 | 7581 |      || !((1L << B1_HDLC) & plci->adapter->profile.B1_Protocols) | 
 | 7582 |      || ((bp_parms[3].length != 0) && (GET_WORD(&bp_parms[3].info[1]) != 0) && (GET_WORD(&bp_parms[3].info[1]) != 56000))))) | 
 | 7583 |   { | 
 | 7584 |     return _B1_NOT_SUPPORTED; | 
 | 7585 |   } | 
 | 7586 |   plci->B1_resource = add_b1_facilities (plci, resource[GET_WORD(bp_parms[0].info)], | 
 | 7587 |     (word)(b1_facilities & ~B1_FACILITY_VOICE)); | 
 | 7588 |   adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); | 
 | 7589 |   cai[0] = 6; | 
 | 7590 |   cai[1] = plci->B1_resource; | 
 | 7591 |   for (i=2;i<sizeof(cai);i++) cai[i] = 0; | 
 | 7592 |  | 
 | 7593 |   if ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) | 
 | 7594 |    || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC) | 
 | 7595 |    || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC)) | 
 | 7596 |   { /* B1 - modem */ | 
 | 7597 |     for (i=0;i<7;i++) mdm_cfg[i].length = 0; | 
 | 7598 |  | 
 | 7599 |     if (bp_parms[3].length) | 
 | 7600 |     { | 
 | 7601 |       if(api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwww", mdm_cfg)) | 
 | 7602 |       { | 
 | 7603 |         return (_WRONG_MESSAGE_FORMAT); | 
 | 7604 |       } | 
 | 7605 |          | 
 | 7606 |       cai[2] = 0; /* Bit rate for adaptation */ | 
 | 7607 |  | 
 | 7608 |       dbug(1,dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg[0].info))); | 
 | 7609 |  | 
 | 7610 |       PUT_WORD (&cai[13], 0);                          /* Min Tx speed */ | 
 | 7611 |       PUT_WORD (&cai[15], GET_WORD(mdm_cfg[0].info)); /* Max Tx speed */ | 
 | 7612 |       PUT_WORD (&cai[17], 0);                          /* Min Rx speed */ | 
 | 7613 |       PUT_WORD (&cai[19], GET_WORD(mdm_cfg[0].info)); /* Max Rx speed */ | 
 | 7614 |  | 
 | 7615 |       cai[3] = 0; /* Async framing parameters */ | 
 | 7616 |       switch (GET_WORD (mdm_cfg[2].info)) | 
 | 7617 |       {       /* Parity     */ | 
 | 7618 |       case 1: /* odd parity */ | 
 | 7619 |         cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD); | 
 | 7620 |         dbug(1,dprintf("MDM: odd parity")); | 
 | 7621 |         break; | 
 | 7622 |  | 
 | 7623 |       case 2: /* even parity */ | 
 | 7624 |         cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN); | 
 | 7625 |         dbug(1,dprintf("MDM: even parity")); | 
 | 7626 |         break; | 
 | 7627 |  | 
 | 7628 |       default: | 
 | 7629 |         dbug(1,dprintf("MDM: no parity")); | 
 | 7630 |         break; | 
 | 7631 |       } | 
 | 7632 |  | 
 | 7633 |       switch (GET_WORD (mdm_cfg[3].info)) | 
 | 7634 |       {       /* stop bits   */ | 
 | 7635 |       case 1: /* 2 stop bits */ | 
 | 7636 |         cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS; | 
 | 7637 |         dbug(1,dprintf("MDM: 2 stop bits")); | 
 | 7638 |         break; | 
 | 7639 |  | 
 | 7640 |       default: | 
 | 7641 |         dbug(1,dprintf("MDM: 1 stop bit")); | 
 | 7642 |         break; | 
 | 7643 |       } | 
 | 7644 |  | 
 | 7645 |       switch (GET_WORD (mdm_cfg[1].info)) | 
 | 7646 |       {     /* char length */ | 
 | 7647 |       case 5: | 
 | 7648 |         cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5; | 
 | 7649 |         dbug(1,dprintf("MDM: 5 bits")); | 
 | 7650 |         break; | 
 | 7651 |  | 
 | 7652 |       case 6: | 
 | 7653 |         cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6; | 
 | 7654 |         dbug(1,dprintf("MDM: 6 bits")); | 
 | 7655 |         break; | 
 | 7656 |  | 
 | 7657 |       case 7: | 
 | 7658 |         cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7; | 
 | 7659 |         dbug(1,dprintf("MDM: 7 bits")); | 
 | 7660 |         break; | 
 | 7661 |  | 
 | 7662 |       default: | 
 | 7663 |         dbug(1,dprintf("MDM: 8 bits")); | 
 | 7664 |         break; | 
 | 7665 |       } | 
 | 7666 |  | 
 | 7667 |       cai[7] = 0; /* Line taking options */ | 
 | 7668 |       cai[8] = 0; /* Modulation negotiation options */ | 
 | 7669 |       cai[9] = 0; /* Modulation options */ | 
 | 7670 |  | 
 | 7671 |       if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0)) | 
 | 7672 |       { | 
 | 7673 |         cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION; | 
 | 7674 |         dbug(1, dprintf("MDM: Reverse direction")); | 
 | 7675 |       } | 
 | 7676 |  | 
 | 7677 |       if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN) | 
 | 7678 |       { | 
 | 7679 |         cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN; | 
 | 7680 |         dbug(1, dprintf("MDM: Disable retrain")); | 
 | 7681 |       } | 
 | 7682 |  | 
 | 7683 |       if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE) | 
 | 7684 |       { | 
 | 7685 |         cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE; | 
 | 7686 |         dbug(1, dprintf("MDM: Disable ring tone")); | 
 | 7687 |       } | 
 | 7688 |  | 
 | 7689 |       if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_1800) | 
 | 7690 |       { | 
 | 7691 |         cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ; | 
 | 7692 |         dbug(1, dprintf("MDM: 1800 guard tone")); | 
 | 7693 |       } | 
 | 7694 |       else if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_550 ) | 
 | 7695 |       { | 
 | 7696 |         cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ; | 
 | 7697 |         dbug(1, dprintf("MDM: 550 guard tone")); | 
 | 7698 |       } | 
 | 7699 |  | 
 | 7700 |       if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100) | 
 | 7701 |       { | 
 | 7702 |         cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100; | 
 | 7703 |         dbug(1, dprintf("MDM: V100")); | 
 | 7704 |       } | 
 | 7705 |       else if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS) | 
 | 7706 |       { | 
 | 7707 |         cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS; | 
 | 7708 |         dbug(1, dprintf("MDM: IN CLASS")); | 
 | 7709 |       } | 
 | 7710 |       else if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED) | 
 | 7711 |       { | 
 | 7712 |         cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED; | 
 | 7713 |         dbug(1, dprintf("MDM: DISABLED")); | 
 | 7714 |       } | 
 | 7715 |       cai[0] = 20; | 
 | 7716 |  | 
 | 7717 |       if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18)) | 
 | 7718 |        && (GET_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */ | 
 | 7719 |       { | 
 | 7720 |         plci->requested_options |= 1L << PRIVATE_V18; | 
 | 7721 |       } | 
 | 7722 |       if (GET_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */ | 
 | 7723 |         plci->requested_options |= 1L << PRIVATE_VOWN; | 
 | 7724 |  | 
 | 7725 |       if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) | 
 | 7726 |         & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN))) | 
 | 7727 |       { | 
 | 7728 |         if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwws", mdm_cfg)) | 
 | 7729 |         { | 
 | 7730 |           i = 27; | 
 | 7731 |           if (mdm_cfg[6].length >= 4) | 
 | 7732 |           { | 
 | 7733 |             d = GET_DWORD(&mdm_cfg[6].info[1]); | 
 | 7734 |             cai[7] |= (byte) d;          /* line taking options */ | 
 | 7735 |             cai[9] |= (byte)(d >> 8);    /* modulation options */ | 
 | 7736 |             cai[++i] = (byte)(d >> 16);  /* vown modulation options */ | 
 | 7737 |             cai[++i] = (byte)(d >> 24); | 
 | 7738 |             if (mdm_cfg[6].length >= 8) | 
 | 7739 |             { | 
 | 7740 |               d = GET_DWORD(&mdm_cfg[6].info[5]); | 
 | 7741 |               cai[10] |= (byte) d;        /* disabled modulations mask */ | 
 | 7742 |               cai[11] |= (byte)(d >> 8); | 
 | 7743 |               if (mdm_cfg[6].length >= 12) | 
 | 7744 |               { | 
 | 7745 |                 d = GET_DWORD(&mdm_cfg[6].info[9]); | 
 | 7746 |                 cai[12] = (byte) d;          /* enabled modulations mask */ | 
 | 7747 |                 cai[++i] = (byte)(d >> 8);   /* vown enabled modulations */ | 
 | 7748 |                 cai[++i] = (byte)(d >> 16); | 
 | 7749 |                 cai[++i] = (byte)(d >> 24); | 
 | 7750 |                 cai[++i] = 0; | 
 | 7751 |                 if (mdm_cfg[6].length >= 14) | 
 | 7752 |                 { | 
 | 7753 |                   w = GET_WORD(&mdm_cfg[6].info[13]); | 
 | 7754 |                   if (w != 0) | 
 | 7755 |                     PUT_WORD(&cai[13], w);  /* min tx speed */ | 
 | 7756 |                   if (mdm_cfg[6].length >= 16) | 
 | 7757 |                   { | 
 | 7758 |                     w = GET_WORD(&mdm_cfg[6].info[15]); | 
 | 7759 |                     if (w != 0) | 
 | 7760 |                       PUT_WORD(&cai[15], w);  /* max tx speed */ | 
 | 7761 |                     if (mdm_cfg[6].length >= 18) | 
 | 7762 |                     { | 
 | 7763 |                       w = GET_WORD(&mdm_cfg[6].info[17]); | 
 | 7764 |                       if (w != 0) | 
 | 7765 |                         PUT_WORD(&cai[17], w);  /* min rx speed */ | 
 | 7766 |                       if (mdm_cfg[6].length >= 20) | 
 | 7767 |                       { | 
 | 7768 |                         w = GET_WORD(&mdm_cfg[6].info[19]); | 
 | 7769 |                         if (w != 0) | 
 | 7770 |                           PUT_WORD(&cai[19], w);  /* max rx speed */ | 
 | 7771 |                         if (mdm_cfg[6].length >= 22) | 
 | 7772 |                         { | 
 | 7773 |                           w = GET_WORD(&mdm_cfg[6].info[21]); | 
 | 7774 |                           cai[23] = (byte)(-((short) w));  /* transmit level */ | 
 | 7775 |                           if (mdm_cfg[6].length >= 24) | 
 | 7776 |                           { | 
 | 7777 |                             w = GET_WORD(&mdm_cfg[6].info[23]); | 
 | 7778 |                             cai[22] |= (byte) w;        /* info options mask */ | 
 | 7779 |                             cai[21] |= (byte)(w >> 8);  /* disabled symbol rates */ | 
 | 7780 |                           } | 
 | 7781 |                         } | 
 | 7782 |                       } | 
 | 7783 |                     } | 
 | 7784 |                   } | 
 | 7785 |                 } | 
 | 7786 |               } | 
 | 7787 |             } | 
 | 7788 |           } | 
 | 7789 |           cai[27] = i - 27; | 
 | 7790 |           i++; | 
 | 7791 |           if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwwss", mdm_cfg)) | 
 | 7792 |           { | 
 | 7793 |             if (!api_parse(&mdm_cfg[7].info[1],(word)mdm_cfg[7].length,"sss", mdm_cfg_v18)) | 
 | 7794 |             { | 
 | 7795 |               for (n = 0; n < 3; n++) | 
 | 7796 |               { | 
 | 7797 |                 cai[i] = (byte)(mdm_cfg_v18[n].length); | 
 | 7798 |                 for (j = 1; j < ((word)(cai[i] + 1)); j++) | 
 | 7799 |                   cai[i+j] = mdm_cfg_v18[n].info[j]; | 
 | 7800 |                 i += cai[i] + 1; | 
 | 7801 |               } | 
 | 7802 |             } | 
 | 7803 |           } | 
 | 7804 |           cai[0] = (byte)(i - 1); | 
 | 7805 |         } | 
 | 7806 |       } | 
 | 7807 |  | 
 | 7808 |     } | 
 | 7809 |   } | 
 | 7810 |   if(GET_WORD(bp_parms[0].info)==2 ||                         /* V.110 async */ | 
 | 7811 |      GET_WORD(bp_parms[0].info)==3 )                          /* V.110 sync */ | 
 | 7812 |   { | 
 | 7813 |     if(bp_parms[3].length){ | 
 | 7814 |       dbug(1,dprintf("V.110,%d",GET_WORD(&bp_parms[3].info[1]))); | 
 | 7815 |       switch(GET_WORD(&bp_parms[3].info[1])){                 /* Rate */ | 
 | 7816 |         case 0: | 
 | 7817 |         case 56000: | 
 | 7818 |           if(GET_WORD(bp_parms[0].info)==3){                  /* V.110 sync 56k */ | 
 | 7819 |             dbug(1,dprintf("56k sync HSCX")); | 
 | 7820 |             cai[1] = 8; | 
 | 7821 |             cai[2] = 0; | 
 | 7822 |             cai[3] = 0; | 
 | 7823 |           } | 
 | 7824 |           else if(GET_WORD(bp_parms[0].info)==2){ | 
 | 7825 |             dbug(1,dprintf("56k async DSP")); | 
 | 7826 |             cai[2] = 9; | 
 | 7827 |           } | 
 | 7828 |           break; | 
 | 7829 |         case 50:     cai[2] = 1;  break; | 
 | 7830 |         case 75:     cai[2] = 1;  break; | 
 | 7831 |         case 110:    cai[2] = 1;  break; | 
 | 7832 |         case 150:    cai[2] = 1;  break; | 
 | 7833 |         case 200:    cai[2] = 1;  break; | 
 | 7834 |         case 300:    cai[2] = 1;  break; | 
 | 7835 |         case 600:    cai[2] = 1;  break; | 
 | 7836 |         case 1200:   cai[2] = 2;  break; | 
 | 7837 |         case 2400:   cai[2] = 3;  break; | 
 | 7838 |         case 4800:   cai[2] = 4;  break; | 
 | 7839 |         case 7200:   cai[2] = 10; break; | 
 | 7840 |         case 9600:   cai[2] = 5;  break; | 
 | 7841 |         case 12000:  cai[2] = 13; break; | 
 | 7842 |         case 24000:  cai[2] = 0;  break; | 
 | 7843 |         case 14400:  cai[2] = 11; break; | 
 | 7844 |         case 19200:  cai[2] = 6;  break; | 
 | 7845 |         case 28800:  cai[2] = 12; break; | 
 | 7846 |         case 38400:  cai[2] = 7;  break; | 
 | 7847 |         case 48000:  cai[2] = 8;  break; | 
 | 7848 |         case 76:     cai[2] = 15; break;  /* 75/1200     */ | 
 | 7849 |         case 1201:   cai[2] = 14; break;  /* 1200/75     */ | 
 | 7850 |         case 56001:  cai[2] = 9;  break;  /* V.110 56000 */ | 
 | 7851 |  | 
 | 7852 |         default: | 
 | 7853 |           return _B1_PARM_NOT_SUPPORTED; | 
 | 7854 |       } | 
 | 7855 |       cai[3] = 0; | 
 | 7856 |       if (cai[1] == 13)                                        /* v.110 async */ | 
 | 7857 |       { | 
 | 7858 |         if (bp_parms[3].length >= 8) | 
 | 7859 |         { | 
 | 7860 |           switch (GET_WORD (&bp_parms[3].info[3])) | 
 | 7861 |           {       /* char length */ | 
 | 7862 |           case 5: | 
 | 7863 |             cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5; | 
 | 7864 |             break; | 
 | 7865 |           case 6: | 
 | 7866 |             cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6; | 
 | 7867 |             break; | 
 | 7868 |           case 7: | 
 | 7869 |             cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7; | 
 | 7870 |             break; | 
 | 7871 |           } | 
 | 7872 |           switch (GET_WORD (&bp_parms[3].info[5])) | 
 | 7873 |           {       /* Parity     */ | 
 | 7874 |           case 1: /* odd parity */ | 
 | 7875 |             cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD); | 
 | 7876 |             break; | 
 | 7877 |           case 2: /* even parity */ | 
 | 7878 |             cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN); | 
 | 7879 |             break; | 
 | 7880 |           } | 
 | 7881 |           switch (GET_WORD (&bp_parms[3].info[7])) | 
 | 7882 |           {       /* stop bits   */ | 
 | 7883 |           case 1: /* 2 stop bits */ | 
 | 7884 |             cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS; | 
 | 7885 |             break; | 
 | 7886 |           } | 
 | 7887 |         } | 
 | 7888 |       } | 
 | 7889 |     } | 
 | 7890 |     else if(cai[1]==8 || GET_WORD(bp_parms[0].info)==3 ){ | 
 | 7891 |       dbug(1,dprintf("V.110 default 56k sync")); | 
 | 7892 |       cai[1] = 8; | 
 | 7893 |       cai[2] = 0; | 
 | 7894 |       cai[3] = 0; | 
 | 7895 |     } | 
 | 7896 |     else { | 
 | 7897 |       dbug(1,dprintf("V.110 default 9600 async")); | 
 | 7898 |       cai[2] = 5; | 
 | 7899 |     } | 
 | 7900 |   } | 
 | 7901 |   PUT_WORD(&cai[5],plci->appl->MaxDataLength); | 
 | 7902 |   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])); | 
 | 7903 | /* HexDump ("CAI", sizeof(cai), &cai[0]); */ | 
 | 7904 |  | 
 | 7905 |   add_p(plci, CAI, cai); | 
 | 7906 |   return 0; | 
 | 7907 | } | 
 | 7908 |  | 
 | 7909 | /*------------------------------------------------------------------*/ | 
 | 7910 | /* put parameter for b2 and B3  protocol in the parameter buffer    */ | 
 | 7911 | /*------------------------------------------------------------------*/ | 
 | 7912 |  | 
 | 7913 | word add_b23(PLCI   * plci, API_PARSE * bp) | 
 | 7914 | { | 
 | 7915 |   word i, fax_control_bits; | 
 | 7916 |   byte pos, len; | 
 | 7917 |   byte SAPI = 0x40;  /* default SAPI 16 for x.31 */ | 
 | 7918 |     API_PARSE bp_parms[8]; | 
 | 7919 |   API_PARSE * b1_config; | 
 | 7920 |   API_PARSE * b2_config; | 
 | 7921 |     API_PARSE b2_config_parms[8]; | 
 | 7922 |   API_PARSE * b3_config; | 
 | 7923 |     API_PARSE b3_config_parms[6]; | 
 | 7924 |     API_PARSE global_config[2]; | 
 | 7925 |  | 
 | 7926 |   static byte llc[3] = {2,0,0}; | 
 | 7927 |   static byte dlc[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | 
 | 7928 |   static byte nlc[256]; | 
 | 7929 |   static byte lli[12] = {1,1}; | 
 | 7930 |  | 
 | 7931 |   const byte llc2_out[] = {1,2,4,6,2,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6}; | 
 | 7932 |   const byte llc2_in[]  = {1,3,4,6,3,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6}; | 
 | 7933 |  | 
 | 7934 |   const byte llc3[] = {4,3,2,2,6,6,0}; | 
 | 7935 |   const byte header[] = {0,2,3,3,0,0,0}; | 
 | 7936 |  | 
 | 7937 |   for(i=0;i<8;i++) bp_parms[i].length = 0; | 
 | 7938 |   for(i=0;i<6;i++) b2_config_parms[i].length = 0; | 
 | 7939 |   for(i=0;i<5;i++) b3_config_parms[i].length = 0; | 
 | 7940 |  | 
 | 7941 |   lli[0] = 1; | 
 | 7942 |   lli[1] = 1; | 
 | 7943 |   if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) | 
 | 7944 |     lli[1] |= 2; | 
 | 7945 |   if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) | 
 | 7946 |     lli[1] |= 4; | 
 | 7947 |  | 
 | 7948 |   if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) { | 
 | 7949 |     lli[1] |= 0x10; | 
 | 7950 |     if (plci->rx_dma_descriptor <= 0) { | 
 | 7951 |       plci->rx_dma_descriptor=diva_get_dma_descriptor(plci,&plci->rx_dma_magic); | 
 | 7952 |       if (plci->rx_dma_descriptor >= 0) | 
 | 7953 |         plci->rx_dma_descriptor++; | 
 | 7954 |     } | 
 | 7955 |     if (plci->rx_dma_descriptor > 0) { | 
 | 7956 |       lli[0] = 6; | 
 | 7957 |       lli[1] |= 0x40; | 
 | 7958 |       lli[2] = (byte)(plci->rx_dma_descriptor - 1); | 
 | 7959 |       lli[3] = (byte)plci->rx_dma_magic; | 
 | 7960 |       lli[4] = (byte)(plci->rx_dma_magic >>  8); | 
 | 7961 |       lli[5] = (byte)(plci->rx_dma_magic >> 16); | 
 | 7962 |       lli[6] = (byte)(plci->rx_dma_magic >> 24); | 
 | 7963 |     } | 
 | 7964 |   } | 
 | 7965 |  | 
 | 7966 |   if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) { | 
 | 7967 |     lli[1] |= 0x20; | 
 | 7968 |   } | 
 | 7969 |  | 
 | 7970 |   dbug(1,dprintf("add_b23")); | 
 | 7971 |   api_save_msg(bp, "s", &plci->B_protocol); | 
 | 7972 |  | 
 | 7973 |   if(!bp->length && plci->tel) | 
 | 7974 |   { | 
 | 7975 |     plci->adv_nl = TRUE; | 
 | 7976 |     dbug(1,dprintf("Default adv.Nl")); | 
 | 7977 |     add_p(plci,LLI,lli); | 
 | 7978 |     plci->B2_prot = 1 /*XPARENT*/; | 
 | 7979 |     plci->B3_prot = 0 /*XPARENT*/; | 
 | 7980 |     llc[1] = 2; | 
 | 7981 |     llc[2] = 4; | 
 | 7982 |     add_p(plci, LLC, llc); | 
 | 7983 |     dlc[0] = 2; | 
 | 7984 |     PUT_WORD(&dlc[1],plci->appl->MaxDataLength); | 
 | 7985 |     add_p(plci, DLC, dlc); | 
 | 7986 |     return 0; | 
 | 7987 |   } | 
 | 7988 |  | 
 | 7989 |   if(!bp->length) /*default*/ | 
 | 7990 |   {    | 
 | 7991 |     dbug(1,dprintf("ret default")); | 
 | 7992 |     add_p(plci,LLI,lli); | 
 | 7993 |     plci->B2_prot = 0 /*X.75   */; | 
 | 7994 |     plci->B3_prot = 0 /*XPARENT*/; | 
 | 7995 |     llc[1] = 1; | 
 | 7996 |     llc[2] = 4; | 
 | 7997 |     add_p(plci, LLC, llc); | 
 | 7998 |     dlc[0] = 2; | 
 | 7999 |     PUT_WORD(&dlc[1],plci->appl->MaxDataLength); | 
 | 8000 |     add_p(plci, DLC, dlc); | 
 | 8001 |     return 0; | 
 | 8002 |   } | 
 | 8003 |   dbug(1,dprintf("b_prot_len=%d",(word)bp->length)); | 
 | 8004 |   if((word)bp->length > 256)    return _WRONG_MESSAGE_FORMAT; | 
 | 8005 |  | 
 | 8006 |   if(api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms)) | 
 | 8007 |   { | 
 | 8008 |     bp_parms[6].length = 0; | 
 | 8009 |     if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms)) | 
 | 8010 |     { | 
 | 8011 |       dbug(1,dprintf("b-form.!")); | 
 | 8012 |       return _WRONG_MESSAGE_FORMAT; | 
 | 8013 |     } | 
 | 8014 |   } | 
 | 8015 |   else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms)) | 
 | 8016 |   { | 
 | 8017 |     dbug(1,dprintf("b-form.!")); | 
 | 8018 |     return _WRONG_MESSAGE_FORMAT; | 
 | 8019 |   } | 
 | 8020 |  | 
 | 8021 |   if(plci->tel==ADV_VOICE) /* transparent B on advanced voice */ | 
 | 8022 |   {   | 
 | 8023 |     if(GET_WORD(bp_parms[1].info)!=1 | 
 | 8024 |     || GET_WORD(bp_parms[2].info)!=0) return _B2_NOT_SUPPORTED; | 
 | 8025 |     plci->adv_nl = TRUE; | 
 | 8026 |   } | 
 | 8027 |   else if(plci->tel) return _B2_NOT_SUPPORTED; | 
 | 8028 |  | 
 | 8029 |  | 
 | 8030 |   if ((GET_WORD(bp_parms[1].info) == B2_RTP) | 
 | 8031 |    && (GET_WORD(bp_parms[2].info) == B3_RTP) | 
 | 8032 |    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP))) | 
 | 8033 |   { | 
 | 8034 |     add_p(plci,LLI,lli); | 
 | 8035 |     plci->B2_prot = (byte) GET_WORD(bp_parms[1].info); | 
 | 8036 |     plci->B3_prot = (byte) GET_WORD(bp_parms[2].info); | 
 | 8037 |     llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? 14 : 13; | 
 | 8038 |     llc[2] = 4; | 
 | 8039 |     add_p(plci, LLC, llc); | 
 | 8040 |     dlc[0] = 2; | 
 | 8041 |     PUT_WORD(&dlc[1],plci->appl->MaxDataLength); | 
 | 8042 |     dlc[3] = 3; /* Addr A */ | 
 | 8043 |     dlc[4] = 1; /* Addr B */ | 
 | 8044 |     dlc[5] = 7; /* modulo mode */ | 
 | 8045 |     dlc[6] = 7; /* window size */ | 
 | 8046 |     dlc[7] = 0; /* XID len Lo  */ | 
 | 8047 |     dlc[8] = 0; /* XID len Hi  */ | 
 | 8048 |     for (i = 0; i < bp_parms[4].length; i++) | 
 | 8049 |       dlc[9+i] = bp_parms[4].info[1+i]; | 
 | 8050 |     dlc[0] = (byte)(8 + bp_parms[4].length); | 
 | 8051 |     add_p(plci, DLC, dlc); | 
 | 8052 |     for (i = 0; i < bp_parms[5].length; i++) | 
 | 8053 |       nlc[1+i] = bp_parms[5].info[1+i]; | 
 | 8054 |     nlc[0] = (byte)(bp_parms[5].length); | 
 | 8055 |     add_p(plci, NLC, nlc); | 
 | 8056 |     return 0; | 
 | 8057 |   } | 
 | 8058 |  | 
 | 8059 |  | 
 | 8060 |  | 
 | 8061 |   if ((GET_WORD(bp_parms[1].info) >= 32) | 
 | 8062 |    || (!((1L << GET_WORD(bp_parms[1].info)) & plci->adapter->profile.B2_Protocols) | 
 | 8063 |     && ((GET_WORD(bp_parms[1].info) != B2_PIAFS) | 
 | 8064 |      || !(plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS))))) | 
 | 8065 |  | 
 | 8066 |   { | 
 | 8067 |     return _B2_NOT_SUPPORTED; | 
 | 8068 |   } | 
 | 8069 |   if ((GET_WORD(bp_parms[2].info) >= 32) | 
 | 8070 |    || !((1L << GET_WORD(bp_parms[2].info)) & plci->adapter->profile.B3_Protocols)) | 
 | 8071 |   { | 
 | 8072 |     return _B3_NOT_SUPPORTED; | 
 | 8073 |   } | 
 | 8074 |   if ((GET_WORD(bp_parms[1].info) != B2_SDLC) | 
 | 8075 |    && ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) | 
 | 8076 |     || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC) | 
 | 8077 |     || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC))) | 
 | 8078 |   { | 
 | 8079 |     return (add_modem_b23 (plci, bp_parms)); | 
 | 8080 |   } | 
 | 8081 |  | 
 | 8082 |   add_p(plci,LLI,lli); | 
 | 8083 |  | 
 | 8084 |   plci->B2_prot = (byte) GET_WORD(bp_parms[1].info); | 
 | 8085 |   plci->B3_prot = (byte) GET_WORD(bp_parms[2].info); | 
 | 8086 |   if(plci->B2_prot==12) SAPI = 0; /* default SAPI D-channel */ | 
 | 8087 |  | 
 | 8088 |   if(bp_parms[6].length) | 
 | 8089 |   { | 
 | 8090 |     if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config)) | 
 | 8091 |     { | 
 | 8092 |       return _WRONG_MESSAGE_FORMAT; | 
 | 8093 |     } | 
 | 8094 |     switch(GET_WORD(global_config[0].info)) | 
 | 8095 |     { | 
 | 8096 |     case 1: | 
 | 8097 |       plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE; | 
 | 8098 |       break; | 
 | 8099 |     case 2: | 
 | 8100 |       plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER; | 
 | 8101 |       break; | 
 | 8102 |     } | 
 | 8103 |   } | 
 | 8104 |   dbug(1,dprintf("call_dir=%04x", plci->call_dir)); | 
 | 8105 |  | 
 | 8106 |  | 
 | 8107 |   if (plci->B2_prot == B2_PIAFS) | 
 | 8108 |     llc[1] = PIAFS_CRC; | 
 | 8109 |   else | 
 | 8110 | /* IMPLEMENT_PIAFS */ | 
 | 8111 |   { | 
 | 8112 |     llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? | 
 | 8113 |              llc2_out[GET_WORD(bp_parms[1].info)] : llc2_in[GET_WORD(bp_parms[1].info)]; | 
 | 8114 |   } | 
 | 8115 |   llc[2] = llc3[GET_WORD(bp_parms[2].info)]; | 
 | 8116 |  | 
 | 8117 |   add_p(plci, LLC, llc); | 
 | 8118 |  | 
 | 8119 |   dlc[0] = 2; | 
 | 8120 |   PUT_WORD(&dlc[1], plci->appl->MaxDataLength + | 
 | 8121 |                       header[GET_WORD(bp_parms[2].info)]); | 
 | 8122 |  | 
 | 8123 |   b1_config = &bp_parms[3]; | 
 | 8124 |   nlc[0] = 0; | 
 | 8125 |   if(plci->B3_prot == 4 | 
 | 8126 |   || plci->B3_prot == 5) | 
 | 8127 |   { | 
 | 8128 |     for (i=0;i<sizeof(T30_INFO);i++) nlc[i] = 0; | 
 | 8129 |     nlc[0] = sizeof(T30_INFO); | 
 | 8130 |     if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) | 
 | 8131 |       ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI; | 
 | 8132 |     ((T30_INFO *)&nlc[1])->rate_div_2400 = 0xff; | 
 | 8133 |     if(b1_config->length>=2) | 
 | 8134 |     { | 
 | 8135 |       ((T30_INFO *)&nlc[1])->rate_div_2400 = (byte)(GET_WORD(&b1_config->info[1])/2400); | 
 | 8136 |     } | 
 | 8137 |   } | 
 | 8138 |   b2_config = &bp_parms[4]; | 
 | 8139 |  | 
 | 8140 |  | 
 | 8141 |   if (llc[1] == PIAFS_CRC) | 
 | 8142 |   { | 
 | 8143 |     if (plci->B3_prot != B3_TRANSPARENT) | 
 | 8144 |     { | 
 | 8145 |       return _B_STACK_NOT_SUPPORTED; | 
 | 8146 |     } | 
 | 8147 |     if(b2_config->length && api_parse(&b2_config->info[1], (word)b2_config->length, "bwww", b2_config_parms)) { | 
 | 8148 |       return _WRONG_MESSAGE_FORMAT; | 
 | 8149 |     } | 
 | 8150 |     PUT_WORD(&dlc[1],plci->appl->MaxDataLength); | 
 | 8151 |     dlc[3] = 0; /* Addr A */ | 
 | 8152 |     dlc[4] = 0; /* Addr B */ | 
 | 8153 |     dlc[5] = 0; /* modulo mode */ | 
 | 8154 |     dlc[6] = 0; /* window size */ | 
 | 8155 |     if (b2_config->length >= 7){ | 
 | 8156 |       dlc[ 7] = 7;  | 
 | 8157 |       dlc[ 8] = 0;  | 
 | 8158 |       dlc[ 9] = b2_config_parms[0].info[0]; /* PIAFS protocol Speed configuration */ | 
 | 8159 |       dlc[10] = b2_config_parms[1].info[0]; /* V.42bis P0 */ | 
 | 8160 |       dlc[11] = b2_config_parms[1].info[1]; /* V.42bis P0 */ | 
 | 8161 |       dlc[12] = b2_config_parms[2].info[0]; /* V.42bis P1 */ | 
 | 8162 |       dlc[13] = b2_config_parms[2].info[1]; /* V.42bis P1 */ | 
 | 8163 |       dlc[14] = b2_config_parms[3].info[0]; /* V.42bis P2 */ | 
 | 8164 |       dlc[15] = b2_config_parms[3].info[1]; /* V.42bis P2 */ | 
 | 8165 |       dlc[ 0] = 15; | 
 | 8166 |       if(b2_config->length >= 8) { /* PIAFS control abilities */ | 
 | 8167 |         dlc[ 7] = 10;  | 
 | 8168 |         dlc[16] = 2; /* Length of PIAFS extention */ | 
 | 8169 |         dlc[17] = PIAFS_UDATA_ABILITIES; /* control (UDATA) ability */ | 
 | 8170 |         dlc[18] = b2_config_parms[4].info[0]; /* value */ | 
 | 8171 |         dlc[ 0] = 18; | 
 | 8172 |       } | 
 | 8173 |     } | 
 | 8174 |     else /* default values, 64K, variable, no compression */ | 
 | 8175 |     { | 
 | 8176 |       dlc[ 7] = 7;  | 
 | 8177 |       dlc[ 8] = 0;  | 
 | 8178 |       dlc[ 9] = 0x03; /* PIAFS protocol Speed configuration */ | 
 | 8179 |       dlc[10] = 0x03; /* V.42bis P0 */ | 
 | 8180 |       dlc[11] = 0;    /* V.42bis P0 */ | 
 | 8181 |       dlc[12] = 0;    /* V.42bis P1 */ | 
 | 8182 |       dlc[13] = 0;    /* V.42bis P1 */ | 
 | 8183 |       dlc[14] = 0;    /* V.42bis P2 */ | 
 | 8184 |       dlc[15] = 0;    /* V.42bis P2 */ | 
 | 8185 |     dlc[ 0] = 15; | 
 | 8186 |     } | 
 | 8187 |     add_p(plci, DLC, dlc); | 
 | 8188 |   } | 
 | 8189 |   else | 
 | 8190 |  | 
 | 8191 |   if ((llc[1] == V120_L2) || (llc[1] == V120_V42BIS)) | 
 | 8192 |   { | 
 | 8193 |     if (plci->B3_prot != B3_TRANSPARENT) | 
 | 8194 |       return _B_STACK_NOT_SUPPORTED; | 
 | 8195 |  | 
 | 8196 |     dlc[0] = 6; | 
 | 8197 |     PUT_WORD (&dlc[1], GET_WORD (&dlc[1]) + 2); | 
 | 8198 |     dlc[3] = 0x08; | 
 | 8199 |     dlc[4] = 0x01; | 
 | 8200 |     dlc[5] = 127; | 
 | 8201 |     dlc[6] = 7; | 
 | 8202 |     if (b2_config->length != 0) | 
 | 8203 |     { | 
 | 8204 |       if((llc[1]==V120_V42BIS) && api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) { | 
 | 8205 |         return _WRONG_MESSAGE_FORMAT; | 
 | 8206 |       } | 
 | 8207 |       dlc[3] = (byte)((b2_config->info[2] << 3) | ((b2_config->info[1] >> 5) & 0x04)); | 
 | 8208 |       dlc[4] = (byte)((b2_config->info[1] << 1) | 0x01); | 
 | 8209 |       if (b2_config->info[3] != 128) | 
 | 8210 |       { | 
 | 8211 |         dbug(1,dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); | 
 | 8212 |         return _B2_PARM_NOT_SUPPORTED; | 
 | 8213 |       } | 
 | 8214 |       dlc[5] = (byte)(b2_config->info[3] - 1); | 
 | 8215 |       dlc[6] = b2_config->info[4]; | 
 | 8216 |       if(llc[1]==V120_V42BIS){ | 
 | 8217 |         if (b2_config->length >= 10){ | 
 | 8218 |           dlc[ 7] = 6;  | 
 | 8219 |           dlc[ 8] = 0;  | 
 | 8220 |           dlc[ 9] = b2_config_parms[4].info[0]; | 
 | 8221 |           dlc[10] = b2_config_parms[4].info[1]; | 
 | 8222 |           dlc[11] = b2_config_parms[5].info[0]; | 
 | 8223 |           dlc[12] = b2_config_parms[5].info[1]; | 
 | 8224 |           dlc[13] = b2_config_parms[6].info[0]; | 
 | 8225 |           dlc[14] = b2_config_parms[6].info[1]; | 
 | 8226 |           dlc[ 0] = 14; | 
 | 8227 |           dbug(1,dprintf("b2_config_parms[4].info[0] [1]:  %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1])); | 
 | 8228 |           dbug(1,dprintf("b2_config_parms[5].info[0] [1]:  %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1])); | 
 | 8229 |           dbug(1,dprintf("b2_config_parms[6].info[0] [1]:  %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1])); | 
 | 8230 |         } | 
 | 8231 |         else { | 
 | 8232 |           dlc[ 6] = 14; | 
 | 8233 |         } | 
 | 8234 |       } | 
 | 8235 |     } | 
 | 8236 |   } | 
 | 8237 |   else | 
 | 8238 |   { | 
 | 8239 |     if(b2_config->length) | 
 | 8240 |     { | 
 | 8241 |       dbug(1,dprintf("B2-Config")); | 
 | 8242 |       if(llc[1]==X75_V42BIS){ | 
 | 8243 |         if(api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) | 
 | 8244 |         { | 
 | 8245 |           return _WRONG_MESSAGE_FORMAT; | 
 | 8246 |         } | 
 | 8247 |       } | 
 | 8248 |       else { | 
 | 8249 |         if(api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbs", b2_config_parms)) | 
 | 8250 |         { | 
 | 8251 |           return _WRONG_MESSAGE_FORMAT; | 
 | 8252 |         } | 
 | 8253 |       } | 
 | 8254 |           /* if B2 Protocol is LAPD, b2_config structure is different */ | 
 | 8255 |       if(llc[1]==6) | 
 | 8256 |       { | 
 | 8257 |         dlc[0] = 4; | 
 | 8258 |         if(b2_config->length>=1) dlc[2] = b2_config->info[1];      /* TEI */ | 
 | 8259 |         else dlc[2] = 0x01; | 
 | 8260 |         if( (b2_config->length>=2) && (plci->B2_prot==12) ) | 
 | 8261 |         { | 
 | 8262 |           SAPI = b2_config->info[2];    /* SAPI */ | 
 | 8263 |         } | 
 | 8264 |         dlc[1] = SAPI; | 
 | 8265 |         if( (b2_config->length>=3) && (b2_config->info[3]==128) ) | 
 | 8266 |         { | 
 | 8267 |           dlc[3] = 127;      /* Mode */ | 
 | 8268 |         } | 
 | 8269 |         else | 
 | 8270 |         { | 
 | 8271 |           dlc[3] = 7;        /* Mode */ | 
 | 8272 |         } | 
 | 8273 |     | 
 | 8274 |         if(b2_config->length>=4) dlc[4] = b2_config->info[4];      /* Window */ | 
 | 8275 |         else dlc[4] = 1; | 
 | 8276 |         dbug(1,dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); | 
 | 8277 |         if(b2_config->length>5) return _B2_PARM_NOT_SUPPORTED; | 
 | 8278 |       } | 
 | 8279 |       else | 
 | 8280 |       { | 
 | 8281 |         dlc[0] = (byte)(b2_config_parms[4].length+6); | 
 | 8282 |         dlc[3] = b2_config->info[1]; | 
 | 8283 |         dlc[4] = b2_config->info[2]; | 
 | 8284 |         if(b2_config->info[3]!=8 && b2_config->info[3]!=128){ | 
 | 8285 |           dbug(1,dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); | 
 | 8286 |           return _B2_PARM_NOT_SUPPORTED; | 
 | 8287 |         } | 
 | 8288 |  | 
 | 8289 |         dlc[5] = (byte)(b2_config->info[3]-1); | 
 | 8290 |         dlc[6] = b2_config->info[4]; | 
 | 8291 |         if(dlc[6]>dlc[5]){ | 
 | 8292 |           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])); | 
 | 8293 |           return _B2_PARM_NOT_SUPPORTED; | 
 | 8294 |         } | 
 | 8295 |   | 
 | 8296 |         if(llc[1]==X75_V42BIS) { | 
 | 8297 |           if (b2_config->length >= 10){ | 
 | 8298 |             dlc[ 7] = 6;  | 
 | 8299 |             dlc[ 8] = 0;  | 
 | 8300 |             dlc[ 9] = b2_config_parms[4].info[0]; | 
 | 8301 |             dlc[10] = b2_config_parms[4].info[1]; | 
 | 8302 |             dlc[11] = b2_config_parms[5].info[0]; | 
 | 8303 |             dlc[12] = b2_config_parms[5].info[1]; | 
 | 8304 |             dlc[13] = b2_config_parms[6].info[0]; | 
 | 8305 |             dlc[14] = b2_config_parms[6].info[1]; | 
 | 8306 |             dlc[ 0] = 14; | 
 | 8307 |             dbug(1,dprintf("b2_config_parms[4].info[0] [1]:  %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1])); | 
 | 8308 |             dbug(1,dprintf("b2_config_parms[5].info[0] [1]:  %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1])); | 
 | 8309 |             dbug(1,dprintf("b2_config_parms[6].info[0] [1]:  %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1])); | 
 | 8310 |           } | 
 | 8311 |           else { | 
 | 8312 |             dlc[ 6] = 14; | 
 | 8313 |           } | 
 | 8314 |  | 
 | 8315 |         } | 
 | 8316 |         else { | 
 | 8317 |           PUT_WORD(&dlc[7], (word)b2_config_parms[4].length); | 
 | 8318 |           for(i=0; i<b2_config_parms[4].length; i++) | 
 | 8319 |             dlc[11+i] = b2_config_parms[4].info[1+i]; | 
 | 8320 |         } | 
 | 8321 |       } | 
 | 8322 |     } | 
 | 8323 |   } | 
 | 8324 |   add_p(plci, DLC, dlc); | 
 | 8325 |  | 
 | 8326 |   b3_config = &bp_parms[5]; | 
 | 8327 |   if(b3_config->length) | 
 | 8328 |   { | 
 | 8329 |     if(plci->B3_prot == 4  | 
 | 8330 |     || plci->B3_prot == 5) | 
 | 8331 |     { | 
 | 8332 |       if(api_parse(&b3_config->info[1], (word)b3_config->length, "wwss", b3_config_parms)) | 
 | 8333 |       { | 
 | 8334 |         return _WRONG_MESSAGE_FORMAT; | 
 | 8335 |       } | 
 | 8336 |       i = GET_WORD((byte   *)(b3_config_parms[0].info)); | 
 | 8337 |       ((T30_INFO *)&nlc[1])->resolution = (byte)(((i & 0x0001) || | 
 | 8338 |         ((plci->B3_prot == 4) && (((byte)(GET_WORD((byte   *)b3_config_parms[1].info))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200 : 0); | 
 | 8339 |       ((T30_INFO *)&nlc[1])->data_format = (byte)(GET_WORD((byte   *)b3_config_parms[1].info)); | 
 | 8340 |       fax_control_bits = T30_CONTROL_BIT_ALL_FEATURES; | 
 | 8341 |       if ((((T30_INFO *)&nlc[1])->rate_div_2400 != 0) && (((T30_INFO *)&nlc[1])->rate_div_2400 <= 6)) | 
 | 8342 |         fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_V34FAX; | 
 | 8343 |       if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) | 
 | 8344 |       { | 
 | 8345 |  | 
 | 8346 |         if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) | 
 | 8347 |           & (1L << PRIVATE_FAX_PAPER_FORMATS)) | 
 | 8348 |         { | 
 | 8349 |           ((T30_INFO *)&nlc[1])->resolution |= T30_RESOLUTION_R8_1540 | | 
 | 8350 |             T30_RESOLUTION_R16_1540_OR_400 | T30_RESOLUTION_300_300 | | 
 | 8351 |             T30_RESOLUTION_INCH_BASED | T30_RESOLUTION_METRIC_BASED; | 
 | 8352 |         } | 
 | 8353 |  | 
 | 8354 |  ((T30_INFO *)&nlc[1])->recording_properties = | 
 | 8355 |    T30_RECORDING_WIDTH_ISO_A3 | | 
 | 8356 |    (T30_RECORDING_LENGTH_UNLIMITED << 2) | | 
 | 8357 |    (T30_MIN_SCANLINE_TIME_00_00_00 << 4); | 
 | 8358 |       } | 
 | 8359 |       if(plci->B3_prot == 5) | 
 | 8360 |       { | 
 | 8361 |         if (i & 0x0002) /* Accept incoming fax-polling requests */ | 
 | 8362 |           fax_control_bits |= T30_CONTROL_BIT_ACCEPT_POLLING; | 
 | 8363 |         if (i & 0x2000) /* Do not use MR compression */ | 
 | 8364 |           fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_2D_CODING; | 
 | 8365 |         if (i & 0x4000) /* Do not use MMR compression */ | 
 | 8366 |           fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_T6_CODING; | 
 | 8367 |         if (i & 0x8000) /* Do not use ECM */ | 
 | 8368 |           fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_ECM; | 
 | 8369 |         if (plci->fax_connect_info_length != 0) | 
 | 8370 |         { | 
 | 8371 |           ((T30_INFO *)&nlc[1])->resolution = ((T30_INFO   *)plci->fax_connect_info_buffer)->resolution; | 
 | 8372 |           ((T30_INFO *)&nlc[1])->data_format = ((T30_INFO   *)plci->fax_connect_info_buffer)->data_format; | 
 | 8373 |           ((T30_INFO *)&nlc[1])->recording_properties = ((T30_INFO   *)plci->fax_connect_info_buffer)->recording_properties; | 
 | 8374 |           fax_control_bits |= GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low) & | 
 | 8375 |             (T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS); | 
 | 8376 |         } | 
 | 8377 |       } | 
 | 8378 |       /* copy station id to NLC */ | 
 | 8379 |       for(i=0; i<20; i++) | 
 | 8380 |       { | 
 | 8381 |         if(i<b3_config_parms[2].length) | 
 | 8382 |         { | 
 | 8383 |           ((T30_INFO *)&nlc[1])->station_id[i] = ((byte   *)b3_config_parms[2].info)[1+i]; | 
 | 8384 |         } | 
 | 8385 |         else | 
 | 8386 |         { | 
 | 8387 |           ((T30_INFO *)&nlc[1])->station_id[i] = ' '; | 
 | 8388 |         } | 
 | 8389 |       } | 
 | 8390 |       ((T30_INFO *)&nlc[1])->station_id_len = 20; | 
 | 8391 |       /* copy head line to NLC */ | 
 | 8392 |       if(b3_config_parms[3].length) | 
 | 8393 |       { | 
 | 8394 |  | 
 | 8395 |         pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20]))); | 
 | 8396 |         if (pos != 0) | 
 | 8397 |         { | 
 | 8398 |           if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE) | 
 | 8399 |             pos = 0; | 
 | 8400 |           else | 
 | 8401 |           { | 
 | 8402 |             ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; | 
 | 8403 |             ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; | 
 | 8404 |             len = (byte)b3_config_parms[2].length; | 
 | 8405 |             if (len > 20) | 
 | 8406 |               len = 20; | 
 | 8407 |             if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE) | 
 | 8408 |             { | 
 | 8409 |               for (i = 0; i < len; i++) | 
 | 8410 |                 ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte   *)b3_config_parms[2].info)[1+i]; | 
 | 8411 |               ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; | 
 | 8412 |               ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; | 
 | 8413 |             } | 
 | 8414 |           } | 
 | 8415 |         } | 
 | 8416 |  | 
 | 8417 |         len = (byte)b3_config_parms[3].length; | 
 | 8418 |         if (len > CAPI_MAX_HEAD_LINE_SPACE - pos) | 
 | 8419 |           len = (byte)(CAPI_MAX_HEAD_LINE_SPACE - pos); | 
 | 8420 |         ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len); | 
 | 8421 |         nlc[0] += (byte)(pos + len); | 
 | 8422 |         for (i = 0; i < len; i++) | 
 | 8423 |           ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte   *)b3_config_parms[3].info)[1+i]; | 
 | 8424 |         } | 
 | 8425 |       else | 
 | 8426 |         ((T30_INFO *)&nlc[1])->head_line_len = 0; | 
 | 8427 |  | 
 | 8428 |       plci->nsf_control_bits = 0; | 
 | 8429 |       if(plci->B3_prot == 5) | 
 | 8430 |       { | 
 | 8431 |         if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD)) | 
 | 8432 |          && (GET_WORD((byte   *)b3_config_parms[1].info) & 0x8000)) /* Private SUB/SEP/PWD enable */ | 
 | 8433 |         { | 
 | 8434 |           plci->requested_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD; | 
 | 8435 |         } | 
 | 8436 |         if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD)) | 
 | 8437 |          && (GET_WORD((byte   *)b3_config_parms[1].info) & 0x4000)) /* Private non-standard facilities enable */ | 
 | 8438 |         { | 
 | 8439 |           plci->requested_options |= 1L << PRIVATE_FAX_NONSTANDARD; | 
 | 8440 |         } | 
 | 8441 |         if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) | 
 | 8442 |           & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) | 
 | 8443 |         { | 
 | 8444 |         if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) | 
 | 8445 |           & (1L << PRIVATE_FAX_SUB_SEP_PWD)) | 
 | 8446 |         { | 
 | 8447 |           fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD; | 
 | 8448 |           if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING) | 
 | 8449 |             fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; | 
 | 8450 |           } | 
 | 8451 |             len = nlc[0]; | 
 | 8452 |           pos = ((byte)(((T30_INFO *) 0)->station_id + 20)); | 
 | 8453 |    if (pos < plci->fax_connect_info_length) | 
 | 8454 |    { | 
 | 8455 |      for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) | 
 | 8456 |               nlc[++len] = plci->fax_connect_info_buffer[pos++]; | 
 | 8457 |           } | 
 | 8458 |    else | 
 | 8459 |      nlc[++len] = 0; | 
 | 8460 |    if (pos < plci->fax_connect_info_length) | 
 | 8461 |    { | 
 | 8462 |      for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) | 
 | 8463 |               nlc[++len] = plci->fax_connect_info_buffer[pos++]; | 
 | 8464 |           } | 
 | 8465 |    else | 
 | 8466 |      nlc[++len] = 0; | 
 | 8467 |           if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) | 
 | 8468 |             & (1L << PRIVATE_FAX_NONSTANDARD)) | 
 | 8469 |           { | 
 | 8470 |      if ((pos < plci->fax_connect_info_length) && (plci->fax_connect_info_buffer[pos] != 0)) | 
 | 8471 |      { | 
 | 8472 |               if ((plci->fax_connect_info_buffer[pos] >= 3) && (plci->fax_connect_info_buffer[pos+1] >= 2)) | 
 | 8473 |                 plci->nsf_control_bits = GET_WORD(&plci->fax_connect_info_buffer[pos+2]); | 
 | 8474 |        for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) | 
 | 8475 |                 nlc[++len] = plci->fax_connect_info_buffer[pos++]; | 
 | 8476 |             } | 
 | 8477 |      else | 
 | 8478 |      { | 
 | 8479 |               if(api_parse(&b3_config->info[1], (word)b3_config->length, "wwsss", b3_config_parms)) | 
 | 8480 |               { | 
 | 8481 |                 dbug(1,dprintf("non-standard facilities info missing or wrong format")); | 
 | 8482 |                 nlc[++len] = 0; | 
 | 8483 |               } | 
 | 8484 |        else | 
 | 8485 |        { | 
 | 8486 |                 if ((b3_config_parms[4].length >= 3) && (b3_config_parms[4].info[1] >= 2)) | 
 | 8487 |                   plci->nsf_control_bits = GET_WORD(&b3_config_parms[4].info[2]); | 
 | 8488 |          nlc[++len] = (byte)(b3_config_parms[4].length); | 
 | 8489 |          for (i = 0; i < b3_config_parms[4].length; i++) | 
 | 8490 |     nlc[++len] = b3_config_parms[4].info[1+i]; | 
 | 8491 |        } | 
 | 8492 |             } | 
 | 8493 |           } | 
 | 8494 |             nlc[0] = len; | 
 | 8495 |    if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) | 
 | 8496 |     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) | 
 | 8497 |    { | 
 | 8498 |             ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI_NEG; | 
 | 8499 |           } | 
 | 8500 |         } | 
 | 8501 |       } | 
 | 8502 |  | 
 | 8503 |       PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits); | 
 | 8504 |       len = ((byte)(((T30_INFO *) 0)->station_id + 20)); | 
 | 8505 |       for (i = 0; i < len; i++) | 
 | 8506 |         plci->fax_connect_info_buffer[i] = nlc[1+i]; | 
 | 8507 |       ((T30_INFO   *) plci->fax_connect_info_buffer)->head_line_len = 0; | 
 | 8508 |       i += ((T30_INFO *)&nlc[1])->head_line_len; | 
 | 8509 |       while (i < nlc[0]) | 
 | 8510 |         plci->fax_connect_info_buffer[len++] = nlc[++i]; | 
 | 8511 |       plci->fax_connect_info_length = len; | 
 | 8512 |     } | 
 | 8513 |     else | 
 | 8514 |     { | 
 | 8515 |       nlc[0] = 14; | 
 | 8516 |       if(b3_config->length!=16) | 
 | 8517 |         return _B3_PARM_NOT_SUPPORTED; | 
 | 8518 |       for(i=0; i<12; i++) nlc[1+i] = b3_config->info[1+i]; | 
 | 8519 |       if(GET_WORD(&b3_config->info[13])!=8 && GET_WORD(&b3_config->info[13])!=128) | 
 | 8520 |         return _B3_PARM_NOT_SUPPORTED; | 
 | 8521 |       nlc[13] = b3_config->info[13]; | 
 | 8522 |       if(GET_WORD(&b3_config->info[15])>=nlc[13]) | 
 | 8523 |         return _B3_PARM_NOT_SUPPORTED; | 
 | 8524 |       nlc[14] = b3_config->info[15]; | 
 | 8525 |     } | 
 | 8526 |   } | 
 | 8527 |   else | 
 | 8528 |   { | 
 | 8529 |     if (plci->B3_prot == 4  | 
 | 8530 |      || plci->B3_prot == 5 /*T.30 - FAX*/ ) return _B3_PARM_NOT_SUPPORTED; | 
 | 8531 |   } | 
 | 8532 |   add_p(plci, NLC, nlc); | 
 | 8533 |   return 0; | 
 | 8534 | } | 
 | 8535 |  | 
 | 8536 | /*----------------------------------------------------------------*/ | 
 | 8537 | /*      make the same as add_b23, but only for the modem related  */ | 
 | 8538 | /*      L2 and L3 B-Chan protocol.                                */ | 
 | 8539 | /*                                                                */ | 
 | 8540 | /*      Enabled L2 and L3 Configurations:                         */ | 
 | 8541 | /*        If L1 == Modem all negotiation                          */ | 
 | 8542 | /*          only L2 == Modem with full negotiation is allowed     */ | 
 | 8543 | /*        If L1 == Modem async or sync                            */ | 
 | 8544 | /*          only L2 == Transparent is allowed                     */ | 
 | 8545 | /*        L3 == Modem or L3 == Transparent are allowed            */ | 
 | 8546 | /*      B2 Configuration for modem:                               */ | 
 | 8547 | /*          word : enable/disable compression, bitoptions         */ | 
 | 8548 | /*      B3 Configuration for modem:                               */ | 
 | 8549 | /*          empty                                                 */ | 
 | 8550 | /*----------------------------------------------------------------*/ | 
 | 8551 | static word add_modem_b23 (PLCI  * plci, API_PARSE* bp_parms) | 
 | 8552 | { | 
 | 8553 |   static byte lli[12] = {1,1}; | 
 | 8554 |   static byte llc[3] = {2,0,0}; | 
 | 8555 |   static byte dlc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | 
 | 8556 |     API_PARSE mdm_config[2]; | 
 | 8557 |   word i; | 
 | 8558 |   word b2_config = 0; | 
 | 8559 |  | 
 | 8560 |   for(i=0;i<2;i++) mdm_config[i].length = 0; | 
 | 8561 |   for(i=0;i<sizeof(dlc);i++) dlc[i] = 0; | 
 | 8562 |  | 
 | 8563 |   if (((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) | 
 | 8564 |     && (GET_WORD(bp_parms[1].info) != B2_MODEM_EC_COMPRESSION)) | 
 | 8565 |    || ((GET_WORD(bp_parms[0].info) != B1_MODEM_ALL_NEGOTIATE) | 
 | 8566 |     && (GET_WORD(bp_parms[1].info) != B2_TRANSPARENT))) | 
 | 8567 |   { | 
 | 8568 |     return (_B_STACK_NOT_SUPPORTED); | 
 | 8569 |   } | 
 | 8570 |   if ((GET_WORD(bp_parms[2].info) != B3_MODEM) | 
 | 8571 |    && (GET_WORD(bp_parms[2].info) != B3_TRANSPARENT)) | 
 | 8572 |   { | 
 | 8573 |     return (_B_STACK_NOT_SUPPORTED); | 
 | 8574 |   } | 
 | 8575 |  | 
 | 8576 |   plci->B2_prot = (byte) GET_WORD(bp_parms[1].info); | 
 | 8577 |   plci->B3_prot = (byte) GET_WORD(bp_parms[2].info); | 
 | 8578 |  | 
 | 8579 |   if ((GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) && bp_parms[4].length) | 
 | 8580 |   { | 
 | 8581 |     if (api_parse (&bp_parms[4].info[1], | 
 | 8582 |                   (word)bp_parms[4].length, "w", | 
 | 8583 |                   mdm_config)) | 
 | 8584 |     { | 
 | 8585 |       return (_WRONG_MESSAGE_FORMAT); | 
 | 8586 |     } | 
 | 8587 |     b2_config = GET_WORD(mdm_config[0].info); | 
 | 8588 |   } | 
 | 8589 |  | 
 | 8590 |   /* OK, L2 is modem */ | 
 | 8591 |  | 
 | 8592 |   lli[0] = 1; | 
 | 8593 |   lli[1] = 1; | 
 | 8594 |   if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) | 
 | 8595 |     lli[1] |= 2; | 
 | 8596 |   if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) | 
 | 8597 |     lli[1] |= 4; | 
 | 8598 |  | 
 | 8599 |   if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) { | 
 | 8600 |     lli[1] |= 0x10; | 
 | 8601 |     if (plci->rx_dma_descriptor <= 0) { | 
 | 8602 |       plci->rx_dma_descriptor=diva_get_dma_descriptor(plci,&plci->rx_dma_magic); | 
 | 8603 |       if (plci->rx_dma_descriptor >= 0) | 
 | 8604 |         plci->rx_dma_descriptor++; | 
 | 8605 |     } | 
 | 8606 |     if (plci->rx_dma_descriptor > 0) { | 
 | 8607 |       lli[1] |= 0x40; | 
 | 8608 |       lli[0] = 6; | 
 | 8609 |       lli[2] = (byte)(plci->rx_dma_descriptor - 1); | 
 | 8610 |       lli[3] = (byte)plci->rx_dma_magic; | 
 | 8611 |       lli[4] = (byte)(plci->rx_dma_magic >>  8); | 
 | 8612 |       lli[5] = (byte)(plci->rx_dma_magic >> 16); | 
 | 8613 |       lli[6] = (byte)(plci->rx_dma_magic >> 24); | 
 | 8614 |     } | 
 | 8615 |   } | 
 | 8616 |  | 
 | 8617 |   if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) { | 
 | 8618 |     lli[1] |= 0x20; | 
 | 8619 |   } | 
 | 8620 |  | 
 | 8621 |   llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? | 
 | 8622 |     /*V42*/ 10 : /*V42_IN*/ 9; | 
 | 8623 |   llc[2] = 4;                      /* pass L3 always transparent */ | 
 | 8624 |   add_p(plci, LLI, lli); | 
 | 8625 |   add_p(plci, LLC, llc); | 
 | 8626 |   i =  1; | 
 | 8627 |   PUT_WORD (&dlc[i], plci->appl->MaxDataLength); | 
 | 8628 |   i += 2; | 
 | 8629 |   if (GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) | 
 | 8630 |   { | 
 | 8631 |     if (bp_parms[4].length) | 
 | 8632 |   { | 
 | 8633 |     dbug(1, dprintf("MDM b2_config=%02x", b2_config)); | 
 | 8634 |     dlc[i++] = 3; /* Addr A */ | 
 | 8635 |     dlc[i++] = 1; /* Addr B */ | 
 | 8636 |     dlc[i++] = 7; /* modulo mode */ | 
 | 8637 |     dlc[i++] = 7; /* window size */ | 
 | 8638 |     dlc[i++] = 0; /* XID len Lo  */ | 
 | 8639 |     dlc[i++] = 0; /* XID len Hi  */ | 
 | 8640 |  | 
 | 8641 |     if (b2_config & MDM_B2_DISABLE_V42bis) | 
 | 8642 |     { | 
 | 8643 |       dlc[i] |= DLC_MODEMPROT_DISABLE_V42_V42BIS; | 
 | 8644 |     } | 
 | 8645 |     if (b2_config & MDM_B2_DISABLE_MNP) | 
 | 8646 |     { | 
 | 8647 |       dlc[i] |= DLC_MODEMPROT_DISABLE_MNP_MNP5; | 
 | 8648 |     } | 
 | 8649 |     if (b2_config & MDM_B2_DISABLE_TRANS) | 
 | 8650 |     { | 
 | 8651 |       dlc[i] |= DLC_MODEMPROT_REQUIRE_PROTOCOL; | 
 | 8652 |     } | 
 | 8653 |     if (b2_config & MDM_B2_DISABLE_V42) | 
 | 8654 |     { | 
 | 8655 |       dlc[i] |= DLC_MODEMPROT_DISABLE_V42_DETECT; | 
 | 8656 |     } | 
 | 8657 |     if (b2_config & MDM_B2_DISABLE_COMP) | 
 | 8658 |     { | 
 | 8659 |       dlc[i] |= DLC_MODEMPROT_DISABLE_COMPRESSION; | 
 | 8660 |     } | 
 | 8661 |     i++; | 
 | 8662 |   } | 
 | 8663 |   } | 
 | 8664 |   else | 
 | 8665 |   { | 
 | 8666 |     dlc[i++] = 3; /* Addr A */ | 
 | 8667 |     dlc[i++] = 1; /* Addr B */ | 
 | 8668 |     dlc[i++] = 7; /* modulo mode */ | 
 | 8669 |     dlc[i++] = 7; /* window size */ | 
 | 8670 |     dlc[i++] = 0; /* XID len Lo  */ | 
 | 8671 |     dlc[i++] = 0; /* XID len Hi  */ | 
 | 8672 |     dlc[i++] = DLC_MODEMPROT_DISABLE_V42_V42BIS | | 
 | 8673 |                DLC_MODEMPROT_DISABLE_MNP_MNP5 | | 
 | 8674 |                DLC_MODEMPROT_DISABLE_V42_DETECT | | 
 | 8675 |                DLC_MODEMPROT_DISABLE_COMPRESSION; | 
 | 8676 |   } | 
 | 8677 |   dlc[0] = (byte)(i - 1); | 
 | 8678 | /* HexDump ("DLC", sizeof(dlc), &dlc[0]); */ | 
 | 8679 |   add_p(plci, DLC, dlc); | 
 | 8680 |   return (0); | 
 | 8681 | } | 
 | 8682 |  | 
 | 8683 |  | 
 | 8684 | /*------------------------------------------------------------------*/ | 
 | 8685 | /* send a request for the signaling entity                          */ | 
 | 8686 | /*------------------------------------------------------------------*/ | 
 | 8687 |  | 
 | 8688 | void sig_req(PLCI   * plci, byte req, byte Id) | 
 | 8689 | { | 
 | 8690 |   if(!plci) return; | 
 | 8691 |   if(plci->adapter->adapter_disabled) return; | 
 | 8692 |   dbug(1,dprintf("sig_req(%x)",req)); | 
 | 8693 |   if (req == REMOVE) | 
 | 8694 |     plci->sig_remove_id = plci->Sig.Id; | 
 | 8695 |   if(plci->req_in==plci->req_in_start) { | 
 | 8696 |     plci->req_in +=2; | 
 | 8697 |     plci->RBuffer[plci->req_in++] = 0; | 
 | 8698 |   } | 
 | 8699 |   PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start-2); | 
 | 8700 |   plci->RBuffer[plci->req_in++] = Id;   /* sig/nl flag */ | 
 | 8701 |   plci->RBuffer[plci->req_in++] = req;  /* request */ | 
 | 8702 |   plci->RBuffer[plci->req_in++] = 0;    /* channel */ | 
 | 8703 |   plci->req_in_start = plci->req_in; | 
 | 8704 | } | 
 | 8705 |  | 
 | 8706 | /*------------------------------------------------------------------*/ | 
 | 8707 | /* send a request for the network layer entity                      */ | 
 | 8708 | /*------------------------------------------------------------------*/ | 
 | 8709 |  | 
 | 8710 | void nl_req_ncci(PLCI   * plci, byte req, byte ncci) | 
 | 8711 | { | 
 | 8712 |   if(!plci) return; | 
 | 8713 |   if(plci->adapter->adapter_disabled) return; | 
 | 8714 |   dbug(1,dprintf("nl_req %02x %02x %02x", plci->Id, req, ncci)); | 
 | 8715 |   if (req == REMOVE) | 
 | 8716 |   { | 
 | 8717 |     plci->nl_remove_id = plci->NL.Id; | 
 | 8718 |     ncci_remove (plci, 0, (byte)(ncci != 0)); | 
 | 8719 |     ncci = 0; | 
 | 8720 |   } | 
 | 8721 |   if(plci->req_in==plci->req_in_start) { | 
 | 8722 |     plci->req_in +=2; | 
 | 8723 |     plci->RBuffer[plci->req_in++] = 0; | 
 | 8724 |   } | 
 | 8725 |   PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start-2); | 
 | 8726 |   plci->RBuffer[plci->req_in++] = 1;    /* sig/nl flag */ | 
 | 8727 |   plci->RBuffer[plci->req_in++] = req;  /* request */ | 
 | 8728 |   plci->RBuffer[plci->req_in++] = plci->adapter->ncci_ch[ncci];   /* channel */ | 
 | 8729 |   plci->req_in_start = plci->req_in; | 
 | 8730 | } | 
 | 8731 |  | 
 | 8732 | void send_req(PLCI   * plci) | 
 | 8733 | { | 
 | 8734 |   ENTITY   * e; | 
 | 8735 |   word l; | 
 | 8736 | /*  word i; */ | 
 | 8737 |  | 
 | 8738 |   if(!plci) return; | 
 | 8739 |   if(plci->adapter->adapter_disabled) return; | 
 | 8740 |   channel_xmit_xon (plci); | 
 | 8741 |  | 
 | 8742 |         /* if nothing to do, return */ | 
 | 8743 |   if(plci->req_in==plci->req_out) return; | 
 | 8744 |   dbug(1,dprintf("send_req(in=%d,out=%d)",plci->req_in,plci->req_out)); | 
 | 8745 |  | 
 | 8746 |   if(plci->nl_req || plci->sig_req) return; | 
 | 8747 |  | 
 | 8748 |   l = GET_WORD(&plci->RBuffer[plci->req_out]); | 
 | 8749 |   plci->req_out += 2; | 
 | 8750 |   plci->XData[0].P = &plci->RBuffer[plci->req_out]; | 
 | 8751 |   plci->req_out += l; | 
 | 8752 |   if(plci->RBuffer[plci->req_out]==1) | 
 | 8753 |   { | 
 | 8754 |     e = &plci->NL; | 
 | 8755 |     plci->req_out++; | 
 | 8756 |     e->Req = plci->nl_req = plci->RBuffer[plci->req_out++]; | 
 | 8757 |     e->ReqCh = plci->RBuffer[plci->req_out++]; | 
 | 8758 |     if(!(e->Id & 0x1f)) | 
 | 8759 |     { | 
 | 8760 |       e->Id = NL_ID; | 
 | 8761 |       plci->RBuffer[plci->req_out-4] = CAI; | 
 | 8762 |       plci->RBuffer[plci->req_out-3] = 1; | 
 | 8763 |       plci->RBuffer[plci->req_out-2] = (plci->Sig.Id==0xff) ? 0 : plci->Sig.Id; | 
 | 8764 |       plci->RBuffer[plci->req_out-1] = 0; | 
 | 8765 |       l+=3; | 
 | 8766 |       plci->nl_global_req = plci->nl_req; | 
 | 8767 |     } | 
 | 8768 |     dbug(1,dprintf("%x:NLREQ(%x:%x:%x)",plci->adapter->Id,e->Id,e->Req,e->ReqCh)); | 
 | 8769 |   } | 
 | 8770 |   else | 
 | 8771 |   { | 
 | 8772 |     e = &plci->Sig; | 
 | 8773 |     if(plci->RBuffer[plci->req_out]) | 
 | 8774 |       e->Id = plci->RBuffer[plci->req_out]; | 
 | 8775 |     plci->req_out++; | 
 | 8776 |     e->Req = plci->sig_req = plci->RBuffer[plci->req_out++]; | 
 | 8777 |     e->ReqCh = plci->RBuffer[plci->req_out++]; | 
 | 8778 |     if(!(e->Id & 0x1f)) | 
 | 8779 |       plci->sig_global_req = plci->sig_req; | 
 | 8780 |     dbug(1,dprintf("%x:SIGREQ(%x:%x:%x)",plci->adapter->Id,e->Id,e->Req,e->ReqCh)); | 
 | 8781 |   } | 
 | 8782 |   plci->XData[0].PLength = l; | 
 | 8783 |   e->X = plci->XData; | 
 | 8784 |   plci->adapter->request(e); | 
 | 8785 |   dbug(1,dprintf("send_ok")); | 
 | 8786 | } | 
 | 8787 |  | 
 | 8788 | void send_data(PLCI   * plci) | 
 | 8789 | { | 
 | 8790 |   DIVA_CAPI_ADAPTER   * a; | 
 | 8791 |   DATA_B3_DESC   * data; | 
 | 8792 |   NCCI   *ncci_ptr; | 
 | 8793 |   word ncci; | 
 | 8794 |  | 
 | 8795 |   if (!plci->nl_req && plci->ncci_ring_list) | 
 | 8796 |   { | 
 | 8797 |     a = plci->adapter; | 
 | 8798 |     ncci = plci->ncci_ring_list; | 
 | 8799 |     do | 
 | 8800 |     { | 
 | 8801 |       ncci = a->ncci_next[ncci]; | 
 | 8802 |       ncci_ptr = &(a->ncci[ncci]); | 
 | 8803 |       if (!(a->ncci_ch[ncci] | 
 | 8804 |          && (a->ch_flow_control[a->ncci_ch[ncci]] & N_OK_FC_PENDING))) | 
 | 8805 |       { | 
 | 8806 |         if (ncci_ptr->data_pending) | 
 | 8807 |         { | 
 | 8808 |           if ((a->ncci_state[ncci] == CONNECTED) | 
 | 8809 |            || (a->ncci_state[ncci] == INC_ACT_PENDING) | 
 | 8810 |            || (plci->send_disc == ncci)) | 
 | 8811 |           { | 
 | 8812 |             data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]); | 
 | 8813 |             if ((plci->B2_prot == B2_V120_ASYNC) | 
 | 8814 |              || (plci->B2_prot == B2_V120_ASYNC_V42BIS) | 
 | 8815 |              || (plci->B2_prot == B2_V120_BIT_TRANSPARENT)) | 
 | 8816 |             { | 
 | 8817 |               plci->NData[1].P = TransmitBufferGet (plci->appl, data->P); | 
 | 8818 |               plci->NData[1].PLength = data->Length; | 
 | 8819 |               if (data->Flags & 0x10) | 
 | 8820 |                 plci->NData[0].P = v120_break_header; | 
 | 8821 |               else | 
 | 8822 |                 plci->NData[0].P = v120_default_header; | 
 | 8823 |               plci->NData[0].PLength = 1 ; | 
 | 8824 |               plci->NL.XNum = 2; | 
 | 8825 |               plci->NL.Req = plci->nl_req = (byte)((data->Flags&0x07)<<4 |N_DATA); | 
 | 8826 |             } | 
 | 8827 |             else | 
 | 8828 |             { | 
 | 8829 |               plci->NData[0].P = TransmitBufferGet (plci->appl, data->P); | 
 | 8830 |               plci->NData[0].PLength = data->Length; | 
 | 8831 |               if (data->Flags & 0x10) | 
 | 8832 |                 plci->NL.Req = plci->nl_req = (byte)N_UDATA; | 
 | 8833 |  | 
 | 8834 |               else if ((plci->B3_prot == B3_RTP) && (data->Flags & 0x01)) | 
 | 8835 |                 plci->NL.Req = plci->nl_req = (byte)N_BDATA; | 
 | 8836 |  | 
 | 8837 |               else | 
 | 8838 |                 plci->NL.Req = plci->nl_req = (byte)((data->Flags&0x07)<<4 |N_DATA); | 
 | 8839 |             } | 
 | 8840 |             plci->NL.X = plci->NData; | 
 | 8841 |             plci->NL.ReqCh = a->ncci_ch[ncci]; | 
 | 8842 |             dbug(1,dprintf("%x:DREQ(%x:%x)",a->Id,plci->NL.Id,plci->NL.Req)); | 
 | 8843 |             plci->data_sent = TRUE; | 
 | 8844 |             plci->data_sent_ptr = data->P; | 
 | 8845 |             a->request(&plci->NL); | 
 | 8846 |           } | 
 | 8847 |           else { | 
 | 8848 |             cleanup_ncci_data (plci, ncci); | 
 | 8849 |           } | 
 | 8850 |         } | 
 | 8851 |         else if (plci->send_disc == ncci) | 
 | 8852 |         { | 
 | 8853 |           /* dprintf("N_DISC"); */ | 
 | 8854 |           plci->NData[0].PLength = 0; | 
 | 8855 |           plci->NL.ReqCh = a->ncci_ch[ncci]; | 
 | 8856 |           plci->NL.Req = plci->nl_req = N_DISC; | 
 | 8857 |           a->request(&plci->NL); | 
 | 8858 |           plci->command = _DISCONNECT_B3_R; | 
 | 8859 |           plci->send_disc = 0; | 
 | 8860 |         } | 
 | 8861 |       } | 
 | 8862 |     } while (!plci->nl_req && (ncci != plci->ncci_ring_list)); | 
 | 8863 |     plci->ncci_ring_list = ncci; | 
 | 8864 |   } | 
 | 8865 | } | 
 | 8866 |  | 
 | 8867 | void listen_check(DIVA_CAPI_ADAPTER   * a) | 
 | 8868 | { | 
 | 8869 |   word i,j; | 
 | 8870 |   PLCI   * plci; | 
 | 8871 |   byte activnotifiedcalls = 0; | 
 | 8872 |  | 
 | 8873 |   dbug(1,dprintf("listen_check(%d,%d)",a->listen_active,a->max_listen)); | 
 | 8874 |   if (!remove_started && !a->adapter_disabled) | 
 | 8875 |   { | 
 | 8876 |     for(i=0;i<a->max_plci;i++) | 
 | 8877 |     { | 
 | 8878 |       plci = &(a->plci[i]); | 
 | 8879 |       if(plci->notifiedcall) activnotifiedcalls++; | 
 | 8880 |     } | 
 | 8881 |     dbug(1,dprintf("listen_check(%d)",activnotifiedcalls)); | 
 | 8882 |  | 
 | 8883 |     for(i=a->listen_active; i < ((word)(a->max_listen+activnotifiedcalls)); i++) { | 
 | 8884 |       if((j=get_plci(a))) { | 
 | 8885 |         a->listen_active++; | 
 | 8886 |         plci = &a->plci[j-1]; | 
 | 8887 |         plci->State = LISTENING; | 
 | 8888 |  | 
 | 8889 |         add_p(plci,OAD,"\x01\xfd"); | 
 | 8890 |  | 
 | 8891 |         add_p(plci,KEY,"\x04\x43\x41\x32\x30"); | 
 | 8892 |  | 
 | 8893 |         add_p(plci,CAI,"\x01\xc0"); | 
 | 8894 |         add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 8895 |         add_p(plci,LLI,"\x01\xc4");                  /* support Dummy CR FAC + MWI + SpoofNotify */        | 
 | 8896 |         add_p(plci,SHIFT|6,NULL); | 
 | 8897 |         add_p(plci,SIN,"\x02\x00\x00"); | 
 | 8898 |         plci->internal_command = LISTEN_SIG_ASSIGN_PEND;     /* do indicate_req if OK  */ | 
 | 8899 |         sig_req(plci,ASSIGN,DSIG_ID); | 
 | 8900 |         send_req(plci); | 
 | 8901 |       } | 
 | 8902 |     } | 
 | 8903 |   } | 
 | 8904 | } | 
 | 8905 |  | 
 | 8906 | /*------------------------------------------------------------------*/ | 
 | 8907 | /* functions for all parameters sent in INDs                        */ | 
 | 8908 | /*------------------------------------------------------------------*/ | 
 | 8909 |  | 
 | 8910 | void IndParse(PLCI   * plci, word * parms_id, byte   ** parms, byte multiIEsize) | 
 | 8911 | { | 
 | 8912 |   word ploc;            /* points to current location within packet */ | 
 | 8913 |   byte w; | 
 | 8914 |   byte wlen; | 
 | 8915 |   byte codeset,lock; | 
 | 8916 |   byte   * in; | 
 | 8917 |   word i; | 
 | 8918 |   word code; | 
 | 8919 |   word mIEindex = 0; | 
 | 8920 |   ploc = 0; | 
 | 8921 |   codeset = 0; | 
 | 8922 |   lock = 0; | 
 | 8923 |  | 
 | 8924 |   in = plci->Sig.RBuffer->P; | 
 | 8925 |   for(i=0; i<parms_id[0]; i++)   /* multiIE parms_id contains just the 1st */ | 
 | 8926 |   {                            /* element but parms array is larger      */ | 
 | 8927 |     parms[i] = (byte   *)""; | 
 | 8928 |   } | 
 | 8929 |   for(i=0; i<multiIEsize; i++) | 
 | 8930 |   { | 
 | 8931 |     parms[i] = (byte   *)""; | 
 | 8932 |   } | 
 | 8933 |  | 
 | 8934 |   while(ploc<plci->Sig.RBuffer->length-1) { | 
 | 8935 |  | 
 | 8936 |         /* read information element id and length                   */ | 
 | 8937 |     w = in[ploc]; | 
 | 8938 |  | 
 | 8939 |     if(w & 0x80) { | 
 | 8940 | /*    w &=0xf0; removed, cannot detect congestion levels */ | 
 | 8941 | /*    upper 4 bit masked with w==SHIFT now               */ | 
 | 8942 |       wlen = 0; | 
 | 8943 |     } | 
 | 8944 |     else { | 
 | 8945 |       wlen = (byte)(in[ploc+1]+1); | 
 | 8946 |     } | 
 | 8947 |         /* check if length valid (not exceeding end of packet)      */ | 
 | 8948 |     if((ploc+wlen) > 270) return ; | 
 | 8949 |     if(lock & 0x80) lock &=0x7f; | 
 | 8950 |     else codeset = lock; | 
 | 8951 |  | 
 | 8952 |     if((w&0xf0)==SHIFT) { | 
 | 8953 |       codeset = in[ploc]; | 
 | 8954 |       if(!(codeset & 0x08)) lock = (byte)(codeset & 7); | 
 | 8955 |       codeset &=7; | 
 | 8956 |       lock |=0x80; | 
 | 8957 |     } | 
 | 8958 |     else { | 
 | 8959 |       if(w==ESC && wlen>=3) code = in[ploc+2] |0x800; | 
 | 8960 |       else code = w; | 
 | 8961 |       code |= (codeset<<8); | 
 | 8962 |  | 
 | 8963 |       for(i=1; i<parms_id[0]+1 && parms_id[i]!=code; i++); | 
 | 8964 |  | 
 | 8965 |       if(i<parms_id[0]+1) { | 
 | 8966 |         if(!multiIEsize) { /* with multiIEs use next field index,          */ | 
 | 8967 |           mIEindex = i-1;    /* with normal IEs use same index like parms_id */ | 
 | 8968 |         } | 
 | 8969 |  | 
 | 8970 |         parms[mIEindex] = &in[ploc+1]; | 
 | 8971 |         dbug(1,dprintf("mIE[%d]=0x%x",*parms[mIEindex],in[ploc])); | 
 | 8972 |         if(parms_id[i]==OAD | 
 | 8973 |         || parms_id[i]==CONN_NR | 
 | 8974 |         || parms_id[i]==CAD) { | 
 | 8975 |           if(in[ploc+2] &0x80) { | 
 | 8976 |             in[ploc+0] = (byte)(in[ploc+1]+1); | 
 | 8977 |             in[ploc+1] = (byte)(in[ploc+2] &0x7f); | 
 | 8978 |             in[ploc+2] = 0x80; | 
 | 8979 |             parms[mIEindex] = &in[ploc]; | 
 | 8980 |           } | 
 | 8981 |         } | 
 | 8982 |         mIEindex++;       /* effects multiIEs only */ | 
 | 8983 |       } | 
 | 8984 |     } | 
 | 8985 |  | 
 | 8986 |     ploc +=(wlen+1); | 
 | 8987 |   } | 
 | 8988 |   return ; | 
 | 8989 | } | 
 | 8990 |  | 
 | 8991 | /*------------------------------------------------------------------*/ | 
 | 8992 | /* try to match a cip from received BC and HLC                      */ | 
 | 8993 | /*------------------------------------------------------------------*/ | 
 | 8994 |  | 
 | 8995 | byte ie_compare(byte   * ie1, byte * ie2) | 
 | 8996 | { | 
 | 8997 |   word i; | 
 | 8998 |   if(!ie1 || ! ie2) return FALSE; | 
 | 8999 |   if(!ie1[0]) return FALSE; | 
 | 9000 |   for(i=0;i<(word)(ie1[0]+1);i++) if(ie1[i]!=ie2[i]) return FALSE; | 
 | 9001 |   return TRUE; | 
 | 9002 | } | 
 | 9003 |  | 
 | 9004 | word find_cip(DIVA_CAPI_ADAPTER   * a, byte   * bc, byte   * hlc) | 
 | 9005 | { | 
 | 9006 |   word i; | 
 | 9007 |   word j; | 
 | 9008 |  | 
 | 9009 |   for(i=9;i && !ie_compare(bc,cip_bc[i][a->u_law]);i--); | 
 | 9010 |  | 
 | 9011 |   for(j=16;j<29 && | 
 | 9012 |            (!ie_compare(bc,cip_bc[j][a->u_law]) || !ie_compare(hlc,cip_hlc[j])); j++); | 
 | 9013 |   if(j==29) return i; | 
 | 9014 |   return j; | 
 | 9015 | } | 
 | 9016 |  | 
 | 9017 |  | 
 | 9018 | static byte AddInfo(byte   **add_i, | 
 | 9019 |                     byte   **fty_i, | 
 | 9020 |                     byte   *esc_chi, | 
 | 9021 |                     byte *facility) | 
 | 9022 | { | 
 | 9023 |   byte i; | 
 | 9024 |   byte j; | 
 | 9025 |   byte k; | 
 | 9026 |   byte flen; | 
 | 9027 |   byte len=0; | 
 | 9028 |    /* facility is a nested structure */ | 
 | 9029 |    /* FTY can be more than once      */ | 
 | 9030 |  | 
 | 9031 |   if(esc_chi[0] && !(esc_chi[esc_chi[0]])&0x7f ) | 
 | 9032 |   { | 
 | 9033 |     add_i[0] = (byte   *)"\x02\x02\x00"; /* use neither b nor d channel */ | 
 | 9034 |   } | 
 | 9035 |  | 
 | 9036 |   else | 
 | 9037 |   { | 
 | 9038 |     add_i[0] = (byte   *)""; | 
 | 9039 |   } | 
 | 9040 |   if(!fty_i[0][0]) | 
 | 9041 |   { | 
 | 9042 |     add_i[3] = (byte   *)""; | 
 | 9043 |   } | 
 | 9044 |   else | 
 | 9045 |   {    /* facility array found  */ | 
 | 9046 |     for(i=0,j=1;i<MAX_MULTI_IE && fty_i[i][0];i++) | 
 | 9047 |     { | 
 | 9048 |       dbug(1,dprintf("AddIFac[%d]",fty_i[i][0])); | 
 | 9049 |       len += fty_i[i][0]; | 
 | 9050 |       len += 2; | 
 | 9051 |       flen=fty_i[i][0]; | 
 | 9052 |       facility[j++]=0x1c; /* copy fac IE */ | 
 | 9053 |       for(k=0;k<=flen;k++,j++) | 
 | 9054 |       { | 
 | 9055 |         facility[j]=fty_i[i][k]; | 
 | 9056 | /*      dbug(1,dprintf("%x ",facility[j])); */ | 
 | 9057 |       } | 
 | 9058 |     } | 
 | 9059 |     facility[0] = len; | 
 | 9060 |     add_i[3] = facility; | 
 | 9061 |   } | 
 | 9062 | /*  dbug(1,dprintf("FacArrLen=%d ",len)); */ | 
 | 9063 |   len = add_i[0][0]+add_i[1][0]+add_i[2][0]+add_i[3][0]; | 
 | 9064 |   len += 4;                          /* calculate length of all */ | 
 | 9065 |   return(len); | 
 | 9066 | } | 
 | 9067 |  | 
 | 9068 | /*------------------------------------------------------------------*/ | 
 | 9069 | /* voice and codec features                                         */ | 
 | 9070 | /*------------------------------------------------------------------*/ | 
 | 9071 |  | 
 | 9072 | void SetVoiceChannel(PLCI   *plci, byte   *chi, DIVA_CAPI_ADAPTER   * a) | 
 | 9073 | { | 
 | 9074 |   byte voice_chi[] = "\x02\x18\x01"; | 
 | 9075 |   byte channel; | 
 | 9076 |  | 
 | 9077 |   channel = chi[chi[0]]&0x3; | 
 | 9078 |   dbug(1,dprintf("ExtDevON(Ch=0x%x)",channel)); | 
 | 9079 |   voice_chi[2] = (channel) ? channel : 1; | 
 | 9080 |   add_p(plci,FTY,"\x02\x01\x07");             /* B On, default on 1 */ | 
 | 9081 |   add_p(plci,ESC,voice_chi);                  /* Channel */ | 
 | 9082 |   sig_req(plci,TEL_CTRL,0); | 
 | 9083 |   send_req(plci); | 
 | 9084 |   if(a->AdvSignalPLCI) | 
 | 9085 |   { | 
 | 9086 |     adv_voice_write_coefs (a->AdvSignalPLCI, ADV_VOICE_WRITE_ACTIVATION); | 
 | 9087 |   } | 
 | 9088 | } | 
 | 9089 |  | 
 | 9090 | void VoiceChannelOff(PLCI   *plci) | 
 | 9091 | { | 
 | 9092 |   dbug(1,dprintf("ExtDevOFF")); | 
 | 9093 |   add_p(plci,FTY,"\x02\x01\x08");             /* B Off */ | 
 | 9094 |   sig_req(plci,TEL_CTRL,0); | 
 | 9095 |   send_req(plci); | 
 | 9096 |   if(plci->adapter->AdvSignalPLCI) | 
 | 9097 |   { | 
 | 9098 |     adv_voice_clear_config (plci->adapter->AdvSignalPLCI); | 
 | 9099 |   } | 
 | 9100 | } | 
 | 9101 |  | 
 | 9102 |  | 
 | 9103 | word AdvCodecSupport(DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, byte hook_listen) | 
 | 9104 | { | 
 | 9105 |   word j; | 
 | 9106 |   PLCI   *splci; | 
 | 9107 |  | 
 | 9108 |   /* check if hardware supports handset with hook states (adv.codec) */ | 
 | 9109 |   /* or if just a on board codec is supported                        */ | 
 | 9110 |   /* the advanced codec plci is just for internal use                */ | 
 | 9111 |  | 
 | 9112 |   /* diva Pro with on-board codec:                                   */ | 
 | 9113 |   if(a->profile.Global_Options & HANDSET) | 
 | 9114 |   { | 
 | 9115 |     /* new call, but hook states are already signalled */ | 
 | 9116 |     if(a->AdvCodecFLAG) | 
 | 9117 |     { | 
 | 9118 |       if(a->AdvSignalAppl!=appl || a->AdvSignalPLCI) | 
 | 9119 |       { | 
 | 9120 |         dbug(1,dprintf("AdvSigPlci=0x%x",a->AdvSignalPLCI)); | 
 | 9121 |         return 0x2001; /* codec in use by another application */ | 
 | 9122 |       } | 
 | 9123 |       if(plci!=0) | 
 | 9124 |       { | 
 | 9125 |         a->AdvSignalPLCI = plci; | 
 | 9126 |         plci->tel=ADV_VOICE; | 
 | 9127 |       } | 
 | 9128 |       return 0;                      /* adv codec still used */ | 
 | 9129 |     } | 
 | 9130 |     if((j=get_plci(a))) | 
 | 9131 |     { | 
 | 9132 |       splci = &a->plci[j-1]; | 
 | 9133 |       splci->tel = CODEC_PERMANENT; | 
 | 9134 |       /* hook_listen indicates if a facility_req with handset/hook support */ | 
 | 9135 |       /* was sent. Otherwise if just a call on an external device was made */ | 
 | 9136 |       /* the codec will be used but the hook info will be discarded (just  */ | 
 | 9137 |       /* the external controller is in use                                 */ | 
 | 9138 |       if(hook_listen) splci->State = ADVANCED_VOICE_SIG; | 
 | 9139 |       else | 
 | 9140 |       { | 
 | 9141 |         splci->State = ADVANCED_VOICE_NOSIG; | 
 | 9142 |         if(plci) | 
 | 9143 |         { | 
 | 9144 |           plci->spoofed_msg = SPOOFING_REQUIRED; | 
 | 9145 |         } | 
 | 9146 |                                                /* indicate D-ch connect if  */ | 
 | 9147 |       }                                        /* codec is connected OK     */ | 
 | 9148 |       if(plci!=0) | 
 | 9149 |       { | 
 | 9150 |         a->AdvSignalPLCI = plci; | 
 | 9151 |         plci->tel=ADV_VOICE; | 
 | 9152 |       } | 
 | 9153 |       a->AdvSignalAppl = appl; | 
 | 9154 |       a->AdvCodecFLAG = TRUE; | 
 | 9155 |       a->AdvCodecPLCI = splci; | 
 | 9156 |       add_p(splci,CAI,"\x01\x15"); | 
 | 9157 |       add_p(splci,LLI,"\x01\x00"); | 
 | 9158 |       add_p(splci,ESC,"\x02\x18\x00"); | 
 | 9159 |       add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 9160 |       splci->internal_command = PERM_COD_ASSIGN; | 
 | 9161 |       dbug(1,dprintf("Codec Assign")); | 
 | 9162 |       sig_req(splci,ASSIGN,DSIG_ID); | 
 | 9163 |       send_req(splci); | 
 | 9164 |     } | 
 | 9165 |     else | 
 | 9166 |     { | 
 | 9167 |       return 0x2001; /* wrong state, no more plcis */ | 
 | 9168 |     } | 
 | 9169 |   } | 
 | 9170 |   else if(a->profile.Global_Options & ON_BOARD_CODEC) | 
 | 9171 |   { | 
 | 9172 |     if(hook_listen) return 0x300B;               /* Facility not supported */ | 
 | 9173 |                                                  /* no hook with SCOM      */ | 
 | 9174 |     if(plci!=0) plci->tel = CODEC; | 
 | 9175 |     dbug(1,dprintf("S/SCOM codec")); | 
 | 9176 |     /* first time we use the scom-s codec we must shut down the internal   */ | 
 | 9177 |     /* handset application of the card. This can be done by an assign with */ | 
 | 9178 |     /* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/ | 
 | 9179 |     if(!a->scom_appl_disable){ | 
 | 9180 |       if((j=get_plci(a))) { | 
 | 9181 |         splci = &a->plci[j-1]; | 
 | 9182 |         add_p(splci,CAI,"\x01\x80"); | 
 | 9183 |         add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 9184 |         sig_req(splci,ASSIGN,0xC0);  /* 0xc0 is the TEL_ID */ | 
 | 9185 |         send_req(splci); | 
 | 9186 |         a->scom_appl_disable = TRUE; | 
 | 9187 |       } | 
 | 9188 |       else{ | 
 | 9189 |         return 0x2001; /* wrong state, no more plcis */ | 
 | 9190 |       } | 
 | 9191 |     } | 
 | 9192 |   } | 
 | 9193 |   else return 0x300B;               /* Facility not supported */ | 
 | 9194 |  | 
 | 9195 |   return 0; | 
 | 9196 | } | 
 | 9197 |  | 
 | 9198 |  | 
 | 9199 | void CodecIdCheck(DIVA_CAPI_ADAPTER   *a, PLCI   *plci) | 
 | 9200 | { | 
 | 9201 |  | 
 | 9202 |   dbug(1,dprintf("CodecIdCheck")); | 
 | 9203 |  | 
 | 9204 |   if(a->AdvSignalPLCI == plci) | 
 | 9205 |   { | 
 | 9206 |     dbug(1,dprintf("PLCI owns codec")); | 
 | 9207 |     VoiceChannelOff(a->AdvCodecPLCI); | 
 | 9208 |     if(a->AdvCodecPLCI->State == ADVANCED_VOICE_NOSIG) | 
 | 9209 |     { | 
 | 9210 |       dbug(1,dprintf("remove temp codec PLCI")); | 
 | 9211 |       plci_remove(a->AdvCodecPLCI); | 
 | 9212 |       a->AdvCodecFLAG  = 0; | 
 | 9213 |       a->AdvCodecPLCI  = NULL; | 
 | 9214 |       a->AdvSignalAppl = NULL; | 
 | 9215 |     } | 
 | 9216 |     a->AdvSignalPLCI = NULL; | 
 | 9217 |   } | 
 | 9218 | } | 
 | 9219 |  | 
 | 9220 | /* ------------------------------------------------------------------- | 
 | 9221 |     Ask for physical address of card on PCI bus | 
 | 9222 |    ------------------------------------------------------------------- */ | 
 | 9223 | static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER  * a, | 
 | 9224 |                                         IDI_SYNC_REQ  * preq) { | 
 | 9225 |   a->sdram_bar = 0; | 
 | 9226 |   if (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR) { | 
 | 9227 |     ENTITY   * e = (ENTITY   *)preq; | 
 | 9228 |  | 
 | 9229 |     e->user[0] = a->Id - 1; | 
 | 9230 |     preq->xdi_sdram_bar.info.bar    = 0; | 
 | 9231 |     preq->xdi_sdram_bar.Req         = 0; | 
 | 9232 |     preq->xdi_sdram_bar.Rc           = IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR; | 
 | 9233 |  | 
 | 9234 |     (*(a->request))(e); | 
 | 9235 |  | 
 | 9236 |     a->sdram_bar = preq->xdi_sdram_bar.info.bar; | 
 | 9237 |     dbug(3,dprintf("A(%d) SDRAM BAR = %08x", a->Id, a->sdram_bar)); | 
 | 9238 |   } | 
 | 9239 | } | 
 | 9240 |  | 
 | 9241 | /* ------------------------------------------------------------------- | 
 | 9242 |      Ask XDI about extended features | 
 | 9243 |    ------------------------------------------------------------------- */ | 
 | 9244 | static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER  * a) { | 
 | 9245 |   IDI_SYNC_REQ   * preq; | 
 | 9246 |     char buffer[              ((sizeof(preq->xdi_extended_features)+4) > sizeof(ENTITY)) ?                     (sizeof(preq->xdi_extended_features)+4) : sizeof(ENTITY)]; | 
 | 9247 |  | 
 | 9248 |     char features[4]; | 
 | 9249 |   preq = (IDI_SYNC_REQ   *)&buffer[0]; | 
 | 9250 |  | 
 | 9251 |   if (!diva_xdi_extended_features) { | 
 | 9252 |     ENTITY   * e = (ENTITY   *)preq; | 
 | 9253 |     diva_xdi_extended_features |= 0x80000000; | 
 | 9254 |  | 
 | 9255 |     e->user[0] = a->Id - 1; | 
 | 9256 |     preq->xdi_extended_features.Req = 0; | 
 | 9257 |     preq->xdi_extended_features.Rc  = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES; | 
 | 9258 |     preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features); | 
 | 9259 |     preq->xdi_extended_features.info.features = &features[0]; | 
 | 9260 |  | 
 | 9261 |     (*(a->request))(e); | 
 | 9262 |  | 
 | 9263 |     if (features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) { | 
 | 9264 |       /* | 
 | 9265 |          Check features located in the byte '0' | 
 | 9266 |          */ | 
 | 9267 |       if (features[0] & DIVA_XDI_EXTENDED_FEATURE_CMA) { | 
 | 9268 |         diva_xdi_extended_features |= DIVA_CAPI_USE_CMA; | 
 | 9269 |       } | 
 | 9270 |       if (features[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA) { | 
 | 9271 |         diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_RX_DMA; | 
 | 9272 |         dbug(1,dprintf("XDI provides RxDMA")); | 
 | 9273 |       } | 
 | 9274 |       if (features[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR) { | 
 | 9275 |         diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR; | 
 | 9276 |       } | 
 | 9277 |       if (features[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC) { | 
 | 9278 |         diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL; | 
 | 9279 |         dbug(3,dprintf("XDI provides NO_CANCEL_RC feature")); | 
 | 9280 |       } | 
 | 9281 |  | 
 | 9282 |     } | 
 | 9283 |   } | 
 | 9284 |  | 
 | 9285 |   diva_ask_for_xdi_sdram_bar (a, preq); | 
 | 9286 | } | 
 | 9287 |  | 
 | 9288 | /*------------------------------------------------------------------*/ | 
 | 9289 | /* automatic law                                                    */ | 
 | 9290 | /*------------------------------------------------------------------*/ | 
 | 9291 | /* called from OS specific part after init time to get the Law              */ | 
 | 9292 | /* a-law (Euro) and u-law (us,japan) use different BCs in the Setup message */ | 
 | 9293 | void AutomaticLaw(DIVA_CAPI_ADAPTER   *a) | 
 | 9294 | { | 
 | 9295 |   word j; | 
 | 9296 |   PLCI   *splci; | 
 | 9297 |  | 
 | 9298 |   if(a->automatic_law) { | 
 | 9299 |     return; | 
 | 9300 |   } | 
 | 9301 |   if((j=get_plci(a))) { | 
 | 9302 |     diva_get_extended_adapter_features (a); | 
 | 9303 |     splci = &a->plci[j-1]; | 
 | 9304 |     a->automatic_lawPLCI = splci; | 
 | 9305 |     a->automatic_law = 1; | 
 | 9306 |     add_p(splci,CAI,"\x01\x80"); | 
 | 9307 |     add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 9308 |     splci->internal_command = USELAW_REQ; | 
 | 9309 |     splci->command = 0; | 
 | 9310 |     splci->number = 0; | 
 | 9311 |     sig_req(splci,ASSIGN,DSIG_ID); | 
 | 9312 |     send_req(splci); | 
 | 9313 |   } | 
 | 9314 | } | 
 | 9315 |  | 
 | 9316 | /* called from OS specific part if an application sends an Capi20Release */ | 
 | 9317 | word CapiRelease(word Id) | 
 | 9318 | { | 
 | 9319 |   word i, j, appls_found; | 
 | 9320 |   PLCI   *plci; | 
 | 9321 |   APPL   *this; | 
 | 9322 |   DIVA_CAPI_ADAPTER   *a; | 
 | 9323 |  | 
 | 9324 |   if (!Id) | 
 | 9325 |   { | 
 | 9326 |     dbug(0,dprintf("A: CapiRelease(Id==0)")); | 
 | 9327 |     return (_WRONG_APPL_ID); | 
 | 9328 |   } | 
 | 9329 |  | 
 | 9330 |   this = &application[Id-1];               /* get application pointer */ | 
 | 9331 |  | 
 | 9332 |   for(i=0,appls_found=0; i<max_appl; i++) | 
 | 9333 |   { | 
 | 9334 |     if(application[i].Id)       /* an application has been found        */ | 
 | 9335 |     { | 
 | 9336 |       appls_found++; | 
 | 9337 |     } | 
 | 9338 |   } | 
 | 9339 |  | 
 | 9340 |   for(i=0; i<max_adapter; i++)             /* scan all adapters...    */ | 
 | 9341 |   { | 
 | 9342 |     a = &adapter[i]; | 
 | 9343 |     if (a->request) | 
 | 9344 |     { | 
 | 9345 |       a->Info_Mask[Id-1] = 0; | 
 | 9346 |       a->CIP_Mask[Id-1] = 0; | 
 | 9347 |       a->Notification_Mask[Id-1] = 0; | 
 | 9348 |       a->codec_listen[Id-1] = NULL; | 
 | 9349 |       a->requested_options_table[Id-1] = 0; | 
 | 9350 |       for(j=0; j<a->max_plci; j++)           /* and all PLCIs connected */ | 
 | 9351 |       {                                      /* with this application   */ | 
 | 9352 |         plci = &a->plci[j]; | 
 | 9353 |         if(plci->Id)                         /* if plci owns no application */ | 
 | 9354 |         {                                    /* it may be not jet connected */ | 
 | 9355 |           if(plci->State==INC_CON_PENDING | 
 | 9356 |           || plci->State==INC_CON_ALERT) | 
 | 9357 |           { | 
 | 9358 |             if(test_c_ind_mask_bit (plci, (word)(Id-1))) | 
 | 9359 |             { | 
 | 9360 |               clear_c_ind_mask_bit (plci, (word)(Id-1)); | 
 | 9361 |               if(c_ind_mask_empty (plci)) | 
 | 9362 |               { | 
 | 9363 |                 sig_req(plci,HANGUP,0); | 
 | 9364 |                 send_req(plci); | 
 | 9365 |                 plci->State = OUTG_DIS_PENDING; | 
 | 9366 |               } | 
 | 9367 |             } | 
 | 9368 |           } | 
 | 9369 |           if(test_c_ind_mask_bit (plci, (word)(Id-1))) | 
 | 9370 |           { | 
 | 9371 |             clear_c_ind_mask_bit (plci, (word)(Id-1)); | 
 | 9372 |             if(c_ind_mask_empty (plci)) | 
 | 9373 |             { | 
 | 9374 |               if(!plci->appl) | 
 | 9375 |               { | 
 | 9376 |                 plci_remove(plci); | 
 | 9377 |                 plci->State = IDLE; | 
 | 9378 |               } | 
 | 9379 |             } | 
 | 9380 |           } | 
 | 9381 |           if(plci->appl==this) | 
 | 9382 |           { | 
 | 9383 |             plci->appl = NULL; | 
 | 9384 |             plci_remove(plci); | 
 | 9385 |             plci->State = IDLE; | 
 | 9386 |           } | 
 | 9387 |         } | 
 | 9388 |       } | 
 | 9389 |       listen_check(a); | 
 | 9390 |  | 
 | 9391 |       if(a->flag_dynamic_l1_down) | 
 | 9392 |       { | 
 | 9393 |         if(appls_found==1)            /* last application does a capi release */ | 
 | 9394 |         { | 
 | 9395 |           if((j=get_plci(a))) | 
 | 9396 |           { | 
 | 9397 |             plci = &a->plci[j-1]; | 
 | 9398 |             plci->command = 0; | 
 | 9399 |             add_p(plci,OAD,"\x01\xfd"); | 
 | 9400 |             add_p(plci,CAI,"\x01\x80"); | 
 | 9401 |             add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 9402 |             add_p(plci,SHIFT|6,NULL); | 
 | 9403 |             add_p(plci,SIN,"\x02\x00\x00"); | 
 | 9404 |             plci->internal_command = REM_L1_SIG_ASSIGN_PEND; | 
 | 9405 |             sig_req(plci,ASSIGN,DSIG_ID); | 
 | 9406 |             add_p(plci,FTY,"\x02\xff\x06"); /* l1 down */ | 
 | 9407 |             sig_req(plci,SIG_CTRL,0); | 
 | 9408 |             send_req(plci); | 
 | 9409 |           } | 
 | 9410 |         } | 
 | 9411 |       } | 
 | 9412 |       if(a->AdvSignalAppl==this) | 
 | 9413 |       { | 
 | 9414 |         this->NullCREnable = FALSE; | 
 | 9415 |         if (a->AdvCodecPLCI) | 
 | 9416 |         { | 
 | 9417 |           plci_remove(a->AdvCodecPLCI); | 
 | 9418 |           a->AdvCodecPLCI->tel = 0; | 
 | 9419 |           a->AdvCodecPLCI->adv_nl = 0; | 
 | 9420 |         } | 
 | 9421 |         a->AdvSignalAppl = NULL; | 
 | 9422 |         a->AdvSignalPLCI = NULL; | 
 | 9423 |         a->AdvCodecFLAG = 0; | 
 | 9424 |         a->AdvCodecPLCI = NULL; | 
 | 9425 |       } | 
 | 9426 |     } | 
 | 9427 |   } | 
 | 9428 |  | 
 | 9429 |   this->Id = 0; | 
 | 9430 |  | 
 | 9431 |   return GOOD; | 
 | 9432 | } | 
 | 9433 |  | 
 | 9434 | static word plci_remove_check(PLCI   *plci) | 
 | 9435 | { | 
 | 9436 |   if(!plci) return TRUE; | 
 | 9437 |   if(!plci->NL.Id && c_ind_mask_empty (plci)) | 
 | 9438 |   { | 
 | 9439 |     if(plci->Sig.Id == 0xff) | 
 | 9440 |       plci->Sig.Id = 0; | 
 | 9441 |     if(!plci->Sig.Id) | 
 | 9442 |     { | 
 | 9443 |       dbug(1,dprintf("plci_remove_complete(%x)",plci->Id)); | 
 | 9444 |       dbug(1,dprintf("tel=0x%x,Sig=0x%x",plci->tel,plci->Sig.Id)); | 
 | 9445 |       if (plci->Id) | 
 | 9446 |       { | 
 | 9447 |         CodecIdCheck(plci->adapter, plci); | 
 | 9448 |         clear_b1_config (plci); | 
 | 9449 |         ncci_remove (plci, 0, FALSE); | 
 | 9450 |         plci_free_msg_in_queue (plci); | 
 | 9451 |         channel_flow_control_remove (plci); | 
 | 9452 |         plci->Id = 0; | 
 | 9453 |         plci->State = IDLE; | 
 | 9454 |         plci->channels = 0; | 
 | 9455 |         plci->appl = NULL; | 
 | 9456 |         plci->notifiedcall = 0; | 
 | 9457 |       } | 
 | 9458 |       listen_check(plci->adapter); | 
 | 9459 |       return TRUE; | 
 | 9460 |     } | 
 | 9461 |   } | 
 | 9462 |   return FALSE; | 
 | 9463 | } | 
 | 9464 |  | 
 | 9465 |  | 
 | 9466 | /*------------------------------------------------------------------*/ | 
 | 9467 |  | 
 | 9468 | static byte plci_nl_busy (PLCI   *plci) | 
 | 9469 | { | 
 | 9470 |   /* only applicable for non-multiplexed protocols */ | 
 | 9471 |   return (plci->nl_req | 
 | 9472 |     || (plci->ncci_ring_list | 
 | 9473 |      && plci->adapter->ncci_ch[plci->ncci_ring_list] | 
 | 9474 |      && (plci->adapter->ch_flow_control[plci->adapter->ncci_ch[plci->ncci_ring_list]] & N_OK_FC_PENDING))); | 
 | 9475 | } | 
 | 9476 |  | 
 | 9477 |  | 
 | 9478 | /*------------------------------------------------------------------*/ | 
 | 9479 | /* DTMF facilities                                                  */ | 
 | 9480 | /*------------------------------------------------------------------*/ | 
 | 9481 |  | 
 | 9482 |  | 
 | 9483 | static struct | 
 | 9484 | { | 
 | 9485 |   byte send_mask; | 
 | 9486 |   byte listen_mask; | 
 | 9487 |   byte character; | 
 | 9488 |   byte code; | 
 | 9489 | } dtmf_digit_map[] = | 
 | 9490 | { | 
 | 9491 |   { 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK }, | 
 | 9492 |   { 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR }, | 
 | 9493 |   { 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0 }, | 
 | 9494 |   { 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1 }, | 
 | 9495 |   { 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2 }, | 
 | 9496 |   { 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3 }, | 
 | 9497 |   { 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4 }, | 
 | 9498 |   { 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5 }, | 
 | 9499 |   { 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6 }, | 
 | 9500 |   { 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7 }, | 
 | 9501 |   { 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8 }, | 
 | 9502 |   { 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9 }, | 
 | 9503 |   { 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A }, | 
 | 9504 |   { 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B }, | 
 | 9505 |   { 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C }, | 
 | 9506 |   { 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D }, | 
 | 9507 |   { 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A }, | 
 | 9508 |   { 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B }, | 
 | 9509 |   { 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C }, | 
 | 9510 |   { 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D }, | 
 | 9511 |  | 
 | 9512 |   { 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE }, | 
 | 9513 |   { 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE }, | 
 | 9514 |   { 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE }, | 
 | 9515 |   { 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE }, | 
 | 9516 |   { 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE }, | 
 | 9517 |   { 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE }, | 
 | 9518 |   { 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE }, | 
 | 9519 |   { 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE }, | 
 | 9520 |   { 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE }, | 
 | 9521 |   { 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE }, | 
 | 9522 |   { 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE }, | 
 | 9523 |   { 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE }, | 
 | 9524 |   { 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE }, | 
 | 9525 |   { 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE }, | 
 | 9526 |   { 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE }, | 
 | 9527 |   { 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE }, | 
 | 9528 |   { 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE }, | 
 | 9529 |   { 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE }, | 
 | 9530 |   { 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE }, | 
 | 9531 |   { 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE }, | 
 | 9532 |   { 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE }, | 
 | 9533 |   { 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE }, | 
 | 9534 |   { 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE }, | 
 | 9535 |   { 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL }, | 
 | 9536 |   { 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE }, | 
 | 9537 |   { 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE }, | 
 | 9538 |   { 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE }, | 
 | 9539 |   { 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE }, | 
 | 9540 |   { 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE }, | 
 | 9541 |   { 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE }, | 
 | 9542 |   { 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE }, | 
 | 9543 |   { 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE }, | 
 | 9544 |   { 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE }, | 
 | 9545 |   { 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS }, | 
 | 9546 |   { 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID }, | 
 | 9547 |   { 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH }, | 
 | 9548 |   { 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390 }, | 
 | 9549 |   { 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1 }, | 
 | 9550 |   { 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2 }, | 
 | 9551 |   { 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3 }, | 
 | 9552 |   { 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4 }, | 
 | 9553 |   { 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5 }, | 
 | 9554 |   { 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6 }, | 
 | 9555 |   { 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7 }, | 
 | 9556 |   { 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8 }, | 
 | 9557 |   { 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9 }, | 
 | 9558 |   { 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0 }, | 
 | 9559 |   { 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1 }, | 
 | 9560 |   { 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2 }, | 
 | 9561 |   { 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP }, | 
 | 9562 |   { 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1 }, | 
 | 9563 |   { 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST }, | 
 | 9564 |  | 
 | 9565 | }; | 
 | 9566 |  | 
 | 9567 | #define DTMF_DIGIT_MAP_ENTRIES (sizeof(dtmf_digit_map) / sizeof(dtmf_digit_map[0])) | 
 | 9568 |  | 
 | 9569 |  | 
 | 9570 | static void dtmf_enable_receiver (PLCI   *plci, byte enable_mask) | 
 | 9571 | { | 
 | 9572 |   word min_digit_duration, min_gap_duration; | 
 | 9573 |  | 
 | 9574 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_enable_receiver %02x", | 
 | 9575 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 9576 |     (char   *)(FILE_), __LINE__, enable_mask)); | 
 | 9577 |  | 
 | 9578 |   if (enable_mask != 0) | 
 | 9579 |   { | 
 | 9580 |     min_digit_duration = (plci->dtmf_rec_pulse_ms == 0) ? 40 : plci->dtmf_rec_pulse_ms; | 
 | 9581 |     min_gap_duration = (plci->dtmf_rec_pause_ms == 0) ? 40 : plci->dtmf_rec_pause_ms; | 
 | 9582 |     plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER; | 
 | 9583 |     PUT_WORD (&plci->internal_req_buffer[1], min_digit_duration); | 
 | 9584 |     PUT_WORD (&plci->internal_req_buffer[3], min_gap_duration); | 
 | 9585 |     plci->NData[0].PLength = 5; | 
 | 9586 |  | 
 | 9587 |     PUT_WORD (&plci->internal_req_buffer[5], INTERNAL_IND_BUFFER_SIZE); | 
 | 9588 |     plci->NData[0].PLength += 2; | 
 | 9589 |     capidtmf_recv_enable (&(plci->capidtmf_state), min_digit_duration, min_gap_duration); | 
 | 9590 |  | 
 | 9591 |   } | 
 | 9592 |   else | 
 | 9593 |   { | 
 | 9594 |     plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER; | 
 | 9595 |     plci->NData[0].PLength = 1; | 
 | 9596 |  | 
 | 9597 |     capidtmf_recv_disable (&(plci->capidtmf_state)); | 
 | 9598 |  | 
 | 9599 |   } | 
 | 9600 |   plci->NData[0].P = plci->internal_req_buffer; | 
 | 9601 |   plci->NL.X = plci->NData; | 
 | 9602 |   plci->NL.ReqCh = 0; | 
 | 9603 |   plci->NL.Req = plci->nl_req = (byte) N_UDATA; | 
 | 9604 |   plci->adapter->request (&plci->NL); | 
 | 9605 | } | 
 | 9606 |  | 
 | 9607 |  | 
 | 9608 | static void dtmf_send_digits (PLCI   *plci, byte   *digit_buffer, word digit_count) | 
 | 9609 | { | 
 | 9610 |   word w, i; | 
 | 9611 |  | 
 | 9612 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_digits %d", | 
 | 9613 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 9614 |     (char   *)(FILE_), __LINE__, digit_count)); | 
 | 9615 |  | 
 | 9616 |   plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_SEND_DIGITS; | 
 | 9617 |   w = (plci->dtmf_send_pulse_ms == 0) ? 40 : plci->dtmf_send_pulse_ms; | 
 | 9618 |   PUT_WORD (&plci->internal_req_buffer[1], w); | 
 | 9619 |   w = (plci->dtmf_send_pause_ms == 0) ? 40 : plci->dtmf_send_pause_ms; | 
 | 9620 |   PUT_WORD (&plci->internal_req_buffer[3], w); | 
 | 9621 |   for (i = 0; i < digit_count; i++) | 
 | 9622 |   { | 
 | 9623 |     w = 0; | 
 | 9624 |     while ((w < DTMF_DIGIT_MAP_ENTRIES) | 
 | 9625 |       && (digit_buffer[i] != dtmf_digit_map[w].character)) | 
 | 9626 |     { | 
 | 9627 |       w++; | 
 | 9628 |     } | 
 | 9629 |     plci->internal_req_buffer[5+i] = (w < DTMF_DIGIT_MAP_ENTRIES) ? | 
 | 9630 |       dtmf_digit_map[w].code : DTMF_DIGIT_TONE_CODE_STAR; | 
 | 9631 |   } | 
 | 9632 |   plci->NData[0].PLength = 5 + digit_count; | 
 | 9633 |   plci->NData[0].P = plci->internal_req_buffer; | 
 | 9634 |   plci->NL.X = plci->NData; | 
 | 9635 |   plci->NL.ReqCh = 0; | 
 | 9636 |   plci->NL.Req = plci->nl_req = (byte) N_UDATA; | 
 | 9637 |   plci->adapter->request (&plci->NL); | 
 | 9638 | } | 
 | 9639 |  | 
 | 9640 |  | 
 | 9641 | static void dtmf_rec_clear_config (PLCI   *plci) | 
 | 9642 | { | 
 | 9643 |  | 
 | 9644 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_rec_clear_config", | 
 | 9645 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 9646 |     (char   *)(FILE_), __LINE__)); | 
 | 9647 |  | 
 | 9648 |   plci->dtmf_rec_active = 0; | 
 | 9649 |   plci->dtmf_rec_pulse_ms = 0; | 
 | 9650 |   plci->dtmf_rec_pause_ms = 0; | 
 | 9651 |  | 
 | 9652 |   capidtmf_init (&(plci->capidtmf_state), plci->adapter->u_law); | 
 | 9653 |  | 
 | 9654 | } | 
 | 9655 |  | 
 | 9656 |  | 
 | 9657 | static void dtmf_send_clear_config (PLCI   *plci) | 
 | 9658 | { | 
 | 9659 |  | 
 | 9660 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_clear_config", | 
 | 9661 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 9662 |     (char   *)(FILE_), __LINE__)); | 
 | 9663 |  | 
 | 9664 |   plci->dtmf_send_requests = 0; | 
 | 9665 |   plci->dtmf_send_pulse_ms = 0; | 
 | 9666 |   plci->dtmf_send_pause_ms = 0; | 
 | 9667 | } | 
 | 9668 |  | 
 | 9669 |  | 
 | 9670 | static void dtmf_prepare_switch (dword Id, PLCI   *plci) | 
 | 9671 | { | 
 | 9672 |  | 
 | 9673 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_prepare_switch", | 
 | 9674 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9675 |  | 
 | 9676 |   while (plci->dtmf_send_requests != 0) | 
 | 9677 |     dtmf_confirmation (Id, plci); | 
 | 9678 | } | 
 | 9679 |  | 
 | 9680 |  | 
 | 9681 | static word dtmf_save_config (dword Id, PLCI   *plci, byte Rc) | 
 | 9682 | { | 
 | 9683 |  | 
 | 9684 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_save_config %02x %d", | 
 | 9685 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 9686 |  | 
 | 9687 |   return (GOOD); | 
 | 9688 | } | 
 | 9689 |  | 
 | 9690 |  | 
 | 9691 | static word dtmf_restore_config (dword Id, PLCI   *plci, byte Rc) | 
 | 9692 | { | 
 | 9693 |   word Info; | 
 | 9694 |  | 
 | 9695 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_restore_config %02x %d", | 
 | 9696 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 9697 |  | 
 | 9698 |   Info = GOOD; | 
 | 9699 |   if (plci->B1_facilities & B1_FACILITY_DTMFR) | 
 | 9700 |   { | 
 | 9701 |     switch (plci->adjust_b_state) | 
 | 9702 |     { | 
 | 9703 |     case ADJUST_B_RESTORE_DTMF_1: | 
 | 9704 |       plci->internal_command = plci->adjust_b_command; | 
 | 9705 |       if (plci_nl_busy (plci)) | 
 | 9706 |       { | 
 | 9707 |         plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; | 
 | 9708 |         break; | 
 | 9709 |       } | 
 | 9710 |       dtmf_enable_receiver (plci, plci->dtmf_rec_active); | 
 | 9711 |       plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_2; | 
 | 9712 |       break; | 
 | 9713 |     case ADJUST_B_RESTORE_DTMF_2: | 
 | 9714 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 9715 |       { | 
 | 9716 |         dbug (1, dprintf ("[%06lx] %s,%d: Reenable DTMF receiver failed %02x", | 
 | 9717 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 9718 |         Info = _WRONG_STATE; | 
 | 9719 |         break; | 
 | 9720 |       } | 
 | 9721 |       break; | 
 | 9722 |     } | 
 | 9723 |   } | 
 | 9724 |   return (Info); | 
 | 9725 | } | 
 | 9726 |  | 
 | 9727 |  | 
 | 9728 | static void dtmf_command (dword Id, PLCI   *plci, byte Rc) | 
 | 9729 | { | 
 | 9730 |   word internal_command, Info; | 
 | 9731 |   byte mask; | 
 | 9732 |     byte result[4]; | 
 | 9733 |  | 
 | 9734 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d", | 
 | 9735 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command, | 
 | 9736 |     plci->dtmf_cmd, plci->dtmf_rec_pulse_ms, plci->dtmf_rec_pause_ms, | 
 | 9737 |     plci->dtmf_send_pulse_ms, plci->dtmf_send_pause_ms)); | 
 | 9738 |  | 
 | 9739 |   Info = GOOD; | 
 | 9740 |   result[0] = 2; | 
 | 9741 |   PUT_WORD (&result[1], DTMF_SUCCESS); | 
 | 9742 |   internal_command = plci->internal_command; | 
 | 9743 |   plci->internal_command = 0; | 
 | 9744 |   mask = 0x01; | 
 | 9745 |   switch (plci->dtmf_cmd) | 
 | 9746 |   { | 
 | 9747 |  | 
 | 9748 |   case DTMF_LISTEN_TONE_START: | 
 | 9749 |     mask <<= 1; | 
 | 9750 |   case DTMF_LISTEN_MF_START: | 
 | 9751 |     mask <<= 1; | 
 | 9752 |  | 
 | 9753 |   case DTMF_LISTEN_START: | 
 | 9754 |     switch (internal_command) | 
 | 9755 |     { | 
 | 9756 |     default: | 
 | 9757 |       adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities | | 
 | 9758 |         B1_FACILITY_DTMFR), DTMF_COMMAND_1); | 
 | 9759 |     case DTMF_COMMAND_1: | 
 | 9760 |       if (adjust_b_process (Id, plci, Rc) != GOOD) | 
 | 9761 |       { | 
 | 9762 |         dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed", | 
 | 9763 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9764 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 9765 |         break; | 
 | 9766 |       } | 
 | 9767 |       if (plci->internal_command) | 
 | 9768 |         return; | 
 | 9769 |     case DTMF_COMMAND_2: | 
 | 9770 |       if (plci_nl_busy (plci)) | 
 | 9771 |       { | 
 | 9772 |         plci->internal_command = DTMF_COMMAND_2; | 
 | 9773 |         return; | 
 | 9774 |       } | 
 | 9775 |       plci->internal_command = DTMF_COMMAND_3; | 
 | 9776 |       dtmf_enable_receiver (plci, (byte)(plci->dtmf_rec_active | mask)); | 
 | 9777 |       return; | 
 | 9778 |     case DTMF_COMMAND_3: | 
 | 9779 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 9780 |       { | 
 | 9781 |         dbug (1, dprintf ("[%06lx] %s,%d: Enable DTMF receiver failed %02x", | 
 | 9782 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 9783 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 9784 |         break; | 
 | 9785 |       } | 
 | 9786 |  | 
 | 9787 |       plci->tone_last_indication_code = DTMF_SIGNAL_NO_TONE; | 
 | 9788 |  | 
 | 9789 |       plci->dtmf_rec_active |= mask; | 
 | 9790 |       break; | 
 | 9791 |     } | 
 | 9792 |     break; | 
 | 9793 |  | 
 | 9794 |  | 
 | 9795 |   case DTMF_LISTEN_TONE_STOP: | 
 | 9796 |     mask <<= 1; | 
 | 9797 |   case DTMF_LISTEN_MF_STOP: | 
 | 9798 |     mask <<= 1; | 
 | 9799 |  | 
 | 9800 |   case DTMF_LISTEN_STOP: | 
 | 9801 |     switch (internal_command) | 
 | 9802 |     { | 
 | 9803 |     default: | 
 | 9804 |       plci->dtmf_rec_active &= ~mask; | 
 | 9805 |       if (plci->dtmf_rec_active) | 
 | 9806 |         break; | 
 | 9807 | /* | 
 | 9808 |     case DTMF_COMMAND_1: | 
 | 9809 |       if (plci->dtmf_rec_active) | 
 | 9810 |       { | 
 | 9811 |         if (plci_nl_busy (plci)) | 
 | 9812 |         { | 
 | 9813 |           plci->internal_command = DTMF_COMMAND_1; | 
 | 9814 |           return; | 
 | 9815 |         } | 
 | 9816 |         plci->dtmf_rec_active &= ~mask; | 
 | 9817 |         plci->internal_command = DTMF_COMMAND_2; | 
 | 9818 |         dtmf_enable_receiver (plci, FALSE); | 
 | 9819 |         return; | 
 | 9820 |       } | 
 | 9821 |       Rc = OK; | 
 | 9822 |     case DTMF_COMMAND_2: | 
 | 9823 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 9824 |       { | 
 | 9825 |         dbug (1, dprintf ("[%06lx] %s,%d: Disable DTMF receiver failed %02x", | 
 | 9826 |           UnMapId (Id), (char far *)(FILE_), __LINE__, Rc)); | 
 | 9827 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 9828 |         break; | 
 | 9829 |       } | 
 | 9830 | */ | 
 | 9831 |       adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities & | 
 | 9832 |         ~(B1_FACILITY_DTMFX | B1_FACILITY_DTMFR)), DTMF_COMMAND_3); | 
 | 9833 |     case DTMF_COMMAND_3: | 
 | 9834 |       if (adjust_b_process (Id, plci, Rc) != GOOD) | 
 | 9835 |       { | 
 | 9836 |         dbug (1, dprintf ("[%06lx] %s,%d: Unload DTMF failed", | 
 | 9837 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9838 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 9839 |         break; | 
 | 9840 |       } | 
 | 9841 |       if (plci->internal_command) | 
 | 9842 |         return; | 
 | 9843 |       break; | 
 | 9844 |     } | 
 | 9845 |     break; | 
 | 9846 |  | 
 | 9847 |  | 
 | 9848 |   case DTMF_SEND_TONE: | 
 | 9849 |     mask <<= 1; | 
 | 9850 |   case DTMF_SEND_MF: | 
 | 9851 |     mask <<= 1; | 
 | 9852 |  | 
 | 9853 |   case DTMF_DIGITS_SEND: | 
 | 9854 |     switch (internal_command) | 
 | 9855 |     { | 
 | 9856 |     default: | 
 | 9857 |       adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities | | 
 | 9858 |         ((plci->dtmf_parameter_length != 0) ? B1_FACILITY_DTMFX | B1_FACILITY_DTMFR : B1_FACILITY_DTMFX)), | 
 | 9859 |         DTMF_COMMAND_1); | 
 | 9860 |     case DTMF_COMMAND_1: | 
 | 9861 |       if (adjust_b_process (Id, plci, Rc) != GOOD) | 
 | 9862 |       { | 
 | 9863 |         dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed", | 
 | 9864 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9865 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 9866 |         break; | 
 | 9867 |       } | 
 | 9868 |       if (plci->internal_command) | 
 | 9869 |         return; | 
 | 9870 |     case DTMF_COMMAND_2: | 
 | 9871 |       if (plci_nl_busy (plci)) | 
 | 9872 |       { | 
 | 9873 |         plci->internal_command = DTMF_COMMAND_2; | 
 | 9874 |         return; | 
 | 9875 |       } | 
 | 9876 |       plci->dtmf_msg_number_queue[(plci->dtmf_send_requests)++] = plci->number; | 
 | 9877 |       plci->internal_command = DTMF_COMMAND_3; | 
 | 9878 |       dtmf_send_digits (plci, &plci->saved_msg.parms[3].info[1], plci->saved_msg.parms[3].length); | 
 | 9879 |       return; | 
 | 9880 |     case DTMF_COMMAND_3: | 
 | 9881 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 9882 |       { | 
 | 9883 |         dbug (1, dprintf ("[%06lx] %s,%d: Send DTMF digits failed %02x", | 
 | 9884 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 9885 |         if (plci->dtmf_send_requests != 0) | 
 | 9886 |           (plci->dtmf_send_requests)--; | 
 | 9887 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 9888 |         break; | 
 | 9889 |       } | 
 | 9890 |       return; | 
 | 9891 |     } | 
 | 9892 |     break; | 
 | 9893 |   } | 
 | 9894 |   sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number, | 
 | 9895 |     "wws", Info, SELECTOR_DTMF, result); | 
 | 9896 | } | 
 | 9897 |  | 
 | 9898 |  | 
 | 9899 | static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg) | 
 | 9900 | { | 
 | 9901 |   word Info; | 
 | 9902 |   word i, j; | 
 | 9903 |   byte mask; | 
 | 9904 |     API_PARSE dtmf_parms[5]; | 
 | 9905 |     byte result[40]; | 
 | 9906 |  | 
 | 9907 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_request", | 
 | 9908 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9909 |  | 
 | 9910 |   Info = GOOD; | 
 | 9911 |   result[0] = 2; | 
 | 9912 |   PUT_WORD (&result[1], DTMF_SUCCESS); | 
 | 9913 |   if (!(a->profile.Global_Options & GL_DTMF_SUPPORTED)) | 
 | 9914 |   { | 
 | 9915 |     dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported", | 
 | 9916 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9917 |     Info = _FACILITY_NOT_SUPPORTED; | 
 | 9918 |   } | 
 | 9919 |   else if (api_parse (&msg[1].info[1], msg[1].length, "w", dtmf_parms)) | 
 | 9920 |   { | 
 | 9921 |     dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 9922 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9923 |     Info = _WRONG_MESSAGE_FORMAT; | 
 | 9924 |   } | 
 | 9925 |  | 
 | 9926 |   else if ((GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES) | 
 | 9927 |     || (GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_SEND_CODES)) | 
 | 9928 |   { | 
 | 9929 |     if (!((a->requested_options_table[appl->Id-1]) | 
 | 9930 |         & (1L << PRIVATE_DTMF_TONE))) | 
 | 9931 |     { | 
 | 9932 |       dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x", | 
 | 9933 |         UnMapId (Id), (char   *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info))); | 
 | 9934 |       PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST); | 
 | 9935 |     } | 
 | 9936 |     else | 
 | 9937 |     { | 
 | 9938 |       for (i = 0; i < 32; i++) | 
 | 9939 |         result[4 + i] = 0; | 
 | 9940 |       if (GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES) | 
 | 9941 |       { | 
 | 9942 |         for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++) | 
 | 9943 |         { | 
 | 9944 |           if (dtmf_digit_map[i].listen_mask != 0) | 
 | 9945 |             result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7)); | 
 | 9946 |         } | 
 | 9947 |       } | 
 | 9948 |       else | 
 | 9949 |       { | 
 | 9950 |         for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++) | 
 | 9951 |         { | 
 | 9952 |           if (dtmf_digit_map[i].send_mask != 0) | 
 | 9953 |             result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7)); | 
 | 9954 |         } | 
 | 9955 |       } | 
 | 9956 |       result[0] = 3 + 32; | 
 | 9957 |       result[3] = 32; | 
 | 9958 |     } | 
 | 9959 |   } | 
 | 9960 |  | 
 | 9961 |   else if (plci == NULL) | 
 | 9962 |   { | 
 | 9963 |     dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI", | 
 | 9964 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9965 |     Info = _WRONG_IDENTIFIER; | 
 | 9966 |   } | 
 | 9967 |   else | 
 | 9968 |   { | 
 | 9969 |     if (!plci->State | 
 | 9970 |      || !plci->NL.Id || plci->nl_remove_id) | 
 | 9971 |     { | 
 | 9972 |       dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", | 
 | 9973 |         UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 9974 |       Info = _WRONG_STATE; | 
 | 9975 |     } | 
 | 9976 |     else | 
 | 9977 |     { | 
 | 9978 |       plci->command = 0; | 
 | 9979 |       plci->dtmf_cmd = GET_WORD (dtmf_parms[0].info); | 
 | 9980 |       mask = 0x01; | 
 | 9981 |       switch (plci->dtmf_cmd) | 
 | 9982 |       { | 
 | 9983 |  | 
 | 9984 |       case DTMF_LISTEN_TONE_START: | 
 | 9985 |       case DTMF_LISTEN_TONE_STOP: | 
 | 9986 |         mask <<= 1; | 
 | 9987 |       case DTMF_LISTEN_MF_START: | 
 | 9988 |       case DTMF_LISTEN_MF_STOP: | 
 | 9989 |         mask <<= 1; | 
 | 9990 |         if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id-1]) | 
 | 9991 |           & (1L << PRIVATE_DTMF_TONE))) | 
 | 9992 |         { | 
 | 9993 |           dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x", | 
 | 9994 |             UnMapId (Id), (char   *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info))); | 
 | 9995 |           PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST); | 
 | 9996 |           break; | 
 | 9997 |         } | 
 | 9998 |  | 
 | 9999 |       case DTMF_LISTEN_START: | 
 | 10000 |       case DTMF_LISTEN_STOP: | 
 | 10001 |         if (!(a->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF) | 
 | 10002 |          && !(a->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) | 
 | 10003 |         { | 
 | 10004 |           dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported", | 
 | 10005 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 10006 |           Info = _FACILITY_NOT_SUPPORTED; | 
 | 10007 |           break; | 
 | 10008 |         } | 
 | 10009 |         if (mask & DTMF_LISTEN_ACTIVE_FLAG) | 
 | 10010 |         { | 
 | 10011 |           if (api_parse (&msg[1].info[1], msg[1].length, "wwws", dtmf_parms)) | 
 | 10012 |           { | 
 | 10013 |             plci->dtmf_rec_pulse_ms = 0; | 
 | 10014 |             plci->dtmf_rec_pause_ms = 0; | 
 | 10015 |           } | 
 | 10016 |           else | 
 | 10017 |           { | 
 | 10018 |             plci->dtmf_rec_pulse_ms = GET_WORD (dtmf_parms[1].info); | 
 | 10019 |             plci->dtmf_rec_pause_ms = GET_WORD (dtmf_parms[2].info); | 
 | 10020 |           } | 
 | 10021 |         } | 
 | 10022 |         start_internal_command (Id, plci, dtmf_command); | 
 | 10023 |         return (FALSE); | 
 | 10024 |  | 
 | 10025 |  | 
 | 10026 |       case DTMF_SEND_TONE: | 
 | 10027 |         mask <<= 1; | 
 | 10028 |       case DTMF_SEND_MF: | 
 | 10029 |         mask <<= 1; | 
 | 10030 |         if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id-1]) | 
 | 10031 |           & (1L << PRIVATE_DTMF_TONE))) | 
 | 10032 |         { | 
 | 10033 |           dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x", | 
 | 10034 |             UnMapId (Id), (char   *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info))); | 
 | 10035 |           PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST); | 
 | 10036 |           break; | 
 | 10037 |         } | 
 | 10038 |  | 
 | 10039 |       case DTMF_DIGITS_SEND: | 
 | 10040 |         if (api_parse (&msg[1].info[1], msg[1].length, "wwws", dtmf_parms)) | 
 | 10041 |         { | 
 | 10042 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 10043 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 10044 |           Info = _WRONG_MESSAGE_FORMAT; | 
 | 10045 |           break; | 
 | 10046 |         } | 
 | 10047 |         if (mask & DTMF_LISTEN_ACTIVE_FLAG) | 
 | 10048 |         { | 
 | 10049 |           plci->dtmf_send_pulse_ms = GET_WORD (dtmf_parms[1].info); | 
 | 10050 |           plci->dtmf_send_pause_ms = GET_WORD (dtmf_parms[2].info); | 
 | 10051 |         } | 
 | 10052 |         i = 0; | 
 | 10053 |         j = 0; | 
 | 10054 |         while ((i < dtmf_parms[3].length) && (j < DTMF_DIGIT_MAP_ENTRIES)) | 
 | 10055 |         { | 
 | 10056 |           j = 0; | 
 | 10057 |           while ((j < DTMF_DIGIT_MAP_ENTRIES) | 
 | 10058 |             && ((dtmf_parms[3].info[i+1] != dtmf_digit_map[j].character) | 
 | 10059 |              || ((dtmf_digit_map[j].send_mask & mask) == 0))) | 
 | 10060 |           { | 
 | 10061 |             j++; | 
 | 10062 |           } | 
 | 10063 |           i++; | 
 | 10064 |         } | 
 | 10065 |         if (j == DTMF_DIGIT_MAP_ENTRIES) | 
 | 10066 |         { | 
 | 10067 |           dbug (1, dprintf ("[%06lx] %s,%d: Incorrect DTMF digit %02x", | 
 | 10068 |             UnMapId (Id), (char   *)(FILE_), __LINE__, dtmf_parms[3].info[i])); | 
 | 10069 |           PUT_WORD (&result[1], DTMF_INCORRECT_DIGIT); | 
 | 10070 |           break; | 
 | 10071 |         } | 
 | 10072 |         if (plci->dtmf_send_requests >= | 
 | 10073 |           sizeof(plci->dtmf_msg_number_queue) / sizeof(plci->dtmf_msg_number_queue[0])) | 
 | 10074 |         { | 
 | 10075 |           dbug (1, dprintf ("[%06lx] %s,%d: DTMF request overrun", | 
 | 10076 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 10077 |           Info = _WRONG_STATE; | 
 | 10078 |           break; | 
 | 10079 |         } | 
 | 10080 |         api_save_msg (dtmf_parms, "wwws", &plci->saved_msg); | 
 | 10081 |         start_internal_command (Id, plci, dtmf_command); | 
 | 10082 |         return (FALSE); | 
 | 10083 |  | 
 | 10084 |       default: | 
 | 10085 |         dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x", | 
 | 10086 |           UnMapId (Id), (char   *)(FILE_), __LINE__, plci->dtmf_cmd)); | 
 | 10087 |         PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST); | 
 | 10088 |       } | 
 | 10089 |     } | 
 | 10090 |   } | 
 | 10091 |   sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, | 
 | 10092 |     "wws", Info, SELECTOR_DTMF, result); | 
 | 10093 |   return (FALSE); | 
 | 10094 | } | 
 | 10095 |  | 
 | 10096 |  | 
 | 10097 | static void dtmf_confirmation (dword Id, PLCI   *plci) | 
 | 10098 | { | 
 | 10099 |   word Info; | 
 | 10100 |   word i; | 
 | 10101 |     byte result[4]; | 
 | 10102 |  | 
 | 10103 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation", | 
 | 10104 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 10105 |  | 
 | 10106 |   Info = GOOD; | 
 | 10107 |   result[0] = 2; | 
 | 10108 |   PUT_WORD (&result[1], DTMF_SUCCESS); | 
 | 10109 |   if (plci->dtmf_send_requests != 0) | 
 | 10110 |   { | 
 | 10111 |     sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->dtmf_msg_number_queue[0], | 
 | 10112 |       "wws", GOOD, SELECTOR_DTMF, result); | 
 | 10113 |     (plci->dtmf_send_requests)--; | 
 | 10114 |     for (i = 0; i < plci->dtmf_send_requests; i++) | 
 | 10115 |       plci->dtmf_msg_number_queue[i] = plci->dtmf_msg_number_queue[i+1];       | 
 | 10116 |   } | 
 | 10117 | } | 
 | 10118 |  | 
 | 10119 |  | 
 | 10120 | static void dtmf_indication (dword Id, PLCI   *plci, byte   *msg, word length) | 
 | 10121 | { | 
 | 10122 |   word i, j, n; | 
 | 10123 |  | 
 | 10124 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_indication", | 
 | 10125 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 10126 |  | 
 | 10127 |   n = 0; | 
 | 10128 |   for (i = 1; i < length; i++) | 
 | 10129 |   { | 
 | 10130 |     j = 0; | 
 | 10131 |     while ((j < DTMF_DIGIT_MAP_ENTRIES) | 
 | 10132 |       && ((msg[i] != dtmf_digit_map[j].code) | 
 | 10133 |        || ((dtmf_digit_map[j].listen_mask & plci->dtmf_rec_active) == 0))) | 
 | 10134 |     { | 
 | 10135 |       j++; | 
 | 10136 |     } | 
 | 10137 |     if (j < DTMF_DIGIT_MAP_ENTRIES) | 
 | 10138 |     { | 
 | 10139 |  | 
 | 10140 |       if ((dtmf_digit_map[j].listen_mask & DTMF_TONE_LISTEN_ACTIVE_FLAG) | 
 | 10141 |        && (plci->tone_last_indication_code == DTMF_SIGNAL_NO_TONE) | 
 | 10142 |        && (dtmf_digit_map[j].character != DTMF_SIGNAL_UNIDENTIFIED_TONE)) | 
 | 10143 |       { | 
 | 10144 |         if (n + 1 == i) | 
 | 10145 |         { | 
 | 10146 |           for (i = length; i > n + 1; i--) | 
 | 10147 |             msg[i] = msg[i - 1]; | 
 | 10148 |           length++; | 
 | 10149 |           i++; | 
 | 10150 |         } | 
 | 10151 |         msg[++n] = DTMF_SIGNAL_UNIDENTIFIED_TONE; | 
 | 10152 |       } | 
 | 10153 |       plci->tone_last_indication_code = dtmf_digit_map[j].character; | 
 | 10154 |  | 
 | 10155 |       msg[++n] = dtmf_digit_map[j].character; | 
 | 10156 |     } | 
 | 10157 |   } | 
 | 10158 |   if (n != 0) | 
 | 10159 |   { | 
 | 10160 |     msg[0] = (byte) n; | 
 | 10161 |     sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "wS", SELECTOR_DTMF, msg); | 
 | 10162 |   } | 
 | 10163 | } | 
 | 10164 |  | 
 | 10165 |  | 
 | 10166 | /*------------------------------------------------------------------*/ | 
 | 10167 | /* DTMF parameters                                                  */ | 
 | 10168 | /*------------------------------------------------------------------*/ | 
 | 10169 |  | 
 | 10170 | static void dtmf_parameter_write (PLCI   *plci) | 
 | 10171 | { | 
 | 10172 |   word i; | 
 | 10173 |     byte parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE + 2]; | 
 | 10174 |  | 
 | 10175 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_write", | 
 | 10176 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 10177 |     (char   *)(FILE_), __LINE__)); | 
 | 10178 |  | 
 | 10179 |   parameter_buffer[0] = plci->dtmf_parameter_length + 1; | 
 | 10180 |   parameter_buffer[1] = DSP_CTRL_SET_DTMF_PARAMETERS; | 
 | 10181 |   for (i = 0; i < plci->dtmf_parameter_length; i++) | 
 | 10182 |     parameter_buffer[2+i] = plci->dtmf_parameter_buffer[i]; | 
 | 10183 |   add_p (plci, FTY, parameter_buffer); | 
 | 10184 |   sig_req (plci, TEL_CTRL, 0); | 
 | 10185 |   send_req (plci); | 
 | 10186 | } | 
 | 10187 |  | 
 | 10188 |  | 
 | 10189 | static void dtmf_parameter_clear_config (PLCI   *plci) | 
 | 10190 | { | 
 | 10191 |  | 
 | 10192 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_clear_config", | 
 | 10193 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 10194 |     (char   *)(FILE_), __LINE__)); | 
 | 10195 |  | 
 | 10196 |   plci->dtmf_parameter_length = 0; | 
 | 10197 | } | 
 | 10198 |  | 
 | 10199 |  | 
 | 10200 | static void dtmf_parameter_prepare_switch (dword Id, PLCI   *plci) | 
 | 10201 | { | 
 | 10202 |  | 
 | 10203 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_prepare_switch", | 
 | 10204 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 10205 |  | 
 | 10206 | } | 
 | 10207 |  | 
 | 10208 |  | 
 | 10209 | static word dtmf_parameter_save_config (dword Id, PLCI   *plci, byte Rc) | 
 | 10210 | { | 
 | 10211 |  | 
 | 10212 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d", | 
 | 10213 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 10214 |  | 
 | 10215 |   return (GOOD); | 
 | 10216 | } | 
 | 10217 |  | 
 | 10218 |  | 
 | 10219 | static word dtmf_parameter_restore_config (dword Id, PLCI   *plci, byte Rc) | 
 | 10220 | { | 
 | 10221 |   word Info; | 
 | 10222 |  | 
 | 10223 |   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d", | 
 | 10224 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 10225 |  | 
 | 10226 |   Info = GOOD; | 
 | 10227 |   if ((plci->B1_facilities & B1_FACILITY_DTMFR) | 
 | 10228 |    && (plci->dtmf_parameter_length != 0)) | 
 | 10229 |   { | 
 | 10230 |     switch (plci->adjust_b_state) | 
 | 10231 |     { | 
 | 10232 |     case ADJUST_B_RESTORE_DTMF_PARAMETER_1: | 
 | 10233 |       plci->internal_command = plci->adjust_b_command; | 
 | 10234 |       if (plci->sig_req) | 
 | 10235 |       { | 
 | 10236 |         plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1; | 
 | 10237 |         break; | 
 | 10238 |       } | 
 | 10239 |       dtmf_parameter_write (plci); | 
 | 10240 |       plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_2; | 
 | 10241 |       break; | 
 | 10242 |     case ADJUST_B_RESTORE_DTMF_PARAMETER_2: | 
 | 10243 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 10244 |       { | 
 | 10245 |         dbug (1, dprintf ("[%06lx] %s,%d: Restore DTMF parameters failed %02x", | 
 | 10246 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 10247 |         Info = _WRONG_STATE; | 
 | 10248 |         break; | 
 | 10249 |       } | 
 | 10250 |       break; | 
 | 10251 |     } | 
 | 10252 |   } | 
 | 10253 |   return (Info); | 
 | 10254 | } | 
 | 10255 |  | 
 | 10256 |  | 
 | 10257 | /*------------------------------------------------------------------*/ | 
 | 10258 | /* Line interconnect facilities                                     */ | 
 | 10259 | /*------------------------------------------------------------------*/ | 
 | 10260 |  | 
 | 10261 |  | 
 | 10262 | LI_CONFIG   *li_config_table; | 
 | 10263 | word li_total_channels; | 
 | 10264 |  | 
 | 10265 |  | 
 | 10266 | /*------------------------------------------------------------------*/ | 
 | 10267 | /* translate a CHI information element to a channel number          */ | 
 | 10268 | /* returns 0xff - any channel                                       */ | 
 | 10269 | /*         0xfe - chi wrong coding                                  */ | 
 | 10270 | /*         0xfd - D-channel                                         */ | 
 | 10271 | /*         0x00 - no channel                                        */ | 
 | 10272 | /*         else channel number / PRI: timeslot                      */ | 
 | 10273 | /* if channels is provided we accept more than one channel.         */ | 
 | 10274 | /*------------------------------------------------------------------*/ | 
 | 10275 |  | 
 | 10276 | static byte chi_to_channel (byte   *chi, dword *pchannelmap) | 
 | 10277 | { | 
 | 10278 |   int p; | 
 | 10279 |   int i; | 
 | 10280 |   dword map; | 
 | 10281 |   byte excl; | 
 | 10282 |   byte ofs; | 
 | 10283 |   byte ch; | 
 | 10284 |  | 
 | 10285 |   if (pchannelmap) *pchannelmap = 0; | 
 | 10286 |   if(!chi[0]) return 0xff; | 
 | 10287 |   excl = 0; | 
 | 10288 |  | 
 | 10289 |   if(chi[1] & 0x20) { | 
 | 10290 |     if(chi[0]==1 && chi[1]==0xac) return 0xfd; /* exclusive d-channel */ | 
 | 10291 |     for(i=1; i<chi[0] && !(chi[i] &0x80); i++); | 
 | 10292 |     if(i==chi[0] || !(chi[i] &0x80)) return 0xfe; | 
 | 10293 |     if((chi[1] |0xc8)!=0xe9) return 0xfe; | 
 | 10294 |     if(chi[1] &0x08) excl = 0x40; | 
 | 10295 |  | 
 | 10296 |         /* int. id present */ | 
 | 10297 |     if(chi[1] &0x40) { | 
 | 10298 |       p=i+1; | 
 | 10299 |       for(i=p; i<chi[0] && !(chi[i] &0x80); i++); | 
 | 10300 |       if(i==chi[0] || !(chi[i] &0x80)) return 0xfe; | 
 | 10301 |     } | 
 | 10302 |  | 
 | 10303 |         /* coding standard, Number/Map, Channel Type */ | 
 | 10304 |     p=i+1; | 
 | 10305 |     for(i=p; i<chi[0] && !(chi[i] &0x80); i++); | 
 | 10306 |     if(i==chi[0] || !(chi[i] &0x80)) return 0xfe; | 
 | 10307 |     if((chi[p]|0xd0)!=0xd3) return 0xfe; | 
 | 10308 |  | 
 | 10309 |         /* Number/Map */ | 
 | 10310 |     if(chi[p] &0x10) { | 
 | 10311 |  | 
 | 10312 |         /* map */ | 
 | 10313 |       if((chi[0]-p)==4) ofs = 0; | 
 | 10314 |       else if((chi[0]-p)==3) ofs = 1; | 
 | 10315 |       else return 0xfe; | 
 | 10316 |       ch = 0; | 
 | 10317 |       map = 0; | 
 | 10318 |       for(i=0; i<4 && p<chi[0]; i++) { | 
 | 10319 |         p++; | 
 | 10320 |         ch += 8; | 
 | 10321 |         map <<= 8; | 
 | 10322 |         if(chi[p]) { | 
 | 10323 |           for (ch=0; !(chi[p] & (1 << ch)); ch++); | 
 | 10324 |           map |= chi[p]; | 
 | 10325 |         } | 
 | 10326 |       } | 
 | 10327 |       ch += ofs; | 
 | 10328 |       map <<= ofs; | 
 | 10329 |     } | 
 | 10330 |     else { | 
 | 10331 |  | 
 | 10332 |         /* number */ | 
 | 10333 |       p=i+1; | 
 | 10334 |       ch = chi[p] &0x3f; | 
 | 10335 |       if(pchannelmap) { | 
 | 10336 |         if((byte)(chi[0]-p)>30) return 0xfe; | 
 | 10337 |         map = 0; | 
 | 10338 |         for(i=p; i<=chi[0]; i++) { | 
 | 10339 |           if ((chi[i] &0x7f) > 31) return 0xfe; | 
 | 10340 |           map |= (1L << (chi[i] &0x7f)); | 
 | 10341 |         } | 
 | 10342 |       } | 
 | 10343 |       else { | 
 | 10344 |         if(p!=chi[0]) return 0xfe; | 
 | 10345 |         if (ch > 31) return 0xfe; | 
 | 10346 |         map = (1L << ch); | 
 | 10347 |       } | 
 | 10348 |       if(chi[p] &0x40) return 0xfe; | 
 | 10349 |     } | 
 | 10350 |     if (pchannelmap) *pchannelmap = map; | 
 | 10351 |     else if (map != ((dword)(1L << ch))) return 0xfe; | 
 | 10352 |     return (byte)(excl | ch); | 
 | 10353 |   } | 
 | 10354 |   else {  /* not PRI */ | 
 | 10355 |     for(i=1; i<chi[0] && !(chi[i] &0x80); i++); | 
 | 10356 |     if(i!=chi[0] || !(chi[i] &0x80)) return 0xfe; | 
 | 10357 |     if(chi[1] &0x08) excl = 0x40; | 
 | 10358 |  | 
 | 10359 |     switch(chi[1] |0x98) { | 
 | 10360 |     case 0x98: return 0; | 
 | 10361 |     case 0x99: | 
 | 10362 |       if (pchannelmap) *pchannelmap = 2; | 
 | 10363 |       return excl |1; | 
 | 10364 |     case 0x9a: | 
 | 10365 |       if (pchannelmap) *pchannelmap = 4; | 
 | 10366 |       return excl |2; | 
 | 10367 |     case 0x9b: return 0xff; | 
 | 10368 |     case 0x9c: return 0xfd; /* d-ch */ | 
 | 10369 |     default: return 0xfe; | 
 | 10370 |     } | 
 | 10371 |   } | 
 | 10372 | } | 
 | 10373 |  | 
 | 10374 |  | 
 | 10375 | static void mixer_set_bchannel_id_esc (PLCI   *plci, byte bchannel_id) | 
 | 10376 | { | 
 | 10377 |   DIVA_CAPI_ADAPTER   *a; | 
 | 10378 |   PLCI   *splci; | 
 | 10379 |   byte old_id; | 
 | 10380 |  | 
 | 10381 |   a = plci->adapter; | 
 | 10382 |   old_id = plci->li_bchannel_id; | 
 | 10383 |   if (a->li_pri) | 
 | 10384 |   { | 
 | 10385 |     if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) | 
 | 10386 |       li_config_table[a->li_base + (old_id - 1)].plci = NULL; | 
 | 10387 |     plci->li_bchannel_id = (bchannel_id & 0x1f) + 1; | 
 | 10388 |     if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) | 
 | 10389 |       li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; | 
 | 10390 |   } | 
 | 10391 |   else | 
 | 10392 |   { | 
 | 10393 |     if (((bchannel_id & 0x03) == 1) || ((bchannel_id & 0x03) == 2)) | 
 | 10394 |     { | 
 | 10395 |       if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) | 
 | 10396 |         li_config_table[a->li_base + (old_id - 1)].plci = NULL; | 
 | 10397 |       plci->li_bchannel_id = bchannel_id & 0x03; | 
 | 10398 |       if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE)) | 
 | 10399 |       { | 
 | 10400 |         splci = a->AdvSignalPLCI; | 
 | 10401 |         if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL) | 
 | 10402 |         { | 
 | 10403 |           if ((splci->li_bchannel_id != 0) | 
 | 10404 |            && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci)) | 
 | 10405 |           { | 
 | 10406 |             li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL; | 
 | 10407 |           } | 
 | 10408 |           splci->li_bchannel_id = 3 - plci->li_bchannel_id; | 
 | 10409 |           li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci; | 
 | 10410 |           dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d", | 
 | 10411 |             (dword)((splci->Id << 8) | UnMapController (splci->adapter->Id)), | 
 | 10412 |             (char   *)(FILE_), __LINE__, splci->li_bchannel_id)); | 
 | 10413 |         } | 
 | 10414 |       } | 
 | 10415 |       if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) | 
 | 10416 |         li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; | 
 | 10417 |     } | 
 | 10418 |   } | 
 | 10419 |   if ((old_id == 0) && (plci->li_bchannel_id != 0) | 
 | 10420 |    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 10421 |   { | 
 | 10422 |     mixer_clear_config (plci); | 
 | 10423 |   } | 
 | 10424 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d", | 
 | 10425 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 10426 |     (char   *)(FILE_), __LINE__, bchannel_id, plci->li_bchannel_id)); | 
 | 10427 | } | 
 | 10428 |  | 
 | 10429 |  | 
 | 10430 | static void mixer_set_bchannel_id (PLCI   *plci, byte   *chi) | 
 | 10431 | { | 
 | 10432 |   DIVA_CAPI_ADAPTER   *a; | 
 | 10433 |   PLCI   *splci; | 
 | 10434 |   byte ch, old_id; | 
 | 10435 |  | 
 | 10436 |   a = plci->adapter; | 
 | 10437 |   old_id = plci->li_bchannel_id; | 
 | 10438 |   ch = chi_to_channel (chi, NULL); | 
 | 10439 |   if (!(ch & 0x80)) | 
 | 10440 |   { | 
 | 10441 |     if (a->li_pri) | 
 | 10442 |     { | 
 | 10443 |       if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) | 
 | 10444 |         li_config_table[a->li_base + (old_id - 1)].plci = NULL; | 
 | 10445 |       plci->li_bchannel_id = (ch & 0x1f) + 1; | 
 | 10446 |       if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) | 
 | 10447 |         li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; | 
 | 10448 |     } | 
 | 10449 |     else | 
 | 10450 |     { | 
 | 10451 |       if (((ch & 0x1f) == 1) || ((ch & 0x1f) == 2)) | 
 | 10452 |       { | 
 | 10453 |         if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) | 
 | 10454 |           li_config_table[a->li_base + (old_id - 1)].plci = NULL; | 
 | 10455 |         plci->li_bchannel_id = ch & 0x1f; | 
 | 10456 |         if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE)) | 
 | 10457 |         { | 
 | 10458 |           splci = a->AdvSignalPLCI; | 
 | 10459 |           if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL) | 
 | 10460 |           { | 
 | 10461 |             if ((splci->li_bchannel_id != 0) | 
 | 10462 |              && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci)) | 
 | 10463 |             { | 
 | 10464 |               li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL; | 
 | 10465 |             } | 
 | 10466 |             splci->li_bchannel_id = 3 - plci->li_bchannel_id; | 
 | 10467 |             li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci; | 
 | 10468 |             dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", | 
 | 10469 |               (dword)((splci->Id << 8) | UnMapController (splci->adapter->Id)), | 
 | 10470 |               (char   *)(FILE_), __LINE__, splci->li_bchannel_id)); | 
 | 10471 |           } | 
 | 10472 |         } | 
 | 10473 |         if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) | 
 | 10474 |           li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; | 
 | 10475 |       } | 
 | 10476 |     } | 
 | 10477 |   } | 
 | 10478 |   if ((old_id == 0) && (plci->li_bchannel_id != 0) | 
 | 10479 |    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 10480 |   { | 
 | 10481 |     mixer_clear_config (plci); | 
 | 10482 |   } | 
 | 10483 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d", | 
 | 10484 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 10485 |     (char   *)(FILE_), __LINE__, ch, plci->li_bchannel_id)); | 
 | 10486 | } | 
 | 10487 |  | 
 | 10488 |  | 
 | 10489 | #define MIXER_MAX_DUMP_CHANNELS 34 | 
 | 10490 |  | 
 | 10491 | static void mixer_calculate_coefs (DIVA_CAPI_ADAPTER   *a) | 
 | 10492 | { | 
 | 10493 | static char hex_digit_table[0x10] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; | 
 | 10494 |   word n, i, j; | 
 | 10495 |   char *p; | 
 | 10496 |     char hex_line[2 * MIXER_MAX_DUMP_CHANNELS + MIXER_MAX_DUMP_CHANNELS / 8 + 4]; | 
 | 10497 |  | 
 | 10498 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_calculate_coefs", | 
 | 10499 |     (dword)(UnMapController (a->Id)), (char   *)(FILE_), __LINE__)); | 
 | 10500 |  | 
 | 10501 |   for (i = 0; i < li_total_channels; i++) | 
 | 10502 |   { | 
 | 10503 |     li_config_table[i].channel &= LI_CHANNEL_ADDRESSES_SET; | 
 | 10504 |     if (li_config_table[i].chflags != 0) | 
 | 10505 |       li_config_table[i].channel |= LI_CHANNEL_INVOLVED; | 
 | 10506 |     else | 
 | 10507 |     { | 
 | 10508 |       for (j = 0; j < li_total_channels; j++) | 
 | 10509 |       { | 
 | 10510 |         if (((li_config_table[i].flag_table[j]) != 0) | 
 | 10511 |          || ((li_config_table[j].flag_table[i]) != 0)) | 
 | 10512 |         { | 
 | 10513 |           li_config_table[i].channel |= LI_CHANNEL_INVOLVED; | 
 | 10514 |         } | 
 | 10515 |         if (((li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) != 0) | 
 | 10516 |          || ((li_config_table[j].flag_table[i] & LI_FLAG_CONFERENCE) != 0)) | 
 | 10517 |         { | 
 | 10518 |           li_config_table[i].channel |= LI_CHANNEL_CONFERENCE; | 
 | 10519 |         } | 
 | 10520 |       } | 
 | 10521 |     } | 
 | 10522 |   } | 
 | 10523 |   for (i = 0; i < li_total_channels; i++) | 
 | 10524 |   { | 
 | 10525 |     for (j = 0; j < li_total_channels; j++) | 
 | 10526 |     { | 
 | 10527 |       li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC); | 
 | 10528 |       if (li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) | 
 | 10529 |         li_config_table[i].coef_table[j] |= LI_COEF_CH_CH; | 
 | 10530 |     } | 
 | 10531 |   } | 
 | 10532 |   for (n = 0; n < li_total_channels; n++) | 
 | 10533 |   { | 
 | 10534 |     if (li_config_table[n].channel & LI_CHANNEL_CONFERENCE) | 
 | 10535 |     { | 
 | 10536 |       for (i = 0; i < li_total_channels; i++) | 
 | 10537 |       { | 
 | 10538 |         if (li_config_table[i].channel & LI_CHANNEL_CONFERENCE) | 
 | 10539 |         { | 
 | 10540 |           for (j = 0; j < li_total_channels; j++) | 
 | 10541 |           { | 
 | 10542 |             li_config_table[i].coef_table[j] |= | 
 | 10543 |               li_config_table[i].coef_table[n] & li_config_table[n].coef_table[j]; | 
 | 10544 |           } | 
 | 10545 |         } | 
 | 10546 |       } | 
 | 10547 |     } | 
 | 10548 |   } | 
 | 10549 |   for (i = 0; i < li_total_channels; i++) | 
 | 10550 |   { | 
 | 10551 |     if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) | 
 | 10552 |     { | 
 | 10553 |       li_config_table[i].coef_table[i] &= ~LI_COEF_CH_CH; | 
 | 10554 |       for (j = 0; j < li_total_channels; j++) | 
 | 10555 |       { | 
 | 10556 |         if (li_config_table[i].coef_table[j] & LI_COEF_CH_CH) | 
 | 10557 |           li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE; | 
 | 10558 |       } | 
 | 10559 |       if (li_config_table[i].flag_table[i] & LI_FLAG_CONFERENCE) | 
 | 10560 |         li_config_table[i].coef_table[i] |= LI_COEF_CH_CH; | 
 | 10561 |     } | 
 | 10562 |   } | 
 | 10563 |   for (i = 0; i < li_total_channels; i++) | 
 | 10564 |   { | 
 | 10565 |     if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) | 
 | 10566 |     { | 
 | 10567 |       for (j = 0; j < li_total_channels; j++) | 
 | 10568 |       { | 
 | 10569 |         if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) | 
 | 10570 |           li_config_table[i].coef_table[j] |= LI_COEF_CH_CH; | 
 | 10571 |         if (li_config_table[i].flag_table[j] & LI_FLAG_MONITOR) | 
 | 10572 |           li_config_table[i].coef_table[j] |= LI_COEF_CH_PC; | 
 | 10573 |         if (li_config_table[i].flag_table[j] & LI_FLAG_MIX) | 
 | 10574 |           li_config_table[i].coef_table[j] |= LI_COEF_PC_CH; | 
 | 10575 |         if (li_config_table[i].flag_table[j] & LI_FLAG_PCCONNECT) | 
 | 10576 |           li_config_table[i].coef_table[j] |= LI_COEF_PC_PC; | 
 | 10577 |       } | 
 | 10578 |       if (li_config_table[i].chflags & LI_CHFLAG_MONITOR) | 
 | 10579 |       { | 
 | 10580 |         for (j = 0; j < li_total_channels; j++) | 
 | 10581 |         { | 
 | 10582 |           if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) | 
 | 10583 |           { | 
 | 10584 |             li_config_table[i].coef_table[j] |= LI_COEF_CH_PC; | 
 | 10585 |             if (li_config_table[j].chflags & LI_CHFLAG_MIX) | 
 | 10586 |               li_config_table[i].coef_table[j] |= LI_COEF_PC_CH | LI_COEF_PC_PC; | 
 | 10587 |           } | 
 | 10588 |         } | 
 | 10589 |       } | 
 | 10590 |       if (li_config_table[i].chflags & LI_CHFLAG_MIX) | 
 | 10591 |       { | 
 | 10592 |         for (j = 0; j < li_total_channels; j++) | 
 | 10593 |         { | 
 | 10594 |           if (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT) | 
 | 10595 |             li_config_table[j].coef_table[i] |= LI_COEF_PC_CH; | 
 | 10596 |         } | 
 | 10597 |       } | 
 | 10598 |       if (li_config_table[i].chflags & LI_CHFLAG_LOOP) | 
 | 10599 |       { | 
 | 10600 |         for (j = 0; j < li_total_channels; j++) | 
 | 10601 |         { | 
 | 10602 |           if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) | 
 | 10603 |           { | 
 | 10604 |             for (n = 0; n < li_total_channels; n++) | 
 | 10605 |             { | 
 | 10606 |               if (li_config_table[n].flag_table[i] & LI_FLAG_INTERCONNECT) | 
 | 10607 |               { | 
 | 10608 |                 li_config_table[n].coef_table[j] |= LI_COEF_CH_CH; | 
 | 10609 |                 if (li_config_table[j].chflags & LI_CHFLAG_MIX) | 
 | 10610 |                 { | 
 | 10611 |                   li_config_table[n].coef_table[j] |= LI_COEF_PC_CH; | 
 | 10612 |                   if (li_config_table[n].chflags & LI_CHFLAG_MONITOR) | 
 | 10613 |                     li_config_table[n].coef_table[j] |= LI_COEF_CH_PC | LI_COEF_PC_PC; | 
 | 10614 |                 } | 
 | 10615 |                 else if (li_config_table[n].chflags & LI_CHFLAG_MONITOR) | 
 | 10616 |                   li_config_table[n].coef_table[j] |= LI_COEF_CH_PC; | 
 | 10617 |               } | 
 | 10618 |             } | 
 | 10619 |           } | 
 | 10620 |         } | 
 | 10621 |       } | 
 | 10622 |     } | 
 | 10623 |   } | 
 | 10624 |   for (i = 0; i < li_total_channels; i++) | 
 | 10625 |   { | 
 | 10626 |     if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) | 
 | 10627 |     { | 
 | 10628 |       if (li_config_table[i].chflags & (LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP)) | 
 | 10629 |         li_config_table[i].channel |= LI_CHANNEL_ACTIVE; | 
 | 10630 |       if (li_config_table[i].chflags & LI_CHFLAG_MONITOR) | 
 | 10631 |         li_config_table[i].channel |= LI_CHANNEL_RX_DATA; | 
 | 10632 |       if (li_config_table[i].chflags & LI_CHFLAG_MIX) | 
 | 10633 |         li_config_table[i].channel |= LI_CHANNEL_TX_DATA; | 
 | 10634 |       for (j = 0; j < li_total_channels; j++) | 
 | 10635 |       { | 
 | 10636 |         if ((li_config_table[i].flag_table[j] & | 
 | 10637 |           (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_MONITOR)) | 
 | 10638 |          || (li_config_table[j].flag_table[i] & | 
 | 10639 |           (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX))) | 
 | 10640 |         { | 
 | 10641 |           li_config_table[i].channel |= LI_CHANNEL_ACTIVE; | 
 | 10642 |         } | 
 | 10643 |         if (li_config_table[i].flag_table[j] & (LI_FLAG_PCCONNECT | LI_FLAG_MONITOR)) | 
 | 10644 |           li_config_table[i].channel |= LI_CHANNEL_RX_DATA; | 
 | 10645 |         if (li_config_table[j].flag_table[i] & (LI_FLAG_PCCONNECT | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX)) | 
 | 10646 |           li_config_table[i].channel |= LI_CHANNEL_TX_DATA; | 
 | 10647 |       } | 
 | 10648 |       if (!(li_config_table[i].channel & LI_CHANNEL_ACTIVE)) | 
 | 10649 |       { | 
 | 10650 |         li_config_table[i].coef_table[i] |= LI_COEF_PC_CH | LI_COEF_CH_PC; | 
 | 10651 |         li_config_table[i].channel |= LI_CHANNEL_TX_DATA | LI_CHANNEL_RX_DATA; | 
 | 10652 |       } | 
 | 10653 |     } | 
 | 10654 |   } | 
 | 10655 |   for (i = 0; i < li_total_channels; i++) | 
 | 10656 |   { | 
 | 10657 |     if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) | 
 | 10658 |     { | 
 | 10659 |       j = 0; | 
 | 10660 |       while ((j < li_total_channels) && !(li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT)) | 
 | 10661 |         j++; | 
 | 10662 |       if (j < li_total_channels) | 
 | 10663 |       { | 
 | 10664 |         for (j = 0; j < li_total_channels; j++) | 
 | 10665 |         { | 
 | 10666 |           li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_PC_CH); | 
 | 10667 |           if (li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT) | 
 | 10668 |             li_config_table[i].coef_table[j] |= LI_COEF_PC_CH; | 
 | 10669 |         } | 
 | 10670 |       } | 
 | 10671 |     } | 
 | 10672 |   } | 
 | 10673 |   n = li_total_channels; | 
 | 10674 |   if (n > MIXER_MAX_DUMP_CHANNELS) | 
 | 10675 |     n = MIXER_MAX_DUMP_CHANNELS; | 
 | 10676 |   p = hex_line; | 
 | 10677 |   for (j = 0; j < n; j++) | 
 | 10678 |   { | 
 | 10679 |     if ((j & 0x7) == 0) | 
 | 10680 |       *(p++) = ' '; | 
 | 10681 |     *(p++) = hex_digit_table[li_config_table[j].curchnl >> 4]; | 
 | 10682 |     *(p++) = hex_digit_table[li_config_table[j].curchnl & 0xf]; | 
 | 10683 |   } | 
 | 10684 |   *p = '\0'; | 
 | 10685 |   dbug (1, dprintf ("[%06lx] CURRENT %s", | 
 | 10686 |     (dword)(UnMapController (a->Id)), (char   *) hex_line)); | 
 | 10687 |   p = hex_line; | 
 | 10688 |   for (j = 0; j < n; j++) | 
 | 10689 |   { | 
 | 10690 |     if ((j & 0x7) == 0) | 
 | 10691 |       *(p++) = ' '; | 
 | 10692 |     *(p++) = hex_digit_table[li_config_table[j].channel >> 4]; | 
 | 10693 |     *(p++) = hex_digit_table[li_config_table[j].channel & 0xf]; | 
 | 10694 |   } | 
 | 10695 |   *p = '\0'; | 
 | 10696 |   dbug (1, dprintf ("[%06lx] CHANNEL %s", | 
 | 10697 |     (dword)(UnMapController (a->Id)), (char   *) hex_line)); | 
 | 10698 |   p = hex_line; | 
 | 10699 |   for (j = 0; j < n; j++) | 
 | 10700 |   { | 
 | 10701 |     if ((j & 0x7) == 0) | 
 | 10702 |       *(p++) = ' '; | 
 | 10703 |     *(p++) = hex_digit_table[li_config_table[j].chflags >> 4]; | 
 | 10704 |     *(p++) = hex_digit_table[li_config_table[j].chflags & 0xf]; | 
 | 10705 |   } | 
 | 10706 |   *p = '\0'; | 
 | 10707 |   dbug (1, dprintf ("[%06lx] CHFLAG  %s", | 
 | 10708 |     (dword)(UnMapController (a->Id)), (char   *) hex_line)); | 
 | 10709 |   for (i = 0; i < n; i++) | 
 | 10710 |   { | 
 | 10711 |     p = hex_line; | 
 | 10712 |     for (j = 0; j < n; j++) | 
 | 10713 |     { | 
 | 10714 |       if ((j & 0x7) == 0) | 
 | 10715 |         *(p++) = ' '; | 
 | 10716 |       *(p++) = hex_digit_table[li_config_table[i].flag_table[j] >> 4]; | 
 | 10717 |       *(p++) = hex_digit_table[li_config_table[i].flag_table[j] & 0xf]; | 
 | 10718 |     } | 
 | 10719 |     *p = '\0'; | 
 | 10720 |     dbug (1, dprintf ("[%06lx] FLAG[%02x]%s", | 
 | 10721 |       (dword)(UnMapController (a->Id)), i, (char   *) hex_line)); | 
 | 10722 |   } | 
 | 10723 |   for (i = 0; i < n; i++) | 
 | 10724 |   { | 
 | 10725 |     p = hex_line; | 
 | 10726 |     for (j = 0; j < n; j++) | 
 | 10727 |     { | 
 | 10728 |       if ((j & 0x7) == 0) | 
 | 10729 |         *(p++) = ' '; | 
 | 10730 |       *(p++) = hex_digit_table[li_config_table[i].coef_table[j] >> 4]; | 
 | 10731 |       *(p++) = hex_digit_table[li_config_table[i].coef_table[j] & 0xf]; | 
 | 10732 |     } | 
 | 10733 |     *p = '\0'; | 
 | 10734 |     dbug (1, dprintf ("[%06lx] COEF[%02x]%s", | 
 | 10735 |       (dword)(UnMapController (a->Id)), i, (char   *) hex_line)); | 
 | 10736 |   } | 
 | 10737 | } | 
 | 10738 |  | 
 | 10739 |  | 
 | 10740 | static struct | 
 | 10741 | { | 
 | 10742 |   byte mask; | 
 | 10743 |   byte line_flags; | 
 | 10744 | } mixer_write_prog_pri[] = | 
 | 10745 | { | 
 | 10746 |   { LI_COEF_CH_CH, 0 }, | 
 | 10747 |   { LI_COEF_CH_PC, MIXER_COEF_LINE_TO_PC_FLAG }, | 
 | 10748 |   { LI_COEF_PC_CH, MIXER_COEF_LINE_FROM_PC_FLAG }, | 
 | 10749 |   { LI_COEF_PC_PC, MIXER_COEF_LINE_TO_PC_FLAG | MIXER_COEF_LINE_FROM_PC_FLAG } | 
 | 10750 | }; | 
 | 10751 |  | 
 | 10752 | static struct | 
 | 10753 | { | 
 | 10754 |   byte from_ch; | 
 | 10755 |   byte to_ch; | 
 | 10756 |   byte mask; | 
 | 10757 |   byte xconnect_override; | 
 | 10758 | } mixer_write_prog_bri[] = | 
 | 10759 | { | 
 | 10760 |   { 0, 0, LI_COEF_CH_CH, 0x01 },  /* B      to B      */ | 
 | 10761 |   { 1, 0, LI_COEF_CH_CH, 0x01 },  /* Alt B  to B      */ | 
 | 10762 |   { 0, 0, LI_COEF_PC_CH, 0x80 },  /* PC     to B      */ | 
 | 10763 |   { 1, 0, LI_COEF_PC_CH, 0x01 },  /* Alt PC to B      */ | 
 | 10764 |   { 2, 0, LI_COEF_CH_CH, 0x00 },  /* IC     to B      */ | 
 | 10765 |   { 3, 0, LI_COEF_CH_CH, 0x00 },  /* Alt IC to B      */ | 
 | 10766 |   { 0, 0, LI_COEF_CH_PC, 0x80 },  /* B      to PC     */ | 
 | 10767 |   { 1, 0, LI_COEF_CH_PC, 0x01 },  /* Alt B  to PC     */ | 
 | 10768 |   { 0, 0, LI_COEF_PC_PC, 0x01 },  /* PC     to PC     */ | 
 | 10769 |   { 1, 0, LI_COEF_PC_PC, 0x01 },  /* Alt PC to PC     */ | 
 | 10770 |   { 2, 0, LI_COEF_CH_PC, 0x00 },  /* IC     to PC     */ | 
 | 10771 |   { 3, 0, LI_COEF_CH_PC, 0x00 },  /* Alt IC to PC     */ | 
 | 10772 |   { 0, 2, LI_COEF_CH_CH, 0x00 },  /* B      to IC     */ | 
 | 10773 |   { 1, 2, LI_COEF_CH_CH, 0x00 },  /* Alt B  to IC     */ | 
 | 10774 |   { 0, 2, LI_COEF_PC_CH, 0x00 },  /* PC     to IC     */ | 
 | 10775 |   { 1, 2, LI_COEF_PC_CH, 0x00 },  /* Alt PC to IC     */ | 
 | 10776 |   { 2, 2, LI_COEF_CH_CH, 0x00 },  /* IC     to IC     */ | 
 | 10777 |   { 3, 2, LI_COEF_CH_CH, 0x00 },  /* Alt IC to IC     */ | 
 | 10778 |   { 1, 1, LI_COEF_CH_CH, 0x01 },  /* Alt B  to Alt B  */ | 
 | 10779 |   { 0, 1, LI_COEF_CH_CH, 0x01 },  /* B      to Alt B  */ | 
 | 10780 |   { 1, 1, LI_COEF_PC_CH, 0x80 },  /* Alt PC to Alt B  */ | 
 | 10781 |   { 0, 1, LI_COEF_PC_CH, 0x01 },  /* PC     to Alt B  */ | 
 | 10782 |   { 3, 1, LI_COEF_CH_CH, 0x00 },  /* Alt IC to Alt B  */ | 
 | 10783 |   { 2, 1, LI_COEF_CH_CH, 0x00 },  /* IC     to Alt B  */ | 
 | 10784 |   { 1, 1, LI_COEF_CH_PC, 0x80 },  /* Alt B  to Alt PC */ | 
 | 10785 |   { 0, 1, LI_COEF_CH_PC, 0x01 },  /* B      to Alt PC */ | 
 | 10786 |   { 1, 1, LI_COEF_PC_PC, 0x01 },  /* Alt PC to Alt PC */ | 
 | 10787 |   { 0, 1, LI_COEF_PC_PC, 0x01 },  /* PC     to Alt PC */ | 
 | 10788 |   { 3, 1, LI_COEF_CH_PC, 0x00 },  /* Alt IC to Alt PC */ | 
 | 10789 |   { 2, 1, LI_COEF_CH_PC, 0x00 },  /* IC     to Alt PC */ | 
 | 10790 |   { 1, 3, LI_COEF_CH_CH, 0x00 },  /* Alt B  to Alt IC */ | 
 | 10791 |   { 0, 3, LI_COEF_CH_CH, 0x00 },  /* B      to Alt IC */ | 
 | 10792 |   { 1, 3, LI_COEF_PC_CH, 0x00 },  /* Alt PC to Alt IC */ | 
 | 10793 |   { 0, 3, LI_COEF_PC_CH, 0x00 },  /* PC     to Alt IC */ | 
 | 10794 |   { 3, 3, LI_COEF_CH_CH, 0x00 },  /* Alt IC to Alt IC */ | 
 | 10795 |   { 2, 3, LI_COEF_CH_CH, 0x00 }   /* IC     to Alt IC */ | 
 | 10796 | }; | 
 | 10797 |  | 
 | 10798 | static byte mixer_swapped_index_bri[] = | 
 | 10799 | { | 
 | 10800 |   18,  /* B      to B      */ | 
 | 10801 |   19,  /* Alt B  to B      */ | 
 | 10802 |   20,  /* PC     to B      */ | 
 | 10803 |   21,  /* Alt PC to B      */ | 
 | 10804 |   22,  /* IC     to B      */ | 
 | 10805 |   23,  /* Alt IC to B      */ | 
 | 10806 |   24,  /* B      to PC     */ | 
 | 10807 |   25,  /* Alt B  to PC     */ | 
 | 10808 |   26,  /* PC     to PC     */ | 
 | 10809 |   27,  /* Alt PC to PC     */ | 
 | 10810 |   28,  /* IC     to PC     */ | 
 | 10811 |   29,  /* Alt IC to PC     */ | 
 | 10812 |   30,  /* B      to IC     */ | 
 | 10813 |   31,  /* Alt B  to IC     */ | 
 | 10814 |   32,  /* PC     to IC     */ | 
 | 10815 |   33,  /* Alt PC to IC     */ | 
 | 10816 |   34,  /* IC     to IC     */ | 
 | 10817 |   35,  /* Alt IC to IC     */ | 
 | 10818 |   0,   /* Alt B  to Alt B  */ | 
 | 10819 |   1,   /* B      to Alt B  */ | 
 | 10820 |   2,   /* Alt PC to Alt B  */ | 
 | 10821 |   3,   /* PC     to Alt B  */ | 
 | 10822 |   4,   /* Alt IC to Alt B  */ | 
 | 10823 |   5,   /* IC     to Alt B  */ | 
 | 10824 |   6,   /* Alt B  to Alt PC */ | 
 | 10825 |   7,   /* B      to Alt PC */ | 
 | 10826 |   8,   /* Alt PC to Alt PC */ | 
 | 10827 |   9,   /* PC     to Alt PC */ | 
 | 10828 |   10,  /* Alt IC to Alt PC */ | 
 | 10829 |   11,  /* IC     to Alt PC */ | 
 | 10830 |   12,  /* Alt B  to Alt IC */ | 
 | 10831 |   13,  /* B      to Alt IC */ | 
 | 10832 |   14,  /* Alt PC to Alt IC */ | 
 | 10833 |   15,  /* PC     to Alt IC */ | 
 | 10834 |   16,  /* Alt IC to Alt IC */ | 
 | 10835 |   17   /* IC     to Alt IC */ | 
 | 10836 | }; | 
 | 10837 |  | 
 | 10838 | static struct | 
 | 10839 | { | 
 | 10840 |   byte mask; | 
 | 10841 |   byte from_pc; | 
 | 10842 |   byte to_pc; | 
 | 10843 | } xconnect_write_prog[] = | 
 | 10844 | { | 
 | 10845 |   { LI_COEF_CH_CH, FALSE, FALSE }, | 
 | 10846 |   { LI_COEF_CH_PC, FALSE, TRUE }, | 
 | 10847 |   { LI_COEF_PC_CH, TRUE, FALSE }, | 
 | 10848 |   { LI_COEF_PC_PC, TRUE, TRUE } | 
 | 10849 | }; | 
 | 10850 |  | 
 | 10851 |  | 
 | 10852 | static void xconnect_query_addresses (PLCI   *plci) | 
 | 10853 | { | 
 | 10854 |   DIVA_CAPI_ADAPTER   *a; | 
 | 10855 |   word w, ch; | 
 | 10856 |   byte   *p; | 
 | 10857 |  | 
 | 10858 |   dbug (1, dprintf ("[%06lx] %s,%d: xconnect_query_addresses", | 
 | 10859 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 10860 |     (char   *)(FILE_), __LINE__)); | 
 | 10861 |  | 
 | 10862 |   a = plci->adapter; | 
 | 10863 |   if (a->li_pri && ((plci->li_bchannel_id == 0) | 
 | 10864 |    || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))) | 
 | 10865 |   { | 
 | 10866 |     dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out", | 
 | 10867 |       (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 10868 |       (char   *)(FILE_), __LINE__)); | 
 | 10869 |     return; | 
 | 10870 |   } | 
 | 10871 |   p = plci->internal_req_buffer; | 
 | 10872 |   ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0; | 
 | 10873 |   *(p++) = UDATA_REQUEST_XCONNECT_FROM; | 
 | 10874 |   w = ch; | 
 | 10875 |   *(p++) = (byte) w; | 
 | 10876 |   *(p++) = (byte)(w >> 8); | 
 | 10877 |   w = ch | XCONNECT_CHANNEL_PORT_PC; | 
 | 10878 |   *(p++) = (byte) w; | 
 | 10879 |   *(p++) = (byte)(w >> 8); | 
 | 10880 |   plci->NData[0].P = plci->internal_req_buffer; | 
 | 10881 |   plci->NData[0].PLength = p - plci->internal_req_buffer; | 
 | 10882 |   plci->NL.X = plci->NData; | 
 | 10883 |   plci->NL.ReqCh = 0; | 
 | 10884 |   plci->NL.Req = plci->nl_req = (byte) N_UDATA; | 
 | 10885 |   plci->adapter->request (&plci->NL); | 
 | 10886 | } | 
 | 10887 |  | 
 | 10888 |  | 
 | 10889 | static void xconnect_write_coefs (PLCI   *plci, word internal_command) | 
 | 10890 | { | 
 | 10891 |  | 
 | 10892 |   dbug (1, dprintf ("[%06lx] %s,%d: xconnect_write_coefs %04x", | 
 | 10893 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 10894 |     (char   *)(FILE_), __LINE__, internal_command)); | 
 | 10895 |  | 
 | 10896 |   plci->li_write_command = internal_command; | 
 | 10897 |   plci->li_write_channel = 0; | 
 | 10898 | } | 
 | 10899 |  | 
 | 10900 |  | 
 | 10901 | static byte xconnect_write_coefs_process (dword Id, PLCI   *plci, byte Rc) | 
 | 10902 | { | 
 | 10903 |   DIVA_CAPI_ADAPTER   *a; | 
 | 10904 |   word w, n, i, j, r, s, to_ch; | 
 | 10905 |   dword d; | 
 | 10906 |   byte   *p; | 
 | 10907 |   struct xconnect_transfer_address_s   *transfer_address; | 
 | 10908 |   byte ch_map[MIXER_CHANNELS_BRI]; | 
 | 10909 |  | 
 | 10910 |   dbug (1, dprintf ("[%06x] %s,%d: xconnect_write_coefs_process %02x %d", | 
 | 10911 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->li_write_channel)); | 
 | 10912 |  | 
 | 10913 |   a = plci->adapter; | 
 | 10914 |   if ((plci->li_bchannel_id == 0) | 
 | 10915 |    || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)) | 
 | 10916 |   { | 
 | 10917 |     dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out", | 
 | 10918 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 10919 |     return (TRUE); | 
 | 10920 |   } | 
 | 10921 |   i = a->li_base + (plci->li_bchannel_id - 1); | 
 | 10922 |   j = plci->li_write_channel; | 
 | 10923 |   p = plci->internal_req_buffer; | 
 | 10924 |   if (j != 0) | 
 | 10925 |   { | 
 | 10926 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 10927 |     { | 
 | 10928 |       dbug (1, dprintf ("[%06lx] %s,%d: LI write coefs failed %02x", | 
 | 10929 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 10930 |       return (FALSE); | 
 | 10931 |     } | 
 | 10932 |   } | 
 | 10933 |   if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 10934 |   { | 
 | 10935 |     r = 0; | 
 | 10936 |     s = 0; | 
 | 10937 |     if (j < li_total_channels) | 
 | 10938 |     { | 
 | 10939 |       if (li_config_table[i].channel & LI_CHANNEL_ADDRESSES_SET) | 
 | 10940 |       { | 
 | 10941 |         s = ((li_config_table[i].send_b.card_address.low | li_config_table[i].send_b.card_address.high) ? | 
 | 10942 |             (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_PC | LI_COEF_PC_PC)) & | 
 | 10943 |           ((li_config_table[i].send_pc.card_address.low | li_config_table[i].send_pc.card_address.high) ? | 
 | 10944 |             (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_PC_CH)); | 
 | 10945 |       } | 
 | 10946 |       r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); | 
 | 10947 |       while ((j < li_total_channels) | 
 | 10948 |         && ((r == 0) | 
 | 10949 |          || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET)) | 
 | 10950 |          || (!li_config_table[j].adapter->li_pri | 
 | 10951 |           && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI)) | 
 | 10952 |          || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low) | 
 | 10953 |            || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high)) | 
 | 10954 |           && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT) | 
 | 10955 |            || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT))) | 
 | 10956 |          || ((li_config_table[j].adapter->li_base != a->li_base) | 
 | 10957 |           && !(r & s & | 
 | 10958 |             ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? | 
 | 10959 |               (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & | 
 | 10960 |             ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? | 
 | 10961 |               (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)))))) | 
 | 10962 |       { | 
 | 10963 |         j++; | 
 | 10964 |         if (j < li_total_channels) | 
 | 10965 |           r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); | 
 | 10966 |       } | 
 | 10967 |     } | 
 | 10968 |     if (j < li_total_channels) | 
 | 10969 |     { | 
 | 10970 |       plci->internal_command = plci->li_write_command; | 
 | 10971 |       if (plci_nl_busy (plci)) | 
 | 10972 |         return (TRUE); | 
 | 10973 |       to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0; | 
 | 10974 |       *(p++) = UDATA_REQUEST_XCONNECT_TO; | 
 | 10975 |       do | 
 | 10976 |       { | 
 | 10977 |         if (li_config_table[j].adapter->li_base != a->li_base) | 
 | 10978 |         { | 
 | 10979 |           r &= s & | 
 | 10980 |             ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? | 
 | 10981 |               (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & | 
 | 10982 |             ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? | 
 | 10983 |               (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)); | 
 | 10984 |         } | 
 | 10985 |         n = 0; | 
 | 10986 |         do | 
 | 10987 |         { | 
 | 10988 |           if (r & xconnect_write_prog[n].mask) | 
 | 10989 |           { | 
 | 10990 |             if (xconnect_write_prog[n].from_pc) | 
 | 10991 |               transfer_address = &(li_config_table[j].send_pc); | 
 | 10992 |             else | 
 | 10993 |               transfer_address = &(li_config_table[j].send_b); | 
 | 10994 |             d = transfer_address->card_address.low; | 
 | 10995 |             *(p++) = (byte) d; | 
 | 10996 |             *(p++) = (byte)(d >> 8); | 
 | 10997 |             *(p++) = (byte)(d >> 16); | 
 | 10998 |             *(p++) = (byte)(d >> 24); | 
 | 10999 |             d = transfer_address->card_address.high; | 
 | 11000 |             *(p++) = (byte) d; | 
 | 11001 |             *(p++) = (byte)(d >> 8); | 
 | 11002 |             *(p++) = (byte)(d >> 16); | 
 | 11003 |             *(p++) = (byte)(d >> 24); | 
 | 11004 |             d = transfer_address->offset; | 
 | 11005 |             *(p++) = (byte) d; | 
 | 11006 |             *(p++) = (byte)(d >> 8); | 
 | 11007 |             *(p++) = (byte)(d >> 16); | 
 | 11008 |             *(p++) = (byte)(d >> 24); | 
 | 11009 |             w = xconnect_write_prog[n].to_pc ? to_ch | XCONNECT_CHANNEL_PORT_PC : to_ch; | 
 | 11010 |             *(p++) = (byte) w; | 
 | 11011 |             *(p++) = (byte)(w >> 8); | 
 | 11012 |             w = ((li_config_table[i].coef_table[j] & xconnect_write_prog[n].mask) == 0) ? 0x01 : | 
 | 11013 |               (li_config_table[i].adapter->u_law ? | 
 | 11014 |                  (li_config_table[j].adapter->u_law ? 0x80 : 0x86) : | 
 | 11015 |                  (li_config_table[j].adapter->u_law ? 0x7a : 0x80)); | 
 | 11016 |             *(p++) = (byte) w; | 
 | 11017 |             *(p++) = (byte) 0; | 
 | 11018 |             li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4; | 
 | 11019 |           } | 
 | 11020 |           n++; | 
 | 11021 |         } while ((n < sizeof(xconnect_write_prog) / sizeof(xconnect_write_prog[0])) | 
 | 11022 |           && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE)); | 
 | 11023 |         if (n == sizeof(xconnect_write_prog) / sizeof(xconnect_write_prog[0])) | 
 | 11024 |         { | 
 | 11025 |           do | 
 | 11026 |           { | 
 | 11027 |             j++; | 
 | 11028 |             if (j < li_total_channels) | 
 | 11029 |               r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); | 
 | 11030 |           } while ((j < li_total_channels) | 
 | 11031 |             && ((r == 0) | 
 | 11032 |              || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET)) | 
 | 11033 |              || (!li_config_table[j].adapter->li_pri | 
 | 11034 |               && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI)) | 
 | 11035 |              || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low) | 
 | 11036 |                || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high)) | 
 | 11037 |               && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT) | 
 | 11038 |                || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT))) | 
 | 11039 |              || ((li_config_table[j].adapter->li_base != a->li_base) | 
 | 11040 |               && !(r & s & | 
 | 11041 |                 ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? | 
 | 11042 |                   (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & | 
 | 11043 |                 ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? | 
 | 11044 |                   (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)))))); | 
 | 11045 |         } | 
 | 11046 |       } while ((j < li_total_channels) | 
 | 11047 |         && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE)); | 
 | 11048 |     } | 
 | 11049 |     else if (j == li_total_channels) | 
 | 11050 |     { | 
 | 11051 |       plci->internal_command = plci->li_write_command; | 
 | 11052 |       if (plci_nl_busy (plci)) | 
 | 11053 |         return (TRUE); | 
 | 11054 |       if (a->li_pri) | 
 | 11055 |       { | 
 | 11056 |         *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC; | 
 | 11057 |         w = 0; | 
 | 11058 |         if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) | 
 | 11059 |           w |= MIXER_FEATURE_ENABLE_TX_DATA; | 
 | 11060 |         if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) | 
 | 11061 |           w |= MIXER_FEATURE_ENABLE_RX_DATA; | 
 | 11062 |         *(p++) = (byte) w; | 
 | 11063 |         *(p++) = (byte)(w >> 8); | 
 | 11064 |       } | 
 | 11065 |       else | 
 | 11066 |       { | 
 | 11067 |         *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI; | 
 | 11068 |         w = 0; | 
 | 11069 |         if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI) | 
 | 11070 |          && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)) | 
 | 11071 |         { | 
 | 11072 |           w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); | 
 | 11073 |         } | 
 | 11074 |         if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) | 
 | 11075 |           w |= MIXER_FEATURE_ENABLE_TX_DATA; | 
 | 11076 |         if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) | 
 | 11077 |           w |= MIXER_FEATURE_ENABLE_RX_DATA; | 
 | 11078 |         *(p++) = (byte) w; | 
 | 11079 |         *(p++) = (byte)(w >> 8); | 
 | 11080 |         for (j = 0; j < sizeof(ch_map); j += 2) | 
 | 11081 |         { | 
 | 11082 |           if (plci->li_bchannel_id == 2) | 
 | 11083 |           { | 
 | 11084 |             ch_map[j] = (byte)(j+1); | 
 | 11085 |             ch_map[j+1] = (byte) j; | 
 | 11086 |           } | 
 | 11087 |           else | 
 | 11088 |           { | 
 | 11089 |             ch_map[j] = (byte) j; | 
 | 11090 |             ch_map[j+1] = (byte)(j+1); | 
 | 11091 |           } | 
 | 11092 |         } | 
 | 11093 |         for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++) | 
 | 11094 |         { | 
 | 11095 |           i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; | 
 | 11096 |           j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; | 
 | 11097 |           if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) | 
 | 11098 |           { | 
 | 11099 |             *p = (mixer_write_prog_bri[n].xconnect_override != 0) ? | 
 | 11100 |               mixer_write_prog_bri[n].xconnect_override : | 
 | 11101 |               ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); | 
 | 11102 |             if ((i >= a->li_base + MIXER_BCHANNELS_BRI) || (j >= a->li_base + MIXER_BCHANNELS_BRI)) | 
 | 11103 |             { | 
 | 11104 |               w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); | 
 | 11105 |               li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; | 
 | 11106 |             } | 
 | 11107 |           } | 
 | 11108 |           else | 
 | 11109 |           { | 
 | 11110 |             *p = 0x00; | 
 | 11111 |             if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE)) | 
 | 11112 |             { | 
 | 11113 |               w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n]; | 
 | 11114 |               if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length) | 
 | 11115 |                 *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w]; | 
 | 11116 |             } | 
 | 11117 |           } | 
 | 11118 |           p++; | 
 | 11119 |         } | 
 | 11120 |       } | 
 | 11121 |       j = li_total_channels + 1; | 
 | 11122 |     } | 
 | 11123 |   } | 
 | 11124 |   else | 
 | 11125 |   { | 
 | 11126 |     if (j <= li_total_channels) | 
 | 11127 |     { | 
 | 11128 |       plci->internal_command = plci->li_write_command; | 
 | 11129 |       if (plci_nl_busy (plci)) | 
 | 11130 |         return (TRUE); | 
 | 11131 |       if (j < a->li_base) | 
 | 11132 |         j = a->li_base; | 
 | 11133 |       if (a->li_pri) | 
 | 11134 |       { | 
 | 11135 |         *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC; | 
 | 11136 |         w = 0; | 
 | 11137 |         if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) | 
 | 11138 |           w |= MIXER_FEATURE_ENABLE_TX_DATA; | 
 | 11139 |         if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) | 
 | 11140 |           w |= MIXER_FEATURE_ENABLE_RX_DATA; | 
 | 11141 |         *(p++) = (byte) w; | 
 | 11142 |         *(p++) = (byte)(w >> 8); | 
 | 11143 |         for (n = 0; n < sizeof(mixer_write_prog_pri) / sizeof(mixer_write_prog_pri[0]); n++) | 
 | 11144 |         { | 
 | 11145 |           *(p++) = (byte)((plci->li_bchannel_id - 1) | mixer_write_prog_pri[n].line_flags); | 
 | 11146 |           for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++) | 
 | 11147 |           { | 
 | 11148 |             w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); | 
 | 11149 |             if (w & mixer_write_prog_pri[n].mask) | 
 | 11150 |             { | 
 | 11151 |               *(p++) = (li_config_table[i].coef_table[j] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01; | 
 | 11152 |               li_config_table[i].coef_table[j] ^= mixer_write_prog_pri[n].mask << 4; | 
 | 11153 |             } | 
 | 11154 |             else | 
 | 11155 |               *(p++) = 0x00; | 
 | 11156 |           } | 
 | 11157 |           *(p++) = (byte)((plci->li_bchannel_id - 1) | MIXER_COEF_LINE_ROW_FLAG | mixer_write_prog_pri[n].line_flags); | 
 | 11158 |           for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++) | 
 | 11159 |           { | 
 | 11160 |             w = ((li_config_table[j].coef_table[i] & 0xf) ^ (li_config_table[j].coef_table[i] >> 4)); | 
 | 11161 |             if (w & mixer_write_prog_pri[n].mask) | 
 | 11162 |             { | 
 | 11163 |               *(p++) = (li_config_table[j].coef_table[i] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01; | 
 | 11164 |               li_config_table[j].coef_table[i] ^= mixer_write_prog_pri[n].mask << 4; | 
 | 11165 |             } | 
 | 11166 |             else | 
 | 11167 |               *(p++) = 0x00; | 
 | 11168 |           } | 
 | 11169 |         } | 
 | 11170 |       } | 
 | 11171 |       else | 
 | 11172 |       { | 
 | 11173 |         *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI; | 
 | 11174 |         w = 0; | 
 | 11175 |         if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI) | 
 | 11176 |          && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)) | 
 | 11177 |         { | 
 | 11178 |           w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); | 
 | 11179 |         } | 
 | 11180 |         if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) | 
 | 11181 |           w |= MIXER_FEATURE_ENABLE_TX_DATA; | 
 | 11182 |         if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) | 
 | 11183 |           w |= MIXER_FEATURE_ENABLE_RX_DATA; | 
 | 11184 |         *(p++) = (byte) w; | 
 | 11185 |         *(p++) = (byte)(w >> 8); | 
 | 11186 |         for (j = 0; j < sizeof(ch_map); j += 2) | 
 | 11187 |         { | 
 | 11188 |           if (plci->li_bchannel_id == 2) | 
 | 11189 |           { | 
 | 11190 |             ch_map[j] = (byte)(j+1); | 
 | 11191 |             ch_map[j+1] = (byte) j; | 
 | 11192 |           } | 
 | 11193 |           else | 
 | 11194 |           { | 
 | 11195 |             ch_map[j] = (byte) j; | 
 | 11196 |             ch_map[j+1] = (byte)(j+1); | 
 | 11197 |           } | 
 | 11198 |         } | 
 | 11199 |         for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++) | 
 | 11200 |         { | 
 | 11201 |           i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; | 
 | 11202 |           j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; | 
 | 11203 |           if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) | 
 | 11204 |           { | 
 | 11205 |             *p = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); | 
 | 11206 |             w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); | 
 | 11207 |             li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; | 
 | 11208 |           } | 
 | 11209 |           else | 
 | 11210 |           { | 
 | 11211 |             *p = 0x00; | 
 | 11212 |             if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE)) | 
 | 11213 |             { | 
 | 11214 |               w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n]; | 
 | 11215 |               if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length) | 
 | 11216 |                 *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w]; | 
 | 11217 |             } | 
 | 11218 |           } | 
 | 11219 |           p++; | 
 | 11220 |         } | 
 | 11221 |       } | 
 | 11222 |       j = li_total_channels + 1; | 
 | 11223 |     } | 
 | 11224 |   } | 
 | 11225 |   plci->li_write_channel = j; | 
 | 11226 |   if (p != plci->internal_req_buffer) | 
 | 11227 |   { | 
 | 11228 |     plci->NData[0].P = plci->internal_req_buffer; | 
 | 11229 |     plci->NData[0].PLength = p - plci->internal_req_buffer; | 
 | 11230 |     plci->NL.X = plci->NData; | 
 | 11231 |     plci->NL.ReqCh = 0; | 
 | 11232 |     plci->NL.Req = plci->nl_req = (byte) N_UDATA; | 
 | 11233 |     plci->adapter->request (&plci->NL); | 
 | 11234 |   } | 
 | 11235 |   return (TRUE); | 
 | 11236 | } | 
 | 11237 |  | 
 | 11238 |  | 
 | 11239 | static void mixer_notify_update (PLCI   *plci, byte others) | 
 | 11240 | { | 
 | 11241 |   DIVA_CAPI_ADAPTER   *a; | 
 | 11242 |   word i, w; | 
 | 11243 |   PLCI   *notify_plci; | 
 | 11244 |     byte msg[sizeof(CAPI_MSG_HEADER) + 6]; | 
 | 11245 |  | 
 | 11246 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_notify_update %d", | 
 | 11247 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 11248 |     (char   *)(FILE_), __LINE__, others)); | 
 | 11249 |  | 
 | 11250 |   a = plci->adapter; | 
 | 11251 |   if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED) | 
 | 11252 |   { | 
 | 11253 |     if (others) | 
 | 11254 |       plci->li_notify_update = TRUE; | 
 | 11255 |     i = 0; | 
 | 11256 |     do | 
 | 11257 |     { | 
 | 11258 |       notify_plci = NULL; | 
 | 11259 |       if (others) | 
 | 11260 |       { | 
 | 11261 |         while ((i < li_total_channels) && (li_config_table[i].plci == NULL)) | 
 | 11262 |           i++; | 
 | 11263 |         if (i < li_total_channels) | 
 | 11264 |           notify_plci = li_config_table[i++].plci; | 
 | 11265 |       } | 
 | 11266 |       else | 
 | 11267 |       { | 
 | 11268 |         if ((plci->li_bchannel_id != 0) | 
 | 11269 |          && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 11270 |         { | 
 | 11271 |           notify_plci = plci; | 
 | 11272 |         } | 
 | 11273 |       } | 
 | 11274 |       if ((notify_plci != NULL) | 
 | 11275 |        && !notify_plci->li_notify_update | 
 | 11276 |        && (notify_plci->appl != NULL) | 
 | 11277 |        && (notify_plci->State) | 
 | 11278 |        && notify_plci->NL.Id && !notify_plci->nl_remove_id) | 
 | 11279 |       { | 
 | 11280 |         notify_plci->li_notify_update = TRUE; | 
 | 11281 |         ((CAPI_MSG *) msg)->header.length = 18; | 
 | 11282 |         ((CAPI_MSG *) msg)->header.appl_id = notify_plci->appl->Id; | 
 | 11283 |         ((CAPI_MSG *) msg)->header.command = _FACILITY_R; | 
 | 11284 |         ((CAPI_MSG *) msg)->header.number = 0; | 
 | 11285 |         ((CAPI_MSG *) msg)->header.controller = notify_plci->adapter->Id; | 
 | 11286 |         ((CAPI_MSG *) msg)->header.plci = notify_plci->Id; | 
 | 11287 |         ((CAPI_MSG *) msg)->header.ncci = 0; | 
 | 11288 |         ((CAPI_MSG *) msg)->info.facility_req.Selector = SELECTOR_LINE_INTERCONNECT; | 
 | 11289 |         ((CAPI_MSG *) msg)->info.facility_req.structs[0] = 3; | 
 | 11290 |         PUT_WORD (&(((CAPI_MSG *) msg)->info.facility_req.structs[1]), LI_REQ_SILENT_UPDATE); | 
 | 11291 |         ((CAPI_MSG *) msg)->info.facility_req.structs[3] = 0; | 
 | 11292 |         w = api_put (notify_plci->appl, (CAPI_MSG *) msg); | 
 | 11293 |         if (w != _QUEUE_FULL) | 
 | 11294 |         { | 
 | 11295 |           if (w != 0) | 
 | 11296 |           { | 
 | 11297 |             dbug (1, dprintf ("[%06lx] %s,%d: Interconnect notify failed %06x %d", | 
 | 11298 |               (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 11299 |               (char   *)(FILE_), __LINE__, | 
 | 11300 |               (dword)((notify_plci->Id << 8) | UnMapController (notify_plci->adapter->Id)), w)); | 
 | 11301 |           } | 
 | 11302 |           notify_plci->li_notify_update = FALSE; | 
 | 11303 |         } | 
 | 11304 |       } | 
 | 11305 |     } while (others && (notify_plci != NULL)); | 
 | 11306 |     if (others) | 
 | 11307 |       plci->li_notify_update = FALSE; | 
 | 11308 |   } | 
 | 11309 | } | 
 | 11310 |  | 
 | 11311 |  | 
 | 11312 | static void mixer_clear_config (PLCI   *plci) | 
 | 11313 | { | 
 | 11314 |   DIVA_CAPI_ADAPTER   *a; | 
 | 11315 |   word i, j; | 
 | 11316 |  | 
 | 11317 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_clear_config", | 
 | 11318 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 11319 |     (char   *)(FILE_), __LINE__)); | 
 | 11320 |  | 
 | 11321 |   plci->li_notify_update = FALSE; | 
 | 11322 |   plci->li_plci_b_write_pos = 0; | 
 | 11323 |   plci->li_plci_b_read_pos = 0; | 
 | 11324 |   plci->li_plci_b_req_pos = 0; | 
 | 11325 |   a = plci->adapter; | 
 | 11326 |   if ((plci->li_bchannel_id != 0) | 
 | 11327 |    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 11328 |   { | 
 | 11329 |     i = a->li_base + (plci->li_bchannel_id - 1); | 
 | 11330 |     li_config_table[i].curchnl = 0; | 
 | 11331 |     li_config_table[i].channel = 0; | 
 | 11332 |     li_config_table[i].chflags = 0; | 
 | 11333 |     for (j = 0; j < li_total_channels; j++) | 
 | 11334 |     { | 
 | 11335 |       li_config_table[j].flag_table[i] = 0; | 
 | 11336 |       li_config_table[i].flag_table[j] = 0; | 
 | 11337 |       li_config_table[i].coef_table[j] = 0; | 
 | 11338 |       li_config_table[j].coef_table[i] = 0; | 
 | 11339 |     } | 
 | 11340 |     if (!a->li_pri) | 
 | 11341 |     { | 
 | 11342 |       li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; | 
 | 11343 |       if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) | 
 | 11344 |       { | 
 | 11345 |         i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); | 
 | 11346 |         li_config_table[i].curchnl = 0; | 
 | 11347 |         li_config_table[i].channel = 0; | 
 | 11348 |         li_config_table[i].chflags = 0; | 
 | 11349 |         for (j = 0; j < li_total_channels; j++) | 
 | 11350 |         { | 
 | 11351 |           li_config_table[i].flag_table[j] = 0; | 
 | 11352 |           li_config_table[j].flag_table[i] = 0; | 
 | 11353 |           li_config_table[i].coef_table[j] = 0; | 
 | 11354 |           li_config_table[j].coef_table[i] = 0; | 
 | 11355 |         } | 
 | 11356 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) | 
 | 11357 |         { | 
 | 11358 |           i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); | 
 | 11359 |           li_config_table[i].curchnl = 0; | 
 | 11360 |           li_config_table[i].channel = 0; | 
 | 11361 |           li_config_table[i].chflags = 0; | 
 | 11362 |           for (j = 0; j < li_total_channels; j++) | 
 | 11363 |           { | 
 | 11364 |             li_config_table[i].flag_table[j] = 0; | 
 | 11365 |             li_config_table[j].flag_table[i] = 0; | 
 | 11366 |             li_config_table[i].coef_table[j] = 0; | 
 | 11367 |             li_config_table[j].coef_table[i] = 0; | 
 | 11368 |           } | 
 | 11369 |         } | 
 | 11370 |       } | 
 | 11371 |     } | 
 | 11372 |   } | 
 | 11373 | } | 
 | 11374 |  | 
 | 11375 |  | 
 | 11376 | static void mixer_prepare_switch (dword Id, PLCI   *plci) | 
 | 11377 | { | 
 | 11378 |  | 
 | 11379 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_prepare_switch", | 
 | 11380 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11381 |  | 
 | 11382 |   do | 
 | 11383 |   { | 
 | 11384 |     mixer_indication_coefs_set (Id, plci); | 
 | 11385 |   } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos); | 
 | 11386 | } | 
 | 11387 |  | 
 | 11388 |  | 
 | 11389 | static word mixer_save_config (dword Id, PLCI   *plci, byte Rc) | 
 | 11390 | { | 
 | 11391 |   DIVA_CAPI_ADAPTER   *a; | 
 | 11392 |   word i, j; | 
 | 11393 |  | 
 | 11394 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_save_config %02x %d", | 
 | 11395 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 11396 |  | 
 | 11397 |   a = plci->adapter; | 
 | 11398 |   if ((plci->li_bchannel_id != 0) | 
 | 11399 |    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 11400 |   { | 
 | 11401 |     i = a->li_base + (plci->li_bchannel_id - 1); | 
 | 11402 |     for (j = 0; j < li_total_channels; j++) | 
 | 11403 |     { | 
 | 11404 |       li_config_table[i].coef_table[j] &= 0xf; | 
 | 11405 |       li_config_table[j].coef_table[i] &= 0xf; | 
 | 11406 |     } | 
 | 11407 |     if (!a->li_pri) | 
 | 11408 |       li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; | 
 | 11409 |   } | 
 | 11410 |   return (GOOD); | 
 | 11411 | } | 
 | 11412 |  | 
 | 11413 |  | 
 | 11414 | static word mixer_restore_config (dword Id, PLCI   *plci, byte Rc) | 
 | 11415 | { | 
 | 11416 |   DIVA_CAPI_ADAPTER   *a; | 
 | 11417 |   word Info; | 
 | 11418 |  | 
 | 11419 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_restore_config %02x %d", | 
 | 11420 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 11421 |  | 
 | 11422 |   Info = GOOD; | 
 | 11423 |   a = plci->adapter; | 
 | 11424 |   if ((plci->B1_facilities & B1_FACILITY_MIXER) | 
 | 11425 |    && (plci->li_bchannel_id != 0) | 
 | 11426 |    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 11427 |   { | 
 | 11428 |     switch (plci->adjust_b_state) | 
 | 11429 |     { | 
 | 11430 |     case ADJUST_B_RESTORE_MIXER_1: | 
 | 11431 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 11432 |       { | 
 | 11433 |         plci->internal_command = plci->adjust_b_command; | 
 | 11434 |         if (plci_nl_busy (plci)) | 
 | 11435 |         { | 
 | 11436 |           plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1; | 
 | 11437 |           break; | 
 | 11438 |         } | 
 | 11439 |         xconnect_query_addresses (plci); | 
 | 11440 |         plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_2; | 
 | 11441 |         break; | 
 | 11442 |       } | 
 | 11443 |       plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; | 
 | 11444 |       Rc = OK; | 
 | 11445 |     case ADJUST_B_RESTORE_MIXER_2: | 
 | 11446 |     case ADJUST_B_RESTORE_MIXER_3: | 
 | 11447 |     case ADJUST_B_RESTORE_MIXER_4: | 
 | 11448 |       if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) | 
 | 11449 |       { | 
 | 11450 |         dbug (1, dprintf ("[%06lx] %s,%d: Adjust B query addresses failed %02x", | 
 | 11451 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 11452 |         Info = _WRONG_STATE; | 
 | 11453 |         break; | 
 | 11454 |       } | 
 | 11455 |       if (Rc == OK) | 
 | 11456 |       { | 
 | 11457 |         if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) | 
 | 11458 |           plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_3; | 
 | 11459 |         else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4) | 
 | 11460 |           plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; | 
 | 11461 |       } | 
 | 11462 |       else if (Rc == 0) | 
 | 11463 |       { | 
 | 11464 |         if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) | 
 | 11465 |           plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_4; | 
 | 11466 |         else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3) | 
 | 11467 |           plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; | 
 | 11468 |       } | 
 | 11469 |       if (plci->adjust_b_state != ADJUST_B_RESTORE_MIXER_5) | 
 | 11470 |       { | 
 | 11471 |         plci->internal_command = plci->adjust_b_command; | 
 | 11472 |         break; | 
 | 11473 |       } | 
 | 11474 |     case ADJUST_B_RESTORE_MIXER_5: | 
 | 11475 |       xconnect_write_coefs (plci, plci->adjust_b_command); | 
 | 11476 |       plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_6; | 
 | 11477 |       Rc = OK; | 
 | 11478 |     case ADJUST_B_RESTORE_MIXER_6: | 
 | 11479 |       if (!xconnect_write_coefs_process (Id, plci, Rc)) | 
 | 11480 |       { | 
 | 11481 |         dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed", | 
 | 11482 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11483 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 11484 |         break; | 
 | 11485 |       } | 
 | 11486 |       if (plci->internal_command) | 
 | 11487 |         break; | 
 | 11488 |       plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_7; | 
 | 11489 |     case ADJUST_B_RESTORE_MIXER_7: | 
 | 11490 |       break; | 
 | 11491 |     } | 
 | 11492 |   } | 
 | 11493 |   return (Info); | 
 | 11494 | } | 
 | 11495 |  | 
 | 11496 |  | 
 | 11497 | static void mixer_command (dword Id, PLCI   *plci, byte Rc) | 
 | 11498 | { | 
 | 11499 |   DIVA_CAPI_ADAPTER   *a; | 
 | 11500 |   word i, internal_command, Info; | 
 | 11501 |  | 
 | 11502 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x", | 
 | 11503 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command, | 
 | 11504 |     plci->li_cmd)); | 
 | 11505 |  | 
 | 11506 |   Info = GOOD; | 
 | 11507 |   a = plci->adapter; | 
 | 11508 |   internal_command = plci->internal_command; | 
 | 11509 |   plci->internal_command = 0; | 
 | 11510 |   switch (plci->li_cmd) | 
 | 11511 |   { | 
 | 11512 |   case LI_REQ_CONNECT: | 
 | 11513 |   case LI_REQ_DISCONNECT: | 
 | 11514 |   case LI_REQ_SILENT_UPDATE: | 
 | 11515 |     switch (internal_command) | 
 | 11516 |     { | 
 | 11517 |     default: | 
 | 11518 |       if (plci->li_channel_bits & LI_CHANNEL_INVOLVED) | 
 | 11519 |       { | 
 | 11520 |         adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities | | 
 | 11521 |           B1_FACILITY_MIXER), MIXER_COMMAND_1); | 
 | 11522 |       } | 
 | 11523 |     case MIXER_COMMAND_1: | 
 | 11524 |       if (plci->li_channel_bits & LI_CHANNEL_INVOLVED) | 
 | 11525 |       { | 
 | 11526 |         if (adjust_b_process (Id, plci, Rc) != GOOD) | 
 | 11527 |         { | 
 | 11528 |           dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed", | 
 | 11529 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11530 |           Info = _FACILITY_NOT_SUPPORTED; | 
 | 11531 |           break; | 
 | 11532 |         } | 
 | 11533 |         if (plci->internal_command) | 
 | 11534 |           return; | 
 | 11535 |       } | 
 | 11536 |       plci->li_plci_b_req_pos = plci->li_plci_b_write_pos; | 
 | 11537 |       if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED) | 
 | 11538 |        || ((get_b1_facilities (plci, plci->B1_resource) & B1_FACILITY_MIXER) | 
 | 11539 |         && (add_b1_facilities (plci, plci->B1_resource, (word)(plci->B1_facilities & | 
 | 11540 |          ~B1_FACILITY_MIXER)) == plci->B1_resource))) | 
 | 11541 |       { | 
 | 11542 |         xconnect_write_coefs (plci, MIXER_COMMAND_2); | 
 | 11543 |       } | 
 | 11544 |       else | 
 | 11545 |       { | 
 | 11546 |         do | 
 | 11547 |         { | 
 | 11548 |           mixer_indication_coefs_set (Id, plci); | 
 | 11549 |         } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos); | 
 | 11550 |       } | 
 | 11551 |     case MIXER_COMMAND_2: | 
 | 11552 |       if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED) | 
 | 11553 |        || ((get_b1_facilities (plci, plci->B1_resource) & B1_FACILITY_MIXER) | 
 | 11554 |         && (add_b1_facilities (plci, plci->B1_resource, (word)(plci->B1_facilities & | 
 | 11555 |          ~B1_FACILITY_MIXER)) == plci->B1_resource))) | 
 | 11556 |       { | 
 | 11557 |         if (!xconnect_write_coefs_process (Id, plci, Rc)) | 
 | 11558 |         { | 
 | 11559 |           dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed", | 
 | 11560 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11561 |           if (plci->li_plci_b_write_pos != plci->li_plci_b_req_pos) | 
 | 11562 |           { | 
 | 11563 |             do | 
 | 11564 |             { | 
 | 11565 |               plci->li_plci_b_write_pos = (plci->li_plci_b_write_pos == 0) ? | 
 | 11566 |                 LI_PLCI_B_QUEUE_ENTRIES-1 : plci->li_plci_b_write_pos - 1; | 
 | 11567 |               i = (plci->li_plci_b_write_pos == 0) ? | 
 | 11568 |                 LI_PLCI_B_QUEUE_ENTRIES-1 : plci->li_plci_b_write_pos - 1; | 
 | 11569 |             } while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos) | 
 | 11570 |               && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)); | 
 | 11571 |           } | 
 | 11572 |           Info = _FACILITY_NOT_SUPPORTED; | 
 | 11573 |           break; | 
 | 11574 |         } | 
 | 11575 |         if (plci->internal_command) | 
 | 11576 |           return; | 
 | 11577 |       } | 
 | 11578 |       if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED)) | 
 | 11579 |       { | 
 | 11580 |         adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities & | 
 | 11581 |           ~B1_FACILITY_MIXER), MIXER_COMMAND_3); | 
 | 11582 |       } | 
 | 11583 |     case MIXER_COMMAND_3: | 
 | 11584 |       if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED)) | 
 | 11585 |       { | 
 | 11586 |         if (adjust_b_process (Id, plci, Rc) != GOOD) | 
 | 11587 |         { | 
 | 11588 |           dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed", | 
 | 11589 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11590 |           Info = _FACILITY_NOT_SUPPORTED; | 
 | 11591 |           break; | 
 | 11592 |         } | 
 | 11593 |         if (plci->internal_command) | 
 | 11594 |           return; | 
 | 11595 |       } | 
 | 11596 |       break; | 
 | 11597 |     } | 
 | 11598 |     break; | 
 | 11599 |   } | 
 | 11600 |   if ((plci->li_bchannel_id == 0) | 
 | 11601 |    || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)) | 
 | 11602 |   { | 
 | 11603 |     dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out %d", | 
 | 11604 |       UnMapId (Id), (char   *)(FILE_), __LINE__, (int)(plci->li_bchannel_id))); | 
 | 11605 |   } | 
 | 11606 |   else | 
 | 11607 |   { | 
 | 11608 |     i = a->li_base + (plci->li_bchannel_id - 1); | 
 | 11609 |     li_config_table[i].curchnl = plci->li_channel_bits; | 
 | 11610 |     if (!a->li_pri && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) | 
 | 11611 |     { | 
 | 11612 |       i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); | 
 | 11613 |       li_config_table[i].curchnl = plci->li_channel_bits; | 
 | 11614 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) | 
 | 11615 |       { | 
 | 11616 |         i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); | 
 | 11617 |         li_config_table[i].curchnl = plci->li_channel_bits; | 
 | 11618 |       } | 
 | 11619 |     } | 
 | 11620 |   } | 
 | 11621 | } | 
 | 11622 |  | 
 | 11623 |  | 
 | 11624 | static void li_update_connect (dword Id, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, | 
 | 11625 |   dword plci_b_id, byte connect, dword li_flags) | 
 | 11626 | { | 
 | 11627 |   word i, ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s; | 
 | 11628 |   PLCI   *plci_b; | 
 | 11629 |   DIVA_CAPI_ADAPTER   *a_b; | 
 | 11630 |  | 
 | 11631 |   a_b = &(adapter[MapController ((byte)(plci_b_id & 0x7f)) - 1]); | 
 | 11632 |   plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]); | 
 | 11633 |   ch_a = a->li_base + (plci->li_bchannel_id - 1); | 
 | 11634 |   if (!a->li_pri && (plci->tel == ADV_VOICE) | 
 | 11635 |    && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER)) | 
 | 11636 |   { | 
 | 11637 |     ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE; | 
 | 11638 |     ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? | 
 | 11639 |       a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v; | 
 | 11640 |   } | 
 | 11641 |   else | 
 | 11642 |   { | 
 | 11643 |     ch_a_v = ch_a; | 
 | 11644 |     ch_a_s = ch_a; | 
 | 11645 |   } | 
 | 11646 |   ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1); | 
 | 11647 |   if (!a_b->li_pri && (plci_b->tel == ADV_VOICE) | 
 | 11648 |    && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER)) | 
 | 11649 |   { | 
 | 11650 |     ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE; | 
 | 11651 |     ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? | 
 | 11652 |       a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v; | 
 | 11653 |   } | 
 | 11654 |   else | 
 | 11655 |   { | 
 | 11656 |     ch_b_v = ch_b; | 
 | 11657 |     ch_b_s = ch_b; | 
 | 11658 |   } | 
 | 11659 |   if (connect) | 
 | 11660 |   { | 
 | 11661 |     li_config_table[ch_a].flag_table[ch_a_v] &= ~LI_FLAG_MONITOR; | 
 | 11662 |     li_config_table[ch_a].flag_table[ch_a_s] &= ~LI_FLAG_MONITOR; | 
 | 11663 |     li_config_table[ch_a_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); | 
 | 11664 |     li_config_table[ch_a_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); | 
 | 11665 |   } | 
 | 11666 |   li_config_table[ch_a].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR; | 
 | 11667 |   li_config_table[ch_a].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR; | 
 | 11668 |   li_config_table[ch_b_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); | 
 | 11669 |   li_config_table[ch_b_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); | 
 | 11670 |   if (ch_a_v == ch_b_v) | 
 | 11671 |   { | 
 | 11672 |     li_config_table[ch_a_v].flag_table[ch_b_v] &= ~LI_FLAG_CONFERENCE; | 
 | 11673 |     li_config_table[ch_a_s].flag_table[ch_b_s] &= ~LI_FLAG_CONFERENCE; | 
 | 11674 |   } | 
 | 11675 |   else | 
 | 11676 |   { | 
 | 11677 |     if (li_config_table[ch_a_v].flag_table[ch_b_v] & LI_FLAG_CONFERENCE) | 
 | 11678 |     { | 
 | 11679 |       for (i = 0; i < li_total_channels; i++) | 
 | 11680 |       { | 
 | 11681 |         if (i != ch_a_v) | 
 | 11682 |           li_config_table[ch_a_v].flag_table[i] &= ~LI_FLAG_CONFERENCE; | 
 | 11683 |       } | 
 | 11684 |     } | 
 | 11685 |     if (li_config_table[ch_a_s].flag_table[ch_b_v] & LI_FLAG_CONFERENCE) | 
 | 11686 |     { | 
 | 11687 |       for (i = 0; i < li_total_channels; i++) | 
 | 11688 |       { | 
 | 11689 |         if (i != ch_a_s) | 
 | 11690 |           li_config_table[ch_a_s].flag_table[i] &= ~LI_FLAG_CONFERENCE; | 
 | 11691 |       } | 
 | 11692 |     } | 
 | 11693 |     if (li_config_table[ch_b_v].flag_table[ch_a_v] & LI_FLAG_CONFERENCE) | 
 | 11694 |     { | 
 | 11695 |       for (i = 0; i < li_total_channels; i++) | 
 | 11696 |       { | 
 | 11697 |         if (i != ch_a_v) | 
 | 11698 |           li_config_table[i].flag_table[ch_a_v] &= ~LI_FLAG_CONFERENCE; | 
 | 11699 |       } | 
 | 11700 |     } | 
 | 11701 |     if (li_config_table[ch_b_v].flag_table[ch_a_s] & LI_FLAG_CONFERENCE) | 
 | 11702 |     { | 
 | 11703 |       for (i = 0; i < li_total_channels; i++) | 
 | 11704 |       { | 
 | 11705 |         if (i != ch_a_s) | 
 | 11706 |           li_config_table[i].flag_table[ch_a_s] &= ~LI_FLAG_CONFERENCE; | 
 | 11707 |       } | 
 | 11708 |     } | 
 | 11709 |   } | 
 | 11710 |   if (li_flags & LI_FLAG_CONFERENCE_A_B) | 
 | 11711 |   { | 
 | 11712 |     li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; | 
 | 11713 |     li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; | 
 | 11714 |     li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; | 
 | 11715 |     li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; | 
 | 11716 |   } | 
 | 11717 |   if (li_flags & LI_FLAG_CONFERENCE_B_A) | 
 | 11718 |   { | 
 | 11719 |     li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; | 
 | 11720 |     li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; | 
 | 11721 |     li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; | 
 | 11722 |     li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; | 
 | 11723 |   } | 
 | 11724 |   if (li_flags & LI_FLAG_MONITOR_A) | 
 | 11725 |   { | 
 | 11726 |     li_config_table[ch_a].flag_table[ch_a_v] |= LI_FLAG_MONITOR; | 
 | 11727 |     li_config_table[ch_a].flag_table[ch_a_s] |= LI_FLAG_MONITOR; | 
 | 11728 |   } | 
 | 11729 |   if (li_flags & LI_FLAG_MONITOR_B) | 
 | 11730 |   { | 
 | 11731 |     li_config_table[ch_a].flag_table[ch_b_v] |= LI_FLAG_MONITOR; | 
 | 11732 |     li_config_table[ch_a].flag_table[ch_b_s] |= LI_FLAG_MONITOR; | 
 | 11733 |   } | 
 | 11734 |   if (li_flags & LI_FLAG_ANNOUNCEMENT_A) | 
 | 11735 |   { | 
 | 11736 |     li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; | 
 | 11737 |     li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; | 
 | 11738 |   } | 
 | 11739 |   if (li_flags & LI_FLAG_ANNOUNCEMENT_B) | 
 | 11740 |   { | 
 | 11741 |     li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; | 
 | 11742 |     li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; | 
 | 11743 |   } | 
 | 11744 |   if (li_flags & LI_FLAG_MIX_A) | 
 | 11745 |   { | 
 | 11746 |     li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_MIX; | 
 | 11747 |     li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_MIX; | 
 | 11748 |   } | 
 | 11749 |   if (li_flags & LI_FLAG_MIX_B) | 
 | 11750 |   { | 
 | 11751 |     li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_MIX; | 
 | 11752 |     li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_MIX; | 
 | 11753 |   } | 
 | 11754 |   if (ch_a_v != ch_a_s) | 
 | 11755 |   { | 
 | 11756 |     li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; | 
 | 11757 |     li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; | 
 | 11758 |   } | 
 | 11759 |   if (ch_b_v != ch_b_s) | 
 | 11760 |   { | 
 | 11761 |     li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; | 
 | 11762 |     li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; | 
 | 11763 |   } | 
 | 11764 | } | 
 | 11765 |  | 
 | 11766 |  | 
 | 11767 | static void li2_update_connect (dword Id, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, | 
 | 11768 |   dword plci_b_id, byte connect, dword li_flags) | 
 | 11769 | { | 
 | 11770 |   word ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s; | 
 | 11771 |   PLCI   *plci_b; | 
 | 11772 |   DIVA_CAPI_ADAPTER   *a_b; | 
 | 11773 |  | 
 | 11774 |   a_b = &(adapter[MapController ((byte)(plci_b_id & 0x7f)) - 1]); | 
 | 11775 |   plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]); | 
 | 11776 |   ch_a = a->li_base + (plci->li_bchannel_id - 1); | 
 | 11777 |   if (!a->li_pri && (plci->tel == ADV_VOICE) | 
 | 11778 |    && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER)) | 
 | 11779 |   { | 
 | 11780 |     ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE; | 
 | 11781 |     ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? | 
 | 11782 |       a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v; | 
 | 11783 |   } | 
 | 11784 |   else | 
 | 11785 |   { | 
 | 11786 |     ch_a_v = ch_a; | 
 | 11787 |     ch_a_s = ch_a; | 
 | 11788 |   } | 
 | 11789 |   ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1); | 
 | 11790 |   if (!a_b->li_pri && (plci_b->tel == ADV_VOICE) | 
 | 11791 |    && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER)) | 
 | 11792 |   { | 
 | 11793 |     ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE; | 
 | 11794 |     ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? | 
 | 11795 |       a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v; | 
 | 11796 |   } | 
 | 11797 |   else | 
 | 11798 |   { | 
 | 11799 |     ch_b_v = ch_b; | 
 | 11800 |     ch_b_s = ch_b; | 
 | 11801 |   } | 
 | 11802 |   if (connect) | 
 | 11803 |   { | 
 | 11804 |     li_config_table[ch_b].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR; | 
 | 11805 |     li_config_table[ch_b].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR; | 
 | 11806 |     li_config_table[ch_b_v].flag_table[ch_b] &= ~LI_FLAG_MIX; | 
 | 11807 |     li_config_table[ch_b_s].flag_table[ch_b] &= ~LI_FLAG_MIX; | 
 | 11808 |     li_config_table[ch_b].flag_table[ch_b] &= ~LI_FLAG_PCCONNECT; | 
 | 11809 |     li_config_table[ch_b].chflags &= ~(LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP); | 
 | 11810 |   } | 
 | 11811 |   li_config_table[ch_b_v].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); | 
 | 11812 |   li_config_table[ch_b_s].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); | 
 | 11813 |   li_config_table[ch_b_v].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); | 
 | 11814 |   li_config_table[ch_b_s].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); | 
 | 11815 |   li_config_table[ch_a_v].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); | 
 | 11816 |   li_config_table[ch_a_v].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); | 
 | 11817 |   li_config_table[ch_a_s].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); | 
 | 11818 |   li_config_table[ch_a_s].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); | 
 | 11819 |   if (li_flags & LI2_FLAG_INTERCONNECT_A_B) | 
 | 11820 |   { | 
 | 11821 |     li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT; | 
 | 11822 |     li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT; | 
 | 11823 |     li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT; | 
 | 11824 |     li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT; | 
 | 11825 |   } | 
 | 11826 |   if (li_flags & LI2_FLAG_INTERCONNECT_B_A) | 
 | 11827 |   { | 
 | 11828 |     li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; | 
 | 11829 |     li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; | 
 | 11830 |     li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; | 
 | 11831 |     li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; | 
 | 11832 |   } | 
 | 11833 |   if (li_flags & LI2_FLAG_MONITOR_B) | 
 | 11834 |   { | 
 | 11835 |     li_config_table[ch_b].flag_table[ch_b_v] |= LI_FLAG_MONITOR; | 
 | 11836 |     li_config_table[ch_b].flag_table[ch_b_s] |= LI_FLAG_MONITOR; | 
 | 11837 |   } | 
 | 11838 |   if (li_flags & LI2_FLAG_MIX_B) | 
 | 11839 |   { | 
 | 11840 |     li_config_table[ch_b_v].flag_table[ch_b] |= LI_FLAG_MIX; | 
 | 11841 |     li_config_table[ch_b_s].flag_table[ch_b] |= LI_FLAG_MIX; | 
 | 11842 |   } | 
 | 11843 |   if (li_flags & LI2_FLAG_MONITOR_X) | 
 | 11844 |     li_config_table[ch_b].chflags |= LI_CHFLAG_MONITOR; | 
 | 11845 |   if (li_flags & LI2_FLAG_MIX_X) | 
 | 11846 |     li_config_table[ch_b].chflags |= LI_CHFLAG_MIX; | 
 | 11847 |   if (li_flags & LI2_FLAG_LOOP_B) | 
 | 11848 |   { | 
 | 11849 |     li_config_table[ch_b_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; | 
 | 11850 |     li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; | 
 | 11851 |     li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; | 
 | 11852 |     li_config_table[ch_b_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; | 
 | 11853 |   } | 
 | 11854 |   if (li_flags & LI2_FLAG_LOOP_PC) | 
 | 11855 |     li_config_table[ch_b].flag_table[ch_b] |= LI_FLAG_PCCONNECT; | 
 | 11856 |   if (li_flags & LI2_FLAG_LOOP_X) | 
 | 11857 |     li_config_table[ch_b].chflags |= LI_CHFLAG_LOOP; | 
 | 11858 |   if (li_flags & LI2_FLAG_PCCONNECT_A_B) | 
 | 11859 |     li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_PCCONNECT; | 
 | 11860 |   if (li_flags & LI2_FLAG_PCCONNECT_B_A) | 
 | 11861 |     li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_PCCONNECT; | 
 | 11862 |   if (ch_a_v != ch_a_s) | 
 | 11863 |   { | 
 | 11864 |     li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; | 
 | 11865 |     li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; | 
 | 11866 |   } | 
 | 11867 |   if (ch_b_v != ch_b_s) | 
 | 11868 |   { | 
 | 11869 |     li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; | 
 | 11870 |     li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; | 
 | 11871 |   } | 
 | 11872 | } | 
 | 11873 |  | 
 | 11874 |  | 
 | 11875 | static word li_check_main_plci (dword Id, PLCI   *plci) | 
 | 11876 | { | 
 | 11877 |   if (plci == NULL) | 
 | 11878 |   { | 
 | 11879 |     dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI", | 
 | 11880 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11881 |     return (_WRONG_IDENTIFIER); | 
 | 11882 |   } | 
 | 11883 |   if (!plci->State | 
 | 11884 |    || !plci->NL.Id || plci->nl_remove_id | 
 | 11885 |    || (plci->li_bchannel_id == 0)) | 
 | 11886 |   { | 
 | 11887 |     dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", | 
 | 11888 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11889 |     return (_WRONG_STATE); | 
 | 11890 |   } | 
 | 11891 |   li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = plci; | 
 | 11892 |   return (GOOD); | 
 | 11893 | } | 
 | 11894 |  | 
 | 11895 |  | 
 | 11896 | static PLCI   *li_check_plci_b (dword Id, PLCI   *plci, | 
 | 11897 |   dword plci_b_id, word plci_b_write_pos, byte   *p_result) | 
 | 11898 | { | 
 | 11899 |   byte ctlr_b; | 
 | 11900 |   PLCI   *plci_b; | 
 | 11901 |  | 
 | 11902 |   if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : | 
 | 11903 |     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) | 
 | 11904 |   { | 
 | 11905 |     dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun", | 
 | 11906 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11907 |     PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); | 
 | 11908 |     return (NULL); | 
 | 11909 |   } | 
 | 11910 |   ctlr_b = 0; | 
 | 11911 |   if ((plci_b_id & 0x7f) != 0) | 
 | 11912 |   { | 
 | 11913 |     ctlr_b = MapController ((byte)(plci_b_id & 0x7f)); | 
 | 11914 |     if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL))) | 
 | 11915 |       ctlr_b = 0; | 
 | 11916 |   } | 
 | 11917 |   if ((ctlr_b == 0) | 
 | 11918 |    || (((plci_b_id >> 8) & 0xff) == 0) | 
 | 11919 |    || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci)) | 
 | 11920 |   { | 
 | 11921 |     dbug (1, dprintf ("[%06lx] %s,%d: LI invalid second PLCI %08lx", | 
 | 11922 |       UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id)); | 
 | 11923 |     PUT_WORD (p_result, _WRONG_IDENTIFIER); | 
 | 11924 |     return (NULL); | 
 | 11925 |   } | 
 | 11926 |   plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]); | 
 | 11927 |   if (!plci_b->State | 
 | 11928 |    || !plci_b->NL.Id || plci_b->nl_remove_id | 
 | 11929 |    || (plci_b->li_bchannel_id == 0)) | 
 | 11930 |   { | 
 | 11931 |     dbug (1, dprintf ("[%06lx] %s,%d: LI peer in wrong state %08lx", | 
 | 11932 |       UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id)); | 
 | 11933 |     PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); | 
 | 11934 |     return (NULL); | 
 | 11935 |   } | 
 | 11936 |   li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci = plci_b; | 
 | 11937 |   if (((byte)(plci_b_id & ~EXT_CONTROLLER)) != | 
 | 11938 |     ((byte)(UnMapController (plci->adapter->Id) & ~EXT_CONTROLLER)) | 
 | 11939 |    && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 11940 |     || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT))) | 
 | 11941 |   { | 
 | 11942 |     dbug (1, dprintf ("[%06lx] %s,%d: LI not on same ctrl %08lx", | 
 | 11943 |       UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id)); | 
 | 11944 |     PUT_WORD (p_result, _WRONG_IDENTIFIER); | 
 | 11945 |     return (NULL); | 
 | 11946 |   } | 
 | 11947 |   if (!(get_b1_facilities (plci_b, add_b1_facilities (plci_b, plci_b->B1_resource, | 
 | 11948 |     (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER)) | 
 | 11949 |   { | 
 | 11950 |     dbug (1, dprintf ("[%06lx] %s,%d: Interconnect peer cannot mix %d", | 
 | 11951 |       UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b->B1_resource)); | 
 | 11952 |     PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); | 
 | 11953 |     return (NULL); | 
 | 11954 |   } | 
 | 11955 |   return (plci_b); | 
 | 11956 | } | 
 | 11957 |  | 
 | 11958 |  | 
 | 11959 | static PLCI   *li2_check_plci_b (dword Id, PLCI   *plci, | 
 | 11960 |   dword plci_b_id, word plci_b_write_pos, byte   *p_result) | 
 | 11961 | { | 
 | 11962 |   byte ctlr_b; | 
 | 11963 |   PLCI   *plci_b; | 
 | 11964 |  | 
 | 11965 |   if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : | 
 | 11966 |     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) | 
 | 11967 |   { | 
 | 11968 |     dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun", | 
 | 11969 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 11970 |     PUT_WORD (p_result, _WRONG_STATE); | 
 | 11971 |     return (NULL); | 
 | 11972 |   } | 
 | 11973 |   ctlr_b = 0; | 
 | 11974 |   if ((plci_b_id & 0x7f) != 0) | 
 | 11975 |   { | 
 | 11976 |     ctlr_b = MapController ((byte)(plci_b_id & 0x7f)); | 
 | 11977 |     if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL))) | 
 | 11978 |       ctlr_b = 0; | 
 | 11979 |   } | 
 | 11980 |   if ((ctlr_b == 0) | 
 | 11981 |    || (((plci_b_id >> 8) & 0xff) == 0) | 
 | 11982 |    || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci)) | 
 | 11983 |   { | 
 | 11984 |     dbug (1, dprintf ("[%06lx] %s,%d: LI invalid second PLCI %08lx", | 
 | 11985 |       UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id)); | 
 | 11986 |     PUT_WORD (p_result, _WRONG_IDENTIFIER); | 
 | 11987 |     return (NULL); | 
 | 11988 |   } | 
 | 11989 |   plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]); | 
 | 11990 |   if (!plci_b->State | 
 | 11991 |    || !plci_b->NL.Id || plci_b->nl_remove_id | 
 | 11992 |    || (plci_b->li_bchannel_id == 0) | 
 | 11993 |    || (li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci != plci_b)) | 
 | 11994 |   { | 
 | 11995 |     dbug (1, dprintf ("[%06lx] %s,%d: LI peer in wrong state %08lx", | 
 | 11996 |       UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id)); | 
 | 11997 |     PUT_WORD (p_result, _WRONG_STATE); | 
 | 11998 |     return (NULL); | 
 | 11999 |   } | 
 | 12000 |   if (((byte)(plci_b_id & ~EXT_CONTROLLER)) != | 
 | 12001 |     ((byte)(UnMapController (plci->adapter->Id) & ~EXT_CONTROLLER)) | 
 | 12002 |    && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 12003 |     || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT))) | 
 | 12004 |   { | 
 | 12005 |     dbug (1, dprintf ("[%06lx] %s,%d: LI not on same ctrl %08lx", | 
 | 12006 |       UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id)); | 
 | 12007 |     PUT_WORD (p_result, _WRONG_IDENTIFIER); | 
 | 12008 |     return (NULL); | 
 | 12009 |   } | 
 | 12010 |   if (!(get_b1_facilities (plci_b, add_b1_facilities (plci_b, plci_b->B1_resource, | 
 | 12011 |     (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER)) | 
 | 12012 |   { | 
 | 12013 |     dbug (1, dprintf ("[%06lx] %s,%d: Interconnect peer cannot mix %d", | 
 | 12014 |       UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b->B1_resource)); | 
 | 12015 |     PUT_WORD (p_result, _WRONG_STATE); | 
 | 12016 |     return (NULL); | 
 | 12017 |   } | 
 | 12018 |   return (plci_b); | 
 | 12019 | } | 
 | 12020 |  | 
 | 12021 |  | 
 | 12022 | static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg) | 
 | 12023 | { | 
 | 12024 |   word Info; | 
 | 12025 |   word i; | 
 | 12026 |   dword d, li_flags, plci_b_id; | 
 | 12027 |   PLCI   *plci_b; | 
 | 12028 |     API_PARSE li_parms[3]; | 
 | 12029 |     API_PARSE li_req_parms[3]; | 
 | 12030 |     API_PARSE li_participant_struct[2]; | 
 | 12031 |     API_PARSE li_participant_parms[3]; | 
 | 12032 |   word participant_parms_pos; | 
 | 12033 |   byte result_buffer[32]; | 
 | 12034 |   byte   *result; | 
 | 12035 |   word result_pos; | 
 | 12036 |   word plci_b_write_pos; | 
 | 12037 |  | 
 | 12038 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_request", | 
 | 12039 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12040 |  | 
 | 12041 |   Info = GOOD; | 
 | 12042 |   result = result_buffer; | 
 | 12043 |   result_buffer[0] = 0; | 
 | 12044 |   if (!(a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)) | 
 | 12045 |   { | 
 | 12046 |     dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported", | 
 | 12047 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12048 |     Info = _FACILITY_NOT_SUPPORTED; | 
 | 12049 |   } | 
 | 12050 |   else if (api_parse (&msg[1].info[1], msg[1].length, "ws", li_parms)) | 
 | 12051 |   { | 
 | 12052 |     dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12053 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12054 |     Info = _WRONG_MESSAGE_FORMAT; | 
 | 12055 |   } | 
 | 12056 |   else | 
 | 12057 |   { | 
 | 12058 |     result_buffer[0] = 3; | 
 | 12059 |     PUT_WORD (&result_buffer[1], GET_WORD (li_parms[0].info)); | 
 | 12060 |     result_buffer[3] = 0; | 
 | 12061 |     switch (GET_WORD (li_parms[0].info)) | 
 | 12062 |     { | 
 | 12063 |     case LI_GET_SUPPORTED_SERVICES: | 
 | 12064 |       if (appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) | 
 | 12065 |       { | 
 | 12066 |         result_buffer[0] = 17; | 
 | 12067 |         result_buffer[3] = 14; | 
 | 12068 |         PUT_WORD (&result_buffer[4], GOOD); | 
 | 12069 |         d = 0; | 
 | 12070 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_CH) | 
 | 12071 |           d |= LI_CONFERENCING_SUPPORTED; | 
 | 12072 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC) | 
 | 12073 |           d |= LI_MONITORING_SUPPORTED; | 
 | 12074 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH) | 
 | 12075 |           d |= LI_ANNOUNCEMENTS_SUPPORTED | LI_MIXING_SUPPORTED; | 
 | 12076 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 12077 |           d |= LI_CROSS_CONTROLLER_SUPPORTED; | 
 | 12078 |         PUT_DWORD (&result_buffer[6], d); | 
 | 12079 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 12080 |         { | 
 | 12081 |           d = 0; | 
 | 12082 |           for (i = 0; i < li_total_channels; i++) | 
 | 12083 |           { | 
 | 12084 |             if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 12085 |              && (li_config_table[i].adapter->li_pri | 
 | 12086 |               || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI))) | 
 | 12087 |             { | 
 | 12088 |               d++; | 
 | 12089 |             } | 
 | 12090 |           } | 
 | 12091 |         } | 
 | 12092 |         else | 
 | 12093 |         { | 
 | 12094 |           d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI; | 
 | 12095 |         } | 
 | 12096 |         PUT_DWORD (&result_buffer[10], d / 2); | 
 | 12097 |         PUT_DWORD (&result_buffer[14], d); | 
 | 12098 |       } | 
 | 12099 |       else | 
 | 12100 |       { | 
 | 12101 |         result_buffer[0] = 25; | 
 | 12102 |         result_buffer[3] = 22; | 
 | 12103 |         PUT_WORD (&result_buffer[4], GOOD); | 
 | 12104 |         d = LI2_ASYMMETRIC_SUPPORTED | LI2_B_LOOPING_SUPPORTED | LI2_X_LOOPING_SUPPORTED; | 
 | 12105 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC) | 
 | 12106 |           d |= LI2_MONITORING_SUPPORTED | LI2_REMOTE_MONITORING_SUPPORTED; | 
 | 12107 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH) | 
 | 12108 |           d |= LI2_MIXING_SUPPORTED | LI2_REMOTE_MIXING_SUPPORTED; | 
 | 12109 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_PC) | 
 | 12110 |           d |= LI2_PC_LOOPING_SUPPORTED; | 
 | 12111 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 12112 |           d |= LI2_CROSS_CONTROLLER_SUPPORTED; | 
 | 12113 |         PUT_DWORD (&result_buffer[6], d); | 
 | 12114 |         d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI; | 
 | 12115 |         PUT_DWORD (&result_buffer[10], d / 2); | 
 | 12116 |         PUT_DWORD (&result_buffer[14], d - 1); | 
 | 12117 |         if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 12118 |         { | 
 | 12119 |           d = 0; | 
 | 12120 |           for (i = 0; i < li_total_channels; i++) | 
 | 12121 |           { | 
 | 12122 |             if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) | 
 | 12123 |              && (li_config_table[i].adapter->li_pri | 
 | 12124 |               || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI))) | 
 | 12125 |             { | 
 | 12126 |               d++; | 
 | 12127 |             } | 
 | 12128 |           } | 
 | 12129 |         } | 
 | 12130 |         PUT_DWORD (&result_buffer[18], d / 2); | 
 | 12131 |         PUT_DWORD (&result_buffer[22], d - 1); | 
 | 12132 |       } | 
 | 12133 |       break; | 
 | 12134 |  | 
 | 12135 |     case LI_REQ_CONNECT: | 
 | 12136 |       if (li_parms[1].length == 8) | 
 | 12137 |       { | 
 | 12138 |         appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC; | 
 | 12139 |         if (api_parse (&li_parms[1].info[1], li_parms[1].length, "dd", li_req_parms)) | 
 | 12140 |         { | 
 | 12141 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12142 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12143 |           Info = _WRONG_MESSAGE_FORMAT; | 
 | 12144 |           break; | 
 | 12145 |         } | 
 | 12146 |         plci_b_id = GET_DWORD (li_req_parms[0].info) & 0xffff; | 
 | 12147 |         li_flags = GET_DWORD (li_req_parms[1].info); | 
 | 12148 |         Info = li_check_main_plci (Id, plci); | 
 | 12149 |         result_buffer[0] = 9; | 
 | 12150 |         result_buffer[3] = 6; | 
 | 12151 |         PUT_DWORD (&result_buffer[4], plci_b_id); | 
 | 12152 |         PUT_WORD (&result_buffer[8], GOOD); | 
 | 12153 |         if (Info != GOOD) | 
 | 12154 |           break; | 
 | 12155 |         result = plci->saved_msg.info; | 
 | 12156 |         for (i = 0; i <= result_buffer[0]; i++) | 
 | 12157 |           result[i] = result_buffer[i]; | 
 | 12158 |         plci_b_write_pos = plci->li_plci_b_write_pos; | 
 | 12159 |         plci_b = li_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[8]); | 
 | 12160 |         if (plci_b == NULL) | 
 | 12161 |           break; | 
 | 12162 |         li_update_connect (Id, a, plci, plci_b_id, TRUE, li_flags); | 
 | 12163 |         plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_LAST_FLAG; | 
 | 12164 |         plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; | 
 | 12165 |         plci->li_plci_b_write_pos = plci_b_write_pos; | 
 | 12166 |       } | 
 | 12167 |       else | 
 | 12168 |       { | 
 | 12169 |         appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC; | 
 | 12170 |         if (api_parse (&li_parms[1].info[1], li_parms[1].length, "ds", li_req_parms)) | 
 | 12171 |         { | 
 | 12172 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12173 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12174 |           Info = _WRONG_MESSAGE_FORMAT; | 
 | 12175 |           break; | 
 | 12176 |         } | 
 | 12177 |         li_flags = GET_DWORD (li_req_parms[0].info) & ~(LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A); | 
 | 12178 |         Info = li_check_main_plci (Id, plci); | 
 | 12179 |         result_buffer[0] = 7; | 
 | 12180 |         result_buffer[3] = 4; | 
 | 12181 |         PUT_WORD (&result_buffer[4], Info); | 
 | 12182 |         result_buffer[6] = 0; | 
 | 12183 |         if (Info != GOOD) | 
 | 12184 |           break; | 
 | 12185 |         result = plci->saved_msg.info; | 
 | 12186 |         for (i = 0; i <= result_buffer[0]; i++) | 
 | 12187 |           result[i] = result_buffer[i]; | 
 | 12188 |         plci_b_write_pos = plci->li_plci_b_write_pos; | 
 | 12189 |         participant_parms_pos = 0; | 
 | 12190 |         result_pos = 7; | 
 | 12191 |         li2_update_connect (Id, a, plci, UnMapId (Id), TRUE, li_flags); | 
 | 12192 |         while (participant_parms_pos < li_req_parms[1].length) | 
 | 12193 |         { | 
 | 12194 |           result[result_pos] = 6; | 
 | 12195 |           result_pos += 7; | 
 | 12196 |           PUT_DWORD (&result[result_pos - 6], 0); | 
 | 12197 |           PUT_WORD (&result[result_pos - 2], GOOD); | 
 | 12198 |           if (api_parse (&li_req_parms[1].info[1 + participant_parms_pos], | 
 | 12199 |             (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct)) | 
 | 12200 |           { | 
 | 12201 |             dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12202 |               UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12203 |             PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); | 
 | 12204 |             break; | 
 | 12205 |           } | 
 | 12206 |           if (api_parse (&li_participant_struct[0].info[1], | 
 | 12207 |             li_participant_struct[0].length, "dd", li_participant_parms)) | 
 | 12208 |           { | 
 | 12209 |             dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12210 |               UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12211 |             PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); | 
 | 12212 |             break; | 
 | 12213 |           } | 
 | 12214 |           plci_b_id = GET_DWORD (li_participant_parms[0].info) & 0xffff; | 
 | 12215 |           li_flags = GET_DWORD (li_participant_parms[1].info); | 
 | 12216 |           PUT_DWORD (&result[result_pos - 6], plci_b_id); | 
 | 12217 |           if (sizeof(result) - result_pos < 7) | 
 | 12218 |           { | 
 | 12219 |             dbug (1, dprintf ("[%06lx] %s,%d: LI result overrun", | 
 | 12220 |               UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12221 |             PUT_WORD (&result[result_pos - 2], _WRONG_STATE); | 
 | 12222 |             break; | 
 | 12223 |           } | 
 | 12224 |           plci_b = li2_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]); | 
 | 12225 |           if (plci_b != NULL) | 
 | 12226 |           { | 
 | 12227 |             li2_update_connect (Id, a, plci, plci_b_id, TRUE, li_flags); | 
 | 12228 |             plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | | 
 | 12229 |               ((li_flags & (LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A | | 
 | 12230 |               LI2_FLAG_PCCONNECT_A_B | LI2_FLAG_PCCONNECT_B_A)) ? 0 : LI_PLCI_B_DISC_FLAG); | 
 | 12231 |             plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; | 
 | 12232 |           } | 
 | 12233 |           participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) - | 
 | 12234 |             (&li_req_parms[1].info[1])); | 
 | 12235 |         } | 
 | 12236 |         result[0] = (byte)(result_pos - 1); | 
 | 12237 |         result[3] = (byte)(result_pos - 4); | 
 | 12238 |         result[6] = (byte)(result_pos - 7); | 
 | 12239 |         i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1; | 
 | 12240 |         if ((plci_b_write_pos == plci->li_plci_b_read_pos) | 
 | 12241 |          || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) | 
 | 12242 |         { | 
 | 12243 |           plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; | 
 | 12244 |           plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; | 
 | 12245 |         } | 
 | 12246 |         else | 
 | 12247 |           plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; | 
 | 12248 |         plci->li_plci_b_write_pos = plci_b_write_pos; | 
 | 12249 |       } | 
 | 12250 |       mixer_calculate_coefs (a); | 
 | 12251 |       plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; | 
 | 12252 |       mixer_notify_update (plci, TRUE); | 
 | 12253 |       sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, | 
 | 12254 |         "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); | 
 | 12255 |       plci->command = 0; | 
 | 12256 |       plci->li_cmd = GET_WORD (li_parms[0].info); | 
 | 12257 |       start_internal_command (Id, plci, mixer_command); | 
 | 12258 |       return (FALSE); | 
 | 12259 |  | 
 | 12260 |     case LI_REQ_DISCONNECT: | 
 | 12261 |       if (li_parms[1].length == 4) | 
 | 12262 |       { | 
 | 12263 |         appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC; | 
 | 12264 |         if (api_parse (&li_parms[1].info[1], li_parms[1].length, "d", li_req_parms)) | 
 | 12265 |         { | 
 | 12266 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12267 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12268 |           Info = _WRONG_MESSAGE_FORMAT; | 
 | 12269 |           break; | 
 | 12270 |         } | 
 | 12271 |         plci_b_id = GET_DWORD (li_req_parms[0].info) & 0xffff; | 
 | 12272 |         Info = li_check_main_plci (Id, plci); | 
 | 12273 |         result_buffer[0] = 9; | 
 | 12274 |         result_buffer[3] = 6; | 
 | 12275 |         PUT_DWORD (&result_buffer[4], GET_DWORD (li_req_parms[0].info)); | 
 | 12276 |         PUT_WORD (&result_buffer[8], GOOD); | 
 | 12277 |         if (Info != GOOD) | 
 | 12278 |           break; | 
 | 12279 |         result = plci->saved_msg.info; | 
 | 12280 |         for (i = 0; i <= result_buffer[0]; i++) | 
 | 12281 |           result[i] = result_buffer[i]; | 
 | 12282 |         plci_b_write_pos = plci->li_plci_b_write_pos; | 
 | 12283 |         plci_b = li_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[8]); | 
 | 12284 |         if (plci_b == NULL) | 
 | 12285 |           break; | 
 | 12286 |         li_update_connect (Id, a, plci, plci_b_id, FALSE, 0); | 
 | 12287 |         plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG | LI_PLCI_B_LAST_FLAG; | 
 | 12288 |         plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; | 
 | 12289 |         plci->li_plci_b_write_pos = plci_b_write_pos; | 
 | 12290 |       } | 
 | 12291 |       else | 
 | 12292 |       { | 
 | 12293 |         appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC; | 
 | 12294 |         if (api_parse (&li_parms[1].info[1], li_parms[1].length, "s", li_req_parms)) | 
 | 12295 |         { | 
 | 12296 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12297 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12298 |           Info = _WRONG_MESSAGE_FORMAT; | 
 | 12299 |           break; | 
 | 12300 |         } | 
 | 12301 |         Info = li_check_main_plci (Id, plci); | 
 | 12302 |         result_buffer[0] = 7; | 
 | 12303 |         result_buffer[3] = 4; | 
 | 12304 |         PUT_WORD (&result_buffer[4], Info); | 
 | 12305 |         result_buffer[6] = 0; | 
 | 12306 |         if (Info != GOOD) | 
 | 12307 |           break; | 
 | 12308 |         result = plci->saved_msg.info; | 
 | 12309 |         for (i = 0; i <= result_buffer[0]; i++) | 
 | 12310 |           result[i] = result_buffer[i]; | 
 | 12311 |         plci_b_write_pos = plci->li_plci_b_write_pos; | 
 | 12312 |         participant_parms_pos = 0; | 
 | 12313 |         result_pos = 7; | 
 | 12314 |         while (participant_parms_pos < li_req_parms[0].length) | 
 | 12315 |         { | 
 | 12316 |           result[result_pos] = 6; | 
 | 12317 |           result_pos += 7; | 
 | 12318 |           PUT_DWORD (&result[result_pos - 6], 0); | 
 | 12319 |           PUT_WORD (&result[result_pos - 2], GOOD); | 
 | 12320 |           if (api_parse (&li_req_parms[0].info[1 + participant_parms_pos], | 
 | 12321 |             (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct)) | 
 | 12322 |           { | 
 | 12323 |             dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12324 |               UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12325 |             PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); | 
 | 12326 |             break; | 
 | 12327 |           } | 
 | 12328 |           if (api_parse (&li_participant_struct[0].info[1], | 
 | 12329 |             li_participant_struct[0].length, "d", li_participant_parms)) | 
 | 12330 |           { | 
 | 12331 |             dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12332 |               UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12333 |             PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); | 
 | 12334 |             break; | 
 | 12335 |           } | 
 | 12336 |           plci_b_id = GET_DWORD (li_participant_parms[0].info) & 0xffff; | 
 | 12337 |           PUT_DWORD (&result[result_pos - 6], plci_b_id); | 
 | 12338 |           if (sizeof(result) - result_pos < 7) | 
 | 12339 |           { | 
 | 12340 |             dbug (1, dprintf ("[%06lx] %s,%d: LI result overrun", | 
 | 12341 |               UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12342 |             PUT_WORD (&result[result_pos - 2], _WRONG_STATE); | 
 | 12343 |             break; | 
 | 12344 |           } | 
 | 12345 |           plci_b = li2_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]); | 
 | 12346 |           if (plci_b != NULL) | 
 | 12347 |           { | 
 | 12348 |             li2_update_connect (Id, a, plci, plci_b_id, FALSE, 0); | 
 | 12349 |             plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG; | 
 | 12350 |             plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; | 
 | 12351 |           } | 
 | 12352 |           participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) - | 
 | 12353 |             (&li_req_parms[0].info[1])); | 
 | 12354 |         } | 
 | 12355 |         result[0] = (byte)(result_pos - 1); | 
 | 12356 |         result[3] = (byte)(result_pos - 4); | 
 | 12357 |         result[6] = (byte)(result_pos - 7); | 
 | 12358 |         i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1; | 
 | 12359 |         if ((plci_b_write_pos == plci->li_plci_b_read_pos) | 
 | 12360 |          || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) | 
 | 12361 |         { | 
 | 12362 |           plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; | 
 | 12363 |           plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; | 
 | 12364 |         } | 
 | 12365 |         else | 
 | 12366 |           plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; | 
 | 12367 |         plci->li_plci_b_write_pos = plci_b_write_pos; | 
 | 12368 |       } | 
 | 12369 |       mixer_calculate_coefs (a); | 
 | 12370 |       plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; | 
 | 12371 |       mixer_notify_update (plci, TRUE); | 
 | 12372 |       sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, | 
 | 12373 |         "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); | 
 | 12374 |       plci->command = 0; | 
 | 12375 |       plci->li_cmd = GET_WORD (li_parms[0].info); | 
 | 12376 |       start_internal_command (Id, plci, mixer_command); | 
 | 12377 |       return (FALSE); | 
 | 12378 |  | 
 | 12379 |     case LI_REQ_SILENT_UPDATE: | 
 | 12380 |       if (!plci || !plci->State | 
 | 12381 |        || !plci->NL.Id || plci->nl_remove_id | 
 | 12382 |        || (plci->li_bchannel_id == 0) | 
 | 12383 |        || (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci != plci)) | 
 | 12384 |       { | 
 | 12385 |         dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", | 
 | 12386 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12387 |         return (FALSE); | 
 | 12388 |       } | 
 | 12389 |       plci_b_write_pos = plci->li_plci_b_write_pos; | 
 | 12390 |       if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : | 
 | 12391 |         LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) | 
 | 12392 |       { | 
 | 12393 |         dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun", | 
 | 12394 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12395 |         return (FALSE); | 
 | 12396 |       } | 
 | 12397 |       i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1; | 
 | 12398 |       if ((plci_b_write_pos == plci->li_plci_b_read_pos) | 
 | 12399 |        || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) | 
 | 12400 |       { | 
 | 12401 |         plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; | 
 | 12402 |         plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; | 
 | 12403 |       } | 
 | 12404 |       else | 
 | 12405 |         plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; | 
 | 12406 |       plci->li_plci_b_write_pos = plci_b_write_pos; | 
 | 12407 |       plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; | 
 | 12408 |       plci->command = 0; | 
 | 12409 |       plci->li_cmd = GET_WORD (li_parms[0].info); | 
 | 12410 |       start_internal_command (Id, plci, mixer_command); | 
 | 12411 |       return (FALSE); | 
 | 12412 |  | 
 | 12413 |     default: | 
 | 12414 |       dbug (1, dprintf ("[%06lx] %s,%d: LI unknown request %04x", | 
 | 12415 |         UnMapId (Id), (char   *)(FILE_), __LINE__, GET_WORD (li_parms[0].info))); | 
 | 12416 |       Info = _FACILITY_NOT_SUPPORTED; | 
 | 12417 |     } | 
 | 12418 |   } | 
 | 12419 |   sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, | 
 | 12420 |     "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); | 
 | 12421 |   return (FALSE); | 
 | 12422 | } | 
 | 12423 |  | 
 | 12424 |  | 
 | 12425 | static void mixer_indication_coefs_set (dword Id, PLCI   *plci) | 
 | 12426 | { | 
 | 12427 |   dword d; | 
 | 12428 |   DIVA_CAPI_ADAPTER   *a; | 
 | 12429 |     byte result[12]; | 
 | 12430 |  | 
 | 12431 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set", | 
 | 12432 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12433 |  | 
 | 12434 |   a = plci->adapter; | 
 | 12435 |   if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos) | 
 | 12436 |   { | 
 | 12437 |     do | 
 | 12438 |     { | 
 | 12439 |       d = plci->li_plci_b_queue[plci->li_plci_b_read_pos]; | 
 | 12440 |       if (!(d & LI_PLCI_B_SKIP_FLAG)) | 
 | 12441 |       { | 
 | 12442 |         if (plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) | 
 | 12443 |         { | 
 | 12444 |           if (d & LI_PLCI_B_DISC_FLAG) | 
 | 12445 |           { | 
 | 12446 |             result[0] = 5; | 
 | 12447 |             PUT_WORD (&result[1], LI_IND_DISCONNECT); | 
 | 12448 |             result[3] = 2; | 
 | 12449 |             PUT_WORD (&result[4], _LI_USER_INITIATED); | 
 | 12450 |           } | 
 | 12451 |           else | 
 | 12452 |           { | 
 | 12453 |             result[0] = 7; | 
 | 12454 |             PUT_WORD (&result[1], LI_IND_CONNECT_ACTIVE); | 
 | 12455 |             result[3] = 4; | 
 | 12456 |             PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK); | 
 | 12457 |           } | 
 | 12458 |         } | 
 | 12459 |         else | 
 | 12460 |         { | 
 | 12461 |           if (d & LI_PLCI_B_DISC_FLAG) | 
 | 12462 |           { | 
 | 12463 |             result[0] = 9; | 
 | 12464 |             PUT_WORD (&result[1], LI_IND_DISCONNECT); | 
 | 12465 |             result[3] = 6; | 
 | 12466 |             PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK); | 
 | 12467 |             PUT_WORD (&result[8], _LI_USER_INITIATED); | 
 | 12468 |           } | 
 | 12469 |           else | 
 | 12470 |           { | 
 | 12471 |             result[0] = 7; | 
 | 12472 |             PUT_WORD (&result[1], LI_IND_CONNECT_ACTIVE); | 
 | 12473 |             result[3] = 4; | 
 | 12474 |             PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK); | 
 | 12475 |           } | 
 | 12476 |         } | 
 | 12477 |         sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, | 
 | 12478 |           "ws", SELECTOR_LINE_INTERCONNECT, result); | 
 | 12479 |       } | 
 | 12480 |       plci->li_plci_b_read_pos = (plci->li_plci_b_read_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? | 
 | 12481 |         0 : plci->li_plci_b_read_pos + 1; | 
 | 12482 |     } while (!(d & LI_PLCI_B_LAST_FLAG) && (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)); | 
 | 12483 |   } | 
 | 12484 | } | 
 | 12485 |  | 
 | 12486 |  | 
 | 12487 | static void mixer_indication_xconnect_from (dword Id, PLCI   *plci, byte   *msg, word length) | 
 | 12488 | { | 
 | 12489 |   word i, j, ch; | 
 | 12490 |   struct xconnect_transfer_address_s s,   *p; | 
 | 12491 |   DIVA_CAPI_ADAPTER   *a; | 
 | 12492 |  | 
 | 12493 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_from %d", | 
 | 12494 |     UnMapId (Id), (char   *)(FILE_), __LINE__, (int) length)); | 
 | 12495 |  | 
 | 12496 |   a = plci->adapter; | 
 | 12497 |   i = 1; | 
 | 12498 |   for (i = 1; i < length; i += 16) | 
 | 12499 |   { | 
 | 12500 |     s.card_address.low = msg[i] | (msg[i+1] << 8) | (((dword)(msg[i+2])) << 16) | (((dword)(msg[i+3])) << 24); | 
 | 12501 |     s.card_address.high = msg[i+4] | (msg[i+5] << 8) | (((dword)(msg[i+6])) << 16) | (((dword)(msg[i+7])) << 24); | 
 | 12502 |     s.offset = msg[i+8] | (msg[i+9] << 8) | (((dword)(msg[i+10])) << 16) | (((dword)(msg[i+11])) << 24); | 
 | 12503 |     ch = msg[i+12] | (msg[i+13] << 8); | 
 | 12504 |     j = ch & XCONNECT_CHANNEL_NUMBER_MASK; | 
 | 12505 |     if (!a->li_pri && (plci->li_bchannel_id == 2)) | 
 | 12506 |       j = 1 - j; | 
 | 12507 |     j += a->li_base; | 
 | 12508 |     if (ch & XCONNECT_CHANNEL_PORT_PC) | 
 | 12509 |       p = &(li_config_table[j].send_pc); | 
 | 12510 |     else | 
 | 12511 |       p = &(li_config_table[j].send_b); | 
 | 12512 |     p->card_address.low = s.card_address.low; | 
 | 12513 |     p->card_address.high = s.card_address.high; | 
 | 12514 |     p->offset = s.offset; | 
 | 12515 |     li_config_table[j].channel |= LI_CHANNEL_ADDRESSES_SET; | 
 | 12516 |   } | 
 | 12517 |   if (plci->internal_command_queue[0] | 
 | 12518 |    && ((plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) | 
 | 12519 |     || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3) | 
 | 12520 |     || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4))) | 
 | 12521 |   { | 
 | 12522 |     (*(plci->internal_command_queue[0]))(Id, plci, 0); | 
 | 12523 |     if (!plci->internal_command) | 
 | 12524 |       next_internal_command (Id, plci); | 
 | 12525 |   } | 
 | 12526 |   mixer_notify_update (plci, TRUE); | 
 | 12527 | } | 
 | 12528 |  | 
 | 12529 |  | 
 | 12530 | static void mixer_indication_xconnect_to (dword Id, PLCI   *plci, byte   *msg, word length) | 
 | 12531 | { | 
 | 12532 |  | 
 | 12533 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_to %d", | 
 | 12534 |     UnMapId (Id), (char   *)(FILE_), __LINE__, (int) length)); | 
 | 12535 |  | 
 | 12536 | } | 
 | 12537 |  | 
 | 12538 |  | 
 | 12539 | static byte mixer_notify_source_removed (PLCI   *plci, dword plci_b_id) | 
 | 12540 | { | 
 | 12541 |   word plci_b_write_pos; | 
 | 12542 |  | 
 | 12543 |   plci_b_write_pos = plci->li_plci_b_write_pos; | 
 | 12544 |   if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : | 
 | 12545 |     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 1) | 
 | 12546 |   { | 
 | 12547 |     dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun", | 
 | 12548 |       (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 12549 |       (char   *)(FILE_), __LINE__)); | 
 | 12550 |     return (FALSE); | 
 | 12551 |   } | 
 | 12552 |   plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG; | 
 | 12553 |   plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; | 
 | 12554 |   plci->li_plci_b_write_pos = plci_b_write_pos; | 
 | 12555 |   return (TRUE); | 
 | 12556 | } | 
 | 12557 |  | 
 | 12558 |  | 
 | 12559 | static void mixer_remove (PLCI   *plci) | 
 | 12560 | { | 
 | 12561 |   DIVA_CAPI_ADAPTER   *a; | 
 | 12562 |   PLCI   *notify_plci; | 
 | 12563 |   dword plci_b_id; | 
 | 12564 |   word i, j; | 
 | 12565 |  | 
 | 12566 |   dbug (1, dprintf ("[%06lx] %s,%d: mixer_remove", | 
 | 12567 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 12568 |     (char   *)(FILE_), __LINE__)); | 
 | 12569 |  | 
 | 12570 |   a = plci->adapter; | 
 | 12571 |   plci_b_id = (plci->Id << 8) | UnMapController (plci->adapter->Id); | 
 | 12572 |   if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED) | 
 | 12573 |   { | 
 | 12574 |     if ((plci->li_bchannel_id != 0) | 
 | 12575 |      && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 12576 |     { | 
 | 12577 |       i = a->li_base + (plci->li_bchannel_id - 1); | 
 | 12578 |       if ((li_config_table[i].curchnl | li_config_table[i].channel) & LI_CHANNEL_INVOLVED) | 
 | 12579 |       { | 
 | 12580 |         for (j = 0; j < li_total_channels; j++) | 
 | 12581 |         { | 
 | 12582 |           if ((li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) | 
 | 12583 |            || (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT)) | 
 | 12584 |           { | 
 | 12585 |             notify_plci = li_config_table[j].plci; | 
 | 12586 |             if ((notify_plci != NULL) | 
 | 12587 |              && (notify_plci != plci) | 
 | 12588 |              && (notify_plci->appl != NULL) | 
 | 12589 |              && !(notify_plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) | 
 | 12590 |              && (notify_plci->State) | 
 | 12591 |              && notify_plci->NL.Id && !notify_plci->nl_remove_id) | 
 | 12592 |             { | 
 | 12593 |               mixer_notify_source_removed (notify_plci, plci_b_id); | 
 | 12594 |             } | 
 | 12595 |           } | 
 | 12596 |         } | 
 | 12597 |         mixer_clear_config (plci); | 
 | 12598 |         mixer_calculate_coefs (a); | 
 | 12599 |         mixer_notify_update (plci, TRUE); | 
 | 12600 |       } | 
 | 12601 |       li_config_table[i].plci = NULL; | 
 | 12602 |       plci->li_bchannel_id = 0; | 
 | 12603 |     } | 
 | 12604 |   } | 
 | 12605 | } | 
 | 12606 |  | 
 | 12607 |  | 
 | 12608 | /*------------------------------------------------------------------*/ | 
 | 12609 | /* Echo canceller facilities                                        */ | 
 | 12610 | /*------------------------------------------------------------------*/ | 
 | 12611 |  | 
 | 12612 |  | 
 | 12613 | static void ec_write_parameters (PLCI   *plci) | 
 | 12614 | { | 
 | 12615 |   word w; | 
 | 12616 |     byte parameter_buffer[6]; | 
 | 12617 |  | 
 | 12618 |   dbug (1, dprintf ("[%06lx] %s,%d: ec_write_parameters", | 
 | 12619 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 12620 |     (char   *)(FILE_), __LINE__)); | 
 | 12621 |  | 
 | 12622 |   parameter_buffer[0] = 5; | 
 | 12623 |   parameter_buffer[1] = DSP_CTRL_SET_LEC_PARAMETERS; | 
 | 12624 |   PUT_WORD (¶meter_buffer[2], plci->ec_idi_options); | 
 | 12625 |   plci->ec_idi_options &= ~LEC_RESET_COEFFICIENTS; | 
 | 12626 |   w = (plci->ec_tail_length == 0) ? 128 : plci->ec_tail_length; | 
 | 12627 |   PUT_WORD (¶meter_buffer[4], w); | 
 | 12628 |   add_p (plci, FTY, parameter_buffer); | 
 | 12629 |   sig_req (plci, TEL_CTRL, 0); | 
 | 12630 |   send_req (plci); | 
 | 12631 | } | 
 | 12632 |  | 
 | 12633 |  | 
 | 12634 | static void ec_clear_config (PLCI   *plci) | 
 | 12635 | { | 
 | 12636 |  | 
 | 12637 |   dbug (1, dprintf ("[%06lx] %s,%d: ec_clear_config", | 
 | 12638 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 12639 |     (char   *)(FILE_), __LINE__)); | 
 | 12640 |  | 
 | 12641 |   plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | | 
 | 12642 |     LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING; | 
 | 12643 |   plci->ec_tail_length = 0; | 
 | 12644 | } | 
 | 12645 |  | 
 | 12646 |  | 
 | 12647 | static void ec_prepare_switch (dword Id, PLCI   *plci) | 
 | 12648 | { | 
 | 12649 |  | 
 | 12650 |   dbug (1, dprintf ("[%06lx] %s,%d: ec_prepare_switch", | 
 | 12651 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12652 |  | 
 | 12653 | } | 
 | 12654 |  | 
 | 12655 |  | 
 | 12656 | static word ec_save_config (dword Id, PLCI   *plci, byte Rc) | 
 | 12657 | { | 
 | 12658 |  | 
 | 12659 |   dbug (1, dprintf ("[%06lx] %s,%d: ec_save_config %02x %d", | 
 | 12660 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 12661 |  | 
 | 12662 |   return (GOOD); | 
 | 12663 | } | 
 | 12664 |  | 
 | 12665 |  | 
 | 12666 | static word ec_restore_config (dword Id, PLCI   *plci, byte Rc) | 
 | 12667 | { | 
 | 12668 |   word Info; | 
 | 12669 |  | 
 | 12670 |   dbug (1, dprintf ("[%06lx] %s,%d: ec_restore_config %02x %d", | 
 | 12671 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 12672 |  | 
 | 12673 |   Info = GOOD; | 
 | 12674 |   if (plci->B1_facilities & B1_FACILITY_EC) | 
 | 12675 |   { | 
 | 12676 |     switch (plci->adjust_b_state) | 
 | 12677 |     { | 
 | 12678 |     case ADJUST_B_RESTORE_EC_1: | 
 | 12679 |       plci->internal_command = plci->adjust_b_command; | 
 | 12680 |       if (plci->sig_req) | 
 | 12681 |       { | 
 | 12682 |         plci->adjust_b_state = ADJUST_B_RESTORE_EC_1; | 
 | 12683 |         break; | 
 | 12684 |       } | 
 | 12685 |       ec_write_parameters (plci); | 
 | 12686 |       plci->adjust_b_state = ADJUST_B_RESTORE_EC_2; | 
 | 12687 |       break; | 
 | 12688 |     case ADJUST_B_RESTORE_EC_2: | 
 | 12689 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 12690 |       { | 
 | 12691 |         dbug (1, dprintf ("[%06lx] %s,%d: Restore EC failed %02x", | 
 | 12692 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 12693 |         Info = _WRONG_STATE; | 
 | 12694 |         break; | 
 | 12695 |       } | 
 | 12696 |       break; | 
 | 12697 |     } | 
 | 12698 |   } | 
 | 12699 |   return (Info); | 
 | 12700 | } | 
 | 12701 |  | 
 | 12702 |  | 
 | 12703 | static void ec_command (dword Id, PLCI   *plci, byte Rc) | 
 | 12704 | { | 
 | 12705 |   word internal_command, Info; | 
 | 12706 |     byte result[8]; | 
 | 12707 |  | 
 | 12708 |   dbug (1, dprintf ("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d", | 
 | 12709 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command, | 
 | 12710 |     plci->ec_cmd, plci->ec_idi_options, plci->ec_tail_length)); | 
 | 12711 |  | 
 | 12712 |   Info = GOOD; | 
 | 12713 |   if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) | 
 | 12714 |   { | 
 | 12715 |     result[0] = 2; | 
 | 12716 |     PUT_WORD (&result[1], EC_SUCCESS); | 
 | 12717 |   } | 
 | 12718 |   else | 
 | 12719 |   { | 
 | 12720 |     result[0] = 5; | 
 | 12721 |     PUT_WORD (&result[1], plci->ec_cmd); | 
 | 12722 |     result[3] = 2; | 
 | 12723 |     PUT_WORD (&result[4], GOOD); | 
 | 12724 |   } | 
 | 12725 |   internal_command = plci->internal_command; | 
 | 12726 |   plci->internal_command = 0; | 
 | 12727 |   switch (plci->ec_cmd) | 
 | 12728 |   { | 
 | 12729 |   case EC_ENABLE_OPERATION: | 
 | 12730 |   case EC_FREEZE_COEFFICIENTS: | 
 | 12731 |   case EC_RESUME_COEFFICIENT_UPDATE: | 
 | 12732 |   case EC_RESET_COEFFICIENTS: | 
 | 12733 |     switch (internal_command) | 
 | 12734 |     { | 
 | 12735 |     default: | 
 | 12736 |       adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities | | 
 | 12737 |         B1_FACILITY_EC), EC_COMMAND_1); | 
 | 12738 |     case EC_COMMAND_1: | 
 | 12739 |       if (adjust_b_process (Id, plci, Rc) != GOOD) | 
 | 12740 |       { | 
 | 12741 |         dbug (1, dprintf ("[%06lx] %s,%d: Load EC failed", | 
 | 12742 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12743 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 12744 |         break; | 
 | 12745 |       } | 
 | 12746 |       if (plci->internal_command) | 
 | 12747 |         return; | 
 | 12748 |     case EC_COMMAND_2: | 
 | 12749 |       if (plci->sig_req) | 
 | 12750 |       { | 
 | 12751 |         plci->internal_command = EC_COMMAND_2; | 
 | 12752 |         return; | 
 | 12753 |       } | 
 | 12754 |       plci->internal_command = EC_COMMAND_3; | 
 | 12755 |       ec_write_parameters (plci); | 
 | 12756 |       return; | 
 | 12757 |     case EC_COMMAND_3: | 
 | 12758 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 12759 |       { | 
 | 12760 |         dbug (1, dprintf ("[%06lx] %s,%d: Enable EC failed %02x", | 
 | 12761 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 12762 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 12763 |         break; | 
 | 12764 |       } | 
 | 12765 |       break; | 
 | 12766 |     } | 
 | 12767 |     break; | 
 | 12768 |  | 
 | 12769 |   case EC_DISABLE_OPERATION: | 
 | 12770 |     switch (internal_command) | 
 | 12771 |     { | 
 | 12772 |     default: | 
 | 12773 |     case EC_COMMAND_1: | 
 | 12774 |       if (plci->B1_facilities & B1_FACILITY_EC) | 
 | 12775 |       { | 
 | 12776 |         if (plci->sig_req) | 
 | 12777 |         { | 
 | 12778 |           plci->internal_command = EC_COMMAND_1; | 
 | 12779 |           return; | 
 | 12780 |         } | 
 | 12781 |         plci->internal_command = EC_COMMAND_2; | 
 | 12782 |         ec_write_parameters (plci); | 
 | 12783 |         return; | 
 | 12784 |       } | 
 | 12785 |       Rc = OK; | 
 | 12786 |     case EC_COMMAND_2: | 
 | 12787 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 12788 |       { | 
 | 12789 |         dbug (1, dprintf ("[%06lx] %s,%d: Disable EC failed %02x", | 
 | 12790 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 12791 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 12792 |         break; | 
 | 12793 |       } | 
 | 12794 |       adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities & | 
 | 12795 |         ~B1_FACILITY_EC), EC_COMMAND_3); | 
 | 12796 |     case EC_COMMAND_3: | 
 | 12797 |       if (adjust_b_process (Id, plci, Rc) != GOOD) | 
 | 12798 |       { | 
 | 12799 |         dbug (1, dprintf ("[%06lx] %s,%d: Unload EC failed", | 
 | 12800 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12801 |         Info = _FACILITY_NOT_SUPPORTED; | 
 | 12802 |         break; | 
 | 12803 |       } | 
 | 12804 |       if (plci->internal_command) | 
 | 12805 |         return; | 
 | 12806 |       break; | 
 | 12807 |     } | 
 | 12808 |     break; | 
 | 12809 |   } | 
 | 12810 |   sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number, | 
 | 12811 |     "wws", Info, (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? | 
 | 12812 |     PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); | 
 | 12813 | } | 
 | 12814 |  | 
 | 12815 |  | 
 | 12816 | static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg) | 
 | 12817 | { | 
 | 12818 |   word Info; | 
 | 12819 |   word opt; | 
 | 12820 |     API_PARSE ec_parms[3]; | 
 | 12821 |     byte result[16]; | 
 | 12822 |  | 
 | 12823 |   dbug (1, dprintf ("[%06lx] %s,%d: ec_request", | 
 | 12824 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12825 |  | 
 | 12826 |   Info = GOOD; | 
 | 12827 |   result[0] = 0; | 
 | 12828 |   if (!(a->man_profile.private_options & (1L << PRIVATE_ECHO_CANCELLER))) | 
 | 12829 |   { | 
 | 12830 |     dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported", | 
 | 12831 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12832 |     Info = _FACILITY_NOT_SUPPORTED; | 
 | 12833 |   } | 
 | 12834 |   else | 
 | 12835 |   { | 
 | 12836 |     if (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) | 
 | 12837 |     { | 
 | 12838 |       if (api_parse (&msg[1].info[1], msg[1].length, "w", ec_parms)) | 
 | 12839 |       { | 
 | 12840 |         dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12841 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12842 |         Info = _WRONG_MESSAGE_FORMAT; | 
 | 12843 |       } | 
 | 12844 |       else | 
 | 12845 |       { | 
 | 12846 |         if (plci == NULL) | 
 | 12847 |         { | 
 | 12848 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI", | 
 | 12849 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12850 |           Info = _WRONG_IDENTIFIER; | 
 | 12851 |         } | 
 | 12852 |         else if (!plci->State || !plci->NL.Id || plci->nl_remove_id) | 
 | 12853 |         { | 
 | 12854 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", | 
 | 12855 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12856 |           Info = _WRONG_STATE; | 
 | 12857 |         } | 
 | 12858 |         else | 
 | 12859 |         { | 
 | 12860 |           plci->command = 0; | 
 | 12861 |           plci->ec_cmd = GET_WORD (ec_parms[0].info); | 
 | 12862 |           plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS); | 
 | 12863 |           result[0] = 2; | 
 | 12864 |           PUT_WORD (&result[1], EC_SUCCESS); | 
 | 12865 |           if (msg[1].length >= 4) | 
 | 12866 |           { | 
 | 12867 |             opt = GET_WORD (&ec_parms[0].info[2]); | 
 | 12868 |             plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING | | 
 | 12869 |               LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS); | 
 | 12870 |             if (!(opt & EC_DISABLE_NON_LINEAR_PROCESSING)) | 
 | 12871 |               plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING; | 
 | 12872 |             if (opt & EC_DETECT_DISABLE_TONE) | 
 | 12873 |               plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR; | 
 | 12874 |             if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS)) | 
 | 12875 |               plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS; | 
 | 12876 |             if (msg[1].length >= 6) | 
 | 12877 |             { | 
 | 12878 |               plci->ec_tail_length = GET_WORD (&ec_parms[0].info[4]); | 
 | 12879 |             } | 
 | 12880 |           } | 
 | 12881 |           switch (plci->ec_cmd) | 
 | 12882 |           { | 
 | 12883 |           case EC_ENABLE_OPERATION: | 
 | 12884 |             plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; | 
 | 12885 |             start_internal_command (Id, plci, ec_command); | 
 | 12886 |             return (FALSE); | 
 | 12887 |  | 
 | 12888 |           case EC_DISABLE_OPERATION: | 
 | 12889 |             plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | | 
 | 12890 |               LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING | | 
 | 12891 |               LEC_RESET_COEFFICIENTS; | 
 | 12892 |             start_internal_command (Id, plci, ec_command); | 
 | 12893 |             return (FALSE); | 
 | 12894 |  | 
 | 12895 |           case EC_FREEZE_COEFFICIENTS: | 
 | 12896 |             plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS; | 
 | 12897 |             start_internal_command (Id, plci, ec_command); | 
 | 12898 |             return (FALSE); | 
 | 12899 |  | 
 | 12900 |           case EC_RESUME_COEFFICIENT_UPDATE: | 
 | 12901 |             plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; | 
 | 12902 |             start_internal_command (Id, plci, ec_command); | 
 | 12903 |             return (FALSE); | 
 | 12904 |  | 
 | 12905 |           case EC_RESET_COEFFICIENTS: | 
 | 12906 |             plci->ec_idi_options |= LEC_RESET_COEFFICIENTS; | 
 | 12907 |             start_internal_command (Id, plci, ec_command); | 
 | 12908 |             return (FALSE); | 
 | 12909 |  | 
 | 12910 |           default: | 
 | 12911 |             dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x", | 
 | 12912 |               UnMapId (Id), (char   *)(FILE_), __LINE__, plci->ec_cmd)); | 
 | 12913 |             PUT_WORD (&result[1], EC_UNSUPPORTED_OPERATION); | 
 | 12914 |           } | 
 | 12915 |         } | 
 | 12916 |       } | 
 | 12917 |     } | 
 | 12918 |     else | 
 | 12919 |     { | 
 | 12920 |       if (api_parse (&msg[1].info[1], msg[1].length, "ws", ec_parms)) | 
 | 12921 |       { | 
 | 12922 |         dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", | 
 | 12923 |           UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12924 |         Info = _WRONG_MESSAGE_FORMAT; | 
 | 12925 |       } | 
 | 12926 |       else | 
 | 12927 |       { | 
 | 12928 |         if (GET_WORD (ec_parms[0].info) == EC_GET_SUPPORTED_SERVICES) | 
 | 12929 |         { | 
 | 12930 |           result[0] = 11; | 
 | 12931 |           PUT_WORD (&result[1], EC_GET_SUPPORTED_SERVICES); | 
 | 12932 |           result[3] = 8; | 
 | 12933 |           PUT_WORD (&result[4], GOOD); | 
 | 12934 |           PUT_WORD (&result[6], 0x0007); | 
 | 12935 |           PUT_WORD (&result[8], LEC_MAX_SUPPORTED_TAIL_LENGTH); | 
 | 12936 |           PUT_WORD (&result[10], 0); | 
 | 12937 |         } | 
 | 12938 |         else if (plci == NULL) | 
 | 12939 |         { | 
 | 12940 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI", | 
 | 12941 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12942 |           Info = _WRONG_IDENTIFIER; | 
 | 12943 |         } | 
 | 12944 |         else if (!plci->State || !plci->NL.Id || plci->nl_remove_id) | 
 | 12945 |         { | 
 | 12946 |           dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", | 
 | 12947 |             UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 12948 |           Info = _WRONG_STATE; | 
 | 12949 |         } | 
 | 12950 |         else | 
 | 12951 |         { | 
 | 12952 |           plci->command = 0; | 
 | 12953 |           plci->ec_cmd = GET_WORD (ec_parms[0].info); | 
 | 12954 |           plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS); | 
 | 12955 |           result[0] = 5; | 
 | 12956 |           PUT_WORD (&result[1], plci->ec_cmd); | 
 | 12957 |           result[3] = 2; | 
 | 12958 |           PUT_WORD (&result[4], GOOD); | 
 | 12959 |           plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING | | 
 | 12960 |             LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS); | 
 | 12961 |           plci->ec_tail_length = 0; | 
 | 12962 |           if (ec_parms[1].length >= 2) | 
 | 12963 |           { | 
 | 12964 |             opt = GET_WORD (&ec_parms[1].info[1]); | 
 | 12965 |             if (opt & EC_ENABLE_NON_LINEAR_PROCESSING) | 
 | 12966 |               plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING; | 
 | 12967 |             if (opt & EC_DETECT_DISABLE_TONE) | 
 | 12968 |               plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR; | 
 | 12969 |             if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS)) | 
 | 12970 |               plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS; | 
 | 12971 |             if (ec_parms[1].length >= 4) | 
 | 12972 |             { | 
 | 12973 |               plci->ec_tail_length = GET_WORD (&ec_parms[1].info[3]); | 
 | 12974 |             } | 
 | 12975 |           } | 
 | 12976 |           switch (plci->ec_cmd) | 
 | 12977 |           { | 
 | 12978 |           case EC_ENABLE_OPERATION: | 
 | 12979 |             plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; | 
 | 12980 |             start_internal_command (Id, plci, ec_command); | 
 | 12981 |             return (FALSE); | 
 | 12982 |  | 
 | 12983 |           case EC_DISABLE_OPERATION: | 
 | 12984 |             plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | | 
 | 12985 |               LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING | | 
 | 12986 |               LEC_RESET_COEFFICIENTS; | 
 | 12987 |             start_internal_command (Id, plci, ec_command); | 
 | 12988 |             return (FALSE); | 
 | 12989 |  | 
 | 12990 |           default: | 
 | 12991 |             dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x", | 
 | 12992 |               UnMapId (Id), (char   *)(FILE_), __LINE__, plci->ec_cmd)); | 
 | 12993 |             PUT_WORD (&result[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP); | 
 | 12994 |           } | 
 | 12995 |         } | 
 | 12996 |       } | 
 | 12997 |     } | 
 | 12998 |   } | 
 | 12999 |   sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, | 
 | 13000 |     "wws", Info, (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? | 
 | 13001 |     PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); | 
 | 13002 |   return (FALSE); | 
 | 13003 | } | 
 | 13004 |  | 
 | 13005 |  | 
 | 13006 | static void ec_indication (dword Id, PLCI   *plci, byte   *msg, word length) | 
 | 13007 | { | 
 | 13008 |     byte result[8]; | 
 | 13009 |  | 
 | 13010 |   dbug (1, dprintf ("[%06lx] %s,%d: ec_indication", | 
 | 13011 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 13012 |  | 
 | 13013 |   if (!(plci->ec_idi_options & LEC_MANUAL_DISABLE)) | 
 | 13014 |   { | 
 | 13015 |     if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) | 
 | 13016 |     { | 
 | 13017 |       result[0] = 2; | 
 | 13018 |       PUT_WORD (&result[1], 0); | 
 | 13019 |       switch (msg[1]) | 
 | 13020 |       { | 
 | 13021 |       case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ: | 
 | 13022 |         PUT_WORD (&result[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ); | 
 | 13023 |         break; | 
 | 13024 |       case LEC_DISABLE_TYPE_REVERSED_2100HZ: | 
 | 13025 |         PUT_WORD (&result[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ); | 
 | 13026 |         break; | 
 | 13027 |       case LEC_DISABLE_RELEASED: | 
 | 13028 |         PUT_WORD (&result[1], EC_BYPASS_RELEASED); | 
 | 13029 |         break; | 
 | 13030 |       } | 
 | 13031 |     } | 
 | 13032 |     else | 
 | 13033 |     { | 
 | 13034 |       result[0] = 5; | 
 | 13035 |       PUT_WORD (&result[1], EC_BYPASS_INDICATION); | 
 | 13036 |       result[3] = 2; | 
 | 13037 |       PUT_WORD (&result[4], 0); | 
 | 13038 |       switch (msg[1]) | 
 | 13039 |       { | 
 | 13040 |       case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ: | 
 | 13041 |         PUT_WORD (&result[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ); | 
 | 13042 |         break; | 
 | 13043 |       case LEC_DISABLE_TYPE_REVERSED_2100HZ: | 
 | 13044 |         PUT_WORD (&result[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ); | 
 | 13045 |         break; | 
 | 13046 |       case LEC_DISABLE_RELEASED: | 
 | 13047 |         PUT_WORD (&result[4], EC_BYPASS_RELEASED); | 
 | 13048 |         break; | 
 | 13049 |       } | 
 | 13050 |     } | 
 | 13051 |     sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? | 
 | 13052 |       PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); | 
 | 13053 |   } | 
 | 13054 | } | 
 | 13055 |  | 
 | 13056 |  | 
 | 13057 |  | 
 | 13058 | /*------------------------------------------------------------------*/ | 
 | 13059 | /* Advanced voice                                                   */ | 
 | 13060 | /*------------------------------------------------------------------*/ | 
 | 13061 |  | 
 | 13062 | static void adv_voice_write_coefs (PLCI   *plci, word write_command) | 
 | 13063 | { | 
 | 13064 |   DIVA_CAPI_ADAPTER   *a; | 
 | 13065 |   word i; | 
 | 13066 |   byte *p; | 
 | 13067 |  | 
 | 13068 |   word w, n, j, k; | 
 | 13069 |   byte ch_map[MIXER_CHANNELS_BRI]; | 
 | 13070 |  | 
 | 13071 |     byte coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE + 2]; | 
 | 13072 |  | 
 | 13073 |   dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_write_coefs %d", | 
 | 13074 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 13075 |     (char   *)(FILE_), __LINE__, write_command)); | 
 | 13076 |  | 
 | 13077 |   a = plci->adapter; | 
 | 13078 |   p = coef_buffer + 1; | 
 | 13079 |   *(p++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS; | 
 | 13080 |   i = 0; | 
 | 13081 |   while (i + sizeof(word) <= a->adv_voice_coef_length) | 
 | 13082 |   { | 
 | 13083 |     PUT_WORD (p, GET_WORD (a->adv_voice_coef_buffer + i)); | 
 | 13084 |     p += 2; | 
 | 13085 |     i += 2; | 
 | 13086 |   } | 
 | 13087 |   while (i < ADV_VOICE_OLD_COEF_COUNT * sizeof(word)) | 
 | 13088 |   { | 
 | 13089 |     PUT_WORD (p, 0x8000); | 
 | 13090 |     p += 2; | 
 | 13091 |     i += 2; | 
 | 13092 |   } | 
 | 13093 |  | 
 | 13094 |   if (!a->li_pri && (plci->li_bchannel_id == 0)) | 
 | 13095 |   { | 
 | 13096 |     if ((li_config_table[a->li_base].plci == NULL) && (li_config_table[a->li_base + 1].plci != NULL)) | 
 | 13097 |     { | 
 | 13098 |       plci->li_bchannel_id = 1; | 
 | 13099 |       li_config_table[a->li_base].plci = plci; | 
 | 13100 |       dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", | 
 | 13101 |         (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 13102 |         (char   *)(FILE_), __LINE__, plci->li_bchannel_id)); | 
 | 13103 |     } | 
 | 13104 |     else if ((li_config_table[a->li_base].plci != NULL) && (li_config_table[a->li_base + 1].plci == NULL)) | 
 | 13105 |     { | 
 | 13106 |       plci->li_bchannel_id = 2; | 
 | 13107 |       li_config_table[a->li_base + 1].plci = plci; | 
 | 13108 |       dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", | 
 | 13109 |         (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 13110 |         (char   *)(FILE_), __LINE__, plci->li_bchannel_id)); | 
 | 13111 |     } | 
 | 13112 |   } | 
 | 13113 |   if (!a->li_pri && (plci->li_bchannel_id != 0) | 
 | 13114 |    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 13115 |   { | 
 | 13116 |     i = a->li_base + (plci->li_bchannel_id - 1); | 
 | 13117 |     switch (write_command) | 
 | 13118 |     { | 
 | 13119 |     case ADV_VOICE_WRITE_ACTIVATION: | 
 | 13120 |       j = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); | 
 | 13121 |       k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); | 
 | 13122 |       if (!(plci->B1_facilities & B1_FACILITY_MIXER)) | 
 | 13123 |       { | 
 | 13124 |         li_config_table[j].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX; | 
 | 13125 |         li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR; | 
 | 13126 |       } | 
 | 13127 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) | 
 | 13128 |       { | 
 | 13129 |         li_config_table[k].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX; | 
 | 13130 |         li_config_table[i].flag_table[k] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR; | 
 | 13131 |         li_config_table[k].flag_table[j] |= LI_FLAG_CONFERENCE; | 
 | 13132 |         li_config_table[j].flag_table[k] |= LI_FLAG_CONFERENCE; | 
 | 13133 |       } | 
 | 13134 |       mixer_calculate_coefs (a); | 
 | 13135 |       li_config_table[i].curchnl = li_config_table[i].channel; | 
 | 13136 |       li_config_table[j].curchnl = li_config_table[j].channel; | 
 | 13137 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) | 
 | 13138 |         li_config_table[k].curchnl = li_config_table[k].channel; | 
 | 13139 |       break; | 
 | 13140 |  | 
 | 13141 |     case ADV_VOICE_WRITE_DEACTIVATION: | 
 | 13142 |       for (j = 0; j < li_total_channels; j++) | 
 | 13143 |       { | 
 | 13144 |         li_config_table[i].flag_table[j] = 0; | 
 | 13145 |         li_config_table[j].flag_table[i] = 0; | 
 | 13146 |       } | 
 | 13147 |       k = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); | 
 | 13148 |       for (j = 0; j < li_total_channels; j++) | 
 | 13149 |       { | 
 | 13150 |         li_config_table[k].flag_table[j] = 0; | 
 | 13151 |         li_config_table[j].flag_table[k] = 0; | 
 | 13152 |       } | 
 | 13153 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) | 
 | 13154 |       { | 
 | 13155 |         k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); | 
 | 13156 |         for (j = 0; j < li_total_channels; j++) | 
 | 13157 |         { | 
 | 13158 |           li_config_table[k].flag_table[j] = 0; | 
 | 13159 |           li_config_table[j].flag_table[k] = 0; | 
 | 13160 |         } | 
 | 13161 |       } | 
 | 13162 |       mixer_calculate_coefs (a); | 
 | 13163 |       break; | 
 | 13164 |     } | 
 | 13165 |     if (plci->B1_facilities & B1_FACILITY_MIXER) | 
 | 13166 |     { | 
 | 13167 |       w = 0; | 
 | 13168 |       if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length) | 
 | 13169 |         w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); | 
 | 13170 |       if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) | 
 | 13171 |         w |= MIXER_FEATURE_ENABLE_TX_DATA; | 
 | 13172 |       if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) | 
 | 13173 |         w |= MIXER_FEATURE_ENABLE_RX_DATA; | 
 | 13174 |       *(p++) = (byte) w; | 
 | 13175 |       *(p++) = (byte)(w >> 8); | 
 | 13176 |       for (j = 0; j < sizeof(ch_map); j += 2) | 
 | 13177 |       { | 
 | 13178 |         ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1)); | 
 | 13179 |         ch_map[j+1] = (byte)(j + (2 - plci->li_bchannel_id)); | 
 | 13180 |       } | 
 | 13181 |       for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++) | 
 | 13182 |       { | 
 | 13183 |         i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; | 
 | 13184 |         j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; | 
 | 13185 |         if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) | 
 | 13186 |         { | 
 | 13187 |           *(p++) = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); | 
 | 13188 |           w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); | 
 | 13189 |           li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; | 
 | 13190 |         } | 
 | 13191 |         else | 
 | 13192 |         { | 
 | 13193 |           *(p++) = (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n < a->adv_voice_coef_length) ? | 
 | 13194 |             a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n] : 0x00; | 
 | 13195 |         } | 
 | 13196 |       } | 
 | 13197 |     } | 
 | 13198 |     else | 
 | 13199 |     { | 
 | 13200 |       for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++) | 
 | 13201 |         *(p++) = a->adv_voice_coef_buffer[i]; | 
 | 13202 |     } | 
 | 13203 |   } | 
 | 13204 |   else | 
 | 13205 |  | 
 | 13206 |   { | 
 | 13207 |     for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++) | 
 | 13208 |       *(p++) = a->adv_voice_coef_buffer[i]; | 
 | 13209 |   } | 
 | 13210 |   coef_buffer[0] = (p - coef_buffer) - 1; | 
 | 13211 |   add_p (plci, FTY, coef_buffer); | 
 | 13212 |   sig_req (plci, TEL_CTRL, 0); | 
 | 13213 |   send_req (plci); | 
 | 13214 | } | 
 | 13215 |  | 
 | 13216 |  | 
 | 13217 | static void adv_voice_clear_config (PLCI   *plci) | 
 | 13218 | { | 
 | 13219 |   DIVA_CAPI_ADAPTER   *a; | 
 | 13220 |  | 
 | 13221 |   word i, j; | 
 | 13222 |  | 
 | 13223 |  | 
 | 13224 |   dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_clear_config", | 
 | 13225 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 13226 |     (char   *)(FILE_), __LINE__)); | 
 | 13227 |  | 
 | 13228 |   a = plci->adapter; | 
 | 13229 |   if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) | 
 | 13230 |   { | 
 | 13231 |     a->adv_voice_coef_length = 0; | 
 | 13232 |  | 
 | 13233 |     if (!a->li_pri && (plci->li_bchannel_id != 0) | 
 | 13234 |      && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 13235 |     { | 
 | 13236 |       i = a->li_base + (plci->li_bchannel_id - 1); | 
 | 13237 |       li_config_table[i].curchnl = 0; | 
 | 13238 |       li_config_table[i].channel = 0; | 
 | 13239 |       li_config_table[i].chflags = 0; | 
 | 13240 |       for (j = 0; j < li_total_channels; j++) | 
 | 13241 |       { | 
 | 13242 |         li_config_table[i].flag_table[j] = 0; | 
 | 13243 |         li_config_table[j].flag_table[i] = 0; | 
 | 13244 |         li_config_table[i].coef_table[j] = 0; | 
 | 13245 |         li_config_table[j].coef_table[i] = 0; | 
 | 13246 |       } | 
 | 13247 |       li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; | 
 | 13248 |       i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); | 
 | 13249 |       li_config_table[i].curchnl = 0; | 
 | 13250 |       li_config_table[i].channel = 0; | 
 | 13251 |       li_config_table[i].chflags = 0; | 
 | 13252 |       for (j = 0; j < li_total_channels; j++) | 
 | 13253 |       { | 
 | 13254 |         li_config_table[i].flag_table[j] = 0; | 
 | 13255 |         li_config_table[j].flag_table[i] = 0; | 
 | 13256 |         li_config_table[i].coef_table[j] = 0; | 
 | 13257 |         li_config_table[j].coef_table[i] = 0; | 
 | 13258 |       } | 
 | 13259 |       if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) | 
 | 13260 |       { | 
 | 13261 |         i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); | 
 | 13262 |         li_config_table[i].curchnl = 0; | 
 | 13263 |         li_config_table[i].channel = 0; | 
 | 13264 |         li_config_table[i].chflags = 0; | 
 | 13265 |         for (j = 0; j < li_total_channels; j++) | 
 | 13266 |         { | 
 | 13267 |           li_config_table[i].flag_table[j] = 0; | 
 | 13268 |           li_config_table[j].flag_table[i] = 0; | 
 | 13269 |           li_config_table[i].coef_table[j] = 0; | 
 | 13270 |           li_config_table[j].coef_table[i] = 0; | 
 | 13271 |         } | 
 | 13272 |       } | 
 | 13273 |     } | 
 | 13274 |  | 
 | 13275 |   } | 
 | 13276 | } | 
 | 13277 |  | 
 | 13278 |  | 
 | 13279 | static void adv_voice_prepare_switch (dword Id, PLCI   *plci) | 
 | 13280 | { | 
 | 13281 |  | 
 | 13282 |   dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_prepare_switch", | 
 | 13283 |     UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 13284 |  | 
 | 13285 | } | 
 | 13286 |  | 
 | 13287 |  | 
 | 13288 | static word adv_voice_save_config (dword Id, PLCI   *plci, byte Rc) | 
 | 13289 | { | 
 | 13290 |  | 
 | 13291 |   dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_save_config %02x %d", | 
 | 13292 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 13293 |  | 
 | 13294 |   return (GOOD); | 
 | 13295 | } | 
 | 13296 |  | 
 | 13297 |  | 
 | 13298 | static word adv_voice_restore_config (dword Id, PLCI   *plci, byte Rc) | 
 | 13299 | { | 
 | 13300 |   DIVA_CAPI_ADAPTER   *a; | 
 | 13301 |   word Info; | 
 | 13302 |  | 
 | 13303 |   dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_restore_config %02x %d", | 
 | 13304 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 13305 |  | 
 | 13306 |   Info = GOOD; | 
 | 13307 |   a = plci->adapter; | 
 | 13308 |   if ((plci->B1_facilities & B1_FACILITY_VOICE) | 
 | 13309 |    && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) | 
 | 13310 |   { | 
 | 13311 |     switch (plci->adjust_b_state) | 
 | 13312 |     { | 
 | 13313 |     case ADJUST_B_RESTORE_VOICE_1: | 
 | 13314 |       plci->internal_command = plci->adjust_b_command; | 
 | 13315 |       if (plci->sig_req) | 
 | 13316 |       { | 
 | 13317 |         plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1; | 
 | 13318 |         break; | 
 | 13319 |       } | 
 | 13320 |       adv_voice_write_coefs (plci, ADV_VOICE_WRITE_UPDATE); | 
 | 13321 |       plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_2; | 
 | 13322 |       break; | 
 | 13323 |     case ADJUST_B_RESTORE_VOICE_2: | 
 | 13324 |       if ((Rc != OK) && (Rc != OK_FC)) | 
 | 13325 |       { | 
 | 13326 |         dbug (1, dprintf ("[%06lx] %s,%d: Restore voice config failed %02x", | 
 | 13327 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 13328 |         Info = _WRONG_STATE; | 
 | 13329 |         break; | 
 | 13330 |       } | 
 | 13331 |       break; | 
 | 13332 |     } | 
 | 13333 |   } | 
 | 13334 |   return (Info); | 
 | 13335 | } | 
 | 13336 |  | 
 | 13337 |  | 
 | 13338 |  | 
 | 13339 |  | 
 | 13340 | /*------------------------------------------------------------------*/ | 
 | 13341 | /* B1 resource switching                                            */ | 
 | 13342 | /*------------------------------------------------------------------*/ | 
 | 13343 |  | 
 | 13344 | static byte b1_facilities_table[] = | 
 | 13345 | { | 
 | 13346 |   0x00,  /* 0  No bchannel resources      */ | 
 | 13347 |   0x00,  /* 1  Codec (automatic law)      */ | 
 | 13348 |   0x00,  /* 2  Codec (A-law)              */ | 
 | 13349 |   0x00,  /* 3  Codec (y-law)              */ | 
 | 13350 |   0x00,  /* 4  HDLC for X.21              */ | 
 | 13351 |   0x00,  /* 5  HDLC                       */ | 
 | 13352 |   0x00,  /* 6  External Device 0          */ | 
 | 13353 |   0x00,  /* 7  External Device 1          */ | 
 | 13354 |   0x00,  /* 8  HDLC 56k                   */ | 
 | 13355 |   0x00,  /* 9  Transparent                */ | 
 | 13356 |   0x00,  /* 10 Loopback to network        */ | 
 | 13357 |   0x00,  /* 11 Test pattern to net        */ | 
 | 13358 |   0x00,  /* 12 Rate adaptation sync       */ | 
 | 13359 |   0x00,  /* 13 Rate adaptation async      */ | 
 | 13360 |   0x00,  /* 14 R-Interface                */ | 
 | 13361 |   0x00,  /* 15 HDLC 128k leased line      */ | 
 | 13362 |   0x00,  /* 16 FAX                        */ | 
 | 13363 |   0x00,  /* 17 Modem async                */ | 
 | 13364 |   0x00,  /* 18 Modem sync HDLC            */ | 
 | 13365 |   0x00,  /* 19 V.110 async HDLC           */ | 
 | 13366 |   0x12,  /* 20 Adv voice (Trans,mixer)    */ | 
 | 13367 |   0x00,  /* 21 Codec connected to IC      */ | 
 | 13368 |   0x0c,  /* 22 Trans,DTMF                 */ | 
 | 13369 |   0x1e,  /* 23 Trans,DTMF+mixer           */ | 
 | 13370 |   0x1f,  /* 24 Trans,DTMF+mixer+local     */ | 
 | 13371 |   0x13,  /* 25 Trans,mixer+local          */ | 
 | 13372 |   0x12,  /* 26 HDLC,mixer                 */ | 
 | 13373 |   0x12,  /* 27 HDLC 56k,mixer             */ | 
 | 13374 |   0x2c,  /* 28 Trans,LEC+DTMF             */ | 
 | 13375 |   0x3e,  /* 29 Trans,LEC+DTMF+mixer       */ | 
 | 13376 |   0x3f,  /* 30 Trans,LEC+DTMF+mixer+local */ | 
 | 13377 |   0x2c,  /* 31 RTP,LEC+DTMF               */ | 
 | 13378 |   0x3e,  /* 32 RTP,LEC+DTMF+mixer         */ | 
 | 13379 |   0x3f,  /* 33 RTP,LEC+DTMF+mixer+local   */ | 
 | 13380 |   0x00,  /* 34 Signaling task             */ | 
 | 13381 |   0x00,  /* 35 PIAFS                      */ | 
 | 13382 |   0x0c,  /* 36 Trans,DTMF+TONE            */ | 
 | 13383 |   0x1e,  /* 37 Trans,DTMF+TONE+mixer      */ | 
 | 13384 |   0x1f   /* 38 Trans,DTMF+TONE+mixer+local*/ | 
 | 13385 | }; | 
 | 13386 |  | 
 | 13387 |  | 
 | 13388 | static word get_b1_facilities (PLCI   * plci, byte b1_resource) | 
 | 13389 | { | 
 | 13390 |   word b1_facilities; | 
 | 13391 |  | 
 | 13392 |   b1_facilities = b1_facilities_table[b1_resource]; | 
 | 13393 |   if ((b1_resource == 9) || (b1_resource == 20) || (b1_resource == 25)) | 
 | 13394 |   { | 
 | 13395 |  | 
 | 13396 |     if (!(((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE)) | 
 | 13397 |        || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id-1] & (1L << PRIVATE_DTMF_TONE))))) | 
 | 13398 |  | 
 | 13399 |     { | 
 | 13400 |       if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND) | 
 | 13401 |         b1_facilities |= B1_FACILITY_DTMFX; | 
 | 13402 |       if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE) | 
 | 13403 |         b1_facilities |= B1_FACILITY_DTMFR; | 
 | 13404 |     } | 
 | 13405 |   } | 
 | 13406 |   if ((b1_resource == 17) || (b1_resource == 18)) | 
 | 13407 |   { | 
 | 13408 |     if (plci->adapter->manufacturer_features & (MANUFACTURER_FEATURE_V18 | MANUFACTURER_FEATURE_VOWN)) | 
 | 13409 |       b1_facilities |= B1_FACILITY_DTMFX | B1_FACILITY_DTMFR; | 
 | 13410 |   } | 
 | 13411 | /* | 
 | 13412 |   dbug (1, dprintf ("[%06lx] %s,%d: get_b1_facilities %d %04x", | 
 | 13413 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 13414 |     (char far *)(FILE_), __LINE__, b1_resource, b1_facilites)); | 
 | 13415 | */ | 
 | 13416 |   return (b1_facilities); | 
 | 13417 | } | 
 | 13418 |  | 
 | 13419 |  | 
 | 13420 | static byte add_b1_facilities (PLCI   * plci, byte b1_resource, word b1_facilities) | 
 | 13421 | { | 
 | 13422 |   byte b; | 
 | 13423 |  | 
 | 13424 |   switch (b1_resource) | 
 | 13425 |   { | 
 | 13426 |   case 5: | 
 | 13427 |   case 26: | 
 | 13428 |     if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) | 
 | 13429 |       b = 26; | 
 | 13430 |     else | 
 | 13431 |       b = 5; | 
 | 13432 |     break; | 
 | 13433 |  | 
 | 13434 |   case 8: | 
 | 13435 |   case 27: | 
 | 13436 |     if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) | 
 | 13437 |       b = 27; | 
 | 13438 |     else | 
 | 13439 |       b = 8; | 
 | 13440 |     break; | 
 | 13441 |  | 
 | 13442 |   case 9: | 
 | 13443 |   case 20: | 
 | 13444 |   case 22: | 
 | 13445 |   case 23: | 
 | 13446 |   case 24: | 
 | 13447 |   case 25: | 
 | 13448 |   case 28: | 
 | 13449 |   case 29: | 
 | 13450 |   case 30: | 
 | 13451 |   case 36: | 
 | 13452 |   case 37: | 
 | 13453 |   case 38: | 
 | 13454 |     if (b1_facilities & B1_FACILITY_EC) | 
 | 13455 |     { | 
 | 13456 |       if (b1_facilities & B1_FACILITY_LOCAL) | 
 | 13457 |         b = 30; | 
 | 13458 |       else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) | 
 | 13459 |         b = 29; | 
 | 13460 |       else | 
 | 13461 |         b = 28; | 
 | 13462 |     } | 
 | 13463 |  | 
 | 13464 |     else if ((b1_facilities & (B1_FACILITY_DTMFX | B1_FACILITY_DTMFR | B1_FACILITY_MIXER)) | 
 | 13465 |       && (((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE)) | 
 | 13466 |        || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id-1] & (1L << PRIVATE_DTMF_TONE))))) | 
 | 13467 |     { | 
 | 13468 |       if (b1_facilities & B1_FACILITY_LOCAL) | 
 | 13469 |         b = 38; | 
 | 13470 |       else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) | 
 | 13471 |         b = 37; | 
 | 13472 |       else | 
 | 13473 |         b = 36; | 
 | 13474 |     } | 
 | 13475 |  | 
 | 13476 |     else if (((plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF) | 
 | 13477 |       && !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) | 
 | 13478 |      || ((b1_facilities & B1_FACILITY_DTMFR) | 
 | 13479 |       && ((b1_facilities & B1_FACILITY_MIXER) | 
 | 13480 |        || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))) | 
 | 13481 |      || ((b1_facilities & B1_FACILITY_DTMFX) | 
 | 13482 |       && ((b1_facilities & B1_FACILITY_MIXER) | 
 | 13483 |        || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND)))) | 
 | 13484 |     { | 
 | 13485 |       if (b1_facilities & B1_FACILITY_LOCAL) | 
 | 13486 |         b = 24; | 
 | 13487 |       else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) | 
 | 13488 |         b = 23; | 
 | 13489 |       else | 
 | 13490 |         b = 22; | 
 | 13491 |     } | 
 | 13492 |     else | 
 | 13493 |     { | 
 | 13494 |       if (b1_facilities & B1_FACILITY_LOCAL) | 
 | 13495 |         b = 25; | 
 | 13496 |       else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) | 
 | 13497 |         b = 20; | 
 | 13498 |       else | 
 | 13499 |         b = 9; | 
 | 13500 |     } | 
 | 13501 |     break; | 
 | 13502 |  | 
 | 13503 |   case 31: | 
 | 13504 |   case 32: | 
 | 13505 |   case 33: | 
 | 13506 |     if (b1_facilities & B1_FACILITY_LOCAL) | 
 | 13507 |       b = 33; | 
 | 13508 |     else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) | 
 | 13509 |       b = 32; | 
 | 13510 |     else | 
 | 13511 |       b = 31; | 
 | 13512 |     break; | 
 | 13513 |  | 
 | 13514 |   default: | 
 | 13515 |     b = b1_resource; | 
 | 13516 |   } | 
 | 13517 |   dbug (1, dprintf ("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x", | 
 | 13518 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 13519 |     (char   *)(FILE_), __LINE__, | 
 | 13520 |     b1_resource, b1_facilities, b, get_b1_facilities (plci, b))); | 
 | 13521 |   return (b); | 
 | 13522 | } | 
 | 13523 |  | 
 | 13524 |  | 
 | 13525 | static void adjust_b1_facilities (PLCI   *plci, byte new_b1_resource, word new_b1_facilities) | 
 | 13526 | { | 
 | 13527 |   word removed_facilities; | 
 | 13528 |  | 
 | 13529 |   dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x", | 
 | 13530 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 13531 |     (char   *)(FILE_), __LINE__, new_b1_resource, new_b1_facilities, | 
 | 13532 |     new_b1_facilities & get_b1_facilities (plci, new_b1_resource))); | 
 | 13533 |  | 
 | 13534 |   new_b1_facilities &= get_b1_facilities (plci, new_b1_resource); | 
 | 13535 |   removed_facilities = plci->B1_facilities & ~new_b1_facilities; | 
 | 13536 |  | 
 | 13537 |   if (removed_facilities & B1_FACILITY_EC) | 
 | 13538 |     ec_clear_config (plci); | 
 | 13539 |  | 
 | 13540 |  | 
 | 13541 |   if (removed_facilities & B1_FACILITY_DTMFR) | 
 | 13542 |   { | 
 | 13543 |     dtmf_rec_clear_config (plci); | 
 | 13544 |     dtmf_parameter_clear_config (plci); | 
 | 13545 |   } | 
 | 13546 |   if (removed_facilities & B1_FACILITY_DTMFX) | 
 | 13547 |     dtmf_send_clear_config (plci); | 
 | 13548 |  | 
 | 13549 |  | 
 | 13550 |   if (removed_facilities & B1_FACILITY_MIXER) | 
 | 13551 |     mixer_clear_config (plci); | 
 | 13552 |  | 
 | 13553 |   if (removed_facilities & B1_FACILITY_VOICE) | 
 | 13554 |     adv_voice_clear_config (plci); | 
 | 13555 |   plci->B1_facilities = new_b1_facilities; | 
 | 13556 | } | 
 | 13557 |  | 
 | 13558 |  | 
 | 13559 | static void adjust_b_clear (PLCI   *plci) | 
 | 13560 | { | 
 | 13561 |  | 
 | 13562 |   dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_clear", | 
 | 13563 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 13564 |     (char   *)(FILE_), __LINE__)); | 
 | 13565 |  | 
 | 13566 |   plci->adjust_b_restore = FALSE; | 
 | 13567 | } | 
 | 13568 |  | 
 | 13569 |  | 
 | 13570 | static word adjust_b_process (dword Id, PLCI   *plci, byte Rc) | 
 | 13571 | { | 
 | 13572 |   word Info; | 
 | 13573 |   byte b1_resource; | 
 | 13574 |   NCCI   * ncci_ptr; | 
 | 13575 |     API_PARSE bp[2]; | 
 | 13576 |  | 
 | 13577 |   dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_process %02x %d", | 
 | 13578 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); | 
 | 13579 |  | 
 | 13580 |   Info = GOOD; | 
 | 13581 |   switch (plci->adjust_b_state) | 
 | 13582 |   { | 
 | 13583 |   case ADJUST_B_START: | 
 | 13584 |     if ((plci->adjust_b_parms_msg == NULL) | 
 | 13585 |      && (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1) | 
 | 13586 |      && ((plci->adjust_b_mode & ~(ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | | 
 | 13587 |       ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_RESTORE)) == 0)) | 
 | 13588 |     { | 
 | 13589 |       b1_resource = (plci->adjust_b_mode == ADJUST_B_MODE_NO_RESOURCE) ? | 
 | 13590 |         0 : add_b1_facilities (plci, plci->B1_resource, plci->adjust_b_facilities); | 
 | 13591 |       if (b1_resource == plci->B1_resource) | 
 | 13592 |       { | 
 | 13593 |         adjust_b1_facilities (plci, b1_resource, plci->adjust_b_facilities); | 
 | 13594 |         break; | 
 | 13595 |       } | 
 | 13596 |       if (plci->adjust_b_facilities & ~get_b1_facilities (plci, b1_resource)) | 
 | 13597 |       { | 
 | 13598 |         dbug (1, dprintf ("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x", | 
 | 13599 |           UnMapId (Id), (char   *)(FILE_), __LINE__, | 
 | 13600 |           plci->B1_resource, b1_resource, plci->adjust_b_facilities)); | 
 | 13601 |         Info = _WRONG_STATE; | 
 | 13602 |         break; | 
 | 13603 |       } | 
 | 13604 |     } | 
 | 13605 |     if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) | 
 | 13606 |     { | 
 | 13607 |  | 
 | 13608 |       mixer_prepare_switch (Id, plci); | 
 | 13609 |  | 
 | 13610 |  | 
 | 13611 |       dtmf_prepare_switch (Id, plci); | 
 | 13612 |       dtmf_parameter_prepare_switch (Id, plci); | 
 | 13613 |  | 
 | 13614 |  | 
 | 13615 |       ec_prepare_switch (Id, plci); | 
 | 13616 |  | 
 | 13617 |       adv_voice_prepare_switch (Id, plci); | 
 | 13618 |     } | 
 | 13619 |     plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1; | 
 | 13620 |     Rc = OK; | 
 | 13621 |   case ADJUST_B_SAVE_MIXER_1: | 
 | 13622 |     if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) | 
 | 13623 |     { | 
 | 13624 |  | 
 | 13625 |       Info = mixer_save_config (Id, plci, Rc); | 
 | 13626 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13627 |         break; | 
 | 13628 |  | 
 | 13629 |     } | 
 | 13630 |     plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1; | 
 | 13631 |     Rc = OK; | 
 | 13632 |   case ADJUST_B_SAVE_DTMF_1: | 
 | 13633 |     if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) | 
 | 13634 |     { | 
 | 13635 |  | 
 | 13636 |       Info = dtmf_save_config (Id, plci, Rc); | 
 | 13637 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13638 |         break; | 
 | 13639 |  | 
 | 13640 |     } | 
 | 13641 |     plci->adjust_b_state = ADJUST_B_REMOVE_L23_1; | 
 | 13642 |   case ADJUST_B_REMOVE_L23_1: | 
 | 13643 |     if ((plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23) | 
 | 13644 |      && plci->NL.Id && !plci->nl_remove_id) | 
 | 13645 |     { | 
 | 13646 |       plci->internal_command = plci->adjust_b_command; | 
 | 13647 |       if (plci->adjust_b_ncci != 0) | 
 | 13648 |       { | 
 | 13649 |         ncci_ptr = &(plci->adapter->ncci[plci->adjust_b_ncci]); | 
 | 13650 |         while (ncci_ptr->data_pending) | 
 | 13651 |         { | 
 | 13652 |           plci->data_sent_ptr = ncci_ptr->DBuffer[ncci_ptr->data_out].P; | 
 | 13653 |           data_rc (plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]); | 
 | 13654 |         } | 
 | 13655 |         while (ncci_ptr->data_ack_pending) | 
 | 13656 |           data_ack (plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]); | 
 | 13657 |       } | 
 | 13658 |       nl_req_ncci (plci, REMOVE, | 
 | 13659 |         (byte)((plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) ? plci->adjust_b_ncci : 0)); | 
 | 13660 |       send_req (plci); | 
 | 13661 |       plci->adjust_b_state = ADJUST_B_REMOVE_L23_2; | 
 | 13662 |       break; | 
 | 13663 |     } | 
 | 13664 |     plci->adjust_b_state = ADJUST_B_REMOVE_L23_2; | 
 | 13665 |     Rc = OK; | 
 | 13666 |   case ADJUST_B_REMOVE_L23_2: | 
 | 13667 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 13668 |     { | 
 | 13669 |       dbug (1, dprintf ("[%06lx] %s,%d: Adjust B remove failed %02x", | 
 | 13670 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 13671 |       Info = _WRONG_STATE; | 
 | 13672 |       break; | 
 | 13673 |     } | 
 | 13674 |     if (plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23) | 
 | 13675 |     { | 
 | 13676 |       if (plci_nl_busy (plci)) | 
 | 13677 |       { | 
 | 13678 |         plci->internal_command = plci->adjust_b_command; | 
 | 13679 |         break; | 
 | 13680 |       } | 
 | 13681 |     } | 
 | 13682 |     plci->adjust_b_state = ADJUST_B_SAVE_EC_1; | 
 | 13683 |     Rc = OK; | 
 | 13684 |   case ADJUST_B_SAVE_EC_1: | 
 | 13685 |     if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) | 
 | 13686 |     { | 
 | 13687 |  | 
 | 13688 |       Info = ec_save_config (Id, plci, Rc); | 
 | 13689 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13690 |         break; | 
 | 13691 |  | 
 | 13692 |     } | 
 | 13693 |     plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1; | 
 | 13694 |     Rc = OK; | 
 | 13695 |   case ADJUST_B_SAVE_DTMF_PARAMETER_1: | 
 | 13696 |     if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) | 
 | 13697 |     { | 
 | 13698 |  | 
 | 13699 |       Info = dtmf_parameter_save_config (Id, plci, Rc); | 
 | 13700 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13701 |         break; | 
 | 13702 |  | 
 | 13703 |     } | 
 | 13704 |     plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1; | 
 | 13705 |     Rc = OK; | 
 | 13706 |   case ADJUST_B_SAVE_VOICE_1: | 
 | 13707 |     if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) | 
 | 13708 |     { | 
 | 13709 |       Info = adv_voice_save_config (Id, plci, Rc); | 
 | 13710 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13711 |         break; | 
 | 13712 |     } | 
 | 13713 |     plci->adjust_b_state = ADJUST_B_SWITCH_L1_1; | 
 | 13714 |   case ADJUST_B_SWITCH_L1_1: | 
 | 13715 |     if (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1) | 
 | 13716 |     { | 
 | 13717 |       if (plci->sig_req) | 
 | 13718 |       { | 
 | 13719 |         plci->internal_command = plci->adjust_b_command; | 
 | 13720 |         break; | 
 | 13721 |       } | 
 | 13722 |       if (plci->adjust_b_parms_msg != NULL) | 
 | 13723 |         api_load_msg (plci->adjust_b_parms_msg, bp); | 
 | 13724 |       else | 
 | 13725 |         api_load_msg (&plci->B_protocol, bp); | 
 | 13726 |       Info = add_b1 (plci, bp, | 
 | 13727 |         (word)((plci->adjust_b_mode & ADJUST_B_MODE_NO_RESOURCE) ? 2 : 0), | 
 | 13728 |         plci->adjust_b_facilities); | 
 | 13729 |       if (Info != GOOD) | 
 | 13730 |       { | 
 | 13731 |         dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x", | 
 | 13732 |           UnMapId (Id), (char   *)(FILE_), __LINE__, | 
 | 13733 |           plci->B1_resource, plci->adjust_b_facilities)); | 
 | 13734 |         break; | 
 | 13735 |       } | 
 | 13736 |       plci->internal_command = plci->adjust_b_command; | 
 | 13737 |       sig_req (plci, RESOURCES, 0); | 
 | 13738 |       send_req (plci); | 
 | 13739 |       plci->adjust_b_state = ADJUST_B_SWITCH_L1_2; | 
 | 13740 |       break; | 
 | 13741 |     } | 
 | 13742 |     plci->adjust_b_state = ADJUST_B_SWITCH_L1_2; | 
 | 13743 |     Rc = OK; | 
 | 13744 |   case ADJUST_B_SWITCH_L1_2: | 
 | 13745 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 13746 |     { | 
 | 13747 |       dbug (1, dprintf ("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x", | 
 | 13748 |         UnMapId (Id), (char   *)(FILE_), __LINE__, | 
 | 13749 |         Rc, plci->B1_resource, plci->adjust_b_facilities)); | 
 | 13750 |       Info = _WRONG_STATE; | 
 | 13751 |       break; | 
 | 13752 |     } | 
 | 13753 |     plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1; | 
 | 13754 |     Rc = OK; | 
 | 13755 |   case ADJUST_B_RESTORE_VOICE_1: | 
 | 13756 |   case ADJUST_B_RESTORE_VOICE_2: | 
 | 13757 |     if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) | 
 | 13758 |     { | 
 | 13759 |       Info = adv_voice_restore_config (Id, plci, Rc); | 
 | 13760 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13761 |         break; | 
 | 13762 |     } | 
 | 13763 |     plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1; | 
 | 13764 |     Rc = OK; | 
 | 13765 |   case ADJUST_B_RESTORE_DTMF_PARAMETER_1: | 
 | 13766 |   case ADJUST_B_RESTORE_DTMF_PARAMETER_2: | 
 | 13767 |     if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) | 
 | 13768 |     { | 
 | 13769 |  | 
 | 13770 |       Info = dtmf_parameter_restore_config (Id, plci, Rc); | 
 | 13771 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13772 |         break; | 
 | 13773 |  | 
 | 13774 |     } | 
 | 13775 |     plci->adjust_b_state = ADJUST_B_RESTORE_EC_1; | 
 | 13776 |     Rc = OK; | 
 | 13777 |   case ADJUST_B_RESTORE_EC_1: | 
 | 13778 |   case ADJUST_B_RESTORE_EC_2: | 
 | 13779 |     if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) | 
 | 13780 |     { | 
 | 13781 |  | 
 | 13782 |       Info = ec_restore_config (Id, plci, Rc); | 
 | 13783 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13784 |         break; | 
 | 13785 |  | 
 | 13786 |     } | 
 | 13787 |     plci->adjust_b_state = ADJUST_B_ASSIGN_L23_1; | 
 | 13788 |   case ADJUST_B_ASSIGN_L23_1: | 
 | 13789 |     if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23) | 
 | 13790 |     { | 
 | 13791 |       if (plci_nl_busy (plci)) | 
 | 13792 |       { | 
 | 13793 |         plci->internal_command = plci->adjust_b_command; | 
 | 13794 |         break; | 
 | 13795 |       } | 
 | 13796 |       if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) | 
 | 13797 |         plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; | 
 | 13798 |       if (plci->adjust_b_parms_msg != NULL) | 
 | 13799 |         api_load_msg (plci->adjust_b_parms_msg, bp); | 
 | 13800 |       else | 
 | 13801 |         api_load_msg (&plci->B_protocol, bp); | 
 | 13802 |       Info = add_b23 (plci, bp); | 
 | 13803 |       if (Info != GOOD) | 
 | 13804 |       { | 
 | 13805 |         dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x", | 
 | 13806 |           UnMapId (Id), (char   *)(FILE_), __LINE__, Info)); | 
 | 13807 |         break; | 
 | 13808 |       } | 
 | 13809 |       plci->internal_command = plci->adjust_b_command; | 
 | 13810 |       nl_req_ncci (plci, ASSIGN, 0); | 
 | 13811 |       send_req (plci); | 
 | 13812 |       plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2; | 
 | 13813 |       break; | 
 | 13814 |     } | 
 | 13815 |     plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2; | 
 | 13816 |     Rc = ASSIGN_OK; | 
 | 13817 |   case ADJUST_B_ASSIGN_L23_2: | 
 | 13818 |     if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK)) | 
 | 13819 |     { | 
 | 13820 |       dbug (1, dprintf ("[%06lx] %s,%d: Adjust B assign failed %02x", | 
 | 13821 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 13822 |       Info = _WRONG_STATE; | 
 | 13823 |       break; | 
 | 13824 |     } | 
 | 13825 |     if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23) | 
 | 13826 |     { | 
 | 13827 |       if (Rc != ASSIGN_OK) | 
 | 13828 |       { | 
 | 13829 |         plci->internal_command = plci->adjust_b_command; | 
 | 13830 |         break; | 
 | 13831 |       } | 
 | 13832 |     } | 
 | 13833 |     if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT) | 
 | 13834 |     { | 
 | 13835 |       plci->adjust_b_restore = TRUE; | 
 | 13836 |       break; | 
 | 13837 |     } | 
 | 13838 |     plci->adjust_b_state = ADJUST_B_CONNECT_1; | 
 | 13839 |   case ADJUST_B_CONNECT_1: | 
 | 13840 |     if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) | 
 | 13841 |     { | 
 | 13842 |       plci->internal_command = plci->adjust_b_command; | 
 | 13843 |       if (plci_nl_busy (plci)) | 
 | 13844 |         break; | 
 | 13845 |       nl_req_ncci (plci, N_CONNECT, 0); | 
 | 13846 |       send_req (plci); | 
 | 13847 |       plci->adjust_b_state = ADJUST_B_CONNECT_2; | 
 | 13848 |       break; | 
 | 13849 |     } | 
 | 13850 |     plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; | 
 | 13851 |     Rc = OK; | 
 | 13852 |   case ADJUST_B_CONNECT_2: | 
 | 13853 |   case ADJUST_B_CONNECT_3: | 
 | 13854 |   case ADJUST_B_CONNECT_4: | 
 | 13855 |     if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) | 
 | 13856 |     { | 
 | 13857 |       dbug (1, dprintf ("[%06lx] %s,%d: Adjust B connect failed %02x", | 
 | 13858 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 13859 |       Info = _WRONG_STATE; | 
 | 13860 |       break; | 
 | 13861 |     } | 
 | 13862 |     if (Rc == OK) | 
 | 13863 |     { | 
 | 13864 |       if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) | 
 | 13865 |       { | 
 | 13866 |         get_ncci (plci, (byte)(Id >> 16), plci->adjust_b_ncci); | 
 | 13867 |         Id = (Id & 0xffff) | (((dword)(plci->adjust_b_ncci)) << 16); | 
 | 13868 |       } | 
 | 13869 |       if (plci->adjust_b_state == ADJUST_B_CONNECT_2) | 
 | 13870 |         plci->adjust_b_state = ADJUST_B_CONNECT_3; | 
 | 13871 |       else if (plci->adjust_b_state == ADJUST_B_CONNECT_4) | 
 | 13872 |         plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; | 
 | 13873 |     } | 
 | 13874 |     else if (Rc == 0) | 
 | 13875 |     { | 
 | 13876 |       if (plci->adjust_b_state == ADJUST_B_CONNECT_2) | 
 | 13877 |         plci->adjust_b_state = ADJUST_B_CONNECT_4; | 
 | 13878 |       else if (plci->adjust_b_state == ADJUST_B_CONNECT_3) | 
 | 13879 |         plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; | 
 | 13880 |     } | 
 | 13881 |     if (plci->adjust_b_state != ADJUST_B_RESTORE_DTMF_1) | 
 | 13882 |     { | 
 | 13883 |       plci->internal_command = plci->adjust_b_command; | 
 | 13884 |       break; | 
 | 13885 |     } | 
 | 13886 |     Rc = OK; | 
 | 13887 |   case ADJUST_B_RESTORE_DTMF_1: | 
 | 13888 |   case ADJUST_B_RESTORE_DTMF_2: | 
 | 13889 |     if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) | 
 | 13890 |     { | 
 | 13891 |  | 
 | 13892 |       Info = dtmf_restore_config (Id, plci, Rc); | 
 | 13893 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13894 |         break; | 
 | 13895 |  | 
 | 13896 |     } | 
 | 13897 |     plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1; | 
 | 13898 |     Rc = OK; | 
 | 13899 |   case ADJUST_B_RESTORE_MIXER_1: | 
 | 13900 |   case ADJUST_B_RESTORE_MIXER_2: | 
 | 13901 |   case ADJUST_B_RESTORE_MIXER_3: | 
 | 13902 |   case ADJUST_B_RESTORE_MIXER_4: | 
 | 13903 |   case ADJUST_B_RESTORE_MIXER_5: | 
 | 13904 |   case ADJUST_B_RESTORE_MIXER_6: | 
 | 13905 |   case ADJUST_B_RESTORE_MIXER_7: | 
 | 13906 |     if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) | 
 | 13907 |     { | 
 | 13908 |  | 
 | 13909 |       Info = mixer_restore_config (Id, plci, Rc); | 
 | 13910 |       if ((Info != GOOD) || plci->internal_command) | 
 | 13911 |         break; | 
 | 13912 |  | 
 | 13913 |     } | 
 | 13914 |     plci->adjust_b_state = ADJUST_B_END; | 
 | 13915 |   case ADJUST_B_END: | 
 | 13916 |     break; | 
 | 13917 |   } | 
 | 13918 |   return (Info); | 
 | 13919 | } | 
 | 13920 |  | 
 | 13921 |  | 
 | 13922 | static void adjust_b1_resource (dword Id, PLCI   *plci, API_SAVE   *bp_msg, word b1_facilities, word internal_command) | 
 | 13923 | { | 
 | 13924 |  | 
 | 13925 |   dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_resource %d %04x", | 
 | 13926 |     UnMapId (Id), (char   *)(FILE_), __LINE__, | 
 | 13927 |     plci->B1_resource, b1_facilities)); | 
 | 13928 |  | 
 | 13929 |   plci->adjust_b_parms_msg = bp_msg; | 
 | 13930 |   plci->adjust_b_facilities = b1_facilities; | 
 | 13931 |   plci->adjust_b_command = internal_command; | 
 | 13932 |   plci->adjust_b_ncci = (word)(Id >> 16); | 
 | 13933 |   if ((bp_msg == NULL) && (plci->B1_resource == 0)) | 
 | 13934 |     plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_SWITCH_L1; | 
 | 13935 |   else | 
 | 13936 |     plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | ADJUST_B_MODE_RESTORE; | 
 | 13937 |   plci->adjust_b_state = ADJUST_B_START; | 
 | 13938 |   dbug (1, dprintf ("[%06lx] %s,%d: Adjust B1 resource %d %04x...", | 
 | 13939 |     UnMapId (Id), (char   *)(FILE_), __LINE__, | 
 | 13940 |     plci->B1_resource, b1_facilities)); | 
 | 13941 | } | 
 | 13942 |  | 
 | 13943 |  | 
 | 13944 | static void adjust_b_restore (dword Id, PLCI   *plci, byte Rc) | 
 | 13945 | { | 
 | 13946 |   word internal_command; | 
 | 13947 |  | 
 | 13948 |   dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_restore %02x %04x", | 
 | 13949 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 13950 |  | 
 | 13951 |   internal_command = plci->internal_command; | 
 | 13952 |   plci->internal_command = 0; | 
 | 13953 |   switch (internal_command) | 
 | 13954 |   { | 
 | 13955 |   default: | 
 | 13956 |     plci->command = 0; | 
 | 13957 |     if (plci->req_in != 0) | 
 | 13958 |     { | 
 | 13959 |       plci->internal_command = ADJUST_B_RESTORE_1; | 
 | 13960 |       break; | 
 | 13961 |     } | 
 | 13962 |     Rc = OK; | 
 | 13963 |   case ADJUST_B_RESTORE_1: | 
 | 13964 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 13965 |     { | 
 | 13966 |       dbug (1, dprintf ("[%06lx] %s,%d: Adjust B enqueued failed %02x", | 
 | 13967 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 13968 |     } | 
 | 13969 |     plci->adjust_b_parms_msg = NULL; | 
 | 13970 |     plci->adjust_b_facilities = plci->B1_facilities; | 
 | 13971 |     plci->adjust_b_command = ADJUST_B_RESTORE_2; | 
 | 13972 |     plci->adjust_b_ncci = (word)(Id >> 16); | 
 | 13973 |     plci->adjust_b_mode = ADJUST_B_MODE_RESTORE; | 
 | 13974 |     plci->adjust_b_state = ADJUST_B_START; | 
 | 13975 |     dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore...", | 
 | 13976 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 13977 |   case ADJUST_B_RESTORE_2: | 
 | 13978 |     if (adjust_b_process (Id, plci, Rc) != GOOD) | 
 | 13979 |     { | 
 | 13980 |       dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore failed", | 
 | 13981 |         UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 13982 |     } | 
 | 13983 |     if (plci->internal_command) | 
 | 13984 |       break; | 
 | 13985 |     break; | 
 | 13986 |   } | 
 | 13987 | } | 
 | 13988 |  | 
 | 13989 |  | 
 | 13990 | static void reset_b3_command (dword Id, PLCI   *plci, byte Rc) | 
 | 13991 | { | 
 | 13992 |   word Info; | 
 | 13993 |   word internal_command; | 
 | 13994 |  | 
 | 13995 |   dbug (1, dprintf ("[%06lx] %s,%d: reset_b3_command %02x %04x", | 
 | 13996 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 13997 |  | 
 | 13998 |   Info = GOOD; | 
 | 13999 |   internal_command = plci->internal_command; | 
 | 14000 |   plci->internal_command = 0; | 
 | 14001 |   switch (internal_command) | 
 | 14002 |   { | 
 | 14003 |   default: | 
 | 14004 |     plci->command = 0; | 
 | 14005 |     plci->adjust_b_parms_msg = NULL; | 
 | 14006 |     plci->adjust_b_facilities = plci->B1_facilities; | 
 | 14007 |     plci->adjust_b_command = RESET_B3_COMMAND_1; | 
 | 14008 |     plci->adjust_b_ncci = (word)(Id >> 16); | 
 | 14009 |     plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_CONNECT; | 
 | 14010 |     plci->adjust_b_state = ADJUST_B_START; | 
 | 14011 |     dbug (1, dprintf ("[%06lx] %s,%d: Reset B3...", | 
 | 14012 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14013 |   case RESET_B3_COMMAND_1: | 
 | 14014 |     Info = adjust_b_process (Id, plci, Rc); | 
 | 14015 |     if (Info != GOOD) | 
 | 14016 |     { | 
 | 14017 |       dbug (1, dprintf ("[%06lx] %s,%d: Reset failed", | 
 | 14018 |         UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14019 |       break; | 
 | 14020 |     } | 
 | 14021 |     if (plci->internal_command) | 
 | 14022 |       return; | 
 | 14023 |     break; | 
 | 14024 |   } | 
 | 14025 | /*  sendf (plci->appl, _RESET_B3_R | CONFIRM, Id, plci->number, "w", Info);*/ | 
 | 14026 |   sendf(plci->appl,_RESET_B3_I,Id,0,"s",""); | 
 | 14027 | } | 
 | 14028 |  | 
 | 14029 |  | 
 | 14030 | static void select_b_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14031 | { | 
 | 14032 |   word Info; | 
 | 14033 |   word internal_command; | 
 | 14034 |   byte esc_chi[3]; | 
 | 14035 |  | 
 | 14036 |   dbug (1, dprintf ("[%06lx] %s,%d: select_b_command %02x %04x", | 
 | 14037 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14038 |  | 
 | 14039 |   Info = GOOD; | 
 | 14040 |   internal_command = plci->internal_command; | 
 | 14041 |   plci->internal_command = 0; | 
 | 14042 |   switch (internal_command) | 
 | 14043 |   { | 
 | 14044 |   default: | 
 | 14045 |     plci->command = 0; | 
 | 14046 |     plci->adjust_b_parms_msg = &plci->saved_msg; | 
 | 14047 |     if ((plci->tel == ADV_VOICE) && (plci == plci->adapter->AdvSignalPLCI)) | 
 | 14048 |       plci->adjust_b_facilities = plci->B1_facilities | B1_FACILITY_VOICE; | 
 | 14049 |     else | 
 | 14050 |       plci->adjust_b_facilities = plci->B1_facilities & ~B1_FACILITY_VOICE; | 
 | 14051 |     plci->adjust_b_command = SELECT_B_COMMAND_1; | 
 | 14052 |     plci->adjust_b_ncci = (word)(Id >> 16); | 
 | 14053 |     if (plci->saved_msg.parms[0].length == 0) | 
 | 14054 |     { | 
 | 14055 |       plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 | | 
 | 14056 |         ADJUST_B_MODE_NO_RESOURCE; | 
 | 14057 |     } | 
 | 14058 |     else | 
 | 14059 |     { | 
 | 14060 |       plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 | | 
 | 14061 |         ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE; | 
 | 14062 |     } | 
 | 14063 |     plci->adjust_b_state = ADJUST_B_START; | 
 | 14064 |     dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol...", | 
 | 14065 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14066 |   case SELECT_B_COMMAND_1: | 
 | 14067 |     Info = adjust_b_process (Id, plci, Rc); | 
 | 14068 |     if (Info != GOOD) | 
 | 14069 |     { | 
 | 14070 |       dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol failed", | 
 | 14071 |         UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14072 |       break; | 
 | 14073 |     } | 
 | 14074 |     if (plci->internal_command) | 
 | 14075 |       return; | 
 | 14076 |     if (plci->tel == ADV_VOICE) | 
 | 14077 |     { | 
 | 14078 |       esc_chi[0] = 0x02; | 
 | 14079 |       esc_chi[1] = 0x18; | 
 | 14080 |       esc_chi[2] = plci->b_channel; | 
 | 14081 |       SetVoiceChannel (plci->adapter->AdvCodecPLCI, esc_chi, plci->adapter); | 
 | 14082 |     } | 
 | 14083 |     break; | 
 | 14084 |   } | 
 | 14085 |   sendf (plci->appl, _SELECT_B_REQ | CONFIRM, Id, plci->number, "w", Info); | 
 | 14086 | } | 
 | 14087 |  | 
 | 14088 |  | 
 | 14089 | static void fax_connect_ack_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14090 | { | 
 | 14091 |   word Info; | 
 | 14092 |   word internal_command; | 
 | 14093 |  | 
 | 14094 |   dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x", | 
 | 14095 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14096 |  | 
 | 14097 |   Info = GOOD; | 
 | 14098 |   internal_command = plci->internal_command; | 
 | 14099 |   plci->internal_command = 0; | 
 | 14100 |   switch (internal_command) | 
 | 14101 |   { | 
 | 14102 |   default: | 
 | 14103 |     plci->command = 0; | 
 | 14104 |   case FAX_CONNECT_ACK_COMMAND_1: | 
 | 14105 |     if (plci_nl_busy (plci)) | 
 | 14106 |     { | 
 | 14107 |       plci->internal_command = FAX_CONNECT_ACK_COMMAND_1; | 
 | 14108 |       return; | 
 | 14109 |     } | 
 | 14110 |     plci->internal_command = FAX_CONNECT_ACK_COMMAND_2; | 
 | 14111 |     plci->NData[0].P = plci->fax_connect_info_buffer; | 
 | 14112 |     plci->NData[0].PLength = plci->fax_connect_info_length; | 
 | 14113 |     plci->NL.X = plci->NData; | 
 | 14114 |     plci->NL.ReqCh = 0; | 
 | 14115 |     plci->NL.Req = plci->nl_req = (byte) N_CONNECT_ACK; | 
 | 14116 |     plci->adapter->request (&plci->NL); | 
 | 14117 |     return; | 
 | 14118 |   case FAX_CONNECT_ACK_COMMAND_2: | 
 | 14119 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 14120 |     { | 
 | 14121 |       dbug (1, dprintf ("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x", | 
 | 14122 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 14123 |       break; | 
 | 14124 |     } | 
 | 14125 |   } | 
 | 14126 |   if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) | 
 | 14127 |    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) | 
 | 14128 |   { | 
 | 14129 |     if (plci->B3_prot == 4) | 
 | 14130 |       sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); | 
 | 14131 |     else | 
 | 14132 |       sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); | 
 | 14133 |     plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; | 
 | 14134 |   } | 
 | 14135 | } | 
 | 14136 |  | 
 | 14137 |  | 
 | 14138 | static void fax_edata_ack_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14139 | { | 
 | 14140 |   word Info; | 
 | 14141 |   word internal_command; | 
 | 14142 |  | 
 | 14143 |   dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x", | 
 | 14144 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14145 |  | 
 | 14146 |   Info = GOOD; | 
 | 14147 |   internal_command = plci->internal_command; | 
 | 14148 |   plci->internal_command = 0; | 
 | 14149 |   switch (internal_command) | 
 | 14150 |   { | 
 | 14151 |   default: | 
 | 14152 |     plci->command = 0; | 
 | 14153 |   case FAX_EDATA_ACK_COMMAND_1: | 
 | 14154 |     if (plci_nl_busy (plci)) | 
 | 14155 |     { | 
 | 14156 |       plci->internal_command = FAX_EDATA_ACK_COMMAND_1; | 
 | 14157 |       return; | 
 | 14158 |     } | 
 | 14159 |     plci->internal_command = FAX_EDATA_ACK_COMMAND_2; | 
 | 14160 |     plci->NData[0].P = plci->fax_connect_info_buffer; | 
 | 14161 |     plci->NData[0].PLength = plci->fax_edata_ack_length; | 
 | 14162 |     plci->NL.X = plci->NData; | 
 | 14163 |     plci->NL.ReqCh = 0; | 
 | 14164 |     plci->NL.Req = plci->nl_req = (byte) N_EDATA; | 
 | 14165 |     plci->adapter->request (&plci->NL); | 
 | 14166 |     return; | 
 | 14167 |   case FAX_EDATA_ACK_COMMAND_2: | 
 | 14168 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 14169 |     { | 
 | 14170 |       dbug (1, dprintf ("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x", | 
 | 14171 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 14172 |       break; | 
 | 14173 |     } | 
 | 14174 |   } | 
 | 14175 | } | 
 | 14176 |  | 
 | 14177 |  | 
 | 14178 | static void fax_connect_info_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14179 | { | 
 | 14180 |   word Info; | 
 | 14181 |   word internal_command; | 
 | 14182 |  | 
 | 14183 |   dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_info_command %02x %04x", | 
 | 14184 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14185 |  | 
 | 14186 |   Info = GOOD; | 
 | 14187 |   internal_command = plci->internal_command; | 
 | 14188 |   plci->internal_command = 0; | 
 | 14189 |   switch (internal_command) | 
 | 14190 |   { | 
 | 14191 |   default: | 
 | 14192 |     plci->command = 0; | 
 | 14193 |   case FAX_CONNECT_INFO_COMMAND_1: | 
 | 14194 |     if (plci_nl_busy (plci)) | 
 | 14195 |     { | 
 | 14196 |       plci->internal_command = FAX_CONNECT_INFO_COMMAND_1; | 
 | 14197 |       return; | 
 | 14198 |     } | 
 | 14199 |     plci->internal_command = FAX_CONNECT_INFO_COMMAND_2; | 
 | 14200 |     plci->NData[0].P = plci->fax_connect_info_buffer; | 
 | 14201 |     plci->NData[0].PLength = plci->fax_connect_info_length; | 
 | 14202 |     plci->NL.X = plci->NData; | 
 | 14203 |     plci->NL.ReqCh = 0; | 
 | 14204 |     plci->NL.Req = plci->nl_req = (byte) N_EDATA; | 
 | 14205 |     plci->adapter->request (&plci->NL); | 
 | 14206 |     return; | 
 | 14207 |   case FAX_CONNECT_INFO_COMMAND_2: | 
 | 14208 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 14209 |     { | 
 | 14210 |       dbug (1, dprintf ("[%06lx] %s,%d: FAX setting connect info failed %02x", | 
 | 14211 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 14212 |       Info = _WRONG_STATE; | 
 | 14213 |       break; | 
 | 14214 |     } | 
 | 14215 |     if (plci_nl_busy (plci)) | 
 | 14216 |     { | 
 | 14217 |       plci->internal_command = FAX_CONNECT_INFO_COMMAND_2; | 
 | 14218 |       return; | 
 | 14219 |     } | 
 | 14220 |     plci->command = _CONNECT_B3_R; | 
 | 14221 |     nl_req_ncci (plci, N_CONNECT, 0); | 
 | 14222 |     send_req (plci); | 
 | 14223 |     return; | 
 | 14224 |   } | 
 | 14225 |   sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); | 
 | 14226 | } | 
 | 14227 |  | 
 | 14228 |  | 
 | 14229 | static void fax_adjust_b23_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14230 | { | 
 | 14231 |   word Info; | 
 | 14232 |   word internal_command; | 
 | 14233 |  | 
 | 14234 |   dbug (1, dprintf ("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x", | 
 | 14235 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14236 |  | 
 | 14237 |   Info = GOOD; | 
 | 14238 |   internal_command = plci->internal_command; | 
 | 14239 |   plci->internal_command = 0; | 
 | 14240 |   switch (internal_command) | 
 | 14241 |   { | 
 | 14242 |   default: | 
 | 14243 |     plci->command = 0; | 
 | 14244 |     plci->adjust_b_parms_msg = NULL; | 
 | 14245 |     plci->adjust_b_facilities = plci->B1_facilities; | 
 | 14246 |     plci->adjust_b_command = FAX_ADJUST_B23_COMMAND_1; | 
 | 14247 |     plci->adjust_b_ncci = (word)(Id >> 16); | 
 | 14248 |     plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23; | 
 | 14249 |     plci->adjust_b_state = ADJUST_B_START; | 
 | 14250 |     dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust B23...", | 
 | 14251 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14252 |   case FAX_ADJUST_B23_COMMAND_1: | 
 | 14253 |     Info = adjust_b_process (Id, plci, Rc); | 
 | 14254 |     if (Info != GOOD) | 
 | 14255 |     { | 
 | 14256 |       dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust failed", | 
 | 14257 |         UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14258 |       break; | 
 | 14259 |     } | 
 | 14260 |     if (plci->internal_command) | 
 | 14261 |       return; | 
 | 14262 |   case FAX_ADJUST_B23_COMMAND_2: | 
 | 14263 |     if (plci_nl_busy (plci)) | 
 | 14264 |     { | 
 | 14265 |       plci->internal_command = FAX_ADJUST_B23_COMMAND_2; | 
 | 14266 |       return; | 
 | 14267 |     } | 
 | 14268 |     plci->command = _CONNECT_B3_R; | 
 | 14269 |     nl_req_ncci (plci, N_CONNECT, 0); | 
 | 14270 |     send_req (plci); | 
 | 14271 |     return; | 
 | 14272 |   } | 
 | 14273 |   sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); | 
 | 14274 | } | 
 | 14275 |  | 
 | 14276 |  | 
 | 14277 | static void fax_disconnect_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14278 | { | 
 | 14279 |   word internal_command; | 
 | 14280 |  | 
 | 14281 |   dbug (1, dprintf ("[%06lx] %s,%d: fax_disconnect_command %02x %04x", | 
 | 14282 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14283 |  | 
 | 14284 |   internal_command = plci->internal_command; | 
 | 14285 |   plci->internal_command = 0; | 
 | 14286 |   switch (internal_command) | 
 | 14287 |   { | 
 | 14288 |   default: | 
 | 14289 |     plci->command = 0; | 
 | 14290 |     plci->internal_command = FAX_DISCONNECT_COMMAND_1; | 
 | 14291 |     return; | 
 | 14292 |   case FAX_DISCONNECT_COMMAND_1: | 
 | 14293 |   case FAX_DISCONNECT_COMMAND_2: | 
 | 14294 |   case FAX_DISCONNECT_COMMAND_3: | 
 | 14295 |     if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) | 
 | 14296 |     { | 
 | 14297 |       dbug (1, dprintf ("[%06lx] %s,%d: FAX disconnect EDATA failed %02x", | 
 | 14298 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 14299 |       break; | 
 | 14300 |     } | 
 | 14301 |     if (Rc == OK) | 
 | 14302 |     { | 
 | 14303 |       if ((internal_command == FAX_DISCONNECT_COMMAND_1) | 
 | 14304 |        || (internal_command == FAX_DISCONNECT_COMMAND_2)) | 
 | 14305 |       { | 
 | 14306 |         plci->internal_command = FAX_DISCONNECT_COMMAND_2; | 
 | 14307 |       } | 
 | 14308 |     } | 
 | 14309 |     else if (Rc == 0) | 
 | 14310 |     { | 
 | 14311 |       if (internal_command == FAX_DISCONNECT_COMMAND_1) | 
 | 14312 |         plci->internal_command = FAX_DISCONNECT_COMMAND_3; | 
 | 14313 |     } | 
 | 14314 |     return; | 
 | 14315 |   } | 
 | 14316 | } | 
 | 14317 |  | 
 | 14318 |  | 
 | 14319 |  | 
 | 14320 | static void rtp_connect_b3_req_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14321 | { | 
 | 14322 |   word Info; | 
 | 14323 |   word internal_command; | 
 | 14324 |  | 
 | 14325 |   dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x", | 
 | 14326 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14327 |  | 
 | 14328 |   Info = GOOD; | 
 | 14329 |   internal_command = plci->internal_command; | 
 | 14330 |   plci->internal_command = 0; | 
 | 14331 |   switch (internal_command) | 
 | 14332 |   { | 
 | 14333 |   default: | 
 | 14334 |     plci->command = 0; | 
 | 14335 |   case RTP_CONNECT_B3_REQ_COMMAND_1: | 
 | 14336 |     if (plci_nl_busy (plci)) | 
 | 14337 |     { | 
 | 14338 |       plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_1; | 
 | 14339 |       return; | 
 | 14340 |     } | 
 | 14341 |     plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2; | 
 | 14342 |     nl_req_ncci (plci, N_CONNECT, 0); | 
 | 14343 |     send_req (plci); | 
 | 14344 |     return; | 
 | 14345 |   case RTP_CONNECT_B3_REQ_COMMAND_2: | 
 | 14346 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 14347 |     { | 
 | 14348 |       dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect info failed %02x", | 
 | 14349 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 14350 |       Info = _WRONG_STATE; | 
 | 14351 |       break; | 
 | 14352 |     } | 
 | 14353 |     if (plci_nl_busy (plci)) | 
 | 14354 |     { | 
 | 14355 |       plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2; | 
 | 14356 |       return; | 
 | 14357 |     } | 
 | 14358 |     plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_3; | 
 | 14359 |     plci->NData[0].PLength = plci->internal_req_buffer[0]; | 
 | 14360 |     plci->NData[0].P = plci->internal_req_buffer + 1; | 
 | 14361 |     plci->NL.X = plci->NData; | 
 | 14362 |     plci->NL.ReqCh = 0; | 
 | 14363 |     plci->NL.Req = plci->nl_req = (byte) N_UDATA; | 
 | 14364 |     plci->adapter->request (&plci->NL); | 
 | 14365 |     break; | 
 | 14366 |   case RTP_CONNECT_B3_REQ_COMMAND_3: | 
 | 14367 |     return; | 
 | 14368 |   } | 
 | 14369 |   sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); | 
 | 14370 | } | 
 | 14371 |  | 
 | 14372 |  | 
 | 14373 | static void rtp_connect_b3_res_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14374 | { | 
 | 14375 |   word Info; | 
 | 14376 |   word internal_command; | 
 | 14377 |  | 
 | 14378 |   dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x", | 
 | 14379 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14380 |  | 
 | 14381 |   Info = GOOD; | 
 | 14382 |   internal_command = plci->internal_command; | 
 | 14383 |   plci->internal_command = 0; | 
 | 14384 |   switch (internal_command) | 
 | 14385 |   { | 
 | 14386 |   default: | 
 | 14387 |     plci->command = 0; | 
 | 14388 |   case RTP_CONNECT_B3_RES_COMMAND_1: | 
 | 14389 |     if (plci_nl_busy (plci)) | 
 | 14390 |     { | 
 | 14391 |       plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_1; | 
 | 14392 |       return; | 
 | 14393 |     } | 
 | 14394 |     plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2; | 
 | 14395 |     nl_req_ncci (plci, N_CONNECT_ACK, (byte)(Id >> 16)); | 
 | 14396 |     send_req (plci); | 
 | 14397 |     return; | 
 | 14398 |   case RTP_CONNECT_B3_RES_COMMAND_2: | 
 | 14399 |     if ((Rc != OK) && (Rc != OK_FC)) | 
 | 14400 |     { | 
 | 14401 |       dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x", | 
 | 14402 |         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc)); | 
 | 14403 |       Info = _WRONG_STATE; | 
 | 14404 |       break; | 
 | 14405 |     } | 
 | 14406 |     if (plci_nl_busy (plci)) | 
 | 14407 |     { | 
 | 14408 |       plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2; | 
 | 14409 |       return; | 
 | 14410 |     } | 
 | 14411 |     sendf (plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); | 
 | 14412 |     plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_3; | 
 | 14413 |     plci->NData[0].PLength = plci->internal_req_buffer[0]; | 
 | 14414 |     plci->NData[0].P = plci->internal_req_buffer + 1; | 
 | 14415 |     plci->NL.X = plci->NData; | 
 | 14416 |     plci->NL.ReqCh = 0; | 
 | 14417 |     plci->NL.Req = plci->nl_req = (byte) N_UDATA; | 
 | 14418 |     plci->adapter->request (&plci->NL); | 
 | 14419 |     return; | 
 | 14420 |   case RTP_CONNECT_B3_RES_COMMAND_3: | 
 | 14421 |     return; | 
 | 14422 |   } | 
 | 14423 | } | 
 | 14424 |  | 
 | 14425 |  | 
 | 14426 |  | 
 | 14427 | static void hold_save_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14428 | { | 
 | 14429 |     byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ | 
 | 14430 |   word Info; | 
 | 14431 |   word internal_command; | 
 | 14432 |  | 
 | 14433 |   dbug (1, dprintf ("[%06lx] %s,%d: hold_save_command %02x %04x", | 
 | 14434 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14435 |  | 
 | 14436 |   Info = GOOD; | 
 | 14437 |   internal_command = plci->internal_command; | 
 | 14438 |   plci->internal_command = 0; | 
 | 14439 |   switch (internal_command) | 
 | 14440 |   { | 
 | 14441 |   default: | 
 | 14442 |     if (!plci->NL.Id) | 
 | 14443 |       break; | 
 | 14444 |     plci->command = 0; | 
 | 14445 |     plci->adjust_b_parms_msg = NULL; | 
 | 14446 |     plci->adjust_b_facilities = plci->B1_facilities; | 
 | 14447 |     plci->adjust_b_command = HOLD_SAVE_COMMAND_1; | 
 | 14448 |     plci->adjust_b_ncci = (word)(Id >> 16); | 
 | 14449 |     plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23; | 
 | 14450 |     plci->adjust_b_state = ADJUST_B_START; | 
 | 14451 |     dbug (1, dprintf ("[%06lx] %s,%d: HOLD save...", | 
 | 14452 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14453 |   case HOLD_SAVE_COMMAND_1: | 
 | 14454 |     Info = adjust_b_process (Id, plci, Rc); | 
 | 14455 |     if (Info != GOOD) | 
 | 14456 |     { | 
 | 14457 |       dbug (1, dprintf ("[%06lx] %s,%d: HOLD save failed", | 
 | 14458 |         UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14459 |       break; | 
 | 14460 |     } | 
 | 14461 |     if (plci->internal_command) | 
 | 14462 |       return; | 
 | 14463 |   } | 
 | 14464 |   sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind); | 
 | 14465 | } | 
 | 14466 |  | 
 | 14467 |  | 
 | 14468 | static void retrieve_restore_command (dword Id, PLCI   *plci, byte Rc) | 
 | 14469 | { | 
 | 14470 |     byte SS_Ind[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/ | 
 | 14471 |   word Info; | 
 | 14472 |   word internal_command; | 
 | 14473 |  | 
 | 14474 |   dbug (1, dprintf ("[%06lx] %s,%d: retrieve_restore_command %02x %04x", | 
 | 14475 |     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command)); | 
 | 14476 |  | 
 | 14477 |   Info = GOOD; | 
 | 14478 |   internal_command = plci->internal_command; | 
 | 14479 |   plci->internal_command = 0; | 
 | 14480 |   switch (internal_command) | 
 | 14481 |   { | 
 | 14482 |   default: | 
 | 14483 |     plci->command = 0; | 
 | 14484 |     plci->adjust_b_parms_msg = NULL; | 
 | 14485 |     plci->adjust_b_facilities = plci->B1_facilities; | 
 | 14486 |     plci->adjust_b_command = RETRIEVE_RESTORE_COMMAND_1; | 
 | 14487 |     plci->adjust_b_ncci = (word)(Id >> 16); | 
 | 14488 |     plci->adjust_b_mode = ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE; | 
 | 14489 |     plci->adjust_b_state = ADJUST_B_START; | 
 | 14490 |     dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore...", | 
 | 14491 |       UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14492 |   case RETRIEVE_RESTORE_COMMAND_1: | 
 | 14493 |     Info = adjust_b_process (Id, plci, Rc); | 
 | 14494 |     if (Info != GOOD) | 
 | 14495 |     { | 
 | 14496 |       dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore failed", | 
 | 14497 |         UnMapId (Id), (char   *)(FILE_), __LINE__)); | 
 | 14498 |       break; | 
 | 14499 |     } | 
 | 14500 |     if (plci->internal_command) | 
 | 14501 |       return; | 
 | 14502 |   } | 
 | 14503 |   sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind); | 
 | 14504 | } | 
 | 14505 |  | 
 | 14506 |  | 
 | 14507 | static void init_b1_config (PLCI   *plci) | 
 | 14508 | { | 
 | 14509 |  | 
 | 14510 |   dbug (1, dprintf ("[%06lx] %s,%d: init_b1_config", | 
 | 14511 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 14512 |     (char   *)(FILE_), __LINE__)); | 
 | 14513 |  | 
 | 14514 |   plci->B1_resource = 0; | 
 | 14515 |   plci->B1_facilities = 0; | 
 | 14516 |  | 
 | 14517 |   plci->li_bchannel_id = 0; | 
 | 14518 |   mixer_clear_config (plci); | 
 | 14519 |  | 
 | 14520 |  | 
 | 14521 |   ec_clear_config (plci); | 
 | 14522 |  | 
 | 14523 |  | 
 | 14524 |   dtmf_rec_clear_config (plci); | 
 | 14525 |   dtmf_send_clear_config (plci); | 
 | 14526 |   dtmf_parameter_clear_config (plci); | 
 | 14527 |  | 
 | 14528 |   adv_voice_clear_config (plci); | 
 | 14529 |   adjust_b_clear (plci); | 
 | 14530 | } | 
 | 14531 |  | 
 | 14532 |  | 
 | 14533 | static void clear_b1_config (PLCI   *plci) | 
 | 14534 | { | 
 | 14535 |  | 
 | 14536 |   dbug (1, dprintf ("[%06lx] %s,%d: clear_b1_config", | 
 | 14537 |     (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), | 
 | 14538 |     (char   *)(FILE_), __LINE__)); | 
 | 14539 |  | 
 | 14540 |   adv_voice_clear_config (plci); | 
 | 14541 |   adjust_b_clear (plci); | 
 | 14542 |  | 
 | 14543 |   ec_clear_config (plci); | 
 | 14544 |  | 
 | 14545 |  | 
 | 14546 |   dtmf_rec_clear_config (plci); | 
 | 14547 |   dtmf_send_clear_config (plci); | 
 | 14548 |   dtmf_parameter_clear_config (plci); | 
 | 14549 |  | 
 | 14550 |  | 
 | 14551 |   if ((plci->li_bchannel_id != 0) | 
 | 14552 |    && (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci == plci)) | 
 | 14553 |   { | 
 | 14554 |     mixer_clear_config (plci); | 
 | 14555 |     li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = NULL; | 
 | 14556 |     plci->li_bchannel_id = 0; | 
 | 14557 |   } | 
 | 14558 |  | 
 | 14559 |   plci->B1_resource = 0; | 
 | 14560 |   plci->B1_facilities = 0; | 
 | 14561 | } | 
 | 14562 |  | 
 | 14563 |  | 
 | 14564 | /* ----------------------------------------------------------------- | 
 | 14565 |                 XON protocol local helpers | 
 | 14566 |    ----------------------------------------------------------------- */ | 
 | 14567 | static void channel_flow_control_remove (PLCI   * plci) { | 
 | 14568 |   DIVA_CAPI_ADAPTER   * a = plci->adapter; | 
 | 14569 |   word i; | 
 | 14570 |   for(i=1;i<MAX_NL_CHANNEL+1;i++) { | 
 | 14571 |     if (a->ch_flow_plci[i] == plci->Id) { | 
 | 14572 |       a->ch_flow_plci[i] = 0; | 
 | 14573 |       a->ch_flow_control[i] = 0; | 
 | 14574 |     } | 
 | 14575 |   } | 
 | 14576 | } | 
 | 14577 |  | 
 | 14578 | static void channel_x_on (PLCI   * plci, byte ch) { | 
 | 14579 |   DIVA_CAPI_ADAPTER   * a = plci->adapter; | 
 | 14580 |   if (a->ch_flow_control[ch] & N_XON_SENT) { | 
 | 14581 |     a->ch_flow_control[ch] &= ~N_XON_SENT; | 
 | 14582 |   } | 
 | 14583 | } | 
 | 14584 |  | 
 | 14585 | static void channel_x_off (PLCI   * plci, byte ch, byte flag) { | 
 | 14586 |   DIVA_CAPI_ADAPTER   * a = plci->adapter; | 
 | 14587 |   if ((a->ch_flow_control[ch] & N_RX_FLOW_CONTROL_MASK) == 0) { | 
 | 14588 |     a->ch_flow_control[ch] |= (N_CH_XOFF | flag); | 
 | 14589 |     a->ch_flow_plci[ch] = plci->Id; | 
 | 14590 |     a->ch_flow_control_pending++; | 
 | 14591 |   } | 
 | 14592 | } | 
 | 14593 |  | 
 | 14594 | static void channel_request_xon (PLCI   * plci, byte ch) { | 
 | 14595 |   DIVA_CAPI_ADAPTER   * a = plci->adapter; | 
 | 14596 |  | 
 | 14597 |   if (a->ch_flow_control[ch] & N_CH_XOFF) { | 
 | 14598 |     a->ch_flow_control[ch] |= N_XON_REQ; | 
 | 14599 |     a->ch_flow_control[ch] &= ~N_CH_XOFF; | 
 | 14600 |     a->ch_flow_control[ch] &= ~N_XON_CONNECT_IND; | 
 | 14601 |   } | 
 | 14602 | } | 
 | 14603 |  | 
 | 14604 | static void channel_xmit_extended_xon (PLCI   * plci) { | 
 | 14605 |   DIVA_CAPI_ADAPTER   * a; | 
 | 14606 |   int max_ch = sizeof(a->ch_flow_control)/sizeof(a->ch_flow_control[0]); | 
 | 14607 |   int i, one_requested = 0; | 
 | 14608 |  | 
 | 14609 |   if ((!plci) || (!plci->Id) || ((a = plci->adapter) == 0)) { | 
 | 14610 |     return; | 
 | 14611 |   } | 
 | 14612 |  | 
 | 14613 |   for (i = 0; i < max_ch; i++) { | 
 | 14614 |     if ((a->ch_flow_control[i] & N_CH_XOFF) && | 
 | 14615 |         (a->ch_flow_control[i] & N_XON_CONNECT_IND) && | 
 | 14616 |         (plci->Id == a->ch_flow_plci[i])) { | 
 | 14617 |       channel_request_xon (plci, (byte)i); | 
 | 14618 |       one_requested = 1; | 
 | 14619 |     } | 
 | 14620 |   } | 
 | 14621 |  | 
 | 14622 |   if (one_requested) { | 
 | 14623 |     channel_xmit_xon (plci); | 
 | 14624 |   } | 
 | 14625 | } | 
 | 14626 |  | 
 | 14627 | /* | 
 | 14628 |   Try to xmit next X_ON | 
 | 14629 |   */ | 
 | 14630 | static int find_channel_with_pending_x_on (DIVA_CAPI_ADAPTER   * a, PLCI   * plci) { | 
 | 14631 |   int max_ch = sizeof(a->ch_flow_control)/sizeof(a->ch_flow_control[0]); | 
 | 14632 |   int i; | 
 | 14633 |  | 
 | 14634 |   if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) { | 
 | 14635 |     return (0); | 
 | 14636 |   } | 
 | 14637 |  | 
 | 14638 |   if (a->last_flow_control_ch >= max_ch) { | 
 | 14639 |     a->last_flow_control_ch = 1; | 
 | 14640 |   } | 
 | 14641 |   for (i=a->last_flow_control_ch; i < max_ch; i++) { | 
 | 14642 |     if ((a->ch_flow_control[i] & N_XON_REQ) && | 
 | 14643 |         (plci->Id == a->ch_flow_plci[i])) { | 
 | 14644 |       a->last_flow_control_ch = i+1; | 
 | 14645 |       return (i); | 
 | 14646 |     } | 
 | 14647 |   } | 
 | 14648 |  | 
 | 14649 |   for (i = 1; i < a->last_flow_control_ch; i++) { | 
 | 14650 |     if ((a->ch_flow_control[i] & N_XON_REQ) && | 
 | 14651 |         (plci->Id == a->ch_flow_plci[i])) { | 
 | 14652 |       a->last_flow_control_ch = i+1; | 
 | 14653 |       return (i); | 
 | 14654 |     } | 
 | 14655 |   } | 
 | 14656 |  | 
 | 14657 |   return (0); | 
 | 14658 | } | 
 | 14659 |  | 
 | 14660 | static void channel_xmit_xon (PLCI   * plci) { | 
 | 14661 |   DIVA_CAPI_ADAPTER   * a = plci->adapter; | 
 | 14662 |   byte ch; | 
 | 14663 |  | 
 | 14664 |   if (plci->nl_req || !plci->NL.Id || plci->nl_remove_id) { | 
 | 14665 |     return; | 
 | 14666 |   } | 
 | 14667 |   if ((ch = (byte)find_channel_with_pending_x_on (a, plci)) == 0) { | 
 | 14668 |     return; | 
 | 14669 |   } | 
 | 14670 |   a->ch_flow_control[ch] &= ~N_XON_REQ; | 
 | 14671 |   a->ch_flow_control[ch] |= N_XON_SENT; | 
 | 14672 |  | 
 | 14673 |   plci->NL.Req = plci->nl_req = (byte)N_XON; | 
 | 14674 |   plci->NL.ReqCh         = ch; | 
 | 14675 |   plci->NL.X             = plci->NData; | 
 | 14676 |   plci->NL.XNum          = 1; | 
 | 14677 |   plci->NData[0].P       = &plci->RBuffer[0]; | 
 | 14678 |   plci->NData[0].PLength = 0; | 
 | 14679 |  | 
 | 14680 |   plci->adapter->request(&plci->NL); | 
 | 14681 | } | 
 | 14682 |  | 
 | 14683 | static int channel_can_xon (PLCI   * plci, byte ch) { | 
 | 14684 |   APPL   * APPLptr; | 
 | 14685 |   DIVA_CAPI_ADAPTER   * a; | 
 | 14686 |   word NCCIcode; | 
 | 14687 |   dword count; | 
 | 14688 |   word Num; | 
 | 14689 |   word i; | 
 | 14690 |  | 
 | 14691 |   APPLptr = plci->appl; | 
 | 14692 |   a = plci->adapter; | 
 | 14693 |  | 
 | 14694 |   if (!APPLptr) | 
 | 14695 |     return (0); | 
 | 14696 |  | 
 | 14697 |   NCCIcode = a->ch_ncci[ch] | (((word) a->Id) << 8); | 
 | 14698 |  | 
 | 14699 |                 /* count all buffers within the Application pool    */ | 
 | 14700 |                 /* belonging to the same NCCI. XON if a first is    */ | 
 | 14701 |                 /* used.                                            */ | 
 | 14702 |   count = 0; | 
 | 14703 |   Num = 0xffff; | 
 | 14704 |   for(i=0; i<APPLptr->MaxBuffer; i++) { | 
 | 14705 |     if(NCCIcode==APPLptr->DataNCCI[i]) count++; | 
 | 14706 |     if(!APPLptr->DataNCCI[i] && Num==0xffff) Num = i; | 
 | 14707 |   } | 
 | 14708 |   if ((count > 2) || (Num == 0xffff)) { | 
 | 14709 |     return (0); | 
 | 14710 |   } | 
 | 14711 |   return (1); | 
 | 14712 | } | 
 | 14713 |  | 
 | 14714 |  | 
 | 14715 | /*------------------------------------------------------------------*/ | 
 | 14716 |  | 
 | 14717 | static word CPN_filter_ok(byte   *cpn,DIVA_CAPI_ADAPTER   * a,word offset) | 
 | 14718 | { | 
 | 14719 |   return 1; | 
 | 14720 | } | 
 | 14721 |  | 
 | 14722 |  | 
 | 14723 |  | 
 | 14724 | /**********************************************************************************/ | 
 | 14725 | /* function groups the listening applications according to the CIP mask and the   */ | 
 | 14726 | /* Info_Mask. Each group gets just one Connect_Ind. Some application manufacturer */ | 
 | 14727 | /* are not multi-instance capable, so they start e.g. 30 applications what causes */ | 
 | 14728 | /* big problems on application level (one call, 30 Connect_Ind, ect). The         */ | 
 | 14729 | /* function must be enabled by setting "a->group_optimization_enabled" from the   */ | 
 | 14730 | /* OS specific part (per adapter).                                                */ | 
 | 14731 | /**********************************************************************************/ | 
 | 14732 | static void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci) | 
 | 14733 | { | 
 | 14734 |   word i,j,k,busy,group_found; | 
 | 14735 |   dword info_mask_group[MAX_CIP_TYPES]; | 
 | 14736 |   dword cip_mask_group[MAX_CIP_TYPES]; | 
 | 14737 |   word appl_number_group_type[MAX_APPL]; | 
 | 14738 |   PLCI   *auxplci; | 
 | 14739 |  | 
 | 14740 |   set_group_ind_mask (plci); /* all APPLs within this inc. call are allowed to dial in */ | 
 | 14741 |  | 
 | 14742 |   if(!a->group_optimization_enabled) | 
 | 14743 |   { | 
 | 14744 |     dbug(1,dprintf("No group optimization")); | 
 | 14745 |     return; | 
 | 14746 |   } | 
 | 14747 |  | 
 | 14748 |   dbug(1,dprintf("Group optimization = 0x%x...", a->group_optimization_enabled)); | 
 | 14749 |  | 
 | 14750 |   for(i=0;i<MAX_CIP_TYPES;i++) | 
 | 14751 |   { | 
 | 14752 |     info_mask_group[i] = 0; | 
 | 14753 |     cip_mask_group [i] = 0; | 
 | 14754 |   } | 
 | 14755 |   for(i=0;i<MAX_APPL;i++) | 
 | 14756 |   { | 
 | 14757 |     appl_number_group_type[i] = 0; | 
 | 14758 |   } | 
 | 14759 |   for(i=0; i<max_appl; i++) /* check if any multi instance capable application is present */ | 
 | 14760 |   {  /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */ | 
 | 14761 |     if(application[i].Id && (application[i].MaxNCCI) > 1 && (a->CIP_Mask[i])  && (a->group_optimization_enabled ==1) ) | 
 | 14762 |     { | 
 | 14763 |       dbug(1,dprintf("Multi-Instance capable, no optimization required")); | 
 | 14764 |       return; /* allow good application unfiltered access */ | 
 | 14765 |     } | 
 | 14766 |   } | 
 | 14767 |   for(i=0; i<max_appl; i++) /* Build CIP Groups */ | 
 | 14768 |   { | 
 | 14769 |     if(application[i].Id && a->CIP_Mask[i] ) | 
 | 14770 |     { | 
 | 14771 |       for(k=0,busy=FALSE; k<a->max_plci; k++) | 
 | 14772 |       { | 
 | 14773 |         if(a->plci[k].Id)  | 
 | 14774 |         { | 
 | 14775 |           auxplci = &a->plci[k]; | 
 | 14776 |           if(auxplci->appl == &application[i]) /* application has a busy PLCI */ | 
 | 14777 |           { | 
 | 14778 |             busy = TRUE; | 
 | 14779 |             dbug(1,dprintf("Appl 0x%x is busy",i+1)); | 
 | 14780 |           } | 
 | 14781 |           else if(test_c_ind_mask_bit (auxplci, i)) /* application has an incoming call pending */ | 
 | 14782 |           { | 
 | 14783 |             busy = TRUE; | 
 | 14784 |             dbug(1,dprintf("Appl 0x%x has inc. call pending",i+1)); | 
 | 14785 |           } | 
 | 14786 |         } | 
 | 14787 |       } | 
 | 14788 |  | 
 | 14789 |       for(j=0,group_found=0; j<=(MAX_CIP_TYPES) && !busy &&!group_found; j++)     /* build groups with free applications only */ | 
 | 14790 |       { | 
 | 14791 |         if(j==MAX_CIP_TYPES)       /* all groups are in use but group still not found */ | 
 | 14792 |         {                           /* the MAX_CIP_TYPES group enables all calls because of field overflow */ | 
 | 14793 |           appl_number_group_type[i] = MAX_CIP_TYPES; | 
 | 14794 |           group_found=TRUE; | 
 | 14795 |           dbug(1,dprintf("Field overflow appl 0x%x",i+1)); | 
 | 14796 |         } | 
 | 14797 |         else if( (info_mask_group[j]==a->CIP_Mask[i]) && (cip_mask_group[j]==a->Info_Mask[i]) )   | 
 | 14798 |         {                                      /* is group already present ?                  */ | 
 | 14799 |           appl_number_group_type[i] = j|0x80;  /* store the group number for each application */ | 
 | 14800 |           group_found=TRUE; | 
 | 14801 |           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])); | 
 | 14802 |         } | 
 | 14803 |         else if(!info_mask_group[j]) | 
 | 14804 |         {                                      /* establish a new group                       */ | 
 | 14805 |           appl_number_group_type[i] = j|0x80;  /* store the group number for each application */ | 
 | 14806 |           info_mask_group[j] = a->CIP_Mask[i]; /* store the new CIP mask for the new group    */ | 
 | 14807 |           cip_mask_group[j] = a->Info_Mask[i]; /* store the new Info_Mask for this new group  */ | 
 | 14808 |           group_found=TRUE; | 
 | 14809 |           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])); | 
 | 14810 |         } | 
 | 14811 |       } | 
 | 14812 |     } | 
 | 14813 |   } | 
 | 14814 |          | 
 | 14815 |   for(i=0; i<max_appl; i++) /* Build group_optimization_mask_table */ | 
 | 14816 |   { | 
 | 14817 |     if(appl_number_group_type[i]) /* application is free, has listens and is member of a group */ | 
 | 14818 |     { | 
 | 14819 |       if(appl_number_group_type[i] == MAX_CIP_TYPES) | 
 | 14820 |       { | 
 | 14821 |         dbug(1,dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled",appl_number_group_type[i],i+1)); | 
 | 14822 |       } | 
 | 14823 |       else | 
 | 14824 |       { | 
 | 14825 |         dbug(1,dprintf("Group 0x%x, valid appl = 0x%x",appl_number_group_type[i],i+1)); | 
 | 14826 |         for(j=i+1; j<max_appl; j++)   /* search other group members and mark them as busy        */ | 
 | 14827 |         { | 
 | 14828 |           if(appl_number_group_type[i] == appl_number_group_type[j])  | 
 | 14829 |           { | 
 | 14830 |             dbug(1,dprintf("Appl 0x%x is member of group 0x%x, no call",j+1,appl_number_group_type[j])); | 
 | 14831 |             clear_group_ind_mask_bit (plci, j);           /* disable call on other group members */ | 
 | 14832 |             appl_number_group_type[j] = 0;       /* remove disabled group member from group list */ | 
 | 14833 |           } | 
 | 14834 |         } | 
 | 14835 |       } | 
 | 14836 |     } | 
 | 14837 |     else                                                 /* application should not get a call */ | 
 | 14838 |     { | 
 | 14839 |       clear_group_ind_mask_bit (plci, i); | 
 | 14840 |     } | 
 | 14841 |   } | 
 | 14842 |  | 
 | 14843 | } | 
 | 14844 |  | 
 | 14845 |  | 
 | 14846 |  | 
 | 14847 | /* OS notifies the driver about a application Capi_Register */ | 
 | 14848 | word CapiRegister(word id) | 
 | 14849 | { | 
 | 14850 |   word i,j,appls_found; | 
 | 14851 |  | 
 | 14852 |   PLCI   *plci; | 
 | 14853 |   DIVA_CAPI_ADAPTER   *a; | 
 | 14854 |  | 
 | 14855 |   for(i=0,appls_found=0; i<max_appl; i++) | 
 | 14856 |   { | 
 | 14857 |     if( application[i].Id && (application[i].Id!=id) ) | 
 | 14858 |     { | 
 | 14859 |       appls_found++;                       /* an application has been found */ | 
 | 14860 |     } | 
 | 14861 |   } | 
 | 14862 |  | 
 | 14863 |   if(appls_found) return TRUE; | 
 | 14864 |   for(i=0; i<max_adapter; i++)                   /* scan all adapters...    */ | 
 | 14865 |   { | 
 | 14866 |     a = &adapter[i]; | 
 | 14867 |     if(a->request) | 
 | 14868 |     { | 
 | 14869 |       if(a->flag_dynamic_l1_down)  /* remove adapter from L1 tristate (Huntgroup) */ | 
 | 14870 |       { | 
 | 14871 |         if(!appls_found)           /* first application does a capi register   */ | 
 | 14872 |         { | 
 | 14873 |           if((j=get_plci(a)))                    /* activate L1 of all adapters */ | 
 | 14874 |           { | 
 | 14875 |             plci = &a->plci[j-1]; | 
 | 14876 |             plci->command = 0; | 
 | 14877 |             add_p(plci,OAD,"\x01\xfd"); | 
 | 14878 |             add_p(plci,CAI,"\x01\x80"); | 
 | 14879 |             add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); | 
 | 14880 |             add_p(plci,SHIFT|6,NULL); | 
 | 14881 |             add_p(plci,SIN,"\x02\x00\x00"); | 
 | 14882 |             plci->internal_command = START_L1_SIG_ASSIGN_PEND; | 
 | 14883 |             sig_req(plci,ASSIGN,DSIG_ID); | 
 | 14884 |             add_p(plci,FTY,"\x02\xff\x07"); /* l1 start */ | 
 | 14885 |             sig_req(plci,SIG_CTRL,0); | 
 | 14886 |             send_req(plci); | 
 | 14887 |           } | 
 | 14888 |         } | 
 | 14889 |       } | 
 | 14890 |     } | 
 | 14891 |   } | 
 | 14892 |   return FALSE; | 
 | 14893 | } | 
 | 14894 |  | 
 | 14895 | /*------------------------------------------------------------------*/ | 
 | 14896 |  | 
 | 14897 | /* Functions for virtual Switching e.g. Transfer by join, Conference */ | 
 | 14898 |  | 
 | 14899 | static void VSwitchReqInd(PLCI   *plci, dword Id, byte   **parms) | 
 | 14900 | { | 
 | 14901 |  word i; | 
 | 14902 |  /* Format of vswitch_t: | 
 | 14903 |  0 byte length | 
 | 14904 |  1 byte VSWITCHIE | 
 | 14905 |  2 byte VSWITCH_REQ/VSWITCH_IND | 
 | 14906 |  3 byte reserved | 
 | 14907 |  4 word VSwitchcommand | 
 | 14908 |  6 word returnerror | 
 | 14909 |  8... Params | 
 | 14910 |  */ | 
 | 14911 |  if(!plci || | 
 | 14912 |   !plci->appl || | 
 | 14913 |   !plci->State || | 
 | 14914 |   plci->Sig.Ind==NCR_FACILITY | 
 | 14915 |   ) | 
 | 14916 |   return; | 
 | 14917 |   | 
 | 14918 |  for(i=0;i<MAX_MULTI_IE;i++) | 
 | 14919 |  { | 
 | 14920 |         if(!parms[i][0]) continue; | 
 | 14921 |   if(parms[i][0]<7) | 
 | 14922 |   { | 
 | 14923 |    parms[i][0]=0; /* kill it */ | 
 | 14924 |    continue; | 
 | 14925 |   } | 
 | 14926 |   dbug(1,dprintf("VSwitchReqInd(%d)",parms[i][4])); | 
 | 14927 |   switch(parms[i][4]) | 
 | 14928 |   { | 
 | 14929 |   case VSJOIN: | 
 | 14930 |    if(!plci->relatedPTYPLCI || | 
 | 14931 |     (plci->ptyState!=S_ECT && plci->relatedPTYPLCI->ptyState!=S_ECT)) | 
 | 14932 |    { /* Error */ | 
 | 14933 |     break; | 
 | 14934 |    } | 
 | 14935 |    /* remember all necessary informations */ | 
 | 14936 |    if(parms[i][0]!=11 || parms[i][8]!=3) /* Length Test */ | 
 | 14937 |    { | 
 | 14938 |     break; | 
 | 14939 |    } | 
 | 14940 |    if(parms[i][2]==VSWITCH_IND && parms[i][9]==1) | 
 | 14941 |    {   /* first indication after ECT-Request on Consultation Call */ | 
 | 14942 |     plci->vswitchstate=parms[i][9]; | 
 | 14943 |     parms[i][9]=2; /* State */ | 
 | 14944 |     /* now ask first Call to join */ | 
 | 14945 |    } | 
 | 14946 |    else if(parms[i][2]==VSWITCH_REQ && parms[i][9]==3) | 
 | 14947 |    { /* Answer of VSWITCH_REQ from first Call */ | 
 | 14948 |     plci->vswitchstate=parms[i][9]; | 
 | 14949 |     /* tell consultation call to join | 
 | 14950 |     and the protocol capabilities of the first call */ | 
 | 14951 |    } | 
 | 14952 |    else | 
 | 14953 |    { /* Error */ | 
 | 14954 |     break; | 
 | 14955 |    }     | 
 | 14956 |    plci->vsprot=parms[i][10]; /* protocol */ | 
 | 14957 |    plci->vsprotdialect=parms[i][11]; /* protocoldialect */ | 
 | 14958 |    /* send join request to related PLCI */ | 
 | 14959 |    parms[i][1]=VSWITCHIE; | 
 | 14960 |    parms[i][2]=VSWITCH_REQ; | 
 | 14961 |     | 
 | 14962 |    plci->relatedPTYPLCI->command = 0; | 
 | 14963 |    plci->relatedPTYPLCI->internal_command = VSWITCH_REQ_PEND; | 
 | 14964 |    add_p(plci->relatedPTYPLCI,ESC,&parms[i][0]); | 
 | 14965 |    sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0); | 
 | 14966 |    send_req(plci->relatedPTYPLCI); | 
 | 14967 |    break; | 
 | 14968 |   case VSTRANSPORT: | 
 | 14969 |   default: | 
 | 14970 |    if(plci->relatedPTYPLCI && | 
 | 14971 |     plci->vswitchstate==3 && | 
 | 14972 |     plci->relatedPTYPLCI->vswitchstate==3) | 
 | 14973 |    { | 
 | 14974 |     add_p(plci->relatedPTYPLCI,ESC,&parms[i][0]); | 
 | 14975 |     sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0); | 
 | 14976 |     send_req(plci->relatedPTYPLCI); | 
 | 14977 |    } | 
 | 14978 |    break; | 
 | 14979 |   }   | 
 | 14980 |   parms[i][0]=0; /* kill it */ | 
 | 14981 |  } | 
 | 14982 | } | 
 | 14983 |  | 
 | 14984 |  | 
 | 14985 | /*------------------------------------------------------------------*/ | 
 | 14986 |  | 
 | 14987 | static int diva_get_dma_descriptor (PLCI   *plci, dword   *dma_magic) { | 
 | 14988 |   ENTITY e; | 
 | 14989 |   IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e; | 
 | 14990 |  | 
 | 14991 |   if (!(diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_RX_DMA)) { | 
 | 14992 |     return (-1); | 
 | 14993 |   } | 
 | 14994 |  | 
 | 14995 |   pReq->xdi_dma_descriptor_operation.Req = 0; | 
 | 14996 |   pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; | 
 | 14997 |  | 
 | 14998 |   pReq->xdi_dma_descriptor_operation.info.operation =     IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC; | 
 | 14999 |   pReq->xdi_dma_descriptor_operation.info.descriptor_number  = -1; | 
 | 15000 |   pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; | 
 | 15001 |   pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0; | 
 | 15002 |  | 
 | 15003 |   e.user[0] = plci->adapter->Id - 1; | 
 | 15004 |   plci->adapter->request((ENTITY*)pReq); | 
 | 15005 |  | 
 | 15006 |   if (!pReq->xdi_dma_descriptor_operation.info.operation && | 
 | 15007 |       (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) && | 
 | 15008 |       pReq->xdi_dma_descriptor_operation.info.descriptor_magic) { | 
 | 15009 |     *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic; | 
 | 15010 |     dbug(3,dprintf("dma_alloc, a:%d (%d-%08x)", | 
 | 15011 |          plci->adapter->Id, | 
 | 15012 |          pReq->xdi_dma_descriptor_operation.info.descriptor_number, | 
 | 15013 |          *dma_magic)); | 
 | 15014 |     return (pReq->xdi_dma_descriptor_operation.info.descriptor_number); | 
 | 15015 |   } else { | 
 | 15016 |     dbug(1,dprintf("dma_alloc failed")); | 
 | 15017 |     return (-1); | 
 | 15018 |   } | 
 | 15019 | } | 
 | 15020 |  | 
 | 15021 | static void diva_free_dma_descriptor (PLCI   *plci, int nr) { | 
 | 15022 |   ENTITY e; | 
 | 15023 |   IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e; | 
 | 15024 |  | 
 | 15025 |   if (nr < 0) { | 
 | 15026 |     return; | 
 | 15027 |   } | 
 | 15028 |  | 
 | 15029 |   pReq->xdi_dma_descriptor_operation.Req = 0; | 
 | 15030 |   pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; | 
 | 15031 |  | 
 | 15032 |   pReq->xdi_dma_descriptor_operation.info.operation =                                                IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE; | 
 | 15033 |   pReq->xdi_dma_descriptor_operation.info.descriptor_number  = nr; | 
 | 15034 |   pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; | 
 | 15035 |   pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0; | 
 | 15036 |  | 
 | 15037 |   e.user[0] = plci->adapter->Id - 1; | 
 | 15038 |   plci->adapter->request((ENTITY*)pReq); | 
 | 15039 |  | 
 | 15040 |   if (!pReq->xdi_dma_descriptor_operation.info.operation) { | 
 | 15041 |     dbug(1,dprintf("dma_free(%d)", nr)); | 
 | 15042 |   } else { | 
 | 15043 |     dbug(1,dprintf("dma_free failed (%d)", nr)); | 
 | 15044 |   } | 
 | 15045 | } | 
 | 15046 |  | 
 | 15047 | /*------------------------------------------------------------------*/ |