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.
26 #include <linux/bitmap.h>
36 #define FILE_ "MESSAGE.C"
39 /*------------------------------------------------------------------*/
40 /* This is options supported for all adapters that are server by */
41 /* XDI driver. Allo it is not necessary to ask it from every adapter*/
42 /* and it is not necessary to save it separate for every adapter */
43 /* Macrose defined here have only local meaning */
44 /*------------------------------------------------------------------*/
45 static dword diva_xdi_extended_features
= 0;
47 #define DIVA_CAPI_USE_CMA 0x00000001
48 #define DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR 0x00000002
49 #define DIVA_CAPI_XDI_PROVIDES_NO_CANCEL 0x00000004
50 #define DIVA_CAPI_XDI_PROVIDES_RX_DMA 0x00000008
53 CAPI can request to process all return codes self only if:
54 protocol code supports this && xdi supports this
56 #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))
58 /*------------------------------------------------------------------*/
59 /* local function prototypes */
60 /*------------------------------------------------------------------*/
62 static void group_optimization(DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
);
63 void AutomaticLaw(DIVA_CAPI_ADAPTER
*);
64 word
CapiRelease(word
);
65 word
CapiRegister(word
);
66 word
api_put(APPL
*, CAPI_MSG
*);
67 static word
api_parse(byte
*, word
, byte
*, API_PARSE
*);
68 static void api_save_msg(API_PARSE
*in
, byte
*format
, API_SAVE
*out
);
69 static void api_load_msg(API_SAVE
*in
, API_PARSE
*out
);
71 word
api_remove_start(void);
72 void api_remove_complete(void);
74 static void plci_remove(PLCI
*);
75 static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER
*a
);
76 static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER
*, IDI_SYNC_REQ
*);
78 void callback(ENTITY
*);
80 static void control_rc(PLCI
*, byte
, byte
, byte
, byte
, byte
);
81 static void data_rc(PLCI
*, byte
);
82 static void data_ack(PLCI
*, byte
);
83 static void sig_ind(PLCI
*);
84 static void SendInfo(PLCI
*, dword
, byte
**, byte
);
85 static void SendSetupInfo(APPL
*, PLCI
*, dword
, byte
**, byte
);
86 static void SendSSExtInd(APPL
*, PLCI
*plci
, dword Id
, byte
**parms
);
88 static void VSwitchReqInd(PLCI
*plci
, dword Id
, byte
**parms
);
90 static void nl_ind(PLCI
*);
92 static byte
connect_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
93 static byte
connect_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
94 static byte
connect_a_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
95 static byte
disconnect_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
96 static byte
disconnect_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
97 static byte
listen_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
98 static byte
info_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
99 static byte
info_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
100 static byte
alert_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
101 static byte
facility_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
102 static byte
facility_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
103 static byte
connect_b3_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
104 static byte
connect_b3_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
105 static byte
connect_b3_a_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
106 static byte
disconnect_b3_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
107 static byte
disconnect_b3_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
108 static byte
data_b3_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
109 static byte
data_b3_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
110 static byte
reset_b3_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
111 static byte
reset_b3_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
112 static byte
connect_b3_t90_a_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
113 static byte
select_b_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
114 static byte
manufacturer_req(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
115 static byte
manufacturer_res(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
117 static word
get_plci(DIVA_CAPI_ADAPTER
*);
118 static void add_p(PLCI
*, byte
, byte
*);
119 static void add_s(PLCI
*plci
, byte code
, API_PARSE
*p
);
120 static void add_ss(PLCI
*plci
, byte code
, API_PARSE
*p
);
121 static void add_ie(PLCI
*plci
, byte code
, byte
*p
, word p_length
);
122 static void add_d(PLCI
*, word
, byte
*);
123 static void add_ai(PLCI
*, API_PARSE
*);
124 static word
add_b1(PLCI
*, API_PARSE
*, word
, word
);
125 static word
add_b23(PLCI
*, API_PARSE
*);
126 static word
add_modem_b23(PLCI
*plci
, API_PARSE
*bp_parms
);
127 static void sig_req(PLCI
*, byte
, byte
);
128 static void nl_req_ncci(PLCI
*, byte
, byte
);
129 static void send_req(PLCI
*);
130 static void send_data(PLCI
*);
131 static word
plci_remove_check(PLCI
*);
132 static void listen_check(DIVA_CAPI_ADAPTER
*);
133 static byte
AddInfo(byte
**, byte
**, byte
*, byte
*);
134 static byte
getChannel(API_PARSE
*);
135 static void IndParse(PLCI
*, const word
*, byte
**, byte
);
136 static byte
ie_compare(byte
*, byte
*);
137 static word
find_cip(DIVA_CAPI_ADAPTER
*, byte
*, byte
*);
138 static word
CPN_filter_ok(byte
*cpn
, DIVA_CAPI_ADAPTER
*, word
);
143 static void channel_flow_control_remove(PLCI
*plci
);
144 static void channel_x_off(PLCI
*plci
, byte ch
, byte flag
);
145 static void channel_x_on(PLCI
*plci
, byte ch
);
146 static void channel_request_xon(PLCI
*plci
, byte ch
);
147 static void channel_xmit_xon(PLCI
*plci
);
148 static int channel_can_xon(PLCI
*plci
, byte ch
);
149 static void channel_xmit_extended_xon(PLCI
*plci
);
151 static byte
SendMultiIE(PLCI
*plci
, dword Id
, byte
**parms
, byte ie_type
, dword info_mask
, byte setupParse
);
152 static word
AdvCodecSupport(DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, byte
);
153 static void CodecIdCheck(DIVA_CAPI_ADAPTER
*, PLCI
*);
154 static void SetVoiceChannel(PLCI
*, byte
*, DIVA_CAPI_ADAPTER
*);
155 static void VoiceChannelOff(PLCI
*plci
);
156 static void adv_voice_write_coefs(PLCI
*plci
, word write_command
);
157 static void adv_voice_clear_config(PLCI
*plci
);
159 static word
get_b1_facilities(PLCI
*plci
, byte b1_resource
);
160 static byte
add_b1_facilities(PLCI
*plci
, byte b1_resource
, word b1_facilities
);
161 static void adjust_b1_facilities(PLCI
*plci
, byte new_b1_resource
, word new_b1_facilities
);
162 static word
adjust_b_process(dword Id
, PLCI
*plci
, byte Rc
);
163 static void adjust_b1_resource(dword Id
, PLCI
*plci
, API_SAVE
*bp_msg
, word b1_facilities
, word internal_command
);
164 static void adjust_b_restore(dword Id
, PLCI
*plci
, byte Rc
);
165 static void reset_b3_command(dword Id
, PLCI
*plci
, byte Rc
);
166 static void select_b_command(dword Id
, PLCI
*plci
, byte Rc
);
167 static void fax_connect_ack_command(dword Id
, PLCI
*plci
, byte Rc
);
168 static void fax_edata_ack_command(dword Id
, PLCI
*plci
, byte Rc
);
169 static void fax_connect_info_command(dword Id
, PLCI
*plci
, byte Rc
);
170 static void fax_adjust_b23_command(dword Id
, PLCI
*plci
, byte Rc
);
171 static void fax_disconnect_command(dword Id
, PLCI
*plci
, byte Rc
);
172 static void hold_save_command(dword Id
, PLCI
*plci
, byte Rc
);
173 static void retrieve_restore_command(dword Id
, PLCI
*plci
, byte Rc
);
174 static void init_b1_config(PLCI
*plci
);
175 static void clear_b1_config(PLCI
*plci
);
177 static void dtmf_command(dword Id
, PLCI
*plci
, byte Rc
);
178 static byte
dtmf_request(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
);
179 static void dtmf_confirmation(dword Id
, PLCI
*plci
);
180 static void dtmf_indication(dword Id
, PLCI
*plci
, byte
*msg
, word length
);
181 static void dtmf_parameter_write(PLCI
*plci
);
184 static void mixer_set_bchannel_id_esc(PLCI
*plci
, byte bchannel_id
);
185 static void mixer_set_bchannel_id(PLCI
*plci
, byte
*chi
);
186 static void mixer_clear_config(PLCI
*plci
);
187 static void mixer_notify_update(PLCI
*plci
, byte others
);
188 static void mixer_command(dword Id
, PLCI
*plci
, byte Rc
);
189 static byte
mixer_request(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
);
190 static void mixer_indication_coefs_set(dword Id
, PLCI
*plci
);
191 static void mixer_indication_xconnect_from(dword Id
, PLCI
*plci
, byte
*msg
, word length
);
192 static void mixer_indication_xconnect_to(dword Id
, PLCI
*plci
, byte
*msg
, word length
);
193 static void mixer_remove(PLCI
*plci
);
196 static void ec_command(dword Id
, PLCI
*plci
, byte Rc
);
197 static byte
ec_request(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
);
198 static void ec_indication(dword Id
, PLCI
*plci
, byte
*msg
, word length
);
201 static void rtp_connect_b3_req_command(dword Id
, PLCI
*plci
, byte Rc
);
202 static void rtp_connect_b3_res_command(dword Id
, PLCI
*plci
, byte Rc
);
205 static int diva_get_dma_descriptor(PLCI
*plci
, dword
*dma_magic
);
206 static void diva_free_dma_descriptor(PLCI
*plci
, int nr
);
208 /*------------------------------------------------------------------*/
209 /* external function prototypes */
210 /*------------------------------------------------------------------*/
212 extern byte
MapController(byte
);
213 extern byte
UnMapController(byte
);
214 #define MapId(Id)(((Id) & 0xffffff00L) | MapController((byte)(Id)))
215 #define UnMapId(Id)(((Id) & 0xffffff00L) | UnMapController((byte)(Id)))
217 void sendf(APPL
*, word
, dword
, word
, byte
*, ...);
218 void *TransmitBufferSet(APPL
*appl
, dword ref
);
219 void *TransmitBufferGet(APPL
*appl
, void *p
);
220 void TransmitBufferFree(APPL
*appl
, void *p
);
221 void *ReceiveBufferGet(APPL
*appl
, int Num
);
223 int fax_head_line_time(char *buffer
);
226 /*------------------------------------------------------------------*/
227 /* Global data definitions */
228 /*------------------------------------------------------------------*/
229 extern byte max_adapter
;
230 extern byte max_appl
;
231 extern DIVA_CAPI_ADAPTER
*adapter
;
232 extern APPL
*application
;
240 static byte remove_started
= false;
241 static PLCI dummy_plci
;
244 static struct _ftable
{
247 byte (*function
)(dword
, word
, DIVA_CAPI_ADAPTER
*, PLCI
*, APPL
*, API_PARSE
*);
249 {_DATA_B3_R
, "dwww", data_b3_req
},
250 {_DATA_B3_I
| RESPONSE
, "w", data_b3_res
},
251 {_INFO_R
, "ss", info_req
},
252 {_INFO_I
| RESPONSE
, "", info_res
},
253 {_CONNECT_R
, "wsssssssss", connect_req
},
254 {_CONNECT_I
| RESPONSE
, "wsssss", connect_res
},
255 {_CONNECT_ACTIVE_I
| RESPONSE
, "", connect_a_res
},
256 {_DISCONNECT_R
, "s", disconnect_req
},
257 {_DISCONNECT_I
| RESPONSE
, "", disconnect_res
},
258 {_LISTEN_R
, "dddss", listen_req
},
259 {_ALERT_R
, "s", alert_req
},
260 {_FACILITY_R
, "ws", facility_req
},
261 {_FACILITY_I
| RESPONSE
, "ws", facility_res
},
262 {_CONNECT_B3_R
, "s", connect_b3_req
},
263 {_CONNECT_B3_I
| RESPONSE
, "ws", connect_b3_res
},
264 {_CONNECT_B3_ACTIVE_I
| RESPONSE
, "", connect_b3_a_res
},
265 {_DISCONNECT_B3_R
, "s", disconnect_b3_req
},
266 {_DISCONNECT_B3_I
| RESPONSE
, "", disconnect_b3_res
},
267 {_RESET_B3_R
, "s", reset_b3_req
},
268 {_RESET_B3_I
| RESPONSE
, "", reset_b3_res
},
269 {_CONNECT_B3_T90_ACTIVE_I
| RESPONSE
, "ws", connect_b3_t90_a_res
},
270 {_CONNECT_B3_T90_ACTIVE_I
| RESPONSE
, "", connect_b3_t90_a_res
},
271 {_SELECT_B_REQ
, "s", select_b_req
},
272 {_MANUFACTURER_R
, "dws", manufacturer_req
},
273 {_MANUFACTURER_I
| RESPONSE
, "dws", manufacturer_res
},
274 {_MANUFACTURER_I
| RESPONSE
, "", manufacturer_res
}
277 static byte
*cip_bc
[29][2] = {
279 { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 1 */
280 { "\x02\x88\x90", "\x02\x88\x90" }, /* 2 */
281 { "\x02\x89\x90", "\x02\x89\x90" }, /* 3 */
282 { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 4 */
283 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 5 */
284 { "\x02\x98\x90", "\x02\x98\x90" }, /* 6 */
285 { "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */
286 { "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */
287 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 9 */
295 { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 16 */
296 { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 17 */
297 { "\x02\x88\x90", "\x02\x88\x90" }, /* 18 */
298 { "\x02\x88\x90", "\x02\x88\x90" }, /* 19 */
299 { "\x02\x88\x90", "\x02\x88\x90" }, /* 20 */
300 { "\x02\x88\x90", "\x02\x88\x90" }, /* 21 */
301 { "\x02\x88\x90", "\x02\x88\x90" }, /* 22 */
302 { "\x02\x88\x90", "\x02\x88\x90" }, /* 23 */
303 { "\x02\x88\x90", "\x02\x88\x90" }, /* 24 */
304 { "\x02\x88\x90", "\x02\x88\x90" }, /* 25 */
305 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 26 */
306 { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 27 */
307 { "\x02\x88\x90", "\x02\x88\x90" } /* 28 */
310 static byte
*cip_hlc
[29] = {
328 "\x02\x91\x81", /* 16 */
329 "\x02\x91\x84", /* 17 */
330 "\x02\x91\xa1", /* 18 */
331 "\x02\x91\xa4", /* 19 */
332 "\x02\x91\xa8", /* 20 */
333 "\x02\x91\xb1", /* 21 */
334 "\x02\x91\xb2", /* 22 */
335 "\x02\x91\xb5", /* 23 */
336 "\x02\x91\xb8", /* 24 */
337 "\x02\x91\xc1", /* 25 */
338 "\x02\x91\x81", /* 26 */
339 "\x03\x91\xe0\x01", /* 27 */
340 "\x03\x91\xe0\x02" /* 28 */
343 /*------------------------------------------------------------------*/
345 #define V120_HEADER_LENGTH 1
346 #define V120_HEADER_EXTEND_BIT 0x80
347 #define V120_HEADER_BREAK_BIT 0x40
348 #define V120_HEADER_C1_BIT 0x04
349 #define V120_HEADER_C2_BIT 0x08
350 #define V120_HEADER_FLUSH_COND (V120_HEADER_BREAK_BIT | V120_HEADER_C1_BIT | V120_HEADER_C2_BIT)
352 static byte v120_default_header
[] =
355 0x83 /* Ext, BR , res, res, C2 , C1 , B , F */
359 static byte v120_break_header
[] =
362 0xc3 | V120_HEADER_BREAK_BIT
/* Ext, BR , res, res, C2 , C1 , B , F */
367 /*------------------------------------------------------------------*/
368 /* API_PUT function */
369 /*------------------------------------------------------------------*/
371 word
api_put(APPL
*appl
, CAPI_MSG
*msg
)
377 DIVA_CAPI_ADAPTER
*a
;
382 API_PARSE msg_parms
[MAX_MSG_PARMS
+ 1];
384 if (msg
->header
.length
< sizeof(msg
->header
) ||
385 msg
->header
.length
> MAX_MSG_SIZE
) {
386 dbug(1, dprintf("bad len"));
390 controller
= (byte
)((msg
->header
.controller
& 0x7f) - 1);
392 /* controller starts with 0 up to (max_adapter - 1) */
393 if (controller
>= max_adapter
)
395 dbug(1, dprintf("invalid ctrl"));
399 a
= &adapter
[controller
];
401 if ((msg
->header
.plci
!= 0) && (msg
->header
.plci
<= a
->max_plci
) && !a
->adapter_disabled
)
403 dbug(1, dprintf("plci=%x", msg
->header
.plci
));
404 plci
= &a
->plci
[msg
->header
.plci
- 1];
405 ncci
= GET_WORD(&msg
->header
.ncci
);
408 || (plci
->State
== INC_CON_PENDING
)
409 || (plci
->State
== INC_CON_ALERT
)
410 || (msg
->header
.command
== (_DISCONNECT_I
| RESPONSE
)))
412 || (msg
->header
.command
== (_DISCONNECT_B3_I
| RESPONSE
))
413 || ((ncci
< MAX_NCCI
+ 1) && (a
->ncci_plci
[ncci
] == plci
->Id
))))
415 i
= plci
->msg_in_read_pos
;
416 j
= plci
->msg_in_write_pos
;
419 if (j
+ msg
->header
.length
+ MSG_IN_OVERHEAD
<= MSG_IN_QUEUE_SIZE
)
420 i
+= MSG_IN_QUEUE_SIZE
- j
;
427 n
= (((CAPI_MSG
*)(plci
->msg_in_queue
))->header
.length
+ MSG_IN_OVERHEAD
+ 3) & 0xfffc;
429 if (i
> MSG_IN_QUEUE_SIZE
- n
)
430 i
= MSG_IN_QUEUE_SIZE
- n
+ 1;
434 if (i
<= ((msg
->header
.length
+ MSG_IN_OVERHEAD
+ 3) & 0xfffc))
437 dbug(0, dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d",
438 msg
->header
.length
, plci
->msg_in_write_pos
,
439 plci
->msg_in_read_pos
, plci
->msg_in_wrap_pos
, i
));
444 if ((((byte
*) msg
) < ((byte
*)(plci
->msg_in_queue
)))
445 || (((byte
*) msg
) >= ((byte
*)(plci
->msg_in_queue
)) + sizeof(plci
->msg_in_queue
)))
447 if (plci
->msg_in_write_pos
!= plci
->msg_in_read_pos
)
450 if (msg
->header
.command
== _DATA_B3_R
)
452 if (msg
->header
.length
< 20)
454 dbug(1, dprintf("DATA_B3 REQ wrong length %d", msg
->header
.length
));
457 ncci_ptr
= &(a
->ncci
[ncci
]);
458 n
= ncci_ptr
->data_pending
;
459 l
= ncci_ptr
->data_ack_pending
;
460 k
= plci
->msg_in_read_pos
;
461 while (k
!= plci
->msg_in_write_pos
)
463 if (k
== plci
->msg_in_wrap_pos
)
465 if ((((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[k
]))->header
.command
== _DATA_B3_R
)
466 && (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[k
]))->header
.ncci
== ncci
))
469 if (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[k
]))->info
.data_b3_req
.Flags
& 0x0004)
473 k
+= (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[k
]))->header
.length
+
474 MSG_IN_OVERHEAD
+ 3) & 0xfffc;
477 if ((n
>= MAX_DATA_B3
) || (l
>= MAX_DATA_ACK
))
479 dbug(0, dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d",
480 ncci_ptr
->data_pending
, n
, ncci_ptr
->data_ack_pending
, l
));
484 if (plci
->req_in
|| plci
->internal_command
)
486 if ((((byte
*) msg
) >= ((byte
*)(plci
->msg_in_queue
)))
487 && (((byte
*) msg
) < ((byte
*)(plci
->msg_in_queue
)) + sizeof(plci
->msg_in_queue
)))
489 dbug(0, dprintf("Q-FULL3(requeue)"));
498 if (plci
->req_in
|| plci
->internal_command
)
502 plci
->command
= msg
->header
.command
;
503 plci
->number
= msg
->header
.number
;
508 dbug(1, dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d",
509 msg
->header
.command
, plci
->req_in
, plci
->internal_command
,
510 msg
->header
.length
, plci
->msg_in_write_pos
,
511 plci
->msg_in_read_pos
, plci
->msg_in_wrap_pos
, i
));
513 plci
->msg_in_wrap_pos
= plci
->msg_in_write_pos
;
514 m
= (CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[j
]);
515 for (i
= 0; i
< msg
->header
.length
; i
++)
516 ((byte
*)(plci
->msg_in_queue
))[j
++] = ((byte
*) msg
)[i
];
517 if (m
->header
.command
== _DATA_B3_R
)
520 m
->info
.data_b3_req
.Data
= (dword
)(long)(TransmitBufferSet(appl
, m
->info
.data_b3_req
.Data
));
524 j
= (j
+ 3) & 0xfffc;
526 *((APPL
**)(&((byte
*)(plci
->msg_in_queue
))[j
])) = appl
;
527 plci
->msg_in_write_pos
= j
+ MSG_IN_OVERHEAD
;
536 dbug(1, dprintf("com=%x", msg
->header
.command
));
538 for (j
= 0; j
< MAX_MSG_PARMS
+ 1; j
++) msg_parms
[j
].length
= 0;
539 for (i
= 0, ret
= _BAD_MSG
; i
< ARRAY_SIZE(ftable
); i
++) {
541 if (ftable
[i
].command
== msg
->header
.command
) {
542 /* break loop if the message is correct, otherwise continue scan */
543 /* (for example: CONNECT_B3_T90_ACT_RES has two specifications) */
544 if (!api_parse(msg
->info
.b
, (word
)(msg
->header
.length
- 12), ftable
[i
].format
, msg_parms
)) {
548 for (j
= 0; j
< MAX_MSG_PARMS
+ 1; j
++) msg_parms
[j
].length
= 0;
552 dbug(1, dprintf("BAD_MSG"));
553 if (plci
) plci
->command
= 0;
558 c
= ftable
[i
].function(GET_DWORD(&msg
->header
.controller
),
565 channel_xmit_extended_xon(plci
);
567 if (c
== 1) send_req(plci
);
568 if (c
== 2 && plci
) plci
->req_in
= plci
->req_in_start
= plci
->req_out
= 0;
569 if (plci
&& !plci
->req_in
) plci
->command
= 0;
574 /*------------------------------------------------------------------*/
575 /* api_parse function, check the format of api messages */
576 /*------------------------------------------------------------------*/
578 static word
api_parse(byte
*msg
, word length
, byte
*format
, API_PARSE
*parms
)
583 for (i
= 0, p
= 0; format
[i
]; i
++) {
586 parms
[i
].info
= &msg
[p
];
599 if (msg
[p
] == 0xff) {
601 parms
[i
].length
= msg
[p
+ 1] + (msg
[p
+ 2] << 8);
602 p
+= (parms
[i
].length
+ 3);
605 parms
[i
].length
= msg
[p
];
606 p
+= (parms
[i
].length
+ 1);
611 if (p
> length
) return true;
613 if (parms
) parms
[i
].info
= NULL
;
617 static void api_save_msg(API_PARSE
*in
, byte
*format
, API_SAVE
*out
)
623 for (i
= 0; format
[i
] != '\0'; i
++)
625 out
->parms
[i
].info
= p
;
626 out
->parms
[i
].length
= in
[i
].length
;
639 n
= in
[i
].length
+ 1;
642 for (j
= 0; j
< n
; j
++)
643 *(p
++) = in
[i
].info
[j
];
645 out
->parms
[i
].info
= NULL
;
646 out
->parms
[i
].length
= 0;
649 static void api_load_msg(API_SAVE
*in
, API_PARSE
*out
)
656 out
[i
].info
= in
->parms
[i
].info
;
657 out
[i
].length
= in
->parms
[i
].length
;
658 } while (in
->parms
[i
++].info
);
662 /*------------------------------------------------------------------*/
663 /* CAPI remove function */
664 /*------------------------------------------------------------------*/
666 word
api_remove_start(void)
671 if (!remove_started
) {
672 remove_started
= true;
673 for (i
= 0; i
< max_adapter
; i
++) {
674 if (adapter
[i
].request
) {
675 for (j
= 0; j
< adapter
[i
].max_plci
; j
++) {
676 if (adapter
[i
].plci
[j
].Sig
.Id
) plci_remove(&adapter
[i
].plci
[j
]);
683 for (i
= 0; i
< max_adapter
; i
++) {
684 if (adapter
[i
].request
) {
685 for (j
= 0; j
< adapter
[i
].max_plci
; j
++) {
686 if (adapter
[i
].plci
[j
].Sig
.Id
) return 1;
691 api_remove_complete();
696 /*------------------------------------------------------------------*/
697 /* internal command queue */
698 /*------------------------------------------------------------------*/
700 static void init_internal_command_queue(PLCI
*plci
)
704 dbug(1, dprintf("%s,%d: init_internal_command_queue",
705 (char *)(FILE_
), __LINE__
));
707 plci
->internal_command
= 0;
708 for (i
= 0; i
< MAX_INTERNAL_COMMAND_LEVELS
; i
++)
709 plci
->internal_command_queue
[i
] = NULL
;
713 static void start_internal_command(dword Id
, PLCI
*plci
, t_std_internal_command command_function
)
717 dbug(1, dprintf("[%06lx] %s,%d: start_internal_command",
718 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
720 if (plci
->internal_command
== 0)
722 plci
->internal_command_queue
[0] = command_function
;
723 (*command_function
)(Id
, plci
, OK
);
728 while (plci
->internal_command_queue
[i
] != NULL
)
730 plci
->internal_command_queue
[i
] = command_function
;
735 static void next_internal_command(dword Id
, PLCI
*plci
)
739 dbug(1, dprintf("[%06lx] %s,%d: next_internal_command",
740 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
742 plci
->internal_command
= 0;
743 plci
->internal_command_queue
[0] = NULL
;
744 while (plci
->internal_command_queue
[1] != NULL
)
746 for (i
= 0; i
< MAX_INTERNAL_COMMAND_LEVELS
- 1; i
++)
747 plci
->internal_command_queue
[i
] = plci
->internal_command_queue
[i
+ 1];
748 plci
->internal_command_queue
[MAX_INTERNAL_COMMAND_LEVELS
- 1] = NULL
;
749 (*(plci
->internal_command_queue
[0]))(Id
, plci
, OK
);
750 if (plci
->internal_command
!= 0)
752 plci
->internal_command_queue
[0] = NULL
;
757 /*------------------------------------------------------------------*/
758 /* NCCI allocate/remove function */
759 /*------------------------------------------------------------------*/
761 static dword ncci_mapping_bug
= 0;
763 static word
get_ncci(PLCI
*plci
, byte ch
, word force_ncci
)
765 DIVA_CAPI_ADAPTER
*a
;
769 if (!ch
|| a
->ch_ncci
[ch
])
772 dbug(1, dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x",
773 ncci_mapping_bug
, ch
, force_ncci
, a
->ncci_ch
[a
->ch_ncci
[ch
]], a
->ch_ncci
[ch
]));
782 if ((ch
< MAX_NCCI
+ 1) && !a
->ncci_ch
[ch
])
787 while ((ncci
< MAX_NCCI
+ 1) && a
->ncci_ch
[ncci
])
789 if (ncci
== MAX_NCCI
+ 1)
796 while ((j
< MAX_NCCI
+ 1) && (a
->ncci_ch
[j
] != i
))
799 if (j
< MAX_NCCI
+ 1)
804 } while ((j
< MAX_NCCI
+ 1) && (a
->ncci_ch
[j
] != i
));
806 } while ((i
< MAX_NL_CHANNEL
+ 1) && (j
< MAX_NCCI
+ 1));
807 if (i
< MAX_NL_CHANNEL
+ 1)
809 dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x",
810 ncci_mapping_bug
, ch
, force_ncci
, i
, k
, j
));
814 dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x",
815 ncci_mapping_bug
, ch
, force_ncci
));
820 a
->ncci_plci
[ncci
] = plci
->Id
;
821 a
->ncci_state
[ncci
] = IDLE
;
822 if (!plci
->ncci_ring_list
)
823 plci
->ncci_ring_list
= ncci
;
825 a
->ncci_next
[ncci
] = a
->ncci_next
[plci
->ncci_ring_list
];
826 a
->ncci_next
[plci
->ncci_ring_list
] = (byte
) ncci
;
828 a
->ncci_ch
[ncci
] = ch
;
829 a
->ch_ncci
[ch
] = (byte
) ncci
;
830 dbug(1, dprintf("NCCI mapping established %ld %02x %02x %02x-%02x",
831 ncci_mapping_bug
, ch
, force_ncci
, ch
, ncci
));
837 static void ncci_free_receive_buffers(PLCI
*plci
, word ncci
)
839 DIVA_CAPI_ADAPTER
*a
;
845 Id
= (((dword
) ncci
) << 16) | (((word
)(plci
->Id
)) << 8) | a
->Id
;
848 if (a
->ncci_plci
[ncci
] == plci
->Id
)
853 dbug(1, dprintf("NCCI mapping appl expected %ld %08lx",
854 ncci_mapping_bug
, Id
));
859 ncci_code
= ncci
| (((word
) a
->Id
) << 8);
860 for (i
= 0; i
< appl
->MaxBuffer
; i
++)
862 if ((appl
->DataNCCI
[i
] == ncci_code
)
863 && (((byte
)(appl
->DataFlags
[i
] >> 8)) == plci
->Id
))
865 appl
->DataNCCI
[i
] = 0;
873 for (ncci
= 1; ncci
< MAX_NCCI
+ 1; ncci
++)
875 if (a
->ncci_plci
[ncci
] == plci
->Id
)
880 dbug(1, dprintf("NCCI mapping no appl %ld %08lx",
881 ncci_mapping_bug
, Id
));
886 ncci_code
= ncci
| (((word
) a
->Id
) << 8);
887 for (i
= 0; i
< appl
->MaxBuffer
; i
++)
889 if ((appl
->DataNCCI
[i
] == ncci_code
)
890 && (((byte
)(appl
->DataFlags
[i
] >> 8)) == plci
->Id
))
892 appl
->DataNCCI
[i
] = 0;
902 static void cleanup_ncci_data(PLCI
*plci
, word ncci
)
906 if (ncci
&& (plci
->adapter
->ncci_plci
[ncci
] == plci
->Id
))
908 ncci_ptr
= &(plci
->adapter
->ncci
[ncci
]);
911 while (ncci_ptr
->data_pending
!= 0)
913 if (!plci
->data_sent
|| (ncci_ptr
->DBuffer
[ncci_ptr
->data_out
].P
!= plci
->data_sent_ptr
))
914 TransmitBufferFree(plci
->appl
, ncci_ptr
->DBuffer
[ncci_ptr
->data_out
].P
);
915 (ncci_ptr
->data_out
)++;
916 if (ncci_ptr
->data_out
== MAX_DATA_B3
)
917 ncci_ptr
->data_out
= 0;
918 (ncci_ptr
->data_pending
)--;
921 ncci_ptr
->data_out
= 0;
922 ncci_ptr
->data_pending
= 0;
923 ncci_ptr
->data_ack_out
= 0;
924 ncci_ptr
->data_ack_pending
= 0;
929 static void ncci_remove(PLCI
*plci
, word ncci
, byte preserve_ncci
)
931 DIVA_CAPI_ADAPTER
*a
;
936 Id
= (((dword
) ncci
) << 16) | (((word
)(plci
->Id
)) << 8) | a
->Id
;
938 ncci_free_receive_buffers(plci
, ncci
);
941 if (a
->ncci_plci
[ncci
] != plci
->Id
)
944 dbug(1, dprintf("NCCI mapping doesn't exist %ld %08lx %02x",
945 ncci_mapping_bug
, Id
, preserve_ncci
));
949 cleanup_ncci_data(plci
, ncci
);
950 dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
951 ncci_mapping_bug
, Id
, preserve_ncci
, a
->ncci_ch
[ncci
], ncci
));
952 a
->ch_ncci
[a
->ncci_ch
[ncci
]] = 0;
955 a
->ncci_ch
[ncci
] = 0;
956 a
->ncci_plci
[ncci
] = 0;
957 a
->ncci_state
[ncci
] = IDLE
;
958 i
= plci
->ncci_ring_list
;
959 while ((i
!= 0) && (a
->ncci_next
[i
] != plci
->ncci_ring_list
) && (a
->ncci_next
[i
] != ncci
))
961 if ((i
!= 0) && (a
->ncci_next
[i
] == ncci
))
964 plci
->ncci_ring_list
= 0;
965 else if (plci
->ncci_ring_list
== ncci
)
966 plci
->ncci_ring_list
= i
;
967 a
->ncci_next
[i
] = a
->ncci_next
[ncci
];
969 a
->ncci_next
[ncci
] = 0;
975 for (ncci
= 1; ncci
< MAX_NCCI
+ 1; ncci
++)
977 if (a
->ncci_plci
[ncci
] == plci
->Id
)
979 cleanup_ncci_data(plci
, ncci
);
980 dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
981 ncci_mapping_bug
, Id
, preserve_ncci
, a
->ncci_ch
[ncci
], ncci
));
982 a
->ch_ncci
[a
->ncci_ch
[ncci
]] = 0;
985 a
->ncci_ch
[ncci
] = 0;
986 a
->ncci_plci
[ncci
] = 0;
987 a
->ncci_state
[ncci
] = IDLE
;
988 a
->ncci_next
[ncci
] = 0;
993 plci
->ncci_ring_list
= 0;
998 /*------------------------------------------------------------------*/
999 /* PLCI remove function */
1000 /*------------------------------------------------------------------*/
1002 static void plci_free_msg_in_queue(PLCI
*plci
)
1008 i
= plci
->msg_in_read_pos
;
1009 while (i
!= plci
->msg_in_write_pos
)
1011 if (i
== plci
->msg_in_wrap_pos
)
1013 if (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[i
]))->header
.command
== _DATA_B3_R
)
1016 TransmitBufferFree(plci
->appl
,
1017 (byte
*)(long)(((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[i
]))->info
.data_b3_req
.Data
));
1021 i
+= (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[i
]))->header
.length
+
1022 MSG_IN_OVERHEAD
+ 3) & 0xfffc;
1026 plci
->msg_in_write_pos
= MSG_IN_QUEUE_SIZE
;
1027 plci
->msg_in_read_pos
= MSG_IN_QUEUE_SIZE
;
1028 plci
->msg_in_wrap_pos
= MSG_IN_QUEUE_SIZE
;
1032 static void plci_remove(PLCI
*plci
)
1036 dbug(1, dprintf("plci_remove(no plci)"));
1039 init_internal_command_queue(plci
);
1040 dbug(1, dprintf("plci_remove(%x,tel=%x)", plci
->Id
, plci
->tel
));
1041 if (plci_remove_check(plci
))
1045 if (plci
->Sig
.Id
== 0xff)
1047 dbug(1, dprintf("D-channel X.25 plci->NL.Id:%0x", plci
->NL
.Id
));
1048 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
1050 nl_req_ncci(plci
, REMOVE
, 0);
1056 if (!plci
->sig_remove_id
1058 || (plci
->req_in
!= plci
->req_out
)
1059 || (plci
->nl_req
|| plci
->sig_req
)))
1061 sig_req(plci
, HANGUP
, 0);
1065 ncci_remove(plci
, 0, false);
1066 plci_free_msg_in_queue(plci
);
1070 if ((plci
->State
== INC_CON_PENDING
) || (plci
->State
== INC_CON_ALERT
))
1071 plci
->State
= OUTG_DIS_PENDING
;
1074 /*------------------------------------------------------------------*/
1075 /* translation function for each message */
1076 /*------------------------------------------------------------------*/
1078 static byte
connect_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1079 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
1087 API_PARSE ai_parms
[5];
1091 static byte esc_chi
[35] = {0x02, 0x18, 0x01};
1092 static byte lli
[2] = {0x01, 0x00};
1097 for (i
= 0; i
< 5; i
++) ai_parms
[i
].length
= 0;
1099 dbug(1, dprintf("connect_req(%d)", parms
->length
));
1100 Info
= _WRONG_IDENTIFIER
;
1103 if (a
->adapter_disabled
)
1105 dbug(1, dprintf("adapter disabled"));
1106 Id
= ((word
)1 << 8) | a
->Id
;
1107 sendf(appl
, _CONNECT_R
| CONFIRM
, Id
, Number
, "w", 0);
1108 sendf(appl
, _DISCONNECT_I
, Id
, 0, "w", _L1_ERROR
);
1111 Info
= _OUT_OF_PLCI
;
1112 if ((i
= get_plci(a
)))
1115 plci
= &a
->plci
[i
- 1];
1117 plci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
1118 /* check 'external controller' bit for codec support */
1119 if (Id
& EXT_CONTROLLER
)
1121 if (AdvCodecSupport(a
, plci
, appl
, 0))
1124 sendf(appl
, _CONNECT_R
| CONFIRM
, Id
, Number
, "w", _WRONG_IDENTIFIER
);
1131 if (bp
->length
)LinkLayer
= bp
->info
[3];
1136 if (!api_parse(&ai
->info
[1], (word
)ai
->length
, "ssss", ai_parms
))
1139 if (ai_parms
[0].length
)
1141 ch
= GET_WORD(ai_parms
[0].info
+ 1);
1142 if (ch
> 4) ch
= 0; /* safety -> ignore ChannelID */
1143 if (ch
== 4) /* explizit CHI in message */
1145 /* check length of B-CH struct */
1146 if ((ai_parms
[0].info
)[3] >= 1)
1148 if ((ai_parms
[0].info
)[4] == CHI
)
1150 p_chi
= &((ai_parms
[0].info
)[5]);
1154 p_chi
= &((ai_parms
[0].info
)[3]);
1156 if (p_chi
[0] > 35) /* check length of channel ID */
1158 Info
= _WRONG_MESSAGE_FORMAT
;
1161 else Info
= _WRONG_MESSAGE_FORMAT
;
1164 if (ch
== 3 && ai_parms
[0].length
>= 7 && ai_parms
[0].length
<= 36)
1166 dir
= GET_WORD(ai_parms
[0].info
+ 3);
1169 for (i
= 0; i
+ 5 <= ai_parms
[0].length
; i
++)
1171 if (ai_parms
[0].info
[i
+ 5] != 0)
1173 if ((ai_parms
[0].info
[i
+ 5] | m
) != 0xff)
1174 Info
= _WRONG_MESSAGE_FORMAT
;
1185 Info
= _WRONG_MESSAGE_FORMAT
;
1188 if ((ai_parms
[0].length
== 36) || (ch_mask
!= ((dword
)(1L << channel
))))
1190 esc_chi
[0] = (byte
)(ai_parms
[0].length
- 2);
1191 for (i
= 0; i
+ 5 <= ai_parms
[0].length
; i
++)
1192 esc_chi
[i
+ 3] = ai_parms
[0].info
[i
+ 5];
1196 esc_chi
[2] = (byte
)channel
;
1197 plci
->b_channel
= (byte
)channel
; /* not correct for ETSI ch 17..31 */
1198 add_p(plci
, LLI
, lli
);
1199 add_p(plci
, ESC
, esc_chi
);
1200 plci
->State
= LOCAL_CONNECT
;
1201 if (!dir
) plci
->call_dir
|= CALL_DIR_FORCE_OUTG_NL
; /* dir 0=DTE, 1=DCE */
1206 else Info
= _WRONG_MESSAGE_FORMAT
;
1209 dbug(1, dprintf("ch=%x,dir=%x,p_ch=%d", ch
, dir
, channel
));
1210 plci
->command
= _CONNECT_R
;
1211 plci
->number
= Number
;
1212 /* x.31 or D-ch free SAPI in LinkLayer? */
1213 if (ch
== 1 && LinkLayer
!= 3 && LinkLayer
!= 12) noCh
= true;
1214 if ((ch
== 0 || ch
== 2 || noCh
|| ch
== 3 || ch
== 4) && !Info
)
1216 /* B-channel used for B3 connections (ch==0), or no B channel */
1217 /* is used (ch==2) or perm. connection (3) is used do a CALL */
1218 if (noCh
) Info
= add_b1(plci
, &parms
[5], 2, 0); /* no resource */
1219 else Info
= add_b1(plci
, &parms
[5], ch
, 0);
1220 add_s(plci
, OAD
, &parms
[2]);
1221 add_s(plci
, OSA
, &parms
[4]);
1222 add_s(plci
, BC
, &parms
[6]);
1223 add_s(plci
, LLC
, &parms
[7]);
1224 add_s(plci
, HLC
, &parms
[8]);
1225 if (a
->Info_Mask
[appl
->Id
- 1] & 0x200)
1227 /* early B3 connect (CIP mask bit 9) no release after a disc */
1228 add_p(plci
, LLI
, "\x01\x01");
1230 if (GET_WORD(parms
[0].info
) < 29) {
1231 add_p(plci
, BC
, cip_bc
[GET_WORD(parms
[0].info
)][a
->u_law
]);
1232 add_p(plci
, HLC
, cip_hlc
[GET_WORD(parms
[0].info
)]);
1234 add_p(plci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
1235 sig_req(plci
, ASSIGN
, DSIG_ID
);
1239 /* D-Channel used for B3 connections */
1240 plci
->Sig
.Id
= 0xff;
1244 if (!Info
&& ch
!= 2 && !noCh
) {
1245 Info
= add_b23(plci
, &parms
[5]);
1247 if (!(plci
->tel
&& !plci
->adv_nl
))nl_req_ncci(plci
, ASSIGN
, 0);
1253 if (ch
== 0 || ch
== 2 || ch
== 3 || noCh
|| ch
== 4)
1255 if (plci
->spoofed_msg
== SPOOFING_REQUIRED
)
1257 api_save_msg(parms
, "wsssssssss", &plci
->saved_msg
);
1258 plci
->spoofed_msg
= CALL_REQ
;
1259 plci
->internal_command
= BLOCK_PLCI
;
1261 dbug(1, dprintf("Spoof"));
1265 if (ch
== 4)add_p(plci
, CHI
, p_chi
);
1266 add_s(plci
, CPN
, &parms
[1]);
1267 add_s(plci
, DSA
, &parms
[3]);
1268 if (noCh
) add_p(plci
, ESC
, "\x02\x18\xfd"); /* D-channel, no B-L3 */
1269 add_ai(plci
, &parms
[9]);
1270 if (!dir
)sig_req(plci
, CALL_REQ
, 0);
1273 plci
->command
= PERM_LIST_REQ
;
1275 sig_req(plci
, LISTEN_REQ
, 0);
1287 _CONNECT_R
| CONFIRM
,
1294 static byte
connect_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1295 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
1299 static byte cau_t
[] = {0, 0, 0x90, 0x91, 0xac, 0x9d, 0x86, 0xd8, 0x9b};
1300 static byte esc_t
[] = {0x03, 0x08, 0x00, 0x00};
1302 API_PARSE ai_parms
[5];
1306 dbug(1, dprintf("connect_res(no plci)"));
1307 return 0; /* no plci, no send */
1310 dbug(1, dprintf("connect_res(State=0x%x)", plci
->State
));
1311 for (i
= 0; i
< 5; i
++) ai_parms
[i
].length
= 0;
1313 dbug(1, dprintf("ai->length=%d", ai
->length
));
1317 if (!api_parse(&ai
->info
[1], (word
)ai
->length
, "ssss", ai_parms
))
1319 dbug(1, dprintf("ai_parms[0].length=%d/0x%x", ai_parms
[0].length
, GET_WORD(ai_parms
[0].info
+ 1)));
1321 if (ai_parms
[0].length
)
1323 ch
= GET_WORD(ai_parms
[0].info
+ 1);
1324 dbug(1, dprintf("BCH-I=0x%x", ch
));
1329 if (plci
->State
== INC_CON_CONNECTED_ALERT
)
1331 dbug(1, dprintf("Connected Alert Call_Res"));
1332 if (a
->Info_Mask
[appl
->Id
- 1] & 0x200)
1334 /* early B3 connect (CIP mask bit 9) no release after a disc */
1335 add_p(plci
, LLI
, "\x01\x01");
1337 add_s(plci
, CONN_NR
, &parms
[2]);
1338 add_s(plci
, LLC
, &parms
[4]);
1339 add_ai(plci
, &parms
[5]);
1340 plci
->State
= INC_CON_ACCEPT
;
1341 sig_req(plci
, CALL_RES
, 0);
1344 else if (plci
->State
== INC_CON_PENDING
|| plci
->State
== INC_CON_ALERT
) {
1345 __clear_bit(appl
->Id
- 1, plci
->c_ind_mask_table
);
1346 dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL
, plci
->c_ind_mask_table
));
1347 Reject
= GET_WORD(parms
[0].info
);
1348 dbug(1, dprintf("Reject=0x%x", Reject
));
1351 if (bitmap_empty(plci
->c_ind_mask_table
, MAX_APPL
))
1353 if ((Reject
& 0xff00) == 0x3400)
1355 esc_t
[2] = ((byte
)(Reject
& 0x00ff)) | 0x80;
1356 add_p(plci
, ESC
, esc_t
);
1357 add_ai(plci
, &parms
[5]);
1358 sig_req(plci
, REJECT
, 0);
1360 else if (Reject
== 1 || Reject
>= 9)
1362 add_ai(plci
, &parms
[5]);
1363 sig_req(plci
, HANGUP
, 0);
1367 esc_t
[2] = cau_t
[(Reject
&0x000f)];
1368 add_p(plci
, ESC
, esc_t
);
1369 add_ai(plci
, &parms
[5]);
1370 sig_req(plci
, REJECT
, 0);
1376 sendf(appl
, _DISCONNECT_I
, Id
, 0, "w", _OTHER_APPL_CONNECTED
);
1381 if (Id
& EXT_CONTROLLER
) {
1382 if (AdvCodecSupport(a
, plci
, appl
, 0)) {
1383 dbug(1, dprintf("connect_res(error from AdvCodecSupport)"));
1384 sig_req(plci
, HANGUP
, 0);
1387 if (plci
->tel
== ADV_VOICE
&& a
->AdvCodecPLCI
)
1389 Info
= add_b23(plci
, &parms
[1]);
1392 dbug(1, dprintf("connect_res(error from add_b23)"));
1393 sig_req(plci
, HANGUP
, 0);
1398 nl_req_ncci(plci
, ASSIGN
, 0);
1407 Info
= add_b23(plci
, &parms
[1]);
1410 dbug(1, dprintf("connect_res(error from add_b23 2)"));
1411 sig_req(plci
, HANGUP
, 0);
1415 nl_req_ncci(plci
, ASSIGN
, 0);
1418 if (plci
->spoofed_msg
== SPOOFING_REQUIRED
)
1420 api_save_msg(parms
, "wsssss", &plci
->saved_msg
);
1421 plci
->spoofed_msg
= CALL_RES
;
1422 plci
->internal_command
= BLOCK_PLCI
;
1424 dbug(1, dprintf("Spoof"));
1428 add_b1(plci
, &parms
[1], ch
, plci
->B1_facilities
);
1429 if (a
->Info_Mask
[appl
->Id
- 1] & 0x200)
1431 /* early B3 connect (CIP mask bit 9) no release after a disc */
1432 add_p(plci
, LLI
, "\x01\x01");
1434 add_s(plci
, CONN_NR
, &parms
[2]);
1435 add_s(plci
, LLC
, &parms
[4]);
1436 add_ai(plci
, &parms
[5]);
1437 plci
->State
= INC_CON_ACCEPT
;
1438 sig_req(plci
, CALL_RES
, 0);
1441 for_each_set_bit(i
, plci
->c_ind_mask_table
, max_appl
)
1442 sendf(&application
[i
], _DISCONNECT_I
, Id
, 0, "w", _OTHER_APPL_CONNECTED
);
1448 static byte
connect_a_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1449 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
1451 dbug(1, dprintf("connect_a_res"));
1455 static byte
disconnect_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1456 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
1461 dbug(1, dprintf("disconnect_req"));
1463 Info
= _WRONG_IDENTIFIER
;
1467 if (plci
->State
== INC_CON_PENDING
|| plci
->State
== INC_CON_ALERT
)
1469 __clear_bit(appl
->Id
- 1, plci
->c_ind_mask_table
);
1471 for_each_set_bit(i
, plci
->c_ind_mask_table
, max_appl
)
1472 sendf(&application
[i
], _DISCONNECT_I
, Id
, 0, "w", 0);
1473 plci
->State
= OUTG_DIS_PENDING
;
1475 if (plci
->Sig
.Id
&& plci
->appl
)
1478 if (plci
->Sig
.Id
!= 0xff)
1480 if (plci
->State
!= INC_DIS_PENDING
)
1482 add_ai(plci
, &msg
[0]);
1483 sig_req(plci
, HANGUP
, 0);
1484 plci
->State
= OUTG_DIS_PENDING
;
1490 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
1493 nl_req_ncci(plci
, REMOVE
, 0);
1494 sendf(appl
, _DISCONNECT_R
| CONFIRM
, Id
, Number
, "w", 0);
1495 sendf(appl
, _DISCONNECT_I
, Id
, 0, "w", 0);
1496 plci
->State
= INC_DIS_PENDING
;
1503 if (!appl
) return false;
1504 sendf(appl
, _DISCONNECT_R
| CONFIRM
, Id
, Number
, "w", Info
);
1508 static byte
disconnect_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1509 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
1511 dbug(1, dprintf("disconnect_res"));
1514 /* clear ind mask bit, just in case of collsion of */
1515 /* DISCONNECT_IND and CONNECT_RES */
1516 __clear_bit(appl
->Id
- 1, plci
->c_ind_mask_table
);
1517 ncci_free_receive_buffers(plci
, 0);
1518 if (plci_remove_check(plci
))
1522 if (plci
->State
== INC_DIS_PENDING
1523 || plci
->State
== SUSPENDING
) {
1524 if (bitmap_empty(plci
->c_ind_mask_table
, MAX_APPL
)) {
1525 if (plci
->State
!= SUSPENDING
) plci
->State
= IDLE
;
1526 dbug(1, dprintf("chs=%d", plci
->channels
));
1527 if (!plci
->channels
) {
1536 static byte
listen_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1537 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
1542 dbug(1, dprintf("listen_req(Appl=0x%x)", appl
->Id
));
1544 Info
= _WRONG_IDENTIFIER
;
1547 a
->Info_Mask
[appl
->Id
- 1] = GET_DWORD(parms
[0].info
);
1548 a
->CIP_Mask
[appl
->Id
- 1] = GET_DWORD(parms
[1].info
);
1549 dbug(1, dprintf("CIP_MASK=0x%lx", GET_DWORD(parms
[1].info
)));
1550 if (a
->Info_Mask
[appl
->Id
- 1] & 0x200) { /* early B3 connect provides */
1551 a
->Info_Mask
[appl
->Id
- 1] |= 0x10; /* call progression infos */
1554 /* check if external controller listen and switch listen on or off*/
1555 if (Id
&EXT_CONTROLLER
&& GET_DWORD(parms
[1].info
)) {
1556 if (a
->profile
.Global_Options
& ON_BOARD_CODEC
) {
1557 dummy_plci
.State
= IDLE
;
1558 a
->codec_listen
[appl
->Id
- 1] = &dummy_plci
;
1559 a
->TelOAD
[0] = (byte
)(parms
[3].length
);
1560 for (i
= 1; parms
[3].length
>= i
&& i
< 22; i
++) {
1561 a
->TelOAD
[i
] = parms
[3].info
[i
];
1564 a
->TelOSA
[0] = (byte
)(parms
[4].length
);
1565 for (i
= 1; parms
[4].length
>= i
&& i
< 22; i
++) {
1566 a
->TelOSA
[i
] = parms
[4].info
[i
];
1570 else Info
= 0x2002; /* wrong controller, codec not supported */
1572 else{ /* clear listen */
1573 a
->codec_listen
[appl
->Id
- 1] = (PLCI
*)0;
1577 _LISTEN_R
| CONFIRM
,
1582 if (a
) listen_check(a
);
1586 static byte
info_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1587 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
1591 PLCI
*rc_plci
= NULL
;
1592 API_PARSE ai_parms
[5];
1595 dbug(1, dprintf("info_req"));
1596 for (i
= 0; i
< 5; i
++) ai_parms
[i
].length
= 0;
1602 if (api_parse(&ai
->info
[1], (word
)ai
->length
, "ssss", ai_parms
))
1604 dbug(1, dprintf("AddInfo wrong"));
1605 Info
= _WRONG_MESSAGE_FORMAT
;
1608 if (!a
) Info
= _WRONG_STATE
;
1611 { /* no fac, with CPN, or KEY */
1613 if (!ai_parms
[3].length
&& plci
->State
&& (msg
[0].length
|| ai_parms
[1].length
))
1615 /* overlap sending option */
1616 dbug(1, dprintf("OvlSnd"));
1617 add_s(plci
, CPN
, &msg
[0]);
1618 add_s(plci
, KEY
, &ai_parms
[1]);
1619 sig_req(plci
, INFO_REQ
, 0);
1624 if (plci
->State
&& ai_parms
[2].length
)
1626 /* User_Info option */
1627 dbug(1, dprintf("UUI"));
1628 add_s(plci
, UUI
, &ai_parms
[2]);
1629 sig_req(plci
, USER_DATA
, 0);
1631 else if (plci
->State
&& ai_parms
[3].length
)
1633 /* Facility option */
1634 dbug(1, dprintf("FAC"));
1635 add_s(plci
, CPN
, &msg
[0]);
1636 add_ai(plci
, &msg
[1]);
1637 sig_req(plci
, FACILITY_REQ
, 0);
1641 Info
= _WRONG_STATE
;
1644 else if ((ai_parms
[1].length
|| ai_parms
[2].length
|| ai_parms
[3].length
) && !Info
)
1646 /* NCR_Facility option -> send UUI and Keypad too */
1647 dbug(1, dprintf("NCR_FAC"));
1648 if ((i
= get_plci(a
)))
1650 rc_plci
= &a
->plci
[i
- 1];
1651 appl
->NullCREnable
= true;
1652 rc_plci
->internal_command
= C_NCR_FAC_REQ
;
1653 rc_plci
->appl
= appl
;
1654 add_p(rc_plci
, CAI
, "\x01\x80");
1655 add_p(rc_plci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
1656 sig_req(rc_plci
, ASSIGN
, DSIG_ID
);
1661 Info
= _OUT_OF_PLCI
;
1666 add_s(rc_plci
, CPN
, &msg
[0]);
1667 add_ai(rc_plci
, &msg
[1]);
1668 sig_req(rc_plci
, NCR_FACILITY
, 0);
1671 /* for application controlled supplementary services */
1677 Info
= _WRONG_MESSAGE_FORMAT
;
1685 { /* appl is not assigned to a PLCI or error condition */
1686 dbug(1, dprintf("localInfoCon"));
1696 static byte
info_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1697 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
1699 dbug(1, dprintf("info_res"));
1703 static byte
alert_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1704 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
1709 dbug(1, dprintf("alert_req"));
1711 Info
= _WRONG_IDENTIFIER
;
1714 Info
= _ALERT_IGNORED
;
1715 if (plci
->State
!= INC_CON_ALERT
) {
1716 Info
= _WRONG_STATE
;
1717 if (plci
->State
== INC_CON_PENDING
) {
1719 plci
->State
= INC_CON_ALERT
;
1720 add_ai(plci
, &msg
[0]);
1721 sig_req(plci
, CALL_ALERT
, 0);
1734 static byte
facility_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
1735 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
1742 long relatedPLCIvalue
;
1743 DIVA_CAPI_ADAPTER
*relatedadapter
;
1745 byte RCparms
[] = "\x05\x00\x00\x02\x00\x00";
1746 byte SSstruct
[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
1748 API_PARSE ss_parms
[11];
1754 dbug(1, dprintf("facility_req"));
1755 for (i
= 0; i
< 9; i
++) ss_parms
[i
].length
= 0;
1761 dbug(1, dprintf("wrong Ctrl"));
1762 Info
= _WRONG_IDENTIFIER
;
1765 selector
= GET_WORD(msg
[0].info
);
1771 case SELECTOR_HANDSET
:
1772 Info
= AdvCodecSupport(a
, plci
, appl
, HOOK_SUPPORT
);
1775 case SELECTOR_SU_SERV
:
1778 Info
= _WRONG_MESSAGE_FORMAT
;
1781 SSreq
= GET_WORD(&(msg
[1].info
[1]));
1782 PUT_WORD(&RCparms
[1], SSreq
);
1786 case S_GET_SUPPORTED_SERVICES
:
1787 if ((i
= get_plci(a
)))
1789 rplci
= &a
->plci
[i
- 1];
1791 add_p(rplci
, CAI
, "\x01\x80");
1792 add_p(rplci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
1793 sig_req(rplci
, ASSIGN
, DSIG_ID
);
1798 PUT_DWORD(&SSstruct
[6], MASK_TERMINAL_PORTABILITY
);
1799 SSparms
= (byte
*)SSstruct
;
1802 rplci
->internal_command
= GETSERV_REQ_PEND
;
1803 rplci
->number
= Number
;
1805 sig_req(rplci
, S_SUPPORTED
, 0);
1811 if (parms
->length
== 7)
1813 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbd", ss_parms
))
1815 dbug(1, dprintf("format wrong"));
1816 Info
= _WRONG_MESSAGE_FORMAT
;
1822 Info
= _WRONG_MESSAGE_FORMAT
;
1825 a
->Notification_Mask
[appl
->Id
- 1] = GET_DWORD(ss_parms
[2].info
);
1826 if (a
->Notification_Mask
[appl
->Id
- 1] & SMASK_MWI
) /* MWI active? */
1828 if ((i
= get_plci(a
)))
1830 rplci
= &a
->plci
[i
- 1];
1832 add_p(rplci
, CAI
, "\x01\x80");
1833 add_p(rplci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
1834 sig_req(rplci
, ASSIGN
, DSIG_ID
);
1841 rplci
->internal_command
= GET_MWI_STATE
;
1842 rplci
->number
= Number
;
1843 sig_req(rplci
, MWI_POLL
, 0);
1849 api_parse(&parms
->info
[1], (word
)parms
->length
, "ws", ss_parms
);
1850 if (plci
&& plci
->State
&& plci
->SuppState
== IDLE
)
1852 plci
->SuppState
= HOLD_REQUEST
;
1853 plci
->command
= C_HOLD_REQ
;
1854 add_s(plci
, CAI
, &ss_parms
[1]);
1855 sig_req(plci
, CALL_HOLD
, 0);
1859 else Info
= 0x3010; /* wrong state */
1862 if (plci
&& plci
->State
&& plci
->SuppState
== CALL_HELD
)
1864 if (Id
& EXT_CONTROLLER
)
1866 if (AdvCodecSupport(a
, plci
, appl
, 0))
1868 Info
= 0x3010; /* wrong state */
1874 plci
->SuppState
= RETRIEVE_REQUEST
;
1875 plci
->command
= C_RETRIEVE_REQ
;
1876 if (plci
->spoofed_msg
== SPOOFING_REQUIRED
)
1878 plci
->spoofed_msg
= CALL_RETRIEVE
;
1879 plci
->internal_command
= BLOCK_PLCI
;
1881 dbug(1, dprintf("Spoof"));
1886 sig_req(plci
, CALL_RETRIEVE
, 0);
1891 else Info
= 0x3010; /* wrong state */
1896 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbs", ss_parms
))
1898 dbug(1, dprintf("format wrong"));
1899 Info
= _WRONG_MESSAGE_FORMAT
;
1903 if (plci
&& plci
->State
)
1905 add_s(plci
, CAI
, &ss_parms
[2]);
1906 plci
->command
= SUSPEND_REQ
;
1907 sig_req(plci
, SUSPEND
, 0);
1908 plci
->State
= SUSPENDING
;
1911 else Info
= 0x3010; /* wrong state */
1915 if (!(i
= get_plci(a
)))
1917 Info
= _OUT_OF_PLCI
;
1920 rplci
= &a
->plci
[i
- 1];
1922 rplci
->number
= Number
;
1924 rplci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
1925 /* check 'external controller' bit for codec support */
1926 if (Id
& EXT_CONTROLLER
)
1928 if (AdvCodecSupport(a
, rplci
, appl
, 0))
1937 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbs", ss_parms
))
1939 dbug(1, dprintf("format wrong"));
1941 Info
= _WRONG_MESSAGE_FORMAT
;
1946 dummy
.info
= "\x00";
1947 add_b1(rplci
, &dummy
, 0, 0);
1948 if (a
->Info_Mask
[appl
->Id
- 1] & 0x200)
1950 /* early B3 connect (CIP mask bit 9) no release after a disc */
1951 add_p(rplci
, LLI
, "\x01\x01");
1953 add_p(rplci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
1954 sig_req(rplci
, ASSIGN
, DSIG_ID
);
1956 add_s(rplci
, CAI
, &ss_parms
[2]);
1957 rplci
->command
= RESUME_REQ
;
1958 sig_req(rplci
, RESUME
, 0);
1959 rplci
->State
= RESUMING
;
1963 case S_CONF_BEGIN
: /* Request */
1965 case S_CONF_ISOLATE
:
1966 case S_CONF_REATTACH
:
1967 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbd", ss_parms
))
1969 dbug(1, dprintf("format wrong"));
1970 Info
= _WRONG_MESSAGE_FORMAT
;
1973 if (plci
&& plci
->State
&& ((plci
->SuppState
== IDLE
) || (plci
->SuppState
== CALL_HELD
)))
1975 d
= GET_DWORD(ss_parms
[2].info
);
1978 dbug(1, dprintf("format wrong"));
1979 Info
= _WRONG_MESSAGE_FORMAT
;
1982 plci
->ptyState
= (byte
)SSreq
;
1988 cai
[1] = CONF_BEGIN
;
1989 plci
->internal_command
= CONF_BEGIN_REQ_PEND
;
1993 plci
->internal_command
= CONF_DROP_REQ_PEND
;
1995 case S_CONF_ISOLATE
:
1996 cai
[1] = CONF_ISOLATE
;
1997 plci
->internal_command
= CONF_ISOLATE_REQ_PEND
;
1999 case S_CONF_REATTACH
:
2000 cai
[1] = CONF_REATTACH
;
2001 plci
->internal_command
= CONF_REATTACH_REQ_PEND
;
2004 cai
[2] = (byte
)d
; /* Conference Size resp. PartyId */
2005 add_p(plci
, CAI
, cai
);
2006 sig_req(plci
, S_SERVICE
, 0);
2010 else Info
= 0x3010; /* wrong state */
2017 if (parms
->length
== 7)
2019 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbd", ss_parms
))
2021 dbug(1, dprintf("format wrong"));
2022 Info
= _WRONG_MESSAGE_FORMAT
;
2026 else if (parms
->length
== 8) /* workaround for the T-View-S */
2028 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbdb", ss_parms
))
2030 dbug(1, dprintf("format wrong"));
2031 Info
= _WRONG_MESSAGE_FORMAT
;
2037 Info
= _WRONG_MESSAGE_FORMAT
;
2042 Info
= _WRONG_MESSAGE_FORMAT
;
2047 Info
= _WRONG_IDENTIFIER
;
2050 relatedPLCIvalue
= GET_DWORD(ss_parms
[2].info
);
2051 relatedPLCIvalue
&= 0x0000FFFF;
2052 dbug(1, dprintf("PTY/ECT/addCONF,relPLCI=%lx", relatedPLCIvalue
));
2053 /* controller starts with 0 up to (max_adapter - 1) */
2054 if (((relatedPLCIvalue
& 0x7f) == 0)
2055 || (MapController((byte
)(relatedPLCIvalue
& 0x7f)) == 0)
2056 || (MapController((byte
)(relatedPLCIvalue
& 0x7f)) > max_adapter
))
2058 if (SSreq
== S_3PTY_END
)
2060 dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI"));
2065 Info
= 0x3010; /* wrong state */
2071 relatedadapter
= &adapter
[MapController((byte
)(relatedPLCIvalue
& 0x7f)) - 1];
2072 relatedPLCIvalue
>>= 8;
2074 for (i
= 0, rplci
= NULL
; i
< relatedadapter
->max_plci
; i
++)
2076 if (relatedadapter
->plci
[i
].Id
== (byte
)relatedPLCIvalue
)
2078 rplci
= &relatedadapter
->plci
[i
];
2081 if (!rplci
|| !relatedPLCIvalue
)
2083 if (SSreq
== S_3PTY_END
)
2085 dbug(1, dprintf("use 2nd PLCI=PLCI"));
2090 Info
= 0x3010; /* wrong state */
2096 dbug(1, dprintf("rplci:%x", rplci));
2097 dbug(1, dprintf("plci:%x", plci));
2098 dbug(1, dprintf("rplci->ptyState:%x", rplci->ptyState));
2099 dbug(1, dprintf("plci->ptyState:%x", plci->ptyState));
2100 dbug(1, dprintf("SSreq:%x", SSreq));
2101 dbug(1, dprintf("rplci->internal_command:%x", rplci->internal_command));
2102 dbug(1, dprintf("rplci->appl:%x", rplci->appl));
2103 dbug(1, dprintf("rplci->Id:%x", rplci->Id));
2105 /* send PTY/ECT req, cannot check all states because of US stuff */
2106 if (!rplci
->internal_command
&& rplci
->appl
)
2109 rplci
->relatedPTYPLCI
= plci
;
2110 plci
->relatedPTYPLCI
= rplci
;
2111 rplci
->ptyState
= (byte
)SSreq
;
2114 rplci
->internal_command
= ECT_REQ_PEND
;
2115 cai
[1] = ECT_EXECUTE
;
2117 rplci
->vswitchstate
= 0;
2119 rplci
->vsprotdialect
= 0;
2120 plci
->vswitchstate
= 0;
2122 plci
->vsprotdialect
= 0;
2125 else if (SSreq
== S_CONF_ADD
)
2127 rplci
->internal_command
= CONF_ADD_REQ_PEND
;
2132 rplci
->internal_command
= PTY_REQ_PEND
;
2133 cai
[1] = (byte
)(SSreq
- 3);
2135 rplci
->number
= Number
;
2136 if (plci
!= rplci
) /* explicit invocation */
2139 cai
[2] = plci
->Sig
.Id
;
2140 dbug(1, dprintf("explicit invocation"));
2144 dbug(1, dprintf("implicit invocation"));
2147 add_p(rplci
, CAI
, cai
);
2148 sig_req(rplci
, S_SERVICE
, 0);
2154 dbug(0, dprintf("Wrong line"));
2155 Info
= 0x3010; /* wrong state */
2160 case S_CALL_DEFLECTION
:
2161 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbwss", ss_parms
))
2163 dbug(1, dprintf("format wrong"));
2164 Info
= _WRONG_MESSAGE_FORMAT
;
2169 Info
= _WRONG_IDENTIFIER
;
2172 /* reuse unused screening indicator */
2173 ss_parms
[3].info
[3] = (byte
)GET_WORD(&(ss_parms
[2].info
[0]));
2175 plci
->internal_command
= CD_REQ_PEND
;
2176 appl
->CDEnable
= true;
2178 cai
[1] = CALL_DEFLECTION
;
2179 add_p(plci
, CAI
, cai
);
2180 add_p(plci
, CPN
, ss_parms
[3].info
);
2181 sig_req(plci
, S_SERVICE
, 0);
2186 case S_CALL_FORWARDING_START
:
2187 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbdwwsss", ss_parms
))
2189 dbug(1, dprintf("format wrong"));
2190 Info
= _WRONG_MESSAGE_FORMAT
;
2194 if ((i
= get_plci(a
)))
2196 rplci
= &a
->plci
[i
- 1];
2198 add_p(rplci
, CAI
, "\x01\x80");
2199 add_p(rplci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
2200 sig_req(rplci
, ASSIGN
, DSIG_ID
);
2205 Info
= _OUT_OF_PLCI
;
2209 /* reuse unused screening indicator */
2210 rplci
->internal_command
= CF_START_PEND
;
2212 rplci
->number
= Number
;
2213 appl
->S_Handle
= GET_DWORD(&(ss_parms
[2].info
[0]));
2215 cai
[1] = 0x70 | (byte
)GET_WORD(&(ss_parms
[3].info
[0])); /* Function */
2216 cai
[2] = (byte
)GET_WORD(&(ss_parms
[4].info
[0])); /* Basic Service */
2217 add_p(rplci
, CAI
, cai
);
2218 add_p(rplci
, OAD
, ss_parms
[5].info
);
2219 add_p(rplci
, CPN
, ss_parms
[6].info
);
2220 sig_req(rplci
, S_SERVICE
, 0);
2225 case S_INTERROGATE_DIVERSION
:
2226 case S_INTERROGATE_NUMBERS
:
2227 case S_CALL_FORWARDING_STOP
:
2228 case S_CCBS_REQUEST
:
2229 case S_CCBS_DEACTIVATE
:
2230 case S_CCBS_INTERROGATE
:
2233 case S_INTERROGATE_NUMBERS
:
2234 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbd", ss_parms
))
2236 dbug(0, dprintf("format wrong"));
2237 Info
= _WRONG_MESSAGE_FORMAT
;
2240 case S_CCBS_REQUEST
:
2241 case S_CCBS_DEACTIVATE
:
2242 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbdw", ss_parms
))
2244 dbug(0, dprintf("format wrong"));
2245 Info
= _WRONG_MESSAGE_FORMAT
;
2248 case S_CCBS_INTERROGATE
:
2249 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbdws", ss_parms
))
2251 dbug(0, dprintf("format wrong"));
2252 Info
= _WRONG_MESSAGE_FORMAT
;
2256 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbdwws", ss_parms
))
2258 dbug(0, dprintf("format wrong"));
2259 Info
= _WRONG_MESSAGE_FORMAT
;
2266 if ((i
= get_plci(a
)))
2268 rplci
= &a
->plci
[i
- 1];
2271 case S_INTERROGATE_DIVERSION
: /* use cai with S_SERVICE below */
2272 cai
[1] = 0x60 | (byte
)GET_WORD(&(ss_parms
[3].info
[0])); /* Function */
2273 rplci
->internal_command
= INTERR_DIVERSION_REQ_PEND
; /* move to rplci if assigned */
2275 case S_INTERROGATE_NUMBERS
: /* use cai with S_SERVICE below */
2276 cai
[1] = DIVERSION_INTERROGATE_NUM
; /* Function */
2277 rplci
->internal_command
= INTERR_NUMBERS_REQ_PEND
; /* move to rplci if assigned */
2279 case S_CALL_FORWARDING_STOP
:
2280 rplci
->internal_command
= CF_STOP_PEND
;
2281 cai
[1] = 0x80 | (byte
)GET_WORD(&(ss_parms
[3].info
[0])); /* Function */
2283 case S_CCBS_REQUEST
:
2284 cai
[1] = CCBS_REQUEST
;
2285 rplci
->internal_command
= CCBS_REQUEST_REQ_PEND
;
2287 case S_CCBS_DEACTIVATE
:
2288 cai
[1] = CCBS_DEACTIVATE
;
2289 rplci
->internal_command
= CCBS_DEACTIVATE_REQ_PEND
;
2291 case S_CCBS_INTERROGATE
:
2292 cai
[1] = CCBS_INTERROGATE
;
2293 rplci
->internal_command
= CCBS_INTERROGATE_REQ_PEND
;
2300 rplci
->number
= Number
;
2301 add_p(rplci
, CAI
, "\x01\x80");
2302 add_p(rplci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
2303 sig_req(rplci
, ASSIGN
, DSIG_ID
);
2308 Info
= _OUT_OF_PLCI
;
2312 appl
->S_Handle
= GET_DWORD(&(ss_parms
[2].info
[0]));
2315 case S_INTERROGATE_NUMBERS
:
2317 add_p(rplci
, CAI
, cai
);
2319 case S_CCBS_REQUEST
:
2320 case S_CCBS_DEACTIVATE
:
2322 PUT_WORD(&cai
[2], GET_WORD(&(ss_parms
[3].info
[0])));
2323 add_p(rplci
, CAI
, cai
);
2325 case S_CCBS_INTERROGATE
:
2327 PUT_WORD(&cai
[2], GET_WORD(&(ss_parms
[3].info
[0])));
2328 add_p(rplci
, CAI
, cai
);
2329 add_p(rplci
, OAD
, ss_parms
[4].info
);
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
);
2339 sig_req(rplci
, S_SERVICE
, 0);
2344 case S_MWI_ACTIVATE
:
2345 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbwdwwwssss", ss_parms
))
2347 dbug(1, dprintf("format wrong"));
2348 Info
= _WRONG_MESSAGE_FORMAT
;
2353 if ((i
= get_plci(a
)))
2355 rplci
= &a
->plci
[i
- 1];
2357 rplci
->cr_enquiry
= true;
2358 add_p(rplci
, CAI
, "\x01\x80");
2359 add_p(rplci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
2360 sig_req(rplci
, ASSIGN
, DSIG_ID
);
2365 Info
= _OUT_OF_PLCI
;
2372 rplci
->cr_enquiry
= false;
2376 rplci
->internal_command
= MWI_ACTIVATE_REQ_PEND
;
2378 rplci
->number
= Number
;
2381 cai
[1] = ACTIVATION_MWI
; /* Function */
2382 PUT_WORD(&cai
[2], GET_WORD(&(ss_parms
[2].info
[0]))); /* Basic Service */
2383 PUT_DWORD(&cai
[4], GET_DWORD(&(ss_parms
[3].info
[0]))); /* Number of Messages */
2384 PUT_WORD(&cai
[8], GET_WORD(&(ss_parms
[4].info
[0]))); /* Message Status */
2385 PUT_WORD(&cai
[10], GET_WORD(&(ss_parms
[5].info
[0]))); /* Message Reference */
2386 PUT_WORD(&cai
[12], GET_WORD(&(ss_parms
[6].info
[0]))); /* Invocation Mode */
2387 add_p(rplci
, CAI
, cai
);
2388 add_p(rplci
, CPN
, ss_parms
[7].info
); /* Receiving User Number */
2389 add_p(rplci
, OAD
, ss_parms
[8].info
); /* Controlling User Number */
2390 add_p(rplci
, OSA
, ss_parms
[9].info
); /* Controlling User Provided Number */
2391 add_p(rplci
, UID
, ss_parms
[10].info
); /* Time */
2392 sig_req(rplci
, S_SERVICE
, 0);
2396 case S_MWI_DEACTIVATE
:
2397 if (api_parse(&parms
->info
[1], (word
)parms
->length
, "wbwwss", ss_parms
))
2399 dbug(1, dprintf("format wrong"));
2400 Info
= _WRONG_MESSAGE_FORMAT
;
2405 if ((i
= get_plci(a
)))
2407 rplci
= &a
->plci
[i
- 1];
2409 rplci
->cr_enquiry
= true;
2410 add_p(rplci
, CAI
, "\x01\x80");
2411 add_p(rplci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
2412 sig_req(rplci
, ASSIGN
, DSIG_ID
);
2417 Info
= _OUT_OF_PLCI
;
2424 rplci
->cr_enquiry
= false;
2428 rplci
->internal_command
= MWI_DEACTIVATE_REQ_PEND
;
2430 rplci
->number
= Number
;
2433 cai
[1] = DEACTIVATION_MWI
; /* Function */
2434 PUT_WORD(&cai
[2], GET_WORD(&(ss_parms
[2].info
[0]))); /* Basic Service */
2435 PUT_WORD(&cai
[4], GET_WORD(&(ss_parms
[3].info
[0]))); /* Invocation Mode */
2436 add_p(rplci
, CAI
, cai
);
2437 add_p(rplci
, CPN
, ss_parms
[4].info
); /* Receiving User Number */
2438 add_p(rplci
, OAD
, ss_parms
[5].info
); /* Controlling User Number */
2439 sig_req(rplci
, S_SERVICE
, 0);
2444 Info
= 0x300E; /* not supported */
2447 break; /* case SELECTOR_SU_SERV: end */
2451 return (dtmf_request(Id
, Number
, a
, plci
, appl
, msg
));
2455 case SELECTOR_LINE_INTERCONNECT
:
2456 return (mixer_request(Id
, Number
, a
, plci
, appl
, msg
));
2460 case PRIV_SELECTOR_ECHO_CANCELLER
:
2461 appl
->appl_flags
|= APPL_FLAG_PRIV_EC_SPEC
;
2462 return (ec_request(Id
, Number
, a
, plci
, appl
, msg
));
2464 case SELECTOR_ECHO_CANCELLER
:
2465 appl
->appl_flags
&= ~APPL_FLAG_PRIV_EC_SPEC
;
2466 return (ec_request(Id
, Number
, a
, plci
, appl
, msg
));
2469 case SELECTOR_V42BIS
:
2471 Info
= _FACILITY_NOT_SUPPORTED
;
2473 } /* end of switch (selector) */
2476 dbug(1, dprintf("SendFacRc"));
2478 _FACILITY_R
| CONFIRM
,
2481 "wws", Info
, selector
, SSparms
);
2485 static byte
facility_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
2486 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
2488 dbug(1, dprintf("facility_res"));
2492 static byte
connect_b3_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
2493 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
2499 word fax_control_bits
, fax_feature_bits
, fax_info_change
;
2503 API_PARSE fax_parms
[9];
2507 dbug(1, dprintf("connect_b3_req"));
2510 if ((plci
->State
== IDLE
) || (plci
->State
== OUTG_DIS_PENDING
)
2511 || (plci
->State
== INC_DIS_PENDING
) || (plci
->SuppState
!= IDLE
))
2513 Info
= _WRONG_STATE
;
2517 /* local reply if assign unsuccessful
2518 or B3 protocol allows only one layer 3 connection
2519 and already connected
2520 or B2 protocol not any LAPD
2521 and connect_b3_req contradicts originate/answer direction */
2523 || (((plci
->B3_prot
!= B3_T90NL
) && (plci
->B3_prot
!= B3_ISO8208
) && (plci
->B3_prot
!= B3_X25_DCE
))
2524 && ((plci
->channels
!= 0)
2525 || (((plci
->B2_prot
!= B2_SDLC
) && (plci
->B2_prot
!= B2_LAPD
) && (plci
->B2_prot
!= B2_LAPD_FREE_SAPI_SEL
))
2526 && ((plci
->call_dir
& CALL_DIR_ANSWER
) && !(plci
->call_dir
& CALL_DIR_FORCE_OUTG_NL
))))))
2528 dbug(1, dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x",
2529 plci
->channels
, plci
->NL
.Id
, plci
->call_dir
, plci
->SuppState
));
2530 Info
= _WRONG_STATE
;
2532 _CONNECT_B3_R
| CONFIRM
,
2538 plci
->requested_options_conn
= 0;
2542 if (plci
->B3_prot
== 2 || plci
->B3_prot
== 3)
2544 if (ncpi
->length
> 2)
2547 if (ncpi
->info
[2] || ncpi
->info
[3])
2549 pvc
[0] = ncpi
->info
[3];
2550 pvc
[1] = ncpi
->info
[2];
2551 add_d(plci
, 2, pvc
);
2556 if (ncpi
->info
[1] & 1) req
= N_CONNECT
| N_D_BIT
;
2557 add_d(plci
, (word
)(ncpi
->length
- 3), &ncpi
->info
[4]);
2561 else if (plci
->B3_prot
== 5)
2563 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
2565 fax_control_bits
= GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
);
2566 fax_feature_bits
= GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->feature_bits_low
);
2567 if (!(fax_control_bits
& T30_CONTROL_BIT_MORE_DOCUMENTS
)
2568 || (fax_feature_bits
& T30_FEATURE_BIT_MORE_DOCUMENTS
))
2570 len
= offsetof(T30_INFO
, universal_6
);
2571 fax_info_change
= false;
2572 if (ncpi
->length
>= 4)
2574 w
= GET_WORD(&ncpi
->info
[3]);
2575 if ((w
& 0x0001) != ((word
)(((T30_INFO
*)(plci
->fax_connect_info_buffer
))->resolution
& 0x0001)))
2577 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->resolution
=
2578 (byte
)((((T30_INFO
*)(plci
->fax_connect_info_buffer
))->resolution
& ~T30_RESOLUTION_R8_0770_OR_200
) |
2579 ((w
& 0x0001) ? T30_RESOLUTION_R8_0770_OR_200
: 0));
2580 fax_info_change
= true;
2582 fax_control_bits
&= ~(T30_CONTROL_BIT_REQUEST_POLLING
| T30_CONTROL_BIT_MORE_DOCUMENTS
);
2583 if (w
& 0x0002) /* Fax-polling request */
2584 fax_control_bits
|= T30_CONTROL_BIT_REQUEST_POLLING
;
2585 if ((w
& 0x0004) /* Request to send / poll another document */
2586 && (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS
))
2588 fax_control_bits
|= T30_CONTROL_BIT_MORE_DOCUMENTS
;
2590 if (ncpi
->length
>= 6)
2592 w
= GET_WORD(&ncpi
->info
[5]);
2593 if (((byte
) w
) != ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->data_format
)
2595 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->data_format
= (byte
) w
;
2596 fax_info_change
= true;
2599 if ((a
->man_profile
.private_options
& (1L << PRIVATE_FAX_SUB_SEP_PWD
))
2600 && (GET_WORD(&ncpi
->info
[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */
2602 plci
->requested_options_conn
|= (1L << PRIVATE_FAX_SUB_SEP_PWD
);
2604 if ((a
->man_profile
.private_options
& (1L << PRIVATE_FAX_NONSTANDARD
))
2605 && (GET_WORD(&ncpi
->info
[5]) & 0x4000)) /* Private non-standard facilities enable */
2607 plci
->requested_options_conn
|= (1L << PRIVATE_FAX_NONSTANDARD
);
2609 fax_control_bits
&= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS
| T30_CONTROL_BIT_ACCEPT_SEL_POLLING
|
2610 T30_CONTROL_BIT_ACCEPT_PASSWORD
);
2611 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[appl
->Id
- 1])
2612 & ((1L << PRIVATE_FAX_SUB_SEP_PWD
) | (1L << PRIVATE_FAX_NONSTANDARD
)))
2614 if (api_parse(&ncpi
->info
[1], ncpi
->length
, "wwwwsss", fax_parms
))
2615 Info
= _WRONG_MESSAGE_FORMAT
;
2618 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[appl
->Id
- 1])
2619 & (1L << PRIVATE_FAX_SUB_SEP_PWD
))
2621 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_SUBADDRESS
| T30_CONTROL_BIT_ACCEPT_PASSWORD
;
2622 if (fax_control_bits
& T30_CONTROL_BIT_ACCEPT_POLLING
)
2623 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_SEL_POLLING
;
2625 w
= fax_parms
[4].length
;
2628 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->station_id_len
= (byte
) w
;
2629 for (i
= 0; i
< w
; i
++)
2630 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->station_id
[i
] = fax_parms
[4].info
[1 + i
];
2631 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->head_line_len
= 0;
2632 len
= offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
;
2633 w
= fax_parms
[5].length
;
2636 plci
->fax_connect_info_buffer
[len
++] = (byte
) w
;
2637 for (i
= 0; i
< w
; i
++)
2638 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[5].info
[1 + i
];
2639 w
= fax_parms
[6].length
;
2642 plci
->fax_connect_info_buffer
[len
++] = (byte
) w
;
2643 for (i
= 0; i
< w
; i
++)
2644 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[6].info
[1 + i
];
2645 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[appl
->Id
- 1])
2646 & (1L << PRIVATE_FAX_NONSTANDARD
))
2648 if (api_parse(&ncpi
->info
[1], ncpi
->length
, "wwwwssss", fax_parms
))
2650 dbug(1, dprintf("non-standard facilities info missing or wrong format"));
2651 plci
->fax_connect_info_buffer
[len
++] = 0;
2655 if ((fax_parms
[7].length
>= 3) && (fax_parms
[7].info
[1] >= 2))
2656 plci
->nsf_control_bits
= GET_WORD(&fax_parms
[7].info
[2]);
2657 plci
->fax_connect_info_buffer
[len
++] = (byte
)(fax_parms
[7].length
);
2658 for (i
= 0; i
< fax_parms
[7].length
; i
++)
2659 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[7].info
[1 + i
];
2666 len
= offsetof(T30_INFO
, universal_6
);
2668 fax_info_change
= true;
2671 if (fax_control_bits
!= GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
))
2673 PUT_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
, fax_control_bits
);
2674 fax_info_change
= true;
2679 plci
->fax_connect_info_length
= len
;
2680 if (fax_info_change
)
2682 if (fax_feature_bits
& T30_FEATURE_BIT_MORE_DOCUMENTS
)
2684 start_internal_command(Id
, plci
, fax_connect_info_command
);
2689 start_internal_command(Id
, plci
, fax_adjust_b23_command
);
2695 else Info
= _WRONG_STATE
;
2697 else Info
= _WRONG_STATE
;
2700 else if (plci
->B3_prot
== B3_RTP
)
2702 plci
->internal_req_buffer
[0] = ncpi
->length
+ 1;
2703 plci
->internal_req_buffer
[1] = UDATA_REQUEST_RTP_RECONFIGURE
;
2704 for (w
= 0; w
< ncpi
->length
; w
++)
2705 plci
->internal_req_buffer
[2 + w
] = ncpi
->info
[1 + w
];
2706 start_internal_command(Id
, plci
, rtp_connect_b3_req_command
);
2712 nl_req_ncci(plci
, req
, 0);
2717 else Info
= _WRONG_IDENTIFIER
;
2720 _CONNECT_B3_R
| CONFIRM
,
2727 static byte
connect_b3_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
2728 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
2737 API_PARSE fax_parms
[9];
2742 dbug(1, dprintf("connect_b3_res"));
2744 ncci
= (word
)(Id
>> 16);
2746 if (a
->ncci_state
[ncci
] == INC_CON_PENDING
) {
2747 if (GET_WORD(&parms
[0].info
[0]) != 0)
2749 a
->ncci_state
[ncci
] = OUTG_REJ_PENDING
;
2750 channel_request_xon(plci
, a
->ncci_ch
[ncci
]);
2751 channel_xmit_xon(plci
);
2752 cleanup_ncci_data(plci
, ncci
);
2753 nl_req_ncci(plci
, N_DISC
, (byte
)ncci
);
2756 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
2758 req
= N_CONNECT_ACK
;
2760 if ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5) || (plci
->B3_prot
== 7))
2763 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[plci
->appl
->Id
- 1])
2764 & (1L << PRIVATE_FAX_NONSTANDARD
))
2766 if (((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5))
2767 && (plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_ENABLE_NSF
)
2768 && (plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_NEGOTIATE_RESP
))
2770 len
= offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
;
2771 if (plci
->fax_connect_info_length
< len
)
2773 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->station_id_len
= 0;
2774 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->head_line_len
= 0;
2776 if (api_parse(&ncpi
->info
[1], ncpi
->length
, "wwwwssss", fax_parms
))
2778 dbug(1, dprintf("non-standard facilities info missing or wrong format"));
2782 if (plci
->fax_connect_info_length
<= len
)
2783 plci
->fax_connect_info_buffer
[len
] = 0;
2784 len
+= 1 + plci
->fax_connect_info_buffer
[len
];
2785 if (plci
->fax_connect_info_length
<= len
)
2786 plci
->fax_connect_info_buffer
[len
] = 0;
2787 len
+= 1 + plci
->fax_connect_info_buffer
[len
];
2788 if ((fax_parms
[7].length
>= 3) && (fax_parms
[7].info
[1] >= 2))
2789 plci
->nsf_control_bits
= GET_WORD(&fax_parms
[7].info
[2]);
2790 plci
->fax_connect_info_buffer
[len
++] = (byte
)(fax_parms
[7].length
);
2791 for (i
= 0; i
< fax_parms
[7].length
; i
++)
2792 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[7].info
[1 + i
];
2794 plci
->fax_connect_info_length
= len
;
2795 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->code
= 0;
2796 start_internal_command(Id
, plci
, fax_connect_ack_command
);
2801 nl_req_ncci(plci
, req
, (byte
)ncci
);
2802 if ((plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
2803 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
2805 if (plci
->B3_prot
== 4)
2806 sendf(appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
2808 sendf(appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "S", plci
->ncpi_buffer
);
2809 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
2813 else if (plci
->B3_prot
== B3_RTP
)
2815 plci
->internal_req_buffer
[0] = ncpi
->length
+ 1;
2816 plci
->internal_req_buffer
[1] = UDATA_REQUEST_RTP_RECONFIGURE
;
2817 for (w
= 0; w
< ncpi
->length
; w
++)
2818 plci
->internal_req_buffer
[2 + w
] = ncpi
->info
[1+w
];
2819 start_internal_command(Id
, plci
, rtp_connect_b3_res_command
);
2825 if (ncpi
->length
> 2) {
2826 if (ncpi
->info
[1] & 1) req
= N_CONNECT_ACK
| N_D_BIT
;
2827 add_d(plci
, (word
)(ncpi
->length
- 3), &ncpi
->info
[4]);
2829 nl_req_ncci(plci
, req
, (byte
)ncci
);
2830 sendf(appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
2831 if (plci
->adjust_b_restore
)
2833 plci
->adjust_b_restore
= false;
2834 start_internal_command(Id
, plci
, adjust_b_restore
);
2843 static byte
connect_b3_a_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
2844 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
2848 ncci
= (word
)(Id
>> 16);
2849 dbug(1, dprintf("connect_b3_a_res(ncci=0x%x)", ncci
));
2851 if (plci
&& ncci
&& (plci
->State
!= IDLE
) && (plci
->State
!= INC_DIS_PENDING
)
2852 && (plci
->State
!= OUTG_DIS_PENDING
))
2854 if (a
->ncci_state
[ncci
] == INC_ACT_PENDING
) {
2855 a
->ncci_state
[ncci
] = CONNECTED
;
2856 if (plci
->State
!= INC_CON_CONNECTED_ALERT
) plci
->State
= CONNECTED
;
2857 channel_request_xon(plci
, a
->ncci_ch
[ncci
]);
2858 channel_xmit_xon(plci
);
2864 static byte
disconnect_b3_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
2865 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
2871 dbug(1, dprintf("disconnect_b3_req"));
2873 Info
= _WRONG_IDENTIFIER
;
2874 ncci
= (word
)(Id
>> 16);
2877 Info
= _WRONG_STATE
;
2878 if ((a
->ncci_state
[ncci
] == CONNECTED
)
2879 || (a
->ncci_state
[ncci
] == OUTG_CON_PENDING
)
2880 || (a
->ncci_state
[ncci
] == INC_CON_PENDING
)
2881 || (a
->ncci_state
[ncci
] == INC_ACT_PENDING
))
2883 a
->ncci_state
[ncci
] = OUTG_DIS_PENDING
;
2884 channel_request_xon(plci
, a
->ncci_ch
[ncci
]);
2885 channel_xmit_xon(plci
);
2887 if (a
->ncci
[ncci
].data_pending
2888 && ((plci
->B3_prot
== B3_TRANSPARENT
)
2889 || (plci
->B3_prot
== B3_T30
)
2890 || (plci
->B3_prot
== B3_T30_WITH_EXTENSIONS
)))
2892 plci
->send_disc
= (byte
)ncci
;
2898 cleanup_ncci_data(plci
, ncci
);
2900 if (plci
->B3_prot
== 2 || plci
->B3_prot
== 3)
2903 if (ncpi
->length
> 3)
2905 add_d(plci
, (word
)(ncpi
->length
- 3), (byte
*)&(ncpi
->info
[4]));
2908 nl_req_ncci(plci
, N_DISC
, (byte
)ncci
);
2914 _DISCONNECT_B3_R
| CONFIRM
,
2921 static byte
disconnect_b3_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
2922 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
2927 ncci
= (word
)(Id
>> 16);
2928 dbug(1, dprintf("disconnect_b3_res(ncci=0x%x", ncci
));
2930 plci
->requested_options_conn
= 0;
2931 plci
->fax_connect_info_length
= 0;
2932 plci
->ncpi_state
= 0x00;
2933 if (((plci
->B3_prot
!= B3_T90NL
) && (plci
->B3_prot
!= B3_ISO8208
) && (plci
->B3_prot
!= B3_X25_DCE
))
2934 && ((plci
->B2_prot
!= B2_LAPD
) && (plci
->B2_prot
!= B2_LAPD_FREE_SAPI_SEL
)))
2936 plci
->call_dir
|= CALL_DIR_FORCE_OUTG_NL
;
2938 for (i
= 0; i
< MAX_CHANNELS_PER_PLCI
&& plci
->inc_dis_ncci_table
[i
] != (byte
)ncci
; i
++);
2939 if (i
< MAX_CHANNELS_PER_PLCI
) {
2940 if (plci
->channels
)plci
->channels
--;
2941 for (; i
< MAX_CHANNELS_PER_PLCI
- 1; i
++) plci
->inc_dis_ncci_table
[i
] = plci
->inc_dis_ncci_table
[i
+ 1];
2942 plci
->inc_dis_ncci_table
[MAX_CHANNELS_PER_PLCI
- 1] = 0;
2944 ncci_free_receive_buffers(plci
, ncci
);
2946 if ((plci
->State
== IDLE
|| plci
->State
== SUSPENDING
) && !plci
->channels
) {
2947 if (plci
->State
== SUSPENDING
) {
2952 "ws", (word
)3, "\x03\x04\x00\x00");
2953 sendf(plci
->appl
, _DISCONNECT_I
, Id
& 0xffffL
, 0, "w", 0);
2961 if ((a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
2962 && ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5))
2963 && (a
->ncci_state
[ncci
] == INC_DIS_PENDING
))
2965 ncci_free_receive_buffers(plci
, ncci
);
2967 nl_req_ncci(plci
, N_EDATA
, (byte
)ncci
);
2969 plci
->adapter
->ncci_state
[ncci
] = IDLE
;
2970 start_internal_command(Id
, plci
, fax_disconnect_command
);
2978 static byte
data_b3_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
2979 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
2987 dbug(1, dprintf("data_b3_req"));
2989 Info
= _WRONG_IDENTIFIER
;
2990 ncci
= (word
)(Id
>> 16);
2991 dbug(1, dprintf("ncci=0x%x, plci=0x%x", ncci
, plci
));
2995 Info
= _WRONG_STATE
;
2996 if ((a
->ncci_state
[ncci
] == CONNECTED
)
2997 || (a
->ncci_state
[ncci
] == INC_ACT_PENDING
))
3000 ncci_ptr
= &(a
->ncci
[ncci
]);
3001 i
= ncci_ptr
->data_out
+ ncci_ptr
->data_pending
;
3002 if (i
>= MAX_DATA_B3
)
3004 data
= &(ncci_ptr
->DBuffer
[i
]);
3005 data
->Number
= Number
;
3006 if ((((byte
*)(parms
[0].info
)) >= ((byte
*)(plci
->msg_in_queue
)))
3007 && (((byte
*)(parms
[0].info
)) < ((byte
*)(plci
->msg_in_queue
)) + sizeof(plci
->msg_in_queue
)))
3010 data
->P
= (byte
*)(long)(*((dword
*)(parms
[0].info
)));
3014 data
->P
= TransmitBufferSet(appl
, *(dword
*)parms
[0].info
);
3015 data
->Length
= GET_WORD(parms
[1].info
);
3016 data
->Handle
= GET_WORD(parms
[2].info
);
3017 data
->Flags
= GET_WORD(parms
[3].info
);
3018 (ncci_ptr
->data_pending
)++;
3020 /* check for delivery confirmation */
3021 if (data
->Flags
& 0x0004)
3023 i
= ncci_ptr
->data_ack_out
+ ncci_ptr
->data_ack_pending
;
3024 if (i
>= MAX_DATA_ACK
)
3026 ncci_ptr
->DataAck
[i
].Number
= data
->Number
;
3027 ncci_ptr
->DataAck
[i
].Handle
= data
->Handle
;
3028 (ncci_ptr
->data_ack_pending
)++;
3039 if ((((byte
*)(parms
[0].info
)) >= ((byte
*)(plci
->msg_in_queue
)))
3040 && (((byte
*)(parms
[0].info
)) < ((byte
*)(plci
->msg_in_queue
)) + sizeof(plci
->msg_in_queue
)))
3043 TransmitBufferFree(appl
, (byte
*)(long)(*((dword
*)(parms
[0].info
))));
3048 _DATA_B3_R
| CONFIRM
,
3051 "ww", GET_WORD(parms
[2].info
), Info
);
3056 static byte
data_b3_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3057 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
3063 dbug(1, dprintf("data_b3_res"));
3065 ncci
= (word
)(Id
>> 16);
3067 n
= GET_WORD(parms
[0].info
);
3068 dbug(1, dprintf("free(%d)", n
));
3069 NCCIcode
= ncci
| (((word
) a
->Id
) << 8);
3070 if (n
< appl
->MaxBuffer
&&
3071 appl
->DataNCCI
[n
] == NCCIcode
&&
3072 (byte
)(appl
->DataFlags
[n
] >> 8) == plci
->Id
) {
3073 dbug(1, dprintf("found"));
3074 appl
->DataNCCI
[n
] = 0;
3076 if (channel_can_xon(plci
, a
->ncci_ch
[ncci
])) {
3077 channel_request_xon(plci
, a
->ncci_ch
[ncci
]);
3079 channel_xmit_xon(plci
);
3081 if (appl
->DataFlags
[n
] & 4) {
3082 nl_req_ncci(plci
, N_DATA_ACK
, (byte
)ncci
);
3090 static byte
reset_b3_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3091 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
3096 dbug(1, dprintf("reset_b3_req"));
3098 Info
= _WRONG_IDENTIFIER
;
3099 ncci
= (word
)(Id
>> 16);
3102 Info
= _WRONG_STATE
;
3103 switch (plci
->B3_prot
)
3107 if (a
->ncci_state
[ncci
] == CONNECTED
)
3109 nl_req_ncci(plci
, N_RESET
, (byte
)ncci
);
3114 case B3_TRANSPARENT
:
3115 if (a
->ncci_state
[ncci
] == CONNECTED
)
3117 start_internal_command(Id
, plci
, reset_b3_command
);
3123 /* reset_b3 must result in a reset_b3_con & reset_b3_Ind */
3125 _RESET_B3_R
| CONFIRM
,
3132 static byte
reset_b3_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3133 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
3137 dbug(1, dprintf("reset_b3_res"));
3139 ncci
= (word
)(Id
>> 16);
3141 switch (plci
->B3_prot
)
3145 if (a
->ncci_state
[ncci
] == INC_RES_PENDING
)
3147 a
->ncci_state
[ncci
] = CONNECTED
;
3148 nl_req_ncci(plci
, N_RESET_ACK
, (byte
)ncci
);
3157 static byte
connect_b3_t90_a_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3158 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
3164 dbug(1, dprintf("connect_b3_t90_a_res"));
3166 ncci
= (word
)(Id
>> 16);
3168 if (a
->ncci_state
[ncci
] == INC_ACT_PENDING
) {
3169 a
->ncci_state
[ncci
] = CONNECTED
;
3171 else if (a
->ncci_state
[ncci
] == INC_CON_PENDING
) {
3172 a
->ncci_state
[ncci
] = CONNECTED
;
3174 req
= N_CONNECT_ACK
;
3176 /* parms[0]==0 for CAPI original message definition! */
3177 if (parms
[0].info
) {
3179 if (ncpi
->length
> 2) {
3180 if (ncpi
->info
[1] & 1) req
= N_CONNECT_ACK
| N_D_BIT
;
3181 add_d(plci
, (word
)(ncpi
->length
- 3), &ncpi
->info
[4]);
3184 nl_req_ncci(plci
, req
, (byte
)ncci
);
3192 static byte
select_b_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3193 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
3198 API_PARSE bp_parms
[7];
3202 Info
= _WRONG_IDENTIFIER
;
3206 dbug(1, dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x",
3207 msg
->length
, plci
->Id
, plci
->tel
, plci
->NL
.Id
, plci
->appl
, plci
->SuppState
));
3208 dbug(1, dprintf("PlciState=0x%x", plci
->State
));
3209 for (i
= 0; i
< 7; i
++) bp_parms
[i
].length
= 0;
3211 /* check if no channel is open, no B3 connected only */
3212 if ((plci
->State
== IDLE
) || (plci
->State
== OUTG_DIS_PENDING
) || (plci
->State
== INC_DIS_PENDING
)
3213 || (plci
->SuppState
!= IDLE
) || plci
->channels
|| plci
->nl_remove_id
)
3215 Info
= _WRONG_STATE
;
3217 /* check message format and fill bp_parms pointer */
3218 else if (msg
->length
&& api_parse(&msg
->info
[1], (word
)msg
->length
, "wwwsss", bp_parms
))
3220 Info
= _WRONG_MESSAGE_FORMAT
;
3224 if ((plci
->State
== INC_CON_PENDING
) || (plci
->State
== INC_CON_ALERT
)) /* send alert tone inband to the network, */
3225 { /* e.g. Qsig or RBS or Cornet-N or xess PRI */
3226 if (Id
& EXT_CONTROLLER
)
3228 sendf(appl
, _SELECT_B_REQ
| CONFIRM
, Id
, Number
, "w", 0x2002); /* wrong controller */
3231 plci
->State
= INC_CON_CONNECTED_ALERT
;
3233 __clear_bit(appl
->Id
- 1, plci
->c_ind_mask_table
);
3234 dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL
, plci
->c_ind_mask_table
));
3235 /* disconnect the other appls its quasi a connect */
3236 for_each_set_bit(i
, plci
->c_ind_mask_table
, max_appl
)
3237 sendf(&application
[i
], _DISCONNECT_I
, Id
, 0, "w", _OTHER_APPL_CONNECTED
);
3240 api_save_msg(msg
, "s", &plci
->saved_msg
);
3242 if (Id
& EXT_CONTROLLER
)
3244 if (tel
) /* external controller in use by this PLCI */
3246 if (a
->AdvSignalAppl
&& a
->AdvSignalAppl
!= appl
)
3248 dbug(1, dprintf("Ext_Ctrl in use 1"));
3249 Info
= _WRONG_STATE
;
3252 else /* external controller NOT in use by this PLCI ? */
3254 if (a
->AdvSignalPLCI
)
3256 dbug(1, dprintf("Ext_Ctrl in use 2"));
3257 Info
= _WRONG_STATE
;
3259 else /* activate the codec */
3261 dbug(1, dprintf("Ext_Ctrl start"));
3262 if (AdvCodecSupport(a
, plci
, appl
, 0))
3264 dbug(1, dprintf("Error in codec procedures"));
3265 Info
= _WRONG_STATE
;
3267 else if (plci
->spoofed_msg
== SPOOFING_REQUIRED
) /* wait until codec is active */
3269 plci
->spoofed_msg
= AWAITING_SELECT_B
;
3270 plci
->internal_command
= BLOCK_PLCI
; /* lock other commands */
3272 dbug(1, dprintf("continue if codec loaded"));
3278 else /* external controller bit is OFF */
3280 if (tel
) /* external controller in use, need to switch off */
3282 if (a
->AdvSignalAppl
== appl
)
3284 CodecIdCheck(a
, plci
);
3287 dbug(1, dprintf("Ext_Ctrl disable"));
3291 dbug(1, dprintf("Ext_Ctrl not requested"));
3297 if (plci
->call_dir
& CALL_DIR_OUT
)
3298 plci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
3299 else if (plci
->call_dir
& CALL_DIR_IN
)
3300 plci
->call_dir
= CALL_DIR_IN
| CALL_DIR_ANSWER
;
3301 start_internal_command(Id
, plci
, select_b_command
);
3306 sendf(appl
, _SELECT_B_REQ
| CONFIRM
, Id
, Number
, "w", Info
);
3310 static byte
manufacturer_req(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3311 PLCI
*plci
, APPL
*appl
, API_PARSE
*parms
)
3317 API_PARSE m_parms
[5];
3322 static byte chi
[2] = {0x01, 0x00};
3323 static byte lli
[2] = {0x01, 0x00};
3324 static byte codec_cai
[2] = {0x01, 0x01};
3325 static byte null_msg
= {0};
3326 static API_PARSE null_parms
= { 0, &null_msg
};
3330 dbug(1, dprintf("manufacturer_req"));
3331 for (i
= 0; i
< 5; i
++) m_parms
[i
].length
= 0;
3333 if (GET_DWORD(parms
[0].info
) != _DI_MANU_ID
) {
3334 Info
= _WRONG_MESSAGE_FORMAT
;
3336 command
= GET_WORD(parms
[1].info
);
3341 case _DI_ASSIGN_PLCI
:
3342 if (api_parse(&m
->info
[1], (word
)m
->length
, "wbbs", m_parms
)) {
3343 Info
= _WRONG_MESSAGE_FORMAT
;
3346 codec
= GET_WORD(m_parms
[0].info
);
3347 ch
= m_parms
[1].info
[0];
3348 dir
= m_parms
[2].info
[0];
3349 if ((i
= get_plci(a
))) {
3350 plci
= &a
->plci
[i
- 1];
3352 plci
->command
= _MANUFACTURER_R
;
3353 plci
->m_command
= command
;
3354 plci
->number
= Number
;
3355 plci
->State
= LOCAL_CONNECT
;
3356 Id
= (((word
)plci
->Id
<< 8) | plci
->adapter
->Id
| 0x80);
3357 dbug(1, dprintf("ManCMD,plci=0x%x", Id
));
3359 if ((ch
== 1 || ch
== 2) && (dir
<= 2)) {
3360 chi
[1] = (byte
)(0x80 | ch
);
3362 plci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
3366 Info
= add_b1(plci
, &m_parms
[3], 0, 0);
3369 add_p(plci
, CAI
, codec_cai
);
3371 /* manual 'swich on' to the codec support without signalling */
3372 /* first 'assign plci' with this function, then use */
3374 if (AdvCodecSupport(a
, plci
, appl
, 0)) {
3375 Info
= _RESOURCE_ERROR
;
3378 Info
= add_b1(plci
, &null_parms
, 0, B1_FACILITY_LOCAL
);
3379 lli
[1] = 0x10; /* local call codec stream */
3384 plci
->State
= LOCAL_CONNECT
;
3385 plci
->manufacturer
= true;
3386 plci
->command
= _MANUFACTURER_R
;
3387 plci
->m_command
= command
;
3388 plci
->number
= Number
;
3392 add_p(plci
, LLI
, lli
);
3393 add_p(plci
, CHI
, chi
);
3394 add_p(plci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
3395 sig_req(plci
, ASSIGN
, DSIG_ID
);
3399 Info
= add_b23(plci
, &m_parms
[3]);
3402 nl_req_ncci(plci
, ASSIGN
, 0);
3408 dbug(1, dprintf("dir=0x%x,spoof=0x%x", dir
, plci
->spoofed_msg
));
3409 if (plci
->spoofed_msg
== SPOOFING_REQUIRED
)
3411 api_save_msg(m_parms
, "wbbs", &plci
->saved_msg
);
3412 plci
->spoofed_msg
= AWAITING_MANUF_CON
;
3413 plci
->internal_command
= BLOCK_PLCI
; /* reject other req meanwhile */
3419 sig_req(plci
, CALL_REQ
, 0);
3422 sig_req(plci
, LISTEN_REQ
, 0);
3429 _MANUFACTURER_R
| CONFIRM
,
3432 "dww", _DI_MANU_ID
, command
, Info
);
3438 else Info
= _OUT_OF_PLCI
;
3444 Info
= _WRONG_IDENTIFIER
;
3447 if (api_parse(&m
->info
[1], (word
)m
->length
, "bs", m_parms
)) {
3448 Info
= _WRONG_MESSAGE_FORMAT
;
3451 req
= m_parms
[0].info
[0];
3452 plci
->command
= _MANUFACTURER_R
;
3453 plci
->m_command
= command
;
3454 plci
->number
= Number
;
3455 if (req
== CALL_REQ
)
3457 plci
->b_channel
= getChannel(&m_parms
[1]);
3458 mixer_set_bchannel_id_esc(plci
, plci
->b_channel
);
3459 if (plci
->spoofed_msg
== SPOOFING_REQUIRED
)
3461 plci
->spoofed_msg
= CALL_REQ
| AWAITING_MANUF_CON
;
3462 plci
->internal_command
= BLOCK_PLCI
; /* reject other req meanwhile */
3467 else if (req
== LAW_REQ
)
3469 plci
->cr_enquiry
= true;
3471 add_ss(plci
, FTY
, &m_parms
[1]);
3472 sig_req(plci
, req
, 0);
3476 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
3480 for (ncci
= 1; ncci
< MAX_NCCI
+ 1; ncci
++)
3482 if ((a
->ncci_plci
[ncci
] == plci
->Id
) && (a
->ncci_state
[ncci
] == CONNECTED
))
3484 a
->ncci_state
[ncci
] = OUTG_DIS_PENDING
;
3485 cleanup_ncci_data(plci
, ncci
);
3486 nl_req_ncci(plci
, N_DISC
, (byte
)ncci
);
3491 nl_req_ncci(plci
, REMOVE
, 0);
3498 /* signalling control for loop activation B-channel */
3501 Info
= _WRONG_IDENTIFIER
;
3505 plci
->command
= _MANUFACTURER_R
;
3506 plci
->number
= Number
;
3507 add_ss(plci
, FTY
, m
);
3508 sig_req(plci
, SIG_CTRL
, 0);
3511 else Info
= _WRONG_MESSAGE_FORMAT
;
3515 /* activation control for receiver/transmitter B-channel */
3518 Info
= _WRONG_IDENTIFIER
;
3522 plci
->command
= _MANUFACTURER_R
;
3523 plci
->number
= Number
;
3524 add_ss(plci
, FTY
, m
);
3525 sig_req(plci
, DSP_CTRL
, 0);
3528 else Info
= _WRONG_MESSAGE_FORMAT
;
3533 /* TEL_CTRL commands to support non standard adjustments: */
3534 /* Ring on/off, Handset micro volume, external micro vol. */
3535 /* handset+external speaker volume, receiver+transm. gain,*/
3536 /* handsfree on (hookinfo off), set mixer command */
3538 if (command
== _DI_ADV_CODEC
)
3540 if (!a
->AdvCodecPLCI
) {
3541 Info
= _WRONG_STATE
;
3544 v_plci
= a
->AdvCodecPLCI
;
3550 && (m
->info
[1] == 0x1c)
3551 && (m
->info
[2] >= 1))
3553 if (m
->info
[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS
)
3555 if ((plci
->tel
!= ADV_VOICE
) || (plci
!= a
->AdvSignalPLCI
))
3557 Info
= _WRONG_STATE
;
3560 a
->adv_voice_coef_length
= m
->info
[2] - 1;
3561 if (a
->adv_voice_coef_length
> m
->length
- 3)
3562 a
->adv_voice_coef_length
= (byte
)(m
->length
- 3);
3563 if (a
->adv_voice_coef_length
> ADV_VOICE_COEF_BUFFER_SIZE
)
3564 a
->adv_voice_coef_length
= ADV_VOICE_COEF_BUFFER_SIZE
;
3565 for (i
= 0; i
< a
->adv_voice_coef_length
; i
++)
3566 a
->adv_voice_coef_buffer
[i
] = m
->info
[4 + i
];
3567 if (plci
->B1_facilities
& B1_FACILITY_VOICE
)
3568 adv_voice_write_coefs(plci
, ADV_VOICE_WRITE_UPDATE
);
3571 else if (m
->info
[3] == DSP_CTRL_SET_DTMF_PARAMETERS
)
3573 if (!(a
->manufacturer_features
& MANUFACTURER_FEATURE_DTMF_PARAMETERS
))
3575 Info
= _FACILITY_NOT_SUPPORTED
;
3579 plci
->dtmf_parameter_length
= m
->info
[2] - 1;
3580 if (plci
->dtmf_parameter_length
> m
->length
- 3)
3581 plci
->dtmf_parameter_length
= (byte
)(m
->length
- 3);
3582 if (plci
->dtmf_parameter_length
> DTMF_PARAMETER_BUFFER_SIZE
)
3583 plci
->dtmf_parameter_length
= DTMF_PARAMETER_BUFFER_SIZE
;
3584 for (i
= 0; i
< plci
->dtmf_parameter_length
; i
++)
3585 plci
->dtmf_parameter_buffer
[i
] = m
->info
[4 + i
];
3586 if (plci
->B1_facilities
& B1_FACILITY_DTMFR
)
3587 dtmf_parameter_write(plci
);
3597 Info
= _WRONG_IDENTIFIER
;
3601 add_ss(v_plci
, FTY
, m
);
3602 sig_req(v_plci
, TEL_CTRL
, 0);
3605 else Info
= _WRONG_MESSAGE_FORMAT
;
3609 case _DI_OPTIONS_REQUEST
:
3610 if (api_parse(&m
->info
[1], (word
)m
->length
, "d", m_parms
)) {
3611 Info
= _WRONG_MESSAGE_FORMAT
;
3614 if (GET_DWORD(m_parms
[0].info
) & ~a
->man_profile
.private_options
)
3616 Info
= _FACILITY_NOT_SUPPORTED
;
3619 a
->requested_options_table
[appl
->Id
- 1] = GET_DWORD(m_parms
[0].info
);
3625 Info
= _WRONG_MESSAGE_FORMAT
;
3631 _MANUFACTURER_R
| CONFIRM
,
3634 "dww", _DI_MANU_ID
, command
, Info
);
3639 static byte
manufacturer_res(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
,
3640 PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
3644 API_PARSE m_parms
[3];
3646 API_PARSE fax_parms
[9];
3651 dbug(1, dprintf("manufacturer_res"));
3653 if ((msg
[0].length
== 0)
3654 || (msg
[1].length
== 0)
3655 || (GET_DWORD(msg
[0].info
) != _DI_MANU_ID
))
3659 indication
= GET_WORD(msg
[1].info
);
3663 case _DI_NEGOTIATE_B3
:
3666 if (((plci
->B3_prot
!= 4) && (plci
->B3_prot
!= 5))
3667 || !(plci
->ncpi_state
& NCPI_NEGOTIATE_B3_SENT
))
3669 dbug(1, dprintf("wrong state for NEGOTIATE_B3 parameters"));
3672 if (api_parse(&msg
[2].info
[1], msg
[2].length
, "ws", m_parms
))
3674 dbug(1, dprintf("wrong format in NEGOTIATE_B3 parameters"));
3678 len
= offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
;
3679 if (plci
->fax_connect_info_length
< len
)
3681 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->station_id_len
= 0;
3682 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->head_line_len
= 0;
3684 if (api_parse(&ncpi
->info
[1], ncpi
->length
, "wwwwssss", fax_parms
))
3686 dbug(1, dprintf("non-standard facilities info missing or wrong format"));
3690 if (plci
->fax_connect_info_length
<= len
)
3691 plci
->fax_connect_info_buffer
[len
] = 0;
3692 len
+= 1 + plci
->fax_connect_info_buffer
[len
];
3693 if (plci
->fax_connect_info_length
<= len
)
3694 plci
->fax_connect_info_buffer
[len
] = 0;
3695 len
+= 1 + plci
->fax_connect_info_buffer
[len
];
3696 if ((fax_parms
[7].length
>= 3) && (fax_parms
[7].info
[1] >= 2))
3697 plci
->nsf_control_bits
= GET_WORD(&fax_parms
[7].info
[2]);
3698 plci
->fax_connect_info_buffer
[len
++] = (byte
)(fax_parms
[7].length
);
3699 for (i
= 0; i
< fax_parms
[7].length
; i
++)
3700 plci
->fax_connect_info_buffer
[len
++] = fax_parms
[7].info
[1 + i
];
3702 plci
->fax_connect_info_length
= len
;
3703 plci
->fax_edata_ack_length
= plci
->fax_connect_info_length
;
3704 start_internal_command(Id
, plci
, fax_edata_ack_command
);
3711 /*------------------------------------------------------------------*/
3712 /* IDI callback function */
3713 /*------------------------------------------------------------------*/
3715 void callback(ENTITY
*e
)
3717 DIVA_CAPI_ADAPTER
*a
;
3728 dbug(1, dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)",
3729 (e
->user
[0] + 1) & 0x7fff, e
->Id
, e
->Req
, e
->Rc
, e
->Ind
));
3731 a
= &(adapter
[(byte
)e
->user
[0]]);
3732 plci
= &(a
->plci
[e
->user
[1]]);
3733 no_cancel_rc
= DIVA_CAPI_SUPPORTS_NO_CANCEL(a
);
3736 If new protocol code and new XDI is used then CAPI should work
3737 fully in accordance with IDI cpec an look on callback field instead
3738 of Rc field for return codes.
3740 if (((e
->complete
== 0xff) && no_cancel_rc
) ||
3741 (e
->Rc
&& !no_cancel_rc
)) {
3747 if (e
->user
[0] & 0x8000)
3750 If REMOVE request was sent then we have to wait until
3751 return code with Id set to zero arrives.
3752 All other return codes should be ignored.
3758 dbug(1, dprintf("cancel RC in REMOVE state"));
3761 channel_flow_control_remove(plci
);
3762 for (i
= 0; i
< 256; i
++)
3764 if (a
->FlowControlIdTable
[i
] == plci
->nl_remove_id
)
3765 a
->FlowControlIdTable
[i
] = 0;
3767 plci
->nl_remove_id
= 0;
3768 if (plci
->rx_dma_descriptor
> 0) {
3769 diva_free_dma_descriptor(plci
, plci
->rx_dma_descriptor
- 1);
3770 plci
->rx_dma_descriptor
= 0;
3775 a
->FlowControlIdTable
[ch
] = e
->Id
;
3776 a
->FlowControlSkipTable
[ch
] = 0;
3778 a
->ch_flow_control
[ch
] |= N_OK_FC_PENDING
;
3779 a
->ch_flow_plci
[ch
] = plci
->Id
;
3785 Cancel return codes self, if feature was requested
3787 if (no_cancel_rc
&& (a
->FlowControlIdTable
[ch
] == e
->Id
) && e
->Id
) {
3788 a
->FlowControlIdTable
[ch
] = 0;
3789 if ((rc
== OK
) && a
->FlowControlSkipTable
[ch
]) {
3790 dbug(3, dprintf("XDI CAPI: RC cancelled Id:0x02, Ch:%02x", e
->Id
, ch
));
3795 if (a
->ch_flow_control
[ch
] & N_OK_FC_PENDING
)
3797 a
->ch_flow_control
[ch
] &= ~N_OK_FC_PENDING
;
3805 control_rc(plci
, 0, rc
, ch
, 0, true);
3810 channel_x_on(plci
, ch
);
3811 if (plci
->internal_command
)
3812 control_rc(plci
, req
, rc
, ch
, 0, true);
3816 if (plci
->nl_global_req
)
3818 global_req
= plci
->nl_global_req
;
3819 plci
->nl_global_req
= 0;
3820 if (rc
!= ASSIGN_OK
) {
3822 if (plci
->rx_dma_descriptor
> 0) {
3823 diva_free_dma_descriptor(plci
, plci
->rx_dma_descriptor
- 1);
3824 plci
->rx_dma_descriptor
= 0;
3827 channel_xmit_xon(plci
);
3828 control_rc(plci
, 0, rc
, ch
, global_req
, true);
3830 else if (plci
->data_sent
)
3832 channel_xmit_xon(plci
);
3833 plci
->data_sent
= false;
3836 if (plci
->internal_command
)
3837 control_rc(plci
, req
, rc
, ch
, 0, true);
3841 channel_xmit_xon(plci
);
3842 control_rc(plci
, req
, rc
, ch
, 0, true);
3850 If REMOVE request was sent then we have to wait until
3851 return code with Id set to zero arrives.
3852 All other return codes should be ignored.
3858 dbug(1, dprintf("cancel RC in REMOVE state"));
3861 plci
->sig_remove_id
= 0;
3864 if (plci
->sig_global_req
)
3866 global_req
= plci
->sig_global_req
;
3867 plci
->sig_global_req
= 0;
3868 if (rc
!= ASSIGN_OK
)
3870 channel_xmit_xon(plci
);
3871 control_rc(plci
, 0, rc
, ch
, global_req
, false);
3875 channel_xmit_xon(plci
);
3876 control_rc(plci
, req
, rc
, ch
, 0, false);
3880 Again: in accordance with IDI spec Rc and Ind can't be delivered in the
3881 same callback. Also if new XDI and protocol code used then jump
3885 channel_xmit_xon(plci
);
3886 goto capi_callback_suffix
;
3890 channel_xmit_xon(plci
);
3893 if (e
->user
[0] & 0x8000) {
3894 byte Ind
= e
->Ind
& 0x0f;
3896 if (((Ind
== N_DISC
) || (Ind
== N_DISC_ACK
)) &&
3897 (a
->ch_flow_plci
[Ch
] == plci
->Id
)) {
3898 if (a
->ch_flow_control
[Ch
] & N_RX_FLOW_CONTROL_MASK
) {
3899 dbug(3, dprintf("XDI CAPI: I: pending N-XON Ch:%02x", Ch
));
3901 a
->ch_flow_control
[Ch
] &= ~N_RX_FLOW_CONTROL_MASK
;
3904 if ((e
->RNR
!= 1) &&
3905 (a
->ch_flow_plci
[Ch
] == plci
->Id
) &&
3906 (a
->ch_flow_control
[Ch
] & N_RX_FLOW_CONTROL_MASK
)) {
3907 a
->ch_flow_control
[Ch
] &= ~N_RX_FLOW_CONTROL_MASK
;
3908 dbug(3, dprintf("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch
));
3916 capi_callback_suffix
:
3918 while (!plci
->req_in
3919 && !plci
->internal_command
3920 && (plci
->msg_in_write_pos
!= plci
->msg_in_read_pos
))
3922 j
= (plci
->msg_in_read_pos
== plci
->msg_in_wrap_pos
) ? 0 : plci
->msg_in_read_pos
;
3924 i
= (((CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[j
]))->header
.length
+ 3) & 0xfffc;
3926 m
= (CAPI_MSG
*)(&((byte
*)(plci
->msg_in_queue
))[j
]);
3927 appl
= *((APPL
**)(&((byte
*)(plci
->msg_in_queue
))[j
+ i
]));
3928 dbug(1, dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d",
3929 m
->header
.command
, plci
->msg_in_write_pos
, plci
->msg_in_read_pos
, plci
->msg_in_wrap_pos
));
3930 if (plci
->msg_in_read_pos
== plci
->msg_in_wrap_pos
)
3932 plci
->msg_in_wrap_pos
= MSG_IN_QUEUE_SIZE
;
3933 plci
->msg_in_read_pos
= i
+ MSG_IN_OVERHEAD
;
3937 plci
->msg_in_read_pos
= j
+ i
+ MSG_IN_OVERHEAD
;
3939 if (plci
->msg_in_read_pos
== plci
->msg_in_write_pos
)
3941 plci
->msg_in_write_pos
= MSG_IN_QUEUE_SIZE
;
3942 plci
->msg_in_read_pos
= MSG_IN_QUEUE_SIZE
;
3944 else if (plci
->msg_in_read_pos
== plci
->msg_in_wrap_pos
)
3946 plci
->msg_in_read_pos
= MSG_IN_QUEUE_SIZE
;
3947 plci
->msg_in_wrap_pos
= MSG_IN_QUEUE_SIZE
;
3949 i
= api_put(appl
, m
);
3952 if (m
->header
.command
== _DATA_B3_R
)
3954 TransmitBufferFree(appl
, (byte
*)(long)(m
->info
.data_b3_req
.Data
));
3956 dbug(1, dprintf("Error 0x%04x from msg(0x%04x)", i
, m
->header
.command
));
3960 if (plci
->li_notify_update
)
3962 plci
->li_notify_update
= false;
3963 mixer_notify_update(plci
, false);
3972 static void control_rc(PLCI
*plci
, byte req
, byte rc
, byte ch
, byte global_req
,
3981 DIVA_CAPI_ADAPTER
*a
;
3984 byte SSparms
[] = "\x05\x00\x00\x02\x00\x00";
3985 byte SSstruct
[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
3988 dbug(0, dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req
, rc
, ch
, global_req
, nl_rc
));
3991 dbug(1, dprintf("req0_in/out=%d/%d", plci
->req_in
, plci
->req_out
));
3992 if (plci
->req_in
!= plci
->req_out
)
3994 if (nl_rc
|| (global_req
!= ASSIGN
) || (rc
== ASSIGN_OK
))
3996 dbug(1, dprintf("req_1return"));
3999 /* cancel outstanding request on the PLCI after SIG ASSIGN failure */
4001 plci
->req_in
= plci
->req_in_start
= plci
->req_out
= 0;
4002 dbug(1, dprintf("control_rc"));
4006 ncci
= a
->ch_ncci
[ch
];
4009 Id
= (((dword
)(ncci
? ncci
: ch
)) << 16) | ((word
)plci
->Id
<< 8) | a
->Id
;
4010 if (plci
->tel
&& plci
->SuppState
!= CALL_HELD
) Id
|= EXT_CONTROLLER
;
4011 Number
= plci
->number
;
4012 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
));
4013 dbug(1, dprintf("channels=0x%x", plci
->channels
));
4014 if (plci_remove_check(plci
))
4016 if (req
== REMOVE
&& rc
== ASSIGN_OK
)
4018 sig_req(plci
, HANGUP
, 0);
4019 sig_req(plci
, REMOVE
, 0);
4024 switch (plci
->command
)
4027 dbug(1, dprintf("HoldRC=0x%x", rc
));
4028 SSparms
[1] = (byte
)S_HOLD
;
4031 plci
->SuppState
= IDLE
;
4034 sendf(appl
, _FACILITY_R
| CONFIRM
, Id
, Number
, "wws", Info
, 3, SSparms
);
4037 case C_RETRIEVE_REQ
:
4038 dbug(1, dprintf("RetrieveRC=0x%x", rc
));
4039 SSparms
[1] = (byte
)S_RETRIEVE
;
4042 plci
->SuppState
= CALL_HELD
;
4045 sendf(appl
, _FACILITY_R
| CONFIRM
, Id
, Number
, "wws", Info
, 3, SSparms
);
4049 dbug(1, dprintf("InfoRC=0x%x", rc
));
4050 if (rc
!= OK
) Info
= _WRONG_STATE
;
4051 sendf(appl
, _INFO_R
| CONFIRM
, Id
, Number
, "w", Info
);
4055 dbug(1, dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x", req
, rc
, global_req
, nl_rc
));
4056 if (plci
->State
== INC_DIS_PENDING
)
4058 if (plci
->Sig
.Id
!= 0xff)
4060 if (((global_req
== ASSIGN
) && (rc
!= ASSIGN_OK
))
4061 || (!nl_rc
&& (req
== CALL_REQ
) && (rc
!= OK
)))
4063 dbug(1, dprintf("No more IDs/Call_Req failed"));
4064 sendf(appl
, _CONNECT_R
| CONFIRM
, Id
& 0xffL
, Number
, "w", _OUT_OF_PLCI
);
4069 if (plci
->State
!= LOCAL_CONNECT
) plci
->State
= OUTG_CON_PENDING
;
4070 sendf(appl
, _CONNECT_R
| CONFIRM
, Id
, Number
, "w", 0);
4072 else /* D-ch activation */
4074 if (rc
!= ASSIGN_OK
)
4076 dbug(1, dprintf("No more IDs/X.25 Call_Req failed"));
4077 sendf(appl
, _CONNECT_R
| CONFIRM
, Id
& 0xffL
, Number
, "w", _OUT_OF_PLCI
);
4082 sendf(appl
, _CONNECT_R
| CONFIRM
, Id
, Number
, "w", 0);
4083 sendf(plci
->appl
, _CONNECT_ACTIVE_I
, Id
, 0, "sss", "", "", "");
4084 plci
->State
= INC_ACT_PENDING
;
4088 case _CONNECT_I
| RESPONSE
:
4089 if (plci
->State
!= INC_DIS_PENDING
)
4090 plci
->State
= INC_CON_ACCEPT
;
4094 if (plci
->State
== INC_DIS_PENDING
)
4096 if (plci
->Sig
.Id
!= 0xff)
4098 plci
->State
= OUTG_DIS_PENDING
;
4099 sendf(appl
, _DISCONNECT_R
| CONFIRM
, Id
, Number
, "w", 0);
4112 sendf(appl
, _CONNECT_B3_R
| CONFIRM
, Id
, Number
, "w", _WRONG_IDENTIFIER
);
4115 ncci
= get_ncci(plci
, ch
, 0);
4116 Id
= (Id
& 0xffff) | (((dword
) ncci
) << 16);
4120 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
4121 sendf(appl
, _CONNECT_B3_R
| CONFIRM
, Id
, Number
, "w", 0);
4122 sendf(appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
4126 a
->ncci_state
[ncci
] = OUTG_CON_PENDING
;
4127 sendf(appl
, _CONNECT_B3_R
| CONFIRM
, Id
, Number
, "w", 0);
4131 case _CONNECT_B3_I
| RESPONSE
:
4135 /* sendf(appl, _RESET_B3_R | CONFIRM, Id, Number, "w", 0);*/
4138 case _DISCONNECT_B3_R
:
4139 sendf(appl
, _DISCONNECT_B3_R
| CONFIRM
, Id
, Number
, "w", 0);
4142 case _MANUFACTURER_R
:
4148 Info
= _WRONG_IDENTIFIER
;
4149 sendf(plci
->appl
, _CONNECT_R
| CONFIRM
, Id
, Number
, "w", Info
);
4153 sendf(plci
->appl
, _CONNECT_R
| CONFIRM
, Id
, Number
, "w", Info
);
4161 else if (plci
->internal_command
)
4163 switch (plci
->internal_command
)
4169 if (rc
== OK
) /* command supported, wait for indication */
4176 /* Get Supported Services */
4177 case GETSERV_REQ_PEND
:
4178 if (rc
== OK
) /* command supported, wait for indication */
4182 PUT_DWORD(&SSstruct
[6], MASK_TERMINAL_PORTABILITY
);
4183 sendf(appl
, _FACILITY_R
| CONFIRM
, Id
, Number
, "wws", 0, 3, SSstruct
);
4187 case INTERR_DIVERSION_REQ_PEND
: /* Interrogate Parameters */
4188 case INTERR_NUMBERS_REQ_PEND
:
4189 case CF_START_PEND
: /* Call Forwarding Start pending */
4190 case CF_STOP_PEND
: /* Call Forwarding Stop pending */
4191 case CCBS_REQUEST_REQ_PEND
:
4192 case CCBS_DEACTIVATE_REQ_PEND
:
4193 case CCBS_INTERROGATE_REQ_PEND
:
4194 switch (plci
->internal_command
)
4196 case INTERR_DIVERSION_REQ_PEND
:
4197 SSparms
[1] = S_INTERROGATE_DIVERSION
;
4199 case INTERR_NUMBERS_REQ_PEND
:
4200 SSparms
[1] = S_INTERROGATE_NUMBERS
;
4203 SSparms
[1] = S_CALL_FORWARDING_START
;
4206 SSparms
[1] = S_CALL_FORWARDING_STOP
;
4208 case CCBS_REQUEST_REQ_PEND
:
4209 SSparms
[1] = S_CCBS_REQUEST
;
4211 case CCBS_DEACTIVATE_REQ_PEND
:
4212 SSparms
[1] = S_CCBS_DEACTIVATE
;
4214 case CCBS_INTERROGATE_REQ_PEND
:
4215 SSparms
[1] = S_CCBS_INTERROGATE
;
4218 if (global_req
== ASSIGN
)
4220 dbug(1, dprintf("AssignDiversion_RC=0x%x/0x%x", req
, rc
));
4223 if (!plci
->appl
) break;
4224 if (rc
== ISDN_GUARD_REJ
)
4226 Info
= _CAPI_GUARD_ERROR
;
4230 Info
= _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED
;
4232 sendf(plci
->appl
, _FACILITY_R
| CONFIRM
, Id
& 0x7,
4233 plci
->number
, "wws", Info
, (word
)3, SSparms
);
4234 if (Info
) plci_remove(plci
);
4237 /* 3pty conference pending */
4239 if (!plci
->relatedPTYPLCI
) break;
4240 rplci
= plci
->relatedPTYPLCI
;
4241 SSparms
[1] = plci
->ptyState
;
4242 rId
= ((word
)rplci
->Id
<< 8) | rplci
->adapter
->Id
;
4243 if (rplci
->tel
) rId
|= EXT_CONTROLLER
;
4246 Info
= 0x300E; /* not supported */
4247 plci
->relatedPTYPLCI
= NULL
;
4251 _FACILITY_R
| CONFIRM
,
4254 "wws", Info
, (word
)3, SSparms
);
4257 /* Explicit Call Transfer pending */
4259 dbug(1, dprintf("ECT_RC=0x%x/0x%x", req
, rc
));
4260 if (!plci
->relatedPTYPLCI
) break;
4261 rplci
= plci
->relatedPTYPLCI
;
4263 rId
= ((word
)rplci
->Id
<< 8) | rplci
->adapter
->Id
;
4264 if (rplci
->tel
) rId
|= EXT_CONTROLLER
;
4267 Info
= 0x300E; /* not supported */
4268 plci
->relatedPTYPLCI
= NULL
;
4272 _FACILITY_R
| CONFIRM
,
4275 "wws", Info
, (word
)3, SSparms
);
4278 case _MANUFACTURER_R
:
4279 dbug(1, dprintf("_Manufacturer_R=0x%x/0x%x", req
, rc
));
4280 if ((global_req
== ASSIGN
) && (rc
!= ASSIGN_OK
))
4282 dbug(1, dprintf("No more IDs"));
4283 sendf(appl
, _MANUFACTURER_R
| CONFIRM
, Id
, Number
, "dww", _DI_MANU_ID
, _MANUFACTURER_R
, _OUT_OF_PLCI
);
4284 plci_remove(plci
); /* after codec init, internal codec commands pending */
4289 dbug(1, dprintf("_Connect_R=0x%x/0x%x", req
, rc
));
4290 if ((global_req
== ASSIGN
) && (rc
!= ASSIGN_OK
))
4292 dbug(1, dprintf("No more IDs"));
4293 sendf(appl
, _CONNECT_R
| CONFIRM
, Id
& 0xffL
, Number
, "w", _OUT_OF_PLCI
);
4294 plci_remove(plci
); /* after codec init, internal codec commands pending */
4298 case PERM_COD_HOOK
: /* finished with Hook_Ind */
4302 dbug(1, dprintf("***Codec Connect_Pending A, Rc = 0x%x", rc
));
4303 plci
->internal_command
= PERM_COD_CONN_PEND
;
4306 case PERM_COD_ASSIGN
:
4307 dbug(1, dprintf("***Codec Assign A, Rc = 0x%x", rc
));
4308 if (rc
!= ASSIGN_OK
) break;
4309 sig_req(plci
, CALL_REQ
, 0);
4311 plci
->internal_command
= PERM_COD_CALL
;
4314 /* Null Call Reference Request pending */
4316 dbug(1, dprintf("NCR_FAC=0x%x/0x%x", req
, rc
));
4317 if (global_req
== ASSIGN
)
4319 if (rc
== ASSIGN_OK
)
4325 sendf(appl
, _INFO_R
| CONFIRM
, Id
& 0xf, Number
, "w", _WRONG_STATE
);
4326 appl
->NullCREnable
= false;
4330 else if (req
== NCR_FACILITY
)
4334 sendf(appl
, _INFO_R
| CONFIRM
, Id
& 0xf, Number
, "w", 0);
4338 sendf(appl
, _INFO_R
| CONFIRM
, Id
& 0xf, Number
, "w", _WRONG_STATE
);
4339 appl
->NullCREnable
= false;
4348 if (a
->ncci_state
[ncci
] == CONNECTED
)
4350 a
->ncci_state
[ncci
] = OUTG_DIS_PENDING
;
4351 cleanup_ncci_data(plci
, ncci
);
4352 nl_req_ncci(plci
, N_DISC
, (byte
)ncci
);
4359 if (plci
->State
== INC_DIS_PENDING
)
4361 sig_req(plci
, CALL_REQ
, 0);
4363 plci
->State
= OUTG_CON_PENDING
;
4367 case MWI_ACTIVATE_REQ_PEND
:
4368 case MWI_DEACTIVATE_REQ_PEND
:
4369 if (global_req
== ASSIGN
&& rc
== ASSIGN_OK
)
4371 dbug(1, dprintf("MWI_REQ assigned"));
4378 Info
= 0x2007; /* Illegal message parameter coding */
4379 dbug(1, dprintf("MWI_REQ invalid parameter"));
4383 Info
= 0x300B; /* not supported */
4384 dbug(1, dprintf("MWI_REQ not supported"));
4386 /* 0x3010: Request not allowed in this state */
4387 PUT_WORD(&SSparms
[4], 0x300E); /* SS not supported */
4390 if (plci
->internal_command
== MWI_ACTIVATE_REQ_PEND
)
4392 PUT_WORD(&SSparms
[1], S_MWI_ACTIVATE
);
4394 else PUT_WORD(&SSparms
[1], S_MWI_DEACTIVATE
);
4396 if (plci
->cr_enquiry
)
4399 _FACILITY_R
| CONFIRM
,
4402 "wws", Info
, (word
)3, SSparms
);
4403 if (rc
!= OK
) plci_remove(plci
);
4408 _FACILITY_R
| CONFIRM
,
4411 "wws", Info
, (word
)3, SSparms
);
4415 case CONF_BEGIN_REQ_PEND
:
4416 case CONF_ADD_REQ_PEND
:
4417 case CONF_SPLIT_REQ_PEND
:
4418 case CONF_DROP_REQ_PEND
:
4419 case CONF_ISOLATE_REQ_PEND
:
4420 case CONF_REATTACH_REQ_PEND
:
4421 dbug(1, dprintf("CONF_RC=0x%x/0x%x", req
, rc
));
4422 if ((plci
->internal_command
== CONF_ADD_REQ_PEND
) && (!plci
->relatedPTYPLCI
)) break;
4425 switch (plci
->internal_command
)
4427 case CONF_BEGIN_REQ_PEND
:
4428 SSparms
[1] = S_CONF_BEGIN
;
4430 case CONF_ADD_REQ_PEND
:
4431 SSparms
[1] = S_CONF_ADD
;
4432 rplci
= plci
->relatedPTYPLCI
;
4433 rId
= ((word
)rplci
->Id
<< 8) | rplci
->adapter
->Id
;
4435 case CONF_SPLIT_REQ_PEND
:
4436 SSparms
[1] = S_CONF_SPLIT
;
4438 case CONF_DROP_REQ_PEND
:
4439 SSparms
[1] = S_CONF_DROP
;
4441 case CONF_ISOLATE_REQ_PEND
:
4442 SSparms
[1] = S_CONF_ISOLATE
;
4444 case CONF_REATTACH_REQ_PEND
:
4445 SSparms
[1] = S_CONF_REATTACH
;
4451 Info
= 0x300E; /* not supported */
4452 plci
->relatedPTYPLCI
= NULL
;
4456 _FACILITY_R
| CONFIRM
,
4459 "wws", Info
, (word
)3, SSparms
);
4462 case VSWITCH_REQ_PEND
:
4465 if (plci
->relatedPTYPLCI
)
4467 plci
->relatedPTYPLCI
->vswitchstate
= 0;
4468 plci
->relatedPTYPLCI
->vsprot
= 0;
4469 plci
->relatedPTYPLCI
->vsprotdialect
= 0;
4471 plci
->vswitchstate
= 0;
4473 plci
->vsprotdialect
= 0;
4477 if (plci
->relatedPTYPLCI
&&
4478 plci
->vswitchstate
== 1 &&
4479 plci
->relatedPTYPLCI
->vswitchstate
== 3) /* join complete */
4480 plci
->vswitchstate
= 3;
4484 /* Call Deflection Request pending (SSCT) */
4486 SSparms
[1] = S_CALL_DEFLECTION
;
4489 Info
= 0x300E; /* not supported */
4490 plci
->appl
->CDEnable
= 0;
4492 sendf(plci
->appl
, _FACILITY_R
| CONFIRM
, Id
,
4493 plci
->number
, "wws", Info
, (word
)3, SSparms
);
4496 case RTP_CONNECT_B3_REQ_COMMAND_2
:
4499 ncci
= get_ncci(plci
, ch
, 0);
4500 Id
= (Id
& 0xffff) | (((dword
) ncci
) << 16);
4502 a
->ncci_state
[ncci
] = OUTG_CON_PENDING
;
4507 if (plci
->internal_command_queue
[0])
4509 (*(plci
->internal_command_queue
[0]))(Id
, plci
, rc
);
4510 if (plci
->internal_command
)
4515 next_internal_command(Id
, plci
);
4520 Id
= ((word
)plci
->Id
<< 8) | plci
->adapter
->Id
;
4521 if (plci
->tel
) Id
|= EXT_CONTROLLER
;
4523 switch (plci
->internal_command
)
4528 case START_L1_SIG_ASSIGN_PEND
:
4529 case REM_L1_SIG_ASSIGN_PEND
:
4530 if (global_req
== ASSIGN
)
4536 dbug(1, dprintf("***L1 Req rem PLCI"));
4537 plci
->internal_command
= 0;
4538 sig_req(plci
, REMOVE
, 0);
4543 /* Call Deflection Request pending, just no appl ptr assigned */
4545 SSparms
[1] = S_CALL_DEFLECTION
;
4548 Info
= 0x300E; /* not supported */
4550 for (i
= 0; i
< max_appl
; i
++)
4552 if (application
[i
].CDEnable
)
4554 if (!application
[i
].Id
) application
[i
].CDEnable
= 0;
4557 sendf(&application
[i
], _FACILITY_R
| CONFIRM
, Id
,
4558 plci
->number
, "wws", Info
, (word
)3, SSparms
);
4559 if (Info
) application
[i
].CDEnable
= 0;
4563 plci
->internal_command
= 0;
4566 case PERM_COD_HOOK
: /* finished with Hook_Ind */
4570 plci
->internal_command
= PERM_COD_CONN_PEND
;
4571 dbug(1, dprintf("***Codec Connect_Pending, Rc = 0x%x", rc
));
4574 case PERM_COD_ASSIGN
:
4575 dbug(1, dprintf("***Codec Assign, Rc = 0x%x", rc
));
4576 plci
->internal_command
= 0;
4577 if (rc
!= ASSIGN_OK
) break;
4578 plci
->internal_command
= PERM_COD_CALL
;
4579 sig_req(plci
, CALL_REQ
, 0);
4583 case LISTEN_SIG_ASSIGN_PEND
:
4584 if (rc
== ASSIGN_OK
)
4586 plci
->internal_command
= 0;
4587 dbug(1, dprintf("ListenCheck, new SIG_ID = 0x%x", plci
->Sig
.Id
));
4588 add_p(plci
, ESC
, "\x02\x18\x00"); /* support call waiting */
4589 sig_req(plci
, INDICATE_REQ
, 0);
4594 dbug(1, dprintf("ListenCheck failed (assignRc=0x%x)", rc
));
4602 if (global_req
== ASSIGN
)
4604 if (rc
== ASSIGN_OK
)
4606 sig_req(plci
, LAW_REQ
, 0);
4608 dbug(1, dprintf("Auto-Law assigned"));
4612 dbug(1, dprintf("Auto-Law assign failed"));
4613 a
->automatic_law
= 3;
4614 plci
->internal_command
= 0;
4615 a
->automatic_lawPLCI
= NULL
;
4619 else if (req
== LAW_REQ
&& rc
== OK
)
4621 dbug(1, dprintf("Auto-Law initiated"));
4622 a
->automatic_law
= 2;
4623 plci
->internal_command
= 0;
4627 dbug(1, dprintf("Auto-Law not supported"));
4628 a
->automatic_law
= 3;
4629 plci
->internal_command
= 0;
4630 sig_req(plci
, REMOVE
, 0);
4632 a
->automatic_lawPLCI
= NULL
;
4636 plci_remove_check(plci
);
4640 static void data_rc(PLCI
*plci
, byte ch
)
4643 DIVA_CAPI_ADAPTER
*a
;
4650 TransmitBufferFree(plci
->appl
, plci
->data_sent_ptr
);
4652 ncci
= a
->ch_ncci
[ch
];
4653 if (ncci
&& (a
->ncci_plci
[ncci
] == plci
->Id
))
4655 ncci_ptr
= &(a
->ncci
[ncci
]);
4656 dbug(1, dprintf("data_out=%d, data_pending=%d", ncci_ptr
->data_out
, ncci_ptr
->data_pending
));
4657 if (ncci_ptr
->data_pending
)
4659 data
= &(ncci_ptr
->DBuffer
[ncci_ptr
->data_out
]);
4660 if (!(data
->Flags
& 4) && a
->ncci_state
[ncci
])
4662 Id
= (((dword
)ncci
) << 16) | ((word
)plci
->Id
<< 8) | a
->Id
;
4663 if (plci
->tel
) Id
|= EXT_CONTROLLER
;
4664 sendf(plci
->appl
, _DATA_B3_R
| CONFIRM
, Id
, data
->Number
,
4665 "ww", data
->Handle
, 0);
4667 (ncci_ptr
->data_out
)++;
4668 if (ncci_ptr
->data_out
== MAX_DATA_B3
)
4669 ncci_ptr
->data_out
= 0;
4670 (ncci_ptr
->data_pending
)--;
4676 static void data_ack(PLCI
*plci
, byte ch
)
4679 DIVA_CAPI_ADAPTER
*a
;
4684 ncci
= a
->ch_ncci
[ch
];
4685 ncci_ptr
= &(a
->ncci
[ncci
]);
4686 if (ncci_ptr
->data_ack_pending
)
4688 if (a
->ncci_state
[ncci
] && (a
->ncci_plci
[ncci
] == plci
->Id
))
4690 Id
= (((dword
)ncci
) << 16) | ((word
)plci
->Id
<< 8) | a
->Id
;
4691 if (plci
->tel
) Id
|= EXT_CONTROLLER
;
4692 sendf(plci
->appl
, _DATA_B3_R
| CONFIRM
, Id
, ncci_ptr
->DataAck
[ncci_ptr
->data_ack_out
].Number
,
4693 "ww", ncci_ptr
->DataAck
[ncci_ptr
->data_ack_out
].Handle
, 0);
4695 (ncci_ptr
->data_ack_out
)++;
4696 if (ncci_ptr
->data_ack_out
== MAX_DATA_ACK
)
4697 ncci_ptr
->data_ack_out
= 0;
4698 (ncci_ptr
->data_ack_pending
)--;
4702 static void sig_ind(PLCI
*plci
)
4711 DIVA_CAPI_ADAPTER
*a
;
4712 API_PARSE saved_parms
[MAX_MSG_PARMS
+ 1];
4713 #define MAXPARMSIDS 31
4714 byte
*parms
[MAXPARMSIDS
];
4716 byte
*multi_fac_parms
[MAX_MULTI_IE
];
4717 byte
*multi_pi_parms
[MAX_MULTI_IE
];
4718 byte
*multi_ssext_parms
[MAX_MULTI_IE
];
4719 byte
*multi_CiPN_parms
[MAX_MULTI_IE
];
4721 byte
*multi_vswitch_parms
[MAX_MULTI_IE
];
4728 byte
*esc_profile
= "";
4732 byte chi
[] = "\x02\x18\x01";
4733 byte voice_cai
[] = "\x06\x14\x00\x00\x00\x00\x08";
4734 byte resume_cau
[] = "\x05\x05\x00\x02\x00\x00";
4735 /* ESC_MSGTYPE must be the last but one message, a new IE has to be */
4736 /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */
4737 /* SMSG is situated at the end because its 0 (for compatibility reasons */
4738 /* (see Info_Mask Bit 4, first IE. then the message type) */
4739 static const word parms_id
[] =
4740 {MAXPARMSIDS
, CPN
, 0xff, DSA
, OSA
, BC
, LLC
, HLC
, ESC_CAUSE
, DSP
, DT
, CHA
,
4741 UUI
, CONG_RR
, CONG_RNR
, ESC_CHI
, KEY
, CHI
, CAU
, ESC_LAW
,
4742 RDN
, RDX
, CONN_NR
, RIN
, NI
, CAI
, ESC_CR
,
4743 CST
, ESC_PROFILE
, 0xff, ESC_MSGTYPE
, SMSG
};
4744 /* 14 FTY repl by ESC_CHI */
4745 /* 18 PI repl by ESC_LAW */
4746 /* removed OAD changed to 0xff for future use, OAD is multiIE now */
4747 static const word multi_fac_id
[] = {1, FTY
};
4748 static const word multi_pi_id
[] = {1, PI
};
4749 static const word multi_CiPN_id
[] = {1, OAD
};
4750 static const word multi_ssext_id
[] = {1, ESC_SSEXT
};
4752 static const word multi_vswitch_id
[] = {1, ESC_VSWITCH
};
4756 byte SS_Ind
[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
4757 byte CF_Ind
[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
4758 byte Interr_Err_Ind
[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
4759 byte CONF_Ind
[] = "\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00";
4760 byte force_mt_info
= false;
4766 Id
= ((word
)plci
->Id
<< 8) | a
->Id
;
4767 PUT_WORD(&SS_Ind
[4], 0x0000);
4769 if (plci
->sig_remove_id
)
4771 plci
->Sig
.RNR
= 2; /* discard */
4772 dbug(1, dprintf("SIG discard while remove pending"));
4775 if (plci
->tel
&& plci
->SuppState
!= CALL_HELD
) Id
|= EXT_CONTROLLER
;
4776 dbug(1, dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d",
4777 Id
, plci
->Id
, plci
->tel
, plci
->State
, plci
->channels
, plci
->hangup_flow_ctrl_timer
));
4778 if (plci
->Sig
.Ind
== CALL_HOLD_ACK
&& plci
->channels
)
4783 if (plci
->Sig
.Ind
== HANGUP
&& plci
->channels
)
4786 plci
->hangup_flow_ctrl_timer
++;
4787 /* recover the network layer after timeout */
4788 if (plci
->hangup_flow_ctrl_timer
== 100)
4790 dbug(1, dprintf("Exceptional disc"));
4792 plci
->hangup_flow_ctrl_timer
= 0;
4793 for (ncci
= 1; ncci
< MAX_NCCI
+ 1; ncci
++)
4795 if (a
->ncci_plci
[ncci
] == plci
->Id
)
4797 cleanup_ncci_data(plci
, ncci
);
4798 if (plci
->channels
)plci
->channels
--;
4800 sendf(plci
->appl
, _DISCONNECT_B3_I
, (((dword
) ncci
) << 16) | Id
, 0, "ws", 0, "");
4804 sendf(plci
->appl
, _DISCONNECT_I
, Id
, 0, "w", 0);
4811 /* do first parse the info with no OAD in, because OAD will be converted */
4812 /* first the multiple facility IE, then mult. progress ind. */
4813 /* then the parameters for the info_ind + conn_ind */
4814 IndParse(plci
, multi_fac_id
, multi_fac_parms
, MAX_MULTI_IE
);
4815 IndParse(plci
, multi_pi_id
, multi_pi_parms
, MAX_MULTI_IE
);
4816 IndParse(plci
, multi_ssext_id
, multi_ssext_parms
, MAX_MULTI_IE
);
4818 IndParse(plci
, multi_vswitch_id
, multi_vswitch_parms
, MAX_MULTI_IE
);
4820 IndParse(plci
, parms_id
, parms
, 0);
4821 IndParse(plci
, multi_CiPN_id
, multi_CiPN_parms
, MAX_MULTI_IE
);
4822 esc_chi
= parms
[14];
4823 esc_law
= parms
[18];
4824 pty_cai
= parms
[24];
4826 esc_profile
= parms
[27];
4827 if (esc_cr
[0] && plci
)
4829 if (plci
->cr_enquiry
&& plci
->appl
)
4831 plci
->cr_enquiry
= false;
4834 /* b = total length */
4835 /* b = indication type */
4836 /* b = length of all IEs */
4838 /* S = IE1 length + cont. */
4840 /* S = IE2 length + cont. */
4845 "dwbbbbSbS", _DI_MANU_ID
, plci
->m_command
,
4846 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
);
4849 /* create the additional info structure */
4850 add_i
[1] = parms
[15]; /* KEY of additional info */
4851 add_i
[2] = parms
[11]; /* UUI of additional info */
4852 ai_len
= AddInfo(add_i
, multi_fac_parms
, esc_chi
, facility
);
4854 /* the ESC_LAW indicates if u-Law or a-Law is actually used by the card */
4855 /* indication returns by the card if requested by the function */
4856 /* AutomaticLaw() after driver init */
4857 if (a
->automatic_law
< 4)
4861 dbug(0, dprintf("u-Law selected"));
4865 dbug(0, dprintf("a-Law selected"));
4868 a
->automatic_law
= 4;
4869 if (plci
== a
->automatic_lawPLCI
) {
4870 plci
->internal_command
= 0;
4871 sig_req(plci
, REMOVE
, 0);
4873 a
->automatic_lawPLCI
= NULL
;
4878 dbug(1, dprintf("[%06x] CardProfile: %lx %lx %lx %lx %lx",
4879 UnMapController(a
->Id
), GET_DWORD(&esc_profile
[6]),
4880 GET_DWORD(&esc_profile
[10]), GET_DWORD(&esc_profile
[14]),
4881 GET_DWORD(&esc_profile
[18]), GET_DWORD(&esc_profile
[46])));
4883 a
->profile
.Global_Options
&= 0x000000ffL
;
4884 a
->profile
.B1_Protocols
&= 0x000003ffL
;
4885 a
->profile
.B2_Protocols
&= 0x00001fdfL
;
4886 a
->profile
.B3_Protocols
&= 0x000000b7L
;
4888 a
->profile
.Global_Options
&= GET_DWORD(&esc_profile
[6]) |
4889 GL_BCHANNEL_OPERATION_SUPPORTED
;
4890 a
->profile
.B1_Protocols
&= GET_DWORD(&esc_profile
[10]);
4891 a
->profile
.B2_Protocols
&= GET_DWORD(&esc_profile
[14]);
4892 a
->profile
.B3_Protocols
&= GET_DWORD(&esc_profile
[18]);
4893 a
->manufacturer_features
= GET_DWORD(&esc_profile
[46]);
4894 a
->man_profile
.private_options
= 0;
4896 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_ECHO_CANCELLER
)
4898 a
->man_profile
.private_options
|= 1L << PRIVATE_ECHO_CANCELLER
;
4899 a
->profile
.Global_Options
|= GL_ECHO_CANCELLER_SUPPORTED
;
4903 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_RTP
)
4904 a
->man_profile
.private_options
|= 1L << PRIVATE_RTP
;
4905 a
->man_profile
.rtp_primary_payloads
= GET_DWORD(&esc_profile
[50]);
4906 a
->man_profile
.rtp_additional_payloads
= GET_DWORD(&esc_profile
[54]);
4909 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_T38
)
4910 a
->man_profile
.private_options
|= 1L << PRIVATE_T38
;
4913 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD
)
4914 a
->man_profile
.private_options
|= 1L << PRIVATE_FAX_SUB_SEP_PWD
;
4917 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_V18
)
4918 a
->man_profile
.private_options
|= 1L << PRIVATE_V18
;
4921 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_DTMF_TONE
)
4922 a
->man_profile
.private_options
|= 1L << PRIVATE_DTMF_TONE
;
4925 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_PIAFS
)
4926 a
->man_profile
.private_options
|= 1L << PRIVATE_PIAFS
;
4929 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
4930 a
->man_profile
.private_options
|= 1L << PRIVATE_FAX_PAPER_FORMATS
;
4933 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_VOWN
)
4934 a
->man_profile
.private_options
|= 1L << PRIVATE_VOWN
;
4937 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_NONSTANDARD
)
4938 a
->man_profile
.private_options
|= 1L << PRIVATE_FAX_NONSTANDARD
;
4943 a
->profile
.Global_Options
&= 0x0000007fL
;
4944 a
->profile
.B1_Protocols
&= 0x000003dfL
;
4945 a
->profile
.B2_Protocols
&= 0x00001adfL
;
4946 a
->profile
.B3_Protocols
&= 0x000000b7L
;
4947 a
->manufacturer_features
&= MANUFACTURER_FEATURE_HARDDTMF
;
4949 if (a
->manufacturer_features
& (MANUFACTURER_FEATURE_HARDDTMF
|
4950 MANUFACTURER_FEATURE_SOFTDTMF_SEND
| MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
))
4952 a
->profile
.Global_Options
|= GL_DTMF_SUPPORTED
;
4954 a
->manufacturer_features
&= ~MANUFACTURER_FEATURE_OOB_CHANNEL
;
4955 dbug(1, dprintf("[%06x] Profile: %lx %lx %lx %lx %lx",
4956 UnMapController(a
->Id
), a
->profile
.Global_Options
,
4957 a
->profile
.B1_Protocols
, a
->profile
.B2_Protocols
,
4958 a
->profile
.B3_Protocols
, a
->manufacturer_features
));
4960 /* codec plci for the handset/hook state support is just an internal id */
4961 if (plci
!= a
->AdvCodecPLCI
)
4963 force_mt_info
= SendMultiIE(plci
, Id
, multi_fac_parms
, FTY
, 0x20, 0);
4964 force_mt_info
|= SendMultiIE(plci
, Id
, multi_pi_parms
, PI
, 0x210, 0);
4965 SendSSExtInd(NULL
, plci
, Id
, multi_ssext_parms
);
4966 SendInfo(plci
, Id
, parms
, force_mt_info
);
4968 VSwitchReqInd(plci
, Id
, multi_vswitch_parms
);
4972 /* switch the codec to the b-channel */
4973 if (esc_chi
[0] && plci
&& !plci
->SuppState
) {
4974 plci
->b_channel
= esc_chi
[esc_chi
[0]]&0x1f;
4975 mixer_set_bchannel_id_esc(plci
, plci
->b_channel
);
4976 dbug(1, dprintf("storeChannel=0x%x", plci
->b_channel
));
4977 if (plci
->tel
== ADV_VOICE
&& plci
->appl
) {
4978 SetVoiceChannel(a
->AdvCodecPLCI
, esc_chi
, a
);
4982 if (plci
->appl
) plci
->appl
->Number
++;
4984 switch (plci
->Sig
.Ind
) {
4985 /* Response to Get_Supported_Services request */
4987 dbug(1, dprintf("S_Supported"));
4988 if (!plci
->appl
) break;
4989 if (pty_cai
[0] == 4)
4991 PUT_DWORD(&CF_Ind
[6], GET_DWORD(&pty_cai
[1]));
4995 PUT_DWORD(&CF_Ind
[6], MASK_TERMINAL_PORTABILITY
| MASK_HOLD_RETRIEVE
);
4997 PUT_WORD(&CF_Ind
[1], 0);
4998 PUT_WORD(&CF_Ind
[4], 0);
4999 sendf(plci
->appl
, _FACILITY_R
| CONFIRM
, Id
& 0x7, plci
->number
, "wws", 0, 3, CF_Ind
);
5003 /* Supplementary Service rejected */
5005 dbug(1, dprintf("S_Reject=0x%x", pty_cai
[5]));
5006 if (!pty_cai
[0]) break;
5011 case THREE_PTY_BEGIN
:
5012 if (!plci
->relatedPTYPLCI
) break;
5013 tplci
= plci
->relatedPTYPLCI
;
5014 rId
= ((word
)tplci
->Id
<< 8) | tplci
->adapter
->Id
;
5015 if (tplci
->tel
) rId
|= EXT_CONTROLLER
;
5016 if (pty_cai
[5] == ECT_EXECUTE
)
5018 PUT_WORD(&SS_Ind
[1], S_ECT
);
5020 plci
->vswitchstate
= 0;
5021 plci
->relatedPTYPLCI
->vswitchstate
= 0;
5026 PUT_WORD(&SS_Ind
[1], pty_cai
[5] + 3);
5028 if (pty_cai
[2] != 0xff)
5030 PUT_WORD(&SS_Ind
[4], 0x3600 | (word
)pty_cai
[2]);
5034 PUT_WORD(&SS_Ind
[4], 0x300E);
5036 plci
->relatedPTYPLCI
= NULL
;
5038 sendf(tplci
->appl
, _FACILITY_I
, rId
, 0, "ws", 3, SS_Ind
);
5041 case CALL_DEFLECTION
:
5042 if (pty_cai
[2] != 0xff)
5044 PUT_WORD(&SS_Ind
[4], 0x3600 | (word
)pty_cai
[2]);
5048 PUT_WORD(&SS_Ind
[4], 0x300E);
5050 PUT_WORD(&SS_Ind
[1], pty_cai
[5]);
5051 for (i
= 0; i
< max_appl
; i
++)
5053 if (application
[i
].CDEnable
)
5055 if (application
[i
].Id
) sendf(&application
[i
], _FACILITY_I
, Id
, 0, "ws", 3, SS_Ind
);
5056 application
[i
].CDEnable
= false;
5061 case DEACTIVATION_DIVERSION
:
5062 case ACTIVATION_DIVERSION
:
5063 case DIVERSION_INTERROGATE_CFU
:
5064 case DIVERSION_INTERROGATE_CFB
:
5065 case DIVERSION_INTERROGATE_CFNR
:
5066 case DIVERSION_INTERROGATE_NUM
:
5068 case CCBS_DEACTIVATE
:
5069 case CCBS_INTERROGATE
:
5070 if (!plci
->appl
) break;
5071 if (pty_cai
[2] != 0xff)
5073 PUT_WORD(&Interr_Err_Ind
[4], 0x3600 | (word
)pty_cai
[2]);
5077 PUT_WORD(&Interr_Err_Ind
[4], 0x300E);
5081 case DEACTIVATION_DIVERSION
:
5082 dbug(1, dprintf("Deact_Div"));
5083 Interr_Err_Ind
[0] = 0x9;
5084 Interr_Err_Ind
[3] = 0x6;
5085 PUT_WORD(&Interr_Err_Ind
[1], S_CALL_FORWARDING_STOP
);
5087 case ACTIVATION_DIVERSION
:
5088 dbug(1, dprintf("Act_Div"));
5089 Interr_Err_Ind
[0] = 0x9;
5090 Interr_Err_Ind
[3] = 0x6;
5091 PUT_WORD(&Interr_Err_Ind
[1], S_CALL_FORWARDING_START
);
5093 case DIVERSION_INTERROGATE_CFU
:
5094 case DIVERSION_INTERROGATE_CFB
:
5095 case DIVERSION_INTERROGATE_CFNR
:
5096 dbug(1, dprintf("Interr_Div"));
5097 Interr_Err_Ind
[0] = 0xa;
5098 Interr_Err_Ind
[3] = 0x7;
5099 PUT_WORD(&Interr_Err_Ind
[1], S_INTERROGATE_DIVERSION
);
5101 case DIVERSION_INTERROGATE_NUM
:
5102 dbug(1, dprintf("Interr_Num"));
5103 Interr_Err_Ind
[0] = 0xa;
5104 Interr_Err_Ind
[3] = 0x7;
5105 PUT_WORD(&Interr_Err_Ind
[1], S_INTERROGATE_NUMBERS
);
5108 dbug(1, dprintf("CCBS Request"));
5109 Interr_Err_Ind
[0] = 0xd;
5110 Interr_Err_Ind
[3] = 0xa;
5111 PUT_WORD(&Interr_Err_Ind
[1], S_CCBS_REQUEST
);
5113 case CCBS_DEACTIVATE
:
5114 dbug(1, dprintf("CCBS Deactivate"));
5115 Interr_Err_Ind
[0] = 0x9;
5116 Interr_Err_Ind
[3] = 0x6;
5117 PUT_WORD(&Interr_Err_Ind
[1], S_CCBS_DEACTIVATE
);
5119 case CCBS_INTERROGATE
:
5120 dbug(1, dprintf("CCBS Interrogate"));
5121 Interr_Err_Ind
[0] = 0xb;
5122 Interr_Err_Ind
[3] = 0x8;
5123 PUT_WORD(&Interr_Err_Ind
[1], S_CCBS_INTERROGATE
);
5126 PUT_DWORD(&Interr_Err_Ind
[6], plci
->appl
->S_Handle
);
5127 sendf(plci
->appl
, _FACILITY_I
, Id
& 0x7, 0, "ws", 3, Interr_Err_Ind
);
5130 case ACTIVATION_MWI
:
5131 case DEACTIVATION_MWI
:
5132 if (pty_cai
[5] == ACTIVATION_MWI
)
5134 PUT_WORD(&SS_Ind
[1], S_MWI_ACTIVATE
);
5136 else PUT_WORD(&SS_Ind
[1], S_MWI_DEACTIVATE
);
5138 if (pty_cai
[2] != 0xff)
5140 PUT_WORD(&SS_Ind
[4], 0x3600 | (word
)pty_cai
[2]);
5144 PUT_WORD(&SS_Ind
[4], 0x300E);
5147 if (plci
->cr_enquiry
)
5149 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xf, 0, "ws", 3, SS_Ind
);
5154 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", 3, SS_Ind
);
5157 case CONF_ADD
: /* ERROR */
5167 PUT_WORD(&CONF_Ind
[1], S_CONF_BEGIN
);
5173 PUT_WORD(&CONF_Ind
[1], S_CONF_DROP
);
5174 plci
->ptyState
= CONNECTED
;
5179 PUT_WORD(&CONF_Ind
[1], S_CONF_ISOLATE
);
5180 plci
->ptyState
= CONNECTED
;
5185 PUT_WORD(&CONF_Ind
[1], S_CONF_REATTACH
);
5186 plci
->ptyState
= CONNECTED
;
5189 PUT_WORD(&CONF_Ind
[1], S_CONF_ADD
);
5190 plci
->relatedPTYPLCI
= NULL
;
5191 tplci
= plci
->relatedPTYPLCI
;
5192 if (tplci
) tplci
->ptyState
= CONNECTED
;
5193 plci
->ptyState
= CONNECTED
;
5197 if (pty_cai
[2] != 0xff)
5199 PUT_WORD(&CONF_Ind
[4], 0x3600 | (word
)pty_cai
[2]);
5203 PUT_WORD(&CONF_Ind
[4], 0x3303); /* Time-out: network did not respond
5204 within the required time */
5207 PUT_DWORD(&CONF_Ind
[6], 0x0);
5208 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", 3, CONF_Ind
);
5213 /* Supplementary Service indicates success */
5215 dbug(1, dprintf("Service_Ind"));
5216 PUT_WORD(&CF_Ind
[4], 0);
5220 case THREE_PTY_BEGIN
:
5222 if (!plci
->relatedPTYPLCI
) break;
5223 tplci
= plci
->relatedPTYPLCI
;
5224 rId
= ((word
)tplci
->Id
<< 8) | tplci
->adapter
->Id
;
5225 if (tplci
->tel
) rId
|= EXT_CONTROLLER
;
5226 if (pty_cai
[5] == ECT_EXECUTE
)
5228 PUT_WORD(&SS_Ind
[1], S_ECT
);
5230 if (plci
->vswitchstate
!= 3)
5233 plci
->ptyState
= IDLE
;
5234 plci
->relatedPTYPLCI
= NULL
;
5239 dbug(1, dprintf("ECT OK"));
5240 sendf(tplci
->appl
, _FACILITY_I
, rId
, 0, "ws", 3, SS_Ind
);
5247 switch (plci
->ptyState
)
5250 plci
->ptyState
= CONNECTED
;
5251 dbug(1, dprintf("3PTY ON"));
5255 plci
->ptyState
= IDLE
;
5256 plci
->relatedPTYPLCI
= NULL
;
5258 dbug(1, dprintf("3PTY OFF"));
5261 PUT_WORD(&SS_Ind
[1], pty_cai
[5] + 3);
5262 sendf(tplci
->appl
, _FACILITY_I
, rId
, 0, "ws", 3, SS_Ind
);
5266 case CALL_DEFLECTION
:
5267 PUT_WORD(&SS_Ind
[1], pty_cai
[5]);
5268 for (i
= 0; i
< max_appl
; i
++)
5270 if (application
[i
].CDEnable
)
5272 if (application
[i
].Id
) sendf(&application
[i
], _FACILITY_I
, Id
, 0, "ws", 3, SS_Ind
);
5273 application
[i
].CDEnable
= false;
5278 case DEACTIVATION_DIVERSION
:
5279 case ACTIVATION_DIVERSION
:
5280 if (!plci
->appl
) break;
5281 PUT_WORD(&CF_Ind
[1], pty_cai
[5] + 2);
5282 PUT_DWORD(&CF_Ind
[6], plci
->appl
->S_Handle
);
5283 sendf(plci
->appl
, _FACILITY_I
, Id
& 0x7, 0, "ws", 3, CF_Ind
);
5287 case DIVERSION_INTERROGATE_CFU
:
5288 case DIVERSION_INTERROGATE_CFB
:
5289 case DIVERSION_INTERROGATE_CFNR
:
5290 case DIVERSION_INTERROGATE_NUM
:
5292 case CCBS_DEACTIVATE
:
5293 case CCBS_INTERROGATE
:
5294 if (!plci
->appl
) break;
5297 case DIVERSION_INTERROGATE_CFU
:
5298 case DIVERSION_INTERROGATE_CFB
:
5299 case DIVERSION_INTERROGATE_CFNR
:
5300 dbug(1, dprintf("Interr_Div"));
5301 PUT_WORD(&pty_cai
[1], S_INTERROGATE_DIVERSION
);
5302 pty_cai
[3] = pty_cai
[0] - 3; /* Supplementary Service-specific parameter len */
5304 case DIVERSION_INTERROGATE_NUM
:
5305 dbug(1, dprintf("Interr_Num"));
5306 PUT_WORD(&pty_cai
[1], S_INTERROGATE_NUMBERS
);
5307 pty_cai
[3] = pty_cai
[0] - 3; /* Supplementary Service-specific parameter len */
5310 dbug(1, dprintf("CCBS Request"));
5311 PUT_WORD(&pty_cai
[1], S_CCBS_REQUEST
);
5312 pty_cai
[3] = pty_cai
[0] - 3; /* Supplementary Service-specific parameter len */
5314 case CCBS_DEACTIVATE
:
5315 dbug(1, dprintf("CCBS Deactivate"));
5316 PUT_WORD(&pty_cai
[1], S_CCBS_DEACTIVATE
);
5317 pty_cai
[3] = pty_cai
[0] - 3; /* Supplementary Service-specific parameter len */
5319 case CCBS_INTERROGATE
:
5320 dbug(1, dprintf("CCBS Interrogate"));
5321 PUT_WORD(&pty_cai
[1], S_CCBS_INTERROGATE
);
5322 pty_cai
[3] = pty_cai
[0] - 3; /* Supplementary Service-specific parameter len */
5325 PUT_WORD(&pty_cai
[4], 0); /* Supplementary Service Reason */
5326 PUT_DWORD(&pty_cai
[6], plci
->appl
->S_Handle
);
5327 sendf(plci
->appl
, _FACILITY_I
, Id
& 0x7, 0, "wS", 3, pty_cai
);
5331 case ACTIVATION_MWI
:
5332 case DEACTIVATION_MWI
:
5333 if (pty_cai
[5] == ACTIVATION_MWI
)
5335 PUT_WORD(&SS_Ind
[1], S_MWI_ACTIVATE
);
5337 else PUT_WORD(&SS_Ind
[1], S_MWI_DEACTIVATE
);
5338 if (plci
->cr_enquiry
)
5340 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xf, 0, "ws", 3, SS_Ind
);
5345 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", 3, SS_Ind
);
5348 case MWI_INDICATION
:
5349 if (pty_cai
[0] >= 0x12)
5351 PUT_WORD(&pty_cai
[3], S_MWI_INDICATE
);
5352 pty_cai
[2] = pty_cai
[0] - 2; /* len Parameter */
5353 pty_cai
[5] = pty_cai
[0] - 5; /* Supplementary Service-specific parameter len */
5354 if (plci
->appl
&& (a
->Notification_Mask
[plci
->appl
->Id
- 1] & SMASK_MWI
))
5356 if (plci
->internal_command
== GET_MWI_STATE
) /* result on Message Waiting Listen */
5358 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xf, 0, "wS", 3, &pty_cai
[2]);
5362 else sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "wS", 3, &pty_cai
[2]);
5367 for (i
= 0; i
< max_appl
; i
++)
5369 if (a
->Notification_Mask
[i
]&SMASK_MWI
)
5371 sendf(&application
[i
], _FACILITY_I
, Id
& 0x7, 0, "wS", 3, &pty_cai
[2]);
5379 facility
[2] = 0; /* returncode */
5381 else facility
[2] = 0xff;
5386 facility
[2] = 0xff; /* returncode */
5389 facility
[1] = MWI_RESPONSE
; /* Function */
5390 add_p(plci
, CAI
, facility
);
5391 add_p(plci
, ESC
, multi_ssext_parms
[0]); /* remembered parameter -> only one possible */
5392 sig_req(plci
, S_SERVICE
, 0);
5395 next_internal_command(Id
, plci
);
5397 case CONF_ADD
: /* OK */
5402 case CONF_PARTYDISC
:
5408 PUT_WORD(&CONF_Ind
[1], S_CONF_BEGIN
);
5409 if (pty_cai
[0] == 6)
5412 PUT_DWORD(&CONF_Ind
[6], d
); /* PartyID */
5416 PUT_DWORD(&CONF_Ind
[6], 0x0);
5420 PUT_WORD(&CONF_Ind
[1], S_CONF_ISOLATE
);
5425 PUT_WORD(&CONF_Ind
[1], S_CONF_REATTACH
);
5430 PUT_WORD(&CONF_Ind
[1], S_CONF_DROP
);
5435 PUT_WORD(&CONF_Ind
[1], S_CONF_ADD
);
5437 PUT_DWORD(&CONF_Ind
[6], d
); /* PartyID */
5438 tplci
= plci
->relatedPTYPLCI
;
5439 if (tplci
) tplci
->ptyState
= CONNECTED
;
5441 case CONF_PARTYDISC
:
5444 PUT_WORD(&CONF_Ind
[1], S_CONF_PARTYDISC
);
5446 PUT_DWORD(&CONF_Ind
[4], d
); /* PartyID */
5449 plci
->ptyState
= CONNECTED
;
5450 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", 3, CONF_Ind
);
5452 case CCBS_INFO_RETAIN
:
5453 case CCBS_ERASECALLLINKAGEID
:
5454 case CCBS_STOP_ALERTING
:
5459 case CCBS_INFO_RETAIN
:
5460 PUT_WORD(&CONF_Ind
[1], S_CCBS_INFO_RETAIN
);
5462 case CCBS_STOP_ALERTING
:
5463 PUT_WORD(&CONF_Ind
[1], S_CCBS_STOP_ALERTING
);
5465 case CCBS_ERASECALLLINKAGEID
:
5466 PUT_WORD(&CONF_Ind
[1], S_CCBS_ERASECALLLINKAGEID
);
5474 PUT_WORD(&CONF_Ind
[4], w
); /* PartyID */
5476 if (plci
->appl
&& (a
->Notification_Mask
[plci
->appl
->Id
- 1] & SMASK_CCBS
))
5478 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", 3, CONF_Ind
);
5482 for (i
= 0; i
< max_appl
; i
++)
5483 if (a
->Notification_Mask
[i
] & SMASK_CCBS
)
5484 sendf(&application
[i
], _FACILITY_I
, Id
& 0x7, 0, "ws", 3, CONF_Ind
);
5493 i
= _L3_CAUSE
| cau
[2];
5494 if (cau
[2] == 0) i
= 0x3603;
5500 PUT_WORD(&SS_Ind
[1], S_HOLD
);
5501 PUT_WORD(&SS_Ind
[4], i
);
5502 if (plci
->SuppState
== HOLD_REQUEST
)
5504 plci
->SuppState
= IDLE
;
5505 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", 3, SS_Ind
);
5510 if (plci
->SuppState
== HOLD_REQUEST
)
5512 plci
->SuppState
= CALL_HELD
;
5513 CodecIdCheck(a
, plci
);
5514 start_internal_command(Id
, plci
, hold_save_command
);
5518 case CALL_RETRIEVE_REJ
:
5522 i
= _L3_CAUSE
| cau
[2];
5523 if (cau
[2] == 0) i
= 0x3603;
5529 PUT_WORD(&SS_Ind
[1], S_RETRIEVE
);
5530 PUT_WORD(&SS_Ind
[4], i
);
5531 if (plci
->SuppState
== RETRIEVE_REQUEST
)
5533 plci
->SuppState
= CALL_HELD
;
5534 CodecIdCheck(a
, plci
);
5535 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", 3, SS_Ind
);
5539 case CALL_RETRIEVE_ACK
:
5540 PUT_WORD(&SS_Ind
[1], S_RETRIEVE
);
5541 if (plci
->SuppState
== RETRIEVE_REQUEST
)
5543 plci
->SuppState
= IDLE
;
5544 plci
->call_dir
|= CALL_DIR_FORCE_OUTG_NL
;
5545 plci
->b_channel
= esc_chi
[esc_chi
[0]]&0x1f;
5548 mixer_set_bchannel_id_esc(plci
, plci
->b_channel
);
5549 dbug(1, dprintf("RetrChannel=0x%x", plci
->b_channel
));
5550 SetVoiceChannel(a
->AdvCodecPLCI
, esc_chi
, a
);
5551 if (plci
->B2_prot
== B2_TRANSPARENT
&& plci
->B3_prot
== B3_TRANSPARENT
)
5553 dbug(1, dprintf("Get B-ch"));
5554 start_internal_command(Id
, plci
, retrieve_restore_command
);
5557 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", 3, SS_Ind
);
5560 start_internal_command(Id
, plci
, retrieve_restore_command
);
5565 if (plci
->State
!= LISTENING
) {
5566 sig_req(plci
, HANGUP
, 0);
5570 cip
= find_cip(a
, parms
[4], parms
[6]);
5571 cip_mask
= 1L << cip
;
5572 dbug(1, dprintf("cip=%d,cip_mask=%lx", cip
, cip_mask
));
5573 bitmap_zero(plci
->c_ind_mask_table
, MAX_APPL
);
5574 if (!remove_started
&& !a
->adapter_disabled
)
5576 group_optimization(a
, plci
);
5577 for_each_set_bit(i
, plci
->group_optimization_mask_table
, max_appl
) {
5578 if (application
[i
].Id
5579 && (a
->CIP_Mask
[i
] & 1 || a
->CIP_Mask
[i
] & cip_mask
)
5580 && CPN_filter_ok(parms
[0], a
, i
)) {
5581 dbug(1, dprintf("storedcip_mask[%d]=0x%lx", i
, a
->CIP_Mask
[i
]));
5582 __set_bit(i
, plci
->c_ind_mask_table
);
5583 dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL
, plci
->c_ind_mask_table
));
5584 plci
->State
= INC_CON_PENDING
;
5585 plci
->call_dir
= (plci
->call_dir
& ~(CALL_DIR_OUT
| CALL_DIR_ORIGINATE
)) |
5586 CALL_DIR_IN
| CALL_DIR_ANSWER
;
5588 plci
->b_channel
= esc_chi
[esc_chi
[0]] & 0x1f;
5589 mixer_set_bchannel_id_esc(plci
, plci
->b_channel
);
5591 /* if a listen on the ext controller is done, check if hook states */
5592 /* are supported or if just a on board codec must be activated */
5593 if (a
->codec_listen
[i
] && !a
->AdvSignalPLCI
) {
5594 if (a
->profile
.Global_Options
& HANDSET
)
5595 plci
->tel
= ADV_VOICE
;
5596 else if (a
->profile
.Global_Options
& ON_BOARD_CODEC
)
5598 if (plci
->tel
) Id
|= EXT_CONTROLLER
;
5599 a
->codec_listen
[i
] = plci
;
5602 sendf(&application
[i
], _CONNECT_I
, Id
, 0,
5603 "wSSSSSSSbSSSSS", cip
, /* CIP */
5604 parms
[0], /* CalledPartyNumber */
5605 multi_CiPN_parms
[0], /* CallingPartyNumber */
5606 parms
[2], /* CalledPartySubad */
5607 parms
[3], /* CallingPartySubad */
5608 parms
[4], /* BearerCapability */
5609 parms
[5], /* LowLC */
5610 parms
[6], /* HighLC */
5611 ai_len
, /* nested struct add_i */
5612 add_i
[0], /* B channel info */
5613 add_i
[1], /* keypad facility */
5614 add_i
[2], /* user user data */
5615 add_i
[3], /* nested facility */
5616 multi_CiPN_parms
[1] /* second CiPN(SCR) */
5618 SendSSExtInd(&application
[i
],
5622 SendSetupInfo(&application
[i
],
5626 SendMultiIE(plci
, Id
, multi_pi_parms
, PI
, 0x210, true));
5629 dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL
, plci
->c_ind_mask_table
));
5631 if (bitmap_empty(plci
->c_ind_mask_table
, MAX_APPL
)) {
5632 sig_req(plci
, HANGUP
, 0);
5636 plci
->notifiedcall
= 0;
5641 case CALL_PEND_NOTIFY
:
5642 plci
->notifiedcall
= 1;
5648 if (plci
->State
== ADVANCED_VOICE_SIG
|| plci
->State
== ADVANCED_VOICE_NOSIG
)
5650 if (plci
->internal_command
== PERM_COD_CONN_PEND
)
5652 if (plci
->State
== ADVANCED_VOICE_NOSIG
)
5654 dbug(1, dprintf("***Codec OK"));
5655 if (a
->AdvSignalPLCI
)
5657 tplci
= a
->AdvSignalPLCI
;
5658 if (tplci
->spoofed_msg
)
5660 dbug(1, dprintf("***Spoofed Msg(0x%x)", tplci
->spoofed_msg
));
5662 tplci
->internal_command
= 0;
5663 x_Id
= ((word
)tplci
->Id
<< 8) | tplci
->adapter
->Id
| 0x80;
5664 switch (tplci
->spoofed_msg
)
5667 tplci
->command
= _CONNECT_I
| RESPONSE
;
5668 api_load_msg(&tplci
->saved_msg
, saved_parms
);
5669 add_b1(tplci
, &saved_parms
[1], 0, tplci
->B1_facilities
);
5670 if (tplci
->adapter
->Info_Mask
[tplci
->appl
->Id
- 1] & 0x200)
5672 /* early B3 connect (CIP mask bit 9) no release after a disc */
5673 add_p(tplci
, LLI
, "\x01\x01");
5675 add_s(tplci
, CONN_NR
, &saved_parms
[2]);
5676 add_s(tplci
, LLC
, &saved_parms
[4]);
5677 add_ai(tplci
, &saved_parms
[5]);
5678 tplci
->State
= INC_CON_ACCEPT
;
5679 sig_req(tplci
, CALL_RES
, 0);
5683 case AWAITING_SELECT_B
:
5684 dbug(1, dprintf("Select_B continue"));
5685 start_internal_command(x_Id
, tplci
, select_b_command
);
5688 case AWAITING_MANUF_CON
: /* Get_Plci per Manufacturer_Req to ext controller */
5691 dbug(1, dprintf("No SigID!"));
5692 sendf(tplci
->appl
, _MANUFACTURER_R
| CONFIRM
, x_Id
, tplci
->number
, "dww", _DI_MANU_ID
, _MANUFACTURER_R
, _OUT_OF_PLCI
);
5696 tplci
->command
= _MANUFACTURER_R
;
5697 api_load_msg(&tplci
->saved_msg
, saved_parms
);
5698 dir
= saved_parms
[2].info
[0];
5700 sig_req(tplci
, CALL_REQ
, 0);
5703 sig_req(tplci
, LISTEN_REQ
, 0);
5706 sendf(tplci
->appl
, _MANUFACTURER_R
| CONFIRM
, x_Id
, tplci
->number
, "dww", _DI_MANU_ID
, _MANUFACTURER_R
, 0);
5709 case (CALL_REQ
| AWAITING_MANUF_CON
):
5710 sig_req(tplci
, CALL_REQ
, 0);
5717 dbug(1, dprintf("No SigID!"));
5718 sendf(tplci
->appl
, _CONNECT_R
| CONFIRM
, tplci
->adapter
->Id
, 0, "w", _OUT_OF_PLCI
);
5722 tplci
->command
= _CONNECT_R
;
5723 api_load_msg(&tplci
->saved_msg
, saved_parms
);
5724 add_s(tplci
, CPN
, &saved_parms
[1]);
5725 add_s(tplci
, DSA
, &saved_parms
[3]);
5726 add_ai(tplci
, &saved_parms
[9]);
5727 sig_req(tplci
, CALL_REQ
, 0);
5732 tplci
->command
= C_RETRIEVE_REQ
;
5733 sig_req(tplci
, CALL_RETRIEVE
, 0);
5737 tplci
->spoofed_msg
= 0;
5738 if (tplci
->internal_command
== 0)
5739 next_internal_command(x_Id
, tplci
);
5742 next_internal_command(Id
, plci
);
5745 dbug(1, dprintf("***Codec Hook Init Req"));
5746 plci
->internal_command
= PERM_COD_HOOK
;
5747 add_p(plci
, FTY
, "\x01\x09"); /* Get Hook State*/
5748 sig_req(plci
, TEL_CTRL
, 0);
5752 else if (plci
->command
!= _MANUFACTURER_R
/* old style permanent connect */
5753 && plci
->State
!= INC_ACT_PENDING
)
5755 mixer_set_bchannel_id_esc(plci
, plci
->b_channel
);
5756 if (plci
->tel
== ADV_VOICE
&& plci
->SuppState
== IDLE
) /* with permanent codec switch on immediately */
5758 chi
[2] = plci
->b_channel
;
5759 SetVoiceChannel(a
->AdvCodecPLCI
, chi
, a
);
5761 sendf(plci
->appl
, _CONNECT_ACTIVE_I
, Id
, 0, "Sss", parms
[21], "", "");
5762 plci
->State
= INC_ACT_PENDING
;
5767 ie
= multi_fac_parms
[0]; /* inspect the facility hook indications */
5768 if (plci
->State
== ADVANCED_VOICE_SIG
&& ie
[0]) {
5769 switch (ie
[1] & 0x91) {
5770 case 0x80: /* hook off */
5772 if (plci
->internal_command
== PERM_COD_HOOK
)
5774 dbug(1, dprintf("init:hook_off"));
5775 plci
->hook_state
= ie
[1];
5776 next_internal_command(Id
, plci
);
5779 else /* ignore doubled hook indications */
5781 if (((plci
->hook_state
) & 0xf0) == 0x80)
5783 dbug(1, dprintf("ignore hook"));
5786 plci
->hook_state
= ie
[1]&0x91;
5788 /* check for incoming call pending */
5789 /* and signal '+'.Appl must decide */
5790 /* with connect_res if call must */
5791 /* accepted or not */
5792 for (i
= 0, tplci
= NULL
; i
< max_appl
; i
++) {
5793 if (a
->codec_listen
[i
]
5794 && (a
->codec_listen
[i
]->State
== INC_CON_PENDING
5795 || a
->codec_listen
[i
]->State
== INC_CON_ALERT
)) {
5796 tplci
= a
->codec_listen
[i
];
5797 tplci
->appl
= &application
[i
];
5800 /* no incoming call, do outgoing call */
5801 /* and signal '+' if outg. setup */
5802 if (!a
->AdvSignalPLCI
&& !tplci
) {
5803 if ((i
= get_plci(a
))) {
5804 a
->AdvSignalPLCI
= &a
->plci
[i
- 1];
5805 tplci
= a
->AdvSignalPLCI
;
5806 tplci
->tel
= ADV_VOICE
;
5807 PUT_WORD(&voice_cai
[5], a
->AdvSignalAppl
->MaxDataLength
);
5808 if (a
->Info_Mask
[a
->AdvSignalAppl
->Id
- 1] & 0x200) {
5809 /* early B3 connect (CIP mask bit 9) no release after a disc */
5810 add_p(tplci
, LLI
, "\x01\x01");
5812 add_p(tplci
, CAI
, voice_cai
);
5813 add_p(tplci
, OAD
, a
->TelOAD
);
5814 add_p(tplci
, OSA
, a
->TelOSA
);
5815 add_p(tplci
, SHIFT
| 6, NULL
);
5816 add_p(tplci
, SIN
, "\x02\x01\x00");
5817 add_p(tplci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
5818 sig_req(tplci
, ASSIGN
, DSIG_ID
);
5819 a
->AdvSignalPLCI
->internal_command
= HOOK_OFF_REQ
;
5820 a
->AdvSignalPLCI
->command
= 0;
5821 tplci
->appl
= a
->AdvSignalAppl
;
5822 tplci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
5829 Id
= ((word
)tplci
->Id
<< 8) | a
->Id
;
5830 Id
|= EXT_CONTROLLER
;
5835 "ws", (word
)0, "\x01+");
5838 case 0x90: /* hook on */
5840 if (plci
->internal_command
== PERM_COD_HOOK
)
5842 dbug(1, dprintf("init:hook_on"));
5843 plci
->hook_state
= ie
[1] & 0x91;
5844 next_internal_command(Id
, plci
);
5847 else /* ignore doubled hook indications */
5849 if (((plci
->hook_state
) & 0xf0) == 0x90) break;
5850 plci
->hook_state
= ie
[1] & 0x91;
5852 /* hangup the adv. voice call and signal '-' to the appl */
5853 if (a
->AdvSignalPLCI
) {
5854 Id
= ((word
)a
->AdvSignalPLCI
->Id
<< 8) | a
->Id
;
5855 if (plci
->tel
) Id
|= EXT_CONTROLLER
;
5856 sendf(a
->AdvSignalAppl
,
5860 "ws", (word
)0, "\x01-");
5861 a
->AdvSignalPLCI
->internal_command
= HOOK_ON_REQ
;
5862 a
->AdvSignalPLCI
->command
= 0;
5863 sig_req(a
->AdvSignalPLCI
, HANGUP
, 0);
5864 send_req(a
->AdvSignalPLCI
);
5872 __clear_bit(plci
->appl
->Id
- 1, plci
->c_ind_mask_table
);
5873 PUT_WORD(&resume_cau
[4], GOOD
);
5874 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", (word
)3, resume_cau
);
5878 bitmap_zero(plci
->c_ind_mask_table
, MAX_APPL
);
5880 if (plci
->NL
.Id
&& !plci
->nl_remove_id
) {
5882 nl_req_ncci(plci
, REMOVE
, 0);
5884 if (!plci
->sig_remove_id
) {
5885 plci
->internal_command
= 0;
5886 sig_req(plci
, REMOVE
, 0);
5889 if (!plci
->channels
) {
5890 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", (word
)3, "\x05\x04\x00\x02\x00\x00");
5891 sendf(plci
->appl
, _DISCONNECT_I
, Id
, 0, "w", 0);
5899 plci
->hangup_flow_ctrl_timer
= 0;
5900 if (plci
->manufacturer
&& plci
->State
== LOCAL_CONNECT
) break;
5903 i
= _L3_CAUSE
| cau
[2];
5904 if (cau
[2] == 0) i
= 0;
5905 else if (cau
[2] == 8) i
= _L1_ERROR
;
5906 else if (cau
[2] == 9 || cau
[2] == 10) i
= _L2_ERROR
;
5907 else if (cau
[2] == 5) i
= _CAPI_GUARD_ERROR
;
5913 if (plci
->State
== INC_CON_PENDING
|| plci
->State
== INC_CON_ALERT
)
5915 for_each_set_bit(i
, plci
->c_ind_mask_table
, max_appl
)
5916 sendf(&application
[i
], _DISCONNECT_I
, Id
, 0, "w", 0);
5920 bitmap_zero(plci
->c_ind_mask_table
, MAX_APPL
);
5924 if (plci
->State
== LISTENING
)
5926 plci
->notifiedcall
= 0;
5929 plci
->State
= INC_DIS_PENDING
;
5930 if (bitmap_empty(plci
->c_ind_mask_table
, MAX_APPL
))
5933 if (plci
->NL
.Id
&& !plci
->nl_remove_id
)
5936 nl_req_ncci(plci
, REMOVE
, 0);
5938 if (!plci
->sig_remove_id
)
5940 plci
->internal_command
= 0;
5941 sig_req(plci
, REMOVE
, 0);
5948 /* collision of DISCONNECT or CONNECT_RES with HANGUP can */
5949 /* result in a second HANGUP! Don't generate another */
5951 if (plci
->State
!= IDLE
&& plci
->State
!= INC_DIS_PENDING
)
5953 if (plci
->State
== RESUMING
)
5955 PUT_WORD(&resume_cau
[4], i
);
5956 sendf(plci
->appl
, _FACILITY_I
, Id
, 0, "ws", (word
)3, resume_cau
);
5958 plci
->State
= INC_DIS_PENDING
;
5959 sendf(plci
->appl
, _DISCONNECT_I
, Id
, 0, "w", i
);
5965 SendSSExtInd(NULL
, plci
, Id
, multi_ssext_parms
);
5969 VSwitchReqInd(plci
, Id
, multi_vswitch_parms
);
5972 if (plci
->relatedPTYPLCI
&&
5973 plci
->vswitchstate
== 3 &&
5974 plci
->relatedPTYPLCI
->vswitchstate
== 3 &&
5975 parms
[MAXPARMSIDS
- 1][0])
5977 add_p(plci
->relatedPTYPLCI
, SMSG
, parms
[MAXPARMSIDS
- 1]);
5978 sig_req(plci
->relatedPTYPLCI
, VSWITCH_REQ
, 0);
5979 send_req(plci
->relatedPTYPLCI
);
5981 else VSwitchReqInd(plci
, Id
, multi_vswitch_parms
);
5988 static void SendSetupInfo(APPL
*appl
, PLCI
*plci
, dword Id
, byte
**parms
, byte Info_Sent_Flag
)
5996 dbug(1, dprintf("SetupInfo"));
5998 for (i
= 0; i
< MAXPARMSIDS
; i
++) {
6005 dbug(1, dprintf("CPN "));
6006 Info_Number
= 0x0070;
6008 Info_Sent_Flag
= true;
6010 case 8: /* display */
6011 dbug(1, dprintf("display(%d)", i
));
6012 Info_Number
= 0x0028;
6014 Info_Sent_Flag
= true;
6016 case 16: /* Channel Id */
6017 dbug(1, dprintf("CHI"));
6018 Info_Number
= 0x0018;
6020 Info_Sent_Flag
= true;
6021 mixer_set_bchannel_id(plci
, Info_Element
);
6023 case 19: /* Redirected Number */
6024 dbug(1, dprintf("RDN"));
6025 Info_Number
= 0x0074;
6027 Info_Sent_Flag
= true;
6029 case 20: /* Redirected Number extended */
6030 dbug(1, dprintf("RDX"));
6031 Info_Number
= 0x0073;
6033 Info_Sent_Flag
= true;
6035 case 22: /* Redirecing Number */
6036 dbug(1, dprintf("RIN"));
6037 Info_Number
= 0x0076;
6039 Info_Sent_Flag
= true;
6047 if (i
== MAXPARMSIDS
- 2) { /* to indicate the message type "Setup" */
6048 Info_Number
= 0x8000 | 5;
6053 if (Info_Sent_Flag
&& Info_Number
) {
6054 if (plci
->adapter
->Info_Mask
[appl
->Id
- 1] & Info_Mask
) {
6055 sendf(appl
, _INFO_I
, Id
, 0, "wS", Info_Number
, Info_Element
);
6062 static void SendInfo(PLCI
*plci
, dword Id
, byte
**parms
, byte iesent
)
6071 static byte charges
[5] = {4, 0, 0, 0, 0};
6072 static byte cause
[] = {0x02, 0x80, 0x00};
6075 dbug(1, dprintf("InfoParse "));
6080 && plci
->Sig
.Ind
!= NCR_FACILITY
6083 dbug(1, dprintf("NoParse "));
6087 for (i
= 0; i
< MAXPARMSIDS
; i
++) {
6094 dbug(1, dprintf("CPN "));
6095 Info_Number
= 0x0070;
6098 case 7: /* ESC_CAU */
6099 dbug(1, dprintf("cau(0x%x)", ie
[2]));
6100 Info_Number
= 0x0008;
6103 Info_Element
= NULL
;
6105 case 8: /* display */
6106 dbug(1, dprintf("display(%d)", i
));
6107 Info_Number
= 0x0028;
6110 case 9: /* Date display */
6111 dbug(1, dprintf("date(%d)", i
));
6112 Info_Number
= 0x0029;
6115 case 10: /* charges */
6116 for (j
= 0; j
< 4; j
++) charges
[1 + j
] = 0;
6117 for (j
= 0; j
< ie
[0] && !(ie
[1 + j
] & 0x80); j
++);
6118 for (k
= 1, j
++; j
< ie
[0] && k
<= 4; j
++, k
++) charges
[k
] = ie
[1 + j
];
6119 Info_Number
= 0x4000;
6121 Info_Element
= charges
;
6123 case 11: /* user user info */
6124 dbug(1, dprintf("uui"));
6125 Info_Number
= 0x007E;
6128 case 12: /* congestion receiver ready */
6129 dbug(1, dprintf("clRDY"));
6130 Info_Number
= 0x00B0;
6134 case 13: /* congestion receiver not ready */
6135 dbug(1, dprintf("clNRDY"));
6136 Info_Number
= 0x00BF;
6140 case 15: /* Keypad Facility */
6141 dbug(1, dprintf("KEY"));
6142 Info_Number
= 0x002C;
6145 case 16: /* Channel Id */
6146 dbug(1, dprintf("CHI"));
6147 Info_Number
= 0x0018;
6149 mixer_set_bchannel_id(plci
, Info_Element
);
6151 case 17: /* if no 1tr6 cause, send full cause, else esc_cause */
6152 dbug(1, dprintf("q9cau(0x%x)", ie
[2]));
6153 if (!cause
[2] || cause
[2] < 0x80) break; /* eg. layer 1 error */
6154 Info_Number
= 0x0008;
6156 if (cause
[2] != ie
[2]) Info_Element
= cause
;
6158 case 19: /* Redirected Number */
6159 dbug(1, dprintf("RDN"));
6160 Info_Number
= 0x0074;
6163 case 22: /* Redirecing Number */
6164 dbug(1, dprintf("RIN"));
6165 Info_Number
= 0x0076;
6168 case 23: /* Notification Indicator */
6169 dbug(1, dprintf("NI"));
6170 Info_Number
= (word
)NI
;
6173 case 26: /* Call State */
6174 dbug(1, dprintf("CST"));
6175 Info_Number
= (word
)CST
;
6176 Info_Mask
= 0x01; /* do with cause i.e. for now */
6178 case MAXPARMSIDS
- 2: /* Escape Message Type, must be the last indication */
6179 dbug(1, dprintf("ESC/MT[0x%x]", ie
[3]));
6180 Info_Number
= 0x8000 | ie
[3];
6181 if (iesent
) Info_Mask
= 0xffff;
6182 else Info_Mask
= 0x10;
6193 if (plci
->Sig
.Ind
== NCR_FACILITY
) /* check controller broadcast */
6195 for (j
= 0; j
< max_appl
; j
++)
6197 appl
= &application
[j
];
6200 && plci
->adapter
->Info_Mask
[appl
->Id
- 1] & Info_Mask
)
6202 dbug(1, dprintf("NCR_Ind"));
6204 sendf(&application
[j
], _INFO_I
, Id
& 0x0f, 0, "wS", Info_Number
, Info_Element
);
6208 else if (!plci
->appl
)
6209 { /* overlap receiving broadcast */
6210 if (Info_Number
== CPN
6211 || Info_Number
== KEY
6212 || Info_Number
== NI
6213 || Info_Number
== DSP
6214 || Info_Number
== UUI
)
6216 for_each_set_bit(j
, plci
->c_ind_mask_table
, max_appl
) {
6217 dbug(1, dprintf("Ovl_Ind"));
6219 sendf(&application
[j
], _INFO_I
, Id
, 0, "wS", Info_Number
, Info_Element
);
6222 } /* all other signalling states */
6223 else if (Info_Number
6224 && plci
->adapter
->Info_Mask
[plci
->appl
->Id
- 1] & Info_Mask
)
6226 dbug(1, dprintf("Std_Ind"));
6228 sendf(plci
->appl
, _INFO_I
, Id
, 0, "wS", Info_Number
, Info_Element
);
6234 static byte
SendMultiIE(PLCI
*plci
, dword Id
, byte
**parms
, byte ie_type
,
6235 dword info_mask
, byte setupParse
)
6249 && plci
->Sig
.Ind
!= NCR_FACILITY
6253 dbug(1, dprintf("NoM-IEParse "));
6256 dbug(1, dprintf("M-IEParse "));
6258 for (i
= 0; i
< MAX_MULTI_IE
; i
++)
6265 dbug(1, dprintf("[Ind0x%x]:IE=0x%x", plci
->Sig
.Ind
, ie_type
));
6266 Info_Number
= (word
)ie_type
;
6267 Info_Mask
= (word
)info_mask
;
6270 if (plci
->Sig
.Ind
== NCR_FACILITY
) /* check controller broadcast */
6272 for (j
= 0; j
< max_appl
; j
++)
6274 appl
= &application
[j
];
6277 && plci
->adapter
->Info_Mask
[appl
->Id
- 1] & Info_Mask
)
6280 dbug(1, dprintf("Mlt_NCR_Ind"));
6281 sendf(&application
[j
], _INFO_I
, Id
& 0x0f, 0, "wS", Info_Number
, Info_Element
);
6285 else if (!plci
->appl
&& Info_Number
)
6286 { /* overlap receiving broadcast */
6287 for_each_set_bit(j
, plci
->c_ind_mask_table
, max_appl
) {
6289 dbug(1, dprintf("Mlt_Ovl_Ind"));
6290 sendf(&application
[j
] , _INFO_I
, Id
, 0, "wS", Info_Number
, Info_Element
);
6292 } /* all other signalling states */
6293 else if (Info_Number
6294 && plci
->adapter
->Info_Mask
[plci
->appl
->Id
- 1] & Info_Mask
)
6297 dbug(1, dprintf("Mlt_Std_Ind"));
6298 sendf(plci
->appl
, _INFO_I
, Id
, 0, "wS", Info_Number
, Info_Element
);
6304 static void SendSSExtInd(APPL
*appl
, PLCI
*plci
, dword Id
, byte
**parms
)
6307 /* Format of multi_ssext_parms[i][]:
6310 2 byte SSEXT_REQ/SSEXT_IND
6318 && plci
->Sig
.Ind
!= NCR_FACILITY
6320 for (i
= 0; i
< MAX_MULTI_IE
; i
++)
6322 if (parms
[i
][0] < 6) continue;
6323 if (parms
[i
][2] == SSEXT_REQ
) continue;
6327 parms
[i
][0] = 0; /* kill it */
6328 sendf(appl
, _MANUFACTURER_I
,
6336 else if (plci
->appl
)
6338 parms
[i
][0] = 0; /* kill it */
6339 sendf(plci
->appl
, _MANUFACTURER_I
,
6350 static void nl_ind(PLCI
*plci
)
6355 DIVA_CAPI_ADAPTER
*a
;
6361 byte len
, ncci_state
;
6364 word fax_feature_bits
;
6365 byte fax_send_edata_ack
;
6366 static byte v120_header_buffer
[2 + 3];
6367 static word fax_info
[] = {
6368 0, /* T30_SUCCESS */
6369 _FAX_NO_CONNECTION
, /* T30_ERR_NO_DIS_RECEIVED */
6370 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TIMEOUT_NO_RESPONSE */
6371 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_RESPONSE */
6372 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TOO_MANY_REPEATS */
6373 _FAX_PROTOCOL_ERROR
, /* T30_ERR_UNEXPECTED_MESSAGE */
6374 _FAX_REMOTE_ABORT
, /* T30_ERR_UNEXPECTED_DCN */
6375 _FAX_LOCAL_ABORT
, /* T30_ERR_DTC_UNSUPPORTED */
6376 _FAX_TRAINING_ERROR
, /* T30_ERR_ALL_RATES_FAILED */
6377 _FAX_TRAINING_ERROR
, /* T30_ERR_TOO_MANY_TRAINS */
6378 _FAX_PARAMETER_ERROR
, /* T30_ERR_RECEIVE_CORRUPTED */
6379 _FAX_REMOTE_ABORT
, /* T30_ERR_UNEXPECTED_DISC */
6380 _FAX_LOCAL_ABORT
, /* T30_ERR_APPLICATION_DISC */
6381 _FAX_REMOTE_REJECT
, /* T30_ERR_INCOMPATIBLE_DIS */
6382 _FAX_LOCAL_ABORT
, /* T30_ERR_INCOMPATIBLE_DCS */
6383 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TIMEOUT_NO_COMMAND */
6384 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_COMMAND */
6385 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG */
6386 _FAX_PROTOCOL_ERROR
, /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG */
6387 _FAX_NO_CONNECTION
, /* T30_ERR_NOT_IDENTIFIED */
6388 _FAX_PROTOCOL_ERROR
, /* T30_ERR_SUPERVISORY_TIMEOUT */
6389 _FAX_PARAMETER_ERROR
, /* T30_ERR_TOO_LONG_SCAN_LINE */
6390 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS */
6391 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR */
6392 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCS_AFTER_FTT */
6393 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCS_AFTER_EOM */
6394 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCS_AFTER_MPS */
6395 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCN_AFTER_MCF */
6396 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_DCN_AFTER_RTN */
6397 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_CFR */
6398 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_MCF_AFTER_EOP */
6399 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_MCF_AFTER_EOM */
6400 _FAX_PROTOCOL_ERROR
, /* T30_ERR_RETRY_NO_MCF_AFTER_MPS */
6401 0x331d, /* T30_ERR_SUB_SEP_UNSUPPORTED */
6402 0x331e, /* T30_ERR_PWD_UNSUPPORTED */
6403 0x331f, /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED */
6404 _FAX_PROTOCOL_ERROR
, /* T30_ERR_INVALID_COMMAND_FRAME */
6405 _FAX_PARAMETER_ERROR
, /* T30_ERR_UNSUPPORTED_PAGE_CODING */
6406 _FAX_PARAMETER_ERROR
, /* T30_ERR_INVALID_PAGE_CODING */
6407 _FAX_REMOTE_REJECT
, /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG */
6408 _FAX_LOCAL_ABORT
, /* T30_ERR_TIMEOUT_FROM_APPLICATION */
6409 _FAX_PROTOCOL_ERROR
, /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */
6410 _FAX_PROTOCOL_ERROR
, /* T30_ERR_V34FAX_TRAINING_TIMEOUT */
6411 _FAX_PROTOCOL_ERROR
, /* T30_ERR_V34FAX_UNEXPECTED_V21 */
6412 _FAX_PROTOCOL_ERROR
, /* T30_ERR_V34FAX_PRIMARY_CTS_ON */
6413 _FAX_LOCAL_ABORT
, /* T30_ERR_V34FAX_TURNAROUND_POLLING */
6414 _FAX_LOCAL_ABORT
/* T30_ERR_V34FAX_V8_INCOMPATIBILITY */
6417 byte dtmf_code_buffer
[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE
+ 1];
6420 static word rtp_info
[] = {
6421 GOOD
, /* RTP_SUCCESS */
6422 0x3600 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE */
6425 static dword udata_forwarding_table
[0x100 / sizeof(dword
)] =
6427 0x0020301e, 0x00000000, 0x00000000, 0x00000000,
6428 0x00000000, 0x00000000, 0x00000000, 0x00000000
6431 ch
= plci
->NL
.IndCh
;
6433 ncci
= a
->ch_ncci
[ch
];
6434 Id
= (((dword
)(ncci
? ncci
: ch
)) << 16) | (((word
) plci
->Id
) << 8) | a
->Id
;
6435 if (plci
->tel
) Id
|= EXT_CONTROLLER
;
6436 APPLptr
= plci
->appl
;
6437 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",
6438 plci
->NL
.Id
, Id
, plci
->Id
, plci
->tel
, plci
->State
, ch
, plci
->channels
, plci
->NL
.Ind
& 0x0f));
6440 /* in the case if no connect_active_Ind was sent to the appl we wait for */
6442 if (plci
->nl_remove_id
)
6444 plci
->NL
.RNR
= 2; /* discard */
6445 dbug(1, dprintf("NL discard while remove pending"));
6448 if ((plci
->NL
.Ind
& 0x0f) == N_CONNECT
)
6450 if (plci
->State
== INC_DIS_PENDING
6451 || plci
->State
== OUTG_DIS_PENDING
6452 || plci
->State
== IDLE
)
6454 plci
->NL
.RNR
= 2; /* discard */
6455 dbug(1, dprintf("discard n_connect"));
6458 if (plci
->State
< INC_ACT_PENDING
)
6460 plci
->NL
.RNR
= 1; /* flow control */
6461 channel_x_off(plci
, ch
, N_XON_CONNECT_IND
);
6466 if (!APPLptr
) /* no application or invalid data */
6467 { /* while reloading the DSP */
6468 dbug(1, dprintf("discard1"));
6473 if (((plci
->NL
.Ind
& 0x0f) == N_UDATA
)
6474 && (((plci
->B2_prot
!= B2_SDLC
) && ((plci
->B1_resource
== 17) || (plci
->B1_resource
== 18)))
6475 || (plci
->B2_prot
== 7)
6476 || (plci
->B3_prot
== 7)))
6478 plci
->ncpi_buffer
[0] = 0;
6480 ncpi_state
= plci
->ncpi_state
;
6481 if (plci
->NL
.complete
== 1)
6483 byte
*data
= &plci
->NL
.RBuffer
->P
[0];
6485 if ((plci
->NL
.RBuffer
->length
>= 12)
6486 && ((*data
== DSP_UDATA_INDICATION_DCD_ON
)
6487 || (*data
== DSP_UDATA_INDICATION_CTS_ON
)))
6489 word conn_opt
, ncpi_opt
= 0x00;
6490 /* HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */
6492 if (*data
== DSP_UDATA_INDICATION_DCD_ON
)
6493 plci
->ncpi_state
|= NCPI_MDM_DCD_ON_RECEIVED
;
6494 if (*data
== DSP_UDATA_INDICATION_CTS_ON
)
6495 plci
->ncpi_state
|= NCPI_MDM_CTS_ON_RECEIVED
;
6497 data
++; /* indication code */
6498 data
+= 2; /* timestamp */
6499 if ((*data
== DSP_CONNECTED_NORM_V18
) || (*data
== DSP_CONNECTED_NORM_VOWN
))
6500 ncpi_state
&= ~(NCPI_MDM_DCD_ON_RECEIVED
| NCPI_MDM_CTS_ON_RECEIVED
);
6501 data
++; /* connected norm */
6502 conn_opt
= GET_WORD(data
);
6503 data
+= 2; /* connected options */
6505 PUT_WORD(&(plci
->ncpi_buffer
[1]), (word
)(GET_DWORD(data
) & 0x0000FFFF));
6507 if (conn_opt
& DSP_CONNECTED_OPTION_MASK_V42
)
6509 ncpi_opt
|= MDM_NCPI_ECM_V42
;
6511 else if (conn_opt
& DSP_CONNECTED_OPTION_MASK_MNP
)
6513 ncpi_opt
|= MDM_NCPI_ECM_MNP
;
6517 ncpi_opt
|= MDM_NCPI_TRANSPARENT
;
6519 if (conn_opt
& DSP_CONNECTED_OPTION_MASK_COMPRESSION
)
6521 ncpi_opt
|= MDM_NCPI_COMPRESSED
;
6523 PUT_WORD(&(plci
->ncpi_buffer
[3]), ncpi_opt
);
6524 plci
->ncpi_buffer
[0] = 4;
6526 plci
->ncpi_state
|= NCPI_VALID_CONNECT_B3_IND
| NCPI_VALID_CONNECT_B3_ACT
| NCPI_VALID_DISC_B3_IND
;
6529 if (plci
->B3_prot
== 7)
6531 if (((a
->ncci_state
[ncci
] == INC_ACT_PENDING
) || (a
->ncci_state
[ncci
] == OUTG_CON_PENDING
))
6532 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6533 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6535 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
6536 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "S", plci
->ncpi_buffer
);
6537 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6541 if (!((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
- 1])
6542 & ((1L << PRIVATE_V18
) | (1L << PRIVATE_VOWN
)))
6543 || !(ncpi_state
& NCPI_MDM_DCD_ON_RECEIVED
)
6544 || !(ncpi_state
& NCPI_MDM_CTS_ON_RECEIVED
))
6552 if (plci
->NL
.complete
== 2)
6554 if (((plci
->NL
.Ind
& 0x0f) == N_UDATA
)
6555 && !(udata_forwarding_table
[plci
->RData
[0].P
[0] >> 5] & (1L << (plci
->RData
[0].P
[0] & 0x1f))))
6557 switch (plci
->RData
[0].P
[0])
6560 case DTMF_UDATA_INDICATION_FAX_CALLING_TONE
:
6561 if (plci
->dtmf_rec_active
& DTMF_LISTEN_ACTIVE_FLAG
)
6562 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "ws", SELECTOR_DTMF
, "\x01X");
6564 case DTMF_UDATA_INDICATION_ANSWER_TONE
:
6565 if (plci
->dtmf_rec_active
& DTMF_LISTEN_ACTIVE_FLAG
)
6566 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "ws", SELECTOR_DTMF
, "\x01Y");
6568 case DTMF_UDATA_INDICATION_DIGITS_RECEIVED
:
6569 dtmf_indication(Id
, plci
, plci
->RData
[0].P
, plci
->RData
[0].PLength
);
6571 case DTMF_UDATA_INDICATION_DIGITS_SENT
:
6572 dtmf_confirmation(Id
, plci
);
6576 case UDATA_INDICATION_MIXER_TAP_DATA
:
6577 capidtmf_recv_process_block(&(plci
->capidtmf_state
), plci
->RData
[0].P
+ 1, (word
)(plci
->RData
[0].PLength
- 1));
6578 i
= capidtmf_indication(&(plci
->capidtmf_state
), dtmf_code_buffer
+ 1);
6581 dtmf_code_buffer
[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED
;
6582 dtmf_indication(Id
, plci
, dtmf_code_buffer
, (word
)(i
+ 1));
6587 case UDATA_INDICATION_MIXER_COEFS_SET
:
6588 mixer_indication_coefs_set(Id
, plci
);
6590 case UDATA_INDICATION_XCONNECT_FROM
:
6591 mixer_indication_xconnect_from(Id
, plci
, plci
->RData
[0].P
, plci
->RData
[0].PLength
);
6593 case UDATA_INDICATION_XCONNECT_TO
:
6594 mixer_indication_xconnect_to(Id
, plci
, plci
->RData
[0].P
, plci
->RData
[0].PLength
);
6598 case LEC_UDATA_INDICATION_DISABLE_DETECT
:
6599 ec_indication(Id
, plci
, plci
->RData
[0].P
, plci
->RData
[0].PLength
);
6610 if ((plci
->RData
[0].PLength
!= 0)
6611 && ((plci
->B2_prot
== B2_V120_ASYNC
)
6612 || (plci
->B2_prot
== B2_V120_ASYNC_V42BIS
)
6613 || (plci
->B2_prot
== B2_V120_BIT_TRANSPARENT
)))
6616 sendf(plci
->appl
, _DATA_B3_I
, Id
, 0,
6619 (plci
->NL
.RNum
< 2) ? 0 : plci
->RData
[1].PLength
,
6627 sendf(plci
->appl
, _DATA_B3_I
, Id
, 0,
6630 plci
->RData
[0].PLength
,
6639 fax_feature_bits
= 0;
6640 if ((plci
->NL
.Ind
& 0x0f) == N_CONNECT
||
6641 (plci
->NL
.Ind
& 0x0f) == N_CONNECT_ACK
||
6642 (plci
->NL
.Ind
& 0x0f) == N_DISC
||
6643 (plci
->NL
.Ind
& 0x0f) == N_EDATA
||
6644 (plci
->NL
.Ind
& 0x0f) == N_DISC_ACK
)
6647 plci
->ncpi_buffer
[0] = 0;
6648 switch (plci
->B3_prot
) {
6651 break; /* no network control protocol info - jfr */
6654 for (i
= 0; i
< plci
->NL
.RLength
; i
++) plci
->ncpi_buffer
[4 + i
] = plci
->NL
.RBuffer
->P
[i
];
6655 plci
->ncpi_buffer
[0] = (byte
)(i
+ 3);
6656 plci
->ncpi_buffer
[1] = (byte
)(plci
->NL
.Ind
& N_D_BIT
? 1 : 0);
6657 plci
->ncpi_buffer
[2] = 0;
6658 plci
->ncpi_buffer
[3] = 0;
6660 case 4: /*T.30 - FAX*/
6661 case 5: /*T.30 - FAX*/
6662 if (plci
->NL
.RLength
>= sizeof(T30_INFO
))
6664 dbug(1, dprintf("FaxStatus %04x", ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
));
6666 PUT_WORD(&(plci
->ncpi_buffer
[1]), ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->rate_div_2400
* 2400);
6667 fax_feature_bits
= GET_WORD(&((T30_INFO
*)plci
->NL
.RBuffer
->P
)->feature_bits_low
);
6668 i
= (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->resolution
& T30_RESOLUTION_R8_0770_OR_200
) ? 0x0001 : 0x0000;
6669 if (plci
->B3_prot
== 5)
6671 if (!(fax_feature_bits
& T30_FEATURE_BIT_ECM
))
6672 i
|= 0x8000; /* This is not an ECM connection */
6673 if (fax_feature_bits
& T30_FEATURE_BIT_T6_CODING
)
6674 i
|= 0x4000; /* This is a connection with MMR compression */
6675 if (fax_feature_bits
& T30_FEATURE_BIT_2D_CODING
)
6676 i
|= 0x2000; /* This is a connection with MR compression */
6677 if (fax_feature_bits
& T30_FEATURE_BIT_MORE_DOCUMENTS
)
6678 i
|= 0x0004; /* More documents */
6679 if (fax_feature_bits
& T30_FEATURE_BIT_POLLING
)
6680 i
|= 0x0002; /* Fax-polling indication */
6682 dbug(1, dprintf("FAX Options %04x %04x", fax_feature_bits
, i
));
6683 PUT_WORD(&(plci
->ncpi_buffer
[3]), i
);
6684 PUT_WORD(&(plci
->ncpi_buffer
[5]), ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->data_format
);
6685 plci
->ncpi_buffer
[7] = ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->pages_low
;
6686 plci
->ncpi_buffer
[8] = ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->pages_high
;
6687 plci
->ncpi_buffer
[len
] = 0;
6688 if (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->station_id_len
)
6690 plci
->ncpi_buffer
[len
] = 20;
6691 for (i
= 0; i
< T30_MAX_STATION_ID_LENGTH
; i
++)
6692 plci
->ncpi_buffer
[++len
] = ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->station_id
[i
];
6694 if (((plci
->NL
.Ind
& 0x0f) == N_DISC
) || ((plci
->NL
.Ind
& 0x0f) == N_DISC_ACK
))
6696 if (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
< ARRAY_SIZE(fax_info
))
6697 info
= fax_info
[((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
];
6699 info
= _FAX_PROTOCOL_ERROR
;
6702 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[plci
->appl
->Id
- 1])
6703 & ((1L << PRIVATE_FAX_SUB_SEP_PWD
) | (1L << PRIVATE_FAX_NONSTANDARD
)))
6705 i
= offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
+ ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->head_line_len
;
6706 while (i
< plci
->NL
.RBuffer
->length
)
6707 plci
->ncpi_buffer
[++len
] = plci
->NL
.RBuffer
->P
[i
++];
6710 plci
->ncpi_buffer
[0] = len
;
6711 fax_feature_bits
= GET_WORD(&((T30_INFO
*)plci
->NL
.RBuffer
->P
)->feature_bits_low
);
6712 PUT_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->feature_bits_low
, fax_feature_bits
);
6714 plci
->ncpi_state
|= NCPI_VALID_CONNECT_B3_IND
;
6715 if (((plci
->NL
.Ind
& 0x0f) == N_CONNECT_ACK
)
6716 || (((plci
->NL
.Ind
& 0x0f) == N_CONNECT
)
6717 && (fax_feature_bits
& T30_FEATURE_BIT_POLLING
))
6718 || (((plci
->NL
.Ind
& 0x0f) == N_EDATA
)
6719 && ((((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_TRAIN_OK
)
6720 || (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_DIS
)
6721 || (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_DTC
))))
6723 plci
->ncpi_state
|= NCPI_VALID_CONNECT_B3_ACT
;
6725 if (((plci
->NL
.Ind
& 0x0f) == N_DISC
)
6726 || ((plci
->NL
.Ind
& 0x0f) == N_DISC_ACK
)
6727 || (((plci
->NL
.Ind
& 0x0f) == N_EDATA
)
6728 && (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_EOP_CAPI
)))
6730 plci
->ncpi_state
|= NCPI_VALID_CONNECT_B3_ACT
| NCPI_VALID_DISC_B3_IND
;
6736 if (((plci
->NL
.Ind
& 0x0f) == N_DISC
) || ((plci
->NL
.Ind
& 0x0f) == N_DISC_ACK
))
6738 if (plci
->NL
.RLength
!= 0)
6740 info
= rtp_info
[plci
->NL
.RBuffer
->P
[0]];
6741 plci
->ncpi_buffer
[0] = plci
->NL
.RLength
- 1;
6742 for (i
= 1; i
< plci
->NL
.RLength
; i
++)
6743 plci
->ncpi_buffer
[i
] = plci
->NL
.RBuffer
->P
[i
];
6751 switch (plci
->NL
.Ind
& 0x0f) {
6753 if ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5))
6755 dbug(1, dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci
, a
->ncci_state
[ncci
],
6756 ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
));
6757 fax_send_edata_ack
= (((T30_INFO
*)(plci
->fax_connect_info_buffer
))->operating_mode
== T30_OPERATING_MODE_CAPI_NEG
);
6759 if ((plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_ENABLE_NSF
)
6760 && (plci
->nsf_control_bits
& (T30_NSF_CONTROL_BIT_NEGOTIATE_IND
| T30_NSF_CONTROL_BIT_NEGOTIATE_RESP
))
6761 && (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
== EDATA_T30_DIS
)
6762 && (a
->ncci_state
[ncci
] == OUTG_CON_PENDING
)
6763 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6764 && !(plci
->ncpi_state
& NCPI_NEGOTIATE_B3_SENT
))
6766 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->code
= ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
;
6767 sendf(plci
->appl
, _MANUFACTURER_I
, Id
, 0, "dwbS", _DI_MANU_ID
, _DI_NEGOTIATE_B3
,
6768 (byte
)(plci
->ncpi_buffer
[0] + 1), plci
->ncpi_buffer
);
6769 plci
->ncpi_state
|= NCPI_NEGOTIATE_B3_SENT
;
6770 if (plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_NEGOTIATE_RESP
)
6771 fax_send_edata_ack
= false;
6774 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
6776 switch (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
)
6779 if ((a
->ncci_state
[ncci
] == OUTG_CON_PENDING
)
6780 && !(GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
) & T30_CONTROL_BIT_REQUEST_POLLING
)
6781 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6782 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6784 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
6785 if (plci
->B3_prot
== 4)
6786 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
6788 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "S", plci
->ncpi_buffer
);
6789 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6793 case EDATA_T30_TRAIN_OK
:
6794 if ((a
->ncci_state
[ncci
] == INC_ACT_PENDING
)
6795 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6796 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6798 if (plci
->B3_prot
== 4)
6799 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
6801 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "S", plci
->ncpi_buffer
);
6802 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6806 case EDATA_T30_EOP_CAPI
:
6807 if (a
->ncci_state
[ncci
] == CONNECTED
)
6809 sendf(plci
->appl
, _DISCONNECT_B3_I
, Id
, 0, "wS", GOOD
, plci
->ncpi_buffer
);
6810 a
->ncci_state
[ncci
] = INC_DIS_PENDING
;
6811 plci
->ncpi_state
= 0;
6812 fax_send_edata_ack
= false;
6819 switch (((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
)
6821 case EDATA_T30_TRAIN_OK
:
6822 if ((a
->ncci_state
[ncci
] == INC_ACT_PENDING
)
6823 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6824 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6826 if (plci
->B3_prot
== 4)
6827 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
6829 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "S", plci
->ncpi_buffer
);
6830 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6835 if (fax_send_edata_ack
)
6837 ((T30_INFO
*)(plci
->fax_connect_info_buffer
))->code
= ((T30_INFO
*)plci
->NL
.RBuffer
->P
)->code
;
6838 plci
->fax_edata_ack_length
= 1;
6839 start_internal_command(Id
, plci
, fax_edata_ack_command
);
6844 dbug(1, dprintf("EDATA ncci=0x%x state=%d", ncci
, a
->ncci_state
[ncci
]));
6848 if (!a
->ch_ncci
[ch
])
6850 ncci
= get_ncci(plci
, ch
, 0);
6851 Id
= (Id
& 0xffff) | (((dword
) ncci
) << 16);
6853 dbug(1, dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d",
6854 ch
, a
->ncci_state
[ncci
], a
->ncci_plci
[ncci
], plci
->Id
, plci
->State
));
6856 msg
= _CONNECT_B3_I
;
6857 if (a
->ncci_state
[ncci
] == IDLE
)
6859 else if (plci
->B3_prot
== 1)
6860 msg
= _CONNECT_B3_T90_ACTIVE_I
;
6862 a
->ncci_state
[ncci
] = INC_CON_PENDING
;
6863 if (plci
->B3_prot
== 4)
6864 sendf(plci
->appl
, msg
, Id
, 0, "s", "");
6866 sendf(plci
->appl
, msg
, Id
, 0, "S", plci
->ncpi_buffer
);
6869 dbug(1, dprintf("N_connect_Ack"));
6870 if (plci
->internal_command_queue
[0]
6871 && ((plci
->adjust_b_state
== ADJUST_B_CONNECT_2
)
6872 || (plci
->adjust_b_state
== ADJUST_B_CONNECT_3
)
6873 || (plci
->adjust_b_state
== ADJUST_B_CONNECT_4
)))
6875 (*(plci
->internal_command_queue
[0]))(Id
, plci
, 0);
6876 if (!plci
->internal_command
)
6877 next_internal_command(Id
, plci
);
6880 msg
= _CONNECT_B3_ACTIVE_I
;
6881 if (plci
->B3_prot
== 1)
6883 if (a
->ncci_state
[ncci
] != OUTG_CON_PENDING
)
6884 msg
= _CONNECT_B3_T90_ACTIVE_I
;
6885 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
6886 sendf(plci
->appl
, msg
, Id
, 0, "S", plci
->ncpi_buffer
);
6888 else if ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5) || (plci
->B3_prot
== 7))
6890 if ((a
->ncci_state
[ncci
] == OUTG_CON_PENDING
)
6891 && (plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
6892 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
6894 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
6895 if (plci
->B3_prot
== 4)
6896 sendf(plci
->appl
, msg
, Id
, 0, "s", "");
6898 sendf(plci
->appl
, msg
, Id
, 0, "S", plci
->ncpi_buffer
);
6899 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
6904 a
->ncci_state
[ncci
] = INC_ACT_PENDING
;
6905 sendf(plci
->appl
, msg
, Id
, 0, "S", plci
->ncpi_buffer
);
6907 if (plci
->adjust_b_restore
)
6909 plci
->adjust_b_restore
= false;
6910 start_internal_command(Id
, plci
, adjust_b_restore
);
6915 if (plci
->internal_command_queue
[0]
6916 && ((plci
->internal_command
== FAX_DISCONNECT_COMMAND_1
)
6917 || (plci
->internal_command
== FAX_DISCONNECT_COMMAND_2
)
6918 || (plci
->internal_command
== FAX_DISCONNECT_COMMAND_3
)))
6920 (*(plci
->internal_command_queue
[0]))(Id
, plci
, 0);
6921 if (!plci
->internal_command
)
6922 next_internal_command(Id
, plci
);
6924 ncci_state
= a
->ncci_state
[ncci
];
6925 ncci_remove(plci
, ncci
, false);
6927 /* with N_DISC or N_DISC_ACK the IDI frees the respective */
6928 /* channel, so we cannot store the state in ncci_state! The */
6929 /* information which channel we received a N_DISC is thus */
6930 /* stored in the inc_dis_ncci_table buffer. */
6931 for (i
= 0; plci
->inc_dis_ncci_table
[i
]; i
++);
6932 plci
->inc_dis_ncci_table
[i
] = (byte
) ncci
;
6934 /* need a connect_b3_ind before a disconnect_b3_ind with FAX */
6936 && (plci
->B1_resource
== 16)
6937 && (plci
->State
<= CONNECTED
))
6940 i
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->rate_div_2400
* 2400;
6941 PUT_WORD(&plci
->ncpi_buffer
[1], i
);
6942 PUT_WORD(&plci
->ncpi_buffer
[3], 0);
6943 i
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->data_format
;
6944 PUT_WORD(&plci
->ncpi_buffer
[5], i
);
6945 PUT_WORD(&plci
->ncpi_buffer
[7], 0);
6946 plci
->ncpi_buffer
[len
] = 0;
6947 plci
->ncpi_buffer
[0] = len
;
6948 if (plci
->B3_prot
== 4)
6949 sendf(plci
->appl
, _CONNECT_B3_I
, Id
, 0, "s", "");
6953 if ((plci
->requested_options_conn
| plci
->requested_options
| a
->requested_options_table
[plci
->appl
->Id
- 1])
6954 & ((1L << PRIVATE_FAX_SUB_SEP_PWD
) | (1L << PRIVATE_FAX_NONSTANDARD
)))
6956 plci
->ncpi_buffer
[++len
] = 0;
6957 plci
->ncpi_buffer
[++len
] = 0;
6958 plci
->ncpi_buffer
[++len
] = 0;
6959 plci
->ncpi_buffer
[0] = len
;
6962 sendf(plci
->appl
, _CONNECT_B3_I
, Id
, 0, "S", plci
->ncpi_buffer
);
6964 sendf(plci
->appl
, _DISCONNECT_B3_I
, Id
, 0, "wS", info
, plci
->ncpi_buffer
);
6965 plci
->ncpi_state
= 0;
6966 sig_req(plci
, HANGUP
, 0);
6968 plci
->State
= OUTG_DIS_PENDING
;
6971 else if ((a
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
6972 && ((plci
->B3_prot
== 4) || (plci
->B3_prot
== 5))
6973 && ((ncci_state
== INC_DIS_PENDING
) || (ncci_state
== IDLE
)))
6975 if (ncci_state
== IDLE
)
6979 if ((plci
->State
== IDLE
|| plci
->State
== SUSPENDING
) && !plci
->channels
) {
6980 if (plci
->State
== SUSPENDING
) {
6985 "ws", (word
)3, "\x03\x04\x00\x00");
6986 sendf(plci
->appl
, _DISCONNECT_I
, Id
& 0xffffL
, 0, "w", 0);
6993 else if (plci
->channels
)
6995 sendf(plci
->appl
, _DISCONNECT_B3_I
, Id
, 0, "wS", info
, plci
->ncpi_buffer
);
6996 plci
->ncpi_state
= 0;
6997 if ((ncci_state
== OUTG_REJ_PENDING
)
6998 && ((plci
->B3_prot
!= B3_T90NL
) && (plci
->B3_prot
!= B3_ISO8208
) && (plci
->B3_prot
!= B3_X25_DCE
)))
7000 sig_req(plci
, HANGUP
, 0);
7002 plci
->State
= OUTG_DIS_PENDING
;
7007 a
->ncci_state
[ncci
] = INC_RES_PENDING
;
7008 sendf(plci
->appl
, _RESET_B3_I
, Id
, 0, "S", plci
->ncpi_buffer
);
7011 a
->ncci_state
[ncci
] = CONNECTED
;
7012 sendf(plci
->appl
, _RESET_B3_I
, Id
, 0, "S", plci
->ncpi_buffer
);
7016 if (!(udata_forwarding_table
[plci
->NL
.RBuffer
->P
[0] >> 5] & (1L << (plci
->NL
.RBuffer
->P
[0] & 0x1f))))
7018 plci
->RData
[0].P
= plci
->internal_ind_buffer
+ (-((int)(long)(plci
->internal_ind_buffer
)) & 3);
7019 plci
->RData
[0].PLength
= INTERNAL_IND_BUFFER_SIZE
;
7020 plci
->NL
.R
= plci
->RData
;
7027 if (((a
->ncci_state
[ncci
] != CONNECTED
) && (plci
->B2_prot
== 1)) /* transparent */
7028 || (a
->ncci_state
[ncci
] == IDLE
)
7029 || (a
->ncci_state
[ncci
] == INC_DIS_PENDING
))
7034 if ((a
->ncci_state
[ncci
] != CONNECTED
)
7035 && (a
->ncci_state
[ncci
] != OUTG_DIS_PENDING
)
7036 && (a
->ncci_state
[ncci
] != OUTG_REJ_PENDING
))
7038 dbug(1, dprintf("flow control"));
7039 plci
->NL
.RNR
= 1; /* flow control */
7040 channel_x_off(plci
, ch
, 0);
7044 NCCIcode
= ncci
| (((word
)a
->Id
) << 8);
7046 /* count all buffers within the Application pool */
7047 /* belonging to the same NCCI. If this is below the */
7048 /* number of buffers available per NCCI we accept */
7049 /* this packet, otherwise we reject it */
7052 for (i
= 0; i
< APPLptr
->MaxBuffer
; i
++) {
7053 if (NCCIcode
== APPLptr
->DataNCCI
[i
]) count
++;
7054 if (!APPLptr
->DataNCCI
[i
] && Num
== 0xffff) Num
= i
;
7057 if (count
>= APPLptr
->MaxNCCIData
|| Num
== 0xffff)
7059 dbug(3, dprintf("Flow-Control"));
7061 if (++(APPLptr
->NCCIDataFlowCtrlTimer
) >=
7062 (word
)((a
->manufacturer_features
& MANUFACTURER_FEATURE_OOB_CHANNEL
) ? 40 : 2000))
7065 dbug(3, dprintf("DiscardData"));
7067 channel_x_off(plci
, ch
, 0);
7073 APPLptr
->NCCIDataFlowCtrlTimer
= 0;
7076 plci
->RData
[0].P
= ReceiveBufferGet(APPLptr
, Num
);
7077 if (!plci
->RData
[0].P
) {
7079 channel_x_off(plci
, ch
, 0);
7083 APPLptr
->DataNCCI
[Num
] = NCCIcode
;
7084 APPLptr
->DataFlags
[Num
] = (plci
->Id
<< 8) | (plci
->NL
.Ind
>> 4);
7085 dbug(3, dprintf("Buffer(%d), Max = %d", Num
, APPLptr
->MaxBuffer
));
7088 plci
->RFlags
= plci
->NL
.Ind
>> 4;
7089 plci
->RData
[0].PLength
= APPLptr
->MaxDataLength
;
7090 plci
->NL
.R
= plci
->RData
;
7091 if ((plci
->NL
.RLength
!= 0)
7092 && ((plci
->B2_prot
== B2_V120_ASYNC
)
7093 || (plci
->B2_prot
== B2_V120_ASYNC_V42BIS
)
7094 || (plci
->B2_prot
== B2_V120_BIT_TRANSPARENT
)))
7096 plci
->RData
[1].P
= plci
->RData
[0].P
;
7097 plci
->RData
[1].PLength
= plci
->RData
[0].PLength
;
7098 plci
->RData
[0].P
= v120_header_buffer
+ (-((unsigned long)v120_header_buffer
) & 3);
7099 if ((plci
->NL
.RBuffer
->P
[0] & V120_HEADER_EXTEND_BIT
) || (plci
->NL
.RLength
== 1))
7100 plci
->RData
[0].PLength
= 1;
7102 plci
->RData
[0].PLength
= 2;
7103 if (plci
->NL
.RBuffer
->P
[0] & V120_HEADER_BREAK_BIT
)
7104 plci
->RFlags
|= 0x0010;
7105 if (plci
->NL
.RBuffer
->P
[0] & (V120_HEADER_C1_BIT
| V120_HEADER_C2_BIT
))
7106 plci
->RFlags
|= 0x8000;
7111 if ((plci
->NL
.Ind
& 0x0f) == N_UDATA
)
7112 plci
->RFlags
|= 0x0010;
7114 else if ((plci
->B3_prot
== B3_RTP
) && ((plci
->NL
.Ind
& 0x0f) == N_BDATA
))
7115 plci
->RFlags
|= 0x0001;
7129 /*------------------------------------------------------------------*/
7130 /* find a free PLCI */
7131 /*------------------------------------------------------------------*/
7133 static word
get_plci(DIVA_CAPI_ADAPTER
*a
)
7138 for (i
= 0; i
< a
->max_plci
&& a
->plci
[i
].Id
; i
++);
7139 if (i
== a
->max_plci
) {
7140 dbug(1, dprintf("get_plci: out of PLCIs"));
7144 plci
->Id
= (byte
)(i
+ 1);
7152 plci
->relatedPTYPLCI
= NULL
;
7154 plci
->SuppState
= IDLE
;
7157 plci
->B1_resource
= 0;
7162 plci
->m_command
= 0;
7163 init_internal_command_queue(plci
);
7165 plci
->req_in_start
= 0;
7168 plci
->msg_in_write_pos
= MSG_IN_QUEUE_SIZE
;
7169 plci
->msg_in_read_pos
= MSG_IN_QUEUE_SIZE
;
7170 plci
->msg_in_wrap_pos
= MSG_IN_QUEUE_SIZE
;
7172 plci
->data_sent
= false;
7173 plci
->send_disc
= 0;
7174 plci
->sig_global_req
= 0;
7175 plci
->sig_remove_id
= 0;
7176 plci
->nl_global_req
= 0;
7177 plci
->nl_remove_id
= 0;
7179 plci
->manufacturer
= false;
7180 plci
->call_dir
= CALL_DIR_OUT
| CALL_DIR_ORIGINATE
;
7181 plci
->spoofed_msg
= 0;
7183 plci
->cr_enquiry
= false;
7184 plci
->hangup_flow_ctrl_timer
= 0;
7186 plci
->ncci_ring_list
= 0;
7187 for (j
= 0; j
< MAX_CHANNELS_PER_PLCI
; j
++) plci
->inc_dis_ncci_table
[j
] = 0;
7188 bitmap_zero(plci
->c_ind_mask_table
, MAX_APPL
);
7189 bitmap_fill(plci
->group_optimization_mask_table
, MAX_APPL
);
7190 plci
->fax_connect_info_length
= 0;
7191 plci
->nsf_control_bits
= 0;
7192 plci
->ncpi_state
= 0x00;
7193 plci
->ncpi_buffer
[0] = 0;
7195 plci
->requested_options_conn
= 0;
7196 plci
->requested_options
= 0;
7197 plci
->notifiedcall
= 0;
7198 plci
->vswitchstate
= 0;
7200 plci
->vsprotdialect
= 0;
7201 init_b1_config(plci
);
7202 dbug(1, dprintf("get_plci(%x)", plci
->Id
));
7206 /*------------------------------------------------------------------*/
7207 /* put a parameter in the parameter buffer */
7208 /*------------------------------------------------------------------*/
7210 static void add_p(PLCI
*plci
, byte code
, byte
*p
)
7215 if (p
) p_length
= p
[0];
7216 add_ie(plci
, code
, p
, p_length
);
7219 /*------------------------------------------------------------------*/
7220 /* put a structure in the parameter buffer */
7221 /*------------------------------------------------------------------*/
7222 static void add_s(PLCI
*plci
, byte code
, API_PARSE
*p
)
7224 if (p
) add_ie(plci
, code
, p
->info
, (word
)p
->length
);
7227 /*------------------------------------------------------------------*/
7228 /* put multiple structures in the parameter buffer */
7229 /*------------------------------------------------------------------*/
7230 static void add_ss(PLCI
*plci
, byte code
, API_PARSE
*p
)
7235 dbug(1, dprintf("add_ss(%x,len=%d)", code
, p
->length
));
7236 for (i
= 2; i
< (byte
)p
->length
; i
+= p
->info
[i
] + 2) {
7237 dbug(1, dprintf("add_ss_ie(%x,len=%d)", p
->info
[i
- 1], p
->info
[i
]));
7238 add_ie(plci
, p
->info
[i
- 1], (byte
*)&(p
->info
[i
]), (word
)p
->info
[i
]);
7243 /*------------------------------------------------------------------*/
7244 /* return the channel number sent by the application in a esc_chi */
7245 /*------------------------------------------------------------------*/
7246 static byte
getChannel(API_PARSE
*p
)
7251 for (i
= 2; i
< (byte
)p
->length
; i
+= p
->info
[i
] + 2) {
7252 if (p
->info
[i
] == 2) {
7253 if (p
->info
[i
- 1] == ESC
&& p
->info
[i
+ 1] == CHI
) return (p
->info
[i
+ 2]);
7261 /*------------------------------------------------------------------*/
7262 /* put an information element in the parameter buffer */
7263 /*------------------------------------------------------------------*/
7265 static void add_ie(PLCI
*plci
, byte code
, byte
*p
, word p_length
)
7269 if (!(code
& 0x80) && !p_length
) return;
7271 if (plci
->req_in
== plci
->req_in_start
) {
7277 plci
->RBuffer
[plci
->req_in
++] = code
;
7280 plci
->RBuffer
[plci
->req_in
++] = (byte
)p_length
;
7281 for (i
= 0; i
< p_length
; i
++) plci
->RBuffer
[plci
->req_in
++] = p
[1 + i
];
7284 plci
->RBuffer
[plci
->req_in
++] = 0;
7287 /*------------------------------------------------------------------*/
7288 /* put a unstructured data into the buffer */
7289 /*------------------------------------------------------------------*/
7291 static void add_d(PLCI
*plci
, word length
, byte
*p
)
7295 if (plci
->req_in
== plci
->req_in_start
) {
7301 for (i
= 0; i
< length
; i
++) plci
->RBuffer
[plci
->req_in
++] = p
[i
];
7304 /*------------------------------------------------------------------*/
7305 /* put parameters from the Additional Info parameter in the */
7306 /* parameter buffer */
7307 /*------------------------------------------------------------------*/
7309 static void add_ai(PLCI
*plci
, API_PARSE
*ai
)
7312 API_PARSE ai_parms
[5];
7314 for (i
= 0; i
< 5; i
++) ai_parms
[i
].length
= 0;
7318 if (api_parse(&ai
->info
[1], (word
)ai
->length
, "ssss", ai_parms
))
7321 add_s(plci
, KEY
, &ai_parms
[1]);
7322 add_s(plci
, UUI
, &ai_parms
[2]);
7323 add_ss(plci
, FTY
, &ai_parms
[3]);
7326 /*------------------------------------------------------------------*/
7327 /* put parameter for b1 protocol in the parameter buffer */
7328 /*------------------------------------------------------------------*/
7330 static word
add_b1(PLCI
*plci
, API_PARSE
*bp
, word b_channel_info
,
7333 API_PARSE bp_parms
[8];
7334 API_PARSE mdm_cfg
[9];
7335 API_PARSE global_config
[2];
7337 byte resource
[] = {5, 9, 13, 12, 16, 39, 9, 17, 17, 18};
7338 byte voice_cai
[] = "\x06\x14\x00\x00\x00\x00\x08";
7341 API_PARSE mdm_cfg_v18
[4];
7346 for (i
= 0; i
< 8; i
++) bp_parms
[i
].length
= 0;
7347 for (i
= 0; i
< 2; i
++) global_config
[i
].length
= 0;
7349 dbug(1, dprintf("add_b1"));
7350 api_save_msg(bp
, "s", &plci
->B_protocol
);
7352 if (b_channel_info
== 2) {
7353 plci
->B1_resource
= 0;
7354 adjust_b1_facilities(plci
, plci
->B1_resource
, b1_facilities
);
7355 add_p(plci
, CAI
, "\x01\x00");
7356 dbug(1, dprintf("Cai=1,0 (no resource)"));
7360 if (plci
->tel
== CODEC_PERMANENT
) return 0;
7361 else if (plci
->tel
== CODEC
) {
7362 plci
->B1_resource
= 1;
7363 adjust_b1_facilities(plci
, plci
->B1_resource
, b1_facilities
);
7364 add_p(plci
, CAI
, "\x01\x01");
7365 dbug(1, dprintf("Cai=1,1 (Codec)"));
7368 else if (plci
->tel
== ADV_VOICE
) {
7369 plci
->B1_resource
= add_b1_facilities(plci
, 9, (word
)(b1_facilities
| B1_FACILITY_VOICE
));
7370 adjust_b1_facilities(plci
, plci
->B1_resource
, (word
)(b1_facilities
| B1_FACILITY_VOICE
));
7371 voice_cai
[1] = plci
->B1_resource
;
7372 PUT_WORD(&voice_cai
[5], plci
->appl
->MaxDataLength
);
7373 add_p(plci
, CAI
, voice_cai
);
7374 dbug(1, dprintf("Cai=1,0x%x (AdvVoice)", voice_cai
[1]));
7377 plci
->call_dir
&= ~(CALL_DIR_ORIGINATE
| CALL_DIR_ANSWER
);
7378 if (plci
->call_dir
& CALL_DIR_OUT
)
7379 plci
->call_dir
|= CALL_DIR_ORIGINATE
;
7380 else if (plci
->call_dir
& CALL_DIR_IN
)
7381 plci
->call_dir
|= CALL_DIR_ANSWER
;
7384 plci
->B1_resource
= 0x5;
7385 adjust_b1_facilities(plci
, plci
->B1_resource
, b1_facilities
);
7386 add_p(plci
, CAI
, "\x01\x05");
7390 dbug(1, dprintf("b_prot_len=%d", (word
)bp
->length
));
7391 if (bp
->length
> 256) return _WRONG_MESSAGE_FORMAT
;
7392 if (api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwsssb", bp_parms
))
7394 bp_parms
[6].length
= 0;
7395 if (api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwsss", bp_parms
))
7397 dbug(1, dprintf("b-form.!"));
7398 return _WRONG_MESSAGE_FORMAT
;
7401 else if (api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwssss", bp_parms
))
7403 dbug(1, dprintf("b-form.!"));
7404 return _WRONG_MESSAGE_FORMAT
;
7407 if (bp_parms
[6].length
)
7409 if (api_parse(&bp_parms
[6].info
[1], (word
)bp_parms
[6].length
, "w", global_config
))
7411 return _WRONG_MESSAGE_FORMAT
;
7413 switch (GET_WORD(global_config
[0].info
))
7416 plci
->call_dir
= (plci
->call_dir
& ~CALL_DIR_ANSWER
) | CALL_DIR_ORIGINATE
;
7419 plci
->call_dir
= (plci
->call_dir
& ~CALL_DIR_ORIGINATE
) | CALL_DIR_ANSWER
;
7423 dbug(1, dprintf("call_dir=%04x", plci
->call_dir
));
7426 if ((GET_WORD(bp_parms
[0].info
) == B1_RTP
)
7427 && (plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_RTP
)))
7429 plci
->B1_resource
= add_b1_facilities(plci
, 31, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7430 adjust_b1_facilities(plci
, plci
->B1_resource
, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7431 cai
[1] = plci
->B1_resource
;
7435 PUT_WORD(&cai
[5], plci
->appl
->MaxDataLength
);
7436 for (i
= 0; i
< bp_parms
[3].length
; i
++)
7437 cai
[7 + i
] = bp_parms
[3].info
[1 + i
];
7438 cai
[0] = 6 + bp_parms
[3].length
;
7439 add_p(plci
, CAI
, cai
);
7444 if ((GET_WORD(bp_parms
[0].info
) == B1_PIAFS
)
7445 && (plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_PIAFS
)))
7447 plci
->B1_resource
= add_b1_facilities(plci
, 35/* PIAFS HARDWARE FACILITY */, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7448 adjust_b1_facilities(plci
, plci
->B1_resource
, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7449 cai
[1] = plci
->B1_resource
;
7453 PUT_WORD(&cai
[5], plci
->appl
->MaxDataLength
);
7455 add_p(plci
, CAI
, cai
);
7460 if ((GET_WORD(bp_parms
[0].info
) >= 32)
7461 || (!((1L << GET_WORD(bp_parms
[0].info
)) & plci
->adapter
->profile
.B1_Protocols
)
7462 && ((GET_WORD(bp_parms
[0].info
) != 3)
7463 || !((1L << B1_HDLC
) & plci
->adapter
->profile
.B1_Protocols
)
7464 || ((bp_parms
[3].length
!= 0) && (GET_WORD(&bp_parms
[3].info
[1]) != 0) && (GET_WORD(&bp_parms
[3].info
[1]) != 56000)))))
7466 return _B1_NOT_SUPPORTED
;
7468 plci
->B1_resource
= add_b1_facilities(plci
, resource
[GET_WORD(bp_parms
[0].info
)],
7469 (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7470 adjust_b1_facilities(plci
, plci
->B1_resource
, (word
)(b1_facilities
& ~B1_FACILITY_VOICE
));
7472 cai
[1] = plci
->B1_resource
;
7473 for (i
= 2; i
< sizeof(cai
); i
++) cai
[i
] = 0;
7475 if ((GET_WORD(bp_parms
[0].info
) == B1_MODEM_ALL_NEGOTIATE
)
7476 || (GET_WORD(bp_parms
[0].info
) == B1_MODEM_ASYNC
)
7477 || (GET_WORD(bp_parms
[0].info
) == B1_MODEM_SYNC_HDLC
))
7479 for (i
= 0; i
< 7; i
++) mdm_cfg
[i
].length
= 0;
7481 if (bp_parms
[3].length
)
7483 if (api_parse(&bp_parms
[3].info
[1], (word
)bp_parms
[3].length
, "wwwwww", mdm_cfg
))
7485 return (_WRONG_MESSAGE_FORMAT
);
7488 cai
[2] = 0; /* Bit rate for adaptation */
7490 dbug(1, dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg
[0].info
)));
7492 PUT_WORD(&cai
[13], 0); /* Min Tx speed */
7493 PUT_WORD(&cai
[15], GET_WORD(mdm_cfg
[0].info
)); /* Max Tx speed */
7494 PUT_WORD(&cai
[17], 0); /* Min Rx speed */
7495 PUT_WORD(&cai
[19], GET_WORD(mdm_cfg
[0].info
)); /* Max Rx speed */
7497 cai
[3] = 0; /* Async framing parameters */
7498 switch (GET_WORD(mdm_cfg
[2].info
))
7500 case 1: /* odd parity */
7501 cai
[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE
| DSP_CAI_ASYNC_PARITY_ODD
);
7502 dbug(1, dprintf("MDM: odd parity"));
7505 case 2: /* even parity */
7506 cai
[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE
| DSP_CAI_ASYNC_PARITY_EVEN
);
7507 dbug(1, dprintf("MDM: even parity"));
7511 dbug(1, dprintf("MDM: no parity"));
7515 switch (GET_WORD(mdm_cfg
[3].info
))
7517 case 1: /* 2 stop bits */
7518 cai
[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS
;
7519 dbug(1, dprintf("MDM: 2 stop bits"));
7523 dbug(1, dprintf("MDM: 1 stop bit"));
7527 switch (GET_WORD(mdm_cfg
[1].info
))
7530 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5
;
7531 dbug(1, dprintf("MDM: 5 bits"));
7535 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6
;
7536 dbug(1, dprintf("MDM: 6 bits"));
7540 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7
;
7541 dbug(1, dprintf("MDM: 7 bits"));
7545 dbug(1, dprintf("MDM: 8 bits"));
7549 cai
[7] = 0; /* Line taking options */
7550 cai
[8] = 0; /* Modulation negotiation options */
7551 cai
[9] = 0; /* Modulation options */
7553 if (((plci
->call_dir
& CALL_DIR_ORIGINATE
) != 0) ^ ((plci
->call_dir
& CALL_DIR_OUT
) != 0))
7555 cai
[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION
;
7556 dbug(1, dprintf("MDM: Reverse direction"));
7559 if (GET_WORD(mdm_cfg
[4].info
) & MDM_CAPI_DISABLE_RETRAIN
)
7561 cai
[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN
;
7562 dbug(1, dprintf("MDM: Disable retrain"));
7565 if (GET_WORD(mdm_cfg
[4].info
) & MDM_CAPI_DISABLE_RING_TONE
)
7567 cai
[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE
| DSP_CAI_MODEM_DISABLE_ANSWER_TONE
;
7568 dbug(1, dprintf("MDM: Disable ring tone"));
7571 if (GET_WORD(mdm_cfg
[4].info
) & MDM_CAPI_GUARD_1800
)
7573 cai
[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ
;
7574 dbug(1, dprintf("MDM: 1800 guard tone"));
7576 else if (GET_WORD(mdm_cfg
[4].info
) & MDM_CAPI_GUARD_550
)
7578 cai
[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ
;
7579 dbug(1, dprintf("MDM: 550 guard tone"));
7582 if ((GET_WORD(mdm_cfg
[5].info
) & 0x00ff) == MDM_CAPI_NEG_V100
)
7584 cai
[8] |= DSP_CAI_MODEM_NEGOTIATE_V100
;
7585 dbug(1, dprintf("MDM: V100"));
7587 else if ((GET_WORD(mdm_cfg
[5].info
) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS
)
7589 cai
[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS
;
7590 dbug(1, dprintf("MDM: IN CLASS"));
7592 else if ((GET_WORD(mdm_cfg
[5].info
) & 0x00ff) == MDM_CAPI_NEG_DISABLED
)
7594 cai
[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED
;
7595 dbug(1, dprintf("MDM: DISABLED"));
7599 if ((plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_V18
))
7600 && (GET_WORD(mdm_cfg
[5].info
) & 0x8000)) /* Private V.18 enable */
7602 plci
->requested_options
|= 1L << PRIVATE_V18
;
7604 if (GET_WORD(mdm_cfg
[5].info
) & 0x4000) /* Private VOWN enable */
7605 plci
->requested_options
|= 1L << PRIVATE_VOWN
;
7607 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
- 1])
7608 & ((1L << PRIVATE_V18
) | (1L << PRIVATE_VOWN
)))
7610 if (!api_parse(&bp_parms
[3].info
[1], (word
)bp_parms
[3].length
, "wwwwwws", mdm_cfg
))
7613 if (mdm_cfg
[6].length
>= 4)
7615 d
= GET_DWORD(&mdm_cfg
[6].info
[1]);
7616 cai
[7] |= (byte
) d
; /* line taking options */
7617 cai
[9] |= (byte
)(d
>> 8); /* modulation options */
7618 cai
[++i
] = (byte
)(d
>> 16); /* vown modulation options */
7619 cai
[++i
] = (byte
)(d
>> 24);
7620 if (mdm_cfg
[6].length
>= 8)
7622 d
= GET_DWORD(&mdm_cfg
[6].info
[5]);
7623 cai
[10] |= (byte
) d
; /* disabled modulations mask */
7624 cai
[11] |= (byte
)(d
>> 8);
7625 if (mdm_cfg
[6].length
>= 12)
7627 d
= GET_DWORD(&mdm_cfg
[6].info
[9]);
7628 cai
[12] = (byte
) d
; /* enabled modulations mask */
7629 cai
[++i
] = (byte
)(d
>> 8); /* vown enabled modulations */
7630 cai
[++i
] = (byte
)(d
>> 16);
7631 cai
[++i
] = (byte
)(d
>> 24);
7633 if (mdm_cfg
[6].length
>= 14)
7635 w
= GET_WORD(&mdm_cfg
[6].info
[13]);
7637 PUT_WORD(&cai
[13], w
); /* min tx speed */
7638 if (mdm_cfg
[6].length
>= 16)
7640 w
= GET_WORD(&mdm_cfg
[6].info
[15]);
7642 PUT_WORD(&cai
[15], w
); /* max tx speed */
7643 if (mdm_cfg
[6].length
>= 18)
7645 w
= GET_WORD(&mdm_cfg
[6].info
[17]);
7647 PUT_WORD(&cai
[17], w
); /* min rx speed */
7648 if (mdm_cfg
[6].length
>= 20)
7650 w
= GET_WORD(&mdm_cfg
[6].info
[19]);
7652 PUT_WORD(&cai
[19], w
); /* max rx speed */
7653 if (mdm_cfg
[6].length
>= 22)
7655 w
= GET_WORD(&mdm_cfg
[6].info
[21]);
7656 cai
[23] = (byte
)(-((short) w
)); /* transmit level */
7657 if (mdm_cfg
[6].length
>= 24)
7659 w
= GET_WORD(&mdm_cfg
[6].info
[23]);
7660 cai
[22] |= (byte
) w
; /* info options mask */
7661 cai
[21] |= (byte
)(w
>> 8); /* disabled symbol rates */
7673 if (!api_parse(&bp_parms
[3].info
[1], (word
)bp_parms
[3].length
, "wwwwwwss", mdm_cfg
))
7675 if (!api_parse(&mdm_cfg
[7].info
[1], (word
)mdm_cfg
[7].length
, "sss", mdm_cfg_v18
))
7677 for (n
= 0; n
< 3; n
++)
7679 cai
[i
] = (byte
)(mdm_cfg_v18
[n
].length
);
7680 for (j
= 1; j
< ((word
)(cai
[i
] + 1)); j
++)
7681 cai
[i
+ j
] = mdm_cfg_v18
[n
].info
[j
];
7686 cai
[0] = (byte
)(i
- 1);
7692 if (GET_WORD(bp_parms
[0].info
) == 2 || /* V.110 async */
7693 GET_WORD(bp_parms
[0].info
) == 3) /* V.110 sync */
7695 if (bp_parms
[3].length
) {
7696 dbug(1, dprintf("V.110,%d", GET_WORD(&bp_parms
[3].info
[1])));
7697 switch (GET_WORD(&bp_parms
[3].info
[1])) { /* Rate */
7700 if (GET_WORD(bp_parms
[0].info
) == 3) { /* V.110 sync 56k */
7701 dbug(1, dprintf("56k sync HSCX"));
7706 else if (GET_WORD(bp_parms
[0].info
) == 2) {
7707 dbug(1, dprintf("56k async DSP"));
7711 case 50: cai
[2] = 1; break;
7712 case 75: cai
[2] = 1; break;
7713 case 110: cai
[2] = 1; break;
7714 case 150: cai
[2] = 1; break;
7715 case 200: cai
[2] = 1; break;
7716 case 300: cai
[2] = 1; break;
7717 case 600: cai
[2] = 1; break;
7718 case 1200: cai
[2] = 2; break;
7719 case 2400: cai
[2] = 3; break;
7720 case 4800: cai
[2] = 4; break;
7721 case 7200: cai
[2] = 10; break;
7722 case 9600: cai
[2] = 5; break;
7723 case 12000: cai
[2] = 13; break;
7724 case 24000: cai
[2] = 0; break;
7725 case 14400: cai
[2] = 11; break;
7726 case 19200: cai
[2] = 6; break;
7727 case 28800: cai
[2] = 12; break;
7728 case 38400: cai
[2] = 7; break;
7729 case 48000: cai
[2] = 8; break;
7730 case 76: cai
[2] = 15; break; /* 75/1200 */
7731 case 1201: cai
[2] = 14; break; /* 1200/75 */
7732 case 56001: cai
[2] = 9; break; /* V.110 56000 */
7735 return _B1_PARM_NOT_SUPPORTED
;
7738 if (cai
[1] == 13) /* v.110 async */
7740 if (bp_parms
[3].length
>= 8)
7742 switch (GET_WORD(&bp_parms
[3].info
[3]))
7745 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5
;
7748 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6
;
7751 cai
[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7
;
7754 switch (GET_WORD(&bp_parms
[3].info
[5]))
7756 case 1: /* odd parity */
7757 cai
[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE
| DSP_CAI_ASYNC_PARITY_ODD
);
7759 case 2: /* even parity */
7760 cai
[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE
| DSP_CAI_ASYNC_PARITY_EVEN
);
7763 switch (GET_WORD(&bp_parms
[3].info
[7]))
7765 case 1: /* 2 stop bits */
7766 cai
[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS
;
7772 else if (cai
[1] == 8 || GET_WORD(bp_parms
[0].info
) == 3) {
7773 dbug(1, dprintf("V.110 default 56k sync"));
7779 dbug(1, dprintf("V.110 default 9600 async"));
7783 PUT_WORD(&cai
[5], plci
->appl
->MaxDataLength
);
7784 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]));
7785 /* HexDump ("CAI", sizeof(cai), &cai[0]); */
7787 add_p(plci
, CAI
, cai
);
7791 /*------------------------------------------------------------------*/
7792 /* put parameter for b2 and B3 protocol in the parameter buffer */
7793 /*------------------------------------------------------------------*/
7795 static word
add_b23(PLCI
*plci
, API_PARSE
*bp
)
7797 word i
, fax_control_bits
;
7799 byte SAPI
= 0x40; /* default SAPI 16 for x.31 */
7800 API_PARSE bp_parms
[8];
7801 API_PARSE
*b1_config
;
7802 API_PARSE
*b2_config
;
7803 API_PARSE b2_config_parms
[8];
7804 API_PARSE
*b3_config
;
7805 API_PARSE b3_config_parms
[6];
7806 API_PARSE global_config
[2];
7808 static byte llc
[3] = {2,0,0};
7809 static byte dlc
[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
7810 static byte nlc
[256];
7811 static byte lli
[12] = {1,1};
7813 const byte llc2_out
[] = {1,2,4,6,2,0,0,0, X75_V42BIS
,V120_L2
,V120_V42BIS
,V120_L2
,6};
7814 const byte llc2_in
[] = {1,3,4,6,3,0,0,0, X75_V42BIS
,V120_L2
,V120_V42BIS
,V120_L2
,6};
7816 const byte llc3
[] = {4,3,2,2,6,6,0};
7817 const byte header
[] = {0,2,3,3,0,0,0};
7819 for (i
= 0; i
< 8; i
++) bp_parms
[i
].length
= 0;
7820 for (i
= 0; i
< 6; i
++) b2_config_parms
[i
].length
= 0;
7821 for (i
= 0; i
< 5; i
++) b3_config_parms
[i
].length
= 0;
7825 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL
)
7827 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_OOB_CHANNEL
)
7830 if ((lli
[1] & 0x02) && (diva_xdi_extended_features
& DIVA_CAPI_USE_CMA
)) {
7832 if (plci
->rx_dma_descriptor
<= 0) {
7833 plci
->rx_dma_descriptor
= diva_get_dma_descriptor(plci
, &plci
->rx_dma_magic
);
7834 if (plci
->rx_dma_descriptor
>= 0)
7835 plci
->rx_dma_descriptor
++;
7837 if (plci
->rx_dma_descriptor
> 0) {
7840 lli
[2] = (byte
)(plci
->rx_dma_descriptor
- 1);
7841 lli
[3] = (byte
)plci
->rx_dma_magic
;
7842 lli
[4] = (byte
)(plci
->rx_dma_magic
>> 8);
7843 lli
[5] = (byte
)(plci
->rx_dma_magic
>> 16);
7844 lli
[6] = (byte
)(plci
->rx_dma_magic
>> 24);
7848 if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci
->adapter
)) {
7852 dbug(1, dprintf("add_b23"));
7853 api_save_msg(bp
, "s", &plci
->B_protocol
);
7855 if (!bp
->length
&& plci
->tel
)
7857 plci
->adv_nl
= true;
7858 dbug(1, dprintf("Default adv.Nl"));
7859 add_p(plci
, LLI
, lli
);
7860 plci
->B2_prot
= 1 /*XPARENT*/;
7861 plci
->B3_prot
= 0 /*XPARENT*/;
7864 add_p(plci
, LLC
, llc
);
7866 PUT_WORD(&dlc
[1], plci
->appl
->MaxDataLength
);
7867 add_p(plci
, DLC
, dlc
);
7871 if (!bp
->length
) /*default*/
7873 dbug(1, dprintf("ret default"));
7874 add_p(plci
, LLI
, lli
);
7875 plci
->B2_prot
= 0 /*X.75 */;
7876 plci
->B3_prot
= 0 /*XPARENT*/;
7879 add_p(plci
, LLC
, llc
);
7881 PUT_WORD(&dlc
[1], plci
->appl
->MaxDataLength
);
7882 add_p(plci
, DLC
, dlc
);
7885 dbug(1, dprintf("b_prot_len=%d", (word
)bp
->length
));
7886 if ((word
)bp
->length
> 256) return _WRONG_MESSAGE_FORMAT
;
7888 if (api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwsssb", bp_parms
))
7890 bp_parms
[6].length
= 0;
7891 if (api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwsss", bp_parms
))
7893 dbug(1, dprintf("b-form.!"));
7894 return _WRONG_MESSAGE_FORMAT
;
7897 else if (api_parse(&bp
->info
[1], (word
)bp
->length
, "wwwssss", bp_parms
))
7899 dbug(1, dprintf("b-form.!"));
7900 return _WRONG_MESSAGE_FORMAT
;
7903 if (plci
->tel
== ADV_VOICE
) /* transparent B on advanced voice */
7905 if (GET_WORD(bp_parms
[1].info
) != 1
7906 || GET_WORD(bp_parms
[2].info
) != 0) return _B2_NOT_SUPPORTED
;
7907 plci
->adv_nl
= true;
7909 else if (plci
->tel
) return _B2_NOT_SUPPORTED
;
7912 if ((GET_WORD(bp_parms
[1].info
) == B2_RTP
)
7913 && (GET_WORD(bp_parms
[2].info
) == B3_RTP
)
7914 && (plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_RTP
)))
7916 add_p(plci
, LLI
, lli
);
7917 plci
->B2_prot
= (byte
) GET_WORD(bp_parms
[1].info
);
7918 plci
->B3_prot
= (byte
) GET_WORD(bp_parms
[2].info
);
7919 llc
[1] = (plci
->call_dir
& (CALL_DIR_ORIGINATE
| CALL_DIR_FORCE_OUTG_NL
)) ? 14 : 13;
7921 add_p(plci
, LLC
, llc
);
7923 PUT_WORD(&dlc
[1], plci
->appl
->MaxDataLength
);
7924 dlc
[3] = 3; /* Addr A */
7925 dlc
[4] = 1; /* Addr B */
7926 dlc
[5] = 7; /* modulo mode */
7927 dlc
[6] = 7; /* window size */
7928 dlc
[7] = 0; /* XID len Lo */
7929 dlc
[8] = 0; /* XID len Hi */
7930 for (i
= 0; i
< bp_parms
[4].length
; i
++)
7931 dlc
[9 + i
] = bp_parms
[4].info
[1 + i
];
7932 dlc
[0] = (byte
)(8 + bp_parms
[4].length
);
7933 add_p(plci
, DLC
, dlc
);
7934 for (i
= 0; i
< bp_parms
[5].length
; i
++)
7935 nlc
[1 + i
] = bp_parms
[5].info
[1 + i
];
7936 nlc
[0] = (byte
)(bp_parms
[5].length
);
7937 add_p(plci
, NLC
, nlc
);
7943 if ((GET_WORD(bp_parms
[1].info
) >= 32)
7944 || (!((1L << GET_WORD(bp_parms
[1].info
)) & plci
->adapter
->profile
.B2_Protocols
)
7945 && ((GET_WORD(bp_parms
[1].info
) != B2_PIAFS
)
7946 || !(plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_PIAFS
)))))
7949 return _B2_NOT_SUPPORTED
;
7951 if ((GET_WORD(bp_parms
[2].info
) >= 32)
7952 || !((1L << GET_WORD(bp_parms
[2].info
)) & plci
->adapter
->profile
.B3_Protocols
))
7954 return _B3_NOT_SUPPORTED
;
7956 if ((GET_WORD(bp_parms
[1].info
) != B2_SDLC
)
7957 && ((GET_WORD(bp_parms
[0].info
) == B1_MODEM_ALL_NEGOTIATE
)
7958 || (GET_WORD(bp_parms
[0].info
) == B1_MODEM_ASYNC
)
7959 || (GET_WORD(bp_parms
[0].info
) == B1_MODEM_SYNC_HDLC
)))
7961 return (add_modem_b23(plci
, bp_parms
));
7964 add_p(plci
, LLI
, lli
);
7966 plci
->B2_prot
= (byte
)GET_WORD(bp_parms
[1].info
);
7967 plci
->B3_prot
= (byte
)GET_WORD(bp_parms
[2].info
);
7968 if (plci
->B2_prot
== 12) SAPI
= 0; /* default SAPI D-channel */
7970 if (bp_parms
[6].length
)
7972 if (api_parse(&bp_parms
[6].info
[1], (word
)bp_parms
[6].length
, "w", global_config
))
7974 return _WRONG_MESSAGE_FORMAT
;
7976 switch (GET_WORD(global_config
[0].info
))
7979 plci
->call_dir
= (plci
->call_dir
& ~CALL_DIR_ANSWER
) | CALL_DIR_ORIGINATE
;
7982 plci
->call_dir
= (plci
->call_dir
& ~CALL_DIR_ORIGINATE
) | CALL_DIR_ANSWER
;
7986 dbug(1, dprintf("call_dir=%04x", plci
->call_dir
));
7989 if (plci
->B2_prot
== B2_PIAFS
)
7992 /* IMPLEMENT_PIAFS */
7994 llc
[1] = (plci
->call_dir
& (CALL_DIR_ORIGINATE
| CALL_DIR_FORCE_OUTG_NL
)) ?
7995 llc2_out
[GET_WORD(bp_parms
[1].info
)] : llc2_in
[GET_WORD(bp_parms
[1].info
)];
7997 llc
[2] = llc3
[GET_WORD(bp_parms
[2].info
)];
7999 add_p(plci
, LLC
, llc
);
8002 PUT_WORD(&dlc
[1], plci
->appl
->MaxDataLength
+
8003 header
[GET_WORD(bp_parms
[2].info
)]);
8005 b1_config
= &bp_parms
[3];
8007 if (plci
->B3_prot
== 4
8008 || plci
->B3_prot
== 5)
8010 for (i
= 0; i
< sizeof(T30_INFO
); i
++) nlc
[i
] = 0;
8011 nlc
[0] = sizeof(T30_INFO
);
8012 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
8013 ((T30_INFO
*)&nlc
[1])->operating_mode
= T30_OPERATING_MODE_CAPI
;
8014 ((T30_INFO
*)&nlc
[1])->rate_div_2400
= 0xff;
8015 if (b1_config
->length
>= 2)
8017 ((T30_INFO
*)&nlc
[1])->rate_div_2400
= (byte
)(GET_WORD(&b1_config
->info
[1]) / 2400);
8020 b2_config
= &bp_parms
[4];
8023 if (llc
[1] == PIAFS_CRC
)
8025 if (plci
->B3_prot
!= B3_TRANSPARENT
)
8027 return _B_STACK_NOT_SUPPORTED
;
8029 if (b2_config
->length
&& api_parse(&b2_config
->info
[1], (word
)b2_config
->length
, "bwww", b2_config_parms
)) {
8030 return _WRONG_MESSAGE_FORMAT
;
8032 PUT_WORD(&dlc
[1], plci
->appl
->MaxDataLength
);
8033 dlc
[3] = 0; /* Addr A */
8034 dlc
[4] = 0; /* Addr B */
8035 dlc
[5] = 0; /* modulo mode */
8036 dlc
[6] = 0; /* window size */
8037 if (b2_config
->length
>= 7) {
8040 dlc
[9] = b2_config_parms
[0].info
[0]; /* PIAFS protocol Speed configuration */
8041 dlc
[10] = b2_config_parms
[1].info
[0]; /* V.42bis P0 */
8042 dlc
[11] = b2_config_parms
[1].info
[1]; /* V.42bis P0 */
8043 dlc
[12] = b2_config_parms
[2].info
[0]; /* V.42bis P1 */
8044 dlc
[13] = b2_config_parms
[2].info
[1]; /* V.42bis P1 */
8045 dlc
[14] = b2_config_parms
[3].info
[0]; /* V.42bis P2 */
8046 dlc
[15] = b2_config_parms
[3].info
[1]; /* V.42bis P2 */
8048 if (b2_config
->length
>= 8) { /* PIAFS control abilities */
8050 dlc
[16] = 2; /* Length of PIAFS extension */
8051 dlc
[17] = PIAFS_UDATA_ABILITIES
; /* control (UDATA) ability */
8052 dlc
[18] = b2_config_parms
[4].info
[0]; /* value */
8056 else /* default values, 64K, variable, no compression */
8060 dlc
[9] = 0x03; /* PIAFS protocol Speed configuration */
8061 dlc
[10] = 0x03; /* V.42bis P0 */
8062 dlc
[11] = 0; /* V.42bis P0 */
8063 dlc
[12] = 0; /* V.42bis P1 */
8064 dlc
[13] = 0; /* V.42bis P1 */
8065 dlc
[14] = 0; /* V.42bis P2 */
8066 dlc
[15] = 0; /* V.42bis P2 */
8069 add_p(plci
, DLC
, dlc
);
8073 if ((llc
[1] == V120_L2
) || (llc
[1] == V120_V42BIS
))
8075 if (plci
->B3_prot
!= B3_TRANSPARENT
)
8076 return _B_STACK_NOT_SUPPORTED
;
8079 PUT_WORD(&dlc
[1], GET_WORD(&dlc
[1]) + 2);
8084 if (b2_config
->length
!= 0)
8086 if ((llc
[1] == V120_V42BIS
) && api_parse(&b2_config
->info
[1], (word
)b2_config
->length
, "bbbbwww", b2_config_parms
)) {
8087 return _WRONG_MESSAGE_FORMAT
;
8089 dlc
[3] = (byte
)((b2_config
->info
[2] << 3) | ((b2_config
->info
[1] >> 5) & 0x04));
8090 dlc
[4] = (byte
)((b2_config
->info
[1] << 1) | 0x01);
8091 if (b2_config
->info
[3] != 128)
8093 dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc
[0], dlc
[1], dlc
[2], dlc
[3], dlc
[4]));
8094 return _B2_PARM_NOT_SUPPORTED
;
8096 dlc
[5] = (byte
)(b2_config
->info
[3] - 1);
8097 dlc
[6] = b2_config
->info
[4];
8098 if (llc
[1] == V120_V42BIS
) {
8099 if (b2_config
->length
>= 10) {
8102 dlc
[9] = b2_config_parms
[4].info
[0];
8103 dlc
[10] = b2_config_parms
[4].info
[1];
8104 dlc
[11] = b2_config_parms
[5].info
[0];
8105 dlc
[12] = b2_config_parms
[5].info
[1];
8106 dlc
[13] = b2_config_parms
[6].info
[0];
8107 dlc
[14] = b2_config_parms
[6].info
[1];
8109 dbug(1, dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms
[4].info
[0], b2_config_parms
[4].info
[1]));
8110 dbug(1, dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms
[5].info
[0], b2_config_parms
[5].info
[1]));
8111 dbug(1, dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms
[6].info
[0], b2_config_parms
[6].info
[1]));
8121 if (b2_config
->length
)
8123 dbug(1, dprintf("B2-Config"));
8124 if (llc
[1] == X75_V42BIS
) {
8125 if (api_parse(&b2_config
->info
[1], (word
)b2_config
->length
, "bbbbwww", b2_config_parms
))
8127 return _WRONG_MESSAGE_FORMAT
;
8131 if (api_parse(&b2_config
->info
[1], (word
)b2_config
->length
, "bbbbs", b2_config_parms
))
8133 return _WRONG_MESSAGE_FORMAT
;
8136 /* if B2 Protocol is LAPD, b2_config structure is different */
8140 if (b2_config
->length
>= 1) dlc
[2] = b2_config
->info
[1]; /* TEI */
8142 if ((b2_config
->length
>= 2) && (plci
->B2_prot
== 12))
8144 SAPI
= b2_config
->info
[2]; /* SAPI */
8147 if ((b2_config
->length
>= 3) && (b2_config
->info
[3] == 128))
8149 dlc
[3] = 127; /* Mode */
8153 dlc
[3] = 7; /* Mode */
8156 if (b2_config
->length
>= 4) dlc
[4] = b2_config
->info
[4]; /* Window */
8158 dbug(1, dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc
[0], dlc
[1], dlc
[2], dlc
[3], dlc
[4]));
8159 if (b2_config
->length
> 5) return _B2_PARM_NOT_SUPPORTED
;
8163 dlc
[0] = (byte
)(b2_config_parms
[4].length
+ 6);
8164 dlc
[3] = b2_config
->info
[1];
8165 dlc
[4] = b2_config
->info
[2];
8166 if (b2_config
->info
[3] != 8 && b2_config
->info
[3] != 128) {
8167 dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc
[0], dlc
[1], dlc
[2], dlc
[3], dlc
[4]));
8168 return _B2_PARM_NOT_SUPPORTED
;
8171 dlc
[5] = (byte
)(b2_config
->info
[3] - 1);
8172 dlc
[6] = b2_config
->info
[4];
8173 if (dlc
[6] > dlc
[5]) {
8174 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]));
8175 return _B2_PARM_NOT_SUPPORTED
;
8178 if (llc
[1] == X75_V42BIS
) {
8179 if (b2_config
->length
>= 10) {
8182 dlc
[9] = b2_config_parms
[4].info
[0];
8183 dlc
[10] = b2_config_parms
[4].info
[1];
8184 dlc
[11] = b2_config_parms
[5].info
[0];
8185 dlc
[12] = b2_config_parms
[5].info
[1];
8186 dlc
[13] = b2_config_parms
[6].info
[0];
8187 dlc
[14] = b2_config_parms
[6].info
[1];
8189 dbug(1, dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms
[4].info
[0], b2_config_parms
[4].info
[1]));
8190 dbug(1, dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms
[5].info
[0], b2_config_parms
[5].info
[1]));
8191 dbug(1, dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms
[6].info
[0], b2_config_parms
[6].info
[1]));
8199 PUT_WORD(&dlc
[7], (word
)b2_config_parms
[4].length
);
8200 for (i
= 0; i
< b2_config_parms
[4].length
; i
++)
8201 dlc
[11 + i
] = b2_config_parms
[4].info
[1 + i
];
8206 add_p(plci
, DLC
, dlc
);
8208 b3_config
= &bp_parms
[5];
8209 if (b3_config
->length
)
8211 if (plci
->B3_prot
== 4
8212 || plci
->B3_prot
== 5)
8214 if (api_parse(&b3_config
->info
[1], (word
)b3_config
->length
, "wwss", b3_config_parms
))
8216 return _WRONG_MESSAGE_FORMAT
;
8218 i
= GET_WORD((byte
*)(b3_config_parms
[0].info
));
8219 ((T30_INFO
*)&nlc
[1])->resolution
= (byte
)(((i
& 0x0001) ||
8220 ((plci
->B3_prot
== 4) && (((byte
)(GET_WORD((byte
*)b3_config_parms
[1].info
))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200
: 0);
8221 ((T30_INFO
*)&nlc
[1])->data_format
= (byte
)(GET_WORD((byte
*)b3_config_parms
[1].info
));
8222 fax_control_bits
= T30_CONTROL_BIT_ALL_FEATURES
;
8223 if ((((T30_INFO
*)&nlc
[1])->rate_div_2400
!= 0) && (((T30_INFO
*)&nlc
[1])->rate_div_2400
<= 6))
8224 fax_control_bits
&= ~T30_CONTROL_BIT_ENABLE_V34FAX
;
8225 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_FAX_PAPER_FORMATS
)
8228 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
- 1])
8229 & (1L << PRIVATE_FAX_PAPER_FORMATS
))
8231 ((T30_INFO
*)&nlc
[1])->resolution
|= T30_RESOLUTION_R8_1540
|
8232 T30_RESOLUTION_R16_1540_OR_400
| T30_RESOLUTION_300_300
|
8233 T30_RESOLUTION_INCH_BASED
| T30_RESOLUTION_METRIC_BASED
;
8236 ((T30_INFO
*)&nlc
[1])->recording_properties
=
8237 T30_RECORDING_WIDTH_ISO_A3
|
8238 (T30_RECORDING_LENGTH_UNLIMITED
<< 2) |
8239 (T30_MIN_SCANLINE_TIME_00_00_00
<< 4);
8241 if (plci
->B3_prot
== 5)
8243 if (i
& 0x0002) /* Accept incoming fax-polling requests */
8244 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_POLLING
;
8245 if (i
& 0x2000) /* Do not use MR compression */
8246 fax_control_bits
&= ~T30_CONTROL_BIT_ENABLE_2D_CODING
;
8247 if (i
& 0x4000) /* Do not use MMR compression */
8248 fax_control_bits
&= ~T30_CONTROL_BIT_ENABLE_T6_CODING
;
8249 if (i
& 0x8000) /* Do not use ECM */
8250 fax_control_bits
&= ~T30_CONTROL_BIT_ENABLE_ECM
;
8251 if (plci
->fax_connect_info_length
!= 0)
8253 ((T30_INFO
*)&nlc
[1])->resolution
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->resolution
;
8254 ((T30_INFO
*)&nlc
[1])->data_format
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->data_format
;
8255 ((T30_INFO
*)&nlc
[1])->recording_properties
= ((T30_INFO
*)plci
->fax_connect_info_buffer
)->recording_properties
;
8256 fax_control_bits
|= GET_WORD(&((T30_INFO
*)plci
->fax_connect_info_buffer
)->control_bits_low
) &
8257 (T30_CONTROL_BIT_REQUEST_POLLING
| T30_CONTROL_BIT_MORE_DOCUMENTS
);
8260 /* copy station id to NLC */
8261 for (i
= 0; i
< T30_MAX_STATION_ID_LENGTH
; i
++)
8263 if (i
< b3_config_parms
[2].length
)
8265 ((T30_INFO
*)&nlc
[1])->station_id
[i
] = ((byte
*)b3_config_parms
[2].info
)[1 + i
];
8269 ((T30_INFO
*)&nlc
[1])->station_id
[i
] = ' ';
8272 ((T30_INFO
*)&nlc
[1])->station_id_len
= T30_MAX_STATION_ID_LENGTH
;
8273 /* copy head line to NLC */
8274 if (b3_config_parms
[3].length
)
8277 pos
= (byte
)(fax_head_line_time(&(((T30_INFO
*)&nlc
[1])->station_id
[T30_MAX_STATION_ID_LENGTH
])));
8280 if (CAPI_MAX_DATE_TIME_LENGTH
+ 2 + b3_config_parms
[3].length
> CAPI_MAX_HEAD_LINE_SPACE
)
8284 nlc
[1 + offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
+ pos
++] = ' ';
8285 nlc
[1 + offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
+ pos
++] = ' ';
8286 len
= (byte
)b3_config_parms
[2].length
;
8289 if (CAPI_MAX_DATE_TIME_LENGTH
+ 2 + len
+ 2 + b3_config_parms
[3].length
<= CAPI_MAX_HEAD_LINE_SPACE
)
8291 for (i
= 0; i
< len
; i
++)
8292 nlc
[1 + offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
+ pos
++] = ((byte
*)b3_config_parms
[2].info
)[1 + i
];
8293 nlc
[1 + offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
+ pos
++] = ' ';
8294 nlc
[1 + offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
+ pos
++] = ' ';
8299 len
= (byte
)b3_config_parms
[3].length
;
8300 if (len
> CAPI_MAX_HEAD_LINE_SPACE
- pos
)
8301 len
= (byte
)(CAPI_MAX_HEAD_LINE_SPACE
- pos
);
8302 ((T30_INFO
*)&nlc
[1])->head_line_len
= (byte
)(pos
+ len
);
8303 nlc
[0] += (byte
)(pos
+ len
);
8304 for (i
= 0; i
< len
; i
++)
8305 nlc
[1 + offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
+ pos
++] = ((byte
*)b3_config_parms
[3].info
)[1 + i
];
8307 ((T30_INFO
*)&nlc
[1])->head_line_len
= 0;
8309 plci
->nsf_control_bits
= 0;
8310 if (plci
->B3_prot
== 5)
8312 if ((plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_FAX_SUB_SEP_PWD
))
8313 && (GET_WORD((byte
*)b3_config_parms
[1].info
) & 0x8000)) /* Private SUB/SEP/PWD enable */
8315 plci
->requested_options
|= 1L << PRIVATE_FAX_SUB_SEP_PWD
;
8317 if ((plci
->adapter
->man_profile
.private_options
& (1L << PRIVATE_FAX_NONSTANDARD
))
8318 && (GET_WORD((byte
*)b3_config_parms
[1].info
) & 0x4000)) /* Private non-standard facilities enable */
8320 plci
->requested_options
|= 1L << PRIVATE_FAX_NONSTANDARD
;
8322 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
- 1])
8323 & ((1L << PRIVATE_FAX_SUB_SEP_PWD
) | (1L << PRIVATE_FAX_NONSTANDARD
)))
8325 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
- 1])
8326 & (1L << PRIVATE_FAX_SUB_SEP_PWD
))
8328 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_SUBADDRESS
| T30_CONTROL_BIT_ACCEPT_PASSWORD
;
8329 if (fax_control_bits
& T30_CONTROL_BIT_ACCEPT_POLLING
)
8330 fax_control_bits
|= T30_CONTROL_BIT_ACCEPT_SEL_POLLING
;
8333 pos
= offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
;
8334 if (pos
< plci
->fax_connect_info_length
)
8336 for (i
= 1 + plci
->fax_connect_info_buffer
[pos
]; i
!= 0; i
--)
8337 nlc
[++len
] = plci
->fax_connect_info_buffer
[pos
++];
8341 if (pos
< plci
->fax_connect_info_length
)
8343 for (i
= 1 + plci
->fax_connect_info_buffer
[pos
]; i
!= 0; i
--)
8344 nlc
[++len
] = plci
->fax_connect_info_buffer
[pos
++];
8348 if ((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[plci
->appl
->Id
- 1])
8349 & (1L << PRIVATE_FAX_NONSTANDARD
))
8351 if ((pos
< plci
->fax_connect_info_length
) && (plci
->fax_connect_info_buffer
[pos
] != 0))
8353 if ((plci
->fax_connect_info_buffer
[pos
] >= 3) && (plci
->fax_connect_info_buffer
[pos
+ 1] >= 2))
8354 plci
->nsf_control_bits
= GET_WORD(&plci
->fax_connect_info_buffer
[pos
+ 2]);
8355 for (i
= 1 + plci
->fax_connect_info_buffer
[pos
]; i
!= 0; i
--)
8356 nlc
[++len
] = plci
->fax_connect_info_buffer
[pos
++];
8360 if (api_parse(&b3_config
->info
[1], (word
)b3_config
->length
, "wwsss", b3_config_parms
))
8362 dbug(1, dprintf("non-standard facilities info missing or wrong format"));
8367 if ((b3_config_parms
[4].length
>= 3) && (b3_config_parms
[4].info
[1] >= 2))
8368 plci
->nsf_control_bits
= GET_WORD(&b3_config_parms
[4].info
[2]);
8369 nlc
[++len
] = (byte
)(b3_config_parms
[4].length
);
8370 for (i
= 0; i
< b3_config_parms
[4].length
; i
++)
8371 nlc
[++len
] = b3_config_parms
[4].info
[1 + i
];
8376 if ((plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_ENABLE_NSF
)
8377 && (plci
->nsf_control_bits
& T30_NSF_CONTROL_BIT_NEGOTIATE_RESP
))
8379 ((T30_INFO
*)&nlc
[1])->operating_mode
= T30_OPERATING_MODE_CAPI_NEG
;
8384 PUT_WORD(&(((T30_INFO
*)&nlc
[1])->control_bits_low
), fax_control_bits
);
8385 len
= offsetof(T30_INFO
, station_id
) + T30_MAX_STATION_ID_LENGTH
;
8386 for (i
= 0; i
< len
; i
++)
8387 plci
->fax_connect_info_buffer
[i
] = nlc
[1 + i
];
8388 ((T30_INFO
*) plci
->fax_connect_info_buffer
)->head_line_len
= 0;
8389 i
+= ((T30_INFO
*)&nlc
[1])->head_line_len
;
8391 plci
->fax_connect_info_buffer
[len
++] = nlc
[++i
];
8392 plci
->fax_connect_info_length
= len
;
8397 if (b3_config
->length
!= 16)
8398 return _B3_PARM_NOT_SUPPORTED
;
8399 for (i
= 0; i
< 12; i
++) nlc
[1 + i
] = b3_config
->info
[1 + i
];
8400 if (GET_WORD(&b3_config
->info
[13]) != 8 && GET_WORD(&b3_config
->info
[13]) != 128)
8401 return _B3_PARM_NOT_SUPPORTED
;
8402 nlc
[13] = b3_config
->info
[13];
8403 if (GET_WORD(&b3_config
->info
[15]) >= nlc
[13])
8404 return _B3_PARM_NOT_SUPPORTED
;
8405 nlc
[14] = b3_config
->info
[15];
8410 if (plci
->B3_prot
== 4
8411 || plci
->B3_prot
== 5 /*T.30 - FAX*/) return _B3_PARM_NOT_SUPPORTED
;
8413 add_p(plci
, NLC
, nlc
);
8417 /*----------------------------------------------------------------*/
8418 /* make the same as add_b23, but only for the modem related */
8419 /* L2 and L3 B-Chan protocol. */
8421 /* Enabled L2 and L3 Configurations: */
8422 /* If L1 == Modem all negotiation */
8423 /* only L2 == Modem with full negotiation is allowed */
8424 /* If L1 == Modem async or sync */
8425 /* only L2 == Transparent is allowed */
8426 /* L3 == Modem or L3 == Transparent are allowed */
8427 /* B2 Configuration for modem: */
8428 /* word : enable/disable compression, bitoptions */
8429 /* B3 Configuration for modem: */
8431 /*----------------------------------------------------------------*/
8432 static word
add_modem_b23(PLCI
*plci
, API_PARSE
*bp_parms
)
8434 static byte lli
[12] = {1,1};
8435 static byte llc
[3] = {2,0,0};
8436 static byte dlc
[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
8437 API_PARSE mdm_config
[2];
8441 for (i
= 0; i
< 2; i
++) mdm_config
[i
].length
= 0;
8442 for (i
= 0; i
< sizeof(dlc
); i
++) dlc
[i
] = 0;
8444 if (((GET_WORD(bp_parms
[0].info
) == B1_MODEM_ALL_NEGOTIATE
)
8445 && (GET_WORD(bp_parms
[1].info
) != B2_MODEM_EC_COMPRESSION
))
8446 || ((GET_WORD(bp_parms
[0].info
) != B1_MODEM_ALL_NEGOTIATE
)
8447 && (GET_WORD(bp_parms
[1].info
) != B2_TRANSPARENT
)))
8449 return (_B_STACK_NOT_SUPPORTED
);
8451 if ((GET_WORD(bp_parms
[2].info
) != B3_MODEM
)
8452 && (GET_WORD(bp_parms
[2].info
) != B3_TRANSPARENT
))
8454 return (_B_STACK_NOT_SUPPORTED
);
8457 plci
->B2_prot
= (byte
) GET_WORD(bp_parms
[1].info
);
8458 plci
->B3_prot
= (byte
) GET_WORD(bp_parms
[2].info
);
8460 if ((GET_WORD(bp_parms
[1].info
) == B2_MODEM_EC_COMPRESSION
) && bp_parms
[4].length
)
8462 if (api_parse(&bp_parms
[4].info
[1],
8463 (word
)bp_parms
[4].length
, "w",
8466 return (_WRONG_MESSAGE_FORMAT
);
8468 b2_config
= GET_WORD(mdm_config
[0].info
);
8471 /* OK, L2 is modem */
8475 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL
)
8477 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_OOB_CHANNEL
)
8480 if ((lli
[1] & 0x02) && (diva_xdi_extended_features
& DIVA_CAPI_USE_CMA
)) {
8482 if (plci
->rx_dma_descriptor
<= 0) {
8483 plci
->rx_dma_descriptor
= diva_get_dma_descriptor(plci
, &plci
->rx_dma_magic
);
8484 if (plci
->rx_dma_descriptor
>= 0)
8485 plci
->rx_dma_descriptor
++;
8487 if (plci
->rx_dma_descriptor
> 0) {
8490 lli
[2] = (byte
)(plci
->rx_dma_descriptor
- 1);
8491 lli
[3] = (byte
)plci
->rx_dma_magic
;
8492 lli
[4] = (byte
)(plci
->rx_dma_magic
>> 8);
8493 lli
[5] = (byte
)(plci
->rx_dma_magic
>> 16);
8494 lli
[6] = (byte
)(plci
->rx_dma_magic
>> 24);
8498 if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci
->adapter
)) {
8502 llc
[1] = (plci
->call_dir
& (CALL_DIR_ORIGINATE
| CALL_DIR_FORCE_OUTG_NL
)) ?
8503 /*V42*/ 10 : /*V42_IN*/ 9;
8504 llc
[2] = 4; /* pass L3 always transparent */
8505 add_p(plci
, LLI
, lli
);
8506 add_p(plci
, LLC
, llc
);
8508 PUT_WORD(&dlc
[i
], plci
->appl
->MaxDataLength
);
8510 if (GET_WORD(bp_parms
[1].info
) == B2_MODEM_EC_COMPRESSION
)
8512 if (bp_parms
[4].length
)
8514 dbug(1, dprintf("MDM b2_config=%02x", b2_config
));
8515 dlc
[i
++] = 3; /* Addr A */
8516 dlc
[i
++] = 1; /* Addr B */
8517 dlc
[i
++] = 7; /* modulo mode */
8518 dlc
[i
++] = 7; /* window size */
8519 dlc
[i
++] = 0; /* XID len Lo */
8520 dlc
[i
++] = 0; /* XID len Hi */
8522 if (b2_config
& MDM_B2_DISABLE_V42bis
)
8524 dlc
[i
] |= DLC_MODEMPROT_DISABLE_V42_V42BIS
;
8526 if (b2_config
& MDM_B2_DISABLE_MNP
)
8528 dlc
[i
] |= DLC_MODEMPROT_DISABLE_MNP_MNP5
;
8530 if (b2_config
& MDM_B2_DISABLE_TRANS
)
8532 dlc
[i
] |= DLC_MODEMPROT_REQUIRE_PROTOCOL
;
8534 if (b2_config
& MDM_B2_DISABLE_V42
)
8536 dlc
[i
] |= DLC_MODEMPROT_DISABLE_V42_DETECT
;
8538 if (b2_config
& MDM_B2_DISABLE_COMP
)
8540 dlc
[i
] |= DLC_MODEMPROT_DISABLE_COMPRESSION
;
8547 dlc
[i
++] = 3; /* Addr A */
8548 dlc
[i
++] = 1; /* Addr B */
8549 dlc
[i
++] = 7; /* modulo mode */
8550 dlc
[i
++] = 7; /* window size */
8551 dlc
[i
++] = 0; /* XID len Lo */
8552 dlc
[i
++] = 0; /* XID len Hi */
8553 dlc
[i
++] = DLC_MODEMPROT_DISABLE_V42_V42BIS
|
8554 DLC_MODEMPROT_DISABLE_MNP_MNP5
|
8555 DLC_MODEMPROT_DISABLE_V42_DETECT
|
8556 DLC_MODEMPROT_DISABLE_COMPRESSION
;
8558 dlc
[0] = (byte
)(i
- 1);
8559 /* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
8560 add_p(plci
, DLC
, dlc
);
8565 /*------------------------------------------------------------------*/
8566 /* send a request for the signaling entity */
8567 /*------------------------------------------------------------------*/
8569 static void sig_req(PLCI
*plci
, byte req
, byte Id
)
8572 if (plci
->adapter
->adapter_disabled
) return;
8573 dbug(1, dprintf("sig_req(%x)", req
));
8575 plci
->sig_remove_id
= plci
->Sig
.Id
;
8576 if (plci
->req_in
== plci
->req_in_start
) {
8578 plci
->RBuffer
[plci
->req_in
++] = 0;
8580 PUT_WORD(&plci
->RBuffer
[plci
->req_in_start
], plci
->req_in
-plci
->req_in_start
- 2);
8581 plci
->RBuffer
[plci
->req_in
++] = Id
; /* sig/nl flag */
8582 plci
->RBuffer
[plci
->req_in
++] = req
; /* request */
8583 plci
->RBuffer
[plci
->req_in
++] = 0; /* channel */
8584 plci
->req_in_start
= plci
->req_in
;
8587 /*------------------------------------------------------------------*/
8588 /* send a request for the network layer entity */
8589 /*------------------------------------------------------------------*/
8591 static void nl_req_ncci(PLCI
*plci
, byte req
, byte ncci
)
8594 if (plci
->adapter
->adapter_disabled
) return;
8595 dbug(1, dprintf("nl_req %02x %02x %02x", plci
->Id
, req
, ncci
));
8598 plci
->nl_remove_id
= plci
->NL
.Id
;
8599 ncci_remove(plci
, 0, (byte
)(ncci
!= 0));
8602 if (plci
->req_in
== plci
->req_in_start
) {
8604 plci
->RBuffer
[plci
->req_in
++] = 0;
8606 PUT_WORD(&plci
->RBuffer
[plci
->req_in_start
], plci
->req_in
-plci
->req_in_start
- 2);
8607 plci
->RBuffer
[plci
->req_in
++] = 1; /* sig/nl flag */
8608 plci
->RBuffer
[plci
->req_in
++] = req
; /* request */
8609 plci
->RBuffer
[plci
->req_in
++] = plci
->adapter
->ncci_ch
[ncci
]; /* channel */
8610 plci
->req_in_start
= plci
->req_in
;
8613 static void send_req(PLCI
*plci
)
8620 if (plci
->adapter
->adapter_disabled
) return;
8621 channel_xmit_xon(plci
);
8623 /* if nothing to do, return */
8624 if (plci
->req_in
== plci
->req_out
) return;
8625 dbug(1, dprintf("send_req(in=%d,out=%d)", plci
->req_in
, plci
->req_out
));
8627 if (plci
->nl_req
|| plci
->sig_req
) return;
8629 l
= GET_WORD(&plci
->RBuffer
[plci
->req_out
]);
8631 plci
->XData
[0].P
= &plci
->RBuffer
[plci
->req_out
];
8633 if (plci
->RBuffer
[plci
->req_out
] == 1)
8637 e
->Req
= plci
->nl_req
= plci
->RBuffer
[plci
->req_out
++];
8638 e
->ReqCh
= plci
->RBuffer
[plci
->req_out
++];
8639 if (!(e
->Id
& 0x1f))
8642 plci
->RBuffer
[plci
->req_out
- 4] = CAI
;
8643 plci
->RBuffer
[plci
->req_out
- 3] = 1;
8644 plci
->RBuffer
[plci
->req_out
- 2] = (plci
->Sig
.Id
== 0xff) ? 0 : plci
->Sig
.Id
;
8645 plci
->RBuffer
[plci
->req_out
- 1] = 0;
8647 plci
->nl_global_req
= plci
->nl_req
;
8649 dbug(1, dprintf("%x:NLREQ(%x:%x:%x)", plci
->adapter
->Id
, e
->Id
, e
->Req
, e
->ReqCh
));
8654 if (plci
->RBuffer
[plci
->req_out
])
8655 e
->Id
= plci
->RBuffer
[plci
->req_out
];
8657 e
->Req
= plci
->sig_req
= plci
->RBuffer
[plci
->req_out
++];
8658 e
->ReqCh
= plci
->RBuffer
[plci
->req_out
++];
8659 if (!(e
->Id
& 0x1f))
8660 plci
->sig_global_req
= plci
->sig_req
;
8661 dbug(1, dprintf("%x:SIGREQ(%x:%x:%x)", plci
->adapter
->Id
, e
->Id
, e
->Req
, e
->ReqCh
));
8663 plci
->XData
[0].PLength
= l
;
8665 plci
->adapter
->request(e
);
8666 dbug(1, dprintf("send_ok"));
8669 static void send_data(PLCI
*plci
)
8671 DIVA_CAPI_ADAPTER
*a
;
8676 if (!plci
->nl_req
&& plci
->ncci_ring_list
)
8679 ncci
= plci
->ncci_ring_list
;
8682 ncci
= a
->ncci_next
[ncci
];
8683 ncci_ptr
= &(a
->ncci
[ncci
]);
8684 if (!(a
->ncci_ch
[ncci
]
8685 && (a
->ch_flow_control
[a
->ncci_ch
[ncci
]] & N_OK_FC_PENDING
)))
8687 if (ncci_ptr
->data_pending
)
8689 if ((a
->ncci_state
[ncci
] == CONNECTED
)
8690 || (a
->ncci_state
[ncci
] == INC_ACT_PENDING
)
8691 || (plci
->send_disc
== ncci
))
8693 data
= &(ncci_ptr
->DBuffer
[ncci_ptr
->data_out
]);
8694 if ((plci
->B2_prot
== B2_V120_ASYNC
)
8695 || (plci
->B2_prot
== B2_V120_ASYNC_V42BIS
)
8696 || (plci
->B2_prot
== B2_V120_BIT_TRANSPARENT
))
8698 plci
->NData
[1].P
= TransmitBufferGet(plci
->appl
, data
->P
);
8699 plci
->NData
[1].PLength
= data
->Length
;
8700 if (data
->Flags
& 0x10)
8701 plci
->NData
[0].P
= v120_break_header
;
8703 plci
->NData
[0].P
= v120_default_header
;
8704 plci
->NData
[0].PLength
= 1;
8706 plci
->NL
.Req
= plci
->nl_req
= (byte
)((data
->Flags
& 0x07) << 4 | N_DATA
);
8710 plci
->NData
[0].P
= TransmitBufferGet(plci
->appl
, data
->P
);
8711 plci
->NData
[0].PLength
= data
->Length
;
8712 if (data
->Flags
& 0x10)
8713 plci
->NL
.Req
= plci
->nl_req
= (byte
)N_UDATA
;
8715 else if ((plci
->B3_prot
== B3_RTP
) && (data
->Flags
& 0x01))
8716 plci
->NL
.Req
= plci
->nl_req
= (byte
)N_BDATA
;
8719 plci
->NL
.Req
= plci
->nl_req
= (byte
)((data
->Flags
& 0x07) << 4 | N_DATA
);
8721 plci
->NL
.X
= plci
->NData
;
8722 plci
->NL
.ReqCh
= a
->ncci_ch
[ncci
];
8723 dbug(1, dprintf("%x:DREQ(%x:%x)", a
->Id
, plci
->NL
.Id
, plci
->NL
.Req
));
8724 plci
->data_sent
= true;
8725 plci
->data_sent_ptr
= data
->P
;
8726 a
->request(&plci
->NL
);
8729 cleanup_ncci_data(plci
, ncci
);
8732 else if (plci
->send_disc
== ncci
)
8734 /* dprintf("N_DISC"); */
8735 plci
->NData
[0].PLength
= 0;
8736 plci
->NL
.ReqCh
= a
->ncci_ch
[ncci
];
8737 plci
->NL
.Req
= plci
->nl_req
= N_DISC
;
8738 a
->request(&plci
->NL
);
8739 plci
->command
= _DISCONNECT_B3_R
;
8740 plci
->send_disc
= 0;
8743 } while (!plci
->nl_req
&& (ncci
!= plci
->ncci_ring_list
));
8744 plci
->ncci_ring_list
= ncci
;
8748 static void listen_check(DIVA_CAPI_ADAPTER
*a
)
8752 byte activnotifiedcalls
= 0;
8754 dbug(1, dprintf("listen_check(%d,%d)", a
->listen_active
, a
->max_listen
));
8755 if (!remove_started
&& !a
->adapter_disabled
)
8757 for (i
= 0; i
< a
->max_plci
; i
++)
8759 plci
= &(a
->plci
[i
]);
8760 if (plci
->notifiedcall
) activnotifiedcalls
++;
8762 dbug(1, dprintf("listen_check(%d)", activnotifiedcalls
));
8764 for (i
= a
->listen_active
; i
< ((word
)(a
->max_listen
+ activnotifiedcalls
)); i
++) {
8765 if ((j
= get_plci(a
))) {
8767 plci
= &a
->plci
[j
- 1];
8768 plci
->State
= LISTENING
;
8770 add_p(plci
, OAD
, "\x01\xfd");
8772 add_p(plci
, KEY
, "\x04\x43\x41\x32\x30");
8774 add_p(plci
, CAI
, "\x01\xc0");
8775 add_p(plci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
8776 add_p(plci
, LLI
, "\x01\xc4"); /* support Dummy CR FAC + MWI + SpoofNotify */
8777 add_p(plci
, SHIFT
| 6, NULL
);
8778 add_p(plci
, SIN
, "\x02\x00\x00");
8779 plci
->internal_command
= LISTEN_SIG_ASSIGN_PEND
; /* do indicate_req if OK */
8780 sig_req(plci
, ASSIGN
, DSIG_ID
);
8787 /*------------------------------------------------------------------*/
8788 /* functions for all parameters sent in INDs */
8789 /*------------------------------------------------------------------*/
8791 static void IndParse(PLCI
*plci
, const word
*parms_id
, byte
**parms
, byte multiIEsize
)
8793 word ploc
; /* points to current location within packet */
8805 in
= plci
->Sig
.RBuffer
->P
;
8806 for (i
= 0; i
< parms_id
[0]; i
++) /* multiIE parms_id contains just the 1st */
8807 { /* element but parms array is larger */
8808 parms
[i
] = (byte
*)"";
8810 for (i
= 0; i
< multiIEsize
; i
++)
8812 parms
[i
] = (byte
*)"";
8815 while (ploc
< plci
->Sig
.RBuffer
->length
- 1) {
8817 /* read information element id and length */
8821 /* w &=0xf0; removed, cannot detect congestion levels */
8822 /* upper 4 bit masked with w==SHIFT now */
8826 wlen
= (byte
)(in
[ploc
+ 1] + 1);
8828 /* check if length valid (not exceeding end of packet) */
8829 if ((ploc
+ wlen
) > 270) return;
8830 if (lock
& 0x80) lock
&= 0x7f;
8831 else codeset
= lock
;
8833 if ((w
& 0xf0) == SHIFT
) {
8835 if (!(codeset
& 0x08)) lock
= (byte
)(codeset
& 7);
8840 if (w
== ESC
&& wlen
>= 3) code
= in
[ploc
+ 2] | 0x800;
8842 code
|= (codeset
<< 8);
8844 for (i
= 1; i
< parms_id
[0] + 1 && parms_id
[i
] != code
; i
++);
8846 if (i
< parms_id
[0] + 1) {
8847 if (!multiIEsize
) { /* with multiIEs use next field index, */
8848 mIEindex
= i
- 1; /* with normal IEs use same index like parms_id */
8851 parms
[mIEindex
] = &in
[ploc
+ 1];
8852 dbug(1, dprintf("mIE[%d]=0x%x", *parms
[mIEindex
], in
[ploc
]));
8853 if (parms_id
[i
] == OAD
8854 || parms_id
[i
] == CONN_NR
8855 || parms_id
[i
] == CAD
) {
8856 if (in
[ploc
+ 2] & 0x80) {
8857 in
[ploc
+ 0] = (byte
)(in
[ploc
+ 1] + 1);
8858 in
[ploc
+ 1] = (byte
)(in
[ploc
+ 2] & 0x7f);
8859 in
[ploc
+ 2] = 0x80;
8860 parms
[mIEindex
] = &in
[ploc
];
8863 mIEindex
++; /* effects multiIEs only */
8872 /*------------------------------------------------------------------*/
8873 /* try to match a cip from received BC and HLC */
8874 /*------------------------------------------------------------------*/
8876 static byte
ie_compare(byte
*ie1
, byte
*ie2
)
8879 if (!ie1
|| !ie2
) return false;
8880 if (!ie1
[0]) return false;
8881 for (i
= 0; i
< (word
)(ie1
[0] + 1); i
++) if (ie1
[i
] != ie2
[i
]) return false;
8885 static word
find_cip(DIVA_CAPI_ADAPTER
*a
, byte
*bc
, byte
*hlc
)
8890 for (i
= 9; i
&& !ie_compare(bc
, cip_bc
[i
][a
->u_law
]); i
--);
8892 for (j
= 16; j
< 29 &&
8893 (!ie_compare(bc
, cip_bc
[j
][a
->u_law
]) || !ie_compare(hlc
, cip_hlc
[j
])); j
++);
8894 if (j
== 29) return i
;
8899 static byte
AddInfo(byte
**add_i
,
8909 /* facility is a nested structure */
8910 /* FTY can be more than once */
8912 if (esc_chi
[0] && !(esc_chi
[esc_chi
[0]] & 0x7f))
8914 add_i
[0] = (byte
*)"\x02\x02\x00"; /* use neither b nor d channel */
8919 add_i
[0] = (byte
*)"";
8923 add_i
[3] = (byte
*)"";
8926 { /* facility array found */
8927 for (i
= 0, j
= 1; i
< MAX_MULTI_IE
&& fty_i
[i
][0]; i
++)
8929 dbug(1, dprintf("AddIFac[%d]", fty_i
[i
][0]));
8933 facility
[j
++] = 0x1c; /* copy fac IE */
8934 for (k
= 0; k
<= flen
; k
++, j
++)
8936 facility
[j
] = fty_i
[i
][k
];
8937 /* dbug(1, dprintf("%x ",facility[j])); */
8941 add_i
[3] = facility
;
8943 /* dbug(1, dprintf("FacArrLen=%d ",len)); */
8944 len
= add_i
[0][0] + add_i
[1][0] + add_i
[2][0] + add_i
[3][0];
8945 len
+= 4; /* calculate length of all */
8949 /*------------------------------------------------------------------*/
8950 /* voice and codec features */
8951 /*------------------------------------------------------------------*/
8953 static void SetVoiceChannel(PLCI
*plci
, byte
*chi
, DIVA_CAPI_ADAPTER
*a
)
8955 byte voice_chi
[] = "\x02\x18\x01";
8958 channel
= chi
[chi
[0]] & 0x3;
8959 dbug(1, dprintf("ExtDevON(Ch=0x%x)", channel
));
8960 voice_chi
[2] = (channel
) ? channel
: 1;
8961 add_p(plci
, FTY
, "\x02\x01\x07"); /* B On, default on 1 */
8962 add_p(plci
, ESC
, voice_chi
); /* Channel */
8963 sig_req(plci
, TEL_CTRL
, 0);
8965 if (a
->AdvSignalPLCI
)
8967 adv_voice_write_coefs(a
->AdvSignalPLCI
, ADV_VOICE_WRITE_ACTIVATION
);
8971 static void VoiceChannelOff(PLCI
*plci
)
8973 dbug(1, dprintf("ExtDevOFF"));
8974 add_p(plci
, FTY
, "\x02\x01\x08"); /* B Off */
8975 sig_req(plci
, TEL_CTRL
, 0);
8977 if (plci
->adapter
->AdvSignalPLCI
)
8979 adv_voice_clear_config(plci
->adapter
->AdvSignalPLCI
);
8984 static word
AdvCodecSupport(DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
,
8990 /* check if hardware supports handset with hook states (adv.codec) */
8991 /* or if just a on board codec is supported */
8992 /* the advanced codec plci is just for internal use */
8994 /* diva Pro with on-board codec: */
8995 if (a
->profile
.Global_Options
& HANDSET
)
8997 /* new call, but hook states are already signalled */
8998 if (a
->AdvCodecFLAG
)
9000 if (a
->AdvSignalAppl
!= appl
|| a
->AdvSignalPLCI
)
9002 dbug(1, dprintf("AdvSigPlci=0x%x", a
->AdvSignalPLCI
));
9003 return 0x2001; /* codec in use by another application */
9007 a
->AdvSignalPLCI
= plci
;
9008 plci
->tel
= ADV_VOICE
;
9010 return 0; /* adv codec still used */
9012 if ((j
= get_plci(a
)))
9014 splci
= &a
->plci
[j
- 1];
9015 splci
->tel
= CODEC_PERMANENT
;
9016 /* hook_listen indicates if a facility_req with handset/hook support */
9017 /* was sent. Otherwise if just a call on an external device was made */
9018 /* the codec will be used but the hook info will be discarded (just */
9019 /* the external controller is in use */
9020 if (hook_listen
) splci
->State
= ADVANCED_VOICE_SIG
;
9023 splci
->State
= ADVANCED_VOICE_NOSIG
;
9026 plci
->spoofed_msg
= SPOOFING_REQUIRED
;
9028 /* indicate D-ch connect if */
9029 } /* codec is connected OK */
9032 a
->AdvSignalPLCI
= plci
;
9033 plci
->tel
= ADV_VOICE
;
9035 a
->AdvSignalAppl
= appl
;
9036 a
->AdvCodecFLAG
= true;
9037 a
->AdvCodecPLCI
= splci
;
9038 add_p(splci
, CAI
, "\x01\x15");
9039 add_p(splci
, LLI
, "\x01\x00");
9040 add_p(splci
, ESC
, "\x02\x18\x00");
9041 add_p(splci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
9042 splci
->internal_command
= PERM_COD_ASSIGN
;
9043 dbug(1, dprintf("Codec Assign"));
9044 sig_req(splci
, ASSIGN
, DSIG_ID
);
9049 return 0x2001; /* wrong state, no more plcis */
9052 else if (a
->profile
.Global_Options
& ON_BOARD_CODEC
)
9054 if (hook_listen
) return 0x300B; /* Facility not supported */
9055 /* no hook with SCOM */
9056 if (plci
!= NULL
) plci
->tel
= CODEC
;
9057 dbug(1, dprintf("S/SCOM codec"));
9058 /* first time we use the scom-s codec we must shut down the internal */
9059 /* handset application of the card. This can be done by an assign with */
9060 /* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/
9061 if (!a
->scom_appl_disable
) {
9062 if ((j
= get_plci(a
))) {
9063 splci
= &a
->plci
[j
- 1];
9064 add_p(splci
, CAI
, "\x01\x80");
9065 add_p(splci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
9066 sig_req(splci
, ASSIGN
, 0xC0); /* 0xc0 is the TEL_ID */
9068 a
->scom_appl_disable
= true;
9071 return 0x2001; /* wrong state, no more plcis */
9075 else return 0x300B; /* Facility not supported */
9081 static void CodecIdCheck(DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
)
9084 dbug(1, dprintf("CodecIdCheck"));
9086 if (a
->AdvSignalPLCI
== plci
)
9088 dbug(1, dprintf("PLCI owns codec"));
9089 VoiceChannelOff(a
->AdvCodecPLCI
);
9090 if (a
->AdvCodecPLCI
->State
== ADVANCED_VOICE_NOSIG
)
9092 dbug(1, dprintf("remove temp codec PLCI"));
9093 plci_remove(a
->AdvCodecPLCI
);
9094 a
->AdvCodecFLAG
= 0;
9095 a
->AdvCodecPLCI
= NULL
;
9096 a
->AdvSignalAppl
= NULL
;
9098 a
->AdvSignalPLCI
= NULL
;
9102 /* -------------------------------------------------------------------
9103 Ask for physical address of card on PCI bus
9104 ------------------------------------------------------------------- */
9105 static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER
*a
,
9106 IDI_SYNC_REQ
*preq
) {
9108 if (diva_xdi_extended_features
& DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR
) {
9109 ENTITY
*e
= (ENTITY
*)preq
;
9111 e
->user
[0] = a
->Id
- 1;
9112 preq
->xdi_sdram_bar
.info
.bar
= 0;
9113 preq
->xdi_sdram_bar
.Req
= 0;
9114 preq
->xdi_sdram_bar
.Rc
= IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR
;
9118 a
->sdram_bar
= preq
->xdi_sdram_bar
.info
.bar
;
9119 dbug(3, dprintf("A(%d) SDRAM BAR = %08x", a
->Id
, a
->sdram_bar
));
9123 /* -------------------------------------------------------------------
9124 Ask XDI about extended features
9125 ------------------------------------------------------------------- */
9126 static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER
*a
) {
9128 char buffer
[((sizeof(preq
->xdi_extended_features
) + 4) > sizeof(ENTITY
)) ? (sizeof(preq
->xdi_extended_features
) + 4) : sizeof(ENTITY
)];
9131 preq
= (IDI_SYNC_REQ
*)&buffer
[0];
9133 if (!diva_xdi_extended_features
) {
9134 ENTITY
*e
= (ENTITY
*)preq
;
9135 diva_xdi_extended_features
|= 0x80000000;
9137 e
->user
[0] = a
->Id
- 1;
9138 preq
->xdi_extended_features
.Req
= 0;
9139 preq
->xdi_extended_features
.Rc
= IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES
;
9140 preq
->xdi_extended_features
.info
.buffer_length_in_bytes
= sizeof(features
);
9141 preq
->xdi_extended_features
.info
.features
= &features
[0];
9145 if (features
[0] & DIVA_XDI_EXTENDED_FEATURES_VALID
) {
9147 Check features located in the byte '0'
9149 if (features
[0] & DIVA_XDI_EXTENDED_FEATURE_CMA
) {
9150 diva_xdi_extended_features
|= DIVA_CAPI_USE_CMA
;
9152 if (features
[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA
) {
9153 diva_xdi_extended_features
|= DIVA_CAPI_XDI_PROVIDES_RX_DMA
;
9154 dbug(1, dprintf("XDI provides RxDMA"));
9156 if (features
[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR
) {
9157 diva_xdi_extended_features
|= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR
;
9159 if (features
[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC
) {
9160 diva_xdi_extended_features
|= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL
;
9161 dbug(3, dprintf("XDI provides NO_CANCEL_RC feature"));
9167 diva_ask_for_xdi_sdram_bar(a
, preq
);
9170 /*------------------------------------------------------------------*/
9172 /*------------------------------------------------------------------*/
9173 /* called from OS specific part after init time to get the Law */
9174 /* a-law (Euro) and u-law (us,japan) use different BCs in the Setup message */
9175 void AutomaticLaw(DIVA_CAPI_ADAPTER
*a
)
9180 if (a
->automatic_law
) {
9183 if ((j
= get_plci(a
))) {
9184 diva_get_extended_adapter_features(a
);
9185 splci
= &a
->plci
[j
- 1];
9186 a
->automatic_lawPLCI
= splci
;
9187 a
->automatic_law
= 1;
9188 add_p(splci
, CAI
, "\x01\x80");
9189 add_p(splci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
9190 splci
->internal_command
= USELAW_REQ
;
9193 sig_req(splci
, ASSIGN
, DSIG_ID
);
9198 /* called from OS specific part if an application sends an Capi20Release */
9199 word
CapiRelease(word Id
)
9201 word i
, j
, appls_found
;
9204 DIVA_CAPI_ADAPTER
*a
;
9208 dbug(0, dprintf("A: CapiRelease(Id==0)"));
9209 return (_WRONG_APPL_ID
);
9212 this = &application
[Id
- 1]; /* get application pointer */
9214 for (i
= 0, appls_found
= 0; i
< max_appl
; i
++)
9216 if (application
[i
].Id
) /* an application has been found */
9222 for (i
= 0; i
< max_adapter
; i
++) /* scan all adapters... */
9227 a
->Info_Mask
[Id
- 1] = 0;
9228 a
->CIP_Mask
[Id
- 1] = 0;
9229 a
->Notification_Mask
[Id
- 1] = 0;
9230 a
->codec_listen
[Id
- 1] = NULL
;
9231 a
->requested_options_table
[Id
- 1] = 0;
9232 for (j
= 0; j
< a
->max_plci
; j
++) /* and all PLCIs connected */
9233 { /* with this application */
9235 if (plci
->Id
) /* if plci owns no application */
9236 { /* it may be not jet connected */
9237 if (plci
->State
== INC_CON_PENDING
9238 || plci
->State
== INC_CON_ALERT
)
9240 if (test_bit(Id
- 1, plci
->c_ind_mask_table
))
9242 __clear_bit(Id
- 1, plci
->c_ind_mask_table
);
9243 if (bitmap_empty(plci
->c_ind_mask_table
, MAX_APPL
))
9245 sig_req(plci
, HANGUP
, 0);
9247 plci
->State
= OUTG_DIS_PENDING
;
9251 if (test_bit(Id
- 1, plci
->c_ind_mask_table
))
9253 __clear_bit(Id
- 1, plci
->c_ind_mask_table
);
9254 if (bitmap_empty(plci
->c_ind_mask_table
, MAX_APPL
))
9263 if (plci
->appl
== this)
9273 if (a
->flag_dynamic_l1_down
)
9275 if (appls_found
== 1) /* last application does a capi release */
9277 if ((j
= get_plci(a
)))
9279 plci
= &a
->plci
[j
- 1];
9281 add_p(plci
, OAD
, "\x01\xfd");
9282 add_p(plci
, CAI
, "\x01\x80");
9283 add_p(plci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
9284 add_p(plci
, SHIFT
| 6, NULL
);
9285 add_p(plci
, SIN
, "\x02\x00\x00");
9286 plci
->internal_command
= REM_L1_SIG_ASSIGN_PEND
;
9287 sig_req(plci
, ASSIGN
, DSIG_ID
);
9288 add_p(plci
, FTY
, "\x02\xff\x06"); /* l1 down */
9289 sig_req(plci
, SIG_CTRL
, 0);
9294 if (a
->AdvSignalAppl
== this)
9296 this->NullCREnable
= false;
9297 if (a
->AdvCodecPLCI
)
9299 plci_remove(a
->AdvCodecPLCI
);
9300 a
->AdvCodecPLCI
->tel
= 0;
9301 a
->AdvCodecPLCI
->adv_nl
= 0;
9303 a
->AdvSignalAppl
= NULL
;
9304 a
->AdvSignalPLCI
= NULL
;
9305 a
->AdvCodecFLAG
= 0;
9306 a
->AdvCodecPLCI
= NULL
;
9316 static word
plci_remove_check(PLCI
*plci
)
9318 if (!plci
) return true;
9319 if (!plci
->NL
.Id
&& bitmap_empty(plci
->c_ind_mask_table
, MAX_APPL
))
9321 if (plci
->Sig
.Id
== 0xff)
9325 dbug(1, dprintf("plci_remove_complete(%x)", plci
->Id
));
9326 dbug(1, dprintf("tel=0x%x,Sig=0x%x", plci
->tel
, plci
->Sig
.Id
));
9329 CodecIdCheck(plci
->adapter
, plci
);
9330 clear_b1_config(plci
);
9331 ncci_remove(plci
, 0, false);
9332 plci_free_msg_in_queue(plci
);
9333 channel_flow_control_remove(plci
);
9338 plci
->notifiedcall
= 0;
9340 listen_check(plci
->adapter
);
9348 /*------------------------------------------------------------------*/
9350 static byte
plci_nl_busy(PLCI
*plci
)
9352 /* only applicable for non-multiplexed protocols */
9353 return (plci
->nl_req
9354 || (plci
->ncci_ring_list
9355 && plci
->adapter
->ncci_ch
[plci
->ncci_ring_list
]
9356 && (plci
->adapter
->ch_flow_control
[plci
->adapter
->ncci_ch
[plci
->ncci_ring_list
]] & N_OK_FC_PENDING
)));
9360 /*------------------------------------------------------------------*/
9361 /* DTMF facilities */
9362 /*------------------------------------------------------------------*/
9371 } dtmf_digit_map
[] =
9373 { 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK
},
9374 { 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR
},
9375 { 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0
},
9376 { 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1
},
9377 { 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2
},
9378 { 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3
},
9379 { 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4
},
9380 { 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5
},
9381 { 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6
},
9382 { 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7
},
9383 { 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8
},
9384 { 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9
},
9385 { 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A
},
9386 { 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B
},
9387 { 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C
},
9388 { 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D
},
9389 { 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A
},
9390 { 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B
},
9391 { 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C
},
9392 { 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D
},
9394 { 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE
},
9395 { 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE
},
9396 { 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE
},
9397 { 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE
},
9398 { 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE
},
9399 { 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE
},
9400 { 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE
},
9401 { 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE
},
9402 { 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE
},
9403 { 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE
},
9404 { 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE
},
9405 { 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE
},
9406 { 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE
},
9407 { 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE
},
9408 { 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE
},
9409 { 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE
},
9410 { 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE
},
9411 { 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE
},
9412 { 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE
},
9413 { 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE
},
9414 { 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE
},
9415 { 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE
},
9416 { 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE
},
9417 { 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL
},
9418 { 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE
},
9419 { 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE
},
9420 { 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE
},
9421 { 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE
},
9422 { 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE
},
9423 { 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE
},
9424 { 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE
},
9425 { 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE
},
9426 { 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE
},
9427 { 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS
},
9428 { 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID
},
9429 { 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH
},
9430 { 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390
},
9431 { 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1
},
9432 { 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2
},
9433 { 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3
},
9434 { 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4
},
9435 { 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5
},
9436 { 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6
},
9437 { 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7
},
9438 { 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8
},
9439 { 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9
},
9440 { 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0
},
9441 { 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1
},
9442 { 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2
},
9443 { 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP
},
9444 { 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1
},
9445 { 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST
},
9449 #define DTMF_DIGIT_MAP_ENTRIES ARRAY_SIZE(dtmf_digit_map)
9452 static void dtmf_enable_receiver(PLCI
*plci
, byte enable_mask
)
9454 word min_digit_duration
, min_gap_duration
;
9456 dbug(1, dprintf("[%06lx] %s,%d: dtmf_enable_receiver %02x",
9457 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
9458 (char *)(FILE_
), __LINE__
, enable_mask
));
9460 if (enable_mask
!= 0)
9462 min_digit_duration
= (plci
->dtmf_rec_pulse_ms
== 0) ? 40 : plci
->dtmf_rec_pulse_ms
;
9463 min_gap_duration
= (plci
->dtmf_rec_pause_ms
== 0) ? 40 : plci
->dtmf_rec_pause_ms
;
9464 plci
->internal_req_buffer
[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER
;
9465 PUT_WORD(&plci
->internal_req_buffer
[1], min_digit_duration
);
9466 PUT_WORD(&plci
->internal_req_buffer
[3], min_gap_duration
);
9467 plci
->NData
[0].PLength
= 5;
9469 PUT_WORD(&plci
->internal_req_buffer
[5], INTERNAL_IND_BUFFER_SIZE
);
9470 plci
->NData
[0].PLength
+= 2;
9471 capidtmf_recv_enable(&(plci
->capidtmf_state
), min_digit_duration
, min_gap_duration
);
9476 plci
->internal_req_buffer
[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER
;
9477 plci
->NData
[0].PLength
= 1;
9479 capidtmf_recv_disable(&(plci
->capidtmf_state
));
9482 plci
->NData
[0].P
= plci
->internal_req_buffer
;
9483 plci
->NL
.X
= plci
->NData
;
9485 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
9486 plci
->adapter
->request(&plci
->NL
);
9490 static void dtmf_send_digits(PLCI
*plci
, byte
*digit_buffer
, word digit_count
)
9494 dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_digits %d",
9495 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
9496 (char *)(FILE_
), __LINE__
, digit_count
));
9498 plci
->internal_req_buffer
[0] = DTMF_UDATA_REQUEST_SEND_DIGITS
;
9499 w
= (plci
->dtmf_send_pulse_ms
== 0) ? 40 : plci
->dtmf_send_pulse_ms
;
9500 PUT_WORD(&plci
->internal_req_buffer
[1], w
);
9501 w
= (plci
->dtmf_send_pause_ms
== 0) ? 40 : plci
->dtmf_send_pause_ms
;
9502 PUT_WORD(&plci
->internal_req_buffer
[3], w
);
9503 for (i
= 0; i
< digit_count
; i
++)
9506 while ((w
< DTMF_DIGIT_MAP_ENTRIES
)
9507 && (digit_buffer
[i
] != dtmf_digit_map
[w
].character
))
9511 plci
->internal_req_buffer
[5 + i
] = (w
< DTMF_DIGIT_MAP_ENTRIES
) ?
9512 dtmf_digit_map
[w
].code
: DTMF_DIGIT_TONE_CODE_STAR
;
9514 plci
->NData
[0].PLength
= 5 + digit_count
;
9515 plci
->NData
[0].P
= plci
->internal_req_buffer
;
9516 plci
->NL
.X
= plci
->NData
;
9518 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
9519 plci
->adapter
->request(&plci
->NL
);
9523 static void dtmf_rec_clear_config(PLCI
*plci
)
9526 dbug(1, dprintf("[%06lx] %s,%d: dtmf_rec_clear_config",
9527 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
9528 (char *)(FILE_
), __LINE__
));
9530 plci
->dtmf_rec_active
= 0;
9531 plci
->dtmf_rec_pulse_ms
= 0;
9532 plci
->dtmf_rec_pause_ms
= 0;
9534 capidtmf_init(&(plci
->capidtmf_state
), plci
->adapter
->u_law
);
9539 static void dtmf_send_clear_config(PLCI
*plci
)
9542 dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_clear_config",
9543 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
9544 (char *)(FILE_
), __LINE__
));
9546 plci
->dtmf_send_requests
= 0;
9547 plci
->dtmf_send_pulse_ms
= 0;
9548 plci
->dtmf_send_pause_ms
= 0;
9552 static void dtmf_prepare_switch(dword Id
, PLCI
*plci
)
9555 dbug(1, dprintf("[%06lx] %s,%d: dtmf_prepare_switch",
9556 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9558 while (plci
->dtmf_send_requests
!= 0)
9559 dtmf_confirmation(Id
, plci
);
9563 static word
dtmf_save_config(dword Id
, PLCI
*plci
, byte Rc
)
9566 dbug(1, dprintf("[%06lx] %s,%d: dtmf_save_config %02x %d",
9567 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
9573 static word
dtmf_restore_config(dword Id
, PLCI
*plci
, byte Rc
)
9577 dbug(1, dprintf("[%06lx] %s,%d: dtmf_restore_config %02x %d",
9578 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
9581 if (plci
->B1_facilities
& B1_FACILITY_DTMFR
)
9583 switch (plci
->adjust_b_state
)
9585 case ADJUST_B_RESTORE_DTMF_1
:
9586 plci
->internal_command
= plci
->adjust_b_command
;
9587 if (plci_nl_busy(plci
))
9589 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_1
;
9592 dtmf_enable_receiver(plci
, plci
->dtmf_rec_active
);
9593 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_2
;
9595 case ADJUST_B_RESTORE_DTMF_2
:
9596 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
9598 dbug(1, dprintf("[%06lx] %s,%d: Reenable DTMF receiver failed %02x",
9599 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
9600 Info
= _WRONG_STATE
;
9610 static void dtmf_command(dword Id
, PLCI
*plci
, byte Rc
)
9612 word internal_command
, Info
;
9616 dbug(1, dprintf("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d",
9617 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
,
9618 plci
->dtmf_cmd
, plci
->dtmf_rec_pulse_ms
, plci
->dtmf_rec_pause_ms
,
9619 plci
->dtmf_send_pulse_ms
, plci
->dtmf_send_pause_ms
));
9623 PUT_WORD(&result
[1], DTMF_SUCCESS
);
9624 internal_command
= plci
->internal_command
;
9625 plci
->internal_command
= 0;
9627 switch (plci
->dtmf_cmd
)
9630 case DTMF_LISTEN_TONE_START
:
9631 mask
<<= 1; /* fall through */
9632 case DTMF_LISTEN_MF_START
:
9633 mask
<<= 1; /* fall through */
9635 case DTMF_LISTEN_START
:
9636 switch (internal_command
)
9639 adjust_b1_resource(Id
, plci
, NULL
, (word
)(plci
->B1_facilities
|
9640 B1_FACILITY_DTMFR
), DTMF_COMMAND_1
);
9642 case DTMF_COMMAND_1
:
9643 if (adjust_b_process(Id
, plci
, Rc
) != GOOD
)
9645 dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed",
9646 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9647 Info
= _FACILITY_NOT_SUPPORTED
;
9650 if (plci
->internal_command
)
9653 case DTMF_COMMAND_2
:
9654 if (plci_nl_busy(plci
))
9656 plci
->internal_command
= DTMF_COMMAND_2
;
9659 plci
->internal_command
= DTMF_COMMAND_3
;
9660 dtmf_enable_receiver(plci
, (byte
)(plci
->dtmf_rec_active
| mask
));
9662 case DTMF_COMMAND_3
:
9663 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
9665 dbug(1, dprintf("[%06lx] %s,%d: Enable DTMF receiver failed %02x",
9666 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
9667 Info
= _FACILITY_NOT_SUPPORTED
;
9671 plci
->tone_last_indication_code
= DTMF_SIGNAL_NO_TONE
;
9673 plci
->dtmf_rec_active
|= mask
;
9679 case DTMF_LISTEN_TONE_STOP
:
9680 mask
<<= 1; /* fall through */
9681 case DTMF_LISTEN_MF_STOP
:
9682 mask
<<= 1; /* fall through */
9684 case DTMF_LISTEN_STOP
:
9685 switch (internal_command
)
9688 plci
->dtmf_rec_active
&= ~mask
;
9689 if (plci
->dtmf_rec_active
)
9692 case DTMF_COMMAND_1:
9693 if (plci->dtmf_rec_active)
9695 if (plci_nl_busy (plci))
9697 plci->internal_command = DTMF_COMMAND_1;
9700 plci->dtmf_rec_active &= ~mask;
9701 plci->internal_command = DTMF_COMMAND_2;
9702 dtmf_enable_receiver (plci, false);
9706 case DTMF_COMMAND_2:
9707 if ((Rc != OK) && (Rc != OK_FC))
9709 dbug (1, dprintf("[%06lx] %s,%d: Disable DTMF receiver failed %02x",
9710 UnMapId (Id), (char far *)(FILE_), __LINE__, Rc));
9711 Info = _FACILITY_NOT_SUPPORTED;
9715 adjust_b1_resource(Id
, plci
, NULL
, (word
)(plci
->B1_facilities
&
9716 ~(B1_FACILITY_DTMFX
| B1_FACILITY_DTMFR
)), DTMF_COMMAND_3
);
9718 case DTMF_COMMAND_3
:
9719 if (adjust_b_process(Id
, plci
, Rc
) != GOOD
)
9721 dbug(1, dprintf("[%06lx] %s,%d: Unload DTMF failed",
9722 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9723 Info
= _FACILITY_NOT_SUPPORTED
;
9726 if (plci
->internal_command
)
9733 case DTMF_SEND_TONE
:
9734 mask
<<= 1; /* fall through */
9736 mask
<<= 1; /* fall through */
9738 case DTMF_DIGITS_SEND
:
9739 switch (internal_command
)
9742 adjust_b1_resource(Id
, plci
, NULL
, (word
)(plci
->B1_facilities
|
9743 ((plci
->dtmf_parameter_length
!= 0) ? B1_FACILITY_DTMFX
| B1_FACILITY_DTMFR
: B1_FACILITY_DTMFX
)),
9746 case DTMF_COMMAND_1
:
9747 if (adjust_b_process(Id
, plci
, Rc
) != GOOD
)
9749 dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed",
9750 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9751 Info
= _FACILITY_NOT_SUPPORTED
;
9754 if (plci
->internal_command
)
9757 case DTMF_COMMAND_2
:
9758 if (plci_nl_busy(plci
))
9760 plci
->internal_command
= DTMF_COMMAND_2
;
9763 plci
->dtmf_msg_number_queue
[(plci
->dtmf_send_requests
)++] = plci
->number
;
9764 plci
->internal_command
= DTMF_COMMAND_3
;
9765 dtmf_send_digits(plci
, &plci
->saved_msg
.parms
[3].info
[1], plci
->saved_msg
.parms
[3].length
);
9767 case DTMF_COMMAND_3
:
9768 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
9770 dbug(1, dprintf("[%06lx] %s,%d: Send DTMF digits failed %02x",
9771 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
9772 if (plci
->dtmf_send_requests
!= 0)
9773 (plci
->dtmf_send_requests
)--;
9774 Info
= _FACILITY_NOT_SUPPORTED
;
9781 sendf(plci
->appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, plci
->number
,
9782 "wws", Info
, SELECTOR_DTMF
, result
);
9786 static byte
dtmf_request(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
9791 API_PARSE dtmf_parms
[5];
9794 dbug(1, dprintf("[%06lx] %s,%d: dtmf_request",
9795 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9799 PUT_WORD(&result
[1], DTMF_SUCCESS
);
9800 if (!(a
->profile
.Global_Options
& GL_DTMF_SUPPORTED
))
9802 dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
9803 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9804 Info
= _FACILITY_NOT_SUPPORTED
;
9806 else if (api_parse(&msg
[1].info
[1], msg
[1].length
, "w", dtmf_parms
))
9808 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
9809 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9810 Info
= _WRONG_MESSAGE_FORMAT
;
9813 else if ((GET_WORD(dtmf_parms
[0].info
) == DTMF_GET_SUPPORTED_DETECT_CODES
)
9814 || (GET_WORD(dtmf_parms
[0].info
) == DTMF_GET_SUPPORTED_SEND_CODES
))
9816 if (!((a
->requested_options_table
[appl
->Id
- 1])
9817 & (1L << PRIVATE_DTMF_TONE
)))
9819 dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
9820 UnMapId(Id
), (char *)(FILE_
), __LINE__
, GET_WORD(dtmf_parms
[0].info
)));
9821 PUT_WORD(&result
[1], DTMF_UNKNOWN_REQUEST
);
9825 for (i
= 0; i
< 32; i
++)
9827 if (GET_WORD(dtmf_parms
[0].info
) == DTMF_GET_SUPPORTED_DETECT_CODES
)
9829 for (i
= 0; i
< DTMF_DIGIT_MAP_ENTRIES
; i
++)
9831 if (dtmf_digit_map
[i
].listen_mask
!= 0)
9832 result
[4 + (dtmf_digit_map
[i
].character
>> 3)] |= (1 << (dtmf_digit_map
[i
].character
& 0x7));
9837 for (i
= 0; i
< DTMF_DIGIT_MAP_ENTRIES
; i
++)
9839 if (dtmf_digit_map
[i
].send_mask
!= 0)
9840 result
[4 + (dtmf_digit_map
[i
].character
>> 3)] |= (1 << (dtmf_digit_map
[i
].character
& 0x7));
9848 else if (plci
== NULL
)
9850 dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
9851 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9852 Info
= _WRONG_IDENTIFIER
;
9857 || !plci
->NL
.Id
|| plci
->nl_remove_id
)
9859 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
9860 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9861 Info
= _WRONG_STATE
;
9866 plci
->dtmf_cmd
= GET_WORD(dtmf_parms
[0].info
);
9868 switch (plci
->dtmf_cmd
)
9871 case DTMF_LISTEN_TONE_START
:
9872 case DTMF_LISTEN_TONE_STOP
:
9873 mask
<<= 1; /* fall through */
9874 case DTMF_LISTEN_MF_START
:
9875 case DTMF_LISTEN_MF_STOP
:
9877 if (!((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[appl
->Id
- 1])
9878 & (1L << PRIVATE_DTMF_TONE
)))
9880 dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
9881 UnMapId(Id
), (char *)(FILE_
), __LINE__
, GET_WORD(dtmf_parms
[0].info
)));
9882 PUT_WORD(&result
[1], DTMF_UNKNOWN_REQUEST
);
9887 case DTMF_LISTEN_START
:
9888 case DTMF_LISTEN_STOP
:
9889 if (!(a
->manufacturer_features
& MANUFACTURER_FEATURE_HARDDTMF
)
9890 && !(a
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
))
9892 dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
9893 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9894 Info
= _FACILITY_NOT_SUPPORTED
;
9897 if (mask
& DTMF_LISTEN_ACTIVE_FLAG
)
9899 if (api_parse(&msg
[1].info
[1], msg
[1].length
, "wwws", dtmf_parms
))
9901 plci
->dtmf_rec_pulse_ms
= 0;
9902 plci
->dtmf_rec_pause_ms
= 0;
9906 plci
->dtmf_rec_pulse_ms
= GET_WORD(dtmf_parms
[1].info
);
9907 plci
->dtmf_rec_pause_ms
= GET_WORD(dtmf_parms
[2].info
);
9910 start_internal_command(Id
, plci
, dtmf_command
);
9914 case DTMF_SEND_TONE
:
9915 mask
<<= 1; /* fall through */
9918 if (!((plci
->requested_options_conn
| plci
->requested_options
| plci
->adapter
->requested_options_table
[appl
->Id
- 1])
9919 & (1L << PRIVATE_DTMF_TONE
)))
9921 dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
9922 UnMapId(Id
), (char *)(FILE_
), __LINE__
, GET_WORD(dtmf_parms
[0].info
)));
9923 PUT_WORD(&result
[1], DTMF_UNKNOWN_REQUEST
);
9928 case DTMF_DIGITS_SEND
:
9929 if (api_parse(&msg
[1].info
[1], msg
[1].length
, "wwws", dtmf_parms
))
9931 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
9932 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9933 Info
= _WRONG_MESSAGE_FORMAT
;
9936 if (mask
& DTMF_LISTEN_ACTIVE_FLAG
)
9938 plci
->dtmf_send_pulse_ms
= GET_WORD(dtmf_parms
[1].info
);
9939 plci
->dtmf_send_pause_ms
= GET_WORD(dtmf_parms
[2].info
);
9943 while ((i
< dtmf_parms
[3].length
) && (j
< DTMF_DIGIT_MAP_ENTRIES
))
9946 while ((j
< DTMF_DIGIT_MAP_ENTRIES
)
9947 && ((dtmf_parms
[3].info
[i
+ 1] != dtmf_digit_map
[j
].character
)
9948 || ((dtmf_digit_map
[j
].send_mask
& mask
) == 0)))
9954 if (j
== DTMF_DIGIT_MAP_ENTRIES
)
9956 dbug(1, dprintf("[%06lx] %s,%d: Incorrect DTMF digit %02x",
9957 UnMapId(Id
), (char *)(FILE_
), __LINE__
, dtmf_parms
[3].info
[i
]));
9958 PUT_WORD(&result
[1], DTMF_INCORRECT_DIGIT
);
9961 if (plci
->dtmf_send_requests
>= ARRAY_SIZE(plci
->dtmf_msg_number_queue
))
9963 dbug(1, dprintf("[%06lx] %s,%d: DTMF request overrun",
9964 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9965 Info
= _WRONG_STATE
;
9968 api_save_msg(dtmf_parms
, "wwws", &plci
->saved_msg
);
9969 start_internal_command(Id
, plci
, dtmf_command
);
9973 dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
9974 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci
->dtmf_cmd
));
9975 PUT_WORD(&result
[1], DTMF_UNKNOWN_REQUEST
);
9979 sendf(appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
9980 "wws", Info
, SELECTOR_DTMF
, result
);
9985 static void dtmf_confirmation(dword Id
, PLCI
*plci
)
9990 dbug(1, dprintf("[%06lx] %s,%d: dtmf_confirmation",
9991 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
9994 PUT_WORD(&result
[1], DTMF_SUCCESS
);
9995 if (plci
->dtmf_send_requests
!= 0)
9997 sendf(plci
->appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, plci
->dtmf_msg_number_queue
[0],
9998 "wws", GOOD
, SELECTOR_DTMF
, result
);
9999 (plci
->dtmf_send_requests
)--;
10000 for (i
= 0; i
< plci
->dtmf_send_requests
; i
++)
10001 plci
->dtmf_msg_number_queue
[i
] = plci
->dtmf_msg_number_queue
[i
+ 1];
10006 static void dtmf_indication(dword Id
, PLCI
*plci
, byte
*msg
, word length
)
10010 dbug(1, dprintf("[%06lx] %s,%d: dtmf_indication",
10011 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
10014 for (i
= 1; i
< length
; i
++)
10017 while ((j
< DTMF_DIGIT_MAP_ENTRIES
)
10018 && ((msg
[i
] != dtmf_digit_map
[j
].code
)
10019 || ((dtmf_digit_map
[j
].listen_mask
& plci
->dtmf_rec_active
) == 0)))
10023 if (j
< DTMF_DIGIT_MAP_ENTRIES
)
10026 if ((dtmf_digit_map
[j
].listen_mask
& DTMF_TONE_LISTEN_ACTIVE_FLAG
)
10027 && (plci
->tone_last_indication_code
== DTMF_SIGNAL_NO_TONE
)
10028 && (dtmf_digit_map
[j
].character
!= DTMF_SIGNAL_UNIDENTIFIED_TONE
))
10032 for (i
= length
; i
> n
+ 1; i
--)
10033 msg
[i
] = msg
[i
- 1];
10037 msg
[++n
] = DTMF_SIGNAL_UNIDENTIFIED_TONE
;
10039 plci
->tone_last_indication_code
= dtmf_digit_map
[j
].character
;
10041 msg
[++n
] = dtmf_digit_map
[j
].character
;
10047 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "wS", SELECTOR_DTMF
, msg
);
10052 /*------------------------------------------------------------------*/
10053 /* DTMF parameters */
10054 /*------------------------------------------------------------------*/
10056 static void dtmf_parameter_write(PLCI
*plci
)
10059 byte parameter_buffer
[DTMF_PARAMETER_BUFFER_SIZE
+ 2];
10061 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_write",
10062 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
10063 (char *)(FILE_
), __LINE__
));
10065 parameter_buffer
[0] = plci
->dtmf_parameter_length
+ 1;
10066 parameter_buffer
[1] = DSP_CTRL_SET_DTMF_PARAMETERS
;
10067 for (i
= 0; i
< plci
->dtmf_parameter_length
; i
++)
10068 parameter_buffer
[2 + i
] = plci
->dtmf_parameter_buffer
[i
];
10069 add_p(plci
, FTY
, parameter_buffer
);
10070 sig_req(plci
, TEL_CTRL
, 0);
10075 static void dtmf_parameter_clear_config(PLCI
*plci
)
10078 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_clear_config",
10079 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
10080 (char *)(FILE_
), __LINE__
));
10082 plci
->dtmf_parameter_length
= 0;
10086 static void dtmf_parameter_prepare_switch(dword Id
, PLCI
*plci
)
10089 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_prepare_switch",
10090 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
10095 static word
dtmf_parameter_save_config(dword Id
, PLCI
*plci
, byte Rc
)
10098 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d",
10099 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
10105 static word
dtmf_parameter_restore_config(dword Id
, PLCI
*plci
, byte Rc
)
10109 dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d",
10110 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
10113 if ((plci
->B1_facilities
& B1_FACILITY_DTMFR
)
10114 && (plci
->dtmf_parameter_length
!= 0))
10116 switch (plci
->adjust_b_state
)
10118 case ADJUST_B_RESTORE_DTMF_PARAMETER_1
:
10119 plci
->internal_command
= plci
->adjust_b_command
;
10122 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_PARAMETER_1
;
10125 dtmf_parameter_write(plci
);
10126 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_PARAMETER_2
;
10128 case ADJUST_B_RESTORE_DTMF_PARAMETER_2
:
10129 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
10131 dbug(1, dprintf("[%06lx] %s,%d: Restore DTMF parameters failed %02x",
10132 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
10133 Info
= _WRONG_STATE
;
10143 /*------------------------------------------------------------------*/
10144 /* Line interconnect facilities */
10145 /*------------------------------------------------------------------*/
10148 LI_CONFIG
*li_config_table
;
10149 word li_total_channels
;
10152 /*------------------------------------------------------------------*/
10153 /* translate a CHI information element to a channel number */
10154 /* returns 0xff - any channel */
10155 /* 0xfe - chi wrong coding */
10156 /* 0xfd - D-channel */
10157 /* 0x00 - no channel */
10158 /* else channel number / PRI: timeslot */
10159 /* if channels is provided we accept more than one channel. */
10160 /*------------------------------------------------------------------*/
10162 static byte
chi_to_channel(byte
*chi
, dword
*pchannelmap
)
10171 if (pchannelmap
) *pchannelmap
= 0;
10172 if (!chi
[0]) return 0xff;
10175 if (chi
[1] & 0x20) {
10176 if (chi
[0] == 1 && chi
[1] == 0xac) return 0xfd; /* exclusive d-channel */
10177 for (i
= 1; i
< chi
[0] && !(chi
[i
] & 0x80); i
++);
10178 if (i
== chi
[0] || !(chi
[i
] & 0x80)) return 0xfe;
10179 if ((chi
[1] | 0xc8) != 0xe9) return 0xfe;
10180 if (chi
[1] & 0x08) excl
= 0x40;
10182 /* int. id present */
10183 if (chi
[1] & 0x40) {
10185 for (i
= p
; i
< chi
[0] && !(chi
[i
] & 0x80); i
++);
10186 if (i
== chi
[0] || !(chi
[i
] & 0x80)) return 0xfe;
10189 /* coding standard, Number/Map, Channel Type */
10191 for (i
= p
; i
< chi
[0] && !(chi
[i
] & 0x80); i
++);
10192 if (i
== chi
[0] || !(chi
[i
] & 0x80)) return 0xfe;
10193 if ((chi
[p
] | 0xd0) != 0xd3) return 0xfe;
10196 if (chi
[p
] & 0x10) {
10199 if ((chi
[0] - p
) == 4) ofs
= 0;
10200 else if ((chi
[0] - p
) == 3) ofs
= 1;
10204 for (i
= 0; i
< 4 && p
< chi
[0]; i
++) {
10209 for (ch
= 0; !(chi
[p
] & (1 << ch
)); ch
++);
10220 ch
= chi
[p
] & 0x3f;
10222 if ((byte
)(chi
[0] - p
) > 30) return 0xfe;
10224 for (i
= p
; i
<= chi
[0]; i
++) {
10225 if ((chi
[i
] & 0x7f) > 31) return 0xfe;
10226 map
|= (1L << (chi
[i
] & 0x7f));
10230 if (p
!= chi
[0]) return 0xfe;
10231 if (ch
> 31) return 0xfe;
10234 if (chi
[p
] & 0x40) return 0xfe;
10236 if (pchannelmap
) *pchannelmap
= map
;
10237 else if (map
!= ((dword
)(1L << ch
))) return 0xfe;
10238 return (byte
)(excl
| ch
);
10240 else { /* not PRI */
10241 for (i
= 1; i
< chi
[0] && !(chi
[i
] & 0x80); i
++);
10242 if (i
!= chi
[0] || !(chi
[i
] & 0x80)) return 0xfe;
10243 if (chi
[1] & 0x08) excl
= 0x40;
10245 switch (chi
[1] | 0x98) {
10246 case 0x98: return 0;
10248 if (pchannelmap
) *pchannelmap
= 2;
10251 if (pchannelmap
) *pchannelmap
= 4;
10253 case 0x9b: return 0xff;
10254 case 0x9c: return 0xfd; /* d-ch */
10255 default: return 0xfe;
10261 static void mixer_set_bchannel_id_esc(PLCI
*plci
, byte bchannel_id
)
10263 DIVA_CAPI_ADAPTER
*a
;
10268 old_id
= plci
->li_bchannel_id
;
10271 if ((old_id
!= 0) && (li_config_table
[a
->li_base
+ (old_id
- 1)].plci
== plci
))
10272 li_config_table
[a
->li_base
+ (old_id
- 1)].plci
= NULL
;
10273 plci
->li_bchannel_id
= (bchannel_id
& 0x1f) + 1;
10274 if (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== NULL
)
10275 li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
10279 if (((bchannel_id
& 0x03) == 1) || ((bchannel_id
& 0x03) == 2))
10281 if ((old_id
!= 0) && (li_config_table
[a
->li_base
+ (old_id
- 1)].plci
== plci
))
10282 li_config_table
[a
->li_base
+ (old_id
- 1)].plci
= NULL
;
10283 plci
->li_bchannel_id
= bchannel_id
& 0x03;
10284 if ((a
->AdvSignalPLCI
!= NULL
) && (a
->AdvSignalPLCI
!= plci
) && (a
->AdvSignalPLCI
->tel
== ADV_VOICE
))
10286 splci
= a
->AdvSignalPLCI
;
10287 if (li_config_table
[a
->li_base
+ (2 - plci
->li_bchannel_id
)].plci
== NULL
)
10289 if ((splci
->li_bchannel_id
!= 0)
10290 && (li_config_table
[a
->li_base
+ (splci
->li_bchannel_id
- 1)].plci
== splci
))
10292 li_config_table
[a
->li_base
+ (splci
->li_bchannel_id
- 1)].plci
= NULL
;
10294 splci
->li_bchannel_id
= 3 - plci
->li_bchannel_id
;
10295 li_config_table
[a
->li_base
+ (2 - plci
->li_bchannel_id
)].plci
= splci
;
10296 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d",
10297 (dword
)((splci
->Id
<< 8) | UnMapController(splci
->adapter
->Id
)),
10298 (char *)(FILE_
), __LINE__
, splci
->li_bchannel_id
));
10301 if (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== NULL
)
10302 li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
10305 if ((old_id
== 0) && (plci
->li_bchannel_id
!= 0)
10306 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
10308 mixer_clear_config(plci
);
10310 dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d",
10311 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
10312 (char *)(FILE_
), __LINE__
, bchannel_id
, plci
->li_bchannel_id
));
10316 static void mixer_set_bchannel_id(PLCI
*plci
, byte
*chi
)
10318 DIVA_CAPI_ADAPTER
*a
;
10323 old_id
= plci
->li_bchannel_id
;
10324 ch
= chi_to_channel(chi
, NULL
);
10329 if ((old_id
!= 0) && (li_config_table
[a
->li_base
+ (old_id
- 1)].plci
== plci
))
10330 li_config_table
[a
->li_base
+ (old_id
- 1)].plci
= NULL
;
10331 plci
->li_bchannel_id
= (ch
& 0x1f) + 1;
10332 if (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== NULL
)
10333 li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
10337 if (((ch
& 0x1f) == 1) || ((ch
& 0x1f) == 2))
10339 if ((old_id
!= 0) && (li_config_table
[a
->li_base
+ (old_id
- 1)].plci
== plci
))
10340 li_config_table
[a
->li_base
+ (old_id
- 1)].plci
= NULL
;
10341 plci
->li_bchannel_id
= ch
& 0x1f;
10342 if ((a
->AdvSignalPLCI
!= NULL
) && (a
->AdvSignalPLCI
!= plci
) && (a
->AdvSignalPLCI
->tel
== ADV_VOICE
))
10344 splci
= a
->AdvSignalPLCI
;
10345 if (li_config_table
[a
->li_base
+ (2 - plci
->li_bchannel_id
)].plci
== NULL
)
10347 if ((splci
->li_bchannel_id
!= 0)
10348 && (li_config_table
[a
->li_base
+ (splci
->li_bchannel_id
- 1)].plci
== splci
))
10350 li_config_table
[a
->li_base
+ (splci
->li_bchannel_id
- 1)].plci
= NULL
;
10352 splci
->li_bchannel_id
= 3 - plci
->li_bchannel_id
;
10353 li_config_table
[a
->li_base
+ (2 - plci
->li_bchannel_id
)].plci
= splci
;
10354 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
10355 (dword
)((splci
->Id
<< 8) | UnMapController(splci
->adapter
->Id
)),
10356 (char *)(FILE_
), __LINE__
, splci
->li_bchannel_id
));
10359 if (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== NULL
)
10360 li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
10364 if ((old_id
== 0) && (plci
->li_bchannel_id
!= 0)
10365 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
10367 mixer_clear_config(plci
);
10369 dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d",
10370 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
10371 (char *)(FILE_
), __LINE__
, ch
, plci
->li_bchannel_id
));
10375 #define MIXER_MAX_DUMP_CHANNELS 34
10377 static void mixer_calculate_coefs(DIVA_CAPI_ADAPTER
*a
)
10381 char hex_line
[2 * MIXER_MAX_DUMP_CHANNELS
+ MIXER_MAX_DUMP_CHANNELS
/ 8 + 4];
10383 dbug(1, dprintf("[%06lx] %s,%d: mixer_calculate_coefs",
10384 (dword
)(UnMapController(a
->Id
)), (char *)(FILE_
), __LINE__
));
10386 for (i
= 0; i
< li_total_channels
; i
++)
10388 li_config_table
[i
].channel
&= LI_CHANNEL_ADDRESSES_SET
;
10389 if (li_config_table
[i
].chflags
!= 0)
10390 li_config_table
[i
].channel
|= LI_CHANNEL_INVOLVED
;
10393 for (j
= 0; j
< li_total_channels
; j
++)
10395 if (((li_config_table
[i
].flag_table
[j
]) != 0)
10396 || ((li_config_table
[j
].flag_table
[i
]) != 0))
10398 li_config_table
[i
].channel
|= LI_CHANNEL_INVOLVED
;
10400 if (((li_config_table
[i
].flag_table
[j
] & LI_FLAG_CONFERENCE
) != 0)
10401 || ((li_config_table
[j
].flag_table
[i
] & LI_FLAG_CONFERENCE
) != 0))
10403 li_config_table
[i
].channel
|= LI_CHANNEL_CONFERENCE
;
10408 for (i
= 0; i
< li_total_channels
; i
++)
10410 for (j
= 0; j
< li_total_channels
; j
++)
10412 li_config_table
[i
].coef_table
[j
] &= ~(LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
);
10413 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_CONFERENCE
)
10414 li_config_table
[i
].coef_table
[j
] |= LI_COEF_CH_CH
;
10417 for (n
= 0; n
< li_total_channels
; n
++)
10419 if (li_config_table
[n
].channel
& LI_CHANNEL_CONFERENCE
)
10421 for (i
= 0; i
< li_total_channels
; i
++)
10423 if (li_config_table
[i
].channel
& LI_CHANNEL_CONFERENCE
)
10425 for (j
= 0; j
< li_total_channels
; j
++)
10427 li_config_table
[i
].coef_table
[j
] |=
10428 li_config_table
[i
].coef_table
[n
] & li_config_table
[n
].coef_table
[j
];
10434 for (i
= 0; i
< li_total_channels
; i
++)
10436 if (li_config_table
[i
].channel
& LI_CHANNEL_INVOLVED
)
10438 li_config_table
[i
].coef_table
[i
] &= ~LI_COEF_CH_CH
;
10439 for (j
= 0; j
< li_total_channels
; j
++)
10441 if (li_config_table
[i
].coef_table
[j
] & LI_COEF_CH_CH
)
10442 li_config_table
[i
].flag_table
[j
] |= LI_FLAG_CONFERENCE
;
10444 if (li_config_table
[i
].flag_table
[i
] & LI_FLAG_CONFERENCE
)
10445 li_config_table
[i
].coef_table
[i
] |= LI_COEF_CH_CH
;
10448 for (i
= 0; i
< li_total_channels
; i
++)
10450 if (li_config_table
[i
].channel
& LI_CHANNEL_INVOLVED
)
10452 for (j
= 0; j
< li_total_channels
; j
++)
10454 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_INTERCONNECT
)
10455 li_config_table
[i
].coef_table
[j
] |= LI_COEF_CH_CH
;
10456 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_MONITOR
)
10457 li_config_table
[i
].coef_table
[j
] |= LI_COEF_CH_PC
;
10458 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_MIX
)
10459 li_config_table
[i
].coef_table
[j
] |= LI_COEF_PC_CH
;
10460 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_PCCONNECT
)
10461 li_config_table
[i
].coef_table
[j
] |= LI_COEF_PC_PC
;
10463 if (li_config_table
[i
].chflags
& LI_CHFLAG_MONITOR
)
10465 for (j
= 0; j
< li_total_channels
; j
++)
10467 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_INTERCONNECT
)
10469 li_config_table
[i
].coef_table
[j
] |= LI_COEF_CH_PC
;
10470 if (li_config_table
[j
].chflags
& LI_CHFLAG_MIX
)
10471 li_config_table
[i
].coef_table
[j
] |= LI_COEF_PC_CH
| LI_COEF_PC_PC
;
10475 if (li_config_table
[i
].chflags
& LI_CHFLAG_MIX
)
10477 for (j
= 0; j
< li_total_channels
; j
++)
10479 if (li_config_table
[j
].flag_table
[i
] & LI_FLAG_INTERCONNECT
)
10480 li_config_table
[j
].coef_table
[i
] |= LI_COEF_PC_CH
;
10483 if (li_config_table
[i
].chflags
& LI_CHFLAG_LOOP
)
10485 for (j
= 0; j
< li_total_channels
; j
++)
10487 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_INTERCONNECT
)
10489 for (n
= 0; n
< li_total_channels
; n
++)
10491 if (li_config_table
[n
].flag_table
[i
] & LI_FLAG_INTERCONNECT
)
10493 li_config_table
[n
].coef_table
[j
] |= LI_COEF_CH_CH
;
10494 if (li_config_table
[j
].chflags
& LI_CHFLAG_MIX
)
10496 li_config_table
[n
].coef_table
[j
] |= LI_COEF_PC_CH
;
10497 if (li_config_table
[n
].chflags
& LI_CHFLAG_MONITOR
)
10498 li_config_table
[n
].coef_table
[j
] |= LI_COEF_CH_PC
| LI_COEF_PC_PC
;
10500 else if (li_config_table
[n
].chflags
& LI_CHFLAG_MONITOR
)
10501 li_config_table
[n
].coef_table
[j
] |= LI_COEF_CH_PC
;
10509 for (i
= 0; i
< li_total_channels
; i
++)
10511 if (li_config_table
[i
].channel
& LI_CHANNEL_INVOLVED
)
10513 if (li_config_table
[i
].chflags
& (LI_CHFLAG_MONITOR
| LI_CHFLAG_MIX
| LI_CHFLAG_LOOP
))
10514 li_config_table
[i
].channel
|= LI_CHANNEL_ACTIVE
;
10515 if (li_config_table
[i
].chflags
& LI_CHFLAG_MONITOR
)
10516 li_config_table
[i
].channel
|= LI_CHANNEL_RX_DATA
;
10517 if (li_config_table
[i
].chflags
& LI_CHFLAG_MIX
)
10518 li_config_table
[i
].channel
|= LI_CHANNEL_TX_DATA
;
10519 for (j
= 0; j
< li_total_channels
; j
++)
10521 if ((li_config_table
[i
].flag_table
[j
] &
10522 (LI_FLAG_INTERCONNECT
| LI_FLAG_PCCONNECT
| LI_FLAG_CONFERENCE
| LI_FLAG_MONITOR
))
10523 || (li_config_table
[j
].flag_table
[i
] &
10524 (LI_FLAG_INTERCONNECT
| LI_FLAG_PCCONNECT
| LI_FLAG_CONFERENCE
| LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
)))
10526 li_config_table
[i
].channel
|= LI_CHANNEL_ACTIVE
;
10528 if (li_config_table
[i
].flag_table
[j
] & (LI_FLAG_PCCONNECT
| LI_FLAG_MONITOR
))
10529 li_config_table
[i
].channel
|= LI_CHANNEL_RX_DATA
;
10530 if (li_config_table
[j
].flag_table
[i
] & (LI_FLAG_PCCONNECT
| LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
))
10531 li_config_table
[i
].channel
|= LI_CHANNEL_TX_DATA
;
10533 if (!(li_config_table
[i
].channel
& LI_CHANNEL_ACTIVE
))
10535 li_config_table
[i
].coef_table
[i
] |= LI_COEF_PC_CH
| LI_COEF_CH_PC
;
10536 li_config_table
[i
].channel
|= LI_CHANNEL_TX_DATA
| LI_CHANNEL_RX_DATA
;
10540 for (i
= 0; i
< li_total_channels
; i
++)
10542 if (li_config_table
[i
].channel
& LI_CHANNEL_INVOLVED
)
10545 while ((j
< li_total_channels
) && !(li_config_table
[i
].flag_table
[j
] & LI_FLAG_ANNOUNCEMENT
))
10547 if (j
< li_total_channels
)
10549 for (j
= 0; j
< li_total_channels
; j
++)
10551 li_config_table
[i
].coef_table
[j
] &= ~(LI_COEF_CH_CH
| LI_COEF_PC_CH
);
10552 if (li_config_table
[i
].flag_table
[j
] & LI_FLAG_ANNOUNCEMENT
)
10553 li_config_table
[i
].coef_table
[j
] |= LI_COEF_PC_CH
;
10558 n
= li_total_channels
;
10559 if (n
> MIXER_MAX_DUMP_CHANNELS
)
10560 n
= MIXER_MAX_DUMP_CHANNELS
;
10563 for (j
= 0; j
< n
; j
++)
10565 if ((j
& 0x7) == 0)
10567 p
= hex_byte_pack(p
, li_config_table
[j
].curchnl
);
10570 dbug(1, dprintf("[%06lx] CURRENT %s",
10571 (dword
)(UnMapController(a
->Id
)), (char *)hex_line
));
10573 for (j
= 0; j
< n
; j
++)
10575 if ((j
& 0x7) == 0)
10577 p
= hex_byte_pack(p
, li_config_table
[j
].channel
);
10580 dbug(1, dprintf("[%06lx] CHANNEL %s",
10581 (dword
)(UnMapController(a
->Id
)), (char *)hex_line
));
10583 for (j
= 0; j
< n
; j
++)
10585 if ((j
& 0x7) == 0)
10587 p
= hex_byte_pack(p
, li_config_table
[j
].chflags
);
10590 dbug(1, dprintf("[%06lx] CHFLAG %s",
10591 (dword
)(UnMapController(a
->Id
)), (char *)hex_line
));
10592 for (i
= 0; i
< n
; i
++)
10595 for (j
= 0; j
< n
; j
++)
10597 if ((j
& 0x7) == 0)
10599 p
= hex_byte_pack(p
, li_config_table
[i
].flag_table
[j
]);
10602 dbug(1, dprintf("[%06lx] FLAG[%02x]%s",
10603 (dword
)(UnMapController(a
->Id
)), i
, (char *)hex_line
));
10605 for (i
= 0; i
< n
; i
++)
10608 for (j
= 0; j
< n
; j
++)
10610 if ((j
& 0x7) == 0)
10612 p
= hex_byte_pack(p
, li_config_table
[i
].coef_table
[j
]);
10615 dbug(1, dprintf("[%06lx] COEF[%02x]%s",
10616 (dword
)(UnMapController(a
->Id
)), i
, (char *)hex_line
));
10625 } mixer_write_prog_pri
[] =
10627 { LI_COEF_CH_CH
, 0 },
10628 { LI_COEF_CH_PC
, MIXER_COEF_LINE_TO_PC_FLAG
},
10629 { LI_COEF_PC_CH
, MIXER_COEF_LINE_FROM_PC_FLAG
},
10630 { LI_COEF_PC_PC
, MIXER_COEF_LINE_TO_PC_FLAG
| MIXER_COEF_LINE_FROM_PC_FLAG
}
10638 byte xconnect_override
;
10639 } mixer_write_prog_bri
[] =
10641 { 0, 0, LI_COEF_CH_CH
, 0x01 }, /* B to B */
10642 { 1, 0, LI_COEF_CH_CH
, 0x01 }, /* Alt B to B */
10643 { 0, 0, LI_COEF_PC_CH
, 0x80 }, /* PC to B */
10644 { 1, 0, LI_COEF_PC_CH
, 0x01 }, /* Alt PC to B */
10645 { 2, 0, LI_COEF_CH_CH
, 0x00 }, /* IC to B */
10646 { 3, 0, LI_COEF_CH_CH
, 0x00 }, /* Alt IC to B */
10647 { 0, 0, LI_COEF_CH_PC
, 0x80 }, /* B to PC */
10648 { 1, 0, LI_COEF_CH_PC
, 0x01 }, /* Alt B to PC */
10649 { 0, 0, LI_COEF_PC_PC
, 0x01 }, /* PC to PC */
10650 { 1, 0, LI_COEF_PC_PC
, 0x01 }, /* Alt PC to PC */
10651 { 2, 0, LI_COEF_CH_PC
, 0x00 }, /* IC to PC */
10652 { 3, 0, LI_COEF_CH_PC
, 0x00 }, /* Alt IC to PC */
10653 { 0, 2, LI_COEF_CH_CH
, 0x00 }, /* B to IC */
10654 { 1, 2, LI_COEF_CH_CH
, 0x00 }, /* Alt B to IC */
10655 { 0, 2, LI_COEF_PC_CH
, 0x00 }, /* PC to IC */
10656 { 1, 2, LI_COEF_PC_CH
, 0x00 }, /* Alt PC to IC */
10657 { 2, 2, LI_COEF_CH_CH
, 0x00 }, /* IC to IC */
10658 { 3, 2, LI_COEF_CH_CH
, 0x00 }, /* Alt IC to IC */
10659 { 1, 1, LI_COEF_CH_CH
, 0x01 }, /* Alt B to Alt B */
10660 { 0, 1, LI_COEF_CH_CH
, 0x01 }, /* B to Alt B */
10661 { 1, 1, LI_COEF_PC_CH
, 0x80 }, /* Alt PC to Alt B */
10662 { 0, 1, LI_COEF_PC_CH
, 0x01 }, /* PC to Alt B */
10663 { 3, 1, LI_COEF_CH_CH
, 0x00 }, /* Alt IC to Alt B */
10664 { 2, 1, LI_COEF_CH_CH
, 0x00 }, /* IC to Alt B */
10665 { 1, 1, LI_COEF_CH_PC
, 0x80 }, /* Alt B to Alt PC */
10666 { 0, 1, LI_COEF_CH_PC
, 0x01 }, /* B to Alt PC */
10667 { 1, 1, LI_COEF_PC_PC
, 0x01 }, /* Alt PC to Alt PC */
10668 { 0, 1, LI_COEF_PC_PC
, 0x01 }, /* PC to Alt PC */
10669 { 3, 1, LI_COEF_CH_PC
, 0x00 }, /* Alt IC to Alt PC */
10670 { 2, 1, LI_COEF_CH_PC
, 0x00 }, /* IC to Alt PC */
10671 { 1, 3, LI_COEF_CH_CH
, 0x00 }, /* Alt B to Alt IC */
10672 { 0, 3, LI_COEF_CH_CH
, 0x00 }, /* B to Alt IC */
10673 { 1, 3, LI_COEF_PC_CH
, 0x00 }, /* Alt PC to Alt IC */
10674 { 0, 3, LI_COEF_PC_CH
, 0x00 }, /* PC to Alt IC */
10675 { 3, 3, LI_COEF_CH_CH
, 0x00 }, /* Alt IC to Alt IC */
10676 { 2, 3, LI_COEF_CH_CH
, 0x00 } /* IC to Alt IC */
10679 static byte mixer_swapped_index_bri
[] =
10682 19, /* Alt B to B */
10684 21, /* Alt PC to B */
10686 23, /* Alt IC to B */
10688 25, /* Alt B to PC */
10690 27, /* Alt PC to PC */
10692 29, /* Alt IC to PC */
10694 31, /* Alt B to IC */
10696 33, /* Alt PC to IC */
10698 35, /* Alt IC to IC */
10699 0, /* Alt B to Alt B */
10700 1, /* B to Alt B */
10701 2, /* Alt PC to Alt B */
10702 3, /* PC to Alt B */
10703 4, /* Alt IC to Alt B */
10704 5, /* IC to Alt B */
10705 6, /* Alt B to Alt PC */
10706 7, /* B to Alt PC */
10707 8, /* Alt PC to Alt PC */
10708 9, /* PC to Alt PC */
10709 10, /* Alt IC to Alt PC */
10710 11, /* IC to Alt PC */
10711 12, /* Alt B to Alt IC */
10712 13, /* B to Alt IC */
10713 14, /* Alt PC to Alt IC */
10714 15, /* PC to Alt IC */
10715 16, /* Alt IC to Alt IC */
10716 17 /* IC to Alt IC */
10724 } xconnect_write_prog
[] =
10726 { LI_COEF_CH_CH
, false, false },
10727 { LI_COEF_CH_PC
, false, true },
10728 { LI_COEF_PC_CH
, true, false },
10729 { LI_COEF_PC_PC
, true, true }
10733 static void xconnect_query_addresses(PLCI
*plci
)
10735 DIVA_CAPI_ADAPTER
*a
;
10739 dbug(1, dprintf("[%06lx] %s,%d: xconnect_query_addresses",
10740 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
10741 (char *)(FILE_
), __LINE__
));
10744 if (a
->li_pri
&& ((plci
->li_bchannel_id
== 0)
10745 || (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
!= plci
)))
10747 dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out",
10748 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
10749 (char *)(FILE_
), __LINE__
));
10752 p
= plci
->internal_req_buffer
;
10753 ch
= (a
->li_pri
) ? plci
->li_bchannel_id
- 1 : 0;
10754 *(p
++) = UDATA_REQUEST_XCONNECT_FROM
;
10757 *(p
++) = (byte
)(w
>> 8);
10758 w
= ch
| XCONNECT_CHANNEL_PORT_PC
;
10760 *(p
++) = (byte
)(w
>> 8);
10761 plci
->NData
[0].P
= plci
->internal_req_buffer
;
10762 plci
->NData
[0].PLength
= p
- plci
->internal_req_buffer
;
10763 plci
->NL
.X
= plci
->NData
;
10764 plci
->NL
.ReqCh
= 0;
10765 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
10766 plci
->adapter
->request(&plci
->NL
);
10770 static void xconnect_write_coefs(PLCI
*plci
, word internal_command
)
10773 dbug(1, dprintf("[%06lx] %s,%d: xconnect_write_coefs %04x",
10774 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
10775 (char *)(FILE_
), __LINE__
, internal_command
));
10777 plci
->li_write_command
= internal_command
;
10778 plci
->li_write_channel
= 0;
10782 static byte
xconnect_write_coefs_process(dword Id
, PLCI
*plci
, byte Rc
)
10784 DIVA_CAPI_ADAPTER
*a
;
10785 word w
, n
, i
, j
, r
, s
, to_ch
;
10788 struct xconnect_transfer_address_s
*transfer_address
;
10789 byte ch_map
[MIXER_CHANNELS_BRI
];
10791 dbug(1, dprintf("[%06x] %s,%d: xconnect_write_coefs_process %02x %d",
10792 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->li_write_channel
));
10795 if ((plci
->li_bchannel_id
== 0)
10796 || (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
!= plci
))
10798 dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out",
10799 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
10802 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
10803 j
= plci
->li_write_channel
;
10804 p
= plci
->internal_req_buffer
;
10807 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
10809 dbug(1, dprintf("[%06lx] %s,%d: LI write coefs failed %02x",
10810 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
10814 if (li_config_table
[i
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
10818 if (j
< li_total_channels
)
10820 if (li_config_table
[i
].channel
& LI_CHANNEL_ADDRESSES_SET
)
10822 s
= ((li_config_table
[i
].send_b
.card_address
.low
| li_config_table
[i
].send_b
.card_address
.high
) ?
10823 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_PC
| LI_COEF_PC_PC
)) &
10824 ((li_config_table
[i
].send_pc
.card_address
.low
| li_config_table
[i
].send_pc
.card_address
.high
) ?
10825 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_CH
| LI_COEF_PC_CH
));
10827 r
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
10828 while ((j
< li_total_channels
)
10830 || (!(li_config_table
[j
].channel
& LI_CHANNEL_ADDRESSES_SET
))
10831 || (!li_config_table
[j
].adapter
->li_pri
10832 && (j
>= li_config_table
[j
].adapter
->li_base
+ MIXER_BCHANNELS_BRI
))
10833 || (((li_config_table
[j
].send_b
.card_address
.low
!= li_config_table
[i
].send_b
.card_address
.low
)
10834 || (li_config_table
[j
].send_b
.card_address
.high
!= li_config_table
[i
].send_b
.card_address
.high
))
10835 && (!(a
->manufacturer_features
& MANUFACTURER_FEATURE_DMACONNECT
)
10836 || !(li_config_table
[j
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_DMACONNECT
)))
10837 || ((li_config_table
[j
].adapter
->li_base
!= a
->li_base
)
10839 ((li_config_table
[j
].send_b
.card_address
.low
| li_config_table
[j
].send_b
.card_address
.high
) ?
10840 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_PC_CH
| LI_COEF_PC_PC
)) &
10841 ((li_config_table
[j
].send_pc
.card_address
.low
| li_config_table
[j
].send_pc
.card_address
.high
) ?
10842 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_CH
| LI_COEF_CH_PC
))))))
10845 if (j
< li_total_channels
)
10846 r
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
10849 if (j
< li_total_channels
)
10851 plci
->internal_command
= plci
->li_write_command
;
10852 if (plci_nl_busy(plci
))
10854 to_ch
= (a
->li_pri
) ? plci
->li_bchannel_id
- 1 : 0;
10855 *(p
++) = UDATA_REQUEST_XCONNECT_TO
;
10858 if (li_config_table
[j
].adapter
->li_base
!= a
->li_base
)
10861 ((li_config_table
[j
].send_b
.card_address
.low
| li_config_table
[j
].send_b
.card_address
.high
) ?
10862 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_PC_CH
| LI_COEF_PC_PC
)) &
10863 ((li_config_table
[j
].send_pc
.card_address
.low
| li_config_table
[j
].send_pc
.card_address
.high
) ?
10864 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_CH
| LI_COEF_CH_PC
));
10869 if (r
& xconnect_write_prog
[n
].mask
)
10871 if (xconnect_write_prog
[n
].from_pc
)
10872 transfer_address
= &(li_config_table
[j
].send_pc
);
10874 transfer_address
= &(li_config_table
[j
].send_b
);
10875 d
= transfer_address
->card_address
.low
;
10877 *(p
++) = (byte
)(d
>> 8);
10878 *(p
++) = (byte
)(d
>> 16);
10879 *(p
++) = (byte
)(d
>> 24);
10880 d
= transfer_address
->card_address
.high
;
10882 *(p
++) = (byte
)(d
>> 8);
10883 *(p
++) = (byte
)(d
>> 16);
10884 *(p
++) = (byte
)(d
>> 24);
10885 d
= transfer_address
->offset
;
10887 *(p
++) = (byte
)(d
>> 8);
10888 *(p
++) = (byte
)(d
>> 16);
10889 *(p
++) = (byte
)(d
>> 24);
10890 w
= xconnect_write_prog
[n
].to_pc
? to_ch
| XCONNECT_CHANNEL_PORT_PC
: to_ch
;
10892 *(p
++) = (byte
)(w
>> 8);
10893 w
= ((li_config_table
[i
].coef_table
[j
] & xconnect_write_prog
[n
].mask
) == 0) ? 0x01 :
10894 (li_config_table
[i
].adapter
->u_law
?
10895 (li_config_table
[j
].adapter
->u_law
? 0x80 : 0x86) :
10896 (li_config_table
[j
].adapter
->u_law
? 0x7a : 0x80));
10899 li_config_table
[i
].coef_table
[j
] ^= xconnect_write_prog
[n
].mask
<< 4;
10902 } while ((n
< ARRAY_SIZE(xconnect_write_prog
))
10903 && ((p
- plci
->internal_req_buffer
) + 16 < INTERNAL_REQ_BUFFER_SIZE
));
10904 if (n
== ARRAY_SIZE(xconnect_write_prog
))
10909 if (j
< li_total_channels
)
10910 r
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
10911 } while ((j
< li_total_channels
)
10913 || (!(li_config_table
[j
].channel
& LI_CHANNEL_ADDRESSES_SET
))
10914 || (!li_config_table
[j
].adapter
->li_pri
10915 && (j
>= li_config_table
[j
].adapter
->li_base
+ MIXER_BCHANNELS_BRI
))
10916 || (((li_config_table
[j
].send_b
.card_address
.low
!= li_config_table
[i
].send_b
.card_address
.low
)
10917 || (li_config_table
[j
].send_b
.card_address
.high
!= li_config_table
[i
].send_b
.card_address
.high
))
10918 && (!(a
->manufacturer_features
& MANUFACTURER_FEATURE_DMACONNECT
)
10919 || !(li_config_table
[j
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_DMACONNECT
)))
10920 || ((li_config_table
[j
].adapter
->li_base
!= a
->li_base
)
10922 ((li_config_table
[j
].send_b
.card_address
.low
| li_config_table
[j
].send_b
.card_address
.high
) ?
10923 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_PC_CH
| LI_COEF_PC_PC
)) &
10924 ((li_config_table
[j
].send_pc
.card_address
.low
| li_config_table
[j
].send_pc
.card_address
.high
) ?
10925 (LI_COEF_CH_CH
| LI_COEF_CH_PC
| LI_COEF_PC_CH
| LI_COEF_PC_PC
) : (LI_COEF_CH_CH
| LI_COEF_CH_PC
))))));
10927 } while ((j
< li_total_channels
)
10928 && ((p
- plci
->internal_req_buffer
) + 16 < INTERNAL_REQ_BUFFER_SIZE
));
10930 else if (j
== li_total_channels
)
10932 plci
->internal_command
= plci
->li_write_command
;
10933 if (plci_nl_busy(plci
))
10937 *(p
++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC
;
10939 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
10940 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
10941 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
10942 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
10944 *(p
++) = (byte
)(w
>> 8);
10948 *(p
++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI
;
10950 if ((plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
)
10951 && (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) <= a
->adv_voice_coef_length
))
10953 w
= GET_WORD(a
->adv_voice_coef_buffer
+ ADV_VOICE_NEW_COEF_BASE
);
10955 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
10956 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
10957 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
10958 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
10960 *(p
++) = (byte
)(w
>> 8);
10961 for (j
= 0; j
< sizeof(ch_map
); j
+= 2)
10963 if (plci
->li_bchannel_id
== 2)
10965 ch_map
[j
] = (byte
)(j
+ 1);
10966 ch_map
[j
+ 1] = (byte
) j
;
10970 ch_map
[j
] = (byte
) j
;
10971 ch_map
[j
+ 1] = (byte
)(j
+ 1);
10974 for (n
= 0; n
< ARRAY_SIZE(mixer_write_prog_bri
); n
++)
10976 i
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].to_ch
];
10977 j
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].from_ch
];
10978 if (li_config_table
[i
].channel
& li_config_table
[j
].channel
& LI_CHANNEL_INVOLVED
)
10980 *p
= (mixer_write_prog_bri
[n
].xconnect_override
!= 0) ?
10981 mixer_write_prog_bri
[n
].xconnect_override
:
10982 ((li_config_table
[i
].coef_table
[j
] & mixer_write_prog_bri
[n
].mask
) ? 0x80 : 0x01);
10983 if ((i
>= a
->li_base
+ MIXER_BCHANNELS_BRI
) || (j
>= a
->li_base
+ MIXER_BCHANNELS_BRI
))
10985 w
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
10986 li_config_table
[i
].coef_table
[j
] ^= (w
& mixer_write_prog_bri
[n
].mask
) << 4;
10992 if ((a
->AdvSignalPLCI
!= NULL
) && (a
->AdvSignalPLCI
->tel
== ADV_VOICE
))
10994 w
= (plci
== a
->AdvSignalPLCI
) ? n
: mixer_swapped_index_bri
[n
];
10995 if (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + w
< a
->adv_voice_coef_length
)
10996 *p
= a
->adv_voice_coef_buffer
[ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + w
];
11002 j
= li_total_channels
+ 1;
11007 if (j
<= li_total_channels
)
11009 plci
->internal_command
= plci
->li_write_command
;
11010 if (plci_nl_busy(plci
))
11012 if (j
< a
->li_base
)
11016 *(p
++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC
;
11018 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
11019 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
11020 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
11021 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
11023 *(p
++) = (byte
)(w
>> 8);
11024 for (n
= 0; n
< ARRAY_SIZE(mixer_write_prog_pri
); n
++)
11026 *(p
++) = (byte
)((plci
->li_bchannel_id
- 1) | mixer_write_prog_pri
[n
].line_flags
);
11027 for (j
= a
->li_base
; j
< a
->li_base
+ MIXER_CHANNELS_PRI
; j
++)
11029 w
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
11030 if (w
& mixer_write_prog_pri
[n
].mask
)
11032 *(p
++) = (li_config_table
[i
].coef_table
[j
] & mixer_write_prog_pri
[n
].mask
) ? 0x80 : 0x01;
11033 li_config_table
[i
].coef_table
[j
] ^= mixer_write_prog_pri
[n
].mask
<< 4;
11038 *(p
++) = (byte
)((plci
->li_bchannel_id
- 1) | MIXER_COEF_LINE_ROW_FLAG
| mixer_write_prog_pri
[n
].line_flags
);
11039 for (j
= a
->li_base
; j
< a
->li_base
+ MIXER_CHANNELS_PRI
; j
++)
11041 w
= ((li_config_table
[j
].coef_table
[i
] & 0xf) ^ (li_config_table
[j
].coef_table
[i
] >> 4));
11042 if (w
& mixer_write_prog_pri
[n
].mask
)
11044 *(p
++) = (li_config_table
[j
].coef_table
[i
] & mixer_write_prog_pri
[n
].mask
) ? 0x80 : 0x01;
11045 li_config_table
[j
].coef_table
[i
] ^= mixer_write_prog_pri
[n
].mask
<< 4;
11054 *(p
++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI
;
11056 if ((plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
)
11057 && (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) <= a
->adv_voice_coef_length
))
11059 w
= GET_WORD(a
->adv_voice_coef_buffer
+ ADV_VOICE_NEW_COEF_BASE
);
11061 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
11062 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
11063 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
11064 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
11066 *(p
++) = (byte
)(w
>> 8);
11067 for (j
= 0; j
< sizeof(ch_map
); j
+= 2)
11069 if (plci
->li_bchannel_id
== 2)
11071 ch_map
[j
] = (byte
)(j
+ 1);
11072 ch_map
[j
+ 1] = (byte
) j
;
11076 ch_map
[j
] = (byte
) j
;
11077 ch_map
[j
+ 1] = (byte
)(j
+ 1);
11080 for (n
= 0; n
< ARRAY_SIZE(mixer_write_prog_bri
); n
++)
11082 i
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].to_ch
];
11083 j
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].from_ch
];
11084 if (li_config_table
[i
].channel
& li_config_table
[j
].channel
& LI_CHANNEL_INVOLVED
)
11086 *p
= ((li_config_table
[i
].coef_table
[j
] & mixer_write_prog_bri
[n
].mask
) ? 0x80 : 0x01);
11087 w
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
11088 li_config_table
[i
].coef_table
[j
] ^= (w
& mixer_write_prog_bri
[n
].mask
) << 4;
11093 if ((a
->AdvSignalPLCI
!= NULL
) && (a
->AdvSignalPLCI
->tel
== ADV_VOICE
))
11095 w
= (plci
== a
->AdvSignalPLCI
) ? n
: mixer_swapped_index_bri
[n
];
11096 if (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + w
< a
->adv_voice_coef_length
)
11097 *p
= a
->adv_voice_coef_buffer
[ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + w
];
11103 j
= li_total_channels
+ 1;
11106 plci
->li_write_channel
= j
;
11107 if (p
!= plci
->internal_req_buffer
)
11109 plci
->NData
[0].P
= plci
->internal_req_buffer
;
11110 plci
->NData
[0].PLength
= p
- plci
->internal_req_buffer
;
11111 plci
->NL
.X
= plci
->NData
;
11112 plci
->NL
.ReqCh
= 0;
11113 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
11114 plci
->adapter
->request(&plci
->NL
);
11120 static void mixer_notify_update(PLCI
*plci
, byte others
)
11122 DIVA_CAPI_ADAPTER
*a
;
11125 byte msg
[sizeof(CAPI_MSG_HEADER
) + 6];
11127 dbug(1, dprintf("[%06lx] %s,%d: mixer_notify_update %d",
11128 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
11129 (char *)(FILE_
), __LINE__
, others
));
11132 if (a
->profile
.Global_Options
& GL_LINE_INTERCONNECT_SUPPORTED
)
11135 plci
->li_notify_update
= true;
11139 notify_plci
= NULL
;
11142 while ((i
< li_total_channels
) && (li_config_table
[i
].plci
== NULL
))
11144 if (i
< li_total_channels
)
11145 notify_plci
= li_config_table
[i
++].plci
;
11149 if ((plci
->li_bchannel_id
!= 0)
11150 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
11152 notify_plci
= plci
;
11155 if ((notify_plci
!= NULL
)
11156 && !notify_plci
->li_notify_update
11157 && (notify_plci
->appl
!= NULL
)
11158 && (notify_plci
->State
)
11159 && notify_plci
->NL
.Id
&& !notify_plci
->nl_remove_id
)
11161 notify_plci
->li_notify_update
= true;
11162 ((CAPI_MSG
*) msg
)->header
.length
= 18;
11163 ((CAPI_MSG
*) msg
)->header
.appl_id
= notify_plci
->appl
->Id
;
11164 ((CAPI_MSG
*) msg
)->header
.command
= _FACILITY_R
;
11165 ((CAPI_MSG
*) msg
)->header
.number
= 0;
11166 ((CAPI_MSG
*) msg
)->header
.controller
= notify_plci
->adapter
->Id
;
11167 ((CAPI_MSG
*) msg
)->header
.plci
= notify_plci
->Id
;
11168 ((CAPI_MSG
*) msg
)->header
.ncci
= 0;
11169 ((CAPI_MSG
*) msg
)->info
.facility_req
.Selector
= SELECTOR_LINE_INTERCONNECT
;
11170 ((CAPI_MSG
*) msg
)->info
.facility_req
.structs
[0] = 3;
11171 ((CAPI_MSG
*) msg
)->info
.facility_req
.structs
[1] = LI_REQ_SILENT_UPDATE
& 0xff;
11172 ((CAPI_MSG
*) msg
)->info
.facility_req
.structs
[2] = LI_REQ_SILENT_UPDATE
>> 8;
11173 ((CAPI_MSG
*) msg
)->info
.facility_req
.structs
[3] = 0;
11174 w
= api_put(notify_plci
->appl
, (CAPI_MSG
*) msg
);
11175 if (w
!= _QUEUE_FULL
)
11179 dbug(1, dprintf("[%06lx] %s,%d: Interconnect notify failed %06x %d",
11180 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
11181 (char *)(FILE_
), __LINE__
,
11182 (dword
)((notify_plci
->Id
<< 8) | UnMapController(notify_plci
->adapter
->Id
)), w
));
11184 notify_plci
->li_notify_update
= false;
11187 } while (others
&& (notify_plci
!= NULL
));
11189 plci
->li_notify_update
= false;
11194 static void mixer_clear_config(PLCI
*plci
)
11196 DIVA_CAPI_ADAPTER
*a
;
11199 dbug(1, dprintf("[%06lx] %s,%d: mixer_clear_config",
11200 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
11201 (char *)(FILE_
), __LINE__
));
11203 plci
->li_notify_update
= false;
11204 plci
->li_plci_b_write_pos
= 0;
11205 plci
->li_plci_b_read_pos
= 0;
11206 plci
->li_plci_b_req_pos
= 0;
11208 if ((plci
->li_bchannel_id
!= 0)
11209 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
11211 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11212 li_config_table
[i
].curchnl
= 0;
11213 li_config_table
[i
].channel
= 0;
11214 li_config_table
[i
].chflags
= 0;
11215 for (j
= 0; j
< li_total_channels
; j
++)
11217 li_config_table
[j
].flag_table
[i
] = 0;
11218 li_config_table
[i
].flag_table
[j
] = 0;
11219 li_config_table
[i
].coef_table
[j
] = 0;
11220 li_config_table
[j
].coef_table
[i
] = 0;
11224 li_config_table
[i
].coef_table
[i
] |= LI_COEF_CH_PC_SET
| LI_COEF_PC_CH_SET
;
11225 if ((plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
))
11227 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
11228 li_config_table
[i
].curchnl
= 0;
11229 li_config_table
[i
].channel
= 0;
11230 li_config_table
[i
].chflags
= 0;
11231 for (j
= 0; j
< li_total_channels
; j
++)
11233 li_config_table
[i
].flag_table
[j
] = 0;
11234 li_config_table
[j
].flag_table
[i
] = 0;
11235 li_config_table
[i
].coef_table
[j
] = 0;
11236 li_config_table
[j
].coef_table
[i
] = 0;
11238 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
11240 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
11241 li_config_table
[i
].curchnl
= 0;
11242 li_config_table
[i
].channel
= 0;
11243 li_config_table
[i
].chflags
= 0;
11244 for (j
= 0; j
< li_total_channels
; j
++)
11246 li_config_table
[i
].flag_table
[j
] = 0;
11247 li_config_table
[j
].flag_table
[i
] = 0;
11248 li_config_table
[i
].coef_table
[j
] = 0;
11249 li_config_table
[j
].coef_table
[i
] = 0;
11258 static void mixer_prepare_switch(dword Id
, PLCI
*plci
)
11261 dbug(1, dprintf("[%06lx] %s,%d: mixer_prepare_switch",
11262 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11266 mixer_indication_coefs_set(Id
, plci
);
11267 } while (plci
->li_plci_b_read_pos
!= plci
->li_plci_b_req_pos
);
11271 static word
mixer_save_config(dword Id
, PLCI
*plci
, byte Rc
)
11273 DIVA_CAPI_ADAPTER
*a
;
11276 dbug(1, dprintf("[%06lx] %s,%d: mixer_save_config %02x %d",
11277 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
11280 if ((plci
->li_bchannel_id
!= 0)
11281 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
11283 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11284 for (j
= 0; j
< li_total_channels
; j
++)
11286 li_config_table
[i
].coef_table
[j
] &= 0xf;
11287 li_config_table
[j
].coef_table
[i
] &= 0xf;
11290 li_config_table
[i
].coef_table
[i
] |= LI_COEF_CH_PC_SET
| LI_COEF_PC_CH_SET
;
11296 static word
mixer_restore_config(dword Id
, PLCI
*plci
, byte Rc
)
11298 DIVA_CAPI_ADAPTER
*a
;
11301 dbug(1, dprintf("[%06lx] %s,%d: mixer_restore_config %02x %d",
11302 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
11306 if ((plci
->B1_facilities
& B1_FACILITY_MIXER
)
11307 && (plci
->li_bchannel_id
!= 0)
11308 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
11310 switch (plci
->adjust_b_state
)
11312 case ADJUST_B_RESTORE_MIXER_1
:
11313 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11315 plci
->internal_command
= plci
->adjust_b_command
;
11316 if (plci_nl_busy(plci
))
11318 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_1
;
11321 xconnect_query_addresses(plci
);
11322 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_2
;
11325 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_5
;
11328 case ADJUST_B_RESTORE_MIXER_2
:
11329 case ADJUST_B_RESTORE_MIXER_3
:
11330 case ADJUST_B_RESTORE_MIXER_4
:
11331 if ((Rc
!= OK
) && (Rc
!= OK_FC
) && (Rc
!= 0))
11333 dbug(1, dprintf("[%06lx] %s,%d: Adjust B query addresses failed %02x",
11334 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
11335 Info
= _WRONG_STATE
;
11340 if (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_2
)
11341 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_3
;
11342 else if (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_4
)
11343 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_5
;
11347 if (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_2
)
11348 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_4
;
11349 else if (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_3
)
11350 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_5
;
11352 if (plci
->adjust_b_state
!= ADJUST_B_RESTORE_MIXER_5
)
11354 plci
->internal_command
= plci
->adjust_b_command
;
11358 case ADJUST_B_RESTORE_MIXER_5
:
11359 xconnect_write_coefs(plci
, plci
->adjust_b_command
);
11360 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_6
;
11363 case ADJUST_B_RESTORE_MIXER_6
:
11364 if (!xconnect_write_coefs_process(Id
, plci
, Rc
))
11366 dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed",
11367 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11368 Info
= _FACILITY_NOT_SUPPORTED
;
11371 if (plci
->internal_command
)
11373 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_7
;
11374 case ADJUST_B_RESTORE_MIXER_7
:
11382 static void mixer_command(dword Id
, PLCI
*plci
, byte Rc
)
11384 DIVA_CAPI_ADAPTER
*a
;
11385 word i
, internal_command
;
11387 dbug(1, dprintf("[%06lx] %s,%d: mixer_command %02x %04x %04x",
11388 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
,
11392 internal_command
= plci
->internal_command
;
11393 plci
->internal_command
= 0;
11394 switch (plci
->li_cmd
)
11396 case LI_REQ_CONNECT
:
11397 case LI_REQ_DISCONNECT
:
11398 case LI_REQ_SILENT_UPDATE
:
11399 switch (internal_command
)
11402 if (plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
)
11404 adjust_b1_resource(Id
, plci
, NULL
, (word
)(plci
->B1_facilities
|
11405 B1_FACILITY_MIXER
), MIXER_COMMAND_1
);
11408 case MIXER_COMMAND_1
:
11409 if (plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
)
11411 if (adjust_b_process(Id
, plci
, Rc
) != GOOD
)
11413 dbug(1, dprintf("[%06lx] %s,%d: Load mixer failed",
11414 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11417 if (plci
->internal_command
)
11420 plci
->li_plci_b_req_pos
= plci
->li_plci_b_write_pos
;
11421 if ((plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
)
11422 || ((get_b1_facilities(plci
, plci
->B1_resource
) & B1_FACILITY_MIXER
)
11423 && (add_b1_facilities(plci
, plci
->B1_resource
, (word
)(plci
->B1_facilities
&
11424 ~B1_FACILITY_MIXER
)) == plci
->B1_resource
)))
11426 xconnect_write_coefs(plci
, MIXER_COMMAND_2
);
11432 mixer_indication_coefs_set(Id
, plci
);
11433 } while (plci
->li_plci_b_read_pos
!= plci
->li_plci_b_req_pos
);
11436 case MIXER_COMMAND_2
:
11437 if ((plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
)
11438 || ((get_b1_facilities(plci
, plci
->B1_resource
) & B1_FACILITY_MIXER
)
11439 && (add_b1_facilities(plci
, plci
->B1_resource
, (word
)(plci
->B1_facilities
&
11440 ~B1_FACILITY_MIXER
)) == plci
->B1_resource
)))
11442 if (!xconnect_write_coefs_process(Id
, plci
, Rc
))
11444 dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed",
11445 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11446 if (plci
->li_plci_b_write_pos
!= plci
->li_plci_b_req_pos
)
11450 plci
->li_plci_b_write_pos
= (plci
->li_plci_b_write_pos
== 0) ?
11451 LI_PLCI_B_QUEUE_ENTRIES
- 1 : plci
->li_plci_b_write_pos
- 1;
11452 i
= (plci
->li_plci_b_write_pos
== 0) ?
11453 LI_PLCI_B_QUEUE_ENTRIES
- 1 : plci
->li_plci_b_write_pos
- 1;
11454 } while ((plci
->li_plci_b_write_pos
!= plci
->li_plci_b_req_pos
)
11455 && !(plci
->li_plci_b_queue
[i
] & LI_PLCI_B_LAST_FLAG
));
11459 if (plci
->internal_command
)
11462 if (!(plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
))
11464 adjust_b1_resource(Id
, plci
, NULL
, (word
)(plci
->B1_facilities
&
11465 ~B1_FACILITY_MIXER
), MIXER_COMMAND_3
);
11468 case MIXER_COMMAND_3
:
11469 if (!(plci
->li_channel_bits
& LI_CHANNEL_INVOLVED
))
11471 if (adjust_b_process(Id
, plci
, Rc
) != GOOD
)
11473 dbug(1, dprintf("[%06lx] %s,%d: Unload mixer failed",
11474 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11477 if (plci
->internal_command
)
11484 if ((plci
->li_bchannel_id
== 0)
11485 || (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
!= plci
))
11487 dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out %d",
11488 UnMapId(Id
), (char *)(FILE_
), __LINE__
, (int)(plci
->li_bchannel_id
)));
11492 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11493 li_config_table
[i
].curchnl
= plci
->li_channel_bits
;
11494 if (!a
->li_pri
&& (plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
))
11496 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
11497 li_config_table
[i
].curchnl
= plci
->li_channel_bits
;
11498 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
11500 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
11501 li_config_table
[i
].curchnl
= plci
->li_channel_bits
;
11508 static void li_update_connect(dword Id
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
,
11509 dword plci_b_id
, byte connect
, dword li_flags
)
11511 word i
, ch_a
, ch_a_v
, ch_a_s
, ch_b
, ch_b_v
, ch_b_s
;
11513 DIVA_CAPI_ADAPTER
*a_b
;
11515 a_b
= &(adapter
[MapController((byte
)(plci_b_id
& 0x7f)) - 1]);
11516 plci_b
= &(a_b
->plci
[((plci_b_id
>> 8) & 0xff) - 1]);
11517 ch_a
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11518 if (!a
->li_pri
&& (plci
->tel
== ADV_VOICE
)
11519 && (plci
== a
->AdvSignalPLCI
) && (Id
& EXT_CONTROLLER
))
11521 ch_a_v
= ch_a
+ MIXER_IC_CHANNEL_BASE
;
11522 ch_a_s
= (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
) ?
11523 a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
) : ch_a_v
;
11530 ch_b
= a_b
->li_base
+ (plci_b
->li_bchannel_id
- 1);
11531 if (!a_b
->li_pri
&& (plci_b
->tel
== ADV_VOICE
)
11532 && (plci_b
== a_b
->AdvSignalPLCI
) && (plci_b_id
& EXT_CONTROLLER
))
11534 ch_b_v
= ch_b
+ MIXER_IC_CHANNEL_BASE
;
11535 ch_b_s
= (a_b
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
) ?
11536 a_b
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci_b
->li_bchannel_id
) : ch_b_v
;
11545 li_config_table
[ch_a
].flag_table
[ch_a_v
] &= ~LI_FLAG_MONITOR
;
11546 li_config_table
[ch_a
].flag_table
[ch_a_s
] &= ~LI_FLAG_MONITOR
;
11547 li_config_table
[ch_a_v
].flag_table
[ch_a
] &= ~(LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
);
11548 li_config_table
[ch_a_s
].flag_table
[ch_a
] &= ~(LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
);
11550 li_config_table
[ch_a
].flag_table
[ch_b_v
] &= ~LI_FLAG_MONITOR
;
11551 li_config_table
[ch_a
].flag_table
[ch_b_s
] &= ~LI_FLAG_MONITOR
;
11552 li_config_table
[ch_b_v
].flag_table
[ch_a
] &= ~(LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
);
11553 li_config_table
[ch_b_s
].flag_table
[ch_a
] &= ~(LI_FLAG_ANNOUNCEMENT
| LI_FLAG_MIX
);
11554 if (ch_a_v
== ch_b_v
)
11556 li_config_table
[ch_a_v
].flag_table
[ch_b_v
] &= ~LI_FLAG_CONFERENCE
;
11557 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] &= ~LI_FLAG_CONFERENCE
;
11561 if (li_config_table
[ch_a_v
].flag_table
[ch_b_v
] & LI_FLAG_CONFERENCE
)
11563 for (i
= 0; i
< li_total_channels
; i
++)
11566 li_config_table
[ch_a_v
].flag_table
[i
] &= ~LI_FLAG_CONFERENCE
;
11569 if (li_config_table
[ch_a_s
].flag_table
[ch_b_v
] & LI_FLAG_CONFERENCE
)
11571 for (i
= 0; i
< li_total_channels
; i
++)
11574 li_config_table
[ch_a_s
].flag_table
[i
] &= ~LI_FLAG_CONFERENCE
;
11577 if (li_config_table
[ch_b_v
].flag_table
[ch_a_v
] & LI_FLAG_CONFERENCE
)
11579 for (i
= 0; i
< li_total_channels
; i
++)
11582 li_config_table
[i
].flag_table
[ch_a_v
] &= ~LI_FLAG_CONFERENCE
;
11585 if (li_config_table
[ch_b_v
].flag_table
[ch_a_s
] & LI_FLAG_CONFERENCE
)
11587 for (i
= 0; i
< li_total_channels
; i
++)
11590 li_config_table
[i
].flag_table
[ch_a_s
] &= ~LI_FLAG_CONFERENCE
;
11594 if (li_flags
& LI_FLAG_CONFERENCE_A_B
)
11596 li_config_table
[ch_b_v
].flag_table
[ch_a_v
] |= LI_FLAG_CONFERENCE
;
11597 li_config_table
[ch_b_s
].flag_table
[ch_a_v
] |= LI_FLAG_CONFERENCE
;
11598 li_config_table
[ch_b_v
].flag_table
[ch_a_s
] |= LI_FLAG_CONFERENCE
;
11599 li_config_table
[ch_b_s
].flag_table
[ch_a_s
] |= LI_FLAG_CONFERENCE
;
11601 if (li_flags
& LI_FLAG_CONFERENCE_B_A
)
11603 li_config_table
[ch_a_v
].flag_table
[ch_b_v
] |= LI_FLAG_CONFERENCE
;
11604 li_config_table
[ch_a_v
].flag_table
[ch_b_s
] |= LI_FLAG_CONFERENCE
;
11605 li_config_table
[ch_a_s
].flag_table
[ch_b_v
] |= LI_FLAG_CONFERENCE
;
11606 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] |= LI_FLAG_CONFERENCE
;
11608 if (li_flags
& LI_FLAG_MONITOR_A
)
11610 li_config_table
[ch_a
].flag_table
[ch_a_v
] |= LI_FLAG_MONITOR
;
11611 li_config_table
[ch_a
].flag_table
[ch_a_s
] |= LI_FLAG_MONITOR
;
11613 if (li_flags
& LI_FLAG_MONITOR_B
)
11615 li_config_table
[ch_a
].flag_table
[ch_b_v
] |= LI_FLAG_MONITOR
;
11616 li_config_table
[ch_a
].flag_table
[ch_b_s
] |= LI_FLAG_MONITOR
;
11618 if (li_flags
& LI_FLAG_ANNOUNCEMENT_A
)
11620 li_config_table
[ch_a_v
].flag_table
[ch_a
] |= LI_FLAG_ANNOUNCEMENT
;
11621 li_config_table
[ch_a_s
].flag_table
[ch_a
] |= LI_FLAG_ANNOUNCEMENT
;
11623 if (li_flags
& LI_FLAG_ANNOUNCEMENT_B
)
11625 li_config_table
[ch_b_v
].flag_table
[ch_a
] |= LI_FLAG_ANNOUNCEMENT
;
11626 li_config_table
[ch_b_s
].flag_table
[ch_a
] |= LI_FLAG_ANNOUNCEMENT
;
11628 if (li_flags
& LI_FLAG_MIX_A
)
11630 li_config_table
[ch_a_v
].flag_table
[ch_a
] |= LI_FLAG_MIX
;
11631 li_config_table
[ch_a_s
].flag_table
[ch_a
] |= LI_FLAG_MIX
;
11633 if (li_flags
& LI_FLAG_MIX_B
)
11635 li_config_table
[ch_b_v
].flag_table
[ch_a
] |= LI_FLAG_MIX
;
11636 li_config_table
[ch_b_s
].flag_table
[ch_a
] |= LI_FLAG_MIX
;
11638 if (ch_a_v
!= ch_a_s
)
11640 li_config_table
[ch_a_v
].flag_table
[ch_a_s
] |= LI_FLAG_CONFERENCE
;
11641 li_config_table
[ch_a_s
].flag_table
[ch_a_v
] |= LI_FLAG_CONFERENCE
;
11643 if (ch_b_v
!= ch_b_s
)
11645 li_config_table
[ch_b_v
].flag_table
[ch_b_s
] |= LI_FLAG_CONFERENCE
;
11646 li_config_table
[ch_b_s
].flag_table
[ch_b_v
] |= LI_FLAG_CONFERENCE
;
11651 static void li2_update_connect(dword Id
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
,
11652 dword plci_b_id
, byte connect
, dword li_flags
)
11654 word ch_a
, ch_a_v
, ch_a_s
, ch_b
, ch_b_v
, ch_b_s
;
11656 DIVA_CAPI_ADAPTER
*a_b
;
11658 a_b
= &(adapter
[MapController((byte
)(plci_b_id
& 0x7f)) - 1]);
11659 plci_b
= &(a_b
->plci
[((plci_b_id
>> 8) & 0xff) - 1]);
11660 ch_a
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
11661 if (!a
->li_pri
&& (plci
->tel
== ADV_VOICE
)
11662 && (plci
== a
->AdvSignalPLCI
) && (Id
& EXT_CONTROLLER
))
11664 ch_a_v
= ch_a
+ MIXER_IC_CHANNEL_BASE
;
11665 ch_a_s
= (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
) ?
11666 a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
) : ch_a_v
;
11673 ch_b
= a_b
->li_base
+ (plci_b
->li_bchannel_id
- 1);
11674 if (!a_b
->li_pri
&& (plci_b
->tel
== ADV_VOICE
)
11675 && (plci_b
== a_b
->AdvSignalPLCI
) && (plci_b_id
& EXT_CONTROLLER
))
11677 ch_b_v
= ch_b
+ MIXER_IC_CHANNEL_BASE
;
11678 ch_b_s
= (a_b
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
) ?
11679 a_b
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci_b
->li_bchannel_id
) : ch_b_v
;
11688 li_config_table
[ch_b
].flag_table
[ch_b_v
] &= ~LI_FLAG_MONITOR
;
11689 li_config_table
[ch_b
].flag_table
[ch_b_s
] &= ~LI_FLAG_MONITOR
;
11690 li_config_table
[ch_b_v
].flag_table
[ch_b
] &= ~LI_FLAG_MIX
;
11691 li_config_table
[ch_b_s
].flag_table
[ch_b
] &= ~LI_FLAG_MIX
;
11692 li_config_table
[ch_b
].flag_table
[ch_b
] &= ~LI_FLAG_PCCONNECT
;
11693 li_config_table
[ch_b
].chflags
&= ~(LI_CHFLAG_MONITOR
| LI_CHFLAG_MIX
| LI_CHFLAG_LOOP
);
11695 li_config_table
[ch_b_v
].flag_table
[ch_a_v
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11696 li_config_table
[ch_b_s
].flag_table
[ch_a_v
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11697 li_config_table
[ch_b_v
].flag_table
[ch_a_s
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11698 li_config_table
[ch_b_s
].flag_table
[ch_a_s
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11699 li_config_table
[ch_a_v
].flag_table
[ch_b_v
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11700 li_config_table
[ch_a_v
].flag_table
[ch_b_s
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11701 li_config_table
[ch_a_s
].flag_table
[ch_b_v
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11702 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] &= ~(LI_FLAG_INTERCONNECT
| LI_FLAG_CONFERENCE
);
11703 if (li_flags
& LI2_FLAG_INTERCONNECT_A_B
)
11705 li_config_table
[ch_b_v
].flag_table
[ch_a_v
] |= LI_FLAG_INTERCONNECT
;
11706 li_config_table
[ch_b_s
].flag_table
[ch_a_v
] |= LI_FLAG_INTERCONNECT
;
11707 li_config_table
[ch_b_v
].flag_table
[ch_a_s
] |= LI_FLAG_INTERCONNECT
;
11708 li_config_table
[ch_b_s
].flag_table
[ch_a_s
] |= LI_FLAG_INTERCONNECT
;
11710 if (li_flags
& LI2_FLAG_INTERCONNECT_B_A
)
11712 li_config_table
[ch_a_v
].flag_table
[ch_b_v
] |= LI_FLAG_INTERCONNECT
;
11713 li_config_table
[ch_a_v
].flag_table
[ch_b_s
] |= LI_FLAG_INTERCONNECT
;
11714 li_config_table
[ch_a_s
].flag_table
[ch_b_v
] |= LI_FLAG_INTERCONNECT
;
11715 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] |= LI_FLAG_INTERCONNECT
;
11717 if (li_flags
& LI2_FLAG_MONITOR_B
)
11719 li_config_table
[ch_b
].flag_table
[ch_b_v
] |= LI_FLAG_MONITOR
;
11720 li_config_table
[ch_b
].flag_table
[ch_b_s
] |= LI_FLAG_MONITOR
;
11722 if (li_flags
& LI2_FLAG_MIX_B
)
11724 li_config_table
[ch_b_v
].flag_table
[ch_b
] |= LI_FLAG_MIX
;
11725 li_config_table
[ch_b_s
].flag_table
[ch_b
] |= LI_FLAG_MIX
;
11727 if (li_flags
& LI2_FLAG_MONITOR_X
)
11728 li_config_table
[ch_b
].chflags
|= LI_CHFLAG_MONITOR
;
11729 if (li_flags
& LI2_FLAG_MIX_X
)
11730 li_config_table
[ch_b
].chflags
|= LI_CHFLAG_MIX
;
11731 if (li_flags
& LI2_FLAG_LOOP_B
)
11733 li_config_table
[ch_b_v
].flag_table
[ch_b_v
] |= LI_FLAG_INTERCONNECT
;
11734 li_config_table
[ch_b_s
].flag_table
[ch_b_v
] |= LI_FLAG_INTERCONNECT
;
11735 li_config_table
[ch_b_v
].flag_table
[ch_b_s
] |= LI_FLAG_INTERCONNECT
;
11736 li_config_table
[ch_b_s
].flag_table
[ch_b_s
] |= LI_FLAG_INTERCONNECT
;
11738 if (li_flags
& LI2_FLAG_LOOP_PC
)
11739 li_config_table
[ch_b
].flag_table
[ch_b
] |= LI_FLAG_PCCONNECT
;
11740 if (li_flags
& LI2_FLAG_LOOP_X
)
11741 li_config_table
[ch_b
].chflags
|= LI_CHFLAG_LOOP
;
11742 if (li_flags
& LI2_FLAG_PCCONNECT_A_B
)
11743 li_config_table
[ch_b_s
].flag_table
[ch_a_s
] |= LI_FLAG_PCCONNECT
;
11744 if (li_flags
& LI2_FLAG_PCCONNECT_B_A
)
11745 li_config_table
[ch_a_s
].flag_table
[ch_b_s
] |= LI_FLAG_PCCONNECT
;
11746 if (ch_a_v
!= ch_a_s
)
11748 li_config_table
[ch_a_v
].flag_table
[ch_a_s
] |= LI_FLAG_CONFERENCE
;
11749 li_config_table
[ch_a_s
].flag_table
[ch_a_v
] |= LI_FLAG_CONFERENCE
;
11751 if (ch_b_v
!= ch_b_s
)
11753 li_config_table
[ch_b_v
].flag_table
[ch_b_s
] |= LI_FLAG_CONFERENCE
;
11754 li_config_table
[ch_b_s
].flag_table
[ch_b_v
] |= LI_FLAG_CONFERENCE
;
11759 static word
li_check_main_plci(dword Id
, PLCI
*plci
)
11763 dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
11764 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11765 return (_WRONG_IDENTIFIER
);
11768 || !plci
->NL
.Id
|| plci
->nl_remove_id
11769 || (plci
->li_bchannel_id
== 0))
11771 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
11772 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11773 return (_WRONG_STATE
);
11775 li_config_table
[plci
->adapter
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= plci
;
11780 static PLCI
*li_check_plci_b(dword Id
, PLCI
*plci
,
11781 dword plci_b_id
, word plci_b_write_pos
, byte
*p_result
)
11786 if (((plci
->li_plci_b_read_pos
> plci_b_write_pos
) ? plci
->li_plci_b_read_pos
:
11787 LI_PLCI_B_QUEUE_ENTRIES
+ plci
->li_plci_b_read_pos
) - plci_b_write_pos
- 1 < 2)
11789 dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
11790 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11791 PUT_WORD(p_result
, _REQUEST_NOT_ALLOWED_IN_THIS_STATE
);
11795 if ((plci_b_id
& 0x7f) != 0)
11797 ctlr_b
= MapController((byte
)(plci_b_id
& 0x7f));
11798 if ((ctlr_b
> max_adapter
) || ((ctlr_b
!= 0) && (adapter
[ctlr_b
- 1].request
== NULL
)))
11802 || (((plci_b_id
>> 8) & 0xff) == 0)
11803 || (((plci_b_id
>> 8) & 0xff) > adapter
[ctlr_b
- 1].max_plci
))
11805 dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx",
11806 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11807 PUT_WORD(p_result
, _WRONG_IDENTIFIER
);
11810 plci_b
= &(adapter
[ctlr_b
- 1].plci
[((plci_b_id
>> 8) & 0xff) - 1]);
11812 || !plci_b
->NL
.Id
|| plci_b
->nl_remove_id
11813 || (plci_b
->li_bchannel_id
== 0))
11815 dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx",
11816 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11817 PUT_WORD(p_result
, _REQUEST_NOT_ALLOWED_IN_THIS_STATE
);
11820 li_config_table
[plci_b
->adapter
->li_base
+ (plci_b
->li_bchannel_id
- 1)].plci
= plci_b
;
11821 if (((byte
)(plci_b_id
& ~EXT_CONTROLLER
)) !=
11822 ((byte
)(UnMapController(plci
->adapter
->Id
) & ~EXT_CONTROLLER
))
11823 && (!(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11824 || !(plci_b
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)))
11826 dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx",
11827 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11828 PUT_WORD(p_result
, _WRONG_IDENTIFIER
);
11831 if (!(get_b1_facilities(plci_b
, add_b1_facilities(plci_b
, plci_b
->B1_resource
,
11832 (word
)(plci_b
->B1_facilities
| B1_FACILITY_MIXER
))) & B1_FACILITY_MIXER
))
11834 dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d",
11835 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci_b
->B1_resource
));
11836 PUT_WORD(p_result
, _REQUEST_NOT_ALLOWED_IN_THIS_STATE
);
11843 static PLCI
*li2_check_plci_b(dword Id
, PLCI
*plci
,
11844 dword plci_b_id
, word plci_b_write_pos
, byte
*p_result
)
11849 if (((plci
->li_plci_b_read_pos
> plci_b_write_pos
) ? plci
->li_plci_b_read_pos
:
11850 LI_PLCI_B_QUEUE_ENTRIES
+ plci
->li_plci_b_read_pos
) - plci_b_write_pos
- 1 < 2)
11852 dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
11853 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11854 PUT_WORD(p_result
, _WRONG_STATE
);
11858 if ((plci_b_id
& 0x7f) != 0)
11860 ctlr_b
= MapController((byte
)(plci_b_id
& 0x7f));
11861 if ((ctlr_b
> max_adapter
) || ((ctlr_b
!= 0) && (adapter
[ctlr_b
- 1].request
== NULL
)))
11865 || (((plci_b_id
>> 8) & 0xff) == 0)
11866 || (((plci_b_id
>> 8) & 0xff) > adapter
[ctlr_b
- 1].max_plci
))
11868 dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx",
11869 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11870 PUT_WORD(p_result
, _WRONG_IDENTIFIER
);
11873 plci_b
= &(adapter
[ctlr_b
- 1].plci
[((plci_b_id
>> 8) & 0xff) - 1]);
11875 || !plci_b
->NL
.Id
|| plci_b
->nl_remove_id
11876 || (plci_b
->li_bchannel_id
== 0)
11877 || (li_config_table
[plci_b
->adapter
->li_base
+ (plci_b
->li_bchannel_id
- 1)].plci
!= plci_b
))
11879 dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx",
11880 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11881 PUT_WORD(p_result
, _WRONG_STATE
);
11884 if (((byte
)(plci_b_id
& ~EXT_CONTROLLER
)) !=
11885 ((byte
)(UnMapController(plci
->adapter
->Id
) & ~EXT_CONTROLLER
))
11886 && (!(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11887 || !(plci_b
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)))
11889 dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx",
11890 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci_b_id
));
11891 PUT_WORD(p_result
, _WRONG_IDENTIFIER
);
11894 if (!(get_b1_facilities(plci_b
, add_b1_facilities(plci_b
, plci_b
->B1_resource
,
11895 (word
)(plci_b
->B1_facilities
| B1_FACILITY_MIXER
))) & B1_FACILITY_MIXER
))
11897 dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d",
11898 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci_b
->B1_resource
));
11899 PUT_WORD(p_result
, _WRONG_STATE
);
11906 static byte
mixer_request(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
11910 dword d
, li_flags
, plci_b_id
;
11912 API_PARSE li_parms
[3];
11913 API_PARSE li_req_parms
[3];
11914 API_PARSE li_participant_struct
[2];
11915 API_PARSE li_participant_parms
[3];
11916 word participant_parms_pos
;
11917 byte result_buffer
[32];
11920 word plci_b_write_pos
;
11922 dbug(1, dprintf("[%06lx] %s,%d: mixer_request",
11923 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11926 result
= result_buffer
;
11927 result_buffer
[0] = 0;
11928 if (!(a
->profile
.Global_Options
& GL_LINE_INTERCONNECT_SUPPORTED
))
11930 dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
11931 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11932 Info
= _FACILITY_NOT_SUPPORTED
;
11934 else if (api_parse(&msg
[1].info
[1], msg
[1].length
, "ws", li_parms
))
11936 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
11937 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
11938 Info
= _WRONG_MESSAGE_FORMAT
;
11942 result_buffer
[0] = 3;
11943 PUT_WORD(&result_buffer
[1], GET_WORD(li_parms
[0].info
));
11944 result_buffer
[3] = 0;
11945 switch (GET_WORD(li_parms
[0].info
))
11947 case LI_GET_SUPPORTED_SERVICES
:
11948 if (appl
->appl_flags
& APPL_FLAG_OLD_LI_SPEC
)
11950 result_buffer
[0] = 17;
11951 result_buffer
[3] = 14;
11952 PUT_WORD(&result_buffer
[4], GOOD
);
11954 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_CH_CH
)
11955 d
|= LI_CONFERENCING_SUPPORTED
;
11956 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_CH_PC
)
11957 d
|= LI_MONITORING_SUPPORTED
;
11958 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_PC_CH
)
11959 d
|= LI_ANNOUNCEMENTS_SUPPORTED
| LI_MIXING_SUPPORTED
;
11960 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11961 d
|= LI_CROSS_CONTROLLER_SUPPORTED
;
11962 PUT_DWORD(&result_buffer
[6], d
);
11963 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11966 for (i
= 0; i
< li_total_channels
; i
++)
11968 if ((li_config_table
[i
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11969 && (li_config_table
[i
].adapter
->li_pri
11970 || (i
< li_config_table
[i
].adapter
->li_base
+ MIXER_BCHANNELS_BRI
)))
11978 d
= a
->li_pri
? a
->li_channels
: MIXER_BCHANNELS_BRI
;
11980 PUT_DWORD(&result_buffer
[10], d
/ 2);
11981 PUT_DWORD(&result_buffer
[14], d
);
11985 result_buffer
[0] = 25;
11986 result_buffer
[3] = 22;
11987 PUT_WORD(&result_buffer
[4], GOOD
);
11988 d
= LI2_ASYMMETRIC_SUPPORTED
| LI2_B_LOOPING_SUPPORTED
| LI2_X_LOOPING_SUPPORTED
;
11989 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_CH_PC
)
11990 d
|= LI2_MONITORING_SUPPORTED
| LI2_REMOTE_MONITORING_SUPPORTED
;
11991 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_PC_CH
)
11992 d
|= LI2_MIXING_SUPPORTED
| LI2_REMOTE_MIXING_SUPPORTED
;
11993 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_MIXER_PC_PC
)
11994 d
|= LI2_PC_LOOPING_SUPPORTED
;
11995 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
11996 d
|= LI2_CROSS_CONTROLLER_SUPPORTED
;
11997 PUT_DWORD(&result_buffer
[6], d
);
11998 d
= a
->li_pri
? a
->li_channels
: MIXER_BCHANNELS_BRI
;
11999 PUT_DWORD(&result_buffer
[10], d
/ 2);
12000 PUT_DWORD(&result_buffer
[14], d
- 1);
12001 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12004 for (i
= 0; i
< li_total_channels
; i
++)
12006 if ((li_config_table
[i
].adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XCONNECT
)
12007 && (li_config_table
[i
].adapter
->li_pri
12008 || (i
< li_config_table
[i
].adapter
->li_base
+ MIXER_BCHANNELS_BRI
)))
12014 PUT_DWORD(&result_buffer
[18], d
/ 2);
12015 PUT_DWORD(&result_buffer
[22], d
- 1);
12019 case LI_REQ_CONNECT
:
12020 if (li_parms
[1].length
== 8)
12022 appl
->appl_flags
|= APPL_FLAG_OLD_LI_SPEC
;
12023 if (api_parse(&li_parms
[1].info
[1], li_parms
[1].length
, "dd", li_req_parms
))
12025 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12026 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12027 Info
= _WRONG_MESSAGE_FORMAT
;
12030 plci_b_id
= GET_DWORD(li_req_parms
[0].info
) & 0xffff;
12031 li_flags
= GET_DWORD(li_req_parms
[1].info
);
12032 Info
= li_check_main_plci(Id
, plci
);
12033 result_buffer
[0] = 9;
12034 result_buffer
[3] = 6;
12035 PUT_DWORD(&result_buffer
[4], plci_b_id
);
12036 PUT_WORD(&result_buffer
[8], GOOD
);
12039 result
= plci
->saved_msg
.info
;
12040 for (i
= 0; i
<= result_buffer
[0]; i
++)
12041 result
[i
] = result_buffer
[i
];
12042 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12043 plci_b
= li_check_plci_b(Id
, plci
, plci_b_id
, plci_b_write_pos
, &result
[8]);
12044 if (plci_b
== NULL
)
12046 li_update_connect(Id
, a
, plci
, plci_b_id
, true, li_flags
);
12047 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
| LI_PLCI_B_LAST_FLAG
;
12048 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ? 0 : plci_b_write_pos
+ 1;
12049 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12053 appl
->appl_flags
&= ~APPL_FLAG_OLD_LI_SPEC
;
12054 if (api_parse(&li_parms
[1].info
[1], li_parms
[1].length
, "ds", li_req_parms
))
12056 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12057 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12058 Info
= _WRONG_MESSAGE_FORMAT
;
12061 li_flags
= GET_DWORD(li_req_parms
[0].info
) & ~(LI2_FLAG_INTERCONNECT_A_B
| LI2_FLAG_INTERCONNECT_B_A
);
12062 Info
= li_check_main_plci(Id
, plci
);
12063 result_buffer
[0] = 7;
12064 result_buffer
[3] = 4;
12065 PUT_WORD(&result_buffer
[4], Info
);
12066 result_buffer
[6] = 0;
12069 result
= plci
->saved_msg
.info
;
12070 for (i
= 0; i
<= result_buffer
[0]; i
++)
12071 result
[i
] = result_buffer
[i
];
12072 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12073 participant_parms_pos
= 0;
12075 li2_update_connect(Id
, a
, plci
, UnMapId(Id
), true, li_flags
);
12076 while (participant_parms_pos
< li_req_parms
[1].length
)
12078 result
[result_pos
] = 6;
12080 PUT_DWORD(&result
[result_pos
- 6], 0);
12081 PUT_WORD(&result
[result_pos
- 2], GOOD
);
12082 if (api_parse(&li_req_parms
[1].info
[1 + participant_parms_pos
],
12083 (word
)(li_parms
[1].length
- participant_parms_pos
), "s", li_participant_struct
))
12085 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12086 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12087 PUT_WORD(&result
[result_pos
- 2], _WRONG_MESSAGE_FORMAT
);
12090 if (api_parse(&li_participant_struct
[0].info
[1],
12091 li_participant_struct
[0].length
, "dd", li_participant_parms
))
12093 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12094 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12095 PUT_WORD(&result
[result_pos
- 2], _WRONG_MESSAGE_FORMAT
);
12098 plci_b_id
= GET_DWORD(li_participant_parms
[0].info
) & 0xffff;
12099 li_flags
= GET_DWORD(li_participant_parms
[1].info
);
12100 PUT_DWORD(&result
[result_pos
- 6], plci_b_id
);
12101 if (sizeof(result
) - result_pos
< 7)
12103 dbug(1, dprintf("[%06lx] %s,%d: LI result overrun",
12104 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12105 PUT_WORD(&result
[result_pos
- 2], _WRONG_STATE
);
12108 plci_b
= li2_check_plci_b(Id
, plci
, plci_b_id
, plci_b_write_pos
, &result
[result_pos
- 2]);
12109 if (plci_b
!= NULL
)
12111 li2_update_connect(Id
, a
, plci
, plci_b_id
, true, li_flags
);
12112 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
|
12113 ((li_flags
& (LI2_FLAG_INTERCONNECT_A_B
| LI2_FLAG_INTERCONNECT_B_A
|
12114 LI2_FLAG_PCCONNECT_A_B
| LI2_FLAG_PCCONNECT_B_A
)) ? 0 : LI_PLCI_B_DISC_FLAG
);
12115 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ? 0 : plci_b_write_pos
+ 1;
12117 participant_parms_pos
= (word
)((&li_participant_struct
[0].info
[1 + li_participant_struct
[0].length
]) -
12118 (&li_req_parms
[1].info
[1]));
12120 result
[0] = (byte
)(result_pos
- 1);
12121 result
[3] = (byte
)(result_pos
- 4);
12122 result
[6] = (byte
)(result_pos
- 7);
12123 i
= (plci_b_write_pos
== 0) ? LI_PLCI_B_QUEUE_ENTRIES
- 1 : plci_b_write_pos
- 1;
12124 if ((plci_b_write_pos
== plci
->li_plci_b_read_pos
)
12125 || (plci
->li_plci_b_queue
[i
] & LI_PLCI_B_LAST_FLAG
))
12127 plci
->li_plci_b_queue
[plci_b_write_pos
] = LI_PLCI_B_SKIP_FLAG
| LI_PLCI_B_LAST_FLAG
;
12128 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ? 0 : plci_b_write_pos
+ 1;
12131 plci
->li_plci_b_queue
[i
] |= LI_PLCI_B_LAST_FLAG
;
12132 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12134 mixer_calculate_coefs(a
);
12135 plci
->li_channel_bits
= li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].channel
;
12136 mixer_notify_update(plci
, true);
12137 sendf(appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
12138 "wwS", Info
, SELECTOR_LINE_INTERCONNECT
, result
);
12140 plci
->li_cmd
= GET_WORD(li_parms
[0].info
);
12141 start_internal_command(Id
, plci
, mixer_command
);
12144 case LI_REQ_DISCONNECT
:
12145 if (li_parms
[1].length
== 4)
12147 appl
->appl_flags
|= APPL_FLAG_OLD_LI_SPEC
;
12148 if (api_parse(&li_parms
[1].info
[1], li_parms
[1].length
, "d", li_req_parms
))
12150 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12151 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12152 Info
= _WRONG_MESSAGE_FORMAT
;
12155 plci_b_id
= GET_DWORD(li_req_parms
[0].info
) & 0xffff;
12156 Info
= li_check_main_plci(Id
, plci
);
12157 result_buffer
[0] = 9;
12158 result_buffer
[3] = 6;
12159 PUT_DWORD(&result_buffer
[4], GET_DWORD(li_req_parms
[0].info
));
12160 PUT_WORD(&result_buffer
[8], GOOD
);
12163 result
= plci
->saved_msg
.info
;
12164 for (i
= 0; i
<= result_buffer
[0]; i
++)
12165 result
[i
] = result_buffer
[i
];
12166 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12167 plci_b
= li_check_plci_b(Id
, plci
, plci_b_id
, plci_b_write_pos
, &result
[8]);
12168 if (plci_b
== NULL
)
12170 li_update_connect(Id
, a
, plci
, plci_b_id
, false, 0);
12171 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
| LI_PLCI_B_DISC_FLAG
| LI_PLCI_B_LAST_FLAG
;
12172 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ? 0 : plci_b_write_pos
+ 1;
12173 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12177 appl
->appl_flags
&= ~APPL_FLAG_OLD_LI_SPEC
;
12178 if (api_parse(&li_parms
[1].info
[1], li_parms
[1].length
, "s", li_req_parms
))
12180 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12181 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12182 Info
= _WRONG_MESSAGE_FORMAT
;
12185 Info
= li_check_main_plci(Id
, plci
);
12186 result_buffer
[0] = 7;
12187 result_buffer
[3] = 4;
12188 PUT_WORD(&result_buffer
[4], Info
);
12189 result_buffer
[6] = 0;
12192 result
= plci
->saved_msg
.info
;
12193 for (i
= 0; i
<= result_buffer
[0]; i
++)
12194 result
[i
] = result_buffer
[i
];
12195 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12196 participant_parms_pos
= 0;
12198 while (participant_parms_pos
< li_req_parms
[0].length
)
12200 result
[result_pos
] = 6;
12202 PUT_DWORD(&result
[result_pos
- 6], 0);
12203 PUT_WORD(&result
[result_pos
- 2], GOOD
);
12204 if (api_parse(&li_req_parms
[0].info
[1 + participant_parms_pos
],
12205 (word
)(li_parms
[1].length
- participant_parms_pos
), "s", li_participant_struct
))
12207 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12208 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12209 PUT_WORD(&result
[result_pos
- 2], _WRONG_MESSAGE_FORMAT
);
12212 if (api_parse(&li_participant_struct
[0].info
[1],
12213 li_participant_struct
[0].length
, "d", li_participant_parms
))
12215 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12216 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12217 PUT_WORD(&result
[result_pos
- 2], _WRONG_MESSAGE_FORMAT
);
12220 plci_b_id
= GET_DWORD(li_participant_parms
[0].info
) & 0xffff;
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
, false, 0);
12233 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
| LI_PLCI_B_DISC_FLAG
;
12234 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ? 0 : plci_b_write_pos
+ 1;
12236 participant_parms_pos
= (word
)((&li_participant_struct
[0].info
[1 + li_participant_struct
[0].length
]) -
12237 (&li_req_parms
[0].info
[1]));
12239 result
[0] = (byte
)(result_pos
- 1);
12240 result
[3] = (byte
)(result_pos
- 4);
12241 result
[6] = (byte
)(result_pos
- 7);
12242 i
= (plci_b_write_pos
== 0) ? LI_PLCI_B_QUEUE_ENTRIES
- 1 : plci_b_write_pos
- 1;
12243 if ((plci_b_write_pos
== plci
->li_plci_b_read_pos
)
12244 || (plci
->li_plci_b_queue
[i
] & LI_PLCI_B_LAST_FLAG
))
12246 plci
->li_plci_b_queue
[plci_b_write_pos
] = LI_PLCI_B_SKIP_FLAG
| LI_PLCI_B_LAST_FLAG
;
12247 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ? 0 : plci_b_write_pos
+ 1;
12250 plci
->li_plci_b_queue
[i
] |= LI_PLCI_B_LAST_FLAG
;
12251 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12253 mixer_calculate_coefs(a
);
12254 plci
->li_channel_bits
= li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].channel
;
12255 mixer_notify_update(plci
, true);
12256 sendf(appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
12257 "wwS", Info
, SELECTOR_LINE_INTERCONNECT
, result
);
12259 plci
->li_cmd
= GET_WORD(li_parms
[0].info
);
12260 start_internal_command(Id
, plci
, mixer_command
);
12263 case LI_REQ_SILENT_UPDATE
:
12264 if (!plci
|| !plci
->State
12265 || !plci
->NL
.Id
|| plci
->nl_remove_id
12266 || (plci
->li_bchannel_id
== 0)
12267 || (li_config_table
[plci
->adapter
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
!= plci
))
12269 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
12270 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12273 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12274 if (((plci
->li_plci_b_read_pos
> plci_b_write_pos
) ? plci
->li_plci_b_read_pos
:
12275 LI_PLCI_B_QUEUE_ENTRIES
+ plci
->li_plci_b_read_pos
) - plci_b_write_pos
- 1 < 2)
12277 dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
12278 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12281 i
= (plci_b_write_pos
== 0) ? LI_PLCI_B_QUEUE_ENTRIES
- 1 : plci_b_write_pos
- 1;
12282 if ((plci_b_write_pos
== plci
->li_plci_b_read_pos
)
12283 || (plci
->li_plci_b_queue
[i
] & LI_PLCI_B_LAST_FLAG
))
12285 plci
->li_plci_b_queue
[plci_b_write_pos
] = LI_PLCI_B_SKIP_FLAG
| LI_PLCI_B_LAST_FLAG
;
12286 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ? 0 : plci_b_write_pos
+ 1;
12289 plci
->li_plci_b_queue
[i
] |= LI_PLCI_B_LAST_FLAG
;
12290 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12291 plci
->li_channel_bits
= li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].channel
;
12293 plci
->li_cmd
= GET_WORD(li_parms
[0].info
);
12294 start_internal_command(Id
, plci
, mixer_command
);
12298 dbug(1, dprintf("[%06lx] %s,%d: LI unknown request %04x",
12299 UnMapId(Id
), (char *)(FILE_
), __LINE__
, GET_WORD(li_parms
[0].info
)));
12300 Info
= _FACILITY_NOT_SUPPORTED
;
12303 sendf(appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
12304 "wwS", Info
, SELECTOR_LINE_INTERCONNECT
, result
);
12309 static void mixer_indication_coefs_set(dword Id
, PLCI
*plci
)
12314 dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_coefs_set",
12315 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12317 if (plci
->li_plci_b_read_pos
!= plci
->li_plci_b_req_pos
)
12321 d
= plci
->li_plci_b_queue
[plci
->li_plci_b_read_pos
];
12322 if (!(d
& LI_PLCI_B_SKIP_FLAG
))
12324 if (plci
->appl
->appl_flags
& APPL_FLAG_OLD_LI_SPEC
)
12326 if (d
& LI_PLCI_B_DISC_FLAG
)
12329 PUT_WORD(&result
[1], LI_IND_DISCONNECT
);
12331 PUT_WORD(&result
[4], _LI_USER_INITIATED
);
12336 PUT_WORD(&result
[1], LI_IND_CONNECT_ACTIVE
);
12338 PUT_DWORD(&result
[4], d
& ~LI_PLCI_B_FLAG_MASK
);
12343 if (d
& LI_PLCI_B_DISC_FLAG
)
12346 PUT_WORD(&result
[1], LI_IND_DISCONNECT
);
12348 PUT_DWORD(&result
[4], d
& ~LI_PLCI_B_FLAG_MASK
);
12349 PUT_WORD(&result
[8], _LI_USER_INITIATED
);
12354 PUT_WORD(&result
[1], LI_IND_CONNECT_ACTIVE
);
12356 PUT_DWORD(&result
[4], d
& ~LI_PLCI_B_FLAG_MASK
);
12359 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0,
12360 "ws", SELECTOR_LINE_INTERCONNECT
, result
);
12362 plci
->li_plci_b_read_pos
= (plci
->li_plci_b_read_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ?
12363 0 : plci
->li_plci_b_read_pos
+ 1;
12364 } while (!(d
& LI_PLCI_B_LAST_FLAG
) && (plci
->li_plci_b_read_pos
!= plci
->li_plci_b_req_pos
));
12369 static void mixer_indication_xconnect_from(dword Id
, PLCI
*plci
, byte
*msg
, word length
)
12372 struct xconnect_transfer_address_s s
, *p
;
12373 DIVA_CAPI_ADAPTER
*a
;
12375 dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_from %d",
12376 UnMapId(Id
), (char *)(FILE_
), __LINE__
, (int)length
));
12380 for (i
= 1; i
< length
; i
+= 16)
12382 s
.card_address
.low
= msg
[i
] | (msg
[i
+ 1] << 8) | (((dword
)(msg
[i
+ 2])) << 16) | (((dword
)(msg
[i
+ 3])) << 24);
12383 s
.card_address
.high
= msg
[i
+ 4] | (msg
[i
+ 5] << 8) | (((dword
)(msg
[i
+ 6])) << 16) | (((dword
)(msg
[i
+ 7])) << 24);
12384 s
.offset
= msg
[i
+ 8] | (msg
[i
+ 9] << 8) | (((dword
)(msg
[i
+ 10])) << 16) | (((dword
)(msg
[i
+ 11])) << 24);
12385 ch
= msg
[i
+ 12] | (msg
[i
+ 13] << 8);
12386 j
= ch
& XCONNECT_CHANNEL_NUMBER_MASK
;
12387 if (!a
->li_pri
&& (plci
->li_bchannel_id
== 2))
12390 if (ch
& XCONNECT_CHANNEL_PORT_PC
)
12391 p
= &(li_config_table
[j
].send_pc
);
12393 p
= &(li_config_table
[j
].send_b
);
12394 p
->card_address
.low
= s
.card_address
.low
;
12395 p
->card_address
.high
= s
.card_address
.high
;
12396 p
->offset
= s
.offset
;
12397 li_config_table
[j
].channel
|= LI_CHANNEL_ADDRESSES_SET
;
12399 if (plci
->internal_command_queue
[0]
12400 && ((plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_2
)
12401 || (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_3
)
12402 || (plci
->adjust_b_state
== ADJUST_B_RESTORE_MIXER_4
)))
12404 (*(plci
->internal_command_queue
[0]))(Id
, plci
, 0);
12405 if (!plci
->internal_command
)
12406 next_internal_command(Id
, plci
);
12408 mixer_notify_update(plci
, true);
12412 static void mixer_indication_xconnect_to(dword Id
, PLCI
*plci
, byte
*msg
, word length
)
12415 dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_to %d",
12416 UnMapId(Id
), (char *)(FILE_
), __LINE__
, (int) length
));
12421 static byte
mixer_notify_source_removed(PLCI
*plci
, dword plci_b_id
)
12423 word plci_b_write_pos
;
12425 plci_b_write_pos
= plci
->li_plci_b_write_pos
;
12426 if (((plci
->li_plci_b_read_pos
> plci_b_write_pos
) ? plci
->li_plci_b_read_pos
:
12427 LI_PLCI_B_QUEUE_ENTRIES
+ plci
->li_plci_b_read_pos
) - plci_b_write_pos
- 1 < 1)
12429 dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
12430 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
12431 (char *)(FILE_
), __LINE__
));
12434 plci
->li_plci_b_queue
[plci_b_write_pos
] = plci_b_id
| LI_PLCI_B_DISC_FLAG
;
12435 plci_b_write_pos
= (plci_b_write_pos
== LI_PLCI_B_QUEUE_ENTRIES
- 1) ? 0 : plci_b_write_pos
+ 1;
12436 plci
->li_plci_b_write_pos
= plci_b_write_pos
;
12441 static void mixer_remove(PLCI
*plci
)
12443 DIVA_CAPI_ADAPTER
*a
;
12448 dbug(1, dprintf("[%06lx] %s,%d: mixer_remove",
12449 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
12450 (char *)(FILE_
), __LINE__
));
12453 plci_b_id
= (plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
);
12454 if (a
->profile
.Global_Options
& GL_LINE_INTERCONNECT_SUPPORTED
)
12456 if ((plci
->li_bchannel_id
!= 0)
12457 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
12459 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
12460 if ((li_config_table
[i
].curchnl
| li_config_table
[i
].channel
) & LI_CHANNEL_INVOLVED
)
12462 for (j
= 0; j
< li_total_channels
; j
++)
12464 if ((li_config_table
[i
].flag_table
[j
] & LI_FLAG_INTERCONNECT
)
12465 || (li_config_table
[j
].flag_table
[i
] & LI_FLAG_INTERCONNECT
))
12467 notify_plci
= li_config_table
[j
].plci
;
12468 if ((notify_plci
!= NULL
)
12469 && (notify_plci
!= plci
)
12470 && (notify_plci
->appl
!= NULL
)
12471 && !(notify_plci
->appl
->appl_flags
& APPL_FLAG_OLD_LI_SPEC
)
12472 && (notify_plci
->State
)
12473 && notify_plci
->NL
.Id
&& !notify_plci
->nl_remove_id
)
12475 mixer_notify_source_removed(notify_plci
, plci_b_id
);
12479 mixer_clear_config(plci
);
12480 mixer_calculate_coefs(a
);
12481 mixer_notify_update(plci
, true);
12483 li_config_table
[i
].plci
= NULL
;
12484 plci
->li_bchannel_id
= 0;
12490 /*------------------------------------------------------------------*/
12491 /* Echo canceller facilities */
12492 /*------------------------------------------------------------------*/
12495 static void ec_write_parameters(PLCI
*plci
)
12498 byte parameter_buffer
[6];
12500 dbug(1, dprintf("[%06lx] %s,%d: ec_write_parameters",
12501 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
12502 (char *)(FILE_
), __LINE__
));
12504 parameter_buffer
[0] = 5;
12505 parameter_buffer
[1] = DSP_CTRL_SET_LEC_PARAMETERS
;
12506 PUT_WORD(¶meter_buffer
[2], plci
->ec_idi_options
);
12507 plci
->ec_idi_options
&= ~LEC_RESET_COEFFICIENTS
;
12508 w
= (plci
->ec_tail_length
== 0) ? 128 : plci
->ec_tail_length
;
12509 PUT_WORD(¶meter_buffer
[4], w
);
12510 add_p(plci
, FTY
, parameter_buffer
);
12511 sig_req(plci
, TEL_CTRL
, 0);
12516 static void ec_clear_config(PLCI
*plci
)
12519 dbug(1, dprintf("[%06lx] %s,%d: ec_clear_config",
12520 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
12521 (char *)(FILE_
), __LINE__
));
12523 plci
->ec_idi_options
= LEC_ENABLE_ECHO_CANCELLER
|
12524 LEC_MANUAL_DISABLE
| LEC_ENABLE_NONLINEAR_PROCESSING
;
12525 plci
->ec_tail_length
= 0;
12529 static void ec_prepare_switch(dword Id
, PLCI
*plci
)
12532 dbug(1, dprintf("[%06lx] %s,%d: ec_prepare_switch",
12533 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12538 static word
ec_save_config(dword Id
, PLCI
*plci
, byte Rc
)
12541 dbug(1, dprintf("[%06lx] %s,%d: ec_save_config %02x %d",
12542 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
12548 static word
ec_restore_config(dword Id
, PLCI
*plci
, byte Rc
)
12552 dbug(1, dprintf("[%06lx] %s,%d: ec_restore_config %02x %d",
12553 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
12556 if (plci
->B1_facilities
& B1_FACILITY_EC
)
12558 switch (plci
->adjust_b_state
)
12560 case ADJUST_B_RESTORE_EC_1
:
12561 plci
->internal_command
= plci
->adjust_b_command
;
12564 plci
->adjust_b_state
= ADJUST_B_RESTORE_EC_1
;
12567 ec_write_parameters(plci
);
12568 plci
->adjust_b_state
= ADJUST_B_RESTORE_EC_2
;
12570 case ADJUST_B_RESTORE_EC_2
:
12571 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
12573 dbug(1, dprintf("[%06lx] %s,%d: Restore EC failed %02x",
12574 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
12575 Info
= _WRONG_STATE
;
12585 static void ec_command(dword Id
, PLCI
*plci
, byte Rc
)
12587 word internal_command
, Info
;
12590 dbug(1, dprintf("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d",
12591 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
,
12592 plci
->ec_cmd
, plci
->ec_idi_options
, plci
->ec_tail_length
));
12595 if (plci
->appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
)
12598 PUT_WORD(&result
[1], EC_SUCCESS
);
12603 PUT_WORD(&result
[1], plci
->ec_cmd
);
12605 PUT_WORD(&result
[4], GOOD
);
12607 internal_command
= plci
->internal_command
;
12608 plci
->internal_command
= 0;
12609 switch (plci
->ec_cmd
)
12611 case EC_ENABLE_OPERATION
:
12612 case EC_FREEZE_COEFFICIENTS
:
12613 case EC_RESUME_COEFFICIENT_UPDATE
:
12614 case EC_RESET_COEFFICIENTS
:
12615 switch (internal_command
)
12618 adjust_b1_resource(Id
, plci
, NULL
, (word
)(plci
->B1_facilities
|
12619 B1_FACILITY_EC
), EC_COMMAND_1
);
12622 if (adjust_b_process(Id
, plci
, Rc
) != GOOD
)
12624 dbug(1, dprintf("[%06lx] %s,%d: Load EC failed",
12625 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12626 Info
= _FACILITY_NOT_SUPPORTED
;
12629 if (plci
->internal_command
)
12635 plci
->internal_command
= EC_COMMAND_2
;
12638 plci
->internal_command
= EC_COMMAND_3
;
12639 ec_write_parameters(plci
);
12642 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
12644 dbug(1, dprintf("[%06lx] %s,%d: Enable EC failed %02x",
12645 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
12646 Info
= _FACILITY_NOT_SUPPORTED
;
12653 case EC_DISABLE_OPERATION
:
12654 switch (internal_command
)
12658 if (plci
->B1_facilities
& B1_FACILITY_EC
)
12662 plci
->internal_command
= EC_COMMAND_1
;
12665 plci
->internal_command
= EC_COMMAND_2
;
12666 ec_write_parameters(plci
);
12672 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
12674 dbug(1, dprintf("[%06lx] %s,%d: Disable EC failed %02x",
12675 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
12676 Info
= _FACILITY_NOT_SUPPORTED
;
12679 adjust_b1_resource(Id
, plci
, NULL
, (word
)(plci
->B1_facilities
&
12680 ~B1_FACILITY_EC
), EC_COMMAND_3
);
12683 if (adjust_b_process(Id
, plci
, Rc
) != GOOD
)
12685 dbug(1, dprintf("[%06lx] %s,%d: Unload EC failed",
12686 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12687 Info
= _FACILITY_NOT_SUPPORTED
;
12690 if (plci
->internal_command
)
12696 sendf(plci
->appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, plci
->number
,
12697 "wws", Info
, (plci
->appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
) ?
12698 PRIV_SELECTOR_ECHO_CANCELLER
: SELECTOR_ECHO_CANCELLER
, result
);
12702 static byte
ec_request(dword Id
, word Number
, DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
, APPL
*appl
, API_PARSE
*msg
)
12706 API_PARSE ec_parms
[3];
12709 dbug(1, dprintf("[%06lx] %s,%d: ec_request",
12710 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12714 if (!(a
->man_profile
.private_options
& (1L << PRIVATE_ECHO_CANCELLER
)))
12716 dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
12717 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12718 Info
= _FACILITY_NOT_SUPPORTED
;
12722 if (appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
)
12724 if (api_parse(&msg
[1].info
[1], msg
[1].length
, "w", ec_parms
))
12726 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12727 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12728 Info
= _WRONG_MESSAGE_FORMAT
;
12734 dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
12735 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12736 Info
= _WRONG_IDENTIFIER
;
12738 else if (!plci
->State
|| !plci
->NL
.Id
|| plci
->nl_remove_id
)
12740 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
12741 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12742 Info
= _WRONG_STATE
;
12747 plci
->ec_cmd
= GET_WORD(ec_parms
[0].info
);
12748 plci
->ec_idi_options
&= ~(LEC_MANUAL_DISABLE
| LEC_RESET_COEFFICIENTS
);
12750 PUT_WORD(&result
[1], EC_SUCCESS
);
12751 if (msg
[1].length
>= 4)
12753 opt
= GET_WORD(&ec_parms
[0].info
[2]);
12754 plci
->ec_idi_options
&= ~(LEC_ENABLE_NONLINEAR_PROCESSING
|
12755 LEC_ENABLE_2100HZ_DETECTOR
| LEC_REQUIRE_2100HZ_REVERSALS
);
12756 if (!(opt
& EC_DISABLE_NON_LINEAR_PROCESSING
))
12757 plci
->ec_idi_options
|= LEC_ENABLE_NONLINEAR_PROCESSING
;
12758 if (opt
& EC_DETECT_DISABLE_TONE
)
12759 plci
->ec_idi_options
|= LEC_ENABLE_2100HZ_DETECTOR
;
12760 if (!(opt
& EC_DO_NOT_REQUIRE_REVERSALS
))
12761 plci
->ec_idi_options
|= LEC_REQUIRE_2100HZ_REVERSALS
;
12762 if (msg
[1].length
>= 6)
12764 plci
->ec_tail_length
= GET_WORD(&ec_parms
[0].info
[4]);
12767 switch (plci
->ec_cmd
)
12769 case EC_ENABLE_OPERATION
:
12770 plci
->ec_idi_options
&= ~LEC_FREEZE_COEFFICIENTS
;
12771 start_internal_command(Id
, plci
, ec_command
);
12774 case EC_DISABLE_OPERATION
:
12775 plci
->ec_idi_options
= LEC_ENABLE_ECHO_CANCELLER
|
12776 LEC_MANUAL_DISABLE
| LEC_ENABLE_NONLINEAR_PROCESSING
|
12777 LEC_RESET_COEFFICIENTS
;
12778 start_internal_command(Id
, plci
, ec_command
);
12781 case EC_FREEZE_COEFFICIENTS
:
12782 plci
->ec_idi_options
|= LEC_FREEZE_COEFFICIENTS
;
12783 start_internal_command(Id
, plci
, ec_command
);
12786 case EC_RESUME_COEFFICIENT_UPDATE
:
12787 plci
->ec_idi_options
&= ~LEC_FREEZE_COEFFICIENTS
;
12788 start_internal_command(Id
, plci
, ec_command
);
12791 case EC_RESET_COEFFICIENTS
:
12792 plci
->ec_idi_options
|= LEC_RESET_COEFFICIENTS
;
12793 start_internal_command(Id
, plci
, ec_command
);
12797 dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x",
12798 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci
->ec_cmd
));
12799 PUT_WORD(&result
[1], EC_UNSUPPORTED_OPERATION
);
12806 if (api_parse(&msg
[1].info
[1], msg
[1].length
, "ws", ec_parms
))
12808 dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
12809 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12810 Info
= _WRONG_MESSAGE_FORMAT
;
12814 if (GET_WORD(ec_parms
[0].info
) == EC_GET_SUPPORTED_SERVICES
)
12817 PUT_WORD(&result
[1], EC_GET_SUPPORTED_SERVICES
);
12819 PUT_WORD(&result
[4], GOOD
);
12820 PUT_WORD(&result
[6], 0x0007);
12821 PUT_WORD(&result
[8], LEC_MAX_SUPPORTED_TAIL_LENGTH
);
12822 PUT_WORD(&result
[10], 0);
12824 else if (plci
== NULL
)
12826 dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
12827 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12828 Info
= _WRONG_IDENTIFIER
;
12830 else if (!plci
->State
|| !plci
->NL
.Id
|| plci
->nl_remove_id
)
12832 dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
12833 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12834 Info
= _WRONG_STATE
;
12839 plci
->ec_cmd
= GET_WORD(ec_parms
[0].info
);
12840 plci
->ec_idi_options
&= ~(LEC_MANUAL_DISABLE
| LEC_RESET_COEFFICIENTS
);
12842 PUT_WORD(&result
[1], plci
->ec_cmd
);
12844 PUT_WORD(&result
[4], GOOD
);
12845 plci
->ec_idi_options
&= ~(LEC_ENABLE_NONLINEAR_PROCESSING
|
12846 LEC_ENABLE_2100HZ_DETECTOR
| LEC_REQUIRE_2100HZ_REVERSALS
);
12847 plci
->ec_tail_length
= 0;
12848 if (ec_parms
[1].length
>= 2)
12850 opt
= GET_WORD(&ec_parms
[1].info
[1]);
12851 if (opt
& EC_ENABLE_NON_LINEAR_PROCESSING
)
12852 plci
->ec_idi_options
|= LEC_ENABLE_NONLINEAR_PROCESSING
;
12853 if (opt
& EC_DETECT_DISABLE_TONE
)
12854 plci
->ec_idi_options
|= LEC_ENABLE_2100HZ_DETECTOR
;
12855 if (!(opt
& EC_DO_NOT_REQUIRE_REVERSALS
))
12856 plci
->ec_idi_options
|= LEC_REQUIRE_2100HZ_REVERSALS
;
12857 if (ec_parms
[1].length
>= 4)
12859 plci
->ec_tail_length
= GET_WORD(&ec_parms
[1].info
[3]);
12862 switch (plci
->ec_cmd
)
12864 case EC_ENABLE_OPERATION
:
12865 plci
->ec_idi_options
&= ~LEC_FREEZE_COEFFICIENTS
;
12866 start_internal_command(Id
, plci
, ec_command
);
12869 case EC_DISABLE_OPERATION
:
12870 plci
->ec_idi_options
= LEC_ENABLE_ECHO_CANCELLER
|
12871 LEC_MANUAL_DISABLE
| LEC_ENABLE_NONLINEAR_PROCESSING
|
12872 LEC_RESET_COEFFICIENTS
;
12873 start_internal_command(Id
, plci
, ec_command
);
12877 dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x",
12878 UnMapId(Id
), (char *)(FILE_
), __LINE__
, plci
->ec_cmd
));
12879 PUT_WORD(&result
[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP
);
12885 sendf(appl
, _FACILITY_R
| CONFIRM
, Id
& 0xffffL
, Number
,
12886 "wws", Info
, (appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
) ?
12887 PRIV_SELECTOR_ECHO_CANCELLER
: SELECTOR_ECHO_CANCELLER
, result
);
12892 static void ec_indication(dword Id
, PLCI
*plci
, byte
*msg
, word length
)
12896 dbug(1, dprintf("[%06lx] %s,%d: ec_indication",
12897 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
12899 if (!(plci
->ec_idi_options
& LEC_MANUAL_DISABLE
))
12901 if (plci
->appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
)
12904 PUT_WORD(&result
[1], 0);
12907 case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ
:
12908 PUT_WORD(&result
[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ
);
12910 case LEC_DISABLE_TYPE_REVERSED_2100HZ
:
12911 PUT_WORD(&result
[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ
);
12913 case LEC_DISABLE_RELEASED
:
12914 PUT_WORD(&result
[1], EC_BYPASS_RELEASED
);
12921 PUT_WORD(&result
[1], EC_BYPASS_INDICATION
);
12923 PUT_WORD(&result
[4], 0);
12926 case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ
:
12927 PUT_WORD(&result
[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ
);
12929 case LEC_DISABLE_TYPE_REVERSED_2100HZ
:
12930 PUT_WORD(&result
[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ
);
12932 case LEC_DISABLE_RELEASED
:
12933 PUT_WORD(&result
[4], EC_BYPASS_RELEASED
);
12937 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "ws", (plci
->appl
->appl_flags
& APPL_FLAG_PRIV_EC_SPEC
) ?
12938 PRIV_SELECTOR_ECHO_CANCELLER
: SELECTOR_ECHO_CANCELLER
, result
);
12944 /*------------------------------------------------------------------*/
12945 /* Advanced voice */
12946 /*------------------------------------------------------------------*/
12948 static void adv_voice_write_coefs(PLCI
*plci
, word write_command
)
12950 DIVA_CAPI_ADAPTER
*a
;
12955 byte ch_map
[MIXER_CHANNELS_BRI
];
12957 byte coef_buffer
[ADV_VOICE_COEF_BUFFER_SIZE
+ 2];
12959 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_write_coefs %d",
12960 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
12961 (char *)(FILE_
), __LINE__
, write_command
));
12964 p
= coef_buffer
+ 1;
12965 *(p
++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS
;
12967 while (i
+ sizeof(word
) <= a
->adv_voice_coef_length
)
12969 PUT_WORD(p
, GET_WORD(a
->adv_voice_coef_buffer
+ i
));
12973 while (i
< ADV_VOICE_OLD_COEF_COUNT
* sizeof(word
))
12975 PUT_WORD(p
, 0x8000);
12980 if (!a
->li_pri
&& (plci
->li_bchannel_id
== 0))
12982 if ((li_config_table
[a
->li_base
].plci
== NULL
) && (li_config_table
[a
->li_base
+ 1].plci
!= NULL
))
12984 plci
->li_bchannel_id
= 1;
12985 li_config_table
[a
->li_base
].plci
= plci
;
12986 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
12987 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
12988 (char *)(FILE_
), __LINE__
, plci
->li_bchannel_id
));
12990 else if ((li_config_table
[a
->li_base
].plci
!= NULL
) && (li_config_table
[a
->li_base
+ 1].plci
== NULL
))
12992 plci
->li_bchannel_id
= 2;
12993 li_config_table
[a
->li_base
+ 1].plci
= plci
;
12994 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
12995 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
12996 (char *)(FILE_
), __LINE__
, plci
->li_bchannel_id
));
12999 if (!a
->li_pri
&& (plci
->li_bchannel_id
!= 0)
13000 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
13002 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
13003 switch (write_command
)
13005 case ADV_VOICE_WRITE_ACTIVATION
:
13006 j
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
13007 k
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
13008 if (!(plci
->B1_facilities
& B1_FACILITY_MIXER
))
13010 li_config_table
[j
].flag_table
[i
] |= LI_FLAG_CONFERENCE
| LI_FLAG_MIX
;
13011 li_config_table
[i
].flag_table
[j
] |= LI_FLAG_CONFERENCE
| LI_FLAG_MONITOR
;
13013 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
13015 li_config_table
[k
].flag_table
[i
] |= LI_FLAG_CONFERENCE
| LI_FLAG_MIX
;
13016 li_config_table
[i
].flag_table
[k
] |= LI_FLAG_CONFERENCE
| LI_FLAG_MONITOR
;
13017 li_config_table
[k
].flag_table
[j
] |= LI_FLAG_CONFERENCE
;
13018 li_config_table
[j
].flag_table
[k
] |= LI_FLAG_CONFERENCE
;
13020 mixer_calculate_coefs(a
);
13021 li_config_table
[i
].curchnl
= li_config_table
[i
].channel
;
13022 li_config_table
[j
].curchnl
= li_config_table
[j
].channel
;
13023 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
13024 li_config_table
[k
].curchnl
= li_config_table
[k
].channel
;
13027 case ADV_VOICE_WRITE_DEACTIVATION
:
13028 for (j
= 0; j
< li_total_channels
; j
++)
13030 li_config_table
[i
].flag_table
[j
] = 0;
13031 li_config_table
[j
].flag_table
[i
] = 0;
13033 k
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
13034 for (j
= 0; j
< li_total_channels
; j
++)
13036 li_config_table
[k
].flag_table
[j
] = 0;
13037 li_config_table
[j
].flag_table
[k
] = 0;
13039 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
13041 k
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
13042 for (j
= 0; j
< li_total_channels
; j
++)
13044 li_config_table
[k
].flag_table
[j
] = 0;
13045 li_config_table
[j
].flag_table
[k
] = 0;
13048 mixer_calculate_coefs(a
);
13051 if (plci
->B1_facilities
& B1_FACILITY_MIXER
)
13054 if (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) <= a
->adv_voice_coef_length
)
13055 w
= GET_WORD(a
->adv_voice_coef_buffer
+ ADV_VOICE_NEW_COEF_BASE
);
13056 if (li_config_table
[i
].channel
& LI_CHANNEL_TX_DATA
)
13057 w
|= MIXER_FEATURE_ENABLE_TX_DATA
;
13058 if (li_config_table
[i
].channel
& LI_CHANNEL_RX_DATA
)
13059 w
|= MIXER_FEATURE_ENABLE_RX_DATA
;
13061 *(p
++) = (byte
)(w
>> 8);
13062 for (j
= 0; j
< sizeof(ch_map
); j
+= 2)
13064 ch_map
[j
] = (byte
)(j
+ (plci
->li_bchannel_id
- 1));
13065 ch_map
[j
+ 1] = (byte
)(j
+ (2 - plci
->li_bchannel_id
));
13067 for (n
= 0; n
< ARRAY_SIZE(mixer_write_prog_bri
); n
++)
13069 i
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].to_ch
];
13070 j
= a
->li_base
+ ch_map
[mixer_write_prog_bri
[n
].from_ch
];
13071 if (li_config_table
[i
].channel
& li_config_table
[j
].channel
& LI_CHANNEL_INVOLVED
)
13073 *(p
++) = ((li_config_table
[i
].coef_table
[j
] & mixer_write_prog_bri
[n
].mask
) ? 0x80 : 0x01);
13074 w
= ((li_config_table
[i
].coef_table
[j
] & 0xf) ^ (li_config_table
[i
].coef_table
[j
] >> 4));
13075 li_config_table
[i
].coef_table
[j
] ^= (w
& mixer_write_prog_bri
[n
].mask
) << 4;
13079 *(p
++) = (ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + n
< a
->adv_voice_coef_length
) ?
13080 a
->adv_voice_coef_buffer
[ADV_VOICE_NEW_COEF_BASE
+ sizeof(word
) + n
] : 0x00;
13086 for (i
= ADV_VOICE_NEW_COEF_BASE
; i
< a
->adv_voice_coef_length
; i
++)
13087 *(p
++) = a
->adv_voice_coef_buffer
[i
];
13093 for (i
= ADV_VOICE_NEW_COEF_BASE
; i
< a
->adv_voice_coef_length
; i
++)
13094 *(p
++) = a
->adv_voice_coef_buffer
[i
];
13096 coef_buffer
[0] = (p
- coef_buffer
) - 1;
13097 add_p(plci
, FTY
, coef_buffer
);
13098 sig_req(plci
, TEL_CTRL
, 0);
13103 static void adv_voice_clear_config(PLCI
*plci
)
13105 DIVA_CAPI_ADAPTER
*a
;
13110 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_clear_config",
13111 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
13112 (char *)(FILE_
), __LINE__
));
13115 if ((plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
))
13117 a
->adv_voice_coef_length
= 0;
13119 if (!a
->li_pri
&& (plci
->li_bchannel_id
!= 0)
13120 && (li_config_table
[a
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
13122 i
= a
->li_base
+ (plci
->li_bchannel_id
- 1);
13123 li_config_table
[i
].curchnl
= 0;
13124 li_config_table
[i
].channel
= 0;
13125 li_config_table
[i
].chflags
= 0;
13126 for (j
= 0; j
< li_total_channels
; j
++)
13128 li_config_table
[i
].flag_table
[j
] = 0;
13129 li_config_table
[j
].flag_table
[i
] = 0;
13130 li_config_table
[i
].coef_table
[j
] = 0;
13131 li_config_table
[j
].coef_table
[i
] = 0;
13133 li_config_table
[i
].coef_table
[i
] |= LI_COEF_CH_PC_SET
| LI_COEF_PC_CH_SET
;
13134 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (plci
->li_bchannel_id
- 1);
13135 li_config_table
[i
].curchnl
= 0;
13136 li_config_table
[i
].channel
= 0;
13137 li_config_table
[i
].chflags
= 0;
13138 for (j
= 0; j
< li_total_channels
; j
++)
13140 li_config_table
[i
].flag_table
[j
] = 0;
13141 li_config_table
[j
].flag_table
[i
] = 0;
13142 li_config_table
[i
].coef_table
[j
] = 0;
13143 li_config_table
[j
].coef_table
[i
] = 0;
13145 if (a
->manufacturer_features
& MANUFACTURER_FEATURE_SLAVE_CODEC
)
13147 i
= a
->li_base
+ MIXER_IC_CHANNEL_BASE
+ (2 - plci
->li_bchannel_id
);
13148 li_config_table
[i
].curchnl
= 0;
13149 li_config_table
[i
].channel
= 0;
13150 li_config_table
[i
].chflags
= 0;
13151 for (j
= 0; j
< li_total_channels
; j
++)
13153 li_config_table
[i
].flag_table
[j
] = 0;
13154 li_config_table
[j
].flag_table
[i
] = 0;
13155 li_config_table
[i
].coef_table
[j
] = 0;
13156 li_config_table
[j
].coef_table
[i
] = 0;
13165 static void adv_voice_prepare_switch(dword Id
, PLCI
*plci
)
13168 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_prepare_switch",
13169 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
13174 static word
adv_voice_save_config(dword Id
, PLCI
*plci
, byte Rc
)
13177 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_save_config %02x %d",
13178 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
13184 static word
adv_voice_restore_config(dword Id
, PLCI
*plci
, byte Rc
)
13186 DIVA_CAPI_ADAPTER
*a
;
13189 dbug(1, dprintf("[%06lx] %s,%d: adv_voice_restore_config %02x %d",
13190 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
13194 if ((plci
->B1_facilities
& B1_FACILITY_VOICE
)
13195 && (plci
->tel
== ADV_VOICE
) && (plci
== a
->AdvSignalPLCI
))
13197 switch (plci
->adjust_b_state
)
13199 case ADJUST_B_RESTORE_VOICE_1
:
13200 plci
->internal_command
= plci
->adjust_b_command
;
13203 plci
->adjust_b_state
= ADJUST_B_RESTORE_VOICE_1
;
13206 adv_voice_write_coefs(plci
, ADV_VOICE_WRITE_UPDATE
);
13207 plci
->adjust_b_state
= ADJUST_B_RESTORE_VOICE_2
;
13209 case ADJUST_B_RESTORE_VOICE_2
:
13210 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
13212 dbug(1, dprintf("[%06lx] %s,%d: Restore voice config failed %02x",
13213 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
13214 Info
= _WRONG_STATE
;
13226 /*------------------------------------------------------------------*/
13227 /* B1 resource switching */
13228 /*------------------------------------------------------------------*/
13230 static byte b1_facilities_table
[] =
13232 0x00, /* 0 No bchannel resources */
13233 0x00, /* 1 Codec (automatic law) */
13234 0x00, /* 2 Codec (A-law) */
13235 0x00, /* 3 Codec (y-law) */
13236 0x00, /* 4 HDLC for X.21 */
13238 0x00, /* 6 External Device 0 */
13239 0x00, /* 7 External Device 1 */
13240 0x00, /* 8 HDLC 56k */
13241 0x00, /* 9 Transparent */
13242 0x00, /* 10 Loopback to network */
13243 0x00, /* 11 Test pattern to net */
13244 0x00, /* 12 Rate adaptation sync */
13245 0x00, /* 13 Rate adaptation async */
13246 0x00, /* 14 R-Interface */
13247 0x00, /* 15 HDLC 128k leased line */
13249 0x00, /* 17 Modem async */
13250 0x00, /* 18 Modem sync HDLC */
13251 0x00, /* 19 V.110 async HDLC */
13252 0x12, /* 20 Adv voice (Trans,mixer) */
13253 0x00, /* 21 Codec connected to IC */
13254 0x0c, /* 22 Trans,DTMF */
13255 0x1e, /* 23 Trans,DTMF+mixer */
13256 0x1f, /* 24 Trans,DTMF+mixer+local */
13257 0x13, /* 25 Trans,mixer+local */
13258 0x12, /* 26 HDLC,mixer */
13259 0x12, /* 27 HDLC 56k,mixer */
13260 0x2c, /* 28 Trans,LEC+DTMF */
13261 0x3e, /* 29 Trans,LEC+DTMF+mixer */
13262 0x3f, /* 30 Trans,LEC+DTMF+mixer+local */
13263 0x2c, /* 31 RTP,LEC+DTMF */
13264 0x3e, /* 32 RTP,LEC+DTMF+mixer */
13265 0x3f, /* 33 RTP,LEC+DTMF+mixer+local */
13266 0x00, /* 34 Signaling task */
13267 0x00, /* 35 PIAFS */
13268 0x0c, /* 36 Trans,DTMF+TONE */
13269 0x1e, /* 37 Trans,DTMF+TONE+mixer */
13270 0x1f /* 38 Trans,DTMF+TONE+mixer+local*/
13274 static word
get_b1_facilities(PLCI
*plci
, byte b1_resource
)
13276 word b1_facilities
;
13278 b1_facilities
= b1_facilities_table
[b1_resource
];
13279 if ((b1_resource
== 9) || (b1_resource
== 20) || (b1_resource
== 25))
13282 if (!(((plci
->requested_options_conn
| plci
->requested_options
) & (1L << PRIVATE_DTMF_TONE
))
13283 || (plci
->appl
&& (plci
->adapter
->requested_options_table
[plci
->appl
->Id
- 1] & (1L << PRIVATE_DTMF_TONE
)))))
13286 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_SEND
)
13287 b1_facilities
|= B1_FACILITY_DTMFX
;
13288 if (plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
)
13289 b1_facilities
|= B1_FACILITY_DTMFR
;
13292 if ((b1_resource
== 17) || (b1_resource
== 18))
13294 if (plci
->adapter
->manufacturer_features
& (MANUFACTURER_FEATURE_V18
| MANUFACTURER_FEATURE_VOWN
))
13295 b1_facilities
|= B1_FACILITY_DTMFX
| B1_FACILITY_DTMFR
;
13298 dbug (1, dprintf("[%06lx] %s,%d: get_b1_facilities %d %04x",
13299 (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
13300 (char far *)(FILE_), __LINE__, b1_resource, b1_facilites));
13302 return (b1_facilities
);
13306 static byte
add_b1_facilities(PLCI
*plci
, byte b1_resource
, word b1_facilities
)
13310 switch (b1_resource
)
13314 if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13322 if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13340 if (b1_facilities
& B1_FACILITY_EC
)
13342 if (b1_facilities
& B1_FACILITY_LOCAL
)
13344 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13350 else if ((b1_facilities
& (B1_FACILITY_DTMFX
| B1_FACILITY_DTMFR
| B1_FACILITY_MIXER
))
13351 && (((plci
->requested_options_conn
| plci
->requested_options
) & (1L << PRIVATE_DTMF_TONE
))
13352 || (plci
->appl
&& (plci
->adapter
->requested_options_table
[plci
->appl
->Id
- 1] & (1L << PRIVATE_DTMF_TONE
)))))
13354 if (b1_facilities
& B1_FACILITY_LOCAL
)
13356 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13362 else if (((plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_HARDDTMF
)
13363 && !(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
))
13364 || ((b1_facilities
& B1_FACILITY_DTMFR
)
13365 && ((b1_facilities
& B1_FACILITY_MIXER
)
13366 || !(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE
)))
13367 || ((b1_facilities
& B1_FACILITY_DTMFX
)
13368 && ((b1_facilities
& B1_FACILITY_MIXER
)
13369 || !(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_SOFTDTMF_SEND
))))
13371 if (b1_facilities
& B1_FACILITY_LOCAL
)
13373 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13380 if (b1_facilities
& B1_FACILITY_LOCAL
)
13382 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13392 if (b1_facilities
& B1_FACILITY_LOCAL
)
13394 else if (b1_facilities
& (B1_FACILITY_MIXER
| B1_FACILITY_VOICE
))
13403 dbug(1, dprintf("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x",
13404 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
13405 (char *)(FILE_
), __LINE__
,
13406 b1_resource
, b1_facilities
, b
, get_b1_facilities(plci
, b
)));
13411 static void adjust_b1_facilities(PLCI
*plci
, byte new_b1_resource
, word new_b1_facilities
)
13413 word removed_facilities
;
13415 dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x",
13416 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
13417 (char *)(FILE_
), __LINE__
, new_b1_resource
, new_b1_facilities
,
13418 new_b1_facilities
& get_b1_facilities(plci
, new_b1_resource
)));
13420 new_b1_facilities
&= get_b1_facilities(plci
, new_b1_resource
);
13421 removed_facilities
= plci
->B1_facilities
& ~new_b1_facilities
;
13423 if (removed_facilities
& B1_FACILITY_EC
)
13424 ec_clear_config(plci
);
13427 if (removed_facilities
& B1_FACILITY_DTMFR
)
13429 dtmf_rec_clear_config(plci
);
13430 dtmf_parameter_clear_config(plci
);
13432 if (removed_facilities
& B1_FACILITY_DTMFX
)
13433 dtmf_send_clear_config(plci
);
13436 if (removed_facilities
& B1_FACILITY_MIXER
)
13437 mixer_clear_config(plci
);
13439 if (removed_facilities
& B1_FACILITY_VOICE
)
13440 adv_voice_clear_config(plci
);
13441 plci
->B1_facilities
= new_b1_facilities
;
13445 static void adjust_b_clear(PLCI
*plci
)
13448 dbug(1, dprintf("[%06lx] %s,%d: adjust_b_clear",
13449 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
13450 (char *)(FILE_
), __LINE__
));
13452 plci
->adjust_b_restore
= false;
13456 static word
adjust_b_process(dword Id
, PLCI
*plci
, byte Rc
)
13463 dbug(1, dprintf("[%06lx] %s,%d: adjust_b_process %02x %d",
13464 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->adjust_b_state
));
13467 switch (plci
->adjust_b_state
)
13469 case ADJUST_B_START
:
13470 if ((plci
->adjust_b_parms_msg
== NULL
)
13471 && (plci
->adjust_b_mode
& ADJUST_B_MODE_SWITCH_L1
)
13472 && ((plci
->adjust_b_mode
& ~(ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_SWITCH_L1
|
13473 ADJUST_B_MODE_NO_RESOURCE
| ADJUST_B_MODE_RESTORE
)) == 0))
13475 b1_resource
= (plci
->adjust_b_mode
== ADJUST_B_MODE_NO_RESOURCE
) ?
13476 0 : add_b1_facilities(plci
, plci
->B1_resource
, plci
->adjust_b_facilities
);
13477 if (b1_resource
== plci
->B1_resource
)
13479 adjust_b1_facilities(plci
, b1_resource
, plci
->adjust_b_facilities
);
13482 if (plci
->adjust_b_facilities
& ~get_b1_facilities(plci
, b1_resource
))
13484 dbug(1, dprintf("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x",
13485 UnMapId(Id
), (char *)(FILE_
), __LINE__
,
13486 plci
->B1_resource
, b1_resource
, plci
->adjust_b_facilities
));
13487 Info
= _WRONG_STATE
;
13491 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13494 mixer_prepare_switch(Id
, plci
);
13497 dtmf_prepare_switch(Id
, plci
);
13498 dtmf_parameter_prepare_switch(Id
, plci
);
13501 ec_prepare_switch(Id
, plci
);
13503 adv_voice_prepare_switch(Id
, plci
);
13505 plci
->adjust_b_state
= ADJUST_B_SAVE_MIXER_1
;
13508 case ADJUST_B_SAVE_MIXER_1
:
13509 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13512 Info
= mixer_save_config(Id
, plci
, Rc
);
13513 if ((Info
!= GOOD
) || plci
->internal_command
)
13517 plci
->adjust_b_state
= ADJUST_B_SAVE_DTMF_1
;
13520 case ADJUST_B_SAVE_DTMF_1
:
13521 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13524 Info
= dtmf_save_config(Id
, plci
, Rc
);
13525 if ((Info
!= GOOD
) || plci
->internal_command
)
13529 plci
->adjust_b_state
= ADJUST_B_REMOVE_L23_1
;
13531 case ADJUST_B_REMOVE_L23_1
:
13532 if ((plci
->adjust_b_mode
& ADJUST_B_MODE_REMOVE_L23
)
13533 && plci
->NL
.Id
&& !plci
->nl_remove_id
)
13535 plci
->internal_command
= plci
->adjust_b_command
;
13536 if (plci
->adjust_b_ncci
!= 0)
13538 ncci_ptr
= &(plci
->adapter
->ncci
[plci
->adjust_b_ncci
]);
13539 while (ncci_ptr
->data_pending
)
13541 plci
->data_sent_ptr
= ncci_ptr
->DBuffer
[ncci_ptr
->data_out
].P
;
13542 data_rc(plci
, plci
->adapter
->ncci_ch
[plci
->adjust_b_ncci
]);
13544 while (ncci_ptr
->data_ack_pending
)
13545 data_ack(plci
, plci
->adapter
->ncci_ch
[plci
->adjust_b_ncci
]);
13547 nl_req_ncci(plci
, REMOVE
,
13548 (byte
)((plci
->adjust_b_mode
& ADJUST_B_MODE_CONNECT
) ? plci
->adjust_b_ncci
: 0));
13550 plci
->adjust_b_state
= ADJUST_B_REMOVE_L23_2
;
13553 plci
->adjust_b_state
= ADJUST_B_REMOVE_L23_2
;
13556 case ADJUST_B_REMOVE_L23_2
:
13557 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
13559 dbug(1, dprintf("[%06lx] %s,%d: Adjust B remove failed %02x",
13560 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
13561 Info
= _WRONG_STATE
;
13564 if (plci
->adjust_b_mode
& ADJUST_B_MODE_REMOVE_L23
)
13566 if (plci_nl_busy(plci
))
13568 plci
->internal_command
= plci
->adjust_b_command
;
13572 plci
->adjust_b_state
= ADJUST_B_SAVE_EC_1
;
13575 case ADJUST_B_SAVE_EC_1
:
13576 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13579 Info
= ec_save_config(Id
, plci
, Rc
);
13580 if ((Info
!= GOOD
) || plci
->internal_command
)
13584 plci
->adjust_b_state
= ADJUST_B_SAVE_DTMF_PARAMETER_1
;
13587 case ADJUST_B_SAVE_DTMF_PARAMETER_1
:
13588 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13591 Info
= dtmf_parameter_save_config(Id
, plci
, Rc
);
13592 if ((Info
!= GOOD
) || plci
->internal_command
)
13596 plci
->adjust_b_state
= ADJUST_B_SAVE_VOICE_1
;
13599 case ADJUST_B_SAVE_VOICE_1
:
13600 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SAVE
)
13602 Info
= adv_voice_save_config(Id
, plci
, Rc
);
13603 if ((Info
!= GOOD
) || plci
->internal_command
)
13606 plci
->adjust_b_state
= ADJUST_B_SWITCH_L1_1
;
13608 case ADJUST_B_SWITCH_L1_1
:
13609 if (plci
->adjust_b_mode
& ADJUST_B_MODE_SWITCH_L1
)
13613 plci
->internal_command
= plci
->adjust_b_command
;
13616 if (plci
->adjust_b_parms_msg
!= NULL
)
13617 api_load_msg(plci
->adjust_b_parms_msg
, bp
);
13619 api_load_msg(&plci
->B_protocol
, bp
);
13620 Info
= add_b1(plci
, bp
,
13621 (word
)((plci
->adjust_b_mode
& ADJUST_B_MODE_NO_RESOURCE
) ? 2 : 0),
13622 plci
->adjust_b_facilities
);
13625 dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x",
13626 UnMapId(Id
), (char *)(FILE_
), __LINE__
,
13627 plci
->B1_resource
, plci
->adjust_b_facilities
));
13630 plci
->internal_command
= plci
->adjust_b_command
;
13631 sig_req(plci
, RESOURCES
, 0);
13633 plci
->adjust_b_state
= ADJUST_B_SWITCH_L1_2
;
13636 plci
->adjust_b_state
= ADJUST_B_SWITCH_L1_2
;
13639 case ADJUST_B_SWITCH_L1_2
:
13640 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
13642 dbug(1, dprintf("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x",
13643 UnMapId(Id
), (char *)(FILE_
), __LINE__
,
13644 Rc
, plci
->B1_resource
, plci
->adjust_b_facilities
));
13645 Info
= _WRONG_STATE
;
13648 plci
->adjust_b_state
= ADJUST_B_RESTORE_VOICE_1
;
13651 case ADJUST_B_RESTORE_VOICE_1
:
13652 case ADJUST_B_RESTORE_VOICE_2
:
13653 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13655 Info
= adv_voice_restore_config(Id
, plci
, Rc
);
13656 if ((Info
!= GOOD
) || plci
->internal_command
)
13659 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_PARAMETER_1
;
13662 case ADJUST_B_RESTORE_DTMF_PARAMETER_1
:
13663 case ADJUST_B_RESTORE_DTMF_PARAMETER_2
:
13664 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13667 Info
= dtmf_parameter_restore_config(Id
, plci
, Rc
);
13668 if ((Info
!= GOOD
) || plci
->internal_command
)
13672 plci
->adjust_b_state
= ADJUST_B_RESTORE_EC_1
;
13675 case ADJUST_B_RESTORE_EC_1
:
13676 case ADJUST_B_RESTORE_EC_2
:
13677 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13680 Info
= ec_restore_config(Id
, plci
, Rc
);
13681 if ((Info
!= GOOD
) || plci
->internal_command
)
13685 plci
->adjust_b_state
= ADJUST_B_ASSIGN_L23_1
;
13687 case ADJUST_B_ASSIGN_L23_1
:
13688 if (plci
->adjust_b_mode
& ADJUST_B_MODE_ASSIGN_L23
)
13690 if (plci_nl_busy(plci
))
13692 plci
->internal_command
= plci
->adjust_b_command
;
13695 if (plci
->adjust_b_mode
& ADJUST_B_MODE_CONNECT
)
13696 plci
->call_dir
|= CALL_DIR_FORCE_OUTG_NL
;
13697 if (plci
->adjust_b_parms_msg
!= NULL
)
13698 api_load_msg(plci
->adjust_b_parms_msg
, bp
);
13700 api_load_msg(&plci
->B_protocol
, bp
);
13701 Info
= add_b23(plci
, bp
);
13704 dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x",
13705 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Info
));
13708 plci
->internal_command
= plci
->adjust_b_command
;
13709 nl_req_ncci(plci
, ASSIGN
, 0);
13711 plci
->adjust_b_state
= ADJUST_B_ASSIGN_L23_2
;
13714 plci
->adjust_b_state
= ADJUST_B_ASSIGN_L23_2
;
13717 case ADJUST_B_ASSIGN_L23_2
:
13718 if ((Rc
!= OK
) && (Rc
!= OK_FC
) && (Rc
!= ASSIGN_OK
))
13720 dbug(1, dprintf("[%06lx] %s,%d: Adjust B assign failed %02x",
13721 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
13722 Info
= _WRONG_STATE
;
13725 if (plci
->adjust_b_mode
& ADJUST_B_MODE_ASSIGN_L23
)
13727 if (Rc
!= ASSIGN_OK
)
13729 plci
->internal_command
= plci
->adjust_b_command
;
13733 if (plci
->adjust_b_mode
& ADJUST_B_MODE_USER_CONNECT
)
13735 plci
->adjust_b_restore
= true;
13738 plci
->adjust_b_state
= ADJUST_B_CONNECT_1
;
13740 case ADJUST_B_CONNECT_1
:
13741 if (plci
->adjust_b_mode
& ADJUST_B_MODE_CONNECT
)
13743 plci
->internal_command
= plci
->adjust_b_command
;
13744 if (plci_nl_busy(plci
))
13746 nl_req_ncci(plci
, N_CONNECT
, 0);
13748 plci
->adjust_b_state
= ADJUST_B_CONNECT_2
;
13751 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_1
;
13754 case ADJUST_B_CONNECT_2
:
13755 case ADJUST_B_CONNECT_3
:
13756 case ADJUST_B_CONNECT_4
:
13757 if ((Rc
!= OK
) && (Rc
!= OK_FC
) && (Rc
!= 0))
13759 dbug(1, dprintf("[%06lx] %s,%d: Adjust B connect failed %02x",
13760 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
13761 Info
= _WRONG_STATE
;
13766 if (plci
->adjust_b_mode
& ADJUST_B_MODE_CONNECT
)
13768 get_ncci(plci
, (byte
)(Id
>> 16), plci
->adjust_b_ncci
);
13769 Id
= (Id
& 0xffff) | (((dword
)(plci
->adjust_b_ncci
)) << 16);
13771 if (plci
->adjust_b_state
== ADJUST_B_CONNECT_2
)
13772 plci
->adjust_b_state
= ADJUST_B_CONNECT_3
;
13773 else if (plci
->adjust_b_state
== ADJUST_B_CONNECT_4
)
13774 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_1
;
13778 if (plci
->adjust_b_state
== ADJUST_B_CONNECT_2
)
13779 plci
->adjust_b_state
= ADJUST_B_CONNECT_4
;
13780 else if (plci
->adjust_b_state
== ADJUST_B_CONNECT_3
)
13781 plci
->adjust_b_state
= ADJUST_B_RESTORE_DTMF_1
;
13783 if (plci
->adjust_b_state
!= ADJUST_B_RESTORE_DTMF_1
)
13785 plci
->internal_command
= plci
->adjust_b_command
;
13790 case ADJUST_B_RESTORE_DTMF_1
:
13791 case ADJUST_B_RESTORE_DTMF_2
:
13792 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13795 Info
= dtmf_restore_config(Id
, plci
, Rc
);
13796 if ((Info
!= GOOD
) || plci
->internal_command
)
13800 plci
->adjust_b_state
= ADJUST_B_RESTORE_MIXER_1
;
13803 case ADJUST_B_RESTORE_MIXER_1
:
13804 case ADJUST_B_RESTORE_MIXER_2
:
13805 case ADJUST_B_RESTORE_MIXER_3
:
13806 case ADJUST_B_RESTORE_MIXER_4
:
13807 case ADJUST_B_RESTORE_MIXER_5
:
13808 case ADJUST_B_RESTORE_MIXER_6
:
13809 case ADJUST_B_RESTORE_MIXER_7
:
13810 if (plci
->adjust_b_mode
& ADJUST_B_MODE_RESTORE
)
13813 Info
= mixer_restore_config(Id
, plci
, Rc
);
13814 if ((Info
!= GOOD
) || plci
->internal_command
)
13818 plci
->adjust_b_state
= ADJUST_B_END
;
13826 static void adjust_b1_resource(dword Id
, PLCI
*plci
, API_SAVE
*bp_msg
, word b1_facilities
, word internal_command
)
13829 dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_resource %d %04x",
13830 UnMapId(Id
), (char *)(FILE_
), __LINE__
,
13831 plci
->B1_resource
, b1_facilities
));
13833 plci
->adjust_b_parms_msg
= bp_msg
;
13834 plci
->adjust_b_facilities
= b1_facilities
;
13835 plci
->adjust_b_command
= internal_command
;
13836 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
13837 if ((bp_msg
== NULL
) && (plci
->B1_resource
== 0))
13838 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_NO_RESOURCE
| ADJUST_B_MODE_SWITCH_L1
;
13840 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_SWITCH_L1
| ADJUST_B_MODE_RESTORE
;
13841 plci
->adjust_b_state
= ADJUST_B_START
;
13842 dbug(1, dprintf("[%06lx] %s,%d: Adjust B1 resource %d %04x...",
13843 UnMapId(Id
), (char *)(FILE_
), __LINE__
,
13844 plci
->B1_resource
, b1_facilities
));
13848 static void adjust_b_restore(dword Id
, PLCI
*plci
, byte Rc
)
13850 word internal_command
;
13852 dbug(1, dprintf("[%06lx] %s,%d: adjust_b_restore %02x %04x",
13853 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
13855 internal_command
= plci
->internal_command
;
13856 plci
->internal_command
= 0;
13857 switch (internal_command
)
13861 if (plci
->req_in
!= 0)
13863 plci
->internal_command
= ADJUST_B_RESTORE_1
;
13868 case ADJUST_B_RESTORE_1
:
13869 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
13871 dbug(1, dprintf("[%06lx] %s,%d: Adjust B enqueued failed %02x",
13872 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
13874 plci
->adjust_b_parms_msg
= NULL
;
13875 plci
->adjust_b_facilities
= plci
->B1_facilities
;
13876 plci
->adjust_b_command
= ADJUST_B_RESTORE_2
;
13877 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
13878 plci
->adjust_b_mode
= ADJUST_B_MODE_RESTORE
;
13879 plci
->adjust_b_state
= ADJUST_B_START
;
13880 dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore...",
13881 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
13883 case ADJUST_B_RESTORE_2
:
13884 if (adjust_b_process(Id
, plci
, Rc
) != GOOD
)
13886 dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore failed",
13887 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
13889 if (plci
->internal_command
)
13896 static void reset_b3_command(dword Id
, PLCI
*plci
, byte Rc
)
13899 word internal_command
;
13901 dbug(1, dprintf("[%06lx] %s,%d: reset_b3_command %02x %04x",
13902 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
13905 internal_command
= plci
->internal_command
;
13906 plci
->internal_command
= 0;
13907 switch (internal_command
)
13911 plci
->adjust_b_parms_msg
= NULL
;
13912 plci
->adjust_b_facilities
= plci
->B1_facilities
;
13913 plci
->adjust_b_command
= RESET_B3_COMMAND_1
;
13914 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
13915 plci
->adjust_b_mode
= ADJUST_B_MODE_REMOVE_L23
| ADJUST_B_MODE_ASSIGN_L23
| ADJUST_B_MODE_CONNECT
;
13916 plci
->adjust_b_state
= ADJUST_B_START
;
13917 dbug(1, dprintf("[%06lx] %s,%d: Reset B3...",
13918 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
13920 case RESET_B3_COMMAND_1
:
13921 Info
= adjust_b_process(Id
, plci
, Rc
);
13924 dbug(1, dprintf("[%06lx] %s,%d: Reset failed",
13925 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
13928 if (plci
->internal_command
)
13932 /* sendf (plci->appl, _RESET_B3_R | CONFIRM, Id, plci->number, "w", Info);*/
13933 sendf(plci
->appl
, _RESET_B3_I
, Id
, 0, "s", "");
13937 static void select_b_command(dword Id
, PLCI
*plci
, byte Rc
)
13940 word internal_command
;
13943 dbug(1, dprintf("[%06lx] %s,%d: select_b_command %02x %04x",
13944 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
13947 internal_command
= plci
->internal_command
;
13948 plci
->internal_command
= 0;
13949 switch (internal_command
)
13953 plci
->adjust_b_parms_msg
= &plci
->saved_msg
;
13954 if ((plci
->tel
== ADV_VOICE
) && (plci
== plci
->adapter
->AdvSignalPLCI
))
13955 plci
->adjust_b_facilities
= plci
->B1_facilities
| B1_FACILITY_VOICE
;
13957 plci
->adjust_b_facilities
= plci
->B1_facilities
& ~B1_FACILITY_VOICE
;
13958 plci
->adjust_b_command
= SELECT_B_COMMAND_1
;
13959 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
13960 if (plci
->saved_msg
.parms
[0].length
== 0)
13962 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_REMOVE_L23
| ADJUST_B_MODE_SWITCH_L1
|
13963 ADJUST_B_MODE_NO_RESOURCE
;
13967 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_REMOVE_L23
| ADJUST_B_MODE_SWITCH_L1
|
13968 ADJUST_B_MODE_ASSIGN_L23
| ADJUST_B_MODE_USER_CONNECT
| ADJUST_B_MODE_RESTORE
;
13970 plci
->adjust_b_state
= ADJUST_B_START
;
13971 dbug(1, dprintf("[%06lx] %s,%d: Select B protocol...",
13972 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
13974 case SELECT_B_COMMAND_1
:
13975 Info
= adjust_b_process(Id
, plci
, Rc
);
13978 dbug(1, dprintf("[%06lx] %s,%d: Select B protocol failed",
13979 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
13982 if (plci
->internal_command
)
13984 if (plci
->tel
== ADV_VOICE
)
13988 esc_chi
[2] = plci
->b_channel
;
13989 SetVoiceChannel(plci
->adapter
->AdvCodecPLCI
, esc_chi
, plci
->adapter
);
13993 sendf(plci
->appl
, _SELECT_B_REQ
| CONFIRM
, Id
, plci
->number
, "w", Info
);
13997 static void fax_connect_ack_command(dword Id
, PLCI
*plci
, byte Rc
)
13999 word internal_command
;
14001 dbug(1, dprintf("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
14002 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14004 internal_command
= plci
->internal_command
;
14005 plci
->internal_command
= 0;
14006 switch (internal_command
)
14009 plci
->command
= 0; /* fall through */
14010 case FAX_CONNECT_ACK_COMMAND_1
:
14011 if (plci_nl_busy(plci
))
14013 plci
->internal_command
= FAX_CONNECT_ACK_COMMAND_1
;
14016 plci
->internal_command
= FAX_CONNECT_ACK_COMMAND_2
;
14017 plci
->NData
[0].P
= plci
->fax_connect_info_buffer
;
14018 plci
->NData
[0].PLength
= plci
->fax_connect_info_length
;
14019 plci
->NL
.X
= plci
->NData
;
14020 plci
->NL
.ReqCh
= 0;
14021 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_CONNECT_ACK
;
14022 plci
->adapter
->request(&plci
->NL
);
14024 case FAX_CONNECT_ACK_COMMAND_2
:
14025 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14027 dbug(1, dprintf("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x",
14028 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
14032 if ((plci
->ncpi_state
& NCPI_VALID_CONNECT_B3_ACT
)
14033 && !(plci
->ncpi_state
& NCPI_CONNECT_B3_ACT_SENT
))
14035 if (plci
->B3_prot
== 4)
14036 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
14038 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "S", plci
->ncpi_buffer
);
14039 plci
->ncpi_state
|= NCPI_CONNECT_B3_ACT_SENT
;
14044 static void fax_edata_ack_command(dword Id
, PLCI
*plci
, byte Rc
)
14046 word internal_command
;
14048 dbug(1, dprintf("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
14049 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14051 internal_command
= plci
->internal_command
;
14052 plci
->internal_command
= 0;
14053 switch (internal_command
)
14058 case FAX_EDATA_ACK_COMMAND_1
:
14059 if (plci_nl_busy(plci
))
14061 plci
->internal_command
= FAX_EDATA_ACK_COMMAND_1
;
14064 plci
->internal_command
= FAX_EDATA_ACK_COMMAND_2
;
14065 plci
->NData
[0].P
= plci
->fax_connect_info_buffer
;
14066 plci
->NData
[0].PLength
= plci
->fax_edata_ack_length
;
14067 plci
->NL
.X
= plci
->NData
;
14068 plci
->NL
.ReqCh
= 0;
14069 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_EDATA
;
14070 plci
->adapter
->request(&plci
->NL
);
14072 case FAX_EDATA_ACK_COMMAND_2
:
14073 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14075 dbug(1, dprintf("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x",
14076 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
14083 static void fax_connect_info_command(dword Id
, PLCI
*plci
, byte Rc
)
14086 word internal_command
;
14088 dbug(1, dprintf("[%06lx] %s,%d: fax_connect_info_command %02x %04x",
14089 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14092 internal_command
= plci
->internal_command
;
14093 plci
->internal_command
= 0;
14094 switch (internal_command
)
14097 plci
->command
= 0; /* fall through */
14098 case FAX_CONNECT_INFO_COMMAND_1
:
14099 if (plci_nl_busy(plci
))
14101 plci
->internal_command
= FAX_CONNECT_INFO_COMMAND_1
;
14104 plci
->internal_command
= FAX_CONNECT_INFO_COMMAND_2
;
14105 plci
->NData
[0].P
= plci
->fax_connect_info_buffer
;
14106 plci
->NData
[0].PLength
= plci
->fax_connect_info_length
;
14107 plci
->NL
.X
= plci
->NData
;
14108 plci
->NL
.ReqCh
= 0;
14109 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_EDATA
;
14110 plci
->adapter
->request(&plci
->NL
);
14112 case FAX_CONNECT_INFO_COMMAND_2
:
14113 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14115 dbug(1, dprintf("[%06lx] %s,%d: FAX setting connect info failed %02x",
14116 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
14117 Info
= _WRONG_STATE
;
14120 if (plci_nl_busy(plci
))
14122 plci
->internal_command
= FAX_CONNECT_INFO_COMMAND_2
;
14125 plci
->command
= _CONNECT_B3_R
;
14126 nl_req_ncci(plci
, N_CONNECT
, 0);
14130 sendf(plci
->appl
, _CONNECT_B3_R
| CONFIRM
, Id
, plci
->number
, "w", Info
);
14134 static void fax_adjust_b23_command(dword Id
, PLCI
*plci
, byte Rc
)
14137 word internal_command
;
14139 dbug(1, dprintf("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x",
14140 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14143 internal_command
= plci
->internal_command
;
14144 plci
->internal_command
= 0;
14145 switch (internal_command
)
14149 plci
->adjust_b_parms_msg
= NULL
;
14150 plci
->adjust_b_facilities
= plci
->B1_facilities
;
14151 plci
->adjust_b_command
= FAX_ADJUST_B23_COMMAND_1
;
14152 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
14153 plci
->adjust_b_mode
= ADJUST_B_MODE_REMOVE_L23
| ADJUST_B_MODE_ASSIGN_L23
;
14154 plci
->adjust_b_state
= ADJUST_B_START
;
14155 dbug(1, dprintf("[%06lx] %s,%d: FAX adjust B23...",
14156 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
14158 case FAX_ADJUST_B23_COMMAND_1
:
14159 Info
= adjust_b_process(Id
, plci
, Rc
);
14162 dbug(1, dprintf("[%06lx] %s,%d: FAX adjust failed",
14163 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
14166 if (plci
->internal_command
)
14169 case FAX_ADJUST_B23_COMMAND_2
:
14170 if (plci_nl_busy(plci
))
14172 plci
->internal_command
= FAX_ADJUST_B23_COMMAND_2
;
14175 plci
->command
= _CONNECT_B3_R
;
14176 nl_req_ncci(plci
, N_CONNECT
, 0);
14180 sendf(plci
->appl
, _CONNECT_B3_R
| CONFIRM
, Id
, plci
->number
, "w", Info
);
14184 static void fax_disconnect_command(dword Id
, PLCI
*plci
, byte Rc
)
14186 word internal_command
;
14188 dbug(1, dprintf("[%06lx] %s,%d: fax_disconnect_command %02x %04x",
14189 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14191 internal_command
= plci
->internal_command
;
14192 plci
->internal_command
= 0;
14193 switch (internal_command
)
14197 plci
->internal_command
= FAX_DISCONNECT_COMMAND_1
;
14199 case FAX_DISCONNECT_COMMAND_1
:
14200 case FAX_DISCONNECT_COMMAND_2
:
14201 case FAX_DISCONNECT_COMMAND_3
:
14202 if ((Rc
!= OK
) && (Rc
!= OK_FC
) && (Rc
!= 0))
14204 dbug(1, dprintf("[%06lx] %s,%d: FAX disconnect EDATA failed %02x",
14205 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
14210 if ((internal_command
== FAX_DISCONNECT_COMMAND_1
)
14211 || (internal_command
== FAX_DISCONNECT_COMMAND_2
))
14213 plci
->internal_command
= FAX_DISCONNECT_COMMAND_2
;
14218 if (internal_command
== FAX_DISCONNECT_COMMAND_1
)
14219 plci
->internal_command
= FAX_DISCONNECT_COMMAND_3
;
14227 static void rtp_connect_b3_req_command(dword Id
, PLCI
*plci
, byte Rc
)
14230 word internal_command
;
14232 dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x",
14233 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14236 internal_command
= plci
->internal_command
;
14237 plci
->internal_command
= 0;
14238 switch (internal_command
)
14241 plci
->command
= 0; /* fall through */
14242 case RTP_CONNECT_B3_REQ_COMMAND_1
:
14243 if (plci_nl_busy(plci
))
14245 plci
->internal_command
= RTP_CONNECT_B3_REQ_COMMAND_1
;
14248 plci
->internal_command
= RTP_CONNECT_B3_REQ_COMMAND_2
;
14249 nl_req_ncci(plci
, N_CONNECT
, 0);
14252 case RTP_CONNECT_B3_REQ_COMMAND_2
:
14253 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14255 dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect info failed %02x",
14256 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
14257 Info
= _WRONG_STATE
;
14260 if (plci_nl_busy(plci
))
14262 plci
->internal_command
= RTP_CONNECT_B3_REQ_COMMAND_2
;
14265 plci
->internal_command
= RTP_CONNECT_B3_REQ_COMMAND_3
;
14266 plci
->NData
[0].PLength
= plci
->internal_req_buffer
[0];
14267 plci
->NData
[0].P
= plci
->internal_req_buffer
+ 1;
14268 plci
->NL
.X
= plci
->NData
;
14269 plci
->NL
.ReqCh
= 0;
14270 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
14271 plci
->adapter
->request(&plci
->NL
);
14273 case RTP_CONNECT_B3_REQ_COMMAND_3
:
14276 sendf(plci
->appl
, _CONNECT_B3_R
| CONFIRM
, Id
, plci
->number
, "w", Info
);
14280 static void rtp_connect_b3_res_command(dword Id
, PLCI
*plci
, byte Rc
)
14282 word internal_command
;
14284 dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
14285 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14287 internal_command
= plci
->internal_command
;
14288 plci
->internal_command
= 0;
14289 switch (internal_command
)
14292 plci
->command
= 0; /* fall through */
14293 case RTP_CONNECT_B3_RES_COMMAND_1
:
14294 if (plci_nl_busy(plci
))
14296 plci
->internal_command
= RTP_CONNECT_B3_RES_COMMAND_1
;
14299 plci
->internal_command
= RTP_CONNECT_B3_RES_COMMAND_2
;
14300 nl_req_ncci(plci
, N_CONNECT_ACK
, (byte
)(Id
>> 16));
14303 case RTP_CONNECT_B3_RES_COMMAND_2
:
14304 if ((Rc
!= OK
) && (Rc
!= OK_FC
))
14306 dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
14307 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
));
14310 if (plci_nl_busy(plci
))
14312 plci
->internal_command
= RTP_CONNECT_B3_RES_COMMAND_2
;
14315 sendf(plci
->appl
, _CONNECT_B3_ACTIVE_I
, Id
, 0, "s", "");
14316 plci
->internal_command
= RTP_CONNECT_B3_RES_COMMAND_3
;
14317 plci
->NData
[0].PLength
= plci
->internal_req_buffer
[0];
14318 plci
->NData
[0].P
= plci
->internal_req_buffer
+ 1;
14319 plci
->NL
.X
= plci
->NData
;
14320 plci
->NL
.ReqCh
= 0;
14321 plci
->NL
.Req
= plci
->nl_req
= (byte
) N_UDATA
;
14322 plci
->adapter
->request(&plci
->NL
);
14324 case RTP_CONNECT_B3_RES_COMMAND_3
:
14331 static void hold_save_command(dword Id
, PLCI
*plci
, byte Rc
)
14333 byte SS_Ind
[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
14335 word internal_command
;
14337 dbug(1, dprintf("[%06lx] %s,%d: hold_save_command %02x %04x",
14338 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14341 internal_command
= plci
->internal_command
;
14342 plci
->internal_command
= 0;
14343 switch (internal_command
)
14349 plci
->adjust_b_parms_msg
= NULL
;
14350 plci
->adjust_b_facilities
= plci
->B1_facilities
;
14351 plci
->adjust_b_command
= HOLD_SAVE_COMMAND_1
;
14352 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
14353 plci
->adjust_b_mode
= ADJUST_B_MODE_SAVE
| ADJUST_B_MODE_REMOVE_L23
;
14354 plci
->adjust_b_state
= ADJUST_B_START
;
14355 dbug(1, dprintf("[%06lx] %s,%d: HOLD save...",
14356 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
14358 case HOLD_SAVE_COMMAND_1
:
14359 Info
= adjust_b_process(Id
, plci
, Rc
);
14362 dbug(1, dprintf("[%06lx] %s,%d: HOLD save failed",
14363 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
14366 if (plci
->internal_command
)
14369 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "ws", 3, SS_Ind
);
14373 static void retrieve_restore_command(dword Id
, PLCI
*plci
, byte Rc
)
14375 byte SS_Ind
[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/
14377 word internal_command
;
14379 dbug(1, dprintf("[%06lx] %s,%d: retrieve_restore_command %02x %04x",
14380 UnMapId(Id
), (char *)(FILE_
), __LINE__
, Rc
, plci
->internal_command
));
14383 internal_command
= plci
->internal_command
;
14384 plci
->internal_command
= 0;
14385 switch (internal_command
)
14389 plci
->adjust_b_parms_msg
= NULL
;
14390 plci
->adjust_b_facilities
= plci
->B1_facilities
;
14391 plci
->adjust_b_command
= RETRIEVE_RESTORE_COMMAND_1
;
14392 plci
->adjust_b_ncci
= (word
)(Id
>> 16);
14393 plci
->adjust_b_mode
= ADJUST_B_MODE_ASSIGN_L23
| ADJUST_B_MODE_USER_CONNECT
| ADJUST_B_MODE_RESTORE
;
14394 plci
->adjust_b_state
= ADJUST_B_START
;
14395 dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore...",
14396 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
14398 case RETRIEVE_RESTORE_COMMAND_1
:
14399 Info
= adjust_b_process(Id
, plci
, Rc
);
14402 dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore failed",
14403 UnMapId(Id
), (char *)(FILE_
), __LINE__
));
14406 if (plci
->internal_command
)
14409 sendf(plci
->appl
, _FACILITY_I
, Id
& 0xffffL
, 0, "ws", 3, SS_Ind
);
14413 static void init_b1_config(PLCI
*plci
)
14416 dbug(1, dprintf("[%06lx] %s,%d: init_b1_config",
14417 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
14418 (char *)(FILE_
), __LINE__
));
14420 plci
->B1_resource
= 0;
14421 plci
->B1_facilities
= 0;
14423 plci
->li_bchannel_id
= 0;
14424 mixer_clear_config(plci
);
14427 ec_clear_config(plci
);
14430 dtmf_rec_clear_config(plci
);
14431 dtmf_send_clear_config(plci
);
14432 dtmf_parameter_clear_config(plci
);
14434 adv_voice_clear_config(plci
);
14435 adjust_b_clear(plci
);
14439 static void clear_b1_config(PLCI
*plci
)
14442 dbug(1, dprintf("[%06lx] %s,%d: clear_b1_config",
14443 (dword
)((plci
->Id
<< 8) | UnMapController(plci
->adapter
->Id
)),
14444 (char *)(FILE_
), __LINE__
));
14446 adv_voice_clear_config(plci
);
14447 adjust_b_clear(plci
);
14449 ec_clear_config(plci
);
14452 dtmf_rec_clear_config(plci
);
14453 dtmf_send_clear_config(plci
);
14454 dtmf_parameter_clear_config(plci
);
14457 if ((plci
->li_bchannel_id
!= 0)
14458 && (li_config_table
[plci
->adapter
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
== plci
))
14460 mixer_clear_config(plci
);
14461 li_config_table
[plci
->adapter
->li_base
+ (plci
->li_bchannel_id
- 1)].plci
= NULL
;
14462 plci
->li_bchannel_id
= 0;
14465 plci
->B1_resource
= 0;
14466 plci
->B1_facilities
= 0;
14470 /* -----------------------------------------------------------------
14471 XON protocol local helpers
14472 ----------------------------------------------------------------- */
14473 static void channel_flow_control_remove(PLCI
*plci
) {
14474 DIVA_CAPI_ADAPTER
*a
= plci
->adapter
;
14476 for (i
= 1; i
< MAX_NL_CHANNEL
+ 1; i
++) {
14477 if (a
->ch_flow_plci
[i
] == plci
->Id
) {
14478 a
->ch_flow_plci
[i
] = 0;
14479 a
->ch_flow_control
[i
] = 0;
14484 static void channel_x_on(PLCI
*plci
, byte ch
) {
14485 DIVA_CAPI_ADAPTER
*a
= plci
->adapter
;
14486 if (a
->ch_flow_control
[ch
] & N_XON_SENT
) {
14487 a
->ch_flow_control
[ch
] &= ~N_XON_SENT
;
14491 static void channel_x_off(PLCI
*plci
, byte ch
, byte flag
) {
14492 DIVA_CAPI_ADAPTER
*a
= plci
->adapter
;
14493 if ((a
->ch_flow_control
[ch
] & N_RX_FLOW_CONTROL_MASK
) == 0) {
14494 a
->ch_flow_control
[ch
] |= (N_CH_XOFF
| flag
);
14495 a
->ch_flow_plci
[ch
] = plci
->Id
;
14496 a
->ch_flow_control_pending
++;
14500 static void channel_request_xon(PLCI
*plci
, byte ch
) {
14501 DIVA_CAPI_ADAPTER
*a
= plci
->adapter
;
14503 if (a
->ch_flow_control
[ch
] & N_CH_XOFF
) {
14504 a
->ch_flow_control
[ch
] |= N_XON_REQ
;
14505 a
->ch_flow_control
[ch
] &= ~N_CH_XOFF
;
14506 a
->ch_flow_control
[ch
] &= ~N_XON_CONNECT_IND
;
14510 static void channel_xmit_extended_xon(PLCI
*plci
) {
14511 DIVA_CAPI_ADAPTER
*a
;
14512 int max_ch
= ARRAY_SIZE(a
->ch_flow_control
);
14513 int i
, one_requested
= 0;
14515 if ((!plci
) || (!plci
->Id
) || ((a
= plci
->adapter
) == NULL
)) {
14519 for (i
= 0; i
< max_ch
; i
++) {
14520 if ((a
->ch_flow_control
[i
] & N_CH_XOFF
) &&
14521 (a
->ch_flow_control
[i
] & N_XON_CONNECT_IND
) &&
14522 (plci
->Id
== a
->ch_flow_plci
[i
])) {
14523 channel_request_xon(plci
, (byte
)i
);
14528 if (one_requested
) {
14529 channel_xmit_xon(plci
);
14534 Try to xmit next X_ON
14536 static int find_channel_with_pending_x_on(DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
) {
14537 int max_ch
= ARRAY_SIZE(a
->ch_flow_control
);
14540 if (!(plci
->adapter
->manufacturer_features
& MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL
)) {
14544 if (a
->last_flow_control_ch
>= max_ch
) {
14545 a
->last_flow_control_ch
= 1;
14547 for (i
= a
->last_flow_control_ch
; i
< max_ch
; i
++) {
14548 if ((a
->ch_flow_control
[i
] & N_XON_REQ
) &&
14549 (plci
->Id
== a
->ch_flow_plci
[i
])) {
14550 a
->last_flow_control_ch
= i
+ 1;
14555 for (i
= 1; i
< a
->last_flow_control_ch
; i
++) {
14556 if ((a
->ch_flow_control
[i
] & N_XON_REQ
) &&
14557 (plci
->Id
== a
->ch_flow_plci
[i
])) {
14558 a
->last_flow_control_ch
= i
+ 1;
14566 static void channel_xmit_xon(PLCI
*plci
) {
14567 DIVA_CAPI_ADAPTER
*a
= plci
->adapter
;
14570 if (plci
->nl_req
|| !plci
->NL
.Id
|| plci
->nl_remove_id
) {
14573 if ((ch
= (byte
)find_channel_with_pending_x_on(a
, plci
)) == 0) {
14576 a
->ch_flow_control
[ch
] &= ~N_XON_REQ
;
14577 a
->ch_flow_control
[ch
] |= N_XON_SENT
;
14579 plci
->NL
.Req
= plci
->nl_req
= (byte
)N_XON
;
14580 plci
->NL
.ReqCh
= ch
;
14581 plci
->NL
.X
= plci
->NData
;
14583 plci
->NData
[0].P
= &plci
->RBuffer
[0];
14584 plci
->NData
[0].PLength
= 0;
14586 plci
->adapter
->request(&plci
->NL
);
14589 static int channel_can_xon(PLCI
*plci
, byte ch
) {
14591 DIVA_CAPI_ADAPTER
*a
;
14597 APPLptr
= plci
->appl
;
14603 NCCIcode
= a
->ch_ncci
[ch
] | (((word
) a
->Id
) << 8);
14605 /* count all buffers within the Application pool */
14606 /* belonging to the same NCCI. XON if a first is */
14610 for (i
= 0; i
< APPLptr
->MaxBuffer
; i
++) {
14611 if (NCCIcode
== APPLptr
->DataNCCI
[i
]) count
++;
14612 if (!APPLptr
->DataNCCI
[i
] && Num
== 0xffff) Num
= i
;
14614 if ((count
> 2) || (Num
== 0xffff)) {
14621 /*------------------------------------------------------------------*/
14623 static word
CPN_filter_ok(byte
*cpn
, DIVA_CAPI_ADAPTER
*a
, word offset
)
14630 /**********************************************************************************/
14631 /* function groups the listening applications according to the CIP mask and the */
14632 /* Info_Mask. Each group gets just one Connect_Ind. Some application manufacturer */
14633 /* are not multi-instance capable, so they start e.g. 30 applications what causes */
14634 /* big problems on application level (one call, 30 Connect_Ind, ect). The */
14635 /* function must be enabled by setting "a->group_optimization_enabled" from the */
14636 /* OS specific part (per adapter). */
14637 /**********************************************************************************/
14638 static void group_optimization(DIVA_CAPI_ADAPTER
*a
, PLCI
*plci
)
14640 word i
, j
, k
, busy
, group_found
;
14641 dword info_mask_group
[MAX_CIP_TYPES
];
14642 dword cip_mask_group
[MAX_CIP_TYPES
];
14643 word appl_number_group_type
[MAX_APPL
];
14646 /* all APPLs within this inc. call are allowed to dial in */
14647 bitmap_fill(plci
->group_optimization_mask_table
, MAX_APPL
);
14649 if (!a
->group_optimization_enabled
)
14651 dbug(1, dprintf("No group optimization"));
14655 dbug(1, dprintf("Group optimization = 0x%x...", a
->group_optimization_enabled
));
14657 for (i
= 0; i
< MAX_CIP_TYPES
; i
++)
14659 info_mask_group
[i
] = 0;
14660 cip_mask_group
[i
] = 0;
14662 for (i
= 0; i
< MAX_APPL
; i
++)
14664 appl_number_group_type
[i
] = 0;
14666 for (i
= 0; i
< max_appl
; i
++) /* check if any multi instance capable application is present */
14667 { /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */
14668 if (application
[i
].Id
&& (application
[i
].MaxNCCI
) > 1 && (a
->CIP_Mask
[i
]) && (a
->group_optimization_enabled
== 1))
14670 dbug(1, dprintf("Multi-Instance capable, no optimization required"));
14671 return; /* allow good application unfiltered access */
14674 for (i
= 0; i
< max_appl
; i
++) /* Build CIP Groups */
14676 if (application
[i
].Id
&& a
->CIP_Mask
[i
])
14678 for (k
= 0, busy
= false; k
< a
->max_plci
; k
++)
14682 auxplci
= &a
->plci
[k
];
14683 if (auxplci
->appl
== &application
[i
]) {
14684 /* application has a busy PLCI */
14686 dbug(1, dprintf("Appl 0x%x is busy", i
+ 1));
14687 } else if (test_bit(i
, plci
->c_ind_mask_table
)) {
14688 /* application has an incoming call pending */
14690 dbug(1, dprintf("Appl 0x%x has inc. call pending", i
+ 1));
14695 for (j
= 0, group_found
= 0; j
<= (MAX_CIP_TYPES
) && !busy
&& !group_found
; j
++) /* build groups with free applications only */
14697 if (j
== MAX_CIP_TYPES
) /* all groups are in use but group still not found */
14698 { /* the MAX_CIP_TYPES group enables all calls because of field overflow */
14699 appl_number_group_type
[i
] = MAX_CIP_TYPES
;
14700 group_found
= true;
14701 dbug(1, dprintf("Field overflow appl 0x%x", i
+ 1));
14703 else if ((info_mask_group
[j
] == a
->CIP_Mask
[i
]) && (cip_mask_group
[j
] == a
->Info_Mask
[i
]))
14704 { /* is group already present ? */
14705 appl_number_group_type
[i
] = j
| 0x80; /* store the group number for each application */
14706 group_found
= true;
14707 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
]));
14709 else if (!info_mask_group
[j
])
14710 { /* establish a new group */
14711 appl_number_group_type
[i
] = j
| 0x80; /* store the group number for each application */
14712 info_mask_group
[j
] = a
->CIP_Mask
[i
]; /* store the new CIP mask for the new group */
14713 cip_mask_group
[j
] = a
->Info_Mask
[i
]; /* store the new Info_Mask for this new group */
14714 group_found
= true;
14715 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
]));
14721 for (i
= 0; i
< max_appl
; i
++) /* Build group_optimization_mask_table */
14723 if (appl_number_group_type
[i
]) /* application is free, has listens and is member of a group */
14725 if (appl_number_group_type
[i
] == MAX_CIP_TYPES
)
14727 dbug(1, dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled", appl_number_group_type
[i
], i
+ 1));
14731 dbug(1, dprintf("Group 0x%x, valid appl = 0x%x", appl_number_group_type
[i
], i
+ 1));
14732 for (j
= i
+ 1; j
< max_appl
; j
++) /* search other group members and mark them as busy */
14734 if (appl_number_group_type
[i
] == appl_number_group_type
[j
])
14736 dbug(1, dprintf("Appl 0x%x is member of group 0x%x, no call", j
+ 1, appl_number_group_type
[j
]));
14737 /* disable call on other group members */
14738 __clear_bit(j
, plci
->group_optimization_mask_table
);
14739 appl_number_group_type
[j
] = 0; /* remove disabled group member from group list */
14744 else /* application should not get a call */
14746 __clear_bit(i
, plci
->group_optimization_mask_table
);
14754 /* OS notifies the driver about a application Capi_Register */
14755 word
CapiRegister(word id
)
14757 word i
, j
, appls_found
;
14760 DIVA_CAPI_ADAPTER
*a
;
14762 for (i
= 0, appls_found
= 0; i
< max_appl
; i
++)
14764 if (application
[i
].Id
&& (application
[i
].Id
!= id
))
14766 appls_found
++; /* an application has been found */
14770 if (appls_found
) return true;
14771 for (i
= 0; i
< max_adapter
; i
++) /* scan all adapters... */
14776 if (a
->flag_dynamic_l1_down
) /* remove adapter from L1 tristate (Huntgroup) */
14778 if (!appls_found
) /* first application does a capi register */
14780 if ((j
= get_plci(a
))) /* activate L1 of all adapters */
14782 plci
= &a
->plci
[j
- 1];
14784 add_p(plci
, OAD
, "\x01\xfd");
14785 add_p(plci
, CAI
, "\x01\x80");
14786 add_p(plci
, UID
, "\x06\x43\x61\x70\x69\x32\x30");
14787 add_p(plci
, SHIFT
| 6, NULL
);
14788 add_p(plci
, SIN
, "\x02\x00\x00");
14789 plci
->internal_command
= START_L1_SIG_ASSIGN_PEND
;
14790 sig_req(plci
, ASSIGN
, DSIG_ID
);
14791 add_p(plci
, FTY
, "\x02\xff\x07"); /* l1 start */
14792 sig_req(plci
, SIG_CTRL
, 0);
14802 /*------------------------------------------------------------------*/
14804 /* Functions for virtual Switching e.g. Transfer by join, Conference */
14806 static void VSwitchReqInd(PLCI
*plci
, dword Id
, byte
**parms
)
14809 /* Format of vswitch_t:
14812 2 byte VSWITCH_REQ/VSWITCH_IND
14814 4 word VSwitchcommand
14821 plci
->Sig
.Ind
== NCR_FACILITY
14825 for (i
= 0; i
< MAX_MULTI_IE
; i
++)
14827 if (!parms
[i
][0]) continue;
14828 if (parms
[i
][0] < 7)
14830 parms
[i
][0] = 0; /* kill it */
14833 dbug(1, dprintf("VSwitchReqInd(%d)", parms
[i
][4]));
14834 switch (parms
[i
][4])
14837 if (!plci
->relatedPTYPLCI
||
14838 (plci
->ptyState
!= S_ECT
&& plci
->relatedPTYPLCI
->ptyState
!= S_ECT
))
14842 /* remember all necessary informations */
14843 if (parms
[i
][0] != 11 || parms
[i
][8] != 3) /* Length Test */
14847 if (parms
[i
][2] == VSWITCH_IND
&& parms
[i
][9] == 1)
14848 { /* first indication after ECT-Request on Consultation Call */
14849 plci
->vswitchstate
= parms
[i
][9];
14850 parms
[i
][9] = 2; /* State */
14851 /* now ask first Call to join */
14853 else if (parms
[i
][2] == VSWITCH_REQ
&& parms
[i
][9] == 3)
14854 { /* Answer of VSWITCH_REQ from first Call */
14855 plci
->vswitchstate
= parms
[i
][9];
14856 /* tell consultation call to join
14857 and the protocol capabilities of the first call */
14863 plci
->vsprot
= parms
[i
][10]; /* protocol */
14864 plci
->vsprotdialect
= parms
[i
][11]; /* protocoldialect */
14865 /* send join request to related PLCI */
14866 parms
[i
][1] = VSWITCHIE
;
14867 parms
[i
][2] = VSWITCH_REQ
;
14869 plci
->relatedPTYPLCI
->command
= 0;
14870 plci
->relatedPTYPLCI
->internal_command
= VSWITCH_REQ_PEND
;
14871 add_p(plci
->relatedPTYPLCI
, ESC
, &parms
[i
][0]);
14872 sig_req(plci
->relatedPTYPLCI
, VSWITCH_REQ
, 0);
14873 send_req(plci
->relatedPTYPLCI
);
14877 if (plci
->relatedPTYPLCI
&&
14878 plci
->vswitchstate
== 3 &&
14879 plci
->relatedPTYPLCI
->vswitchstate
== 3)
14881 add_p(plci
->relatedPTYPLCI
, ESC
, &parms
[i
][0]);
14882 sig_req(plci
->relatedPTYPLCI
, VSWITCH_REQ
, 0);
14883 send_req(plci
->relatedPTYPLCI
);
14887 parms
[i
][0] = 0; /* kill it */
14892 /*------------------------------------------------------------------*/
14894 static int diva_get_dma_descriptor(PLCI
*plci
, dword
*dma_magic
) {
14896 IDI_SYNC_REQ
*pReq
= (IDI_SYNC_REQ
*)&e
;
14898 if (!(diva_xdi_extended_features
& DIVA_CAPI_XDI_PROVIDES_RX_DMA
)) {
14902 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
14903 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
14905 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC
;
14906 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= -1;
14907 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
14908 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
14910 e
.user
[0] = plci
->adapter
->Id
- 1;
14911 plci
->adapter
->request((ENTITY
*)pReq
);
14913 if (!pReq
->xdi_dma_descriptor_operation
.info
.operation
&&
14914 (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
>= 0) &&
14915 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
) {
14916 *dma_magic
= pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
;
14917 dbug(3, dprintf("dma_alloc, a:%d (%d-%08x)",
14919 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
,
14921 return (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
);
14923 dbug(1, dprintf("dma_alloc failed"));
14928 static void diva_free_dma_descriptor(PLCI
*plci
, int nr
) {
14930 IDI_SYNC_REQ
*pReq
= (IDI_SYNC_REQ
*)&e
;
14936 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
14937 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
14939 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE
;
14940 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= nr
;
14941 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
14942 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
14944 e
.user
[0] = plci
->adapter
->Id
- 1;
14945 plci
->adapter
->request((ENTITY
*)pReq
);
14947 if (!pReq
->xdi_dma_descriptor_operation
.info
.operation
) {
14948 dbug(1, dprintf("dma_free(%d)", nr
));
14950 dbug(1, dprintf("dma_free failed (%d)", nr
));
14954 /*------------------------------------------------------------------*/