comparison src/cs/services/atp/atp_services.c @ 0:b6a5e36de839

src/cs: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:39:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:b6a5e36de839
1 /*******************************************************************************
2 *
3 * File Name : atp_services.c
4 *
5 * Functions gathering all the functions defined in BT9901
6 *
7 * (C) Texas Instruments, all rights reserved
8 *
9 * Version number : 0.1 Date : 28-Feb-2000
10 * 0.9 Updated and reviewed : 10-May-2000
11 *
12 * History : 0.1 - Created by E. Baissus
13 *
14 *
15 * Author : Eric Baissus : e-baissus@ti.com
16 *
17 * (C) Copyright 2000 by Texas Instruments Incorporated, All Rights Reserved
18 ******************************************************************************/
19 #include "rv/rv_general.h"
20 #include "rvf/rvf_api.h"
21 #include "atp/atp_api.h"
22 #include "atp/atp_i.h"
23 #include "atp/atp_config.h"
24 #include "atp/atp_messages.h"
25 #include "atp/atp_cmd.h"
26 #include "rvm/rvm_use_id_list.h"
27
28 #include <string.h>
29
30 #define ATP_DEBUG_MSG_ENABLED
31 //#define ATP_HEX_DUMP_ENABLED
32
33 #ifdef ATP_DEBUG_MSG_ENABLED
34 #include <stdio.h>
35
36 static char gbl_debug_message[100] = "";
37 #endif
38
39 static T_ATP_RET atp_interpret_data(T_ATP_PORT_STRUCT *port_p,T_ATP_SW_NB spp_sw_nb,
40 T_ATP_SW_NB appli_sw_nb);
41
42 static void atp_mb_call_back(T_RVF_MB_ID mb);
43
44
45 #ifdef ATP_HEX_DUMP_ENABLED
46
47 /******************************************************************************
48 * Function name: atp_sprint_int_as_hex
49 *
50 * Description : Convert bytes to hexadecimal strings.
51 *
52 * Return : Length.
53 *
54 ******************************************************************************/
55 int atp_sprint_int_as_hex(char *buf, unsigned int n, int width, char padding)
56 {
57 unsigned int m = n; // MUST be unsigned because it will be right shifted
58 int size = 0;
59 int i;
60 char digit;
61 char *buf_start = buf;
62
63 // Count number of digits in <n>
64 do {
65 size++;
66 } while (m >>= 4);
67
68 // Shift significant part of <n> into the top-most bits
69 n <<= 4 * (8 - size);
70
71 // Pad output buffer with <padding>
72 if (0 < width && width <= 8) {
73 width = (width > size ? width - size : 0);
74 while (width--)
75 *buf++ = padding;
76 }
77
78 // Convert <n>, outputting the hex digits
79 for (i = 0; i < size; i++) {
80 digit = (n >> 28) & 0xF;
81 digit += (digit < 10 ? '0' : 'A' - 10);
82 *buf++ = digit;
83 n <<= 4;
84 }
85
86 // Null terminate
87 *buf = 0;
88
89 return buf - buf_start;
90 }
91
92
93 /******************************************************************************
94 * Function name: atp_hexdump_buf
95 *
96 * Description : Display buffers as hexadecimal strings.
97 *
98 * Return : None.
99 *
100 ******************************************************************************/
101 void atp_hexdump_buf(char *buf, int size)
102 {
103 int n, i, multiline;
104 char string[(8+1) + (16+1) + (3<<4) + 1];
105 char *s;
106
107 multiline = (size > 16);
108
109 while (size > 0)
110 {
111 s = string;
112 n = (size > 16 ? 16 : size);
113
114 // Print address
115 if (multiline) {
116 s += atp_sprint_int_as_hex(s, (unsigned int) buf, 8, ' ');
117 *s++ = ' ';
118 }
119
120 // Print the textual representation
121 for (i = 0; i < n; i++)
122 *s++ = (buf[i] >= ' ' && buf[i] < 127 ? buf[i] : '.');
123
124 // Pad textual representation with spaces
125 if (multiline)
126 for (i = 0; i < 16 - n; i++)
127 *s++ = ' ';
128
129 // Print hexedecimal bytes
130 for (i = 0; i < n; i++) {
131 *s++ = ' ';
132 s += atp_sprint_int_as_hex(s, (unsigned int) buf[i] & 0xFF, 2, '0');
133 }
134
135 *s = 0;
136 rvf_send_trace (string,
137 strlen (string),
138 NULL_PARAM,
139 RV_TRACE_LEVEL_DEBUG_LOW,
140 ATP_USE_ID);
141 buf += 16;
142 size -= 16;
143 }
144 }
145 #endif
146
147 /******************************************************************************
148 * Function name: atp_open_port_rqst
149 *
150 * Description : Initialise a port creation
151 *
152 * Parameters : see BT9901
153 *
154 * Return : RV_OK
155 * RV_INVALID_PARAMETER : one of the id (atrget or initiator was wrong)
156 * RV_MEMORY_ERR : not enough memory in ATP PRIM MB to create a new port
157 *
158 * History : 0.1 (1-Marsh-2000) - Created
159 * : 0.9 (5-May-2000) - Reviewed
160 ******************************************************************************/
161 T_ATP_RET atp_open_port_rqst(T_ATP_SW_ENTITY_ID initiator_id, T_ATP_SW_ENTITY_ID target_id,
162 T_ATP_PORT_NB port_nb, T_ATP_PORT_INFO port_info,
163 T_ATP_NO_COPY_INFO no_copy_info, T_ATP_CUSTOM_INFO * cust_info_p)
164 {
165 T_ATP_PORT_STRUCT *new_port_p = NULL;
166 T_ATP_OPEN_PORT_IND *open_port_event_p = NULL;
167 T_ATP_SW_ENTITY_STRUCT *initiator_p = NULL;
168 T_ATP_SW_ENTITY_STRUCT *target_p = NULL;
169
170 /* Check for invalid parameters and get the pointers on the structures that */
171 /* gather information about the initiator and target SW entities */
172 if ((initiator_id > ATP_MAX_NB_SW_ENTITY) || \
173 (target_id > ATP_MAX_NB_SW_ENTITY) || \
174 ((initiator_p = atp_sw_entity_table_p[initiator_id]) == NULL) || \
175 ((target_p = atp_sw_entity_table_p[target_id]) == NULL))
176 {
177 atp_error_switch (ATP_ERROR_FAILED_TO_OPEN_A_PORT,
178 ATP_PARAM_ERROR,
179 NULL);
180 return (RV_INVALID_PARAMETER);
181 }
182
183 /* Then, check whether ATP is started */
184 if (atp_swe_state != ATP_STARTED)
185 {
186 atp_error_switch (ATP_ERROR_FAILED_TO_OPEN_A_PORT,
187 ATP_ISSUED_IN_A_WRONG_STATE_ERROR,
188 NULL);
189 return (RV_NOT_SUPPORTED);
190 }
191
192 /* Create an instance gathering the port information and initialise it */
193 /* (refer to atp_init_port ()) */
194 if (atp_create_port (&new_port_p) != RV_OK)
195 {
196 atp_error_switch (ATP_ERROR_FAILED_TO_OPEN_A_PORT,
197 ATP_MEMORY_ERROR,
198 NULL);
199 return (RV_MEMORY_ERR);
200 }
201
202 /* Increase the number of port currently in use */
203 initiator_p->nb_open_port++;
204 target_p->nb_open_port++;
205
206 /* Update information about the initiator */
207 new_port_p->cmd_info.state = READY_FOR_NEW_CMD;
208 new_port_p->port_state = ATP_OPEN_PENDING;
209 (new_port_p->port_info[0]).sw_id = initiator_id;
210 (new_port_p->port_info[0]).port_nb = port_nb;
211 (new_port_p->port_info[0]).ring_type = port_info.ring_type;
212 (new_port_p->port_info[0]).signal_mask = (T_ATP_SIGNAL_MASK) (port_info.signal_mask & (ATP_ALL_THE_SIGNAL_UNMASK));
213
214 /* Update information about the target */
215 (new_port_p->port_info[1]).sw_id = target_id;
216
217 /* Store the requested port configuration */
218 if ((initiator_p->mode).cmd_support_mode == CMD_SUPPORT_OFF)
219 {
220
221 /* Check for invalid configuration */
222 if (port_info.port_config > NOT_DEFINED_CONFIG)
223 {
224 atp_error_switch (ATP_ERROR_FAILED_TO_OPEN_A_PORT,
225 ATP_PARAM_ERROR,
226 NULL);
227
228 /* Withdraw the instance gathering the port information */
229 atp_delete_port (new_port_p);
230
231 /* Decrease number of port currently in use */
232 initiator_p->nb_open_port--;
233 target_p->nb_open_port--;
234 return (RV_INVALID_PARAMETER);
235 }
236 new_port_p->port_config = port_info.port_config;
237 }
238
239 /* Get settings related the COPY_OFF mode */
240 if ((initiator_p->mode).cp_mode == COPY_OFF)
241 {
242
243 /* Get the number of bytes left free for the RX header and trailer */
244 if (no_copy_info.rx_head_mode == RX_HEADER_ON)
245 {
246 ((new_port_p->port_info[0]).no_copy_info).rx_head_size = no_copy_info.rx_head_size;
247 ((new_port_p->port_info[0]).no_copy_info).rx_trail_size = no_copy_info.rx_trail_size;
248 }
249
250 /* Get the number of bytes left free for the TX header and trailer */
251 if (no_copy_info.tx_head_mode == TX_HEADER_ON)
252 {
253 ((new_port_p->port_info[0]).no_copy_info).tx_head_size = no_copy_info.tx_head_size;
254 ((new_port_p->port_info[0]).no_copy_info).tx_trail_size = no_copy_info.tx_trail_size;
255 }
256
257 /* Get memory bank information */
258 (new_port_p->port_info[0]).tx_mb = no_copy_info.tx_mb;
259 (new_port_p->port_info[0]).rx_mb = no_copy_info.rx_mb;
260
261 /* Copy those information on both sides. Of course TX -> RX and RX -> TX */
262 (new_port_p->port_info[1]).tx_mb = no_copy_info.rx_mb;
263 (new_port_p->port_info[1]).rx_mb = no_copy_info.tx_mb;
264
265 /* Get the packet mode (i.e. SEGMENTED_PACKET) */
266 ((new_port_p->port_info[0]).no_copy_info).packet_mode = no_copy_info.packet_mode;
267 }
268
269 /* At last, send an ATP_OPEN_PORT_IND event to the target */
270 switch (rvf_get_buf (atp_mb_prim, \
271 sizeof (T_ATP_OPEN_PORT_IND), \
272 (T_RVF_BUFFER **) &open_port_event_p))
273 {
274 case RVF_GREEN:
275 {
276 (open_port_event_p->rv_hdr).msg_id = ATP_OPEN_PORT_IND;
277 open_port_event_p->initiator_id = initiator_id;
278 open_port_event_p->initiator_port_nb = port_nb;
279 open_port_event_p->custom_info_p = cust_info_p;
280 break;
281 }
282
283 /* Insufficient resources */
284 case RVF_YELLOW:
285 {
286 rvf_free_buf ((T_RVF_BUFFER *) open_port_event_p);
287 }
288 default:
289 {
290
291 /* Withdraw the instance gathering the port information */
292 atp_delete_port (new_port_p);
293
294 /* Decrease number of port currently in use */
295 initiator_p->nb_open_port--;
296 target_p->nb_open_port--;
297 atp_error_switch (ATP_ERROR_FAILED_TO_OPEN_A_PORT,
298 ATP_MEMORY_ERROR,
299 NULL);
300 return (RV_MEMORY_ERR);
301 }
302 }
303 return (atp_send_message (target_p->return_path, \
304 (T_ATP_MESSAGE *) open_port_event_p));
305 }
306
307
308 /******************************************************************************
309 * Function name: atp_open_port_rsp
310 *
311 * Description : Response from the target to a open port request
312 *
313 * Parameters : see BT9901
314 *
315 * Return : RV_OK
316 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
317 * RV_NOT_SUPPORTED : port already open
318 * RV_INTERNAL_ERR : Error generated because bad initialisation of MB
319 *
320 * atp_error can be called if MB is RED
321 *
322 * History : 0.1 (1-Marsh-2000) - Created
323 * : 0.9 (5-May-2000) - Reviewed
324 ******************************************************************************/
325
326 T_ATP_RET atp_open_port_rsp(T_ATP_SW_ENTITY_ID initiator_id, T_ATP_PORT_NB initiator_port_nb,
327 T_ATP_SW_ENTITY_ID target_id, T_ATP_PORT_NB target_port_nb,
328 T_ATP_PORT_INFO port_info, T_ATP_NO_COPY_INFO no_copy_info,
329 T_ATP_CUSTOM_INFO * custom_info_p, T_ATP_OPEN_PORT_RESULT result)
330
331 {
332 T_ATP_SW_NB sw_nb = 0;
333 T_ATP_PORT_STRUCT *port_p = NULL;
334 T_ATP_OPEN_PORT_CFM *open_port_cfm_event_p = NULL;
335 T_ATP_SW_ENTITY_STRUCT *initiator_p = NULL;
336 T_ATP_SW_ENTITY_STRUCT *target_p = NULL;
337
338 /* Check for invalid parameters, get the pointers on the structures that */
339 /* gather information about the initiator and remote SW entities and get */
340 /* the port associated with initiator SW entity */
341 if ((initiator_id > ATP_MAX_NB_SW_ENTITY) || \
342 (target_id > ATP_MAX_NB_SW_ENTITY) || \
343 ((initiator_p = atp_sw_entity_table_p[initiator_id]) == NULL) || \
344 ((target_p = atp_sw_entity_table_p[target_id]) == NULL) || \
345 (atp_get_port (initiator_id, \
346 initiator_port_nb, \
347 &port_p, \
348 &sw_nb) != RV_OK))
349 {
350 atp_error_switch (ATP_ERROR_FAILED_TO_ACCEPT_A_PORT,
351 ATP_PARAM_ERROR,
352 NULL);
353 return (RV_INVALID_PARAMETER);
354 }
355
356 /* Check whether the port is waiting for an ATP_OPEN_PORT_CFM event */
357 if (port_p->port_state != ATP_OPEN_PENDING)
358 {
359 atp_error_switch (ATP_ERROR_FAILED_TO_ACCEPT_A_PORT,
360 ATP_ISSUED_IN_A_WRONG_STATE_ERROR,
361 NULL);
362 return (RV_NOT_SUPPORTED);
363 }
364
365 /* Fill in the ATP_OPEN_PORT_CFM event to be sent back to the initiator */
366 if (rvf_get_buf (atp_mb_prim, \
367 sizeof (T_ATP_OPEN_PORT_CFM), \
368 (T_RVF_BUFFER **) &open_port_cfm_event_p) == RVF_RED)
369 {
370
371 /* Withdraw the instance gathering the port information */
372 atp_delete_port (port_p);
373 atp_error (ATP_ERROR_MB_PRIM_RED);
374 return (RV_MEMORY_ERR);
375 }
376 (open_port_cfm_event_p->rv_hdr).msg_id = ATP_OPEN_PORT_CFM;
377 open_port_cfm_event_p->initiator_port_nb = initiator_port_nb;
378 open_port_cfm_event_p->custom_info_p = custom_info_p;
379
380 /* Send a negative ATP_OPEN_PORT_CFM event right now whether the target */
381 /* denies opening the port */
382 if ((open_port_cfm_event_p->result = result) != OPEN_PORT_OK)
383 {
384
385 /* Withdraw the instance gathering the port information */
386 atp_delete_port (port_p);
387
388 /* Decrease number of port currently in use */
389 initiator_p->nb_open_port--;
390 target_p->nb_open_port--;
391
392 /* Send a negative ATP_OPEN_PORT_CFM event to the initiator */
393 atp_send_message (initiator_p->return_path,
394 (T_ATP_MESSAGE *) open_port_cfm_event_p);
395 return (RV_OK);
396 }
397
398 /* By default, set the port in 'Command Mode'. Hence, the port is ready */
399 /* to exchange AT commands */
400 port_p->port_state = ATP_CMD_MODE;
401
402 /* Update information about the target */
403 (port_p->port_info[1]).port_nb = target_port_nb;
404 (port_p->port_info[1]).ring_type = port_info.ring_type;
405 (port_p->port_info[1]).signal_mask = (T_ATP_SIGNAL_MASK) (port_info.signal_mask & ATP_ALL_THE_SIGNAL_UNMASK);
406
407 /* One of the SW entity is a transport layer that does not handle AT commands */
408 if ((port_p->port_config == NOT_DEFINED_CONFIG) && \
409 ((target_p->mode).cmd_support_mode == CMD_SUPPORT_OFF))
410 {
411
412 /* Check for an invalid configuration */
413 if (port_info.port_config > NOT_DEFINED_CONFIG)
414 {
415 atp_error_switch (ATP_ERROR_FAILED_TO_OPEN_A_PORT,
416 ATP_PARAM_ERROR,
417 NULL);
418
419 /* Clean up */
420 rvf_free_buf ((T_RVF_BUFFER *) open_port_cfm_event_p);
421 return (RV_INVALID_PARAMETER);
422 }
423
424 /* Update the port configuration */
425 port_p->port_config = port_info.port_config;
426 }
427
428 /* Get settings related the COPY_OFF mode */
429 if ((target_p->mode).cp_mode == COPY_OFF)
430 {
431
432 /* Get the number of bytes left free for the RX header and trailer */
433 if (no_copy_info.rx_head_mode == RX_HEADER_ON)
434 {
435 ((port_p->port_info[1]).no_copy_info).rx_head_size = no_copy_info.rx_head_size;
436 ((port_p->port_info[1]).no_copy_info).rx_trail_size = no_copy_info.rx_trail_size;
437 }
438
439 /* Get the number of bytes left free for the TX header and trailer */
440 if (no_copy_info.tx_head_mode == TX_HEADER_ON)
441 {
442 ((port_p->port_info[1]).no_copy_info).tx_head_size = no_copy_info.tx_head_size;
443 ((port_p->port_info[1]).no_copy_info).tx_trail_size = no_copy_info.tx_trail_size;
444 }
445
446 /* Get memory bank information */
447 if (no_copy_info.rx_mb != RVF_INVALID_MB_ID)
448 {
449 (port_p->port_info[1]).rx_mb = no_copy_info.rx_mb;
450 }
451 if (no_copy_info.tx_mb != RVF_INVALID_MB_ID)
452 {
453 (port_p->port_info[1]).tx_mb = no_copy_info.tx_mb;
454 }
455
456 /* Get the packet mode (i.e. SEGMENTED_PACKET) */
457 ((port_p->port_info[1]).no_copy_info).packet_mode = no_copy_info.packet_mode;
458 }
459
460 /* If only one of the SW entities has provided valid memory banks, */
461 /* copy those information on both sides. Of course TX -> RX and RX -> TX */
462 if ((port_p->port_info[0]).rx_mb == RVF_INVALID_MB_ID)
463 {
464 (port_p->port_info[0]).rx_mb = (port_p->port_info[1]).tx_mb;
465 }
466 if ((port_p->port_info[0]).tx_mb == RVF_INVALID_MB_ID)
467 {
468 (port_p->port_info[0]).tx_mb = (port_p->port_info[1]).rx_mb;
469 }
470
471 #ifdef ATP_DEBUG_MSG_ENABLED
472 (void) sprintf (gbl_debug_message,
473 "ATP: Init (RX: 0x%.4X TX: 0x%.4X), Target (RX: 0x%.4X TX: 0x%.4X) ",
474 port_p->port_info[0].rx_mb,
475 port_p->port_info[0].tx_mb,
476 port_p->port_info[1].rx_mb,
477 port_p->port_info[1].tx_mb);
478 rvf_send_trace (gbl_debug_message,
479 (UINT8) strlen (gbl_debug_message),
480 NULL_PARAM,
481 RV_TRACE_LEVEL_DEBUG_MEDIUM,
482 ATP_USE_ID);
483 #endif
484
485 /* At the end, no memory banks should be invalid */
486 if ((port_p->port_info[0].tx_mb == RVF_INVALID_MB_ID) || \
487 (port_p->port_info[0].rx_mb == RVF_INVALID_MB_ID) || \
488 (port_p->port_info[1].tx_mb == RVF_INVALID_MB_ID) || \
489 (port_p->port_info[1].rx_mb == RVF_INVALID_MB_ID))
490 {
491 ATP_SEND_TRACE ("ATP: Some memory banks not specified ",
492 RV_TRACE_LEVEL_ERROR);
493 atp_error_switch (ATP_ERROR_FAILED_TO_ACCEPT_A_PORT,
494 ATP_PARAM_ERROR,
495 NULL);
496
497 /* Clean up */
498 rvf_free_buf ((T_RVF_BUFFER *) open_port_cfm_event_p);
499 return (RV_INTERNAL_ERR);
500 }
501
502 /* If needed, allocate a buffer for DCE or DTE information */
503 if (((initiator_p->mode).cmd_support_mode == CMD_SUPPORT_OFF) || \
504 ((target_p->mode).cmd_support_mode == CMD_SUPPORT_OFF))
505 {
506 switch (port_p->port_config)
507 {
508 case DCE_CONFIG:
509 case DTE_CONFIG:
510 {
511 T_ATP_DCE_INFO *dce_info_p = NULL;
512
513 ATP_SEND_TRACE ("ATP: A port has been open with DCE/DTE mode activated",
514 RV_TRACE_LEVEL_DEBUG_LOW);
515
516 /* Allocate a buffer for DCE or DTE information */
517 if (rvf_get_buf (atp_mb_prim, \
518 sizeof (T_ATP_DCE_INFO), \
519 (T_RVF_BUFFER **) &dce_info_p) == RVF_RED)
520 {
521 atp_error_switch (ATP_ERROR_FAILED_TO_ACCEPT_A_PORT,
522 ATP_MEMORY_ERROR,
523 NULL);
524
525 /* Clean up */
526 rvf_free_buf ((T_RVF_BUFFER *) open_port_cfm_event_p);
527 return (RV_MEMORY_ERR);
528 }
529
530 /* Initialize DCE or DTE information */
531 atp_cmd_init_dce_info (dce_info_p);
532 port_p->dce_info_p = dce_info_p;
533 break;
534 }
535 case DATA_CONFIG:
536 {
537
538 /* The port is plugged on a transport layer */
539 port_p->port_state = ATP_DATA_MODE;
540 break;
541 }
542 default:
543 {
544 ATP_SEND_TRACE ("ATP: Failed to open a port (port configuration not specified)",
545 RV_TRACE_LEVEL_ERROR);
546 atp_error_switch (ATP_ERROR_FAILED_TO_ACCEPT_A_PORT,
547 ATP_PARAM_ERROR,
548 NULL);
549
550 /* Clean up */
551 rvf_free_buf ((T_RVF_BUFFER *) open_port_cfm_event_p);
552 return (RV_INTERNAL_ERR);
553 }
554 }
555 }
556
557 /* At last, send an ATP_OPEN_PORT_CFM event to the initiator */
558 return (atp_send_message (initiator_p->return_path, \
559 (T_ATP_MESSAGE *) open_port_cfm_event_p));
560 }
561
562
563
564
565 /******************************************************************************
566 * Function name: atp_close_port
567 *
568 * Description : Close a port
569 *
570 * Parameters : see BT9901
571 *
572 * Return : RV_OK
573 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
574 *
575 * atp_error can be called if MB is RED
576 *
577 * History : 0.1 (1-Marsh-2000) - Created
578 * : 0.9 (5-May-2000) - Reviewed
579 ******************************************************************************/
580 T_ATP_RET atp_close_port(T_ATP_SW_ENTITY_ID closer_sw_id, T_ATP_PORT_NB closer_port_nb)
581 {
582 T_ATP_SW_ENTITY_STRUCT * closer_sw_id_p, * other_sw_id_p;
583 T_ATP_PORT_STRUCT * port_p;
584 T_ATP_SW_NB closer_sw_nb,other_sw_nb;
585 T_ATP_PORT_CLOSED * port_closed_event_p;
586
587 /* Get the pointer on the port structure */
588 if(atp_get_port(closer_sw_id,closer_port_nb,&port_p,&closer_sw_nb) != RV_OK)
589 {
590 atp_error_switch(ATP_ERROR_FAILED_TO_CLOSE_A_PORT,ATP_PARAM_ERROR,NULL);
591 return RV_INVALID_PARAMETER; /* This port does not exist */
592 }
593
594 other_sw_nb= (T_ATP_SW_NB) (! closer_sw_nb);
595
596
597
598 /* Send an event to the other sw entity indicating the port has been closed */
599 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_PORT_CLOSED),(void **) &port_closed_event_p)==RVF_RED)
600 {
601 atp_error_switch(ATP_ERROR_FAILED_TO_CLOSE_A_PORT,ATP_MEMORY_ERROR,NULL);
602 return RV_MEMORY_ERR;
603 }
604
605 port_closed_event_p->rv_hdr.msg_id = ATP_PORT_CLOSED;
606 port_closed_event_p->port_nb = port_p->port_info[other_sw_nb].port_nb;
607 port_closed_event_p->closer_port_nb = closer_port_nb;
608 port_closed_event_p->closer_sw_id = closer_sw_id;
609
610 /* Get pointer on the other sw entity data structure */
611 other_sw_id_p=atp_sw_entity_table_p[port_p->port_info[other_sw_nb].sw_id];
612 closer_sw_id_p = atp_sw_entity_table_p[closer_sw_id];
613
614 /* Send the event and update open port nb */
615
616 atp_send_message(other_sw_id_p->return_path,(T_ATP_MESSAGE *) port_closed_event_p);
617
618 /* Decrease number of port for each SW entity */
619 other_sw_id_p->nb_open_port--;
620 closer_sw_id_p->nb_open_port--;
621
622 atp_delete_port(port_p);
623
624
625 return RV_OK;
626 }
627
628
629
630
631
632 /******************************************************************************
633 * Function name: atp_send_cmd
634 *
635 * Description : Send a command
636 *
637 * Parameters : see BT9901
638 *
639 * Return : RV_OK
640 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
641 * RV_NOT_SUPPORTED : command needed to be translated and was unknow by ATP
642 *
643 * atp_error can be called if MB is RED
644 *
645 * History : 0.1 (1-Marsh-2000) - Created
646 * : 0.9 (5-May-2000) - Reviewed
647 *
648 * Note : Sender SW Entity cannot in DCE_ON
649 *
650 ******************************************************************************/
651 T_ATP_RET atp_send_cmd(T_ATP_SW_ENTITY_ID sender_sw_id, T_ATP_PORT_NB sender_port_nb,
652 T_ATP_CMD_TYPE cmd_type,T_ATP_CMD_NB cmd_nb, T_ATP_CMD * cmd_info_p)
653 {
654 T_ATP_PORT_STRUCT * port_p;
655 T_ATP_SW_NB sender_sw_nb, other_sw_nb;
656 T_ATP_CMD_RDY * cmd_ready_event_p;
657 T_ATP_TXT_CMD_RDY * txt_cmd_ready_event_p;
658 T_ATP_SW_ENTITY_STRUCT * other_sw_entity_p;
659 T_ATP_TXT_CMD text_p;
660 UINT16 length;
661 T_ATP_BUFFER atp_buffer_p;
662 T_ATP_NO_COPY_DATA_RDY * no_copy_data_ready_p;
663 T_ATP_RET return_status;
664
665 /* Get the pointer on the port structure */
666 if(atp_get_port(sender_sw_id,sender_port_nb,&port_p,&sender_sw_nb) != RV_OK)
667 {
668 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_PARAM_ERROR,NULL);
669 return RV_INVALID_PARAMETER; /* This port does not exist */
670 }
671 other_sw_nb=(T_ATP_SW_NB) (! sender_sw_nb);
672
673 if (port_p->port_state == ATP_OPEN_PENDING)
674 {
675 /* Port is not completely open */
676 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
677 return RV_NOT_SUPPORTED;
678 }
679
680 /* get pointer on the other SW entity data structure in order to get info */
681 other_sw_entity_p=atp_sw_entity_table_p[port_p->port_info[other_sw_nb].sw_id];
682
683 /* Check if the port is available */
684 if ( (port_p->cmd_info.state != READY_FOR_NEW_CMD) &&
685 (cmd_type == AT_CMD))
686 { // A new command cannot been sent if a result code has not been previously received */
687 rvf_send_trace("ATP : Refused to send a new command on a port which was waiting for a result ",77,
688 NULL_PARAM,RV_TRACE_LEVEL_WARNING, ATP_USE_ID);
689 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_WAITING_FOR_RESULT,NULL);
690 return RV_NOT_SUPPORTED;
691 }
692
693 if (cmd_type == AT_CMD)
694 {
695 port_p->cmd_info.state = WAITING_FOR_RESULT; // Prevent any new command entry
696 }
697
698
699
700 if (other_sw_entity_p->mode.cmd_support_mode == CMD_SUPPORT_OFF)
701 {
702 /* Other SW entity does not support to get command directly */
703 if ( (port_p->port_config == DATA_CONFIG) ||
704 (port_p->port_state == ATP_DATA_MODE) )
705 {
706 ATP_SEND_TRACE ("ATP: A command cannot be sent on a DATA_ONLY configuration port",RV_TRACE_LEVEL_WARNING);
707 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_WAITING_FOR_RESULT,NULL);
708 return RV_NOT_SUPPORTED;
709 }
710
711 /* DCE or DTE emulation is ON */
712 /* Must translate the command and put it into a buffer of data */
713
714 /* Check if the answer is a result code from a ON_GOING interpretation of a raw data buffer
715 containing several commands */
716 if ((cmd_type == RESULT_CODE) && (port_p->cmd_info.status == ON_GOING) && (cmd_nb == ATP_OK_NB))
717 {
718 // Then interpret data. Either sends result to peer device or resend a command to appli
719 // START SEMAPHORE
720 port_p->cmd_info.state=READY_FOR_NEW_CMD;
721 return_status=atp_interpret_data(port_p,other_sw_nb,sender_sw_nb);
722 // STOP SEMAPHORE
723 // other = transport layer , sender = appli
724
725 if (return_status == RV_MEMORY_ERR)
726 {
727 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_MEMORY_ERROR,NULL);
728 return RV_MEMORY_ERR;
729 }
730
731 return RV_OK;
732 }
733
734 /* Otherwise can be : result code was not OK -> so re-init cmd_info and send the result code to peer
735 normal command to send
736 final result to send -> so re-init cmd_info and send the result code to peer
737
738 /* Obtain buffer with command translated into data buffer ready for TX*/
739 if(atp_create_data_buffer_from_cmd(INTERPRETED_MODE,
740 port_p->port_info[other_sw_nb].no_copy_info.rx_head_size,
741 port_p->port_info[other_sw_nb].no_copy_info.rx_trail_size,
742 (T_ATP_DCE_INFO *) port_p->dce_info_p,
743 port_p->port_info[other_sw_nb].rx_mb,
744 cmd_type,
745 cmd_nb,NULL,cmd_info_p,
746 &atp_buffer_p,&length)!=RV_OK)
747 {
748 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_CANNOT_TRANSLATE_CMD,NULL);
749 return RV_NOT_SUPPORTED;
750 }
751
752 /* Send it to the other SW entity via an ATP_NO_COPY_DATA_RDY */
753 /* Note: it is assumed that only COPY OFF instance can be DCE ON */
754 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_NO_COPY_DATA_RDY),(void **) &no_copy_data_ready_p)==RVF_RED)
755 {
756 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_MEMORY_ERROR,NULL);
757 return RV_MEMORY_ERR;
758 }
759
760 no_copy_data_ready_p->rv_hdr.msg_id = ATP_NO_COPY_DATA_RDY;
761 no_copy_data_ready_p->port_nb = port_p->port_info[other_sw_nb].port_nb;
762 no_copy_data_ready_p->buffer_size = length-port_p->port_info[other_sw_nb].no_copy_info.rx_head_size
763 -port_p->port_info[other_sw_nb].no_copy_info.rx_trail_size;
764 no_copy_data_ready_p->atp_buffer_p = atp_buffer_p;
765
766 /* Re-accept to deal with any new command */
767 if (cmd_type == RESULT_CODE)
768 {
769 atp_init_cmd_info_struct(port_p); /* Re-initilalise all the cmd_info structure */
770 }
771 else
772 {
773 if(cmd_type == AT_CMD)
774 {
775 port_p->cmd_info.state=WAITING_FOR_RESULT;
776 }
777 }
778 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) no_copy_data_ready_p);
779
780 return RV_OK;
781
782 } /* End of the DCE case */
783
784
785
786
787
788 if(other_sw_entity_p->mode.cmd_mode==TXT_MODE)
789 {
790 /* Other SW entity wants command in text format */
791 if (atp_translate_cmd_to_txt(cmd_type,cmd_nb,cmd_info_p,
792 port_p->port_info[other_sw_nb].rx_mb,&text_p,&length)==RV_OK)
793 {
794 /* The command has been properly translated */
795 /* Send an event to the other sw entity with the text buffer*/
796 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_TXT_CMD_RDY),(void **) &txt_cmd_ready_event_p)==RVF_RED)
797 {
798 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_MEMORY_ERROR,NULL);
799 return RV_MEMORY_ERR;
800 }
801
802 txt_cmd_ready_event_p->rv_hdr.msg_id = ATP_TXT_CMD_RDY;
803 txt_cmd_ready_event_p->cmd_type = cmd_type;
804 txt_cmd_ready_event_p->txt_cmd_p = text_p;
805 txt_cmd_ready_event_p->port_nb = port_p->port_info[other_sw_nb].port_nb;
806
807 /* Re-accept to deal with any new command */
808 if (cmd_type == RESULT_CODE) { port_p->cmd_info.state=READY_FOR_NEW_CMD;}
809
810 /* Send the event */
811 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) txt_cmd_ready_event_p);
812 return RV_OK;
813 }
814
815 /* This command cannot be translated into text */
816 /* Send a command event without text translation */
817 rvf_send_trace("ATP : CMD coult not be translated into text format ",51,NULL_PARAM,
818 RV_TRACE_LEVEL_WARNING, ATP_USE_ID);
819 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_CANNOT_TRANSLATE_CMD,NULL);
820 return RV_NOT_SUPPORTED;
821
822 }
823
824 /* Otherwise, means that target SWE is also in CMD format */
825 /* Other SW entity will have command in same format (command format) */
826 /* Send an event to the other sw entity forwarding the command */
827 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_CMD_RDY),(void **) &cmd_ready_event_p)==RVF_RED)
828 {
829 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_MEMORY_ERROR,NULL);
830 return RV_MEMORY_ERR;
831 }
832
833 cmd_ready_event_p->rv_hdr.msg_id = ATP_CMD_RDY;
834 cmd_ready_event_p->cmd_type = cmd_type;
835 cmd_ready_event_p->cmd_nb = cmd_nb;
836 cmd_ready_event_p->cmd_info_p = cmd_info_p;
837 cmd_ready_event_p->port_nb = port_p->port_info[other_sw_nb].port_nb;
838
839 /* Re-accept to deal with any new command */
840 if (cmd_type == RESULT_CODE) { port_p->cmd_info.state=READY_FOR_NEW_CMD;}
841
842 /* Send the event */
843 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) cmd_ready_event_p);
844 return RV_OK;
845 }
846
847
848
849
850
851
852
853
854 /******************************************************************************
855 * Function name: atp_send_txt_cmd
856 *
857 * Description : Send a command in text format
858 *
859 * Parameters : see BT9901
860 *
861 * Return : RV_OK
862 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
863 *
864 * atp_error can be called if MB is RED
865 * If the cmd needed to be translated and was unknown by ATP, the cmd is sent
866 * in text format
867 *
868 * History : 0.1 (1-Marsh-2000) - Created
869 * : 0.9 (5-May-2000) - Reviewed
870 ******************************************************************************/
871 T_ATP_RET atp_send_txt_cmd(T_ATP_SW_ENTITY_ID sender_sw_id, T_ATP_PORT_NB sender_port_nb,
872 T_ATP_CMD_TYPE cmd_type, T_ATP_TXT_CMD txt_p)
873 {
874 T_ATP_PORT_STRUCT * port_p;
875 T_ATP_SW_NB sender_sw_nb, other_sw_nb;
876 T_ATP_CMD_RDY * cmd_ready_event_p;
877 T_ATP_TXT_CMD_RDY * txt_cmd_ready_event_p;
878 T_ATP_SW_ENTITY_STRUCT * other_sw_entity_p;
879 T_ATP_NO_COPY_DATA_RDY * no_copy_data_ready_p;
880 T_ATP_CMD * cmd_info_p;
881 T_ATP_CMD_TYPE found_cmd_type;
882 T_ATP_CMD_NB found_cmd_nb;
883 T_ATP_BUFFER atp_buffer_p;
884 T_ATP_RET return_status;
885
886 UINT16 length;
887 void * dummy_p = NULL;
888
889
890 /* Get the pointer on the port structure */
891 if(atp_get_port(sender_sw_id,sender_port_nb,&port_p,&sender_sw_nb) != RV_OK)
892 {
893 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_PARAM_ERROR,NULL);
894 return RV_INVALID_PARAMETER; /* This port does not exist */
895 }
896 other_sw_nb=(T_ATP_SW_NB) (! sender_sw_nb);
897
898 /* get pointer on the other SW entity data structure in order to get info */
899 other_sw_entity_p=atp_sw_entity_table_p[port_p->port_info[other_sw_nb].sw_id];
900
901 if (port_p->port_state == ATP_OPEN_PENDING)
902 {
903 /* Port is not completely open */
904 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
905 return RV_NOT_SUPPORTED;
906 }
907
908 if ( (other_sw_entity_p->mode.cmd_support_mode==CMD_SUPPORT_OFF) &&
909 (port_p->port_state != ATP_CMD_MODE))
910 {
911 ATP_SEND_TRACE ("ATP : Refused to send a command to a SWE in data mode ",
912 RV_TRACE_LEVEL_WARNING);
913 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_WAITING_FOR_RESULT,NULL);
914 return RV_NOT_SUPPORTED;
915 }
916
917
918 /* Check if the port is available */
919 if ( (port_p->cmd_info.state != READY_FOR_NEW_CMD) &&
920 (cmd_type == AT_CMD))
921 { // A new command cannot been sent if a result code has not been previously received */
922 rvf_send_trace("ATP : Refused to send a new command on a port which was waiting for a result ",77,
923 NULL_PARAM,RV_TRACE_LEVEL_WARNING, ATP_USE_ID);
924 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_WAITING_FOR_RESULT,NULL);
925 return RV_NOT_SUPPORTED;
926 }
927
928 if (cmd_type == AT_CMD)
929 {
930 port_p->cmd_info.state = WAITING_FOR_RESULT; // Prevent any new command entry
931 }
932
933
934
935
936 if (other_sw_entity_p->mode.cmd_support_mode==CMD_SUPPORT_OFF)
937 {
938 /* Other SW entity does not support to get command directly */
939 if (port_p->port_config == DATA_CONFIG)
940 {
941 ATP_SEND_TRACE ("ATP: A command cannot be sent on a DATA_ONLY configuration port",RV_TRACE_LEVEL_WARNING);
942 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_WAITING_FOR_RESULT,NULL);
943 return RV_NOT_SUPPORTED;
944 }
945
946 /* DCE or DTE emulation is ON */
947 /* Must translate the command and put it into a buffer of data */
948 found_cmd_type = cmd_type;
949 found_cmd_nb = 0xFF;
950
951 if ((found_cmd_type == UNKNOWN) || (found_cmd_type == RESULT_CODE))
952 {
953 // Check if the answer is a RESULT_CODE with OK or ERROR
954 atp_translate_txt_to_cmd(txt_p,cmd_type,&found_cmd_type,&found_cmd_nb,
955 port_p->port_info[other_sw_nb].rx_mb,
956 (T_ATP_CMD **) &dummy_p); // => found_cmd_type and found_cmd_nb may be updated now
957 }
958
959 /* Check if the answer is a result code from a ON_GOING interpretation of a raw data buffer
960 containing several commands */
961 if ((found_cmd_type == RESULT_CODE) && (port_p->cmd_info.status == ON_GOING) && (found_cmd_nb == ATP_OK_NB))
962 {
963 rvf_free_buf(txt_p);
964 // Then interpret data. Either sends result to peer device or resend a command to appli
965 // START SEMAPHORE
966 port_p->cmd_info.state=READY_FOR_NEW_CMD;
967 return_status=atp_interpret_data(port_p,other_sw_nb,sender_sw_nb);
968 // STOP SEMAPHORE
969 // other = transport layer , sender = appli
970
971 if (return_status == RV_MEMORY_ERR)
972 {
973 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_MEMORY_ERROR,NULL);
974 return RV_MEMORY_ERR;
975 }
976
977 return RV_OK;
978 }
979
980
981 /* Otherwise can be : result code was not OK -> so re-init cmd_info and send the result code to peer
982 normal command to send
983 final result to send -> so re-init cmd_info and send the result code to peer */
984
985
986 /* Obtain buffer with command translated into data buffer ready for TX*/
987 if(atp_create_data_buffer_from_cmd(TXT_MODE,
988 port_p->port_info[other_sw_nb].no_copy_info.rx_head_size,
989 port_p->port_info[other_sw_nb].no_copy_info.rx_trail_size,
990 port_p->dce_info_p,
991 port_p->port_info[other_sw_nb].rx_mb,
992 found_cmd_type,0,txt_p,NULL,
993 &atp_buffer_p,&length)!=RV_OK)
994 {
995 rvf_free_buf(txt_p);
996 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_CANNOT_TRANSLATE_CMD,NULL);
997 return RV_NOT_SUPPORTED;
998 }
999
1000 /* Send it to the other SW entity via an ATP_NO_COPY_DATA_RDY */
1001 /* Note: it is assumed that only COPY OFF instance can be DCE ON */
1002 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_NO_COPY_DATA_RDY),(void **) &no_copy_data_ready_p)==RVF_RED)
1003 {
1004 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_MEMORY_ERROR,NULL);
1005 return RV_MEMORY_ERR;
1006 }
1007
1008 no_copy_data_ready_p->rv_hdr.msg_id = ATP_NO_COPY_DATA_RDY;
1009 no_copy_data_ready_p->port_nb = port_p->port_info[other_sw_nb].port_nb;
1010 no_copy_data_ready_p->buffer_size = length-port_p->port_info[other_sw_nb].no_copy_info.rx_head_size
1011 -port_p->port_info[other_sw_nb].no_copy_info.rx_trail_size;
1012 no_copy_data_ready_p->atp_buffer_p = atp_buffer_p;
1013
1014
1015 /* Re-accept to deal with any new command */
1016 if (found_cmd_type == RESULT_CODE)
1017 {
1018 atp_init_cmd_info_struct(port_p); /* Re-initilalise all the cmd_info structure */
1019 }
1020 else
1021 {
1022 if(found_cmd_type == AT_CMD)
1023 {
1024 port_p->cmd_info.state=WAITING_FOR_RESULT;
1025 }
1026 } atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) no_copy_data_ready_p);
1027
1028 return RV_OK;
1029 }
1030
1031
1032 if(other_sw_entity_p->mode.cmd_mode==INTERPRETED_MODE)
1033 {
1034 /* Other SW entity will have command in interpreted format */
1035 if (atp_translate_txt_to_cmd((T_ATP_TXT_CMD) txt_p,cmd_type,&found_cmd_type,
1036 &found_cmd_nb,port_p->port_info[other_sw_nb].rx_mb,
1037 &cmd_info_p)==RV_OK)
1038 {
1039 /* The command has been properly translated into command format*/
1040 /* Release text buffer */
1041 rvf_free_buf(txt_p);
1042
1043 /* Send an event to the other sw entity with the command buffer*/
1044 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_CMD_RDY),(void **) &cmd_ready_event_p)==RVF_RED)
1045 {
1046 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_MEMORY_ERROR,NULL);
1047 return RV_MEMORY_ERR;
1048 }
1049
1050 cmd_ready_event_p->rv_hdr.msg_id=ATP_CMD_RDY;
1051 cmd_ready_event_p->cmd_type=found_cmd_type;
1052 cmd_ready_event_p->cmd_nb=found_cmd_nb;
1053 cmd_ready_event_p->cmd_info_p=cmd_info_p;
1054 cmd_ready_event_p->port_nb=port_p->port_info[other_sw_nb].port_nb;
1055
1056 /* Re-accept to deal with any new command */
1057 if (found_cmd_type == RESULT_CODE) { port_p->cmd_info.state=READY_FOR_NEW_CMD;}
1058
1059 /* Send the event */
1060 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) cmd_ready_event_p);
1061 return RV_OK;
1062 }
1063 /* Otherwise, the text has not been translated properly
1064 Forward to the SW entity in text format */
1065 }
1066
1067
1068
1069 /* Send Command in text format */
1070 /* Send an event to the other sw entity with the text buffer*/
1071 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_TXT_CMD_RDY),(void **) &txt_cmd_ready_event_p)==RVF_RED)
1072 {
1073 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_MEMORY_ERROR,NULL);
1074 return RV_MEMORY_ERR;
1075 }
1076
1077 txt_cmd_ready_event_p->rv_hdr.msg_id=ATP_TXT_CMD_RDY;
1078 txt_cmd_ready_event_p->cmd_type=cmd_type;
1079 txt_cmd_ready_event_p->txt_cmd_p=txt_p;
1080 txt_cmd_ready_event_p->port_nb=port_p->port_info[other_sw_nb].port_nb;
1081
1082 /* Re-accept to deal with any new command */
1083 if ( (cmd_type == RESULT_CODE) ||
1084 (cmd_type == UNKNOWN)) // This case is to deal with the case of TXT SWE 1 sending a result code with cmd_type = UNKNOW
1085 // to another TXT SWE
1086 { port_p->cmd_info.state=READY_FOR_NEW_CMD;}
1087
1088 /* Send the event */
1089 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) txt_cmd_ready_event_p);
1090
1091 return RV_OK;
1092 }
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102 /******************************************************************************
1103 * Function name: atp_send_data
1104 *
1105 * Description : Send data on a port
1106 *
1107 * Parameters : see BT9901
1108 *
1109 * Return : RV_OK
1110 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
1111 *
1112 * atperror can be called if MB is RED
1113 *
1114 * History : 0.1 (1-Marsh-2000) - Created
1115 * : 0.9 (5-May-2000) - Reviewed
1116 ******************************************************************************/
1117 T_ATP_RET atp_send_data(T_ATP_SW_ENTITY_ID sender_sw_id, T_ATP_PORT_NB sender_port_nb,
1118 void * data_buffer_p, UINT32 buffer_size, UINT32 *nb_bytes_left_p)
1119 {
1120 T_ATP_PORT_STRUCT * port_p;
1121 T_ATP_SW_NB sender_sw_nb;
1122 T_ATP_SW_ENTITY_STRUCT * other_sw_entity_p;
1123 UINT32 real_buffer_size;
1124 T_ATP_NO_COPY_DATA_RDY *no_copy_data_ready_p;
1125 T_ATP_DATA_RDY *data_ready_p;
1126 T_ATP_RX_PACKET *rx_packet_p;
1127 UINT32 i,offset;
1128 T_ATP_BUFFER rvf_buffer_p;
1129 T_ATP_PORT_END_STRUCT * other_port_info_p;
1130
1131 #ifdef ATP_DEBUG_MSG_ENABLED
1132 (void) sprintf (gbl_debug_message,
1133 "ATP: send_data invoked (Size: %d, Port: %d) ",
1134 buffer_size,
1135 sender_port_nb);
1136 rvf_send_trace (gbl_debug_message,
1137 (UINT8) strlen (gbl_debug_message),
1138 NULL_PARAM,
1139 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1140 ATP_USE_ID);
1141 #endif
1142
1143 #ifdef ATP_HEX_DUMP_ENABLED
1144 atp_hexdump_buf (data_buffer_p,
1145 buffer_size);
1146 #endif
1147
1148 /* Bytes left to be sent: sender should wait and retransmit later on if needed */
1149 *nb_bytes_left_p=buffer_size;
1150
1151 /* Get the pointer on the port structure */
1152 if(atp_get_port(sender_sw_id,sender_port_nb,&port_p,&sender_sw_nb) != RV_OK)
1153 {
1154 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_PARAM_ERROR,NULL);
1155 return RV_INVALID_PARAMETER; /* This port does not exist */
1156 }
1157
1158 if (port_p->port_state == ATP_OPEN_PENDING)
1159 {
1160 /* Port is not completely open */
1161 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
1162 return RV_NOT_SUPPORTED;
1163 }
1164
1165 /* Get other port */
1166 if ((port_p->redirect_mode==ATP_REDIRECT_ON) &&
1167 (port_p->port_state==ATP_DATA_MODE)) /* redirection is activated */
1168 {
1169 other_port_info_p= & (port_p->redirect_port_p->port_info[port_p->redirect_port_end_nb]);
1170 }
1171 else
1172 {
1173 other_port_info_p= & (port_p->port_info[(! sender_sw_nb)]);
1174 }
1175
1176
1177 /* get pointer on the other SW entity data structure in order to get info */
1178 other_sw_entity_p=atp_sw_entity_table_p[(* other_port_info_p).sw_id];
1179
1180
1181 /* Get a buffer to send or store the data */
1182 /* real_buffer_size is the size of the buffer to transmit */
1183 if(other_sw_entity_p->mode.cp_mode==COPY_OFF)
1184 { /* In this case, need to eventually add header and trailer sizes*/
1185 real_buffer_size=buffer_size+other_port_info_p->no_copy_info.rx_head_size
1186 + other_port_info_p->no_copy_info.rx_trail_size;
1187 }
1188 else
1189 {
1190 real_buffer_size=buffer_size;
1191 }
1192
1193 if (rvf_get_buf(other_port_info_p->rx_mb,real_buffer_size,(void **) &rvf_buffer_p)==RVF_RED)
1194 { /* No memory available to store the data */
1195
1196 #ifdef ATP_DEBUG_MSG_ENABLED
1197 (void) sprintf (gbl_debug_message,
1198 "ATP: send_data. Insufficient memory (Bytes left: %d, Bank: %d) ",
1199 *nb_bytes_left_p,
1200 other_port_info_p->rx_mb);
1201 rvf_send_trace (gbl_debug_message,
1202 (UINT8) strlen (gbl_debug_message),
1203 NULL_PARAM,
1204 RV_TRACE_LEVEL_WARNING,
1205 ATP_USE_ID);
1206 #endif
1207
1208 /* Sends a signal to stop the TX FLOW CONTROL of the sender
1209 ie the receiver set its RX_FLOW_CTRL to OFF */
1210 atp_set_signal(other_port_info_p->sw_id,other_port_info_p->port_nb,
1211 ATP_RX_FLOW_OFF,ATP_RX_FLOW_UNMASK);
1212 return RV_NOT_SUPPORTED;
1213 }
1214
1215
1216 /* Copy data into RVF buffer */
1217 offset=other_port_info_p->no_copy_info.rx_head_size;
1218 for(i=0;i<buffer_size;i++)
1219 {
1220 rvf_buffer_p[i+offset]=((UINT8 *) data_buffer_p)[i];
1221 }
1222
1223
1224 switch (other_sw_entity_p->mode.cp_mode)
1225 {
1226 case COPY_OFF:
1227 {
1228 /* Send a ATP_NO_COPY_DATA_RDY event */
1229 if (rvf_get_buf(other_port_info_p->rx_mb,sizeof(T_ATP_NO_COPY_DATA_RDY),(void **) &no_copy_data_ready_p)==RVF_RED)
1230 {
1231 #ifdef ATP_DEBUG_MSG_ENABLED
1232 (void) sprintf (gbl_debug_message,
1233 "ATP: send_data. Insufficient memory (Bytes left: %d, Bank: %d) ",
1234 *nb_bytes_left_p,
1235 other_port_info_p->rx_mb);
1236 rvf_send_trace (gbl_debug_message,
1237 (UINT8) strlen (gbl_debug_message),
1238 NULL_PARAM,
1239 RV_TRACE_LEVEL_WARNING,
1240 ATP_USE_ID);
1241 #endif
1242
1243 /* Sends a signal to stop the TX FLOW CONTROL of the sender
1244 ie the receiver set its RX_FLOW_CTRL to OFF */
1245 atp_set_signal(other_port_info_p->sw_id,other_port_info_p->port_nb,
1246 ATP_RX_FLOW_OFF,ATP_RX_FLOW_UNMASK);
1247
1248 rvf_free_buf (rvf_buffer_p);
1249 return RV_NOT_SUPPORTED;
1250 }
1251
1252 no_copy_data_ready_p->rv_hdr.msg_id=ATP_NO_COPY_DATA_RDY;
1253 no_copy_data_ready_p->port_nb=other_port_info_p->port_nb;
1254 no_copy_data_ready_p->buffer_size=buffer_size; /* Indicate only length of payload ! */
1255 no_copy_data_ready_p->atp_buffer_p=rvf_buffer_p;
1256
1257 #ifdef ATP_DEBUG_MSG_ENABLED
1258 (void) sprintf (gbl_debug_message,
1259 "ATP: NO_COPY_DATA_RDY sent (Port: %d, Size: %d) ",
1260 no_copy_data_ready_p->port_nb,
1261 no_copy_data_ready_p->buffer_size);
1262 rvf_send_trace (gbl_debug_message,
1263 (UINT8) strlen (gbl_debug_message),
1264 NULL_PARAM,
1265 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1266 ATP_USE_ID);
1267 #endif
1268
1269 /* Send the event */
1270 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) no_copy_data_ready_p);
1271 *nb_bytes_left_p=0;
1272 return RV_OK;
1273 }
1274 case COPY_ON:
1275 {
1276
1277 /* Queue the packet and send an ATP_DATA_RDY event */
1278 /* Get enqueue header */
1279 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_RX_PACKET),(void **) &rx_packet_p)==RVF_RED)
1280 {
1281 rvf_free_buf (rvf_buffer_p);
1282 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1283 return RV_MEMORY_ERR;
1284 }
1285 rx_packet_p->first_byte=0;
1286 rx_packet_p->last_byte=real_buffer_size-1;
1287 rx_packet_p->atp_buffer_p=rvf_buffer_p;
1288 rx_packet_p->next_byte_to_read=rx_packet_p->first_byte;
1289
1290 /* Get an ATP_DATA_RDY event */
1291 if (rvf_get_buf(other_port_info_p->rx_mb,sizeof(T_ATP_DATA_RDY),(void **) &data_ready_p)==RVF_RED)
1292 {
1293 #ifdef ATP_DEBUG_MSG_ENABLED
1294 (void) sprintf (gbl_debug_message,
1295 "ATP: send_data. Insufficient memory (Bytes left: %d, Bank: %d) ",
1296 *nb_bytes_left_p,
1297 other_port_info_p->rx_mb);
1298 rvf_send_trace (gbl_debug_message,
1299 (UINT8) strlen (gbl_debug_message),
1300 NULL_PARAM,
1301 RV_TRACE_LEVEL_WARNING,
1302 ATP_USE_ID);
1303 #endif
1304
1305 /* Sends a signal to stop the TX FLOW CONTROL of the sender
1306 ie the receiver set its RX_FLOW_CTRL to OFF */
1307 atp_set_signal(other_port_info_p->sw_id,other_port_info_p->port_nb,
1308 ATP_RX_FLOW_OFF,ATP_RX_FLOW_UNMASK);
1309
1310 rvf_free_buf (rx_packet_p);
1311 rvf_free_buf (rvf_buffer_p);
1312 return RV_NOT_SUPPORTED;
1313 }
1314 data_ready_p->rv_hdr.msg_id=ATP_DATA_RDY;
1315 data_ready_p->port_nb=other_port_info_p->port_nb;
1316 data_ready_p->nb_bytes=real_buffer_size;
1317
1318 /* Queue the packet */
1319 rvf_enqueue (&(other_port_info_p->rx_queue), rx_packet_p);
1320 other_port_info_p->rx_data_left += real_buffer_size;
1321
1322 #ifdef ATP_DEBUG_MSG_ENABLED
1323 (void) sprintf (gbl_debug_message,
1324 "ATP: DATA_RDY sent (Port: %d, Size [Packet]: %d, Left [Overall]: %d) ",
1325 data_ready_p->port_nb,
1326 data_ready_p->nb_bytes,
1327 other_port_info_p->rx_data_left);
1328 rvf_send_trace (gbl_debug_message,
1329 (UINT8) strlen (gbl_debug_message),
1330 NULL_PARAM,
1331 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1332 ATP_USE_ID);
1333 #endif
1334
1335 /* Send the event */
1336 if (atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *)data_ready_p) != RV_OK)
1337 {
1338 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_PARAM_ERROR,NULL);
1339 return RV_INTERNAL_ERR;
1340 }
1341 *nb_bytes_left_p=0;
1342 return RV_OK;
1343 }
1344 default:
1345 {
1346 break;
1347 }
1348 }
1349 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_OTHER_SWE_NOT_IN_PROPER_MODE,NULL);
1350 rvf_free_buf (rvf_buffer_p);
1351 return RV_NOT_SUPPORTED;
1352 }
1353
1354
1355
1356
1357
1358
1359
1360
1361 /******************************************************************************
1362 * Function name: atp_no_copy_send_data
1363 *
1364 * Description : Send data on a port.
1365 *
1366 * Parameters : see BT9901 :
1367 *
1368 * Return : RV_OK
1369 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
1370 *
1371 * atp_error can be called if MB is RED
1372 *
1373 * History : 0.1 (1-Marsh-2000) - Created
1374 * : 0.9 (5-May-2000) - Pas au point !!!!!!!
1375 ******************************************************************************/
1376 T_ATP_RET atp_no_copy_send_data(T_ATP_SW_ENTITY_ID sender_sw_id, T_ATP_PORT_NB sender_port_nb,
1377 T_ATP_BUFFER atp_buffer_p, UINT32 payload_size)
1378 {
1379 T_ATP_PORT_STRUCT * port_p;
1380 T_ATP_SW_NB sender_sw_nb;
1381 T_ATP_SW_ENTITY_STRUCT * other_sw_entity_p;
1382 T_ATP_NO_COPY_DATA_RDY * no_copy_data_ready_p;
1383 T_ATP_DATA_RDY *data_ready_p;
1384 T_ATP_RX_PACKET *rx_packet_p;
1385 UINT32 rx_head,tx_head,rx_trail,tx_trail,tx_data_size,i,data_length,tx_buffer_size;
1386 T_ATP_BUFFER tx_buffer_p;
1387 T_ATP_PORT_END_STRUCT * other_port_info_p;
1388 T_RVF_MB_STATUS mb_status;
1389 UINT8 switch_memory;
1390 T_ATP_SW_NB other_sw_nb;
1391 T_ATP_ESCAPE_SEQUENCE_STATUS escape_status; // status indicating if the escape sequence has been found in the data flow
1392 UINT8 nb_escape_extra_character; // Number of character of the escape sequence which has been already found
1393
1394 #ifdef ATP_DEBUG_MSG_ENABLED
1395 (void) sprintf (gbl_debug_message,
1396 "ATP: no_copy_send_data invoked (Size: %d, Port: %d) ",
1397 payload_size,
1398 sender_port_nb);
1399 rvf_send_trace (gbl_debug_message,
1400 (UINT8) strlen (gbl_debug_message),
1401 NULL_PARAM,
1402 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1403 ATP_USE_ID);
1404 #endif
1405
1406 /* Get the pointer on the port structure */
1407 if(atp_get_port(sender_sw_id,sender_port_nb,&port_p,&sender_sw_nb) != RV_OK)
1408 {
1409 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_PARAM_ERROR,NULL);
1410 return RV_INVALID_PARAMETER; /* This port does not exist */
1411 }
1412 other_sw_nb=(T_ATP_SW_NB) (! sender_sw_nb);
1413
1414 if (port_p->port_state == ATP_OPEN_PENDING)
1415 {
1416 /* Port is not completely open */
1417 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
1418 return RV_NOT_SUPPORTED;
1419 }
1420
1421 /* Get other port */
1422 if ((port_p->redirect_mode==ATP_REDIRECT_ON) &&
1423 (port_p->port_state==ATP_DATA_MODE)) /* redirection is activated */
1424 {
1425 other_port_info_p= & (port_p->redirect_port_p->port_info[port_p->redirect_port_end_nb]);
1426 }
1427 else
1428 {
1429 other_port_info_p= & (port_p->port_info[(! sender_sw_nb)]);
1430 }
1431
1432
1433 /* get pointer on the other SW entity data structure in order to get info */
1434 other_sw_entity_p=atp_sw_entity_table_p[(* other_port_info_p).sw_id];
1435
1436 /* Get info on rx and tx value => to make the code more readable */
1437 rx_head=other_port_info_p->no_copy_info.rx_head_size;
1438 rx_trail=other_port_info_p->no_copy_info.rx_trail_size;
1439 tx_head=port_p->port_info[sender_sw_nb].no_copy_info.tx_head_size;
1440 tx_trail=port_p->port_info[sender_sw_nb].no_copy_info.tx_trail_size;
1441
1442
1443
1444 /* If sender is a transport layer and if ATP needs to emulate DCE or DTE
1445 then interpret the data and send proper command to other SWE */
1446 if ((atp_sw_entity_table_p[sender_sw_id]->mode.cmd_support_mode == CMD_SUPPORT_OFF) &&
1447 ( (port_p->port_state!=ATP_DATA_MODE) && (port_p->port_config != DATA_CONFIG)))
1448 {
1449 T_RV_RET return_status;
1450 T_ATP_CMD_BUFFER_RDY is_ready;
1451
1452 /* Allocate text buffer */
1453 if (rvf_get_buf(other_port_info_p->rx_mb,payload_size+1,(void **) &tx_buffer_p)==RVF_RED)
1454 {
1455 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1456 return RV_MEMORY_ERR;
1457 }
1458
1459 /* And update txt buffer with the data contained in the received packet */
1460 /* Packet in segment mode (cf L2CAP) ? */
1461 if (port_p->port_info[sender_sw_nb].no_copy_info.packet_mode==SEGMENTED_PACKET)
1462 {
1463 tx_data_size=payload_size+1; /* + 1 for 0 at the end */
1464 atp_copy_buffer_from_l2cap((void *) atp_buffer_p,(void *) tx_buffer_p,payload_size,0);
1465 tx_buffer_p[payload_size]=0; /* End of the String */
1466 atp_free_l2cap_buffer((UINT8 *)atp_buffer_p);
1467 }
1468 else
1469 {
1470 tx_data_size=payload_size;
1471 atp_copy_buffer(&atp_buffer_p[tx_head],tx_buffer_p,(UINT32) tx_data_size);
1472 rvf_free_buf(atp_buffer_p); /* Release data buffer : text is now pointed by txt_cmd_p */
1473
1474 }
1475
1476 /* Command is stored in tx_buffer_p . tx_length (without 0 at end) = payload_size */
1477
1478 if (port_p->port_config == DCE_CONFIG) // ATP is emulating DCE
1479 {
1480 // DCE accept several AT commands to be assembled on the same line
1481 // In case ATP DCE receives new commands where ATP has not finished to provide
1482 // all the commands to SWE -> ignore new command
1483 if (port_p->cmd_info.status == ON_GOING)
1484 {
1485 ATP_SEND_TRACE ("ATP/DCE : Receives new commands from DTE whereas previous line has not been processed : ignore ",RV_TRACE_LEVEL_WARNING);
1486 // port_p->cmd_info.status = FINISHED;
1487 // if (port_p->cmd_info.cmd_txt_p != NULL)
1488 // {
1489 // rvf_free_buf(port_p->cmd_info.cmd_txt_p);
1490 // }
1491 // port_p->cmd_info.cmd_txt_p=NULL;
1492 // port_p->cmd_info.next_position=ATP_CMD_INVALID_POSITION;
1493 // port_p->cmd_info.cmd_txt_length=0;
1494
1495 // SHALL WE SEND A RESULT TO DTE ???????
1496 rvf_free_buf((UINT8 *) tx_buffer_p);
1497 return RV_OK;
1498 }
1499
1500
1501 /* Check if mode Echo is ON */
1502 /* In case ECHO mode is activated and DCE , re-send the packet to sender */
1503 if (port_p->dce_info_p->echo_mode == ECHO_ON)
1504 {
1505 if (atp_send_data(other_port_info_p->sw_id,other_port_info_p->port_nb,
1506 tx_buffer_p,strlen((char *) tx_buffer_p),&data_length) != RV_OK)
1507 {
1508 ATP_SEND_TRACE ("ATP : Failed to send command back in echo mode",
1509 RV_TRACE_LEVEL_ERROR);
1510 }
1511 }
1512 } /* End of if ATP = DCE */
1513
1514
1515 /* Update internal cmd buffer: especially, in case cmd is sent character per character */
1516 /* In this case, this function gathers the caracter . is_ready = ATP_CMD_BUFFER_IS _RDY */
1517 /* once a complete command has been received . In this case, the command and related information */
1518 /* is available in port_p->cmd_info structure. */
1519 return_status = atp_update_cmd_buffer(port_p,tx_buffer_p,(UINT16) payload_size,&is_ready);
1520
1521 /* Error in the data received. Sends an error to the remote device. */
1522 if (return_status != RV_OK)
1523 {
1524 port_p->cmd_info.status=FINISHED; // will not get any new command
1525 atp_send_cmd(port_p->port_info[other_sw_nb].sw_id,port_p->port_info[other_sw_nb].port_nb,
1526 RESULT_CODE,ATP_ERROR_NB,NULL);
1527 atp_init_cmd_info_struct(port_p);
1528 return RV_OK;
1529 }
1530
1531 if (is_ready == ATP_CMD_BUFFER_IS_NOT_RDY)
1532 {
1533 /* Wait for following characters */
1534 return RV_OK;
1535 }
1536
1537
1538 /* Let's start to process the command */
1539 return_status = atp_interpret_data(port_p,sender_sw_nb,other_sw_nb); // sender = transport layer , other = appli
1540
1541 if (return_status == RV_MEMORY_ERR)
1542 {
1543 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1544 return RV_MEMORY_ERR;
1545 }
1546
1547 return RV_OK;
1548 } /* End of DCE Emu part */
1549
1550
1551
1552
1553
1554
1555 /* Data copy */
1556 /*---------------------------------------------------------------------*/
1557
1558 /* First case: Target needs a copy */
1559 data_length=payload_size; /* Nb of bytes of the real data (not including header...) */
1560
1561 /* Check ESCAPE SEQUENCE if DCE mode enabled */
1562 if ( (atp_sw_entity_table_p[sender_sw_id]->mode.cmd_support_mode == CMD_SUPPORT_OFF) &&
1563 (port_p->port_config == DCE_CONFIG))
1564 {
1565 // In this case, need to check escape sequence
1566 escape_status = atp_escape_sequence_process(port_p,atp_buffer_p,data_length,
1567 port_p->port_info[sender_sw_nb].no_copy_info.packet_mode);
1568 nb_escape_extra_character = port_p->dce_info_p->nb_plus_received; // Number of escape sequence character already received
1569
1570 if (escape_status == ATP_ESCAPE_SEQUENCE_SUCCESS)
1571 {
1572 // Escape sequence has been found
1573 ATP_SEND_TRACE ("ATP: An escape sequence has been found. Send CMD_ABORT ",RV_TRACE_LEVEL_DEBUG_LOW);
1574 atp_send_cmd(sender_sw_id,sender_port_nb,CMD_ABORT,0,NULL);
1575 atp_reset_escape_sequence(port_p); // Delete all buffer including current atp_buffer_p
1576 }
1577 if (escape_status != ATP_ESCAPE_SEQUENCE_FAILED)
1578 {
1579 return RV_OK; // If SUCCESS or WAIT, no data need to be forwarded
1580 }
1581 }
1582 else
1583 {
1584 nb_escape_extra_character = 0;
1585 }
1586
1587
1588
1589
1590 if(other_sw_entity_p->mode.cp_mode==COPY_ON)
1591 {
1592 /* So Queue the packet and send an ATP_DATA_RDY event */
1593 /* Get enqueue header */
1594 if (rvf_get_buf(other_port_info_p->rx_mb,sizeof(T_ATP_RX_PACKET),(void **) &rx_packet_p)==RVF_RED)
1595 {
1596 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1597 return RV_MEMORY_ERR;
1598 }
1599
1600 if (nb_escape_extra_character > 0)
1601 {
1602 atp_pipe_extra_character(port_p,other_port_info_p); // send in the pipe the character that has been
1603
1604 // Reset internal structure but does not release data buffer !
1605 port_p->dce_info_p->nb_plus_received = 0;
1606 for(i=0;i<MAX_NB_OF_CHARACTER_FOR_END_SEQUENCE;i++)
1607 {
1608 port_p->dce_info_p->escape_sequence_tmp_buffer_p[i] = NULL;
1609 port_p->dce_info_p->length_of_escape_sequence_tmp_buffer_p[i] = 0;
1610 }
1611 }
1612
1613 rx_packet_p->first_byte=tx_head;
1614 rx_packet_p->last_byte=tx_head+payload_size-1;
1615 rx_packet_p->atp_buffer_p=atp_buffer_p;
1616 rx_packet_p->next_byte_to_read=rx_packet_p->first_byte;
1617
1618 /* Queue the packet */
1619 rvf_enqueue (&(other_port_info_p->rx_queue), rx_packet_p);
1620 other_port_info_p->rx_data_left+=payload_size;
1621
1622 /* Get a ATP_DATA_RDY event */
1623 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_DATA_RDY),(void **) &data_ready_p)==RVF_RED)
1624 {
1625 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1626 return RV_MEMORY_ERR;
1627 }
1628
1629 data_ready_p->rv_hdr.msg_id=ATP_DATA_RDY;
1630 data_ready_p->port_nb=other_port_info_p->port_nb;
1631 data_ready_p->nb_bytes=payload_size;
1632
1633 #ifdef ATP_DEBUG_MSG_ENABLED
1634 (void) sprintf (gbl_debug_message,
1635 "ATP: DATA_RDY sent (Port: %d, Size [Packet]: %d, Left [Overall]: %d) ",
1636 data_ready_p->port_nb,
1637 data_ready_p->nb_bytes,
1638 other_port_info_p->rx_data_left);
1639 rvf_send_trace (gbl_debug_message,
1640 (UINT8) strlen (gbl_debug_message),
1641 NULL_PARAM,
1642 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1643 ATP_USE_ID);
1644 #endif
1645
1646 /* Send the event */
1647 if (atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *)data_ready_p) != RV_OK)
1648 {
1649 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_PARAM_ERROR,NULL);
1650 return RV_INTERNAL_ERR;
1651 }
1652 return RV_OK;
1653 }
1654
1655
1656
1657
1658 /* Second case : Target is COPY OFF but packet features are not compatible => needs a copy */
1659 if( (tx_head!=rx_head) || (tx_trail!=rx_trail) ||
1660 ( (port_p->port_info[sender_sw_nb].no_copy_info.packet_mode == SEGMENTED_PACKET) &&
1661 (other_port_info_p->no_copy_info.packet_mode != SEGMENTED_PACKET) ) )
1662 {
1663 tx_data_size=payload_size+nb_escape_extra_character;
1664 tx_buffer_size=tx_data_size+rx_head+rx_trail;
1665
1666
1667 /* Data will be copied into a buffer which will be forwarded to upper layers */
1668 /* Get this buffer from the port MB. If not enough memory available then use
1669 ATP_MB, make the copy , release the initial buffer and try to re-switch the buffer
1670 into the port MB (use of swicth_memory for that purpose */
1671
1672 switch_memory=0; /* Ie no needs to switch from ATP_MB to port MB */
1673 mb_status=rvf_get_buf(other_port_info_p->rx_mb,tx_buffer_size,(void **) &tx_buffer_p);
1674 if (mb_status==RVF_RED)
1675 {
1676 /* Then use own atp_prim MB.... for temporary work ! */
1677 mb_status=rvf_get_buf(atp_mb_prim,tx_buffer_size,(void **) &tx_buffer_p);
1678 switch_memory=1; /* Switch is needed */
1679 if (mb_status==RVF_YELLOW)
1680 {
1681 /* Then , sender should definitely stop to send data !!! */
1682 atp_set_signal(other_port_info_p->sw_id,other_port_info_p->port_nb,
1683 ATP_TX_FLOW_OFF,ATP_TX_FLOW_UNMASK);
1684 }
1685
1686 if (mb_status==RVF_RED)
1687 {
1688 /* Even no memory enough in atp_mb_prim -> big problem */
1689 rvf_send_trace("ATP : not enough memeory for temporary copy from COPY_OFF to COPY OFF SWEs (atp_no_copy_send_data ft) ",
1690 103,
1691 NULL_PARAM,
1692 RV_TRACE_LEVEL_ERROR,
1693 ATP_USE_ID);
1694
1695 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1696 return RV_MEMORY_ERR;
1697
1698 }
1699
1700 }
1701
1702 if (nb_escape_extra_character>0)
1703 {
1704 // Add character that has been removed due to escape sequence scanning
1705 memcpy(&tx_buffer_p[rx_head],port_p->dce_info_p->escape_sequence,
1706 nb_escape_extra_character);
1707 atp_reset_escape_sequence(port_p);
1708 }
1709
1710 if (port_p->port_info[sender_sw_nb].no_copy_info.packet_mode==NORMAL_PACKET)
1711 { /* Packet is not a L2CAP segmented packet */
1712 atp_copy_buffer(&atp_buffer_p[tx_head],&tx_buffer_p[rx_head+nb_escape_extra_character]
1713 ,(tx_data_size-nb_escape_extra_character));
1714 rvf_free_buf(atp_buffer_p);
1715
1716 }
1717 else
1718 { /* Sender Packet was in segmented */
1719 atp_copy_buffer_from_l2cap((void *)atp_buffer_p,(void *) &tx_buffer_p[rx_head+nb_escape_extra_character],
1720 (UINT32)(tx_data_size-nb_escape_extra_character),0);
1721 atp_free_l2cap_buffer( (UINT8 *)atp_buffer_p);
1722
1723 }
1724
1725 /* Copy dummy byte */
1726 for(i=0;i<rx_head;i++)
1727 {
1728 tx_buffer_p[i]=0x00;
1729 }
1730
1731 for(i=tx_data_size+rx_head;i<tx_buffer_size;i++)
1732 {
1733 tx_buffer_p[i]=0x00;
1734 }
1735
1736 /* Release previous buffer */
1737 atp_buffer_p=tx_buffer_p; /* Update to send the data */
1738 data_length=tx_data_size;
1739
1740 /* And switch to port MB if possible */
1741 if (switch_memory==1)
1742 {
1743 rvf_count_buf(other_port_info_p->rx_mb,tx_buffer_p);
1744 }
1745
1746
1747 }
1748 else
1749 {
1750 /* else => a single forward is possible if same packet requirements (RVF/header/trailer/packet mode)*/
1751
1752 if (nb_escape_extra_character>0)
1753 {
1754 // Send characters that has been removed due to escape sequence scanning
1755 UINT8 * buffer_p;
1756
1757 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_NO_COPY_DATA_RDY),(void **) &no_copy_data_ready_p)==RVF_RED)
1758 {
1759 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1760 return RV_MEMORY_ERR;
1761 }
1762 if (rvf_get_buf(atp_mb_prim,nb_escape_extra_character,(void **) &buffer_p)==RVF_RED)
1763 {
1764 rvf_free_buf (no_copy_data_ready_p);
1765 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1766 return RV_MEMORY_ERR;
1767 }
1768 // Copy data into the buffer
1769 memcpy(buffer_p,port_p->dce_info_p->escape_sequence,nb_escape_extra_character);
1770
1771 // And send
1772 no_copy_data_ready_p->rv_hdr.msg_id=ATP_NO_COPY_DATA_RDY;
1773 no_copy_data_ready_p->port_nb=other_port_info_p->port_nb;
1774 no_copy_data_ready_p->buffer_size=nb_escape_extra_character;
1775 no_copy_data_ready_p->atp_buffer_p=buffer_p;
1776
1777 #ifdef ATP_DEBUG_MSG_ENABLED
1778 (void) sprintf (gbl_debug_message,
1779 "ATP: NO_COPY_DATA_RDY sent (Port: %d, Size: %d) ",
1780 no_copy_data_ready_p->port_nb,
1781 no_copy_data_ready_p->buffer_size);
1782 rvf_send_trace (gbl_debug_message,
1783 (UINT8) strlen (gbl_debug_message),
1784 NULL_PARAM,
1785 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1786 ATP_USE_ID);
1787 #endif
1788
1789 /* Send the event */
1790 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) no_copy_data_ready_p);
1791
1792 // Reset temporary data used by the escape sequence algo
1793 atp_reset_escape_sequence(port_p);
1794 }
1795 }
1796
1797
1798
1799
1800 /* Send a ATP_NO_COPY_DATA_RDY event with the data*/
1801 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_NO_COPY_DATA_RDY),(void **) &no_copy_data_ready_p)==RVF_RED)
1802 {
1803 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_DATA,ATP_MEMORY_ERROR,NULL);
1804 return RV_MEMORY_ERR;
1805 }
1806
1807 no_copy_data_ready_p->rv_hdr.msg_id=ATP_NO_COPY_DATA_RDY;
1808 no_copy_data_ready_p->port_nb=other_port_info_p->port_nb;
1809 no_copy_data_ready_p->buffer_size=data_length;
1810 no_copy_data_ready_p->atp_buffer_p=atp_buffer_p;
1811
1812 #ifdef ATP_DEBUG_MSG_ENABLED
1813 (void) sprintf (gbl_debug_message,
1814 "ATP: NO_COPY_DATA_RDY sent (Port: %d, Size: %d) ",
1815 no_copy_data_ready_p->port_nb,
1816 no_copy_data_ready_p->buffer_size);
1817 rvf_send_trace (gbl_debug_message,
1818 (UINT8) strlen (gbl_debug_message),
1819 NULL_PARAM,
1820 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1821 ATP_USE_ID);
1822 #endif
1823
1824 /* Send the event */
1825 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *) no_copy_data_ready_p);
1826 return RV_OK;
1827 }
1828
1829
1830
1831
1832 /******************************************************************************
1833 * Function name: atp_get_data
1834 *
1835 * Description : Copy data in the SW entity buffer
1836 *
1837 * Parameters : see BT9901
1838 *
1839 * Return : RV_OK
1840 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
1841 *
1842 * atp_error can be called if MB is RED
1843 *
1844 * History : 0.1 (1-Marsh-2000) - Created
1845 * : 0.9 (5-May-2000) - Added L2CAP packet support from sender
1846 ******************************************************************************/
1847 T_ATP_RET atp_get_data(T_ATP_SW_ENTITY_ID receiver_sw_id, T_ATP_PORT_NB receiver_port_nb,
1848 UINT8 * data_buffer, UINT32 nb_to_read, UINT32 *nb_read_p,
1849 UINT32 *nb_left_p)
1850 {
1851 T_ATP_PORT_STRUCT * port_p;
1852 T_ATP_SW_NB receiver_sw_nb;
1853 T_ATP_RX_PACKET *rx_packet_p;
1854 UINT32 start_index,nb_to_copy;
1855 T_ATP_PACKET_MODE packet_mode;
1856
1857 #ifdef ATP_DEBUG_MSG_ENABLED
1858 (void) sprintf (gbl_debug_message,
1859 "ATP: get_data invoked (Size: %d, Port: %d) ",
1860 nb_to_read,
1861 receiver_port_nb);
1862 rvf_send_trace (gbl_debug_message,
1863 (UINT8) strlen (gbl_debug_message),
1864 NULL_PARAM,
1865 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1866 ATP_USE_ID);
1867 #endif
1868
1869 /* Get the pointer on the port structure */
1870 if(atp_get_port(receiver_sw_id,receiver_port_nb,&port_p,&receiver_sw_nb) != RV_OK)
1871 {
1872 atp_error_switch(ATP_ERROR_FAILED_TO_GET_DATA,ATP_PARAM_ERROR,NULL);
1873 return RV_INVALID_PARAMETER; /* This port does not exist */
1874 }
1875
1876 if (port_p->port_state == ATP_OPEN_PENDING)
1877 {
1878 /* Port is not completely open */
1879 atp_error_switch(ATP_ERROR_FAILED_TO_GET_DATA,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
1880 return RV_NOT_SUPPORTED;
1881 }
1882
1883 /* Get information on the format of the data to copy */
1884 if ((port_p->redirect_mode==ATP_REDIRECT_ON) &&
1885 (port_p->port_state==ATP_DATA_MODE)) /* redirection is activated */
1886 {
1887 packet_mode= port_p->redirect_port_p->port_info[port_p->redirect_port_end_nb].no_copy_info.packet_mode;
1888 }
1889 else
1890 {
1891 packet_mode=port_p->port_info[(! receiver_sw_nb)].no_copy_info.packet_mode; /* packet mode of the sender */
1892 }
1893 *nb_read_p=0; // No data has been copied yet
1894
1895 /* Check number of data available */
1896 if ((port_p->port_info[receiver_sw_nb].rx_data_left == 0) || \
1897 (RVF_IS_QUEUE_EMPTY((port_p->port_info[receiver_sw_nb].rx_queue))))
1898 { /* No pending packet are available in the RX queue */
1899 *nb_left_p=0;
1900
1901 #ifdef ATP_DEBUG_MSG_ENABLED
1902 (void) sprintf (gbl_debug_message,
1903 "ATP: get_data (Read: %d, Left [Packet]: %d, Left [Overall]: %d) ",
1904 *nb_read_p,
1905 *nb_left_p,
1906 port_p->port_info[receiver_sw_nb].rx_data_left);
1907 rvf_send_trace (gbl_debug_message,
1908 (UINT8) strlen (gbl_debug_message),
1909 NULL_PARAM,
1910 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1911 ATP_USE_ID);
1912 #endif
1913 return RV_OK;
1914 }
1915
1916 // TO UPDATE IN ORDER TO COPE WITH L2CAP PACKETS !!!!!
1917 rx_packet_p=(T_ATP_RX_PACKET *) rvf_dequeue (&(port_p->port_info[receiver_sw_nb].rx_queue));
1918 start_index=rx_packet_p->next_byte_to_read; /* Next byte can start at [0] */
1919 nb_to_copy=Min(rx_packet_p->last_byte-start_index+1,nb_to_read); /* Number of byte from this packet to copy */
1920
1921 if (packet_mode==NORMAL_PACKET)
1922 { /* Stored Data is in a single buffer */
1923 atp_copy_buffer(&(rx_packet_p->atp_buffer_p[start_index]),&(data_buffer[*nb_read_p]),nb_to_copy);
1924 }
1925 else
1926 {
1927 atp_copy_buffer_from_l2cap(rx_packet_p->atp_buffer_p,&data_buffer[*nb_read_p],nb_to_copy,start_index);
1928 }
1929
1930 /* Update counters */
1931 port_p->port_info[receiver_sw_nb].rx_data_left-=nb_to_copy; /* Overall number of bytes */
1932 /* left to be read */
1933 rx_packet_p->next_byte_to_read=rx_packet_p->next_byte_to_read+nb_to_copy;
1934
1935 *nb_read_p=nb_to_copy; /* Number of byte read */
1936 *nb_left_p=rx_packet_p->last_byte+1-rx_packet_p->next_byte_to_read; /* Number of bytes left */
1937 /* to be read */
1938
1939 #ifdef ATP_DEBUG_MSG_ENABLED
1940 (void) sprintf (gbl_debug_message,
1941 "ATP: get_data (Read: %d, Left [Packet]: %d, Left [Overall]: %d) ",
1942 *nb_read_p,
1943 *nb_left_p,
1944 port_p->port_info[receiver_sw_nb].rx_data_left);
1945 rvf_send_trace (gbl_debug_message,
1946 (UINT8) strlen (gbl_debug_message),
1947 NULL_PARAM,
1948 RV_TRACE_LEVEL_DEBUG_MEDIUM,
1949 ATP_USE_ID);
1950 #endif
1951
1952 if (*nb_left_p < 1)
1953 {
1954 /* Buffer has been entirely copied : free buffer */
1955 if (packet_mode==NORMAL_PACKET)
1956 {
1957 rvf_free_buf(rx_packet_p->atp_buffer_p);
1958 }
1959 else
1960 {
1961 atp_free_l2cap_buffer ((UINT8 *) rx_packet_p->atp_buffer_p);
1962 }
1963 rvf_free_buf(rx_packet_p);
1964 return RV_OK;
1965 }
1966
1967 /* In this case, still some data need to be read from the RX packet */
1968 /* Re-enqueue the buffer and go out of the while loop */
1969 rvf_enqueue_head(&(port_p->port_info[receiver_sw_nb].rx_queue),rx_packet_p);
1970 return RV_OK;
1971 }
1972
1973
1974
1975
1976
1977
1978
1979
1980 /******************************************************************************
1981 * Function name: atp_set_mode
1982 *
1983 * Description : Change the mode of the port
1984 *
1985 * Parameters : see BT9901
1986 *
1987 * Return : RV_OK
1988 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
1989 *
1990 * atp_error can be called if MB is RED
1991 *
1992 * History : 0.1 (09-May-2000) - Created
1993 *
1994 ******************************************************************************/
1995 T_ATP_RET atp_set_mode(T_ATP_SW_ENTITY_ID sender_sw_id, T_ATP_PORT_NB sender_port_nb,
1996 T_ATP_PORT_MODE mode)
1997 {
1998
1999
2000 T_ATP_PORT_STRUCT * port_p;
2001 T_ATP_SW_NB sender_sw_nb, other_sw_nb;
2002 T_ATP_SW_ENTITY_STRUCT * other_sw_entity_p;
2003 T_ATP_PORT_MODE_CHANGED * mode_changed_p;
2004
2005
2006 /* Get the pointer on the port structure */
2007 if(atp_get_port(sender_sw_id,sender_port_nb,&port_p,&sender_sw_nb) != RV_OK)
2008 {
2009 atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_MODE,ATP_PARAM_ERROR,NULL);
2010 return RV_INVALID_PARAMETER; /* This port does not exist */
2011 }
2012 other_sw_nb=(T_ATP_SW_NB) (! sender_sw_nb);
2013
2014 if (port_p->port_state == ATP_OPEN_PENDING)
2015 {
2016 /* Port is not completely open */
2017 atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_MODE,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
2018 return RV_NOT_SUPPORTED;
2019 }
2020 /* get pointer on the other SW entity data structure in order to get info */
2021 other_sw_entity_p=atp_sw_entity_table_p[port_p->port_info[other_sw_nb].sw_id];
2022
2023
2024 /* Change the mode of the port */
2025 if (mode==ATP_PORT_DATA_MODE)
2026 {
2027 port_p->port_state=ATP_DATA_MODE;
2028 }
2029 else
2030 {
2031 port_p->port_state=ATP_CMD_MODE;
2032 // And reset the cmd_info field
2033 atp_init_cmd_info_struct(port_p);
2034 }
2035
2036
2037
2038 /* And send an event to the other SW entity if the other is not a TL ie does not support commands
2039 (otherwise, mode switch is completely transmparent ...*/
2040 if (other_sw_entity_p->mode.cmd_support_mode != CMD_SUPPORT_OFF)
2041 {
2042 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_PORT_MODE_CHANGED),(void **) &mode_changed_p)==RVF_RED)
2043 {
2044 atp_error(ATP_ERROR_MB_PRIM_RED);
2045 return (RV_MEMORY_ERR);
2046 }
2047
2048 mode_changed_p->rv_hdr.msg_id=ATP_PORT_MODE_CHANGED;
2049 mode_changed_p->port_nb=port_p->port_info[other_sw_nb].port_nb;
2050 mode_changed_p->mode=mode;
2051
2052
2053 /* Send the event */
2054 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *)mode_changed_p);
2055 }
2056 else
2057 {
2058 // Other SWE does not support command : So, is a DCE ?
2059 if (port_p->port_config == DCE_CONFIG)
2060 {
2061 // Reset fields used by the escape sequence algorithm
2062 atp_reset_escape_sequence(port_p);
2063 }
2064 }
2065
2066 return RV_OK;
2067 }
2068
2069 /******************************************************************************
2070 * Function name: atp_set_signal
2071 *
2072 * Description : Set signal value of the port
2073 *
2074 * Parameters : see BT9901
2075 *
2076 * Return : RV_OK
2077 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
2078 *
2079 * atp_error can be called if MB is RED
2080 *
2081 * History : 0.1 (1-Marsh-2000) - Created
2082 *
2083 ******************************************************************************/
2084 T_ATP_RET atp_set_signal(T_ATP_SW_ENTITY_ID sender_sw_id, T_ATP_PORT_NB sender_port_nb,
2085 T_ATP_PORT_SIGNAL set_signal, T_ATP_SIGNAL_CHANGE_MASK set_mask)
2086 {
2087 T_ATP_PORT_STRUCT * port_p;
2088 T_ATP_SW_NB sender_sw_nb, other_sw_nb;
2089 T_ATP_SW_ENTITY_STRUCT * other_sw_entity_p;
2090 UINT8 signal_changed;
2091 T_ATP_SIGNAL_CHANGED * signal_changed_p;
2092 T_ATP_PORT_SIGNAL sender_signal,other_signal,set_signal_value;
2093 T_ATP_SIGNAL_CHANGE_MASK get_mask,new_mask; /* Mask on the signal changed for the other SW entity */
2094 T_ATP_PORT_END_STRUCT * other_port_info_p;
2095 BOOLEAN wait_for_mb_callback;
2096
2097 /* Get the pointer on the port structure */
2098 if(atp_get_port(sender_sw_id,sender_port_nb,&port_p,&sender_sw_nb) != RV_OK)
2099 {
2100 atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_SIGNAL,ATP_PARAM_ERROR,NULL);
2101 return RV_INVALID_PARAMETER; /* This port does not exist */
2102 }
2103
2104 /* Get pointer on the other SW entity data structure in order to get info */
2105 /* Get other port taking care on redirection*/
2106 if ((port_p->redirect_mode==ATP_REDIRECT_ON) &&
2107 (port_p->port_state==ATP_DATA_MODE)) /* redirection is activated */
2108 {
2109 other_port_info_p= & (port_p->redirect_port_p->port_info[port_p->redirect_port_end_nb]);
2110 other_sw_nb=(T_ATP_SW_NB) (port_p->redirect_port_end_nb);
2111 }
2112 else
2113 {
2114 other_port_info_p= & (port_p->port_info[(! sender_sw_nb)]);
2115 other_sw_nb=(T_ATP_SW_NB) (! sender_sw_nb);
2116 }
2117
2118 /* Get pointer on the other SW entity data structure in order to get info */
2119 other_sw_entity_p=atp_sw_entity_table_p[(* other_port_info_p).sw_id];
2120
2121 if (port_p->port_state == ATP_OPEN_PENDING)
2122 {
2123 /* Port is not completely open */
2124 atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_SIGNAL,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
2125 return RV_NOT_SUPPORTED;
2126 }
2127 sender_signal=port_p->port_info[sender_sw_nb].signal;
2128 other_signal=other_port_info_p->signal;
2129
2130 get_mask=0;
2131 wait_for_mb_callback=FALSE;
2132
2133 /* Set RX flow control signal ? */
2134 if ((set_mask & ATP_RX_FLOW_UNMASK)!=0) /* Sender wants to set its RX flow */
2135 { /* Get sender RX bit value */
2136 set_signal_value = (T_ATP_SIGNAL_MASK)( set_signal & ATP_RX_FLOW_UNMASK );
2137
2138 /* set_signal = ATP_RX_FLOW_ON or ATP_RX_FLOW_OFF */
2139 if (set_signal_value == ATP_RX_FLOW_ON)
2140 { /* Caller wants to set ATP_RX_FLOW_CTRL */
2141 /* Set it into sender signal status and set TX_FLOW_ON on the other port */
2142 sender_signal |= ATP_RX_FLOW_ON;
2143 rvf_send_trace ("ATP: RX FLOW set to ON. Port ",
2144 29,
2145 sender_port_nb,
2146 RV_TRACE_LEVEL_DEBUG_LOW,
2147 ATP_USE_ID);
2148 if (( other_signal & ATP_TX_FLOW_UNMASK) == ATP_TX_FLOW_OFF)
2149 { /* TX_FLOW_CTRL was OFF for the other entity : set it */
2150 other_signal |= ATP_TX_FLOW_ON;
2151
2152 /* A signal will be generated even if it has been issue earlier */
2153 get_mask |= ATP_TX_FLOW_UNMASK;
2154 }
2155 }
2156 else
2157 { /* Caller wants to clear ATP_RX_FLOW_CTRL => RX_FLOW = OFF */
2158 /* Clear RX bit on the sender */
2159 sender_signal &= (~ ATP_RX_FLOW_UNMASK);
2160 rvf_send_trace ("ATP: RX FLOW set to OFF. Port ",
2161 30,
2162 sender_port_nb,
2163 RV_TRACE_LEVEL_DEBUG_LOW,
2164 ATP_USE_ID);
2165 wait_for_mb_callback = TRUE;
2166
2167 /* Other TX bit value = OFF */
2168 if (( other_signal & ATP_TX_FLOW_UNMASK) == ATP_TX_FLOW_ON)
2169 { /* TX_FLOW_CTRL was ON for the other entity : clear it */
2170 other_signal &= (~ ATP_TX_FLOW_UNMASK);
2171
2172 /* A signal will be generated even if it has been issue earlier */
2173 get_mask |= ATP_TX_FLOW_UNMASK;
2174 }
2175 }
2176 }
2177
2178 /* Set TX flow control signal ? */
2179 if ((set_mask & ATP_TX_FLOW_UNMASK)!=0) /* Sender wants to set the TX flow */
2180 { /* Get sender TX bit value */
2181 set_signal_value = (T_ATP_SIGNAL_MASK) (set_signal & ATP_TX_FLOW_UNMASK);
2182
2183 /* set_signal = ATP_TX_FLOW_ON or ATP_TX_FLOW_OFF */
2184 if (set_signal_value == ATP_TX_FLOW_ON)
2185 { /* Caller wants to set ATP_TX_FLOW_CTRL */
2186 /* Set it into sender signal status and set RX_FLOW_ON on the other port */
2187 sender_signal |= ATP_TX_FLOW_ON;
2188 rvf_send_trace ("ATP: TX FLOW set to ON. Port ",
2189 29,
2190 sender_port_nb,
2191 RV_TRACE_LEVEL_DEBUG_LOW,
2192 ATP_USE_ID);
2193 if (( other_signal & ATP_RX_FLOW_UNMASK) == ATP_RX_FLOW_OFF)
2194 { /* RX_FLOW_CTRL was OFF for the other entity : set it */
2195 other_signal |= ATP_RX_FLOW_ON;
2196 get_mask |= ATP_RX_FLOW_UNMASK;
2197 }
2198 }
2199 else
2200 { /* Caller wants to clear ATP_TX_FLOW_CTRL */
2201 /* Clear TX bit on the sender */
2202 sender_signal &= (~ ATP_TX_FLOW_UNMASK);
2203 rvf_send_trace ("ATP: TX FLOW set to OFF. Port ",
2204 30,
2205 sender_port_nb,
2206 RV_TRACE_LEVEL_DEBUG_LOW,
2207 ATP_USE_ID);
2208
2209 /* Other TX bit value = OFF */
2210 if (( other_signal & ATP_RX_FLOW_UNMASK) == ATP_RX_FLOW_ON)
2211 { /* RX_FLOW_CTRL was ON for the other entity : clear it*/
2212 other_signal &= (~ ATP_RX_FLOW_UNMASK);
2213 get_mask |= ATP_RX_FLOW_UNMASK;
2214 }
2215 }
2216 }
2217
2218 /* Set other signals */
2219 /* Other signals to handle */
2220 new_mask= (T_ATP_SIGNAL_MASK) (set_mask & ATP_NON_RX_TX_SIGNAL_UNMASK);
2221
2222 /* Take only the good signals */
2223 signal_changed= (T_ATP_SIGNAL_MASK) (set_signal & new_mask);
2224
2225 port_p->port_info->signal= (T_ATP_SIGNAL_MASK) ((sender_signal & (~ new_mask)) | signal_changed);
2226 other_port_info_p->signal = (T_ATP_SIGNAL_MASK) ((other_signal & (~ new_mask)) | signal_changed);
2227 get_mask |= new_mask;
2228
2229 /* Set the callback function to send signal TX_ON later on */
2230 if (wait_for_mb_callback)
2231 {
2232
2233 /* Getting the sendee. */
2234 port_p->port_waiting_for_mb_callback = sender_sw_nb;
2235 if (rvf_set_callback_func(port_p->port_info[sender_sw_nb].rx_mb,atp_mb_call_back))
2236 {
2237 rvf_change_callback_func( (T_RVF_MB_ID) (port_p->port_info[sender_sw_nb].rx_mb),atp_mb_call_back);
2238 }
2239 }
2240 if (get_mask !=0)
2241 { /* Send a ATP_SIGNAL_CHANGED event */
2242 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_SIGNAL_CHANGED),(void **) &signal_changed_p)==RVF_RED)
2243 {
2244 atp_error(ATP_ERROR_MB_PRIM_RED);
2245 return (RV_MEMORY_ERR);
2246 }
2247
2248 signal_changed_p->rv_hdr.msg_id=ATP_SIGNAL_CHANGED;
2249 signal_changed_p->mask=get_mask;
2250 signal_changed_p->port_nb=other_port_info_p->port_nb;
2251 signal_changed_p->signal=other_port_info_p->signal;
2252 signal_changed_p->mb=other_port_info_p->tx_mb;
2253
2254 /* Send the event */
2255 atp_send_message(other_sw_entity_p->return_path,(T_ATP_MESSAGE *)signal_changed_p);
2256 }
2257 return RV_OK;
2258 }
2259
2260
2261
2262
2263 /******************************************************************************
2264 * Function name: atp_get_signal
2265 *
2266 * Description : Get signal value of the port
2267 *
2268 * Parameters : see BT9901
2269 *
2270 * Return : RV_OK
2271 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
2272 *
2273 * atp_error can be called if MB is RED
2274 *
2275 * History : 0.1 (1-Marsh-2000) - Created
2276 *
2277 ******************************************************************************/
2278 T_ATP_RET atp_get_signal(T_ATP_SW_ENTITY_ID sw_id, T_ATP_PORT_NB port_nb,
2279 T_ATP_PORT_SIGNAL * signal_p)
2280 {
2281
2282 T_ATP_PORT_STRUCT * port_p;
2283 T_ATP_SW_NB sw_nb;
2284
2285 /* Get the pointer on the port structure */
2286 if(atp_get_port(sw_id,port_nb,&port_p,&sw_nb) != RV_OK)
2287 {
2288 atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_SIGNAL,ATP_PARAM_ERROR,NULL);
2289 return RV_INVALID_PARAMETER; /* This port does not exist */
2290 }
2291
2292 if (port_p->port_state == ATP_OPEN_PENDING)
2293 {
2294 /* Port is not completely open */
2295 atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_SIGNAL,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
2296 return RV_NOT_SUPPORTED;
2297 }
2298
2299 *signal_p=port_p->port_info[sw_nb].signal;
2300
2301 return RV_OK;
2302 }
2303
2304
2305
2306
2307
2308
2309
2310
2311 /******************************************************************************
2312 * Function name: atp_flow_redirect
2313 *
2314 * Description : Redirect the flow from one port to another one
2315 *
2316 * Parameters : see BT9901
2317 *
2318 * Return : RV_OK
2319 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
2320 *
2321 * atp_error can be called if MB is RED
2322 *
2323 * History : 0.1 (22-May-2000) - Created
2324 *
2325 ******************************************************************************/
2326 T_ATP_RET atp_flow_redirect(T_ATP_SW_ENTITY_ID sw_id, T_ATP_PORT_NB port_nb_1,
2327 T_ATP_PORT_NB port_nb_2, T_ATP_REDIRECT_MODE redirect_mode)
2328 {
2329
2330 T_ATP_SW_NB sw_nb_1,sw_nb_2,other_sw_nb_1,other_sw_nb_2;
2331 T_ATP_PORT_STRUCT *port_1_p,*port_2_p;
2332
2333
2334
2335 /* Find port information */
2336
2337 /* Get the pointer on the port structure related to the port number 1 */
2338 if(atp_get_port(sw_id,port_nb_1,&port_1_p,&sw_nb_1) != RV_OK)
2339 {
2340 atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_FLOW_REDIRECTION,ATP_PARAM_ERROR,NULL);
2341 return RV_INVALID_PARAMETER; /* This port does not exist */
2342 }
2343 other_sw_nb_1=(T_ATP_SW_NB) (! sw_nb_1);
2344
2345 /* Get the pointer on the port structure related to the port number 2 */
2346 if(atp_get_port(sw_id,port_nb_2,&port_2_p,&sw_nb_2) != RV_OK)
2347 {
2348 atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_FLOW_REDIRECTION,ATP_PARAM_ERROR,NULL);
2349 return RV_INVALID_PARAMETER; /* This port does not exist */
2350 }
2351 other_sw_nb_2=(T_ATP_SW_NB) (! sw_nb_2);
2352
2353
2354 // START SEMAPHORE
2355 if (redirect_mode == ATP_REDIRECT_ON)
2356 {
2357 port_1_p->redirect_mode=ATP_REDIRECT_ON;
2358 port_2_p->redirect_mode=ATP_REDIRECT_ON;
2359
2360 port_1_p->redirect_port_p=port_2_p;
2361 port_2_p->redirect_port_p=port_1_p;
2362
2363 port_1_p->redirect_port_end_nb=other_sw_nb_2;
2364 port_2_p->redirect_port_end_nb=other_sw_nb_1;
2365
2366 // END SEMAPHORE
2367
2368 return RV_OK;
2369 }
2370
2371
2372 /* Else, pass from REDIRECT_ON to REDIRECT_OFF */
2373 port_1_p->redirect_mode=ATP_REDIRECT_OFF;
2374 port_2_p->redirect_mode=ATP_REDIRECT_OFF;
2375
2376 port_1_p->redirect_port_p=NULL;
2377 port_2_p->redirect_port_p=NULL;
2378
2379 port_1_p->redirect_port_end_nb=0;
2380 port_2_p->redirect_port_end_nb=0;
2381
2382
2383 // END SEMAPHORE
2384
2385 return RV_OK;
2386 }
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396 /******************************************************************************
2397 * Function name: atp_free_message
2398 *
2399 * Description : Generic function service provided to SW entity to free an ATP buffer
2400 *
2401 * Parameters : pointer on the buffer
2402 *
2403 * Return : return of the rvf_free_buf function
2404 *
2405 * History : 0.1 (1-Marsh-2000) - Created
2406 *
2407 ******************************************************************************/
2408 T_ATP_RET atp_free_message(void * buffer_p)
2409
2410 {
2411 return rvf_free_buf(buffer_p);
2412 }
2413
2414
2415
2416 /******************************************************************************
2417 * Function name: atp_free_buffer
2418 *
2419 * Description : Generic function service provided to SW entity to free an ATP buffer
2420 *
2421 * Parameters : pointer on the buffer
2422 *
2423 * Return : return of the rvf_free_buf function
2424 *
2425 * History : 0.1 (1-Marsh-2000) - Created
2426 *
2427 ******************************************************************************/
2428 T_ATP_RET atp_free_buffer(void * buffer_p)
2429
2430 {
2431 if (buffer_p != NULL)
2432 {
2433 return rvf_free_buf(buffer_p);
2434 }
2435 return RV_OK;
2436 }
2437
2438
2439
2440 /******************************************************************************
2441 * Function name: atp_get_buffer
2442 *
2443 * Description : Generic function service provided to SW entity to free an ATP buffer
2444 *
2445 * Parameters : pointer on the buffer
2446 *
2447 * Return : return of the rvf_free_buf function
2448 *
2449 * History : 0.1 (1-Marsh-2000) - Created
2450 *
2451 ******************************************************************************/
2452 T_ATP_RET atp_get_buffer(UINT32 buffer_size,void ** buffer_pp)
2453
2454 {
2455 if ( rvf_get_buf(atp_mb_prim,buffer_size,(void **) buffer_pp) == RVF_RED)
2456 {
2457 atp_error_switch(ATP_ERROR_FAILED_TO_GET_MEMORY,ATP_MEMORY_ERROR,NULL);
2458 return RV_NOT_SUPPORTED;
2459 }
2460 return RV_OK;
2461 }
2462
2463
2464 /******************************************************************************
2465 * Function name: atp_get_buffer_from_tx_mb
2466 *
2467 * Description : Function used to get memory from the tx memory bank of the SWE
2468 *
2469 * Parameters :
2470 *
2471 * Return : return of the rvf_free_buf function
2472 *
2473 * History : 0.1 (1-Marsh-2000) - Created
2474 *
2475 ******************************************************************************/
2476 T_ATP_RET atp_get_buffer_from_tx_mb(T_ATP_SW_ENTITY_ID sender_sw_id,T_ATP_PORT_NB sender_port_nb,
2477 UINT32 buffer_size,void ** buffer_pp)
2478
2479 {
2480 T_ATP_PORT_STRUCT * port_p;
2481 T_ATP_SW_NB sender_sw_nb;
2482 T_ATP_PORT_END_STRUCT * other_port_info_p;
2483
2484 /* Get the pointer on the port structure */
2485 if(atp_get_port(sender_sw_id,sender_port_nb,&port_p,&sender_sw_nb) != RV_OK)
2486 {
2487 atp_error_switch(ATP_ERROR_FAILED_TO_GET_MEMORY,ATP_MEMORY_ERROR,NULL);
2488 return RV_INVALID_PARAMETER; /* This port does not exist */
2489 }
2490 other_port_info_p= & (port_p->port_info[(! sender_sw_nb)]);
2491
2492 if ( rvf_get_buf(port_p->port_info[sender_sw_nb].tx_mb,buffer_size,buffer_pp)
2493 == RVF_RED)
2494 {
2495 /* Sends a signal to stop the TX FLOW CONTROL of the sender
2496 ie the receiver set its RX_FLOW_CTRL to OFF */
2497 atp_set_signal(other_port_info_p->sw_id,other_port_info_p->port_nb,
2498 ATP_RX_FLOW_OFF,ATP_RX_FLOW_UNMASK);
2499 return RV_NOT_SUPPORTED;
2500 }
2501 return RV_OK;
2502 }
2503
2504
2505 /******************************************************************************
2506 * Function name: atp_update_cmd_buffer
2507 * Description : This function gathers data used to transmit buffer into
2508 * the port internal buffer before sending it to interpretation.
2509 * Especially usefull for character per character AT command
2510 * transmission
2511 *
2512 * Parameters : is_ready indicates if the txt_buffer is ready for interpretation
2513 * Return : return RV_OK if
2514 * or RV_MEMORY_ERR
2515 *
2516 * History : 0.1 (8-Nov-2000) - Created - Eric
2517 *
2518 ******************************************************************************/
2519 T_ATP_RET atp_update_cmd_buffer(T_ATP_PORT_STRUCT * port_p,
2520 UINT8 * new_txt_cmd_buffer_p, UINT16 txt_cmd_buffer_length,
2521 T_ATP_CMD_BUFFER_RDY * is_ready_p)
2522 {
2523 UINT16 i,j;
2524 UINT8 position;
2525
2526
2527 /* Check if a full command is available in the new buffer */
2528 *is_ready_p = ATP_CMD_BUFFER_IS_NOT_RDY;
2529 for(i=0;i<txt_cmd_buffer_length;i++)
2530 {
2531
2532 /* Is there a CR characrter ??*/
2533 if (new_txt_cmd_buffer_p[i] == port_p->dce_info_p->cr_character) // cr character has been found in the txt command
2534 {
2535 if ( (i != 0 ) || (port_p->cmd_info.next_position != 0) ) // and cr is not the first character of the command line
2536 {
2537 *is_ready_p = ATP_CMD_BUFFER_IS_RDY; // OK for interpretation
2538 break;
2539 }
2540
2541 }
2542 }
2543
2544
2545 /* Check that buffer is not only <lf> with no previously sent character */
2546 j=0;
2547 if ( (new_txt_cmd_buffer_p[0] == port_p->dce_info_p->lf_character) &&
2548 (port_p->cmd_info.next_position == 0))
2549 {
2550 j=1; // skip lf if it is the first caracter of a chain ie the last...
2551 }
2552
2553 /* Process data */
2554 if ((txt_cmd_buffer_length - j ) > 0) // there is something to copy
2555 {
2556 /* if buffer does not exist, create it */
2557 if (port_p->cmd_info.cmd_txt_p == NULL)
2558 {
2559 if ( rvf_get_buf(atp_mb_prim,ATP_MAX_CMD_LENGTH,(void **) &port_p->cmd_info.cmd_txt_p) == RVF_RED)
2560 {
2561 atp_error_switch(ATP_ERROR_FAILED_TO_ACCEPT_A_PORT,ATP_MEMORY_ERROR,NULL);
2562 return RV_MEMORY_ERR;
2563 }
2564 }
2565
2566 /* Copy buffer */
2567 position = (UINT8) port_p->cmd_info.next_position; // is next position to write on
2568
2569 for(i=j;i<txt_cmd_buffer_length;i++)
2570 {
2571 if ( (new_txt_cmd_buffer_p[i] == port_p->dce_info_p->bs_character) && // Back space character
2572 (port_p->port_config == DCE_CONFIG)) // And ATP emulates a DCE
2573 {
2574 /* A backspace character has been sent */
2575 if (position > 0)
2576 {
2577 position--;
2578 port_p->cmd_info.cmd_txt_p[position] = ' ';
2579 }
2580
2581 }
2582 else
2583 {
2584 port_p->cmd_info.cmd_txt_p[position] = new_txt_cmd_buffer_p[i];
2585 if (++position == ATP_MAX_CMD_LENGTH)
2586 {
2587 ATP_SEND_TRACE ("ATP : The command received by ATP is too long versus ATP buffer length",RV_TRACE_LEVEL_WARNING);
2588 return RV_NOT_SUPPORTED;
2589 }
2590 }
2591 }
2592
2593 if (*is_ready_p == ATP_CMD_BUFFER_IS_RDY)
2594 {
2595
2596 port_p->cmd_info.cmd_txt_p[position] = 0; // Set 0 at the end of the chain
2597 ATP_SEND_TRACE ("ATP CMD : cmd buffer is ready to be interpreted = ",RV_TRACE_LEVEL_DEBUG_MEDIUM);
2598 rvf_send_trace(port_p->cmd_info.cmd_txt_p,(UINT8) strlen(port_p->cmd_info.cmd_txt_p),NULL_PARAM,
2599 RV_TRACE_LEVEL_DEBUG_MEDIUM,ATP_USE_ID);
2600
2601 // Ready for interpretation
2602 port_p->cmd_info.cmd_txt_length = (UINT8) (position);
2603 port_p->cmd_info.next_position = 0;
2604 port_p->cmd_info.status = NOT_STARTED;
2605 }
2606 else
2607 {
2608 // Waiting for new characters
2609 port_p->cmd_info.next_position = (UINT8) (position);
2610
2611 // Tracing
2612 port_p->cmd_info.cmd_txt_p[port_p->cmd_info.next_position] = 0;
2613 ATP_SEND_TRACE ("ATP CMD : cmd buffer in the pipe = ",RV_TRACE_LEVEL_DEBUG_LOW);
2614 rvf_send_trace(port_p->cmd_info.cmd_txt_p,(UINT8) strlen(port_p->cmd_info.cmd_txt_p),NULL_PARAM,
2615 RV_TRACE_LEVEL_DEBUG_LOW,ATP_USE_ID);
2616 }
2617
2618
2619 }
2620
2621
2622
2623 rvf_free_buf(new_txt_cmd_buffer_p);
2624
2625 return RV_OK;
2626 }
2627
2628
2629
2630
2631
2632
2633 /******************************************************************************
2634 * Function name: atp_interpret_data
2635 * Description : This function is called when DATA received on a transport layer
2636 * must be interpreted in order to emelate a DCE behaviour
2637 * The command are either interpreted directly by DCE
2638 * or sent in INTERPRETED or TXT format to the appli
2639 * If end of the buffer to interpret is reached, send a OK result
2640 * code to remote DTE
2641 * If an error is encountered in the buffer, send a ERROR result
2642 * code to the remote DTE
2643 *
2644 * Parameters : pointer on port structure
2645 * memory bank to use
2646 * spp_sw_id = sw id of the transport layer SW entity
2647 * spp_port_nb = port_nb related to spp_sw_id
2648 * appli_sw_id = sw id of the appli SW entity
2649 * appli_port_nb = port_nb related to appli_sw_id
2650 *
2651 * Return : return RV_OK
2652 * or RV_MEMORY_ERR
2653 *
2654 * History : 0.1 (1-Marsh-2000) - Created
2655 *
2656 ******************************************************************************/
2657 T_ATP_RET atp_interpret_data(T_ATP_PORT_STRUCT *port_p,
2658 T_ATP_SW_NB spp_sw_nb, T_ATP_SW_NB appli_sw_nb)
2659
2660 {
2661 T_ATP_TXT_CMD new_txt_cmd_p;
2662 UINT16 txt_length;
2663 T_ATP_CMD_TYPE cmd_type;
2664 T_ATP_CMD_NB cmd_nb;
2665 T_ATP_CMD *cmd_info_p;
2666 T_ATP_RET return_status;
2667
2668 return_status = atp_interpret_raw_data(port_p,port_p->port_info[appli_sw_nb].rx_mb,
2669 &cmd_type,&cmd_nb,&cmd_info_p,&new_txt_cmd_p,&txt_length);
2670
2671
2672 if (return_status == RV_MEMORY_ERR)
2673 {
2674 return RV_MEMORY_ERR;
2675 }
2676
2677 if (return_status == RV_OK)
2678 {
2679 // Check if a command need to be sent
2680 if ((cmd_type != UNKNOWN) && (new_txt_cmd_p == NULL))
2681 {
2682 if ( (port_p->port_config == DTE_CONFIG) && (cmd_type == AT_CMD))
2683 {
2684 /* If the command is a AT_CMD whereas ATP is emulating a DTE, then it is certainly
2685 because it is the echo of the command that DTE sent previously */
2686 atp_send_cmd(port_p->port_info[spp_sw_nb].sw_id,port_p->port_info[spp_sw_nb].port_nb,
2687 PRELIMINARY_RESULT_CODE,cmd_nb,cmd_info_p);
2688 }
2689 else
2690 {
2691 atp_send_cmd(port_p->port_info[spp_sw_nb].sw_id,port_p->port_info[spp_sw_nb].port_nb,
2692 cmd_type,cmd_nb,cmd_info_p);
2693 }
2694 }
2695 else
2696 {
2697 if (new_txt_cmd_p != NULL)
2698 {
2699 atp_send_txt_cmd(port_p->port_info[spp_sw_nb].sw_id,port_p->port_info[spp_sw_nb].port_nb,
2700 cmd_type,new_txt_cmd_p);
2701 }
2702 else
2703 {
2704 // In this case, last command has been properly interpreted by DCE and
2705 // status has been set to FINISHED by interprete raw data
2706 // DCE must sends a result OK to remote device
2707 if (port_p->cmd_info.status != FINISHED)
2708 {
2709 rvf_send_trace("ATP : status state invalid from interpret_raw_data function ",60,
2710 NULL_PARAM,RV_TRACE_LEVEL_WARNING,ATP_USE_ID);
2711
2712 port_p->cmd_info.status = FINISHED;
2713 }
2714
2715 atp_send_cmd(port_p->port_info[appli_sw_nb].sw_id,port_p->port_info[appli_sw_nb].port_nb,
2716 RESULT_CODE,ATP_OK_NB,NULL);
2717 }
2718 }
2719 }
2720 else
2721 {
2722 // Error in the data received
2723 // Sends an error to the remote device
2724 port_p->cmd_info.status=FINISHED; // will not get any new command
2725 atp_send_cmd(port_p->port_info[appli_sw_nb].sw_id,port_p->port_info[appli_sw_nb].port_nb,
2726 RESULT_CODE,ATP_ERROR_NB,NULL);
2727 }
2728
2729 /// IS IT OK ?
2730 if (port_p->cmd_info.status==FINISHED)
2731 {
2732 atp_init_cmd_info_struct(port_p);
2733 }
2734
2735
2736 return RV_OK;
2737 }
2738
2739
2740
2741
2742 /******************************************************************************
2743 * Function name: atp_init_cmd_info_struct
2744 * Description : Initialise field of the icmd_info structure.
2745 *
2746 * Parameters : port_p -> pointer on the port structure
2747 *
2748 * Return : return RV_OK
2749 *
2750 * History : 0.1 (1-September-2000) - Created
2751 *
2752 ******************************************************************************/
2753 T_ATP_RET atp_init_cmd_info_struct(T_ATP_PORT_STRUCT * port_p)
2754 {
2755 // START SEMAPHORE ??
2756 port_p->cmd_info.cmd_txt_length=0;
2757 if (port_p->cmd_info.cmd_txt_p != NULL)
2758 {
2759 rvf_free_buf (port_p->cmd_info.cmd_txt_p);
2760 }
2761 port_p->cmd_info.cmd_txt_p = NULL;
2762 port_p->cmd_info.next_position=0;
2763 port_p->cmd_info.state = READY_FOR_NEW_CMD;
2764 port_p->cmd_info.status = NOT_STARTED;
2765 // STOP SEMAPHORE ??
2766 return RV_OK;
2767 }
2768
2769
2770
2771 /******************************************************************************
2772 * Function name: atp_error_switch
2773 * Description : This function send ERROR events
2774 *
2775 * Parameters :
2776 *
2777 * Return : return RV_OK
2778 * or RV_MEMORY_ERR
2779 *
2780 * History : 0.1 (1-September-2000) - Created
2781 *
2782 ******************************************************************************/
2783 T_ATP_RET atp_error_switch(T_ATP_ERROR_MAIN_REASON main_reason,
2784 T_ATP_ERROR_TYPE error_type,T_RV_RETURN * return_path_p)
2785 {
2786 T_ATP_ERROR * error_p;
2787
2788
2789 switch(main_reason)
2790 {
2791 case ATP_ERROR_FAILED_TO_OPEN_A_PORT:
2792 {
2793 ATP_SEND_TRACE ("ATP : Failed to open a new port", RV_TRACE_LEVEL_WARNING);
2794 break;
2795 }
2796 case ATP_ERROR_FAILED_TO_ACCEPT_A_PORT:
2797 {
2798 ATP_SEND_TRACE ("ATP : Failed to accept a new port", RV_TRACE_LEVEL_WARNING);
2799 break;
2800 }
2801 case ATP_ERROR_FAILED_TO_SEND_CMD:
2802 {
2803 ATP_SEND_TRACE ("ATP : Failed to send a command on a port ", RV_TRACE_LEVEL_WARNING);
2804 break;
2805 }
2806 case ATP_ERROR_FAILED_TO_CLOSE_A_PORT:
2807 {
2808 ATP_SEND_TRACE ("ATP : Failed to close a port",RV_TRACE_LEVEL_WARNING);
2809 break;
2810 }
2811 case ATP_ERROR_FAILED_TO_SEND_DATA:
2812 {
2813 ATP_SEND_TRACE ("ATP : Failed to send data", RV_TRACE_LEVEL_WARNING);
2814 break;
2815 }
2816 case ATP_ERROR_FAILED_TO_GET_DATA:
2817 {
2818 ATP_SEND_TRACE ("ATP : Failed to get data ", RV_TRACE_LEVEL_WARNING);
2819 break;
2820 }
2821 case ATP_ERROR_FAILED_TO_HANDLE_MODE:
2822 {
2823 ATP_SEND_TRACE ("ATP : Failed to handle mode related function", RV_TRACE_LEVEL_WARNING);
2824 break;
2825 }
2826 case ATP_ERROR_FAILED_TO_HANDLE_SIGNAL:
2827 {
2828 ATP_SEND_TRACE ("ATP : Failed to handle signal related function", RV_TRACE_LEVEL_WARNING);
2829 break;
2830 }
2831 case ATP_ERROR_FAILED_TO_HANDLE_FLOW_REDIRECTION:
2832 {
2833 ATP_SEND_TRACE ("ATP : Failed to redirect flow ", RV_TRACE_LEVEL_WARNING);
2834 break;
2835 }
2836
2837 case ATP_ERROR_FAILED_TO_HANDLE_REGISTRATION:
2838 {
2839 ATP_SEND_TRACE ("ATP : Failed to register or deregister or get info on an other SWE ", RV_TRACE_LEVEL_WARNING);
2840 break;
2841 }
2842 default:
2843 {
2844 ATP_SEND_TRACE ("ATP : Failed with an unkown main reason", RV_TRACE_LEVEL_WARNING);
2845 break;
2846 }
2847
2848 }
2849
2850 switch(error_type)
2851 {
2852 case ATP_MEMORY_ERROR:
2853 {
2854 ATP_SEND_TRACE ("ATP : Memory Issue . ATP PRIM memory bank is RED !", RV_TRACE_LEVEL_ERROR);
2855 atp_error(ATP_ERROR_MB_PRIM_RED);
2856 break;
2857 }
2858 case ATP_PARAM_ERROR:
2859 {
2860 ATP_SEND_TRACE ("ATP : Function has been called with wrong parameter value(s) ", RV_TRACE_LEVEL_WARNING);
2861 break;
2862 }
2863 case ATP_ISSUED_IN_A_WRONG_STATE_ERROR:
2864 {
2865 ATP_SEND_TRACE ("ATP : Function has been called in a wrong state (port still not open or ATP not ready) ", RV_TRACE_LEVEL_WARNING);
2866 break;
2867 }
2868 case ATP_WAITING_FOR_RESULT:
2869 {
2870 ATP_SEND_TRACE ("ATP : Tried to send a new AT_CMD whereas the previous one did not ge any result yet", RV_TRACE_LEVEL_WARNING);
2871 break;
2872 }
2873 case ATP_CANNOT_TRANSLATE_CMD:
2874 {
2875 ATP_SEND_TRACE ("ATP : Failed to translate a command (interprete mode <-> text or data mode) ", RV_TRACE_LEVEL_WARNING);
2876 break;
2877 }
2878 case ATP_OTHER_SWE_NOT_IN_PROPER_MODE:
2879 {
2880 ATP_SEND_TRACE ("ATP : The other SWE is not in proper mode (COPY_ON/OFF, DCE ON/OFF ...)", RV_TRACE_LEVEL_WARNING);
2881 break;
2882 }
2883 case ATP_SAME_ACTION_ALREADY_DONE:
2884 {
2885 ATP_SEND_TRACE ("ATP : This action has already been performed earlier ", RV_TRACE_LEVEL_WARNING);
2886 break;
2887 }
2888 case ATP_NO_MORE_RESSOURCE:
2889 {
2890 ATP_SEND_TRACE ("ATP : There is no more ressource to handle this action", RV_TRACE_LEVEL_WARNING);
2891 break;
2892 }
2893 default:
2894 {
2895 ATP_SEND_TRACE ("ATP : Failed with an unkown error reason", RV_TRACE_LEVEL_WARNING);
2896 break;
2897 }
2898 }
2899
2900 /* Get the primitive and sends it */
2901 if(return_path_p != NULL)
2902 {
2903 if (rvf_get_buf(atp_mb_prim,sizeof(T_ATP_ERROR),(void **) &error_p)==RVF_RED)
2904 {
2905 atp_error(ATP_ERROR_MB_PRIM_RED);
2906 }
2907
2908 error_p->rv_hdr.msg_id = ATP_ERROR;
2909 error_p->main_reason = main_reason;
2910 error_p->error_type = error_type;
2911
2912 /* Send the event */
2913 return atp_send_message(*return_path_p,(T_ATP_MESSAGE *)error_p);
2914 }
2915
2916 return RV_OK;
2917 }
2918
2919
2920
2921
2922
2923 /******************************************************************************
2924 * Function name: atp_get_info_on_port_end
2925 *
2926 * Description : Provide information on the other end of the port
2927 * (for example, which format of data the other SW entity is expecting )
2928 *
2929 * Parameters : see BT9901
2930 *
2931 * Return : RV_OK
2932 * RV_INVALID_PARAMETER : one of the id or port_nb was wrong : ignore call
2933 * RV_NOT_SUPPORTED : command needed to be translated and was unknow by ATP
2934 *
2935 * atp_error can be called if MB is RED
2936 *
2937 * History : 0.1 19-Dec-2001
2938 *
2939 ******************************************************************************/
2940 T_ATP_RET atp_get_info_on_port_end (T_ATP_SW_ENTITY_ID requester_sw_id, T_ATP_PORT_NB requester_port_nb,
2941 T_ATP_OTHER_PORT_END_INFO * other_info_p)
2942 {
2943 T_ATP_PORT_STRUCT * port_p;
2944 T_ATP_SW_NB requester_sw_nb, other_sw_nb;
2945 T_ATP_SW_ENTITY_STRUCT * other_sw_entity_p;
2946
2947 /* Get the pointer on the port structure */
2948 if(atp_get_port(requester_sw_id,requester_port_nb,&port_p,&requester_sw_nb) != RV_OK)
2949 {
2950 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_PARAM_ERROR,NULL);
2951 return RV_INVALID_PARAMETER; /* This port does not exist */
2952 }
2953 other_sw_nb=(T_ATP_SW_NB) (! requester_sw_nb);
2954
2955 if (port_p->port_state == ATP_OPEN_PENDING)
2956 {
2957 /* Port is not completely open yet */
2958 atp_error_switch(ATP_ERROR_FAILED_TO_SEND_CMD,ATP_ISSUED_IN_A_WRONG_STATE_ERROR,NULL);
2959 return RV_NOT_SUPPORTED;
2960 }
2961
2962 /* get pointer on the other SW entity data structure in order to get info */
2963 other_sw_entity_p=atp_sw_entity_table_p[port_p->port_info[other_sw_nb].sw_id];
2964
2965 /* Copy information */
2966 strcpy((char *) other_info_p->name,(char *) other_sw_entity_p->sw_entity_name);
2967 other_info_p->mode = other_sw_entity_p->mode;
2968 other_info_p->no_copy_info = (port_p->port_info[other_sw_nb]).no_copy_info;
2969
2970 return OK;
2971 }
2972
2973
2974
2975 /******************************************************************************
2976 * Function name: atp_mb_call_back
2977 *
2978 * Description : Indicate to a SW entity that the mb has ran GREEN again
2979 * This function is called when a RX_MB which was RED
2980 * (so TX_FLOW_OFF has been sent to the other SWE)
2981 * , has been switched to GREEN . In this case, a TX_FLOW_ON has
2982 * to be sent to the SWE which was sending the data.
2983 *
2984 * Return : RV_OK if the signal has been sent to the proper SWE
2985 * Otherwise, RV_NOT_SUPPORTED
2986 *
2987 * History : 0.1 27-05-2002
2988 *
2989 ******************************************************************************/
2990 void atp_mb_call_back(T_RVF_MB_ID mb)
2991 {
2992 T_ATP_SW_NB sw_nb = ATP_MAX_SW_NB;
2993 T_ATP_PORT_STRUCT *port_p = NULL;
2994
2995 /* Searching for the ports whose RX memory bank matches with 'mb'. */
2996 for (port_p = atp_first_port_p;
2997 port_p != NULL;
2998 port_p = port_p->next_p)
2999 {
3000
3001 /* Setting the flow control to ATP_RX_FLOW_ON. */
3002 if (((sw_nb = port_p->port_waiting_for_mb_callback) != ATP_MAX_SW_NB) && \
3003 ((port_p->port_info[sw_nb]).rx_mb == mb))
3004 {
3005
3006 /* Setting the sendee to an invalid value. */
3007 port_p->port_waiting_for_mb_callback = ATP_MAX_SW_NB;
3008
3009 /* Setting the flow control to ATP_RX_FLOW_ON. */
3010 atp_set_signal ((port_p->port_info[sw_nb]).sw_id,
3011 (port_p->port_info[sw_nb]).port_nb,
3012 ATP_RX_FLOW_ON,
3013 ATP_RX_FLOW_UNMASK);
3014 }
3015 }
3016 }