3 Copyright (c) Eicon Networks, 2002.
5 This source file is supplied for the use with
6 Eicon Networks range of DIVA Server Adapters.
8 Eicon File Revision : 2.1
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
17 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
40 #define FILE_ "MESSAGE.C"
51 /*------------------------------------------------------------------*/
52 /* This is options supported for all adapters that are server by */
53 /* XDI driver. Allo it is not necessary to ask it from every adapter*/
54 /* and it is not necessary to save it separate for every adapter */
55 /* Macrose defined here have only local meaning */
56 /*------------------------------------------------------------------*/
57 static dword diva_xdi_extended_features
= 0;
59 #define DIVA_CAPI_USE_CMA 0x00000001
60 #define DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR 0x00000002
61 #define DIVA_CAPI_XDI_PROVIDES_NO_CANCEL 0x00000004
62 #define DIVA_CAPI_XDI_PROVIDES_RX_DMA 0x00000008
65 CAPI can request to process all return codes self only if:
66 protocol code supports this && xdi supports this
68 #define DIVA_CAPI_SUPPORTS_NO_CANCEL(__a__) (((__a__)->manufacturer_features&MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)&& ((__a__)->manufacturer_features & MANUFACTURER_FEATURE_OK_FC_LABEL) && (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_NO_CANCEL))
70 /*------------------------------------------------------------------*/
71 /* local function prototypes */
72 /*------------------------------------------------------------------*/
74 static void group_optimization(DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
);
75 static void set_group_ind_mask (PLCI
*plci
);
76 static void clear_group_ind_mask_bit (PLCI
*plci
, word b
);
77 static byte
test_group_ind_mask_bit (PLCI
*plci
, word b
);
78 void AutomaticLaw(DIVA_CAPI_ADAPTER
*);
79 word
CapiRelease(word
);
80 word
CapiRegister(word
);
81 word
api_put(APPL
*, CAPI_MSG
*);
82 static word
api_parse(byte
*, word
, byte
*, API_PARSE
*);
83 static void api_save_msg(API_PARSE
*in
, byte
*format
, API_SAVE
*out
);
84 static void api_load_msg(API_SAVE
*in
, API_PARSE
*out
);
86 word
api_remove_start(void);
87 void api_remove_complete(void);
89 static void plci_remove(PLCI
*);
90 static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER
* a
);
91 static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER
*, IDI_SYNC_REQ
*);
93 void callback(ENTITY
*);
95 static void control_rc(PLCI
*, byte
, byte
, byte
, byte
, byte
);
96 static void data_rc(PLCI
*, byte
);
97 static void data_ack(PLCI
*, byte
);
98 static void sig_ind(PLCI
*);
99 static void SendInfo(PLCI
*, dword
, byte
* *, byte
);
100 static void SendSetupInfo(APPL
*, PLCI
*, dword
, byte
* *, byte
);
101 static void SendSSExtInd(APPL
*, PLCI
* plci
, dword Id
, byte
* * parms
);
103 static void VSwitchReqInd(PLCI
*plci
, dword Id
, byte
**parms
);
105 static void nl_ind(PLCI
*);
107 static byte
connect_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
108 static byte
connect_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
109 static byte
connect_a_res(dword
,word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
110 static byte
disconnect_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
111 static byte
disconnect_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
112 static byte
listen_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
113 static byte
info_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
114 static byte
info_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
115 static byte
alert_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
116 static byte
facility_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
117 static byte
facility_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
118 static byte
connect_b3_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
119 static byte
connect_b3_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
120 static byte
connect_b3_a_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
121 static byte
disconnect_b3_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
122 static byte
disconnect_b3_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
123 static byte
data_b3_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
124 static byte
data_b3_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
125 static byte
reset_b3_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
126 static byte
reset_b3_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
127 static byte
connect_b3_t90_a_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
128 static byte
select_b_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
129 static byte
manufacturer_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
130 static byte
manufacturer_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
132 static word
get_plci(DIVA_CAPI_ADAPTER
*);
133 static void add_p(PLCI
*, byte
, byte
*);
134 static void add_s(PLCI
* plci
, byte code
, API_PARSE
* p
);
135 static void add_ss(PLCI
* plci
, byte code
, API_PARSE
* p
);
136 static void add_ie(PLCI
* plci
, byte code
, byte
* p
, word p_length
);
137 static void add_d(PLCI
*, word
, byte
*);
138 static void add_ai(PLCI
*, API_PARSE
*);
139 static word
add_b1(PLCI
*, API_PARSE
*, word
, word
);
140 static word
add_b23(PLCI
*, API_PARSE
*);
141 static word
add_modem_b23 (PLCI
* plci
, API_PARSE
* bp_parms
);
142 static void sig_req(PLCI
*, byte
, byte
);
143 static void nl_req_ncci(PLCI
*, byte
, byte
);
144 static void send_req(PLCI
*);
145 static void send_data(PLCI
*);
146 static word
plci_remove_check(PLCI
*);
147 static void listen_check(DIVA_CAPI_ADAPTER
*);
148 static byte
AddInfo(byte
**, byte
**, byte
*, byte
*);
149 static byte
getChannel(API_PARSE
*);
150 static void IndParse(PLCI
*, word
*, byte
**, byte
);
151 static byte
ie_compare(byte
*, byte
*);
152 static word
find_cip(DIVA_CAPI_ADAPTER
*, byte
*, byte
*);
153 static word
CPN_filter_ok(byte
*cpn
,DIVA_CAPI_ADAPTER
*,word
);
158 static void channel_flow_control_remove (PLCI
* plci
);
159 static void channel_x_off (PLCI
* plci
, byte ch
, byte flag
);
160 static void channel_x_on (PLCI
* plci
, byte ch
);
161 static void channel_request_xon (PLCI
* plci
, byte ch
);
162 static void channel_xmit_xon (PLCI
* plci
);
163 static int channel_can_xon (PLCI
* plci
, byte ch
);
164 static void channel_xmit_extended_xon (PLCI
* plci
);
166 static byte
SendMultiIE(PLCI
* plci
, dword Id
, byte
* * parms
, byte ie_type
, dword info_mask
, byte setupParse
);
167 static word
AdvCodecSupport(DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, byte
);
168 static void CodecIdCheck(DIVA_CAPI_ADAPTER
*, PLCI
*);
169 static void SetVoiceChannel(PLCI
*, byte
*, DIVA_CAPI_ADAPTER
* );
170 static void VoiceChannelOff(PLCI
*plci
);
171 static void adv_voice_write_coefs (PLCI
*plci
, word write_command
);
172 static void adv_voice_clear_config (PLCI
*plci
);
174 static word
get_b1_facilities (PLCI
* plci
, byte b1_resource
);
175 static byte
add_b1_facilities (PLCI
* plci
, byte b1_resource
, word b1_facilities
);
176 static void adjust_b1_facilities (PLCI
*plci
, byte new_b1_resource
, word new_b1_facilities
);
177 static word
adjust_b_process (dword Id
, PLCI
*plci
, byte Rc
);
178 static void adjust_b1_resource (dword Id
, PLCI
*plci
, API_SAVE
*bp_msg
, word b1_facilities
, word internal_command
);
179 static void adjust_b_restore (dword Id
, PLCI
*plci
, byte Rc
);
180 static void reset_b3_command (dword Id
, PLCI
*plci
, byte Rc
);
181 static void select_b_command (dword Id
, PLCI
*plci
, byte Rc
);
182 static void fax_connect_ack_command (dword Id
, PLCI
*plci
, byte Rc
);
183 static void fax_edata_ack_command (dword Id
, PLCI
*plci
, byte Rc
);
184 static void fax_connect_info_command (dword Id
, PLCI
*plci
, byte Rc
);
185 static void fax_adjust_b23_command (dword Id
, PLCI
*plci
, byte Rc
);
186 static void fax_disconnect_command (dword Id
, PLCI
*plci
, byte Rc
);
187 static void hold_save_command (dword Id
, PLCI
*plci
, byte Rc
);
188 static void retrieve_restore_command (dword Id
, PLCI
*plci
, byte Rc
);
189 static void init_b1_config (PLCI
*plci
);
190 static void clear_b1_config (PLCI
*plci
);
192 static void dtmf_command (dword Id
, PLCI
*plci
, byte Rc
);
193 static byte
dtmf_request (dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
);
194 static void dtmf_confirmation (dword Id
, PLCI
*plci
);
195 static void dtmf_indication (dword Id
, PLCI
*plci
, byte
*msg
, word length
);
196 static void dtmf_parameter_write (PLCI
*plci
);
199 static void mixer_set_bchannel_id_esc (PLCI
*plci
, byte bchannel_id
);
200 static void mixer_set_bchannel_id (PLCI
*plci
, byte
*chi
);
201 static void mixer_clear_config (PLCI
*plci
);
202 static void mixer_notify_update (PLCI
*plci
, byte others
);
203 static void mixer_command (dword Id
, PLCI
*plci
, byte Rc
);
204 static byte
mixer_request (dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
);
205 static void mixer_indication_coefs_set (dword Id
, PLCI
*plci
);
206 static void mixer_indication_xconnect_from (dword Id
, PLCI
*plci
, byte
*msg
, word length
);
207 static void mixer_indication_xconnect_to (dword Id
, PLCI
*plci
, byte
*msg
, word length
);
208 static void mixer_remove (PLCI
*plci
);
211 static void ec_command (dword Id
, PLCI
*plci
, byte Rc
);
212 static byte
ec_request (dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
);
213 static void ec_indication (dword Id
, PLCI
*plci
, byte
*msg
, word length
);
216 static void rtp_connect_b3_req_command (dword Id
, PLCI
*plci
, byte Rc
);
217 static void rtp_connect_b3_res_command (dword Id
, PLCI
*plci
, byte Rc
);
220 static int diva_get_dma_descriptor (PLCI
*plci
, dword
*dma_magic
);
221 static void diva_free_dma_descriptor (PLCI
*plci
, int nr
);
223 /*------------------------------------------------------------------*/
224 /* external function prototypes */
225 /*------------------------------------------------------------------*/
227 extern byte
MapController (byte
);
228 extern byte
UnMapController (byte
);
229 #define MapId(Id) (((Id) & 0xffffff00L) | MapController ((byte)(Id)))
230 #define UnMapId(Id) (((Id) & 0xffffff00L) | UnMapController ((byte)(Id)))
232 void sendf(APPL
*, word
, dword
, word
, byte
*, ...);
233 void * TransmitBufferSet(APPL
* appl
, dword ref
);
234 void * TransmitBufferGet(APPL
* appl
, void * p
);
235 void TransmitBufferFree(APPL
* appl
, void * p
);
236 void * ReceiveBufferGet(APPL
* appl
, int Num
);
238 int fax_head_line_time (char *buffer
);
241 /*------------------------------------------------------------------*/
242 /* Global data definitions */
243 /*------------------------------------------------------------------*/
244 extern byte max_adapter
;
245 extern byte max_appl
;
246 extern DIVA_CAPI_ADAPTER
* adapter
;
247 extern APPL
* application
;
255 static byte remove_started
= false;
256 static PLCI dummy_plci
;
259 static struct _ftable
{
262 byte (* function
)(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
264 {_DATA_B3_R
, "dwww", data_b3_req
},
265 {_DATA_B3_I
|RESPONSE
, "w", data_b3_res
},
266 {_INFO_R
, "ss", info_req
},
267 {_INFO_I
|RESPONSE
, "", info_res
},
268 {_CONNECT_R
, "wsssssssss", connect_req
},
269 {_CONNECT_I
|RESPONSE
, "wsssss", connect_res
},
270 {_CONNECT_ACTIVE_I
|RESPONSE
, "", connect_a_res
},
271 {_DISCONNECT_R
, "s", disconnect_req
},
272 {_DISCONNECT_I
|RESPONSE
, "", disconnect_res
},
273 {_LISTEN_R
, "dddss", listen_req
},
274 {_ALERT_R
, "s", alert_req
},
275 {_FACILITY_R
, "ws", facility_req
},
276 {_FACILITY_I
|RESPONSE
, "ws", facility_res
},
277 {_CONNECT_B3_R
, "s", connect_b3_req
},
278 {_CONNECT_B3_I
|RESPONSE
, "ws", connect_b3_res
},
279 {_CONNECT_B3_ACTIVE_I
|RESPONSE
, "", connect_b3_a_res
},
280 {_DISCONNECT_B3_R
, "s", disconnect_b3_req
},
281 {_DISCONNECT_B3_I
|RESPONSE
, "", disconnect_b3_res
},
282 {_RESET_B3_R
, "s", reset_b3_req
},
283 {_RESET_B3_I
|RESPONSE
, "", reset_b3_res
},
284 {_CONNECT_B3_T90_ACTIVE_I
|RESPONSE
, "ws", connect_b3_t90_a_res
},
285 {_CONNECT_B3_T90_ACTIVE_I
|RESPONSE
, "", connect_b3_t90_a_res
},
286 {_SELECT_B_REQ
, "s", select_b_req
},
287 {_MANUFACTURER_R
, "dws", manufacturer_req
},
288 {_MANUFACTURER_I
|RESPONSE
, "dws", manufacturer_res
},
289 {_MANUFACTURER_I
|RESPONSE
, "", manufacturer_res
}
292 static byte
* cip_bc
[29][2] = {
294 { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 1 */
295 { "\x02\x88\x90", "\x02\x88\x90" }, /* 2 */
296 { "\x02\x89\x90", "\x02\x89\x90" }, /* 3 */
297 { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 4 */
298 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 5 */
299 { "\x02\x98\x90", "\x02\x98\x90" }, /* 6 */
300 { "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */
301 { "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */
302 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 9 */
310 { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 16 */
311 { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 17 */
312 { "\x02\x88\x90", "\x02\x88\x90" }, /* 18 */
313 { "\x02\x88\x90", "\x02\x88\x90" }, /* 19 */
314 { "\x02\x88\x90", "\x02\x88\x90" }, /* 20 */
315 { "\x02\x88\x90", "\x02\x88\x90" }, /* 21 */
316 { "\x02\x88\x90", "\x02\x88\x90" }, /* 22 */
317 { "\x02\x88\x90", "\x02\x88\x90" }, /* 23 */
318 { "\x02\x88\x90", "\x02\x88\x90" }, /* 24 */
319 { "\x02\x88\x90", "\x02\x88\x90" }, /* 25 */
320 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 26 */
321 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 27 */
322 { "\x02\x88\x90", "\x02\x88\x90" } /* 28 */
325 static byte
* cip_hlc
[29] = {
343 "\x02\x91\x81", /* 16 */
344 "\x02\x91\x84", /* 17 */
345 "\x02\x91\xa1", /* 18 */
346 "\x02\x91\xa4", /* 19 */
347 "\x02\x91\xa8", /* 20 */
348 "\x02\x91\xb1", /* 21 */
349 "\x02\x91\xb2", /* 22 */
350 "\x02\x91\xb5", /* 23 */
351 "\x02\x91\xb8", /* 24 */
352 "\x02\x91\xc1", /* 25 */
353 "\x02\x91\x81", /* 26 */
354 "\x03\x91\xe0\x01", /* 27 */
355 "\x03\x91\xe0\x02" /* 28 */
358 /*------------------------------------------------------------------*/
360 #define V120_HEADER_LENGTH 1
361 #define V120_HEADER_EXTEND_BIT 0x80
362 #define V120_HEADER_BREAK_BIT 0x40
363 #define V120_HEADER_C1_BIT 0x04
364 #define V120_HEADER_C2_BIT 0x08
365 #define V120_HEADER_FLUSH_COND (V120_HEADER_BREAK_BIT | V120_HEADER_C1_BIT | V120_HEADER_C2_BIT)
367 static byte v120_default_header
[] =
370 0x83 /* Ext, BR , res, res, C2 , C1 , B , F */
374 static byte v120_break_header
[] =
377 0xc3 | V120_HEADER_BREAK_BIT
/* Ext, BR , res, res, C2 , C1 , B , F */
382 /*------------------------------------------------------------------*/
383 /* API_PUT function */
384 /*------------------------------------------------------------------*/
386 word
api_put(APPL
* appl
, CAPI_MSG
* msg
)
392 DIVA_CAPI_ADAPTER
* a
;
397 API_PARSE msg_parms
[MAX_MSG_PARMS
+1];
399 if (msg
->header
.length
< sizeof (msg
->header
) ||
400 msg
->header
.length
> MAX_MSG_SIZE
) {
401 dbug(1,dprintf("bad len"));
405 controller
= (byte
)((msg
->header
.controller
&0x7f)-1);
407 /* controller starts with 0 up to (max_adapter - 1) */
408 if ( controller
>= max_adapter
)
410 dbug(1,dprintf("invalid ctrl"));
414 a
= &adapter
[controller
];
416 if ((msg
->header
.plci
!= 0) && (msg
->header
.plci
<= a
->max_plci
) && !a
->adapter_disabled
)
418 dbug(1,dprintf("plci=%x",msg
->header
.plci
));
419 plci
= &a
->plci
[msg
->header
.plci
-1];
420 ncci
= GET_WORD(&msg
->header
.ncci
);
423 || (plci
->State
== INC_CON_PENDING
)
424 || (plci
->State
== INC_CON_ALERT
)
425 || (msg
->header
.command
== (_DISCONNECT_I
|RESPONSE
)))
427 || (msg
->header
.command
== (_DISCONNECT_B3_I
|RESPONSE
))
428 || ((ncci
< MAX_NCCI
+1) && (a
->ncci_plci
[ncci
] == plci
->Id
))))
430 i
= plci
->msg_in_read_pos
;
431 j
= plci
->msg_in_write_pos
;
434 if (j
+ msg
->header
.length
+ MSG_IN_OVERHEAD
<= MSG_IN_QUEUE_SIZE
)
435 i
+= MSG_IN_QUEUE_SIZE
- j
;
442 n
= (((CAPI_MSG
*)(plci
->msg_in_queue
))->header
.length
+ MSG_IN_OVERHEAD
+ 3) & 0xfffc;
444 if (i
> MSG_IN_QUEUE_SIZE
- n
)
445 i
= MSG_IN_QUEUE_SIZE
- n
+ 1;
449 if (i
<= ((msg
->header
.length
+ MSG_IN_OVERHEAD
+ 3) & 0xfffc))
452 dbug(0,dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d",
453 msg
->header
.length
, plci
->msg_in_write_pos
,
454 plci
->msg_in_read_pos
, plci
->msg_in_wrap_pos
, i
));
459 if ((((byte
*) msg
) < ((byte
*)(plci
->msg_in_queue
)))
460 || (((byte
*) msg
) >= ((byte
*)(plci
->msg_in_queue
)) + sizeof(plci
->msg_in_queue
)))
462 if (plci
->msg_in_write_pos
!= plci
->msg_in_read_pos
)
465 if (msg
->header
.command
== _DATA_B3_R
)
467 if (msg
->header
.length
< 20)
469 dbug(1,dprintf("DATA_B3 REQ wrong length %d", msg
->header
.length
));
472 ncci_ptr
= &(a
->ncci
[ncci
]);
473 n
= ncci_ptr
->data_pending
;
474 l
= ncci_ptr
->data_ack_pending
;
475 k
= plci
->msg_in_read_pos
;
476 while (k
!= plci
->msg_in_write_pos
)
478 if (k
== plci
->msg_in_wrap_pos
)
480 if ((((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[k
]))->header
.command
== _DATA_B3_R
)
481 && (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[k
]))->header
.ncci
== ncci
))
484 if (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[k
]))->info
.data_b3_req
.Flags
& 0x0004)
488 k
+= (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[k
]))->header
.length
+
489 MSG_IN_OVERHEAD
+ 3) & 0xfffc;
492 if ((n
>= MAX_DATA_B3
) || (l
>= MAX_DATA_ACK
))
494 dbug(0,dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d",
495 ncci_ptr
->data_pending
, n
, ncci_ptr
->data_ack_pending
, l
));
499 if (plci
->req_in
|| plci
->internal_command
)
501 if ((((byte
*) msg
) >= ((byte
*)(plci
->msg_in_queue
)))
502 && (((byte
*) msg
) < ((byte
*)(plci
->msg_in_queue
)) + sizeof(plci
->msg_in_queue
)))
504 dbug(0,dprintf("Q-FULL3(requeue)"));
513 if (plci
->req_in
|| plci
->internal_command
)
517 plci
->command
= msg
->header
.command
;
518 plci
->number
= msg
->header
.number
;
523 dbug(1,dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d",
524 msg
->header
.command
, plci
->req_in
, plci
->internal_command
,
525 msg
->header
.length
, plci
->msg_in_write_pos
,
526 plci
->msg_in_read_pos
, plci
->msg_in_wrap_pos
, i
));
528 plci
->msg_in_wrap_pos
= plci
->msg_in_write_pos
;
529 m
= (CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[j
]);
530 for (i
= 0; i
< msg
->header
.length
; i
++)
531 ((byte
*)(plci
->msg_in_queue
))[j
++] = ((byte
*) msg
)[i
];
532 if (m
->header
.command
== _DATA_B3_R
)
535 m
->info
.data_b3_req
.Data
= (dword
)(long)(TransmitBufferSet (appl
, m
->info
.data_b3_req
.Data
));
539 j
= (j
+ 3) & 0xfffc;
541 *((APPL
* *)(&((byte
*)(plci
->msg_in_queue
))[j
])) = appl
;
542 plci
->msg_in_write_pos
= j
+ MSG_IN_OVERHEAD
;
551 dbug(1,dprintf("com=%x",msg
->header
.command
));
553 for(j
=0;j
<MAX_MSG_PARMS
+1;j
++) msg_parms
[j
].length
= 0;
554 for(i
=0, ret
= _BAD_MSG
;
555 i
<(sizeof(ftable
)/sizeof(struct _ftable
));
558 if(ftable
[i
].command
==msg
->header
.command
) {
559 /* break loop if the message is correct, otherwise continue scan */
560 /* (for example: CONNECT_B3_T90_ACT_RES has two specifications) */
561 if(!api_parse(msg
->info
.b
,(word
)(msg
->header
.length
-12),ftable
[i
].format
,msg_parms
)) {
565 for(j
=0;j
<MAX_MSG_PARMS
+1;j
++) msg_parms
[j
].length
= 0;
569 dbug(1,dprintf("BAD_MSG"));
570 if(plci
) plci
->command
= 0;
575 c
= ftable
[i
].function(GET_DWORD(&msg
->header
.controller
),
582 channel_xmit_extended_xon (plci
);
584 if(c
==1) send_req(plci
);
585 if(c
==2 && plci
) plci
->req_in
= plci
->req_in_start
= plci
->req_out
= 0;
586 if(plci
&& !plci
->req_in
) plci
->command
= 0;
591 /*------------------------------------------------------------------*/
592 /* api_parse function, check the format of api messages */
593 /*------------------------------------------------------------------*/
595 static word
api_parse(byte
*msg
, word length
, byte
*format
, API_PARSE
*parms
)
600 for(i
=0,p
=0; format
[i
]; i
++) {
603 parms
[i
].info
= &msg
[p
];
618 parms
[i
].length
= msg
[p
+1] + (msg
[p
+2]<<8);
619 p
+=(parms
[i
].length
+3);
622 parms
[i
].length
= msg
[p
];
623 p
+=(parms
[i
].length
+1);
628 if(p
>length
) return true;
630 if(parms
) parms
[i
].info
= NULL
;
634 static void api_save_msg(API_PARSE
*in
, byte
*format
, API_SAVE
*out
)
640 for (i
= 0; format
[i
] != '\0'; i
++)
642 out
->parms
[i
].info
= p
;
643 out
->parms
[i
].length
= in
[i
].length
;
656 n
= in
[i
].length
+ 1;
659 for (j
= 0; j
< n
; j
++)
660 *(p
++) = in
[i
].info
[j
];
662 out
->parms
[i
].info
= NULL
;
663 out
->parms
[i
].length
= 0;
666 static void api_load_msg(API_SAVE
*in
, API_PARSE
*out
)
673 out
[i
].info
= in
->parms
[i
].info
;
674 out
[i
].length
= in
->parms
[i
].length
;
675 } while (in
->parms
[i
++].info
);
679 /*------------------------------------------------------------------*/
680 /* CAPI remove function */
681 /*------------------------------------------------------------------*/
683 word
api_remove_start(void)
688 if(!remove_started
) {
689 remove_started
= true;
690 for(i
=0;i
<max_adapter
;i
++) {
691 if(adapter
[i
].request
) {
692 for(j
=0;j
<adapter
[i
].max_plci
;j
++) {
693 if(adapter
[i
].plci
[j
].Sig
.Id
) plci_remove(&adapter
[i
].plci
[j
]);
700 for(i
=0;i
<max_adapter
;i
++) {
701 if(adapter
[i
].request
) {
702 for(j
=0;j
<adapter
[i
].max_plci
;j
++) {
703 if(adapter
[i
].plci
[j
].Sig
.Id
) return 1;
708 api_remove_complete();
713 /*------------------------------------------------------------------*/
714 /* internal command queue */
715 /*------------------------------------------------------------------*/
717 static void init_internal_command_queue (PLCI
*plci
)
721 dbug (1, dprintf ("%s,%d: init_internal_command_queue",
722 (char *)(FILE_
), __LINE__
));
724 plci
->internal_command
= 0;
725 for (i
= 0; i
< MAX_INTERNAL_COMMAND_LEVELS
; i
++)
726 plci
->internal_command_queue
[i
] = NULL
;
730 static void start_internal_command (dword Id
, PLCI
*plci
, t_std_internal_command command_function
)
734 dbug (1, dprintf ("[%06lx] %s,%d: start_internal_command",
735 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
737 if (plci
->internal_command
== 0)
739 plci
->internal_command_queue
[0] = command_function
;
740 (* command_function
)(Id
, plci
, OK
);
745 while (plci
->internal_command_queue
[i
] != NULL
)
747 plci
->internal_command_queue
[i
] = command_function
;
752 static void next_internal_command (dword Id
, PLCI
*plci
)
756 dbug (1, dprintf ("[%06lx] %s,%d: next_internal_command",
757 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
759 plci
->internal_command
= 0;
760 plci
->internal_command_queue
[0] = NULL
;
761 while (plci
->internal_command_queue
[1] != NULL
)
763 for (i
= 0; i
< MAX_INTERNAL_COMMAND_LEVELS
- 1; i
++)
764 plci
->internal_command_queue
[i
] = plci
->internal_command_queue
[i
+1];
765 plci
->internal_command_queue
[MAX_INTERNAL_COMMAND_LEVELS
- 1] = NULL
;
766 (*(plci
->internal_command_queue
[0]))(Id
, plci
, OK
);
767 if (plci
->internal_command
!= 0)
769 plci
->internal_command_queue
[0] = NULL
;
774 /*------------------------------------------------------------------*/
775 /* NCCI allocate/remove function */
776 /*------------------------------------------------------------------*/
778 static dword ncci_mapping_bug
= 0;
780 static word
get_ncci (PLCI
*plci
, byte ch
, word force_ncci
)
782 DIVA_CAPI_ADAPTER
*a
;
786 if (!ch
|| a
->ch_ncci
[ch
])
789 dbug(1,dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x",
790 ncci_mapping_bug
, ch
, force_ncci
, a
->ncci_ch
[a
->ch_ncci
[ch
]], a
->ch_ncci
[ch
]));
799 if ((ch
< MAX_NCCI
+1) && !a
->ncci_ch
[ch
])
804 while ((ncci
< MAX_NCCI
+1) && a
->ncci_ch
[ncci
])
806 if (ncci
== MAX_NCCI
+1)
813 while ((j
< MAX_NCCI
+1) && (a
->ncci_ch
[j
] != i
))
821 } while ((j
< MAX_NCCI
+1) && (a
->ncci_ch
[j
] != i
));
823 } while ((i
< MAX_NL_CHANNEL
+1) && (j
< MAX_NCCI
+1));
824 if (i
< MAX_NL_CHANNEL
+1)
826 dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x",
827 ncci_mapping_bug
, ch
, force_ncci
, i
, k
, j
));
831 dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x",
832 ncci_mapping_bug
, ch
, force_ncci
));
837 a
->ncci_plci
[ncci
] = plci
->Id
;
838 a
->ncci_state
[ncci
] = IDLE
;
839 if (!plci
->ncci_ring_list
)
840 plci
->ncci_ring_list
= ncci
;
842 a
->ncci_next
[ncci
] = a
->ncci_next
[plci
->ncci_ring_list
];
843 a
->ncci_next
[plci
->ncci_ring_list
] = (byte
) ncci
;
845 a
->ncci_ch
[ncci
] = ch
;
846 a
->ch_ncci
[ch
] = (byte
) ncci
;
847 dbug(1,dprintf("NCCI mapping established %ld %02x %02x %02x-%02x",
848 ncci_mapping_bug
, ch
, force_ncci
, ch
, ncci
));
854 static void ncci_free_receive_buffers (PLCI
*plci
, word ncci
)
856 DIVA_CAPI_ADAPTER
*a
;
862 Id
= (((dword
) ncci
) << 16) | (((word
)(plci
->Id
)) << 8) | a
->Id
;
865 if (a
->ncci_plci
[ncci
] == plci
->Id
)
870 dbug(1,dprintf("NCCI mapping appl expected %ld %08lx",
871 ncci_mapping_bug
, Id
));
876 ncci_code
= ncci
| (((word
) a
->Id
) << 8);
877 for (i
= 0; i
< appl
->MaxBuffer
; i
++)
879 if ((appl
->DataNCCI
[i
] == ncci_code
)
880 && (((byte
)(appl
->DataFlags
[i
] >> 8)) == plci
->Id
))
882 appl
->DataNCCI
[i
] = 0;
890 for (ncci
= 1; ncci
< MAX_NCCI
+1; ncci
++)
892 if (a
->ncci_plci
[ncci
] == plci
->Id
)
897 dbug(1,dprintf("NCCI mapping no appl %ld %08lx",
898 ncci_mapping_bug
, Id
));
903 ncci_code
= ncci
| (((word
) a
->Id
) << 8);
904 for (i
= 0; i
< appl
->MaxBuffer
; i
++)
906 if ((appl
->DataNCCI
[i
] == ncci_code
)
907 && (((byte
)(appl
->DataFlags
[i
] >> 8)) == plci
->Id
))
909 appl
->DataNCCI
[i
] = 0;
919 static void cleanup_ncci_data (PLCI
*plci
, word ncci
)
923 if (ncci
&& (plci
->adapter
->ncci_plci
[ncci
] == plci
->Id
))
925 ncci_ptr
= &(plci
->adapter
->ncci
[ncci
]);
928 while (ncci_ptr
->data_pending
!= 0)
930 if (!plci
->data_sent
|| (ncci_ptr
->DBuffer
[ncci_ptr
->data_out
].P
!= plci
->data_sent_ptr
))
931 TransmitBufferFree (plci
->appl
, ncci_ptr
->DBuffer
[ncci_ptr
->data_out
].P
);
932 (ncci_ptr
->data_out
)++;
933 if (ncci_ptr
->data_out
== MAX_DATA_B3
)
934 ncci_ptr
->data_out
= 0;
935 (ncci_ptr
->data_pending
)--;
938 ncci_ptr
->data_out
= 0;
939 ncci_ptr
->data_pending
= 0;
940 ncci_ptr
->data_ack_out
= 0;
941 ncci_ptr
->data_ack_pending
= 0;
946 static void ncci_remove (PLCI
*plci
, word ncci
, byte preserve_ncci
)
948 DIVA_CAPI_ADAPTER
*a
;
953 Id
= (((dword
) ncci
) << 16) | (((word
)(plci
->Id
)) << 8) | a
->Id
;
955 ncci_free_receive_buffers (plci
, ncci
);
958 if (a
->ncci_plci
[ncci
] != plci
->Id
)
961 dbug(1,dprintf("NCCI mapping doesn't exist %ld %08lx %02x",
962 ncci_mapping_bug
, Id
, preserve_ncci
));
966 cleanup_ncci_data (plci
, ncci
);
967 dbug(1,dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
968 ncci_mapping_bug
, Id
, preserve_ncci
, a
->ncci_ch
[ncci
], ncci
));
969 a
->ch_ncci
[a
->ncci_ch
[ncci
]] = 0;
972 a
->ncci_ch
[ncci
] = 0;
973 a
->ncci_plci
[ncci
] = 0;
974 a
->ncci_state
[ncci
] = IDLE
;
975 i
= plci
->ncci_ring_list
;
976 while ((i
!= 0) && (a
->ncci_next
[i
] != plci
->ncci_ring_list
) && (a
->ncci_next
[i
] != ncci
))
978 if ((i
!= 0) && (a
->ncci_next
[i
] == ncci
))
981 plci
->ncci_ring_list
= 0;
982 else if (plci
->ncci_ring_list
== ncci
)
983 plci
->ncci_ring_list
= i
;
984 a
->ncci_next
[i
] = a
->ncci_next
[ncci
];
986 a
->ncci_next
[ncci
] = 0;
992 for (ncci
= 1; ncci
< MAX_NCCI
+1; ncci
++)
994 if (a
->ncci_plci
[ncci
] == plci
->Id
)
996 cleanup_ncci_data (plci
, ncci
);
997 dbug(1,dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
998 ncci_mapping_bug
, Id
, preserve_ncci
, a
->ncci_ch
[ncci
], ncci
));
999 a
->ch_ncci
[a
->ncci_ch
[ncci
]] = 0;
1002 a
->ncci_ch
[ncci
] = 0;
1003 a
->ncci_plci
[ncci
] = 0;
1004 a
->ncci_state
[ncci
] = IDLE
;
1005 a
->ncci_next
[ncci
] = 0;
1010 plci
->ncci_ring_list
= 0;
1015 /*------------------------------------------------------------------*/
1016 /* PLCI remove function */
1017 /*------------------------------------------------------------------*/
1019 static void plci_free_msg_in_queue (PLCI
*plci
)
1025 i
= plci
->msg_in_read_pos
;
1026 while (i
!= plci
->msg_in_write_pos
)
1028 if (i
== plci
->msg_in_wrap_pos
)
1030 if (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[i
]))->header
.command
== _DATA_B3_R
)
1033 TransmitBufferFree (plci
->appl
,
1034 (byte
*)(long)(((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[i
]))->info
.data_b3_req
.Data
));
1038 i
+= (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[i
]))->header
.length
+
1039 MSG_IN_OVERHEAD
+ 3) & 0xfffc;
1043 plci
->msg_in_write_pos
= MSG_IN_QUEUE_SIZE
;
1044 plci
->msg_in_read_pos
= MSG_IN_QUEUE_SIZE
;
1045 plci
->msg_in_wrap_pos
= MSG_IN_QUEUE_SIZE
;
1049 static void plci_remove(PLCI
* plci
)
1053 dbug(1,dprintf("plci_remove(no plci)"));
1056 init_internal_command_queue (plci
);
1057 dbug(1,dprintf("plci_remove(%x,tel=%x)",plci
->Id
,plci
->tel
));
1058 if(plci_remove_check(plci
))
1062 if (plci
->Sig
.Id
== 0xff)
1064 dbug(1,dprintf("D-channel X.25 plci->NL.Id:%0x", plci
->NL
.Id
));
1065 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
1067 nl_req_ncci(plci
,REMOVE
,0);
1073 if (!plci
->sig_remove_id
1075 || (plci
->req_in
!=plci
->req_out
)
1076 || (plci
->nl_req
|| plci
->sig_req
)))
1078 sig_req(plci
,HANGUP
,0);
1082 ncci_remove (plci
, 0, false);
1083 plci_free_msg_in_queue (plci
);
1087 if ((plci
->State
== INC_CON_PENDING
) || (plci
->State
== INC_CON_ALERT
))
1088 plci
->State
= OUTG_DIS_PENDING
;
1091 /*------------------------------------------------------------------*/
1092 /* Application Group function helpers */
1093 /*------------------------------------------------------------------*/
1095 static void set_group_ind_mask (PLCI
*plci
)
1099 for (i
= 0; i
< C_IND_MASK_DWORDS
; i
++)
1100 plci
->group_optimization_mask_table
[i
] = 0xffffffffL
;
1103 static void clear_group_ind_mask_bit (PLCI
*plci
, word b
)
1105 plci
->group_optimization_mask_table
[b
>> 5] &= ~(1L << (b
& 0x1f));
1108 static byte
test_group_ind_mask_bit (PLCI
*plci
, word b
)
1110 return ((plci
->group_optimization_mask_table
[b
>> 5] & (1L << (b
& 0x1f))) != 0);
1113 /*------------------------------------------------------------------*/
1114 /* c_ind_mask operations for arbitrary MAX_APPL */
1115 /*------------------------------------------------------------------*/
1117 static void clear_c_ind_mask (PLCI
*plci
)
1121 for (i
= 0; i
< C_IND_MASK_DWORDS
; i
++)
1122 plci
->c_ind_mask_table
[i
] = 0;
1125 static byte
c_ind_mask_empty (PLCI
*plci
)
1130 while ((i
< C_IND_MASK_DWORDS
) && (plci
->c_ind_mask_table
[i
] == 0))
1132 return (i
== C_IND_MASK_DWORDS
);
1135 static void set_c_ind_mask_bit (PLCI
*plci
, word b
)
1137 plci
->c_ind_mask_table
[b
>> 5] |= (1L << (b
& 0x1f));
1140 static void clear_c_ind_mask_bit (PLCI
*plci
, word b
)
1142 plci
->c_ind_mask_table
[b
>> 5] &= ~(1L << (b
& 0x1f));
1145 static byte
test_c_ind_mask_bit (PLCI
*plci
, word b
)
1147 return ((plci
->c_ind_mask_table
[b
>> 5] & (1L << (b
& 0x1f))) != 0);
1150 static void dump_c_ind_mask (PLCI
*plci
)
1152 static char hex_digit_table
[0x10] =
1153 {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
1159 for (i
= 0; i
< C_IND_MASK_DWORDS
; i
+= 4)
1163 for (j
= 0; j
< 4; j
++)
1165 if (i
+j
< C_IND_MASK_DWORDS
)
1167 d
= plci
->c_ind_mask_table
[i
+j
];
1168 for (k
= 0; k
< 8; k
++)
1170 *(--p
) = hex_digit_table
[d
& 0xf];
1176 for (k
= 0; k
< 8; k
++)
1181 dbug(1,dprintf ("c_ind_mask =%s", (char *) p
));
1189 #define dump_plcis(a)
1193 /*------------------------------------------------------------------*/
1194 /* translation function for each message */
1195 /*------------------------------------------------------------------*/
1197 byte
connect_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
1206 API_PARSE ai_parms
[5];
1210 static byte esc_chi
[35] = {0x02,0x18,0x01};
1211 static byte lli
[2] = {0x01,0x00};
1216 for(i
=0;i
<5;i
++) ai_parms
[i
].length
= 0;
1218 dbug(1,dprintf("connect_req(%d)",parms
->length
));
1219 Info
= _WRONG_IDENTIFIER
;
1222 if(a
->adapter_disabled
)
1224 dbug(1,dprintf("adapter disabled"));
1225 Id
= ((word
)1<<8)|a
->Id
;
1226 sendf(appl
,_CONNECT_R
|CONFIRM
,Id
,Number
,"w",0);
1227 sendf(appl
, _DISCONNECT_I
, Id
, 0, "w", _L1_ERROR
);
1230 Info
= _OUT_OF_PLCI
;
1234 plci
= &a
->plci
[i
-1];
1236 plci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
1237 /* check 'external controller' bit for codec support */
1238 if(Id
& EXT_CONTROLLER
)
1240 if(AdvCodecSupport(a
, plci
, appl
, 0) )
1243 sendf(appl
, _CONNECT_R
|CONFIRM
, Id
, Number
, "w", _WRONG_IDENTIFIER
);
1250 if(bp
->length
)LinkLayer
= bp
->info
[3];
1255 if(!api_parse(&ai
->info
[1],(word
)ai
->length
,"ssss",ai_parms
))
1258 if(ai_parms
[0].length
)
1260 ch
= GET_WORD(ai_parms
[0].info
+1);
1261 if(ch
>4) ch
=0; /* safety -> ignore ChannelID */
1262 if(ch
==4) /* explizit CHI in message */
1264 /* check length of B-CH struct */
1265 if((ai_parms
[0].info
)[3]>=1)
1267 if((ai_parms
[0].info
)[4]==CHI
)
1269 p_chi
= &((ai_parms
[0].info
)[5]);
1273 p_chi
= &((ai_parms
[0].info
)[3]);
1275 if(p_chi
[0]>35) /* check length of channel ID */
1277 Info
= _WRONG_MESSAGE_FORMAT
;
1280 else Info
= _WRONG_MESSAGE_FORMAT
;
1283 if(ch
==3 && ai_parms
[0].length
>=7 && ai_parms
[0].length
<=36)
1285 dir
= GET_WORD(ai_parms
[0].info
+3);
1288 for(i
=0; i
+5<=ai_parms
[0].length
; i
++)
1290 if(ai_parms
[0].info
[i
+5]!=0)
1292 if((ai_parms
[0].info
[i
+5] | m
) != 0xff)
1293 Info
= _WRONG_MESSAGE_FORMAT
;
1304 Info
= _WRONG_MESSAGE_FORMAT
;
1307 if ((ai_parms
[0].length
== 36) || (ch_mask
!= ((dword
)(1L << channel
))))
1309 esc_chi
[0] = (byte
)(ai_parms
[0].length
- 2);
1310 for(i
=0; i
+5<=ai_parms
[0].length
; i
++)
1311 esc_chi
[i
+3] = ai_parms
[0].info
[i
+5];
1315 esc_chi
[2] = (byte
)channel
;
1316 plci
->b_channel
= (byte
)channel
; /* not correct for ETSI ch 17..31 */
1317 add_p(plci
,LLI
,lli
);
1318 add_p(plci
,ESC
,esc_chi
);
1319 plci
->State
= LOCAL_CONNECT
;
1320 if(!dir
) plci
->call_dir
|= CALL_DIR_FORCE_OUTG_NL
; /* dir 0=DTE, 1=DCE */
1325 else Info
= _WRONG_MESSAGE_FORMAT
;
1328 dbug(1,dprintf("ch=%x,dir=%x,p_ch=%d",ch
,dir
,channel
));
1329 plci
->command
= _CONNECT_R
;
1330 plci
->number
= Number
;
1331 /* x.31 or D-ch free SAPI in LinkLayer? */
1332 if(ch
==1 && LinkLayer
!=3 && LinkLayer
!=12) noCh
= true;
1333 if((ch
==0 || ch
==2 || noCh
|| ch
==3 || ch
==4) && !Info
)
1335 /* B-channel used for B3 connections (ch==0), or no B channel */
1336 /* is used (ch==2) or perm. connection (3) is used do a CALL */
1337 if(noCh
) Info
= add_b1(plci
,&parms
[5],2,0); /* no resource */
1338 else Info
= add_b1(plci
,&parms
[5],ch
,0);
1339 add_s(plci
,OAD
,&parms
[2]);
1340 add_s(plci
,OSA
,&parms
[4]);
1341 add_s(plci
,BC
,&parms
[6]);
1342 add_s(plci
,LLC
,&parms
[7]);
1343 add_s(plci
,HLC
,&parms
[8]);
1344 CIP
= GET_WORD(parms
[0].info
);
1345 if (a
->Info_Mask
[appl
->Id
-1] & 0x200)
1347 /* early B3 connect (CIP mask bit 9) no release after a disc */
1348 add_p(plci
,LLI
,"\x01\x01");
1350 if(GET_WORD(parms
[0].info
)<29) {
1351 add_p(plci
,BC
,cip_bc
[GET_WORD(parms
[0].info
)][a
->u_law
]);
1352 add_p(plci
,HLC
,cip_hlc
[GET_WORD(parms
[0].info
)]);
1354 add_p(plci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
1355 sig_req(plci
,ASSIGN
,DSIG_ID
);
1359 /* D-Channel used for B3 connections */
1360 plci
->Sig
.Id
= 0xff;
1364 if(!Info
&& ch
!=2 && !noCh
) {
1365 Info
= add_b23(plci
,&parms
[5]);
1367 if(!(plci
->tel
&& !plci
->adv_nl
))nl_req_ncci(plci
,ASSIGN
,0);
1373 if(ch
==0 || ch
==2 || ch
==3 || noCh
|| ch
==4)
1375 if(plci
->spoofed_msg
==SPOOFING_REQUIRED
)
1377 api_save_msg(parms
, "wsssssssss", &plci
->saved_msg
);
1378 plci
->spoofed_msg
= CALL_REQ
;
1379 plci
->internal_command
= BLOCK_PLCI
;
1381 dbug(1,dprintf("Spoof"));
1385 if(ch
==4)add_p(plci
,CHI
,p_chi
);
1386 add_s(plci
,CPN
,&parms
[1]);
1387 add_s(plci
,DSA
,&parms
[3]);
1388 if(noCh
) add_p(plci
,ESC
,"\x02\x18\xfd"); /* D-channel, no B-L3 */
1389 add_ai(plci
,&parms
[9]);
1390 if(!dir
)sig_req(plci
,CALL_REQ
,0);
1393 plci
->command
= PERM_LIST_REQ
;
1395 sig_req(plci
,LISTEN_REQ
,0);
1414 byte
connect_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
1418 static byte cau_t
[] = {0,0,0x90,0x91,0xac,0x9d,0x86,0xd8,0x9b};
1419 static byte esc_t
[] = {0x03,0x08,0x00,0x00};
1421 API_PARSE ai_parms
[5];
1425 dbug(1,dprintf("connect_res(no plci)"));
1426 return 0; /* no plci, no send */
1429 dbug(1,dprintf("connect_res(State=0x%x)",plci
->State
));
1430 for(i
=0;i
<5;i
++) ai_parms
[i
].length
= 0;
1432 dbug(1,dprintf("ai->length=%d",ai
->length
));
1436 if(!api_parse(&ai
->info
[1],(word
)ai
->length
,"ssss",ai_parms
))
1438 dbug(1,dprintf("ai_parms[0].length=%d/0x%x",ai_parms
[0].length
,GET_WORD(ai_parms
[0].info
+1)));
1440 if(ai_parms
[0].length
)
1442 ch
= GET_WORD(ai_parms
[0].info
+1);
1443 dbug(1,dprintf("BCH-I=0x%x",ch
));
1448 if(plci
->State
==INC_CON_CONNECTED_ALERT
)
1450 dbug(1,dprintf("Connected Alert Call_Res"));
1451 if (a
->Info_Mask
[appl
->Id
-1] & 0x200)
1453 /* early B3 connect (CIP mask bit 9) no release after a disc */
1454 add_p(plci
,LLI
,"\x01\x01");
1456 add_s(plci
, CONN_NR
, &parms
[2]);
1457 add_s(plci
, LLC
, &parms
[4]);
1458 add_ai(plci
, &parms
[5]);
1459 plci
->State
= INC_CON_ACCEPT
;
1460 sig_req(plci
, CALL_RES
,0);
1463 else if(plci
->State
==INC_CON_PENDING
|| plci
->State
==INC_CON_ALERT
) {
1464 clear_c_ind_mask_bit (plci
, (word
)(appl
->Id
-1));
1465 dump_c_ind_mask (plci
);
1466 Reject
= GET_WORD(parms
[0].info
);
1467 dbug(1,dprintf("Reject=0x%x",Reject
));
1470 if(c_ind_mask_empty (plci
))
1472 if((Reject
&0xff00)==0x3400)
1474 esc_t
[2] = ((byte
)(Reject
&0x00ff)) | 0x80;
1475 add_p(plci
,ESC
,esc_t
);
1476 add_ai(plci
, &parms
[5]);
1477 sig_req(plci
,REJECT
,0);
1479 else if(Reject
==1 || Reject
>9)
1481 add_ai(plci
, &parms
[5]);
1482 sig_req(plci
,HANGUP
,0);
1486 esc_t
[2] = cau_t
[(Reject
&0x000f)];
1487 add_p(plci
,ESC
,esc_t
);
1488 add_ai(plci
, &parms
[5]);
1489 sig_req(plci
,REJECT
,0);
1495 sendf(appl
, _DISCONNECT_I
, Id
, 0, "w", _OTHER_APPL_CONNECTED
);
1500 if(Id
& EXT_CONTROLLER
){
1501 if(AdvCodecSupport(a
, plci
, appl
, 0)){
1502 dbug(1,dprintf("connect_res(error from AdvCodecSupport)"));
1503 sig_req(plci
,HANGUP
,0);
1506 if(plci
->tel
== ADV_VOICE
&& a
->AdvCodecPLCI
)
1508 Info
= add_b23(plci
, &parms
[1]);
1511 dbug(1,dprintf("connect_res(error from add_b23)"));
1512 sig_req(plci
,HANGUP
,0);
1517 nl_req_ncci(plci
, ASSIGN
, 0);
1526 Info
= add_b23(plci
, &parms
[1]);
1529 dbug(1,dprintf("connect_res(error from add_b23 2)"));
1530 sig_req(plci
,HANGUP
,0);
1534 nl_req_ncci(plci
, ASSIGN
, 0);
1537 if(plci
->spoofed_msg
==SPOOFING_REQUIRED
)
1539 api_save_msg(parms
, "wsssss", &plci
->saved_msg
);
1540 plci
->spoofed_msg
= CALL_RES
;
1541 plci
->internal_command
= BLOCK_PLCI
;
1543 dbug(1,dprintf("Spoof"));
1547 add_b1 (plci
, &parms
[1], ch
, plci
->B1_facilities
);
1548 if (a
->Info_Mask
[appl
->Id
-1] & 0x200)
1550 /* early B3 connect (CIP mask bit 9) no release after a disc */
1551 add_p(plci
,LLI
,"\x01\x01");
1553 add_s(plci
, CONN_NR
, &parms
[2]);
1554 add_s(plci
, LLC
, &parms
[4]);
1555 add_ai(plci
, &parms
[5]);
1556 plci
->State
= INC_CON_ACCEPT
;
1557 sig_req(plci
, CALL_RES
,0);
1560 for(i
=0; i
<max_appl
; i
++) {
1561 if(test_c_ind_mask_bit (plci
, i
)) {
1562 sendf(&application
[i
], _DISCONNECT_I
, Id
, 0, "w", _OTHER_APPL_CONNECTED
);
1570 byte
connect_a_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
1572 dbug(1,dprintf("connect_a_res"));
1576 byte
disconnect_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
1581 dbug(1,dprintf("disconnect_req"));
1583 Info
= _WRONG_IDENTIFIER
;
1587 if(plci
->State
==INC_CON_PENDING
|| plci
->State
==INC_CON_ALERT
)
1589 clear_c_ind_mask_bit (plci
, (word
)(appl
->Id
-1));
1591 for(i
=0; i
<max_appl
; i
++)
1593 if(test_c_ind_mask_bit (plci
, i
))
1594 sendf(&application
[i
], _DISCONNECT_I
, Id
, 0, "w", 0);
1596 plci
->State
= OUTG_DIS_PENDING
;
1598 if(plci
->Sig
.Id
&& plci
->appl
)
1601 if(plci
->Sig
.Id
!=0xff)
1603 if(plci
->State
!=INC_DIS_PENDING
)
1605 add_ai(plci
, &msg
[0]);
1606 sig_req(plci
,HANGUP
,0);
1607 plci
->State
= OUTG_DIS_PENDING
;
1613 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
1615 mixer_remove (plci
);
1616 nl_req_ncci(plci
,REMOVE
,0);
1617 sendf(appl
,_DISCONNECT_R
|CONFIRM
,Id
,Number
,"w",0);
1618 sendf(appl
, _DISCONNECT_I
, Id
, 0, "w", 0);
1619 plci
->State
= INC_DIS_PENDING
;
1626 if(!appl
) return false;
1627 sendf(appl
, _DISCONNECT_R
|CONFIRM
, Id
, Number
, "w",Info
);
1631 byte
disconnect_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
1633 dbug(1,dprintf("disconnect_res"));
1636 /* clear ind mask bit, just in case of collsion of */
1637 /* DISCONNECT_IND and CONNECT_RES */
1638 clear_c_ind_mask_bit (plci
, (word
)(appl
->Id
-1));
1639 ncci_free_receive_buffers (plci
, 0);
1640 if(plci_remove_check(plci
))
1644 if(plci
->State
==INC_DIS_PENDING
1645 || plci
->State
==SUSPENDING
) {
1646 if(c_ind_mask_empty (plci
)) {
1647 if(plci
->State
!=SUSPENDING
)plci
->State
= IDLE
;
1648 dbug(1,dprintf("chs=%d",plci
->channels
));
1649 if(!plci
->channels
) {
1658 byte
listen_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
1663 dbug(1,dprintf("listen_req(Appl=0x%x)",appl
->Id
));
1665 Info
= _WRONG_IDENTIFIER
;
1668 a
->Info_Mask
[appl
->Id
-1] = GET_DWORD(parms
[0].info
);
1669 a
->CIP_Mask
[appl
->Id
-1] = GET_DWORD(parms
[1].info
);
1670 dbug(1,dprintf("CIP_MASK=0x%lx",GET_DWORD(parms
[1].info
)));
1671 if (a
->Info_Mask
[appl
->Id
-1] & 0x200){ /* early B3 connect provides */
1672 a
->Info_Mask
[appl
->Id
-1] |= 0x10; /* call progression infos */
1675 /* check if external controller listen and switch listen on or off*/
1676 if(Id
&EXT_CONTROLLER
&& GET_DWORD(parms
[1].info
)){
1677 if(a
->profile
.Global_Options
& ON_BOARD_CODEC
) {
1678 dummy_plci
.State
= IDLE
;
1679 a
->codec_listen
[appl
->Id
-1] = &dummy_plci
;
1680 a
->TelOAD
[0] = (byte
)(parms
[3].length
);
1681 for(i
=1;parms
[3].length
>=i
&& i
<22;i
++) {
1682 a
->TelOAD
[i
] = parms
[3].info
[i
];
1685 a
->TelOSA
[0] = (byte
)(parms
[4].length
);
1686 for(i
=1;parms
[4].length
>=i
&& i
<22;i
++) {
1687 a
->TelOSA
[i
] = parms
[4].info
[i
];
1691 else Info
= 0x2002; /* wrong controller, codec not supported */
1693 else{ /* clear listen */
1694 a
->codec_listen
[appl
->Id
-1] = (PLCI
*)0;
1703 if (a
) listen_check(a
);
1707 byte
info_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
1711 PLCI
* rc_plci
= NULL
;
1712 API_PARSE ai_parms
[5];
1715 dbug(1,dprintf("info_req"));
1716 for(i
=0;i
<5;i
++) ai_parms
[i
].length
= 0;
1722 if(api_parse(&ai
->info
[1],(word
)ai
->length
,"ssss",ai_parms
))
1724 dbug(1,dprintf("AddInfo wrong"));
1725 Info
= _WRONG_MESSAGE_FORMAT
;
1728 if(!a
) Info
= _WRONG_STATE
;
1731 { /* no fac, with CPN, or KEY */
1733 if(!ai_parms
[3].length
&& plci
->State
&& (msg
[0].length
|| ai_parms
[1].length
) )
1735 /* overlap sending option */
1736 dbug(1,dprintf("OvlSnd"));
1737 add_s(plci
,CPN
,&msg
[0]);
1738 add_s(plci
,KEY
,&ai_parms
[1]);
1739 sig_req(plci
,INFO_REQ
,0);
1744 if(plci
->State
&& ai_parms
[2].length
)
1746 /* User_Info option */
1747 dbug(1,dprintf("UUI"));
1748 add_s(plci
,UUI
,&ai_parms
[2]);
1749 sig_req(plci
,USER_DATA
,0);
1751 else if(plci
->State
&& ai_parms
[3].length
)
1753 /* Facility option */
1754 dbug(1,dprintf("FAC"));
1755 add_s(plci
,CPN
,&msg
[0]);
1756 add_ai(plci
, &msg
[1]);
1757 sig_req(plci
,FACILITY_REQ
,0);
1761 Info
= _WRONG_STATE
;
1764 else if((ai_parms
[1].length
|| ai_parms
[2].length
|| ai_parms
[3].length
) && !Info
)
1766 /* NCR_Facility option -> send UUI and Keypad too */
1767 dbug(1,dprintf("NCR_FAC"));
1770 rc_plci
= &a
->plci
[i
-1];
1771 appl
->NullCREnable
= true;
1772 rc_plci
->internal_command
= C_NCR_FAC_REQ
;
1773 rc_plci
->appl
= appl
;
1774 add_p(rc_plci
,CAI
,"\x01\x80");
1775 add_p(rc_plci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
1776 sig_req(rc_plci
,ASSIGN
,DSIG_ID
);
1781 Info
= _OUT_OF_PLCI
;
1786 add_s(rc_plci
,CPN
,&msg
[0]);
1787 add_ai(rc_plci
, &msg
[1]);
1788 sig_req(rc_plci
,NCR_FACILITY
,0);
1791 /* for application controlled supplementary services */
1797 Info
= _WRONG_MESSAGE_FORMAT
;
1805 { /* appl is not assigned to a PLCI or error condition */
1806 dbug(1,dprintf("localInfoCon"));
1816 byte
info_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
1818 dbug(1,dprintf("info_res"));
1822 byte
alert_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
1827 dbug(1,dprintf("alert_req"));
1829 Info
= _WRONG_IDENTIFIER
;
1832 Info
= _ALERT_IGNORED
;
1833 if(plci
->State
!=INC_CON_ALERT
) {
1834 Info
= _WRONG_STATE
;
1835 if(plci
->State
==INC_CON_PENDING
) {
1837 plci
->State
=INC_CON_ALERT
;
1838 add_ai(plci
, &msg
[0]);
1839 sig_req(plci
,CALL_ALERT
,0);
1852 byte
facility_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
1859 long relatedPLCIvalue
;
1860 DIVA_CAPI_ADAPTER
* relatedadapter
;
1861 byte
* SSparms
= "";
1862 byte RCparms
[] = "\x05\x00\x00\x02\x00\x00";
1863 byte SSstruct
[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
1865 API_PARSE ss_parms
[11];
1871 dbug(1,dprintf("facility_req"));
1872 for(i
=0;i
<9;i
++) ss_parms
[i
].length
= 0;
1878 dbug(1,dprintf("wrong Ctrl"));
1879 Info
= _WRONG_IDENTIFIER
;
1882 selector
= GET_WORD(msg
[0].info
);
1888 case SELECTOR_HANDSET
:
1889 Info
= AdvCodecSupport(a
, plci
, appl
, HOOK_SUPPORT
);
1892 case SELECTOR_SU_SERV
:
1895 Info
= _WRONG_MESSAGE_FORMAT
;
1898 SSreq
= GET_WORD(&(msg
[1].info
[1]));
1899 PUT_WORD(&RCparms
[1],SSreq
);
1903 case S_GET_SUPPORTED_SERVICES
:
1906 rplci
= &a
->plci
[i
-1];
1908 add_p(rplci
,CAI
,"\x01\x80");
1909 add_p(rplci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
1910 sig_req(rplci
,ASSIGN
,DSIG_ID
);
1915 PUT_DWORD(&SSstruct
[6], MASK_TERMINAL_PORTABILITY
);
1916 SSparms
= (byte
*)SSstruct
;
1919 rplci
->internal_command
= GETSERV_REQ_PEND
;
1920 rplci
->number
= Number
;
1922 sig_req(rplci
,S_SUPPORTED
,0);
1928 if(parms
->length
==7)
1930 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbd",ss_parms
))
1932 dbug(1,dprintf("format wrong"));
1933 Info
= _WRONG_MESSAGE_FORMAT
;
1939 Info
= _WRONG_MESSAGE_FORMAT
;
1942 a
->Notification_Mask
[appl
->Id
-1] = GET_DWORD(ss_parms
[2].info
);
1943 if(a
->Notification_Mask
[appl
->Id
-1] & SMASK_MWI
) /* MWI active? */
1947 rplci
= &a
->plci
[i
-1];
1949 add_p(rplci
,CAI
,"\x01\x80");
1950 add_p(rplci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
1951 sig_req(rplci
,ASSIGN
,DSIG_ID
);
1958 rplci
->internal_command
= GET_MWI_STATE
;
1959 rplci
->number
= Number
;
1960 sig_req(rplci
,MWI_POLL
,0);
1966 api_parse(&parms
->info
[1],(word
)parms
->length
,"ws",ss_parms
);
1967 if(plci
&& plci
->State
&& plci
->SuppState
==IDLE
)
1969 plci
->SuppState
= HOLD_REQUEST
;
1970 plci
->command
= C_HOLD_REQ
;
1971 add_s(plci
,CAI
,&ss_parms
[1]);
1972 sig_req(plci
,CALL_HOLD
,0);
1976 else Info
= 0x3010; /* wrong state */
1979 if(plci
&& plci
->State
&& plci
->SuppState
==CALL_HELD
)
1981 if(Id
& EXT_CONTROLLER
)
1983 if(AdvCodecSupport(a
, plci
, appl
, 0))
1985 Info
= 0x3010; /* wrong state */
1991 plci
->SuppState
= RETRIEVE_REQUEST
;
1992 plci
->command
= C_RETRIEVE_REQ
;
1993 if(plci
->spoofed_msg
==SPOOFING_REQUIRED
)
1995 plci
->spoofed_msg
= CALL_RETRIEVE
;
1996 plci
->internal_command
= BLOCK_PLCI
;
1998 dbug(1,dprintf("Spoof"));
2003 sig_req(plci
,CALL_RETRIEVE
,0);
2008 else Info
= 0x3010; /* wrong state */
2013 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbs",ss_parms
))
2015 dbug(1,dprintf("format wrong"));
2016 Info
= _WRONG_MESSAGE_FORMAT
;
2020 if(plci
&& plci
->State
)
2022 add_s(plci
,CAI
,&ss_parms
[2]);
2023 plci
->command
= SUSPEND_REQ
;
2024 sig_req(plci
,SUSPEND
,0);
2025 plci
->State
= SUSPENDING
;
2028 else Info
= 0x3010; /* wrong state */
2032 if(!(i
=get_plci(a
)) )
2034 Info
= _OUT_OF_PLCI
;
2037 rplci
= &a
->plci
[i
-1];
2039 rplci
->number
= Number
;
2041 rplci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
2042 /* check 'external controller' bit for codec support */
2043 if(Id
& EXT_CONTROLLER
)
2045 if(AdvCodecSupport(a
, rplci
, appl
, 0) )
2054 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbs",ss_parms
))
2056 dbug(1,dprintf("format wrong"));
2058 Info
= _WRONG_MESSAGE_FORMAT
;
2063 dummy
.info
= "\x00";
2064 add_b1(rplci
, &dummy
, 0, 0);
2065 if (a
->Info_Mask
[appl
->Id
-1] & 0x200)
2067 /* early B3 connect (CIP mask bit 9) no release after a disc */
2068 add_p(rplci
,LLI
,"\x01\x01");
2070 add_p(rplci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
2071 sig_req(rplci
,ASSIGN
,DSIG_ID
);
2073 add_s(rplci
,CAI
,&ss_parms
[2]);
2074 rplci
->command
= RESUME_REQ
;
2075 sig_req(rplci
,RESUME
,0);
2076 rplci
->State
= RESUMING
;
2080 case S_CONF_BEGIN
: /* Request */
2082 case S_CONF_ISOLATE
:
2083 case S_CONF_REATTACH
:
2084 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbd",ss_parms
))
2086 dbug(1,dprintf("format wrong"));
2087 Info
= _WRONG_MESSAGE_FORMAT
;
2090 if(plci
&& plci
->State
&& ((plci
->SuppState
==IDLE
)||(plci
->SuppState
==CALL_HELD
)))
2092 d
= GET_DWORD(ss_parms
[2].info
);
2095 dbug(1,dprintf("format wrong"));
2096 Info
= _WRONG_MESSAGE_FORMAT
;
2099 plci
->ptyState
= (byte
)SSreq
;
2105 cai
[1] = CONF_BEGIN
;
2106 plci
->internal_command
= CONF_BEGIN_REQ_PEND
;
2110 plci
->internal_command
= CONF_DROP_REQ_PEND
;
2112 case S_CONF_ISOLATE
:
2113 cai
[1] = CONF_ISOLATE
;
2114 plci
->internal_command
= CONF_ISOLATE_REQ_PEND
;
2116 case S_CONF_REATTACH
:
2117 cai
[1] = CONF_REATTACH
;
2118 plci
->internal_command
= CONF_REATTACH_REQ_PEND
;
2121 cai
[2] = (byte
)d
; /* Conference Size resp. PartyId */
2122 add_p(plci
,CAI
,cai
);
2123 sig_req(plci
,S_SERVICE
,0);
2127 else Info
= 0x3010; /* wrong state */
2134 if(parms
->length
==7)
2136 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbd",ss_parms
))
2138 dbug(1,dprintf("format wrong"));
2139 Info
= _WRONG_MESSAGE_FORMAT
;
2143 else if(parms
->length
==8) /* workaround for the T-View-S */
2145 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbdb",ss_parms
))
2147 dbug(1,dprintf("format wrong"));
2148 Info
= _WRONG_MESSAGE_FORMAT
;
2154 Info
= _WRONG_MESSAGE_FORMAT
;
2159 Info
= _WRONG_MESSAGE_FORMAT
;
2164 Info
= _WRONG_IDENTIFIER
;
2167 relatedPLCIvalue
= GET_DWORD(ss_parms
[2].info
);
2168 relatedPLCIvalue
&= 0x0000FFFF;
2169 dbug(1,dprintf("PTY/ECT/addCONF,relPLCI=%lx",relatedPLCIvalue
));
2170 /* controller starts with 0 up to (max_adapter - 1) */
2171 if (((relatedPLCIvalue
& 0x7f) == 0)
2172 || (MapController ((byte
)(relatedPLCIvalue
& 0x7f)) == 0)
2173 || (MapController ((byte
)(relatedPLCIvalue
& 0x7f)) > max_adapter
))
2175 if(SSreq
==S_3PTY_END
)
2177 dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI"));
2182 Info
= 0x3010; /* wrong state */
2188 relatedadapter
= &adapter
[MapController ((byte
)(relatedPLCIvalue
& 0x7f))-1];
2189 relatedPLCIvalue
>>=8;
2191 for(i
=0,rplci
=NULL
;i
<relatedadapter
->max_plci
;i
++)
2193 if(relatedadapter
->plci
[i
].Id
== (byte
)relatedPLCIvalue
)
2195 rplci
= &relatedadapter
->plci
[i
];
2198 if(!rplci
|| !relatedPLCIvalue
)
2200 if(SSreq
==S_3PTY_END
)
2202 dbug(1, dprintf("use 2nd PLCI=PLCI"));
2207 Info
= 0x3010; /* wrong state */
2213 dbug(1,dprintf("rplci:%x",rplci));
2214 dbug(1,dprintf("plci:%x",plci));
2215 dbug(1,dprintf("rplci->ptyState:%x",rplci->ptyState));
2216 dbug(1,dprintf("plci->ptyState:%x",plci->ptyState));
2217 dbug(1,dprintf("SSreq:%x",SSreq));
2218 dbug(1,dprintf("rplci->internal_command:%x",rplci->internal_command));
2219 dbug(1,dprintf("rplci->appl:%x",rplci->appl));
2220 dbug(1,dprintf("rplci->Id:%x",rplci->Id));
2222 /* send PTY/ECT req, cannot check all states because of US stuff */
2223 if( !rplci
->internal_command
&& rplci
->appl
)
2226 rplci
->relatedPTYPLCI
= plci
;
2227 plci
->relatedPTYPLCI
= rplci
;
2228 rplci
->ptyState
= (byte
)SSreq
;
2231 rplci
->internal_command
= ECT_REQ_PEND
;
2232 cai
[1] = ECT_EXECUTE
;
2234 rplci
->vswitchstate
=0;
2236 rplci
->vsprotdialect
=0;
2237 plci
->vswitchstate
=0;
2239 plci
->vsprotdialect
=0;
2242 else if(SSreq
==S_CONF_ADD
)
2244 rplci
->internal_command
= CONF_ADD_REQ_PEND
;
2249 rplci
->internal_command
= PTY_REQ_PEND
;
2250 cai
[1] = (byte
)(SSreq
-3);
2252 rplci
->number
= Number
;
2253 if(plci
!=rplci
) /* explicit invocation */
2256 cai
[2] = plci
->Sig
.Id
;
2257 dbug(1,dprintf("explicit invocation"));
2261 dbug(1,dprintf("implicit invocation"));
2264 add_p(rplci
,CAI
,cai
);
2265 sig_req(rplci
,S_SERVICE
,0);
2271 dbug(0,dprintf("Wrong line"));
2272 Info
= 0x3010; /* wrong state */
2277 case S_CALL_DEFLECTION
:
2278 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbwss",ss_parms
))
2280 dbug(1,dprintf("format wrong"));
2281 Info
= _WRONG_MESSAGE_FORMAT
;
2286 Info
= _WRONG_IDENTIFIER
;
2289 /* reuse unused screening indicator */
2290 ss_parms
[3].info
[3] = (byte
)GET_WORD(&(ss_parms
[2].info
[0]));
2292 plci
->internal_command
= CD_REQ_PEND
;
2293 appl
->CDEnable
= true;
2295 cai
[1] = CALL_DEFLECTION
;
2296 add_p(plci
,CAI
,cai
);
2297 add_p(plci
,CPN
,ss_parms
[3].info
);
2298 sig_req(plci
,S_SERVICE
,0);
2303 case S_CALL_FORWARDING_START
:
2304 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbdwwsss",ss_parms
))
2306 dbug(1,dprintf("format wrong"));
2307 Info
= _WRONG_MESSAGE_FORMAT
;
2313 rplci
= &a
->plci
[i
-1];
2315 add_p(rplci
,CAI
,"\x01\x80");
2316 add_p(rplci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
2317 sig_req(rplci
,ASSIGN
,DSIG_ID
);
2322 Info
= _OUT_OF_PLCI
;
2326 /* reuse unused screening indicator */
2327 rplci
->internal_command
= CF_START_PEND
;
2329 rplci
->number
= Number
;
2330 appl
->S_Handle
= GET_DWORD(&(ss_parms
[2].info
[0]));
2332 cai
[1] = 0x70|(byte
)GET_WORD(&(ss_parms
[3].info
[0])); /* Function */
2333 cai
[2] = (byte
)GET_WORD(&(ss_parms
[4].info
[0])); /* Basic Service */
2334 add_p(rplci
,CAI
,cai
);
2335 add_p(rplci
,OAD
,ss_parms
[5].info
);
2336 add_p(rplci
,CPN
,ss_parms
[6].info
);
2337 sig_req(rplci
,S_SERVICE
,0);
2342 case S_INTERROGATE_DIVERSION
:
2343 case S_INTERROGATE_NUMBERS
:
2344 case S_CALL_FORWARDING_STOP
:
2345 case S_CCBS_REQUEST
:
2346 case S_CCBS_DEACTIVATE
:
2347 case S_CCBS_INTERROGATE
:
2350 case S_INTERROGATE_NUMBERS
:
2351 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbd",ss_parms
))
2353 dbug(0,dprintf("format wrong"));
2354 Info
= _WRONG_MESSAGE_FORMAT
;
2357 case S_CCBS_REQUEST
:
2358 case S_CCBS_DEACTIVATE
:
2359 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbdw",ss_parms
))
2361 dbug(0,dprintf("format wrong"));
2362 Info
= _WRONG_MESSAGE_FORMAT
;
2365 case S_CCBS_INTERROGATE
:
2366 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbdws",ss_parms
))
2368 dbug(0,dprintf("format wrong"));
2369 Info
= _WRONG_MESSAGE_FORMAT
;
2373 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbdwws",ss_parms
))
2375 dbug(0,dprintf("format wrong"));
2376 Info
= _WRONG_MESSAGE_FORMAT
;
2385 rplci
= &a
->plci
[i
-1];
2388 case S_INTERROGATE_DIVERSION
: /* use cai with S_SERVICE below */
2389 cai
[1] = 0x60|(byte
)GET_WORD(&(ss_parms
[3].info
[0])); /* Function */
2390 rplci
->internal_command
= INTERR_DIVERSION_REQ_PEND
; /* move to rplci if assigned */
2392 case S_INTERROGATE_NUMBERS
: /* use cai with S_SERVICE below */
2393 cai
[1] = DIVERSION_INTERROGATE_NUM
; /* Function */
2394 rplci
->internal_command
= INTERR_NUMBERS_REQ_PEND
; /* move to rplci if assigned */
2396 case S_CALL_FORWARDING_STOP
:
2397 rplci
->internal_command
= CF_STOP_PEND
;
2398 cai
[1] = 0x80|(byte
)GET_WORD(&(ss_parms
[3].info
[0])); /* Function */
2400 case S_CCBS_REQUEST
:
2401 cai
[1] = CCBS_REQUEST
;
2402 rplci
->internal_command
= CCBS_REQUEST_REQ_PEND
;
2404 case S_CCBS_DEACTIVATE
:
2405 cai
[1] = CCBS_DEACTIVATE
;
2406 rplci
->internal_command
= CCBS_DEACTIVATE_REQ_PEND
;
2408 case S_CCBS_INTERROGATE
:
2409 cai
[1] = CCBS_INTERROGATE
;
2410 rplci
->internal_command
= CCBS_INTERROGATE_REQ_PEND
;
2417 rplci
->number
= Number
;
2418 add_p(rplci
,CAI
,"\x01\x80");
2419 add_p(rplci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
2420 sig_req(rplci
,ASSIGN
,DSIG_ID
);
2425 Info
= _OUT_OF_PLCI
;
2429 appl
->S_Handle
= GET_DWORD(&(ss_parms
[2].info
[0]));
2432 case S_INTERROGATE_NUMBERS
:
2434 add_p(rplci
,CAI
,cai
);
2436 case S_CCBS_REQUEST
:
2437 case S_CCBS_DEACTIVATE
:
2439 PUT_WORD(&cai
[2],GET_WORD(&(ss_parms
[3].info
[0])));
2440 add_p(rplci
,CAI
,cai
);
2442 case S_CCBS_INTERROGATE
:
2444 PUT_WORD(&cai
[2],GET_WORD(&(ss_parms
[3].info
[0])));
2445 add_p(rplci
,CAI
,cai
);
2446 add_p(rplci
,OAD
,ss_parms
[4].info
);
2450 cai
[2] = (byte
)GET_WORD(&(ss_parms
[4].info
[0])); /* Basic Service */
2451 add_p(rplci
,CAI
,cai
);
2452 add_p(rplci
,OAD
,ss_parms
[5].info
);
2456 sig_req(rplci
,S_SERVICE
,0);
2461 case S_MWI_ACTIVATE
:
2462 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbwdwwwssss",ss_parms
))
2464 dbug(1,dprintf("format wrong"));
2465 Info
= _WRONG_MESSAGE_FORMAT
;
2472 rplci
= &a
->plci
[i
-1];
2474 rplci
->cr_enquiry
=true;
2475 add_p(rplci
,CAI
,"\x01\x80");
2476 add_p(rplci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
2477 sig_req(rplci
,ASSIGN
,DSIG_ID
);
2482 Info
= _OUT_OF_PLCI
;
2489 rplci
->cr_enquiry
=false;
2493 rplci
->internal_command
= MWI_ACTIVATE_REQ_PEND
;
2495 rplci
->number
= Number
;
2498 cai
[1] = ACTIVATION_MWI
; /* Function */
2499 PUT_WORD(&cai
[2],GET_WORD(&(ss_parms
[2].info
[0]))); /* Basic Service */
2500 PUT_DWORD(&cai
[4],GET_DWORD(&(ss_parms
[3].info
[0]))); /* Number of Messages */
2501 PUT_WORD(&cai
[8],GET_WORD(&(ss_parms
[4].info
[0]))); /* Message Status */
2502 PUT_WORD(&cai
[10],GET_WORD(&(ss_parms
[5].info
[0]))); /* Message Reference */
2503 PUT_WORD(&cai
[12],GET_WORD(&(ss_parms
[6].info
[0]))); /* Invocation Mode */
2504 add_p(rplci
,CAI
,cai
);
2505 add_p(rplci
,CPN
,ss_parms
[7].info
); /* Receiving User Number */
2506 add_p(rplci
,OAD
,ss_parms
[8].info
); /* Controlling User Number */
2507 add_p(rplci
,OSA
,ss_parms
[9].info
); /* Controlling User Provided Number */
2508 add_p(rplci
,UID
,ss_parms
[10].info
); /* Time */
2509 sig_req(rplci
,S_SERVICE
,0);
2513 case S_MWI_DEACTIVATE
:
2514 if(api_parse(&parms
->info
[1],(word
)parms
->length
,"wbwwss",ss_parms
))
2516 dbug(1,dprintf("format wrong"));
2517 Info
= _WRONG_MESSAGE_FORMAT
;
2524 rplci
= &a
->plci
[i
-1];
2526 rplci
->cr_enquiry
=true;
2527 add_p(rplci
,CAI
,"\x01\x80");
2528 add_p(rplci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
2529 sig_req(rplci
,ASSIGN
,DSIG_ID
);
2534 Info
= _OUT_OF_PLCI
;
2541 rplci
->cr_enquiry
=false;
2545 rplci
->internal_command
= MWI_DEACTIVATE_REQ_PEND
;
2547 rplci
->number
= Number
;
2550 cai
[1] = DEACTIVATION_MWI
; /* Function */
2551 PUT_WORD(&cai
[2],GET_WORD(&(ss_parms
[2].info
[0]))); /* Basic Service */
2552 PUT_WORD(&cai
[4],GET_WORD(&(ss_parms
[3].info
[0]))); /* Invocation Mode */
2553 add_p(rplci
,CAI
,cai
);
2554 add_p(rplci
,CPN
,ss_parms
[4].info
); /* Receiving User Number */
2555 add_p(rplci
,OAD
,ss_parms
[5].info
); /* Controlling User Number */
2556 sig_req(rplci
,S_SERVICE
,0);
2561 Info
= 0x300E; /* not supported */
2564 break; /* case SELECTOR_SU_SERV: end */
2568 return (dtmf_request (Id
, Number
, a
, plci
, appl
, msg
));
2572 case SELECTOR_LINE_INTERCONNECT
:
2573 return (mixer_request (Id
, Number
, a
, plci
, appl
, msg
));
2577 case PRIV_SELECTOR_ECHO_CANCELLER
:
2578 appl
->appl_flags
|= APPL_FLAG_PRIV_EC_SPEC
;
2579 return (ec_request (Id
, Number
, a
, plci
, appl
, msg
));
2581 case SELECTOR_ECHO_CANCELLER
:
2582 appl
->appl_flags
&= ~APPL_FLAG_PRIV_EC_SPEC
;
2583 return (ec_request (Id
, Number
, a
, plci
, appl
, msg
));
2586 case SELECTOR_V42BIS
:
2588 Info
= _FACILITY_NOT_SUPPORTED
;
2590 } /* end of switch(selector) */
2593 dbug(1,dprintf("SendFacRc"));
2595 _FACILITY_R
|CONFIRM
,
2598 "wws",Info
,selector
,SSparms
);
2602 byte
facility_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
2604 dbug(1,dprintf("facility_res"));
2608 byte
connect_b3_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
2614 word fax_control_bits
, fax_feature_bits
, fax_info_change
;
2618 API_PARSE fax_parms
[9];
2622 dbug(1,dprintf("connect_b3_req"));
2625 if ((plci
->State
== IDLE
) || (plci
->State
== OUTG_DIS_PENDING
)
2626 || (plci
->State
== INC_DIS_PENDING
) || (plci
->SuppState
!= IDLE
))
2628 Info
= _WRONG_STATE
;
2632 /* local reply if assign unsuccessfull
2633 or B3 protocol allows only one layer 3 connection
2634 and already connected
2635 or B2 protocol not any LAPD
2636 and connect_b3_req contradicts originate/answer direction */
2638 || (((plci
->B3_prot
!= B3_T90NL
) && (plci
->B3_prot
!= B3_ISO8208
) && (plci
->B3_prot
!= B3_X25_DCE
))
2639 && ((plci
->channels
!= 0)
2640 || (((plci
->B2_prot
!= B2_SDLC
) && (plci
->B2_prot
!= B2_LAPD
) && (plci
->B2_prot
!= B2_LAPD_FREE_SAPI_SEL
))
2641 && ((plci
->call_dir
& CALL_DIR_ANSWER
) && !(plci
->call_dir
& CALL_DIR_FORCE_OUTG_NL
))))))
2643 dbug(1,dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x",
2644 plci
->channels
,plci
->NL
.Id
,plci
->call_dir
,plci
->SuppState
));
2645 Info
= _WRONG_STATE
;
2647 _CONNECT_B3_R
|CONFIRM
,
2653 plci
->requested_options_conn
= 0;
2657 if(plci
->B3_prot
==2 || plci
->B3_prot
==3)
2662 if(ncpi
->info
[2] || ncpi
->info
[3])
2664 pvc
[0] = ncpi
->info
[3];
2665 pvc
[1] = ncpi
->info
[2];
2671 if(ncpi
->info
[1] &1) req
= N_CONNECT
| N_D_BIT
;
2672 add_d(plci
,(word
)(ncpi
->length
-3),&ncpi
->info
[4]);
2676 else if(plci
->B3_prot
==5)
2678 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
2680 fax_control_bits
= GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
);
2681 fax_feature_bits
= GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->feature_bits_low
);
2682 if (!(fax_control_bits
& T30_CONTROL_BIT_MORE_DOCUMENTS
)
2683 || (fax_feature_bits
& T30_FEATURE_BIT_MORE_DOCUMENTS
))
2685 len
= (byte
)(offsetof(T30_INFO
, universal_6
));
2686 fax_info_change
= false;
2687 if (ncpi
->length
>= 4)
2689 w
= GET_WORD(&ncpi
->info
[3]);
2690 if ((w
& 0x0001) != ((word
)(((T30_INFO
*)(plci
->fax_connect_info_buffer
))->resolution
& 0x0001)))
2692 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->resolution
=
2693 (byte
)((((T30_INFO
*)(plci
->fax_connect_info_buffer
))->resolution
& ~T30_RESOLUTION_R8_0770_OR_200
) |
2694 ((w
& 0x0001) ? T30_RESOLUTION_R8_0770_OR_200
: 0));
2695 fax_info_change
= true;
2697 fax_control_bits
&= ~(T30_CONTROL_BIT_REQUEST_POLLING
| T30_CONTROL_BIT_MORE_DOCUMENTS
);
2698 if (w
& 0x0002) /* Fax-polling request */
2699 fax_control_bits
|= T30_CONTROL_BIT_REQUEST_POLLING
;
2700 if ((w
& 0x0004) /* Request to send / poll another document */
2701 && (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS
))
2703 fax_control_bits
|= T30_CONTROL_BIT_MORE_DOCUMENTS
;
2705 if (ncpi
->length
>= 6)
2707 w
= GET_WORD(&ncpi
->info
[5]);
2708 if (((byte
) w
) != ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->data_format
)
2710 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->data_format
= (byte
) w
;
2711 fax_info_change
= true;
2714 if ((a
->man_profile
.private_options
& (1L << PRIVATE_FAX_SUB_SEP_PWD
))
2715 && (GET_WORD(&ncpi
->info
[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */
2717 plci
->requested_options_conn
|= (1L << PRIVATE_FAX_SUB_SEP_PWD
);
2719 if ((a
->man_profile
.private_options
& (1L << PRIVATE_FAX_NONSTANDARD
))
2720 && (GET_WORD(&ncpi
->info
[5]) & 0x4000)) /* Private non-standard facilities enable */
2722 plci
->requested_options_conn
|= (1L << PRIVATE_FAX_NONSTANDARD
);
2724 fax_control_bits
&= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS
| T30_CONTROL_BIT_ACCEPT_SEL_POLLING
|
2725 T30_CONTROL_BIT_ACCEPT_PASSWORD
);
2726 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[appl
->Id
-1])
2727 & ((1L << PRIVATE_FAX_SUB_SEP_PWD
) | (1L << PRIVATE_FAX_NONSTANDARD
)))
2729 if (api_parse (&ncpi
->info
[1], ncpi
->length
, "wwwwsss", fax_parms
))
2730 Info
= _WRONG_MESSAGE_FORMAT
;
2733 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[appl
->Id
-1])
2734 & (1L << PRIVATE_FAX_SUB_SEP_PWD
))
2736 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_SUBADDRESS
| T30_CONTROL_BIT_ACCEPT_PASSWORD
;
2737 if (fax_control_bits
& T30_CONTROL_BIT_ACCEPT_POLLING
)
2738 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_SEL_POLLING
;
2740 w
= fax_parms
[4].length
;
2743 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->station_id_len
= (byte
) w
;
2744 for (i
= 0; i
< w
; i
++)
2745 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->station_id
[i
] = fax_parms
[4].info
[1+i
];
2746 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->head_line_len
= 0;
2747 len
= (byte
)(offsetof(T30_INFO
, station_id
) + 20);
2748 w
= fax_parms
[5].length
;
2751 plci
->fax_connect_info_buffer
[len
++] = (byte
) w
;
2752 for (i
= 0; i
< w
; i
++)
2753 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[5].info
[1+i
];
2754 w
= fax_parms
[6].length
;
2757 plci
->fax_connect_info_buffer
[len
++] = (byte
) w
;
2758 for (i
= 0; i
< w
; i
++)
2759 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[6].info
[1+i
];
2760 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[appl
->Id
-1])
2761 & (1L << PRIVATE_FAX_NONSTANDARD
))
2763 if (api_parse (&ncpi
->info
[1], ncpi
->length
, "wwwwssss", fax_parms
))
2765 dbug(1,dprintf("non-standard facilities info missing or wrong format"));
2766 plci
->fax_connect_info_buffer
[len
++] = 0;
2770 if ((fax_parms
[7].length
>= 3) && (fax_parms
[7].info
[1] >= 2))
2771 plci
->nsf_control_bits
= GET_WORD(&fax_parms
[7].info
[2]);
2772 plci
->fax_connect_info_buffer
[len
++] = (byte
)(fax_parms
[7].length
);
2773 for (i
= 0; i
< fax_parms
[7].length
; i
++)
2774 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[7].info
[1+i
];
2781 len
= (byte
)(offsetof(T30_INFO
, universal_6
));
2783 fax_info_change
= true;
2786 if (fax_control_bits
!= GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
))
2788 PUT_WORD (&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
, fax_control_bits
);
2789 fax_info_change
= true;
2794 plci
->fax_connect_info_length
= len
;
2795 if (fax_info_change
)
2797 if (fax_feature_bits
& T30_FEATURE_BIT_MORE_DOCUMENTS
)
2799 start_internal_command (Id
, plci
, fax_connect_info_command
);
2804 start_internal_command (Id
, plci
, fax_adjust_b23_command
);
2810 else Info
= _WRONG_STATE
;
2812 else Info
= _WRONG_STATE
;
2815 else if (plci
->B3_prot
== B3_RTP
)
2817 plci
->internal_req_buffer
[0] = ncpi
->length
+ 1;
2818 plci
->internal_req_buffer
[1] = UDATA_REQUEST_RTP_RECONFIGURE
;
2819 for (w
= 0; w
< ncpi
->length
; w
++)
2820 plci
->internal_req_buffer
[2+w
] = ncpi
->info
[1+w
];
2821 start_internal_command (Id
, plci
, rtp_connect_b3_req_command
);
2827 nl_req_ncci(plci
,req
,0);
2832 else Info
= _WRONG_IDENTIFIER
;
2835 _CONNECT_B3_R
|CONFIRM
,
2842 byte
connect_b3_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
2851 API_PARSE fax_parms
[9];
2856 dbug(1,dprintf("connect_b3_res"));
2858 ncci
= (word
)(Id
>>16);
2860 if(a
->ncci_state
[ncci
]==INC_CON_PENDING
) {
2861 if (GET_WORD (&parms
[0].info
[0]) != 0)
2863 a
->ncci_state
[ncci
] = OUTG_REJ_PENDING
;
2864 channel_request_xon (plci
, a
->ncci_ch
[ncci
]);
2865 channel_xmit_xon (plci
);
2866 cleanup_ncci_data (plci
, ncci
);
2867 nl_req_ncci(plci
,N_DISC
,(byte
)ncci
);
2870 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
2872 req
= N_CONNECT_ACK
;
2874 if ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5) || (plci
->B3_prot
== 7))
2877 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[plci
->appl
->Id
-1])
2878 & (1L << PRIVATE_FAX_NONSTANDARD
))
2880 if (((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5))
2881 && (plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_ENABLE_NSF
)
2882 && (plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_NEGOTIATE_RESP
))
2884 len
= (byte
)(offsetof(T30_INFO
, station_id
) + 20);
2885 if (plci
->fax_connect_info_length
< len
)
2887 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->station_id_len
= 0;
2888 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->head_line_len
= 0;
2890 if (api_parse (&ncpi
->info
[1], ncpi
->length
, "wwwwssss", fax_parms
))
2892 dbug(1,dprintf("non-standard facilities info missing or wrong format"));
2896 if (plci
->fax_connect_info_length
<= len
)
2897 plci
->fax_connect_info_buffer
[len
] = 0;
2898 len
+= 1 + plci
->fax_connect_info_buffer
[len
];
2899 if (plci
->fax_connect_info_length
<= len
)
2900 plci
->fax_connect_info_buffer
[len
] = 0;
2901 len
+= 1 + plci
->fax_connect_info_buffer
[len
];
2902 if ((fax_parms
[7].length
>= 3) && (fax_parms
[7].info
[1] >= 2))
2903 plci
->nsf_control_bits
= GET_WORD(&fax_parms
[7].info
[2]);
2904 plci
->fax_connect_info_buffer
[len
++] = (byte
)(fax_parms
[7].length
);
2905 for (i
= 0; i
< fax_parms
[7].length
; i
++)
2906 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[7].info
[1+i
];
2908 plci
->fax_connect_info_length
= len
;
2909 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->code
= 0;
2910 start_internal_command (Id
, plci
, fax_connect_ack_command
);
2915 nl_req_ncci(plci
,req
,(byte
)ncci
);
2916 if ((plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
2917 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
2919 if (plci
->B3_prot
== 4)
2920 sendf(appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"s","");
2922 sendf(appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"S",plci
->ncpi_buffer
);
2923 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
2927 else if (plci
->B3_prot
== B3_RTP
)
2929 plci
->internal_req_buffer
[0] = ncpi
->length
+ 1;
2930 plci
->internal_req_buffer
[1] = UDATA_REQUEST_RTP_RECONFIGURE
;
2931 for (w
= 0; w
< ncpi
->length
; w
++)
2932 plci
->internal_req_buffer
[2+w
] = ncpi
->info
[1+w
];
2933 start_internal_command (Id
, plci
, rtp_connect_b3_res_command
);
2939 if(ncpi
->length
>2) {
2940 if(ncpi
->info
[1] &1) req
= N_CONNECT_ACK
| N_D_BIT
;
2941 add_d(plci
,(word
)(ncpi
->length
-3),&ncpi
->info
[4]);
2943 nl_req_ncci(plci
,req
,(byte
)ncci
);
2944 sendf(appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"s","");
2945 if (plci
->adjust_b_restore
)
2947 plci
->adjust_b_restore
= false;
2948 start_internal_command (Id
, plci
, adjust_b_restore
);
2957 byte
connect_b3_a_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
2961 ncci
= (word
)(Id
>>16);
2962 dbug(1,dprintf("connect_b3_a_res(ncci=0x%x)",ncci
));
2964 if (plci
&& ncci
&& (plci
->State
!= IDLE
) && (plci
->State
!= INC_DIS_PENDING
)
2965 && (plci
->State
!= OUTG_DIS_PENDING
))
2967 if(a
->ncci_state
[ncci
]==INC_ACT_PENDING
) {
2968 a
->ncci_state
[ncci
] = CONNECTED
;
2969 if(plci
->State
!=INC_CON_CONNECTED_ALERT
) plci
->State
= CONNECTED
;
2970 channel_request_xon (plci
, a
->ncci_ch
[ncci
]);
2971 channel_xmit_xon (plci
);
2977 byte
disconnect_b3_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
2983 dbug(1,dprintf("disconnect_b3_req"));
2985 Info
= _WRONG_IDENTIFIER
;
2986 ncci
= (word
)(Id
>>16);
2989 Info
= _WRONG_STATE
;
2990 if ((a
->ncci_state
[ncci
] == CONNECTED
)
2991 || (a
->ncci_state
[ncci
] == OUTG_CON_PENDING
)
2992 || (a
->ncci_state
[ncci
] == INC_CON_PENDING
)
2993 || (a
->ncci_state
[ncci
] == INC_ACT_PENDING
))
2995 a
->ncci_state
[ncci
] = OUTG_DIS_PENDING
;
2996 channel_request_xon (plci
, a
->ncci_ch
[ncci
]);
2997 channel_xmit_xon (plci
);
2999 if (a
->ncci
[ncci
].data_pending
3000 && ((plci
->B3_prot
== B3_TRANSPARENT
)
3001 || (plci
->B3_prot
== B3_T30
)
3002 || (plci
->B3_prot
== B3_T30_WITH_EXTENSIONS
)))
3004 plci
->send_disc
= (byte
)ncci
;
3010 cleanup_ncci_data (plci
, ncci
);
3012 if(plci
->B3_prot
==2 || plci
->B3_prot
==3)
3017 add_d(plci
, (word
)(ncpi
->length
- 3) ,(byte
*)&(ncpi
->info
[4]));
3020 nl_req_ncci(plci
,N_DISC
,(byte
)ncci
);
3026 _DISCONNECT_B3_R
|CONFIRM
,
3033 byte
disconnect_b3_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
3038 ncci
= (word
)(Id
>>16);
3039 dbug(1,dprintf("disconnect_b3_res(ncci=0x%x",ncci
));
3041 plci
->requested_options_conn
= 0;
3042 plci
->fax_connect_info_length
= 0;
3043 plci
->ncpi_state
= 0x00;
3044 if (((plci
->B3_prot
!= B3_T90NL
) && (plci
->B3_prot
!= B3_ISO8208
) && (plci
->B3_prot
!= B3_X25_DCE
))
3045 && ((plci
->B2_prot
!= B2_LAPD
) && (plci
->B2_prot
!= B2_LAPD_FREE_SAPI_SEL
)))
3047 plci
->call_dir
|= CALL_DIR_FORCE_OUTG_NL
;
3049 for(i
=0; i
<MAX_CHANNELS_PER_PLCI
&& plci
->inc_dis_ncci_table
[i
]!=(byte
)ncci
; i
++);
3050 if(i
<MAX_CHANNELS_PER_PLCI
) {
3051 if(plci
->channels
)plci
->channels
--;
3052 for(; i
<MAX_CHANNELS_PER_PLCI
-1; i
++) plci
->inc_dis_ncci_table
[i
] = plci
->inc_dis_ncci_table
[i
+1];
3053 plci
->inc_dis_ncci_table
[MAX_CHANNELS_PER_PLCI
-1] = 0;
3055 ncci_free_receive_buffers (plci
, ncci
);
3057 if((plci
->State
==IDLE
|| plci
->State
==SUSPENDING
) && !plci
->channels
){
3058 if(plci
->State
== SUSPENDING
){
3063 "ws", (word
)3, "\x03\x04\x00\x00");
3064 sendf(plci
->appl
, _DISCONNECT_I
, Id
& 0xffffL
, 0, "w", 0);
3072 if ((a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
3073 && ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5))
3074 && (a
->ncci_state
[ncci
] == INC_DIS_PENDING
))
3076 ncci_free_receive_buffers (plci
, ncci
);
3078 nl_req_ncci(plci
,N_EDATA
,(byte
)ncci
);
3080 plci
->adapter
->ncci_state
[ncci
] = IDLE
;
3081 start_internal_command (Id
, plci
, fax_disconnect_command
);
3089 byte
data_b3_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
3097 dbug(1,dprintf("data_b3_req"));
3099 Info
= _WRONG_IDENTIFIER
;
3100 ncci
= (word
)(Id
>>16);
3101 dbug(1,dprintf("ncci=0x%x, plci=0x%x",ncci
,plci
));
3105 Info
= _WRONG_STATE
;
3106 if ((a
->ncci_state
[ncci
] == CONNECTED
)
3107 || (a
->ncci_state
[ncci
] == INC_ACT_PENDING
))
3110 ncci_ptr
= &(a
->ncci
[ncci
]);
3111 i
= ncci_ptr
->data_out
+ ncci_ptr
->data_pending
;
3112 if (i
>= MAX_DATA_B3
)
3114 data
= &(ncci_ptr
->DBuffer
[i
]);
3115 data
->Number
= Number
;
3116 if ((((byte
*)(parms
[0].info
)) >= ((byte
*)(plci
->msg_in_queue
)))
3117 && (((byte
*)(parms
[0].info
)) < ((byte
*)(plci
->msg_in_queue
)) + sizeof(plci
->msg_in_queue
)))
3120 data
->P
= (byte
*)(long)(*((dword
*)(parms
[0].info
)));
3124 data
->P
= TransmitBufferSet(appl
,*(dword
*)parms
[0].info
);
3125 data
->Length
= GET_WORD(parms
[1].info
);
3126 data
->Handle
= GET_WORD(parms
[2].info
);
3127 data
->Flags
= GET_WORD(parms
[3].info
);
3128 (ncci_ptr
->data_pending
)++;
3130 /* check for delivery confirmation */
3131 if (data
->Flags
& 0x0004)
3133 i
= ncci_ptr
->data_ack_out
+ ncci_ptr
->data_ack_pending
;
3134 if (i
>= MAX_DATA_ACK
)
3136 ncci_ptr
->DataAck
[i
].Number
= data
->Number
;
3137 ncci_ptr
->DataAck
[i
].Handle
= data
->Handle
;
3138 (ncci_ptr
->data_ack_pending
)++;
3149 if ((((byte
*)(parms
[0].info
)) >= ((byte
*)(plci
->msg_in_queue
)))
3150 && (((byte
*)(parms
[0].info
)) < ((byte
*)(plci
->msg_in_queue
)) + sizeof(plci
->msg_in_queue
)))
3153 TransmitBufferFree (appl
, (byte
*)(long)(*((dword
*)(parms
[0].info
))));
3161 "ww",GET_WORD(parms
[2].info
),Info
);
3166 byte
data_b3_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
3172 dbug(1,dprintf("data_b3_res"));
3174 ncci
= (word
)(Id
>>16);
3176 n
= GET_WORD(parms
[0].info
);
3177 dbug(1,dprintf("free(%d)",n
));
3178 NCCIcode
= ncci
| (((word
) a
->Id
) << 8);
3179 if(n
<appl
->MaxBuffer
&&
3180 appl
->DataNCCI
[n
]==NCCIcode
&&
3181 (byte
)(appl
->DataFlags
[n
]>>8)==plci
->Id
) {
3182 dbug(1,dprintf("found"));
3183 appl
->DataNCCI
[n
] = 0;
3185 if (channel_can_xon (plci
, a
->ncci_ch
[ncci
])) {
3186 channel_request_xon (plci
, a
->ncci_ch
[ncci
]);
3188 channel_xmit_xon (plci
);
3190 if(appl
->DataFlags
[n
] &4) {
3191 nl_req_ncci(plci
,N_DATA_ACK
,(byte
)ncci
);
3199 byte
reset_b3_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
3204 dbug(1,dprintf("reset_b3_req"));
3206 Info
= _WRONG_IDENTIFIER
;
3207 ncci
= (word
)(Id
>>16);
3210 Info
= _WRONG_STATE
;
3211 switch (plci
->B3_prot
)
3215 if(a
->ncci_state
[ncci
]==CONNECTED
)
3217 nl_req_ncci(plci
,N_RESET
,(byte
)ncci
);
3222 case B3_TRANSPARENT
:
3223 if(a
->ncci_state
[ncci
]==CONNECTED
)
3225 start_internal_command (Id
, plci
, reset_b3_command
);
3231 /* reset_b3 must result in a reset_b3_con & reset_b3_Ind */
3233 _RESET_B3_R
|CONFIRM
,
3240 byte
reset_b3_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
3244 dbug(1,dprintf("reset_b3_res"));
3246 ncci
= (word
)(Id
>>16);
3248 switch (plci
->B3_prot
)
3252 if(a
->ncci_state
[ncci
]==INC_RES_PENDING
)
3254 a
->ncci_state
[ncci
] = CONNECTED
;
3255 nl_req_ncci(plci
,N_RESET_ACK
,(byte
)ncci
);
3264 byte
connect_b3_t90_a_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* parms
)
3270 dbug(1,dprintf("connect_b3_t90_a_res"));
3272 ncci
= (word
)(Id
>>16);
3274 if(a
->ncci_state
[ncci
]==INC_ACT_PENDING
) {
3275 a
->ncci_state
[ncci
] = CONNECTED
;
3277 else if(a
->ncci_state
[ncci
]==INC_CON_PENDING
) {
3278 a
->ncci_state
[ncci
] = CONNECTED
;
3280 req
= N_CONNECT_ACK
;
3282 /* parms[0]==0 for CAPI original message definition! */
3285 if(ncpi
->length
>2) {
3286 if(ncpi
->info
[1] &1) req
= N_CONNECT_ACK
| N_D_BIT
;
3287 add_d(plci
,(word
)(ncpi
->length
-3),&ncpi
->info
[4]);
3290 nl_req_ncci(plci
,req
,(byte
)ncci
);
3298 byte
select_b_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
, APPL
* appl
, API_PARSE
* msg
)
3303 API_PARSE bp_parms
[7];
3307 Info
= _WRONG_IDENTIFIER
;
3311 dbug(1,dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x",
3312 msg
->length
,plci
->Id
,plci
->tel
,plci
->NL
.Id
,plci
->appl
,plci
->SuppState
));
3313 dbug(1,dprintf("PlciState=0x%x",plci
->State
));
3314 for(i
=0;i
<7;i
++) bp_parms
[i
].length
= 0;
3316 /* check if no channel is open, no B3 connected only */
3317 if((plci
->State
== IDLE
) || (plci
->State
== OUTG_DIS_PENDING
) || (plci
->State
== INC_DIS_PENDING
)
3318 || (plci
->SuppState
!= IDLE
) || plci
->channels
|| plci
->nl_remove_id
)
3320 Info
= _WRONG_STATE
;
3322 /* check message format and fill bp_parms pointer */
3323 else if(msg
->length
&& api_parse(&msg
->info
[1], (word
)msg
->length
, "wwwsss", bp_parms
))
3325 Info
= _WRONG_MESSAGE_FORMAT
;
3329 if((plci
->State
==INC_CON_PENDING
) || (plci
->State
==INC_CON_ALERT
)) /* send alert tone inband to the network, */
3330 { /* e.g. Qsig or RBS or Cornet-N or xess PRI */
3331 if(Id
& EXT_CONTROLLER
)
3333 sendf(appl
, _SELECT_B_REQ
|CONFIRM
, Id
, Number
, "w", 0x2002); /* wrong controller */
3336 plci
->State
=INC_CON_CONNECTED_ALERT
;
3338 clear_c_ind_mask_bit (plci
, (word
)(appl
->Id
-1));
3339 dump_c_ind_mask (plci
);
3340 for(i
=0; i
<max_appl
; i
++) /* disconnect the other appls */
3341 { /* its quasi a connect */
3342 if(test_c_ind_mask_bit (plci
, i
))
3343 sendf(&application
[i
], _DISCONNECT_I
, Id
, 0, "w", _OTHER_APPL_CONNECTED
);
3347 api_save_msg(msg
, "s", &plci
->saved_msg
);
3349 if(Id
& EXT_CONTROLLER
)
3351 if(tel
) /* external controller in use by this PLCI */
3353 if(a
->AdvSignalAppl
&& a
->AdvSignalAppl
!=appl
)
3355 dbug(1,dprintf("Ext_Ctrl in use 1"));
3356 Info
= _WRONG_STATE
;
3359 else /* external controller NOT in use by this PLCI ? */
3361 if(a
->AdvSignalPLCI
)
3363 dbug(1,dprintf("Ext_Ctrl in use 2"));
3364 Info
= _WRONG_STATE
;
3366 else /* activate the codec */
3368 dbug(1,dprintf("Ext_Ctrl start"));
3369 if(AdvCodecSupport(a
, plci
, appl
, 0) )
3371 dbug(1,dprintf("Error in codec procedures"));
3372 Info
= _WRONG_STATE
;
3374 else if(plci
->spoofed_msg
==SPOOFING_REQUIRED
) /* wait until codec is active */
3376 plci
->spoofed_msg
= AWAITING_SELECT_B
;
3377 plci
->internal_command
= BLOCK_PLCI
; /* lock other commands */
3379 dbug(1,dprintf("continue if codec loaded"));
3385 else /* external controller bit is OFF */
3387 if(tel
) /* external controller in use, need to switch off */
3389 if(a
->AdvSignalAppl
==appl
)
3391 CodecIdCheck(a
, plci
);
3394 dbug(1,dprintf("Ext_Ctrl disable"));
3398 dbug(1,dprintf("Ext_Ctrl not requested"));
3404 if (plci
->call_dir
& CALL_DIR_OUT
)
3405 plci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
3406 else if (plci
->call_dir
& CALL_DIR_IN
)
3407 plci
->call_dir
= CALL_DIR_IN
| CALL_DIR_ANSWER
;
3408 start_internal_command (Id
, plci
, select_b_command
);
3413 sendf(appl
, _SELECT_B_REQ
|CONFIRM
, Id
, Number
, "w", Info
);
3417 static byte
manufacturer_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3418 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 static byte
manufacturer_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3747 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
3751 API_PARSE m_parms
[3];
3753 API_PARSE fax_parms
[9];
3758 dbug(1,dprintf("manufacturer_res"));
3760 if ((msg
[0].length
== 0)
3761 || (msg
[1].length
== 0)
3762 || (GET_DWORD(msg
[0].info
)!=_DI_MANU_ID
))
3766 indication
= GET_WORD(msg
[1].info
);
3770 case _DI_NEGOTIATE_B3
:
3773 if (((plci
->B3_prot
!= 4) && (plci
->B3_prot
!= 5))
3774 || !(plci
->ncpi_state
& NCPI_NEGOTIATE_B3_SENT
))
3776 dbug(1,dprintf("wrong state for NEGOTIATE_B3 parameters"));
3779 if (api_parse (&msg
[2].info
[1], msg
[2].length
, "ws", m_parms
))
3781 dbug(1,dprintf("wrong format in NEGOTIATE_B3 parameters"));
3785 len
= (byte
)(offsetof(T30_INFO
, station_id
) + 20);
3786 if (plci
->fax_connect_info_length
< len
)
3788 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->station_id_len
= 0;
3789 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->head_line_len
= 0;
3791 if (api_parse (&ncpi
->info
[1], ncpi
->length
, "wwwwssss", fax_parms
))
3793 dbug(1,dprintf("non-standard facilities info missing or wrong format"));
3797 if (plci
->fax_connect_info_length
<= len
)
3798 plci
->fax_connect_info_buffer
[len
] = 0;
3799 len
+= 1 + plci
->fax_connect_info_buffer
[len
];
3800 if (plci
->fax_connect_info_length
<= len
)
3801 plci
->fax_connect_info_buffer
[len
] = 0;
3802 len
+= 1 + plci
->fax_connect_info_buffer
[len
];
3803 if ((fax_parms
[7].length
>= 3) && (fax_parms
[7].info
[1] >= 2))
3804 plci
->nsf_control_bits
= GET_WORD(&fax_parms
[7].info
[2]);
3805 plci
->fax_connect_info_buffer
[len
++] = (byte
)(fax_parms
[7].length
);
3806 for (i
= 0; i
< fax_parms
[7].length
; i
++)
3807 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[7].info
[1+i
];
3809 plci
->fax_connect_info_length
= len
;
3810 plci
->fax_edata_ack_length
= plci
->fax_connect_info_length
;
3811 start_internal_command (Id
, plci
, fax_edata_ack_command
);
3818 /*------------------------------------------------------------------*/
3819 /* IDI callback function */
3820 /*------------------------------------------------------------------*/
3822 void callback(ENTITY
* e
)
3824 DIVA_CAPI_ADAPTER
* a
;
3835 dbug(1,dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)",
3836 (e
->user
[0]+1)&0x7fff,e
->Id
,e
->Req
,e
->Rc
,e
->Ind
));
3838 a
= &(adapter
[(byte
)e
->user
[0]]);
3839 plci
= &(a
->plci
[e
->user
[1]]);
3840 no_cancel_rc
= DIVA_CAPI_SUPPORTS_NO_CANCEL(a
);
3843 If new protocol code and new XDI is used then CAPI should work
3844 fully in accordance with IDI cpec an look on callback field instead
3845 of Rc field for return codes.
3847 if (((e
->complete
== 0xff) && no_cancel_rc
) ||
3848 (e
->Rc
&& !no_cancel_rc
)) {
3854 if (e
->user
[0] & 0x8000)
3857 If REMOVE request was sent then we have to wait until
3858 return code with Id set to zero arrives.
3859 All other return codes should be ignored.
3865 dbug(1,dprintf("cancel RC in REMOVE state"));
3868 channel_flow_control_remove (plci
);
3869 for (i
= 0; i
< 256; i
++)
3871 if (a
->FlowControlIdTable
[i
] == plci
->nl_remove_id
)
3872 a
->FlowControlIdTable
[i
] = 0;
3874 plci
->nl_remove_id
= 0;
3875 if (plci
->rx_dma_descriptor
> 0) {
3876 diva_free_dma_descriptor (plci
, plci
->rx_dma_descriptor
- 1);
3877 plci
->rx_dma_descriptor
= 0;
3882 a
->FlowControlIdTable
[ch
] = e
->Id
;
3883 a
->FlowControlSkipTable
[ch
] = 0;
3885 a
->ch_flow_control
[ch
] |= N_OK_FC_PENDING
;
3886 a
->ch_flow_plci
[ch
] = plci
->Id
;
3892 Cancel return codes self, if feature was requested
3894 if (no_cancel_rc
&& (a
->FlowControlIdTable
[ch
] == e
->Id
) && e
->Id
) {
3895 a
->FlowControlIdTable
[ch
] = 0;
3896 if ((rc
== OK
) && a
->FlowControlSkipTable
[ch
]) {
3897 dbug(3,dprintf ("XDI CAPI: RC cancelled Id:0x02, Ch:%02x", e
->Id
, ch
));
3902 if (a
->ch_flow_control
[ch
] & N_OK_FC_PENDING
)
3904 a
->ch_flow_control
[ch
] &= ~N_OK_FC_PENDING
;
3912 control_rc (plci
, 0, rc
, ch
, 0, true);
3917 channel_x_on (plci
, ch
);
3918 if (plci
->internal_command
)
3919 control_rc (plci
, req
, rc
, ch
, 0, true);
3923 if (plci
->nl_global_req
)
3925 global_req
= plci
->nl_global_req
;
3926 plci
->nl_global_req
= 0;
3927 if (rc
!= ASSIGN_OK
) {
3929 if (plci
->rx_dma_descriptor
> 0) {
3930 diva_free_dma_descriptor (plci
, plci
->rx_dma_descriptor
- 1);
3931 plci
->rx_dma_descriptor
= 0;
3934 channel_xmit_xon (plci
);
3935 control_rc (plci
, 0, rc
, ch
, global_req
, true);
3937 else if (plci
->data_sent
)
3939 channel_xmit_xon (plci
);
3940 plci
->data_sent
= false;
3943 if (plci
->internal_command
)
3944 control_rc (plci
, req
, rc
, ch
, 0, true);
3948 channel_xmit_xon (plci
);
3949 control_rc (plci
, req
, rc
, ch
, 0, true);
3957 If REMOVE request was sent then we have to wait until
3958 return code with Id set to zero arrives.
3959 All other return codes should be ignored.
3965 dbug(1,dprintf("cancel RC in REMOVE state"));
3968 plci
->sig_remove_id
= 0;
3971 if (plci
->sig_global_req
)
3973 global_req
= plci
->sig_global_req
;
3974 plci
->sig_global_req
= 0;
3975 if (rc
!= ASSIGN_OK
)
3977 channel_xmit_xon (plci
);
3978 control_rc (plci
, 0, rc
, ch
, global_req
, false);
3982 channel_xmit_xon (plci
);
3983 control_rc (plci
, req
, rc
, ch
, 0, false);
3987 Again: in accordance with IDI spec Rc and Ind can't be delivered in the
3988 same callback. Also if new XDI and protocol code used then jump
3992 channel_xmit_xon(plci
);
3993 goto capi_callback_suffix
;
3997 channel_xmit_xon(plci
);
4000 if (e
->user
[0] &0x8000) {
4001 byte Ind
= e
->Ind
& 0x0f;
4003 if (((Ind
==N_DISC
) || (Ind
==N_DISC_ACK
)) &&
4004 (a
->ch_flow_plci
[Ch
] == plci
->Id
)) {
4005 if (a
->ch_flow_control
[Ch
] & N_RX_FLOW_CONTROL_MASK
) {
4006 dbug(3,dprintf ("XDI CAPI: I: pending N-XON Ch:%02x", Ch
));
4008 a
->ch_flow_control
[Ch
] &= ~N_RX_FLOW_CONTROL_MASK
;
4011 if ((e
->RNR
!= 1) &&
4012 (a
->ch_flow_plci
[Ch
] == plci
->Id
) &&
4013 (a
->ch_flow_control
[Ch
] & N_RX_FLOW_CONTROL_MASK
)) {
4014 a
->ch_flow_control
[Ch
] &= ~N_RX_FLOW_CONTROL_MASK
;
4015 dbug(3,dprintf ("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch
));
4023 capi_callback_suffix
:
4025 while (!plci
->req_in
4026 && !plci
->internal_command
4027 && (plci
->msg_in_write_pos
!= plci
->msg_in_read_pos
))
4029 j
= (plci
->msg_in_read_pos
== plci
->msg_in_wrap_pos
) ? 0 : plci
->msg_in_read_pos
;
4031 i
= (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[j
]))->header
.length
+ 3) & 0xfffc;
4033 m
= (CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[j
]);
4034 appl
= *((APPL
* *)(&((byte
*)(plci
->msg_in_queue
))[j
+i
]));
4035 dbug(1,dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d",
4036 m
->header
.command
, plci
->msg_in_write_pos
, plci
->msg_in_read_pos
, plci
->msg_in_wrap_pos
));
4037 if (plci
->msg_in_read_pos
== plci
->msg_in_wrap_pos
)
4039 plci
->msg_in_wrap_pos
= MSG_IN_QUEUE_SIZE
;
4040 plci
->msg_in_read_pos
= i
+ MSG_IN_OVERHEAD
;
4044 plci
->msg_in_read_pos
= j
+ i
+ MSG_IN_OVERHEAD
;
4046 if (plci
->msg_in_read_pos
== plci
->msg_in_write_pos
)
4048 plci
->msg_in_write_pos
= MSG_IN_QUEUE_SIZE
;
4049 plci
->msg_in_read_pos
= MSG_IN_QUEUE_SIZE
;
4051 else if (plci
->msg_in_read_pos
== plci
->msg_in_wrap_pos
)
4053 plci
->msg_in_read_pos
= MSG_IN_QUEUE_SIZE
;
4054 plci
->msg_in_wrap_pos
= MSG_IN_QUEUE_SIZE
;
4056 i
= api_put (appl
, m
);
4059 if (m
->header
.command
== _DATA_B3_R
)
4061 TransmitBufferFree (appl
, (byte
*)(long)(m
->info
.data_b3_req
.Data
));
4063 dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i
, m
->header
.command
));
4067 if (plci
->li_notify_update
)
4069 plci
->li_notify_update
= false;
4070 mixer_notify_update (plci
, false);
4079 static void control_rc(PLCI
*plci
, byte req
, byte rc
, byte ch
, byte global_req
,
4088 DIVA_CAPI_ADAPTER
* a
;
4091 byte SSparms
[] = "\x05\x00\x00\x02\x00\x00";
4092 byte SSstruct
[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
4095 dbug(0,dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req
, rc
, ch
, global_req
, nl_rc
));
4098 dbug(1,dprintf("req0_in/out=%d/%d",plci
->req_in
,plci
->req_out
));
4099 if(plci
->req_in
!=plci
->req_out
)
4101 if (nl_rc
|| (global_req
!= ASSIGN
) || (rc
== ASSIGN_OK
))
4103 dbug(1,dprintf("req_1return"));
4106 /* cancel outstanding request on the PLCI after SIG ASSIGN failure */
4108 plci
->req_in
= plci
->req_in_start
= plci
->req_out
= 0;
4109 dbug(1,dprintf("control_rc"));
4113 ncci
= a
->ch_ncci
[ch
];
4116 Id
= (((dword
)(ncci
? ncci
: ch
)) << 16) | ((word
)plci
->Id
<< 8) | a
->Id
;
4117 if(plci
->tel
&& plci
->SuppState
!=CALL_HELD
) Id
|=EXT_CONTROLLER
;
4118 Number
= plci
->number
;
4119 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
));
4120 dbug(1,dprintf("channels=0x%x",plci
->channels
));
4121 if (plci_remove_check(plci
))
4123 if(req
==REMOVE
&& rc
==ASSIGN_OK
)
4125 sig_req(plci
,HANGUP
,0);
4126 sig_req(plci
,REMOVE
,0);
4131 switch(plci
->command
)
4134 dbug(1,dprintf("HoldRC=0x%x",rc
));
4135 SSparms
[1] = (byte
)S_HOLD
;
4138 plci
->SuppState
= IDLE
;
4141 sendf(appl
,_FACILITY_R
|CONFIRM
,Id
,Number
,"wws",Info
,3,SSparms
);
4144 case C_RETRIEVE_REQ
:
4145 dbug(1,dprintf("RetrieveRC=0x%x",rc
));
4146 SSparms
[1] = (byte
)S_RETRIEVE
;
4149 plci
->SuppState
= CALL_HELD
;
4152 sendf(appl
,_FACILITY_R
|CONFIRM
,Id
,Number
,"wws",Info
,3,SSparms
);
4156 dbug(1,dprintf("InfoRC=0x%x",rc
));
4157 if(rc
!=OK
) Info
=_WRONG_STATE
;
4158 sendf(appl
,_INFO_R
|CONFIRM
,Id
,Number
,"w",Info
);
4162 dbug(1,dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x",req
,rc
,global_req
,nl_rc
));
4163 if (plci
->State
== INC_DIS_PENDING
)
4165 if(plci
->Sig
.Id
!=0xff)
4167 if (((global_req
== ASSIGN
) && (rc
!= ASSIGN_OK
))
4168 || (!nl_rc
&& (req
== CALL_REQ
) && (rc
!= OK
)))
4170 dbug(1,dprintf("No more IDs/Call_Req failed"));
4171 sendf(appl
,_CONNECT_R
|CONFIRM
,Id
&0xffL
,Number
,"w",_OUT_OF_PLCI
);
4176 if(plci
->State
!=LOCAL_CONNECT
)plci
->State
= OUTG_CON_PENDING
;
4177 sendf(appl
,_CONNECT_R
|CONFIRM
,Id
,Number
,"w",0);
4179 else /* D-ch activation */
4181 if (rc
!= ASSIGN_OK
)
4183 dbug(1,dprintf("No more IDs/X.25 Call_Req failed"));
4184 sendf(appl
,_CONNECT_R
|CONFIRM
,Id
&0xffL
,Number
,"w",_OUT_OF_PLCI
);
4189 sendf(appl
,_CONNECT_R
|CONFIRM
,Id
,Number
,"w",0);
4190 sendf(plci
->appl
,_CONNECT_ACTIVE_I
,Id
,0,"sss","","","");
4191 plci
->State
= INC_ACT_PENDING
;
4195 case _CONNECT_I
|RESPONSE
:
4196 if (plci
->State
!= INC_DIS_PENDING
)
4197 plci
->State
= INC_CON_ACCEPT
;
4201 if (plci
->State
== INC_DIS_PENDING
)
4203 if(plci
->Sig
.Id
!=0xff)
4205 plci
->State
= OUTG_DIS_PENDING
;
4206 sendf(appl
,_DISCONNECT_R
|CONFIRM
,Id
,Number
,"w",0);
4219 sendf(appl
,_CONNECT_B3_R
|CONFIRM
,Id
,Number
,"w",_WRONG_IDENTIFIER
);
4222 ncci
= get_ncci (plci
, ch
, 0);
4223 Id
= (Id
& 0xffff) | (((dword
) ncci
) << 16);
4227 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
4228 sendf(appl
,_CONNECT_B3_R
|CONFIRM
,Id
,Number
,"w",0);
4229 sendf(appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"s","");
4233 a
->ncci_state
[ncci
] = OUTG_CON_PENDING
;
4234 sendf(appl
,_CONNECT_B3_R
|CONFIRM
,Id
,Number
,"w",0);
4238 case _CONNECT_B3_I
|RESPONSE
:
4242 /* sendf(appl,_RESET_B3_R|CONFIRM,Id,Number,"w",0);*/
4245 case _DISCONNECT_B3_R
:
4246 sendf(appl
,_DISCONNECT_B3_R
|CONFIRM
,Id
,Number
,"w",0);
4249 case _MANUFACTURER_R
:
4255 Info
= _WRONG_IDENTIFIER
;
4256 sendf(plci
->appl
,_CONNECT_R
|CONFIRM
,Id
,Number
,"w",Info
);
4260 sendf(plci
->appl
,_CONNECT_R
|CONFIRM
,Id
,Number
,"w",Info
);
4268 else if (plci
->internal_command
)
4270 switch(plci
->internal_command
)
4276 if(rc
==OK
) /* command supported, wait for indication */
4283 /* Get Supported Services */
4284 case GETSERV_REQ_PEND
:
4285 if(rc
==OK
) /* command supported, wait for indication */
4289 PUT_DWORD(&SSstruct
[6], MASK_TERMINAL_PORTABILITY
);
4290 sendf(appl
, _FACILITY_R
|CONFIRM
, Id
, Number
, "wws",0,3,SSstruct
);
4294 case INTERR_DIVERSION_REQ_PEND
: /* Interrogate Parameters */
4295 case INTERR_NUMBERS_REQ_PEND
:
4296 case CF_START_PEND
: /* Call Forwarding Start pending */
4297 case CF_STOP_PEND
: /* Call Forwarding Stop pending */
4298 case CCBS_REQUEST_REQ_PEND
:
4299 case CCBS_DEACTIVATE_REQ_PEND
:
4300 case CCBS_INTERROGATE_REQ_PEND
:
4301 switch(plci
->internal_command
)
4303 case INTERR_DIVERSION_REQ_PEND
:
4304 SSparms
[1] = S_INTERROGATE_DIVERSION
;
4306 case INTERR_NUMBERS_REQ_PEND
:
4307 SSparms
[1] = S_INTERROGATE_NUMBERS
;
4310 SSparms
[1] = S_CALL_FORWARDING_START
;
4313 SSparms
[1] = S_CALL_FORWARDING_STOP
;
4315 case CCBS_REQUEST_REQ_PEND
:
4316 SSparms
[1] = S_CCBS_REQUEST
;
4318 case CCBS_DEACTIVATE_REQ_PEND
:
4319 SSparms
[1] = S_CCBS_DEACTIVATE
;
4321 case CCBS_INTERROGATE_REQ_PEND
:
4322 SSparms
[1] = S_CCBS_INTERROGATE
;
4325 if(global_req
==ASSIGN
)
4327 dbug(1,dprintf("AssignDiversion_RC=0x%x/0x%x",req
,rc
));
4330 if(!plci
->appl
) break;
4331 if(rc
==ISDN_GUARD_REJ
)
4333 Info
= _CAPI_GUARD_ERROR
;
4337 Info
= _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED
;
4339 sendf(plci
->appl
,_FACILITY_R
|CONFIRM
,Id
&0x7,
4340 plci
->number
,"wws",Info
,(word
)3,SSparms
);
4341 if(Info
) plci_remove(plci
);
4344 /* 3pty conference pending */
4346 if(!plci
->relatedPTYPLCI
) break;
4347 rplci
= plci
->relatedPTYPLCI
;
4348 SSparms
[1] = plci
->ptyState
;
4349 rId
= ((word
)rplci
->Id
<<8)|rplci
->adapter
->Id
;
4350 if(rplci
->tel
) rId
|=EXT_CONTROLLER
;
4353 Info
= 0x300E; /* not supported */
4354 plci
->relatedPTYPLCI
= NULL
;
4358 _FACILITY_R
|CONFIRM
,
4361 "wws",Info
,(word
)3,SSparms
);
4364 /* Explicit Call Transfer pending */
4366 dbug(1,dprintf("ECT_RC=0x%x/0x%x",req
,rc
));
4367 if(!plci
->relatedPTYPLCI
) break;
4368 rplci
= plci
->relatedPTYPLCI
;
4370 rId
= ((word
)rplci
->Id
<<8)|rplci
->adapter
->Id
;
4371 if(rplci
->tel
) rId
|=EXT_CONTROLLER
;
4374 Info
= 0x300E; /* not supported */
4375 plci
->relatedPTYPLCI
= NULL
;
4379 _FACILITY_R
|CONFIRM
,
4382 "wws",Info
,(word
)3,SSparms
);
4385 case _MANUFACTURER_R
:
4386 dbug(1,dprintf("_Manufacturer_R=0x%x/0x%x",req
,rc
));
4387 if ((global_req
== ASSIGN
) && (rc
!= ASSIGN_OK
))
4389 dbug(1,dprintf("No more IDs"));
4390 sendf(appl
,_MANUFACTURER_R
|CONFIRM
,Id
,Number
,"dww",_DI_MANU_ID
,_MANUFACTURER_R
,_OUT_OF_PLCI
);
4391 plci_remove(plci
); /* after codec init, internal codec commands pending */
4396 dbug(1,dprintf("_Connect_R=0x%x/0x%x",req
,rc
));
4397 if ((global_req
== ASSIGN
) && (rc
!= ASSIGN_OK
))
4399 dbug(1,dprintf("No more IDs"));
4400 sendf(appl
,_CONNECT_R
|CONFIRM
,Id
&0xffL
,Number
,"w",_OUT_OF_PLCI
);
4401 plci_remove(plci
); /* after codec init, internal codec commands pending */
4405 case PERM_COD_HOOK
: /* finished with Hook_Ind */
4409 dbug(1,dprintf("***Codec Connect_Pending A, Rc = 0x%x",rc
));
4410 plci
->internal_command
= PERM_COD_CONN_PEND
;
4413 case PERM_COD_ASSIGN
:
4414 dbug(1,dprintf("***Codec Assign A, Rc = 0x%x",rc
));
4415 if(rc
!=ASSIGN_OK
) break;
4416 sig_req(plci
,CALL_REQ
,0);
4418 plci
->internal_command
= PERM_COD_CALL
;
4421 /* Null Call Reference Request pending */
4423 dbug(1,dprintf("NCR_FAC=0x%x/0x%x",req
,rc
));
4424 if(global_req
==ASSIGN
)
4432 sendf(appl
,_INFO_R
|CONFIRM
,Id
&0xf,Number
,"w",_WRONG_STATE
);
4433 appl
->NullCREnable
= false;
4437 else if(req
==NCR_FACILITY
)
4441 sendf(appl
,_INFO_R
|CONFIRM
,Id
&0xf,Number
,"w",0);
4445 sendf(appl
,_INFO_R
|CONFIRM
,Id
&0xf,Number
,"w",_WRONG_STATE
);
4446 appl
->NullCREnable
= false;
4455 if(a
->ncci_state
[ncci
]==CONNECTED
)
4457 a
->ncci_state
[ncci
] = OUTG_DIS_PENDING
;
4458 cleanup_ncci_data (plci
, ncci
);
4459 nl_req_ncci(plci
,N_DISC
,(byte
)ncci
);
4466 if (plci
->State
== INC_DIS_PENDING
)
4468 sig_req(plci
,CALL_REQ
,0);
4470 plci
->State
=OUTG_CON_PENDING
;
4474 case MWI_ACTIVATE_REQ_PEND
:
4475 case MWI_DEACTIVATE_REQ_PEND
:
4476 if(global_req
== ASSIGN
&& rc
==ASSIGN_OK
)
4478 dbug(1,dprintf("MWI_REQ assigned"));
4485 Info
= 0x2007; /* Illegal message parameter coding */
4486 dbug(1,dprintf("MWI_REQ invalid parameter"));
4490 Info
= 0x300B; /* not supported */
4491 dbug(1,dprintf("MWI_REQ not supported"));
4493 /* 0x3010: Request not allowed in this state */
4494 PUT_WORD(&SSparms
[4],0x300E); /* SS not supported */
4497 if(plci
->internal_command
==MWI_ACTIVATE_REQ_PEND
)
4499 PUT_WORD(&SSparms
[1],S_MWI_ACTIVATE
);
4501 else PUT_WORD(&SSparms
[1],S_MWI_DEACTIVATE
);
4503 if(plci
->cr_enquiry
)
4506 _FACILITY_R
|CONFIRM
,
4509 "wws",Info
,(word
)3,SSparms
);
4510 if(rc
!=OK
) plci_remove(plci
);
4515 _FACILITY_R
|CONFIRM
,
4518 "wws",Info
,(word
)3,SSparms
);
4522 case CONF_BEGIN_REQ_PEND
:
4523 case CONF_ADD_REQ_PEND
:
4524 case CONF_SPLIT_REQ_PEND
:
4525 case CONF_DROP_REQ_PEND
:
4526 case CONF_ISOLATE_REQ_PEND
:
4527 case CONF_REATTACH_REQ_PEND
:
4528 dbug(1,dprintf("CONF_RC=0x%x/0x%x",req
,rc
));
4529 if((plci
->internal_command
==CONF_ADD_REQ_PEND
)&&(!plci
->relatedPTYPLCI
)) break;
4532 switch(plci
->internal_command
)
4534 case CONF_BEGIN_REQ_PEND
:
4535 SSparms
[1] = S_CONF_BEGIN
;
4537 case CONF_ADD_REQ_PEND
:
4538 SSparms
[1] = S_CONF_ADD
;
4539 rplci
= plci
->relatedPTYPLCI
;
4540 rId
= ((word
)rplci
->Id
<<8)|rplci
->adapter
->Id
;
4542 case CONF_SPLIT_REQ_PEND
:
4543 SSparms
[1] = S_CONF_SPLIT
;
4545 case CONF_DROP_REQ_PEND
:
4546 SSparms
[1] = S_CONF_DROP
;
4548 case CONF_ISOLATE_REQ_PEND
:
4549 SSparms
[1] = S_CONF_ISOLATE
;
4551 case CONF_REATTACH_REQ_PEND
:
4552 SSparms
[1] = S_CONF_REATTACH
;
4558 Info
= 0x300E; /* not supported */
4559 plci
->relatedPTYPLCI
= NULL
;
4563 _FACILITY_R
|CONFIRM
,
4566 "wws",Info
,(word
)3,SSparms
);
4569 case VSWITCH_REQ_PEND
:
4572 if(plci
->relatedPTYPLCI
)
4574 plci
->relatedPTYPLCI
->vswitchstate
=0;
4575 plci
->relatedPTYPLCI
->vsprot
=0;
4576 plci
->relatedPTYPLCI
->vsprotdialect
=0;
4578 plci
->vswitchstate
=0;
4580 plci
->vsprotdialect
=0;
4584 if(plci
->relatedPTYPLCI
&&
4585 plci
->vswitchstate
==1 &&
4586 plci
->relatedPTYPLCI
->vswitchstate
==3) /* join complete */
4587 plci
->vswitchstate
=3;
4591 /* Call Deflection Request pending (SSCT) */
4593 SSparms
[1] = S_CALL_DEFLECTION
;
4596 Info
= 0x300E; /* not supported */
4597 plci
->appl
->CDEnable
= 0;
4599 sendf(plci
->appl
,_FACILITY_R
|CONFIRM
,Id
,
4600 plci
->number
,"wws",Info
,(word
)3,SSparms
);
4603 case RTP_CONNECT_B3_REQ_COMMAND_2
:
4606 ncci
= get_ncci (plci
, ch
, 0);
4607 Id
= (Id
& 0xffff) | (((dword
) ncci
) << 16);
4609 a
->ncci_state
[ncci
] = OUTG_CON_PENDING
;
4613 if (plci
->internal_command_queue
[0])
4615 (*(plci
->internal_command_queue
[0]))(Id
, plci
, rc
);
4616 if (plci
->internal_command
)
4621 next_internal_command (Id
, plci
);
4626 Id
= ((word
)plci
->Id
<<8)|plci
->adapter
->Id
;
4627 if(plci
->tel
) Id
|=EXT_CONTROLLER
;
4629 switch(plci
->internal_command
)
4634 case START_L1_SIG_ASSIGN_PEND
:
4635 case REM_L1_SIG_ASSIGN_PEND
:
4636 if(global_req
== ASSIGN
)
4642 dbug(1,dprintf("***L1 Req rem PLCI"));
4643 plci
->internal_command
= 0;
4644 sig_req(plci
,REMOVE
,0);
4649 /* Call Deflection Request pending, just no appl ptr assigned */
4651 SSparms
[1] = S_CALL_DEFLECTION
;
4654 Info
= 0x300E; /* not supported */
4656 for(i
=0; i
<max_appl
; i
++)
4658 if(application
[i
].CDEnable
)
4660 if(!application
[i
].Id
) application
[i
].CDEnable
= 0;
4663 sendf(&application
[i
],_FACILITY_R
|CONFIRM
,Id
,
4664 plci
->number
,"wws",Info
,(word
)3,SSparms
);
4665 if(Info
) application
[i
].CDEnable
= 0;
4669 plci
->internal_command
= 0;
4672 case PERM_COD_HOOK
: /* finished with Hook_Ind */
4676 plci
->internal_command
= PERM_COD_CONN_PEND
;
4677 dbug(1,dprintf("***Codec Connect_Pending, Rc = 0x%x",rc
));
4680 case PERM_COD_ASSIGN
:
4681 dbug(1,dprintf("***Codec Assign, Rc = 0x%x",rc
));
4682 plci
->internal_command
= 0;
4683 if(rc
!=ASSIGN_OK
) break;
4684 plci
->internal_command
= PERM_COD_CALL
;
4685 sig_req(plci
,CALL_REQ
,0);
4689 case LISTEN_SIG_ASSIGN_PEND
:
4692 plci
->internal_command
= 0;
4693 dbug(1,dprintf("ListenCheck, new SIG_ID = 0x%x",plci
->Sig
.Id
));
4694 add_p(plci
,ESC
,"\x02\x18\x00"); /* support call waiting */
4695 sig_req(plci
,INDICATE_REQ
,0);
4700 dbug(1,dprintf("ListenCheck failed (assignRc=0x%x)",rc
));
4708 if(global_req
== ASSIGN
)
4712 sig_req(plci
,LAW_REQ
,0);
4714 dbug(1,dprintf("Auto-Law assigned"));
4718 dbug(1,dprintf("Auto-Law assign failed"));
4719 a
->automatic_law
= 3;
4720 plci
->internal_command
= 0;
4721 a
->automatic_lawPLCI
= NULL
;
4725 else if(req
== LAW_REQ
&& rc
==OK
)
4727 dbug(1,dprintf("Auto-Law initiated"));
4728 a
->automatic_law
= 2;
4729 plci
->internal_command
= 0;
4733 dbug(1,dprintf("Auto-Law not supported"));
4734 a
->automatic_law
= 3;
4735 plci
->internal_command
= 0;
4736 sig_req(plci
,REMOVE
,0);
4738 a
->automatic_lawPLCI
= NULL
;
4742 plci_remove_check(plci
);
4746 static void data_rc(PLCI
*plci
, byte ch
)
4749 DIVA_CAPI_ADAPTER
* a
;
4756 TransmitBufferFree (plci
->appl
, plci
->data_sent_ptr
);
4758 ncci
= a
->ch_ncci
[ch
];
4759 if (ncci
&& (a
->ncci_plci
[ncci
] == plci
->Id
))
4761 ncci_ptr
= &(a
->ncci
[ncci
]);
4762 dbug(1,dprintf("data_out=%d, data_pending=%d",ncci_ptr
->data_out
,ncci_ptr
->data_pending
));
4763 if (ncci_ptr
->data_pending
)
4765 data
= &(ncci_ptr
->DBuffer
[ncci_ptr
->data_out
]);
4766 if (!(data
->Flags
&4) && a
->ncci_state
[ncci
])
4768 Id
= (((dword
)ncci
)<<16)|((word
)plci
->Id
<<8)|a
->Id
;
4769 if(plci
->tel
) Id
|=EXT_CONTROLLER
;
4770 sendf(plci
->appl
,_DATA_B3_R
|CONFIRM
,Id
,data
->Number
,
4771 "ww",data
->Handle
,0);
4773 (ncci_ptr
->data_out
)++;
4774 if (ncci_ptr
->data_out
== MAX_DATA_B3
)
4775 ncci_ptr
->data_out
= 0;
4776 (ncci_ptr
->data_pending
)--;
4782 static void data_ack(PLCI
*plci
, byte ch
)
4785 DIVA_CAPI_ADAPTER
* a
;
4790 ncci
= a
->ch_ncci
[ch
];
4791 ncci_ptr
= &(a
->ncci
[ncci
]);
4792 if (ncci_ptr
->data_ack_pending
)
4794 if (a
->ncci_state
[ncci
] && (a
->ncci_plci
[ncci
] == plci
->Id
))
4796 Id
= (((dword
)ncci
)<<16)|((word
)plci
->Id
<<8)|a
->Id
;
4797 if(plci
->tel
) Id
|=EXT_CONTROLLER
;
4798 sendf(plci
->appl
,_DATA_B3_R
|CONFIRM
,Id
,ncci_ptr
->DataAck
[ncci_ptr
->data_ack_out
].Number
,
4799 "ww",ncci_ptr
->DataAck
[ncci_ptr
->data_ack_out
].Handle
,0);
4801 (ncci_ptr
->data_ack_out
)++;
4802 if (ncci_ptr
->data_ack_out
== MAX_DATA_ACK
)
4803 ncci_ptr
->data_ack_out
= 0;
4804 (ncci_ptr
->data_ack_pending
)--;
4808 static void sig_ind(PLCI
*plci
)
4818 DIVA_CAPI_ADAPTER
* a
;
4819 API_PARSE saved_parms
[MAX_MSG_PARMS
+1];
4820 #define MAXPARMSIDS 31
4821 byte
* parms
[MAXPARMSIDS
];
4823 byte
* multi_fac_parms
[MAX_MULTI_IE
];
4824 byte
* multi_pi_parms
[MAX_MULTI_IE
];
4825 byte
* multi_ssext_parms
[MAX_MULTI_IE
];
4826 byte
* multi_CiPN_parms
[MAX_MULTI_IE
];
4828 byte
* multi_vswitch_parms
[MAX_MULTI_IE
];
4835 byte
*esc_profile
= "";
4838 PLCI
* tplci
= NULL
;
4839 byte chi
[] = "\x02\x18\x01";
4840 byte voice_cai
[] = "\x06\x14\x00\x00\x00\x00\x08";
4841 byte resume_cau
[] = "\x05\x05\x00\x02\x00\x00";
4842 /* ESC_MSGTYPE must be the last but one message, a new IE has to be */
4843 /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */
4844 /* SMSG is situated at the end because its 0 (for compatibility reasons */
4845 /* (see Info_Mask Bit 4, first IE. then the message type) */
4847 {MAXPARMSIDS
, CPN
, 0xff, DSA
, OSA
, BC
, LLC
, HLC
, ESC_CAUSE
, DSP
, DT
, CHA
,
4848 UUI
, CONG_RR
, CONG_RNR
, ESC_CHI
, KEY
, CHI
, CAU
, ESC_LAW
,
4849 RDN
, RDX
, CONN_NR
, RIN
, NI
, CAI
, ESC_CR
,
4850 CST
, ESC_PROFILE
, 0xff, ESC_MSGTYPE
, SMSG
};
4851 /* 14 FTY repl by ESC_CHI */
4852 /* 18 PI repl by ESC_LAW */
4853 /* removed OAD changed to 0xff for future use, OAD is multiIE now */
4854 word multi_fac_id
[] = {1, FTY
};
4855 word multi_pi_id
[] = {1, PI
};
4856 word multi_CiPN_id
[] = {1, OAD
};
4857 word multi_ssext_id
[] = {1, ESC_SSEXT
};
4859 word multi_vswitch_id
[] = {1, ESC_VSWITCH
};
4863 byte SS_Ind
[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
4864 byte CF_Ind
[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
4865 byte Interr_Err_Ind
[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
4866 byte CONF_Ind
[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00";
4867 byte force_mt_info
= false;
4873 Id
= ((word
)plci
->Id
<<8)|a
->Id
;
4874 PUT_WORD(&SS_Ind
[4],0x0000);
4876 if (plci
->sig_remove_id
)
4878 plci
->Sig
.RNR
= 2; /* discard */
4879 dbug(1,dprintf("SIG discard while remove pending"));
4882 if(plci
->tel
&& plci
->SuppState
!=CALL_HELD
) Id
|=EXT_CONTROLLER
;
4883 dbug(1,dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d",
4884 Id
,plci
->Id
,plci
->tel
,plci
->State
,plci
->channels
,plci
->hangup_flow_ctrl_timer
));
4885 if(plci
->Sig
.Ind
==CALL_HOLD_ACK
&& plci
->channels
)
4890 if(plci
->Sig
.Ind
==HANGUP
&& plci
->channels
)
4893 plci
->hangup_flow_ctrl_timer
++;
4894 /* recover the network layer after timeout */
4895 if(plci
->hangup_flow_ctrl_timer
==100)
4897 dbug(1,dprintf("Exceptional disc"));
4899 plci
->hangup_flow_ctrl_timer
= 0;
4900 for (ncci
= 1; ncci
< MAX_NCCI
+1; ncci
++)
4902 if (a
->ncci_plci
[ncci
] == plci
->Id
)
4904 cleanup_ncci_data (plci
, ncci
);
4905 if(plci
->channels
)plci
->channels
--;
4907 sendf(plci
->appl
,_DISCONNECT_B3_I
, (((dword
) ncci
) << 16) | Id
,0,"ws",0,"");
4911 sendf(plci
->appl
, _DISCONNECT_I
, Id
, 0, "w", 0);
4918 /* do first parse the info with no OAD in, because OAD will be converted */
4919 /* first the multiple facility IE, then mult. progress ind. */
4920 /* then the parameters for the info_ind + conn_ind */
4921 IndParse(plci
,multi_fac_id
,multi_fac_parms
,MAX_MULTI_IE
);
4922 IndParse(plci
,multi_pi_id
,multi_pi_parms
,MAX_MULTI_IE
);
4923 IndParse(plci
,multi_ssext_id
,multi_ssext_parms
,MAX_MULTI_IE
);
4925 IndParse(plci
,multi_vswitch_id
,multi_vswitch_parms
,MAX_MULTI_IE
);
4927 IndParse(plci
,parms_id
,parms
,0);
4928 IndParse(plci
,multi_CiPN_id
,multi_CiPN_parms
,MAX_MULTI_IE
);
4929 esc_chi
= parms
[14];
4930 esc_law
= parms
[18];
4931 pty_cai
= parms
[24];
4933 esc_profile
= parms
[27];
4934 if(esc_cr
[0] && plci
)
4936 if(plci
->cr_enquiry
&& plci
->appl
)
4938 plci
->cr_enquiry
= false;
4941 /* b = total length */
4942 /* b = indication type */
4943 /* b = length of all IEs */
4945 /* S = IE1 length + cont. */
4947 /* S = IE2 length + cont. */
4952 "dwbbbbSbS",_DI_MANU_ID
,plci
->m_command
,
4953 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
);
4956 /* create the additional info structure */
4957 add_i
[1] = parms
[15]; /* KEY of additional info */
4958 add_i
[2] = parms
[11]; /* UUI of additional info */
4959 ai_len
= AddInfo(add_i
,multi_fac_parms
, esc_chi
, facility
);
4961 /* the ESC_LAW indicates if u-Law or a-Law is actually used by the card */
4962 /* indication returns by the card if requested by the function */
4963 /* AutomaticLaw() after driver init */
4964 if (a
->automatic_law
<4)
4968 dbug(0,dprintf("u-Law selected"));
4972 dbug(0,dprintf("a-Law selected"));
4975 a
->automatic_law
= 4;
4976 if(plci
==a
->automatic_lawPLCI
) {
4977 plci
->internal_command
= 0;
4978 sig_req(plci
,REMOVE
,0);
4980 a
->automatic_lawPLCI
= NULL
;
4985 dbug (1, dprintf ("[%06x] CardProfile: %lx %lx %lx %lx %lx",
4986 UnMapController (a
->Id
), GET_DWORD (&esc_profile
[6]),
4987 GET_DWORD (&esc_profile
[10]), GET_DWORD (&esc_profile
[14]),
4988 GET_DWORD (&esc_profile
[18]), GET_DWORD (&esc_profile
[46])));
4990 a
->profile
.Global_Options
&= 0x000000ffL
;
4991 a
->profile
.B1_Protocols
&= 0x000003ffL
;
4992 a
->profile
.B2_Protocols
&= 0x00001fdfL
;
4993 a
->profile
.B3_Protocols
&= 0x000000b7L
;
4995 a
->profile
.Global_Options
&= GET_DWORD (&esc_profile
[6]) |
4996 GL_BCHANNEL_OPERATION_SUPPORTED
;
4997 a
->profile
.B1_Protocols
&= GET_DWORD (&esc_profile
[10]);
4998 a
->profile
.B2_Protocols
&= GET_DWORD (&esc_profile
[14]);
4999 a
->profile
.B3_Protocols
&= GET_DWORD (&esc_profile
[18]);
5000 a
->manufacturer_features
= GET_DWORD (&esc_profile
[46]);
5001 a
->man_profile
.private_options
= 0;
5003 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_ECHO_CANCELLER
)
5005 a
->man_profile
.private_options
|= 1L << PRIVATE_ECHO_CANCELLER
;
5006 a
->profile
.Global_Options
|= GL_ECHO_CANCELLER_SUPPORTED
;
5010 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_RTP
)
5011 a
->man_profile
.private_options
|= 1L << PRIVATE_RTP
;
5012 a
->man_profile
.rtp_primary_payloads
= GET_DWORD (&esc_profile
[50]);
5013 a
->man_profile
.rtp_additional_payloads
= GET_DWORD (&esc_profile
[54]);
5016 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_T38
)
5017 a
->man_profile
.private_options
|= 1L << PRIVATE_T38
;
5020 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD
)
5021 a
->man_profile
.private_options
|= 1L << PRIVATE_FAX_SUB_SEP_PWD
;
5024 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_V18
)
5025 a
->man_profile
.private_options
|= 1L << PRIVATE_V18
;
5028 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_DTMF_TONE
)
5029 a
->man_profile
.private_options
|= 1L << PRIVATE_DTMF_TONE
;
5032 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_PIAFS
)
5033 a
->man_profile
.private_options
|= 1L << PRIVATE_PIAFS
;
5036 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
5037 a
->man_profile
.private_options
|= 1L << PRIVATE_FAX_PAPER_FORMATS
;
5040 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_VOWN
)
5041 a
->man_profile
.private_options
|= 1L << PRIVATE_VOWN
;
5044 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_NONSTANDARD
)
5045 a
->man_profile
.private_options
|= 1L << PRIVATE_FAX_NONSTANDARD
;
5050 a
->profile
.Global_Options
&= 0x0000007fL
;
5051 a
->profile
.B1_Protocols
&= 0x000003dfL
;
5052 a
->profile
.B2_Protocols
&= 0x00001adfL
;
5053 a
->profile
.B3_Protocols
&= 0x000000b7L
;
5054 a
->manufacturer_features
&= MANUFACTURER_FEATURE_HARDDTMF
;
5056 if (a
->manufacturer_features
& (MANUFACTURER_FEATURE_HARDDTMF
|
5057 MANUFACTURER_FEATURE_SOFTDTMF_SEND
| MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
))
5059 a
->profile
.Global_Options
|= GL_DTMF_SUPPORTED
;
5061 a
->manufacturer_features
&= ~MANUFACTURER_FEATURE_OOB_CHANNEL
;
5062 dbug (1, dprintf ("[%06x] Profile: %lx %lx %lx %lx %lx",
5063 UnMapController (a
->Id
), a
->profile
.Global_Options
,
5064 a
->profile
.B1_Protocols
, a
->profile
.B2_Protocols
,
5065 a
->profile
.B3_Protocols
, a
->manufacturer_features
));
5067 /* codec plci for the handset/hook state support is just an internal id */
5068 if(plci
!=a
->AdvCodecPLCI
)
5070 force_mt_info
= SendMultiIE(plci
,Id
,multi_fac_parms
, FTY
, 0x20, 0);
5071 force_mt_info
|= SendMultiIE(plci
,Id
,multi_pi_parms
, PI
, 0x210, 0);
5072 SendSSExtInd(NULL
,plci
,Id
,multi_ssext_parms
);
5073 SendInfo(plci
,Id
, parms
, force_mt_info
);
5075 VSwitchReqInd(plci
,Id
,multi_vswitch_parms
);
5079 /* switch the codec to the b-channel */
5080 if(esc_chi
[0] && plci
&& !plci
->SuppState
){
5081 plci
->b_channel
= esc_chi
[esc_chi
[0]]&0x1f;
5082 mixer_set_bchannel_id_esc (plci
, plci
->b_channel
);
5083 dbug(1,dprintf("storeChannel=0x%x",plci
->b_channel
));
5084 if(plci
->tel
==ADV_VOICE
&& plci
->appl
) {
5085 SetVoiceChannel(a
->AdvCodecPLCI
, esc_chi
, a
);
5089 if(plci
->appl
) Number
= plci
->appl
->Number
++;
5091 switch(plci
->Sig
.Ind
) {
5092 /* Response to Get_Supported_Services request */
5094 dbug(1,dprintf("S_Supported"));
5095 if(!plci
->appl
) break;
5098 PUT_DWORD(&CF_Ind
[6],GET_DWORD(&pty_cai
[1]) );
5102 PUT_DWORD(&CF_Ind
[6],MASK_TERMINAL_PORTABILITY
| MASK_HOLD_RETRIEVE
);
5104 PUT_WORD (&CF_Ind
[1], 0);
5105 PUT_WORD (&CF_Ind
[4], 0);
5106 sendf(plci
->appl
,_FACILITY_R
|CONFIRM
,Id
&0x7,plci
->number
, "wws",0,3,CF_Ind
);
5110 /* Supplementary Service rejected */
5112 dbug(1,dprintf("S_Reject=0x%x",pty_cai
[5]));
5113 if(!pty_cai
[0]) break;
5118 case THREE_PTY_BEGIN
:
5119 if(!plci
->relatedPTYPLCI
) break;
5120 tplci
= plci
->relatedPTYPLCI
;
5121 rId
= ( (word
)tplci
->Id
<<8)|tplci
->adapter
->Id
;
5122 if(tplci
->tel
) rId
|=EXT_CONTROLLER
;
5123 if(pty_cai
[5]==ECT_EXECUTE
)
5125 PUT_WORD(&SS_Ind
[1],S_ECT
);
5127 plci
->vswitchstate
=0;
5128 plci
->relatedPTYPLCI
->vswitchstate
=0;
5133 PUT_WORD(&SS_Ind
[1],pty_cai
[5]+3);
5135 if(pty_cai
[2]!=0xff)
5137 PUT_WORD(&SS_Ind
[4],0x3600|(word
)pty_cai
[2]);
5141 PUT_WORD(&SS_Ind
[4],0x300E);
5143 plci
->relatedPTYPLCI
= NULL
;
5145 sendf(tplci
->appl
,_FACILITY_I
,rId
,0,"ws",3, SS_Ind
);
5148 case CALL_DEFLECTION
:
5149 if(pty_cai
[2]!=0xff)
5151 PUT_WORD(&SS_Ind
[4],0x3600|(word
)pty_cai
[2]);
5155 PUT_WORD(&SS_Ind
[4],0x300E);
5157 PUT_WORD(&SS_Ind
[1],pty_cai
[5]);
5158 for(i
=0; i
<max_appl
; i
++)
5160 if(application
[i
].CDEnable
)
5162 if(application
[i
].Id
) sendf(&application
[i
],_FACILITY_I
,Id
,0,"ws",3, SS_Ind
);
5163 application
[i
].CDEnable
= false;
5168 case DEACTIVATION_DIVERSION
:
5169 case ACTIVATION_DIVERSION
:
5170 case DIVERSION_INTERROGATE_CFU
:
5171 case DIVERSION_INTERROGATE_CFB
:
5172 case DIVERSION_INTERROGATE_CFNR
:
5173 case DIVERSION_INTERROGATE_NUM
:
5175 case CCBS_DEACTIVATE
:
5176 case CCBS_INTERROGATE
:
5177 if(!plci
->appl
) break;
5178 if(pty_cai
[2]!=0xff)
5180 PUT_WORD(&Interr_Err_Ind
[4],0x3600|(word
)pty_cai
[2]);
5184 PUT_WORD(&Interr_Err_Ind
[4],0x300E);
5188 case DEACTIVATION_DIVERSION
:
5189 dbug(1,dprintf("Deact_Div"));
5190 Interr_Err_Ind
[0]=0x9;
5191 Interr_Err_Ind
[3]=0x6;
5192 PUT_WORD(&Interr_Err_Ind
[1],S_CALL_FORWARDING_STOP
);
5194 case ACTIVATION_DIVERSION
:
5195 dbug(1,dprintf("Act_Div"));
5196 Interr_Err_Ind
[0]=0x9;
5197 Interr_Err_Ind
[3]=0x6;
5198 PUT_WORD(&Interr_Err_Ind
[1],S_CALL_FORWARDING_START
);
5200 case DIVERSION_INTERROGATE_CFU
:
5201 case DIVERSION_INTERROGATE_CFB
:
5202 case DIVERSION_INTERROGATE_CFNR
:
5203 dbug(1,dprintf("Interr_Div"));
5204 Interr_Err_Ind
[0]=0xa;
5205 Interr_Err_Ind
[3]=0x7;
5206 PUT_WORD(&Interr_Err_Ind
[1],S_INTERROGATE_DIVERSION
);
5208 case DIVERSION_INTERROGATE_NUM
:
5209 dbug(1,dprintf("Interr_Num"));
5210 Interr_Err_Ind
[0]=0xa;
5211 Interr_Err_Ind
[3]=0x7;
5212 PUT_WORD(&Interr_Err_Ind
[1],S_INTERROGATE_NUMBERS
);
5215 dbug(1,dprintf("CCBS Request"));
5216 Interr_Err_Ind
[0]=0xd;
5217 Interr_Err_Ind
[3]=0xa;
5218 PUT_WORD(&Interr_Err_Ind
[1],S_CCBS_REQUEST
);
5220 case CCBS_DEACTIVATE
:
5221 dbug(1,dprintf("CCBS Deactivate"));
5222 Interr_Err_Ind
[0]=0x9;
5223 Interr_Err_Ind
[3]=0x6;
5224 PUT_WORD(&Interr_Err_Ind
[1],S_CCBS_DEACTIVATE
);
5226 case CCBS_INTERROGATE
:
5227 dbug(1,dprintf("CCBS Interrogate"));
5228 Interr_Err_Ind
[0]=0xb;
5229 Interr_Err_Ind
[3]=0x8;
5230 PUT_WORD(&Interr_Err_Ind
[1],S_CCBS_INTERROGATE
);
5233 PUT_DWORD(&Interr_Err_Ind
[6],plci
->appl
->S_Handle
);
5234 sendf(plci
->appl
,_FACILITY_I
,Id
&0x7,0,"ws",3, Interr_Err_Ind
);
5237 case ACTIVATION_MWI
:
5238 case DEACTIVATION_MWI
:
5239 if(pty_cai
[5]==ACTIVATION_MWI
)
5241 PUT_WORD(&SS_Ind
[1],S_MWI_ACTIVATE
);
5243 else PUT_WORD(&SS_Ind
[1],S_MWI_DEACTIVATE
);
5245 if(pty_cai
[2]!=0xff)
5247 PUT_WORD(&SS_Ind
[4],0x3600|(word
)pty_cai
[2]);
5251 PUT_WORD(&SS_Ind
[4],0x300E);
5254 if(plci
->cr_enquiry
)
5256 sendf(plci
->appl
,_FACILITY_I
,Id
&0xf,0,"ws",3, SS_Ind
);
5261 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws",3, SS_Ind
);
5264 case CONF_ADD
: /* ERROR */
5274 PUT_WORD(&CONF_Ind
[1],S_CONF_BEGIN
);
5280 PUT_WORD(&CONF_Ind
[1],S_CONF_DROP
);
5281 plci
->ptyState
= CONNECTED
;
5286 PUT_WORD(&CONF_Ind
[1],S_CONF_ISOLATE
);
5287 plci
->ptyState
= CONNECTED
;
5292 PUT_WORD(&CONF_Ind
[1],S_CONF_REATTACH
);
5293 plci
->ptyState
= CONNECTED
;
5296 PUT_WORD(&CONF_Ind
[1],S_CONF_ADD
);
5297 plci
->relatedPTYPLCI
= NULL
;
5298 tplci
=plci
->relatedPTYPLCI
;
5299 if(tplci
) tplci
->ptyState
= CONNECTED
;
5300 plci
->ptyState
= CONNECTED
;
5304 if(pty_cai
[2]!=0xff)
5306 PUT_WORD(&CONF_Ind
[4],0x3600|(word
)pty_cai
[2]);
5310 PUT_WORD(&CONF_Ind
[4],0x3303); /* Time-out: network did not respond
5311 within the required time */
5314 PUT_DWORD(&CONF_Ind
[6],0x0);
5315 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws",3, CONF_Ind
);
5320 /* Supplementary Service indicates success */
5322 dbug(1,dprintf("Service_Ind"));
5323 PUT_WORD (&CF_Ind
[4], 0);
5327 case THREE_PTY_BEGIN
:
5329 if(!plci
->relatedPTYPLCI
) break;
5330 tplci
= plci
->relatedPTYPLCI
;
5331 rId
= ( (word
)tplci
->Id
<<8)|tplci
->adapter
->Id
;
5332 if(tplci
->tel
) rId
|=EXT_CONTROLLER
;
5333 if(pty_cai
[5]==ECT_EXECUTE
)
5335 PUT_WORD(&SS_Ind
[1],S_ECT
);
5337 if(plci
->vswitchstate
!=3)
5340 plci
->ptyState
= IDLE
;
5341 plci
->relatedPTYPLCI
= NULL
;
5346 dbug(1,dprintf("ECT OK"));
5347 sendf(tplci
->appl
,_FACILITY_I
,rId
,0,"ws",3, SS_Ind
);
5354 switch (plci
->ptyState
)
5357 plci
->ptyState
= CONNECTED
;
5358 dbug(1,dprintf("3PTY ON"));
5362 plci
->ptyState
= IDLE
;
5363 plci
->relatedPTYPLCI
= NULL
;
5365 dbug(1,dprintf("3PTY OFF"));
5368 PUT_WORD(&SS_Ind
[1],pty_cai
[5]+3);
5369 sendf(tplci
->appl
,_FACILITY_I
,rId
,0,"ws",3, SS_Ind
);
5373 case CALL_DEFLECTION
:
5374 PUT_WORD(&SS_Ind
[1],pty_cai
[5]);
5375 for(i
=0; i
<max_appl
; i
++)
5377 if(application
[i
].CDEnable
)
5379 if(application
[i
].Id
) sendf(&application
[i
],_FACILITY_I
,Id
,0,"ws",3, SS_Ind
);
5380 application
[i
].CDEnable
= false;
5385 case DEACTIVATION_DIVERSION
:
5386 case ACTIVATION_DIVERSION
:
5387 if(!plci
->appl
) break;
5388 PUT_WORD(&CF_Ind
[1],pty_cai
[5]+2);
5389 PUT_DWORD(&CF_Ind
[6],plci
->appl
->S_Handle
);
5390 sendf(plci
->appl
,_FACILITY_I
,Id
&0x7,0,"ws",3, CF_Ind
);
5394 case DIVERSION_INTERROGATE_CFU
:
5395 case DIVERSION_INTERROGATE_CFB
:
5396 case DIVERSION_INTERROGATE_CFNR
:
5397 case DIVERSION_INTERROGATE_NUM
:
5399 case CCBS_DEACTIVATE
:
5400 case CCBS_INTERROGATE
:
5401 if(!plci
->appl
) break;
5404 case DIVERSION_INTERROGATE_CFU
:
5405 case DIVERSION_INTERROGATE_CFB
:
5406 case DIVERSION_INTERROGATE_CFNR
:
5407 dbug(1,dprintf("Interr_Div"));
5408 PUT_WORD(&pty_cai
[1],S_INTERROGATE_DIVERSION
);
5409 pty_cai
[3]=pty_cai
[0]-3; /* Supplementary Service-specific parameter len */
5411 case DIVERSION_INTERROGATE_NUM
:
5412 dbug(1,dprintf("Interr_Num"));
5413 PUT_WORD(&pty_cai
[1],S_INTERROGATE_NUMBERS
);
5414 pty_cai
[3]=pty_cai
[0]-3; /* Supplementary Service-specific parameter len */
5417 dbug(1,dprintf("CCBS Request"));
5418 PUT_WORD(&pty_cai
[1],S_CCBS_REQUEST
);
5419 pty_cai
[3]=pty_cai
[0]-3; /* Supplementary Service-specific parameter len */
5421 case CCBS_DEACTIVATE
:
5422 dbug(1,dprintf("CCBS Deactivate"));
5423 PUT_WORD(&pty_cai
[1],S_CCBS_DEACTIVATE
);
5424 pty_cai
[3]=pty_cai
[0]-3; /* Supplementary Service-specific parameter len */
5426 case CCBS_INTERROGATE
:
5427 dbug(1,dprintf("CCBS Interrogate"));
5428 PUT_WORD(&pty_cai
[1],S_CCBS_INTERROGATE
);
5429 pty_cai
[3]=pty_cai
[0]-3; /* Supplementary Service-specific parameter len */
5432 PUT_WORD(&pty_cai
[4],0); /* Supplementary Service Reason */
5433 PUT_DWORD(&pty_cai
[6],plci
->appl
->S_Handle
);
5434 sendf(plci
->appl
,_FACILITY_I
,Id
&0x7,0,"wS",3, pty_cai
);
5438 case ACTIVATION_MWI
:
5439 case DEACTIVATION_MWI
:
5440 if(pty_cai
[5]==ACTIVATION_MWI
)
5442 PUT_WORD(&SS_Ind
[1],S_MWI_ACTIVATE
);
5444 else PUT_WORD(&SS_Ind
[1],S_MWI_DEACTIVATE
);
5445 if(plci
->cr_enquiry
)
5447 sendf(plci
->appl
,_FACILITY_I
,Id
&0xf,0,"ws",3, SS_Ind
);
5452 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws",3, SS_Ind
);
5455 case MWI_INDICATION
:
5456 if(pty_cai
[0]>=0x12)
5458 PUT_WORD(&pty_cai
[3],S_MWI_INDICATE
);
5459 pty_cai
[2]=pty_cai
[0]-2; /* len Parameter */
5460 pty_cai
[5]=pty_cai
[0]-5; /* Supplementary Service-specific parameter len */
5461 if(plci
->appl
&& (a
->Notification_Mask
[plci
->appl
->Id
-1]&SMASK_MWI
))
5463 if(plci
->internal_command
==GET_MWI_STATE
) /* result on Message Waiting Listen */
5465 sendf(plci
->appl
,_FACILITY_I
,Id
&0xf,0,"wS",3, &pty_cai
[2]);
5469 else sendf(plci
->appl
,_FACILITY_I
,Id
,0,"wS",3, &pty_cai
[2]);
5474 for(i
=0; i
<max_appl
; i
++)
5476 if(a
->Notification_Mask
[i
]&SMASK_MWI
)
5478 sendf(&application
[i
],_FACILITY_I
,Id
&0x7,0,"wS",3, &pty_cai
[2]);
5486 facility
[2]= 0; /* returncode */
5488 else facility
[2]= 0xff;
5493 facility
[2]= 0xff; /* returncode */
5496 facility
[1]= MWI_RESPONSE
; /* Function */
5497 add_p(plci
,CAI
,facility
);
5498 add_p(plci
,ESC
,multi_ssext_parms
[0]); /* remembered parameter -> only one possible */
5499 sig_req(plci
,S_SERVICE
,0);
5502 next_internal_command (Id
, plci
);
5504 case CONF_ADD
: /* OK */
5509 case CONF_PARTYDISC
:
5515 PUT_WORD(&CONF_Ind
[1],S_CONF_BEGIN
);
5519 PUT_DWORD(&CONF_Ind
[6],d
); /* PartyID */
5523 PUT_DWORD(&CONF_Ind
[6],0x0);
5527 PUT_WORD(&CONF_Ind
[1],S_CONF_ISOLATE
);
5532 PUT_WORD(&CONF_Ind
[1],S_CONF_REATTACH
);
5537 PUT_WORD(&CONF_Ind
[1],S_CONF_DROP
);
5542 PUT_WORD(&CONF_Ind
[1],S_CONF_ADD
);
5544 PUT_DWORD(&CONF_Ind
[6],d
); /* PartyID */
5545 tplci
=plci
->relatedPTYPLCI
;
5546 if(tplci
) tplci
->ptyState
= CONNECTED
;
5548 case CONF_PARTYDISC
:
5551 PUT_WORD(&CONF_Ind
[1],S_CONF_PARTYDISC
);
5553 PUT_DWORD(&CONF_Ind
[4],d
); /* PartyID */
5556 plci
->ptyState
= CONNECTED
;
5557 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws",3, CONF_Ind
);
5559 case CCBS_INFO_RETAIN
:
5560 case CCBS_ERASECALLLINKAGEID
:
5561 case CCBS_STOP_ALERTING
:
5566 case CCBS_INFO_RETAIN
:
5567 PUT_WORD(&CONF_Ind
[1],S_CCBS_INFO_RETAIN
);
5569 case CCBS_STOP_ALERTING
:
5570 PUT_WORD(&CONF_Ind
[1],S_CCBS_STOP_ALERTING
);
5572 case CCBS_ERASECALLLINKAGEID
:
5573 PUT_WORD(&CONF_Ind
[1],S_CCBS_ERASECALLLINKAGEID
);
5581 PUT_WORD(&CONF_Ind
[4],w
); /* PartyID */
5583 if(plci
->appl
&& (a
->Notification_Mask
[plci
->appl
->Id
-1]&SMASK_CCBS
))
5585 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws",3, CONF_Ind
);
5589 for(i
=0; i
<max_appl
; i
++)
5590 if(a
->Notification_Mask
[i
]&SMASK_CCBS
)
5591 sendf(&application
[i
],_FACILITY_I
,Id
&0x7,0,"ws",3, CONF_Ind
);
5600 i
= _L3_CAUSE
| cau
[2];
5601 if(cau
[2]==0) i
= 0x3603;
5607 PUT_WORD(&SS_Ind
[1],S_HOLD
);
5608 PUT_WORD(&SS_Ind
[4],i
);
5609 if(plci
->SuppState
== HOLD_REQUEST
)
5611 plci
->SuppState
= IDLE
;
5612 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws",3, SS_Ind
);
5617 if(plci
->SuppState
== HOLD_REQUEST
)
5619 plci
->SuppState
= CALL_HELD
;
5620 CodecIdCheck(a
, plci
);
5621 start_internal_command (Id
, plci
, hold_save_command
);
5625 case CALL_RETRIEVE_REJ
:
5629 i
= _L3_CAUSE
| cau
[2];
5630 if(cau
[2]==0) i
= 0x3603;
5636 PUT_WORD(&SS_Ind
[1],S_RETRIEVE
);
5637 PUT_WORD(&SS_Ind
[4],i
);
5638 if(plci
->SuppState
== RETRIEVE_REQUEST
)
5640 plci
->SuppState
= CALL_HELD
;
5641 CodecIdCheck(a
, plci
);
5642 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws",3, SS_Ind
);
5646 case CALL_RETRIEVE_ACK
:
5647 PUT_WORD(&SS_Ind
[1],S_RETRIEVE
);
5648 if(plci
->SuppState
== RETRIEVE_REQUEST
)
5650 plci
->SuppState
= IDLE
;
5651 plci
->call_dir
|= CALL_DIR_FORCE_OUTG_NL
;
5652 plci
->b_channel
= esc_chi
[esc_chi
[0]]&0x1f;
5655 mixer_set_bchannel_id_esc (plci
, plci
->b_channel
);
5656 dbug(1,dprintf("RetrChannel=0x%x",plci
->b_channel
));
5657 SetVoiceChannel(a
->AdvCodecPLCI
, esc_chi
, a
);
5658 if(plci
->B2_prot
==B2_TRANSPARENT
&& plci
->B3_prot
==B3_TRANSPARENT
)
5660 dbug(1,dprintf("Get B-ch"));
5661 start_internal_command (Id
, plci
, retrieve_restore_command
);
5664 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws",3, SS_Ind
);
5667 start_internal_command (Id
, plci
, retrieve_restore_command
);
5672 if(plci
->State
!= LISTENING
) {
5673 sig_req(plci
,HANGUP
,0);
5677 cip
= find_cip(a
,parms
[4],parms
[6]);
5679 dbug(1,dprintf("cip=%d,cip_mask=%lx",cip
,cip_mask
));
5680 clear_c_ind_mask (plci
);
5681 if (!remove_started
&& !a
->adapter_disabled
)
5683 set_c_ind_mask_bit (plci
, MAX_APPL
);
5684 group_optimization(a
, plci
);
5685 for(i
=0; i
<max_appl
; i
++) {
5686 if(application
[i
].Id
5687 && (a
->CIP_Mask
[i
]&1 || a
->CIP_Mask
[i
]&cip_mask
)
5688 && CPN_filter_ok(parms
[0],a
,i
)
5689 && test_group_ind_mask_bit (plci
, i
) ) {
5690 dbug(1,dprintf("storedcip_mask[%d]=0x%lx",i
,a
->CIP_Mask
[i
] ));
5691 set_c_ind_mask_bit (plci
, i
);
5692 dump_c_ind_mask (plci
);
5693 plci
->State
= INC_CON_PENDING
;
5694 plci
->call_dir
= (plci
->call_dir
& ~(CALL_DIR_OUT
| CALL_DIR_ORIGINATE
)) |
5695 CALL_DIR_IN
| CALL_DIR_ANSWER
;
5697 plci
->b_channel
= esc_chi
[esc_chi
[0]]&0x1f;
5698 mixer_set_bchannel_id_esc (plci
, plci
->b_channel
);
5700 /* if a listen on the ext controller is done, check if hook states */
5701 /* are supported or if just a on board codec must be activated */
5702 if(a
->codec_listen
[i
] && !a
->AdvSignalPLCI
) {
5703 if(a
->profile
.Global_Options
& HANDSET
)
5704 plci
->tel
= ADV_VOICE
;
5705 else if(a
->profile
.Global_Options
& ON_BOARD_CODEC
)
5707 if(plci
->tel
) Id
|=EXT_CONTROLLER
;
5708 a
->codec_listen
[i
] = plci
;
5711 sendf(&application
[i
],_CONNECT_I
,Id
,0,
5712 "wSSSSSSSbSSSSS", cip
, /* CIP */
5713 parms
[0], /* CalledPartyNumber */
5714 multi_CiPN_parms
[0], /* CallingPartyNumber */
5715 parms
[2], /* CalledPartySubad */
5716 parms
[3], /* CallingPartySubad */
5717 parms
[4], /* BearerCapability */
5718 parms
[5], /* LowLC */
5719 parms
[6], /* HighLC */
5720 ai_len
, /* nested struct add_i */
5721 add_i
[0], /* B channel info */
5722 add_i
[1], /* keypad facility */
5723 add_i
[2], /* user user data */
5724 add_i
[3], /* nested facility */
5725 multi_CiPN_parms
[1] /* second CiPN(SCR) */
5727 SendSSExtInd(&application
[i
],
5731 SendSetupInfo(&application
[i
],
5735 SendMultiIE(plci
,Id
,multi_pi_parms
, PI
, 0x210, true));
5738 clear_c_ind_mask_bit (plci
, MAX_APPL
);
5739 dump_c_ind_mask (plci
);
5741 if(c_ind_mask_empty (plci
)) {
5742 sig_req(plci
,HANGUP
,0);
5746 plci
->notifiedcall
= 0;
5751 case CALL_PEND_NOTIFY
:
5752 plci
->notifiedcall
= 1;
5758 if(plci
->State
==ADVANCED_VOICE_SIG
|| plci
->State
==ADVANCED_VOICE_NOSIG
)
5760 if(plci
->internal_command
==PERM_COD_CONN_PEND
)
5762 if(plci
->State
==ADVANCED_VOICE_NOSIG
)
5764 dbug(1,dprintf("***Codec OK"));
5765 if(a
->AdvSignalPLCI
)
5767 tplci
= a
->AdvSignalPLCI
;
5768 if(tplci
->spoofed_msg
)
5770 dbug(1,dprintf("***Spoofed Msg(0x%x)",tplci
->spoofed_msg
));
5772 tplci
->internal_command
= 0;
5773 x_Id
= ((word
)tplci
->Id
<<8)|tplci
->adapter
->Id
| 0x80;
5774 switch (tplci
->spoofed_msg
)
5777 tplci
->command
= _CONNECT_I
|RESPONSE
;
5778 api_load_msg (&tplci
->saved_msg
, saved_parms
);
5779 add_b1(tplci
,&saved_parms
[1],0,tplci
->B1_facilities
);
5780 if (tplci
->adapter
->Info_Mask
[tplci
->appl
->Id
-1] & 0x200)
5782 /* early B3 connect (CIP mask bit 9) no release after a disc */
5783 add_p(tplci
,LLI
,"\x01\x01");
5785 add_s(tplci
, CONN_NR
, &saved_parms
[2]);
5786 add_s(tplci
, LLC
, &saved_parms
[4]);
5787 add_ai(tplci
, &saved_parms
[5]);
5788 tplci
->State
= INC_CON_ACCEPT
;
5789 sig_req(tplci
, CALL_RES
,0);
5793 case AWAITING_SELECT_B
:
5794 dbug(1,dprintf("Select_B continue"));
5795 start_internal_command (x_Id
, tplci
, select_b_command
);
5798 case AWAITING_MANUF_CON
: /* Get_Plci per Manufacturer_Req to ext controller */
5801 dbug(1,dprintf("No SigID!"));
5802 sendf(tplci
->appl
, _MANUFACTURER_R
|CONFIRM
,x_Id
,tplci
->number
, "dww",_DI_MANU_ID
,_MANUFACTURER_R
,_OUT_OF_PLCI
);
5806 tplci
->command
= _MANUFACTURER_R
;
5807 api_load_msg (&tplci
->saved_msg
, saved_parms
);
5808 dir
= saved_parms
[2].info
[0];
5810 sig_req(tplci
,CALL_REQ
,0);
5813 sig_req(tplci
,LISTEN_REQ
,0);
5816 sendf(tplci
->appl
, _MANUFACTURER_R
|CONFIRM
,x_Id
,tplci
->number
, "dww",_DI_MANU_ID
,_MANUFACTURER_R
,0);
5819 case (CALL_REQ
|AWAITING_MANUF_CON
):
5820 sig_req(tplci
,CALL_REQ
,0);
5827 dbug(1,dprintf("No SigID!"));
5828 sendf(tplci
->appl
,_CONNECT_R
|CONFIRM
,tplci
->adapter
->Id
,0,"w",_OUT_OF_PLCI
);
5832 tplci
->command
= _CONNECT_R
;
5833 api_load_msg (&tplci
->saved_msg
, saved_parms
);
5834 add_s(tplci
,CPN
,&saved_parms
[1]);
5835 add_s(tplci
,DSA
,&saved_parms
[3]);
5836 add_ai(tplci
,&saved_parms
[9]);
5837 sig_req(tplci
,CALL_REQ
,0);
5842 tplci
->command
= C_RETRIEVE_REQ
;
5843 sig_req(tplci
,CALL_RETRIEVE
,0);
5847 tplci
->spoofed_msg
= 0;
5848 if (tplci
->internal_command
== 0)
5849 next_internal_command (x_Id
, tplci
);
5852 next_internal_command (Id
, plci
);
5855 dbug(1,dprintf("***Codec Hook Init Req"));
5856 plci
->internal_command
= PERM_COD_HOOK
;
5857 add_p(plci
,FTY
,"\x01\x09"); /* Get Hook State*/
5858 sig_req(plci
,TEL_CTRL
,0);
5862 else if(plci
->command
!= _MANUFACTURER_R
/* old style permanent connect */
5863 && plci
->State
!=INC_ACT_PENDING
)
5865 mixer_set_bchannel_id_esc (plci
, plci
->b_channel
);
5866 if(plci
->tel
== ADV_VOICE
&& plci
->SuppState
== IDLE
) /* with permanent codec switch on immediately */
5868 chi
[2] = plci
->b_channel
;
5869 SetVoiceChannel(a
->AdvCodecPLCI
, chi
, a
);
5871 sendf(plci
->appl
,_CONNECT_ACTIVE_I
,Id
,0,"Sss",parms
[21],"","");
5872 plci
->State
= INC_ACT_PENDING
;
5878 ie
= multi_fac_parms
[0]; /* inspect the facility hook indications */
5879 if(plci
->State
==ADVANCED_VOICE_SIG
&& ie
[0]){
5880 switch (ie
[1]&0x91) {
5881 case 0x80: /* hook off */
5883 if(plci
->internal_command
==PERM_COD_HOOK
)
5885 dbug(1,dprintf("init:hook_off"));
5886 plci
->hook_state
= ie
[1];
5887 next_internal_command (Id
, plci
);
5890 else /* ignore doubled hook indications */
5892 if( ((plci
->hook_state
)&0xf0)==0x80)
5894 dbug(1,dprintf("ignore hook"));
5897 plci
->hook_state
= ie
[1]&0x91;
5899 /* check for incoming call pending */
5900 /* and signal '+'.Appl must decide */
5901 /* with connect_res if call must */
5902 /* accepted or not */
5903 for(i
=0, tplci
=NULL
;i
<max_appl
;i
++){
5904 if(a
->codec_listen
[i
]
5905 && (a
->codec_listen
[i
]->State
==INC_CON_PENDING
5906 ||a
->codec_listen
[i
]->State
==INC_CON_ALERT
) ){
5907 tplci
= a
->codec_listen
[i
];
5908 tplci
->appl
= &application
[i
];
5911 /* no incoming call, do outgoing call */
5912 /* and signal '+' if outg. setup */
5913 if(!a
->AdvSignalPLCI
&& !tplci
){
5914 if((i
=get_plci(a
))) {
5915 a
->AdvSignalPLCI
= &a
->plci
[i
-1];
5916 tplci
= a
->AdvSignalPLCI
;
5917 tplci
->tel
= ADV_VOICE
;
5918 PUT_WORD(&voice_cai
[5],a
->AdvSignalAppl
->MaxDataLength
);
5919 if (a
->Info_Mask
[a
->AdvSignalAppl
->Id
-1] & 0x200){
5920 /* early B3 connect (CIP mask bit 9) no release after a disc */
5921 add_p(tplci
,LLI
,"\x01\x01");
5923 add_p(tplci
, CAI
, voice_cai
);
5924 add_p(tplci
, OAD
, a
->TelOAD
);
5925 add_p(tplci
, OSA
, a
->TelOSA
);
5926 add_p(tplci
,SHIFT
|6,NULL
);
5927 add_p(tplci
,SIN
,"\x02\x01\x00");
5928 add_p(tplci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
5929 sig_req(tplci
,ASSIGN
,DSIG_ID
);
5930 a
->AdvSignalPLCI
->internal_command
= HOOK_OFF_REQ
;
5931 a
->AdvSignalPLCI
->command
= 0;
5932 tplci
->appl
= a
->AdvSignalAppl
;
5933 tplci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
5940 Id
= ((word
)tplci
->Id
<<8)|a
->Id
;
5946 "ws", (word
)0, "\x01+");
5949 case 0x90: /* hook on */
5951 if(plci
->internal_command
==PERM_COD_HOOK
)
5953 dbug(1,dprintf("init:hook_on"));
5954 plci
->hook_state
= ie
[1]&0x91;
5955 next_internal_command (Id
, plci
);
5958 else /* ignore doubled hook indications */
5960 if( ((plci
->hook_state
)&0xf0)==0x90) break;
5961 plci
->hook_state
= ie
[1]&0x91;
5963 /* hangup the adv. voice call and signal '-' to the appl */
5964 if(a
->AdvSignalPLCI
) {
5965 Id
= ((word
)a
->AdvSignalPLCI
->Id
<<8)|a
->Id
;
5966 if(plci
->tel
) Id
|=EXT_CONTROLLER
;
5967 sendf(a
->AdvSignalAppl
,
5971 "ws", (word
)0, "\x01-");
5972 a
->AdvSignalPLCI
->internal_command
= HOOK_ON_REQ
;
5973 a
->AdvSignalPLCI
->command
= 0;
5974 sig_req(a
->AdvSignalPLCI
,HANGUP
,0);
5975 send_req(a
->AdvSignalPLCI
);
5983 clear_c_ind_mask_bit (plci
, (word
)(plci
->appl
->Id
-1));
5984 PUT_WORD(&resume_cau
[4],GOOD
);
5985 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws", (word
)3, resume_cau
);
5989 clear_c_ind_mask (plci
);
5991 if (plci
->NL
.Id
&& !plci
->nl_remove_id
) {
5992 mixer_remove (plci
);
5993 nl_req_ncci(plci
,REMOVE
,0);
5995 if (!plci
->sig_remove_id
) {
5996 plci
->internal_command
= 0;
5997 sig_req(plci
,REMOVE
,0);
6000 if(!plci
->channels
) {
6001 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws", (word
)3, "\x05\x04\x00\x02\x00\x00");
6002 sendf(plci
->appl
, _DISCONNECT_I
, Id
, 0, "w", 0);
6010 plci
->hangup_flow_ctrl_timer
=0;
6011 if(plci
->manufacturer
&& plci
->State
==LOCAL_CONNECT
) break;
6014 i
= _L3_CAUSE
| cau
[2];
6015 if(cau
[2]==0) i
= 0;
6016 else if(cau
[2]==8) i
= _L1_ERROR
;
6017 else if(cau
[2]==9 || cau
[2]==10) i
= _L2_ERROR
;
6018 else if(cau
[2]==5) i
= _CAPI_GUARD_ERROR
;
6024 if(plci
->State
==INC_CON_PENDING
|| plci
->State
==INC_CON_ALERT
)
6026 for(i
=0; i
<max_appl
; i
++)
6028 if(test_c_ind_mask_bit (plci
, i
))
6029 sendf(&application
[i
], _DISCONNECT_I
, Id
, 0, "w", 0);
6034 clear_c_ind_mask (plci
);
6038 if (plci
->State
== LISTENING
)
6040 plci
->notifiedcall
=0;
6043 plci
->State
= INC_DIS_PENDING
;
6044 if(c_ind_mask_empty (plci
))
6047 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
6049 mixer_remove (plci
);
6050 nl_req_ncci(plci
,REMOVE
,0);
6052 if (!plci
->sig_remove_id
)
6054 plci
->internal_command
= 0;
6055 sig_req(plci
,REMOVE
,0);
6062 /* collision of DISCONNECT or CONNECT_RES with HANGUP can */
6063 /* result in a second HANGUP! Don't generate another */
6065 if(plci
->State
!=IDLE
&& plci
->State
!=INC_DIS_PENDING
)
6067 if(plci
->State
==RESUMING
)
6069 PUT_WORD(&resume_cau
[4],i
);
6070 sendf(plci
->appl
,_FACILITY_I
,Id
,0,"ws", (word
)3, resume_cau
);
6072 plci
->State
= INC_DIS_PENDING
;
6073 sendf(plci
->appl
,_DISCONNECT_I
,Id
,0,"w",i
);
6079 SendSSExtInd(NULL
,plci
,Id
,multi_ssext_parms
);
6083 VSwitchReqInd(plci
,Id
,multi_vswitch_parms
);
6086 if(plci
->relatedPTYPLCI
&&
6087 plci
->vswitchstate
==3 &&
6088 plci
->relatedPTYPLCI
->vswitchstate
==3 &&
6089 parms
[MAXPARMSIDS
-1][0])
6091 add_p(plci
->relatedPTYPLCI
,SMSG
,parms
[MAXPARMSIDS
-1]);
6092 sig_req(plci
->relatedPTYPLCI
,VSWITCH_REQ
,0);
6093 send_req(plci
->relatedPTYPLCI
);
6095 else VSwitchReqInd(plci
,Id
,multi_vswitch_parms
);
6102 static void SendSetupInfo(APPL
* appl
, PLCI
* plci
, dword Id
, byte
* * parms
, byte Info_Sent_Flag
)
6107 byte
* Info_Element
;
6110 dbug(1,dprintf("SetupInfo"));
6112 for(i
=0; i
<MAXPARMSIDS
; i
++) {
6119 dbug(1,dprintf("CPN "));
6120 Info_Number
= 0x0070;
6122 Info_Sent_Flag
= true;
6124 case 8: /* display */
6125 dbug(1,dprintf("display(%d)",i
));
6126 Info_Number
= 0x0028;
6128 Info_Sent_Flag
= true;
6130 case 16: /* Channel Id */
6131 dbug(1,dprintf("CHI"));
6132 Info_Number
= 0x0018;
6134 Info_Sent_Flag
= true;
6135 mixer_set_bchannel_id (plci
, Info_Element
);
6137 case 19: /* Redirected Number */
6138 dbug(1,dprintf("RDN"));
6139 Info_Number
= 0x0074;
6141 Info_Sent_Flag
= true;
6143 case 20: /* Redirected Number extended */
6144 dbug(1,dprintf("RDX"));
6145 Info_Number
= 0x0073;
6147 Info_Sent_Flag
= true;
6149 case 22: /* Redirecing Number */
6150 dbug(1,dprintf("RIN"));
6151 Info_Number
= 0x0076;
6153 Info_Sent_Flag
= true;
6161 if(i
==MAXPARMSIDS
-2){ /* to indicate the message type "Setup" */
6162 Info_Number
= 0x8000 |5;
6167 if(Info_Sent_Flag
&& Info_Number
){
6168 if(plci
->adapter
->Info_Mask
[appl
->Id
-1] & Info_Mask
) {
6169 sendf(appl
,_INFO_I
,Id
,0,"wS",Info_Number
,Info_Element
);
6176 static void SendInfo(PLCI
*plci
, dword Id
, byte
**parms
, byte iesent
)
6183 byte
* Info_Element
;
6185 static byte charges
[5] = {4,0,0,0,0};
6186 static byte cause
[] = {0x02,0x80,0x00};
6189 dbug(1,dprintf("InfoParse "));
6194 && plci
->Sig
.Ind
!=NCR_FACILITY
6197 dbug(1,dprintf("NoParse "));
6201 for(i
=0; i
<MAXPARMSIDS
; i
++) {
6208 dbug(1,dprintf("CPN "));
6209 Info_Number
= 0x0070;
6212 case 7: /* ESC_CAU */
6213 dbug(1,dprintf("cau(0x%x)",ie
[2]));
6214 Info_Number
= 0x0008;
6217 Info_Element
= NULL
;
6219 case 8: /* display */
6220 dbug(1,dprintf("display(%d)",i
));
6221 Info_Number
= 0x0028;
6224 case 9: /* Date display */
6225 dbug(1,dprintf("date(%d)",i
));
6226 Info_Number
= 0x0029;
6229 case 10: /* charges */
6230 for(j
=0;j
<4;j
++) charges
[1+j
] = 0;
6231 for(j
=0; j
<ie
[0] && !(ie
[1+j
]&0x80); j
++);
6232 for(k
=1,j
++; j
<ie
[0] && k
<=4; j
++,k
++) charges
[k
] = ie
[1+j
];
6233 Info_Number
= 0x4000;
6235 Info_Element
= charges
;
6237 case 11: /* user user info */
6238 dbug(1,dprintf("uui"));
6239 Info_Number
= 0x007E;
6242 case 12: /* congestion receiver ready */
6243 dbug(1,dprintf("clRDY"));
6244 Info_Number
= 0x00B0;
6248 case 13: /* congestion receiver not ready */
6249 dbug(1,dprintf("clNRDY"));
6250 Info_Number
= 0x00BF;
6254 case 15: /* Keypad Facility */
6255 dbug(1,dprintf("KEY"));
6256 Info_Number
= 0x002C;
6259 case 16: /* Channel Id */
6260 dbug(1,dprintf("CHI"));
6261 Info_Number
= 0x0018;
6263 mixer_set_bchannel_id (plci
, Info_Element
);
6265 case 17: /* if no 1tr6 cause, send full cause, else esc_cause */
6266 dbug(1,dprintf("q9cau(0x%x)",ie
[2]));
6267 if(!cause
[2] || cause
[2]<0x80) break; /* eg. layer 1 error */
6268 Info_Number
= 0x0008;
6270 if(cause
[2] != ie
[2]) Info_Element
= cause
;
6272 case 19: /* Redirected Number */
6273 dbug(1,dprintf("RDN"));
6274 Info_Number
= 0x0074;
6277 case 22: /* Redirecing Number */
6278 dbug(1,dprintf("RIN"));
6279 Info_Number
= 0x0076;
6282 case 23: /* Notification Indicator */
6283 dbug(1,dprintf("NI"));
6284 Info_Number
= (word
)NI
;
6287 case 26: /* Call State */
6288 dbug(1,dprintf("CST"));
6289 Info_Number
= (word
)CST
;
6290 Info_Mask
= 0x01; /* do with cause i.e. for now */
6292 case MAXPARMSIDS
-2: /* Escape Message Type, must be the last indication */
6293 dbug(1,dprintf("ESC/MT[0x%x]",ie
[3]));
6294 Info_Number
= 0x8000 |ie
[3];
6295 if(iesent
) Info_Mask
= 0xffff;
6296 else Info_Mask
= 0x10;
6307 if(plci
->Sig
.Ind
==NCR_FACILITY
) /* check controller broadcast */
6309 for(j
=0; j
<max_appl
; j
++)
6311 appl
= &application
[j
];
6314 && plci
->adapter
->Info_Mask
[appl
->Id
-1] &Info_Mask
)
6316 dbug(1,dprintf("NCR_Ind"));
6318 sendf(&application
[j
],_INFO_I
,Id
&0x0f,0,"wS",Info_Number
,Info_Element
);
6322 else if(!plci
->appl
)
6323 { /* overlap receiving broadcast */
6328 || Info_Number
==UUI
)
6330 for(j
=0; j
<max_appl
; j
++)
6332 if(test_c_ind_mask_bit (plci
, j
))
6334 dbug(1,dprintf("Ovl_Ind"));
6336 sendf(&application
[j
],_INFO_I
,Id
,0,"wS",Info_Number
,Info_Element
);
6340 } /* all other signalling states */
6342 && plci
->adapter
->Info_Mask
[plci
->appl
->Id
-1] &Info_Mask
)
6344 dbug(1,dprintf("Std_Ind"));
6346 sendf(plci
->appl
,_INFO_I
,Id
,0,"wS",Info_Number
,Info_Element
);
6352 static byte
SendMultiIE(PLCI
*plci
, dword Id
, byte
**parms
, byte ie_type
,
6353 dword info_mask
, byte setupParse
)
6359 byte
* Info_Element
;
6367 && plci
->Sig
.Ind
!=NCR_FACILITY
6371 dbug(1,dprintf("NoM-IEParse "));
6374 dbug(1,dprintf("M-IEParse "));
6376 for(i
=0; i
<MAX_MULTI_IE
; i
++)
6383 dbug(1,dprintf("[Ind0x%x]:IE=0x%x",plci
->Sig
.Ind
,ie_type
));
6384 Info_Number
= (word
)ie_type
;
6385 Info_Mask
= (word
)info_mask
;
6388 if(plci
->Sig
.Ind
==NCR_FACILITY
) /* check controller broadcast */
6390 for(j
=0; j
<max_appl
; j
++)
6392 appl
= &application
[j
];
6395 && plci
->adapter
->Info_Mask
[appl
->Id
-1] &Info_Mask
)
6398 dbug(1,dprintf("Mlt_NCR_Ind"));
6399 sendf(&application
[j
],_INFO_I
,Id
&0x0f,0,"wS",Info_Number
,Info_Element
);
6403 else if(!plci
->appl
&& Info_Number
)
6404 { /* overlap receiving broadcast */
6405 for(j
=0; j
<max_appl
; j
++)
6407 if(test_c_ind_mask_bit (plci
, j
))
6410 dbug(1,dprintf("Mlt_Ovl_Ind"));
6411 sendf(&application
[j
],_INFO_I
,Id
,0,"wS",Info_Number
,Info_Element
);
6414 } /* all other signalling states */
6416 && plci
->adapter
->Info_Mask
[plci
->appl
->Id
-1] &Info_Mask
)
6419 dbug(1,dprintf("Mlt_Std_Ind"));
6420 sendf(plci
->appl
,_INFO_I
,Id
,0,"wS",Info_Number
,Info_Element
);
6426 static void SendSSExtInd(APPL
* appl
, PLCI
* plci
, dword Id
, byte
* * parms
)
6429 /* Format of multi_ssext_parms[i][]:
6432 2 byte SSEXT_REQ/SSEXT_IND
6440 && plci
->Sig
.Ind
!=NCR_FACILITY
6442 for(i
=0;i
<MAX_MULTI_IE
;i
++)
6444 if(parms
[i
][0]<6) continue;
6445 if(parms
[i
][2]==SSEXT_REQ
) continue;
6449 parms
[i
][0]=0; /* kill it */
6450 sendf(appl
,_MANUFACTURER_I
,
6460 parms
[i
][0]=0; /* kill it */
6461 sendf(plci
->appl
,_MANUFACTURER_I
,
6472 static void nl_ind(PLCI
*plci
)
6477 DIVA_CAPI_ADAPTER
* a
;
6483 byte len
, ncci_state
;
6486 word fax_feature_bits
;
6487 byte fax_send_edata_ack
;
6488 static byte v120_header_buffer
[2 + 3] __attribute__ ((aligned(8)));
6489 static word fax_info
[] = {
6490 0, /* T30_SUCCESS */
6491 _FAX_NO_CONNECTION
, /* T30_ERR_NO_DIS_RECEIVED */
6492 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TIMEOUT_NO_RESPONSE */
6493 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_RESPONSE */
6494 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TOO_MANY_REPEATS */
6495 _FAX_PROTOCOL_ERROR
, /* T30_ERR_UNEXPECTED_MESSAGE */
6496 _FAX_REMOTE_ABORT
, /* T30_ERR_UNEXPECTED_DCN */
6497 _FAX_LOCAL_ABORT
, /* T30_ERR_DTC_UNSUPPORTED */
6498 _FAX_TRAINING_ERROR
, /* T30_ERR_ALL_RATES_FAILED */
6499 _FAX_TRAINING_ERROR
, /* T30_ERR_TOO_MANY_TRAINS */
6500 _FAX_PARAMETER_ERROR
, /* T30_ERR_RECEIVE_CORRUPTED */
6501 _FAX_REMOTE_ABORT
, /* T30_ERR_UNEXPECTED_DISC */
6502 _FAX_LOCAL_ABORT
, /* T30_ERR_APPLICATION_DISC */
6503 _FAX_REMOTE_REJECT
, /* T30_ERR_INCOMPATIBLE_DIS */
6504 _FAX_LOCAL_ABORT
, /* T30_ERR_INCOMPATIBLE_DCS */
6505 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TIMEOUT_NO_COMMAND */
6506 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_COMMAND */
6507 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG */
6508 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG */
6509 _FAX_NO_CONNECTION
, /* T30_ERR_NOT_IDENTIFIED */
6510 _FAX_PROTOCOL_ERROR
, /* T30_ERR_SUPERVISORY_TIMEOUT */
6511 _FAX_PARAMETER_ERROR
, /* T30_ERR_TOO_LONG_SCAN_LINE */
6512 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS */
6513 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR */
6514 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCS_AFTER_FTT */
6515 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCS_AFTER_EOM */
6516 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCS_AFTER_MPS */
6517 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCN_AFTER_MCF */
6518 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCN_AFTER_RTN */
6519 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_CFR */
6520 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_MCF_AFTER_EOP */
6521 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_MCF_AFTER_EOM */
6522 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_MCF_AFTER_MPS */
6523 0x331d, /* T30_ERR_SUB_SEP_UNSUPPORTED */
6524 0x331e, /* T30_ERR_PWD_UNSUPPORTED */
6525 0x331f, /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED */
6526 _FAX_PROTOCOL_ERROR
, /* T30_ERR_INVALID_COMMAND_FRAME */
6527 _FAX_PARAMETER_ERROR
, /* T30_ERR_UNSUPPORTED_PAGE_CODING */
6528 _FAX_PARAMETER_ERROR
, /* T30_ERR_INVALID_PAGE_CODING */
6529 _FAX_REMOTE_REJECT
, /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG */
6530 _FAX_LOCAL_ABORT
, /* T30_ERR_TIMEOUT_FROM_APPLICATION */
6531 _FAX_PROTOCOL_ERROR
, /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */
6532 _FAX_PROTOCOL_ERROR
, /* T30_ERR_V34FAX_TRAINING_TIMEOUT */
6533 _FAX_PROTOCOL_ERROR
, /* T30_ERR_V34FAX_UNEXPECTED_V21 */
6534 _FAX_PROTOCOL_ERROR
, /* T30_ERR_V34FAX_PRIMARY_CTS_ON */
6535 _FAX_LOCAL_ABORT
, /* T30_ERR_V34FAX_TURNAROUND_POLLING */
6536 _FAX_LOCAL_ABORT
/* T30_ERR_V34FAX_V8_INCOMPATIBILITY */
6539 byte dtmf_code_buffer
[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE
+ 1];
6542 static word rtp_info
[] = {
6543 GOOD
, /* RTP_SUCCESS */
6544 0x3600 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE */
6547 static dword udata_forwarding_table
[0x100 / sizeof(dword
)] =
6549 0x0020301e, 0x00000000, 0x00000000, 0x00000000,
6550 0x00000000, 0x00000000, 0x00000000, 0x00000000
6553 ch
= plci
->NL
.IndCh
;
6555 ncci
= a
->ch_ncci
[ch
];
6556 Id
= (((dword
)(ncci
? ncci
: ch
)) << 16) | (((word
) plci
->Id
) << 8) | a
->Id
;
6557 if(plci
->tel
) Id
|=EXT_CONTROLLER
;
6558 APPLptr
= plci
->appl
;
6559 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",
6560 plci
->NL
.Id
,Id
,plci
->Id
,plci
->tel
,plci
->State
,ch
,plci
->channels
,plci
->NL
.Ind
&0x0f));
6562 /* in the case if no connect_active_Ind was sent to the appl we wait for */
6564 if (plci
->nl_remove_id
)
6566 plci
->NL
.RNR
= 2; /* discard */
6567 dbug(1,dprintf("NL discard while remove pending"));
6570 if((plci
->NL
.Ind
&0x0f)==N_CONNECT
)
6572 if(plci
->State
==INC_DIS_PENDING
6573 || plci
->State
==OUTG_DIS_PENDING
6574 || plci
->State
==IDLE
)
6576 plci
->NL
.RNR
= 2; /* discard */
6577 dbug(1,dprintf("discard n_connect"));
6580 if(plci
->State
< INC_ACT_PENDING
)
6582 plci
->NL
.RNR
= 1; /* flow control */
6583 channel_x_off (plci
, ch
, N_XON_CONNECT_IND
);
6588 if(!APPLptr
) /* no application or invalid data */
6589 { /* while reloading the DSP */
6590 dbug(1,dprintf("discard1"));
6595 if (((plci
->NL
.Ind
&0x0f) == N_UDATA
)
6596 && (((plci
->B2_prot
!= B2_SDLC
) && ((plci
->B1_resource
== 17) || (plci
->B1_resource
== 18)))
6597 || (plci
->B2_prot
== 7)
6598 || (plci
->B3_prot
== 7)) )
6600 plci
->ncpi_buffer
[0] = 0;
6602 ncpi_state
= plci
->ncpi_state
;
6603 if (plci
->NL
.complete
== 1)
6605 byte
* data
= &plci
->NL
.RBuffer
->P
[0];
6607 if ((plci
->NL
.RBuffer
->length
>= 12)
6608 &&( (*data
== DSP_UDATA_INDICATION_DCD_ON
)
6609 ||(*data
== DSP_UDATA_INDICATION_CTS_ON
)) )
6611 word conn_opt
, ncpi_opt
= 0x00;
6612 /* HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */
6614 if (*data
== DSP_UDATA_INDICATION_DCD_ON
)
6615 plci
->ncpi_state
|= NCPI_MDM_DCD_ON_RECEIVED
;
6616 if (*data
== DSP_UDATA_INDICATION_CTS_ON
)
6617 plci
->ncpi_state
|= NCPI_MDM_CTS_ON_RECEIVED
;
6619 data
++; /* indication code */
6620 data
+= 2; /* timestamp */
6621 if ((*data
== DSP_CONNECTED_NORM_V18
) || (*data
== DSP_CONNECTED_NORM_VOWN
))
6622 ncpi_state
&= ~(NCPI_MDM_DCD_ON_RECEIVED
| NCPI_MDM_CTS_ON_RECEIVED
);
6623 data
++; /* connected norm */
6624 conn_opt
= GET_WORD(data
);
6625 data
+= 2; /* connected options */
6627 PUT_WORD (&(plci
->ncpi_buffer
[1]), (word
)(GET_DWORD(data
) & 0x0000FFFF));
6629 if (conn_opt
& DSP_CONNECTED_OPTION_MASK_V42
)
6631 ncpi_opt
|= MDM_NCPI_ECM_V42
;
6633 else if (conn_opt
& DSP_CONNECTED_OPTION_MASK_MNP
)
6635 ncpi_opt
|= MDM_NCPI_ECM_MNP
;
6639 ncpi_opt
|= MDM_NCPI_TRANSPARENT
;
6641 if (conn_opt
& DSP_CONNECTED_OPTION_MASK_COMPRESSION
)
6643 ncpi_opt
|= MDM_NCPI_COMPRESSED
;
6645 PUT_WORD (&(plci
->ncpi_buffer
[3]), ncpi_opt
);
6646 plci
->ncpi_buffer
[0] = 4;
6648 plci
->ncpi_state
|= NCPI_VALID_CONNECT_B3_IND
| NCPI_VALID_CONNECT_B3_ACT
| NCPI_VALID_DISC_B3_IND
;
6651 if (plci
->B3_prot
== 7)
6653 if (((a
->ncci_state
[ncci
] == INC_ACT_PENDING
) || (a
->ncci_state
[ncci
] == OUTG_CON_PENDING
))
6654 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6655 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6657 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
6658 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"S",plci
->ncpi_buffer
);
6659 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6663 if (!((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
-1])
6664 & ((1L << PRIVATE_V18
) | (1L << PRIVATE_VOWN
)))
6665 || !(ncpi_state
& NCPI_MDM_DCD_ON_RECEIVED
)
6666 || !(ncpi_state
& NCPI_MDM_CTS_ON_RECEIVED
))
6674 if(plci
->NL
.complete
== 2)
6676 if (((plci
->NL
.Ind
&0x0f) == N_UDATA
)
6677 && !(udata_forwarding_table
[plci
->RData
[0].P
[0] >> 5] & (1L << (plci
->RData
[0].P
[0] & 0x1f))))
6679 switch(plci
->RData
[0].P
[0])
6682 case DTMF_UDATA_INDICATION_FAX_CALLING_TONE
:
6683 if (plci
->dtmf_rec_active
& DTMF_LISTEN_ACTIVE_FLAG
)
6684 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0,"ws", SELECTOR_DTMF
, "\x01X");
6686 case DTMF_UDATA_INDICATION_ANSWER_TONE
:
6687 if (plci
->dtmf_rec_active
& DTMF_LISTEN_ACTIVE_FLAG
)
6688 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0,"ws", SELECTOR_DTMF
, "\x01Y");
6690 case DTMF_UDATA_INDICATION_DIGITS_RECEIVED
:
6691 dtmf_indication (Id
, plci
, plci
->RData
[0].P
, plci
->RData
[0].PLength
);
6693 case DTMF_UDATA_INDICATION_DIGITS_SENT
:
6694 dtmf_confirmation (Id
, plci
);
6698 case UDATA_INDICATION_MIXER_TAP_DATA
:
6699 capidtmf_recv_process_block (&(plci
->capidtmf_state
), plci
->RData
[0].P
+ 1, (word
)(plci
->RData
[0].PLength
- 1));
6700 i
= capidtmf_indication (&(plci
->capidtmf_state
), dtmf_code_buffer
+ 1);
6703 dtmf_code_buffer
[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED
;
6704 dtmf_indication (Id
, plci
, dtmf_code_buffer
, (word
)(i
+ 1));
6709 case UDATA_INDICATION_MIXER_COEFS_SET
:
6710 mixer_indication_coefs_set (Id
, plci
);
6712 case UDATA_INDICATION_XCONNECT_FROM
:
6713 mixer_indication_xconnect_from (Id
, plci
, plci
->RData
[0].P
, plci
->RData
[0].PLength
);
6715 case UDATA_INDICATION_XCONNECT_TO
:
6716 mixer_indication_xconnect_to (Id
, plci
, plci
->RData
[0].P
, plci
->RData
[0].PLength
);
6720 case LEC_UDATA_INDICATION_DISABLE_DETECT
:
6721 ec_indication (Id
, plci
, plci
->RData
[0].P
, plci
->RData
[0].PLength
);
6732 if ((plci
->RData
[0].PLength
!= 0)
6733 && ((plci
->B2_prot
== B2_V120_ASYNC
)
6734 || (plci
->B2_prot
== B2_V120_ASYNC_V42BIS
)
6735 || (plci
->B2_prot
== B2_V120_BIT_TRANSPARENT
)))
6738 sendf(plci
->appl
,_DATA_B3_I
,Id
,0,
6741 (plci
->NL
.RNum
< 2) ? 0 : plci
->RData
[1].PLength
,
6749 sendf(plci
->appl
,_DATA_B3_I
,Id
,0,
6752 plci
->RData
[0].PLength
,
6761 fax_feature_bits
= 0;
6762 if((plci
->NL
.Ind
&0x0f)==N_CONNECT
||
6763 (plci
->NL
.Ind
&0x0f)==N_CONNECT_ACK
||
6764 (plci
->NL
.Ind
&0x0f)==N_DISC
||
6765 (plci
->NL
.Ind
&0x0f)==N_EDATA
||
6766 (plci
->NL
.Ind
&0x0f)==N_DISC_ACK
)
6769 plci
->ncpi_buffer
[0] = 0;
6770 switch (plci
->B3_prot
) {
6773 break; /* no network control protocol info - jfr */
6776 for(i
=0; i
<plci
->NL
.RLength
; i
++) plci
->ncpi_buffer
[4+i
] = plci
->NL
.RBuffer
->P
[i
];
6777 plci
->ncpi_buffer
[0] = (byte
)(i
+3);
6778 plci
->ncpi_buffer
[1] = (byte
)(plci
->NL
.Ind
&N_D_BIT
? 1:0);
6779 plci
->ncpi_buffer
[2] = 0;
6780 plci
->ncpi_buffer
[3] = 0;
6782 case 4: /*T.30 - FAX*/
6783 case 5: /*T.30 - FAX*/
6784 if(plci
->NL
.RLength
>=sizeof(T30_INFO
))
6786 dbug(1,dprintf("FaxStatus %04x", ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
));
6788 PUT_WORD(&(plci
->ncpi_buffer
[1]),((T30_INFO
*)plci
->NL
.RBuffer
->P
)->rate_div_2400
* 2400);
6789 fax_feature_bits
= GET_WORD(&((T30_INFO
*)plci
->NL
.RBuffer
->P
)->feature_bits_low
);
6790 i
= (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->resolution
& T30_RESOLUTION_R8_0770_OR_200
) ? 0x0001 : 0x0000;
6791 if (plci
->B3_prot
== 5)
6793 if (!(fax_feature_bits
& T30_FEATURE_BIT_ECM
))
6794 i
|= 0x8000; /* This is not an ECM connection */
6795 if (fax_feature_bits
& T30_FEATURE_BIT_T6_CODING
)
6796 i
|= 0x4000; /* This is a connection with MMR compression */
6797 if (fax_feature_bits
& T30_FEATURE_BIT_2D_CODING
)
6798 i
|= 0x2000; /* This is a connection with MR compression */
6799 if (fax_feature_bits
& T30_FEATURE_BIT_MORE_DOCUMENTS
)
6800 i
|= 0x0004; /* More documents */
6801 if (fax_feature_bits
& T30_FEATURE_BIT_POLLING
)
6802 i
|= 0x0002; /* Fax-polling indication */
6804 dbug(1,dprintf("FAX Options %04x %04x",fax_feature_bits
,i
));
6805 PUT_WORD(&(plci
->ncpi_buffer
[3]),i
);
6806 PUT_WORD(&(plci
->ncpi_buffer
[5]),((T30_INFO
*)plci
->NL
.RBuffer
->P
)->data_format
);
6807 plci
->ncpi_buffer
[7] = ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->pages_low
;
6808 plci
->ncpi_buffer
[8] = ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->pages_high
;
6809 plci
->ncpi_buffer
[len
] = 0;
6810 if(((T30_INFO
*)plci
->NL
.RBuffer
->P
)->station_id_len
)
6812 plci
->ncpi_buffer
[len
] = 20;
6813 for (i
= 0; i
< 20; i
++)
6814 plci
->ncpi_buffer
[++len
] = ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->station_id
[i
];
6816 if (((plci
->NL
.Ind
& 0x0f) == N_DISC
) || ((plci
->NL
.Ind
& 0x0f) == N_DISC_ACK
))
6818 if (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
< ARRAY_SIZE(fax_info
))
6819 info
= fax_info
[((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
];
6821 info
= _FAX_PROTOCOL_ERROR
;
6824 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[plci
->appl
->Id
-1])
6825 & ((1L << PRIVATE_FAX_SUB_SEP_PWD
) | (1L << PRIVATE_FAX_NONSTANDARD
)))
6827 i
= ((word
)(offsetof(T30_INFO
, station_id
) + 20)) + ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->head_line_len
;
6828 while (i
< plci
->NL
.RBuffer
->length
)
6829 plci
->ncpi_buffer
[++len
] = plci
->NL
.RBuffer
->P
[i
++];
6832 plci
->ncpi_buffer
[0] = len
;
6833 fax_feature_bits
= GET_WORD(&((T30_INFO
*)plci
->NL
.RBuffer
->P
)->feature_bits_low
);
6834 PUT_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->feature_bits_low
, fax_feature_bits
);
6836 plci
->ncpi_state
|= NCPI_VALID_CONNECT_B3_IND
;
6837 if (((plci
->NL
.Ind
&0x0f) == N_CONNECT_ACK
)
6838 || (((plci
->NL
.Ind
&0x0f) == N_CONNECT
)
6839 && (fax_feature_bits
& T30_FEATURE_BIT_POLLING
))
6840 || (((plci
->NL
.Ind
&0x0f) == N_EDATA
)
6841 && ((((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_TRAIN_OK
)
6842 || (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_DIS
)
6843 || (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_DTC
))))
6845 plci
->ncpi_state
|= NCPI_VALID_CONNECT_B3_ACT
;
6847 if (((plci
->NL
.Ind
&0x0f) == N_DISC
)
6848 || ((plci
->NL
.Ind
&0x0f) == N_DISC_ACK
)
6849 || (((plci
->NL
.Ind
&0x0f) == N_EDATA
)
6850 && (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_EOP_CAPI
)))
6852 plci
->ncpi_state
|= NCPI_VALID_CONNECT_B3_ACT
| NCPI_VALID_DISC_B3_IND
;
6858 if (((plci
->NL
.Ind
& 0x0f) == N_DISC
) || ((plci
->NL
.Ind
& 0x0f) == N_DISC_ACK
))
6860 if (plci
->NL
.RLength
!= 0)
6862 info
= rtp_info
[plci
->NL
.RBuffer
->P
[0]];
6863 plci
->ncpi_buffer
[0] = plci
->NL
.RLength
- 1;
6864 for (i
= 1; i
< plci
->NL
.RLength
; i
++)
6865 plci
->ncpi_buffer
[i
] = plci
->NL
.RBuffer
->P
[i
];
6873 switch(plci
->NL
.Ind
&0x0f) {
6875 if ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5))
6877 dbug(1,dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci
, a
->ncci_state
[ncci
],
6878 ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
));
6879 fax_send_edata_ack
= (((T30_INFO
*)(plci
->fax_connect_info_buffer
))->operating_mode
== T30_OPERATING_MODE_CAPI_NEG
);
6881 if ((plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_ENABLE_NSF
)
6882 && (plci
->nsf_control_bits
& (T30_NSF_CONTROL_BIT_NEGOTIATE_IND
| T30_NSF_CONTROL_BIT_NEGOTIATE_RESP
))
6883 && (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_DIS
)
6884 && (a
->ncci_state
[ncci
] == OUTG_CON_PENDING
)
6885 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6886 && !(plci
->ncpi_state
& NCPI_NEGOTIATE_B3_SENT
))
6888 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->code
= ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
;
6889 sendf(plci
->appl
,_MANUFACTURER_I
,Id
,0,"dwbS",_DI_MANU_ID
,_DI_NEGOTIATE_B3
,
6890 (byte
)(plci
->ncpi_buffer
[0] + 1), plci
->ncpi_buffer
);
6891 plci
->ncpi_state
|= NCPI_NEGOTIATE_B3_SENT
;
6892 if (plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_NEGOTIATE_RESP
)
6893 fax_send_edata_ack
= false;
6896 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
6898 switch (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
)
6901 if ((a
->ncci_state
[ncci
] == OUTG_CON_PENDING
)
6902 && !(GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
) & T30_CONTROL_BIT_REQUEST_POLLING
)
6903 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6904 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6906 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
6907 if (plci
->B3_prot
== 4)
6908 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"s","");
6910 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"S",plci
->ncpi_buffer
);
6911 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6915 case EDATA_T30_TRAIN_OK
:
6916 if ((a
->ncci_state
[ncci
] == INC_ACT_PENDING
)
6917 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6918 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6920 if (plci
->B3_prot
== 4)
6921 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"s","");
6923 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"S",plci
->ncpi_buffer
);
6924 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6928 case EDATA_T30_EOP_CAPI
:
6929 if (a
->ncci_state
[ncci
] == CONNECTED
)
6931 sendf(plci
->appl
,_DISCONNECT_B3_I
,Id
,0,"wS",GOOD
,plci
->ncpi_buffer
);
6932 a
->ncci_state
[ncci
] = INC_DIS_PENDING
;
6933 plci
->ncpi_state
= 0;
6934 fax_send_edata_ack
= false;
6941 switch (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
)
6943 case EDATA_T30_TRAIN_OK
:
6944 if ((a
->ncci_state
[ncci
] == INC_ACT_PENDING
)
6945 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6946 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6948 if (plci
->B3_prot
== 4)
6949 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"s","");
6951 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"S",plci
->ncpi_buffer
);
6952 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6957 if (fax_send_edata_ack
)
6959 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->code
= ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
;
6960 plci
->fax_edata_ack_length
= 1;
6961 start_internal_command (Id
, plci
, fax_edata_ack_command
);
6966 dbug(1,dprintf("EDATA ncci=0x%x state=%d", ncci
, a
->ncci_state
[ncci
]));
6970 if (!a
->ch_ncci
[ch
])
6972 ncci
= get_ncci (plci
, ch
, 0);
6973 Id
= (Id
& 0xffff) | (((dword
) ncci
) << 16);
6975 dbug(1,dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d",
6976 ch
, a
->ncci_state
[ncci
], a
->ncci_plci
[ncci
], plci
->Id
, plci
->State
));
6978 msg
= _CONNECT_B3_I
;
6979 if (a
->ncci_state
[ncci
] == IDLE
)
6981 else if (plci
->B3_prot
== 1)
6982 msg
= _CONNECT_B3_T90_ACTIVE_I
;
6984 a
->ncci_state
[ncci
] = INC_CON_PENDING
;
6985 if(plci
->B3_prot
== 4)
6986 sendf(plci
->appl
,msg
,Id
,0,"s","");
6988 sendf(plci
->appl
,msg
,Id
,0,"S",plci
->ncpi_buffer
);
6991 dbug(1,dprintf("N_connect_Ack"));
6992 if (plci
->internal_command_queue
[0]
6993 && ((plci
->adjust_b_state
== ADJUST_B_CONNECT_2
)
6994 || (plci
->adjust_b_state
== ADJUST_B_CONNECT_3
)
6995 || (plci
->adjust_b_state
== ADJUST_B_CONNECT_4
)))
6997 (*(plci
->internal_command_queue
[0]))(Id
, plci
, 0);
6998 if (!plci
->internal_command
)
6999 next_internal_command (Id
, plci
);
7002 msg
= _CONNECT_B3_ACTIVE_I
;
7003 if (plci
->B3_prot
== 1)
7005 if (a
->ncci_state
[ncci
] != OUTG_CON_PENDING
)
7006 msg
= _CONNECT_B3_T90_ACTIVE_I
;
7007 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
7008 sendf(plci
->appl
,msg
,Id
,0,"S",plci
->ncpi_buffer
);
7010 else if ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5) || (plci
->B3_prot
== 7))
7012 if ((a
->ncci_state
[ncci
] == OUTG_CON_PENDING
)
7013 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
7014 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
7016 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
7017 if (plci
->B3_prot
== 4)
7018 sendf(plci
->appl
,msg
,Id
,0,"s","");
7020 sendf(plci
->appl
,msg
,Id
,0,"S",plci
->ncpi_buffer
);
7021 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
7026 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
7027 sendf(plci
->appl
,msg
,Id
,0,"S",plci
->ncpi_buffer
);
7029 if (plci
->adjust_b_restore
)
7031 plci
->adjust_b_restore
= false;
7032 start_internal_command (Id
, plci
, adjust_b_restore
);
7037 if (plci
->internal_command_queue
[0]
7038 && ((plci
->internal_command
== FAX_DISCONNECT_COMMAND_1
)
7039 || (plci
->internal_command
== FAX_DISCONNECT_COMMAND_2
)
7040 || (plci
->internal_command
== FAX_DISCONNECT_COMMAND_3
)))
7042 (*(plci
->internal_command_queue
[0]))(Id
, plci
, 0);
7043 if (!plci
->internal_command
)
7044 next_internal_command (Id
, plci
);
7046 ncci_state
= a
->ncci_state
[ncci
];
7047 ncci_remove (plci
, ncci
, false);
7049 /* with N_DISC or N_DISC_ACK the IDI frees the respective */
7050 /* channel, so we cannot store the state in ncci_state! The */
7051 /* information which channel we received a N_DISC is thus */
7052 /* stored in the inc_dis_ncci_table buffer. */
7053 for(i
=0; plci
->inc_dis_ncci_table
[i
]; i
++);
7054 plci
->inc_dis_ncci_table
[i
] = (byte
) ncci
;
7056 /* need a connect_b3_ind before a disconnect_b3_ind with FAX */
7058 && (plci
->B1_resource
== 16)
7059 && (plci
->State
<= CONNECTED
))
7062 i
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->rate_div_2400
* 2400;
7063 PUT_WORD (&plci
->ncpi_buffer
[1], i
);
7064 PUT_WORD (&plci
->ncpi_buffer
[3], 0);
7065 i
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->data_format
;
7066 PUT_WORD (&plci
->ncpi_buffer
[5], i
);
7067 PUT_WORD (&plci
->ncpi_buffer
[7], 0);
7068 plci
->ncpi_buffer
[len
] = 0;
7069 plci
->ncpi_buffer
[0] = len
;
7070 if(plci
->B3_prot
== 4)
7071 sendf(plci
->appl
,_CONNECT_B3_I
,Id
,0,"s","");
7075 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[plci
->appl
->Id
-1])
7076 & ((1L << PRIVATE_FAX_SUB_SEP_PWD
) | (1L << PRIVATE_FAX_NONSTANDARD
)))
7078 plci
->ncpi_buffer
[++len
] = 0;
7079 plci
->ncpi_buffer
[++len
] = 0;
7080 plci
->ncpi_buffer
[++len
] = 0;
7081 plci
->ncpi_buffer
[0] = len
;
7084 sendf(plci
->appl
,_CONNECT_B3_I
,Id
,0,"S",plci
->ncpi_buffer
);
7086 sendf(plci
->appl
,_DISCONNECT_B3_I
,Id
,0,"wS",info
,plci
->ncpi_buffer
);
7087 plci
->ncpi_state
= 0;
7088 sig_req(plci
,HANGUP
,0);
7090 plci
->State
= OUTG_DIS_PENDING
;
7093 else if ((a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
7094 && ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5))
7095 && ((ncci_state
== INC_DIS_PENDING
) || (ncci_state
== IDLE
)))
7097 if (ncci_state
== IDLE
)
7101 if((plci
->State
==IDLE
|| plci
->State
==SUSPENDING
) && !plci
->channels
){
7102 if(plci
->State
== SUSPENDING
){
7107 "ws", (word
)3, "\x03\x04\x00\x00");
7108 sendf(plci
->appl
, _DISCONNECT_I
, Id
& 0xffffL
, 0, "w", 0);
7115 else if (plci
->channels
)
7117 sendf(plci
->appl
,_DISCONNECT_B3_I
,Id
,0,"wS",info
,plci
->ncpi_buffer
);
7118 plci
->ncpi_state
= 0;
7119 if ((ncci_state
== OUTG_REJ_PENDING
)
7120 && ((plci
->B3_prot
!= B3_T90NL
) && (plci
->B3_prot
!= B3_ISO8208
) && (plci
->B3_prot
!= B3_X25_DCE
)))
7122 sig_req(plci
,HANGUP
,0);
7124 plci
->State
= OUTG_DIS_PENDING
;
7129 a
->ncci_state
[ncci
] = INC_RES_PENDING
;
7130 sendf(plci
->appl
,_RESET_B3_I
,Id
,0,"S",plci
->ncpi_buffer
);
7133 a
->ncci_state
[ncci
] = CONNECTED
;
7134 sendf(plci
->appl
,_RESET_B3_I
,Id
,0,"S",plci
->ncpi_buffer
);
7138 if (!(udata_forwarding_table
[plci
->NL
.RBuffer
->P
[0] >> 5] & (1L << (plci
->NL
.RBuffer
->P
[0] & 0x1f))))
7140 plci
->RData
[0].P
= plci
->internal_ind_buffer
+ (-((int)(long)(plci
->internal_ind_buffer
)) & 3);
7141 plci
->RData
[0].PLength
= INTERNAL_IND_BUFFER_SIZE
;
7142 plci
->NL
.R
= plci
->RData
;
7148 if (((a
->ncci_state
[ncci
] != CONNECTED
) && (plci
->B2_prot
== 1)) /* transparent */
7149 || (a
->ncci_state
[ncci
] == IDLE
)
7150 || (a
->ncci_state
[ncci
] == INC_DIS_PENDING
))
7155 if ((a
->ncci_state
[ncci
] != CONNECTED
)
7156 && (a
->ncci_state
[ncci
] != OUTG_DIS_PENDING
)
7157 && (a
->ncci_state
[ncci
] != OUTG_REJ_PENDING
))
7159 dbug(1,dprintf("flow control"));
7160 plci
->NL
.RNR
= 1; /* flow control */
7161 channel_x_off (plci
, ch
, 0);
7165 NCCIcode
= ncci
| (((word
)a
->Id
) << 8);
7167 /* count all buffers within the Application pool */
7168 /* belonging to the same NCCI. If this is below the */
7169 /* number of buffers available per NCCI we accept */
7170 /* this packet, otherwise we reject it */
7173 for(i
=0; i
<APPLptr
->MaxBuffer
; i
++) {
7174 if(NCCIcode
==APPLptr
->DataNCCI
[i
]) count
++;
7175 if(!APPLptr
->DataNCCI
[i
] && Num
==0xffff) Num
= i
;
7178 if(count
>=APPLptr
->MaxNCCIData
|| Num
==0xffff)
7180 dbug(3,dprintf("Flow-Control"));
7182 if( ++(APPLptr
->NCCIDataFlowCtrlTimer
)>=
7183 (word
)((a
->manufacturer_features
& MANUFACTURER_FEATURE_OOB_CHANNEL
) ? 40 : 2000))
7186 dbug(3,dprintf("DiscardData"));
7188 channel_x_off (plci
, ch
, 0);
7194 APPLptr
->NCCIDataFlowCtrlTimer
= 0;
7197 plci
->RData
[0].P
= ReceiveBufferGet(APPLptr
,Num
);
7198 if(!plci
->RData
[0].P
) {
7200 channel_x_off (plci
, ch
, 0);
7204 APPLptr
->DataNCCI
[Num
] = NCCIcode
;
7205 APPLptr
->DataFlags
[Num
] = (plci
->Id
<<8) | (plci
->NL
.Ind
>>4);
7206 dbug(3,dprintf("Buffer(%d), Max = %d",Num
,APPLptr
->MaxBuffer
));
7209 plci
->RFlags
= plci
->NL
.Ind
>>4;
7210 plci
->RData
[0].PLength
= APPLptr
->MaxDataLength
;
7211 plci
->NL
.R
= plci
->RData
;
7212 if ((plci
->NL
.RLength
!= 0)
7213 && ((plci
->B2_prot
== B2_V120_ASYNC
)
7214 || (plci
->B2_prot
== B2_V120_ASYNC_V42BIS
)
7215 || (plci
->B2_prot
== B2_V120_BIT_TRANSPARENT
)))
7217 plci
->RData
[1].P
= plci
->RData
[0].P
;
7218 plci
->RData
[1].PLength
= plci
->RData
[0].PLength
;
7219 plci
->RData
[0].P
= v120_header_buffer
;
7220 if ((plci
->NL
.RBuffer
->P
[0] & V120_HEADER_EXTEND_BIT
) || (plci
->NL
.RLength
== 1))
7221 plci
->RData
[0].PLength
= 1;
7223 plci
->RData
[0].PLength
= 2;
7224 if (plci
->NL
.RBuffer
->P
[0] & V120_HEADER_BREAK_BIT
)
7225 plci
->RFlags
|= 0x0010;
7226 if (plci
->NL
.RBuffer
->P
[0] & (V120_HEADER_C1_BIT
| V120_HEADER_C2_BIT
))
7227 plci
->RFlags
|= 0x8000;
7232 if((plci
->NL
.Ind
&0x0f)==N_UDATA
)
7233 plci
->RFlags
|= 0x0010;
7235 else if ((plci
->B3_prot
== B3_RTP
) && ((plci
->NL
.Ind
& 0x0f) == N_BDATA
))
7236 plci
->RFlags
|= 0x0001;
7242 data_ack (plci
, ch
);
7250 /*------------------------------------------------------------------*/
7251 /* find a free PLCI */
7252 /*------------------------------------------------------------------*/
7254 static word
get_plci(DIVA_CAPI_ADAPTER
*a
)
7260 for(i
=0;i
<a
->max_plci
&& a
->plci
[i
].Id
;i
++);
7261 if(i
==a
->max_plci
) {
7262 dbug(1,dprintf("get_plci: out of PLCIs"));
7266 plci
->Id
= (byte
)(i
+1);
7274 plci
->relatedPTYPLCI
= NULL
;
7276 plci
->SuppState
= IDLE
;
7279 plci
->B1_resource
= 0;
7284 plci
->m_command
= 0;
7285 init_internal_command_queue (plci
);
7287 plci
->req_in_start
= 0;
7290 plci
->msg_in_write_pos
= MSG_IN_QUEUE_SIZE
;
7291 plci
->msg_in_read_pos
= MSG_IN_QUEUE_SIZE
;
7292 plci
->msg_in_wrap_pos
= MSG_IN_QUEUE_SIZE
;
7294 plci
->data_sent
= false;
7295 plci
->send_disc
= 0;
7296 plci
->sig_global_req
= 0;
7297 plci
->sig_remove_id
= 0;
7298 plci
->nl_global_req
= 0;
7299 plci
->nl_remove_id
= 0;
7301 plci
->manufacturer
= false;
7302 plci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
7303 plci
->spoofed_msg
= 0;
7305 plci
->cr_enquiry
= false;
7306 plci
->hangup_flow_ctrl_timer
= 0;
7308 plci
->ncci_ring_list
= 0;
7309 for(j
=0;j
<MAX_CHANNELS_PER_PLCI
;j
++) plci
->inc_dis_ncci_table
[j
] = 0;
7310 clear_c_ind_mask (plci
);
7311 set_group_ind_mask (plci
);
7312 plci
->fax_connect_info_length
= 0;
7313 plci
->nsf_control_bits
= 0;
7314 plci
->ncpi_state
= 0x00;
7315 plci
->ncpi_buffer
[0] = 0;
7317 plci
->requested_options_conn
= 0;
7318 plci
->requested_options
= 0;
7319 plci
->notifiedcall
= 0;
7320 plci
->vswitchstate
= 0;
7322 plci
->vsprotdialect
= 0;
7323 init_b1_config (plci
);
7324 dbug(1,dprintf("get_plci(%x)",plci
->Id
));
7328 /*------------------------------------------------------------------*/
7329 /* put a parameter in the parameter buffer */
7330 /*------------------------------------------------------------------*/
7332 static void add_p(PLCI
* plci
, byte code
, byte
* p
)
7337 if(p
) p_length
= p
[0];
7338 add_ie(plci
, code
, p
, p_length
);
7341 /*------------------------------------------------------------------*/
7342 /* put a structure in the parameter buffer */
7343 /*------------------------------------------------------------------*/
7344 static void add_s(PLCI
* plci
, byte code
, API_PARSE
* p
)
7346 if(p
) add_ie(plci
, code
, p
->info
, (word
)p
->length
);
7349 /*------------------------------------------------------------------*/
7350 /* put multiple structures in the parameter buffer */
7351 /*------------------------------------------------------------------*/
7352 static void add_ss(PLCI
* plci
, byte code
, API_PARSE
* p
)
7357 dbug(1,dprintf("add_ss(%x,len=%d)",code
,p
->length
));
7358 for(i
=2;i
<(byte
)p
->length
;i
+=p
->info
[i
]+2){
7359 dbug(1,dprintf("add_ss_ie(%x,len=%d)",p
->info
[i
-1],p
->info
[i
]));
7360 add_ie(plci
, p
->info
[i
-1], (byte
*)&(p
->info
[i
]), (word
)p
->info
[i
]);
7365 /*------------------------------------------------------------------*/
7366 /* return the channel number sent by the application in a esc_chi */
7367 /*------------------------------------------------------------------*/
7368 static byte
getChannel(API_PARSE
* p
)
7373 for(i
=2;i
<(byte
)p
->length
;i
+=p
->info
[i
]+2){
7375 if(p
->info
[i
-1]==ESC
&& p
->info
[i
+1]==CHI
) return (p
->info
[i
+2]);
7383 /*------------------------------------------------------------------*/
7384 /* put an information element in the parameter buffer */
7385 /*------------------------------------------------------------------*/
7387 static void add_ie(PLCI
* plci
, byte code
, byte
* p
, word p_length
)
7391 if(!(code
&0x80) && !p_length
) return;
7393 if(plci
->req_in
==plci
->req_in_start
) {
7399 plci
->RBuffer
[plci
->req_in
++] = code
;
7402 plci
->RBuffer
[plci
->req_in
++] = (byte
)p_length
;
7403 for(i
=0;i
<p_length
;i
++) plci
->RBuffer
[plci
->req_in
++] = p
[1+i
];
7406 plci
->RBuffer
[plci
->req_in
++] = 0;
7409 /*------------------------------------------------------------------*/
7410 /* put a unstructured data into the buffer */
7411 /*------------------------------------------------------------------*/
7413 static void add_d(PLCI
*plci
, word length
, byte
*p
)
7417 if(plci
->req_in
==plci
->req_in_start
) {
7423 for(i
=0;i
<length
;i
++) plci
->RBuffer
[plci
->req_in
++] = p
[i
];
7426 /*------------------------------------------------------------------*/
7427 /* put parameters from the Additional Info parameter in the */
7428 /* parameter buffer */
7429 /*------------------------------------------------------------------*/
7431 static void add_ai(PLCI
*plci
, API_PARSE
*ai
)
7434 API_PARSE ai_parms
[5];
7436 for(i
=0;i
<5;i
++) ai_parms
[i
].length
= 0;
7440 if(api_parse(&ai
->info
[1], (word
)ai
->length
, "ssss", ai_parms
))
7443 add_s (plci
,KEY
,&ai_parms
[1]);
7444 add_s (plci
,UUI
,&ai_parms
[2]);
7445 add_ss(plci
,FTY
,&ai_parms
[3]);
7448 /*------------------------------------------------------------------*/
7449 /* put parameter for b1 protocol in the parameter buffer */
7450 /*------------------------------------------------------------------*/
7452 static word
add_b1(PLCI
*plci
, API_PARSE
*bp
, word b_channel_info
,
7455 API_PARSE bp_parms
[8];
7456 API_PARSE mdm_cfg
[9];
7457 API_PARSE global_config
[2];
7459 byte resource
[] = {5,9,13,12,16,39,9,17,17,18};
7460 byte voice_cai
[] = "\x06\x14\x00\x00\x00\x00\x08";
7463 API_PARSE mdm_cfg_v18
[4];
7468 for(i
=0;i
<8;i
++) bp_parms
[i
].length
= 0;
7469 for(i
=0;i
<2;i
++) global_config
[i
].length
= 0;
7471 dbug(1,dprintf("add_b1"));
7472 api_save_msg(bp
, "s", &plci
->B_protocol
);
7474 if(b_channel_info
==2){
7475 plci
->B1_resource
= 0;
7476 adjust_b1_facilities (plci
, plci
->B1_resource
, b1_facilities
);
7477 add_p(plci
, CAI
, "\x01\x00");
7478 dbug(1,dprintf("Cai=1,0 (no resource)"));
7482 if(plci
->tel
== CODEC_PERMANENT
) return 0;
7483 else if(plci
->tel
== CODEC
){
7484 plci
->B1_resource
= 1;
7485 adjust_b1_facilities (plci
, plci
->B1_resource
, b1_facilities
);
7486 add_p(plci
, CAI
, "\x01\x01");
7487 dbug(1,dprintf("Cai=1,1 (Codec)"));
7490 else if(plci
->tel
== ADV_VOICE
){
7491 plci
->B1_resource
= add_b1_facilities (plci
, 9, (word
)(b1_facilities
| B1_FACILITY_VOICE
));
7492 adjust_b1_facilities (plci
, plci
->B1_resource
, (word
)(b1_facilities
| B1_FACILITY_VOICE
));
7493 voice_cai
[1] = plci
->B1_resource
;
7494 PUT_WORD (&voice_cai
[5], plci
->appl
->MaxDataLength
);
7495 add_p(plci
, CAI
, voice_cai
);
7496 dbug(1,dprintf("Cai=1,0x%x (AdvVoice)",voice_cai
[1]));
7499 plci
->call_dir
&= ~(CALL_DIR_ORIGINATE
| CALL_DIR_ANSWER
);
7500 if (plci
->call_dir
& CALL_DIR_OUT
)
7501 plci
->call_dir
|= CALL_DIR_ORIGINATE
;
7502 else if (plci
->call_dir
& CALL_DIR_IN
)
7503 plci
->call_dir
|= CALL_DIR_ANSWER
;
7506 plci
->B1_resource
= 0x5;
7507 adjust_b1_facilities (plci
, plci
->B1_resource
, b1_facilities
);
7508 add_p(plci
, CAI
, "\x01\x05");
7512 dbug(1,dprintf("b_prot_len=%d",(word
)bp
->length
));
7513 if(bp
->length
>256) return _WRONG_MESSAGE_FORMAT
;
7514 if(api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwsssb", bp_parms
))
7516 bp_parms
[6].length
= 0;
7517 if(api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwsss", bp_parms
))
7519 dbug(1,dprintf("b-form.!"));
7520 return _WRONG_MESSAGE_FORMAT
;
7523 else if (api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwssss", bp_parms
))
7525 dbug(1,dprintf("b-form.!"));
7526 return _WRONG_MESSAGE_FORMAT
;
7529 if(bp_parms
[6].length
)
7531 if(api_parse(&bp_parms
[6].info
[1], (word
)bp_parms
[6].length
, "w", global_config
))
7533 return _WRONG_MESSAGE_FORMAT
;
7535 switch(GET_WORD(global_config
[0].info
))
7538 plci
->call_dir
= (plci
->call_dir
& ~CALL_DIR_ANSWER
) | CALL_DIR_ORIGINATE
;
7541 plci
->call_dir
= (plci
->call_dir
& ~CALL_DIR_ORIGINATE
) | CALL_DIR_ANSWER
;
7545 dbug(1,dprintf("call_dir=%04x", plci
->call_dir
));
7548 if ((GET_WORD(bp_parms
[0].info
) == B1_RTP
)
7549 && (plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_RTP
)))
7551 plci
->B1_resource
= add_b1_facilities (plci
, 31, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7552 adjust_b1_facilities (plci
, plci
->B1_resource
, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7553 cai
[1] = plci
->B1_resource
;
7557 PUT_WORD(&cai
[5],plci
->appl
->MaxDataLength
);
7558 for (i
= 0; i
< bp_parms
[3].length
; i
++)
7559 cai
[7+i
] = bp_parms
[3].info
[1+i
];
7560 cai
[0] = 6 + bp_parms
[3].length
;
7561 add_p(plci
, CAI
, cai
);
7566 if ((GET_WORD(bp_parms
[0].info
) == B1_PIAFS
)
7567 && (plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_PIAFS
)))
7569 plci
->B1_resource
= add_b1_facilities (plci
, 35/* PIAFS HARDWARE FACILITY */, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7570 adjust_b1_facilities (plci
, plci
->B1_resource
, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7571 cai
[1] = plci
->B1_resource
;
7575 PUT_WORD(&cai
[5],plci
->appl
->MaxDataLength
);
7577 add_p(plci
, CAI
, cai
);
7582 if ((GET_WORD(bp_parms
[0].info
) >= 32)
7583 || (!((1L << GET_WORD(bp_parms
[0].info
)) & plci
->adapter
->profile
.B1_Protocols
)
7584 && ((GET_WORD(bp_parms
[0].info
) != 3)
7585 || !((1L << B1_HDLC
) & plci
->adapter
->profile
.B1_Protocols
)
7586 || ((bp_parms
[3].length
!= 0) && (GET_WORD(&bp_parms
[3].info
[1]) != 0) && (GET_WORD(&bp_parms
[3].info
[1]) != 56000)))))
7588 return _B1_NOT_SUPPORTED
;
7590 plci
->B1_resource
= add_b1_facilities (plci
, resource
[GET_WORD(bp_parms
[0].info
)],
7591 (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7592 adjust_b1_facilities (plci
, plci
->B1_resource
, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7594 cai
[1] = plci
->B1_resource
;
7595 for (i
=2;i
<sizeof(cai
);i
++) cai
[i
] = 0;
7597 if ((GET_WORD(bp_parms
[0].info
) == B1_MODEM_ALL_NEGOTIATE
)
7598 || (GET_WORD(bp_parms
[0].info
) == B1_MODEM_ASYNC
)
7599 || (GET_WORD(bp_parms
[0].info
) == B1_MODEM_SYNC_HDLC
))
7601 for (i
=0;i
<7;i
++) mdm_cfg
[i
].length
= 0;
7603 if (bp_parms
[3].length
)
7605 if(api_parse(&bp_parms
[3].info
[1],(word
)bp_parms
[3].length
,"wwwwww", mdm_cfg
))
7607 return (_WRONG_MESSAGE_FORMAT
);
7610 cai
[2] = 0; /* Bit rate for adaptation */
7612 dbug(1,dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg
[0].info
)));
7614 PUT_WORD (&cai
[13], 0); /* Min Tx speed */
7615 PUT_WORD (&cai
[15], GET_WORD(mdm_cfg
[0].info
)); /* Max Tx speed */
7616 PUT_WORD (&cai
[17], 0); /* Min Rx speed */
7617 PUT_WORD (&cai
[19], GET_WORD(mdm_cfg
[0].info
)); /* Max Rx speed */
7619 cai
[3] = 0; /* Async framing parameters */
7620 switch (GET_WORD (mdm_cfg
[2].info
))
7622 case 1: /* odd parity */
7623 cai
[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE
| DSP_CAI_ASYNC_PARITY_ODD
);
7624 dbug(1,dprintf("MDM: odd parity"));
7627 case 2: /* even parity */
7628 cai
[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE
| DSP_CAI_ASYNC_PARITY_EVEN
);
7629 dbug(1,dprintf("MDM: even parity"));
7633 dbug(1,dprintf("MDM: no parity"));
7637 switch (GET_WORD (mdm_cfg
[3].info
))
7639 case 1: /* 2 stop bits */
7640 cai
[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS
;
7641 dbug(1,dprintf("MDM: 2 stop bits"));
7645 dbug(1,dprintf("MDM: 1 stop bit"));
7649 switch (GET_WORD (mdm_cfg
[1].info
))
7652 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5
;
7653 dbug(1,dprintf("MDM: 5 bits"));
7657 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6
;
7658 dbug(1,dprintf("MDM: 6 bits"));
7662 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7
;
7663 dbug(1,dprintf("MDM: 7 bits"));
7667 dbug(1,dprintf("MDM: 8 bits"));
7671 cai
[7] = 0; /* Line taking options */
7672 cai
[8] = 0; /* Modulation negotiation options */
7673 cai
[9] = 0; /* Modulation options */
7675 if (((plci
->call_dir
& CALL_DIR_ORIGINATE
) != 0) ^ ((plci
->call_dir
& CALL_DIR_OUT
) != 0))
7677 cai
[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION
;
7678 dbug(1, dprintf("MDM: Reverse direction"));
7681 if (GET_WORD (mdm_cfg
[4].info
) & MDM_CAPI_DISABLE_RETRAIN
)
7683 cai
[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN
;
7684 dbug(1, dprintf("MDM: Disable retrain"));
7687 if (GET_WORD (mdm_cfg
[4].info
) & MDM_CAPI_DISABLE_RING_TONE
)
7689 cai
[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE
| DSP_CAI_MODEM_DISABLE_ANSWER_TONE
;
7690 dbug(1, dprintf("MDM: Disable ring tone"));
7693 if (GET_WORD (mdm_cfg
[4].info
) & MDM_CAPI_GUARD_1800
)
7695 cai
[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ
;
7696 dbug(1, dprintf("MDM: 1800 guard tone"));
7698 else if (GET_WORD (mdm_cfg
[4].info
) & MDM_CAPI_GUARD_550
)
7700 cai
[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ
;
7701 dbug(1, dprintf("MDM: 550 guard tone"));
7704 if ((GET_WORD (mdm_cfg
[5].info
) & 0x00ff) == MDM_CAPI_NEG_V100
)
7706 cai
[8] |= DSP_CAI_MODEM_NEGOTIATE_V100
;
7707 dbug(1, dprintf("MDM: V100"));
7709 else if ((GET_WORD (mdm_cfg
[5].info
) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS
)
7711 cai
[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS
;
7712 dbug(1, dprintf("MDM: IN CLASS"));
7714 else if ((GET_WORD (mdm_cfg
[5].info
) & 0x00ff) == MDM_CAPI_NEG_DISABLED
)
7716 cai
[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED
;
7717 dbug(1, dprintf("MDM: DISABLED"));
7721 if ((plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_V18
))
7722 && (GET_WORD(mdm_cfg
[5].info
) & 0x8000)) /* Private V.18 enable */
7724 plci
->requested_options
|= 1L << PRIVATE_V18
;
7726 if (GET_WORD(mdm_cfg
[5].info
) & 0x4000) /* Private VOWN enable */
7727 plci
->requested_options
|= 1L << PRIVATE_VOWN
;
7729 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
-1])
7730 & ((1L << PRIVATE_V18
) | (1L << PRIVATE_VOWN
)))
7732 if (!api_parse(&bp_parms
[3].info
[1],(word
)bp_parms
[3].length
,"wwwwwws", mdm_cfg
))
7735 if (mdm_cfg
[6].length
>= 4)
7737 d
= GET_DWORD(&mdm_cfg
[6].info
[1]);
7738 cai
[7] |= (byte
) d
; /* line taking options */
7739 cai
[9] |= (byte
)(d
>> 8); /* modulation options */
7740 cai
[++i
] = (byte
)(d
>> 16); /* vown modulation options */
7741 cai
[++i
] = (byte
)(d
>> 24);
7742 if (mdm_cfg
[6].length
>= 8)
7744 d
= GET_DWORD(&mdm_cfg
[6].info
[5]);
7745 cai
[10] |= (byte
) d
; /* disabled modulations mask */
7746 cai
[11] |= (byte
)(d
>> 8);
7747 if (mdm_cfg
[6].length
>= 12)
7749 d
= GET_DWORD(&mdm_cfg
[6].info
[9]);
7750 cai
[12] = (byte
) d
; /* enabled modulations mask */
7751 cai
[++i
] = (byte
)(d
>> 8); /* vown enabled modulations */
7752 cai
[++i
] = (byte
)(d
>> 16);
7753 cai
[++i
] = (byte
)(d
>> 24);
7755 if (mdm_cfg
[6].length
>= 14)
7757 w
= GET_WORD(&mdm_cfg
[6].info
[13]);
7759 PUT_WORD(&cai
[13], w
); /* min tx speed */
7760 if (mdm_cfg
[6].length
>= 16)
7762 w
= GET_WORD(&mdm_cfg
[6].info
[15]);
7764 PUT_WORD(&cai
[15], w
); /* max tx speed */
7765 if (mdm_cfg
[6].length
>= 18)
7767 w
= GET_WORD(&mdm_cfg
[6].info
[17]);
7769 PUT_WORD(&cai
[17], w
); /* min rx speed */
7770 if (mdm_cfg
[6].length
>= 20)
7772 w
= GET_WORD(&mdm_cfg
[6].info
[19]);
7774 PUT_WORD(&cai
[19], w
); /* max rx speed */
7775 if (mdm_cfg
[6].length
>= 22)
7777 w
= GET_WORD(&mdm_cfg
[6].info
[21]);
7778 cai
[23] = (byte
)(-((short) w
)); /* transmit level */
7779 if (mdm_cfg
[6].length
>= 24)
7781 w
= GET_WORD(&mdm_cfg
[6].info
[23]);
7782 cai
[22] |= (byte
) w
; /* info options mask */
7783 cai
[21] |= (byte
)(w
>> 8); /* disabled symbol rates */
7795 if (!api_parse(&bp_parms
[3].info
[1],(word
)bp_parms
[3].length
,"wwwwwwss", mdm_cfg
))
7797 if (!api_parse(&mdm_cfg
[7].info
[1],(word
)mdm_cfg
[7].length
,"sss", mdm_cfg_v18
))
7799 for (n
= 0; n
< 3; n
++)
7801 cai
[i
] = (byte
)(mdm_cfg_v18
[n
].length
);
7802 for (j
= 1; j
< ((word
)(cai
[i
] + 1)); j
++)
7803 cai
[i
+j
] = mdm_cfg_v18
[n
].info
[j
];
7808 cai
[0] = (byte
)(i
- 1);
7814 if(GET_WORD(bp_parms
[0].info
)==2 || /* V.110 async */
7815 GET_WORD(bp_parms
[0].info
)==3 ) /* V.110 sync */
7817 if(bp_parms
[3].length
){
7818 dbug(1,dprintf("V.110,%d",GET_WORD(&bp_parms
[3].info
[1])));
7819 switch(GET_WORD(&bp_parms
[3].info
[1])){ /* Rate */
7822 if(GET_WORD(bp_parms
[0].info
)==3){ /* V.110 sync 56k */
7823 dbug(1,dprintf("56k sync HSCX"));
7828 else if(GET_WORD(bp_parms
[0].info
)==2){
7829 dbug(1,dprintf("56k async DSP"));
7833 case 50: cai
[2] = 1; break;
7834 case 75: cai
[2] = 1; break;
7835 case 110: cai
[2] = 1; break;
7836 case 150: cai
[2] = 1; break;
7837 case 200: cai
[2] = 1; break;
7838 case 300: cai
[2] = 1; break;
7839 case 600: cai
[2] = 1; break;
7840 case 1200: cai
[2] = 2; break;
7841 case 2400: cai
[2] = 3; break;
7842 case 4800: cai
[2] = 4; break;
7843 case 7200: cai
[2] = 10; break;
7844 case 9600: cai
[2] = 5; break;
7845 case 12000: cai
[2] = 13; break;
7846 case 24000: cai
[2] = 0; break;
7847 case 14400: cai
[2] = 11; break;
7848 case 19200: cai
[2] = 6; break;
7849 case 28800: cai
[2] = 12; break;
7850 case 38400: cai
[2] = 7; break;
7851 case 48000: cai
[2] = 8; break;
7852 case 76: cai
[2] = 15; break; /* 75/1200 */
7853 case 1201: cai
[2] = 14; break; /* 1200/75 */
7854 case 56001: cai
[2] = 9; break; /* V.110 56000 */
7857 return _B1_PARM_NOT_SUPPORTED
;
7860 if (cai
[1] == 13) /* v.110 async */
7862 if (bp_parms
[3].length
>= 8)
7864 switch (GET_WORD (&bp_parms
[3].info
[3]))
7867 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5
;
7870 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6
;
7873 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7
;
7876 switch (GET_WORD (&bp_parms
[3].info
[5]))
7878 case 1: /* odd parity */
7879 cai
[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE
| DSP_CAI_ASYNC_PARITY_ODD
);
7881 case 2: /* even parity */
7882 cai
[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE
| DSP_CAI_ASYNC_PARITY_EVEN
);
7885 switch (GET_WORD (&bp_parms
[3].info
[7]))
7887 case 1: /* 2 stop bits */
7888 cai
[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS
;
7894 else if(cai
[1]==8 || GET_WORD(bp_parms
[0].info
)==3 ){
7895 dbug(1,dprintf("V.110 default 56k sync"));
7901 dbug(1,dprintf("V.110 default 9600 async"));
7905 PUT_WORD(&cai
[5],plci
->appl
->MaxDataLength
);
7906 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]));
7907 /* HexDump ("CAI", sizeof(cai), &cai[0]); */
7909 add_p(plci
, CAI
, cai
);
7913 /*------------------------------------------------------------------*/
7914 /* put parameter for b2 and B3 protocol in the parameter buffer */
7915 /*------------------------------------------------------------------*/
7917 static word
add_b23(PLCI
*plci
, API_PARSE
*bp
)
7919 word i
, fax_control_bits
;
7921 byte SAPI
= 0x40; /* default SAPI 16 for x.31 */
7922 API_PARSE bp_parms
[8];
7923 API_PARSE
* b1_config
;
7924 API_PARSE
* b2_config
;
7925 API_PARSE b2_config_parms
[8];
7926 API_PARSE
* b3_config
;
7927 API_PARSE b3_config_parms
[6];
7928 API_PARSE global_config
[2];
7930 static byte llc
[3] = {2,0,0};
7931 static byte dlc
[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
7932 static byte nlc
[256];
7933 static byte lli
[12] = {1,1};
7935 const byte llc2_out
[] = {1,2,4,6,2,0,0,0, X75_V42BIS
,V120_L2
,V120_V42BIS
,V120_L2
,6};
7936 const byte llc2_in
[] = {1,3,4,6,3,0,0,0, X75_V42BIS
,V120_L2
,V120_V42BIS
,V120_L2
,6};
7938 const byte llc3
[] = {4,3,2,2,6,6,0};
7939 const byte header
[] = {0,2,3,3,0,0,0};
7941 for(i
=0;i
<8;i
++) bp_parms
[i
].length
= 0;
7942 for(i
=0;i
<6;i
++) b2_config_parms
[i
].length
= 0;
7943 for(i
=0;i
<5;i
++) b3_config_parms
[i
].length
= 0;
7947 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL
)
7949 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_OOB_CHANNEL
)
7952 if ((lli
[1] & 0x02) && (diva_xdi_extended_features
& DIVA_CAPI_USE_CMA
)) {
7954 if (plci
->rx_dma_descriptor
<= 0) {
7955 plci
->rx_dma_descriptor
=diva_get_dma_descriptor(plci
,&plci
->rx_dma_magic
);
7956 if (plci
->rx_dma_descriptor
>= 0)
7957 plci
->rx_dma_descriptor
++;
7959 if (plci
->rx_dma_descriptor
> 0) {
7962 lli
[2] = (byte
)(plci
->rx_dma_descriptor
- 1);
7963 lli
[3] = (byte
)plci
->rx_dma_magic
;
7964 lli
[4] = (byte
)(plci
->rx_dma_magic
>> 8);
7965 lli
[5] = (byte
)(plci
->rx_dma_magic
>> 16);
7966 lli
[6] = (byte
)(plci
->rx_dma_magic
>> 24);
7970 if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci
->adapter
)) {
7974 dbug(1,dprintf("add_b23"));
7975 api_save_msg(bp
, "s", &plci
->B_protocol
);
7977 if(!bp
->length
&& plci
->tel
)
7979 plci
->adv_nl
= true;
7980 dbug(1,dprintf("Default adv.Nl"));
7981 add_p(plci
,LLI
,lli
);
7982 plci
->B2_prot
= 1 /*XPARENT*/;
7983 plci
->B3_prot
= 0 /*XPARENT*/;
7986 add_p(plci
, LLC
, llc
);
7988 PUT_WORD(&dlc
[1],plci
->appl
->MaxDataLength
);
7989 add_p(plci
, DLC
, dlc
);
7993 if(!bp
->length
) /*default*/
7995 dbug(1,dprintf("ret default"));
7996 add_p(plci
,LLI
,lli
);
7997 plci
->B2_prot
= 0 /*X.75 */;
7998 plci
->B3_prot
= 0 /*XPARENT*/;
8001 add_p(plci
, LLC
, llc
);
8003 PUT_WORD(&dlc
[1],plci
->appl
->MaxDataLength
);
8004 add_p(plci
, DLC
, dlc
);
8007 dbug(1,dprintf("b_prot_len=%d",(word
)bp
->length
));
8008 if((word
)bp
->length
> 256) return _WRONG_MESSAGE_FORMAT
;
8010 if(api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwsssb", bp_parms
))
8012 bp_parms
[6].length
= 0;
8013 if(api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwsss", bp_parms
))
8015 dbug(1,dprintf("b-form.!"));
8016 return _WRONG_MESSAGE_FORMAT
;
8019 else if (api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwssss", bp_parms
))
8021 dbug(1,dprintf("b-form.!"));
8022 return _WRONG_MESSAGE_FORMAT
;
8025 if(plci
->tel
==ADV_VOICE
) /* transparent B on advanced voice */
8027 if(GET_WORD(bp_parms
[1].info
)!=1
8028 || GET_WORD(bp_parms
[2].info
)!=0) return _B2_NOT_SUPPORTED
;
8029 plci
->adv_nl
= true;
8031 else if(plci
->tel
) return _B2_NOT_SUPPORTED
;
8034 if ((GET_WORD(bp_parms
[1].info
) == B2_RTP
)
8035 && (GET_WORD(bp_parms
[2].info
) == B3_RTP
)
8036 && (plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_RTP
)))
8038 add_p(plci
,LLI
,lli
);
8039 plci
->B2_prot
= (byte
) GET_WORD(bp_parms
[1].info
);
8040 plci
->B3_prot
= (byte
) GET_WORD(bp_parms
[2].info
);
8041 llc
[1] = (plci
->call_dir
& (CALL_DIR_ORIGINATE
| CALL_DIR_FORCE_OUTG_NL
)) ? 14 : 13;
8043 add_p(plci
, LLC
, llc
);
8045 PUT_WORD(&dlc
[1],plci
->appl
->MaxDataLength
);
8046 dlc
[3] = 3; /* Addr A */
8047 dlc
[4] = 1; /* Addr B */
8048 dlc
[5] = 7; /* modulo mode */
8049 dlc
[6] = 7; /* window size */
8050 dlc
[7] = 0; /* XID len Lo */
8051 dlc
[8] = 0; /* XID len Hi */
8052 for (i
= 0; i
< bp_parms
[4].length
; i
++)
8053 dlc
[9+i
] = bp_parms
[4].info
[1+i
];
8054 dlc
[0] = (byte
)(8 + bp_parms
[4].length
);
8055 add_p(plci
, DLC
, dlc
);
8056 for (i
= 0; i
< bp_parms
[5].length
; i
++)
8057 nlc
[1+i
] = bp_parms
[5].info
[1+i
];
8058 nlc
[0] = (byte
)(bp_parms
[5].length
);
8059 add_p(plci
, NLC
, nlc
);
8065 if ((GET_WORD(bp_parms
[1].info
) >= 32)
8066 || (!((1L << GET_WORD(bp_parms
[1].info
)) & plci
->adapter
->profile
.B2_Protocols
)
8067 && ((GET_WORD(bp_parms
[1].info
) != B2_PIAFS
)
8068 || !(plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_PIAFS
)))))
8071 return _B2_NOT_SUPPORTED
;
8073 if ((GET_WORD(bp_parms
[2].info
) >= 32)
8074 || !((1L << GET_WORD(bp_parms
[2].info
)) & plci
->adapter
->profile
.B3_Protocols
))
8076 return _B3_NOT_SUPPORTED
;
8078 if ((GET_WORD(bp_parms
[1].info
) != B2_SDLC
)
8079 && ((GET_WORD(bp_parms
[0].info
) == B1_MODEM_ALL_NEGOTIATE
)
8080 || (GET_WORD(bp_parms
[0].info
) == B1_MODEM_ASYNC
)
8081 || (GET_WORD(bp_parms
[0].info
) == B1_MODEM_SYNC_HDLC
)))
8083 return (add_modem_b23 (plci
, bp_parms
));
8086 add_p(plci
,LLI
,lli
);
8088 plci
->B2_prot
= (byte
) GET_WORD(bp_parms
[1].info
);
8089 plci
->B3_prot
= (byte
) GET_WORD(bp_parms
[2].info
);
8090 if(plci
->B2_prot
==12) SAPI
= 0; /* default SAPI D-channel */
8092 if(bp_parms
[6].length
)
8094 if(api_parse(&bp_parms
[6].info
[1], (word
)bp_parms
[6].length
, "w", global_config
))
8096 return _WRONG_MESSAGE_FORMAT
;
8098 switch(GET_WORD(global_config
[0].info
))
8101 plci
->call_dir
= (plci
->call_dir
& ~CALL_DIR_ANSWER
) | CALL_DIR_ORIGINATE
;
8104 plci
->call_dir
= (plci
->call_dir
& ~CALL_DIR_ORIGINATE
) | CALL_DIR_ANSWER
;
8108 dbug(1,dprintf("call_dir=%04x", plci
->call_dir
));
8111 if (plci
->B2_prot
== B2_PIAFS
)
8114 /* IMPLEMENT_PIAFS */
8116 llc
[1] = (plci
->call_dir
& (CALL_DIR_ORIGINATE
| CALL_DIR_FORCE_OUTG_NL
)) ?
8117 llc2_out
[GET_WORD(bp_parms
[1].info
)] : llc2_in
[GET_WORD(bp_parms
[1].info
)];
8119 llc
[2] = llc3
[GET_WORD(bp_parms
[2].info
)];
8121 add_p(plci
, LLC
, llc
);
8124 PUT_WORD(&dlc
[1], plci
->appl
->MaxDataLength
+
8125 header
[GET_WORD(bp_parms
[2].info
)]);
8127 b1_config
= &bp_parms
[3];
8129 if(plci
->B3_prot
== 4
8130 || plci
->B3_prot
== 5)
8132 for (i
=0;i
<sizeof(T30_INFO
);i
++) nlc
[i
] = 0;
8133 nlc
[0] = sizeof(T30_INFO
);
8134 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
8135 ((T30_INFO
*)&nlc
[1])->operating_mode
= T30_OPERATING_MODE_CAPI
;
8136 ((T30_INFO
*)&nlc
[1])->rate_div_2400
= 0xff;
8137 if(b1_config
->length
>=2)
8139 ((T30_INFO
*)&nlc
[1])->rate_div_2400
= (byte
)(GET_WORD(&b1_config
->info
[1])/2400);
8142 b2_config
= &bp_parms
[4];
8145 if (llc
[1] == PIAFS_CRC
)
8147 if (plci
->B3_prot
!= B3_TRANSPARENT
)
8149 return _B_STACK_NOT_SUPPORTED
;
8151 if(b2_config
->length
&& api_parse(&b2_config
->info
[1], (word
)b2_config
->length
, "bwww", b2_config_parms
)) {
8152 return _WRONG_MESSAGE_FORMAT
;
8154 PUT_WORD(&dlc
[1],plci
->appl
->MaxDataLength
);
8155 dlc
[3] = 0; /* Addr A */
8156 dlc
[4] = 0; /* Addr B */
8157 dlc
[5] = 0; /* modulo mode */
8158 dlc
[6] = 0; /* window size */
8159 if (b2_config
->length
>= 7){
8162 dlc
[ 9] = b2_config_parms
[0].info
[0]; /* PIAFS protocol Speed configuration */
8163 dlc
[10] = b2_config_parms
[1].info
[0]; /* V.42bis P0 */
8164 dlc
[11] = b2_config_parms
[1].info
[1]; /* V.42bis P0 */
8165 dlc
[12] = b2_config_parms
[2].info
[0]; /* V.42bis P1 */
8166 dlc
[13] = b2_config_parms
[2].info
[1]; /* V.42bis P1 */
8167 dlc
[14] = b2_config_parms
[3].info
[0]; /* V.42bis P2 */
8168 dlc
[15] = b2_config_parms
[3].info
[1]; /* V.42bis P2 */
8170 if(b2_config
->length
>= 8) { /* PIAFS control abilities */
8172 dlc
[16] = 2; /* Length of PIAFS extention */
8173 dlc
[17] = PIAFS_UDATA_ABILITIES
; /* control (UDATA) ability */
8174 dlc
[18] = b2_config_parms
[4].info
[0]; /* value */
8178 else /* default values, 64K, variable, no compression */
8182 dlc
[ 9] = 0x03; /* PIAFS protocol Speed configuration */
8183 dlc
[10] = 0x03; /* V.42bis P0 */
8184 dlc
[11] = 0; /* V.42bis P0 */
8185 dlc
[12] = 0; /* V.42bis P1 */
8186 dlc
[13] = 0; /* V.42bis P1 */
8187 dlc
[14] = 0; /* V.42bis P2 */
8188 dlc
[15] = 0; /* V.42bis P2 */
8191 add_p(plci
, DLC
, dlc
);
8195 if ((llc
[1] == V120_L2
) || (llc
[1] == V120_V42BIS
))
8197 if (plci
->B3_prot
!= B3_TRANSPARENT
)
8198 return _B_STACK_NOT_SUPPORTED
;
8201 PUT_WORD (&dlc
[1], GET_WORD (&dlc
[1]) + 2);
8206 if (b2_config
->length
!= 0)
8208 if((llc
[1]==V120_V42BIS
) && api_parse(&b2_config
->info
[1], (word
)b2_config
->length
, "bbbbwww", b2_config_parms
)) {
8209 return _WRONG_MESSAGE_FORMAT
;
8211 dlc
[3] = (byte
)((b2_config
->info
[2] << 3) | ((b2_config
->info
[1] >> 5) & 0x04));
8212 dlc
[4] = (byte
)((b2_config
->info
[1] << 1) | 0x01);
8213 if (b2_config
->info
[3] != 128)
8215 dbug(1,dprintf("1D-dlc= %x %x %x %x %x", dlc
[0], dlc
[1], dlc
[2], dlc
[3], dlc
[4]));
8216 return _B2_PARM_NOT_SUPPORTED
;
8218 dlc
[5] = (byte
)(b2_config
->info
[3] - 1);
8219 dlc
[6] = b2_config
->info
[4];
8220 if(llc
[1]==V120_V42BIS
){
8221 if (b2_config
->length
>= 10){
8224 dlc
[ 9] = b2_config_parms
[4].info
[0];
8225 dlc
[10] = b2_config_parms
[4].info
[1];
8226 dlc
[11] = b2_config_parms
[5].info
[0];
8227 dlc
[12] = b2_config_parms
[5].info
[1];
8228 dlc
[13] = b2_config_parms
[6].info
[0];
8229 dlc
[14] = b2_config_parms
[6].info
[1];
8231 dbug(1,dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms
[4].info
[0], b2_config_parms
[4].info
[1]));
8232 dbug(1,dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms
[5].info
[0], b2_config_parms
[5].info
[1]));
8233 dbug(1,dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms
[6].info
[0], b2_config_parms
[6].info
[1]));
8243 if(b2_config
->length
)
8245 dbug(1,dprintf("B2-Config"));
8246 if(llc
[1]==X75_V42BIS
){
8247 if(api_parse(&b2_config
->info
[1], (word
)b2_config
->length
, "bbbbwww", b2_config_parms
))
8249 return _WRONG_MESSAGE_FORMAT
;
8253 if(api_parse(&b2_config
->info
[1], (word
)b2_config
->length
, "bbbbs", b2_config_parms
))
8255 return _WRONG_MESSAGE_FORMAT
;
8258 /* if B2 Protocol is LAPD, b2_config structure is different */
8262 if(b2_config
->length
>=1) dlc
[2] = b2_config
->info
[1]; /* TEI */
8264 if( (b2_config
->length
>=2) && (plci
->B2_prot
==12) )
8266 SAPI
= b2_config
->info
[2]; /* SAPI */
8269 if( (b2_config
->length
>=3) && (b2_config
->info
[3]==128) )
8271 dlc
[3] = 127; /* Mode */
8275 dlc
[3] = 7; /* Mode */
8278 if(b2_config
->length
>=4) dlc
[4] = b2_config
->info
[4]; /* Window */
8280 dbug(1,dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc
[0], dlc
[1], dlc
[2], dlc
[3], dlc
[4]));
8281 if(b2_config
->length
>5) return _B2_PARM_NOT_SUPPORTED
;
8285 dlc
[0] = (byte
)(b2_config_parms
[4].length
+6);
8286 dlc
[3] = b2_config
->info
[1];
8287 dlc
[4] = b2_config
->info
[2];
8288 if(b2_config
->info
[3]!=8 && b2_config
->info
[3]!=128){
8289 dbug(1,dprintf("1D-dlc= %x %x %x %x %x", dlc
[0], dlc
[1], dlc
[2], dlc
[3], dlc
[4]));
8290 return _B2_PARM_NOT_SUPPORTED
;
8293 dlc
[5] = (byte
)(b2_config
->info
[3]-1);
8294 dlc
[6] = b2_config
->info
[4];
8296 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]));
8297 return _B2_PARM_NOT_SUPPORTED
;
8300 if(llc
[1]==X75_V42BIS
) {
8301 if (b2_config
->length
>= 10){
8304 dlc
[ 9] = b2_config_parms
[4].info
[0];
8305 dlc
[10] = b2_config_parms
[4].info
[1];
8306 dlc
[11] = b2_config_parms
[5].info
[0];
8307 dlc
[12] = b2_config_parms
[5].info
[1];
8308 dlc
[13] = b2_config_parms
[6].info
[0];
8309 dlc
[14] = b2_config_parms
[6].info
[1];
8311 dbug(1,dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms
[4].info
[0], b2_config_parms
[4].info
[1]));
8312 dbug(1,dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms
[5].info
[0], b2_config_parms
[5].info
[1]));
8313 dbug(1,dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms
[6].info
[0], b2_config_parms
[6].info
[1]));
8321 PUT_WORD(&dlc
[7], (word
)b2_config_parms
[4].length
);
8322 for(i
=0; i
<b2_config_parms
[4].length
; i
++)
8323 dlc
[11+i
] = b2_config_parms
[4].info
[1+i
];
8328 add_p(plci
, DLC
, dlc
);
8330 b3_config
= &bp_parms
[5];
8331 if(b3_config
->length
)
8333 if(plci
->B3_prot
== 4
8334 || plci
->B3_prot
== 5)
8336 if(api_parse(&b3_config
->info
[1], (word
)b3_config
->length
, "wwss", b3_config_parms
))
8338 return _WRONG_MESSAGE_FORMAT
;
8340 i
= GET_WORD((byte
*)(b3_config_parms
[0].info
));
8341 ((T30_INFO
*)&nlc
[1])->resolution
= (byte
)(((i
& 0x0001) ||
8342 ((plci
->B3_prot
== 4) && (((byte
)(GET_WORD((byte
*)b3_config_parms
[1].info
))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200
: 0);
8343 ((T30_INFO
*)&nlc
[1])->data_format
= (byte
)(GET_WORD((byte
*)b3_config_parms
[1].info
));
8344 fax_control_bits
= T30_CONTROL_BIT_ALL_FEATURES
;
8345 if ((((T30_INFO
*)&nlc
[1])->rate_div_2400
!= 0) && (((T30_INFO
*)&nlc
[1])->rate_div_2400
<= 6))
8346 fax_control_bits
&= ~T30_CONTROL_BIT_ENABLE_V34FAX
;
8347 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
8350 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
-1])
8351 & (1L << PRIVATE_FAX_PAPER_FORMATS
))
8353 ((T30_INFO
*)&nlc
[1])->resolution
|= T30_RESOLUTION_R8_1540
|
8354 T30_RESOLUTION_R16_1540_OR_400
| T30_RESOLUTION_300_300
|
8355 T30_RESOLUTION_INCH_BASED
| T30_RESOLUTION_METRIC_BASED
;
8358 ((T30_INFO
*)&nlc
[1])->recording_properties
=
8359 T30_RECORDING_WIDTH_ISO_A3
|
8360 (T30_RECORDING_LENGTH_UNLIMITED
<< 2) |
8361 (T30_MIN_SCANLINE_TIME_00_00_00
<< 4);
8363 if(plci
->B3_prot
== 5)
8365 if (i
& 0x0002) /* Accept incoming fax-polling requests */
8366 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_POLLING
;
8367 if (i
& 0x2000) /* Do not use MR compression */
8368 fax_control_bits
&= ~T30_CONTROL_BIT_ENABLE_2D_CODING
;
8369 if (i
& 0x4000) /* Do not use MMR compression */
8370 fax_control_bits
&= ~T30_CONTROL_BIT_ENABLE_T6_CODING
;
8371 if (i
& 0x8000) /* Do not use ECM */
8372 fax_control_bits
&= ~T30_CONTROL_BIT_ENABLE_ECM
;
8373 if (plci
->fax_connect_info_length
!= 0)
8375 ((T30_INFO
*)&nlc
[1])->resolution
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->resolution
;
8376 ((T30_INFO
*)&nlc
[1])->data_format
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->data_format
;
8377 ((T30_INFO
*)&nlc
[1])->recording_properties
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->recording_properties
;
8378 fax_control_bits
|= GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
) &
8379 (T30_CONTROL_BIT_REQUEST_POLLING
| T30_CONTROL_BIT_MORE_DOCUMENTS
);
8382 /* copy station id to NLC */
8385 if(i
<b3_config_parms
[2].length
)
8387 ((T30_INFO
*)&nlc
[1])->station_id
[i
] = ((byte
*)b3_config_parms
[2].info
)[1+i
];
8391 ((T30_INFO
*)&nlc
[1])->station_id
[i
] = ' ';
8394 ((T30_INFO
*)&nlc
[1])->station_id_len
= 20;
8395 /* copy head line to NLC */
8396 if(b3_config_parms
[3].length
)
8398 byte
*head_line
= (void *) ((T30_INFO
*)&nlc
[1] + 1);
8400 pos
= (byte
)(fax_head_line_time (&(((T30_INFO
*)&nlc
[1])->station_id
[20])));
8403 if (CAPI_MAX_DATE_TIME_LENGTH
+ 2 + b3_config_parms
[3].length
> CAPI_MAX_HEAD_LINE_SPACE
)
8407 head_line
[pos
++] = ' ';
8408 head_line
[pos
++] = ' ';
8409 len
= (byte
)b3_config_parms
[2].length
;
8412 if (CAPI_MAX_DATE_TIME_LENGTH
+ 2 + len
+ 2 + b3_config_parms
[3].length
<= CAPI_MAX_HEAD_LINE_SPACE
)
8414 for (i
= 0; i
< len
; i
++)
8415 head_line
[pos
++] = ((byte
*)b3_config_parms
[2].info
)[1+i
];
8416 head_line
[pos
++] = ' ';
8417 head_line
[pos
++] = ' ';
8422 len
= (byte
)b3_config_parms
[3].length
;
8423 if (len
> CAPI_MAX_HEAD_LINE_SPACE
- pos
)
8424 len
= (byte
)(CAPI_MAX_HEAD_LINE_SPACE
- pos
);
8425 ((T30_INFO
*)&nlc
[1])->head_line_len
= (byte
)(pos
+ len
);
8426 nlc
[0] += (byte
)(pos
+ len
);
8427 for (i
= 0; i
< len
; i
++)
8428 head_line
[pos
++] = ((byte
*)b3_config_parms
[3].info
)[1+i
];
8431 ((T30_INFO
*)&nlc
[1])->head_line_len
= 0;
8433 plci
->nsf_control_bits
= 0;
8434 if(plci
->B3_prot
== 5)
8436 if ((plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_FAX_SUB_SEP_PWD
))
8437 && (GET_WORD((byte
*)b3_config_parms
[1].info
) & 0x8000)) /* Private SUB/SEP/PWD enable */
8439 plci
->requested_options
|= 1L << PRIVATE_FAX_SUB_SEP_PWD
;
8441 if ((plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_FAX_NONSTANDARD
))
8442 && (GET_WORD((byte
*)b3_config_parms
[1].info
) & 0x4000)) /* Private non-standard facilities enable */
8444 plci
->requested_options
|= 1L << PRIVATE_FAX_NONSTANDARD
;
8446 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
-1])
8447 & ((1L << PRIVATE_FAX_SUB_SEP_PWD
) | (1L << PRIVATE_FAX_NONSTANDARD
)))
8449 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
-1])
8450 & (1L << PRIVATE_FAX_SUB_SEP_PWD
))
8452 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_SUBADDRESS
| T30_CONTROL_BIT_ACCEPT_PASSWORD
;
8453 if (fax_control_bits
& T30_CONTROL_BIT_ACCEPT_POLLING
)
8454 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_SEL_POLLING
;
8457 pos
= (byte
)(offsetof(T30_INFO
, station_id
) + 20);
8458 if (pos
< plci
->fax_connect_info_length
)
8460 for (i
= 1 + plci
->fax_connect_info_buffer
[pos
]; i
!= 0; i
--)
8461 nlc
[++len
] = plci
->fax_connect_info_buffer
[pos
++];
8465 if (pos
< plci
->fax_connect_info_length
)
8467 for (i
= 1 + plci
->fax_connect_info_buffer
[pos
]; i
!= 0; i
--)
8468 nlc
[++len
] = plci
->fax_connect_info_buffer
[pos
++];
8472 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
-1])
8473 & (1L << PRIVATE_FAX_NONSTANDARD
))
8475 if ((pos
< plci
->fax_connect_info_length
) && (plci
->fax_connect_info_buffer
[pos
] != 0))
8477 if ((plci
->fax_connect_info_buffer
[pos
] >= 3) && (plci
->fax_connect_info_buffer
[pos
+1] >= 2))
8478 plci
->nsf_control_bits
= GET_WORD(&plci
->fax_connect_info_buffer
[pos
+2]);
8479 for (i
= 1 + plci
->fax_connect_info_buffer
[pos
]; i
!= 0; i
--)
8480 nlc
[++len
] = plci
->fax_connect_info_buffer
[pos
++];
8484 if(api_parse(&b3_config
->info
[1], (word
)b3_config
->length
, "wwsss", b3_config_parms
))
8486 dbug(1,dprintf("non-standard facilities info missing or wrong format"));
8491 if ((b3_config_parms
[4].length
>= 3) && (b3_config_parms
[4].info
[1] >= 2))
8492 plci
->nsf_control_bits
= GET_WORD(&b3_config_parms
[4].info
[2]);
8493 nlc
[++len
] = (byte
)(b3_config_parms
[4].length
);
8494 for (i
= 0; i
< b3_config_parms
[4].length
; i
++)
8495 nlc
[++len
] = b3_config_parms
[4].info
[1+i
];
8500 if ((plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_ENABLE_NSF
)
8501 && (plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_NEGOTIATE_RESP
))
8503 ((T30_INFO
*)&nlc
[1])->operating_mode
= T30_OPERATING_MODE_CAPI_NEG
;
8508 PUT_WORD(&(((T30_INFO
*)&nlc
[1])->control_bits_low
), fax_control_bits
);
8509 len
= (byte
)(offsetof(T30_INFO
, station_id
) + 20);
8510 for (i
= 0; i
< len
; i
++)
8511 plci
->fax_connect_info_buffer
[i
] = nlc
[1+i
];
8512 ((T30_INFO
*) plci
->fax_connect_info_buffer
)->head_line_len
= 0;
8513 i
+= ((T30_INFO
*)&nlc
[1])->head_line_len
;
8515 plci
->fax_connect_info_buffer
[len
++] = nlc
[++i
];
8516 plci
->fax_connect_info_length
= len
;
8521 if(b3_config
->length
!=16)
8522 return _B3_PARM_NOT_SUPPORTED
;
8523 for(i
=0; i
<12; i
++) nlc
[1+i
] = b3_config
->info
[1+i
];
8524 if(GET_WORD(&b3_config
->info
[13])!=8 && GET_WORD(&b3_config
->info
[13])!=128)
8525 return _B3_PARM_NOT_SUPPORTED
;
8526 nlc
[13] = b3_config
->info
[13];
8527 if(GET_WORD(&b3_config
->info
[15])>=nlc
[13])
8528 return _B3_PARM_NOT_SUPPORTED
;
8529 nlc
[14] = b3_config
->info
[15];
8534 if (plci
->B3_prot
== 4
8535 || plci
->B3_prot
== 5 /*T.30 - FAX*/ ) return _B3_PARM_NOT_SUPPORTED
;
8537 add_p(plci
, NLC
, nlc
);
8541 /*----------------------------------------------------------------*/
8542 /* make the same as add_b23, but only for the modem related */
8543 /* L2 and L3 B-Chan protocol. */
8545 /* Enabled L2 and L3 Configurations: */
8546 /* If L1 == Modem all negotiation */
8547 /* only L2 == Modem with full negotiation is allowed */
8548 /* If L1 == Modem async or sync */
8549 /* only L2 == Transparent is allowed */
8550 /* L3 == Modem or L3 == Transparent are allowed */
8551 /* B2 Configuration for modem: */
8552 /* word : enable/disable compression, bitoptions */
8553 /* B3 Configuration for modem: */
8555 /*----------------------------------------------------------------*/
8556 static word
add_modem_b23 (PLCI
* plci
, API_PARSE
* bp_parms
)
8558 static byte lli
[12] = {1,1};
8559 static byte llc
[3] = {2,0,0};
8560 static byte dlc
[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
8561 API_PARSE mdm_config
[2];
8565 for(i
=0;i
<2;i
++) mdm_config
[i
].length
= 0;
8566 for(i
=0;i
<sizeof(dlc
);i
++) dlc
[i
] = 0;
8568 if (((GET_WORD(bp_parms
[0].info
) == B1_MODEM_ALL_NEGOTIATE
)
8569 && (GET_WORD(bp_parms
[1].info
) != B2_MODEM_EC_COMPRESSION
))
8570 || ((GET_WORD(bp_parms
[0].info
) != B1_MODEM_ALL_NEGOTIATE
)
8571 && (GET_WORD(bp_parms
[1].info
) != B2_TRANSPARENT
)))
8573 return (_B_STACK_NOT_SUPPORTED
);
8575 if ((GET_WORD(bp_parms
[2].info
) != B3_MODEM
)
8576 && (GET_WORD(bp_parms
[2].info
) != B3_TRANSPARENT
))
8578 return (_B_STACK_NOT_SUPPORTED
);
8581 plci
->B2_prot
= (byte
) GET_WORD(bp_parms
[1].info
);
8582 plci
->B3_prot
= (byte
) GET_WORD(bp_parms
[2].info
);
8584 if ((GET_WORD(bp_parms
[1].info
) == B2_MODEM_EC_COMPRESSION
) && bp_parms
[4].length
)
8586 if (api_parse (&bp_parms
[4].info
[1],
8587 (word
)bp_parms
[4].length
, "w",
8590 return (_WRONG_MESSAGE_FORMAT
);
8592 b2_config
= GET_WORD(mdm_config
[0].info
);
8595 /* OK, L2 is modem */
8599 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL
)
8601 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_OOB_CHANNEL
)
8604 if ((lli
[1] & 0x02) && (diva_xdi_extended_features
& DIVA_CAPI_USE_CMA
)) {
8606 if (plci
->rx_dma_descriptor
<= 0) {
8607 plci
->rx_dma_descriptor
=diva_get_dma_descriptor(plci
,&plci
->rx_dma_magic
);
8608 if (plci
->rx_dma_descriptor
>= 0)
8609 plci
->rx_dma_descriptor
++;
8611 if (plci
->rx_dma_descriptor
> 0) {
8614 lli
[2] = (byte
)(plci
->rx_dma_descriptor
- 1);
8615 lli
[3] = (byte
)plci
->rx_dma_magic
;
8616 lli
[4] = (byte
)(plci
->rx_dma_magic
>> 8);
8617 lli
[5] = (byte
)(plci
->rx_dma_magic
>> 16);
8618 lli
[6] = (byte
)(plci
->rx_dma_magic
>> 24);
8622 if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci
->adapter
)) {
8626 llc
[1] = (plci
->call_dir
& (CALL_DIR_ORIGINATE
| CALL_DIR_FORCE_OUTG_NL
)) ?
8627 /*V42*/ 10 : /*V42_IN*/ 9;
8628 llc
[2] = 4; /* pass L3 always transparent */
8629 add_p(plci
, LLI
, lli
);
8630 add_p(plci
, LLC
, llc
);
8632 PUT_WORD (&dlc
[i
], plci
->appl
->MaxDataLength
);
8634 if (GET_WORD(bp_parms
[1].info
) == B2_MODEM_EC_COMPRESSION
)
8636 if (bp_parms
[4].length
)
8638 dbug(1, dprintf("MDM b2_config=%02x", b2_config
));
8639 dlc
[i
++] = 3; /* Addr A */
8640 dlc
[i
++] = 1; /* Addr B */
8641 dlc
[i
++] = 7; /* modulo mode */
8642 dlc
[i
++] = 7; /* window size */
8643 dlc
[i
++] = 0; /* XID len Lo */
8644 dlc
[i
++] = 0; /* XID len Hi */
8646 if (b2_config
& MDM_B2_DISABLE_V42bis
)
8648 dlc
[i
] |= DLC_MODEMPROT_DISABLE_V42_V42BIS
;
8650 if (b2_config
& MDM_B2_DISABLE_MNP
)
8652 dlc
[i
] |= DLC_MODEMPROT_DISABLE_MNP_MNP5
;
8654 if (b2_config
& MDM_B2_DISABLE_TRANS
)
8656 dlc
[i
] |= DLC_MODEMPROT_REQUIRE_PROTOCOL
;
8658 if (b2_config
& MDM_B2_DISABLE_V42
)
8660 dlc
[i
] |= DLC_MODEMPROT_DISABLE_V42_DETECT
;
8662 if (b2_config
& MDM_B2_DISABLE_COMP
)
8664 dlc
[i
] |= DLC_MODEMPROT_DISABLE_COMPRESSION
;
8671 dlc
[i
++] = 3; /* Addr A */
8672 dlc
[i
++] = 1; /* Addr B */
8673 dlc
[i
++] = 7; /* modulo mode */
8674 dlc
[i
++] = 7; /* window size */
8675 dlc
[i
++] = 0; /* XID len Lo */
8676 dlc
[i
++] = 0; /* XID len Hi */
8677 dlc
[i
++] = DLC_MODEMPROT_DISABLE_V42_V42BIS
|
8678 DLC_MODEMPROT_DISABLE_MNP_MNP5
|
8679 DLC_MODEMPROT_DISABLE_V42_DETECT
|
8680 DLC_MODEMPROT_DISABLE_COMPRESSION
;
8682 dlc
[0] = (byte
)(i
- 1);
8683 /* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
8684 add_p(plci
, DLC
, dlc
);
8689 /*------------------------------------------------------------------*/
8690 /* send a request for the signaling entity */
8691 /*------------------------------------------------------------------*/
8693 void sig_req(PLCI
* plci
, byte req
, byte Id
)
8696 if(plci
->adapter
->adapter_disabled
) return;
8697 dbug(1,dprintf("sig_req(%x)",req
));
8699 plci
->sig_remove_id
= plci
->Sig
.Id
;
8700 if(plci
->req_in
==plci
->req_in_start
) {
8702 plci
->RBuffer
[plci
->req_in
++] = 0;
8704 PUT_WORD(&plci
->RBuffer
[plci
->req_in_start
], plci
->req_in
-plci
->req_in_start
-2);
8705 plci
->RBuffer
[plci
->req_in
++] = Id
; /* sig/nl flag */
8706 plci
->RBuffer
[plci
->req_in
++] = req
; /* request */
8707 plci
->RBuffer
[plci
->req_in
++] = 0; /* channel */
8708 plci
->req_in_start
= plci
->req_in
;
8711 /*------------------------------------------------------------------*/
8712 /* send a request for the network layer entity */
8713 /*------------------------------------------------------------------*/
8715 static void nl_req_ncci(PLCI
*plci
, byte req
, byte ncci
)
8718 if(plci
->adapter
->adapter_disabled
) return;
8719 dbug(1,dprintf("nl_req %02x %02x %02x", plci
->Id
, req
, ncci
));
8722 plci
->nl_remove_id
= plci
->NL
.Id
;
8723 ncci_remove (plci
, 0, (byte
)(ncci
!= 0));
8726 if(plci
->req_in
==plci
->req_in_start
) {
8728 plci
->RBuffer
[plci
->req_in
++] = 0;
8730 PUT_WORD(&plci
->RBuffer
[plci
->req_in_start
], plci
->req_in
-plci
->req_in_start
-2);
8731 plci
->RBuffer
[plci
->req_in
++] = 1; /* sig/nl flag */
8732 plci
->RBuffer
[plci
->req_in
++] = req
; /* request */
8733 plci
->RBuffer
[plci
->req_in
++] = plci
->adapter
->ncci_ch
[ncci
]; /* channel */
8734 plci
->req_in_start
= plci
->req_in
;
8737 static void send_req(PLCI
*plci
)
8744 if(plci
->adapter
->adapter_disabled
) return;
8745 channel_xmit_xon (plci
);
8747 /* if nothing to do, return */
8748 if(plci
->req_in
==plci
->req_out
) return;
8749 dbug(1,dprintf("send_req(in=%d,out=%d)",plci
->req_in
,plci
->req_out
));
8751 if(plci
->nl_req
|| plci
->sig_req
) return;
8753 l
= GET_WORD(&plci
->RBuffer
[plci
->req_out
]);
8755 plci
->XData
[0].P
= &plci
->RBuffer
[plci
->req_out
];
8757 if(plci
->RBuffer
[plci
->req_out
]==1)
8761 e
->Req
= plci
->nl_req
= plci
->RBuffer
[plci
->req_out
++];
8762 e
->ReqCh
= plci
->RBuffer
[plci
->req_out
++];
8766 plci
->RBuffer
[plci
->req_out
-4] = CAI
;
8767 plci
->RBuffer
[plci
->req_out
-3] = 1;
8768 plci
->RBuffer
[plci
->req_out
-2] = (plci
->Sig
.Id
==0xff) ? 0 : plci
->Sig
.Id
;
8769 plci
->RBuffer
[plci
->req_out
-1] = 0;
8771 plci
->nl_global_req
= plci
->nl_req
;
8773 dbug(1,dprintf("%x:NLREQ(%x:%x:%x)",plci
->adapter
->Id
,e
->Id
,e
->Req
,e
->ReqCh
));
8778 if(plci
->RBuffer
[plci
->req_out
])
8779 e
->Id
= plci
->RBuffer
[plci
->req_out
];
8781 e
->Req
= plci
->sig_req
= plci
->RBuffer
[plci
->req_out
++];
8782 e
->ReqCh
= plci
->RBuffer
[plci
->req_out
++];
8784 plci
->sig_global_req
= plci
->sig_req
;
8785 dbug(1,dprintf("%x:SIGREQ(%x:%x:%x)",plci
->adapter
->Id
,e
->Id
,e
->Req
,e
->ReqCh
));
8787 plci
->XData
[0].PLength
= l
;
8789 plci
->adapter
->request(e
);
8790 dbug(1,dprintf("send_ok"));
8793 void send_data(PLCI
* plci
)
8795 DIVA_CAPI_ADAPTER
* a
;
8796 DATA_B3_DESC
* data
;
8800 if (!plci
->nl_req
&& plci
->ncci_ring_list
)
8803 ncci
= plci
->ncci_ring_list
;
8806 ncci
= a
->ncci_next
[ncci
];
8807 ncci_ptr
= &(a
->ncci
[ncci
]);
8808 if (!(a
->ncci_ch
[ncci
]
8809 && (a
->ch_flow_control
[a
->ncci_ch
[ncci
]] & N_OK_FC_PENDING
)))
8811 if (ncci_ptr
->data_pending
)
8813 if ((a
->ncci_state
[ncci
] == CONNECTED
)
8814 || (a
->ncci_state
[ncci
] == INC_ACT_PENDING
)
8815 || (plci
->send_disc
== ncci
))
8817 data
= &(ncci_ptr
->DBuffer
[ncci_ptr
->data_out
]);
8818 if ((plci
->B2_prot
== B2_V120_ASYNC
)
8819 || (plci
->B2_prot
== B2_V120_ASYNC_V42BIS
)
8820 || (plci
->B2_prot
== B2_V120_BIT_TRANSPARENT
))
8822 plci
->NData
[1].P
= TransmitBufferGet (plci
->appl
, data
->P
);
8823 plci
->NData
[1].PLength
= data
->Length
;
8824 if (data
->Flags
& 0x10)
8825 plci
->NData
[0].P
= v120_break_header
;
8827 plci
->NData
[0].P
= v120_default_header
;
8828 plci
->NData
[0].PLength
= 1 ;
8830 plci
->NL
.Req
= plci
->nl_req
= (byte
)((data
->Flags
&0x07)<<4 |N_DATA
);
8834 plci
->NData
[0].P
= TransmitBufferGet (plci
->appl
, data
->P
);
8835 plci
->NData
[0].PLength
= data
->Length
;
8836 if (data
->Flags
& 0x10)
8837 plci
->NL
.Req
= plci
->nl_req
= (byte
)N_UDATA
;
8839 else if ((plci
->B3_prot
== B3_RTP
) && (data
->Flags
& 0x01))
8840 plci
->NL
.Req
= plci
->nl_req
= (byte
)N_BDATA
;
8843 plci
->NL
.Req
= plci
->nl_req
= (byte
)((data
->Flags
&0x07)<<4 |N_DATA
);
8845 plci
->NL
.X
= plci
->NData
;
8846 plci
->NL
.ReqCh
= a
->ncci_ch
[ncci
];
8847 dbug(1,dprintf("%x:DREQ(%x:%x)",a
->Id
,plci
->NL
.Id
,plci
->NL
.Req
));
8848 plci
->data_sent
= true;
8849 plci
->data_sent_ptr
= data
->P
;
8850 a
->request(&plci
->NL
);
8853 cleanup_ncci_data (plci
, ncci
);
8856 else if (plci
->send_disc
== ncci
)
8858 /* dprintf("N_DISC"); */
8859 plci
->NData
[0].PLength
= 0;
8860 plci
->NL
.ReqCh
= a
->ncci_ch
[ncci
];
8861 plci
->NL
.Req
= plci
->nl_req
= N_DISC
;
8862 a
->request(&plci
->NL
);
8863 plci
->command
= _DISCONNECT_B3_R
;
8864 plci
->send_disc
= 0;
8867 } while (!plci
->nl_req
&& (ncci
!= plci
->ncci_ring_list
));
8868 plci
->ncci_ring_list
= ncci
;
8872 static void listen_check(DIVA_CAPI_ADAPTER
*a
)
8876 byte activnotifiedcalls
= 0;
8878 dbug(1,dprintf("listen_check(%d,%d)",a
->listen_active
,a
->max_listen
));
8879 if (!remove_started
&& !a
->adapter_disabled
)
8881 for(i
=0;i
<a
->max_plci
;i
++)
8883 plci
= &(a
->plci
[i
]);
8884 if(plci
->notifiedcall
) activnotifiedcalls
++;
8886 dbug(1,dprintf("listen_check(%d)",activnotifiedcalls
));
8888 for(i
=a
->listen_active
; i
< ((word
)(a
->max_listen
+activnotifiedcalls
)); i
++) {
8889 if((j
=get_plci(a
))) {
8891 plci
= &a
->plci
[j
-1];
8892 plci
->State
= LISTENING
;
8894 add_p(plci
,OAD
,"\x01\xfd");
8896 add_p(plci
,KEY
,"\x04\x43\x41\x32\x30");
8898 add_p(plci
,CAI
,"\x01\xc0");
8899 add_p(plci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
8900 add_p(plci
,LLI
,"\x01\xc4"); /* support Dummy CR FAC + MWI + SpoofNotify */
8901 add_p(plci
,SHIFT
|6,NULL
);
8902 add_p(plci
,SIN
,"\x02\x00\x00");
8903 plci
->internal_command
= LISTEN_SIG_ASSIGN_PEND
; /* do indicate_req if OK */
8904 sig_req(plci
,ASSIGN
,DSIG_ID
);
8911 /*------------------------------------------------------------------*/
8912 /* functions for all parameters sent in INDs */
8913 /*------------------------------------------------------------------*/
8915 static void IndParse(PLCI
*plci
, word
*parms_id
, byte
**parms
, byte multiIEsize
)
8917 word ploc
; /* points to current location within packet */
8929 in
= plci
->Sig
.RBuffer
->P
;
8930 for(i
=0; i
<parms_id
[0]; i
++) /* multiIE parms_id contains just the 1st */
8931 { /* element but parms array is larger */
8932 parms
[i
] = (byte
*)"";
8934 for(i
=0; i
<multiIEsize
; i
++)
8936 parms
[i
] = (byte
*)"";
8939 while(ploc
<plci
->Sig
.RBuffer
->length
-1) {
8941 /* read information element id and length */
8945 /* w &=0xf0; removed, cannot detect congestion levels */
8946 /* upper 4 bit masked with w==SHIFT now */
8950 wlen
= (byte
)(in
[ploc
+1]+1);
8952 /* check if length valid (not exceeding end of packet) */
8953 if((ploc
+wlen
) > 270) return ;
8954 if(lock
& 0x80) lock
&=0x7f;
8955 else codeset
= lock
;
8957 if((w
&0xf0)==SHIFT
) {
8959 if(!(codeset
& 0x08)) lock
= (byte
)(codeset
& 7);
8964 if(w
==ESC
&& wlen
>=3) code
= in
[ploc
+2] |0x800;
8966 code
|= (codeset
<<8);
8968 for(i
=1; i
<parms_id
[0]+1 && parms_id
[i
]!=code
; i
++);
8970 if(i
<parms_id
[0]+1) {
8971 if(!multiIEsize
) { /* with multiIEs use next field index, */
8972 mIEindex
= i
-1; /* with normal IEs use same index like parms_id */
8975 parms
[mIEindex
] = &in
[ploc
+1];
8976 dbug(1,dprintf("mIE[%d]=0x%x",*parms
[mIEindex
],in
[ploc
]));
8978 || parms_id
[i
]==CONN_NR
8979 || parms_id
[i
]==CAD
) {
8980 if(in
[ploc
+2] &0x80) {
8981 in
[ploc
+0] = (byte
)(in
[ploc
+1]+1);
8982 in
[ploc
+1] = (byte
)(in
[ploc
+2] &0x7f);
8984 parms
[mIEindex
] = &in
[ploc
];
8987 mIEindex
++; /* effects multiIEs only */
8996 /*------------------------------------------------------------------*/
8997 /* try to match a cip from received BC and HLC */
8998 /*------------------------------------------------------------------*/
9000 static byte
ie_compare(byte
*ie1
, byte
*ie2
)
9003 if(!ie1
|| ! ie2
) return false;
9004 if(!ie1
[0]) return false;
9005 for(i
=0;i
<(word
)(ie1
[0]+1);i
++) if(ie1
[i
]!=ie2
[i
]) return false;
9009 static word
find_cip(DIVA_CAPI_ADAPTER
*a
, byte
*bc
, byte
*hlc
)
9014 for(i
=9;i
&& !ie_compare(bc
,cip_bc
[i
][a
->u_law
]);i
--);
9017 (!ie_compare(bc
,cip_bc
[j
][a
->u_law
]) || !ie_compare(hlc
,cip_hlc
[j
])); j
++);
9023 static byte
AddInfo(byte
**add_i
,
9033 /* facility is a nested structure */
9034 /* FTY can be more than once */
9036 if (esc_chi
[0] && !(esc_chi
[esc_chi
[0]] & 0x7f))
9038 add_i
[0] = (byte
*)"\x02\x02\x00"; /* use neither b nor d channel */
9043 add_i
[0] = (byte
*)"";
9047 add_i
[3] = (byte
*)"";
9050 { /* facility array found */
9051 for(i
=0,j
=1;i
<MAX_MULTI_IE
&& fty_i
[i
][0];i
++)
9053 dbug(1,dprintf("AddIFac[%d]",fty_i
[i
][0]));
9057 facility
[j
++]=0x1c; /* copy fac IE */
9058 for(k
=0;k
<=flen
;k
++,j
++)
9060 facility
[j
]=fty_i
[i
][k
];
9061 /* dbug(1,dprintf("%x ",facility[j])); */
9065 add_i
[3] = facility
;
9067 /* dbug(1,dprintf("FacArrLen=%d ",len)); */
9068 len
= add_i
[0][0]+add_i
[1][0]+add_i
[2][0]+add_i
[3][0];
9069 len
+= 4; /* calculate length of all */
9073 /*------------------------------------------------------------------*/
9074 /* voice and codec features */
9075 /*------------------------------------------------------------------*/
9077 static void SetVoiceChannel(PLCI
*plci
, byte
*chi
, DIVA_CAPI_ADAPTER
*a
)
9079 byte voice_chi
[] = "\x02\x18\x01";
9082 channel
= chi
[chi
[0]]&0x3;
9083 dbug(1,dprintf("ExtDevON(Ch=0x%x)",channel
));
9084 voice_chi
[2] = (channel
) ? channel
: 1;
9085 add_p(plci
,FTY
,"\x02\x01\x07"); /* B On, default on 1 */
9086 add_p(plci
,ESC
,voice_chi
); /* Channel */
9087 sig_req(plci
,TEL_CTRL
,0);
9089 if(a
->AdvSignalPLCI
)
9091 adv_voice_write_coefs (a
->AdvSignalPLCI
, ADV_VOICE_WRITE_ACTIVATION
);
9095 static void VoiceChannelOff(PLCI
*plci
)
9097 dbug(1,dprintf("ExtDevOFF"));
9098 add_p(plci
,FTY
,"\x02\x01\x08"); /* B Off */
9099 sig_req(plci
,TEL_CTRL
,0);
9101 if(plci
->adapter
->AdvSignalPLCI
)
9103 adv_voice_clear_config (plci
->adapter
->AdvSignalPLCI
);
9108 static word
AdvCodecSupport(DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
,
9114 /* check if hardware supports handset with hook states (adv.codec) */
9115 /* or if just a on board codec is supported */
9116 /* the advanced codec plci is just for internal use */
9118 /* diva Pro with on-board codec: */
9119 if(a
->profile
.Global_Options
& HANDSET
)
9121 /* new call, but hook states are already signalled */
9124 if(a
->AdvSignalAppl
!=appl
|| a
->AdvSignalPLCI
)
9126 dbug(1,dprintf("AdvSigPlci=0x%x",a
->AdvSignalPLCI
));
9127 return 0x2001; /* codec in use by another application */
9131 a
->AdvSignalPLCI
= plci
;
9132 plci
->tel
=ADV_VOICE
;
9134 return 0; /* adv codec still used */
9138 splci
= &a
->plci
[j
-1];
9139 splci
->tel
= CODEC_PERMANENT
;
9140 /* hook_listen indicates if a facility_req with handset/hook support */
9141 /* was sent. Otherwise if just a call on an external device was made */
9142 /* the codec will be used but the hook info will be discarded (just */
9143 /* the external controller is in use */
9144 if(hook_listen
) splci
->State
= ADVANCED_VOICE_SIG
;
9147 splci
->State
= ADVANCED_VOICE_NOSIG
;
9150 plci
->spoofed_msg
= SPOOFING_REQUIRED
;
9152 /* indicate D-ch connect if */
9153 } /* codec is connected OK */
9156 a
->AdvSignalPLCI
= plci
;
9157 plci
->tel
=ADV_VOICE
;
9159 a
->AdvSignalAppl
= appl
;
9160 a
->AdvCodecFLAG
= true;
9161 a
->AdvCodecPLCI
= splci
;
9162 add_p(splci
,CAI
,"\x01\x15");
9163 add_p(splci
,LLI
,"\x01\x00");
9164 add_p(splci
,ESC
,"\x02\x18\x00");
9165 add_p(splci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
9166 splci
->internal_command
= PERM_COD_ASSIGN
;
9167 dbug(1,dprintf("Codec Assign"));
9168 sig_req(splci
,ASSIGN
,DSIG_ID
);
9173 return 0x2001; /* wrong state, no more plcis */
9176 else if(a
->profile
.Global_Options
& ON_BOARD_CODEC
)
9178 if(hook_listen
) return 0x300B; /* Facility not supported */
9179 /* no hook with SCOM */
9180 if(plci
!=NULL
) plci
->tel
= CODEC
;
9181 dbug(1,dprintf("S/SCOM codec"));
9182 /* first time we use the scom-s codec we must shut down the internal */
9183 /* handset application of the card. This can be done by an assign with */
9184 /* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/
9185 if(!a
->scom_appl_disable
){
9186 if((j
=get_plci(a
))) {
9187 splci
= &a
->plci
[j
-1];
9188 add_p(splci
,CAI
,"\x01\x80");
9189 add_p(splci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
9190 sig_req(splci
,ASSIGN
,0xC0); /* 0xc0 is the TEL_ID */
9192 a
->scom_appl_disable
= true;
9195 return 0x2001; /* wrong state, no more plcis */
9199 else return 0x300B; /* Facility not supported */
9205 static void CodecIdCheck(DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
)
9208 dbug(1,dprintf("CodecIdCheck"));
9210 if(a
->AdvSignalPLCI
== plci
)
9212 dbug(1,dprintf("PLCI owns codec"));
9213 VoiceChannelOff(a
->AdvCodecPLCI
);
9214 if(a
->AdvCodecPLCI
->State
== ADVANCED_VOICE_NOSIG
)
9216 dbug(1,dprintf("remove temp codec PLCI"));
9217 plci_remove(a
->AdvCodecPLCI
);
9218 a
->AdvCodecFLAG
= 0;
9219 a
->AdvCodecPLCI
= NULL
;
9220 a
->AdvSignalAppl
= NULL
;
9222 a
->AdvSignalPLCI
= NULL
;
9226 /* -------------------------------------------------------------------
9227 Ask for physical address of card on PCI bus
9228 ------------------------------------------------------------------- */
9229 static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER
* a
,
9230 IDI_SYNC_REQ
* preq
) {
9232 if (diva_xdi_extended_features
& DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR
) {
9233 ENTITY
* e
= (ENTITY
*)preq
;
9235 e
->user
[0] = a
->Id
- 1;
9236 preq
->xdi_sdram_bar
.info
.bar
= 0;
9237 preq
->xdi_sdram_bar
.Req
= 0;
9238 preq
->xdi_sdram_bar
.Rc
= IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR
;
9242 a
->sdram_bar
= preq
->xdi_sdram_bar
.info
.bar
;
9243 dbug(3,dprintf("A(%d) SDRAM BAR = %08x", a
->Id
, a
->sdram_bar
));
9247 /* -------------------------------------------------------------------
9248 Ask XDI about extended features
9249 ------------------------------------------------------------------- */
9250 static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER
* a
) {
9251 IDI_SYNC_REQ
* preq
;
9252 char buffer
[ ((sizeof(preq
->xdi_extended_features
)+4) > sizeof(ENTITY
)) ? (sizeof(preq
->xdi_extended_features
)+4) : sizeof(ENTITY
)];
9255 preq
= (IDI_SYNC_REQ
*)&buffer
[0];
9257 if (!diva_xdi_extended_features
) {
9258 ENTITY
* e
= (ENTITY
*)preq
;
9259 diva_xdi_extended_features
|= 0x80000000;
9261 e
->user
[0] = a
->Id
- 1;
9262 preq
->xdi_extended_features
.Req
= 0;
9263 preq
->xdi_extended_features
.Rc
= IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES
;
9264 preq
->xdi_extended_features
.info
.buffer_length_in_bytes
= sizeof(features
);
9265 preq
->xdi_extended_features
.info
.features
= &features
[0];
9269 if (features
[0] & DIVA_XDI_EXTENDED_FEATURES_VALID
) {
9271 Check features located in the byte '0'
9273 if (features
[0] & DIVA_XDI_EXTENDED_FEATURE_CMA
) {
9274 diva_xdi_extended_features
|= DIVA_CAPI_USE_CMA
;
9276 if (features
[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA
) {
9277 diva_xdi_extended_features
|= DIVA_CAPI_XDI_PROVIDES_RX_DMA
;
9278 dbug(1,dprintf("XDI provides RxDMA"));
9280 if (features
[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR
) {
9281 diva_xdi_extended_features
|= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR
;
9283 if (features
[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC
) {
9284 diva_xdi_extended_features
|= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL
;
9285 dbug(3,dprintf("XDI provides NO_CANCEL_RC feature"));
9291 diva_ask_for_xdi_sdram_bar (a
, preq
);
9294 /*------------------------------------------------------------------*/
9296 /*------------------------------------------------------------------*/
9297 /* called from OS specific part after init time to get the Law */
9298 /* a-law (Euro) and u-law (us,japan) use different BCs in the Setup message */
9299 void AutomaticLaw(DIVA_CAPI_ADAPTER
*a
)
9304 if(a
->automatic_law
) {
9307 if((j
=get_plci(a
))) {
9308 diva_get_extended_adapter_features (a
);
9309 splci
= &a
->plci
[j
-1];
9310 a
->automatic_lawPLCI
= splci
;
9311 a
->automatic_law
= 1;
9312 add_p(splci
,CAI
,"\x01\x80");
9313 add_p(splci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
9314 splci
->internal_command
= USELAW_REQ
;
9317 sig_req(splci
,ASSIGN
,DSIG_ID
);
9322 /* called from OS specific part if an application sends an Capi20Release */
9323 word
CapiRelease(word Id
)
9325 word i
, j
, appls_found
;
9328 DIVA_CAPI_ADAPTER
*a
;
9332 dbug(0,dprintf("A: CapiRelease(Id==0)"));
9333 return (_WRONG_APPL_ID
);
9336 this = &application
[Id
-1]; /* get application pointer */
9338 for(i
=0,appls_found
=0; i
<max_appl
; i
++)
9340 if(application
[i
].Id
) /* an application has been found */
9346 for(i
=0; i
<max_adapter
; i
++) /* scan all adapters... */
9351 a
->Info_Mask
[Id
-1] = 0;
9352 a
->CIP_Mask
[Id
-1] = 0;
9353 a
->Notification_Mask
[Id
-1] = 0;
9354 a
->codec_listen
[Id
-1] = NULL
;
9355 a
->requested_options_table
[Id
-1] = 0;
9356 for(j
=0; j
<a
->max_plci
; j
++) /* and all PLCIs connected */
9357 { /* with this application */
9359 if(plci
->Id
) /* if plci owns no application */
9360 { /* it may be not jet connected */
9361 if(plci
->State
==INC_CON_PENDING
9362 || plci
->State
==INC_CON_ALERT
)
9364 if(test_c_ind_mask_bit (plci
, (word
)(Id
-1)))
9366 clear_c_ind_mask_bit (plci
, (word
)(Id
-1));
9367 if(c_ind_mask_empty (plci
))
9369 sig_req(plci
,HANGUP
,0);
9371 plci
->State
= OUTG_DIS_PENDING
;
9375 if(test_c_ind_mask_bit (plci
, (word
)(Id
-1)))
9377 clear_c_ind_mask_bit (plci
, (word
)(Id
-1));
9378 if(c_ind_mask_empty (plci
))
9387 if(plci
->appl
==this)
9397 if(a
->flag_dynamic_l1_down
)
9399 if(appls_found
==1) /* last application does a capi release */
9403 plci
= &a
->plci
[j
-1];
9405 add_p(plci
,OAD
,"\x01\xfd");
9406 add_p(plci
,CAI
,"\x01\x80");
9407 add_p(plci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
9408 add_p(plci
,SHIFT
|6,NULL
);
9409 add_p(plci
,SIN
,"\x02\x00\x00");
9410 plci
->internal_command
= REM_L1_SIG_ASSIGN_PEND
;
9411 sig_req(plci
,ASSIGN
,DSIG_ID
);
9412 add_p(plci
,FTY
,"\x02\xff\x06"); /* l1 down */
9413 sig_req(plci
,SIG_CTRL
,0);
9418 if(a
->AdvSignalAppl
==this)
9420 this->NullCREnable
= false;
9421 if (a
->AdvCodecPLCI
)
9423 plci_remove(a
->AdvCodecPLCI
);
9424 a
->AdvCodecPLCI
->tel
= 0;
9425 a
->AdvCodecPLCI
->adv_nl
= 0;
9427 a
->AdvSignalAppl
= NULL
;
9428 a
->AdvSignalPLCI
= NULL
;
9429 a
->AdvCodecFLAG
= 0;
9430 a
->AdvCodecPLCI
= NULL
;
9440 static word
plci_remove_check(PLCI
*plci
)
9442 if(!plci
) return true;
9443 if(!plci
->NL
.Id
&& c_ind_mask_empty (plci
))
9445 if(plci
->Sig
.Id
== 0xff)
9449 dbug(1,dprintf("plci_remove_complete(%x)",plci
->Id
));
9450 dbug(1,dprintf("tel=0x%x,Sig=0x%x",plci
->tel
,plci
->Sig
.Id
));
9453 CodecIdCheck(plci
->adapter
, plci
);
9454 clear_b1_config (plci
);
9455 ncci_remove (plci
, 0, false);
9456 plci_free_msg_in_queue (plci
);
9457 channel_flow_control_remove (plci
);
9462 plci
->notifiedcall
= 0;
9464 listen_check(plci
->adapter
);
9472 /*------------------------------------------------------------------*/
9474 static byte
plci_nl_busy (PLCI
*plci
)
9476 /* only applicable for non-multiplexed protocols */
9477 return (plci
->nl_req
9478 || (plci
->ncci_ring_list
9479 && plci
->adapter
->ncci_ch
[plci
->ncci_ring_list
]
9480 && (plci
->adapter
->ch_flow_control
[plci
->adapter
->ncci_ch
[plci
->ncci_ring_list
]] & N_OK_FC_PENDING
)));
9484 /*------------------------------------------------------------------*/
9485 /* DTMF facilities */
9486 /*------------------------------------------------------------------*/
9495 } dtmf_digit_map
[] =
9497 { 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK
},
9498 { 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR
},
9499 { 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0
},
9500 { 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1
},
9501 { 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2
},
9502 { 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3
},
9503 { 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4
},
9504 { 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5
},
9505 { 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6
},
9506 { 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7
},
9507 { 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8
},
9508 { 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9
},
9509 { 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A
},
9510 { 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B
},
9511 { 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C
},
9512 { 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D
},
9513 { 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A
},
9514 { 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B
},
9515 { 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C
},
9516 { 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D
},
9518 { 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE
},
9519 { 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE
},
9520 { 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE
},
9521 { 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE
},
9522 { 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE
},
9523 { 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE
},
9524 { 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE
},
9525 { 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE
},
9526 { 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE
},
9527 { 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE
},
9528 { 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE
},
9529 { 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE
},
9530 { 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE
},
9531 { 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE
},
9532 { 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE
},
9533 { 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE
},
9534 { 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE
},
9535 { 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE
},
9536 { 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE
},
9537 { 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE
},
9538 { 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE
},
9539 { 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE
},
9540 { 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE
},
9541 { 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL
},
9542 { 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE
},
9543 { 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE
},
9544 { 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE
},
9545 { 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE
},
9546 { 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE
},
9547 { 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE
},
9548 { 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE
},
9549 { 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE
},
9550 { 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE
},
9551 { 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS
},
9552 { 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID
},
9553 { 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH
},
9554 { 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390
},
9555 { 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1
},
9556 { 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2
},
9557 { 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3
},
9558 { 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4
},
9559 { 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5
},
9560 { 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6
},
9561 { 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7
},
9562 { 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8
},
9563 { 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9
},
9564 { 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0
},
9565 { 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1
},
9566 { 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2
},
9567 { 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP
},
9568 { 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1
},
9569 { 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST
},
9573 #define DTMF_DIGIT_MAP_ENTRIES ARRAY_SIZE(dtmf_digit_map)
9576 static void dtmf_enable_receiver (PLCI
*plci
, byte enable_mask
)
9578 word min_digit_duration
, min_gap_duration
;
9580 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_enable_receiver %02x",
9581 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
9582 (char *)(FILE_
), __LINE__
, enable_mask
));
9584 if (enable_mask
!= 0)
9586 min_digit_duration
= (plci
->dtmf_rec_pulse_ms
== 0) ? 40 : plci
->dtmf_rec_pulse_ms
;
9587 min_gap_duration
= (plci
->dtmf_rec_pause_ms
== 0) ? 40 : plci
->dtmf_rec_pause_ms
;
9588 plci
->internal_req_buffer
[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER
;
9589 PUT_WORD (&plci
->internal_req_buffer
[1], min_digit_duration
);
9590 PUT_WORD (&plci
->internal_req_buffer
[3], min_gap_duration
);
9591 plci
->NData
[0].PLength
= 5;
9593 PUT_WORD (&plci
->internal_req_buffer
[5], INTERNAL_IND_BUFFER_SIZE
);
9594 plci
->NData
[0].PLength
+= 2;
9595 capidtmf_recv_enable (&(plci
->capidtmf_state
), min_digit_duration
, min_gap_duration
);
9600 plci
->internal_req_buffer
[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER
;
9601 plci
->NData
[0].PLength
= 1;
9603 capidtmf_recv_disable (&(plci
->capidtmf_state
));
9606 plci
->NData
[0].P
= plci
->internal_req_buffer
;
9607 plci
->NL
.X
= plci
->NData
;
9609 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
9610 plci
->adapter
->request (&plci
->NL
);
9614 static void dtmf_send_digits (PLCI
*plci
, byte
*digit_buffer
, word digit_count
)
9618 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_digits %d",
9619 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
9620 (char *)(FILE_
), __LINE__
, digit_count
));
9622 plci
->internal_req_buffer
[0] = DTMF_UDATA_REQUEST_SEND_DIGITS
;
9623 w
= (plci
->dtmf_send_pulse_ms
== 0) ? 40 : plci
->dtmf_send_pulse_ms
;
9624 PUT_WORD (&plci
->internal_req_buffer
[1], w
);
9625 w
= (plci
->dtmf_send_pause_ms
== 0) ? 40 : plci
->dtmf_send_pause_ms
;
9626 PUT_WORD (&plci
->internal_req_buffer
[3], w
);
9627 for (i
= 0; i
< digit_count
; i
++)
9630 while ((w
< DTMF_DIGIT_MAP_ENTRIES
)
9631 && (digit_buffer
[i
] != dtmf_digit_map
[w
].character
))
9635 plci
->internal_req_buffer
[5+i
] = (w
< DTMF_DIGIT_MAP_ENTRIES
) ?
9636 dtmf_digit_map
[w
].code
: DTMF_DIGIT_TONE_CODE_STAR
;
9638 plci
->NData
[0].PLength
= 5 + digit_count
;
9639 plci
->NData
[0].P
= plci
->internal_req_buffer
;
9640 plci
->NL
.X
= plci
->NData
;
9642 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
9643 plci
->adapter
->request (&plci
->NL
);
9647 static void dtmf_rec_clear_config (PLCI
*plci
)
9650 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_rec_clear_config",
9651 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
9652 (char *)(FILE_
), __LINE__
));
9654 plci
->dtmf_rec_active
= 0;
9655 plci
->dtmf_rec_pulse_ms
= 0;
9656 plci
->dtmf_rec_pause_ms
= 0;
9658 capidtmf_init (&(plci
->capidtmf_state
), plci
->adapter
->u_law
);
9663 static void dtmf_send_clear_config (PLCI
*plci
)
9666 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_clear_config",
9667 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
9668 (char *)(FILE_
), __LINE__
));
9670 plci
->dtmf_send_requests
= 0;
9671 plci
->dtmf_send_pulse_ms
= 0;
9672 plci
->dtmf_send_pause_ms
= 0;
9676 static void dtmf_prepare_switch (dword Id
, PLCI
*plci
)
9679 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_prepare_switch",
9680 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9682 while (plci
->dtmf_send_requests
!= 0)
9683 dtmf_confirmation (Id
, plci
);
9687 static word
dtmf_save_config (dword Id
, PLCI
*plci
, byte Rc
)
9690 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_save_config %02x %d",
9691 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
9697 static word
dtmf_restore_config (dword Id
, PLCI
*plci
, byte Rc
)
9701 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_restore_config %02x %d",
9702 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
9705 if (plci
->B1_facilities
& B1_FACILITY_DTMFR
)
9707 switch (plci
->adjust_b_state
)
9709 case ADJUST_B_RESTORE_DTMF_1
:
9710 plci
->internal_command
= plci
->adjust_b_command
;
9711 if (plci_nl_busy (plci
))
9713 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_1
;
9716 dtmf_enable_receiver (plci
, plci
->dtmf_rec_active
);
9717 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_2
;
9719 case ADJUST_B_RESTORE_DTMF_2
:
9720 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
9722 dbug (1, dprintf ("[%06lx] %s,%d: Reenable DTMF receiver failed %02x",
9723 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
9724 Info
= _WRONG_STATE
;
9734 static void dtmf_command (dword Id
, PLCI
*plci
, byte Rc
)
9736 word internal_command
, Info
;
9740 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d",
9741 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
,
9742 plci
->dtmf_cmd
, plci
->dtmf_rec_pulse_ms
, plci
->dtmf_rec_pause_ms
,
9743 plci
->dtmf_send_pulse_ms
, plci
->dtmf_send_pause_ms
));
9747 PUT_WORD (&result
[1], DTMF_SUCCESS
);
9748 internal_command
= plci
->internal_command
;
9749 plci
->internal_command
= 0;
9751 switch (plci
->dtmf_cmd
)
9754 case DTMF_LISTEN_TONE_START
:
9756 case DTMF_LISTEN_MF_START
:
9759 case DTMF_LISTEN_START
:
9760 switch (internal_command
)
9763 adjust_b1_resource (Id
, plci
, NULL
, (word
)(plci
->B1_facilities
|
9764 B1_FACILITY_DTMFR
), DTMF_COMMAND_1
);
9765 case DTMF_COMMAND_1
:
9766 if (adjust_b_process (Id
, plci
, Rc
) != GOOD
)
9768 dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed",
9769 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9770 Info
= _FACILITY_NOT_SUPPORTED
;
9773 if (plci
->internal_command
)
9775 case DTMF_COMMAND_2
:
9776 if (plci_nl_busy (plci
))
9778 plci
->internal_command
= DTMF_COMMAND_2
;
9781 plci
->internal_command
= DTMF_COMMAND_3
;
9782 dtmf_enable_receiver (plci
, (byte
)(plci
->dtmf_rec_active
| mask
));
9784 case DTMF_COMMAND_3
:
9785 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
9787 dbug (1, dprintf ("[%06lx] %s,%d: Enable DTMF receiver failed %02x",
9788 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
9789 Info
= _FACILITY_NOT_SUPPORTED
;
9793 plci
->tone_last_indication_code
= DTMF_SIGNAL_NO_TONE
;
9795 plci
->dtmf_rec_active
|= mask
;
9801 case DTMF_LISTEN_TONE_STOP
:
9803 case DTMF_LISTEN_MF_STOP
:
9806 case DTMF_LISTEN_STOP
:
9807 switch (internal_command
)
9810 plci
->dtmf_rec_active
&= ~mask
;
9811 if (plci
->dtmf_rec_active
)
9814 case DTMF_COMMAND_1:
9815 if (plci->dtmf_rec_active)
9817 if (plci_nl_busy (plci))
9819 plci->internal_command = DTMF_COMMAND_1;
9822 plci->dtmf_rec_active &= ~mask;
9823 plci->internal_command = DTMF_COMMAND_2;
9824 dtmf_enable_receiver (plci, false);
9828 case DTMF_COMMAND_2:
9829 if ((Rc != OK) && (Rc != OK_FC))
9831 dbug (1, dprintf ("[%06lx] %s,%d: Disable DTMF receiver failed %02x",
9832 UnMapId (Id), (char far *)(FILE_), __LINE__, Rc));
9833 Info = _FACILITY_NOT_SUPPORTED;
9837 adjust_b1_resource (Id
, plci
, NULL
, (word
)(plci
->B1_facilities
&
9838 ~(B1_FACILITY_DTMFX
| B1_FACILITY_DTMFR
)), DTMF_COMMAND_3
);
9839 case DTMF_COMMAND_3
:
9840 if (adjust_b_process (Id
, plci
, Rc
) != GOOD
)
9842 dbug (1, dprintf ("[%06lx] %s,%d: Unload DTMF failed",
9843 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9844 Info
= _FACILITY_NOT_SUPPORTED
;
9847 if (plci
->internal_command
)
9854 case DTMF_SEND_TONE
:
9859 case DTMF_DIGITS_SEND
:
9860 switch (internal_command
)
9863 adjust_b1_resource (Id
, plci
, NULL
, (word
)(plci
->B1_facilities
|
9864 ((plci
->dtmf_parameter_length
!= 0) ? B1_FACILITY_DTMFX
| B1_FACILITY_DTMFR
: B1_FACILITY_DTMFX
)),
9866 case DTMF_COMMAND_1
:
9867 if (adjust_b_process (Id
, plci
, Rc
) != GOOD
)
9869 dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed",
9870 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9871 Info
= _FACILITY_NOT_SUPPORTED
;
9874 if (plci
->internal_command
)
9876 case DTMF_COMMAND_2
:
9877 if (plci_nl_busy (plci
))
9879 plci
->internal_command
= DTMF_COMMAND_2
;
9882 plci
->dtmf_msg_number_queue
[(plci
->dtmf_send_requests
)++] = plci
->number
;
9883 plci
->internal_command
= DTMF_COMMAND_3
;
9884 dtmf_send_digits (plci
, &plci
->saved_msg
.parms
[3].info
[1], plci
->saved_msg
.parms
[3].length
);
9886 case DTMF_COMMAND_3
:
9887 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
9889 dbug (1, dprintf ("[%06lx] %s,%d: Send DTMF digits failed %02x",
9890 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
9891 if (plci
->dtmf_send_requests
!= 0)
9892 (plci
->dtmf_send_requests
)--;
9893 Info
= _FACILITY_NOT_SUPPORTED
;
9900 sendf (plci
->appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, plci
->number
,
9901 "wws", Info
, SELECTOR_DTMF
, result
);
9905 static byte
dtmf_request (dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
9910 API_PARSE dtmf_parms
[5];
9913 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_request",
9914 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9918 PUT_WORD (&result
[1], DTMF_SUCCESS
);
9919 if (!(a
->profile
.Global_Options
& GL_DTMF_SUPPORTED
))
9921 dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
9922 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9923 Info
= _FACILITY_NOT_SUPPORTED
;
9925 else if (api_parse (&msg
[1].info
[1], msg
[1].length
, "w", dtmf_parms
))
9927 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
9928 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9929 Info
= _WRONG_MESSAGE_FORMAT
;
9932 else if ((GET_WORD (dtmf_parms
[0].info
) == DTMF_GET_SUPPORTED_DETECT_CODES
)
9933 || (GET_WORD (dtmf_parms
[0].info
) == DTMF_GET_SUPPORTED_SEND_CODES
))
9935 if (!((a
->requested_options_table
[appl
->Id
-1])
9936 & (1L << PRIVATE_DTMF_TONE
)))
9938 dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
9939 UnMapId (Id
), (char *)(FILE_
), __LINE__
, GET_WORD (dtmf_parms
[0].info
)));
9940 PUT_WORD (&result
[1], DTMF_UNKNOWN_REQUEST
);
9944 for (i
= 0; i
< 32; i
++)
9946 if (GET_WORD (dtmf_parms
[0].info
) == DTMF_GET_SUPPORTED_DETECT_CODES
)
9948 for (i
= 0; i
< DTMF_DIGIT_MAP_ENTRIES
; i
++)
9950 if (dtmf_digit_map
[i
].listen_mask
!= 0)
9951 result
[4 + (dtmf_digit_map
[i
].character
>> 3)] |= (1 << (dtmf_digit_map
[i
].character
& 0x7));
9956 for (i
= 0; i
< DTMF_DIGIT_MAP_ENTRIES
; i
++)
9958 if (dtmf_digit_map
[i
].send_mask
!= 0)
9959 result
[4 + (dtmf_digit_map
[i
].character
>> 3)] |= (1 << (dtmf_digit_map
[i
].character
& 0x7));
9967 else if (plci
== NULL
)
9969 dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
9970 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9971 Info
= _WRONG_IDENTIFIER
;
9976 || !plci
->NL
.Id
|| plci
->nl_remove_id
)
9978 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
9979 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
9980 Info
= _WRONG_STATE
;
9985 plci
->dtmf_cmd
= GET_WORD (dtmf_parms
[0].info
);
9987 switch (plci
->dtmf_cmd
)
9990 case DTMF_LISTEN_TONE_START
:
9991 case DTMF_LISTEN_TONE_STOP
:
9993 case DTMF_LISTEN_MF_START
:
9994 case DTMF_LISTEN_MF_STOP
:
9996 if (!((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[appl
->Id
-1])
9997 & (1L << PRIVATE_DTMF_TONE
)))
9999 dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
10000 UnMapId (Id
), (char *)(FILE_
), __LINE__
, GET_WORD (dtmf_parms
[0].info
)));
10001 PUT_WORD (&result
[1], DTMF_UNKNOWN_REQUEST
);
10005 case DTMF_LISTEN_START
:
10006 case DTMF_LISTEN_STOP
:
10007 if (!(a
->manufacturer_features
& MANUFACTURER_FEATURE_HARDDTMF
)
10008 && !(a
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
))
10010 dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
10011 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
10012 Info
= _FACILITY_NOT_SUPPORTED
;
10015 if (mask
& DTMF_LISTEN_ACTIVE_FLAG
)
10017 if (api_parse (&msg
[1].info
[1], msg
[1].length
, "wwws", dtmf_parms
))
10019 plci
->dtmf_rec_pulse_ms
= 0;
10020 plci
->dtmf_rec_pause_ms
= 0;
10024 plci
->dtmf_rec_pulse_ms
= GET_WORD (dtmf_parms
[1].info
);
10025 plci
->dtmf_rec_pause_ms
= GET_WORD (dtmf_parms
[2].info
);
10028 start_internal_command (Id
, plci
, dtmf_command
);
10032 case DTMF_SEND_TONE
:
10036 if (!((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[appl
->Id
-1])
10037 & (1L << PRIVATE_DTMF_TONE
)))
10039 dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
10040 UnMapId (Id
), (char *)(FILE_
), __LINE__
, GET_WORD (dtmf_parms
[0].info
)));
10041 PUT_WORD (&result
[1], DTMF_UNKNOWN_REQUEST
);
10045 case DTMF_DIGITS_SEND
:
10046 if (api_parse (&msg
[1].info
[1], msg
[1].length
, "wwws", dtmf_parms
))
10048 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
10049 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
10050 Info
= _WRONG_MESSAGE_FORMAT
;
10053 if (mask
& DTMF_LISTEN_ACTIVE_FLAG
)
10055 plci
->dtmf_send_pulse_ms
= GET_WORD (dtmf_parms
[1].info
);
10056 plci
->dtmf_send_pause_ms
= GET_WORD (dtmf_parms
[2].info
);
10060 while ((i
< dtmf_parms
[3].length
) && (j
< DTMF_DIGIT_MAP_ENTRIES
))
10063 while ((j
< DTMF_DIGIT_MAP_ENTRIES
)
10064 && ((dtmf_parms
[3].info
[i
+1] != dtmf_digit_map
[j
].character
)
10065 || ((dtmf_digit_map
[j
].send_mask
& mask
) == 0)))
10071 if (j
== DTMF_DIGIT_MAP_ENTRIES
)
10073 dbug (1, dprintf ("[%06lx] %s,%d: Incorrect DTMF digit %02x",
10074 UnMapId (Id
), (char *)(FILE_
), __LINE__
, dtmf_parms
[3].info
[i
]));
10075 PUT_WORD (&result
[1], DTMF_INCORRECT_DIGIT
);
10078 if (plci
->dtmf_send_requests
>= ARRAY_SIZE(plci
->dtmf_msg_number_queue
))
10080 dbug (1, dprintf ("[%06lx] %s,%d: DTMF request overrun",
10081 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
10082 Info
= _WRONG_STATE
;
10085 api_save_msg (dtmf_parms
, "wwws", &plci
->saved_msg
);
10086 start_internal_command (Id
, plci
, dtmf_command
);
10090 dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
10091 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci
->dtmf_cmd
));
10092 PUT_WORD (&result
[1], DTMF_UNKNOWN_REQUEST
);
10096 sendf (appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
10097 "wws", Info
, SELECTOR_DTMF
, result
);
10102 static void dtmf_confirmation (dword Id
, PLCI
*plci
)
10108 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation",
10109 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
10113 PUT_WORD (&result
[1], DTMF_SUCCESS
);
10114 if (plci
->dtmf_send_requests
!= 0)
10116 sendf (plci
->appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, plci
->dtmf_msg_number_queue
[0],
10117 "wws", GOOD
, SELECTOR_DTMF
, result
);
10118 (plci
->dtmf_send_requests
)--;
10119 for (i
= 0; i
< plci
->dtmf_send_requests
; i
++)
10120 plci
->dtmf_msg_number_queue
[i
] = plci
->dtmf_msg_number_queue
[i
+1];
10125 static void dtmf_indication (dword Id
, PLCI
*plci
, byte
*msg
, word length
)
10129 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_indication",
10130 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
10133 for (i
= 1; i
< length
; i
++)
10136 while ((j
< DTMF_DIGIT_MAP_ENTRIES
)
10137 && ((msg
[i
] != dtmf_digit_map
[j
].code
)
10138 || ((dtmf_digit_map
[j
].listen_mask
& plci
->dtmf_rec_active
) == 0)))
10142 if (j
< DTMF_DIGIT_MAP_ENTRIES
)
10145 if ((dtmf_digit_map
[j
].listen_mask
& DTMF_TONE_LISTEN_ACTIVE_FLAG
)
10146 && (plci
->tone_last_indication_code
== DTMF_SIGNAL_NO_TONE
)
10147 && (dtmf_digit_map
[j
].character
!= DTMF_SIGNAL_UNIDENTIFIED_TONE
))
10151 for (i
= length
; i
> n
+ 1; i
--)
10152 msg
[i
] = msg
[i
- 1];
10156 msg
[++n
] = DTMF_SIGNAL_UNIDENTIFIED_TONE
;
10158 plci
->tone_last_indication_code
= dtmf_digit_map
[j
].character
;
10160 msg
[++n
] = dtmf_digit_map
[j
].character
;
10166 sendf (plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "wS", SELECTOR_DTMF
, msg
);
10171 /*------------------------------------------------------------------*/
10172 /* DTMF parameters */
10173 /*------------------------------------------------------------------*/
10175 static void dtmf_parameter_write (PLCI
*plci
)
10178 byte parameter_buffer
[DTMF_PARAMETER_BUFFER_SIZE
+ 2];
10180 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_write",
10181 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
10182 (char *)(FILE_
), __LINE__
));
10184 parameter_buffer
[0] = plci
->dtmf_parameter_length
+ 1;
10185 parameter_buffer
[1] = DSP_CTRL_SET_DTMF_PARAMETERS
;
10186 for (i
= 0; i
< plci
->dtmf_parameter_length
; i
++)
10187 parameter_buffer
[2+i
] = plci
->dtmf_parameter_buffer
[i
];
10188 add_p (plci
, FTY
, parameter_buffer
);
10189 sig_req (plci
, TEL_CTRL
, 0);
10194 static void dtmf_parameter_clear_config (PLCI
*plci
)
10197 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_clear_config",
10198 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
10199 (char *)(FILE_
), __LINE__
));
10201 plci
->dtmf_parameter_length
= 0;
10205 static void dtmf_parameter_prepare_switch (dword Id
, PLCI
*plci
)
10208 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_prepare_switch",
10209 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
10214 static word
dtmf_parameter_save_config (dword Id
, PLCI
*plci
, byte Rc
)
10217 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d",
10218 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
10224 static word
dtmf_parameter_restore_config (dword Id
, PLCI
*plci
, byte Rc
)
10228 dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d",
10229 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
10232 if ((plci
->B1_facilities
& B1_FACILITY_DTMFR
)
10233 && (plci
->dtmf_parameter_length
!= 0))
10235 switch (plci
->adjust_b_state
)
10237 case ADJUST_B_RESTORE_DTMF_PARAMETER_1
:
10238 plci
->internal_command
= plci
->adjust_b_command
;
10241 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_PARAMETER_1
;
10244 dtmf_parameter_write (plci
);
10245 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_PARAMETER_2
;
10247 case ADJUST_B_RESTORE_DTMF_PARAMETER_2
:
10248 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
10250 dbug (1, dprintf ("[%06lx] %s,%d: Restore DTMF parameters failed %02x",
10251 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
10252 Info
= _WRONG_STATE
;
10262 /*------------------------------------------------------------------*/
10263 /* Line interconnect facilities */
10264 /*------------------------------------------------------------------*/
10267 LI_CONFIG
*li_config_table
;
10268 word li_total_channels
;
10271 /*------------------------------------------------------------------*/
10272 /* translate a CHI information element to a channel number */
10273 /* returns 0xff - any channel */
10274 /* 0xfe - chi wrong coding */
10275 /* 0xfd - D-channel */
10276 /* 0x00 - no channel */
10277 /* else channel number / PRI: timeslot */
10278 /* if channels is provided we accept more than one channel. */
10279 /*------------------------------------------------------------------*/
10281 static byte
chi_to_channel (byte
*chi
, dword
*pchannelmap
)
10290 if (pchannelmap
) *pchannelmap
= 0;
10291 if(!chi
[0]) return 0xff;
10294 if(chi
[1] & 0x20) {
10295 if(chi
[0]==1 && chi
[1]==0xac) return 0xfd; /* exclusive d-channel */
10296 for(i
=1; i
<chi
[0] && !(chi
[i
] &0x80); i
++);
10297 if(i
==chi
[0] || !(chi
[i
] &0x80)) return 0xfe;
10298 if((chi
[1] |0xc8)!=0xe9) return 0xfe;
10299 if(chi
[1] &0x08) excl
= 0x40;
10301 /* int. id present */
10304 for(i
=p
; i
<chi
[0] && !(chi
[i
] &0x80); i
++);
10305 if(i
==chi
[0] || !(chi
[i
] &0x80)) return 0xfe;
10308 /* coding standard, Number/Map, Channel Type */
10310 for(i
=p
; i
<chi
[0] && !(chi
[i
] &0x80); i
++);
10311 if(i
==chi
[0] || !(chi
[i
] &0x80)) return 0xfe;
10312 if((chi
[p
]|0xd0)!=0xd3) return 0xfe;
10318 if((chi
[0]-p
)==4) ofs
= 0;
10319 else if((chi
[0]-p
)==3) ofs
= 1;
10323 for(i
=0; i
<4 && p
<chi
[0]; i
++) {
10328 for (ch
=0; !(chi
[p
] & (1 << ch
)); ch
++);
10341 if((byte
)(chi
[0]-p
)>30) return 0xfe;
10343 for(i
=p
; i
<=chi
[0]; i
++) {
10344 if ((chi
[i
] &0x7f) > 31) return 0xfe;
10345 map
|= (1L << (chi
[i
] &0x7f));
10349 if(p
!=chi
[0]) return 0xfe;
10350 if (ch
> 31) return 0xfe;
10353 if(chi
[p
] &0x40) return 0xfe;
10355 if (pchannelmap
) *pchannelmap
= map
;
10356 else if (map
!= ((dword
)(1L << ch
))) return 0xfe;
10357 return (byte
)(excl
| ch
);
10359 else { /* not PRI */
10360 for(i
=1; i
<chi
[0] && !(chi
[i
] &0x80); i
++);
10361 if(i
!=chi
[0] || !(chi
[i
] &0x80)) return 0xfe;
10362 if(chi
[1] &0x08) excl
= 0x40;
10364 switch(chi
[1] |0x98) {
10365 case 0x98: return 0;
10367 if (pchannelmap
) *pchannelmap
= 2;
10370 if (pchannelmap
) *pchannelmap
= 4;
10372 case 0x9b: return 0xff;
10373 case 0x9c: return 0xfd; /* d-ch */
10374 default: return 0xfe;
10380 static void mixer_set_bchannel_id_esc (PLCI
*plci
, byte bchannel_id
)
10382 DIVA_CAPI_ADAPTER
*a
;
10387 old_id
= plci
->li_bchannel_id
;
10390 if ((old_id
!= 0) && (li_config_table
[a
->li_base
+ (old_id
- 1)].plci
== plci
))
10391 li_config_table
[a
->li_base
+ (old_id
- 1)].plci
= NULL
;
10392 plci
->li_bchannel_id
= (bchannel_id
& 0x1f) + 1;
10393 if (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== NULL
)
10394 li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
10398 if (((bchannel_id
& 0x03) == 1) || ((bchannel_id
& 0x03) == 2))
10400 if ((old_id
!= 0) && (li_config_table
[a
->li_base
+ (old_id
- 1)].plci
== plci
))
10401 li_config_table
[a
->li_base
+ (old_id
- 1)].plci
= NULL
;
10402 plci
->li_bchannel_id
= bchannel_id
& 0x03;
10403 if ((a
->AdvSignalPLCI
!= NULL
) && (a
->AdvSignalPLCI
!= plci
) && (a
->AdvSignalPLCI
->tel
== ADV_VOICE
))
10405 splci
= a
->AdvSignalPLCI
;
10406 if (li_config_table
[a
->li_base
+ (2 - plci
->li_bchannel_id
)].plci
== NULL
)
10408 if ((splci
->li_bchannel_id
!= 0)
10409 && (li_config_table
[a
->li_base
+ (splci
->li_bchannel_id
- 1)].plci
== splci
))
10411 li_config_table
[a
->li_base
+ (splci
->li_bchannel_id
- 1)].plci
= NULL
;
10413 splci
->li_bchannel_id
= 3 - plci
->li_bchannel_id
;
10414 li_config_table
[a
->li_base
+ (2 - plci
->li_bchannel_id
)].plci
= splci
;
10415 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d",
10416 (dword
)((splci
->Id
<< 8) | UnMapController (splci
->adapter
->Id
)),
10417 (char *)(FILE_
), __LINE__
, splci
->li_bchannel_id
));
10420 if (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== NULL
)
10421 li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
10424 if ((old_id
== 0) && (plci
->li_bchannel_id
!= 0)
10425 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
10427 mixer_clear_config (plci
);
10429 dbug (1, dprintf ("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d",
10430 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
10431 (char *)(FILE_
), __LINE__
, bchannel_id
, plci
->li_bchannel_id
));
10435 static void mixer_set_bchannel_id (PLCI
*plci
, byte
*chi
)
10437 DIVA_CAPI_ADAPTER
*a
;
10442 old_id
= plci
->li_bchannel_id
;
10443 ch
= chi_to_channel (chi
, NULL
);
10448 if ((old_id
!= 0) && (li_config_table
[a
->li_base
+ (old_id
- 1)].plci
== plci
))
10449 li_config_table
[a
->li_base
+ (old_id
- 1)].plci
= NULL
;
10450 plci
->li_bchannel_id
= (ch
& 0x1f) + 1;
10451 if (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== NULL
)
10452 li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
10456 if (((ch
& 0x1f) == 1) || ((ch
& 0x1f) == 2))
10458 if ((old_id
!= 0) && (li_config_table
[a
->li_base
+ (old_id
- 1)].plci
== plci
))
10459 li_config_table
[a
->li_base
+ (old_id
- 1)].plci
= NULL
;
10460 plci
->li_bchannel_id
= ch
& 0x1f;
10461 if ((a
->AdvSignalPLCI
!= NULL
) && (a
->AdvSignalPLCI
!= plci
) && (a
->AdvSignalPLCI
->tel
== ADV_VOICE
))
10463 splci
= a
->AdvSignalPLCI
;
10464 if (li_config_table
[a
->li_base
+ (2 - plci
->li_bchannel_id
)].plci
== NULL
)
10466 if ((splci
->li_bchannel_id
!= 0)
10467 && (li_config_table
[a
->li_base
+ (splci
->li_bchannel_id
- 1)].plci
== splci
))
10469 li_config_table
[a
->li_base
+ (splci
->li_bchannel_id
- 1)].plci
= NULL
;
10471 splci
->li_bchannel_id
= 3 - plci
->li_bchannel_id
;
10472 li_config_table
[a
->li_base
+ (2 - plci
->li_bchannel_id
)].plci
= splci
;
10473 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
10474 (dword
)((splci
->Id
<< 8) | UnMapController (splci
->adapter
->Id
)),
10475 (char *)(FILE_
), __LINE__
, splci
->li_bchannel_id
));
10478 if (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== NULL
)
10479 li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
10483 if ((old_id
== 0) && (plci
->li_bchannel_id
!= 0)
10484 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
10486 mixer_clear_config (plci
);
10488 dbug (1, dprintf ("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d",
10489 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
10490 (char *)(FILE_
), __LINE__
, ch
, plci
->li_bchannel_id
));
10494 #define MIXER_MAX_DUMP_CHANNELS 34
10496 static void mixer_calculate_coefs (DIVA_CAPI_ADAPTER
*a
)
10498 static char hex_digit_table
[0x10] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
10501 char hex_line
[2 * MIXER_MAX_DUMP_CHANNELS
+ MIXER_MAX_DUMP_CHANNELS
/ 8 + 4];
10503 dbug (1, dprintf ("[%06lx] %s,%d: mixer_calculate_coefs",
10504 (dword
)(UnMapController (a
->Id
)), (char *)(FILE_
), __LINE__
));
10506 for (i
= 0; i
< li_total_channels
; i
++)
10508 li_config_table
[i
].channel
&= LI_CHANNEL_ADDRESSES_SET
;
10509 if (li_config_table
[i
].chflags
!= 0)
10510 li_config_table
[i
].channel
|= LI_CHANNEL_INVOLVED
;
10513 for (j
= 0; j
< li_total_channels
; j
++)
10515 if (((li_config_table
[i
].flag_table
[j
]) != 0)
10516 || ((li_config_table
[j
].flag_table
[i
]) != 0))
10518 li_config_table
[i
].channel
|= LI_CHANNEL_INVOLVED
;
10520 if (((li_config_table
[i
].flag_table
[j
] & LI_FLAG_CONFERENCE
) != 0)
10521 || ((li_config_table
[j
].flag_table
[i
] & LI_FLAG_CONFERENCE
) != 0))
10523 li_config_table
[i
].channel
|= LI_CHANNEL_CONFERENCE
;
10528 for (i
= 0; i
< li_total_channels
; i
++)
10530 for (j
= 0; j
< li_total_channels
; j
++)
10532 li_config_table
[i
].coef_table
[j
] &= ~(LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
);
10533 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_CONFERENCE
)
10534 li_config_table
[i
].coef_table
[j
] |= LI_COEF_CH_CH
;
10537 for (n
= 0; n
< li_total_channels
; n
++)
10539 if (li_config_table
[n
].channel
& LI_CHANNEL_CONFERENCE
)
10541 for (i
= 0; i
< li_total_channels
; i
++)
10543 if (li_config_table
[i
].channel
& LI_CHANNEL_CONFERENCE
)
10545 for (j
= 0; j
< li_total_channels
; j
++)
10547 li_config_table
[i
].coef_table
[j
] |=
10548 li_config_table
[i
].coef_table
[n
] & li_config_table
[n
].coef_table
[j
];
10554 for (i
= 0; i
< li_total_channels
; i
++)
10556 if (li_config_table
[i
].channel
& LI_CHANNEL_INVOLVED
)
10558 li_config_table
[i
].coef_table
[i
] &= ~LI_COEF_CH_CH
;
10559 for (j
= 0; j
< li_total_channels
; j
++)
10561 if (li_config_table
[i
].coef_table
[j
] & LI_COEF_CH_CH
)
10562 li_config_table
[i
].flag_table
[j
] |= LI_FLAG_CONFERENCE
;
10564 if (li_config_table
[i
].flag_table
[i
] & LI_FLAG_CONFERENCE
)
10565 li_config_table
[i
].coef_table
[i
] |= LI_COEF_CH_CH
;
10568 for (i
= 0; i
< li_total_channels
; i
++)
10570 if (li_config_table
[i
].channel
& LI_CHANNEL_INVOLVED
)
10572 for (j
= 0; j
< li_total_channels
; j
++)
10574 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_INTERCONNECT
)
10575 li_config_table
[i
].coef_table
[j
] |= LI_COEF_CH_CH
;
10576 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_MONITOR
)
10577 li_config_table
[i
].coef_table
[j
] |= LI_COEF_CH_PC
;
10578 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_MIX
)
10579 li_config_table
[i
].coef_table
[j
] |= LI_COEF_PC_CH
;
10580 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_PCCONNECT
)
10581 li_config_table
[i
].coef_table
[j
] |= LI_COEF_PC_PC
;
10583 if (li_config_table
[i
].chflags
& LI_CHFLAG_MONITOR
)
10585 for (j
= 0; j
< li_total_channels
; j
++)
10587 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_INTERCONNECT
)
10589 li_config_table
[i
].coef_table
[j
] |= LI_COEF_CH_PC
;
10590 if (li_config_table
[j
].chflags
& LI_CHFLAG_MIX
)
10591 li_config_table
[i
].coef_table
[j
] |= LI_COEF_PC_CH
| LI_COEF_PC_PC
;
10595 if (li_config_table
[i
].chflags
& LI_CHFLAG_MIX
)
10597 for (j
= 0; j
< li_total_channels
; j
++)
10599 if (li_config_table
[j
].flag_table
[i
] & LI_FLAG_INTERCONNECT
)
10600 li_config_table
[j
].coef_table
[i
] |= LI_COEF_PC_CH
;
10603 if (li_config_table
[i
].chflags
& LI_CHFLAG_LOOP
)
10605 for (j
= 0; j
< li_total_channels
; j
++)
10607 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_INTERCONNECT
)
10609 for (n
= 0; n
< li_total_channels
; n
++)
10611 if (li_config_table
[n
].flag_table
[i
] & LI_FLAG_INTERCONNECT
)
10613 li_config_table
[n
].coef_table
[j
] |= LI_COEF_CH_CH
;
10614 if (li_config_table
[j
].chflags
& LI_CHFLAG_MIX
)
10616 li_config_table
[n
].coef_table
[j
] |= LI_COEF_PC_CH
;
10617 if (li_config_table
[n
].chflags
& LI_CHFLAG_MONITOR
)
10618 li_config_table
[n
].coef_table
[j
] |= LI_COEF_CH_PC
| LI_COEF_PC_PC
;
10620 else if (li_config_table
[n
].chflags
& LI_CHFLAG_MONITOR
)
10621 li_config_table
[n
].coef_table
[j
] |= LI_COEF_CH_PC
;
10629 for (i
= 0; i
< li_total_channels
; i
++)
10631 if (li_config_table
[i
].channel
& LI_CHANNEL_INVOLVED
)
10633 if (li_config_table
[i
].chflags
& (LI_CHFLAG_MONITOR
| LI_CHFLAG_MIX
| LI_CHFLAG_LOOP
))
10634 li_config_table
[i
].channel
|= LI_CHANNEL_ACTIVE
;
10635 if (li_config_table
[i
].chflags
& LI_CHFLAG_MONITOR
)
10636 li_config_table
[i
].channel
|= LI_CHANNEL_RX_DATA
;
10637 if (li_config_table
[i
].chflags
& LI_CHFLAG_MIX
)
10638 li_config_table
[i
].channel
|= LI_CHANNEL_TX_DATA
;
10639 for (j
= 0; j
< li_total_channels
; j
++)
10641 if ((li_config_table
[i
].flag_table
[j
] &
10642 (LI_FLAG_INTERCONNECT
| LI_FLAG_PCCONNECT
| LI_FLAG_CONFERENCE
| LI_FLAG_MONITOR
))
10643 || (li_config_table
[j
].flag_table
[i
] &
10644 (LI_FLAG_INTERCONNECT
| LI_FLAG_PCCONNECT
| LI_FLAG_CONFERENCE
| LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
)))
10646 li_config_table
[i
].channel
|= LI_CHANNEL_ACTIVE
;
10648 if (li_config_table
[i
].flag_table
[j
] & (LI_FLAG_PCCONNECT
| LI_FLAG_MONITOR
))
10649 li_config_table
[i
].channel
|= LI_CHANNEL_RX_DATA
;
10650 if (li_config_table
[j
].flag_table
[i
] & (LI_FLAG_PCCONNECT
| LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
))
10651 li_config_table
[i
].channel
|= LI_CHANNEL_TX_DATA
;
10653 if (!(li_config_table
[i
].channel
& LI_CHANNEL_ACTIVE
))
10655 li_config_table
[i
].coef_table
[i
] |= LI_COEF_PC_CH
| LI_COEF_CH_PC
;
10656 li_config_table
[i
].channel
|= LI_CHANNEL_TX_DATA
| LI_CHANNEL_RX_DATA
;
10660 for (i
= 0; i
< li_total_channels
; i
++)
10662 if (li_config_table
[i
].channel
& LI_CHANNEL_INVOLVED
)
10665 while ((j
< li_total_channels
) && !(li_config_table
[i
].flag_table
[j
] & LI_FLAG_ANNOUNCEMENT
))
10667 if (j
< li_total_channels
)
10669 for (j
= 0; j
< li_total_channels
; j
++)
10671 li_config_table
[i
].coef_table
[j
] &= ~(LI_COEF_CH_CH
| LI_COEF_PC_CH
);
10672 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_ANNOUNCEMENT
)
10673 li_config_table
[i
].coef_table
[j
] |= LI_COEF_PC_CH
;
10678 n
= li_total_channels
;
10679 if (n
> MIXER_MAX_DUMP_CHANNELS
)
10680 n
= MIXER_MAX_DUMP_CHANNELS
;
10682 for (j
= 0; j
< n
; j
++)
10684 if ((j
& 0x7) == 0)
10686 *(p
++) = hex_digit_table
[li_config_table
[j
].curchnl
>> 4];
10687 *(p
++) = hex_digit_table
[li_config_table
[j
].curchnl
& 0xf];
10690 dbug (1, dprintf ("[%06lx] CURRENT %s",
10691 (dword
)(UnMapController (a
->Id
)), (char *) hex_line
));
10693 for (j
= 0; j
< n
; j
++)
10695 if ((j
& 0x7) == 0)
10697 *(p
++) = hex_digit_table
[li_config_table
[j
].channel
>> 4];
10698 *(p
++) = hex_digit_table
[li_config_table
[j
].channel
& 0xf];
10701 dbug (1, dprintf ("[%06lx] CHANNEL %s",
10702 (dword
)(UnMapController (a
->Id
)), (char *) hex_line
));
10704 for (j
= 0; j
< n
; j
++)
10706 if ((j
& 0x7) == 0)
10708 *(p
++) = hex_digit_table
[li_config_table
[j
].chflags
>> 4];
10709 *(p
++) = hex_digit_table
[li_config_table
[j
].chflags
& 0xf];
10712 dbug (1, dprintf ("[%06lx] CHFLAG %s",
10713 (dword
)(UnMapController (a
->Id
)), (char *) hex_line
));
10714 for (i
= 0; i
< n
; i
++)
10717 for (j
= 0; j
< n
; j
++)
10719 if ((j
& 0x7) == 0)
10721 *(p
++) = hex_digit_table
[li_config_table
[i
].flag_table
[j
] >> 4];
10722 *(p
++) = hex_digit_table
[li_config_table
[i
].flag_table
[j
] & 0xf];
10725 dbug (1, dprintf ("[%06lx] FLAG[%02x]%s",
10726 (dword
)(UnMapController (a
->Id
)), i
, (char *) hex_line
));
10728 for (i
= 0; i
< n
; i
++)
10731 for (j
= 0; j
< n
; j
++)
10733 if ((j
& 0x7) == 0)
10735 *(p
++) = hex_digit_table
[li_config_table
[i
].coef_table
[j
] >> 4];
10736 *(p
++) = hex_digit_table
[li_config_table
[i
].coef_table
[j
] & 0xf];
10739 dbug (1, dprintf ("[%06lx] COEF[%02x]%s",
10740 (dword
)(UnMapController (a
->Id
)), i
, (char *) hex_line
));
10749 } mixer_write_prog_pri
[] =
10751 { LI_COEF_CH_CH
, 0 },
10752 { LI_COEF_CH_PC
, MIXER_COEF_LINE_TO_PC_FLAG
},
10753 { LI_COEF_PC_CH
, MIXER_COEF_LINE_FROM_PC_FLAG
},
10754 { LI_COEF_PC_PC
, MIXER_COEF_LINE_TO_PC_FLAG
| MIXER_COEF_LINE_FROM_PC_FLAG
}
10762 byte xconnect_override
;
10763 } mixer_write_prog_bri
[] =
10765 { 0, 0, LI_COEF_CH_CH
, 0x01 }, /* B to B */
10766 { 1, 0, LI_COEF_CH_CH
, 0x01 }, /* Alt B to B */
10767 { 0, 0, LI_COEF_PC_CH
, 0x80 }, /* PC to B */
10768 { 1, 0, LI_COEF_PC_CH
, 0x01 }, /* Alt PC to B */
10769 { 2, 0, LI_COEF_CH_CH
, 0x00 }, /* IC to B */
10770 { 3, 0, LI_COEF_CH_CH
, 0x00 }, /* Alt IC to B */
10771 { 0, 0, LI_COEF_CH_PC
, 0x80 }, /* B to PC */
10772 { 1, 0, LI_COEF_CH_PC
, 0x01 }, /* Alt B to PC */
10773 { 0, 0, LI_COEF_PC_PC
, 0x01 }, /* PC to PC */
10774 { 1, 0, LI_COEF_PC_PC
, 0x01 }, /* Alt PC to PC */
10775 { 2, 0, LI_COEF_CH_PC
, 0x00 }, /* IC to PC */
10776 { 3, 0, LI_COEF_CH_PC
, 0x00 }, /* Alt IC to PC */
10777 { 0, 2, LI_COEF_CH_CH
, 0x00 }, /* B to IC */
10778 { 1, 2, LI_COEF_CH_CH
, 0x00 }, /* Alt B to IC */
10779 { 0, 2, LI_COEF_PC_CH
, 0x00 }, /* PC to IC */
10780 { 1, 2, LI_COEF_PC_CH
, 0x00 }, /* Alt PC to IC */
10781 { 2, 2, LI_COEF_CH_CH
, 0x00 }, /* IC to IC */
10782 { 3, 2, LI_COEF_CH_CH
, 0x00 }, /* Alt IC to IC */
10783 { 1, 1, LI_COEF_CH_CH
, 0x01 }, /* Alt B to Alt B */
10784 { 0, 1, LI_COEF_CH_CH
, 0x01 }, /* B to Alt B */
10785 { 1, 1, LI_COEF_PC_CH
, 0x80 }, /* Alt PC to Alt B */
10786 { 0, 1, LI_COEF_PC_CH
, 0x01 }, /* PC to Alt B */
10787 { 3, 1, LI_COEF_CH_CH
, 0x00 }, /* Alt IC to Alt B */
10788 { 2, 1, LI_COEF_CH_CH
, 0x00 }, /* IC to Alt B */
10789 { 1, 1, LI_COEF_CH_PC
, 0x80 }, /* Alt B to Alt PC */
10790 { 0, 1, LI_COEF_CH_PC
, 0x01 }, /* B to Alt PC */
10791 { 1, 1, LI_COEF_PC_PC
, 0x01 }, /* Alt PC to Alt PC */
10792 { 0, 1, LI_COEF_PC_PC
, 0x01 }, /* PC to Alt PC */
10793 { 3, 1, LI_COEF_CH_PC
, 0x00 }, /* Alt IC to Alt PC */
10794 { 2, 1, LI_COEF_CH_PC
, 0x00 }, /* IC to Alt PC */
10795 { 1, 3, LI_COEF_CH_CH
, 0x00 }, /* Alt B to Alt IC */
10796 { 0, 3, LI_COEF_CH_CH
, 0x00 }, /* B to Alt IC */
10797 { 1, 3, LI_COEF_PC_CH
, 0x00 }, /* Alt PC to Alt IC */
10798 { 0, 3, LI_COEF_PC_CH
, 0x00 }, /* PC to Alt IC */
10799 { 3, 3, LI_COEF_CH_CH
, 0x00 }, /* Alt IC to Alt IC */
10800 { 2, 3, LI_COEF_CH_CH
, 0x00 } /* IC to Alt IC */
10803 static byte mixer_swapped_index_bri
[] =
10806 19, /* Alt B to B */
10808 21, /* Alt PC to B */
10810 23, /* Alt IC to B */
10812 25, /* Alt B to PC */
10814 27, /* Alt PC to PC */
10816 29, /* Alt IC to PC */
10818 31, /* Alt B to IC */
10820 33, /* Alt PC to IC */
10822 35, /* Alt IC to IC */
10823 0, /* Alt B to Alt B */
10824 1, /* B to Alt B */
10825 2, /* Alt PC to Alt B */
10826 3, /* PC to Alt B */
10827 4, /* Alt IC to Alt B */
10828 5, /* IC to Alt B */
10829 6, /* Alt B to Alt PC */
10830 7, /* B to Alt PC */
10831 8, /* Alt PC to Alt PC */
10832 9, /* PC to Alt PC */
10833 10, /* Alt IC to Alt PC */
10834 11, /* IC to Alt PC */
10835 12, /* Alt B to Alt IC */
10836 13, /* B to Alt IC */
10837 14, /* Alt PC to Alt IC */
10838 15, /* PC to Alt IC */
10839 16, /* Alt IC to Alt IC */
10840 17 /* IC to Alt IC */
10848 } xconnect_write_prog
[] =
10850 { LI_COEF_CH_CH
, false, false },
10851 { LI_COEF_CH_PC
, false, true },
10852 { LI_COEF_PC_CH
, true, false },
10853 { LI_COEF_PC_PC
, true, true }
10857 static void xconnect_query_addresses (PLCI
*plci
)
10859 DIVA_CAPI_ADAPTER
*a
;
10863 dbug (1, dprintf ("[%06lx] %s,%d: xconnect_query_addresses",
10864 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
10865 (char *)(FILE_
), __LINE__
));
10868 if (a
->li_pri
&& ((plci
->li_bchannel_id
== 0)
10869 || (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
!= plci
)))
10871 dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out",
10872 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
10873 (char *)(FILE_
), __LINE__
));
10876 p
= plci
->internal_req_buffer
;
10877 ch
= (a
->li_pri
) ? plci
->li_bchannel_id
- 1 : 0;
10878 *(p
++) = UDATA_REQUEST_XCONNECT_FROM
;
10881 *(p
++) = (byte
)(w
>> 8);
10882 w
= ch
| XCONNECT_CHANNEL_PORT_PC
;
10884 *(p
++) = (byte
)(w
>> 8);
10885 plci
->NData
[0].P
= plci
->internal_req_buffer
;
10886 plci
->NData
[0].PLength
= p
- plci
->internal_req_buffer
;
10887 plci
->NL
.X
= plci
->NData
;
10888 plci
->NL
.ReqCh
= 0;
10889 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
10890 plci
->adapter
->request (&plci
->NL
);
10894 static void xconnect_write_coefs (PLCI
*plci
, word internal_command
)
10897 dbug (1, dprintf ("[%06lx] %s,%d: xconnect_write_coefs %04x",
10898 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
10899 (char *)(FILE_
), __LINE__
, internal_command
));
10901 plci
->li_write_command
= internal_command
;
10902 plci
->li_write_channel
= 0;
10906 static byte
xconnect_write_coefs_process (dword Id
, PLCI
*plci
, byte Rc
)
10908 DIVA_CAPI_ADAPTER
*a
;
10909 word w
, n
, i
, j
, r
, s
, to_ch
;
10912 struct xconnect_transfer_address_s
*transfer_address
;
10913 byte ch_map
[MIXER_CHANNELS_BRI
];
10915 dbug (1, dprintf ("[%06x] %s,%d: xconnect_write_coefs_process %02x %d",
10916 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->li_write_channel
));
10919 if ((plci
->li_bchannel_id
== 0)
10920 || (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
!= plci
))
10922 dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out",
10923 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
10926 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
10927 j
= plci
->li_write_channel
;
10928 p
= plci
->internal_req_buffer
;
10931 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
10933 dbug (1, dprintf ("[%06lx] %s,%d: LI write coefs failed %02x",
10934 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
10938 if (li_config_table
[i
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
10942 if (j
< li_total_channels
)
10944 if (li_config_table
[i
].channel
& LI_CHANNEL_ADDRESSES_SET
)
10946 s
= ((li_config_table
[i
].send_b
.card_address
.low
| li_config_table
[i
].send_b
.card_address
.high
) ?
10947 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_PC
| LI_COEF_PC_PC
)) &
10948 ((li_config_table
[i
].send_pc
.card_address
.low
| li_config_table
[i
].send_pc
.card_address
.high
) ?
10949 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_CH
| LI_COEF_PC_CH
));
10951 r
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
10952 while ((j
< li_total_channels
)
10954 || (!(li_config_table
[j
].channel
& LI_CHANNEL_ADDRESSES_SET
))
10955 || (!li_config_table
[j
].adapter
->li_pri
10956 && (j
>= li_config_table
[j
].adapter
->li_base
+ MIXER_BCHANNELS_BRI
))
10957 || (((li_config_table
[j
].send_b
.card_address
.low
!= li_config_table
[i
].send_b
.card_address
.low
)
10958 || (li_config_table
[j
].send_b
.card_address
.high
!= li_config_table
[i
].send_b
.card_address
.high
))
10959 && (!(a
->manufacturer_features
& MANUFACTURER_FEATURE_DMACONNECT
)
10960 || !(li_config_table
[j
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_DMACONNECT
)))
10961 || ((li_config_table
[j
].adapter
->li_base
!= a
->li_base
)
10963 ((li_config_table
[j
].send_b
.card_address
.low
| li_config_table
[j
].send_b
.card_address
.high
) ?
10964 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_PC_CH
| LI_COEF_PC_PC
)) &
10965 ((li_config_table
[j
].send_pc
.card_address
.low
| li_config_table
[j
].send_pc
.card_address
.high
) ?
10966 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_CH
| LI_COEF_CH_PC
))))))
10969 if (j
< li_total_channels
)
10970 r
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
10973 if (j
< li_total_channels
)
10975 plci
->internal_command
= plci
->li_write_command
;
10976 if (plci_nl_busy (plci
))
10978 to_ch
= (a
->li_pri
) ? plci
->li_bchannel_id
- 1 : 0;
10979 *(p
++) = UDATA_REQUEST_XCONNECT_TO
;
10982 if (li_config_table
[j
].adapter
->li_base
!= a
->li_base
)
10985 ((li_config_table
[j
].send_b
.card_address
.low
| li_config_table
[j
].send_b
.card_address
.high
) ?
10986 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_PC_CH
| LI_COEF_PC_PC
)) &
10987 ((li_config_table
[j
].send_pc
.card_address
.low
| li_config_table
[j
].send_pc
.card_address
.high
) ?
10988 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_CH
| LI_COEF_CH_PC
));
10993 if (r
& xconnect_write_prog
[n
].mask
)
10995 if (xconnect_write_prog
[n
].from_pc
)
10996 transfer_address
= &(li_config_table
[j
].send_pc
);
10998 transfer_address
= &(li_config_table
[j
].send_b
);
10999 d
= transfer_address
->card_address
.low
;
11001 *(p
++) = (byte
)(d
>> 8);
11002 *(p
++) = (byte
)(d
>> 16);
11003 *(p
++) = (byte
)(d
>> 24);
11004 d
= transfer_address
->card_address
.high
;
11006 *(p
++) = (byte
)(d
>> 8);
11007 *(p
++) = (byte
)(d
>> 16);
11008 *(p
++) = (byte
)(d
>> 24);
11009 d
= transfer_address
->offset
;
11011 *(p
++) = (byte
)(d
>> 8);
11012 *(p
++) = (byte
)(d
>> 16);
11013 *(p
++) = (byte
)(d
>> 24);
11014 w
= xconnect_write_prog
[n
].to_pc
? to_ch
| XCONNECT_CHANNEL_PORT_PC
: to_ch
;
11016 *(p
++) = (byte
)(w
>> 8);
11017 w
= ((li_config_table
[i
].coef_table
[j
] & xconnect_write_prog
[n
].mask
) == 0) ? 0x01 :
11018 (li_config_table
[i
].adapter
->u_law
?
11019 (li_config_table
[j
].adapter
->u_law
? 0x80 : 0x86) :
11020 (li_config_table
[j
].adapter
->u_law
? 0x7a : 0x80));
11023 li_config_table
[i
].coef_table
[j
] ^= xconnect_write_prog
[n
].mask
<< 4;
11026 } while ((n
< ARRAY_SIZE(xconnect_write_prog
))
11027 && ((p
- plci
->internal_req_buffer
) + 16 < INTERNAL_REQ_BUFFER_SIZE
));
11028 if (n
== ARRAY_SIZE(xconnect_write_prog
))
11033 if (j
< li_total_channels
)
11034 r
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
11035 } while ((j
< li_total_channels
)
11037 || (!(li_config_table
[j
].channel
& LI_CHANNEL_ADDRESSES_SET
))
11038 || (!li_config_table
[j
].adapter
->li_pri
11039 && (j
>= li_config_table
[j
].adapter
->li_base
+ MIXER_BCHANNELS_BRI
))
11040 || (((li_config_table
[j
].send_b
.card_address
.low
!= li_config_table
[i
].send_b
.card_address
.low
)
11041 || (li_config_table
[j
].send_b
.card_address
.high
!= li_config_table
[i
].send_b
.card_address
.high
))
11042 && (!(a
->manufacturer_features
& MANUFACTURER_FEATURE_DMACONNECT
)
11043 || !(li_config_table
[j
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_DMACONNECT
)))
11044 || ((li_config_table
[j
].adapter
->li_base
!= a
->li_base
)
11046 ((li_config_table
[j
].send_b
.card_address
.low
| li_config_table
[j
].send_b
.card_address
.high
) ?
11047 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_PC_CH
| LI_COEF_PC_PC
)) &
11048 ((li_config_table
[j
].send_pc
.card_address
.low
| li_config_table
[j
].send_pc
.card_address
.high
) ?
11049 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_CH
| LI_COEF_CH_PC
))))));
11051 } while ((j
< li_total_channels
)
11052 && ((p
- plci
->internal_req_buffer
) + 16 < INTERNAL_REQ_BUFFER_SIZE
));
11054 else if (j
== li_total_channels
)
11056 plci
->internal_command
= plci
->li_write_command
;
11057 if (plci_nl_busy (plci
))
11061 *(p
++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC
;
11063 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
11064 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
11065 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
11066 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
11068 *(p
++) = (byte
)(w
>> 8);
11072 *(p
++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI
;
11074 if ((plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
)
11075 && (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) <= a
->adv_voice_coef_length
))
11077 w
= GET_WORD (a
->adv_voice_coef_buffer
+ ADV_VOICE_NEW_COEF_BASE
);
11079 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
11080 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
11081 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
11082 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
11084 *(p
++) = (byte
)(w
>> 8);
11085 for (j
= 0; j
< sizeof(ch_map
); j
+= 2)
11087 if (plci
->li_bchannel_id
== 2)
11089 ch_map
[j
] = (byte
)(j
+1);
11090 ch_map
[j
+1] = (byte
) j
;
11094 ch_map
[j
] = (byte
) j
;
11095 ch_map
[j
+1] = (byte
)(j
+1);
11098 for (n
= 0; n
< ARRAY_SIZE(mixer_write_prog_bri
); n
++)
11100 i
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].to_ch
];
11101 j
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].from_ch
];
11102 if (li_config_table
[i
].channel
& li_config_table
[j
].channel
& LI_CHANNEL_INVOLVED
)
11104 *p
= (mixer_write_prog_bri
[n
].xconnect_override
!= 0) ?
11105 mixer_write_prog_bri
[n
].xconnect_override
:
11106 ((li_config_table
[i
].coef_table
[j
] & mixer_write_prog_bri
[n
].mask
) ? 0x80 : 0x01);
11107 if ((i
>= a
->li_base
+ MIXER_BCHANNELS_BRI
) || (j
>= a
->li_base
+ MIXER_BCHANNELS_BRI
))
11109 w
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
11110 li_config_table
[i
].coef_table
[j
] ^= (w
& mixer_write_prog_bri
[n
].mask
) << 4;
11116 if ((a
->AdvSignalPLCI
!= NULL
) && (a
->AdvSignalPLCI
->tel
== ADV_VOICE
))
11118 w
= (plci
== a
->AdvSignalPLCI
) ? n
: mixer_swapped_index_bri
[n
];
11119 if (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + w
< a
->adv_voice_coef_length
)
11120 *p
= a
->adv_voice_coef_buffer
[ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + w
];
11126 j
= li_total_channels
+ 1;
11131 if (j
<= li_total_channels
)
11133 plci
->internal_command
= plci
->li_write_command
;
11134 if (plci_nl_busy (plci
))
11136 if (j
< a
->li_base
)
11140 *(p
++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC
;
11142 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
11143 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
11144 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
11145 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
11147 *(p
++) = (byte
)(w
>> 8);
11148 for (n
= 0; n
< ARRAY_SIZE(mixer_write_prog_pri
); n
++)
11150 *(p
++) = (byte
)((plci
->li_bchannel_id
- 1) | mixer_write_prog_pri
[n
].line_flags
);
11151 for (j
= a
->li_base
; j
< a
->li_base
+ MIXER_CHANNELS_PRI
; j
++)
11153 w
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
11154 if (w
& mixer_write_prog_pri
[n
].mask
)
11156 *(p
++) = (li_config_table
[i
].coef_table
[j
] & mixer_write_prog_pri
[n
].mask
) ? 0x80 : 0x01;
11157 li_config_table
[i
].coef_table
[j
] ^= mixer_write_prog_pri
[n
].mask
<< 4;
11162 *(p
++) = (byte
)((plci
->li_bchannel_id
- 1) | MIXER_COEF_LINE_ROW_FLAG
| mixer_write_prog_pri
[n
].line_flags
);
11163 for (j
= a
->li_base
; j
< a
->li_base
+ MIXER_CHANNELS_PRI
; j
++)
11165 w
= ((li_config_table
[j
].coef_table
[i
] & 0xf) ^ (li_config_table
[j
].coef_table
[i
] >> 4));
11166 if (w
& mixer_write_prog_pri
[n
].mask
)
11168 *(p
++) = (li_config_table
[j
].coef_table
[i
] & mixer_write_prog_pri
[n
].mask
) ? 0x80 : 0x01;
11169 li_config_table
[j
].coef_table
[i
] ^= mixer_write_prog_pri
[n
].mask
<< 4;
11178 *(p
++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI
;
11180 if ((plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
)
11181 && (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) <= a
->adv_voice_coef_length
))
11183 w
= GET_WORD (a
->adv_voice_coef_buffer
+ ADV_VOICE_NEW_COEF_BASE
);
11185 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
11186 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
11187 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
11188 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
11190 *(p
++) = (byte
)(w
>> 8);
11191 for (j
= 0; j
< sizeof(ch_map
); j
+= 2)
11193 if (plci
->li_bchannel_id
== 2)
11195 ch_map
[j
] = (byte
)(j
+1);
11196 ch_map
[j
+1] = (byte
) j
;
11200 ch_map
[j
] = (byte
) j
;
11201 ch_map
[j
+1] = (byte
)(j
+1);
11204 for (n
= 0; n
< ARRAY_SIZE(mixer_write_prog_bri
); n
++)
11206 i
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].to_ch
];
11207 j
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].from_ch
];
11208 if (li_config_table
[i
].channel
& li_config_table
[j
].channel
& LI_CHANNEL_INVOLVED
)
11210 *p
= ((li_config_table
[i
].coef_table
[j
] & mixer_write_prog_bri
[n
].mask
) ? 0x80 : 0x01);
11211 w
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
11212 li_config_table
[i
].coef_table
[j
] ^= (w
& mixer_write_prog_bri
[n
].mask
) << 4;
11217 if ((a
->AdvSignalPLCI
!= NULL
) && (a
->AdvSignalPLCI
->tel
== ADV_VOICE
))
11219 w
= (plci
== a
->AdvSignalPLCI
) ? n
: mixer_swapped_index_bri
[n
];
11220 if (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + w
< a
->adv_voice_coef_length
)
11221 *p
= a
->adv_voice_coef_buffer
[ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + w
];
11227 j
= li_total_channels
+ 1;
11230 plci
->li_write_channel
= j
;
11231 if (p
!= plci
->internal_req_buffer
)
11233 plci
->NData
[0].P
= plci
->internal_req_buffer
;
11234 plci
->NData
[0].PLength
= p
- plci
->internal_req_buffer
;
11235 plci
->NL
.X
= plci
->NData
;
11236 plci
->NL
.ReqCh
= 0;
11237 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
11238 plci
->adapter
->request (&plci
->NL
);
11244 static void mixer_notify_update (PLCI
*plci
, byte others
)
11246 DIVA_CAPI_ADAPTER
*a
;
11249 byte msg
[sizeof(CAPI_MSG_HEADER
) + 6];
11251 dbug (1, dprintf ("[%06lx] %s,%d: mixer_notify_update %d",
11252 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
11253 (char *)(FILE_
), __LINE__
, others
));
11256 if (a
->profile
.Global_Options
& GL_LINE_INTERCONNECT_SUPPORTED
)
11259 plci
->li_notify_update
= true;
11263 notify_plci
= NULL
;
11266 while ((i
< li_total_channels
) && (li_config_table
[i
].plci
== NULL
))
11268 if (i
< li_total_channels
)
11269 notify_plci
= li_config_table
[i
++].plci
;
11273 if ((plci
->li_bchannel_id
!= 0)
11274 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
11276 notify_plci
= plci
;
11279 if ((notify_plci
!= NULL
)
11280 && !notify_plci
->li_notify_update
11281 && (notify_plci
->appl
!= NULL
)
11282 && (notify_plci
->State
)
11283 && notify_plci
->NL
.Id
&& !notify_plci
->nl_remove_id
)
11285 notify_plci
->li_notify_update
= true;
11286 ((CAPI_MSG
*) msg
)->header
.length
= 18;
11287 ((CAPI_MSG
*) msg
)->header
.appl_id
= notify_plci
->appl
->Id
;
11288 ((CAPI_MSG
*) msg
)->header
.command
= _FACILITY_R
;
11289 ((CAPI_MSG
*) msg
)->header
.number
= 0;
11290 ((CAPI_MSG
*) msg
)->header
.controller
= notify_plci
->adapter
->Id
;
11291 ((CAPI_MSG
*) msg
)->header
.plci
= notify_plci
->Id
;
11292 ((CAPI_MSG
*) msg
)->header
.ncci
= 0;
11293 ((CAPI_MSG
*) msg
)->info
.facility_req
.Selector
= SELECTOR_LINE_INTERCONNECT
;
11294 ((CAPI_MSG
*) msg
)->info
.facility_req
.structs
[0] = 3;
11295 PUT_WORD (&(((CAPI_MSG
*) msg
)->info
.facility_req
.structs
[1]), LI_REQ_SILENT_UPDATE
);
11296 ((CAPI_MSG
*) msg
)->info
.facility_req
.structs
[3] = 0;
11297 w
= api_put (notify_plci
->appl
, (CAPI_MSG
*) msg
);
11298 if (w
!= _QUEUE_FULL
)
11302 dbug (1, dprintf ("[%06lx] %s,%d: Interconnect notify failed %06x %d",
11303 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
11304 (char *)(FILE_
), __LINE__
,
11305 (dword
)((notify_plci
->Id
<< 8) | UnMapController (notify_plci
->adapter
->Id
)), w
));
11307 notify_plci
->li_notify_update
= false;
11310 } while (others
&& (notify_plci
!= NULL
));
11312 plci
->li_notify_update
= false;
11317 static void mixer_clear_config (PLCI
*plci
)
11319 DIVA_CAPI_ADAPTER
*a
;
11322 dbug (1, dprintf ("[%06lx] %s,%d: mixer_clear_config",
11323 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
11324 (char *)(FILE_
), __LINE__
));
11326 plci
->li_notify_update
= false;
11327 plci
->li_plci_b_write_pos
= 0;
11328 plci
->li_plci_b_read_pos
= 0;
11329 plci
->li_plci_b_req_pos
= 0;
11331 if ((plci
->li_bchannel_id
!= 0)
11332 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
11334 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11335 li_config_table
[i
].curchnl
= 0;
11336 li_config_table
[i
].channel
= 0;
11337 li_config_table
[i
].chflags
= 0;
11338 for (j
= 0; j
< li_total_channels
; j
++)
11340 li_config_table
[j
].flag_table
[i
] = 0;
11341 li_config_table
[i
].flag_table
[j
] = 0;
11342 li_config_table
[i
].coef_table
[j
] = 0;
11343 li_config_table
[j
].coef_table
[i
] = 0;
11347 li_config_table
[i
].coef_table
[i
] |= LI_COEF_CH_PC_SET
| LI_COEF_PC_CH_SET
;
11348 if ((plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
))
11350 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
11351 li_config_table
[i
].curchnl
= 0;
11352 li_config_table
[i
].channel
= 0;
11353 li_config_table
[i
].chflags
= 0;
11354 for (j
= 0; j
< li_total_channels
; j
++)
11356 li_config_table
[i
].flag_table
[j
] = 0;
11357 li_config_table
[j
].flag_table
[i
] = 0;
11358 li_config_table
[i
].coef_table
[j
] = 0;
11359 li_config_table
[j
].coef_table
[i
] = 0;
11361 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
11363 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
11364 li_config_table
[i
].curchnl
= 0;
11365 li_config_table
[i
].channel
= 0;
11366 li_config_table
[i
].chflags
= 0;
11367 for (j
= 0; j
< li_total_channels
; j
++)
11369 li_config_table
[i
].flag_table
[j
] = 0;
11370 li_config_table
[j
].flag_table
[i
] = 0;
11371 li_config_table
[i
].coef_table
[j
] = 0;
11372 li_config_table
[j
].coef_table
[i
] = 0;
11381 static void mixer_prepare_switch (dword Id
, PLCI
*plci
)
11384 dbug (1, dprintf ("[%06lx] %s,%d: mixer_prepare_switch",
11385 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11389 mixer_indication_coefs_set (Id
, plci
);
11390 } while (plci
->li_plci_b_read_pos
!= plci
->li_plci_b_req_pos
);
11394 static word
mixer_save_config (dword Id
, PLCI
*plci
, byte Rc
)
11396 DIVA_CAPI_ADAPTER
*a
;
11399 dbug (1, dprintf ("[%06lx] %s,%d: mixer_save_config %02x %d",
11400 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
11403 if ((plci
->li_bchannel_id
!= 0)
11404 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
11406 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11407 for (j
= 0; j
< li_total_channels
; j
++)
11409 li_config_table
[i
].coef_table
[j
] &= 0xf;
11410 li_config_table
[j
].coef_table
[i
] &= 0xf;
11413 li_config_table
[i
].coef_table
[i
] |= LI_COEF_CH_PC_SET
| LI_COEF_PC_CH_SET
;
11419 static word
mixer_restore_config (dword Id
, PLCI
*plci
, byte Rc
)
11421 DIVA_CAPI_ADAPTER
*a
;
11424 dbug (1, dprintf ("[%06lx] %s,%d: mixer_restore_config %02x %d",
11425 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
11429 if ((plci
->B1_facilities
& B1_FACILITY_MIXER
)
11430 && (plci
->li_bchannel_id
!= 0)
11431 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
11433 switch (plci
->adjust_b_state
)
11435 case ADJUST_B_RESTORE_MIXER_1
:
11436 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11438 plci
->internal_command
= plci
->adjust_b_command
;
11439 if (plci_nl_busy (plci
))
11441 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_1
;
11444 xconnect_query_addresses (plci
);
11445 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_2
;
11448 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_5
;
11450 case ADJUST_B_RESTORE_MIXER_2
:
11451 case ADJUST_B_RESTORE_MIXER_3
:
11452 case ADJUST_B_RESTORE_MIXER_4
:
11453 if ((Rc
!= OK
) && (Rc
!= OK_FC
) && (Rc
!= 0))
11455 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B query addresses failed %02x",
11456 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
11457 Info
= _WRONG_STATE
;
11462 if (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_2
)
11463 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_3
;
11464 else if (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_4
)
11465 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_5
;
11469 if (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_2
)
11470 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_4
;
11471 else if (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_3
)
11472 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_5
;
11474 if (plci
->adjust_b_state
!= ADJUST_B_RESTORE_MIXER_5
)
11476 plci
->internal_command
= plci
->adjust_b_command
;
11479 case ADJUST_B_RESTORE_MIXER_5
:
11480 xconnect_write_coefs (plci
, plci
->adjust_b_command
);
11481 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_6
;
11483 case ADJUST_B_RESTORE_MIXER_6
:
11484 if (!xconnect_write_coefs_process (Id
, plci
, Rc
))
11486 dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed",
11487 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11488 Info
= _FACILITY_NOT_SUPPORTED
;
11491 if (plci
->internal_command
)
11493 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_7
;
11494 case ADJUST_B_RESTORE_MIXER_7
:
11502 static void mixer_command (dword Id
, PLCI
*plci
, byte Rc
)
11504 DIVA_CAPI_ADAPTER
*a
;
11505 word i
, internal_command
, Info
;
11507 dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x",
11508 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
,
11513 internal_command
= plci
->internal_command
;
11514 plci
->internal_command
= 0;
11515 switch (plci
->li_cmd
)
11517 case LI_REQ_CONNECT
:
11518 case LI_REQ_DISCONNECT
:
11519 case LI_REQ_SILENT_UPDATE
:
11520 switch (internal_command
)
11523 if (plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
)
11525 adjust_b1_resource (Id
, plci
, NULL
, (word
)(plci
->B1_facilities
|
11526 B1_FACILITY_MIXER
), MIXER_COMMAND_1
);
11528 case MIXER_COMMAND_1
:
11529 if (plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
)
11531 if (adjust_b_process (Id
, plci
, Rc
) != GOOD
)
11533 dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed",
11534 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11535 Info
= _FACILITY_NOT_SUPPORTED
;
11538 if (plci
->internal_command
)
11541 plci
->li_plci_b_req_pos
= plci
->li_plci_b_write_pos
;
11542 if ((plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
)
11543 || ((get_b1_facilities (plci
, plci
->B1_resource
) & B1_FACILITY_MIXER
)
11544 && (add_b1_facilities (plci
, plci
->B1_resource
, (word
)(plci
->B1_facilities
&
11545 ~B1_FACILITY_MIXER
)) == plci
->B1_resource
)))
11547 xconnect_write_coefs (plci
, MIXER_COMMAND_2
);
11553 mixer_indication_coefs_set (Id
, plci
);
11554 } while (plci
->li_plci_b_read_pos
!= plci
->li_plci_b_req_pos
);
11556 case MIXER_COMMAND_2
:
11557 if ((plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
)
11558 || ((get_b1_facilities (plci
, plci
->B1_resource
) & B1_FACILITY_MIXER
)
11559 && (add_b1_facilities (plci
, plci
->B1_resource
, (word
)(plci
->B1_facilities
&
11560 ~B1_FACILITY_MIXER
)) == plci
->B1_resource
)))
11562 if (!xconnect_write_coefs_process (Id
, plci
, Rc
))
11564 dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed",
11565 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11566 if (plci
->li_plci_b_write_pos
!= plci
->li_plci_b_req_pos
)
11570 plci
->li_plci_b_write_pos
= (plci
->li_plci_b_write_pos
== 0) ?
11571 LI_PLCI_B_QUEUE_ENTRIES
-1 : plci
->li_plci_b_write_pos
- 1;
11572 i
= (plci
->li_plci_b_write_pos
== 0) ?
11573 LI_PLCI_B_QUEUE_ENTRIES
-1 : plci
->li_plci_b_write_pos
- 1;
11574 } while ((plci
->li_plci_b_write_pos
!= plci
->li_plci_b_req_pos
)
11575 && !(plci
->li_plci_b_queue
[i
] & LI_PLCI_B_LAST_FLAG
));
11577 Info
= _FACILITY_NOT_SUPPORTED
;
11580 if (plci
->internal_command
)
11583 if (!(plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
))
11585 adjust_b1_resource (Id
, plci
, NULL
, (word
)(plci
->B1_facilities
&
11586 ~B1_FACILITY_MIXER
), MIXER_COMMAND_3
);
11588 case MIXER_COMMAND_3
:
11589 if (!(plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
))
11591 if (adjust_b_process (Id
, plci
, Rc
) != GOOD
)
11593 dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed",
11594 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11595 Info
= _FACILITY_NOT_SUPPORTED
;
11598 if (plci
->internal_command
)
11605 if ((plci
->li_bchannel_id
== 0)
11606 || (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
!= plci
))
11608 dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out %d",
11609 UnMapId (Id
), (char *)(FILE_
), __LINE__
, (int)(plci
->li_bchannel_id
)));
11613 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11614 li_config_table
[i
].curchnl
= plci
->li_channel_bits
;
11615 if (!a
->li_pri
&& (plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
))
11617 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
11618 li_config_table
[i
].curchnl
= plci
->li_channel_bits
;
11619 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
11621 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
11622 li_config_table
[i
].curchnl
= plci
->li_channel_bits
;
11629 static void li_update_connect (dword Id
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
,
11630 dword plci_b_id
, byte connect
, dword li_flags
)
11632 word i
, ch_a
, ch_a_v
, ch_a_s
, ch_b
, ch_b_v
, ch_b_s
;
11634 DIVA_CAPI_ADAPTER
*a_b
;
11636 a_b
= &(adapter
[MapController ((byte
)(plci_b_id
& 0x7f)) - 1]);
11637 plci_b
= &(a_b
->plci
[((plci_b_id
>> 8) & 0xff) - 1]);
11638 ch_a
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11639 if (!a
->li_pri
&& (plci
->tel
== ADV_VOICE
)
11640 && (plci
== a
->AdvSignalPLCI
) && (Id
& EXT_CONTROLLER
))
11642 ch_a_v
= ch_a
+ MIXER_IC_CHANNEL_BASE
;
11643 ch_a_s
= (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
) ?
11644 a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
) : ch_a_v
;
11651 ch_b
= a_b
->li_base
+ (plci_b
->li_bchannel_id
- 1);
11652 if (!a_b
->li_pri
&& (plci_b
->tel
== ADV_VOICE
)
11653 && (plci_b
== a_b
->AdvSignalPLCI
) && (plci_b_id
& EXT_CONTROLLER
))
11655 ch_b_v
= ch_b
+ MIXER_IC_CHANNEL_BASE
;
11656 ch_b_s
= (a_b
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
) ?
11657 a_b
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci_b
->li_bchannel_id
) : ch_b_v
;
11666 li_config_table
[ch_a
].flag_table
[ch_a_v
] &= ~LI_FLAG_MONITOR
;
11667 li_config_table
[ch_a
].flag_table
[ch_a_s
] &= ~LI_FLAG_MONITOR
;
11668 li_config_table
[ch_a_v
].flag_table
[ch_a
] &= ~(LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
);
11669 li_config_table
[ch_a_s
].flag_table
[ch_a
] &= ~(LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
);
11671 li_config_table
[ch_a
].flag_table
[ch_b_v
] &= ~LI_FLAG_MONITOR
;
11672 li_config_table
[ch_a
].flag_table
[ch_b_s
] &= ~LI_FLAG_MONITOR
;
11673 li_config_table
[ch_b_v
].flag_table
[ch_a
] &= ~(LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
);
11674 li_config_table
[ch_b_s
].flag_table
[ch_a
] &= ~(LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
);
11675 if (ch_a_v
== ch_b_v
)
11677 li_config_table
[ch_a_v
].flag_table
[ch_b_v
] &= ~LI_FLAG_CONFERENCE
;
11678 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] &= ~LI_FLAG_CONFERENCE
;
11682 if (li_config_table
[ch_a_v
].flag_table
[ch_b_v
] & LI_FLAG_CONFERENCE
)
11684 for (i
= 0; i
< li_total_channels
; i
++)
11687 li_config_table
[ch_a_v
].flag_table
[i
] &= ~LI_FLAG_CONFERENCE
;
11690 if (li_config_table
[ch_a_s
].flag_table
[ch_b_v
] & LI_FLAG_CONFERENCE
)
11692 for (i
= 0; i
< li_total_channels
; i
++)
11695 li_config_table
[ch_a_s
].flag_table
[i
] &= ~LI_FLAG_CONFERENCE
;
11698 if (li_config_table
[ch_b_v
].flag_table
[ch_a_v
] & LI_FLAG_CONFERENCE
)
11700 for (i
= 0; i
< li_total_channels
; i
++)
11703 li_config_table
[i
].flag_table
[ch_a_v
] &= ~LI_FLAG_CONFERENCE
;
11706 if (li_config_table
[ch_b_v
].flag_table
[ch_a_s
] & LI_FLAG_CONFERENCE
)
11708 for (i
= 0; i
< li_total_channels
; i
++)
11711 li_config_table
[i
].flag_table
[ch_a_s
] &= ~LI_FLAG_CONFERENCE
;
11715 if (li_flags
& LI_FLAG_CONFERENCE_A_B
)
11717 li_config_table
[ch_b_v
].flag_table
[ch_a_v
] |= LI_FLAG_CONFERENCE
;
11718 li_config_table
[ch_b_s
].flag_table
[ch_a_v
] |= LI_FLAG_CONFERENCE
;
11719 li_config_table
[ch_b_v
].flag_table
[ch_a_s
] |= LI_FLAG_CONFERENCE
;
11720 li_config_table
[ch_b_s
].flag_table
[ch_a_s
] |= LI_FLAG_CONFERENCE
;
11722 if (li_flags
& LI_FLAG_CONFERENCE_B_A
)
11724 li_config_table
[ch_a_v
].flag_table
[ch_b_v
] |= LI_FLAG_CONFERENCE
;
11725 li_config_table
[ch_a_v
].flag_table
[ch_b_s
] |= LI_FLAG_CONFERENCE
;
11726 li_config_table
[ch_a_s
].flag_table
[ch_b_v
] |= LI_FLAG_CONFERENCE
;
11727 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] |= LI_FLAG_CONFERENCE
;
11729 if (li_flags
& LI_FLAG_MONITOR_A
)
11731 li_config_table
[ch_a
].flag_table
[ch_a_v
] |= LI_FLAG_MONITOR
;
11732 li_config_table
[ch_a
].flag_table
[ch_a_s
] |= LI_FLAG_MONITOR
;
11734 if (li_flags
& LI_FLAG_MONITOR_B
)
11736 li_config_table
[ch_a
].flag_table
[ch_b_v
] |= LI_FLAG_MONITOR
;
11737 li_config_table
[ch_a
].flag_table
[ch_b_s
] |= LI_FLAG_MONITOR
;
11739 if (li_flags
& LI_FLAG_ANNOUNCEMENT_A
)
11741 li_config_table
[ch_a_v
].flag_table
[ch_a
] |= LI_FLAG_ANNOUNCEMENT
;
11742 li_config_table
[ch_a_s
].flag_table
[ch_a
] |= LI_FLAG_ANNOUNCEMENT
;
11744 if (li_flags
& LI_FLAG_ANNOUNCEMENT_B
)
11746 li_config_table
[ch_b_v
].flag_table
[ch_a
] |= LI_FLAG_ANNOUNCEMENT
;
11747 li_config_table
[ch_b_s
].flag_table
[ch_a
] |= LI_FLAG_ANNOUNCEMENT
;
11749 if (li_flags
& LI_FLAG_MIX_A
)
11751 li_config_table
[ch_a_v
].flag_table
[ch_a
] |= LI_FLAG_MIX
;
11752 li_config_table
[ch_a_s
].flag_table
[ch_a
] |= LI_FLAG_MIX
;
11754 if (li_flags
& LI_FLAG_MIX_B
)
11756 li_config_table
[ch_b_v
].flag_table
[ch_a
] |= LI_FLAG_MIX
;
11757 li_config_table
[ch_b_s
].flag_table
[ch_a
] |= LI_FLAG_MIX
;
11759 if (ch_a_v
!= ch_a_s
)
11761 li_config_table
[ch_a_v
].flag_table
[ch_a_s
] |= LI_FLAG_CONFERENCE
;
11762 li_config_table
[ch_a_s
].flag_table
[ch_a_v
] |= LI_FLAG_CONFERENCE
;
11764 if (ch_b_v
!= ch_b_s
)
11766 li_config_table
[ch_b_v
].flag_table
[ch_b_s
] |= LI_FLAG_CONFERENCE
;
11767 li_config_table
[ch_b_s
].flag_table
[ch_b_v
] |= LI_FLAG_CONFERENCE
;
11772 static void li2_update_connect (dword Id
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
,
11773 dword plci_b_id
, byte connect
, dword li_flags
)
11775 word ch_a
, ch_a_v
, ch_a_s
, ch_b
, ch_b_v
, ch_b_s
;
11777 DIVA_CAPI_ADAPTER
*a_b
;
11779 a_b
= &(adapter
[MapController ((byte
)(plci_b_id
& 0x7f)) - 1]);
11780 plci_b
= &(a_b
->plci
[((plci_b_id
>> 8) & 0xff) - 1]);
11781 ch_a
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11782 if (!a
->li_pri
&& (plci
->tel
== ADV_VOICE
)
11783 && (plci
== a
->AdvSignalPLCI
) && (Id
& EXT_CONTROLLER
))
11785 ch_a_v
= ch_a
+ MIXER_IC_CHANNEL_BASE
;
11786 ch_a_s
= (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
) ?
11787 a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
) : ch_a_v
;
11794 ch_b
= a_b
->li_base
+ (plci_b
->li_bchannel_id
- 1);
11795 if (!a_b
->li_pri
&& (plci_b
->tel
== ADV_VOICE
)
11796 && (plci_b
== a_b
->AdvSignalPLCI
) && (plci_b_id
& EXT_CONTROLLER
))
11798 ch_b_v
= ch_b
+ MIXER_IC_CHANNEL_BASE
;
11799 ch_b_s
= (a_b
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
) ?
11800 a_b
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci_b
->li_bchannel_id
) : ch_b_v
;
11809 li_config_table
[ch_b
].flag_table
[ch_b_v
] &= ~LI_FLAG_MONITOR
;
11810 li_config_table
[ch_b
].flag_table
[ch_b_s
] &= ~LI_FLAG_MONITOR
;
11811 li_config_table
[ch_b_v
].flag_table
[ch_b
] &= ~LI_FLAG_MIX
;
11812 li_config_table
[ch_b_s
].flag_table
[ch_b
] &= ~LI_FLAG_MIX
;
11813 li_config_table
[ch_b
].flag_table
[ch_b
] &= ~LI_FLAG_PCCONNECT
;
11814 li_config_table
[ch_b
].chflags
&= ~(LI_CHFLAG_MONITOR
| LI_CHFLAG_MIX
| LI_CHFLAG_LOOP
);
11816 li_config_table
[ch_b_v
].flag_table
[ch_a_v
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11817 li_config_table
[ch_b_s
].flag_table
[ch_a_v
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11818 li_config_table
[ch_b_v
].flag_table
[ch_a_s
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11819 li_config_table
[ch_b_s
].flag_table
[ch_a_s
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11820 li_config_table
[ch_a_v
].flag_table
[ch_b_v
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11821 li_config_table
[ch_a_v
].flag_table
[ch_b_s
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11822 li_config_table
[ch_a_s
].flag_table
[ch_b_v
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11823 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11824 if (li_flags
& LI2_FLAG_INTERCONNECT_A_B
)
11826 li_config_table
[ch_b_v
].flag_table
[ch_a_v
] |= LI_FLAG_INTERCONNECT
;
11827 li_config_table
[ch_b_s
].flag_table
[ch_a_v
] |= LI_FLAG_INTERCONNECT
;
11828 li_config_table
[ch_b_v
].flag_table
[ch_a_s
] |= LI_FLAG_INTERCONNECT
;
11829 li_config_table
[ch_b_s
].flag_table
[ch_a_s
] |= LI_FLAG_INTERCONNECT
;
11831 if (li_flags
& LI2_FLAG_INTERCONNECT_B_A
)
11833 li_config_table
[ch_a_v
].flag_table
[ch_b_v
] |= LI_FLAG_INTERCONNECT
;
11834 li_config_table
[ch_a_v
].flag_table
[ch_b_s
] |= LI_FLAG_INTERCONNECT
;
11835 li_config_table
[ch_a_s
].flag_table
[ch_b_v
] |= LI_FLAG_INTERCONNECT
;
11836 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] |= LI_FLAG_INTERCONNECT
;
11838 if (li_flags
& LI2_FLAG_MONITOR_B
)
11840 li_config_table
[ch_b
].flag_table
[ch_b_v
] |= LI_FLAG_MONITOR
;
11841 li_config_table
[ch_b
].flag_table
[ch_b_s
] |= LI_FLAG_MONITOR
;
11843 if (li_flags
& LI2_FLAG_MIX_B
)
11845 li_config_table
[ch_b_v
].flag_table
[ch_b
] |= LI_FLAG_MIX
;
11846 li_config_table
[ch_b_s
].flag_table
[ch_b
] |= LI_FLAG_MIX
;
11848 if (li_flags
& LI2_FLAG_MONITOR_X
)
11849 li_config_table
[ch_b
].chflags
|= LI_CHFLAG_MONITOR
;
11850 if (li_flags
& LI2_FLAG_MIX_X
)
11851 li_config_table
[ch_b
].chflags
|= LI_CHFLAG_MIX
;
11852 if (li_flags
& LI2_FLAG_LOOP_B
)
11854 li_config_table
[ch_b_v
].flag_table
[ch_b_v
] |= LI_FLAG_INTERCONNECT
;
11855 li_config_table
[ch_b_s
].flag_table
[ch_b_v
] |= LI_FLAG_INTERCONNECT
;
11856 li_config_table
[ch_b_v
].flag_table
[ch_b_s
] |= LI_FLAG_INTERCONNECT
;
11857 li_config_table
[ch_b_s
].flag_table
[ch_b_s
] |= LI_FLAG_INTERCONNECT
;
11859 if (li_flags
& LI2_FLAG_LOOP_PC
)
11860 li_config_table
[ch_b
].flag_table
[ch_b
] |= LI_FLAG_PCCONNECT
;
11861 if (li_flags
& LI2_FLAG_LOOP_X
)
11862 li_config_table
[ch_b
].chflags
|= LI_CHFLAG_LOOP
;
11863 if (li_flags
& LI2_FLAG_PCCONNECT_A_B
)
11864 li_config_table
[ch_b_s
].flag_table
[ch_a_s
] |= LI_FLAG_PCCONNECT
;
11865 if (li_flags
& LI2_FLAG_PCCONNECT_B_A
)
11866 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] |= LI_FLAG_PCCONNECT
;
11867 if (ch_a_v
!= ch_a_s
)
11869 li_config_table
[ch_a_v
].flag_table
[ch_a_s
] |= LI_FLAG_CONFERENCE
;
11870 li_config_table
[ch_a_s
].flag_table
[ch_a_v
] |= LI_FLAG_CONFERENCE
;
11872 if (ch_b_v
!= ch_b_s
)
11874 li_config_table
[ch_b_v
].flag_table
[ch_b_s
] |= LI_FLAG_CONFERENCE
;
11875 li_config_table
[ch_b_s
].flag_table
[ch_b_v
] |= LI_FLAG_CONFERENCE
;
11880 static word
li_check_main_plci (dword Id
, PLCI
*plci
)
11884 dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
11885 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11886 return (_WRONG_IDENTIFIER
);
11889 || !plci
->NL
.Id
|| plci
->nl_remove_id
11890 || (plci
->li_bchannel_id
== 0))
11892 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
11893 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11894 return (_WRONG_STATE
);
11896 li_config_table
[plci
->adapter
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
11901 static PLCI
*li_check_plci_b (dword Id
, PLCI
*plci
,
11902 dword plci_b_id
, word plci_b_write_pos
, byte
*p_result
)
11907 if (((plci
->li_plci_b_read_pos
> plci_b_write_pos
) ? plci
->li_plci_b_read_pos
:
11908 LI_PLCI_B_QUEUE_ENTRIES
+ plci
->li_plci_b_read_pos
) - plci_b_write_pos
- 1 < 2)
11910 dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
11911 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11912 PUT_WORD (p_result
, _REQUEST_NOT_ALLOWED_IN_THIS_STATE
);
11916 if ((plci_b_id
& 0x7f) != 0)
11918 ctlr_b
= MapController ((byte
)(plci_b_id
& 0x7f));
11919 if ((ctlr_b
> max_adapter
) || ((ctlr_b
!= 0) && (adapter
[ctlr_b
- 1].request
== NULL
)))
11923 || (((plci_b_id
>> 8) & 0xff) == 0)
11924 || (((plci_b_id
>> 8) & 0xff) > adapter
[ctlr_b
- 1].max_plci
))
11926 dbug (1, dprintf ("[%06lx] %s,%d: LI invalid second PLCI %08lx",
11927 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11928 PUT_WORD (p_result
, _WRONG_IDENTIFIER
);
11931 plci_b
= &(adapter
[ctlr_b
- 1].plci
[((plci_b_id
>> 8) & 0xff) - 1]);
11933 || !plci_b
->NL
.Id
|| plci_b
->nl_remove_id
11934 || (plci_b
->li_bchannel_id
== 0))
11936 dbug (1, dprintf ("[%06lx] %s,%d: LI peer in wrong state %08lx",
11937 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11938 PUT_WORD (p_result
, _REQUEST_NOT_ALLOWED_IN_THIS_STATE
);
11941 li_config_table
[plci_b
->adapter
->li_base
+ (plci_b
->li_bchannel_id
- 1)].plci
= plci_b
;
11942 if (((byte
)(plci_b_id
& ~EXT_CONTROLLER
)) !=
11943 ((byte
)(UnMapController (plci
->adapter
->Id
) & ~EXT_CONTROLLER
))
11944 && (!(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11945 || !(plci_b
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)))
11947 dbug (1, dprintf ("[%06lx] %s,%d: LI not on same ctrl %08lx",
11948 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11949 PUT_WORD (p_result
, _WRONG_IDENTIFIER
);
11952 if (!(get_b1_facilities (plci_b
, add_b1_facilities (plci_b
, plci_b
->B1_resource
,
11953 (word
)(plci_b
->B1_facilities
| B1_FACILITY_MIXER
))) & B1_FACILITY_MIXER
))
11955 dbug (1, dprintf ("[%06lx] %s,%d: Interconnect peer cannot mix %d",
11956 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci_b
->B1_resource
));
11957 PUT_WORD (p_result
, _REQUEST_NOT_ALLOWED_IN_THIS_STATE
);
11964 static PLCI
*li2_check_plci_b (dword Id
, PLCI
*plci
,
11965 dword plci_b_id
, word plci_b_write_pos
, byte
*p_result
)
11970 if (((plci
->li_plci_b_read_pos
> plci_b_write_pos
) ? plci
->li_plci_b_read_pos
:
11971 LI_PLCI_B_QUEUE_ENTRIES
+ plci
->li_plci_b_read_pos
) - plci_b_write_pos
- 1 < 2)
11973 dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
11974 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
11975 PUT_WORD (p_result
, _WRONG_STATE
);
11979 if ((plci_b_id
& 0x7f) != 0)
11981 ctlr_b
= MapController ((byte
)(plci_b_id
& 0x7f));
11982 if ((ctlr_b
> max_adapter
) || ((ctlr_b
!= 0) && (adapter
[ctlr_b
- 1].request
== NULL
)))
11986 || (((plci_b_id
>> 8) & 0xff) == 0)
11987 || (((plci_b_id
>> 8) & 0xff) > adapter
[ctlr_b
- 1].max_plci
))
11989 dbug (1, dprintf ("[%06lx] %s,%d: LI invalid second PLCI %08lx",
11990 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11991 PUT_WORD (p_result
, _WRONG_IDENTIFIER
);
11994 plci_b
= &(adapter
[ctlr_b
- 1].plci
[((plci_b_id
>> 8) & 0xff) - 1]);
11996 || !plci_b
->NL
.Id
|| plci_b
->nl_remove_id
11997 || (plci_b
->li_bchannel_id
== 0)
11998 || (li_config_table
[plci_b
->adapter
->li_base
+ (plci_b
->li_bchannel_id
- 1)].plci
!= plci_b
))
12000 dbug (1, dprintf ("[%06lx] %s,%d: LI peer in wrong state %08lx",
12001 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
12002 PUT_WORD (p_result
, _WRONG_STATE
);
12005 if (((byte
)(plci_b_id
& ~EXT_CONTROLLER
)) !=
12006 ((byte
)(UnMapController (plci
->adapter
->Id
) & ~EXT_CONTROLLER
))
12007 && (!(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12008 || !(plci_b
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)))
12010 dbug (1, dprintf ("[%06lx] %s,%d: LI not on same ctrl %08lx",
12011 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
12012 PUT_WORD (p_result
, _WRONG_IDENTIFIER
);
12015 if (!(get_b1_facilities (plci_b
, add_b1_facilities (plci_b
, plci_b
->B1_resource
,
12016 (word
)(plci_b
->B1_facilities
| B1_FACILITY_MIXER
))) & B1_FACILITY_MIXER
))
12018 dbug (1, dprintf ("[%06lx] %s,%d: Interconnect peer cannot mix %d",
12019 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci_b
->B1_resource
));
12020 PUT_WORD (p_result
, _WRONG_STATE
);
12027 static byte
mixer_request (dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
12031 dword d
, li_flags
, plci_b_id
;
12033 API_PARSE li_parms
[3];
12034 API_PARSE li_req_parms
[3];
12035 API_PARSE li_participant_struct
[2];
12036 API_PARSE li_participant_parms
[3];
12037 word participant_parms_pos
;
12038 byte result_buffer
[32];
12041 word plci_b_write_pos
;
12043 dbug (1, dprintf ("[%06lx] %s,%d: mixer_request",
12044 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12047 result
= result_buffer
;
12048 result_buffer
[0] = 0;
12049 if (!(a
->profile
.Global_Options
& GL_LINE_INTERCONNECT_SUPPORTED
))
12051 dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
12052 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12053 Info
= _FACILITY_NOT_SUPPORTED
;
12055 else if (api_parse (&msg
[1].info
[1], msg
[1].length
, "ws", li_parms
))
12057 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12058 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12059 Info
= _WRONG_MESSAGE_FORMAT
;
12063 result_buffer
[0] = 3;
12064 PUT_WORD (&result_buffer
[1], GET_WORD (li_parms
[0].info
));
12065 result_buffer
[3] = 0;
12066 switch (GET_WORD (li_parms
[0].info
))
12068 case LI_GET_SUPPORTED_SERVICES
:
12069 if (appl
->appl_flags
& APPL_FLAG_OLD_LI_SPEC
)
12071 result_buffer
[0] = 17;
12072 result_buffer
[3] = 14;
12073 PUT_WORD (&result_buffer
[4], GOOD
);
12075 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_CH_CH
)
12076 d
|= LI_CONFERENCING_SUPPORTED
;
12077 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_CH_PC
)
12078 d
|= LI_MONITORING_SUPPORTED
;
12079 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_PC_CH
)
12080 d
|= LI_ANNOUNCEMENTS_SUPPORTED
| LI_MIXING_SUPPORTED
;
12081 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12082 d
|= LI_CROSS_CONTROLLER_SUPPORTED
;
12083 PUT_DWORD (&result_buffer
[6], d
);
12084 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12087 for (i
= 0; i
< li_total_channels
; i
++)
12089 if ((li_config_table
[i
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12090 && (li_config_table
[i
].adapter
->li_pri
12091 || (i
< li_config_table
[i
].adapter
->li_base
+ MIXER_BCHANNELS_BRI
)))
12099 d
= a
->li_pri
? a
->li_channels
: MIXER_BCHANNELS_BRI
;
12101 PUT_DWORD (&result_buffer
[10], d
/ 2);
12102 PUT_DWORD (&result_buffer
[14], d
);
12106 result_buffer
[0] = 25;
12107 result_buffer
[3] = 22;
12108 PUT_WORD (&result_buffer
[4], GOOD
);
12109 d
= LI2_ASYMMETRIC_SUPPORTED
| LI2_B_LOOPING_SUPPORTED
| LI2_X_LOOPING_SUPPORTED
;
12110 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_CH_PC
)
12111 d
|= LI2_MONITORING_SUPPORTED
| LI2_REMOTE_MONITORING_SUPPORTED
;
12112 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_PC_CH
)
12113 d
|= LI2_MIXING_SUPPORTED
| LI2_REMOTE_MIXING_SUPPORTED
;
12114 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_PC_PC
)
12115 d
|= LI2_PC_LOOPING_SUPPORTED
;
12116 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12117 d
|= LI2_CROSS_CONTROLLER_SUPPORTED
;
12118 PUT_DWORD (&result_buffer
[6], d
);
12119 d
= a
->li_pri
? a
->li_channels
: MIXER_BCHANNELS_BRI
;
12120 PUT_DWORD (&result_buffer
[10], d
/ 2);
12121 PUT_DWORD (&result_buffer
[14], d
- 1);
12122 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12125 for (i
= 0; i
< li_total_channels
; i
++)
12127 if ((li_config_table
[i
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12128 && (li_config_table
[i
].adapter
->li_pri
12129 || (i
< li_config_table
[i
].adapter
->li_base
+ MIXER_BCHANNELS_BRI
)))
12135 PUT_DWORD (&result_buffer
[18], d
/ 2);
12136 PUT_DWORD (&result_buffer
[22], d
- 1);
12140 case LI_REQ_CONNECT
:
12141 if (li_parms
[1].length
== 8)
12143 appl
->appl_flags
|= APPL_FLAG_OLD_LI_SPEC
;
12144 if (api_parse (&li_parms
[1].info
[1], li_parms
[1].length
, "dd", li_req_parms
))
12146 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12147 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12148 Info
= _WRONG_MESSAGE_FORMAT
;
12151 plci_b_id
= GET_DWORD (li_req_parms
[0].info
) & 0xffff;
12152 li_flags
= GET_DWORD (li_req_parms
[1].info
);
12153 Info
= li_check_main_plci (Id
, plci
);
12154 result_buffer
[0] = 9;
12155 result_buffer
[3] = 6;
12156 PUT_DWORD (&result_buffer
[4], plci_b_id
);
12157 PUT_WORD (&result_buffer
[8], GOOD
);
12160 result
= plci
->saved_msg
.info
;
12161 for (i
= 0; i
<= result_buffer
[0]; i
++)
12162 result
[i
] = result_buffer
[i
];
12163 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12164 plci_b
= li_check_plci_b (Id
, plci
, plci_b_id
, plci_b_write_pos
, &result
[8]);
12165 if (plci_b
== NULL
)
12167 li_update_connect (Id
, a
, plci
, plci_b_id
, true, li_flags
);
12168 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
| LI_PLCI_B_LAST_FLAG
;
12169 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ? 0 : plci_b_write_pos
+ 1;
12170 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12174 appl
->appl_flags
&= ~APPL_FLAG_OLD_LI_SPEC
;
12175 if (api_parse (&li_parms
[1].info
[1], li_parms
[1].length
, "ds", li_req_parms
))
12177 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12178 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12179 Info
= _WRONG_MESSAGE_FORMAT
;
12182 li_flags
= GET_DWORD (li_req_parms
[0].info
) & ~(LI2_FLAG_INTERCONNECT_A_B
| LI2_FLAG_INTERCONNECT_B_A
);
12183 Info
= li_check_main_plci (Id
, plci
);
12184 result_buffer
[0] = 7;
12185 result_buffer
[3] = 4;
12186 PUT_WORD (&result_buffer
[4], Info
);
12187 result_buffer
[6] = 0;
12190 result
= plci
->saved_msg
.info
;
12191 for (i
= 0; i
<= result_buffer
[0]; i
++)
12192 result
[i
] = result_buffer
[i
];
12193 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12194 participant_parms_pos
= 0;
12196 li2_update_connect (Id
, a
, plci
, UnMapId (Id
), true, li_flags
);
12197 while (participant_parms_pos
< li_req_parms
[1].length
)
12199 result
[result_pos
] = 6;
12201 PUT_DWORD (&result
[result_pos
- 6], 0);
12202 PUT_WORD (&result
[result_pos
- 2], GOOD
);
12203 if (api_parse (&li_req_parms
[1].info
[1 + participant_parms_pos
],
12204 (word
)(li_parms
[1].length
- participant_parms_pos
), "s", li_participant_struct
))
12206 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12207 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12208 PUT_WORD (&result
[result_pos
- 2], _WRONG_MESSAGE_FORMAT
);
12211 if (api_parse (&li_participant_struct
[0].info
[1],
12212 li_participant_struct
[0].length
, "dd", li_participant_parms
))
12214 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12215 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12216 PUT_WORD (&result
[result_pos
- 2], _WRONG_MESSAGE_FORMAT
);
12219 plci_b_id
= GET_DWORD (li_participant_parms
[0].info
) & 0xffff;
12220 li_flags
= GET_DWORD (li_participant_parms
[1].info
);
12221 PUT_DWORD (&result
[result_pos
- 6], plci_b_id
);
12222 if (sizeof(result
) - result_pos
< 7)
12224 dbug (1, dprintf ("[%06lx] %s,%d: LI result overrun",
12225 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12226 PUT_WORD (&result
[result_pos
- 2], _WRONG_STATE
);
12229 plci_b
= li2_check_plci_b (Id
, plci
, plci_b_id
, plci_b_write_pos
, &result
[result_pos
- 2]);
12230 if (plci_b
!= NULL
)
12232 li2_update_connect (Id
, a
, plci
, plci_b_id
, true, li_flags
);
12233 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
|
12234 ((li_flags
& (LI2_FLAG_INTERCONNECT_A_B
| LI2_FLAG_INTERCONNECT_B_A
|
12235 LI2_FLAG_PCCONNECT_A_B
| LI2_FLAG_PCCONNECT_B_A
)) ? 0 : LI_PLCI_B_DISC_FLAG
);
12236 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ? 0 : plci_b_write_pos
+ 1;
12238 participant_parms_pos
= (word
)((&li_participant_struct
[0].info
[1 + li_participant_struct
[0].length
]) -
12239 (&li_req_parms
[1].info
[1]));
12241 result
[0] = (byte
)(result_pos
- 1);
12242 result
[3] = (byte
)(result_pos
- 4);
12243 result
[6] = (byte
)(result_pos
- 7);
12244 i
= (plci_b_write_pos
== 0) ? LI_PLCI_B_QUEUE_ENTRIES
-1 : plci_b_write_pos
- 1;
12245 if ((plci_b_write_pos
== plci
->li_plci_b_read_pos
)
12246 || (plci
->li_plci_b_queue
[i
] & LI_PLCI_B_LAST_FLAG
))
12248 plci
->li_plci_b_queue
[plci_b_write_pos
] = LI_PLCI_B_SKIP_FLAG
| LI_PLCI_B_LAST_FLAG
;
12249 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ? 0 : plci_b_write_pos
+ 1;
12252 plci
->li_plci_b_queue
[i
] |= LI_PLCI_B_LAST_FLAG
;
12253 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12255 mixer_calculate_coefs (a
);
12256 plci
->li_channel_bits
= li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].channel
;
12257 mixer_notify_update (plci
, true);
12258 sendf (appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
12259 "wwS", Info
, SELECTOR_LINE_INTERCONNECT
, result
);
12261 plci
->li_cmd
= GET_WORD (li_parms
[0].info
);
12262 start_internal_command (Id
, plci
, mixer_command
);
12265 case LI_REQ_DISCONNECT
:
12266 if (li_parms
[1].length
== 4)
12268 appl
->appl_flags
|= APPL_FLAG_OLD_LI_SPEC
;
12269 if (api_parse (&li_parms
[1].info
[1], li_parms
[1].length
, "d", li_req_parms
))
12271 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12272 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12273 Info
= _WRONG_MESSAGE_FORMAT
;
12276 plci_b_id
= GET_DWORD (li_req_parms
[0].info
) & 0xffff;
12277 Info
= li_check_main_plci (Id
, plci
);
12278 result_buffer
[0] = 9;
12279 result_buffer
[3] = 6;
12280 PUT_DWORD (&result_buffer
[4], GET_DWORD (li_req_parms
[0].info
));
12281 PUT_WORD (&result_buffer
[8], GOOD
);
12284 result
= plci
->saved_msg
.info
;
12285 for (i
= 0; i
<= result_buffer
[0]; i
++)
12286 result
[i
] = result_buffer
[i
];
12287 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12288 plci_b
= li_check_plci_b (Id
, plci
, plci_b_id
, plci_b_write_pos
, &result
[8]);
12289 if (plci_b
== NULL
)
12291 li_update_connect (Id
, a
, plci
, plci_b_id
, false, 0);
12292 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
| LI_PLCI_B_DISC_FLAG
| LI_PLCI_B_LAST_FLAG
;
12293 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ? 0 : plci_b_write_pos
+ 1;
12294 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12298 appl
->appl_flags
&= ~APPL_FLAG_OLD_LI_SPEC
;
12299 if (api_parse (&li_parms
[1].info
[1], li_parms
[1].length
, "s", li_req_parms
))
12301 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12302 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12303 Info
= _WRONG_MESSAGE_FORMAT
;
12306 Info
= li_check_main_plci (Id
, plci
);
12307 result_buffer
[0] = 7;
12308 result_buffer
[3] = 4;
12309 PUT_WORD (&result_buffer
[4], Info
);
12310 result_buffer
[6] = 0;
12313 result
= plci
->saved_msg
.info
;
12314 for (i
= 0; i
<= result_buffer
[0]; i
++)
12315 result
[i
] = result_buffer
[i
];
12316 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12317 participant_parms_pos
= 0;
12319 while (participant_parms_pos
< li_req_parms
[0].length
)
12321 result
[result_pos
] = 6;
12323 PUT_DWORD (&result
[result_pos
- 6], 0);
12324 PUT_WORD (&result
[result_pos
- 2], GOOD
);
12325 if (api_parse (&li_req_parms
[0].info
[1 + participant_parms_pos
],
12326 (word
)(li_parms
[1].length
- participant_parms_pos
), "s", li_participant_struct
))
12328 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12329 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12330 PUT_WORD (&result
[result_pos
- 2], _WRONG_MESSAGE_FORMAT
);
12333 if (api_parse (&li_participant_struct
[0].info
[1],
12334 li_participant_struct
[0].length
, "d", li_participant_parms
))
12336 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12337 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12338 PUT_WORD (&result
[result_pos
- 2], _WRONG_MESSAGE_FORMAT
);
12341 plci_b_id
= GET_DWORD (li_participant_parms
[0].info
) & 0xffff;
12342 PUT_DWORD (&result
[result_pos
- 6], plci_b_id
);
12343 if (sizeof(result
) - result_pos
< 7)
12345 dbug (1, dprintf ("[%06lx] %s,%d: LI result overrun",
12346 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12347 PUT_WORD (&result
[result_pos
- 2], _WRONG_STATE
);
12350 plci_b
= li2_check_plci_b (Id
, plci
, plci_b_id
, plci_b_write_pos
, &result
[result_pos
- 2]);
12351 if (plci_b
!= NULL
)
12353 li2_update_connect (Id
, a
, plci
, plci_b_id
, false, 0);
12354 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
| LI_PLCI_B_DISC_FLAG
;
12355 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ? 0 : plci_b_write_pos
+ 1;
12357 participant_parms_pos
= (word
)((&li_participant_struct
[0].info
[1 + li_participant_struct
[0].length
]) -
12358 (&li_req_parms
[0].info
[1]));
12360 result
[0] = (byte
)(result_pos
- 1);
12361 result
[3] = (byte
)(result_pos
- 4);
12362 result
[6] = (byte
)(result_pos
- 7);
12363 i
= (plci_b_write_pos
== 0) ? LI_PLCI_B_QUEUE_ENTRIES
-1 : plci_b_write_pos
- 1;
12364 if ((plci_b_write_pos
== plci
->li_plci_b_read_pos
)
12365 || (plci
->li_plci_b_queue
[i
] & LI_PLCI_B_LAST_FLAG
))
12367 plci
->li_plci_b_queue
[plci_b_write_pos
] = LI_PLCI_B_SKIP_FLAG
| LI_PLCI_B_LAST_FLAG
;
12368 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ? 0 : plci_b_write_pos
+ 1;
12371 plci
->li_plci_b_queue
[i
] |= LI_PLCI_B_LAST_FLAG
;
12372 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12374 mixer_calculate_coefs (a
);
12375 plci
->li_channel_bits
= li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].channel
;
12376 mixer_notify_update (plci
, true);
12377 sendf (appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
12378 "wwS", Info
, SELECTOR_LINE_INTERCONNECT
, result
);
12380 plci
->li_cmd
= GET_WORD (li_parms
[0].info
);
12381 start_internal_command (Id
, plci
, mixer_command
);
12384 case LI_REQ_SILENT_UPDATE
:
12385 if (!plci
|| !plci
->State
12386 || !plci
->NL
.Id
|| plci
->nl_remove_id
12387 || (plci
->li_bchannel_id
== 0)
12388 || (li_config_table
[plci
->adapter
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
!= plci
))
12390 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
12391 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12394 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12395 if (((plci
->li_plci_b_read_pos
> plci_b_write_pos
) ? plci
->li_plci_b_read_pos
:
12396 LI_PLCI_B_QUEUE_ENTRIES
+ plci
->li_plci_b_read_pos
) - plci_b_write_pos
- 1 < 2)
12398 dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
12399 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12402 i
= (plci_b_write_pos
== 0) ? LI_PLCI_B_QUEUE_ENTRIES
-1 : plci_b_write_pos
- 1;
12403 if ((plci_b_write_pos
== plci
->li_plci_b_read_pos
)
12404 || (plci
->li_plci_b_queue
[i
] & LI_PLCI_B_LAST_FLAG
))
12406 plci
->li_plci_b_queue
[plci_b_write_pos
] = LI_PLCI_B_SKIP_FLAG
| LI_PLCI_B_LAST_FLAG
;
12407 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ? 0 : plci_b_write_pos
+ 1;
12410 plci
->li_plci_b_queue
[i
] |= LI_PLCI_B_LAST_FLAG
;
12411 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12412 plci
->li_channel_bits
= li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].channel
;
12414 plci
->li_cmd
= GET_WORD (li_parms
[0].info
);
12415 start_internal_command (Id
, plci
, mixer_command
);
12419 dbug (1, dprintf ("[%06lx] %s,%d: LI unknown request %04x",
12420 UnMapId (Id
), (char *)(FILE_
), __LINE__
, GET_WORD (li_parms
[0].info
)));
12421 Info
= _FACILITY_NOT_SUPPORTED
;
12424 sendf (appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
12425 "wwS", Info
, SELECTOR_LINE_INTERCONNECT
, result
);
12430 static void mixer_indication_coefs_set (dword Id
, PLCI
*plci
)
12433 DIVA_CAPI_ADAPTER
*a
;
12436 dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set",
12437 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12440 if (plci
->li_plci_b_read_pos
!= plci
->li_plci_b_req_pos
)
12444 d
= plci
->li_plci_b_queue
[plci
->li_plci_b_read_pos
];
12445 if (!(d
& LI_PLCI_B_SKIP_FLAG
))
12447 if (plci
->appl
->appl_flags
& APPL_FLAG_OLD_LI_SPEC
)
12449 if (d
& LI_PLCI_B_DISC_FLAG
)
12452 PUT_WORD (&result
[1], LI_IND_DISCONNECT
);
12454 PUT_WORD (&result
[4], _LI_USER_INITIATED
);
12459 PUT_WORD (&result
[1], LI_IND_CONNECT_ACTIVE
);
12461 PUT_DWORD (&result
[4], d
& ~LI_PLCI_B_FLAG_MASK
);
12466 if (d
& LI_PLCI_B_DISC_FLAG
)
12469 PUT_WORD (&result
[1], LI_IND_DISCONNECT
);
12471 PUT_DWORD (&result
[4], d
& ~LI_PLCI_B_FLAG_MASK
);
12472 PUT_WORD (&result
[8], _LI_USER_INITIATED
);
12477 PUT_WORD (&result
[1], LI_IND_CONNECT_ACTIVE
);
12479 PUT_DWORD (&result
[4], d
& ~LI_PLCI_B_FLAG_MASK
);
12482 sendf (plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0,
12483 "ws", SELECTOR_LINE_INTERCONNECT
, result
);
12485 plci
->li_plci_b_read_pos
= (plci
->li_plci_b_read_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ?
12486 0 : plci
->li_plci_b_read_pos
+ 1;
12487 } while (!(d
& LI_PLCI_B_LAST_FLAG
) && (plci
->li_plci_b_read_pos
!= plci
->li_plci_b_req_pos
));
12492 static void mixer_indication_xconnect_from (dword Id
, PLCI
*plci
, byte
*msg
, word length
)
12495 struct xconnect_transfer_address_s s
, *p
;
12496 DIVA_CAPI_ADAPTER
*a
;
12498 dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_from %d",
12499 UnMapId (Id
), (char *)(FILE_
), __LINE__
, (int) length
));
12503 for (i
= 1; i
< length
; i
+= 16)
12505 s
.card_address
.low
= msg
[i
] | (msg
[i
+1] << 8) | (((dword
)(msg
[i
+2])) << 16) | (((dword
)(msg
[i
+3])) << 24);
12506 s
.card_address
.high
= msg
[i
+4] | (msg
[i
+5] << 8) | (((dword
)(msg
[i
+6])) << 16) | (((dword
)(msg
[i
+7])) << 24);
12507 s
.offset
= msg
[i
+8] | (msg
[i
+9] << 8) | (((dword
)(msg
[i
+10])) << 16) | (((dword
)(msg
[i
+11])) << 24);
12508 ch
= msg
[i
+12] | (msg
[i
+13] << 8);
12509 j
= ch
& XCONNECT_CHANNEL_NUMBER_MASK
;
12510 if (!a
->li_pri
&& (plci
->li_bchannel_id
== 2))
12513 if (ch
& XCONNECT_CHANNEL_PORT_PC
)
12514 p
= &(li_config_table
[j
].send_pc
);
12516 p
= &(li_config_table
[j
].send_b
);
12517 p
->card_address
.low
= s
.card_address
.low
;
12518 p
->card_address
.high
= s
.card_address
.high
;
12519 p
->offset
= s
.offset
;
12520 li_config_table
[j
].channel
|= LI_CHANNEL_ADDRESSES_SET
;
12522 if (plci
->internal_command_queue
[0]
12523 && ((plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_2
)
12524 || (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_3
)
12525 || (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_4
)))
12527 (*(plci
->internal_command_queue
[0]))(Id
, plci
, 0);
12528 if (!plci
->internal_command
)
12529 next_internal_command (Id
, plci
);
12531 mixer_notify_update (plci
, true);
12535 static void mixer_indication_xconnect_to (dword Id
, PLCI
*plci
, byte
*msg
, word length
)
12538 dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_to %d",
12539 UnMapId (Id
), (char *)(FILE_
), __LINE__
, (int) length
));
12544 static byte
mixer_notify_source_removed (PLCI
*plci
, dword plci_b_id
)
12546 word plci_b_write_pos
;
12548 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12549 if (((plci
->li_plci_b_read_pos
> plci_b_write_pos
) ? plci
->li_plci_b_read_pos
:
12550 LI_PLCI_B_QUEUE_ENTRIES
+ plci
->li_plci_b_read_pos
) - plci_b_write_pos
- 1 < 1)
12552 dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
12553 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
12554 (char *)(FILE_
), __LINE__
));
12557 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
| LI_PLCI_B_DISC_FLAG
;
12558 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
-1) ? 0 : plci_b_write_pos
+ 1;
12559 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12564 static void mixer_remove (PLCI
*plci
)
12566 DIVA_CAPI_ADAPTER
*a
;
12571 dbug (1, dprintf ("[%06lx] %s,%d: mixer_remove",
12572 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
12573 (char *)(FILE_
), __LINE__
));
12576 plci_b_id
= (plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
);
12577 if (a
->profile
.Global_Options
& GL_LINE_INTERCONNECT_SUPPORTED
)
12579 if ((plci
->li_bchannel_id
!= 0)
12580 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
12582 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
12583 if ((li_config_table
[i
].curchnl
| li_config_table
[i
].channel
) & LI_CHANNEL_INVOLVED
)
12585 for (j
= 0; j
< li_total_channels
; j
++)
12587 if ((li_config_table
[i
].flag_table
[j
] & LI_FLAG_INTERCONNECT
)
12588 || (li_config_table
[j
].flag_table
[i
] & LI_FLAG_INTERCONNECT
))
12590 notify_plci
= li_config_table
[j
].plci
;
12591 if ((notify_plci
!= NULL
)
12592 && (notify_plci
!= plci
)
12593 && (notify_plci
->appl
!= NULL
)
12594 && !(notify_plci
->appl
->appl_flags
& APPL_FLAG_OLD_LI_SPEC
)
12595 && (notify_plci
->State
)
12596 && notify_plci
->NL
.Id
&& !notify_plci
->nl_remove_id
)
12598 mixer_notify_source_removed (notify_plci
, plci_b_id
);
12602 mixer_clear_config (plci
);
12603 mixer_calculate_coefs (a
);
12604 mixer_notify_update (plci
, true);
12606 li_config_table
[i
].plci
= NULL
;
12607 plci
->li_bchannel_id
= 0;
12613 /*------------------------------------------------------------------*/
12614 /* Echo canceller facilities */
12615 /*------------------------------------------------------------------*/
12618 static void ec_write_parameters (PLCI
*plci
)
12621 byte parameter_buffer
[6];
12623 dbug (1, dprintf ("[%06lx] %s,%d: ec_write_parameters",
12624 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
12625 (char *)(FILE_
), __LINE__
));
12627 parameter_buffer
[0] = 5;
12628 parameter_buffer
[1] = DSP_CTRL_SET_LEC_PARAMETERS
;
12629 PUT_WORD (¶meter_buffer
[2], plci
->ec_idi_options
);
12630 plci
->ec_idi_options
&= ~LEC_RESET_COEFFICIENTS
;
12631 w
= (plci
->ec_tail_length
== 0) ? 128 : plci
->ec_tail_length
;
12632 PUT_WORD (¶meter_buffer
[4], w
);
12633 add_p (plci
, FTY
, parameter_buffer
);
12634 sig_req (plci
, TEL_CTRL
, 0);
12639 static void ec_clear_config (PLCI
*plci
)
12642 dbug (1, dprintf ("[%06lx] %s,%d: ec_clear_config",
12643 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
12644 (char *)(FILE_
), __LINE__
));
12646 plci
->ec_idi_options
= LEC_ENABLE_ECHO_CANCELLER
|
12647 LEC_MANUAL_DISABLE
| LEC_ENABLE_NONLINEAR_PROCESSING
;
12648 plci
->ec_tail_length
= 0;
12652 static void ec_prepare_switch (dword Id
, PLCI
*plci
)
12655 dbug (1, dprintf ("[%06lx] %s,%d: ec_prepare_switch",
12656 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12661 static word
ec_save_config (dword Id
, PLCI
*plci
, byte Rc
)
12664 dbug (1, dprintf ("[%06lx] %s,%d: ec_save_config %02x %d",
12665 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
12671 static word
ec_restore_config (dword Id
, PLCI
*plci
, byte Rc
)
12675 dbug (1, dprintf ("[%06lx] %s,%d: ec_restore_config %02x %d",
12676 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
12679 if (plci
->B1_facilities
& B1_FACILITY_EC
)
12681 switch (plci
->adjust_b_state
)
12683 case ADJUST_B_RESTORE_EC_1
:
12684 plci
->internal_command
= plci
->adjust_b_command
;
12687 plci
->adjust_b_state
= ADJUST_B_RESTORE_EC_1
;
12690 ec_write_parameters (plci
);
12691 plci
->adjust_b_state
= ADJUST_B_RESTORE_EC_2
;
12693 case ADJUST_B_RESTORE_EC_2
:
12694 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
12696 dbug (1, dprintf ("[%06lx] %s,%d: Restore EC failed %02x",
12697 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
12698 Info
= _WRONG_STATE
;
12708 static void ec_command (dword Id
, PLCI
*plci
, byte Rc
)
12710 word internal_command
, Info
;
12713 dbug (1, dprintf ("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d",
12714 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
,
12715 plci
->ec_cmd
, plci
->ec_idi_options
, plci
->ec_tail_length
));
12718 if (plci
->appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
)
12721 PUT_WORD (&result
[1], EC_SUCCESS
);
12726 PUT_WORD (&result
[1], plci
->ec_cmd
);
12728 PUT_WORD (&result
[4], GOOD
);
12730 internal_command
= plci
->internal_command
;
12731 plci
->internal_command
= 0;
12732 switch (plci
->ec_cmd
)
12734 case EC_ENABLE_OPERATION
:
12735 case EC_FREEZE_COEFFICIENTS
:
12736 case EC_RESUME_COEFFICIENT_UPDATE
:
12737 case EC_RESET_COEFFICIENTS
:
12738 switch (internal_command
)
12741 adjust_b1_resource (Id
, plci
, NULL
, (word
)(plci
->B1_facilities
|
12742 B1_FACILITY_EC
), EC_COMMAND_1
);
12744 if (adjust_b_process (Id
, plci
, Rc
) != GOOD
)
12746 dbug (1, dprintf ("[%06lx] %s,%d: Load EC failed",
12747 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12748 Info
= _FACILITY_NOT_SUPPORTED
;
12751 if (plci
->internal_command
)
12756 plci
->internal_command
= EC_COMMAND_2
;
12759 plci
->internal_command
= EC_COMMAND_3
;
12760 ec_write_parameters (plci
);
12763 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
12765 dbug (1, dprintf ("[%06lx] %s,%d: Enable EC failed %02x",
12766 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
12767 Info
= _FACILITY_NOT_SUPPORTED
;
12774 case EC_DISABLE_OPERATION
:
12775 switch (internal_command
)
12779 if (plci
->B1_facilities
& B1_FACILITY_EC
)
12783 plci
->internal_command
= EC_COMMAND_1
;
12786 plci
->internal_command
= EC_COMMAND_2
;
12787 ec_write_parameters (plci
);
12792 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
12794 dbug (1, dprintf ("[%06lx] %s,%d: Disable EC failed %02x",
12795 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
12796 Info
= _FACILITY_NOT_SUPPORTED
;
12799 adjust_b1_resource (Id
, plci
, NULL
, (word
)(plci
->B1_facilities
&
12800 ~B1_FACILITY_EC
), EC_COMMAND_3
);
12802 if (adjust_b_process (Id
, plci
, Rc
) != GOOD
)
12804 dbug (1, dprintf ("[%06lx] %s,%d: Unload EC failed",
12805 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12806 Info
= _FACILITY_NOT_SUPPORTED
;
12809 if (plci
->internal_command
)
12815 sendf (plci
->appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, plci
->number
,
12816 "wws", Info
, (plci
->appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
) ?
12817 PRIV_SELECTOR_ECHO_CANCELLER
: SELECTOR_ECHO_CANCELLER
, result
);
12821 static byte
ec_request (dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
12825 API_PARSE ec_parms
[3];
12828 dbug (1, dprintf ("[%06lx] %s,%d: ec_request",
12829 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12833 if (!(a
->man_profile
.private_options
& (1L << PRIVATE_ECHO_CANCELLER
)))
12835 dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
12836 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12837 Info
= _FACILITY_NOT_SUPPORTED
;
12841 if (appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
)
12843 if (api_parse (&msg
[1].info
[1], msg
[1].length
, "w", ec_parms
))
12845 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12846 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12847 Info
= _WRONG_MESSAGE_FORMAT
;
12853 dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
12854 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12855 Info
= _WRONG_IDENTIFIER
;
12857 else if (!plci
->State
|| !plci
->NL
.Id
|| plci
->nl_remove_id
)
12859 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
12860 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12861 Info
= _WRONG_STATE
;
12866 plci
->ec_cmd
= GET_WORD (ec_parms
[0].info
);
12867 plci
->ec_idi_options
&= ~(LEC_MANUAL_DISABLE
| LEC_RESET_COEFFICIENTS
);
12869 PUT_WORD (&result
[1], EC_SUCCESS
);
12870 if (msg
[1].length
>= 4)
12872 opt
= GET_WORD (&ec_parms
[0].info
[2]);
12873 plci
->ec_idi_options
&= ~(LEC_ENABLE_NONLINEAR_PROCESSING
|
12874 LEC_ENABLE_2100HZ_DETECTOR
| LEC_REQUIRE_2100HZ_REVERSALS
);
12875 if (!(opt
& EC_DISABLE_NON_LINEAR_PROCESSING
))
12876 plci
->ec_idi_options
|= LEC_ENABLE_NONLINEAR_PROCESSING
;
12877 if (opt
& EC_DETECT_DISABLE_TONE
)
12878 plci
->ec_idi_options
|= LEC_ENABLE_2100HZ_DETECTOR
;
12879 if (!(opt
& EC_DO_NOT_REQUIRE_REVERSALS
))
12880 plci
->ec_idi_options
|= LEC_REQUIRE_2100HZ_REVERSALS
;
12881 if (msg
[1].length
>= 6)
12883 plci
->ec_tail_length
= GET_WORD (&ec_parms
[0].info
[4]);
12886 switch (plci
->ec_cmd
)
12888 case EC_ENABLE_OPERATION
:
12889 plci
->ec_idi_options
&= ~LEC_FREEZE_COEFFICIENTS
;
12890 start_internal_command (Id
, plci
, ec_command
);
12893 case EC_DISABLE_OPERATION
:
12894 plci
->ec_idi_options
= LEC_ENABLE_ECHO_CANCELLER
|
12895 LEC_MANUAL_DISABLE
| LEC_ENABLE_NONLINEAR_PROCESSING
|
12896 LEC_RESET_COEFFICIENTS
;
12897 start_internal_command (Id
, plci
, ec_command
);
12900 case EC_FREEZE_COEFFICIENTS
:
12901 plci
->ec_idi_options
|= LEC_FREEZE_COEFFICIENTS
;
12902 start_internal_command (Id
, plci
, ec_command
);
12905 case EC_RESUME_COEFFICIENT_UPDATE
:
12906 plci
->ec_idi_options
&= ~LEC_FREEZE_COEFFICIENTS
;
12907 start_internal_command (Id
, plci
, ec_command
);
12910 case EC_RESET_COEFFICIENTS
:
12911 plci
->ec_idi_options
|= LEC_RESET_COEFFICIENTS
;
12912 start_internal_command (Id
, plci
, ec_command
);
12916 dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x",
12917 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci
->ec_cmd
));
12918 PUT_WORD (&result
[1], EC_UNSUPPORTED_OPERATION
);
12925 if (api_parse (&msg
[1].info
[1], msg
[1].length
, "ws", ec_parms
))
12927 dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
12928 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12929 Info
= _WRONG_MESSAGE_FORMAT
;
12933 if (GET_WORD (ec_parms
[0].info
) == EC_GET_SUPPORTED_SERVICES
)
12936 PUT_WORD (&result
[1], EC_GET_SUPPORTED_SERVICES
);
12938 PUT_WORD (&result
[4], GOOD
);
12939 PUT_WORD (&result
[6], 0x0007);
12940 PUT_WORD (&result
[8], LEC_MAX_SUPPORTED_TAIL_LENGTH
);
12941 PUT_WORD (&result
[10], 0);
12943 else if (plci
== NULL
)
12945 dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
12946 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12947 Info
= _WRONG_IDENTIFIER
;
12949 else if (!plci
->State
|| !plci
->NL
.Id
|| plci
->nl_remove_id
)
12951 dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
12952 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
12953 Info
= _WRONG_STATE
;
12958 plci
->ec_cmd
= GET_WORD (ec_parms
[0].info
);
12959 plci
->ec_idi_options
&= ~(LEC_MANUAL_DISABLE
| LEC_RESET_COEFFICIENTS
);
12961 PUT_WORD (&result
[1], plci
->ec_cmd
);
12963 PUT_WORD (&result
[4], GOOD
);
12964 plci
->ec_idi_options
&= ~(LEC_ENABLE_NONLINEAR_PROCESSING
|
12965 LEC_ENABLE_2100HZ_DETECTOR
| LEC_REQUIRE_2100HZ_REVERSALS
);
12966 plci
->ec_tail_length
= 0;
12967 if (ec_parms
[1].length
>= 2)
12969 opt
= GET_WORD (&ec_parms
[1].info
[1]);
12970 if (opt
& EC_ENABLE_NON_LINEAR_PROCESSING
)
12971 plci
->ec_idi_options
|= LEC_ENABLE_NONLINEAR_PROCESSING
;
12972 if (opt
& EC_DETECT_DISABLE_TONE
)
12973 plci
->ec_idi_options
|= LEC_ENABLE_2100HZ_DETECTOR
;
12974 if (!(opt
& EC_DO_NOT_REQUIRE_REVERSALS
))
12975 plci
->ec_idi_options
|= LEC_REQUIRE_2100HZ_REVERSALS
;
12976 if (ec_parms
[1].length
>= 4)
12978 plci
->ec_tail_length
= GET_WORD (&ec_parms
[1].info
[3]);
12981 switch (plci
->ec_cmd
)
12983 case EC_ENABLE_OPERATION
:
12984 plci
->ec_idi_options
&= ~LEC_FREEZE_COEFFICIENTS
;
12985 start_internal_command (Id
, plci
, ec_command
);
12988 case EC_DISABLE_OPERATION
:
12989 plci
->ec_idi_options
= LEC_ENABLE_ECHO_CANCELLER
|
12990 LEC_MANUAL_DISABLE
| LEC_ENABLE_NONLINEAR_PROCESSING
|
12991 LEC_RESET_COEFFICIENTS
;
12992 start_internal_command (Id
, plci
, ec_command
);
12996 dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x",
12997 UnMapId (Id
), (char *)(FILE_
), __LINE__
, plci
->ec_cmd
));
12998 PUT_WORD (&result
[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP
);
13004 sendf (appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
13005 "wws", Info
, (appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
) ?
13006 PRIV_SELECTOR_ECHO_CANCELLER
: SELECTOR_ECHO_CANCELLER
, result
);
13011 static void ec_indication (dword Id
, PLCI
*plci
, byte
*msg
, word length
)
13015 dbug (1, dprintf ("[%06lx] %s,%d: ec_indication",
13016 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
13018 if (!(plci
->ec_idi_options
& LEC_MANUAL_DISABLE
))
13020 if (plci
->appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
)
13023 PUT_WORD (&result
[1], 0);
13026 case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ
:
13027 PUT_WORD (&result
[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ
);
13029 case LEC_DISABLE_TYPE_REVERSED_2100HZ
:
13030 PUT_WORD (&result
[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ
);
13032 case LEC_DISABLE_RELEASED
:
13033 PUT_WORD (&result
[1], EC_BYPASS_RELEASED
);
13040 PUT_WORD (&result
[1], EC_BYPASS_INDICATION
);
13042 PUT_WORD (&result
[4], 0);
13045 case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ
:
13046 PUT_WORD (&result
[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ
);
13048 case LEC_DISABLE_TYPE_REVERSED_2100HZ
:
13049 PUT_WORD (&result
[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ
);
13051 case LEC_DISABLE_RELEASED
:
13052 PUT_WORD (&result
[4], EC_BYPASS_RELEASED
);
13056 sendf (plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "ws", (plci
->appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
) ?
13057 PRIV_SELECTOR_ECHO_CANCELLER
: SELECTOR_ECHO_CANCELLER
, result
);
13063 /*------------------------------------------------------------------*/
13064 /* Advanced voice */
13065 /*------------------------------------------------------------------*/
13067 static void adv_voice_write_coefs (PLCI
*plci
, word write_command
)
13069 DIVA_CAPI_ADAPTER
*a
;
13074 byte ch_map
[MIXER_CHANNELS_BRI
];
13076 byte coef_buffer
[ADV_VOICE_COEF_BUFFER_SIZE
+ 2];
13078 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_write_coefs %d",
13079 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
13080 (char *)(FILE_
), __LINE__
, write_command
));
13083 p
= coef_buffer
+ 1;
13084 *(p
++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS
;
13086 while (i
+ sizeof(word
) <= a
->adv_voice_coef_length
)
13088 PUT_WORD (p
, GET_WORD (a
->adv_voice_coef_buffer
+ i
));
13092 while (i
< ADV_VOICE_OLD_COEF_COUNT
* sizeof(word
))
13094 PUT_WORD (p
, 0x8000);
13099 if (!a
->li_pri
&& (plci
->li_bchannel_id
== 0))
13101 if ((li_config_table
[a
->li_base
].plci
== NULL
) && (li_config_table
[a
->li_base
+ 1].plci
!= NULL
))
13103 plci
->li_bchannel_id
= 1;
13104 li_config_table
[a
->li_base
].plci
= plci
;
13105 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
13106 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
13107 (char *)(FILE_
), __LINE__
, plci
->li_bchannel_id
));
13109 else if ((li_config_table
[a
->li_base
].plci
!= NULL
) && (li_config_table
[a
->li_base
+ 1].plci
== NULL
))
13111 plci
->li_bchannel_id
= 2;
13112 li_config_table
[a
->li_base
+ 1].plci
= plci
;
13113 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
13114 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
13115 (char *)(FILE_
), __LINE__
, plci
->li_bchannel_id
));
13118 if (!a
->li_pri
&& (plci
->li_bchannel_id
!= 0)
13119 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
13121 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
13122 switch (write_command
)
13124 case ADV_VOICE_WRITE_ACTIVATION
:
13125 j
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
13126 k
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
13127 if (!(plci
->B1_facilities
& B1_FACILITY_MIXER
))
13129 li_config_table
[j
].flag_table
[i
] |= LI_FLAG_CONFERENCE
| LI_FLAG_MIX
;
13130 li_config_table
[i
].flag_table
[j
] |= LI_FLAG_CONFERENCE
| LI_FLAG_MONITOR
;
13132 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
13134 li_config_table
[k
].flag_table
[i
] |= LI_FLAG_CONFERENCE
| LI_FLAG_MIX
;
13135 li_config_table
[i
].flag_table
[k
] |= LI_FLAG_CONFERENCE
| LI_FLAG_MONITOR
;
13136 li_config_table
[k
].flag_table
[j
] |= LI_FLAG_CONFERENCE
;
13137 li_config_table
[j
].flag_table
[k
] |= LI_FLAG_CONFERENCE
;
13139 mixer_calculate_coefs (a
);
13140 li_config_table
[i
].curchnl
= li_config_table
[i
].channel
;
13141 li_config_table
[j
].curchnl
= li_config_table
[j
].channel
;
13142 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
13143 li_config_table
[k
].curchnl
= li_config_table
[k
].channel
;
13146 case ADV_VOICE_WRITE_DEACTIVATION
:
13147 for (j
= 0; j
< li_total_channels
; j
++)
13149 li_config_table
[i
].flag_table
[j
] = 0;
13150 li_config_table
[j
].flag_table
[i
] = 0;
13152 k
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
13153 for (j
= 0; j
< li_total_channels
; j
++)
13155 li_config_table
[k
].flag_table
[j
] = 0;
13156 li_config_table
[j
].flag_table
[k
] = 0;
13158 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
13160 k
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
13161 for (j
= 0; j
< li_total_channels
; j
++)
13163 li_config_table
[k
].flag_table
[j
] = 0;
13164 li_config_table
[j
].flag_table
[k
] = 0;
13167 mixer_calculate_coefs (a
);
13170 if (plci
->B1_facilities
& B1_FACILITY_MIXER
)
13173 if (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) <= a
->adv_voice_coef_length
)
13174 w
= GET_WORD (a
->adv_voice_coef_buffer
+ ADV_VOICE_NEW_COEF_BASE
);
13175 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
13176 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
13177 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
13178 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
13180 *(p
++) = (byte
)(w
>> 8);
13181 for (j
= 0; j
< sizeof(ch_map
); j
+= 2)
13183 ch_map
[j
] = (byte
)(j
+ (plci
->li_bchannel_id
- 1));
13184 ch_map
[j
+1] = (byte
)(j
+ (2 - plci
->li_bchannel_id
));
13186 for (n
= 0; n
< ARRAY_SIZE(mixer_write_prog_bri
); n
++)
13188 i
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].to_ch
];
13189 j
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].from_ch
];
13190 if (li_config_table
[i
].channel
& li_config_table
[j
].channel
& LI_CHANNEL_INVOLVED
)
13192 *(p
++) = ((li_config_table
[i
].coef_table
[j
] & mixer_write_prog_bri
[n
].mask
) ? 0x80 : 0x01);
13193 w
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
13194 li_config_table
[i
].coef_table
[j
] ^= (w
& mixer_write_prog_bri
[n
].mask
) << 4;
13198 *(p
++) = (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + n
< a
->adv_voice_coef_length
) ?
13199 a
->adv_voice_coef_buffer
[ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + n
] : 0x00;
13205 for (i
= ADV_VOICE_NEW_COEF_BASE
; i
< a
->adv_voice_coef_length
; i
++)
13206 *(p
++) = a
->adv_voice_coef_buffer
[i
];
13212 for (i
= ADV_VOICE_NEW_COEF_BASE
; i
< a
->adv_voice_coef_length
; i
++)
13213 *(p
++) = a
->adv_voice_coef_buffer
[i
];
13215 coef_buffer
[0] = (p
- coef_buffer
) - 1;
13216 add_p (plci
, FTY
, coef_buffer
);
13217 sig_req (plci
, TEL_CTRL
, 0);
13222 static void adv_voice_clear_config (PLCI
*plci
)
13224 DIVA_CAPI_ADAPTER
*a
;
13229 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_clear_config",
13230 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
13231 (char *)(FILE_
), __LINE__
));
13234 if ((plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
))
13236 a
->adv_voice_coef_length
= 0;
13238 if (!a
->li_pri
&& (plci
->li_bchannel_id
!= 0)
13239 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
13241 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
13242 li_config_table
[i
].curchnl
= 0;
13243 li_config_table
[i
].channel
= 0;
13244 li_config_table
[i
].chflags
= 0;
13245 for (j
= 0; j
< li_total_channels
; j
++)
13247 li_config_table
[i
].flag_table
[j
] = 0;
13248 li_config_table
[j
].flag_table
[i
] = 0;
13249 li_config_table
[i
].coef_table
[j
] = 0;
13250 li_config_table
[j
].coef_table
[i
] = 0;
13252 li_config_table
[i
].coef_table
[i
] |= LI_COEF_CH_PC_SET
| LI_COEF_PC_CH_SET
;
13253 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
13254 li_config_table
[i
].curchnl
= 0;
13255 li_config_table
[i
].channel
= 0;
13256 li_config_table
[i
].chflags
= 0;
13257 for (j
= 0; j
< li_total_channels
; j
++)
13259 li_config_table
[i
].flag_table
[j
] = 0;
13260 li_config_table
[j
].flag_table
[i
] = 0;
13261 li_config_table
[i
].coef_table
[j
] = 0;
13262 li_config_table
[j
].coef_table
[i
] = 0;
13264 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
13266 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
13267 li_config_table
[i
].curchnl
= 0;
13268 li_config_table
[i
].channel
= 0;
13269 li_config_table
[i
].chflags
= 0;
13270 for (j
= 0; j
< li_total_channels
; j
++)
13272 li_config_table
[i
].flag_table
[j
] = 0;
13273 li_config_table
[j
].flag_table
[i
] = 0;
13274 li_config_table
[i
].coef_table
[j
] = 0;
13275 li_config_table
[j
].coef_table
[i
] = 0;
13284 static void adv_voice_prepare_switch (dword Id
, PLCI
*plci
)
13287 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_prepare_switch",
13288 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
13293 static word
adv_voice_save_config (dword Id
, PLCI
*plci
, byte Rc
)
13296 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_save_config %02x %d",
13297 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
13303 static word
adv_voice_restore_config (dword Id
, PLCI
*plci
, byte Rc
)
13305 DIVA_CAPI_ADAPTER
*a
;
13308 dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_restore_config %02x %d",
13309 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
13313 if ((plci
->B1_facilities
& B1_FACILITY_VOICE
)
13314 && (plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
))
13316 switch (plci
->adjust_b_state
)
13318 case ADJUST_B_RESTORE_VOICE_1
:
13319 plci
->internal_command
= plci
->adjust_b_command
;
13322 plci
->adjust_b_state
= ADJUST_B_RESTORE_VOICE_1
;
13325 adv_voice_write_coefs (plci
, ADV_VOICE_WRITE_UPDATE
);
13326 plci
->adjust_b_state
= ADJUST_B_RESTORE_VOICE_2
;
13328 case ADJUST_B_RESTORE_VOICE_2
:
13329 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
13331 dbug (1, dprintf ("[%06lx] %s,%d: Restore voice config failed %02x",
13332 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
13333 Info
= _WRONG_STATE
;
13345 /*------------------------------------------------------------------*/
13346 /* B1 resource switching */
13347 /*------------------------------------------------------------------*/
13349 static byte b1_facilities_table
[] =
13351 0x00, /* 0 No bchannel resources */
13352 0x00, /* 1 Codec (automatic law) */
13353 0x00, /* 2 Codec (A-law) */
13354 0x00, /* 3 Codec (y-law) */
13355 0x00, /* 4 HDLC for X.21 */
13357 0x00, /* 6 External Device 0 */
13358 0x00, /* 7 External Device 1 */
13359 0x00, /* 8 HDLC 56k */
13360 0x00, /* 9 Transparent */
13361 0x00, /* 10 Loopback to network */
13362 0x00, /* 11 Test pattern to net */
13363 0x00, /* 12 Rate adaptation sync */
13364 0x00, /* 13 Rate adaptation async */
13365 0x00, /* 14 R-Interface */
13366 0x00, /* 15 HDLC 128k leased line */
13368 0x00, /* 17 Modem async */
13369 0x00, /* 18 Modem sync HDLC */
13370 0x00, /* 19 V.110 async HDLC */
13371 0x12, /* 20 Adv voice (Trans,mixer) */
13372 0x00, /* 21 Codec connected to IC */
13373 0x0c, /* 22 Trans,DTMF */
13374 0x1e, /* 23 Trans,DTMF+mixer */
13375 0x1f, /* 24 Trans,DTMF+mixer+local */
13376 0x13, /* 25 Trans,mixer+local */
13377 0x12, /* 26 HDLC,mixer */
13378 0x12, /* 27 HDLC 56k,mixer */
13379 0x2c, /* 28 Trans,LEC+DTMF */
13380 0x3e, /* 29 Trans,LEC+DTMF+mixer */
13381 0x3f, /* 30 Trans,LEC+DTMF+mixer+local */
13382 0x2c, /* 31 RTP,LEC+DTMF */
13383 0x3e, /* 32 RTP,LEC+DTMF+mixer */
13384 0x3f, /* 33 RTP,LEC+DTMF+mixer+local */
13385 0x00, /* 34 Signaling task */
13386 0x00, /* 35 PIAFS */
13387 0x0c, /* 36 Trans,DTMF+TONE */
13388 0x1e, /* 37 Trans,DTMF+TONE+mixer */
13389 0x1f /* 38 Trans,DTMF+TONE+mixer+local*/
13393 static word
get_b1_facilities (PLCI
* plci
, byte b1_resource
)
13395 word b1_facilities
;
13397 b1_facilities
= b1_facilities_table
[b1_resource
];
13398 if ((b1_resource
== 9) || (b1_resource
== 20) || (b1_resource
== 25))
13401 if (!(((plci
->requested_options_conn
| plci
->requested_options
) & (1L << PRIVATE_DTMF_TONE
))
13402 || (plci
->appl
&& (plci
->adapter
->requested_options_table
[plci
->appl
->Id
-1] & (1L << PRIVATE_DTMF_TONE
)))))
13405 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_SEND
)
13406 b1_facilities
|= B1_FACILITY_DTMFX
;
13407 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
)
13408 b1_facilities
|= B1_FACILITY_DTMFR
;
13411 if ((b1_resource
== 17) || (b1_resource
== 18))
13413 if (plci
->adapter
->manufacturer_features
& (MANUFACTURER_FEATURE_V18
| MANUFACTURER_FEATURE_VOWN
))
13414 b1_facilities
|= B1_FACILITY_DTMFX
| B1_FACILITY_DTMFR
;
13417 dbug (1, dprintf ("[%06lx] %s,%d: get_b1_facilities %d %04x",
13418 (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
13419 (char far *)(FILE_), __LINE__, b1_resource, b1_facilites));
13421 return (b1_facilities
);
13425 static byte
add_b1_facilities (PLCI
* plci
, byte b1_resource
, word b1_facilities
)
13429 switch (b1_resource
)
13433 if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13441 if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13459 if (b1_facilities
& B1_FACILITY_EC
)
13461 if (b1_facilities
& B1_FACILITY_LOCAL
)
13463 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13469 else if ((b1_facilities
& (B1_FACILITY_DTMFX
| B1_FACILITY_DTMFR
| B1_FACILITY_MIXER
))
13470 && (((plci
->requested_options_conn
| plci
->requested_options
) & (1L << PRIVATE_DTMF_TONE
))
13471 || (plci
->appl
&& (plci
->adapter
->requested_options_table
[plci
->appl
->Id
-1] & (1L << PRIVATE_DTMF_TONE
)))))
13473 if (b1_facilities
& B1_FACILITY_LOCAL
)
13475 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13481 else if (((plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_HARDDTMF
)
13482 && !(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
))
13483 || ((b1_facilities
& B1_FACILITY_DTMFR
)
13484 && ((b1_facilities
& B1_FACILITY_MIXER
)
13485 || !(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
)))
13486 || ((b1_facilities
& B1_FACILITY_DTMFX
)
13487 && ((b1_facilities
& B1_FACILITY_MIXER
)
13488 || !(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_SEND
))))
13490 if (b1_facilities
& B1_FACILITY_LOCAL
)
13492 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13499 if (b1_facilities
& B1_FACILITY_LOCAL
)
13501 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13511 if (b1_facilities
& B1_FACILITY_LOCAL
)
13513 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13522 dbug (1, dprintf ("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x",
13523 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
13524 (char *)(FILE_
), __LINE__
,
13525 b1_resource
, b1_facilities
, b
, get_b1_facilities (plci
, b
)));
13530 static void adjust_b1_facilities (PLCI
*plci
, byte new_b1_resource
, word new_b1_facilities
)
13532 word removed_facilities
;
13534 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x",
13535 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
13536 (char *)(FILE_
), __LINE__
, new_b1_resource
, new_b1_facilities
,
13537 new_b1_facilities
& get_b1_facilities (plci
, new_b1_resource
)));
13539 new_b1_facilities
&= get_b1_facilities (plci
, new_b1_resource
);
13540 removed_facilities
= plci
->B1_facilities
& ~new_b1_facilities
;
13542 if (removed_facilities
& B1_FACILITY_EC
)
13543 ec_clear_config (plci
);
13546 if (removed_facilities
& B1_FACILITY_DTMFR
)
13548 dtmf_rec_clear_config (plci
);
13549 dtmf_parameter_clear_config (plci
);
13551 if (removed_facilities
& B1_FACILITY_DTMFX
)
13552 dtmf_send_clear_config (plci
);
13555 if (removed_facilities
& B1_FACILITY_MIXER
)
13556 mixer_clear_config (plci
);
13558 if (removed_facilities
& B1_FACILITY_VOICE
)
13559 adv_voice_clear_config (plci
);
13560 plci
->B1_facilities
= new_b1_facilities
;
13564 static void adjust_b_clear (PLCI
*plci
)
13567 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_clear",
13568 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
13569 (char *)(FILE_
), __LINE__
));
13571 plci
->adjust_b_restore
= false;
13575 static word
adjust_b_process (dword Id
, PLCI
*plci
, byte Rc
)
13582 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_process %02x %d",
13583 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
13586 switch (plci
->adjust_b_state
)
13588 case ADJUST_B_START
:
13589 if ((plci
->adjust_b_parms_msg
== NULL
)
13590 && (plci
->adjust_b_mode
& ADJUST_B_MODE_SWITCH_L1
)
13591 && ((plci
->adjust_b_mode
& ~(ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_SWITCH_L1
|
13592 ADJUST_B_MODE_NO_RESOURCE
| ADJUST_B_MODE_RESTORE
)) == 0))
13594 b1_resource
= (plci
->adjust_b_mode
== ADJUST_B_MODE_NO_RESOURCE
) ?
13595 0 : add_b1_facilities (plci
, plci
->B1_resource
, plci
->adjust_b_facilities
);
13596 if (b1_resource
== plci
->B1_resource
)
13598 adjust_b1_facilities (plci
, b1_resource
, plci
->adjust_b_facilities
);
13601 if (plci
->adjust_b_facilities
& ~get_b1_facilities (plci
, b1_resource
))
13603 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x",
13604 UnMapId (Id
), (char *)(FILE_
), __LINE__
,
13605 plci
->B1_resource
, b1_resource
, plci
->adjust_b_facilities
));
13606 Info
= _WRONG_STATE
;
13610 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13613 mixer_prepare_switch (Id
, plci
);
13616 dtmf_prepare_switch (Id
, plci
);
13617 dtmf_parameter_prepare_switch (Id
, plci
);
13620 ec_prepare_switch (Id
, plci
);
13622 adv_voice_prepare_switch (Id
, plci
);
13624 plci
->adjust_b_state
= ADJUST_B_SAVE_MIXER_1
;
13626 case ADJUST_B_SAVE_MIXER_1
:
13627 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13630 Info
= mixer_save_config (Id
, plci
, Rc
);
13631 if ((Info
!= GOOD
) || plci
->internal_command
)
13635 plci
->adjust_b_state
= ADJUST_B_SAVE_DTMF_1
;
13637 case ADJUST_B_SAVE_DTMF_1
:
13638 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13641 Info
= dtmf_save_config (Id
, plci
, Rc
);
13642 if ((Info
!= GOOD
) || plci
->internal_command
)
13646 plci
->adjust_b_state
= ADJUST_B_REMOVE_L23_1
;
13647 case ADJUST_B_REMOVE_L23_1
:
13648 if ((plci
->adjust_b_mode
& ADJUST_B_MODE_REMOVE_L23
)
13649 && plci
->NL
.Id
&& !plci
->nl_remove_id
)
13651 plci
->internal_command
= plci
->adjust_b_command
;
13652 if (plci
->adjust_b_ncci
!= 0)
13654 ncci_ptr
= &(plci
->adapter
->ncci
[plci
->adjust_b_ncci
]);
13655 while (ncci_ptr
->data_pending
)
13657 plci
->data_sent_ptr
= ncci_ptr
->DBuffer
[ncci_ptr
->data_out
].P
;
13658 data_rc (plci
, plci
->adapter
->ncci_ch
[plci
->adjust_b_ncci
]);
13660 while (ncci_ptr
->data_ack_pending
)
13661 data_ack (plci
, plci
->adapter
->ncci_ch
[plci
->adjust_b_ncci
]);
13663 nl_req_ncci (plci
, REMOVE
,
13664 (byte
)((plci
->adjust_b_mode
& ADJUST_B_MODE_CONNECT
) ? plci
->adjust_b_ncci
: 0));
13666 plci
->adjust_b_state
= ADJUST_B_REMOVE_L23_2
;
13669 plci
->adjust_b_state
= ADJUST_B_REMOVE_L23_2
;
13671 case ADJUST_B_REMOVE_L23_2
:
13672 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
13674 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B remove failed %02x",
13675 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
13676 Info
= _WRONG_STATE
;
13679 if (plci
->adjust_b_mode
& ADJUST_B_MODE_REMOVE_L23
)
13681 if (plci_nl_busy (plci
))
13683 plci
->internal_command
= plci
->adjust_b_command
;
13687 plci
->adjust_b_state
= ADJUST_B_SAVE_EC_1
;
13689 case ADJUST_B_SAVE_EC_1
:
13690 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13693 Info
= ec_save_config (Id
, plci
, Rc
);
13694 if ((Info
!= GOOD
) || plci
->internal_command
)
13698 plci
->adjust_b_state
= ADJUST_B_SAVE_DTMF_PARAMETER_1
;
13700 case ADJUST_B_SAVE_DTMF_PARAMETER_1
:
13701 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13704 Info
= dtmf_parameter_save_config (Id
, plci
, Rc
);
13705 if ((Info
!= GOOD
) || plci
->internal_command
)
13709 plci
->adjust_b_state
= ADJUST_B_SAVE_VOICE_1
;
13711 case ADJUST_B_SAVE_VOICE_1
:
13712 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13714 Info
= adv_voice_save_config (Id
, plci
, Rc
);
13715 if ((Info
!= GOOD
) || plci
->internal_command
)
13718 plci
->adjust_b_state
= ADJUST_B_SWITCH_L1_1
;
13719 case ADJUST_B_SWITCH_L1_1
:
13720 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SWITCH_L1
)
13724 plci
->internal_command
= plci
->adjust_b_command
;
13727 if (plci
->adjust_b_parms_msg
!= NULL
)
13728 api_load_msg (plci
->adjust_b_parms_msg
, bp
);
13730 api_load_msg (&plci
->B_protocol
, bp
);
13731 Info
= add_b1 (plci
, bp
,
13732 (word
)((plci
->adjust_b_mode
& ADJUST_B_MODE_NO_RESOURCE
) ? 2 : 0),
13733 plci
->adjust_b_facilities
);
13736 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x",
13737 UnMapId (Id
), (char *)(FILE_
), __LINE__
,
13738 plci
->B1_resource
, plci
->adjust_b_facilities
));
13741 plci
->internal_command
= plci
->adjust_b_command
;
13742 sig_req (plci
, RESOURCES
, 0);
13744 plci
->adjust_b_state
= ADJUST_B_SWITCH_L1_2
;
13747 plci
->adjust_b_state
= ADJUST_B_SWITCH_L1_2
;
13749 case ADJUST_B_SWITCH_L1_2
:
13750 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
13752 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x",
13753 UnMapId (Id
), (char *)(FILE_
), __LINE__
,
13754 Rc
, plci
->B1_resource
, plci
->adjust_b_facilities
));
13755 Info
= _WRONG_STATE
;
13758 plci
->adjust_b_state
= ADJUST_B_RESTORE_VOICE_1
;
13760 case ADJUST_B_RESTORE_VOICE_1
:
13761 case ADJUST_B_RESTORE_VOICE_2
:
13762 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13764 Info
= adv_voice_restore_config (Id
, plci
, Rc
);
13765 if ((Info
!= GOOD
) || plci
->internal_command
)
13768 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_PARAMETER_1
;
13770 case ADJUST_B_RESTORE_DTMF_PARAMETER_1
:
13771 case ADJUST_B_RESTORE_DTMF_PARAMETER_2
:
13772 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13775 Info
= dtmf_parameter_restore_config (Id
, plci
, Rc
);
13776 if ((Info
!= GOOD
) || plci
->internal_command
)
13780 plci
->adjust_b_state
= ADJUST_B_RESTORE_EC_1
;
13782 case ADJUST_B_RESTORE_EC_1
:
13783 case ADJUST_B_RESTORE_EC_2
:
13784 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13787 Info
= ec_restore_config (Id
, plci
, Rc
);
13788 if ((Info
!= GOOD
) || plci
->internal_command
)
13792 plci
->adjust_b_state
= ADJUST_B_ASSIGN_L23_1
;
13793 case ADJUST_B_ASSIGN_L23_1
:
13794 if (plci
->adjust_b_mode
& ADJUST_B_MODE_ASSIGN_L23
)
13796 if (plci_nl_busy (plci
))
13798 plci
->internal_command
= plci
->adjust_b_command
;
13801 if (plci
->adjust_b_mode
& ADJUST_B_MODE_CONNECT
)
13802 plci
->call_dir
|= CALL_DIR_FORCE_OUTG_NL
;
13803 if (plci
->adjust_b_parms_msg
!= NULL
)
13804 api_load_msg (plci
->adjust_b_parms_msg
, bp
);
13806 api_load_msg (&plci
->B_protocol
, bp
);
13807 Info
= add_b23 (plci
, bp
);
13810 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x",
13811 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Info
));
13814 plci
->internal_command
= plci
->adjust_b_command
;
13815 nl_req_ncci (plci
, ASSIGN
, 0);
13817 plci
->adjust_b_state
= ADJUST_B_ASSIGN_L23_2
;
13820 plci
->adjust_b_state
= ADJUST_B_ASSIGN_L23_2
;
13822 case ADJUST_B_ASSIGN_L23_2
:
13823 if ((Rc
!= OK
) && (Rc
!= OK_FC
) && (Rc
!= ASSIGN_OK
))
13825 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B assign failed %02x",
13826 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
13827 Info
= _WRONG_STATE
;
13830 if (plci
->adjust_b_mode
& ADJUST_B_MODE_ASSIGN_L23
)
13832 if (Rc
!= ASSIGN_OK
)
13834 plci
->internal_command
= plci
->adjust_b_command
;
13838 if (plci
->adjust_b_mode
& ADJUST_B_MODE_USER_CONNECT
)
13840 plci
->adjust_b_restore
= true;
13843 plci
->adjust_b_state
= ADJUST_B_CONNECT_1
;
13844 case ADJUST_B_CONNECT_1
:
13845 if (plci
->adjust_b_mode
& ADJUST_B_MODE_CONNECT
)
13847 plci
->internal_command
= plci
->adjust_b_command
;
13848 if (plci_nl_busy (plci
))
13850 nl_req_ncci (plci
, N_CONNECT
, 0);
13852 plci
->adjust_b_state
= ADJUST_B_CONNECT_2
;
13855 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_1
;
13857 case ADJUST_B_CONNECT_2
:
13858 case ADJUST_B_CONNECT_3
:
13859 case ADJUST_B_CONNECT_4
:
13860 if ((Rc
!= OK
) && (Rc
!= OK_FC
) && (Rc
!= 0))
13862 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B connect failed %02x",
13863 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
13864 Info
= _WRONG_STATE
;
13869 if (plci
->adjust_b_mode
& ADJUST_B_MODE_CONNECT
)
13871 get_ncci (plci
, (byte
)(Id
>> 16), plci
->adjust_b_ncci
);
13872 Id
= (Id
& 0xffff) | (((dword
)(plci
->adjust_b_ncci
)) << 16);
13874 if (plci
->adjust_b_state
== ADJUST_B_CONNECT_2
)
13875 plci
->adjust_b_state
= ADJUST_B_CONNECT_3
;
13876 else if (plci
->adjust_b_state
== ADJUST_B_CONNECT_4
)
13877 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_1
;
13881 if (plci
->adjust_b_state
== ADJUST_B_CONNECT_2
)
13882 plci
->adjust_b_state
= ADJUST_B_CONNECT_4
;
13883 else if (plci
->adjust_b_state
== ADJUST_B_CONNECT_3
)
13884 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_1
;
13886 if (plci
->adjust_b_state
!= ADJUST_B_RESTORE_DTMF_1
)
13888 plci
->internal_command
= plci
->adjust_b_command
;
13892 case ADJUST_B_RESTORE_DTMF_1
:
13893 case ADJUST_B_RESTORE_DTMF_2
:
13894 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13897 Info
= dtmf_restore_config (Id
, plci
, Rc
);
13898 if ((Info
!= GOOD
) || plci
->internal_command
)
13902 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_1
;
13904 case ADJUST_B_RESTORE_MIXER_1
:
13905 case ADJUST_B_RESTORE_MIXER_2
:
13906 case ADJUST_B_RESTORE_MIXER_3
:
13907 case ADJUST_B_RESTORE_MIXER_4
:
13908 case ADJUST_B_RESTORE_MIXER_5
:
13909 case ADJUST_B_RESTORE_MIXER_6
:
13910 case ADJUST_B_RESTORE_MIXER_7
:
13911 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13914 Info
= mixer_restore_config (Id
, plci
, Rc
);
13915 if ((Info
!= GOOD
) || plci
->internal_command
)
13919 plci
->adjust_b_state
= ADJUST_B_END
;
13927 static void adjust_b1_resource (dword Id
, PLCI
*plci
, API_SAVE
*bp_msg
, word b1_facilities
, word internal_command
)
13930 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_resource %d %04x",
13931 UnMapId (Id
), (char *)(FILE_
), __LINE__
,
13932 plci
->B1_resource
, b1_facilities
));
13934 plci
->adjust_b_parms_msg
= bp_msg
;
13935 plci
->adjust_b_facilities
= b1_facilities
;
13936 plci
->adjust_b_command
= internal_command
;
13937 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
13938 if ((bp_msg
== NULL
) && (plci
->B1_resource
== 0))
13939 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_NO_RESOURCE
| ADJUST_B_MODE_SWITCH_L1
;
13941 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_SWITCH_L1
| ADJUST_B_MODE_RESTORE
;
13942 plci
->adjust_b_state
= ADJUST_B_START
;
13943 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B1 resource %d %04x...",
13944 UnMapId (Id
), (char *)(FILE_
), __LINE__
,
13945 plci
->B1_resource
, b1_facilities
));
13949 static void adjust_b_restore (dword Id
, PLCI
*plci
, byte Rc
)
13951 word internal_command
;
13953 dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_restore %02x %04x",
13954 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
13956 internal_command
= plci
->internal_command
;
13957 plci
->internal_command
= 0;
13958 switch (internal_command
)
13962 if (plci
->req_in
!= 0)
13964 plci
->internal_command
= ADJUST_B_RESTORE_1
;
13968 case ADJUST_B_RESTORE_1
:
13969 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
13971 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B enqueued failed %02x",
13972 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
13974 plci
->adjust_b_parms_msg
= NULL
;
13975 plci
->adjust_b_facilities
= plci
->B1_facilities
;
13976 plci
->adjust_b_command
= ADJUST_B_RESTORE_2
;
13977 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
13978 plci
->adjust_b_mode
= ADJUST_B_MODE_RESTORE
;
13979 plci
->adjust_b_state
= ADJUST_B_START
;
13980 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore...",
13981 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
13982 case ADJUST_B_RESTORE_2
:
13983 if (adjust_b_process (Id
, plci
, Rc
) != GOOD
)
13985 dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore failed",
13986 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
13988 if (plci
->internal_command
)
13995 static void reset_b3_command (dword Id
, PLCI
*plci
, byte Rc
)
13998 word internal_command
;
14000 dbug (1, dprintf ("[%06lx] %s,%d: reset_b3_command %02x %04x",
14001 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14004 internal_command
= plci
->internal_command
;
14005 plci
->internal_command
= 0;
14006 switch (internal_command
)
14010 plci
->adjust_b_parms_msg
= NULL
;
14011 plci
->adjust_b_facilities
= plci
->B1_facilities
;
14012 plci
->adjust_b_command
= RESET_B3_COMMAND_1
;
14013 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
14014 plci
->adjust_b_mode
= ADJUST_B_MODE_REMOVE_L23
| ADJUST_B_MODE_ASSIGN_L23
| ADJUST_B_MODE_CONNECT
;
14015 plci
->adjust_b_state
= ADJUST_B_START
;
14016 dbug (1, dprintf ("[%06lx] %s,%d: Reset B3...",
14017 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14018 case RESET_B3_COMMAND_1
:
14019 Info
= adjust_b_process (Id
, plci
, Rc
);
14022 dbug (1, dprintf ("[%06lx] %s,%d: Reset failed",
14023 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14026 if (plci
->internal_command
)
14030 /* sendf (plci->appl, _RESET_B3_R | CONFIRM, Id, plci->number, "w", Info);*/
14031 sendf(plci
->appl
,_RESET_B3_I
,Id
,0,"s","");
14035 static void select_b_command (dword Id
, PLCI
*plci
, byte Rc
)
14038 word internal_command
;
14041 dbug (1, dprintf ("[%06lx] %s,%d: select_b_command %02x %04x",
14042 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14045 internal_command
= plci
->internal_command
;
14046 plci
->internal_command
= 0;
14047 switch (internal_command
)
14051 plci
->adjust_b_parms_msg
= &plci
->saved_msg
;
14052 if ((plci
->tel
== ADV_VOICE
) && (plci
== plci
->adapter
->AdvSignalPLCI
))
14053 plci
->adjust_b_facilities
= plci
->B1_facilities
| B1_FACILITY_VOICE
;
14055 plci
->adjust_b_facilities
= plci
->B1_facilities
& ~B1_FACILITY_VOICE
;
14056 plci
->adjust_b_command
= SELECT_B_COMMAND_1
;
14057 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
14058 if (plci
->saved_msg
.parms
[0].length
== 0)
14060 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_REMOVE_L23
| ADJUST_B_MODE_SWITCH_L1
|
14061 ADJUST_B_MODE_NO_RESOURCE
;
14065 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_REMOVE_L23
| ADJUST_B_MODE_SWITCH_L1
|
14066 ADJUST_B_MODE_ASSIGN_L23
| ADJUST_B_MODE_USER_CONNECT
| ADJUST_B_MODE_RESTORE
;
14068 plci
->adjust_b_state
= ADJUST_B_START
;
14069 dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol...",
14070 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14071 case SELECT_B_COMMAND_1
:
14072 Info
= adjust_b_process (Id
, plci
, Rc
);
14075 dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol failed",
14076 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14079 if (plci
->internal_command
)
14081 if (plci
->tel
== ADV_VOICE
)
14085 esc_chi
[2] = plci
->b_channel
;
14086 SetVoiceChannel (plci
->adapter
->AdvCodecPLCI
, esc_chi
, plci
->adapter
);
14090 sendf (plci
->appl
, _SELECT_B_REQ
| CONFIRM
, Id
, plci
->number
, "w", Info
);
14094 static void fax_connect_ack_command (dword Id
, PLCI
*plci
, byte Rc
)
14097 word internal_command
;
14099 dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
14100 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14103 internal_command
= plci
->internal_command
;
14104 plci
->internal_command
= 0;
14105 switch (internal_command
)
14109 case FAX_CONNECT_ACK_COMMAND_1
:
14110 if (plci_nl_busy (plci
))
14112 plci
->internal_command
= FAX_CONNECT_ACK_COMMAND_1
;
14115 plci
->internal_command
= FAX_CONNECT_ACK_COMMAND_2
;
14116 plci
->NData
[0].P
= plci
->fax_connect_info_buffer
;
14117 plci
->NData
[0].PLength
= plci
->fax_connect_info_length
;
14118 plci
->NL
.X
= plci
->NData
;
14119 plci
->NL
.ReqCh
= 0;
14120 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_CONNECT_ACK
;
14121 plci
->adapter
->request (&plci
->NL
);
14123 case FAX_CONNECT_ACK_COMMAND_2
:
14124 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14126 dbug (1, dprintf ("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x",
14127 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
14131 if ((plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
14132 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
14134 if (plci
->B3_prot
== 4)
14135 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"s","");
14137 sendf(plci
->appl
,_CONNECT_B3_ACTIVE_I
,Id
,0,"S",plci
->ncpi_buffer
);
14138 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
14143 static void fax_edata_ack_command (dword Id
, PLCI
*plci
, byte Rc
)
14146 word internal_command
;
14148 dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
14149 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14152 internal_command
= plci
->internal_command
;
14153 plci
->internal_command
= 0;
14154 switch (internal_command
)
14158 case FAX_EDATA_ACK_COMMAND_1
:
14159 if (plci_nl_busy (plci
))
14161 plci
->internal_command
= FAX_EDATA_ACK_COMMAND_1
;
14164 plci
->internal_command
= FAX_EDATA_ACK_COMMAND_2
;
14165 plci
->NData
[0].P
= plci
->fax_connect_info_buffer
;
14166 plci
->NData
[0].PLength
= plci
->fax_edata_ack_length
;
14167 plci
->NL
.X
= plci
->NData
;
14168 plci
->NL
.ReqCh
= 0;
14169 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_EDATA
;
14170 plci
->adapter
->request (&plci
->NL
);
14172 case FAX_EDATA_ACK_COMMAND_2
:
14173 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14175 dbug (1, dprintf ("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x",
14176 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
14183 static void fax_connect_info_command (dword Id
, PLCI
*plci
, byte Rc
)
14186 word internal_command
;
14188 dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_info_command %02x %04x",
14189 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14192 internal_command
= plci
->internal_command
;
14193 plci
->internal_command
= 0;
14194 switch (internal_command
)
14198 case FAX_CONNECT_INFO_COMMAND_1
:
14199 if (plci_nl_busy (plci
))
14201 plci
->internal_command
= FAX_CONNECT_INFO_COMMAND_1
;
14204 plci
->internal_command
= FAX_CONNECT_INFO_COMMAND_2
;
14205 plci
->NData
[0].P
= plci
->fax_connect_info_buffer
;
14206 plci
->NData
[0].PLength
= plci
->fax_connect_info_length
;
14207 plci
->NL
.X
= plci
->NData
;
14208 plci
->NL
.ReqCh
= 0;
14209 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_EDATA
;
14210 plci
->adapter
->request (&plci
->NL
);
14212 case FAX_CONNECT_INFO_COMMAND_2
:
14213 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14215 dbug (1, dprintf ("[%06lx] %s,%d: FAX setting connect info failed %02x",
14216 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
14217 Info
= _WRONG_STATE
;
14220 if (plci_nl_busy (plci
))
14222 plci
->internal_command
= FAX_CONNECT_INFO_COMMAND_2
;
14225 plci
->command
= _CONNECT_B3_R
;
14226 nl_req_ncci (plci
, N_CONNECT
, 0);
14230 sendf (plci
->appl
, _CONNECT_B3_R
| CONFIRM
, Id
, plci
->number
, "w", Info
);
14234 static void fax_adjust_b23_command (dword Id
, PLCI
*plci
, byte Rc
)
14237 word internal_command
;
14239 dbug (1, dprintf ("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x",
14240 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14243 internal_command
= plci
->internal_command
;
14244 plci
->internal_command
= 0;
14245 switch (internal_command
)
14249 plci
->adjust_b_parms_msg
= NULL
;
14250 plci
->adjust_b_facilities
= plci
->B1_facilities
;
14251 plci
->adjust_b_command
= FAX_ADJUST_B23_COMMAND_1
;
14252 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
14253 plci
->adjust_b_mode
= ADJUST_B_MODE_REMOVE_L23
| ADJUST_B_MODE_ASSIGN_L23
;
14254 plci
->adjust_b_state
= ADJUST_B_START
;
14255 dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust B23...",
14256 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14257 case FAX_ADJUST_B23_COMMAND_1
:
14258 Info
= adjust_b_process (Id
, plci
, Rc
);
14261 dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust failed",
14262 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14265 if (plci
->internal_command
)
14267 case FAX_ADJUST_B23_COMMAND_2
:
14268 if (plci_nl_busy (plci
))
14270 plci
->internal_command
= FAX_ADJUST_B23_COMMAND_2
;
14273 plci
->command
= _CONNECT_B3_R
;
14274 nl_req_ncci (plci
, N_CONNECT
, 0);
14278 sendf (plci
->appl
, _CONNECT_B3_R
| CONFIRM
, Id
, plci
->number
, "w", Info
);
14282 static void fax_disconnect_command (dword Id
, PLCI
*plci
, byte Rc
)
14284 word internal_command
;
14286 dbug (1, dprintf ("[%06lx] %s,%d: fax_disconnect_command %02x %04x",
14287 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14289 internal_command
= plci
->internal_command
;
14290 plci
->internal_command
= 0;
14291 switch (internal_command
)
14295 plci
->internal_command
= FAX_DISCONNECT_COMMAND_1
;
14297 case FAX_DISCONNECT_COMMAND_1
:
14298 case FAX_DISCONNECT_COMMAND_2
:
14299 case FAX_DISCONNECT_COMMAND_3
:
14300 if ((Rc
!= OK
) && (Rc
!= OK_FC
) && (Rc
!= 0))
14302 dbug (1, dprintf ("[%06lx] %s,%d: FAX disconnect EDATA failed %02x",
14303 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
14308 if ((internal_command
== FAX_DISCONNECT_COMMAND_1
)
14309 || (internal_command
== FAX_DISCONNECT_COMMAND_2
))
14311 plci
->internal_command
= FAX_DISCONNECT_COMMAND_2
;
14316 if (internal_command
== FAX_DISCONNECT_COMMAND_1
)
14317 plci
->internal_command
= FAX_DISCONNECT_COMMAND_3
;
14325 static void rtp_connect_b3_req_command (dword Id
, PLCI
*plci
, byte Rc
)
14328 word internal_command
;
14330 dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x",
14331 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14334 internal_command
= plci
->internal_command
;
14335 plci
->internal_command
= 0;
14336 switch (internal_command
)
14340 case RTP_CONNECT_B3_REQ_COMMAND_1
:
14341 if (plci_nl_busy (plci
))
14343 plci
->internal_command
= RTP_CONNECT_B3_REQ_COMMAND_1
;
14346 plci
->internal_command
= RTP_CONNECT_B3_REQ_COMMAND_2
;
14347 nl_req_ncci (plci
, N_CONNECT
, 0);
14350 case RTP_CONNECT_B3_REQ_COMMAND_2
:
14351 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14353 dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect info failed %02x",
14354 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
14355 Info
= _WRONG_STATE
;
14358 if (plci_nl_busy (plci
))
14360 plci
->internal_command
= RTP_CONNECT_B3_REQ_COMMAND_2
;
14363 plci
->internal_command
= RTP_CONNECT_B3_REQ_COMMAND_3
;
14364 plci
->NData
[0].PLength
= plci
->internal_req_buffer
[0];
14365 plci
->NData
[0].P
= plci
->internal_req_buffer
+ 1;
14366 plci
->NL
.X
= plci
->NData
;
14367 plci
->NL
.ReqCh
= 0;
14368 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
14369 plci
->adapter
->request (&plci
->NL
);
14371 case RTP_CONNECT_B3_REQ_COMMAND_3
:
14374 sendf (plci
->appl
, _CONNECT_B3_R
| CONFIRM
, Id
, plci
->number
, "w", Info
);
14378 static void rtp_connect_b3_res_command (dword Id
, PLCI
*plci
, byte Rc
)
14381 word internal_command
;
14383 dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
14384 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14387 internal_command
= plci
->internal_command
;
14388 plci
->internal_command
= 0;
14389 switch (internal_command
)
14393 case RTP_CONNECT_B3_RES_COMMAND_1
:
14394 if (plci_nl_busy (plci
))
14396 plci
->internal_command
= RTP_CONNECT_B3_RES_COMMAND_1
;
14399 plci
->internal_command
= RTP_CONNECT_B3_RES_COMMAND_2
;
14400 nl_req_ncci (plci
, N_CONNECT_ACK
, (byte
)(Id
>> 16));
14403 case RTP_CONNECT_B3_RES_COMMAND_2
:
14404 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14406 dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
14407 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
));
14408 Info
= _WRONG_STATE
;
14411 if (plci_nl_busy (plci
))
14413 plci
->internal_command
= RTP_CONNECT_B3_RES_COMMAND_2
;
14416 sendf (plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
14417 plci
->internal_command
= RTP_CONNECT_B3_RES_COMMAND_3
;
14418 plci
->NData
[0].PLength
= plci
->internal_req_buffer
[0];
14419 plci
->NData
[0].P
= plci
->internal_req_buffer
+ 1;
14420 plci
->NL
.X
= plci
->NData
;
14421 plci
->NL
.ReqCh
= 0;
14422 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
14423 plci
->adapter
->request (&plci
->NL
);
14425 case RTP_CONNECT_B3_RES_COMMAND_3
:
14432 static void hold_save_command (dword Id
, PLCI
*plci
, byte Rc
)
14434 byte SS_Ind
[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
14436 word internal_command
;
14438 dbug (1, dprintf ("[%06lx] %s,%d: hold_save_command %02x %04x",
14439 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14442 internal_command
= plci
->internal_command
;
14443 plci
->internal_command
= 0;
14444 switch (internal_command
)
14450 plci
->adjust_b_parms_msg
= NULL
;
14451 plci
->adjust_b_facilities
= plci
->B1_facilities
;
14452 plci
->adjust_b_command
= HOLD_SAVE_COMMAND_1
;
14453 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
14454 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_REMOVE_L23
;
14455 plci
->adjust_b_state
= ADJUST_B_START
;
14456 dbug (1, dprintf ("[%06lx] %s,%d: HOLD save...",
14457 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14458 case HOLD_SAVE_COMMAND_1
:
14459 Info
= adjust_b_process (Id
, plci
, Rc
);
14462 dbug (1, dprintf ("[%06lx] %s,%d: HOLD save failed",
14463 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14466 if (plci
->internal_command
)
14469 sendf (plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "ws", 3, SS_Ind
);
14473 static void retrieve_restore_command (dword Id
, PLCI
*plci
, byte Rc
)
14475 byte SS_Ind
[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/
14477 word internal_command
;
14479 dbug (1, dprintf ("[%06lx] %s,%d: retrieve_restore_command %02x %04x",
14480 UnMapId (Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14483 internal_command
= plci
->internal_command
;
14484 plci
->internal_command
= 0;
14485 switch (internal_command
)
14489 plci
->adjust_b_parms_msg
= NULL
;
14490 plci
->adjust_b_facilities
= plci
->B1_facilities
;
14491 plci
->adjust_b_command
= RETRIEVE_RESTORE_COMMAND_1
;
14492 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
14493 plci
->adjust_b_mode
= ADJUST_B_MODE_ASSIGN_L23
| ADJUST_B_MODE_USER_CONNECT
| ADJUST_B_MODE_RESTORE
;
14494 plci
->adjust_b_state
= ADJUST_B_START
;
14495 dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore...",
14496 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14497 case RETRIEVE_RESTORE_COMMAND_1
:
14498 Info
= adjust_b_process (Id
, plci
, Rc
);
14501 dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore failed",
14502 UnMapId (Id
), (char *)(FILE_
), __LINE__
));
14505 if (plci
->internal_command
)
14508 sendf (plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "ws", 3, SS_Ind
);
14512 static void init_b1_config (PLCI
*plci
)
14515 dbug (1, dprintf ("[%06lx] %s,%d: init_b1_config",
14516 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
14517 (char *)(FILE_
), __LINE__
));
14519 plci
->B1_resource
= 0;
14520 plci
->B1_facilities
= 0;
14522 plci
->li_bchannel_id
= 0;
14523 mixer_clear_config (plci
);
14526 ec_clear_config (plci
);
14529 dtmf_rec_clear_config (plci
);
14530 dtmf_send_clear_config (plci
);
14531 dtmf_parameter_clear_config (plci
);
14533 adv_voice_clear_config (plci
);
14534 adjust_b_clear (plci
);
14538 static void clear_b1_config (PLCI
*plci
)
14541 dbug (1, dprintf ("[%06lx] %s,%d: clear_b1_config",
14542 (dword
)((plci
->Id
<< 8) | UnMapController (plci
->adapter
->Id
)),
14543 (char *)(FILE_
), __LINE__
));
14545 adv_voice_clear_config (plci
);
14546 adjust_b_clear (plci
);
14548 ec_clear_config (plci
);
14551 dtmf_rec_clear_config (plci
);
14552 dtmf_send_clear_config (plci
);
14553 dtmf_parameter_clear_config (plci
);
14556 if ((plci
->li_bchannel_id
!= 0)
14557 && (li_config_table
[plci
->adapter
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
14559 mixer_clear_config (plci
);
14560 li_config_table
[plci
->adapter
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= NULL
;
14561 plci
->li_bchannel_id
= 0;
14564 plci
->B1_resource
= 0;
14565 plci
->B1_facilities
= 0;
14569 /* -----------------------------------------------------------------
14570 XON protocol local helpers
14571 ----------------------------------------------------------------- */
14572 static void channel_flow_control_remove (PLCI
* plci
) {
14573 DIVA_CAPI_ADAPTER
* a
= plci
->adapter
;
14575 for(i
=1;i
<MAX_NL_CHANNEL
+1;i
++) {
14576 if (a
->ch_flow_plci
[i
] == plci
->Id
) {
14577 a
->ch_flow_plci
[i
] = 0;
14578 a
->ch_flow_control
[i
] = 0;
14583 static void channel_x_on (PLCI
* plci
, byte ch
) {
14584 DIVA_CAPI_ADAPTER
* a
= plci
->adapter
;
14585 if (a
->ch_flow_control
[ch
] & N_XON_SENT
) {
14586 a
->ch_flow_control
[ch
] &= ~N_XON_SENT
;
14590 static void channel_x_off (PLCI
* plci
, byte ch
, byte flag
) {
14591 DIVA_CAPI_ADAPTER
* a
= plci
->adapter
;
14592 if ((a
->ch_flow_control
[ch
] & N_RX_FLOW_CONTROL_MASK
) == 0) {
14593 a
->ch_flow_control
[ch
] |= (N_CH_XOFF
| flag
);
14594 a
->ch_flow_plci
[ch
] = plci
->Id
;
14595 a
->ch_flow_control_pending
++;
14599 static void channel_request_xon (PLCI
* plci
, byte ch
) {
14600 DIVA_CAPI_ADAPTER
* a
= plci
->adapter
;
14602 if (a
->ch_flow_control
[ch
] & N_CH_XOFF
) {
14603 a
->ch_flow_control
[ch
] |= N_XON_REQ
;
14604 a
->ch_flow_control
[ch
] &= ~N_CH_XOFF
;
14605 a
->ch_flow_control
[ch
] &= ~N_XON_CONNECT_IND
;
14609 static void channel_xmit_extended_xon (PLCI
* plci
) {
14610 DIVA_CAPI_ADAPTER
* a
;
14611 int max_ch
= ARRAY_SIZE(a
->ch_flow_control
);
14612 int i
, one_requested
= 0;
14614 if ((!plci
) || (!plci
->Id
) || ((a
= plci
->adapter
) == NULL
)) {
14618 for (i
= 0; i
< max_ch
; i
++) {
14619 if ((a
->ch_flow_control
[i
] & N_CH_XOFF
) &&
14620 (a
->ch_flow_control
[i
] & N_XON_CONNECT_IND
) &&
14621 (plci
->Id
== a
->ch_flow_plci
[i
])) {
14622 channel_request_xon (plci
, (byte
)i
);
14627 if (one_requested
) {
14628 channel_xmit_xon (plci
);
14633 Try to xmit next X_ON
14635 static int find_channel_with_pending_x_on (DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
) {
14636 int max_ch
= ARRAY_SIZE(a
->ch_flow_control
);
14639 if (!(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL
)) {
14643 if (a
->last_flow_control_ch
>= max_ch
) {
14644 a
->last_flow_control_ch
= 1;
14646 for (i
=a
->last_flow_control_ch
; i
< max_ch
; i
++) {
14647 if ((a
->ch_flow_control
[i
] & N_XON_REQ
) &&
14648 (plci
->Id
== a
->ch_flow_plci
[i
])) {
14649 a
->last_flow_control_ch
= i
+1;
14654 for (i
= 1; i
< a
->last_flow_control_ch
; i
++) {
14655 if ((a
->ch_flow_control
[i
] & N_XON_REQ
) &&
14656 (plci
->Id
== a
->ch_flow_plci
[i
])) {
14657 a
->last_flow_control_ch
= i
+1;
14665 static void channel_xmit_xon (PLCI
* plci
) {
14666 DIVA_CAPI_ADAPTER
* a
= plci
->adapter
;
14669 if (plci
->nl_req
|| !plci
->NL
.Id
|| plci
->nl_remove_id
) {
14672 if ((ch
= (byte
)find_channel_with_pending_x_on (a
, plci
)) == 0) {
14675 a
->ch_flow_control
[ch
] &= ~N_XON_REQ
;
14676 a
->ch_flow_control
[ch
] |= N_XON_SENT
;
14678 plci
->NL
.Req
= plci
->nl_req
= (byte
)N_XON
;
14679 plci
->NL
.ReqCh
= ch
;
14680 plci
->NL
.X
= plci
->NData
;
14682 plci
->NData
[0].P
= &plci
->RBuffer
[0];
14683 plci
->NData
[0].PLength
= 0;
14685 plci
->adapter
->request(&plci
->NL
);
14688 static int channel_can_xon (PLCI
* plci
, byte ch
) {
14690 DIVA_CAPI_ADAPTER
* a
;
14696 APPLptr
= plci
->appl
;
14702 NCCIcode
= a
->ch_ncci
[ch
] | (((word
) a
->Id
) << 8);
14704 /* count all buffers within the Application pool */
14705 /* belonging to the same NCCI. XON if a first is */
14709 for(i
=0; i
<APPLptr
->MaxBuffer
; i
++) {
14710 if(NCCIcode
==APPLptr
->DataNCCI
[i
]) count
++;
14711 if(!APPLptr
->DataNCCI
[i
] && Num
==0xffff) Num
= i
;
14713 if ((count
> 2) || (Num
== 0xffff)) {
14720 /*------------------------------------------------------------------*/
14722 static word
CPN_filter_ok(byte
*cpn
,DIVA_CAPI_ADAPTER
* a
,word offset
)
14729 /**********************************************************************************/
14730 /* function groups the listening applications according to the CIP mask and the */
14731 /* Info_Mask. Each group gets just one Connect_Ind. Some application manufacturer */
14732 /* are not multi-instance capable, so they start e.g. 30 applications what causes */
14733 /* big problems on application level (one call, 30 Connect_Ind, ect). The */
14734 /* function must be enabled by setting "a->group_optimization_enabled" from the */
14735 /* OS specific part (per adapter). */
14736 /**********************************************************************************/
14737 static void group_optimization(DIVA_CAPI_ADAPTER
* a
, PLCI
* plci
)
14739 word i
,j
,k
,busy
,group_found
;
14740 dword info_mask_group
[MAX_CIP_TYPES
];
14741 dword cip_mask_group
[MAX_CIP_TYPES
];
14742 word appl_number_group_type
[MAX_APPL
];
14745 set_group_ind_mask (plci
); /* all APPLs within this inc. call are allowed to dial in */
14747 if(!a
->group_optimization_enabled
)
14749 dbug(1,dprintf("No group optimization"));
14753 dbug(1,dprintf("Group optimization = 0x%x...", a
->group_optimization_enabled
));
14755 for(i
=0;i
<MAX_CIP_TYPES
;i
++)
14757 info_mask_group
[i
] = 0;
14758 cip_mask_group
[i
] = 0;
14760 for(i
=0;i
<MAX_APPL
;i
++)
14762 appl_number_group_type
[i
] = 0;
14764 for(i
=0; i
<max_appl
; i
++) /* check if any multi instance capable application is present */
14765 { /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */
14766 if(application
[i
].Id
&& (application
[i
].MaxNCCI
) > 1 && (a
->CIP_Mask
[i
]) && (a
->group_optimization_enabled
==1) )
14768 dbug(1,dprintf("Multi-Instance capable, no optimization required"));
14769 return; /* allow good application unfiltered access */
14772 for(i
=0; i
<max_appl
; i
++) /* Build CIP Groups */
14774 if(application
[i
].Id
&& a
->CIP_Mask
[i
] )
14776 for(k
=0,busy
=false; k
<a
->max_plci
; k
++)
14780 auxplci
= &a
->plci
[k
];
14781 if(auxplci
->appl
== &application
[i
]) /* application has a busy PLCI */
14784 dbug(1,dprintf("Appl 0x%x is busy",i
+1));
14786 else if(test_c_ind_mask_bit (auxplci
, i
)) /* application has an incoming call pending */
14789 dbug(1,dprintf("Appl 0x%x has inc. call pending",i
+1));
14794 for(j
=0,group_found
=0; j
<=(MAX_CIP_TYPES
) && !busy
&&!group_found
; j
++) /* build groups with free applications only */
14796 if(j
==MAX_CIP_TYPES
) /* all groups are in use but group still not found */
14797 { /* the MAX_CIP_TYPES group enables all calls because of field overflow */
14798 appl_number_group_type
[i
] = MAX_CIP_TYPES
;
14800 dbug(1,dprintf("Field overflow appl 0x%x",i
+1));
14802 else if( (info_mask_group
[j
]==a
->CIP_Mask
[i
]) && (cip_mask_group
[j
]==a
->Info_Mask
[i
]) )
14803 { /* is group already present ? */
14804 appl_number_group_type
[i
] = j
|0x80; /* store the group number for each application */
14806 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
]));
14808 else if(!info_mask_group
[j
])
14809 { /* establish a new group */
14810 appl_number_group_type
[i
] = j
|0x80; /* store the group number for each application */
14811 info_mask_group
[j
] = a
->CIP_Mask
[i
]; /* store the new CIP mask for the new group */
14812 cip_mask_group
[j
] = a
->Info_Mask
[i
]; /* store the new Info_Mask for this new group */
14814 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
]));
14820 for(i
=0; i
<max_appl
; i
++) /* Build group_optimization_mask_table */
14822 if(appl_number_group_type
[i
]) /* application is free, has listens and is member of a group */
14824 if(appl_number_group_type
[i
] == MAX_CIP_TYPES
)
14826 dbug(1,dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled",appl_number_group_type
[i
],i
+1));
14830 dbug(1,dprintf("Group 0x%x, valid appl = 0x%x",appl_number_group_type
[i
],i
+1));
14831 for(j
=i
+1; j
<max_appl
; j
++) /* search other group members and mark them as busy */
14833 if(appl_number_group_type
[i
] == appl_number_group_type
[j
])
14835 dbug(1,dprintf("Appl 0x%x is member of group 0x%x, no call",j
+1,appl_number_group_type
[j
]));
14836 clear_group_ind_mask_bit (plci
, j
); /* disable call on other group members */
14837 appl_number_group_type
[j
] = 0; /* remove disabled group member from group list */
14842 else /* application should not get a call */
14844 clear_group_ind_mask_bit (plci
, i
);
14852 /* OS notifies the driver about a application Capi_Register */
14853 word
CapiRegister(word id
)
14855 word i
,j
,appls_found
;
14858 DIVA_CAPI_ADAPTER
*a
;
14860 for(i
=0,appls_found
=0; i
<max_appl
; i
++)
14862 if( application
[i
].Id
&& (application
[i
].Id
!=id
) )
14864 appls_found
++; /* an application has been found */
14868 if(appls_found
) return true;
14869 for(i
=0; i
<max_adapter
; i
++) /* scan all adapters... */
14874 if(a
->flag_dynamic_l1_down
) /* remove adapter from L1 tristate (Huntgroup) */
14876 if(!appls_found
) /* first application does a capi register */
14878 if((j
=get_plci(a
))) /* activate L1 of all adapters */
14880 plci
= &a
->plci
[j
-1];
14882 add_p(plci
,OAD
,"\x01\xfd");
14883 add_p(plci
,CAI
,"\x01\x80");
14884 add_p(plci
,UID
,"\x06\x43\x61\x70\x69\x32\x30");
14885 add_p(plci
,SHIFT
|6,NULL
);
14886 add_p(plci
,SIN
,"\x02\x00\x00");
14887 plci
->internal_command
= START_L1_SIG_ASSIGN_PEND
;
14888 sig_req(plci
,ASSIGN
,DSIG_ID
);
14889 add_p(plci
,FTY
,"\x02\xff\x07"); /* l1 start */
14890 sig_req(plci
,SIG_CTRL
,0);
14900 /*------------------------------------------------------------------*/
14902 /* Functions for virtual Switching e.g. Transfer by join, Conference */
14904 static void VSwitchReqInd(PLCI
*plci
, dword Id
, byte
**parms
)
14907 /* Format of vswitch_t:
14910 2 byte VSWITCH_REQ/VSWITCH_IND
14912 4 word VSwitchcommand
14919 plci
->Sig
.Ind
==NCR_FACILITY
14923 for(i
=0;i
<MAX_MULTI_IE
;i
++)
14925 if(!parms
[i
][0]) continue;
14928 parms
[i
][0]=0; /* kill it */
14931 dbug(1,dprintf("VSwitchReqInd(%d)",parms
[i
][4]));
14932 switch(parms
[i
][4])
14935 if(!plci
->relatedPTYPLCI
||
14936 (plci
->ptyState
!=S_ECT
&& plci
->relatedPTYPLCI
->ptyState
!=S_ECT
))
14940 /* remember all necessary informations */
14941 if(parms
[i
][0]!=11 || parms
[i
][8]!=3) /* Length Test */
14945 if(parms
[i
][2]==VSWITCH_IND
&& parms
[i
][9]==1)
14946 { /* first indication after ECT-Request on Consultation Call */
14947 plci
->vswitchstate
=parms
[i
][9];
14948 parms
[i
][9]=2; /* State */
14949 /* now ask first Call to join */
14951 else if(parms
[i
][2]==VSWITCH_REQ
&& parms
[i
][9]==3)
14952 { /* Answer of VSWITCH_REQ from first Call */
14953 plci
->vswitchstate
=parms
[i
][9];
14954 /* tell consultation call to join
14955 and the protocol capabilities of the first call */
14961 plci
->vsprot
=parms
[i
][10]; /* protocol */
14962 plci
->vsprotdialect
=parms
[i
][11]; /* protocoldialect */
14963 /* send join request to related PLCI */
14964 parms
[i
][1]=VSWITCHIE
;
14965 parms
[i
][2]=VSWITCH_REQ
;
14967 plci
->relatedPTYPLCI
->command
= 0;
14968 plci
->relatedPTYPLCI
->internal_command
= VSWITCH_REQ_PEND
;
14969 add_p(plci
->relatedPTYPLCI
,ESC
,&parms
[i
][0]);
14970 sig_req(plci
->relatedPTYPLCI
,VSWITCH_REQ
,0);
14971 send_req(plci
->relatedPTYPLCI
);
14975 if(plci
->relatedPTYPLCI
&&
14976 plci
->vswitchstate
==3 &&
14977 plci
->relatedPTYPLCI
->vswitchstate
==3)
14979 add_p(plci
->relatedPTYPLCI
,ESC
,&parms
[i
][0]);
14980 sig_req(plci
->relatedPTYPLCI
,VSWITCH_REQ
,0);
14981 send_req(plci
->relatedPTYPLCI
);
14985 parms
[i
][0]=0; /* kill it */
14990 /*------------------------------------------------------------------*/
14992 static int diva_get_dma_descriptor (PLCI
*plci
, dword
*dma_magic
) {
14994 IDI_SYNC_REQ
* pReq
= (IDI_SYNC_REQ
*)&e
;
14996 if (!(diva_xdi_extended_features
& DIVA_CAPI_XDI_PROVIDES_RX_DMA
)) {
15000 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
15001 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
15003 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC
;
15004 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= -1;
15005 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
15006 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
15008 e
.user
[0] = plci
->adapter
->Id
- 1;
15009 plci
->adapter
->request((ENTITY
*)pReq
);
15011 if (!pReq
->xdi_dma_descriptor_operation
.info
.operation
&&
15012 (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
>= 0) &&
15013 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
) {
15014 *dma_magic
= pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
;
15015 dbug(3,dprintf("dma_alloc, a:%d (%d-%08x)",
15017 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
,
15019 return (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
);
15021 dbug(1,dprintf("dma_alloc failed"));
15026 static void diva_free_dma_descriptor (PLCI
*plci
, int nr
) {
15028 IDI_SYNC_REQ
* pReq
= (IDI_SYNC_REQ
*)&e
;
15034 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
15035 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
15037 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE
;
15038 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= nr
;
15039 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
15040 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
15042 e
.user
[0] = plci
->adapter
->Id
- 1;
15043 plci
->adapter
->request((ENTITY
*)pReq
);
15045 if (!pReq
->xdi_dma_descriptor_operation
.info
.operation
) {
15046 dbug(1,dprintf("dma_free(%d)", nr
));
15048 dbug(1,dprintf("dma_free failed (%d)", nr
));
15052 /*------------------------------------------------------------------*/