FreeCalypso > hg > fc-magnetite
comparison src/g23m-aci/uart/uart_kerf.c @ 162:53929b40109c
src/g23m-aci: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2016 02:02:43 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
161:4557e2a9c18e | 162:53929b40109c |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : | |
4 | Modul : | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : This modul is part of the entity UART and implements all | |
18 | procedures and functions as described in the | |
19 | SDL-documentation (KER-statemachine) | |
20 +----------------------------------------------------------------------------- | |
21 */ | |
22 | |
23 #ifndef UART_KERF_C | |
24 #define UART_KERF_C | |
25 #endif /* !UART_KERF_C */ | |
26 | |
27 #define ENTITY_UART | |
28 | |
29 /* | |
30 * Turn off spurious LINT warnings | |
31 */ | |
32 /*lint -e415 access of out-of-bounds pointer */ | |
33 /*lint -e416 creation of out-of-bounds pointer */ | |
34 /*lint -e661 possible access of out-of-bounds pointer */ | |
35 /*lint -e662 possible craetion of out-of-bounds pointer */ | |
36 | |
37 | |
38 /*==== INCLUDES =============================================================*/ | |
39 | |
40 #ifdef WIN32 | |
41 #include "nucleus.h" | |
42 #endif /* WIN32 */ | |
43 #include "typedefs.h" /* to get Condat data types */ | |
44 #include "vsi.h" /* to get a lot of macros */ | |
45 #include "macdef.h" /* to get a lot of macros */ | |
46 #include "custom.h" | |
47 #include "gsm.h" /* to get a lot of macros */ | |
48 #include "cnf_uart.h" /* to get cnf-definitions */ | |
49 #include "mon_uart.h" /* to get mon-definitions */ | |
50 #include "prim.h" /* to get the definitions of used SAP and directions */ | |
51 #include "dti.h" /* to get dti lib */ | |
52 #include "pei.h" /* to get PEI interface */ | |
53 #ifdef FF_MULTI_PORT | |
54 #include "gsi.h" /* to get definitions of serial driver */ | |
55 #else /* FF_MULTI_PORT */ | |
56 #ifdef _TARGET_ | |
57 #include "uart/serialswitch.h" | |
58 #include "uart/traceswitch.h" | |
59 #else /* _TARGET_ */ | |
60 #include "serial_dat.h" /* to get definitions of serial driver */ | |
61 #endif /* _TARGET_ */ | |
62 #endif /* FF_MULTI_PORT */ | |
63 #include "uart.h" /* to get the global entity definitions */ | |
64 | |
65 #include "uart_kerf.h" /* to get KER function definitions */ | |
66 #include "uart_drxs.h" /* to get signal definitions for service DRX */ | |
67 #include "uart_dtxs.h" /* to get signal definitions for service DTX */ | |
68 #ifdef FF_MULTI_PORT | |
69 #include "uart_ptxs.h" /* to get signal definitions for service TX */ | |
70 #else /* FF_MULTI_PORT */ | |
71 #include "uart_txs.h" /* to get signal definitions for service TX */ | |
72 #endif /* FF_MULTI_PORT */ | |
73 #include "uart_rts.h" /* to get signal definitions for service RT */ | |
74 #include <string.h> /* JK, delete warnings: to get memmove */ | |
75 /*==== CONST ================================================================*/ | |
76 | |
77 /*==== LOCAL VARS ===========================================================*/ | |
78 | |
79 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
80 | |
81 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
82 | |
83 | |
84 | |
85 /* | |
86 +------------------------------------------------------------------------------ | |
87 | Function : ker_setupUart | |
88 +------------------------------------------------------------------------------ | |
89 | Description : The function ker_setupUart() sets the communication parameters | |
90 | of UART | |
91 | | |
92 | Parameters : no parameter | |
93 | | |
94 +------------------------------------------------------------------------------ | |
95 */ | |
96 GLOBAL void ker_setupUart(void) | |
97 { | |
98 T_UFRET ret; /* Error code returned from a function */ | |
99 | |
100 TRACE_FUNCTION( "ker_setupUart" ); | |
101 | |
102 #ifdef FF_MULTI_PORT | |
103 /* | |
104 * set new XON / XOFF character | |
105 */ | |
106 uart_data->xon = uart_data->ker.act_dcb.XON; | |
107 uart_data->xoff = uart_data->ker.act_dcb.XOFF; | |
108 /* | |
109 * set new parameters | |
110 */ | |
111 #ifndef _SIMULATION_ | |
112 if((ret = GSI_SetConfig(uart_data->device, &uart_data->ker.act_dcb)) | |
113 NEQ DRV_OK) | |
114 { | |
115 TRACE_ERROR_P2 | |
116 ("GSI driver: Serial devise configuration failed; [%d], uart_kerf.c(%d)", | |
117 ret, __LINE__); | |
118 } | |
119 #endif /* !_SIMULATION_ */ | |
120 #else /* FF_MULTI_PORT */ | |
121 /* | |
122 * set new XON / XOFF character | |
123 */ | |
124 uart_data->xon = uart_data->ker.act_xon; | |
125 uart_data->xoff = uart_data->ker.act_xoff; | |
126 /* | |
127 * set new escape sequence parameters | |
128 */ | |
129 uart_data->act_ec = uart_data->ker.act_ec; | |
130 uart_data->act_gp = uart_data->ker.act_gp; | |
131 /* | |
132 * set new parameters | |
133 */ | |
134 /* | |
135 * set up the escape sequence | |
136 */ | |
137 ret = UF_SetEscape (uart_data->device, | |
138 uart_data->act_ec, | |
139 uart_data->act_gp); | |
140 #ifdef _SIMULATION_ | |
141 TRACE_EVENT_P1 ("UF_SetEscape() = %x", (USHORT) ret); | |
142 #endif /* _SIMULATION_ */ | |
143 while ((ret = UF_SetComPar (uart_data->device, | |
144 uart_data->ker.act_br, | |
145 uart_data->ker.act_bpc, | |
146 uart_data->ker.act_sb, | |
147 uart_data->ker.act_par)) EQ UF_NOT_READY) | |
148 { | |
149 if(vsi_t_sleep (VSI_CALLER ONE_FRAME) NEQ VSI_OK) | |
150 { | |
151 TRACE_ERROR_P1("VSI entity: Can't suspend thread, uart_kerf.c(%d)", | |
152 __LINE__); | |
153 } | |
154 } | |
155 | |
156 /* | |
157 * set new flow control | |
158 */ | |
159 if (ret EQ UF_OK) | |
160 { | |
161 if((ret = UF_SetFlowCtrl (uart_data->device, uart_data->ker.act_fc_rx, | |
162 uart_data->xon, uart_data->xoff) NEQ UF_OK) | |
163 AND (uart_data->device NEQ 0)) | |
164 { | |
165 TRACE_ERROR_P2("UF driver: Can't set new flow control, [%d], uart_kerf(%d)", | |
166 ret, __LINE__); | |
167 } | |
168 } | |
169 #endif /* FF_MULTI_PORT */ | |
170 } /* ker_setupUart() */ | |
171 | |
172 | |
173 | |
174 /* | |
175 +------------------------------------------------------------------------------ | |
176 | Function : ker_init | |
177 +------------------------------------------------------------------------------ | |
178 | Description : The function ker_init() initializes the UART | |
179 | | |
180 | Parameters : no parameter | |
181 | | |
182 +------------------------------------------------------------------------------ | |
183 */ | |
184 GLOBAL void ker_init () | |
185 { | |
186 #ifdef FF_MULTI_PORT | |
187 #ifndef _SIMULATION_ | |
188 T_DRV_EXPORT* drv_export; | |
189 #endif /* !_SIMULATION_ */ | |
190 #endif /* FF_MULTI_PORT */ | |
191 | |
192 T_UFRET ret; /* Error code returned from a function */ | |
193 | |
194 TRACE_FUNCTION( "ker_init" ); | |
195 | |
196 /* | |
197 * initialize values | |
198 */ | |
199 #ifdef FF_MULTI_PORT | |
200 uart_data->ker.act_dcb.Baud = GSI_BAUD_9600; | |
201 uart_data->ker.act_dcb.DataBits = GSI_CHAR8; | |
202 uart_data->ker.act_dcb.StopBits = GSI_STOP1; | |
203 uart_data->ker.act_dcb.Parity = GSI_PARITYNO; | |
204 uart_data->ker.act_dcb.RxFlowControl = GSI_FLOWHW; | |
205 uart_data->ker.act_dcb.TxFlowControl = GSI_FLOWHW; | |
206 uart_data->ker.act_dcb.RxBufferSize = GSI_MAX_BUFFER_SIZE; | |
207 uart_data->ker.act_dcb.TxBufferSize = GSI_MAX_BUFFER_SIZE; | |
208 uart_data->ker.act_dcb.RxThreshold = 1; | |
209 uart_data->ker.act_dcb.TxThreshold = 1; | |
210 uart_data->ker.act_dcb.XON = UART_IO_XON_DEFAULT; | |
211 uart_data->ker.act_dcb.XOFF = UART_IO_XOFF_DEFAULT; | |
212 uart_data->ker.act_dcb.EscChar = UART_ESC_CHARACTER_DEFAULT; | |
213 uart_data->ker.act_dcb.GuardPeriod = UART_GUARD_PERIOD_DEFAULT; | |
214 #else /* FF_MULTI_PORT */ | |
215 uart_data->ker.act_br = UF_BAUD_9600; /* 9600 baud */ | |
216 uart_data->ker.act_bpc = bpc_8; /* 8 bits per character */ | |
217 uart_data->ker.act_sb = sb_1; /* 1 stop bit */ | |
218 uart_data->ker.act_par = pa_none; /* no parity no space */ | |
219 uart_data->ker.act_fc_rx = fc_rts; /* Hardware flow control */ | |
220 uart_data->ker.act_fc_tx = fc_rts; /* Hardware flow control */ | |
221 uart_data->ker.act_xon = UART_IO_XON_DEFAULT; /* XOn character */ | |
222 uart_data->ker.act_xoff = UART_IO_XOFF_DEFAULT; /* XOff character */ | |
223 uart_data->ker.act_ec = UART_IO_ESC_CHAR_DEFAULT; /* escape character */ | |
224 uart_data->ker.act_gp = UART_IO_ESC_GP_DEFAULT; /* guard period */ | |
225 #endif /* FF_MULTI_PORT */ | |
226 | |
227 /* bitfield of received UART primitives */ | |
228 uart_data->ker.received_prim = 0; | |
229 uart_data->ker.flush_state = UART_KER_NOT_FLUSHING; | |
230 | |
231 uart_data->ker.rx_data_desc = NULL; /* data received from peer */ | |
232 uart_data->ker.receiving_state = UART_KER_NOT_RECEIVING; | |
233 | |
234 uart_data->ker.tx_data_desc = NULL; /* data to be sent to peer */ | |
235 /* data waiting for access to tx_data_desc */ | |
236 uart_data->ker.tx_data_waiting = NULL; | |
237 uart_data->ker.sending_state = UART_KER_NOT_SENDING; | |
238 uart_data->ker.data_flow_tx = UART_FLOW_ENABLED; | |
239 uart_data->ker.nr_t1 = 0; /* nr running T1 timers yet */ | |
240 uart_data->ker.nr_t2 = 0; /* nr running T2 timers yet */ | |
241 uart_data->ker.n2 = 0; /* max nr of retransmissions */ | |
242 | |
243 #ifdef FF_MULTI_PORT | |
244 /* | |
245 * initialize driver | |
246 */ | |
247 #ifndef _SIMULATION_ | |
248 if((ret=GSI_Init(uart_data->device, uart_data->device, | |
249 pei_uart_driver_signal, &drv_export)) NEQ DRV_OK) | |
250 { | |
251 TRACE_ERROR_P2("GSI driver: InitSerialDevice failed, [%d], uart_kerf.c(%d)", | |
252 ret, __LINE__); | |
253 } | |
254 #endif /* _SIMULATION_ */ | |
255 /* | |
256 * set driver signals | |
257 */ | |
258 #ifndef _SIMULATION_ | |
259 if((ret = GSI_SetSignal(uart_data->device, DRV_SIGTYPE_READ | | |
260 DRV_SIGTYPE_WRITE | | |
261 DRV_SIGTYPE_FLUSH) NEQ DRV_OK) | |
262 { | |
263 TRACE_ERROR_P2("GSI entity: SetSignals failed, [%d], uart_kerf.c(%d)", | |
264 ret, __LINE__); | |
265 } | |
266 #endif /* _SIMULATION_ */ | |
267 #else /* FF_MULTI_PORT */ | |
268 /* | |
269 * initialize driver | |
270 */ | |
271 if((ret = UF_Init (uart_data->device)) NEQ UF_OK) | |
272 { | |
273 TRACE_ERROR_P2("UF driver: InitSerialDevice failed, [%d], uart_kerf.c(%d)", | |
274 ret, __LINE__); | |
275 } | |
276 #ifdef _SIMULATION_ | |
277 TRACE_EVENT_P1 ("UF_Init() = %x", (USHORT) ret); | |
278 #endif /* _SIMULATION_ */ | |
279 | |
280 /* | |
281 * disable UART | |
282 */ | |
283 if((ret = UF_Enable (uart_data->device, FALSE)) NEQ UF_OK) | |
284 { | |
285 TRACE_ERROR_P2("UF driver: DisableDriver failed, [%d], uart_kerf.c(%d)", | |
286 ret, __LINE__); | |
287 } | |
288 /* | |
289 * set buffer size | |
290 */ | |
291 if((ret = UF_SetBuffer (uart_data->device, UF_MAX_BUFFER_SIZE, 1, 1)) | |
292 NEQ UF_OK) | |
293 { | |
294 TRACE_ERROR_P2("UF driver: SetBufferSize failed, [%d], uart_kerf.c(%d)", | |
295 ret, __LINE__); | |
296 } | |
297 #ifdef _SIMULATION_ | |
298 TRACE_EVENT_P1 ("UF_SetBuffer() = %x", (USHORT) ret); | |
299 TRACE_EVENT_P1 ("Buffer avail = %d", | |
300 (USHORT) UF_OutpAvail (uart_data->device)); | |
301 #endif /* _SIMULATION_ */ | |
302 #endif /* FF_MULTI_PORT */ | |
303 | |
304 /* | |
305 * set communication parameters | |
306 */ | |
307 ker_setupUart(); | |
308 | |
309 INIT_STATE( UART_SERVICE_KER , KER_DEAD ); | |
310 | |
311 } /* ker_init() */ | |
312 | |
313 | |
314 | |
315 /* | |
316 +------------------------------------------------------------------------------ | |
317 | Function : ker_analyze_frame_info_command | |
318 +------------------------------------------------------------------------------ | |
319 | Description : The function ker_analyze_frame_info_command() analyzes the | |
320 | information field of incoming frames. | |
321 | The appropriate internal signals are triggered and a response | |
322 | frame information field is generated. | |
323 | | |
324 | Precondition is that the frame check sequence has been | |
325 | verified, the flags have been removed from the frame and | |
326 | message resonses have been removed from the frame. | |
327 | | |
328 | Parameters : forward - result of analysis | |
329 | frame - descriptor which includes frame type | |
330 | | |
331 +------------------------------------------------------------------------------ | |
332 */ | |
333 GLOBAL void ker_analyze_frame_info_command (ULONG* forward, T_desc2* frame) | |
334 { | |
335 T_DLC* dlc; | |
336 UBYTE dlci; | |
337 USHORT i; | |
338 USHORT pos; | |
339 USHORT len; | |
340 | |
341 TRACE_FUNCTION( "ker_analyze_frame_info_command" ); | |
342 | |
343 pos = UART_OFFSET_INFO; | |
344 | |
345 /* | |
346 * parse frame info field until last octet is reached | |
347 * (minimal message has 2 bytes: type + value) | |
348 */ | |
349 while(pos < frame->len) | |
350 { | |
351 len = 0; | |
352 while(!(frame->buffer[pos + len] & UART_EA)) | |
353 { | |
354 len++; | |
355 } | |
356 len+= (frame->buffer[pos + 1] >> UART_MSG_LENGTH_POS) + 2; | |
357 switch(frame->buffer[pos]) | |
358 { | |
359 case UART_MSG_TYPE_CLD_C: | |
360 /* | |
361 * Close Down | |
362 */ | |
363 *forward|= UART_FORWARD_CLD; | |
364 frame->buffer[pos] = UART_MSG_TYPE_CLD_R; | |
365 break; | |
366 case UART_MSG_TYPE_FCON_C: | |
367 /* | |
368 * Flow Control On | |
369 * inform all DRX instances except Control channel | |
370 */ | |
371 uart_data->ker.data_flow_tx = UART_FLOW_ENABLED; | |
372 *forward|= UART_FORWARD_FCON; | |
373 frame->buffer[pos] = UART_MSG_TYPE_FCON_R; | |
374 break; | |
375 case UART_MSG_TYPE_FCOFF_C: | |
376 /* | |
377 * Flow Control Off | |
378 * inform all DRX instances except Control channel | |
379 */ | |
380 uart_data->ker.data_flow_tx = UART_FLOW_DISABLED; | |
381 *forward|= UART_FORWARD_FCOFF; | |
382 frame->buffer[pos] = UART_MSG_TYPE_FCOFF_R; | |
383 break; | |
384 case UART_MSG_TYPE_MSC_C: | |
385 /* | |
386 * Modem Status Command | |
387 * can be 2 or 3 octets | |
388 * (depends if break signal is included or not) | |
389 */ | |
390 dlci = frame->buffer[pos+2] >> UART_DLCI_POS; | |
391 | |
392 if((dlci NEQ UART_DLCI_CONTROL) && | |
393 (uart_data->dlc_instance[dlci] NEQ UART_EMPTY_INSTANCE)) | |
394 { | |
395 dlc = &uart_data->dlc_table[uart_data->dlc_instance[dlci]]; | |
396 | |
397 /* | |
398 * set flow control | |
399 */ | |
400 if(frame->buffer[pos+3] & UART_MSC_FC_MASK) | |
401 dlc->lines|= UART_FC_RX_MASK; | |
402 else | |
403 dlc->lines&= ~UART_FC_RX_MASK; | |
404 | |
405 /* | |
406 * set line states | |
407 */ | |
408 if(frame->buffer[pos+3] & UART_MSC_RTR_MASK) | |
409 dlc->lines&= ~UART_RTS_MASK; | |
410 else | |
411 dlc->lines|= UART_RTS_MASK; | |
412 | |
413 if(frame->buffer[pos+3] & UART_MSC_RTC_MASK) | |
414 dlc->lines&= ~UART_DTR_MASK; | |
415 else | |
416 dlc->lines|= UART_DTR_MASK; | |
417 | |
418 if((len > 4) && | |
419 (frame->buffer[pos+4] & UART_MSC_BRK_MASK)) | |
420 { | |
421 dlc->lines|= UART_BRK_RX_MASK; | |
422 dlc->lines|= ((ULONG)(frame->buffer[pos+4] & UART_MSC_BRKLEN_MASK) >> | |
423 UART_MSC_BRKLEN_POS) << | |
424 UART_BRKLEN_RX_POS; | |
425 } | |
426 *forward|= UART_FORWARD_MSC; | |
427 } | |
428 else | |
429 { | |
430 TRACE_EVENT( "sig_ker_ker_MSC_C: MSC for control channel or \ | |
431 not established DLC" ); | |
432 }; | |
433 frame->buffer[pos] = UART_MSG_TYPE_MSC_R; | |
434 break; | |
435 default: | |
436 TRACE_EVENT( "ker_analyze_frame_info_command: received \ | |
437 unsupported message type" ); | |
438 /* | |
439 * create Non Supported Command response | |
440 */ | |
441 i = 0; | |
442 while(!(frame->buffer[pos + i] & UART_EA)) | |
443 { | |
444 i++; | |
445 } | |
446 if(frame->len < uart_data->n1) | |
447 { | |
448 /* | |
449 * move commands behind current command | |
450 */ | |
451 if(frame->len > (pos + len)) | |
452 { | |
453 if(len NEQ (i + 3)) | |
454 { | |
455 memmove(&frame->buffer[pos + i + 3], | |
456 &frame->buffer[pos + len], | |
457 frame->len - pos - len) | |
458 ;/*lint !e797 Conceivable creation of out-of-bounds pointer*/ | |
459 frame->len = frame->len - len + i + 3; | |
460 } | |
461 } | |
462 else | |
463 frame->len = pos + i + 3; | |
464 /* | |
465 * insert Non Supported Command | |
466 */ | |
467 len = i + 3; | |
468 /*lint -e669 -e670 (Warning -- data overrun/access beyond array) */ | |
469 memmove(&frame->buffer[pos + 2], &frame->buffer[pos], i + 1) | |
470 ;/*lint !e803 !e804 Conceivable data overrun and access beyond array*/ | |
471 /*lint +e669 +e670 (Warning -- data overrun/access beyond array) */ | |
472 frame->buffer[pos + 1] = (((UBYTE)i + 1) << UART_MSG_LENGTH_POS) | | |
473 UART_EA; | |
474 frame->buffer[pos] = UART_MSG_TYPE_NSC_R; | |
475 } | |
476 else | |
477 { | |
478 /* | |
479 * remove command | |
480 */ | |
481 if(frame->len > (pos + len)) | |
482 { | |
483 memmove(&frame->buffer[pos], | |
484 &frame->buffer[pos + len], | |
485 frame->len - pos - len); | |
486 frame->len-= len; | |
487 } | |
488 else | |
489 frame->len = pos; | |
490 len = 0; | |
491 } | |
492 break; | |
493 } | |
494 pos+= len; | |
495 } | |
496 | |
497 } /* ker_analyze_frame_info_command() */ | |
498 | |
499 | |
500 | |
501 /* | |
502 +------------------------------------------------------------------------------ | |
503 | Function : ker_search_msg_type | |
504 +------------------------------------------------------------------------------ | |
505 | Description : The function ker_search_msg_type() searches for a message type | |
506 | in a frame. | |
507 | | |
508 | Parameters : frame - descriptor which includes message type | |
509 | pos - position to start searching | |
510 | type - message type to search for | |
511 | | |
512 | Return : indicator whether message type was found | |
513 | | |
514 +------------------------------------------------------------------------------ | |
515 */ | |
516 LOCAL BOOL ker_search_msg_type (T_desc2* frame, USHORT* pos, UBYTE type) | |
517 { | |
518 TRACE_FUNCTION( "ker_search_msg_type" ); | |
519 | |
520 while(*pos < frame->len) | |
521 { | |
522 if(frame->buffer[*pos] EQ type) | |
523 { | |
524 return TRUE; | |
525 } | |
526 *pos+= (frame->buffer[*pos + 1] >> UART_MSG_LENGTH_POS) + 2; | |
527 } | |
528 return FALSE; | |
529 } /* ker_search_msg_type() */ | |
530 | |
531 | |
532 | |
533 /* | |
534 +------------------------------------------------------------------------------ | |
535 | Function : ker_analyze_frame_info_resonse | |
536 +------------------------------------------------------------------------------ | |
537 | Description : The function ker_analyze_frame_info_response() analyzes the | |
538 | information field of incoming frames. | |
539 | The appropriate internal signals are triggered and the | |
540 | responses are removed from the information field. | |
541 | | |
542 | Precondition is that the frame check sequence has been verified | |
543 | and that the flags have been removed from the frame. | |
544 | | |
545 | Parameters : forward - result of analysis | |
546 | frame - descriptor which includes frame type | |
547 | | |
548 +------------------------------------------------------------------------------ | |
549 */ | |
550 GLOBAL void ker_analyze_frame_info_response (ULONG* forward, T_desc2* frame) | |
551 { | |
552 USHORT pos; | |
553 USHORT len; | |
554 T_DLC* dlc; | |
555 ULONG forward_value; | |
556 USHORT search_pos; | |
557 USHORT search_len; | |
558 UBYTE search_command; | |
559 BOOL search_found; | |
560 BOOL search_whole_msg; | |
561 USHORT i; | |
562 | |
563 TRACE_FUNCTION( "ker_analyze_frame_info_response" ); | |
564 | |
565 /* | |
566 * check for correct message structure: | |
567 * - minimal message length == 2 octets | |
568 * - frame must end with the last message | |
569 */ | |
570 pos = UART_OFFSET_INFO; | |
571 while(pos < frame->len) | |
572 { | |
573 len = 0; | |
574 if(!(frame->buffer[pos] & UART_EA)) | |
575 { | |
576 /* | |
577 * Type field greater than one octet | |
578 */ | |
579 do | |
580 len++; | |
581 while(((pos + len) < frame->len) && | |
582 (!(frame->buffer[pos + len] & UART_EA))); | |
583 } | |
584 if(((pos + len + 1) < frame->len) && | |
585 (frame->buffer[pos + len + 1] & UART_EA)) | |
586 { | |
587 len+= (frame->buffer[pos + 1] >> UART_MSG_LENGTH_POS) + 2; | |
588 if((pos + len) > frame->len) | |
589 /* | |
590 * given length in length field to long | |
591 * remove information field | |
592 */ | |
593 frame->len = UART_OFFSET_INFO; | |
594 else | |
595 pos += len; | |
596 } | |
597 else | |
598 /* | |
599 * one octet length field expected, but not found | |
600 * remove information field | |
601 */ | |
602 frame->len = UART_OFFSET_INFO; | |
603 } | |
604 /* | |
605 * parse frame info field until last octet is reached | |
606 */ | |
607 pos = UART_OFFSET_INFO; | |
608 while(pos < frame->len) | |
609 { | |
610 len = 0; | |
611 while(!(frame->buffer[pos + len] & UART_EA)) | |
612 { | |
613 len++; | |
614 } | |
615 len+= (frame->buffer[pos + 1] >> UART_MSG_LENGTH_POS) + 2; | |
616 if(frame->buffer[pos] & UART_CR) | |
617 { | |
618 /* | |
619 * command detected move to next message | |
620 */ | |
621 pos+= len; | |
622 } | |
623 else | |
624 { | |
625 /* | |
626 * analyze response message | |
627 */ | |
628 switch( frame->buffer[pos] ) | |
629 { | |
630 case UART_MSG_TYPE_CLD_R: | |
631 /* | |
632 * Close Down | |
633 */ | |
634 dlc = &uart_data->dlc_table[UART_CONTROL_INSTANCE]; | |
635 search_command = UART_MSG_TYPE_CLD_C; | |
636 forward_value = UART_FORWARD_CLD; | |
637 search_whole_msg = TRUE; | |
638 break; | |
639 | |
640 case UART_MSG_TYPE_FCON_R: | |
641 /* | |
642 * Flow Control On | |
643 */ | |
644 dlc = &uart_data->dlc_table[UART_CONTROL_INSTANCE]; | |
645 search_command = UART_MSG_TYPE_FCON_C; | |
646 forward_value = 0; | |
647 search_whole_msg = TRUE; | |
648 break; | |
649 | |
650 case UART_MSG_TYPE_FCOFF_R: | |
651 /* | |
652 * Flow Control Off | |
653 */ | |
654 dlc = &uart_data->dlc_table[UART_CONTROL_INSTANCE]; | |
655 search_command = UART_MSG_TYPE_FCOFF_C; | |
656 forward_value = 0; | |
657 search_whole_msg = TRUE; | |
658 break; | |
659 | |
660 case UART_MSG_TYPE_MSC_R: | |
661 /* | |
662 * Modem Status Command | |
663 */ | |
664 dlc = &uart_data->dlc_table[UART_CONTROL_INSTANCE]; | |
665 search_command = UART_MSG_TYPE_MSC_C; | |
666 forward_value = 0; | |
667 search_whole_msg = TRUE; | |
668 break; | |
669 | |
670 case UART_MSG_TYPE_NSC_R: | |
671 /* | |
672 * not supported command, | |
673 */ | |
674 dlc = &uart_data->dlc_table[UART_CONTROL_INSTANCE]; | |
675 if(len > 2) | |
676 search_command = frame->buffer[pos + 2]; | |
677 else | |
678 search_command = 0; | |
679 switch(search_command) | |
680 { | |
681 case UART_MSG_TYPE_CLD_C: | |
682 forward_value = UART_FORWARD_CLD; | |
683 break; | |
684 default: | |
685 forward_value = 0; | |
686 break; | |
687 } | |
688 search_whole_msg = FALSE; | |
689 break; | |
690 | |
691 default: | |
692 TRACE_ERROR( "Error in ker_analyze_frame_info_response: \ | |
693 Unsupported message type received"); | |
694 dlc = &uart_data->dlc_table[UART_CONTROL_INSTANCE]; | |
695 search_command = 0; | |
696 forward_value = 0; | |
697 search_whole_msg = TRUE; | |
698 break; | |
699 } | |
700 /* | |
701 * search and remove command message | |
702 */ | |
703 if(dlc->last_command NEQ NULL) | |
704 { | |
705 search_pos = UART_OFFSET_INFO; | |
706 search_found = FALSE; | |
707 while((search_found EQ FALSE) && | |
708 (ker_search_msg_type(dlc->last_command, | |
709 &search_pos, | |
710 search_command) EQ TRUE)) | |
711 { | |
712 search_len = (dlc->last_command->buffer[search_pos + 1] >> | |
713 UART_MSG_LENGTH_POS) + 2; | |
714 search_found = TRUE; | |
715 if(search_whole_msg EQ TRUE) | |
716 { | |
717 /* | |
718 * check whole message | |
719 */ | |
720 for(i=1; i < search_len; i++) | |
721 { | |
722 if(dlc->last_command->buffer[search_pos + i] NEQ | |
723 frame->buffer[pos + i]) | |
724 search_found = FALSE; | |
725 } | |
726 } | |
727 if(search_found EQ TRUE) | |
728 { | |
729 /* | |
730 * corresponding command message found | |
731 * remove it | |
732 */ | |
733 if(dlc->last_command->len > (search_pos + search_len)) | |
734 { | |
735 memmove(&dlc->last_command->buffer[search_pos], | |
736 &dlc->last_command->buffer[search_pos + search_len], | |
737 dlc->last_command->len - search_pos - search_len); | |
738 dlc->last_command->len-= search_len; | |
739 } | |
740 else | |
741 dlc->last_command->len = search_pos; | |
742 /* | |
743 * set retransmissions to zero and | |
744 * set forward parameter | |
745 */ | |
746 dlc->retransmissions = 0; | |
747 *forward |= forward_value; | |
748 } | |
749 else | |
750 { | |
751 search_pos+= search_len; | |
752 } | |
753 } | |
754 } | |
755 /* | |
756 * remove resonse message | |
757 */ | |
758 if(frame->len > (pos + len)) | |
759 { | |
760 memmove(&frame->buffer[pos], | |
761 &frame->buffer[pos + len], | |
762 frame->len - pos - len); | |
763 frame->len-= len; | |
764 } | |
765 else | |
766 frame->len = pos; | |
767 } | |
768 } | |
769 } /* ker_analyze_frame_info_response() */ | |
770 | |
771 | |
772 | |
773 /* | |
774 +------------------------------------------------------------------------------ | |
775 | Function : ker_mux_dlc_release | |
776 +------------------------------------------------------------------------------ | |
777 | Description : This function closes one open multiplexer channel | |
778 | | |
779 | Parameters : dlc_instance - instance of dlc to release | |
780 | | |
781 +------------------------------------------------------------------------------ | |
782 */ | |
783 GLOBAL void ker_mux_dlc_release (UBYTE dlc_instance) | |
784 { | |
785 T_DLC* dlc; | |
786 UBYTE dlci; | |
787 | |
788 TRACE_FUNCTION( "ker_mux_dlc_release" ); | |
789 | |
790 /* | |
791 * set dlc values | |
792 */ | |
793 dlc = &uart_data->dlc_table[dlc_instance]; | |
794 dlci = dlc->dlci; | |
795 /* | |
796 * stop timer if this was the last running, | |
797 * free copy of last command frame | |
798 */ | |
799 if(dlc->last_command NEQ NULL) | |
800 { | |
801 if(dlc->last_command->buffer[UART_OFFSET_CONTROL] EQ | |
802 UART_UIH_CONTROL_FRAME) | |
803 { | |
804 uart_data->ker.nr_t2--; | |
805 if( uart_data->ker.nr_t2 EQ 0 ) | |
806 sig_ker_rt_stop_t2_req(); | |
807 } | |
808 else | |
809 { | |
810 uart_data->ker.nr_t1--; | |
811 if( uart_data->ker.nr_t1 EQ 0 ) | |
812 sig_ker_rt_stop_t1_req(); | |
813 } | |
814 MFREE_DESC2(dlc->last_command); | |
815 dlc->last_command = NULL; | |
816 } | |
817 /* | |
818 * set connection state | |
819 */ | |
820 dlc->connection_state = UART_CONNECTION_DEAD; | |
821 /* | |
822 * remove DLC instance | |
823 */ | |
824 if(dlc->next_command NEQ NULL) | |
825 { | |
826 MFREE_DESC2(dlc->next_command); | |
827 dlc->next_command = NULL; | |
828 } | |
829 uart_data->dlc_instance[dlci] = UART_EMPTY_INSTANCE; | |
830 dlc->dlci = UART_DLCI_INVALID; | |
831 /* | |
832 * close DTI connection | |
833 */ | |
834 uart_data->drx = dlc->drx; | |
835 uart_data->dtx = dlc->dtx; | |
836 sig_ker_drx_dead_mode_req(); | |
837 sig_ker_dtx_dead_mode_req(); | |
838 if(dlc->dti_state NEQ DTI_CLOSED) | |
839 { | |
840 dti_close(uart_hDTI, uart_data->device, | |
841 UART_DTI_UP_INTERFACE, dlc_instance, FALSE); | |
842 dlc->dti_state = DTI_CLOSED; | |
843 } | |
844 } /* ker_mux_dlc_release() */ | |
845 | |
846 | |
847 | |
848 /* | |
849 +------------------------------------------------------------------------------ | |
850 | Function : ker_mux_close_down | |
851 +------------------------------------------------------------------------------ | |
852 | Description : This function closes all currently open multiplexer channels. | |
853 | | |
854 | Parameters : no parameter | |
855 | | |
856 +------------------------------------------------------------------------------ | |
857 */ | |
858 GLOBAL void ker_mux_close_down () | |
859 { | |
860 UBYTE i; | |
861 | |
862 TRACE_FUNCTION( "ker_mux_close_down" ); | |
863 | |
864 /* | |
865 * close all channels | |
866 */ | |
867 for(i = 0; i <= UART_MAX_NUMBER_OF_CHANNELS; i++) | |
868 { | |
869 /* | |
870 * set dlc values | |
871 */ | |
872 if(uart_data->dlc_table[i].dlci NEQ UART_DLCI_INVALID) | |
873 ker_mux_dlc_release(i); | |
874 } | |
875 /* | |
876 * stop timers | |
877 */ | |
878 uart_data->ker.nr_t1 = 0; | |
879 sig_ker_rt_stop_t1_req(); | |
880 uart_data->ker.nr_t2 = 0; | |
881 sig_ker_rt_stop_t2_req(); | |
882 sig_ker_rt_stop_t3_req(); | |
883 | |
884 } /* ker_mux_close_down() */ | |
885 | |
886 /* | |
887 +------------------------------------------------------------------------------ | |
888 | Function : ker_mux_send_frame | |
889 +------------------------------------------------------------------------------ | |
890 | Description : This function is used to send out a frame in multiplexer mode. | |
891 | It checks if the KER service is currently sending. If not, the | |
892 | descriptor is put in the output queue for the TX service and | |
893 | the service is notified that data is available. If the KER | |
894 | service is in state sending, the descriptor is put in a second | |
895 | queue for later processing. | |
896 | | |
897 | Parameters : frame - descriptor with frame to send | |
898 | | |
899 +------------------------------------------------------------------------------ | |
900 */ | |
901 GLOBAL void ker_mux_send_frame (T_desc2* frame) | |
902 { | |
903 T_desc2* desc; | |
904 | |
905 TRACE_FUNCTION( "ker_mux_send_frame" ); | |
906 | |
907 if(uart_data->ker.tx_data_desc) | |
908 { | |
909 /* | |
910 * currently sending, put frame in waiting queue | |
911 */ | |
912 desc = uart_data->ker.tx_data_waiting; | |
913 if(desc) | |
914 { | |
915 while(desc->next NEQ (ULONG)NULL) | |
916 desc = (T_desc2*)desc->next; | |
917 desc->next = (ULONG)frame; | |
918 } | |
919 else | |
920 uart_data->ker.tx_data_waiting = frame; | |
921 } | |
922 else | |
923 { | |
924 /* | |
925 * send frame immediately | |
926 */ | |
927 uart_data->ker.tx_data_desc = frame; | |
928 sig_ker_tx_data_available_req(uart_data->ker.tx_data_desc, 0); | |
929 } | |
930 } /* ker_mux_send_frame() */ | |
931 | |
932 | |
933 | |
934 /* | |
935 +------------------------------------------------------------------------------ | |
936 | Function : ker_mux_send_command_frame | |
937 +------------------------------------------------------------------------------ | |
938 | Description : This function is used to send out a command frame in | |
939 | multiplexer mode. | |
940 | It enables the response timer and saves a copy of the | |
941 | command frame in the DLC's last_command variable so the | |
942 | frame can be retransmitted if the timer expires. | |
943 | | |
944 | Parameters : dlc_instance - dlc instance the command frame belongs to | |
945 | frame - descriptor with command frame to send | |
946 | | |
947 +------------------------------------------------------------------------------ | |
948 */ | |
949 GLOBAL void ker_mux_send_command_frame (UBYTE dlc_instance, T_desc2* frame) | |
950 { | |
951 T_DLC* dlc; | |
952 T_desc2* desc; | |
953 | |
954 TRACE_FUNCTION( "ker_mux_send_command_frame" ); | |
955 | |
956 dlc = &uart_data->dlc_table[dlc_instance]; | |
957 /* | |
958 * copy frame | |
959 */ | |
960 if(dlc->last_command NEQ NULL) | |
961 { | |
962 /* | |
963 * currently sending, put command frame in waiting queue | |
964 */ | |
965 desc = dlc->next_command; | |
966 if(desc) | |
967 { | |
968 while(desc->next NEQ (ULONG)NULL) | |
969 desc = (T_desc2*)desc->next; | |
970 desc->next = (ULONG)frame; | |
971 } | |
972 else | |
973 dlc->next_command = frame; | |
974 } | |
975 else | |
976 { | |
977 MALLOC(dlc->last_command, (USHORT)(sizeof( T_desc2 ) - 1 + | |
978 frame->len)); | |
979 | |
980 dlc->last_command->next = (ULONG)NULL; | |
981 dlc->last_command->len = frame->len; | |
982 memcpy(dlc->last_command->buffer, frame->buffer, frame->len); | |
983 | |
984 /* | |
985 * set response timer and counter | |
986 */ | |
987 dlc->retransmissions = 0; | |
988 if(frame->buffer[UART_OFFSET_CONTROL] EQ UART_UIH_CONTROL_FRAME) | |
989 { | |
990 /* | |
991 * usual UIH Command frame | |
992 * use T2 timer | |
993 */ | |
994 uart_data->ker.nr_t2++; | |
995 sig_ker_rt_start_t2_req(); | |
996 } | |
997 else | |
998 { | |
999 /* | |
1000 * DISC frame | |
1001 * use T1 timer | |
1002 */ | |
1003 uart_data->ker.nr_t1++; | |
1004 sig_ker_rt_start_t1_req(); | |
1005 } | |
1006 | |
1007 /* | |
1008 * use the usual frame send function to transmit the frame | |
1009 */ | |
1010 ker_mux_send_frame( frame ); | |
1011 } | |
1012 } /* ker_mux_send_command_frame() */ | |
1013 | |
1014 | |
1015 | |
1016 /* | |
1017 +------------------------------------------------------------------------------ | |
1018 | Function : ker_mux_send_line_states | |
1019 +------------------------------------------------------------------------------ | |
1020 | Description : This function is used to send out a frame in multiplexer mode. | |
1021 | It creates an UIH frame with MSC command and includes new line | |
1022 | states. | |
1023 | | |
1024 | Parameters : dlc_instance - instance of DLC | |
1025 | | |
1026 +------------------------------------------------------------------------------ | |
1027 */ | |
1028 GLOBAL void ker_mux_send_line_states(UBYTE dlc_instance) | |
1029 { | |
1030 T_DLC* dlc; | |
1031 T_desc2* frame; | |
1032 USHORT pos; | |
1033 ULONG line_states; | |
1034 | |
1035 TRACE_FUNCTION( "ker_mux_send_line_states" ); | |
1036 | |
1037 dlc = &uart_data->dlc_table[dlc_instance]; | |
1038 line_states = dlc->lines; | |
1039 /* | |
1040 * allocate memory | |
1041 */ | |
1042 MALLOC(frame, (USHORT)(sizeof( T_desc2 ) - 1 + uart_data->n1 + 2)); | |
1043 frame->next = (ULONG)NULL; | |
1044 | |
1045 /* | |
1046 * fill frame | |
1047 */ | |
1048 /* | |
1049 * address field | |
1050 */ | |
1051 pos = 0; | |
1052 frame->buffer[pos] = (UART_DLCI_CONTROL << UART_DLCI_POS) | UART_EA; | |
1053 pos++; | |
1054 /* | |
1055 * control field | |
1056 */ | |
1057 frame->buffer[pos] = UART_UIH_CONTROL_FRAME; | |
1058 pos++; | |
1059 /* | |
1060 * type field | |
1061 */ | |
1062 frame->buffer[pos] = UART_MSG_TYPE_MSC_C; | |
1063 pos++; | |
1064 /* | |
1065 * length field | |
1066 */ | |
1067 if(line_states & UART_BRK_TX_MASK) | |
1068 /* | |
1069 * length 3 with break field | |
1070 */ | |
1071 frame->buffer[pos] = (3 << UART_MSG_LENGTH_POS) | UART_EA; | |
1072 else | |
1073 /* | |
1074 * length 2 without break field | |
1075 */ | |
1076 frame->buffer[pos] = (2 << UART_MSG_LENGTH_POS) | UART_EA; | |
1077 pos++; | |
1078 /* | |
1079 * DLCI field | |
1080 */ | |
1081 frame->buffer[pos] = (dlc->dlci << UART_DLCI_POS) | UART_CR | UART_EA; | |
1082 pos++; | |
1083 /* | |
1084 * V.24 signals | |
1085 */ | |
1086 frame->buffer[pos] = UART_EA; | |
1087 if(!(line_states & UART_DCD_MASK)) | |
1088 frame->buffer[pos] |= UART_MSC_DV_MASK; | |
1089 | |
1090 if(line_states & UART_RI_MASK) | |
1091 frame->buffer[pos] |= UART_MSC_IC_MASK; | |
1092 | |
1093 if(!(line_states & UART_CTS_MASK)) | |
1094 frame->buffer[pos] |= UART_MSC_RTR_MASK; | |
1095 | |
1096 if(!(line_states & UART_DSR_MASK)) | |
1097 frame->buffer[pos] |= UART_MSC_RTC_MASK; | |
1098 | |
1099 if(line_states & UART_FC_TX_MASK) | |
1100 frame->buffer[pos] |= UART_MSC_FC_MASK; | |
1101 | |
1102 pos++; | |
1103 | |
1104 /* | |
1105 * break signal | |
1106 */ | |
1107 if(line_states & UART_BRK_TX_MASK) | |
1108 { | |
1109 frame->buffer[pos] = (((UBYTE)((line_states & UART_BRKLEN_TX_MASK) >> | |
1110 UART_BRKLEN_TX_POS)) << | |
1111 UART_MSC_BRKLEN_POS) | | |
1112 UART_MSC_BRK_MASK | | |
1113 UART_EA; | |
1114 pos++; | |
1115 /* | |
1116 * break sent, so clear break flag | |
1117 */ | |
1118 dlc->lines&= ~UART_BRK_TX_MASK; | |
1119 } | |
1120 | |
1121 | |
1122 /* | |
1123 * send frame | |
1124 */ | |
1125 frame->len = pos; | |
1126 ker_mux_send_command_frame(UART_CONTROL_INSTANCE, frame); | |
1127 | |
1128 } /* ker_mux_send_line_states() */ | |
1129 | |
1130 | |
1131 | |
1132 /* | |
1133 +------------------------------------------------------------------------------ | |
1134 | Function : ker_mux_send_close_down | |
1135 +------------------------------------------------------------------------------ | |
1136 | Description : This function is used to send out a frame in multiplexer mode. | |
1137 | It creates an UIH frame with CLD command | |
1138 | | |
1139 | Parameters : no parameters | |
1140 | | |
1141 +------------------------------------------------------------------------------ | |
1142 */ | |
1143 GLOBAL void ker_mux_send_close_down() | |
1144 { | |
1145 T_desc2* frame; | |
1146 USHORT pos; | |
1147 | |
1148 TRACE_FUNCTION( "ker_mux_send_close_down" ); | |
1149 | |
1150 /* | |
1151 * allocate memory | |
1152 */ | |
1153 MALLOC(frame, (USHORT)(sizeof( T_desc2 ) - 1 + uart_data->n1 + 2)); | |
1154 frame->next = (ULONG)NULL; | |
1155 | |
1156 /* | |
1157 * fill frame | |
1158 */ | |
1159 /* | |
1160 * address field | |
1161 */ | |
1162 pos = 0; | |
1163 frame->buffer[pos] = (UART_DLCI_CONTROL << UART_DLCI_POS) | UART_EA; | |
1164 pos++; | |
1165 /* | |
1166 * control field | |
1167 */ | |
1168 frame->buffer[pos] = UART_UIH_CONTROL_FRAME; | |
1169 pos++; | |
1170 /* | |
1171 * type field | |
1172 */ | |
1173 frame->buffer[pos] = UART_MSG_TYPE_CLD_C; | |
1174 pos++; | |
1175 /* | |
1176 * length field | |
1177 */ | |
1178 frame->buffer[pos] = UART_EA; | |
1179 pos++; | |
1180 | |
1181 /* | |
1182 * send frame | |
1183 */ | |
1184 frame->len = pos; | |
1185 frame->size = pos; | |
1186 frame->offset = 0; | |
1187 ker_mux_send_command_frame(UART_CONTROL_INSTANCE, frame); | |
1188 } /* ker_mux_send_close_down() */ | |
1189 | |
1190 | |
1191 | |
1192 /* | |
1193 +------------------------------------------------------------------------------ | |
1194 | Function : ker_send_disc_frame | |
1195 +------------------------------------------------------------------------------ | |
1196 | Description : This function is used to send out a frame in multiplexer mode. | |
1197 | It creates an DISC frame and sends it. | |
1198 | | |
1199 | Parameters : none | |
1200 | | |
1201 +------------------------------------------------------------------------------ | |
1202 */ | |
1203 GLOBAL void ker_send_disc_frame(UBYTE dlci) | |
1204 { | |
1205 T_desc2* frame; | |
1206 USHORT pos; | |
1207 | |
1208 TRACE_FUNCTION( "ker_send_disc_frame" ); | |
1209 | |
1210 /* | |
1211 * allocate memory | |
1212 */ | |
1213 MALLOC(frame, (USHORT)(sizeof(T_desc2) - 1 + 2)); | |
1214 frame->next = (ULONG)NULL; | |
1215 | |
1216 /* | |
1217 * fill frame | |
1218 */ | |
1219 /* | |
1220 * address field | |
1221 */ | |
1222 pos = 0; | |
1223 frame->buffer[pos] = (dlci << UART_DLCI_POS) | UART_EA; | |
1224 pos++; | |
1225 /* | |
1226 * control field | |
1227 */ | |
1228 frame->buffer[pos] = UART_DISC_FRAME; | |
1229 pos++; | |
1230 | |
1231 /* | |
1232 * send frame | |
1233 */ | |
1234 frame->len = pos; | |
1235 ker_mux_send_command_frame(uart_data->dlc_instance[dlci], frame); | |
1236 | |
1237 } /* ker_send_disc_frame */ | |
1238 | |
1239 | |
1240 | |
1241 /* | |
1242 +------------------------------------------------------------------------------ | |
1243 | Function : ker_receive_sabm_frame | |
1244 +------------------------------------------------------------------------------ | |
1245 | Description : This function analyzes received SABM frames. | |
1246 | | |
1247 | Parameters : forward - result of analysis | |
1248 | frame - frame to analyze | |
1249 | | |
1250 +------------------------------------------------------------------------------ | |
1251 */ | |
1252 GLOBAL void ker_receive_sabm_frame(ULONG* forward, T_desc2* frame) | |
1253 { | |
1254 T_DLC* dlc; | |
1255 UBYTE dlci; | |
1256 UBYTE dlc_instance; | |
1257 UBYTE i; | |
1258 | |
1259 TRACE_FUNCTION( "ker_receive_sabm_frame" ); | |
1260 | |
1261 dlci = frame->buffer[UART_OFFSET_ADDRESS] >> UART_DLCI_POS; | |
1262 dlc_instance = uart_data->dlc_instance[dlci]; | |
1263 | |
1264 /* | |
1265 * analyze message responses | |
1266 */ | |
1267 ker_analyze_frame_info_response(forward, frame); | |
1268 /* | |
1269 * check whether frame for an existing channel | |
1270 */ | |
1271 if(dlc_instance != UART_EMPTY_INSTANCE) | |
1272 { | |
1273 /* | |
1274 * set DLC to this channel | |
1275 */ | |
1276 dlc = &uart_data->dlc_table[dlc_instance]; | |
1277 switch(dlc->connection_state) | |
1278 { | |
1279 case UART_CONNECTION_OPEN: | |
1280 /* | |
1281 * send UA frame | |
1282 */ | |
1283 ker_analyze_frame_info_command(forward, frame); | |
1284 frame->buffer[UART_OFFSET_CONTROL] = UART_UA_FRAME; | |
1285 *forward |= UART_FORWARD_RESPONSE; | |
1286 break; | |
1287 | |
1288 case UART_CONNECTION_DISC_SENT: | |
1289 /* | |
1290 * send DM frame | |
1291 */ | |
1292 ker_analyze_frame_info_command(forward, frame); | |
1293 frame->buffer[UART_OFFSET_CONTROL] = UART_DM_CONTROL_FRAME; | |
1294 *forward |= UART_FORWARD_RESPONSE; | |
1295 break; | |
1296 | |
1297 case UART_CONNECTION_SABM_RCVD: | |
1298 break; | |
1299 | |
1300 default: | |
1301 TRACE_ERROR( "DLC CONNECTION_STATE unexpected" ); | |
1302 break; | |
1303 } | |
1304 } | |
1305 else | |
1306 { | |
1307 ker_analyze_frame_info_command(forward, frame); | |
1308 if( dlci EQ UART_DLCI_CONTROL ) | |
1309 { | |
1310 /* | |
1311 * this is a SABM frame for the control channel, | |
1312 * therefore the appropriate instance is UART_CONTROL_INSTANCE | |
1313 */ | |
1314 dlc = &uart_data->dlc_table[UART_CONTROL_INSTANCE]; | |
1315 if(dlc->dlci EQ UART_DLCI_INVALID) | |
1316 { | |
1317 i = UART_CONTROL_INSTANCE; | |
1318 /* | |
1319 * mark DLC as opened | |
1320 */ | |
1321 dlc->connection_state = UART_CONNECTION_SABM_RCVD; | |
1322 dlc->dlci = dlci; | |
1323 | |
1324 /* | |
1325 * create UA response frame | |
1326 */ | |
1327 frame->buffer[UART_OFFSET_CONTROL] = UART_UA_FRAME; | |
1328 *forward |= UART_FORWARD_SABM; | |
1329 } | |
1330 else | |
1331 { | |
1332 i = UART_MAX_NUMBER_OF_CHANNELS + 1; | |
1333 } | |
1334 } | |
1335 else | |
1336 { | |
1337 /* | |
1338 * if new, check whether there is a free channel left | |
1339 */ | |
1340 for(i=0; i <= UART_MAX_NUMBER_OF_CHANNELS; i++ ) | |
1341 { | |
1342 if(uart_data->dlc_table[i].dlci EQ UART_DLCI_INVALID) | |
1343 { | |
1344 dlc = &uart_data->dlc_table[i]; | |
1345 /* | |
1346 * mark DLC as opened | |
1347 */ | |
1348 dlc->connection_state = UART_CONNECTION_SABM_RCVD; | |
1349 dlc->dlci = dlci; | |
1350 | |
1351 /* | |
1352 * create UA response frame | |
1353 */ | |
1354 frame->buffer[UART_OFFSET_CONTROL] = UART_UA_FRAME; | |
1355 *forward |= UART_FORWARD_SABM; | |
1356 break; | |
1357 } | |
1358 } | |
1359 } | |
1360 if( i > UART_MAX_NUMBER_OF_CHANNELS ) | |
1361 { | |
1362 /* | |
1363 * no free channel found, return DM frame | |
1364 */ | |
1365 frame->buffer[UART_OFFSET_CONTROL] = UART_DM_CONTROL_FRAME; | |
1366 } | |
1367 *forward|= UART_FORWARD_RESPONSE; | |
1368 } | |
1369 } /* ker_receive_sabm_frame */ | |
1370 | |
1371 | |
1372 | |
1373 /* | |
1374 +------------------------------------------------------------------------------ | |
1375 | Function : ker_receive_ua_frame | |
1376 +------------------------------------------------------------------------------ | |
1377 | Description : This function analyzes received UA frames. | |
1378 | | |
1379 | Parameters : forward - result of analysis | |
1380 | frame - frame to analyze | |
1381 | | |
1382 +------------------------------------------------------------------------------ | |
1383 */ | |
1384 GLOBAL void ker_receive_ua_frame(ULONG* forward, T_desc2* frame) | |
1385 { | |
1386 T_DLC* dlc; | |
1387 UBYTE dlci; | |
1388 UBYTE dlc_instance; | |
1389 | |
1390 TRACE_FUNCTION( "ker_receive_ua_frame" ); | |
1391 | |
1392 dlci = frame->buffer[UART_OFFSET_ADDRESS] >> UART_DLCI_POS; | |
1393 dlc_instance = uart_data->dlc_instance[dlci]; | |
1394 | |
1395 /* | |
1396 * analyze message responses | |
1397 */ | |
1398 ker_analyze_frame_info_response(forward, frame); | |
1399 /* | |
1400 * check whether frame for an existing channel | |
1401 */ | |
1402 if(dlc_instance != UART_EMPTY_INSTANCE) | |
1403 { | |
1404 /* | |
1405 * set DLC to this channel | |
1406 */ | |
1407 dlc = &uart_data->dlc_table[dlc_instance]; | |
1408 switch(dlc->connection_state) | |
1409 { | |
1410 case UART_CONNECTION_DISC_SENT: | |
1411 /* | |
1412 * remove DISC frame | |
1413 */ | |
1414 MFREE_DESC2(dlc->last_command); | |
1415 dlc->last_command = NULL; | |
1416 uart_data->ker.nr_t1--; | |
1417 if( uart_data->ker.nr_t1 EQ 0 ) | |
1418 sig_ker_rt_stop_t1_req(); | |
1419 /* | |
1420 * mark channel as closed | |
1421 */ | |
1422 dlc->connection_state = UART_CONNECTION_DEAD; | |
1423 *forward |= UART_FORWARD_DLC_RELEASE; | |
1424 break; | |
1425 | |
1426 case UART_CONNECTION_SABM_RCVD: | |
1427 case UART_CONNECTION_OPEN: | |
1428 break; | |
1429 | |
1430 default: | |
1431 TRACE_ERROR( "DLC CONNECTION_STATE unexpected" ); | |
1432 break; | |
1433 } | |
1434 } | |
1435 } /* ker_receive_ua_frame */ | |
1436 | |
1437 | |
1438 | |
1439 /* | |
1440 +------------------------------------------------------------------------------ | |
1441 | Function : ker_receive_dm_frame | |
1442 +------------------------------------------------------------------------------ | |
1443 | Description : This function analyzes received DM frames. | |
1444 | | |
1445 | Parameters : forward - result of analysis | |
1446 | frame - frame to analyze | |
1447 | | |
1448 +------------------------------------------------------------------------------ | |
1449 */ | |
1450 GLOBAL void ker_receive_dm_frame(ULONG* forward, T_desc2* frame) | |
1451 { | |
1452 T_DLC* dlc; | |
1453 UBYTE dlci; | |
1454 UBYTE dlc_instance; | |
1455 | |
1456 TRACE_FUNCTION( "ker_receive_dm_frame" ); | |
1457 | |
1458 dlci = frame->buffer[UART_OFFSET_ADDRESS] >> UART_DLCI_POS; | |
1459 dlc_instance = uart_data->dlc_instance[dlci]; | |
1460 | |
1461 /* | |
1462 * analyze message responses | |
1463 */ | |
1464 ker_analyze_frame_info_response(forward, frame); | |
1465 /* | |
1466 * check whether frame for an existing channel | |
1467 * and not for Control channel | |
1468 */ | |
1469 if((dlc_instance NEQ UART_EMPTY_INSTANCE) && | |
1470 (dlci NEQ UART_DLCI_CONTROL)) | |
1471 { | |
1472 /* | |
1473 * set DLC to this channel | |
1474 */ | |
1475 dlc = &uart_data->dlc_table[dlc_instance]; | |
1476 switch(dlc->connection_state) | |
1477 { | |
1478 case UART_CONNECTION_DISC_SENT: | |
1479 /* | |
1480 * remove DISC frame | |
1481 */ | |
1482 MFREE_DESC2(dlc->last_command); | |
1483 dlc->last_command = NULL; | |
1484 uart_data->ker.nr_t1--; | |
1485 if( uart_data->ker.nr_t1 EQ 0 ) | |
1486 sig_ker_rt_stop_t1_req(); | |
1487 /* fall through */ | |
1488 case UART_CONNECTION_OPEN: | |
1489 /* | |
1490 * mark channel as closed | |
1491 */ | |
1492 dlc->connection_state = UART_CONNECTION_DEAD; | |
1493 *forward |= UART_FORWARD_DLC_RELEASE; | |
1494 break; | |
1495 | |
1496 case UART_CONNECTION_SABM_RCVD: | |
1497 break; | |
1498 | |
1499 default: | |
1500 TRACE_ERROR( "DLC CONNECTION_STATE unexpected" ); | |
1501 break; | |
1502 } | |
1503 } | |
1504 } /* ker_receive_dm_frame */ | |
1505 | |
1506 | |
1507 | |
1508 /* | |
1509 +------------------------------------------------------------------------------ | |
1510 | Function : ker_receive_disc_frame | |
1511 +------------------------------------------------------------------------------ | |
1512 | Description : This function analyzes received DISC frames. | |
1513 | | |
1514 | Parameters : forward - result of analysis | |
1515 | frame - frame to analyze | |
1516 | | |
1517 +------------------------------------------------------------------------------ | |
1518 */ | |
1519 GLOBAL void ker_receive_disc_frame(ULONG* forward, T_desc2* frame) | |
1520 { | |
1521 T_DLC* dlc; | |
1522 UBYTE dlci; | |
1523 UBYTE dlc_instance; | |
1524 | |
1525 TRACE_FUNCTION( "ker_receive_disc_frame" ); | |
1526 | |
1527 dlci = frame->buffer[UART_OFFSET_ADDRESS] >> UART_DLCI_POS; | |
1528 dlc_instance = uart_data->dlc_instance[dlci]; | |
1529 | |
1530 /* | |
1531 * analyze messages | |
1532 */ | |
1533 ker_analyze_frame_info_response(forward, frame); | |
1534 ker_analyze_frame_info_command(forward, frame); | |
1535 /* | |
1536 * check whether frame for an existing channel | |
1537 */ | |
1538 if(dlc_instance NEQ UART_EMPTY_INSTANCE) | |
1539 { | |
1540 /* | |
1541 * set DLC to this channel | |
1542 */ | |
1543 dlc = &uart_data->dlc_table[dlc_instance]; | |
1544 if(dlci EQ UART_DLCI_CONTROL) | |
1545 { | |
1546 /* | |
1547 * send UA frame | |
1548 */ | |
1549 frame->buffer[UART_OFFSET_CONTROL] = UART_UA_FRAME; | |
1550 *forward |= UART_FORWARD_CLD; | |
1551 } | |
1552 else | |
1553 { | |
1554 switch(dlc->connection_state) | |
1555 { | |
1556 case UART_CONNECTION_DISC_SENT: | |
1557 /* | |
1558 * remove DISC frame | |
1559 */ | |
1560 MFREE_DESC2(dlc->last_command); | |
1561 dlc->last_command = NULL; | |
1562 uart_data->ker.nr_t1--; | |
1563 if( uart_data->ker.nr_t1 EQ 0 ) | |
1564 sig_ker_rt_stop_t1_req(); | |
1565 /* fall through */ | |
1566 case UART_CONNECTION_SABM_RCVD: | |
1567 case UART_CONNECTION_OPEN: | |
1568 /* | |
1569 * mark channel as closed | |
1570 */ | |
1571 dlc->connection_state = UART_CONNECTION_DEAD; | |
1572 /* | |
1573 * send UA frame | |
1574 */ | |
1575 frame->buffer[UART_OFFSET_CONTROL] = UART_UA_FRAME; | |
1576 *forward |= UART_FORWARD_DLC_RELEASE; | |
1577 break; | |
1578 | |
1579 default: | |
1580 TRACE_ERROR( "DLC CONNECTION_STATE unexpected" ); | |
1581 break; | |
1582 } | |
1583 } | |
1584 } | |
1585 else | |
1586 { | |
1587 /* | |
1588 * send DM frame | |
1589 */ | |
1590 frame->buffer[UART_OFFSET_CONTROL] = UART_DM_CONTROL_FRAME; | |
1591 } | |
1592 *forward|= UART_FORWARD_RESPONSE; | |
1593 } /* ker_receive_disc_frame */ | |
1594 | |
1595 | |
1596 | |
1597 /* | |
1598 +------------------------------------------------------------------------------ | |
1599 | Function : ker_receive_uih_control_frame | |
1600 +------------------------------------------------------------------------------ | |
1601 | Description : This function analyzes received UIH Control frames. | |
1602 | | |
1603 | Parameters : forward - result of analysis | |
1604 | frame - frame to analyze | |
1605 | | |
1606 +------------------------------------------------------------------------------ | |
1607 */ | |
1608 GLOBAL void ker_receive_uih_control_frame(ULONG* forward, T_desc2* frame) | |
1609 { | |
1610 T_DLC* dlc; | |
1611 UBYTE dlci; | |
1612 UBYTE dlc_instance; | |
1613 | |
1614 TRACE_FUNCTION( "ker_receive_uih_control_frame" ); | |
1615 | |
1616 dlci = frame->buffer[UART_OFFSET_ADDRESS] >> UART_DLCI_POS; | |
1617 dlc_instance = uart_data->dlc_instance[dlci]; | |
1618 | |
1619 /* | |
1620 * analyze message responses | |
1621 */ | |
1622 ker_analyze_frame_info_response(forward, frame); | |
1623 /* | |
1624 * check whether frame for an existing channel | |
1625 */ | |
1626 if(dlc_instance NEQ UART_EMPTY_INSTANCE) | |
1627 { | |
1628 /* | |
1629 * set DLC to this channel | |
1630 */ | |
1631 dlc = &uart_data->dlc_table[dlc_instance]; | |
1632 /* | |
1633 * check whether it is an command frame | |
1634 * discard frame if it is a response frame | |
1635 */ | |
1636 if(frame->buffer[UART_OFFSET_ADDRESS] & UART_CR) | |
1637 { | |
1638 switch(dlc->connection_state) | |
1639 { | |
1640 case UART_CONNECTION_OPEN: | |
1641 /* | |
1642 * send UIH response frame | |
1643 */ | |
1644 ker_analyze_frame_info_command(forward, frame); | |
1645 *forward|= UART_FORWARD_RESPONSE; | |
1646 break; | |
1647 | |
1648 case UART_CONNECTION_DISC_SENT: | |
1649 /* | |
1650 * send DM frame | |
1651 */ | |
1652 ker_analyze_frame_info_command(forward, frame); | |
1653 frame->buffer[UART_OFFSET_CONTROL] = UART_DM_CONTROL_FRAME; | |
1654 *forward |= UART_FORWARD_RESPONSE; | |
1655 break; | |
1656 | |
1657 case UART_CONNECTION_SABM_RCVD: | |
1658 break; | |
1659 | |
1660 default: | |
1661 TRACE_ERROR( "DLC CONNECTION_STATE unexpected" ); | |
1662 break; | |
1663 } | |
1664 } | |
1665 } | |
1666 else | |
1667 { | |
1668 /* | |
1669 * send DM frame | |
1670 */ | |
1671 ker_analyze_frame_info_command(forward, frame); | |
1672 frame->buffer[UART_OFFSET_CONTROL] = UART_DM_CONTROL_FRAME; | |
1673 *forward |= UART_FORWARD_RESPONSE; | |
1674 } | |
1675 } /* ker_receive_uih_control_frame */ | |
1676 | |
1677 | |
1678 | |
1679 /* | |
1680 +------------------------------------------------------------------------------ | |
1681 | Function : ker_receive_uih_data_frame | |
1682 +------------------------------------------------------------------------------ | |
1683 | Description : This function analyzes received UIH Data frames. | |
1684 | | |
1685 | Parameters : forward - result of analysis | |
1686 | frame - frame to analyze | |
1687 | | |
1688 +------------------------------------------------------------------------------ | |
1689 */ | |
1690 GLOBAL void ker_receive_uih_data_frame(ULONG* forward, T_desc2* frame) | |
1691 { | |
1692 UBYTE dlci; | |
1693 UBYTE dlc_instance; | |
1694 | |
1695 TRACE_FUNCTION( "ker_receive_uih_data_frame" ); | |
1696 | |
1697 dlci = frame->buffer[UART_OFFSET_ADDRESS] >> UART_DLCI_POS; | |
1698 dlc_instance = uart_data->dlc_instance[dlci]; | |
1699 | |
1700 /* | |
1701 * check whether frame for a not existing channel | |
1702 * discard packet if it is for an extisting channel | |
1703 */ | |
1704 if(dlc_instance EQ UART_EMPTY_INSTANCE) | |
1705 { | |
1706 /* | |
1707 * send DM frame | |
1708 * shorten information field | |
1709 */ | |
1710 frame->buffer[UART_OFFSET_CONTROL] = UART_DM_DATA_FRAME; | |
1711 frame->len = UART_OFFSET_INFO; | |
1712 *forward |= UART_FORWARD_RESPONSE; | |
1713 } | |
1714 } /* ker_receive_uih_data_frame */ |