comparison g23m-aci/uart/uart_kerf.c @ 0:75a11d740a02

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