FreeCalypso > hg > freecalypso-citrine
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 */ |