4 Copyright (c) Eicon Networks, 2002.
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
9 Eicon File Revision : 2.1
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)
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.
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.
41 #define FILE_ "MESSAGE.C"
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;
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
66 CAPI can request to process all return codes self only if:
67 protocol code supports this && xdi supports this
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))
71 /*------------------------------------------------------------------*/
72 /* local function prototypes */
73 /*------------------------------------------------------------------*/
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);
87 word api_remove_start(void);
88 void api_remove_complete(void);
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 *);
94 void callback(ENTITY *);
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);
104 static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms);
106 static void nl_ind(PLCI *);
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 *);
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);
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);
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);
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);
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);
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);
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);
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);
221 static int diva_get_dma_descriptor (PLCI *plci, dword *dma_magic);
222 static void diva_free_dma_descriptor (PLCI *plci, int nr);
224 /*------------------------------------------------------------------*/
225 /* external function prototypes */
226 /*------------------------------------------------------------------*/
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)))
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);
239 int fax_head_line_time (char *buffer);
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;
256 static byte remove_started = FALSE;
257 static PLCI dummy_plci;
260 static struct _ftable {
263 byte (* function)(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
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}
293 static byte * cip_bc[29][2] = {
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 */
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 */
326 static byte * cip_hlc[29] = {
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 */
359 /*------------------------------------------------------------------*/
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)
368 static byte v120_default_header[] =
371 0x83 /* Ext, BR , res, res, C2 , C1 , B , F */
375 static byte v120_break_header[] =
378 0xc3 | V120_HEADER_BREAK_BIT /* Ext, BR , res, res, C2 , C1 , B , F */
383 /*------------------------------------------------------------------*/
384 /* API_PUT function */
385 /*------------------------------------------------------------------*/
387 word api_put(APPL * appl, CAPI_MSG * msg)
393 DIVA_CAPI_ADAPTER * a;
398 API_PARSE msg_parms[MAX_MSG_PARMS+1];
400 if (msg->header.length < sizeof (msg->header) ||
401 msg->header.length > MAX_MSG_SIZE) {
402 dbug(1,dprintf("bad len"));
406 controller = (byte)((msg->header.controller &0x7f)-1);
408 /* controller starts with 0 up to (max_adapter - 1) */
409 if ( controller >= max_adapter )
411 dbug(1,dprintf("invalid ctrl"));
415 a = &adapter[controller];
417 if ((msg->header.plci != 0) && (msg->header.plci <= a->max_plci) && !a->adapter_disabled)
419 dbug(1,dprintf("plci=%x",msg->header.plci));
420 plci = &a->plci[msg->header.plci-1];
421 ncci = GET_WORD(&msg->header.ncci);
424 || (plci->State == INC_CON_PENDING)
425 || (plci->State == INC_CON_ALERT)
426 || (msg->header.command == (_DISCONNECT_I|RESPONSE)))
428 || (msg->header.command == (_DISCONNECT_B3_I|RESPONSE))
429 || ((ncci < MAX_NCCI+1) && (a->ncci_plci[ncci] == plci->Id))))
431 i = plci->msg_in_read_pos;
432 j = plci->msg_in_write_pos;
435 if (j + msg->header.length + MSG_IN_OVERHEAD <= MSG_IN_QUEUE_SIZE)
436 i += MSG_IN_QUEUE_SIZE - j;
443 n = (((CAPI_MSG *)(plci->msg_in_queue))->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc;
445 if (i > MSG_IN_QUEUE_SIZE - n)
446 i = MSG_IN_QUEUE_SIZE - n + 1;
450 if (i <= ((msg->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc))
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));
460 if ((((byte *) msg) < ((byte *)(plci->msg_in_queue)))
461 || (((byte *) msg) >= ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
463 if (plci->msg_in_write_pos != plci->msg_in_read_pos)
466 if (msg->header.command == _DATA_B3_R)
468 if (msg->header.length < 20)
470 dbug(1,dprintf("DATA_B3 REQ wrong length %d", msg->header.length));
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)
479 if (k == plci->msg_in_wrap_pos)
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))
485 if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->info.data_b3_req.Flags & 0x0004)
489 k += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.length +
490 MSG_IN_OVERHEAD + 3) & 0xfffc;
493 if ((n >= MAX_DATA_B3) || (l >= MAX_DATA_ACK))
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));
500 if (plci->req_in || plci->internal_command)
502 if ((((byte *) msg) >= ((byte *)(plci->msg_in_queue)))
503 && (((byte *) msg) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
505 dbug(0,dprintf("Q-FULL3(requeue)"));
514 if (plci->req_in || plci->internal_command)
518 plci->command = msg->header.command;
519 plci->number = msg->header.number;
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));
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)
536 m->info.data_b3_req.Data = (dword)(TransmitBufferSet (appl, m->info.data_b3_req.Data));
540 j = (j + 3) & 0xfffc;
542 *((APPL * *)(&((byte *)(plci->msg_in_queue))[j])) = appl;
543 plci->msg_in_write_pos = j + MSG_IN_OVERHEAD;
552 dbug(1,dprintf("com=%x",msg->header.command));
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));
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)) {
566 for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0;
570 dbug(1,dprintf("BAD_MSG"));
571 if(plci) plci->command = 0;
576 c = ftable[i].function(GET_DWORD(&msg->header.controller),
583 channel_xmit_extended_xon (plci);
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;
592 /*------------------------------------------------------------------*/
593 /* api_parse function, check the format of api messages */
594 /*------------------------------------------------------------------*/
596 word api_parse(byte * msg, word length, byte * format, API_PARSE * parms)
601 for(i=0,p=0; format[i]; i++) {
604 parms[i].info = &msg[p];
619 parms[i].length = msg[p+1] + (msg[p+2]<<8);
620 p +=(parms[i].length +3);
623 parms[i].length = msg[p];
624 p +=(parms[i].length +1);
629 if(p>length) return TRUE;
631 if(parms) parms[i].info = NULL;
635 void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out)
641 for (i = 0; format[i] != '\0'; i++)
643 out->parms[i].info = p;
644 out->parms[i].length = in[i].length;
657 n = in[i].length + 1;
660 for (j = 0; j < n; j++)
661 *(p++) = in[i].info[j];
663 out->parms[i].info = NULL;
664 out->parms[i].length = 0;
667 void api_load_msg(API_SAVE *in, API_PARSE *out)
674 out[i].info = in->parms[i].info;
675 out[i].length = in->parms[i].length;
676 } while (in->parms[i++].info);
680 /*------------------------------------------------------------------*/
681 /* CAPI remove function */
682 /*------------------------------------------------------------------*/
684 word api_remove_start(void)
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]);
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;
709 api_remove_complete();
714 /*------------------------------------------------------------------*/
715 /* internal command queue */
716 /*------------------------------------------------------------------*/
718 static void init_internal_command_queue (PLCI *plci)
722 dbug (1, dprintf ("%s,%d: init_internal_command_queue",
723 (char *)(FILE_), __LINE__));
725 plci->internal_command = 0;
726 for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS; i++)
727 plci->internal_command_queue[i] = NULL;
731 static void start_internal_command (dword Id, PLCI *plci, t_std_internal_command command_function)
735 dbug (1, dprintf ("[%06lx] %s,%d: start_internal_command",
736 UnMapId (Id), (char *)(FILE_), __LINE__));
738 if (plci->internal_command == 0)
740 plci->internal_command_queue[0] = command_function;
741 (* command_function)(Id, plci, OK);
746 while (plci->internal_command_queue[i] != 0)
748 plci->internal_command_queue[i] = command_function;
753 static void next_internal_command (dword Id, PLCI *plci)
757 dbug (1, dprintf ("[%06lx] %s,%d: next_internal_command",
758 UnMapId (Id), (char *)(FILE_), __LINE__));
760 plci->internal_command = 0;
761 plci->internal_command_queue[0] = NULL;
762 while (plci->internal_command_queue[1] != 0)
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)
770 plci->internal_command_queue[0] = NULL;
775 /*------------------------------------------------------------------*/
776 /* NCCI allocate/remove function */
777 /*------------------------------------------------------------------*/
779 static dword ncci_mapping_bug = 0;
781 static word get_ncci (PLCI *plci, byte ch, word force_ncci)
783 DIVA_CAPI_ADAPTER *a;
787 if (!ch || a->ch_ncci[ch])
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]));
800 if ((ch < MAX_NCCI+1) && !a->ncci_ch[ch])
805 while ((ncci < MAX_NCCI+1) && a->ncci_ch[ncci])
807 if (ncci == MAX_NCCI+1)
814 while ((j < MAX_NCCI+1) && (a->ncci_ch[j] != i))
822 } while ((j < MAX_NCCI+1) && (a->ncci_ch[j] != i));
824 } while ((i < MAX_NL_CHANNEL+1) && (j < MAX_NCCI+1));
825 if (i < MAX_NL_CHANNEL+1)
827 dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x",
828 ncci_mapping_bug, ch, force_ncci, i, k, j));
832 dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x",
833 ncci_mapping_bug, ch, force_ncci));
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;
843 a->ncci_next[ncci] = a->ncci_next[plci->ncci_ring_list];
844 a->ncci_next[plci->ncci_ring_list] = (byte) ncci;
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));
855 static void ncci_free_receive_buffers (PLCI *plci, word ncci)
857 DIVA_CAPI_ADAPTER *a;
863 Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
866 if (a->ncci_plci[ncci] == plci->Id)
871 dbug(1,dprintf("NCCI mapping appl expected %ld %08lx",
872 ncci_mapping_bug, Id));
877 ncci_code = ncci | (((word) a->Id) << 8);
878 for (i = 0; i < appl->MaxBuffer; i++)
880 if ((appl->DataNCCI[i] == ncci_code)
881 && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
883 appl->DataNCCI[i] = 0;
891 for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
893 if (a->ncci_plci[ncci] == plci->Id)
898 dbug(1,dprintf("NCCI mapping no appl %ld %08lx",
899 ncci_mapping_bug, Id));
904 ncci_code = ncci | (((word) a->Id) << 8);
905 for (i = 0; i < appl->MaxBuffer; i++)
907 if ((appl->DataNCCI[i] == ncci_code)
908 && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
910 appl->DataNCCI[i] = 0;
920 static void cleanup_ncci_data (PLCI *plci, word ncci)
924 if (ncci && (plci->adapter->ncci_plci[ncci] == plci->Id))
926 ncci_ptr = &(plci->adapter->ncci[ncci]);
929 while (ncci_ptr->data_pending != 0)
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)--;
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;
947 static void ncci_remove (PLCI *plci, word ncci, byte preserve_ncci)
949 DIVA_CAPI_ADAPTER *a;
954 Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
956 ncci_free_receive_buffers (plci, ncci);
959 if (a->ncci_plci[ncci] != plci->Id)
962 dbug(1,dprintf("NCCI mapping doesn't exist %ld %08lx %02x",
963 ncci_mapping_bug, Id, preserve_ncci));
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;
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))
979 if ((i != 0) && (a->ncci_next[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];
987 a->ncci_next[ncci] = 0;
993 for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
995 if (a->ncci_plci[ncci] == plci->Id)
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;
1003 a->ncci_ch[ncci] = 0;
1004 a->ncci_plci[ncci] = 0;
1005 a->ncci_state[ncci] = IDLE;
1006 a->ncci_next[ncci] = 0;
1011 plci->ncci_ring_list = 0;
1016 /*------------------------------------------------------------------*/
1017 /* PLCI remove function */
1018 /*------------------------------------------------------------------*/
1020 static void plci_free_msg_in_queue (PLCI *plci)
1026 i = plci->msg_in_read_pos;
1027 while (i != plci->msg_in_write_pos)
1029 if (i == plci->msg_in_wrap_pos)
1031 if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.command == _DATA_B3_R)
1034 TransmitBufferFree (plci->appl,
1035 (byte *)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
1039 i += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.length +
1040 MSG_IN_OVERHEAD + 3) & 0xfffc;
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;
1050 static void plci_remove(PLCI * plci)
1054 dbug(1,dprintf("plci_remove(no plci)"));
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))
1063 if (plci->Sig.Id == 0xff)
1065 dbug(1,dprintf("D-channel X.25 plci->NL.Id:%0x", plci->NL.Id));
1066 if (plci->NL.Id && !plci->nl_remove_id)
1068 nl_req_ncci(plci,REMOVE,0);
1074 if (!plci->sig_remove_id
1076 || (plci->req_in!=plci->req_out)
1077 || (plci->nl_req || plci->sig_req)))
1079 sig_req(plci,HANGUP,0);
1083 ncci_remove (plci, 0, FALSE);
1084 plci_free_msg_in_queue (plci);
1088 if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT))
1089 plci->State = OUTG_DIS_PENDING;
1092 /*------------------------------------------------------------------*/
1093 /* Application Group function helpers */
1094 /*------------------------------------------------------------------*/
1096 static void set_group_ind_mask (PLCI *plci)
1100 for (i = 0; i < C_IND_MASK_DWORDS; i++)
1101 plci->group_optimization_mask_table[i] = 0xffffffffL;
1104 static void clear_group_ind_mask_bit (PLCI *plci, word b)
1106 plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
1109 static byte test_group_ind_mask_bit (PLCI *plci, word b)
1111 return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
1114 /*------------------------------------------------------------------*/
1115 /* c_ind_mask operations for arbitrary MAX_APPL */
1116 /*------------------------------------------------------------------*/
1118 static void clear_c_ind_mask (PLCI *plci)
1122 for (i = 0; i < C_IND_MASK_DWORDS; i++)
1123 plci->c_ind_mask_table[i] = 0;
1126 static byte c_ind_mask_empty (PLCI *plci)
1131 while ((i < C_IND_MASK_DWORDS) && (plci->c_ind_mask_table[i] == 0))
1133 return (i == C_IND_MASK_DWORDS);
1136 static void set_c_ind_mask_bit (PLCI *plci, word b)
1138 plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f));
1141 static void clear_c_ind_mask_bit (PLCI *plci, word b)
1143 plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
1146 static byte test_c_ind_mask_bit (PLCI *plci, word b)
1148 return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
1151 static void dump_c_ind_mask (PLCI *plci)
1153 static char hex_digit_table[0x10] =
1154 {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
1160 for (i = 0; i < C_IND_MASK_DWORDS; i += 4)
1164 for (j = 0; j < 4; j++)
1166 if (i+j < C_IND_MASK_DWORDS)
1168 d = plci->c_ind_mask_table[i+j];
1169 for (k = 0; k < 8; k++)
1171 *(--p) = hex_digit_table[d & 0xf];
1177 for (k = 0; k < 8; k++)
1182 dbug(1,dprintf ("c_ind_mask =%s", (char *) p));
1190 #define dump_plcis(a)
1194 /*------------------------------------------------------------------*/
1195 /* translation function for each message */
1196 /*------------------------------------------------------------------*/
1198 byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
1207 API_PARSE ai_parms[5];
1211 static byte esc_chi[35] = {0x02,0x18,0x01};
1212 static byte lli[2] = {0x01,0x00};
1217 for(i=0;i<5;i++) ai_parms[i].length = 0;
1219 dbug(1,dprintf("connect_req(%d)",parms->length));
1220 Info = _WRONG_IDENTIFIER;
1223 if(a->adapter_disabled)
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);
1231 Info = _OUT_OF_PLCI;
1235 plci = &a->plci[i-1];
1237 plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
1238 /* check 'external controller' bit for codec support */
1239 if(Id & EXT_CONTROLLER)
1241 if(AdvCodecSupport(a, plci, appl, 0) )
1244 sendf(appl, _CONNECT_R|CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER);
1251 if(bp->length)LinkLayer = bp->info[3];
1256 if(!api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms))
1259 if(ai_parms[0].length)
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 */
1265 /* check length of B-CH struct */
1266 if((ai_parms[0].info)[3]>=1)
1268 if((ai_parms[0].info)[4]==CHI)
1270 p_chi = &((ai_parms[0].info)[5]);
1274 p_chi = &((ai_parms[0].info)[3]);
1276 if(p_chi[0]>35) /* check length of channel ID */
1278 Info = _WRONG_MESSAGE_FORMAT;
1281 else Info = _WRONG_MESSAGE_FORMAT;
1284 if(ch==3 && ai_parms[0].length>=7 && ai_parms[0].length<=36)
1286 dir = GET_WORD(ai_parms[0].info+3);
1289 for(i=0; i+5<=ai_parms[0].length; i++)
1291 if(ai_parms[0].info[i+5]!=0)
1293 if((ai_parms[0].info[i+5] | m) != 0xff)
1294 Info = _WRONG_MESSAGE_FORMAT;
1305 Info = _WRONG_MESSAGE_FORMAT;
1308 if ((ai_parms[0].length == 36) || (ch_mask != ((dword)(1L << channel))))
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];
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 */
1326 else Info = _WRONG_MESSAGE_FORMAT;
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)
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)
1348 /* early B3 connect (CIP mask bit 9) no release after a disc */
1349 add_p(plci,LLI,"\x01\x01");
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)]);
1355 add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30");
1356 sig_req(plci,ASSIGN,DSIG_ID);
1360 /* D-Channel used for B3 connections */
1361 plci->Sig.Id = 0xff;
1365 if(!Info && ch!=2 && !noCh ) {
1366 Info = add_b23(plci,&parms[5]);
1368 if(!(plci->tel && !plci->adv_nl))nl_req_ncci(plci,ASSIGN,0);
1374 if(ch==0 || ch==2 || ch==3 || noCh || ch==4)
1376 if(plci->spoofed_msg==SPOOFING_REQUIRED)
1378 api_save_msg(parms, "wsssssssss", &plci->saved_msg);
1379 plci->spoofed_msg = CALL_REQ;
1380 plci->internal_command = BLOCK_PLCI;
1382 dbug(1,dprintf("Spoof"));
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);
1394 plci->command = PERM_LIST_REQ;
1396 sig_req(plci,LISTEN_REQ,0);
1415 byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
1419 static byte cau_t[] = {0,0,0x90,0x91,0xac,0x9d,0x86,0xd8,0x9b};
1420 static byte esc_t[] = {0x03,0x08,0x00,0x00};
1422 API_PARSE ai_parms[5];
1426 dbug(1,dprintf("connect_res(no plci)"));
1427 return 0; /* no plci, no send */
1430 dbug(1,dprintf("connect_res(State=0x%x)",plci->State));
1431 for(i=0;i<5;i++) ai_parms[i].length = 0;
1433 dbug(1,dprintf("ai->length=%d",ai->length));
1437 if(!api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms))
1439 dbug(1,dprintf("ai_parms[0].length=%d/0x%x",ai_parms[0].length,GET_WORD(ai_parms[0].info+1)));
1441 if(ai_parms[0].length)
1443 ch = GET_WORD(ai_parms[0].info+1);
1444 dbug(1,dprintf("BCH-I=0x%x",ch));
1449 if(plci->State==INC_CON_CONNECTED_ALERT)
1451 dbug(1,dprintf("Connected Alert Call_Res"));
1452 if (a->Info_Mask[appl->Id-1] & 0x200)
1454 /* early B3 connect (CIP mask bit 9) no release after a disc */
1455 add_p(plci,LLI,"\x01\x01");
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);
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));
1471 if(c_ind_mask_empty (plci))
1473 if((Reject&0xff00)==0x3400)
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);
1480 else if(Reject==1 || Reject>9)
1482 add_ai(plci, &parms[5]);
1483 sig_req(plci,HANGUP,0);
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);
1496 sendf(appl, _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
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);
1507 if(plci->tel == ADV_VOICE && a->AdvCodecPLCI)
1509 Info = add_b23(plci, &parms[1]);
1512 dbug(1,dprintf("connect_res(error from add_b23)"));
1513 sig_req(plci,HANGUP,0);
1518 nl_req_ncci(plci, ASSIGN, 0);
1527 Info = add_b23(plci, &parms[1]);
1530 dbug(1,dprintf("connect_res(error from add_b23 2)"));
1531 sig_req(plci,HANGUP,0);
1535 nl_req_ncci(plci, ASSIGN, 0);
1538 if(plci->spoofed_msg==SPOOFING_REQUIRED)
1540 api_save_msg(parms, "wsssss", &plci->saved_msg);
1541 plci->spoofed_msg = CALL_RES;
1542 plci->internal_command = BLOCK_PLCI;
1544 dbug(1,dprintf("Spoof"));
1548 add_b1 (plci, &parms[1], ch, plci->B1_facilities);
1549 if (a->Info_Mask[appl->Id-1] & 0x200)
1551 /* early B3 connect (CIP mask bit 9) no release after a disc */
1552 add_p(plci,LLI,"\x01\x01");
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);
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);
1571 byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
1573 dbug(1,dprintf("connect_a_res"));
1577 byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
1582 dbug(1,dprintf("disconnect_req"));
1584 Info = _WRONG_IDENTIFIER;
1588 if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT)
1590 clear_c_ind_mask_bit (plci, (word)(appl->Id-1));
1592 for(i=0; i<max_appl; i++)
1594 if(test_c_ind_mask_bit (plci, i))
1595 sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
1597 plci->State = OUTG_DIS_PENDING;
1599 if(plci->Sig.Id && plci->appl)
1602 if(plci->Sig.Id!=0xff)
1604 if(plci->State!=INC_DIS_PENDING)
1606 add_ai(plci, &msg[0]);
1607 sig_req(plci,HANGUP,0);
1608 plci->State = OUTG_DIS_PENDING;
1614 if (plci->NL.Id && !plci->nl_remove_id)
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;
1627 if(!appl) return FALSE;
1628 sendf(appl, _DISCONNECT_R|CONFIRM, Id, Number, "w",Info);
1632 byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
1634 dbug(1,dprintf("disconnect_res"));
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))
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) {
1659 byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
1664 dbug(1,dprintf("listen_req(Appl=0x%x)",appl->Id));
1666 Info = _WRONG_IDENTIFIER;
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 */
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];
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];
1692 else Info = 0x2002; /* wrong controller, codec not supported */
1694 else{ /* clear listen */
1695 a->codec_listen[appl->Id-1] = (PLCI *)0;
1704 if (a) listen_check(a);
1708 byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
1712 PLCI * rc_plci = NULL;
1713 API_PARSE ai_parms[5];
1716 dbug(1,dprintf("info_req"));
1717 for(i=0;i<5;i++) ai_parms[i].length = 0;
1723 if(api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms))
1725 dbug(1,dprintf("AddInfo wrong"));
1726 Info = _WRONG_MESSAGE_FORMAT;
1729 if(!a) Info = _WRONG_STATE;
1732 { /* no fac, with CPN, or KEY */
1734 if(!ai_parms[3].length && plci->State && (msg[0].length || ai_parms[1].length) )
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);
1745 if(plci->State && ai_parms[2].length)
1747 /* User_Info option */
1748 dbug(1,dprintf("UUI"));
1749 add_s(plci,UUI,&ai_parms[2]);
1750 sig_req(plci,USER_DATA,0);
1752 else if(plci->State && ai_parms[3].length)
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);
1762 Info = _WRONG_STATE;
1765 else if((ai_parms[1].length || ai_parms[2].length || ai_parms[3].length) && !Info)
1767 /* NCR_Facility option -> send UUI and Keypad too */
1768 dbug(1,dprintf("NCR_FAC"));
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);
1782 Info = _OUT_OF_PLCI;
1787 add_s(rc_plci,CPN,&msg[0]);
1788 add_ai(rc_plci, &msg[1]);
1789 sig_req(rc_plci,NCR_FACILITY,0);
1792 /* for application controlled supplementary services */
1798 Info = _WRONG_MESSAGE_FORMAT;
1806 { /* appl is not assigned to a PLCI or error condition */
1807 dbug(1,dprintf("localInfoCon"));
1817 byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
1819 dbug(1,dprintf("info_res"));
1823 byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
1828 dbug(1,dprintf("alert_req"));
1830 Info = _WRONG_IDENTIFIER;
1833 Info = _ALERT_IGNORED;
1834 if(plci->State!=INC_CON_ALERT) {
1835 Info = _WRONG_STATE;
1836 if(plci->State==INC_CON_PENDING) {
1838 plci->State=INC_CON_ALERT;
1839 add_ai(plci, &msg[0]);
1840 sig_req(plci,CALL_ALERT,0);
1853 byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
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";
1866 API_PARSE ss_parms[11];
1872 dbug(1,dprintf("facility_req"));
1873 for(i=0;i<9;i++) ss_parms[i].length = 0;
1879 dbug(1,dprintf("wrong Ctrl"));
1880 Info = _WRONG_IDENTIFIER;
1883 selector = GET_WORD(msg[0].info);
1889 case SELECTOR_HANDSET:
1890 Info = AdvCodecSupport(a, plci, appl, HOOK_SUPPORT);
1893 case SELECTOR_SU_SERV:
1896 Info = _WRONG_MESSAGE_FORMAT;
1899 SSreq = GET_WORD(&(msg[1].info[1]));
1900 PUT_WORD(&RCparms[1],SSreq);
1904 case S_GET_SUPPORTED_SERVICES:
1907 rplci = &a->plci[i-1];
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);
1916 PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
1917 SSparms = (byte *)SSstruct;
1920 rplci->internal_command = GETSERV_REQ_PEND;
1921 rplci->number = Number;
1923 sig_req(rplci,S_SUPPORTED,0);
1929 if(parms->length==7)
1931 if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms))
1933 dbug(1,dprintf("format wrong"));
1934 Info = _WRONG_MESSAGE_FORMAT;
1940 Info = _WRONG_MESSAGE_FORMAT;
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? */
1948 rplci = &a->plci[i-1];
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);
1959 rplci->internal_command = GET_MWI_STATE;
1960 rplci->number = Number;
1961 sig_req(rplci,MWI_POLL,0);
1967 api_parse(&parms->info[1],(word)parms->length,"ws",ss_parms);
1968 if(plci && plci->State && plci->SuppState==IDLE)
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);
1977 else Info = 0x3010; /* wrong state */
1980 if(plci && plci->State && plci->SuppState==CALL_HELD)
1982 if(Id & EXT_CONTROLLER)
1984 if(AdvCodecSupport(a, plci, appl, 0))
1986 Info = 0x3010; /* wrong state */
1992 plci->SuppState = RETRIEVE_REQUEST;
1993 plci->command = C_RETRIEVE_REQ;
1994 if(plci->spoofed_msg==SPOOFING_REQUIRED)
1996 plci->spoofed_msg = CALL_RETRIEVE;
1997 plci->internal_command = BLOCK_PLCI;
1999 dbug(1,dprintf("Spoof"));
2004 sig_req(plci,CALL_RETRIEVE,0);
2009 else Info = 0x3010; /* wrong state */
2014 if(api_parse(&parms->info[1],(word)parms->length,"wbs",ss_parms))
2016 dbug(1,dprintf("format wrong"));
2017 Info = _WRONG_MESSAGE_FORMAT;
2021 if(plci && plci->State)
2023 add_s(plci,CAI,&ss_parms[2]);
2024 plci->command = SUSPEND_REQ;
2025 sig_req(plci,SUSPEND,0);
2026 plci->State = SUSPENDING;
2029 else Info = 0x3010; /* wrong state */
2033 if(!(i=get_plci(a)) )
2035 Info = _OUT_OF_PLCI;
2038 rplci = &a->plci[i-1];
2040 rplci->number = Number;
2042 rplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
2043 /* check 'external controller' bit for codec support */
2044 if(Id & EXT_CONTROLLER)
2046 if(AdvCodecSupport(a, rplci, appl, 0) )
2055 if(api_parse(&parms->info[1],(word)parms->length,"wbs",ss_parms))
2057 dbug(1,dprintf("format wrong"));
2059 Info = _WRONG_MESSAGE_FORMAT;
2064 dummy.info = "\x00";
2065 add_b1(rplci, &dummy, 0, 0);
2066 if (a->Info_Mask[appl->Id-1] & 0x200)
2068 /* early B3 connect (CIP mask bit 9) no release after a disc */
2069 add_p(rplci,LLI,"\x01\x01");
2071 add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
2072 sig_req(rplci,ASSIGN,DSIG_ID);
2074 add_s(rplci,CAI,&ss_parms[2]);
2075 rplci->command = RESUME_REQ;
2076 sig_req(rplci,RESUME,0);
2077 rplci->State = RESUMING;
2081 case S_CONF_BEGIN: /* Request */
2083 case S_CONF_ISOLATE:
2084 case S_CONF_REATTACH:
2085 if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms))
2087 dbug(1,dprintf("format wrong"));
2088 Info = _WRONG_MESSAGE_FORMAT;
2091 if(plci && plci->State && ((plci->SuppState==IDLE)||(plci->SuppState==CALL_HELD)))
2093 d = GET_DWORD(ss_parms[2].info);
2096 dbug(1,dprintf("format wrong"));
2097 Info = _WRONG_MESSAGE_FORMAT;
2100 plci->ptyState = (byte)SSreq;
2106 cai[1] = CONF_BEGIN;
2107 plci->internal_command = CONF_BEGIN_REQ_PEND;
2111 plci->internal_command = CONF_DROP_REQ_PEND;
2113 case S_CONF_ISOLATE:
2114 cai[1] = CONF_ISOLATE;
2115 plci->internal_command = CONF_ISOLATE_REQ_PEND;
2117 case S_CONF_REATTACH:
2118 cai[1] = CONF_REATTACH;
2119 plci->internal_command = CONF_REATTACH_REQ_PEND;
2122 cai[2] = (byte)d; /* Conference Size resp. PartyId */
2123 add_p(plci,CAI,cai);
2124 sig_req(plci,S_SERVICE,0);
2128 else Info = 0x3010; /* wrong state */
2135 if(parms->length==7)
2137 if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms))
2139 dbug(1,dprintf("format wrong"));
2140 Info = _WRONG_MESSAGE_FORMAT;
2144 else if(parms->length==8) /* workaround for the T-View-S */
2146 if(api_parse(&parms->info[1],(word)parms->length,"wbdb",ss_parms))
2148 dbug(1,dprintf("format wrong"));
2149 Info = _WRONG_MESSAGE_FORMAT;
2155 Info = _WRONG_MESSAGE_FORMAT;
2160 Info = _WRONG_MESSAGE_FORMAT;
2165 Info = _WRONG_IDENTIFIER;
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))
2176 if(SSreq==S_3PTY_END)
2178 dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI"));
2183 Info = 0x3010; /* wrong state */
2189 relatedadapter = &adapter[MapController ((byte)(relatedPLCIvalue & 0x7f))-1];
2190 relatedPLCIvalue >>=8;
2192 for(i=0,rplci=NULL;i<relatedadapter->max_plci;i++)
2194 if(relatedadapter->plci[i].Id == (byte)relatedPLCIvalue)
2196 rplci = &relatedadapter->plci[i];
2199 if(!rplci || !relatedPLCIvalue)
2201 if(SSreq==S_3PTY_END)
2203 dbug(1, dprintf("use 2nd PLCI=PLCI"));
2208 Info = 0x3010; /* wrong state */
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));
2223 /* send PTY/ECT req, cannot check all states because of US stuff */
2224 if( !rplci->internal_command && rplci->appl )
2227 rplci->relatedPTYPLCI = plci;
2228 plci->relatedPTYPLCI = rplci;
2229 rplci->ptyState = (byte)SSreq;
2232 rplci->internal_command = ECT_REQ_PEND;
2233 cai[1] = ECT_EXECUTE;
2235 rplci->vswitchstate=0;
2237 rplci->vsprotdialect=0;
2238 plci->vswitchstate=0;
2240 plci->vsprotdialect=0;
2243 else if(SSreq==S_CONF_ADD)
2245 rplci->internal_command = CONF_ADD_REQ_PEND;
2250 rplci->internal_command = PTY_REQ_PEND;
2251 cai[1] = (byte)(SSreq-3);
2253 rplci->number = Number;
2254 if(plci!=rplci) /* explicit invocation */
2257 cai[2] = plci->Sig.Id;
2258 dbug(1,dprintf("explicit invocation"));
2262 dbug(1,dprintf("implicit invocation"));
2265 add_p(rplci,CAI,cai);
2266 sig_req(rplci,S_SERVICE,0);
2272 dbug(0,dprintf("Wrong line"));
2273 Info = 0x3010; /* wrong state */
2278 case S_CALL_DEFLECTION:
2279 if(api_parse(&parms->info[1],(word)parms->length,"wbwss",ss_parms))
2281 dbug(1,dprintf("format wrong"));
2282 Info = _WRONG_MESSAGE_FORMAT;
2287 Info = _WRONG_IDENTIFIER;
2290 /* reuse unused screening indicator */
2291 ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0]));
2293 plci->internal_command = CD_REQ_PEND;
2294 appl->CDEnable = TRUE;
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);
2304 case S_CALL_FORWARDING_START:
2305 if(api_parse(&parms->info[1],(word)parms->length,"wbdwwsss",ss_parms))
2307 dbug(1,dprintf("format wrong"));
2308 Info = _WRONG_MESSAGE_FORMAT;
2314 rplci = &a->plci[i-1];
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);
2323 Info = _OUT_OF_PLCI;
2327 /* reuse unused screening indicator */
2328 rplci->internal_command = CF_START_PEND;
2330 rplci->number = Number;
2331 appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
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);
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:
2351 case S_INTERROGATE_NUMBERS:
2352 if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms))
2354 dbug(0,dprintf("format wrong"));
2355 Info = _WRONG_MESSAGE_FORMAT;
2358 case S_CCBS_REQUEST:
2359 case S_CCBS_DEACTIVATE:
2360 if(api_parse(&parms->info[1],(word)parms->length,"wbdw",ss_parms))
2362 dbug(0,dprintf("format wrong"));
2363 Info = _WRONG_MESSAGE_FORMAT;
2366 case S_CCBS_INTERROGATE:
2367 if(api_parse(&parms->info[1],(word)parms->length,"wbdws",ss_parms))
2369 dbug(0,dprintf("format wrong"));
2370 Info = _WRONG_MESSAGE_FORMAT;
2374 if(api_parse(&parms->info[1],(word)parms->length,"wbdwws",ss_parms))
2376 dbug(0,dprintf("format wrong"));
2377 Info = _WRONG_MESSAGE_FORMAT;
2386 rplci = &a->plci[i-1];
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 */
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 */
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 */
2401 case S_CCBS_REQUEST:
2402 cai[1] = CCBS_REQUEST;
2403 rplci->internal_command = CCBS_REQUEST_REQ_PEND;
2405 case S_CCBS_DEACTIVATE:
2406 cai[1] = CCBS_DEACTIVATE;
2407 rplci->internal_command = CCBS_DEACTIVATE_REQ_PEND;
2409 case S_CCBS_INTERROGATE:
2410 cai[1] = CCBS_INTERROGATE;
2411 rplci->internal_command = CCBS_INTERROGATE_REQ_PEND;
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);
2426 Info = _OUT_OF_PLCI;
2430 appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
2433 case S_INTERROGATE_NUMBERS:
2435 add_p(rplci,CAI,cai);
2437 case S_CCBS_REQUEST:
2438 case S_CCBS_DEACTIVATE:
2440 PUT_WORD(&cai[2],GET_WORD(&(ss_parms[3].info[0])));
2441 add_p(rplci,CAI,cai);
2443 case S_CCBS_INTERROGATE:
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);
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);
2457 sig_req(rplci,S_SERVICE,0);
2462 case S_MWI_ACTIVATE:
2463 if(api_parse(&parms->info[1],(word)parms->length,"wbwdwwwssss",ss_parms))
2465 dbug(1,dprintf("format wrong"));
2466 Info = _WRONG_MESSAGE_FORMAT;
2473 rplci = &a->plci[i-1];
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);
2483 Info = _OUT_OF_PLCI;
2490 rplci->cr_enquiry=FALSE;
2494 rplci->internal_command = MWI_ACTIVATE_REQ_PEND;
2496 rplci->number = Number;
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);
2514 case S_MWI_DEACTIVATE:
2515 if(api_parse(&parms->info[1],(word)parms->length,"wbwwss",ss_parms))
2517 dbug(1,dprintf("format wrong"));
2518 Info = _WRONG_MESSAGE_FORMAT;
2525 rplci = &a->plci[i-1];
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);
2535 Info = _OUT_OF_PLCI;
2542 rplci->cr_enquiry=FALSE;
2546 rplci->internal_command = MWI_DEACTIVATE_REQ_PEND;
2548 rplci->number = Number;
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);
2562 Info = 0x300E; /* not supported */
2565 break; /* case SELECTOR_SU_SERV: end */
2569 return (dtmf_request (Id, Number, a, plci, appl, msg));
2573 case SELECTOR_LINE_INTERCONNECT:
2574 return (mixer_request (Id, Number, a, plci, appl, msg));
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));
2582 case SELECTOR_ECHO_CANCELLER:
2583 appl->appl_flags &= ~APPL_FLAG_PRIV_EC_SPEC;
2584 return (ec_request (Id, Number, a, plci, appl, msg));
2587 case SELECTOR_V42BIS:
2589 Info = _FACILITY_NOT_SUPPORTED;
2591 } /* end of switch(selector) */
2594 dbug(1,dprintf("SendFacRc"));
2596 _FACILITY_R|CONFIRM,
2599 "wws",Info,selector,SSparms);
2603 byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
2605 dbug(1,dprintf("facility_res"));
2609 byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
2615 word fax_control_bits, fax_feature_bits, fax_info_change;
2619 API_PARSE fax_parms[9];
2623 dbug(1,dprintf("connect_b3_req"));
2626 if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING)
2627 || (plci->State == INC_DIS_PENDING) || (plci->SuppState != IDLE))
2629 Info = _WRONG_STATE;
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 */
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))))))
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;
2648 _CONNECT_B3_R|CONFIRM,
2654 plci->requested_options_conn = 0;
2658 if(plci->B3_prot==2 || plci->B3_prot==3)
2663 if(ncpi->info[2] || ncpi->info[3])
2665 pvc[0] = ncpi->info[3];
2666 pvc[1] = ncpi->info[2];
2672 if(ncpi->info[1] &1) req = N_CONNECT | N_D_BIT;
2673 add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]);
2677 else if(plci->B3_prot==5)
2679 if (plci->NL.Id && !plci->nl_remove_id)
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))
2686 len = (byte)(&(((T30_INFO *) 0)->universal_6));
2687 fax_info_change = FALSE;
2688 if (ncpi->length >= 4)
2690 w = GET_WORD(&ncpi->info[3]);
2691 if ((w & 0x0001) != ((word)(((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & 0x0001)))
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;
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))
2704 fax_control_bits |= T30_CONTROL_BIT_MORE_DOCUMENTS;
2706 if (ncpi->length >= 6)
2708 w = GET_WORD(&ncpi->info[5]);
2709 if (((byte) w) != ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format)
2711 ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format = (byte) w;
2712 fax_info_change = TRUE;
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 */
2718 plci->requested_options_conn |= (1L << PRIVATE_FAX_SUB_SEP_PWD);
2720 if ((a->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
2721 && (GET_WORD(&ncpi->info[5]) & 0x4000)) /* Private non-standard facilities enable */
2723 plci->requested_options_conn |= (1L << PRIVATE_FAX_NONSTANDARD);
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)))
2730 if (api_parse (&ncpi->info[1], ncpi->length, "wwwwsss", fax_parms))
2731 Info = _WRONG_MESSAGE_FORMAT;
2734 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1])
2735 & (1L << PRIVATE_FAX_SUB_SEP_PWD))
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;
2741 w = fax_parms[4].length;
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;
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;
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))
2764 if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
2766 dbug(1,dprintf("non-standard facilities info missing or wrong format"));
2767 plci->fax_connect_info_buffer[len++] = 0;
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];
2782 len = (byte)(&(((T30_INFO *) 0)->universal_6));
2784 fax_info_change = TRUE;
2787 if (fax_control_bits != GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low))
2789 PUT_WORD (&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits);
2790 fax_info_change = TRUE;
2795 plci->fax_connect_info_length = len;
2796 if (fax_info_change)
2798 if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
2800 start_internal_command (Id, plci, fax_connect_info_command);
2805 start_internal_command (Id, plci, fax_adjust_b23_command);
2811 else Info = _WRONG_STATE;
2813 else Info = _WRONG_STATE;
2816 else if (plci->B3_prot == B3_RTP)
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);
2828 nl_req_ncci(plci,req,0);
2833 else Info = _WRONG_IDENTIFIER;
2836 _CONNECT_B3_R|CONFIRM,
2843 byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
2852 API_PARSE fax_parms[9];
2857 dbug(1,dprintf("connect_b3_res"));
2859 ncci = (word)(Id>>16);
2861 if(a->ncci_state[ncci]==INC_CON_PENDING) {
2862 if (GET_WORD (&parms[0].info[0]) != 0)
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);
2871 a->ncci_state[ncci] = INC_ACT_PENDING;
2873 req = N_CONNECT_ACK;
2875 if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
2878 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
2879 & (1L << PRIVATE_FAX_NONSTANDARD))
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))
2885 len = ((byte)(((T30_INFO *) 0)->station_id + 20));
2886 if (plci->fax_connect_info_length < len)
2888 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
2889 ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
2891 if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
2893 dbug(1,dprintf("non-standard facilities info missing or wrong format"));
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];
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);
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))
2920 if (plci->B3_prot == 4)
2921 sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
2923 sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
2924 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
2928 else if (plci->B3_prot == B3_RTP)
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);
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]);
2944 nl_req_ncci(plci,req,(byte)ncci);
2945 sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
2946 if (plci->adjust_b_restore)
2948 plci->adjust_b_restore = FALSE;
2949 start_internal_command (Id, plci, adjust_b_restore);
2958 byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
2962 ncci = (word)(Id>>16);
2963 dbug(1,dprintf("connect_b3_a_res(ncci=0x%x)",ncci));
2965 if (plci && ncci && (plci->State != IDLE) && (plci->State != INC_DIS_PENDING)
2966 && (plci->State != OUTG_DIS_PENDING))
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);
2978 byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
2984 dbug(1,dprintf("disconnect_b3_req"));
2986 Info = _WRONG_IDENTIFIER;
2987 ncci = (word)(Id>>16);
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))
2996 a->ncci_state[ncci] = OUTG_DIS_PENDING;
2997 channel_request_xon (plci, a->ncci_ch[ncci]);
2998 channel_xmit_xon (plci);
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)))
3005 plci->send_disc = (byte)ncci;
3011 cleanup_ncci_data (plci, ncci);
3013 if(plci->B3_prot==2 || plci->B3_prot==3)
3018 add_d(plci, (word)(ncpi->length - 3) ,(byte *)&(ncpi->info[4]));
3021 nl_req_ncci(plci,N_DISC,(byte)ncci);
3027 _DISCONNECT_B3_R|CONFIRM,
3034 byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
3039 ncci = (word)(Id>>16);
3040 dbug(1,dprintf("disconnect_b3_res(ncci=0x%x",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)))
3048 plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
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;
3056 ncci_free_receive_buffers (plci, ncci);
3058 if((plci->State==IDLE || plci->State==SUSPENDING) && !plci->channels){
3059 if(plci->State == SUSPENDING){
3064 "ws", (word)3, "\x03\x04\x00\x00");
3065 sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
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))
3077 ncci_free_receive_buffers (plci, ncci);
3079 nl_req_ncci(plci,N_EDATA,(byte)ncci);
3081 plci->adapter->ncci_state[ncci] = IDLE;
3082 start_internal_command (Id, plci, fax_disconnect_command);
3090 byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
3098 dbug(1,dprintf("data_b3_req"));
3100 Info = _WRONG_IDENTIFIER;
3101 ncci = (word)(Id>>16);
3102 dbug(1,dprintf("ncci=0x%x, plci=0x%x",ncci,plci));
3106 Info = _WRONG_STATE;
3107 if ((a->ncci_state[ncci] == CONNECTED)
3108 || (a->ncci_state[ncci] == INC_ACT_PENDING))
3111 ncci_ptr = &(a->ncci[ncci]);
3112 i = ncci_ptr->data_out + ncci_ptr->data_pending;
3113 if (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)))
3121 data->P = (byte *)(*((dword *)(parms[0].info)));
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)++;
3131 /* check for delivery confirmation */
3132 if (data->Flags & 0x0004)
3134 i = ncci_ptr->data_ack_out + ncci_ptr->data_ack_pending;
3135 if (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)++;
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)))
3154 TransmitBufferFree (appl, (byte *)(*((dword *)(parms[0].info))));
3162 "ww",GET_WORD(parms[2].info),Info);
3167 byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
3173 dbug(1,dprintf("data_b3_res"));
3175 ncci = (word)(Id>>16);
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;
3186 if (channel_can_xon (plci, a->ncci_ch[ncci])) {
3187 channel_request_xon (plci, a->ncci_ch[ncci]);
3189 channel_xmit_xon (plci);
3191 if(appl->DataFlags[n] &4) {
3192 nl_req_ncci(plci,N_DATA_ACK,(byte)ncci);
3200 byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
3205 dbug(1,dprintf("reset_b3_req"));
3207 Info = _WRONG_IDENTIFIER;
3208 ncci = (word)(Id>>16);
3211 Info = _WRONG_STATE;
3212 switch (plci->B3_prot)
3216 if(a->ncci_state[ncci]==CONNECTED)
3218 nl_req_ncci(plci,N_RESET,(byte)ncci);
3223 case B3_TRANSPARENT:
3224 if(a->ncci_state[ncci]==CONNECTED)
3226 start_internal_command (Id, plci, reset_b3_command);
3232 /* reset_b3 must result in a reset_b3_con & reset_b3_Ind */
3234 _RESET_B3_R|CONFIRM,
3241 byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
3245 dbug(1,dprintf("reset_b3_res"));
3247 ncci = (word)(Id>>16);
3249 switch (plci->B3_prot)
3253 if(a->ncci_state[ncci]==INC_RES_PENDING)
3255 a->ncci_state[ncci] = CONNECTED;
3256 nl_req_ncci(plci,N_RESET_ACK,(byte)ncci);
3265 byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
3271 dbug(1,dprintf("connect_b3_t90_a_res"));
3273 ncci = (word)(Id>>16);
3275 if(a->ncci_state[ncci]==INC_ACT_PENDING) {
3276 a->ncci_state[ncci] = CONNECTED;
3278 else if(a->ncci_state[ncci]==INC_CON_PENDING) {
3279 a->ncci_state[ncci] = CONNECTED;
3281 req = N_CONNECT_ACK;
3283 /* parms[0]==0 for CAPI original message definition! */
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]);
3291 nl_req_ncci(plci,req,(byte)ncci);
3299 byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
3304 API_PARSE bp_parms[7];
3308 Info = _WRONG_IDENTIFIER;
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;
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)
3321 Info = _WRONG_STATE;
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))
3326 Info = _WRONG_MESSAGE_FORMAT;
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)
3334 sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", 0x2002); /* wrong controller */
3337 plci->State=INC_CON_CONNECTED_ALERT;
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);
3348 api_save_msg(msg, "s", &plci->saved_msg);
3350 if(Id & EXT_CONTROLLER)
3352 if(tel) /* external controller in use by this PLCI */
3354 if(a->AdvSignalAppl && a->AdvSignalAppl!=appl)
3356 dbug(1,dprintf("Ext_Ctrl in use 1"));
3357 Info = _WRONG_STATE;
3360 else /* external controller NOT in use by this PLCI ? */
3362 if(a->AdvSignalPLCI)
3364 dbug(1,dprintf("Ext_Ctrl in use 2"));
3365 Info = _WRONG_STATE;
3367 else /* activate the codec */
3369 dbug(1,dprintf("Ext_Ctrl start"));
3370 if(AdvCodecSupport(a, plci, appl, 0) )
3372 dbug(1,dprintf("Error in codec procedures"));
3373 Info = _WRONG_STATE;
3375 else if(plci->spoofed_msg==SPOOFING_REQUIRED) /* wait until codec is active */
3377 plci->spoofed_msg = AWAITING_SELECT_B;
3378 plci->internal_command = BLOCK_PLCI; /* lock other commands */
3380 dbug(1,dprintf("continue if codec loaded"));
3386 else /* external controller bit is OFF */
3388 if(tel) /* external controller in use, need to switch off */
3390 if(a->AdvSignalAppl==appl)
3392 CodecIdCheck(a, plci);
3395 dbug(1,dprintf("Ext_Ctrl disable"));
3399 dbug(1,dprintf("Ext_Ctrl not requested"));
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);
3414 sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", Info);
3418 byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
3424 API_PARSE m_parms[5];
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 };
3437 dbug(1,dprintf("manufacturer_req"));
3438 for(i=0;i<5;i++) m_parms[i].length = 0;
3440 if(GET_DWORD(parms[0].info)!=_DI_MANU_ID) {
3441 Info = _WRONG_MESSAGE_FORMAT;
3443 command = GET_WORD(parms[1].info);
3448 case _DI_ASSIGN_PLCI:
3449 if(api_parse(&m->info[1],(word)m->length,"wbbs",m_parms)) {
3450 Info = _WRONG_MESSAGE_FORMAT;
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];
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));
3466 if((ch==1 || ch==2) && (dir<=2)) {
3467 chi[1] = (byte)(0x80|ch);
3469 plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
3473 Info = add_b1(plci,&m_parms[3],0,0);
3476 add_p(plci,CAI,codec_cai);
3478 /* manual 'swich on' to the codec support without signalling */
3479 /* first 'assign plci' with this function, then use */
3481 if(AdvCodecSupport(a, plci, appl, 0) ) {
3482 Info = _RESOURCE_ERROR;
3485 Info = add_b1(plci,&null_parms,0,B1_FACILITY_LOCAL);
3486 lli[1] = 0x10; /* local call codec stream */
3491 plci->State = LOCAL_CONNECT;
3492 plci->manufacturer = TRUE;
3493 plci->command = _MANUFACTURER_R;
3494 plci->m_command = command;
3495 plci->number = Number;
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);
3506 Info = add_b23(plci,&m_parms[3]);
3509 nl_req_ncci(plci,ASSIGN,0);
3515 dbug(1,dprintf("dir=0x%x,spoof=0x%x",dir,plci->spoofed_msg));
3516 if (plci->spoofed_msg==SPOOFING_REQUIRED)
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 */
3526 sig_req(plci,CALL_REQ,0);
3529 sig_req(plci,LISTEN_REQ,0);
3536 _MANUFACTURER_R|CONFIRM,
3539 "dww",_DI_MANU_ID,command,Info);
3545 else Info = _OUT_OF_PLCI;
3551 Info = _WRONG_IDENTIFIER;
3554 if(api_parse(&m->info[1],(word)m->length,"bs",m_parms)) {
3555 Info = _WRONG_MESSAGE_FORMAT;
3558 req = m_parms[0].info[0];
3559 plci->command = _MANUFACTURER_R;
3560 plci->m_command = command;
3561 plci->number = Number;
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)
3568 plci->spoofed_msg = CALL_REQ | AWAITING_MANUF_CON;
3569 plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
3574 else if(req==LAW_REQ)
3576 plci->cr_enquiry = TRUE;
3578 add_ss(plci,FTY,&m_parms[1]);
3579 sig_req(plci,req,0);
3583 if (plci->NL.Id && !plci->nl_remove_id)
3587 for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
3589 if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED))
3591 a->ncci_state[ncci] = OUTG_DIS_PENDING;
3592 cleanup_ncci_data (plci, ncci);
3593 nl_req_ncci(plci,N_DISC,(byte)ncci);
3597 mixer_remove (plci);
3598 nl_req_ncci(plci,REMOVE,0);
3605 /* signalling control for loop activation B-channel */
3608 Info = _WRONG_IDENTIFIER;
3612 plci->command = _MANUFACTURER_R;
3613 plci->number = Number;
3615 sig_req(plci,SIG_CTRL,0);
3618 else Info = _WRONG_MESSAGE_FORMAT;
3622 /* activation control for receiver/transmitter B-channel */
3625 Info = _WRONG_IDENTIFIER;
3629 plci->command = _MANUFACTURER_R;
3630 plci->number = Number;
3632 sig_req(plci,DSP_CTRL,0);
3635 else Info = _WRONG_MESSAGE_FORMAT;
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 */
3645 if(command == _DI_ADV_CODEC)
3647 if(!a->AdvCodecPLCI) {
3648 Info = _WRONG_STATE;
3651 v_plci = a->AdvCodecPLCI;
3657 && (m->info[1] == 0x1c)
3658 && (m->info[2] >= 1))
3660 if (m->info[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS)
3662 if ((plci->tel != ADV_VOICE) || (plci != a->AdvSignalPLCI))
3664 Info = _WRONG_STATE;
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);
3678 else if (m->info[3] == DSP_CTRL_SET_DTMF_PARAMETERS)
3680 if (!(a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_PARAMETERS))
3682 Info = _FACILITY_NOT_SUPPORTED;
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);
3704 Info = _WRONG_IDENTIFIER;
3708 add_ss(v_plci,FTY,m);
3709 sig_req(v_plci,TEL_CTRL,0);
3712 else Info = _WRONG_MESSAGE_FORMAT;
3716 case _DI_OPTIONS_REQUEST:
3717 if(api_parse(&m->info[1],(word)m->length,"d",m_parms)) {
3718 Info = _WRONG_MESSAGE_FORMAT;
3721 if (GET_DWORD (m_parms[0].info) & ~a->man_profile.private_options)
3723 Info = _FACILITY_NOT_SUPPORTED;
3726 a->requested_options_table[appl->Id-1] = GET_DWORD (m_parms[0].info);
3732 Info = _WRONG_MESSAGE_FORMAT;
3738 _MANUFACTURER_R|CONFIRM,
3741 "dww",_DI_MANU_ID,command,Info);
3746 byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
3750 API_PARSE m_parms[3];
3752 API_PARSE fax_parms[9];
3757 dbug(1,dprintf("manufacturer_res"));
3759 if ((msg[0].length == 0)
3760 || (msg[1].length == 0)
3761 || (GET_DWORD(msg[0].info)!=_DI_MANU_ID))
3765 indication = GET_WORD(msg[1].info);
3769 case _DI_NEGOTIATE_B3:
3772 if (((plci->B3_prot != 4) && (plci->B3_prot != 5))
3773 || !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
3775 dbug(1,dprintf("wrong state for NEGOTIATE_B3 parameters"));
3778 if (api_parse (&msg[2].info[1], msg[2].length, "ws", m_parms))
3780 dbug(1,dprintf("wrong format in NEGOTIATE_B3 parameters"));
3784 len = ((byte)(((T30_INFO *) 0)->station_id + 20));
3785 if (plci->fax_connect_info_length < len)
3787 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
3788 ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
3790 if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
3792 dbug(1,dprintf("non-standard facilities info missing or wrong format"));
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];
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);
3817 /*------------------------------------------------------------------*/
3818 /* IDI callback function */
3819 /*------------------------------------------------------------------*/
3821 void callback(ENTITY * e)
3823 DIVA_CAPI_ADAPTER * a;
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));
3837 a = &(adapter[(byte)e->user[0]]);
3838 plci = &(a->plci[e->user[1]]);
3839 no_cancel_rc = DIVA_CAPI_SUPPORTS_NO_CANCEL(a);
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.
3846 if (((e->complete == 0xff) && no_cancel_rc) ||
3847 (e->Rc && !no_cancel_rc)) {
3853 if (e->user[0] & 0x8000)
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.
3864 dbug(1,dprintf("cancel RC in REMOVE state"));
3867 channel_flow_control_remove (plci);
3868 for (i = 0; i < 256; i++)
3870 if (a->FlowControlIdTable[i] == plci->nl_remove_id)
3871 a->FlowControlIdTable[i] = 0;
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;
3881 a->FlowControlIdTable[ch] = e->Id;
3882 a->FlowControlSkipTable[ch] = 0;
3884 a->ch_flow_control[ch] |= N_OK_FC_PENDING;
3885 a->ch_flow_plci[ch] = plci->Id;
3891 Cancel return codes self, if feature was requested
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));
3901 if (a->ch_flow_control[ch] & N_OK_FC_PENDING)
3903 a->ch_flow_control[ch] &= ~N_OK_FC_PENDING;
3911 control_rc (plci, 0, rc, ch, 0, TRUE);
3916 channel_x_on (plci, ch);
3917 if (plci->internal_command)
3918 control_rc (plci, req, rc, ch, 0, TRUE);
3922 if (plci->nl_global_req)
3924 global_req = plci->nl_global_req;
3925 plci->nl_global_req = 0;
3926 if (rc != ASSIGN_OK) {
3928 if (plci->rx_dma_descriptor > 0) {
3929 diva_free_dma_descriptor (plci, plci->rx_dma_descriptor - 1);
3930 plci->rx_dma_descriptor = 0;
3933 channel_xmit_xon (plci);
3934 control_rc (plci, 0, rc, ch, global_req, TRUE);
3936 else if (plci->data_sent)
3938 channel_xmit_xon (plci);
3939 plci->data_sent = FALSE;
3942 if (plci->internal_command)
3943 control_rc (plci, req, rc, ch, 0, TRUE);
3947 channel_xmit_xon (plci);
3948 control_rc (plci, req, rc, ch, 0, TRUE);
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.
3964 dbug(1,dprintf("cancel RC in REMOVE state"));
3967 plci->sig_remove_id = 0;
3970 if (plci->sig_global_req)
3972 global_req = plci->sig_global_req;
3973 plci->sig_global_req = 0;
3974 if (rc != ASSIGN_OK)
3976 channel_xmit_xon (plci);
3977 control_rc (plci, 0, rc, ch, global_req, FALSE);
3981 channel_xmit_xon (plci);
3982 control_rc (plci, req, rc, ch, 0, FALSE);
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
3991 channel_xmit_xon(plci);
3992 goto capi_callback_suffix;
3996 channel_xmit_xon(plci);
3999 if (e->user[0] &0x8000) {
4000 byte Ind = e->Ind & 0x0f;
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));
4007 a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
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));
4022 capi_callback_suffix:
4024 while (!plci->req_in
4025 && !plci->internal_command
4026 && (plci->msg_in_write_pos != plci->msg_in_read_pos))
4028 j = (plci->msg_in_read_pos == plci->msg_in_wrap_pos) ? 0 : plci->msg_in_read_pos;
4030 i = (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]))->header.length + 3) & 0xfffc;
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)
4038 plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
4039 plci->msg_in_read_pos = i + MSG_IN_OVERHEAD;
4043 plci->msg_in_read_pos = j + i + MSG_IN_OVERHEAD;
4045 if (plci->msg_in_read_pos == plci->msg_in_write_pos)
4047 plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
4048 plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
4050 else if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
4052 plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
4053 plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
4055 i = api_put (appl, m);
4058 if (m->header.command == _DATA_B3_R)
4060 TransmitBufferFree (appl, (byte *)(m->info.data_b3_req.Data));
4062 dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command));
4066 if (plci->li_notify_update)
4068 plci->li_notify_update = FALSE;
4069 mixer_notify_update (plci, FALSE);
4078 void control_rc(PLCI * plci, byte req, byte rc, byte ch, byte global_req, byte nl_rc)
4086 DIVA_CAPI_ADAPTER * a;
4089 byte SSparms[] = "\x05\x00\x00\x02\x00\x00";
4090 byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
4093 dbug(0,dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc));
4096 dbug(1,dprintf("req0_in/out=%d/%d",plci->req_in,plci->req_out));
4097 if(plci->req_in!=plci->req_out)
4099 if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK))
4101 dbug(1,dprintf("req_1return"));
4104 /* cancel outstanding request on the PLCI after SIG ASSIGN failure */
4106 plci->req_in = plci->req_in_start = plci->req_out = 0;
4107 dbug(1,dprintf("control_rc"));
4111 ncci = a->ch_ncci[ch];
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))
4121 if(req==REMOVE && rc==ASSIGN_OK)
4123 sig_req(plci,HANGUP,0);
4124 sig_req(plci,REMOVE,0);
4129 switch(plci->command)
4132 dbug(1,dprintf("HoldRC=0x%x",rc));
4133 SSparms[1] = (byte)S_HOLD;
4136 plci->SuppState = IDLE;
4139 sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms);
4142 case C_RETRIEVE_REQ:
4143 dbug(1,dprintf("RetrieveRC=0x%x",rc));
4144 SSparms[1] = (byte)S_RETRIEVE;
4147 plci->SuppState = CALL_HELD;
4150 sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms);
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);
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)
4163 if(plci->Sig.Id!=0xff)
4165 if (((global_req == ASSIGN) && (rc != ASSIGN_OK))
4166 || (!nl_rc && (req == CALL_REQ) && (rc != OK)))
4168 dbug(1,dprintf("No more IDs/Call_Req failed"));
4169 sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI);
4174 if(plci->State!=LOCAL_CONNECT)plci->State = OUTG_CON_PENDING;
4175 sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0);
4177 else /* D-ch activation */
4179 if (rc != ASSIGN_OK)
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);
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;
4193 case _CONNECT_I|RESPONSE:
4194 if (plci->State != INC_DIS_PENDING)
4195 plci->State = INC_CON_ACCEPT;
4199 if (plci->State == INC_DIS_PENDING)
4201 if(plci->Sig.Id!=0xff)
4203 plci->State = OUTG_DIS_PENDING;
4204 sendf(appl,_DISCONNECT_R|CONFIRM,Id,Number,"w",0);
4217 sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",_WRONG_IDENTIFIER);
4220 ncci = get_ncci (plci, ch, 0);
4221 Id = (Id & 0xffff) | (((dword) ncci) << 16);
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","");
4231 a->ncci_state[ncci] = OUTG_CON_PENDING;
4232 sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0);
4236 case _CONNECT_B3_I|RESPONSE:
4240 /* sendf(appl,_RESET_B3_R|CONFIRM,Id,Number,"w",0);*/
4243 case _DISCONNECT_B3_R:
4244 sendf(appl,_DISCONNECT_B3_R|CONFIRM,Id,Number,"w",0);
4247 case _MANUFACTURER_R:
4253 Info = _WRONG_IDENTIFIER;
4254 sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info);
4258 sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info);
4266 else if (plci->internal_command)
4268 switch(plci->internal_command)
4274 if(rc==OK) /* command supported, wait for indication */
4281 /* Get Supported Services */
4282 case GETSERV_REQ_PEND:
4283 if(rc==OK) /* command supported, wait for indication */
4287 PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
4288 sendf(appl, _FACILITY_R|CONFIRM, Id, Number, "wws",0,3,SSstruct);
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)
4301 case INTERR_DIVERSION_REQ_PEND:
4302 SSparms[1] = S_INTERROGATE_DIVERSION;
4304 case INTERR_NUMBERS_REQ_PEND:
4305 SSparms[1] = S_INTERROGATE_NUMBERS;
4308 SSparms[1] = S_CALL_FORWARDING_START;
4311 SSparms[1] = S_CALL_FORWARDING_STOP;
4313 case CCBS_REQUEST_REQ_PEND:
4314 SSparms[1] = S_CCBS_REQUEST;
4316 case CCBS_DEACTIVATE_REQ_PEND:
4317 SSparms[1] = S_CCBS_DEACTIVATE;
4319 case CCBS_INTERROGATE_REQ_PEND:
4320 SSparms[1] = S_CCBS_INTERROGATE;
4323 if(global_req==ASSIGN)
4325 dbug(1,dprintf("AssignDiversion_RC=0x%x/0x%x",req,rc));
4328 if(!plci->appl) break;
4329 if(rc==ISDN_GUARD_REJ)
4331 Info = _CAPI_GUARD_ERROR;
4335 Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED;
4337 sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7,
4338 plci->number,"wws",Info,(word)3,SSparms);
4339 if(Info) plci_remove(plci);
4342 /* 3pty conference pending */
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;
4351 Info = 0x300E; /* not supported */
4352 plci->relatedPTYPLCI = NULL;
4356 _FACILITY_R|CONFIRM,
4359 "wws",Info,(word)3,SSparms);
4362 /* Explicit Call Transfer pending */
4364 dbug(1,dprintf("ECT_RC=0x%x/0x%x",req,rc));
4365 if(!plci->relatedPTYPLCI) break;
4366 rplci = plci->relatedPTYPLCI;
4368 rId = ((word)rplci->Id<<8)|rplci->adapter->Id;
4369 if(rplci->tel) rId|=EXT_CONTROLLER;
4372 Info = 0x300E; /* not supported */
4373 plci->relatedPTYPLCI = NULL;
4377 _FACILITY_R|CONFIRM,
4380 "wws",Info,(word)3,SSparms);
4383 case _MANUFACTURER_R:
4384 dbug(1,dprintf("_Manufacturer_R=0x%x/0x%x",req,rc));
4385 if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
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 */
4394 dbug(1,dprintf("_Connect_R=0x%x/0x%x",req,rc));
4395 if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
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 */
4403 case PERM_COD_HOOK: /* finished with Hook_Ind */
4407 dbug(1,dprintf("***Codec Connect_Pending A, Rc = 0x%x",rc));
4408 plci->internal_command = PERM_COD_CONN_PEND;
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);
4416 plci->internal_command = PERM_COD_CALL;
4419 /* Null Call Reference Request pending */
4421 dbug(1,dprintf("NCR_FAC=0x%x/0x%x",req,rc));
4422 if(global_req==ASSIGN)
4430 sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE);
4431 appl->NullCREnable = FALSE;
4435 else if(req==NCR_FACILITY)
4439 sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",0);
4443 sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE);
4444 appl->NullCREnable = FALSE;
4453 if(a->ncci_state[ncci]==CONNECTED)
4455 a->ncci_state[ncci] = OUTG_DIS_PENDING;
4456 cleanup_ncci_data (plci, ncci);
4457 nl_req_ncci(plci,N_DISC,(byte)ncci);
4464 if (plci->State == INC_DIS_PENDING)
4466 sig_req(plci,CALL_REQ,0);
4468 plci->State=OUTG_CON_PENDING;
4472 case MWI_ACTIVATE_REQ_PEND:
4473 case MWI_DEACTIVATE_REQ_PEND:
4474 if(global_req == ASSIGN && rc==ASSIGN_OK)
4476 dbug(1,dprintf("MWI_REQ assigned"));
4483 Info = 0x2007; /* Illegal message parameter coding */
4484 dbug(1,dprintf("MWI_REQ invalid parameter"));
4488 Info = 0x300B; /* not supported */
4489 dbug(1,dprintf("MWI_REQ not supported"));
4491 /* 0x3010: Request not allowed in this state */
4492 PUT_WORD(&SSparms[4],0x300E); /* SS not supported */
4495 if(plci->internal_command==MWI_ACTIVATE_REQ_PEND)
4497 PUT_WORD(&SSparms[1],S_MWI_ACTIVATE);
4499 else PUT_WORD(&SSparms[1],S_MWI_DEACTIVATE);
4501 if(plci->cr_enquiry)
4504 _FACILITY_R|CONFIRM,
4507 "wws",Info,(word)3,SSparms);
4508 if(rc!=OK) plci_remove(plci);
4513 _FACILITY_R|CONFIRM,
4516 "wws",Info,(word)3,SSparms);
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;
4530 switch(plci->internal_command)
4532 case CONF_BEGIN_REQ_PEND:
4533 SSparms[1] = S_CONF_BEGIN;
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;
4540 case CONF_SPLIT_REQ_PEND:
4541 SSparms[1] = S_CONF_SPLIT;
4543 case CONF_DROP_REQ_PEND:
4544 SSparms[1] = S_CONF_DROP;
4546 case CONF_ISOLATE_REQ_PEND:
4547 SSparms[1] = S_CONF_ISOLATE;
4549 case CONF_REATTACH_REQ_PEND:
4550 SSparms[1] = S_CONF_REATTACH;
4556 Info = 0x300E; /* not supported */
4557 plci->relatedPTYPLCI = NULL;
4561 _FACILITY_R|CONFIRM,
4564 "wws",Info,(word)3,SSparms);
4567 case VSWITCH_REQ_PEND:
4570 if(plci->relatedPTYPLCI)
4572 plci->relatedPTYPLCI->vswitchstate=0;
4573 plci->relatedPTYPLCI->vsprot=0;
4574 plci->relatedPTYPLCI->vsprotdialect=0;
4576 plci->vswitchstate=0;
4578 plci->vsprotdialect=0;
4582 if(plci->relatedPTYPLCI &&
4583 plci->vswitchstate==1 &&
4584 plci->relatedPTYPLCI->vswitchstate==3) /* join complete */
4585 plci->vswitchstate=3;
4589 /* Call Deflection Request pending (SSCT) */
4591 SSparms[1] = S_CALL_DEFLECTION;
4594 Info = 0x300E; /* not supported */
4595 plci->appl->CDEnable = 0;
4597 sendf(plci->appl,_FACILITY_R|CONFIRM,Id,
4598 plci->number,"wws",Info,(word)3,SSparms);
4601 case RTP_CONNECT_B3_REQ_COMMAND_2:
4604 ncci = get_ncci (plci, ch, 0);
4605 Id = (Id & 0xffff) | (((dword) ncci) << 16);
4607 a->ncci_state[ncci] = OUTG_CON_PENDING;
4611 if (plci->internal_command_queue[0])
4613 (*(plci->internal_command_queue[0]))(Id, plci, rc);
4614 if (plci->internal_command)
4619 next_internal_command (Id, plci);
4624 Id = ((word)plci->Id<<8)|plci->adapter->Id;
4625 if(plci->tel) Id|=EXT_CONTROLLER;
4627 switch(plci->internal_command)
4632 case START_L1_SIG_ASSIGN_PEND:
4633 case REM_L1_SIG_ASSIGN_PEND:
4634 if(global_req == ASSIGN)
4640 dbug(1,dprintf("***L1 Req rem PLCI"));
4641 plci->internal_command = 0;
4642 sig_req(plci,REMOVE,0);
4647 /* Call Deflection Request pending, just no appl ptr assigned */
4649 SSparms[1] = S_CALL_DEFLECTION;
4652 Info = 0x300E; /* not supported */
4654 for(i=0; i<max_appl; i++)
4656 if(application[i].CDEnable)
4658 if(!application[i].Id) application[i].CDEnable = 0;
4661 sendf(&application[i],_FACILITY_R|CONFIRM,Id,
4662 plci->number,"wws",Info,(word)3,SSparms);
4663 if(Info) application[i].CDEnable = 0;
4667 plci->internal_command = 0;
4670 case PERM_COD_HOOK: /* finished with Hook_Ind */
4674 plci->internal_command = PERM_COD_CONN_PEND;
4675 dbug(1,dprintf("***Codec Connect_Pending, Rc = 0x%x",rc));
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);
4687 case LISTEN_SIG_ASSIGN_PEND:
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);
4698 dbug(1,dprintf("ListenCheck failed (assignRc=0x%x)",rc));
4706 if(global_req == ASSIGN)
4710 sig_req(plci,LAW_REQ,0);
4712 dbug(1,dprintf("Auto-Law assigned"));
4716 dbug(1,dprintf("Auto-Law assign failed"));
4717 a->automatic_law = 3;
4718 plci->internal_command = 0;
4719 a->automatic_lawPLCI = NULL;
4723 else if(req == LAW_REQ && rc==OK)
4725 dbug(1,dprintf("Auto-Law initiated"));
4726 a->automatic_law = 2;
4727 plci->internal_command = 0;
4731 dbug(1,dprintf("Auto-Law not supported"));
4732 a->automatic_law = 3;
4733 plci->internal_command = 0;
4734 sig_req(plci,REMOVE,0);
4736 a->automatic_lawPLCI = NULL;
4740 plci_remove_check(plci);
4744 void data_rc(PLCI * plci, byte ch)
4747 DIVA_CAPI_ADAPTER * a;
4754 TransmitBufferFree (plci->appl, plci->data_sent_ptr);
4756 ncci = a->ch_ncci[ch];
4757 if (ncci && (a->ncci_plci[ncci] == plci->Id))
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)
4763 data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
4764 if (!(data->Flags &4) && a->ncci_state[ncci])
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);
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)--;
4780 void data_ack(PLCI * plci, byte ch)
4783 DIVA_CAPI_ADAPTER * a;
4788 ncci = a->ch_ncci[ch];
4789 ncci_ptr = &(a->ncci[ncci]);
4790 if (ncci_ptr->data_ack_pending)
4792 if (a->ncci_state[ncci] && (a->ncci_plci[ncci] == plci->Id))
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);
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)--;
4806 void sig_ind(PLCI * plci)
4816 DIVA_CAPI_ADAPTER * a;
4817 API_PARSE saved_parms[MAX_MSG_PARMS+1];
4818 #define MAXPARMSIDS 31
4819 byte * parms[MAXPARMSIDS];
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];
4826 byte * multi_vswitch_parms [MAX_MULTI_IE];
4833 byte *esc_profile = "";
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) */
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};
4857 word multi_vswitch_id[] = {1, ESC_VSWITCH};
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;
4871 Id = ((word)plci->Id<<8)|a->Id;
4872 PUT_WORD(&SS_Ind[4],0x0000);
4874 if (plci->sig_remove_id)
4876 plci->Sig.RNR = 2; /* discard */
4877 dbug(1,dprintf("SIG discard while remove pending"));
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)
4888 if(plci->Sig.Ind==HANGUP && plci->channels)
4891 plci->hangup_flow_ctrl_timer++;
4892 /* recover the network layer after timeout */
4893 if(plci->hangup_flow_ctrl_timer==100)
4895 dbug(1,dprintf("Exceptional disc"));
4897 plci->hangup_flow_ctrl_timer = 0;
4898 for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
4900 if (a->ncci_plci[ncci] == plci->Id)
4902 cleanup_ncci_data (plci, ncci);
4903 if(plci->channels)plci->channels--;
4905 sendf(plci->appl,_DISCONNECT_B3_I, (((dword) ncci) << 16) | Id,0,"ws",0,"");
4909 sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
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);
4923 IndParse(plci,multi_vswitch_id,multi_vswitch_parms,MAX_MULTI_IE);
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];
4931 esc_profile = parms[27];
4932 if(esc_cr[0] && plci)
4934 if(plci->cr_enquiry && plci->appl)
4936 plci->cr_enquiry = FALSE;
4939 /* b = total length */
4940 /* b = indication type */
4941 /* b = length of all IEs */
4943 /* S = IE1 length + cont. */
4945 /* S = IE2 lenght + cont. */
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);
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);
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)
4966 dbug(0,dprintf("u-Law selected"));
4970 dbug(0,dprintf("a-Law selected"));
4973 a->automatic_law = 4;
4974 if(plci==a->automatic_lawPLCI) {
4975 plci->internal_command = 0;
4976 sig_req(plci,REMOVE,0);
4978 a->automatic_lawPLCI = NULL;
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])));
4988 a->profile.Global_Options &= 0x000000ffL;
4989 a->profile.B1_Protocols &= 0x000003ffL;
4990 a->profile.B2_Protocols &= 0x00001fdfL;
4991 a->profile.B3_Protocols &= 0x000000b7L;
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;
5001 if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER)
5003 a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER;
5004 a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED;
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]);
5014 if (a->manufacturer_features & MANUFACTURER_FEATURE_T38)
5015 a->man_profile.private_options |= 1L << PRIVATE_T38;
5018 if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD)
5019 a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
5022 if (a->manufacturer_features & MANUFACTURER_FEATURE_V18)
5023 a->man_profile.private_options |= 1L << PRIVATE_V18;
5026 if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE)
5027 a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE;
5030 if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS)
5031 a->man_profile.private_options |= 1L << PRIVATE_PIAFS;
5034 if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
5035 a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS;
5038 if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN)
5039 a->man_profile.private_options |= 1L << PRIVATE_VOWN;
5042 if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD)
5043 a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD;
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;
5054 if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF |
5055 MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
5057 a->profile.Global_Options |= GL_DTMF_SUPPORTED;
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));
5065 /* codec plci for the handset/hook state support is just an internal id */
5066 if(plci!=a->AdvCodecPLCI)
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);
5073 VSwitchReqInd(plci,Id,multi_vswitch_parms);
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);
5087 if(plci->appl) Number = plci->appl->Number++;
5089 switch(plci->Sig.Ind) {
5090 /* Response to Get_Supported_Services request */
5092 dbug(1,dprintf("S_Supported"));
5093 if(!plci->appl) break;
5096 PUT_DWORD(&CF_Ind[6],GET_DWORD(&pty_cai[1]) );
5100 PUT_DWORD(&CF_Ind[6],MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE);
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);
5108 /* Supplementary Service rejected */
5110 dbug(1,dprintf("S_Reject=0x%x",pty_cai[5]));
5111 if(!pty_cai[0]) break;
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)
5123 PUT_WORD(&SS_Ind[1],S_ECT);
5125 plci->vswitchstate=0;
5126 plci->relatedPTYPLCI->vswitchstate=0;
5131 PUT_WORD(&SS_Ind[1],pty_cai[5]+3);
5133 if(pty_cai[2]!=0xff)
5135 PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
5139 PUT_WORD(&SS_Ind[4],0x300E);
5141 plci->relatedPTYPLCI = NULL;
5143 sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);
5146 case CALL_DEFLECTION:
5147 if(pty_cai[2]!=0xff)
5149 PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
5153 PUT_WORD(&SS_Ind[4],0x300E);
5155 PUT_WORD(&SS_Ind[1],pty_cai[5]);
5156 for(i=0; i<max_appl; i++)
5158 if(application[i].CDEnable)
5160 if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind);
5161 application[i].CDEnable = FALSE;
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:
5173 case CCBS_DEACTIVATE:
5174 case CCBS_INTERROGATE:
5175 if(!plci->appl) break;
5176 if(pty_cai[2]!=0xff)
5178 PUT_WORD(&Interr_Err_Ind[4],0x3600|(word)pty_cai[2]);
5182 PUT_WORD(&Interr_Err_Ind[4],0x300E);
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);
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);
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);
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);
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);
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);
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);
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);
5235 case ACTIVATION_MWI:
5236 case DEACTIVATION_MWI:
5237 if(pty_cai[5]==ACTIVATION_MWI)
5239 PUT_WORD(&SS_Ind[1],S_MWI_ACTIVATE);
5241 else PUT_WORD(&SS_Ind[1],S_MWI_DEACTIVATE);
5243 if(pty_cai[2]!=0xff)
5245 PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
5249 PUT_WORD(&SS_Ind[4],0x300E);
5252 if(plci->cr_enquiry)
5254 sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind);
5259 sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
5262 case CONF_ADD: /* ERROR */
5272 PUT_WORD(&CONF_Ind[1],S_CONF_BEGIN);
5278 PUT_WORD(&CONF_Ind[1],S_CONF_DROP);
5279 plci->ptyState = CONNECTED;
5284 PUT_WORD(&CONF_Ind[1],S_CONF_ISOLATE);
5285 plci->ptyState = CONNECTED;
5290 PUT_WORD(&CONF_Ind[1],S_CONF_REATTACH);
5291 plci->ptyState = CONNECTED;
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;
5302 if(pty_cai[2]!=0xff)
5304 PUT_WORD(&CONF_Ind[4],0x3600|(word)pty_cai[2]);
5308 PUT_WORD(&CONF_Ind[4],0x3303); /* Time-out: network did not respond
5309 within the required time */
5312 PUT_DWORD(&CONF_Ind[6],0x0);
5313 sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
5318 /* Supplementary Service indicates success */
5320 dbug(1,dprintf("Service_Ind"));
5321 PUT_WORD (&CF_Ind[4], 0);
5325 case THREE_PTY_BEGIN:
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)
5333 PUT_WORD(&SS_Ind[1],S_ECT);
5335 if(plci->vswitchstate!=3)
5338 plci->ptyState = IDLE;
5339 plci->relatedPTYPLCI = NULL;
5344 dbug(1,dprintf("ECT OK"));
5345 sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);
5352 switch (plci->ptyState)
5355 plci->ptyState = CONNECTED;
5356 dbug(1,dprintf("3PTY ON"));
5360 plci->ptyState = IDLE;
5361 plci->relatedPTYPLCI = NULL;
5363 dbug(1,dprintf("3PTY OFF"));
5366 PUT_WORD(&SS_Ind[1],pty_cai[5]+3);
5367 sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);
5371 case CALL_DEFLECTION:
5372 PUT_WORD(&SS_Ind[1],pty_cai[5]);
5373 for(i=0; i<max_appl; i++)
5375 if(application[i].CDEnable)
5377 if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind);
5378 application[i].CDEnable = FALSE;
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);
5392 case DIVERSION_INTERROGATE_CFU:
5393 case DIVERSION_INTERROGATE_CFB:
5394 case DIVERSION_INTERROGATE_CFNR:
5395 case DIVERSION_INTERROGATE_NUM:
5397 case CCBS_DEACTIVATE:
5398 case CCBS_INTERROGATE:
5399 if(!plci->appl) break;
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 */
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 */
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 */
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 */
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 */
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);
5436 case ACTIVATION_MWI:
5437 case DEACTIVATION_MWI:
5438 if(pty_cai[5]==ACTIVATION_MWI)
5440 PUT_WORD(&SS_Ind[1],S_MWI_ACTIVATE);
5442 else PUT_WORD(&SS_Ind[1],S_MWI_DEACTIVATE);
5443 if(plci->cr_enquiry)
5445 sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind);
5450 sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
5453 case MWI_INDICATION:
5454 if(pty_cai[0]>=0x12)
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))
5461 if(plci->internal_command==GET_MWI_STATE) /* result on Message Waiting Listen */
5463 sendf(plci->appl,_FACILITY_I,Id&0xf,0,"wS",3, &pty_cai[2]);
5467 else sendf(plci->appl,_FACILITY_I,Id,0,"wS",3, &pty_cai[2]);
5472 for(i=0; i<max_appl; i++)
5474 if(a->Notification_Mask[i]&SMASK_MWI)
5476 sendf(&application[i],_FACILITY_I,Id&0x7,0,"wS",3, &pty_cai[2]);
5484 facility[2]= 0; /* returncode */
5486 else facility[2]= 0xff;
5491 facility[2]= 0xff; /* returncode */
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);
5500 next_internal_command (Id, plci);
5502 case CONF_ADD: /* OK */
5507 case CONF_PARTYDISC:
5513 PUT_WORD(&CONF_Ind[1],S_CONF_BEGIN);
5517 PUT_DWORD(&CONF_Ind[6],d); /* PartyID */
5521 PUT_DWORD(&CONF_Ind[6],0x0);
5525 PUT_WORD(&CONF_Ind[1],S_CONF_ISOLATE);
5530 PUT_WORD(&CONF_Ind[1],S_CONF_REATTACH);
5535 PUT_WORD(&CONF_Ind[1],S_CONF_DROP);
5540 PUT_WORD(&CONF_Ind[1],S_CONF_ADD);
5542 PUT_DWORD(&CONF_Ind[6],d); /* PartyID */
5543 tplci=plci->relatedPTYPLCI;
5544 if(tplci) tplci->ptyState = CONNECTED;
5546 case CONF_PARTYDISC:
5549 PUT_WORD(&CONF_Ind[1],S_CONF_PARTYDISC);
5551 PUT_DWORD(&CONF_Ind[4],d); /* PartyID */
5554 plci->ptyState = CONNECTED;
5555 sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
5557 case CCBS_INFO_RETAIN:
5558 case CCBS_ERASECALLLINKAGEID:
5559 case CCBS_STOP_ALERTING:
5564 case CCBS_INFO_RETAIN:
5565 PUT_WORD(&CONF_Ind[1],S_CCBS_INFO_RETAIN);
5567 case CCBS_STOP_ALERTING:
5568 PUT_WORD(&CONF_Ind[1],S_CCBS_STOP_ALERTING);
5570 case CCBS_ERASECALLLINKAGEID:
5571 PUT_WORD(&CONF_Ind[1],S_CCBS_ERASECALLLINKAGEID);
5579 PUT_WORD(&CONF_Ind[4],w); /* PartyID */
5581 if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_CCBS))
5583 sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
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);
5598 i = _L3_CAUSE | cau[2];
5599 if(cau[2]==0) i = 0x3603;
5605 PUT_WORD(&SS_Ind[1],S_HOLD);
5606 PUT_WORD(&SS_Ind[4],i);
5607 if(plci->SuppState == HOLD_REQUEST)
5609 plci->SuppState = IDLE;
5610 sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
5615 if(plci->SuppState == HOLD_REQUEST)
5617 plci->SuppState = CALL_HELD;
5618 CodecIdCheck(a, plci);
5619 start_internal_command (Id, plci, hold_save_command);
5623 case CALL_RETRIEVE_REJ:
5627 i = _L3_CAUSE | cau[2];
5628 if(cau[2]==0) i = 0x3603;
5634 PUT_WORD(&SS_Ind[1],S_RETRIEVE);
5635 PUT_WORD(&SS_Ind[4],i);
5636 if(plci->SuppState == RETRIEVE_REQUEST)
5638 plci->SuppState = CALL_HELD;
5639 CodecIdCheck(a, plci);
5640 sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
5644 case CALL_RETRIEVE_ACK:
5645 PUT_WORD(&SS_Ind[1],S_RETRIEVE);
5646 if(plci->SuppState == RETRIEVE_REQUEST)
5648 plci->SuppState = IDLE;
5649 plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
5650 plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
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)
5658 dbug(1,dprintf("Get B-ch"));
5659 start_internal_command (Id, plci, retrieve_restore_command);
5662 sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
5665 start_internal_command (Id, plci, retrieve_restore_command);
5670 if(plci->State != LISTENING) {
5671 sig_req(plci,HANGUP,0);
5675 cip = find_cip(a,parms[4],parms[6]);
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)
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;
5695 plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
5696 mixer_set_bchannel_id_esc (plci, plci->b_channel);
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)
5705 if(plci->tel) Id|=EXT_CONTROLLER;
5706 a->codec_listen[i] = plci;
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) */
5725 SendSSExtInd(&application[i],
5729 SendSetupInfo(&application[i],
5733 SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, TRUE));
5736 clear_c_ind_mask_bit (plci, MAX_APPL);
5737 dump_c_ind_mask (plci);
5739 if(c_ind_mask_empty (plci)) {
5740 sig_req(plci,HANGUP,0);
5744 plci->notifiedcall = 0;
5749 case CALL_PEND_NOTIFY:
5750 plci->notifiedcall = 1;
5756 if(plci->State==ADVANCED_VOICE_SIG || plci->State==ADVANCED_VOICE_NOSIG)
5758 if(plci->internal_command==PERM_COD_CONN_PEND)
5760 if(plci->State==ADVANCED_VOICE_NOSIG)
5762 dbug(1,dprintf("***Codec OK"));
5763 if(a->AdvSignalPLCI)
5765 tplci = a->AdvSignalPLCI;
5766 if(tplci->spoofed_msg)
5768 dbug(1,dprintf("***Spoofed Msg(0x%x)",tplci->spoofed_msg));
5770 tplci->internal_command = 0;
5771 x_Id = ((word)tplci->Id<<8)|tplci->adapter->Id | 0x80;
5772 switch (tplci->spoofed_msg)
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)
5780 /* early B3 connect (CIP mask bit 9) no release after a disc */
5781 add_p(tplci,LLI,"\x01\x01");
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);
5791 case AWAITING_SELECT_B:
5792 dbug(1,dprintf("Select_B continue"));
5793 start_internal_command (x_Id, tplci, select_b_command);
5796 case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */
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);
5804 tplci->command = _MANUFACTURER_R;
5805 api_load_msg (&tplci->saved_msg, saved_parms);
5806 dir = saved_parms[2].info[0];
5808 sig_req(tplci,CALL_REQ,0);
5811 sig_req(tplci,LISTEN_REQ,0);
5814 sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,0);
5817 case (CALL_REQ|AWAITING_MANUF_CON):
5818 sig_req(tplci,CALL_REQ,0);
5825 dbug(1,dprintf("No SigID!"));
5826 sendf(tplci->appl,_CONNECT_R|CONFIRM,tplci->adapter->Id,0,"w",_OUT_OF_PLCI);
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);
5840 tplci->command = C_RETRIEVE_REQ;
5841 sig_req(tplci,CALL_RETRIEVE,0);
5845 tplci->spoofed_msg = 0;
5846 if (tplci->internal_command == 0)
5847 next_internal_command (x_Id, tplci);
5850 next_internal_command (Id, plci);
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);
5860 else if(plci->command != _MANUFACTURER_R /* old style permanent connect */
5861 && plci->State!=INC_ACT_PENDING)
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 */
5866 chi[2] = plci->b_channel;
5867 SetVoiceChannel(a->AdvCodecPLCI, chi, a);
5869 sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"Sss",parms[21],"","");
5870 plci->State = INC_ACT_PENDING;
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 */
5881 if(plci->internal_command==PERM_COD_HOOK)
5883 dbug(1,dprintf("init:hook_off"));
5884 plci->hook_state = ie[1];
5885 next_internal_command (Id, plci);
5888 else /* ignore doubled hook indications */
5890 if( ((plci->hook_state)&0xf0)==0x80)
5892 dbug(1,dprintf("ignore hook"));
5895 plci->hook_state = ie[1]&0x91;
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];
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");
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;
5938 Id = ((word)tplci->Id<<8)|a->Id;
5944 "ws", (word)0, "\x01+");
5947 case 0x90: /* hook on */
5949 if(plci->internal_command==PERM_COD_HOOK)
5951 dbug(1,dprintf("init:hook_on"));
5952 plci->hook_state = ie[1]&0x91;
5953 next_internal_command (Id, plci);
5956 else /* ignore doubled hook indications */
5958 if( ((plci->hook_state)&0xf0)==0x90) break;
5959 plci->hook_state = ie[1]&0x91;
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,
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);
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);
5987 clear_c_ind_mask (plci);
5989 if (plci->NL.Id && !plci->nl_remove_id) {
5990 mixer_remove (plci);
5991 nl_req_ncci(plci,REMOVE,0);
5993 if (!plci->sig_remove_id) {
5994 plci->internal_command = 0;
5995 sig_req(plci,REMOVE,0);
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);
6008 plci->hangup_flow_ctrl_timer=0;
6009 if(plci->manufacturer && plci->State==LOCAL_CONNECT) break;
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;
6022 if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT)
6024 for(i=0; i<max_appl; i++)
6026 if(test_c_ind_mask_bit (plci, i))
6027 sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
6032 clear_c_ind_mask (plci);
6036 if (plci->State == LISTENING)
6038 plci->notifiedcall=0;
6041 plci->State = INC_DIS_PENDING;
6042 if(c_ind_mask_empty (plci))
6045 if (plci->NL.Id && !plci->nl_remove_id)
6047 mixer_remove (plci);
6048 nl_req_ncci(plci,REMOVE,0);
6050 if (!plci->sig_remove_id)
6052 plci->internal_command = 0;
6053 sig_req(plci,REMOVE,0);
6060 /* collision of DISCONNECT or CONNECT_RES with HANGUP can */
6061 /* result in a second HANGUP! Don't generate another */
6063 if(plci->State!=IDLE && plci->State!=INC_DIS_PENDING)
6065 if(plci->State==RESUMING)
6067 PUT_WORD(&resume_cau[4],i);
6068 sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau);
6070 plci->State = INC_DIS_PENDING;
6071 sendf(plci->appl,_DISCONNECT_I,Id,0,"w",i);
6077 SendSSExtInd(NULL,plci,Id,multi_ssext_parms);
6081 VSwitchReqInd(plci,Id,multi_vswitch_parms);
6084 if(plci->relatedPTYPLCI &&
6085 plci->vswitchstate==3 &&
6086 plci->relatedPTYPLCI->vswitchstate==3 &&
6087 parms[MAXPARMSIDS-1][0])
6089 add_p(plci->relatedPTYPLCI,SMSG,parms[MAXPARMSIDS-1]);
6090 sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0);
6091 send_req(plci->relatedPTYPLCI);
6093 else VSwitchReqInd(plci,Id,multi_vswitch_parms);
6100 static void SendSetupInfo(APPL * appl, PLCI * plci, dword Id, byte * * parms, byte Info_Sent_Flag)
6105 byte * Info_Element;
6108 dbug(1,dprintf("SetupInfo"));
6110 for(i=0; i<MAXPARMSIDS; i++) {
6117 dbug(1,dprintf("CPN "));
6118 Info_Number = 0x0070;
6120 Info_Sent_Flag = TRUE;
6122 case 8: /* display */
6123 dbug(1,dprintf("display(%d)",i));
6124 Info_Number = 0x0028;
6126 Info_Sent_Flag = TRUE;
6128 case 16: /* Channel Id */
6129 dbug(1,dprintf("CHI"));
6130 Info_Number = 0x0018;
6132 Info_Sent_Flag = TRUE;
6133 mixer_set_bchannel_id (plci, Info_Element);
6135 case 19: /* Redirected Number */
6136 dbug(1,dprintf("RDN"));
6137 Info_Number = 0x0074;
6139 Info_Sent_Flag = TRUE;
6141 case 20: /* Redirected Number extended */
6142 dbug(1,dprintf("RDX"));
6143 Info_Number = 0x0073;
6145 Info_Sent_Flag = TRUE;
6147 case 22: /* Redirecing Number */
6148 dbug(1,dprintf("RIN"));
6149 Info_Number = 0x0076;
6151 Info_Sent_Flag = TRUE;
6159 if(i==MAXPARMSIDS-2){ /* to indicate the message type "Setup" */
6160 Info_Number = 0x8000 |5;
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);
6174 void SendInfo(PLCI * plci, dword Id, byte * * parms, byte iesent)
6181 byte * Info_Element;
6183 static byte charges[5] = {4,0,0,0,0};
6184 static byte cause[] = {0x02,0x80,0x00};
6187 dbug(1,dprintf("InfoParse "));
6192 && plci->Sig.Ind!=NCR_FACILITY
6195 dbug(1,dprintf("NoParse "));
6199 for(i=0; i<MAXPARMSIDS; i++) {
6206 dbug(1,dprintf("CPN "));
6207 Info_Number = 0x0070;
6210 case 7: /* ESC_CAU */
6211 dbug(1,dprintf("cau(0x%x)",ie[2]));
6212 Info_Number = 0x0008;
6215 Info_Element = NULL;
6217 case 8: /* display */
6218 dbug(1,dprintf("display(%d)",i));
6219 Info_Number = 0x0028;
6222 case 9: /* Date display */
6223 dbug(1,dprintf("date(%d)",i));
6224 Info_Number = 0x0029;
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;
6233 Info_Element = charges;
6235 case 11: /* user user info */
6236 dbug(1,dprintf("uui"));
6237 Info_Number = 0x007E;
6240 case 12: /* congestion receiver ready */
6241 dbug(1,dprintf("clRDY"));
6242 Info_Number = 0x00B0;
6246 case 13: /* congestion receiver not ready */
6247 dbug(1,dprintf("clNRDY"));
6248 Info_Number = 0x00BF;
6252 case 15: /* Keypad Facility */
6253 dbug(1,dprintf("KEY"));
6254 Info_Number = 0x002C;
6257 case 16: /* Channel Id */
6258 dbug(1,dprintf("CHI"));
6259 Info_Number = 0x0018;
6261 mixer_set_bchannel_id (plci, Info_Element);
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;
6268 if(cause[2] != ie[2]) Info_Element = cause;
6270 case 19: /* Redirected Number */
6271 dbug(1,dprintf("RDN"));
6272 Info_Number = 0x0074;
6275 case 22: /* Redirecing Number */
6276 dbug(1,dprintf("RIN"));
6277 Info_Number = 0x0076;
6280 case 23: /* Notification Indicator */
6281 dbug(1,dprintf("NI"));
6282 Info_Number = (word)NI;
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 */
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;
6305 if(plci->Sig.Ind==NCR_FACILITY) /* check controller broadcast */
6307 for(j=0; j<max_appl; j++)
6309 appl = &application[j];
6312 && plci->adapter->Info_Mask[appl->Id-1] &Info_Mask)
6314 dbug(1,dprintf("NCR_Ind"));
6316 sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element);
6320 else if(!plci->appl)
6321 { /* overlap receiving broadcast */
6326 || Info_Number==UUI )
6328 for(j=0; j<max_appl; j++)
6330 if(test_c_ind_mask_bit (plci, j))
6332 dbug(1,dprintf("Ovl_Ind"));
6334 sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element);
6338 } /* all other signalling states */
6340 && plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask)
6342 dbug(1,dprintf("Std_Ind"));
6344 sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element);
6350 byte SendMultiIE(PLCI * plci, dword Id, byte * * parms, byte ie_type, dword info_mask, byte setupParse)
6356 byte * Info_Element;
6364 && plci->Sig.Ind!=NCR_FACILITY
6368 dbug(1,dprintf("NoM-IEParse "));
6371 dbug(1,dprintf("M-IEParse "));
6373 for(i=0; i<MAX_MULTI_IE; i++)
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;
6385 if(plci->Sig.Ind==NCR_FACILITY) /* check controller broadcast */
6387 for(j=0; j<max_appl; j++)
6389 appl = &application[j];
6392 && plci->adapter->Info_Mask[appl->Id-1] &Info_Mask)
6395 dbug(1,dprintf("Mlt_NCR_Ind"));
6396 sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element);
6400 else if(!plci->appl && Info_Number)
6401 { /* overlap receiving broadcast */
6402 for(j=0; j<max_appl; j++)
6404 if(test_c_ind_mask_bit (plci, j))
6407 dbug(1,dprintf("Mlt_Ovl_Ind"));
6408 sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element);
6411 } /* all other signalling states */
6413 && plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask)
6416 dbug(1,dprintf("Mlt_Std_Ind"));
6417 sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element);
6423 static void SendSSExtInd(APPL * appl, PLCI * plci, dword Id, byte * * parms)
6426 /* Format of multi_ssext_parms[i][]:
6429 2 byte SSEXT_REQ/SSEXT_IND
6437 && plci->Sig.Ind!=NCR_FACILITY
6439 for(i=0;i<MAX_MULTI_IE;i++)
6441 if(parms[i][0]<6) continue;
6442 if(parms[i][2]==SSEXT_REQ) continue;
6446 parms[i][0]=0; /* kill it */
6447 sendf(appl,_MANUFACTURER_I,
6457 parms[i][0]=0; /* kill it */
6458 sendf(plci->appl,_MANUFACTURER_I,
6469 void nl_ind(PLCI * plci)
6474 DIVA_CAPI_ADAPTER * a;
6480 byte len, ncci_state;
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 */
6536 byte dtmf_code_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE + 1];
6539 static word rtp_info[] = {
6540 GOOD, /* RTP_SUCCESS */
6541 0x3600 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE */
6544 static dword udata_forwarding_table[0x100 / sizeof(dword)] =
6546 0x0020301e, 0x00000000, 0x00000000, 0x00000000,
6547 0x00000000, 0x00000000, 0x00000000, 0x00000000
6550 ch = plci->NL.IndCh;
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));
6559 /* in the case if no connect_active_Ind was sent to the appl we wait for */
6561 if (plci->nl_remove_id)
6563 plci->NL.RNR = 2; /* discard */
6564 dbug(1,dprintf("NL discard while remove pending"));
6567 if((plci->NL.Ind &0x0f)==N_CONNECT)
6569 if(plci->State==INC_DIS_PENDING
6570 || plci->State==OUTG_DIS_PENDING
6571 || plci->State==IDLE)
6573 plci->NL.RNR = 2; /* discard */
6574 dbug(1,dprintf("discard n_connect"));
6577 if(plci->State < INC_ACT_PENDING)
6579 plci->NL.RNR = 1; /* flow control */
6580 channel_x_off (plci, ch, N_XON_CONNECT_IND);
6585 if(!APPLptr) /* no application or invalid data */
6586 { /* while reloading the DSP */
6587 dbug(1,dprintf("discard1"));
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)) )
6597 plci->ncpi_buffer[0] = 0;
6599 ncpi_state = plci->ncpi_state;
6600 if (plci->NL.complete == 1)
6602 byte * data = &plci->NL.RBuffer->P[0];
6604 if ((plci->NL.RBuffer->length >= 12)
6605 &&( (*data == DSP_UDATA_INDICATION_DCD_ON)
6606 ||(*data == DSP_UDATA_INDICATION_CTS_ON)) )
6608 word conn_opt, ncpi_opt = 0x00;
6609 /* HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */
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;
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 */
6624 PUT_WORD (&(plci->ncpi_buffer[1]), (word)(GET_DWORD(data) & 0x0000FFFF));
6626 if (conn_opt & DSP_CONNECTED_OPTION_MASK_V42)
6628 ncpi_opt |= MDM_NCPI_ECM_V42;
6630 else if (conn_opt & DSP_CONNECTED_OPTION_MASK_MNP)
6632 ncpi_opt |= MDM_NCPI_ECM_MNP;
6636 ncpi_opt |= MDM_NCPI_TRANSPARENT;
6638 if (conn_opt & DSP_CONNECTED_OPTION_MASK_COMPRESSION)
6640 ncpi_opt |= MDM_NCPI_COMPRESSED;
6642 PUT_WORD (&(plci->ncpi_buffer[3]), ncpi_opt);
6643 plci->ncpi_buffer[0] = 4;
6645 plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND | NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
6648 if (plci->B3_prot == 7)
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))
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;
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))
6671 if(plci->NL.complete == 2)
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))))
6676 switch(plci->RData[0].P[0])
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");
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");
6687 case DTMF_UDATA_INDICATION_DIGITS_RECEIVED:
6688 dtmf_indication (Id, plci, plci->RData[0].P, plci->RData[0].PLength);
6690 case DTMF_UDATA_INDICATION_DIGITS_SENT:
6691 dtmf_confirmation (Id, plci);
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);
6700 dtmf_code_buffer[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED;
6701 dtmf_indication (Id, plci, dtmf_code_buffer, (word)(i + 1));
6706 case UDATA_INDICATION_MIXER_COEFS_SET:
6707 mixer_indication_coefs_set (Id, plci);
6709 case UDATA_INDICATION_XCONNECT_FROM:
6710 mixer_indication_xconnect_from (Id, plci, plci->RData[0].P, plci->RData[0].PLength);
6712 case UDATA_INDICATION_XCONNECT_TO:
6713 mixer_indication_xconnect_to (Id, plci, plci->RData[0].P, plci->RData[0].PLength);
6717 case LEC_UDATA_INDICATION_DISABLE_DETECT:
6718 ec_indication (Id, plci, plci->RData[0].P, plci->RData[0].PLength);
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)))
6735 sendf(plci->appl,_DATA_B3_I,Id,0,
6738 (plci->NL.RNum < 2) ? 0 : plci->RData[1].PLength,
6746 sendf(plci->appl,_DATA_B3_I,Id,0,
6749 plci->RData[0].PLength,
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)
6766 plci->ncpi_buffer[0] = 0;
6767 switch (plci->B3_prot) {
6770 break; /* no network control protocol info - jfr */
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;
6779 case 4: /*T.30 - FAX*/
6780 case 5: /*T.30 - FAX*/
6781 if(plci->NL.RLength>=sizeof(T30_INFO))
6783 dbug(1,dprintf("FaxStatus %04x", ((T30_INFO *)plci->NL.RBuffer->P)->code));
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)
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 */
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)
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];
6813 if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
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];
6818 info = _FAX_PROTOCOL_ERROR;
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)))
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++];
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);
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))))
6842 plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT;
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)))
6849 plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
6855 if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
6857 if (plci->NL.RLength != 0)
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];
6870 switch(plci->NL.Ind &0x0f) {
6872 if ((plci->B3_prot == 4) || (plci->B3_prot == 5))
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);
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))
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;
6893 if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
6895 switch (((T30_INFO *)plci->NL.RBuffer->P)->code)
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))
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","");
6907 sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
6908 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
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))
6917 if (plci->B3_prot == 4)
6918 sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
6920 sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
6921 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
6925 case EDATA_T30_EOP_CAPI:
6926 if (a->ncci_state[ncci] == CONNECTED)
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;
6938 switch (((T30_INFO *)plci->NL.RBuffer->P)->code)
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))
6945 if (plci->B3_prot == 4)
6946 sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
6948 sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
6949 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
6954 if (fax_send_edata_ack)
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);
6963 dbug(1,dprintf("EDATA ncci=0x%x state=%d", ncci, a->ncci_state[ncci]));
6967 if (!a->ch_ncci[ch])
6969 ncci = get_ncci (plci, ch, 0);
6970 Id = (Id & 0xffff) | (((dword) ncci) << 16);
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));
6975 msg = _CONNECT_B3_I;
6976 if (a->ncci_state[ncci] == IDLE)
6978 else if (plci->B3_prot == 1)
6979 msg = _CONNECT_B3_T90_ACTIVE_I;
6981 a->ncci_state[ncci] = INC_CON_PENDING;
6982 if(plci->B3_prot == 4)
6983 sendf(plci->appl,msg,Id,0,"s","");
6985 sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer);
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)))
6994 (*(plci->internal_command_queue[0]))(Id, plci, 0);
6995 if (!plci->internal_command)
6996 next_internal_command (Id, plci);
6999 msg = _CONNECT_B3_ACTIVE_I;
7000 if (plci->B3_prot == 1)
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);
7007 else if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
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))
7013 a->ncci_state[ncci] = INC_ACT_PENDING;
7014 if (plci->B3_prot == 4)
7015 sendf(plci->appl,msg,Id,0,"s","");
7017 sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer);
7018 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
7023 a->ncci_state[ncci] = INC_ACT_PENDING;
7024 sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer);
7026 if (plci->adjust_b_restore)
7028 plci->adjust_b_restore = FALSE;
7029 start_internal_command (Id, plci, adjust_b_restore);
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)))
7039 (*(plci->internal_command_queue[0]))(Id, plci, 0);
7040 if (!plci->internal_command)
7041 next_internal_command (Id, plci);
7043 ncci_state = a->ncci_state[ncci];
7044 ncci_remove (plci, ncci, FALSE);
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;
7053 /* need a connect_b3_ind before a disconnect_b3_ind with FAX */
7055 && (plci->B1_resource == 16)
7056 && (plci->State <= CONNECTED))
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","");
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)))
7075 plci->ncpi_buffer[++len] = 0;
7076 plci->ncpi_buffer[++len] = 0;
7077 plci->ncpi_buffer[++len] = 0;
7078 plci->ncpi_buffer[0] = len;
7081 sendf(plci->appl,_CONNECT_B3_I,Id,0,"S",plci->ncpi_buffer);
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);
7087 plci->State = OUTG_DIS_PENDING;
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)))
7094 if (ncci_state == IDLE)
7098 if((plci->State==IDLE || plci->State==SUSPENDING) && !plci->channels){
7099 if(plci->State == SUSPENDING){
7104 "ws", (word)3, "\x03\x04\x00\x00");
7105 sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
7112 else if (plci->channels)
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)))
7119 sig_req(plci,HANGUP,0);
7121 plci->State = OUTG_DIS_PENDING;
7126 a->ncci_state[ncci] = INC_RES_PENDING;
7127 sendf(plci->appl,_RESET_B3_I,Id,0,"S",plci->ncpi_buffer);
7130 a->ncci_state[ncci] = CONNECTED;
7131 sendf(plci->appl,_RESET_B3_I,Id,0,"S",plci->ncpi_buffer);
7135 if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f))))
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;
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))
7152 if ((a->ncci_state[ncci] != CONNECTED)
7153 && (a->ncci_state[ncci] != OUTG_DIS_PENDING)
7154 && (a->ncci_state[ncci] != OUTG_REJ_PENDING))
7156 dbug(1,dprintf("flow control"));
7157 plci->NL.RNR = 1; /* flow control */
7158 channel_x_off (plci, ch, 0);
7162 NCCIcode = ncci | (((word)a->Id) << 8);
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 */
7170 for(i=0; i<APPLptr->MaxBuffer; i++) {
7171 if(NCCIcode==APPLptr->DataNCCI[i]) count++;
7172 if(!APPLptr->DataNCCI[i] && Num==0xffff) Num = i;
7175 if(count>=APPLptr->MaxNCCIData || Num==0xffff)
7177 dbug(3,dprintf("Flow-Control"));
7179 if( ++(APPLptr->NCCIDataFlowCtrlTimer)>=
7180 (word)((a->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) ? 40 : 2000))
7183 dbug(3,dprintf("DiscardData"));
7185 channel_x_off (plci, ch, 0);
7191 APPLptr->NCCIDataFlowCtrlTimer = 0;
7194 plci->RData[0].P = ReceiveBufferGet(APPLptr,Num);
7195 if(!plci->RData[0].P) {
7197 channel_x_off (plci, ch, 0);
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));
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)))
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;
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;
7229 if((plci->NL.Ind &0x0f)==N_UDATA)
7230 plci->RFlags |= 0x0010;
7232 else if ((plci->B3_prot == B3_RTP) && ((plci->NL.Ind & 0x0f) == N_BDATA))
7233 plci->RFlags |= 0x0001;
7239 data_ack (plci, ch);
7247 /*------------------------------------------------------------------*/
7248 /* find a free PLCI */
7249 /*------------------------------------------------------------------*/
7251 word get_plci(DIVA_CAPI_ADAPTER * 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"));
7263 plci->Id = (byte)(i+1);
7271 plci->relatedPTYPLCI = NULL;
7273 plci->SuppState = IDLE;
7276 plci->B1_resource = 0;
7281 plci->m_command = 0;
7282 init_internal_command_queue (plci);
7284 plci->req_in_start = 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;
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;
7298 plci->manufacturer = FALSE;
7299 plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
7300 plci->spoofed_msg = 0;
7302 plci->cr_enquiry = FALSE;
7303 plci->hangup_flow_ctrl_timer = 0;
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;
7314 plci->requested_options_conn = 0;
7315 plci->requested_options = 0;
7316 plci->notifiedcall = 0;
7317 plci->vswitchstate = 0;
7319 plci->vsprotdialect = 0;
7320 init_b1_config (plci);
7321 dbug(1,dprintf("get_plci(%x)",plci->Id));
7325 /*------------------------------------------------------------------*/
7326 /* put a parameter in the parameter buffer */
7327 /*------------------------------------------------------------------*/
7329 static void add_p(PLCI * plci, byte code, byte * p)
7334 if(p) p_length = p[0];
7335 add_ie(plci, code, p, p_length);
7338 /*------------------------------------------------------------------*/
7339 /* put a structure in the parameter buffer */
7340 /*------------------------------------------------------------------*/
7341 static void add_s(PLCI * plci, byte code, API_PARSE * p)
7343 if(p) add_ie(plci, code, p->info, (word)p->length);
7346 /*------------------------------------------------------------------*/
7347 /* put multiple structures in the parameter buffer */
7348 /*------------------------------------------------------------------*/
7349 static void add_ss(PLCI * plci, byte code, API_PARSE * 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]);
7362 /*------------------------------------------------------------------*/
7363 /* return the channel number sent by the application in a esc_chi */
7364 /*------------------------------------------------------------------*/
7365 static byte getChannel(API_PARSE * p)
7370 for(i=2;i<(byte)p->length;i+=p->info[i]+2){
7372 if(p->info[i-1]==ESC && p->info[i+1]==CHI) return (p->info[i+2]);
7380 /*------------------------------------------------------------------*/
7381 /* put an information element in the parameter buffer */
7382 /*------------------------------------------------------------------*/
7384 static void add_ie(PLCI * plci, byte code, byte * p, word p_length)
7388 if(!(code &0x80) && !p_length) return;
7390 if(plci->req_in==plci->req_in_start) {
7396 plci->RBuffer[plci->req_in++] = code;
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];
7403 plci->RBuffer[plci->req_in++] = 0;
7406 /*------------------------------------------------------------------*/
7407 /* put a unstructured data into the buffer */
7408 /*------------------------------------------------------------------*/
7410 void add_d(PLCI * plci, word length, byte * p)
7414 if(plci->req_in==plci->req_in_start) {
7420 for(i=0;i<length;i++) plci->RBuffer[plci->req_in++] = p[i];
7423 /*------------------------------------------------------------------*/
7424 /* put parameters from the Additional Info parameter in the */
7425 /* parameter buffer */
7426 /*------------------------------------------------------------------*/
7428 void add_ai(PLCI * plci, API_PARSE * ai)
7431 API_PARSE ai_parms[5];
7433 for(i=0;i<5;i++) ai_parms[i].length = 0;
7437 if(api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
7440 add_s (plci,KEY,&ai_parms[1]);
7441 add_s (plci,UUI,&ai_parms[2]);
7442 add_ss(plci,FTY,&ai_parms[3]);
7445 /*------------------------------------------------------------------*/
7446 /* put parameter for b1 protocol in the parameter buffer */
7447 /*------------------------------------------------------------------*/
7449 word add_b1(PLCI * plci, API_PARSE * bp, word b_channel_info, word b1_facilities)
7451 API_PARSE bp_parms[8];
7452 API_PARSE mdm_cfg[9];
7453 API_PARSE global_config[2];
7455 byte resource[] = {5,9,13,12,16,39,9,17,17,18};
7456 byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08";
7459 API_PARSE mdm_cfg_v18[4];
7464 for(i=0;i<8;i++) bp_parms[i].length = 0;
7465 for(i=0;i<2;i++) global_config[i].length = 0;
7467 dbug(1,dprintf("add_b1"));
7468 api_save_msg(bp, "s", &plci->B_protocol);
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)"));
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)"));
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]));
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;
7502 plci->B1_resource = 0x5;
7503 adjust_b1_facilities (plci, plci->B1_resource, b1_facilities);
7504 add_p(plci, CAI, "\x01\x05");
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))
7512 bp_parms[6].length = 0;
7513 if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
7515 dbug(1,dprintf("b-form.!"));
7516 return _WRONG_MESSAGE_FORMAT;
7519 else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
7521 dbug(1,dprintf("b-form.!"));
7522 return _WRONG_MESSAGE_FORMAT;
7525 if(bp_parms[6].length)
7527 if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
7529 return _WRONG_MESSAGE_FORMAT;
7531 switch(GET_WORD(global_config[0].info))
7534 plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
7537 plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
7541 dbug(1,dprintf("call_dir=%04x", plci->call_dir));
7544 if ((GET_WORD(bp_parms[0].info) == B1_RTP)
7545 && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
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;
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);
7562 if ((GET_WORD(bp_parms[0].info) == B1_PIAFS)
7563 && (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))
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;
7571 PUT_WORD(&cai[5],plci->appl->MaxDataLength);
7573 add_p(plci, CAI, cai);
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)))))
7584 return _B1_NOT_SUPPORTED;
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));
7590 cai[1] = plci->B1_resource;
7591 for (i=2;i<sizeof(cai);i++) cai[i] = 0;
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))
7597 for (i=0;i<7;i++) mdm_cfg[i].length = 0;
7599 if (bp_parms[3].length)
7601 if(api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwww", mdm_cfg))
7603 return (_WRONG_MESSAGE_FORMAT);
7606 cai[2] = 0; /* Bit rate for adaptation */
7608 dbug(1,dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg[0].info)));
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 */
7615 cai[3] = 0; /* Async framing parameters */
7616 switch (GET_WORD (mdm_cfg[2].info))
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"));
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"));
7629 dbug(1,dprintf("MDM: no parity"));
7633 switch (GET_WORD (mdm_cfg[3].info))
7635 case 1: /* 2 stop bits */
7636 cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
7637 dbug(1,dprintf("MDM: 2 stop bits"));
7641 dbug(1,dprintf("MDM: 1 stop bit"));
7645 switch (GET_WORD (mdm_cfg[1].info))
7648 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
7649 dbug(1,dprintf("MDM: 5 bits"));
7653 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
7654 dbug(1,dprintf("MDM: 6 bits"));
7658 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
7659 dbug(1,dprintf("MDM: 7 bits"));
7663 dbug(1,dprintf("MDM: 8 bits"));
7667 cai[7] = 0; /* Line taking options */
7668 cai[8] = 0; /* Modulation negotiation options */
7669 cai[9] = 0; /* Modulation options */
7671 if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0))
7673 cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION;
7674 dbug(1, dprintf("MDM: Reverse direction"));
7677 if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN)
7679 cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN;
7680 dbug(1, dprintf("MDM: Disable retrain"));
7683 if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE)
7685 cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE;
7686 dbug(1, dprintf("MDM: Disable ring tone"));
7689 if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_1800)
7691 cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ;
7692 dbug(1, dprintf("MDM: 1800 guard tone"));
7694 else if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_550 )
7696 cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ;
7697 dbug(1, dprintf("MDM: 550 guard tone"));
7700 if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100)
7702 cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100;
7703 dbug(1, dprintf("MDM: V100"));
7705 else if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS)
7707 cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS;
7708 dbug(1, dprintf("MDM: IN CLASS"));
7710 else if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED)
7712 cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED;
7713 dbug(1, dprintf("MDM: DISABLED"));
7717 if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18))
7718 && (GET_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */
7720 plci->requested_options |= 1L << PRIVATE_V18;
7722 if (GET_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */
7723 plci->requested_options |= 1L << PRIVATE_VOWN;
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)))
7728 if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwws", mdm_cfg))
7731 if (mdm_cfg[6].length >= 4)
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)
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)
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);
7751 if (mdm_cfg[6].length >= 14)
7753 w = GET_WORD(&mdm_cfg[6].info[13]);
7755 PUT_WORD(&cai[13], w); /* min tx speed */
7756 if (mdm_cfg[6].length >= 16)
7758 w = GET_WORD(&mdm_cfg[6].info[15]);
7760 PUT_WORD(&cai[15], w); /* max tx speed */
7761 if (mdm_cfg[6].length >= 18)
7763 w = GET_WORD(&mdm_cfg[6].info[17]);
7765 PUT_WORD(&cai[17], w); /* min rx speed */
7766 if (mdm_cfg[6].length >= 20)
7768 w = GET_WORD(&mdm_cfg[6].info[19]);
7770 PUT_WORD(&cai[19], w); /* max rx speed */
7771 if (mdm_cfg[6].length >= 22)
7773 w = GET_WORD(&mdm_cfg[6].info[21]);
7774 cai[23] = (byte)(-((short) w)); /* transmit level */
7775 if (mdm_cfg[6].length >= 24)
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 */
7791 if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwwss", mdm_cfg))
7793 if (!api_parse(&mdm_cfg[7].info[1],(word)mdm_cfg[7].length,"sss", mdm_cfg_v18))
7795 for (n = 0; n < 3; n++)
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];
7804 cai[0] = (byte)(i - 1);
7810 if(GET_WORD(bp_parms[0].info)==2 || /* V.110 async */
7811 GET_WORD(bp_parms[0].info)==3 ) /* V.110 sync */
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 */
7818 if(GET_WORD(bp_parms[0].info)==3){ /* V.110 sync 56k */
7819 dbug(1,dprintf("56k sync HSCX"));
7824 else if(GET_WORD(bp_parms[0].info)==2){
7825 dbug(1,dprintf("56k async DSP"));
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 */
7853 return _B1_PARM_NOT_SUPPORTED;
7856 if (cai[1] == 13) /* v.110 async */
7858 if (bp_parms[3].length >= 8)
7860 switch (GET_WORD (&bp_parms[3].info[3]))
7863 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
7866 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
7869 cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
7872 switch (GET_WORD (&bp_parms[3].info[5]))
7874 case 1: /* odd parity */
7875 cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
7877 case 2: /* even parity */
7878 cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
7881 switch (GET_WORD (&bp_parms[3].info[7]))
7883 case 1: /* 2 stop bits */
7884 cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
7890 else if(cai[1]==8 || GET_WORD(bp_parms[0].info)==3 ){
7891 dbug(1,dprintf("V.110 default 56k sync"));
7897 dbug(1,dprintf("V.110 default 9600 async"));
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]); */
7905 add_p(plci, CAI, cai);
7909 /*------------------------------------------------------------------*/
7910 /* put parameter for b2 and B3 protocol in the parameter buffer */
7911 /*------------------------------------------------------------------*/
7913 word add_b23(PLCI * plci, API_PARSE * bp)
7915 word i, fax_control_bits;
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];
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};
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};
7934 const byte llc3[] = {4,3,2,2,6,6,0};
7935 const byte header[] = {0,2,3,3,0,0,0};
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;
7943 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
7945 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
7948 if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
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++;
7955 if (plci->rx_dma_descriptor > 0) {
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);
7966 if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
7970 dbug(1,dprintf("add_b23"));
7971 api_save_msg(bp, "s", &plci->B_protocol);
7973 if(!bp->length && plci->tel)
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*/;
7982 add_p(plci, LLC, llc);
7984 PUT_WORD(&dlc[1],plci->appl->MaxDataLength);
7985 add_p(plci, DLC, dlc);
7989 if(!bp->length) /*default*/
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*/;
7997 add_p(plci, LLC, llc);
7999 PUT_WORD(&dlc[1],plci->appl->MaxDataLength);
8000 add_p(plci, DLC, dlc);
8003 dbug(1,dprintf("b_prot_len=%d",(word)bp->length));
8004 if((word)bp->length > 256) return _WRONG_MESSAGE_FORMAT;
8006 if(api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
8008 bp_parms[6].length = 0;
8009 if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
8011 dbug(1,dprintf("b-form.!"));
8012 return _WRONG_MESSAGE_FORMAT;
8015 else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
8017 dbug(1,dprintf("b-form.!"));
8018 return _WRONG_MESSAGE_FORMAT;
8021 if(plci->tel==ADV_VOICE) /* transparent B on advanced voice */
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;
8027 else if(plci->tel) return _B2_NOT_SUPPORTED;
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)))
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;
8039 add_p(plci, LLC, llc);
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);
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)))))
8067 return _B2_NOT_SUPPORTED;
8069 if ((GET_WORD(bp_parms[2].info) >= 32)
8070 || !((1L << GET_WORD(bp_parms[2].info)) & plci->adapter->profile.B3_Protocols))
8072 return _B3_NOT_SUPPORTED;
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)))
8079 return (add_modem_b23 (plci, bp_parms));
8082 add_p(plci,LLI,lli);
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 */
8088 if(bp_parms[6].length)
8090 if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
8092 return _WRONG_MESSAGE_FORMAT;
8094 switch(GET_WORD(global_config[0].info))
8097 plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
8100 plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
8104 dbug(1,dprintf("call_dir=%04x", plci->call_dir));
8107 if (plci->B2_prot == B2_PIAFS)
8110 /* IMPLEMENT_PIAFS */
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)];
8115 llc[2] = llc3[GET_WORD(bp_parms[2].info)];
8117 add_p(plci, LLC, llc);
8120 PUT_WORD(&dlc[1], plci->appl->MaxDataLength +
8121 header[GET_WORD(bp_parms[2].info)]);
8123 b1_config = &bp_parms[3];
8125 if(plci->B3_prot == 4
8126 || plci->B3_prot == 5)
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)
8135 ((T30_INFO *)&nlc[1])->rate_div_2400 = (byte)(GET_WORD(&b1_config->info[1])/2400);
8138 b2_config = &bp_parms[4];
8141 if (llc[1] == PIAFS_CRC)
8143 if (plci->B3_prot != B3_TRANSPARENT)
8145 return _B_STACK_NOT_SUPPORTED;
8147 if(b2_config->length && api_parse(&b2_config->info[1], (word)b2_config->length, "bwww", b2_config_parms)) {
8148 return _WRONG_MESSAGE_FORMAT;
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){
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 */
8166 if(b2_config->length >= 8) { /* PIAFS control abilities */
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 */
8174 else /* default values, 64K, variable, no compression */
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 */
8187 add_p(plci, DLC, dlc);
8191 if ((llc[1] == V120_L2) || (llc[1] == V120_V42BIS))
8193 if (plci->B3_prot != B3_TRANSPARENT)
8194 return _B_STACK_NOT_SUPPORTED;
8197 PUT_WORD (&dlc[1], GET_WORD (&dlc[1]) + 2);
8202 if (b2_config->length != 0)
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;
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)
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;
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){
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];
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]));
8239 if(b2_config->length)
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))
8245 return _WRONG_MESSAGE_FORMAT;
8249 if(api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbs", b2_config_parms))
8251 return _WRONG_MESSAGE_FORMAT;
8254 /* if B2 Protocol is LAPD, b2_config structure is different */
8258 if(b2_config->length>=1) dlc[2] = b2_config->info[1]; /* TEI */
8260 if( (b2_config->length>=2) && (plci->B2_prot==12) )
8262 SAPI = b2_config->info[2]; /* SAPI */
8265 if( (b2_config->length>=3) && (b2_config->info[3]==128) )
8267 dlc[3] = 127; /* Mode */
8271 dlc[3] = 7; /* Mode */
8274 if(b2_config->length>=4) dlc[4] = b2_config->info[4]; /* Window */
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;
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;
8289 dlc[5] = (byte)(b2_config->info[3]-1);
8290 dlc[6] = b2_config->info[4];
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;
8296 if(llc[1]==X75_V42BIS) {
8297 if (b2_config->length >= 10){
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];
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]));
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];
8324 add_p(plci, DLC, dlc);
8326 b3_config = &bp_parms[5];
8327 if(b3_config->length)
8329 if(plci->B3_prot == 4
8330 || plci->B3_prot == 5)
8332 if(api_parse(&b3_config->info[1], (word)b3_config->length, "wwss", b3_config_parms))
8334 return _WRONG_MESSAGE_FORMAT;
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)
8346 if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
8347 & (1L << PRIVATE_FAX_PAPER_FORMATS))
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;
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);
8359 if(plci->B3_prot == 5)
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)
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);
8378 /* copy station id to NLC */
8381 if(i<b3_config_parms[2].length)
8383 ((T30_INFO *)&nlc[1])->station_id[i] = ((byte *)b3_config_parms[2].info)[1+i];
8387 ((T30_INFO *)&nlc[1])->station_id[i] = ' ';
8390 ((T30_INFO *)&nlc[1])->station_id_len = 20;
8391 /* copy head line to NLC */
8392 if(b3_config_parms[3].length)
8395 pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20])));
8398 if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
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;
8407 if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
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++] = ' ';
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];
8426 ((T30_INFO *)&nlc[1])->head_line_len = 0;
8428 plci->nsf_control_bits = 0;
8429 if(plci->B3_prot == 5)
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 */
8434 plci->requested_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
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 */
8439 plci->requested_options |= 1L << PRIVATE_FAX_NONSTANDARD;
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)))
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))
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;
8452 pos = ((byte)(((T30_INFO *) 0)->station_id + 20));
8453 if (pos < plci->fax_connect_info_length)
8455 for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
8456 nlc[++len] = plci->fax_connect_info_buffer[pos++];
8460 if (pos < plci->fax_connect_info_length)
8462 for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
8463 nlc[++len] = plci->fax_connect_info_buffer[pos++];
8467 if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
8468 & (1L << PRIVATE_FAX_NONSTANDARD))
8470 if ((pos < plci->fax_connect_info_length) && (plci->fax_connect_info_buffer[pos] != 0))
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++];
8479 if(api_parse(&b3_config->info[1], (word)b3_config->length, "wwsss", b3_config_parms))
8481 dbug(1,dprintf("non-standard facilities info missing or wrong format"));
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];
8495 if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
8496 && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
8498 ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI_NEG;
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;
8510 plci->fax_connect_info_buffer[len++] = nlc[++i];
8511 plci->fax_connect_info_length = len;
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];
8529 if (plci->B3_prot == 4
8530 || plci->B3_prot == 5 /*T.30 - FAX*/ ) return _B3_PARM_NOT_SUPPORTED;
8532 add_p(plci, NLC, nlc);
8536 /*----------------------------------------------------------------*/
8537 /* make the same as add_b23, but only for the modem related */
8538 /* L2 and L3 B-Chan protocol. */
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: */
8550 /*----------------------------------------------------------------*/
8551 static word add_modem_b23 (PLCI * plci, API_PARSE* bp_parms)
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];
8560 for(i=0;i<2;i++) mdm_config[i].length = 0;
8561 for(i=0;i<sizeof(dlc);i++) dlc[i] = 0;
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)))
8568 return (_B_STACK_NOT_SUPPORTED);
8570 if ((GET_WORD(bp_parms[2].info) != B3_MODEM)
8571 && (GET_WORD(bp_parms[2].info) != B3_TRANSPARENT))
8573 return (_B_STACK_NOT_SUPPORTED);
8576 plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
8577 plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
8579 if ((GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) && bp_parms[4].length)
8581 if (api_parse (&bp_parms[4].info[1],
8582 (word)bp_parms[4].length, "w",
8585 return (_WRONG_MESSAGE_FORMAT);
8587 b2_config = GET_WORD(mdm_config[0].info);
8590 /* OK, L2 is modem */
8594 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
8596 if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
8599 if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
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++;
8606 if (plci->rx_dma_descriptor > 0) {
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);
8617 if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
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);
8627 PUT_WORD (&dlc[i], plci->appl->MaxDataLength);
8629 if (GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION)
8631 if (bp_parms[4].length)
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 */
8641 if (b2_config & MDM_B2_DISABLE_V42bis)
8643 dlc[i] |= DLC_MODEMPROT_DISABLE_V42_V42BIS;
8645 if (b2_config & MDM_B2_DISABLE_MNP)
8647 dlc[i] |= DLC_MODEMPROT_DISABLE_MNP_MNP5;
8649 if (b2_config & MDM_B2_DISABLE_TRANS)
8651 dlc[i] |= DLC_MODEMPROT_REQUIRE_PROTOCOL;
8653 if (b2_config & MDM_B2_DISABLE_V42)
8655 dlc[i] |= DLC_MODEMPROT_DISABLE_V42_DETECT;
8657 if (b2_config & MDM_B2_DISABLE_COMP)
8659 dlc[i] |= DLC_MODEMPROT_DISABLE_COMPRESSION;
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;
8677 dlc[0] = (byte)(i - 1);
8678 /* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
8679 add_p(plci, DLC, dlc);
8684 /*------------------------------------------------------------------*/
8685 /* send a request for the signaling entity */
8686 /*------------------------------------------------------------------*/
8688 void sig_req(PLCI * plci, byte req, byte Id)
8691 if(plci->adapter->adapter_disabled) return;
8692 dbug(1,dprintf("sig_req(%x)",req));
8694 plci->sig_remove_id = plci->Sig.Id;
8695 if(plci->req_in==plci->req_in_start) {
8697 plci->RBuffer[plci->req_in++] = 0;
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;
8706 /*------------------------------------------------------------------*/
8707 /* send a request for the network layer entity */
8708 /*------------------------------------------------------------------*/
8710 void nl_req_ncci(PLCI * plci, byte req, byte ncci)
8713 if(plci->adapter->adapter_disabled) return;
8714 dbug(1,dprintf("nl_req %02x %02x %02x", plci->Id, req, ncci));
8717 plci->nl_remove_id = plci->NL.Id;
8718 ncci_remove (plci, 0, (byte)(ncci != 0));
8721 if(plci->req_in==plci->req_in_start) {
8723 plci->RBuffer[plci->req_in++] = 0;
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;
8732 void send_req(PLCI * plci)
8739 if(plci->adapter->adapter_disabled) return;
8740 channel_xmit_xon (plci);
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));
8746 if(plci->nl_req || plci->sig_req) return;
8748 l = GET_WORD(&plci->RBuffer[plci->req_out]);
8750 plci->XData[0].P = &plci->RBuffer[plci->req_out];
8752 if(plci->RBuffer[plci->req_out]==1)
8756 e->Req = plci->nl_req = plci->RBuffer[plci->req_out++];
8757 e->ReqCh = plci->RBuffer[plci->req_out++];
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;
8766 plci->nl_global_req = plci->nl_req;
8768 dbug(1,dprintf("%x:NLREQ(%x:%x:%x)",plci->adapter->Id,e->Id,e->Req,e->ReqCh));
8773 if(plci->RBuffer[plci->req_out])
8774 e->Id = plci->RBuffer[plci->req_out];
8776 e->Req = plci->sig_req = plci->RBuffer[plci->req_out++];
8777 e->ReqCh = plci->RBuffer[plci->req_out++];
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));
8782 plci->XData[0].PLength = l;
8784 plci->adapter->request(e);
8785 dbug(1,dprintf("send_ok"));
8788 void send_data(PLCI * plci)
8790 DIVA_CAPI_ADAPTER * a;
8791 DATA_B3_DESC * data;
8795 if (!plci->nl_req && plci->ncci_ring_list)
8798 ncci = plci->ncci_ring_list;
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)))
8806 if (ncci_ptr->data_pending)
8808 if ((a->ncci_state[ncci] == CONNECTED)
8809 || (a->ncci_state[ncci] == INC_ACT_PENDING)
8810 || (plci->send_disc == ncci))
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))
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;
8822 plci->NData[0].P = v120_default_header;
8823 plci->NData[0].PLength = 1 ;
8825 plci->NL.Req = plci->nl_req = (byte)((data->Flags&0x07)<<4 |N_DATA);
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;
8834 else if ((plci->B3_prot == B3_RTP) && (data->Flags & 0x01))
8835 plci->NL.Req = plci->nl_req = (byte)N_BDATA;
8838 plci->NL.Req = plci->nl_req = (byte)((data->Flags&0x07)<<4 |N_DATA);
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);
8848 cleanup_ncci_data (plci, ncci);
8851 else if (plci->send_disc == ncci)
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;
8862 } while (!plci->nl_req && (ncci != plci->ncci_ring_list));
8863 plci->ncci_ring_list = ncci;
8867 void listen_check(DIVA_CAPI_ADAPTER * a)
8871 byte activnotifiedcalls = 0;
8873 dbug(1,dprintf("listen_check(%d,%d)",a->listen_active,a->max_listen));
8874 if (!remove_started && !a->adapter_disabled)
8876 for(i=0;i<a->max_plci;i++)
8878 plci = &(a->plci[i]);
8879 if(plci->notifiedcall) activnotifiedcalls++;
8881 dbug(1,dprintf("listen_check(%d)",activnotifiedcalls));
8883 for(i=a->listen_active; i < ((word)(a->max_listen+activnotifiedcalls)); i++) {
8884 if((j=get_plci(a))) {
8886 plci = &a->plci[j-1];
8887 plci->State = LISTENING;
8889 add_p(plci,OAD,"\x01\xfd");
8891 add_p(plci,KEY,"\x04\x43\x41\x32\x30");
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);
8906 /*------------------------------------------------------------------*/
8907 /* functions for all parameters sent in INDs */
8908 /*------------------------------------------------------------------*/
8910 void IndParse(PLCI * plci, word * parms_id, byte ** parms, byte multiIEsize)
8912 word ploc; /* points to current location within packet */
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 *)"";
8929 for(i=0; i<multiIEsize; i++)
8931 parms[i] = (byte *)"";
8934 while(ploc<plci->Sig.RBuffer->length-1) {
8936 /* read information element id and length */
8940 /* w &=0xf0; removed, cannot detect congestion levels */
8941 /* upper 4 bit masked with w==SHIFT now */
8945 wlen = (byte)(in[ploc+1]+1);
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;
8952 if((w&0xf0)==SHIFT) {
8954 if(!(codeset & 0x08)) lock = (byte)(codeset & 7);
8959 if(w==ESC && wlen>=3) code = in[ploc+2] |0x800;
8961 code |= (codeset<<8);
8963 for(i=1; i<parms_id[0]+1 && parms_id[i]!=code; i++);
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 */
8970 parms[mIEindex] = &in[ploc+1];
8971 dbug(1,dprintf("mIE[%d]=0x%x",*parms[mIEindex],in[ploc]));
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);
8979 parms[mIEindex] = &in[ploc];
8982 mIEindex++; /* effects multiIEs only */
8991 /*------------------------------------------------------------------*/
8992 /* try to match a cip from received BC and HLC */
8993 /*------------------------------------------------------------------*/
8995 byte ie_compare(byte * ie1, byte * ie2)
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;
9004 word find_cip(DIVA_CAPI_ADAPTER * a, byte * bc, byte * hlc)
9009 for(i=9;i && !ie_compare(bc,cip_bc[i][a->u_law]);i--);
9012 (!ie_compare(bc,cip_bc[j][a->u_law]) || !ie_compare(hlc,cip_hlc[j])); j++);
9018 static byte AddInfo(byte **add_i,
9028 /* facility is a nested structure */
9029 /* FTY can be more than once */
9031 if(esc_chi[0] && !(esc_chi[esc_chi[0]])&0x7f )
9033 add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */
9038 add_i[0] = (byte *)"";
9042 add_i[3] = (byte *)"";
9045 { /* facility array found */
9046 for(i=0,j=1;i<MAX_MULTI_IE && fty_i[i][0];i++)
9048 dbug(1,dprintf("AddIFac[%d]",fty_i[i][0]));
9052 facility[j++]=0x1c; /* copy fac IE */
9053 for(k=0;k<=flen;k++,j++)
9055 facility[j]=fty_i[i][k];
9056 /* dbug(1,dprintf("%x ",facility[j])); */
9060 add_i[3] = facility;
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 */
9068 /*------------------------------------------------------------------*/
9069 /* voice and codec features */
9070 /*------------------------------------------------------------------*/
9072 void SetVoiceChannel(PLCI *plci, byte *chi, DIVA_CAPI_ADAPTER * a)
9074 byte voice_chi[] = "\x02\x18\x01";
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);
9084 if(a->AdvSignalPLCI)
9086 adv_voice_write_coefs (a->AdvSignalPLCI, ADV_VOICE_WRITE_ACTIVATION);
9090 void VoiceChannelOff(PLCI *plci)
9092 dbug(1,dprintf("ExtDevOFF"));
9093 add_p(plci,FTY,"\x02\x01\x08"); /* B Off */
9094 sig_req(plci,TEL_CTRL,0);
9096 if(plci->adapter->AdvSignalPLCI)
9098 adv_voice_clear_config (plci->adapter->AdvSignalPLCI);
9103 word AdvCodecSupport(DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, byte hook_listen)
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 */
9112 /* diva Pro with on-board codec: */
9113 if(a->profile.Global_Options & HANDSET)
9115 /* new call, but hook states are already signalled */
9118 if(a->AdvSignalAppl!=appl || a->AdvSignalPLCI)
9120 dbug(1,dprintf("AdvSigPlci=0x%x",a->AdvSignalPLCI));
9121 return 0x2001; /* codec in use by another application */
9125 a->AdvSignalPLCI = plci;
9126 plci->tel=ADV_VOICE;
9128 return 0; /* adv codec still used */
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;
9141 splci->State = ADVANCED_VOICE_NOSIG;
9144 plci->spoofed_msg = SPOOFING_REQUIRED;
9146 /* indicate D-ch connect if */
9147 } /* codec is connected OK */
9150 a->AdvSignalPLCI = plci;
9151 plci->tel=ADV_VOICE;
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);
9167 return 0x2001; /* wrong state, no more plcis */
9170 else if(a->profile.Global_Options & ON_BOARD_CODEC)
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 */
9186 a->scom_appl_disable = TRUE;
9189 return 0x2001; /* wrong state, no more plcis */
9193 else return 0x300B; /* Facility not supported */
9199 void CodecIdCheck(DIVA_CAPI_ADAPTER *a, PLCI *plci)
9202 dbug(1,dprintf("CodecIdCheck"));
9204 if(a->AdvSignalPLCI == plci)
9206 dbug(1,dprintf("PLCI owns codec"));
9207 VoiceChannelOff(a->AdvCodecPLCI);
9208 if(a->AdvCodecPLCI->State == ADVANCED_VOICE_NOSIG)
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;
9216 a->AdvSignalPLCI = NULL;
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) {
9226 if (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR) {
9227 ENTITY * e = (ENTITY *)preq;
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;
9236 a->sdram_bar = preq->xdi_sdram_bar.info.bar;
9237 dbug(3,dprintf("A(%d) SDRAM BAR = %08x", a->Id, a->sdram_bar));
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)];
9249 preq = (IDI_SYNC_REQ *)&buffer[0];
9251 if (!diva_xdi_extended_features) {
9252 ENTITY * e = (ENTITY *)preq;
9253 diva_xdi_extended_features |= 0x80000000;
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];
9263 if (features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) {
9265 Check features located in the byte '0'
9267 if (features[0] & DIVA_XDI_EXTENDED_FEATURE_CMA) {
9268 diva_xdi_extended_features |= DIVA_CAPI_USE_CMA;
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"));
9274 if (features[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR) {
9275 diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR;
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"));
9285 diva_ask_for_xdi_sdram_bar (a, preq);
9288 /*------------------------------------------------------------------*/
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)
9298 if(a->automatic_law) {
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;
9311 sig_req(splci,ASSIGN,DSIG_ID);
9316 /* called from OS specific part if an application sends an Capi20Release */
9317 word CapiRelease(word Id)
9319 word i, j, appls_found;
9322 DIVA_CAPI_ADAPTER *a;
9326 dbug(0,dprintf("A: CapiRelease(Id==0)"));
9327 return (_WRONG_APPL_ID);
9330 this = &application[Id-1]; /* get application pointer */
9332 for(i=0,appls_found=0; i<max_appl; i++)
9334 if(application[i].Id) /* an application has been found */
9340 for(i=0; i<max_adapter; i++) /* scan all adapters... */
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 */
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)
9358 if(test_c_ind_mask_bit (plci, (word)(Id-1)))
9360 clear_c_ind_mask_bit (plci, (word)(Id-1));
9361 if(c_ind_mask_empty (plci))
9363 sig_req(plci,HANGUP,0);
9365 plci->State = OUTG_DIS_PENDING;
9369 if(test_c_ind_mask_bit (plci, (word)(Id-1)))
9371 clear_c_ind_mask_bit (plci, (word)(Id-1));
9372 if(c_ind_mask_empty (plci))
9381 if(plci->appl==this)
9391 if(a->flag_dynamic_l1_down)
9393 if(appls_found==1) /* last application does a capi release */
9397 plci = &a->plci[j-1];
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);
9412 if(a->AdvSignalAppl==this)
9414 this->NullCREnable = FALSE;
9415 if (a->AdvCodecPLCI)
9417 plci_remove(a->AdvCodecPLCI);
9418 a->AdvCodecPLCI->tel = 0;
9419 a->AdvCodecPLCI->adv_nl = 0;
9421 a->AdvSignalAppl = NULL;
9422 a->AdvSignalPLCI = NULL;
9423 a->AdvCodecFLAG = 0;
9424 a->AdvCodecPLCI = NULL;
9434 static word plci_remove_check(PLCI *plci)
9436 if(!plci) return TRUE;
9437 if(!plci->NL.Id && c_ind_mask_empty (plci))
9439 if(plci->Sig.Id == 0xff)
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));
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);
9456 plci->notifiedcall = 0;
9458 listen_check(plci->adapter);
9466 /*------------------------------------------------------------------*/
9468 static byte plci_nl_busy (PLCI *plci)
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)));
9478 /*------------------------------------------------------------------*/
9479 /* DTMF facilities */
9480 /*------------------------------------------------------------------*/
9489 } dtmf_digit_map[] =
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 },
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 },
9567 #define DTMF_DIGIT_MAP_ENTRIES (sizeof(dtmf_digit_map) / sizeof(dtmf_digit_map[0]))
9570 static void dtmf_enable_receiver (PLCI *plci, byte enable_mask)
9572 word min_digit_duration, min_gap_duration;
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));
9578 if (enable_mask != 0)
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;
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);
9594 plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER;
9595 plci->NData[0].PLength = 1;
9597 capidtmf_recv_disable (&(plci->capidtmf_state));
9600 plci->NData[0].P = plci->internal_req_buffer;
9601 plci->NL.X = plci->NData;
9603 plci->NL.Req = plci->nl_req = (byte) N_UDATA;
9604 plci->adapter->request (&plci->NL);
9608 static void dtmf_send_digits (PLCI *plci, byte *digit_buffer, word digit_count)
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));
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++)
9624 while ((w < DTMF_DIGIT_MAP_ENTRIES)
9625 && (digit_buffer[i] != dtmf_digit_map[w].character))
9629 plci->internal_req_buffer[5+i] = (w < DTMF_DIGIT_MAP_ENTRIES) ?
9630 dtmf_digit_map[w].code : DTMF_DIGIT_TONE_CODE_STAR;
9632 plci->NData[0].PLength = 5 + digit_count;
9633 plci->NData[0].P = plci->internal_req_buffer;
9634 plci->NL.X = plci->NData;
9636 plci->NL.Req = plci->nl_req = (byte) N_UDATA;
9637 plci->adapter->request (&plci->NL);
9641 static void dtmf_rec_clear_config (PLCI *plci)
9644 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_rec_clear_config",
9645 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
9646 (char *)(FILE_), __LINE__));
9648 plci->dtmf_rec_active = 0;
9649 plci->dtmf_rec_pulse_ms = 0;
9650 plci->dtmf_rec_pause_ms = 0;
9652 capidtmf_init (&(plci->capidtmf_state), plci->adapter->u_law);
9657 static void dtmf_send_clear_config (PLCI *plci)
9660 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_clear_config",
9661 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
9662 (char *)(FILE_), __LINE__));
9664 plci->dtmf_send_requests = 0;
9665 plci->dtmf_send_pulse_ms = 0;
9666 plci->dtmf_send_pause_ms = 0;
9670 static void dtmf_prepare_switch (dword Id, PLCI *plci)
9673 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_prepare_switch",
9674 UnMapId (Id), (char *)(FILE_), __LINE__));
9676 while (plci->dtmf_send_requests != 0)
9677 dtmf_confirmation (Id, plci);
9681 static word dtmf_save_config (dword Id, PLCI *plci, byte Rc)
9684 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_save_config %02x %d",
9685 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
9691 static word dtmf_restore_config (dword Id, PLCI *plci, byte Rc)
9695 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_restore_config %02x %d",
9696 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
9699 if (plci->B1_facilities & B1_FACILITY_DTMFR)
9701 switch (plci->adjust_b_state)
9703 case ADJUST_B_RESTORE_DTMF_1:
9704 plci->internal_command = plci->adjust_b_command;
9705 if (plci_nl_busy (plci))
9707 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
9710 dtmf_enable_receiver (plci, plci->dtmf_rec_active);
9711 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_2;
9713 case ADJUST_B_RESTORE_DTMF_2:
9714 if ((Rc != OK) && (Rc != OK_FC))
9716 dbug (1, dprintf ("[%06lx] %s,%d: Reenable DTMF receiver failed %02x",
9717 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
9718 Info = _WRONG_STATE;
9728 static void dtmf_command (dword Id, PLCI *plci, byte Rc)
9730 word internal_command, Info;
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));
9741 PUT_WORD (&result[1], DTMF_SUCCESS);
9742 internal_command = plci->internal_command;
9743 plci->internal_command = 0;
9745 switch (plci->dtmf_cmd)
9748 case DTMF_LISTEN_TONE_START:
9750 case DTMF_LISTEN_MF_START:
9753 case DTMF_LISTEN_START:
9754 switch (internal_command)
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)
9762 dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed",
9763 UnMapId (Id), (char *)(FILE_), __LINE__));
9764 Info = _FACILITY_NOT_SUPPORTED;
9767 if (plci->internal_command)
9769 case DTMF_COMMAND_2:
9770 if (plci_nl_busy (plci))
9772 plci->internal_command = DTMF_COMMAND_2;
9775 plci->internal_command = DTMF_COMMAND_3;
9776 dtmf_enable_receiver (plci, (byte)(plci->dtmf_rec_active | mask));
9778 case DTMF_COMMAND_3:
9779 if ((Rc != OK) && (Rc != OK_FC))
9781 dbug (1, dprintf ("[%06lx] %s,%d: Enable DTMF receiver failed %02x",
9782 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
9783 Info = _FACILITY_NOT_SUPPORTED;
9787 plci->tone_last_indication_code = DTMF_SIGNAL_NO_TONE;
9789 plci->dtmf_rec_active |= mask;
9795 case DTMF_LISTEN_TONE_STOP:
9797 case DTMF_LISTEN_MF_STOP:
9800 case DTMF_LISTEN_STOP:
9801 switch (internal_command)
9804 plci->dtmf_rec_active &= ~mask;
9805 if (plci->dtmf_rec_active)
9808 case DTMF_COMMAND_1:
9809 if (plci->dtmf_rec_active)
9811 if (plci_nl_busy (plci))
9813 plci->internal_command = DTMF_COMMAND_1;
9816 plci->dtmf_rec_active &= ~mask;
9817 plci->internal_command = DTMF_COMMAND_2;
9818 dtmf_enable_receiver (plci, FALSE);
9822 case DTMF_COMMAND_2:
9823 if ((Rc != OK) && (Rc != OK_FC))
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;
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)
9836 dbug (1, dprintf ("[%06lx] %s,%d: Unload DTMF failed",
9837 UnMapId (Id), (char *)(FILE_), __LINE__));
9838 Info = _FACILITY_NOT_SUPPORTED;
9841 if (plci->internal_command)
9848 case DTMF_SEND_TONE:
9853 case DTMF_DIGITS_SEND:
9854 switch (internal_command)
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)),
9860 case DTMF_COMMAND_1:
9861 if (adjust_b_process (Id, plci, Rc) != GOOD)
9863 dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed",
9864 UnMapId (Id), (char *)(FILE_), __LINE__));
9865 Info = _FACILITY_NOT_SUPPORTED;
9868 if (plci->internal_command)
9870 case DTMF_COMMAND_2:
9871 if (plci_nl_busy (plci))
9873 plci->internal_command = DTMF_COMMAND_2;
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);
9880 case DTMF_COMMAND_3:
9881 if ((Rc != OK) && (Rc != OK_FC))
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;
9894 sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
9895 "wws", Info, SELECTOR_DTMF, result);
9899 static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg)
9904 API_PARSE dtmf_parms[5];
9907 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_request",
9908 UnMapId (Id), (char *)(FILE_), __LINE__));
9912 PUT_WORD (&result[1], DTMF_SUCCESS);
9913 if (!(a->profile.Global_Options & GL_DTMF_SUPPORTED))
9915 dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
9916 UnMapId (Id), (char *)(FILE_), __LINE__));
9917 Info = _FACILITY_NOT_SUPPORTED;
9919 else if (api_parse (&msg[1].info[1], msg[1].length, "w", dtmf_parms))
9921 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
9922 UnMapId (Id), (char *)(FILE_), __LINE__));
9923 Info = _WRONG_MESSAGE_FORMAT;
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))
9929 if (!((a->requested_options_table[appl->Id-1])
9930 & (1L << PRIVATE_DTMF_TONE)))
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);
9938 for (i = 0; i < 32; i++)
9940 if (GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
9942 for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
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));
9950 for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
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));
9961 else if (plci == NULL)
9963 dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
9964 UnMapId (Id), (char *)(FILE_), __LINE__));
9965 Info = _WRONG_IDENTIFIER;
9970 || !plci->NL.Id || plci->nl_remove_id)
9972 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
9973 UnMapId (Id), (char *)(FILE_), __LINE__));
9974 Info = _WRONG_STATE;
9979 plci->dtmf_cmd = GET_WORD (dtmf_parms[0].info);
9981 switch (plci->dtmf_cmd)
9984 case DTMF_LISTEN_TONE_START:
9985 case DTMF_LISTEN_TONE_STOP:
9987 case DTMF_LISTEN_MF_START:
9988 case DTMF_LISTEN_MF_STOP:
9990 if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id-1])
9991 & (1L << PRIVATE_DTMF_TONE)))
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);
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))
10004 dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
10005 UnMapId (Id), (char *)(FILE_), __LINE__));
10006 Info = _FACILITY_NOT_SUPPORTED;
10009 if (mask & DTMF_LISTEN_ACTIVE_FLAG)
10011 if (api_parse (&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
10013 plci->dtmf_rec_pulse_ms = 0;
10014 plci->dtmf_rec_pause_ms = 0;
10018 plci->dtmf_rec_pulse_ms = GET_WORD (dtmf_parms[1].info);
10019 plci->dtmf_rec_pause_ms = GET_WORD (dtmf_parms[2].info);
10022 start_internal_command (Id, plci, dtmf_command);
10026 case DTMF_SEND_TONE:
10030 if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id-1])
10031 & (1L << PRIVATE_DTMF_TONE)))
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);
10039 case DTMF_DIGITS_SEND:
10040 if (api_parse (&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
10042 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
10043 UnMapId (Id), (char *)(FILE_), __LINE__));
10044 Info = _WRONG_MESSAGE_FORMAT;
10047 if (mask & DTMF_LISTEN_ACTIVE_FLAG)
10049 plci->dtmf_send_pulse_ms = GET_WORD (dtmf_parms[1].info);
10050 plci->dtmf_send_pause_ms = GET_WORD (dtmf_parms[2].info);
10054 while ((i < dtmf_parms[3].length) && (j < DTMF_DIGIT_MAP_ENTRIES))
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)))
10065 if (j == DTMF_DIGIT_MAP_ENTRIES)
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);
10072 if (plci->dtmf_send_requests >=
10073 sizeof(plci->dtmf_msg_number_queue) / sizeof(plci->dtmf_msg_number_queue[0]))
10075 dbug (1, dprintf ("[%06lx] %s,%d: DTMF request overrun",
10076 UnMapId (Id), (char *)(FILE_), __LINE__));
10077 Info = _WRONG_STATE;
10080 api_save_msg (dtmf_parms, "wwws", &plci->saved_msg);
10081 start_internal_command (Id, plci, dtmf_command);
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);
10091 sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
10092 "wws", Info, SELECTOR_DTMF, result);
10097 static void dtmf_confirmation (dword Id, PLCI *plci)
10103 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation",
10104 UnMapId (Id), (char *)(FILE_), __LINE__));
10108 PUT_WORD (&result[1], DTMF_SUCCESS);
10109 if (plci->dtmf_send_requests != 0)
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];
10120 static void dtmf_indication (dword Id, PLCI *plci, byte *msg, word length)
10124 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_indication",
10125 UnMapId (Id), (char *)(FILE_), __LINE__));
10128 for (i = 1; i < length; i++)
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)))
10137 if (j < DTMF_DIGIT_MAP_ENTRIES)
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))
10146 for (i = length; i > n + 1; i--)
10147 msg[i] = msg[i - 1];
10151 msg[++n] = DTMF_SIGNAL_UNIDENTIFIED_TONE;
10153 plci->tone_last_indication_code = dtmf_digit_map[j].character;
10155 msg[++n] = dtmf_digit_map[j].character;
10161 sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "wS", SELECTOR_DTMF, msg);
10166 /*------------------------------------------------------------------*/
10167 /* DTMF parameters */
10168 /*------------------------------------------------------------------*/
10170 static void dtmf_parameter_write (PLCI *plci)
10173 byte parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE + 2];
10175 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_write",
10176 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
10177 (char *)(FILE_), __LINE__));
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);
10189 static void dtmf_parameter_clear_config (PLCI *plci)
10192 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_clear_config",
10193 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
10194 (char *)(FILE_), __LINE__));
10196 plci->dtmf_parameter_length = 0;
10200 static void dtmf_parameter_prepare_switch (dword Id, PLCI *plci)
10203 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_prepare_switch",
10204 UnMapId (Id), (char *)(FILE_), __LINE__));
10209 static word dtmf_parameter_save_config (dword Id, PLCI *plci, byte Rc)
10212 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d",
10213 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
10219 static word dtmf_parameter_restore_config (dword Id, PLCI *plci, byte Rc)
10223 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d",
10224 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
10227 if ((plci->B1_facilities & B1_FACILITY_DTMFR)
10228 && (plci->dtmf_parameter_length != 0))
10230 switch (plci->adjust_b_state)
10232 case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
10233 plci->internal_command = plci->adjust_b_command;
10236 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
10239 dtmf_parameter_write (plci);
10240 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_2;
10242 case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
10243 if ((Rc != OK) && (Rc != OK_FC))
10245 dbug (1, dprintf ("[%06lx] %s,%d: Restore DTMF parameters failed %02x",
10246 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
10247 Info = _WRONG_STATE;
10257 /*------------------------------------------------------------------*/
10258 /* Line interconnect facilities */
10259 /*------------------------------------------------------------------*/
10262 LI_CONFIG *li_config_table;
10263 word li_total_channels;
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 /*------------------------------------------------------------------*/
10276 static byte chi_to_channel (byte *chi, dword *pchannelmap)
10285 if (pchannelmap) *pchannelmap = 0;
10286 if(!chi[0]) return 0xff;
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;
10296 /* int. id present */
10299 for(i=p; i<chi[0] && !(chi[i] &0x80); i++);
10300 if(i==chi[0] || !(chi[i] &0x80)) return 0xfe;
10303 /* coding standard, Number/Map, Channel Type */
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;
10313 if((chi[0]-p)==4) ofs = 0;
10314 else if((chi[0]-p)==3) ofs = 1;
10318 for(i=0; i<4 && p<chi[0]; i++) {
10323 for (ch=0; !(chi[p] & (1 << ch)); ch++);
10336 if((byte)(chi[0]-p)>30) return 0xfe;
10338 for(i=p; i<=chi[0]; i++) {
10339 if ((chi[i] &0x7f) > 31) return 0xfe;
10340 map |= (1L << (chi[i] &0x7f));
10344 if(p!=chi[0]) return 0xfe;
10345 if (ch > 31) return 0xfe;
10348 if(chi[p] &0x40) return 0xfe;
10350 if (pchannelmap) *pchannelmap = map;
10351 else if (map != ((dword)(1L << ch))) return 0xfe;
10352 return (byte)(excl | ch);
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;
10359 switch(chi[1] |0x98) {
10360 case 0x98: return 0;
10362 if (pchannelmap) *pchannelmap = 2;
10365 if (pchannelmap) *pchannelmap = 4;
10367 case 0x9b: return 0xff;
10368 case 0x9c: return 0xfd; /* d-ch */
10369 default: return 0xfe;
10375 static void mixer_set_bchannel_id_esc (PLCI *plci, byte bchannel_id)
10377 DIVA_CAPI_ADAPTER *a;
10382 old_id = plci->li_bchannel_id;
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;
10393 if (((bchannel_id & 0x03) == 1) || ((bchannel_id & 0x03) == 2))
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))
10400 splci = a->AdvSignalPLCI;
10401 if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
10403 if ((splci->li_bchannel_id != 0)
10404 && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
10406 li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
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));
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;
10419 if ((old_id == 0) && (plci->li_bchannel_id != 0)
10420 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
10422 mixer_clear_config (plci);
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));
10430 static void mixer_set_bchannel_id (PLCI *plci, byte *chi)
10432 DIVA_CAPI_ADAPTER *a;
10437 old_id = plci->li_bchannel_id;
10438 ch = chi_to_channel (chi, NULL);
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;
10451 if (((ch & 0x1f) == 1) || ((ch & 0x1f) == 2))
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))
10458 splci = a->AdvSignalPLCI;
10459 if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
10461 if ((splci->li_bchannel_id != 0)
10462 && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
10464 li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
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));
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;
10478 if ((old_id == 0) && (plci->li_bchannel_id != 0)
10479 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
10481 mixer_clear_config (plci);
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));
10489 #define MIXER_MAX_DUMP_CHANNELS 34
10491 static void mixer_calculate_coefs (DIVA_CAPI_ADAPTER *a)
10493 static char hex_digit_table[0x10] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
10496 char hex_line[2 * MIXER_MAX_DUMP_CHANNELS + MIXER_MAX_DUMP_CHANNELS / 8 + 4];
10498 dbug (1, dprintf ("[%06lx] %s,%d: mixer_calculate_coefs",
10499 (dword)(UnMapController (a->Id)), (char *)(FILE_), __LINE__));
10501 for (i = 0; i < li_total_channels; i++)
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;
10508 for (j = 0; j < li_total_channels; j++)
10510 if (((li_config_table[i].flag_table[j]) != 0)
10511 || ((li_config_table[j].flag_table[i]) != 0))
10513 li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
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))
10518 li_config_table[i].channel |= LI_CHANNEL_CONFERENCE;
10523 for (i = 0; i < li_total_channels; i++)
10525 for (j = 0; j < li_total_channels; j++)
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;
10532 for (n = 0; n < li_total_channels; n++)
10534 if (li_config_table[n].channel & LI_CHANNEL_CONFERENCE)
10536 for (i = 0; i < li_total_channels; i++)
10538 if (li_config_table[i].channel & LI_CHANNEL_CONFERENCE)
10540 for (j = 0; j < li_total_channels; j++)
10542 li_config_table[i].coef_table[j] |=
10543 li_config_table[i].coef_table[n] & li_config_table[n].coef_table[j];
10549 for (i = 0; i < li_total_channels; i++)
10551 if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
10553 li_config_table[i].coef_table[i] &= ~LI_COEF_CH_CH;
10554 for (j = 0; j < li_total_channels; j++)
10556 if (li_config_table[i].coef_table[j] & LI_COEF_CH_CH)
10557 li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE;
10559 if (li_config_table[i].flag_table[i] & LI_FLAG_CONFERENCE)
10560 li_config_table[i].coef_table[i] |= LI_COEF_CH_CH;
10563 for (i = 0; i < li_total_channels; i++)
10565 if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
10567 for (j = 0; j < li_total_channels; j++)
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;
10578 if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
10580 for (j = 0; j < li_total_channels; j++)
10582 if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
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;
10590 if (li_config_table[i].chflags & LI_CHFLAG_MIX)
10592 for (j = 0; j < li_total_channels; j++)
10594 if (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT)
10595 li_config_table[j].coef_table[i] |= LI_COEF_PC_CH;
10598 if (li_config_table[i].chflags & LI_CHFLAG_LOOP)
10600 for (j = 0; j < li_total_channels; j++)
10602 if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
10604 for (n = 0; n < li_total_channels; n++)
10606 if (li_config_table[n].flag_table[i] & LI_FLAG_INTERCONNECT)
10608 li_config_table[n].coef_table[j] |= LI_COEF_CH_CH;
10609 if (li_config_table[j].chflags & LI_CHFLAG_MIX)
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;
10615 else if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
10616 li_config_table[n].coef_table[j] |= LI_COEF_CH_PC;
10624 for (i = 0; i < li_total_channels; i++)
10626 if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
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++)
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)))
10641 li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
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;
10648 if (!(li_config_table[i].channel & LI_CHANNEL_ACTIVE))
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;
10655 for (i = 0; i < li_total_channels; i++)
10657 if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
10660 while ((j < li_total_channels) && !(li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT))
10662 if (j < li_total_channels)
10664 for (j = 0; j < li_total_channels; j++)
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;
10673 n = li_total_channels;
10674 if (n > MIXER_MAX_DUMP_CHANNELS)
10675 n = MIXER_MAX_DUMP_CHANNELS;
10677 for (j = 0; j < n; j++)
10679 if ((j & 0x7) == 0)
10681 *(p++) = hex_digit_table[li_config_table[j].curchnl >> 4];
10682 *(p++) = hex_digit_table[li_config_table[j].curchnl & 0xf];
10685 dbug (1, dprintf ("[%06lx] CURRENT %s",
10686 (dword)(UnMapController (a->Id)), (char *) hex_line));
10688 for (j = 0; j < n; j++)
10690 if ((j & 0x7) == 0)
10692 *(p++) = hex_digit_table[li_config_table[j].channel >> 4];
10693 *(p++) = hex_digit_table[li_config_table[j].channel & 0xf];
10696 dbug (1, dprintf ("[%06lx] CHANNEL %s",
10697 (dword)(UnMapController (a->Id)), (char *) hex_line));
10699 for (j = 0; j < n; j++)
10701 if ((j & 0x7) == 0)
10703 *(p++) = hex_digit_table[li_config_table[j].chflags >> 4];
10704 *(p++) = hex_digit_table[li_config_table[j].chflags & 0xf];
10707 dbug (1, dprintf ("[%06lx] CHFLAG %s",
10708 (dword)(UnMapController (a->Id)), (char *) hex_line));
10709 for (i = 0; i < n; i++)
10712 for (j = 0; j < n; j++)
10714 if ((j & 0x7) == 0)
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];
10720 dbug (1, dprintf ("[%06lx] FLAG[%02x]%s",
10721 (dword)(UnMapController (a->Id)), i, (char *) hex_line));
10723 for (i = 0; i < n; i++)
10726 for (j = 0; j < n; j++)
10728 if ((j & 0x7) == 0)
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];
10734 dbug (1, dprintf ("[%06lx] COEF[%02x]%s",
10735 (dword)(UnMapController (a->Id)), i, (char *) hex_line));
10744 } mixer_write_prog_pri[] =
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 }
10757 byte xconnect_override;
10758 } mixer_write_prog_bri[] =
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 */
10798 static byte mixer_swapped_index_bri[] =
10801 19, /* Alt B to B */
10803 21, /* Alt PC to B */
10805 23, /* Alt IC to B */
10807 25, /* Alt B to PC */
10809 27, /* Alt PC to PC */
10811 29, /* Alt IC to PC */
10813 31, /* Alt B to IC */
10815 33, /* Alt PC 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 */
10843 } xconnect_write_prog[] =
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 }
10852 static void xconnect_query_addresses (PLCI *plci)
10854 DIVA_CAPI_ADAPTER *a;
10858 dbug (1, dprintf ("[%06lx] %s,%d: xconnect_query_addresses",
10859 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
10860 (char *)(FILE_), __LINE__));
10863 if (a->li_pri && ((plci->li_bchannel_id == 0)
10864 || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)))
10866 dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out",
10867 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
10868 (char *)(FILE_), __LINE__));
10871 p = plci->internal_req_buffer;
10872 ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
10873 *(p++) = UDATA_REQUEST_XCONNECT_FROM;
10876 *(p++) = (byte)(w >> 8);
10877 w = ch | XCONNECT_CHANNEL_PORT_PC;
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);
10889 static void xconnect_write_coefs (PLCI *plci, word internal_command)
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));
10896 plci->li_write_command = internal_command;
10897 plci->li_write_channel = 0;
10901 static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
10903 DIVA_CAPI_ADAPTER *a;
10904 word w, n, i, j, r, s, to_ch;
10907 struct xconnect_transfer_address_s *transfer_address;
10908 byte ch_map[MIXER_CHANNELS_BRI];
10910 dbug (1, dprintf ("[%06x] %s,%d: xconnect_write_coefs_process %02x %d",
10911 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->li_write_channel));
10914 if ((plci->li_bchannel_id == 0)
10915 || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
10917 dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out",
10918 UnMapId (Id), (char *)(FILE_), __LINE__));
10921 i = a->li_base + (plci->li_bchannel_id - 1);
10922 j = plci->li_write_channel;
10923 p = plci->internal_req_buffer;
10926 if ((Rc != OK) && (Rc != OK_FC))
10928 dbug (1, dprintf ("[%06lx] %s,%d: LI write coefs failed %02x",
10929 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
10933 if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
10937 if (j < li_total_channels)
10939 if (li_config_table[i].channel & LI_CHANNEL_ADDRESSES_SET)
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));
10946 r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
10947 while ((j < li_total_channels)
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)
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))))))
10964 if (j < li_total_channels)
10965 r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
10968 if (j < li_total_channels)
10970 plci->internal_command = plci->li_write_command;
10971 if (plci_nl_busy (plci))
10973 to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
10974 *(p++) = UDATA_REQUEST_XCONNECT_TO;
10977 if (li_config_table[j].adapter->li_base != a->li_base)
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));
10988 if (r & xconnect_write_prog[n].mask)
10990 if (xconnect_write_prog[n].from_pc)
10991 transfer_address = &(li_config_table[j].send_pc);
10993 transfer_address = &(li_config_table[j].send_b);
10994 d = transfer_address->card_address.low;
10996 *(p++) = (byte)(d >> 8);
10997 *(p++) = (byte)(d >> 16);
10998 *(p++) = (byte)(d >> 24);
10999 d = transfer_address->card_address.high;
11001 *(p++) = (byte)(d >> 8);
11002 *(p++) = (byte)(d >> 16);
11003 *(p++) = (byte)(d >> 24);
11004 d = transfer_address->offset;
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;
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));
11018 li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4;
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]))
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)
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)
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))))));
11046 } while ((j < li_total_channels)
11047 && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
11049 else if (j == li_total_channels)
11051 plci->internal_command = plci->li_write_command;
11052 if (plci_nl_busy (plci))
11056 *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
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;
11063 *(p++) = (byte)(w >> 8);
11067 *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
11069 if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
11070 && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
11072 w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
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;
11079 *(p++) = (byte)(w >> 8);
11080 for (j = 0; j < sizeof(ch_map); j += 2)
11082 if (plci->li_bchannel_id == 2)
11084 ch_map[j] = (byte)(j+1);
11085 ch_map[j+1] = (byte) j;
11089 ch_map[j] = (byte) j;
11090 ch_map[j+1] = (byte)(j+1);
11093 for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++)
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)
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))
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;
11111 if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
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];
11121 j = li_total_channels + 1;
11126 if (j <= li_total_channels)
11128 plci->internal_command = plci->li_write_command;
11129 if (plci_nl_busy (plci))
11131 if (j < a->li_base)
11135 *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
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;
11142 *(p++) = (byte)(w >> 8);
11143 for (n = 0; n < sizeof(mixer_write_prog_pri) / sizeof(mixer_write_prog_pri[0]); n++)
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++)
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)
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;
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++)
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)
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;
11173 *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
11175 if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
11176 && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
11178 w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
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;
11185 *(p++) = (byte)(w >> 8);
11186 for (j = 0; j < sizeof(ch_map); j += 2)
11188 if (plci->li_bchannel_id == 2)
11190 ch_map[j] = (byte)(j+1);
11191 ch_map[j+1] = (byte) j;
11195 ch_map[j] = (byte) j;
11196 ch_map[j+1] = (byte)(j+1);
11199 for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++)
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)
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;
11212 if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
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];
11222 j = li_total_channels + 1;
11225 plci->li_write_channel = j;
11226 if (p != plci->internal_req_buffer)
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);
11239 static void mixer_notify_update (PLCI *plci, byte others)
11241 DIVA_CAPI_ADAPTER *a;
11244 byte msg[sizeof(CAPI_MSG_HEADER) + 6];
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));
11251 if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
11254 plci->li_notify_update = TRUE;
11258 notify_plci = NULL;
11261 while ((i < li_total_channels) && (li_config_table[i].plci == NULL))
11263 if (i < li_total_channels)
11264 notify_plci = li_config_table[i++].plci;
11268 if ((plci->li_bchannel_id != 0)
11269 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
11271 notify_plci = plci;
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)
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)
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));
11302 notify_plci->li_notify_update = FALSE;
11305 } while (others && (notify_plci != NULL));
11307 plci->li_notify_update = FALSE;
11312 static void mixer_clear_config (PLCI *plci)
11314 DIVA_CAPI_ADAPTER *a;
11317 dbug (1, dprintf ("[%06lx] %s,%d: mixer_clear_config",
11318 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
11319 (char *)(FILE_), __LINE__));
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;
11326 if ((plci->li_bchannel_id != 0)
11327 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
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++)
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;
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))
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++)
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;
11356 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
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++)
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;
11376 static void mixer_prepare_switch (dword Id, PLCI *plci)
11379 dbug (1, dprintf ("[%06lx] %s,%d: mixer_prepare_switch",
11380 UnMapId (Id), (char *)(FILE_), __LINE__));
11384 mixer_indication_coefs_set (Id, plci);
11385 } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
11389 static word mixer_save_config (dword Id, PLCI *plci, byte Rc)
11391 DIVA_CAPI_ADAPTER *a;
11394 dbug (1, dprintf ("[%06lx] %s,%d: mixer_save_config %02x %d",
11395 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
11398 if ((plci->li_bchannel_id != 0)
11399 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
11401 i = a->li_base + (plci->li_bchannel_id - 1);
11402 for (j = 0; j < li_total_channels; j++)
11404 li_config_table[i].coef_table[j] &= 0xf;
11405 li_config_table[j].coef_table[i] &= 0xf;
11408 li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
11414 static word mixer_restore_config (dword Id, PLCI *plci, byte Rc)
11416 DIVA_CAPI_ADAPTER *a;
11419 dbug (1, dprintf ("[%06lx] %s,%d: mixer_restore_config %02x %d",
11420 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
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))
11428 switch (plci->adjust_b_state)
11430 case ADJUST_B_RESTORE_MIXER_1:
11431 if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
11433 plci->internal_command = plci->adjust_b_command;
11434 if (plci_nl_busy (plci))
11436 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
11439 xconnect_query_addresses (plci);
11440 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_2;
11443 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
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))
11450 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B query addresses failed %02x",
11451 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
11452 Info = _WRONG_STATE;
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;
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;
11469 if (plci->adjust_b_state != ADJUST_B_RESTORE_MIXER_5)
11471 plci->internal_command = plci->adjust_b_command;
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;
11478 case ADJUST_B_RESTORE_MIXER_6:
11479 if (!xconnect_write_coefs_process (Id, plci, Rc))
11481 dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed",
11482 UnMapId (Id), (char *)(FILE_), __LINE__));
11483 Info = _FACILITY_NOT_SUPPORTED;
11486 if (plci->internal_command)
11488 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_7;
11489 case ADJUST_B_RESTORE_MIXER_7:
11497 static void mixer_command (dword Id, PLCI *plci, byte Rc)
11499 DIVA_CAPI_ADAPTER *a;
11500 word i, internal_command, Info;
11502 dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x",
11503 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
11508 internal_command = plci->internal_command;
11509 plci->internal_command = 0;
11510 switch (plci->li_cmd)
11512 case LI_REQ_CONNECT:
11513 case LI_REQ_DISCONNECT:
11514 case LI_REQ_SILENT_UPDATE:
11515 switch (internal_command)
11518 if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
11520 adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities |
11521 B1_FACILITY_MIXER), MIXER_COMMAND_1);
11523 case MIXER_COMMAND_1:
11524 if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
11526 if (adjust_b_process (Id, plci, Rc) != GOOD)
11528 dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed",
11529 UnMapId (Id), (char *)(FILE_), __LINE__));
11530 Info = _FACILITY_NOT_SUPPORTED;
11533 if (plci->internal_command)
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)))
11542 xconnect_write_coefs (plci, MIXER_COMMAND_2);
11548 mixer_indication_coefs_set (Id, plci);
11549 } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
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)))
11557 if (!xconnect_write_coefs_process (Id, plci, Rc))
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)
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));
11572 Info = _FACILITY_NOT_SUPPORTED;
11575 if (plci->internal_command)
11578 if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
11580 adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities &
11581 ~B1_FACILITY_MIXER), MIXER_COMMAND_3);
11583 case MIXER_COMMAND_3:
11584 if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
11586 if (adjust_b_process (Id, plci, Rc) != GOOD)
11588 dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed",
11589 UnMapId (Id), (char *)(FILE_), __LINE__));
11590 Info = _FACILITY_NOT_SUPPORTED;
11593 if (plci->internal_command)
11600 if ((plci->li_bchannel_id == 0)
11601 || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
11603 dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out %d",
11604 UnMapId (Id), (char *)(FILE_), __LINE__, (int)(plci->li_bchannel_id)));
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))
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)
11616 i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
11617 li_config_table[i].curchnl = plci->li_channel_bits;
11624 static void li_update_connect (dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci,
11625 dword plci_b_id, byte connect, dword li_flags)
11627 word i, ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
11629 DIVA_CAPI_ADAPTER *a_b;
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))
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;
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))
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;
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);
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)
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;
11677 if (li_config_table[ch_a_v].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
11679 for (i = 0; i < li_total_channels; i++)
11682 li_config_table[ch_a_v].flag_table[i] &= ~LI_FLAG_CONFERENCE;
11685 if (li_config_table[ch_a_s].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
11687 for (i = 0; i < li_total_channels; i++)
11690 li_config_table[ch_a_s].flag_table[i] &= ~LI_FLAG_CONFERENCE;
11693 if (li_config_table[ch_b_v].flag_table[ch_a_v] & LI_FLAG_CONFERENCE)
11695 for (i = 0; i < li_total_channels; i++)
11698 li_config_table[i].flag_table[ch_a_v] &= ~LI_FLAG_CONFERENCE;
11701 if (li_config_table[ch_b_v].flag_table[ch_a_s] & LI_FLAG_CONFERENCE)
11703 for (i = 0; i < li_total_channels; i++)
11706 li_config_table[i].flag_table[ch_a_s] &= ~LI_FLAG_CONFERENCE;
11710 if (li_flags & LI_FLAG_CONFERENCE_A_B)
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;
11717 if (li_flags & LI_FLAG_CONFERENCE_B_A)
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;
11724 if (li_flags & LI_FLAG_MONITOR_A)
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;
11729 if (li_flags & LI_FLAG_MONITOR_B)
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;
11734 if (li_flags & LI_FLAG_ANNOUNCEMENT_A)
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;
11739 if (li_flags & LI_FLAG_ANNOUNCEMENT_B)
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;
11744 if (li_flags & LI_FLAG_MIX_A)
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;
11749 if (li_flags & LI_FLAG_MIX_B)
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;
11754 if (ch_a_v != ch_a_s)
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;
11759 if (ch_b_v != ch_b_s)
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;
11767 static void li2_update_connect (dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci,
11768 dword plci_b_id, byte connect, dword li_flags)
11770 word ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
11772 DIVA_CAPI_ADAPTER *a_b;
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))
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;
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))
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;
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);
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)
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;
11826 if (li_flags & LI2_FLAG_INTERCONNECT_B_A)
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;
11833 if (li_flags & LI2_FLAG_MONITOR_B)
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;
11838 if (li_flags & LI2_FLAG_MIX_B)
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;
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)
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;
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)
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;
11867 if (ch_b_v != ch_b_s)
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;
11875 static word li_check_main_plci (dword Id, PLCI *plci)
11879 dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
11880 UnMapId (Id), (char *)(FILE_), __LINE__));
11881 return (_WRONG_IDENTIFIER);
11884 || !plci->NL.Id || plci->nl_remove_id
11885 || (plci->li_bchannel_id == 0))
11887 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
11888 UnMapId (Id), (char *)(FILE_), __LINE__));
11889 return (_WRONG_STATE);
11891 li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = plci;
11896 static PLCI *li_check_plci_b (dword Id, PLCI *plci,
11897 dword plci_b_id, word plci_b_write_pos, byte *p_result)
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)
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);
11911 if ((plci_b_id & 0x7f) != 0)
11913 ctlr_b = MapController ((byte)(plci_b_id & 0x7f));
11914 if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
11918 || (((plci_b_id >> 8) & 0xff) == 0)
11919 || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
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);
11926 plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
11928 || !plci_b->NL.Id || plci_b->nl_remove_id
11929 || (plci_b->li_bchannel_id == 0))
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);
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)))
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);
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))
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);
11959 static PLCI *li2_check_plci_b (dword Id, PLCI *plci,
11960 dword plci_b_id, word plci_b_write_pos, byte *p_result)
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)
11968 dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
11969 UnMapId (Id), (char *)(FILE_), __LINE__));
11970 PUT_WORD (p_result, _WRONG_STATE);
11974 if ((plci_b_id & 0x7f) != 0)
11976 ctlr_b = MapController ((byte)(plci_b_id & 0x7f));
11977 if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
11981 || (((plci_b_id >> 8) & 0xff) == 0)
11982 || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
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);
11989 plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
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))
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);
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)))
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);
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))
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);
12022 static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg)
12026 dword d, li_flags, plci_b_id;
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];
12036 word plci_b_write_pos;
12038 dbug (1, dprintf ("[%06lx] %s,%d: mixer_request",
12039 UnMapId (Id), (char *)(FILE_), __LINE__));
12042 result = result_buffer;
12043 result_buffer[0] = 0;
12044 if (!(a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED))
12046 dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
12047 UnMapId (Id), (char *)(FILE_), __LINE__));
12048 Info = _FACILITY_NOT_SUPPORTED;
12050 else if (api_parse (&msg[1].info[1], msg[1].length, "ws", li_parms))
12052 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12053 UnMapId (Id), (char *)(FILE_), __LINE__));
12054 Info = _WRONG_MESSAGE_FORMAT;
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))
12063 case LI_GET_SUPPORTED_SERVICES:
12064 if (appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
12066 result_buffer[0] = 17;
12067 result_buffer[3] = 14;
12068 PUT_WORD (&result_buffer[4], GOOD);
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)
12082 for (i = 0; i < li_total_channels; i++)
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)))
12094 d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
12096 PUT_DWORD (&result_buffer[10], d / 2);
12097 PUT_DWORD (&result_buffer[14], d);
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)
12120 for (i = 0; i < li_total_channels; i++)
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)))
12130 PUT_DWORD (&result_buffer[18], d / 2);
12131 PUT_DWORD (&result_buffer[22], d - 1);
12135 case LI_REQ_CONNECT:
12136 if (li_parms[1].length == 8)
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))
12141 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12142 UnMapId (Id), (char *)(FILE_), __LINE__));
12143 Info = _WRONG_MESSAGE_FORMAT;
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);
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)
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;
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))
12172 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12173 UnMapId (Id), (char *)(FILE_), __LINE__));
12174 Info = _WRONG_MESSAGE_FORMAT;
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;
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;
12191 li2_update_connect (Id, a, plci, UnMapId (Id), TRUE, li_flags);
12192 while (participant_parms_pos < li_req_parms[1].length)
12194 result[result_pos] = 6;
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))
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);
12206 if (api_parse (&li_participant_struct[0].info[1],
12207 li_participant_struct[0].length, "dd", li_participant_parms))
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);
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)
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);
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)
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;
12233 participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
12234 (&li_req_parms[1].info[1]));
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))
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;
12247 plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
12248 plci->li_plci_b_write_pos = plci_b_write_pos;
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);
12256 plci->li_cmd = GET_WORD (li_parms[0].info);
12257 start_internal_command (Id, plci, mixer_command);
12260 case LI_REQ_DISCONNECT:
12261 if (li_parms[1].length == 4)
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))
12266 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12267 UnMapId (Id), (char *)(FILE_), __LINE__));
12268 Info = _WRONG_MESSAGE_FORMAT;
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);
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)
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;
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))
12296 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12297 UnMapId (Id), (char *)(FILE_), __LINE__));
12298 Info = _WRONG_MESSAGE_FORMAT;
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;
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;
12314 while (participant_parms_pos < li_req_parms[0].length)
12316 result[result_pos] = 6;
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))
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);
12328 if (api_parse (&li_participant_struct[0].info[1],
12329 li_participant_struct[0].length, "d", li_participant_parms))
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);
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)
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);
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)
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;
12352 participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
12353 (&li_req_parms[0].info[1]));
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))
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;
12366 plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
12367 plci->li_plci_b_write_pos = plci_b_write_pos;
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);
12375 plci->li_cmd = GET_WORD (li_parms[0].info);
12376 start_internal_command (Id, plci, mixer_command);
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))
12385 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
12386 UnMapId (Id), (char *)(FILE_), __LINE__));
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)
12393 dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
12394 UnMapId (Id), (char *)(FILE_), __LINE__));
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))
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;
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;
12409 plci->li_cmd = GET_WORD (li_parms[0].info);
12410 start_internal_command (Id, plci, mixer_command);
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;
12419 sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
12420 "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
12425 static void mixer_indication_coefs_set (dword Id, PLCI *plci)
12428 DIVA_CAPI_ADAPTER *a;
12431 dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set",
12432 UnMapId (Id), (char *)(FILE_), __LINE__));
12435 if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
12439 d = plci->li_plci_b_queue[plci->li_plci_b_read_pos];
12440 if (!(d & LI_PLCI_B_SKIP_FLAG))
12442 if (plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
12444 if (d & LI_PLCI_B_DISC_FLAG)
12447 PUT_WORD (&result[1], LI_IND_DISCONNECT);
12449 PUT_WORD (&result[4], _LI_USER_INITIATED);
12454 PUT_WORD (&result[1], LI_IND_CONNECT_ACTIVE);
12456 PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK);
12461 if (d & LI_PLCI_B_DISC_FLAG)
12464 PUT_WORD (&result[1], LI_IND_DISCONNECT);
12466 PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK);
12467 PUT_WORD (&result[8], _LI_USER_INITIATED);
12472 PUT_WORD (&result[1], LI_IND_CONNECT_ACTIVE);
12474 PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK);
12477 sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0,
12478 "ws", SELECTOR_LINE_INTERCONNECT, result);
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));
12487 static void mixer_indication_xconnect_from (dword Id, PLCI *plci, byte *msg, word length)
12490 struct xconnect_transfer_address_s s, *p;
12491 DIVA_CAPI_ADAPTER *a;
12493 dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_from %d",
12494 UnMapId (Id), (char *)(FILE_), __LINE__, (int) length));
12498 for (i = 1; i < length; i += 16)
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))
12508 if (ch & XCONNECT_CHANNEL_PORT_PC)
12509 p = &(li_config_table[j].send_pc);
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;
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)))
12522 (*(plci->internal_command_queue[0]))(Id, plci, 0);
12523 if (!plci->internal_command)
12524 next_internal_command (Id, plci);
12526 mixer_notify_update (plci, TRUE);
12530 static void mixer_indication_xconnect_to (dword Id, PLCI *plci, byte *msg, word length)
12533 dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_to %d",
12534 UnMapId (Id), (char *)(FILE_), __LINE__, (int) length));
12539 static byte mixer_notify_source_removed (PLCI *plci, dword plci_b_id)
12541 word plci_b_write_pos;
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)
12547 dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
12548 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
12549 (char *)(FILE_), __LINE__));
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;
12559 static void mixer_remove (PLCI *plci)
12561 DIVA_CAPI_ADAPTER *a;
12566 dbug (1, dprintf ("[%06lx] %s,%d: mixer_remove",
12567 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
12568 (char *)(FILE_), __LINE__));
12571 plci_b_id = (plci->Id << 8) | UnMapController (plci->adapter->Id);
12572 if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
12574 if ((plci->li_bchannel_id != 0)
12575 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
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)
12580 for (j = 0; j < li_total_channels; j++)
12582 if ((li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
12583 || (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT))
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)
12593 mixer_notify_source_removed (notify_plci, plci_b_id);
12597 mixer_clear_config (plci);
12598 mixer_calculate_coefs (a);
12599 mixer_notify_update (plci, TRUE);
12601 li_config_table[i].plci = NULL;
12602 plci->li_bchannel_id = 0;
12608 /*------------------------------------------------------------------*/
12609 /* Echo canceller facilities */
12610 /*------------------------------------------------------------------*/
12613 static void ec_write_parameters (PLCI *plci)
12616 byte parameter_buffer[6];
12618 dbug (1, dprintf ("[%06lx] %s,%d: ec_write_parameters",
12619 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
12620 (char *)(FILE_), __LINE__));
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);
12634 static void ec_clear_config (PLCI *plci)
12637 dbug (1, dprintf ("[%06lx] %s,%d: ec_clear_config",
12638 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
12639 (char *)(FILE_), __LINE__));
12641 plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
12642 LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING;
12643 plci->ec_tail_length = 0;
12647 static void ec_prepare_switch (dword Id, PLCI *plci)
12650 dbug (1, dprintf ("[%06lx] %s,%d: ec_prepare_switch",
12651 UnMapId (Id), (char *)(FILE_), __LINE__));
12656 static word ec_save_config (dword Id, PLCI *plci, byte Rc)
12659 dbug (1, dprintf ("[%06lx] %s,%d: ec_save_config %02x %d",
12660 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
12666 static word ec_restore_config (dword Id, PLCI *plci, byte Rc)
12670 dbug (1, dprintf ("[%06lx] %s,%d: ec_restore_config %02x %d",
12671 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
12674 if (plci->B1_facilities & B1_FACILITY_EC)
12676 switch (plci->adjust_b_state)
12678 case ADJUST_B_RESTORE_EC_1:
12679 plci->internal_command = plci->adjust_b_command;
12682 plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
12685 ec_write_parameters (plci);
12686 plci->adjust_b_state = ADJUST_B_RESTORE_EC_2;
12688 case ADJUST_B_RESTORE_EC_2:
12689 if ((Rc != OK) && (Rc != OK_FC))
12691 dbug (1, dprintf ("[%06lx] %s,%d: Restore EC failed %02x",
12692 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
12693 Info = _WRONG_STATE;
12703 static void ec_command (dword Id, PLCI *plci, byte Rc)
12705 word internal_command, Info;
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));
12713 if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
12716 PUT_WORD (&result[1], EC_SUCCESS);
12721 PUT_WORD (&result[1], plci->ec_cmd);
12723 PUT_WORD (&result[4], GOOD);
12725 internal_command = plci->internal_command;
12726 plci->internal_command = 0;
12727 switch (plci->ec_cmd)
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)
12736 adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities |
12737 B1_FACILITY_EC), EC_COMMAND_1);
12739 if (adjust_b_process (Id, plci, Rc) != GOOD)
12741 dbug (1, dprintf ("[%06lx] %s,%d: Load EC failed",
12742 UnMapId (Id), (char *)(FILE_), __LINE__));
12743 Info = _FACILITY_NOT_SUPPORTED;
12746 if (plci->internal_command)
12751 plci->internal_command = EC_COMMAND_2;
12754 plci->internal_command = EC_COMMAND_3;
12755 ec_write_parameters (plci);
12758 if ((Rc != OK) && (Rc != OK_FC))
12760 dbug (1, dprintf ("[%06lx] %s,%d: Enable EC failed %02x",
12761 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
12762 Info = _FACILITY_NOT_SUPPORTED;
12769 case EC_DISABLE_OPERATION:
12770 switch (internal_command)
12774 if (plci->B1_facilities & B1_FACILITY_EC)
12778 plci->internal_command = EC_COMMAND_1;
12781 plci->internal_command = EC_COMMAND_2;
12782 ec_write_parameters (plci);
12787 if ((Rc != OK) && (Rc != OK_FC))
12789 dbug (1, dprintf ("[%06lx] %s,%d: Disable EC failed %02x",
12790 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
12791 Info = _FACILITY_NOT_SUPPORTED;
12794 adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities &
12795 ~B1_FACILITY_EC), EC_COMMAND_3);
12797 if (adjust_b_process (Id, plci, Rc) != GOOD)
12799 dbug (1, dprintf ("[%06lx] %s,%d: Unload EC failed",
12800 UnMapId (Id), (char *)(FILE_), __LINE__));
12801 Info = _FACILITY_NOT_SUPPORTED;
12804 if (plci->internal_command)
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);
12816 static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg)
12820 API_PARSE ec_parms[3];
12823 dbug (1, dprintf ("[%06lx] %s,%d: ec_request",
12824 UnMapId (Id), (char *)(FILE_), __LINE__));
12828 if (!(a->man_profile.private_options & (1L << PRIVATE_ECHO_CANCELLER)))
12830 dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
12831 UnMapId (Id), (char *)(FILE_), __LINE__));
12832 Info = _FACILITY_NOT_SUPPORTED;
12836 if (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
12838 if (api_parse (&msg[1].info[1], msg[1].length, "w", ec_parms))
12840 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12841 UnMapId (Id), (char *)(FILE_), __LINE__));
12842 Info = _WRONG_MESSAGE_FORMAT;
12848 dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
12849 UnMapId (Id), (char *)(FILE_), __LINE__));
12850 Info = _WRONG_IDENTIFIER;
12852 else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
12854 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
12855 UnMapId (Id), (char *)(FILE_), __LINE__));
12856 Info = _WRONG_STATE;
12861 plci->ec_cmd = GET_WORD (ec_parms[0].info);
12862 plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
12864 PUT_WORD (&result[1], EC_SUCCESS);
12865 if (msg[1].length >= 4)
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)
12878 plci->ec_tail_length = GET_WORD (&ec_parms[0].info[4]);
12881 switch (plci->ec_cmd)
12883 case EC_ENABLE_OPERATION:
12884 plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
12885 start_internal_command (Id, plci, ec_command);
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);
12895 case EC_FREEZE_COEFFICIENTS:
12896 plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS;
12897 start_internal_command (Id, plci, ec_command);
12900 case EC_RESUME_COEFFICIENT_UPDATE:
12901 plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
12902 start_internal_command (Id, plci, ec_command);
12905 case EC_RESET_COEFFICIENTS:
12906 plci->ec_idi_options |= LEC_RESET_COEFFICIENTS;
12907 start_internal_command (Id, plci, ec_command);
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);
12920 if (api_parse (&msg[1].info[1], msg[1].length, "ws", ec_parms))
12922 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12923 UnMapId (Id), (char *)(FILE_), __LINE__));
12924 Info = _WRONG_MESSAGE_FORMAT;
12928 if (GET_WORD (ec_parms[0].info) == EC_GET_SUPPORTED_SERVICES)
12931 PUT_WORD (&result[1], EC_GET_SUPPORTED_SERVICES);
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);
12938 else if (plci == NULL)
12940 dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
12941 UnMapId (Id), (char *)(FILE_), __LINE__));
12942 Info = _WRONG_IDENTIFIER;
12944 else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
12946 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
12947 UnMapId (Id), (char *)(FILE_), __LINE__));
12948 Info = _WRONG_STATE;
12953 plci->ec_cmd = GET_WORD (ec_parms[0].info);
12954 plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
12956 PUT_WORD (&result[1], plci->ec_cmd);
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)
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)
12973 plci->ec_tail_length = GET_WORD (&ec_parms[1].info[3]);
12976 switch (plci->ec_cmd)
12978 case EC_ENABLE_OPERATION:
12979 plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
12980 start_internal_command (Id, plci, ec_command);
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);
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);
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);
13006 static void ec_indication (dword Id, PLCI *plci, byte *msg, word length)
13010 dbug (1, dprintf ("[%06lx] %s,%d: ec_indication",
13011 UnMapId (Id), (char *)(FILE_), __LINE__));
13013 if (!(plci->ec_idi_options & LEC_MANUAL_DISABLE))
13015 if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
13018 PUT_WORD (&result[1], 0);
13021 case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
13022 PUT_WORD (&result[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
13024 case LEC_DISABLE_TYPE_REVERSED_2100HZ:
13025 PUT_WORD (&result[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
13027 case LEC_DISABLE_RELEASED:
13028 PUT_WORD (&result[1], EC_BYPASS_RELEASED);
13035 PUT_WORD (&result[1], EC_BYPASS_INDICATION);
13037 PUT_WORD (&result[4], 0);
13040 case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
13041 PUT_WORD (&result[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
13043 case LEC_DISABLE_TYPE_REVERSED_2100HZ:
13044 PUT_WORD (&result[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
13046 case LEC_DISABLE_RELEASED:
13047 PUT_WORD (&result[4], EC_BYPASS_RELEASED);
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);
13058 /*------------------------------------------------------------------*/
13059 /* Advanced voice */
13060 /*------------------------------------------------------------------*/
13062 static void adv_voice_write_coefs (PLCI *plci, word write_command)
13064 DIVA_CAPI_ADAPTER *a;
13069 byte ch_map[MIXER_CHANNELS_BRI];
13071 byte coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE + 2];
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));
13078 p = coef_buffer + 1;
13079 *(p++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS;
13081 while (i + sizeof(word) <= a->adv_voice_coef_length)
13083 PUT_WORD (p, GET_WORD (a->adv_voice_coef_buffer + i));
13087 while (i < ADV_VOICE_OLD_COEF_COUNT * sizeof(word))
13089 PUT_WORD (p, 0x8000);
13094 if (!a->li_pri && (plci->li_bchannel_id == 0))
13096 if ((li_config_table[a->li_base].plci == NULL) && (li_config_table[a->li_base + 1].plci != NULL))
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));
13104 else if ((li_config_table[a->li_base].plci != NULL) && (li_config_table[a->li_base + 1].plci == NULL))
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));
13113 if (!a->li_pri && (plci->li_bchannel_id != 0)
13114 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
13116 i = a->li_base + (plci->li_bchannel_id - 1);
13117 switch (write_command)
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))
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;
13127 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
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;
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;
13141 case ADV_VOICE_WRITE_DEACTIVATION:
13142 for (j = 0; j < li_total_channels; j++)
13144 li_config_table[i].flag_table[j] = 0;
13145 li_config_table[j].flag_table[i] = 0;
13147 k = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
13148 for (j = 0; j < li_total_channels; j++)
13150 li_config_table[k].flag_table[j] = 0;
13151 li_config_table[j].flag_table[k] = 0;
13153 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
13155 k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
13156 for (j = 0; j < li_total_channels; j++)
13158 li_config_table[k].flag_table[j] = 0;
13159 li_config_table[j].flag_table[k] = 0;
13162 mixer_calculate_coefs (a);
13165 if (plci->B1_facilities & B1_FACILITY_MIXER)
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;
13175 *(p++) = (byte)(w >> 8);
13176 for (j = 0; j < sizeof(ch_map); j += 2)
13178 ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1));
13179 ch_map[j+1] = (byte)(j + (2 - plci->li_bchannel_id));
13181 for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++)
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)
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;
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;
13200 for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
13201 *(p++) = a->adv_voice_coef_buffer[i];
13207 for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
13208 *(p++) = a->adv_voice_coef_buffer[i];
13210 coef_buffer[0] = (p - coef_buffer) - 1;
13211 add_p (plci, FTY, coef_buffer);
13212 sig_req (plci, TEL_CTRL, 0);
13217 static void adv_voice_clear_config (PLCI *plci)
13219 DIVA_CAPI_ADAPTER *a;
13224 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_clear_config",
13225 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
13226 (char *)(FILE_), __LINE__));
13229 if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
13231 a->adv_voice_coef_length = 0;
13233 if (!a->li_pri && (plci->li_bchannel_id != 0)
13234 && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
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++)
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;
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++)
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;
13259 if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
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++)
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;
13279 static void adv_voice_prepare_switch (dword Id, PLCI *plci)
13282 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_prepare_switch",
13283 UnMapId (Id), (char *)(FILE_), __LINE__));
13288 static word adv_voice_save_config (dword Id, PLCI *plci, byte Rc)
13291 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_save_config %02x %d",
13292 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
13298 static word adv_voice_restore_config (dword Id, PLCI *plci, byte Rc)
13300 DIVA_CAPI_ADAPTER *a;
13303 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_restore_config %02x %d",
13304 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
13308 if ((plci->B1_facilities & B1_FACILITY_VOICE)
13309 && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
13311 switch (plci->adjust_b_state)
13313 case ADJUST_B_RESTORE_VOICE_1:
13314 plci->internal_command = plci->adjust_b_command;
13317 plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
13320 adv_voice_write_coefs (plci, ADV_VOICE_WRITE_UPDATE);
13321 plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_2;
13323 case ADJUST_B_RESTORE_VOICE_2:
13324 if ((Rc != OK) && (Rc != OK_FC))
13326 dbug (1, dprintf ("[%06lx] %s,%d: Restore voice config failed %02x",
13327 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
13328 Info = _WRONG_STATE;
13340 /*------------------------------------------------------------------*/
13341 /* B1 resource switching */
13342 /*------------------------------------------------------------------*/
13344 static byte b1_facilities_table[] =
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 */
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 */
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*/
13388 static word get_b1_facilities (PLCI * plci, byte b1_resource)
13390 word b1_facilities;
13392 b1_facilities = b1_facilities_table[b1_resource];
13393 if ((b1_resource == 9) || (b1_resource == 20) || (b1_resource == 25))
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)))))
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;
13406 if ((b1_resource == 17) || (b1_resource == 18))
13408 if (plci->adapter->manufacturer_features & (MANUFACTURER_FEATURE_V18 | MANUFACTURER_FEATURE_VOWN))
13409 b1_facilities |= B1_FACILITY_DTMFX | B1_FACILITY_DTMFR;
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));
13416 return (b1_facilities);
13420 static byte add_b1_facilities (PLCI * plci, byte b1_resource, word b1_facilities)
13424 switch (b1_resource)
13428 if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13436 if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13454 if (b1_facilities & B1_FACILITY_EC)
13456 if (b1_facilities & B1_FACILITY_LOCAL)
13458 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
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)))))
13468 if (b1_facilities & B1_FACILITY_LOCAL)
13470 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
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))))
13485 if (b1_facilities & B1_FACILITY_LOCAL)
13487 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13494 if (b1_facilities & B1_FACILITY_LOCAL)
13496 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
13506 if (b1_facilities & B1_FACILITY_LOCAL)
13508 else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
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)));
13525 static void adjust_b1_facilities (PLCI *plci, byte new_b1_resource, word new_b1_facilities)
13527 word removed_facilities;
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)));
13534 new_b1_facilities &= get_b1_facilities (plci, new_b1_resource);
13535 removed_facilities = plci->B1_facilities & ~new_b1_facilities;
13537 if (removed_facilities & B1_FACILITY_EC)
13538 ec_clear_config (plci);
13541 if (removed_facilities & B1_FACILITY_DTMFR)
13543 dtmf_rec_clear_config (plci);
13544 dtmf_parameter_clear_config (plci);
13546 if (removed_facilities & B1_FACILITY_DTMFX)
13547 dtmf_send_clear_config (plci);
13550 if (removed_facilities & B1_FACILITY_MIXER)
13551 mixer_clear_config (plci);
13553 if (removed_facilities & B1_FACILITY_VOICE)
13554 adv_voice_clear_config (plci);
13555 plci->B1_facilities = new_b1_facilities;
13559 static void adjust_b_clear (PLCI *plci)
13562 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_clear",
13563 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
13564 (char *)(FILE_), __LINE__));
13566 plci->adjust_b_restore = FALSE;
13570 static word adjust_b_process (dword Id, PLCI *plci, byte Rc)
13577 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_process %02x %d",
13578 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
13581 switch (plci->adjust_b_state)
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))
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)
13593 adjust_b1_facilities (plci, b1_resource, plci->adjust_b_facilities);
13596 if (plci->adjust_b_facilities & ~get_b1_facilities (plci, b1_resource))
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;
13605 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13608 mixer_prepare_switch (Id, plci);
13611 dtmf_prepare_switch (Id, plci);
13612 dtmf_parameter_prepare_switch (Id, plci);
13615 ec_prepare_switch (Id, plci);
13617 adv_voice_prepare_switch (Id, plci);
13619 plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1;
13621 case ADJUST_B_SAVE_MIXER_1:
13622 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13625 Info = mixer_save_config (Id, plci, Rc);
13626 if ((Info != GOOD) || plci->internal_command)
13630 plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1;
13632 case ADJUST_B_SAVE_DTMF_1:
13633 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13636 Info = dtmf_save_config (Id, plci, Rc);
13637 if ((Info != GOOD) || plci->internal_command)
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)
13646 plci->internal_command = plci->adjust_b_command;
13647 if (plci->adjust_b_ncci != 0)
13649 ncci_ptr = &(plci->adapter->ncci[plci->adjust_b_ncci]);
13650 while (ncci_ptr->data_pending)
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]);
13655 while (ncci_ptr->data_ack_pending)
13656 data_ack (plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
13658 nl_req_ncci (plci, REMOVE,
13659 (byte)((plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) ? plci->adjust_b_ncci : 0));
13661 plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
13664 plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
13666 case ADJUST_B_REMOVE_L23_2:
13667 if ((Rc != OK) && (Rc != OK_FC))
13669 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B remove failed %02x",
13670 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
13671 Info = _WRONG_STATE;
13674 if (plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
13676 if (plci_nl_busy (plci))
13678 plci->internal_command = plci->adjust_b_command;
13682 plci->adjust_b_state = ADJUST_B_SAVE_EC_1;
13684 case ADJUST_B_SAVE_EC_1:
13685 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13688 Info = ec_save_config (Id, plci, Rc);
13689 if ((Info != GOOD) || plci->internal_command)
13693 plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1;
13695 case ADJUST_B_SAVE_DTMF_PARAMETER_1:
13696 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13699 Info = dtmf_parameter_save_config (Id, plci, Rc);
13700 if ((Info != GOOD) || plci->internal_command)
13704 plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1;
13706 case ADJUST_B_SAVE_VOICE_1:
13707 if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
13709 Info = adv_voice_save_config (Id, plci, Rc);
13710 if ((Info != GOOD) || plci->internal_command)
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)
13719 plci->internal_command = plci->adjust_b_command;
13722 if (plci->adjust_b_parms_msg != NULL)
13723 api_load_msg (plci->adjust_b_parms_msg, bp);
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);
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));
13736 plci->internal_command = plci->adjust_b_command;
13737 sig_req (plci, RESOURCES, 0);
13739 plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
13742 plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
13744 case ADJUST_B_SWITCH_L1_2:
13745 if ((Rc != OK) && (Rc != OK_FC))
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;
13753 plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
13755 case ADJUST_B_RESTORE_VOICE_1:
13756 case ADJUST_B_RESTORE_VOICE_2:
13757 if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
13759 Info = adv_voice_restore_config (Id, plci, Rc);
13760 if ((Info != GOOD) || plci->internal_command)
13763 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
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)
13770 Info = dtmf_parameter_restore_config (Id, plci, Rc);
13771 if ((Info != GOOD) || plci->internal_command)
13775 plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
13777 case ADJUST_B_RESTORE_EC_1:
13778 case ADJUST_B_RESTORE_EC_2:
13779 if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
13782 Info = ec_restore_config (Id, plci, Rc);
13783 if ((Info != GOOD) || plci->internal_command)
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)
13791 if (plci_nl_busy (plci))
13793 plci->internal_command = plci->adjust_b_command;
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);
13801 api_load_msg (&plci->B_protocol, bp);
13802 Info = add_b23 (plci, bp);
13805 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x",
13806 UnMapId (Id), (char *)(FILE_), __LINE__, Info));
13809 plci->internal_command = plci->adjust_b_command;
13810 nl_req_ncci (plci, ASSIGN, 0);
13812 plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
13815 plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
13817 case ADJUST_B_ASSIGN_L23_2:
13818 if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK))
13820 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B assign failed %02x",
13821 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
13822 Info = _WRONG_STATE;
13825 if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
13827 if (Rc != ASSIGN_OK)
13829 plci->internal_command = plci->adjust_b_command;
13833 if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT)
13835 plci->adjust_b_restore = TRUE;
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)
13842 plci->internal_command = plci->adjust_b_command;
13843 if (plci_nl_busy (plci))
13845 nl_req_ncci (plci, N_CONNECT, 0);
13847 plci->adjust_b_state = ADJUST_B_CONNECT_2;
13850 plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
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))
13857 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B connect failed %02x",
13858 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
13859 Info = _WRONG_STATE;
13864 if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
13866 get_ncci (plci, (byte)(Id >> 16), plci->adjust_b_ncci);
13867 Id = (Id & 0xffff) | (((dword)(plci->adjust_b_ncci)) << 16);
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;
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;
13881 if (plci->adjust_b_state != ADJUST_B_RESTORE_DTMF_1)
13883 plci->internal_command = plci->adjust_b_command;
13887 case ADJUST_B_RESTORE_DTMF_1:
13888 case ADJUST_B_RESTORE_DTMF_2:
13889 if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
13892 Info = dtmf_restore_config (Id, plci, Rc);
13893 if ((Info != GOOD) || plci->internal_command)
13897 plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
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)
13909 Info = mixer_restore_config (Id, plci, Rc);
13910 if ((Info != GOOD) || plci->internal_command)
13914 plci->adjust_b_state = ADJUST_B_END;
13922 static void adjust_b1_resource (dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command)
13925 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_resource %d %04x",
13926 UnMapId (Id), (char *)(FILE_), __LINE__,
13927 plci->B1_resource, b1_facilities));
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;
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));
13944 static void adjust_b_restore (dword Id, PLCI *plci, byte Rc)
13946 word internal_command;
13948 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_restore %02x %04x",
13949 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
13951 internal_command = plci->internal_command;
13952 plci->internal_command = 0;
13953 switch (internal_command)
13957 if (plci->req_in != 0)
13959 plci->internal_command = ADJUST_B_RESTORE_1;
13963 case ADJUST_B_RESTORE_1:
13964 if ((Rc != OK) && (Rc != OK_FC))
13966 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B enqueued failed %02x",
13967 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
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)
13980 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore failed",
13981 UnMapId (Id), (char *)(FILE_), __LINE__));
13983 if (plci->internal_command)
13990 static void reset_b3_command (dword Id, PLCI *plci, byte Rc)
13993 word internal_command;
13995 dbug (1, dprintf ("[%06lx] %s,%d: reset_b3_command %02x %04x",
13996 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
13999 internal_command = plci->internal_command;
14000 plci->internal_command = 0;
14001 switch (internal_command)
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);
14017 dbug (1, dprintf ("[%06lx] %s,%d: Reset failed",
14018 UnMapId (Id), (char *)(FILE_), __LINE__));
14021 if (plci->internal_command)
14025 /* sendf (plci->appl, _RESET_B3_R | CONFIRM, Id, plci->number, "w", Info);*/
14026 sendf(plci->appl,_RESET_B3_I,Id,0,"s","");
14030 static void select_b_command (dword Id, PLCI *plci, byte Rc)
14033 word internal_command;
14036 dbug (1, dprintf ("[%06lx] %s,%d: select_b_command %02x %04x",
14037 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14040 internal_command = plci->internal_command;
14041 plci->internal_command = 0;
14042 switch (internal_command)
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;
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)
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;
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;
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);
14070 dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol failed",
14071 UnMapId (Id), (char *)(FILE_), __LINE__));
14074 if (plci->internal_command)
14076 if (plci->tel == ADV_VOICE)
14080 esc_chi[2] = plci->b_channel;
14081 SetVoiceChannel (plci->adapter->AdvCodecPLCI, esc_chi, plci->adapter);
14085 sendf (plci->appl, _SELECT_B_REQ | CONFIRM, Id, plci->number, "w", Info);
14089 static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc)
14092 word internal_command;
14094 dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
14095 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14098 internal_command = plci->internal_command;
14099 plci->internal_command = 0;
14100 switch (internal_command)
14104 case FAX_CONNECT_ACK_COMMAND_1:
14105 if (plci_nl_busy (plci))
14107 plci->internal_command = FAX_CONNECT_ACK_COMMAND_1;
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);
14118 case FAX_CONNECT_ACK_COMMAND_2:
14119 if ((Rc != OK) && (Rc != OK_FC))
14121 dbug (1, dprintf ("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x",
14122 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
14126 if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
14127 && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
14129 if (plci->B3_prot == 4)
14130 sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
14132 sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
14133 plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
14138 static void fax_edata_ack_command (dword Id, PLCI *plci, byte Rc)
14141 word internal_command;
14143 dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
14144 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14147 internal_command = plci->internal_command;
14148 plci->internal_command = 0;
14149 switch (internal_command)
14153 case FAX_EDATA_ACK_COMMAND_1:
14154 if (plci_nl_busy (plci))
14156 plci->internal_command = FAX_EDATA_ACK_COMMAND_1;
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);
14167 case FAX_EDATA_ACK_COMMAND_2:
14168 if ((Rc != OK) && (Rc != OK_FC))
14170 dbug (1, dprintf ("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x",
14171 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
14178 static void fax_connect_info_command (dword Id, PLCI *plci, byte Rc)
14181 word internal_command;
14183 dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_info_command %02x %04x",
14184 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14187 internal_command = plci->internal_command;
14188 plci->internal_command = 0;
14189 switch (internal_command)
14193 case FAX_CONNECT_INFO_COMMAND_1:
14194 if (plci_nl_busy (plci))
14196 plci->internal_command = FAX_CONNECT_INFO_COMMAND_1;
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);
14207 case FAX_CONNECT_INFO_COMMAND_2:
14208 if ((Rc != OK) && (Rc != OK_FC))
14210 dbug (1, dprintf ("[%06lx] %s,%d: FAX setting connect info failed %02x",
14211 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
14212 Info = _WRONG_STATE;
14215 if (plci_nl_busy (plci))
14217 plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
14220 plci->command = _CONNECT_B3_R;
14221 nl_req_ncci (plci, N_CONNECT, 0);
14225 sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
14229 static void fax_adjust_b23_command (dword Id, PLCI *plci, byte Rc)
14232 word internal_command;
14234 dbug (1, dprintf ("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x",
14235 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14238 internal_command = plci->internal_command;
14239 plci->internal_command = 0;
14240 switch (internal_command)
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);
14256 dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust failed",
14257 UnMapId (Id), (char *)(FILE_), __LINE__));
14260 if (plci->internal_command)
14262 case FAX_ADJUST_B23_COMMAND_2:
14263 if (plci_nl_busy (plci))
14265 plci->internal_command = FAX_ADJUST_B23_COMMAND_2;
14268 plci->command = _CONNECT_B3_R;
14269 nl_req_ncci (plci, N_CONNECT, 0);
14273 sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
14277 static void fax_disconnect_command (dword Id, PLCI *plci, byte Rc)
14279 word internal_command;
14281 dbug (1, dprintf ("[%06lx] %s,%d: fax_disconnect_command %02x %04x",
14282 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14284 internal_command = plci->internal_command;
14285 plci->internal_command = 0;
14286 switch (internal_command)
14290 plci->internal_command = FAX_DISCONNECT_COMMAND_1;
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))
14297 dbug (1, dprintf ("[%06lx] %s,%d: FAX disconnect EDATA failed %02x",
14298 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
14303 if ((internal_command == FAX_DISCONNECT_COMMAND_1)
14304 || (internal_command == FAX_DISCONNECT_COMMAND_2))
14306 plci->internal_command = FAX_DISCONNECT_COMMAND_2;
14311 if (internal_command == FAX_DISCONNECT_COMMAND_1)
14312 plci->internal_command = FAX_DISCONNECT_COMMAND_3;
14320 static void rtp_connect_b3_req_command (dword Id, PLCI *plci, byte Rc)
14323 word internal_command;
14325 dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x",
14326 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14329 internal_command = plci->internal_command;
14330 plci->internal_command = 0;
14331 switch (internal_command)
14335 case RTP_CONNECT_B3_REQ_COMMAND_1:
14336 if (plci_nl_busy (plci))
14338 plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_1;
14341 plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
14342 nl_req_ncci (plci, N_CONNECT, 0);
14345 case RTP_CONNECT_B3_REQ_COMMAND_2:
14346 if ((Rc != OK) && (Rc != OK_FC))
14348 dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect info failed %02x",
14349 UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
14350 Info = _WRONG_STATE;
14353 if (plci_nl_busy (plci))
14355 plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
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);
14366 case RTP_CONNECT_B3_REQ_COMMAND_3:
14369 sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
14373 static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc)
14376 word internal_command;
14378 dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
14379 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14382 internal_command = plci->internal_command;
14383 plci->internal_command = 0;
14384 switch (internal_command)
14388 case RTP_CONNECT_B3_RES_COMMAND_1:
14389 if (plci_nl_busy (plci))
14391 plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_1;
14394 plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
14395 nl_req_ncci (plci, N_CONNECT_ACK, (byte)(Id >> 16));
14398 case RTP_CONNECT_B3_RES_COMMAND_2:
14399 if ((Rc != OK) && (Rc != OK_FC))
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;
14406 if (plci_nl_busy (plci))
14408 plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
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);
14420 case RTP_CONNECT_B3_RES_COMMAND_3:
14427 static void hold_save_command (dword Id, PLCI *plci, byte Rc)
14429 byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
14431 word internal_command;
14433 dbug (1, dprintf ("[%06lx] %s,%d: hold_save_command %02x %04x",
14434 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14437 internal_command = plci->internal_command;
14438 plci->internal_command = 0;
14439 switch (internal_command)
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);
14457 dbug (1, dprintf ("[%06lx] %s,%d: HOLD save failed",
14458 UnMapId (Id), (char *)(FILE_), __LINE__));
14461 if (plci->internal_command)
14464 sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
14468 static void retrieve_restore_command (dword Id, PLCI *plci, byte Rc)
14470 byte SS_Ind[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/
14472 word internal_command;
14474 dbug (1, dprintf ("[%06lx] %s,%d: retrieve_restore_command %02x %04x",
14475 UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
14478 internal_command = plci->internal_command;
14479 plci->internal_command = 0;
14480 switch (internal_command)
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);
14496 dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore failed",
14497 UnMapId (Id), (char *)(FILE_), __LINE__));
14500 if (plci->internal_command)
14503 sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
14507 static void init_b1_config (PLCI *plci)
14510 dbug (1, dprintf ("[%06lx] %s,%d: init_b1_config",
14511 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
14512 (char *)(FILE_), __LINE__));
14514 plci->B1_resource = 0;
14515 plci->B1_facilities = 0;
14517 plci->li_bchannel_id = 0;
14518 mixer_clear_config (plci);
14521 ec_clear_config (plci);
14524 dtmf_rec_clear_config (plci);
14525 dtmf_send_clear_config (plci);
14526 dtmf_parameter_clear_config (plci);
14528 adv_voice_clear_config (plci);
14529 adjust_b_clear (plci);
14533 static void clear_b1_config (PLCI *plci)
14536 dbug (1, dprintf ("[%06lx] %s,%d: clear_b1_config",
14537 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
14538 (char *)(FILE_), __LINE__));
14540 adv_voice_clear_config (plci);
14541 adjust_b_clear (plci);
14543 ec_clear_config (plci);
14546 dtmf_rec_clear_config (plci);
14547 dtmf_send_clear_config (plci);
14548 dtmf_parameter_clear_config (plci);
14551 if ((plci->li_bchannel_id != 0)
14552 && (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci == plci))
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;
14559 plci->B1_resource = 0;
14560 plci->B1_facilities = 0;
14564 /* -----------------------------------------------------------------
14565 XON protocol local helpers
14566 ----------------------------------------------------------------- */
14567 static void channel_flow_control_remove (PLCI * plci) {
14568 DIVA_CAPI_ADAPTER * a = plci->adapter;
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;
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;
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++;
14594 static void channel_request_xon (PLCI * plci, byte ch) {
14595 DIVA_CAPI_ADAPTER * a = plci->adapter;
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;
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;
14609 if ((!plci) || (!plci->Id) || ((a = plci->adapter) == 0)) {
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);
14622 if (one_requested) {
14623 channel_xmit_xon (plci);
14628 Try to xmit next X_ON
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]);
14634 if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) {
14638 if (a->last_flow_control_ch >= max_ch) {
14639 a->last_flow_control_ch = 1;
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;
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;
14660 static void channel_xmit_xon (PLCI * plci) {
14661 DIVA_CAPI_ADAPTER * a = plci->adapter;
14664 if (plci->nl_req || !plci->NL.Id || plci->nl_remove_id) {
14667 if ((ch = (byte)find_channel_with_pending_x_on (a, plci)) == 0) {
14670 a->ch_flow_control[ch] &= ~N_XON_REQ;
14671 a->ch_flow_control[ch] |= N_XON_SENT;
14673 plci->NL.Req = plci->nl_req = (byte)N_XON;
14674 plci->NL.ReqCh = ch;
14675 plci->NL.X = plci->NData;
14677 plci->NData[0].P = &plci->RBuffer[0];
14678 plci->NData[0].PLength = 0;
14680 plci->adapter->request(&plci->NL);
14683 static int channel_can_xon (PLCI * plci, byte ch) {
14685 DIVA_CAPI_ADAPTER * a;
14691 APPLptr = plci->appl;
14697 NCCIcode = a->ch_ncci[ch] | (((word) a->Id) << 8);
14699 /* count all buffers within the Application pool */
14700 /* belonging to the same NCCI. XON if a first is */
14704 for(i=0; i<APPLptr->MaxBuffer; i++) {
14705 if(NCCIcode==APPLptr->DataNCCI[i]) count++;
14706 if(!APPLptr->DataNCCI[i] && Num==0xffff) Num = i;
14708 if ((count > 2) || (Num == 0xffff)) {
14715 /*------------------------------------------------------------------*/
14717 static word CPN_filter_ok(byte *cpn,DIVA_CAPI_ADAPTER * a,word offset)
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)
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];
14740 set_group_ind_mask (plci); /* all APPLs within this inc. call are allowed to dial in */
14742 if(!a->group_optimization_enabled)
14744 dbug(1,dprintf("No group optimization"));
14748 dbug(1,dprintf("Group optimization = 0x%x...", a->group_optimization_enabled));
14750 for(i=0;i<MAX_CIP_TYPES;i++)
14752 info_mask_group[i] = 0;
14753 cip_mask_group [i] = 0;
14755 for(i=0;i<MAX_APPL;i++)
14757 appl_number_group_type[i] = 0;
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) )
14763 dbug(1,dprintf("Multi-Instance capable, no optimization required"));
14764 return; /* allow good application unfiltered access */
14767 for(i=0; i<max_appl; i++) /* Build CIP Groups */
14769 if(application[i].Id && a->CIP_Mask[i] )
14771 for(k=0,busy=FALSE; k<a->max_plci; k++)
14775 auxplci = &a->plci[k];
14776 if(auxplci->appl == &application[i]) /* application has a busy PLCI */
14779 dbug(1,dprintf("Appl 0x%x is busy",i+1));
14781 else if(test_c_ind_mask_bit (auxplci, i)) /* application has an incoming call pending */
14784 dbug(1,dprintf("Appl 0x%x has inc. call pending",i+1));
14789 for(j=0,group_found=0; j<=(MAX_CIP_TYPES) && !busy &&!group_found; j++) /* build groups with free applications only */
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;
14795 dbug(1,dprintf("Field overflow appl 0x%x",i+1));
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 */
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]));
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 */
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]));
14815 for(i=0; i<max_appl; i++) /* Build group_optimization_mask_table */
14817 if(appl_number_group_type[i]) /* application is free, has listens and is member of a group */
14819 if(appl_number_group_type[i] == MAX_CIP_TYPES)
14821 dbug(1,dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled",appl_number_group_type[i],i+1));
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 */
14828 if(appl_number_group_type[i] == appl_number_group_type[j])
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 */
14837 else /* application should not get a call */
14839 clear_group_ind_mask_bit (plci, i);
14847 /* OS notifies the driver about a application Capi_Register */
14848 word CapiRegister(word id)
14850 word i,j,appls_found;
14853 DIVA_CAPI_ADAPTER *a;
14855 for(i=0,appls_found=0; i<max_appl; i++)
14857 if( application[i].Id && (application[i].Id!=id) )
14859 appls_found++; /* an application has been found */
14863 if(appls_found) return TRUE;
14864 for(i=0; i<max_adapter; i++) /* scan all adapters... */
14869 if(a->flag_dynamic_l1_down) /* remove adapter from L1 tristate (Huntgroup) */
14871 if(!appls_found) /* first application does a capi register */
14873 if((j=get_plci(a))) /* activate L1 of all adapters */
14875 plci = &a->plci[j-1];
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);
14895 /*------------------------------------------------------------------*/
14897 /* Functions for virtual Switching e.g. Transfer by join, Conference */
14899 static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms)
14902 /* Format of vswitch_t:
14905 2 byte VSWITCH_REQ/VSWITCH_IND
14907 4 word VSwitchcommand
14914 plci->Sig.Ind==NCR_FACILITY
14918 for(i=0;i<MAX_MULTI_IE;i++)
14920 if(!parms[i][0]) continue;
14923 parms[i][0]=0; /* kill it */
14926 dbug(1,dprintf("VSwitchReqInd(%d)",parms[i][4]));
14927 switch(parms[i][4])
14930 if(!plci->relatedPTYPLCI ||
14931 (plci->ptyState!=S_ECT && plci->relatedPTYPLCI->ptyState!=S_ECT))
14935 /* remember all necessary informations */
14936 if(parms[i][0]!=11 || parms[i][8]!=3) /* Length Test */
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 */
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 */
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;
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);
14970 if(plci->relatedPTYPLCI &&
14971 plci->vswitchstate==3 &&
14972 plci->relatedPTYPLCI->vswitchstate==3)
14974 add_p(plci->relatedPTYPLCI,ESC,&parms[i][0]);
14975 sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0);
14976 send_req(plci->relatedPTYPLCI);
14980 parms[i][0]=0; /* kill it */
14985 /*------------------------------------------------------------------*/
14987 static int diva_get_dma_descriptor (PLCI *plci, dword *dma_magic) {
14989 IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e;
14991 if (!(diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_RX_DMA)) {
14995 pReq->xdi_dma_descriptor_operation.Req = 0;
14996 pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
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;
15003 e.user[0] = plci->adapter->Id - 1;
15004 plci->adapter->request((ENTITY*)pReq);
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)",
15012 pReq->xdi_dma_descriptor_operation.info.descriptor_number,
15014 return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
15016 dbug(1,dprintf("dma_alloc failed"));
15021 static void diva_free_dma_descriptor (PLCI *plci, int nr) {
15023 IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e;
15029 pReq->xdi_dma_descriptor_operation.Req = 0;
15030 pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
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;
15037 e.user[0] = plci->adapter->Id - 1;
15038 plci->adapter->request((ENTITY*)pReq);
15040 if (!pReq->xdi_dma_descriptor_operation.info.operation) {
15041 dbug(1,dprintf("dma_free(%d)", nr));
15043 dbug(1,dprintf("dma_free failed (%d)", nr));
15047 /*------------------------------------------------------------------*/