comparison src/g23m-aci/uart/uart_kerf.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +0000
parents
children
comparison
equal deleted inserted replaced
0:4e78acac3d88 1:fa8dc04885d8
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 */