FreeCalypso > hg > tcs211-l1-reconst
comparison chipsetsw/services/atp/atp_services.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:509db1a7b7b8 |
---|---|
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 } |