FreeCalypso > hg > ffs-editor
view src/cs/services/atp/atp_gsm_bt_api.c @ 0:92470e5d0b9e
src: partial import from FC Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 15 May 2020 01:28:16 +0000 |
parents | |
children |
line wrap: on
line source
/******************************************************************************* * * File Name : atp_gsm_bt_api.c * * This file handles all the interface between GSM AT command handler or Data handler * and the BT protocol stack. It has 2 main functions: * - get the events coming from Bluetooth ATP in direction of GSM, analyse them and * call the proper function of atp_gsm_gsm_api.c * - offer function to GSM so that GSM can use services of the BT PS * * * Version number : 0.1 Date : 10-Jully-2000 * * History : 0.1 - Created by E. Baissus * * Author : Eric Baissus : e-baissus@ti.com * * (C) Copyright 2000 by Texas Instruments Incorporated *****************************************************************************/ #include "rv/rv_general.h" #include "rvf/rvf_api.h" #include "atp/atp_api.h" #include "atp/atp_config.h" #include "atp/atp_messages.h" #include "atp/atp_gsm_bt_api.h" #include "atp/atp_gsm_gsm_api.h" #include "atp/atp_config.h" #include "atp/bti_at.h" #include "atp/atp_i.h" #include "rvm/rvm_use_id_list.h" #include <string.h> /* Internal definitions */ typedef enum { ATP_ACTIVE , // Data exchange in the BT/GSM adapter is on going ATP_NOT_ACTIVE // Data exchange in the BT/GSM adapter is not on going } T_ATP_DATA_ACTIVITY; typedef enum { CMD_PENDING, // GSM should be processing a command from BT CMD_NOT_PENDING // GSM can handle a new command issued by BT } T_ATP_GSM_CMD_STATUS; typedef struct { UINT32 gsm_tx_data_left; // Number of data left to transmit to ATP T_ATP_DATA_ACTIVITY atp_tx_data_activity; // Indicates if data exchange is on going from BT to GSM T_ATP_GSM_CMD_STATUS cmd_status; UINT32 bt_max_payload; UINT16 tx_head_size; UINT16 tx_trail_size; } T_ATP_GSM_PORT_STRUCT; /* Definition used only in this file */ typedef enum { ATP_GSM_OPEN_PORT_PENDING, // The adaptor is processing an open port ATP_GSM_OPEN_PORT_NOT_PENDING // The adaptor is not processing an open port } T_ATP_GSM_OPEN_PORT_PENDING; /* Local variable */ static T_ATP_SW_ENTITY_ID atp_gsm_sw_id; /* Any entity needs to register to ATP and then get an id This id will be identify GSM for ATP */ static T_ATP_PORT_NB initiator_port_nb; /* Port number used by the SWE requesting a new port to GSM */ static T_ATP_SW_ENTITY_ID initiator_id; /* Initiator ID of the SWE requesting to open a port with GSM */ static T_ATP_GSM_OPEN_PORT_PENDING open_port_pending; /* Value can be : PORT_PENDING or PORT_NOT_PENDING A port is said to be in PORT_PENDING when a new port has been requested but this new port is not yet created Only one port at a time can be in PORT_PENDING state If open_port_pending is in PORT_PENDING state, then no new port request is processed */ static UINT8 current_nb_port; // Indicate number of port actually activated static T_ATP_GSM_PORT_STRUCT * port_array[ATP_MAX_NB_OF_PORT_SUPPORTED_BY_GSM]; static UINT32 temp_bt_max_payload; // USed to store BT MFS before the port is actually open /* Function definition */ static T_RV_RET atp_gsm_init_port(T_ATP_GSM_PORT_STRUCT * port_p); static T_RV_RET atp_gsm_init_if(void); static T_RV_RET atp_gsm_get_new_port_nb(UINT8 * port_nb); /****************************************************************************** * Function name: atp_gsm_bt_event_handle * * Description : Main function used to split the events coming from ATP * and call proper function of GSM side (see atp_gsm_gsm_api.c) * * * Parameters : * ATP message * * Return : No return * * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ void atp_gsm_bt_event_handle(void * message_p) { T_RV_RET error = RV_OK; T_BTI_PORT_NB port_nb = 0xFF; switch(((T_ATP_MESSAGE *) message_p)->msg_id) { case ATP_OPEN_PORT_IND : { T_BTI_BT_PORT_INFO bt_port_info; rvf_send_trace("ATP/GSM : Received a ATP_OPEN_PORT_IND from ATP ",50, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); // Store initiator parameters initiator_port_nb=(( T_ATP_OPEN_PORT_IND *) message_p)->initiator_port_nb; initiator_id = (( T_ATP_OPEN_PORT_IND *) message_p)->initiator_id; if ((open_port_pending == ATP_GSM_OPEN_PORT_PENDING) || (atp_gsm_get_new_port_nb(&port_nb)!= RV_OK)) { // A port opening is pending : refuse to open a new port T_ATP_PORT_INFO dummy_port_info; T_ATP_NO_COPY_INFO dummy_no_copy_info; rvf_send_trace("ATP/GSM : Failed to open a port : port opening was pending or max number of port has been reached",97, NULL_PARAM,RV_TRACE_LEVEL_WARNING,ATP_USE_ID); /* Initialise to avoid warning */ memset(&dummy_port_info,0,sizeof(dummy_port_info)); memset(&dummy_no_copy_info,0,sizeof(dummy_no_copy_info)); // Send a negative response to ATP atp_open_port_rsp((( T_ATP_OPEN_PORT_IND *) message_p)->initiator_id,initiator_port_nb,atp_gsm_sw_id,0, dummy_port_info,dummy_no_copy_info,NULL,OPEN_PORT_NOK); rvf_free_buf( (( T_ATP_OPEN_PORT_IND *) message_p)->custom_info_p ); error=RV_NOT_SUPPORTED; } // Send open port indication to GSM /////////////// Need to update data packet size bt_port_info.optimal_bt_max_packet_size = ((T_ATP_CUSTOM_TO_GSM_INFO *) (( T_ATP_OPEN_PORT_IND *) message_p)->custom_info_p)->bt_max_payload; // DO NOT CARE ... temp_bt_max_payload = bt_port_info.optimal_bt_max_packet_size; // Store temporaly the MFS open_port_pending=ATP_GSM_OPEN_PORT_PENDING; // Now , an open port is pending bti_at_open_port_ind(port_nb,bt_port_info); rvf_free_buf( (( T_ATP_OPEN_PORT_IND *) message_p)->custom_info_p ); break; }; case ATP_PORT_CLOSED : { // A close_port has been issue on BT side rvf_send_trace("ATP/GSM : Received a ATP_PORT_CLOSED from ATP ",50, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); // Send close port indication to GSM bti_at_close_port_ind((T_BTI_PORT_NB) ((T_ATP_PORT_CLOSED *) message_p)->port_nb); break; }; case ATP_TXT_CMD_RDY : { // A command in text format has been issued by BT side rvf_send_trace("ATP/GSM : Received a ATP_TXT_CMD_RDY from ATP",45, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); if (((T_ATP_TXT_CMD_RDY *) message_p)->cmd_type == CMD_ABORT) { rvf_send_trace("ATP/GSM : An abort command is requested by ATP ",47, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); port_array[((T_ATP_TXT_CMD_RDY *)message_p)->port_nb]->cmd_status = CMD_NOT_PENDING; bti_at_abort_ind((T_BTI_PORT_NB) ((T_ATP_TXT_CMD_RDY *) message_p)->port_nb); } else { rvf_send_trace( ((T_ATP_TXT_CMD_RDY *) message_p)->txt_cmd_p, (UINT8) strlen(((T_ATP_TXT_CMD_RDY *) message_p)->txt_cmd_p), NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); port_array[((T_ATP_TXT_CMD_RDY *)message_p)->port_nb]->cmd_status = CMD_PENDING; bti_at_cmd_ind((T_BTI_PORT_NB) ((T_ATP_TXT_CMD_RDY *) message_p)->port_nb, (char *) ((T_ATP_TXT_CMD_RDY *) message_p)->txt_cmd_p); } atp_free_buffer(((T_ATP_TXT_CMD_RDY *) message_p)->txt_cmd_p); break; }; case ATP_CMD_RDY : { // A command in binary format has been issued by BT side // This command is ignored since binary format not supported by GSM rvf_send_trace("ATP/GSM : Ignored a ATP_CMD_RDY from ATP",40, NULL_PARAM,RV_TRACE_LEVEL_WARNING, ATP_USE_ID); atp_free_buffer(((T_ATP_CMD_RDY *) message_p)->cmd_info_p); break; }; case ATP_NO_COPY_DATA_RDY : { // BT side issued a no copy format buffer to GSM // This command is ignored and warning is raised rvf_send_trace("ATP/GSM : Ignored a ATP_NO_COPY_DATA_RDY from ATP ",50, NULL_PARAM,RV_TRACE_LEVEL_WARNING, ATP_USE_ID); atp_free_buffer(((T_ATP_NO_COPY_DATA_RDY *) message_p)->atp_buffer_p); break; }; case ATP_DATA_RDY : { // BT side has sent data to GSM rvf_send_trace("ATP/GSM : Received a ATP_DATA_RDY from ATP . Nb of data = ",58, (UINT32) ((T_ATP_DATA_RDY *)message_p)->nb_bytes,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); /* If GSM is not currently handling data exchange, call bti_data_rdy */ if (port_array[((T_ATP_DATA_RDY *)message_p)->port_nb]->atp_tx_data_activity == ATP_NOT_ACTIVE) { port_array[((T_ATP_DATA_RDY *)message_p)->port_nb]->atp_tx_data_activity = ATP_ACTIVE; rvf_send_trace("ATP/GSM : bti_data_ready_ind has been called by BT . Nb_Bytes = ",65, (UINT32) ((T_ATP_DATA_RDY *)message_p)->nb_bytes ,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); bti_data_ready_ind((T_BTI_PORT_NB) ((T_ATP_DATA_RDY *)message_p)->port_nb, (unsigned long) ((T_ATP_DATA_RDY *)message_p)->nb_bytes); } else { UINT8 * dummy_data_buffer = NULL; UINT32 data_left,data_read; ATP_SEND_TRACE("ATP/GSM : Wait before sending data to GSM since GSM is already fetching data", RV_TRACE_LEVEL_DEBUG_LOW); atp_get_data(atp_gsm_sw_id,((T_ATP_DATA_RDY *)message_p)->port_nb,(UINT8 *) dummy_data_buffer, (UINT32) 0,&data_read,&data_left); rvf_send_trace("ATP/GSM : Total number of data to fetch for GSM = ",51, (UINT32) data_left,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); } break; }; case ATP_PORT_MODE_CHANGED : { // BT side has issue a port mode changed (Data or Command) rvf_send_trace("ATP/GSM : Received a ATP_PORT_MODE_CHANGED from ATP",51, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); if( ((T_ATP_PORT_MODE_CHANGED *) message_p)->mode == ATP_PORT_DATA_MODE) { ATP_SEND_TRACE("ATP/GSM: switch to data mode",RV_TRACE_LEVEL_DEBUG_LOW); ATP_SEND_TRACE("ATP/GSM: BT calls bti_data_ready_cnf in order to accept data from GSM",RV_TRACE_LEVEL_DEBUG_LOW); bti_data_ready_cnf((T_BTI_PORT_NB) ((T_ATP_PORT_MODE_CHANGED *) message_p)->port_nb); } else { ATP_SEND_TRACE("ATP/GSM: port has been switched to command mode by BT",RV_TRACE_LEVEL_DEBUG_LOW); } break; }; case ATP_SIGNAL_CHANGED : { // BT side has issued a signal change rvf_send_trace("ATP/GSM : Received a ATP_SIGNAL_CHANGED from ATP",48, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); if ( ( (((T_ATP_SIGNAL_CHANGED *) message_p)->mask) & ATP_TX_FLOW_UNMASK) != 0) { // change on TX flow if( ( (((T_ATP_SIGNAL_CHANGED *) message_p)->mask) & (((T_ATP_SIGNAL_CHANGED *) message_p)->signal) ) == ATP_TX_FLOW_OFF) { // BT side has switch TX GSM flow to OFF rvf_send_trace("ATP/GSM : ATP requested TX GSM Flow to be OFF",45, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); } else { // BT side has switch TX GSM flow to ON rvf_send_trace("ATP/GSM : ATP requested TX GSM Flow to be ON",44, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); if (port_array[((T_ATP_SIGNAL_CHANGED *) message_p)->port_nb]->gsm_tx_data_left != 0) { // Retry to send data to ATP bti_data_ready_req( (T_BTI_PORT_NB) ((T_ATP_SIGNAL_CHANGED *) message_p)->port_nb, port_array[((T_ATP_SIGNAL_CHANGED *) message_p)->port_nb]->gsm_tx_data_left); } } break; } ////////////////////////////////////// // Otherwise, ignore the signal change /////////////////////TO BE UPDATED !!! ///////////////// rvf_send_trace("ATP/GSM : Signal change has been ignored ",41, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); break; }; default: { rvf_send_trace("ATP/GSM : Unknown message received from ATP by ATP_GSM => ignored ",66, NULL_PARAM,RV_TRACE_LEVEL_WARNING,ATP_USE_ID); break; }; } /* Release ATP message buffer */ atp_free_message(message_p); } /****************************************************************************** * Function name: bti_at_init_req * * Description : This function is called by GSM to initialise GSM with ATP * * * Parameters : None * * Return : BTI_AT_OK or BTI_AT_INTERNAL_ERR * * History : 0.1 (10-Jully-2000) * : 0.2 (02-Jan-2001) ******************************************************************************/ void bti_at_init_req(void) { T_ATP_ENTITY_MODE mode; T_ATP_SW_ENTITY_NAME name; T_ATP_CALLBACK return_path; ATP_SEND_TRACE("ATP/GSM : bti_at_init_req has been called by GSM . ", RV_TRACE_LEVEL_DEBUG_LOW); /* Static variable initialisation */ atp_gsm_init_if(); /* Register GSM to ATP */ strcpy((char *) name,ATP_GSM_NAME); return_path.callback_func = atp_gsm_bt_event_handle; return_path.addr_id = RVF_INVALID_ADDR_ID; mode.cmd_mode=TXT_MODE; mode.cp_mode=COPY_ON; mode.cmd_support_mode=CMD_SUPPORT_ON; if(atp_reg(name,return_path,mode,&atp_gsm_sw_id)!=RV_OK) { rvf_send_trace("ATP_GSM: GSM entity registration failed ",39, NULL_PARAM , RV_TRACE_LEVEL_WARNING,ATP_USE_ID); bti_at_init_cnf(BTI_NAK); // Failed registration } else { ATP_SEND_TRACE ("ATP/GSM: GSM entity registration succeeded ",RV_TRACE_LEVEL_DEBUG_LOW); bti_at_init_cnf(BTI_ACK); // Succeeded registration } } /****************************************************************************** * Function name: bti_at_deinit_ind * * Description : This function is called by GSM (?) to de-initialise GSM from ATP * * * Parameters : None * * Return : BTI_AT_OK or BTI_AT_NOT_SUPPORTED * * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ void bti_at_deinit_req(void) { ATP_SEND_TRACE ("ATP_GSM: bti_at_deinit_req has been called by GSM ",RV_TRACE_LEVEL_DEBUG_LOW); atp_dereg(atp_gsm_sw_id); } /****************************************************************************** * Function name: bti_at_deinit_res * * Description : This function is called by GSM to de-initialise GSM from ATP * * * Parameters : None * * Return : BTI_AT_OK or BTI_AT_NOT_SUPPORTED * * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ void bti_at_deinit_res(void) { // DUMMY FUNCTION } /****************************************************************************** * Function name: bti_at_open_port_res * * Description : This function is called by GSM to accept or refuse * an open port request issued by BT side * * * * * History : 0.1 (10-Jully-2000) * : 0.2 (02-Jan-2001) ******************************************************************************/ void bti_at_open_port_res(T_BTI_PORT_NB gsm_port_nb, T_BTI_GSM_PORT_INFO gsm_port_info, T_BTI_ACK ack) { T_ATP_PORT_INFO port_info ; T_ATP_NO_COPY_INFO no_copy_info ; T_RV_RET return_status; T_ATP_CUSTOM_FROM_GSM_INFO * custom_gsm_info_p; T_ATP_OTHER_PORT_END_INFO other_end_info; rvf_send_trace("ATP/GSM : bti_at_open_port_res has been called by GSM . Flag = ",43, (UINT32) ack,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); rvf_send_trace("ATP/GSM : gsm_port_nb = ",24, (UINT32) gsm_port_nb,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); rvf_send_trace("ATP/GSM : GSM indication for MFS = ",35, (UINT32) gsm_port_info.optimal_gsm_max_packet_size, RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); /* Get information on the other end port */ if (atp_get_info_on_port_end(initiator_id,(T_ATP_PORT_NB) initiator_port_nb, &other_end_info) != RV_OK) { ATP_SEND_TRACE("ATP : Failed to get information on other end port ", RV_TRACE_LEVEL_WARNING); no_copy_info.tx_head_size = 0; no_copy_info.tx_trail_size = 0; } else { no_copy_info.tx_head_size = other_end_info.no_copy_info.rx_head_size; no_copy_info.tx_trail_size = other_end_info.no_copy_info.rx_trail_size; } /* Initialise port information */ no_copy_info.rx_head_mode = RX_HEADER_OFF; // COPY ON mode in RX no_copy_info.tx_head_mode = TX_HEADER_OFF; // COPY OFF mode in TX for optimization // no_copy_info.tx_head_mode = TX_HEADER_ON; // COPY OFF mode in TX for optimization ////////// SHOULD BE REMOVED IN CASE GSM SEND DATA WITH HEADER AND TRAILER BIT ////// no_copy_info.tx_head_size = 0; no_copy_info.tx_trail_size = 0; no_copy_info.rx_mb = RVF_INVALID_MB_ID; no_copy_info.tx_mb = RVF_INVALID_MB_ID; no_copy_info.packet_mode = NORMAL_PACKET; /* No L2CAP packet... */ port_info.dce_mask[0]=0x0000; // Do not care, GSM is not in DCE_ON mode port_info.ring_type=ATP_NO_RING_TYPE; port_info.signal_mask=ATP_TX_FLOW_UNMASK; /* Store custom info from GSM */ atp_get_buffer(sizeof(T_ATP_CUSTOM_FROM_GSM_INFO),(void **) &custom_gsm_info_p); custom_gsm_info_p->custom_type = ATP_FROM_GSM_INFO; custom_gsm_info_p ->optimal_gsm_max_packet_size = gsm_port_info.optimal_gsm_max_packet_size; if (ack == BTI_ACK) { ATP_SEND_TRACE("ATP/GSM : GSM accepted to open a port ", RV_TRACE_LEVEL_DEBUG_LOW); // Initialise a new port atp_get_buffer(sizeof(T_ATP_GSM_PORT_STRUCT),(void **) &(port_array[gsm_port_nb])); atp_gsm_init_port(port_array[gsm_port_nb]); port_array[gsm_port_nb]->tx_head_size = no_copy_info.tx_head_size; port_array[gsm_port_nb]->tx_trail_size = no_copy_info.tx_trail_size; return_status = atp_open_port_rsp( initiator_id, (T_ATP_PORT_NB) initiator_port_nb, atp_gsm_sw_id, (T_ATP_PORT_NB) gsm_port_nb, port_info, no_copy_info, (T_ATP_CUSTOM_INFO *) custom_gsm_info_p, OPEN_PORT_OK); } else { rvf_send_trace("ATP/GSM : GSM refused the open port ",36, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); return_status = atp_open_port_rsp( initiator_id, (T_ATP_PORT_NB) initiator_port_nb, atp_gsm_sw_id, (T_ATP_PORT_NB) gsm_port_nb, port_info, no_copy_info, NULL, OPEN_PORT_NOK); } if(return_status != RV_OK) { rvf_send_trace("ATP/GSM : Failed to open a port ",33, NULL_PARAM,RV_TRACE_LEVEL_WARNING, ATP_USE_ID); } open_port_pending = ATP_GSM_OPEN_PORT_NOT_PENDING; } /****************************************************************************** * Function name: bti_at_close_port_res * * Description : Not used by BT PS - Port is always closed * * Parameters : * * Return : BTI_AT_OK * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ void bti_at_close_port_res(T_BTI_PORT_NB gsm_port_nb) { rvf_send_trace("ATP/GSM : bti_at_close_port_res has been called by GSM . Port nb = ",67, (UINT32) gsm_port_nb,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); /* Memory Deallocation */ rvf_free_buf(port_array[gsm_port_nb]); port_array[gsm_port_nb]=NULL; } /****************************************************************************** * Function name: bti_at_cmd_res * * Description : This function is called by GSM to provide result to BT * * Parameters : gsm_port_nb = number of the gsm port * cmd = command in text format * * Return : BTI_AT_OK or BTI_AT_NOT_SUPPORTED * * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ void bti_at_cmd_res(T_BTI_PORT_NB gsm_port_nb, char * cmd) { T_ATP_TXT_CMD txt_buffer_p; ATP_SEND_TRACE ("ATP/GSM : bti_at_cmd_res has been called by GSM . Result is : ", RV_TRACE_LEVEL_DEBUG_LOW); rvf_send_trace(cmd,(UINT8) strlen(cmd), NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); /* Create a BTF buffer and copy command into. The command must be 0-terminated */ atp_get_buffer(strlen(cmd) + 0x00000001,(void **) &txt_buffer_p); strcpy(txt_buffer_p,cmd); port_array[gsm_port_nb]->cmd_status = CMD_NOT_PENDING; if (atp_send_txt_cmd(atp_gsm_sw_id,(T_ATP_PORT_NB) gsm_port_nb, RESULT_CODE,(T_ATP_TXT_CMD) txt_buffer_p) != RV_OK) { rvf_send_trace("ATP/GSM : Error when sending a command to ATP ",46, NULL_PARAM,RV_TRACE_LEVEL_WARNING, ATP_USE_ID); } } /****************************************************************************** * Function name: bti_at_cmd_req * * Description : This function is called by GSM to provide preliminary result to BT * The end of the result will be issed via bti_at_cmd_res * * Parameters : gsm_port_nb = number of the gsm port * cmd = command in text format * * Return : BTI_AT_OK or BTI_AT_NOT_SUPPORTED * * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ void bti_at_cmd_req(T_BTI_PORT_NB gsm_port_nb, char * cmd) { T_ATP_CMD_TYPE cmd_type; T_ATP_TXT_CMD txt_buffer_p; ATP_SEND_TRACE("ATP/GSM : bti_at_cmd_req has been called by GSM. Code is : ", RV_TRACE_LEVEL_DEBUG_LOW); rvf_send_trace(cmd,(UINT8) strlen(cmd), NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); /* Create a BTF buffer and copy command into. The command must be 0-terminated */ atp_get_buffer(strlen(cmd) + 0x00000001,(void **) &txt_buffer_p); strcpy(txt_buffer_p,cmd); if (port_array[gsm_port_nb]->cmd_status == CMD_PENDING) { cmd_type = PRELIMINARY_RESULT_CODE; } else { cmd_type = UNSOLICITED_RESULT; } if (atp_send_txt_cmd(atp_gsm_sw_id,(T_ATP_PORT_NB) gsm_port_nb,cmd_type, (T_ATP_TXT_CMD) txt_buffer_p) != RV_OK) { rvf_send_trace("ATP/GSM : Error when sending a command to ATP ",46, NULL_PARAM,RV_TRACE_LEVEL_WARNING, ATP_USE_ID); } bti_at_cmd_cnf(gsm_port_nb); // Accept new results } /****************************************************************************** * Function name: bti_at_abort_res * * Description : This function is called by GSM to comfirm a command abort * NOT USED BY ATP YET * * Parameters : gsm_port_nb = number of the gsm port * * Return : BTI_AT_NOT_SUPPORTED * * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ void bti_at_abort_res(T_BTI_PORT_NB gsm_port_nb) { rvf_send_trace("ATP/GSM : bti_at_abort_res has been called by GSM . Ignored . Port nb = ",72, (UINT32) gsm_port_nb,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); // Not implemented yet . Maybe usefull to send a commande back to indicate the abortion has succeede (or failed ...) } /****************************************************************************** * Function name: bti_data_ready_req * * Description : This function is called by GSM to indicate that data are * available for BT PS. * * * Parameters : gsm_port_nb = number of the gsm port * nb_bytes_available = number of bytes of data available * * Return : None * * History : 0.1 (10-Jully-2000) * 0.2 (01-Jan-2001) * ******************************************************************************/ void bti_data_ready_req (T_BTI_PORT_NB gsm_port_nb, unsigned long nb_bytes_available) { UINT32 nb_bytes_left,nb_bytes_to_transmit; UINT8 * data_buffer_p; rvf_send_trace("ATP/GSM : data_ready_req has been called by GSM . Nb Bytes = ",61, (UINT32) nb_bytes_available,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); rvf_send_trace("ATP/GSM : Port Number used by GSM = ",37, (UINT32) gsm_port_nb,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); if (nb_bytes_available !=0) { nb_bytes_left= nb_bytes_available; // number of byte to transmit in this function while(nb_bytes_left > 0) { if (nb_bytes_left > port_array[gsm_port_nb]->bt_max_payload) // Bigger than allowed MFS { nb_bytes_to_transmit = port_array[gsm_port_nb]->bt_max_payload; } else { nb_bytes_to_transmit = nb_bytes_left; } /* This code is removed because of an issue with header and trailer size /* It is temporary remplaced by setting to 0 header and trailer */ /* atp_buffer_size = nb_bytes_to_transmit + port_array[(T_ATP_PORT_NB) gsm_port_nb]->tx_head_size+ // port_array[(T_ATP_PORT_NB) gsm_port_nb]->tx_trail_size; // // rvf_send_trace("ATP/GSM : Buffer_size to send to ATP = ",40, // (UINT32) atp_buffer_size,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); // // rvf_send_trace("ATP/GSM : tx_header size = ",27, // (UINT32) port_array[(T_ATP_PORT_NB) gsm_port_nb]->tx_head_size,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); // // rvf_send_trace("ATP/GSM : tx_trail size = ",27, // (UINT32) port_array[(T_ATP_PORT_NB) gsm_port_nb]->tx_trail_size,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); if (atp_get_buffer_from_tx_mb(atp_gsm_sw_id,gsm_port_nb,atp_buffer_size, (void **) &data_buffer_p) == RV_OK) { /* Copy GSM data rvf_send_trace("ATP/GSM : BT calls bti_get_gsm_data and request nb Bytes = ",59, (UINT32) nb_bytes_to_transmit,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); bti_get_gsm_data(gsm_port_nb,(char *) &(data_buffer_p[port_array[(T_ATP_PORT_NB) gsm_port_nb]->tx_head_size]),nb_bytes_to_transmit); atp_no_copy_send_data(atp_gsm_sw_id,gsm_port_nb,data_buffer_p,nb_bytes_to_transmit); nb_bytes_left -= nb_bytes_to_transmit; port_array[gsm_port_nb]->gsm_tx_data_left = nb_bytes_left; } else { port_array[gsm_port_nb]->gsm_tx_data_left = nb_bytes_left; nb_bytes_left = 0; // Flow control has been activated : wait for FLOW ON flag } */ ///////// START REPLACEMENT CODE //////////////// if (atp_get_buffer_from_tx_mb(atp_gsm_sw_id,gsm_port_nb,nb_bytes_to_transmit, (void **) &data_buffer_p) == RV_OK) { /* Copy GSM data */ rvf_send_trace("ATP/GSM : BT calls bti_get_gsm_data and request nb Bytes = ",59, (UINT32) nb_bytes_to_transmit,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); bti_get_gsm_data(gsm_port_nb,(char *) (data_buffer_p),nb_bytes_to_transmit); atp_no_copy_send_data(atp_gsm_sw_id,gsm_port_nb,data_buffer_p,nb_bytes_to_transmit); nb_bytes_left -= nb_bytes_to_transmit; port_array[gsm_port_nb]->gsm_tx_data_left = nb_bytes_left; } else { port_array[gsm_port_nb]->gsm_tx_data_left = nb_bytes_left; nb_bytes_left = 0; // Flow control has been activated : wait for FLOW ON flag } // for (i=0;i<nb_bytes_to_transmit;i++) // { // rvf_send_trace("ATP/GSM : byte received from GSM = ", // 36, (UINT32) (data_buffer_p[i]) ,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); // } } ///////// END REPLACEMENT CODE //////////////// if (port_array[gsm_port_nb]->gsm_tx_data_left == 0) { ATP_SEND_TRACE("ATP/GSM: BT got all the data from GSM . BT calls bti_data_ready_cnf ",RV_TRACE_LEVEL_DEBUG_LOW); bti_data_ready_cnf(gsm_port_nb); // Acknowledge data copy to GSM } } } /****************************************************************************** * Function name: bti_get_bt_data * * Description : This function is called by GSM to get data from BT side . * Copy is processed by BT side * * Parameters : gsm_port_nb = number of the gsm port * data_buffer = pointer on a buffer in which data can be copied * nb_bytes_to_copy = number of bytes to copy into data_buffer * * Return : None * * * History : 0.1 (10-Jully-2000) * 0.2 (01-Jan-2001) * ******************************************************************************/ void bti_get_bt_data (T_BTI_PORT_NB gsm_port_nb, char * data_buffer, unsigned long nb_bytes_to_copy) { UINT32 data_left,data_read; rvf_send_trace("ATP/GSM : bti_get_bt_data has been called by GSM . Requested nb of data = ", 74, (UINT32) nb_bytes_to_copy ,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); if ( (atp_get_data(atp_gsm_sw_id,gsm_port_nb,(UINT8 *) data_buffer, (UINT32) nb_bytes_to_copy,&data_read,&data_left) != RV_OK) || (data_read != (UINT32) nb_bytes_to_copy)) { ATP_SEND_TRACE("ATP/GSM : Could not get data from BT for GSM",RV_TRACE_LEVEL_ERROR); } // for (i=0;i<nb_bytes_to_copy;i++) // { // rvf_send_trace("ATP/GSM : byte sent to GSM = ", // 29, (UINT32) (data_buffer[i]) ,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); // } } /****************************************************************************** * Function name: bti_data_ready_res * * Description : This function is called by GSM to indicate that it can receive * new data from BT PS * * * Parameters : gsm_port_nb = number of the gsm port * * Return : None * * History : 0.1 (10-Jully-2000) * 0.2 (01-Jan-2001) * ******************************************************************************/ void bti_data_ready_res (T_BTI_PORT_NB gsm_port_nb) { UINT8 * dummy_data_buffer = NULL; UINT32 data_left,data_read; rvf_send_trace("ATP/GSM : bti_data_ready_res has been called by GSM ",52, NULL_PARAM,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); rvf_send_trace("ATP/GSM : port_number = ",25, (UINT32) gsm_port_nb,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); /* Use the function atp_get_data to check if there are still data to transmit */ if (atp_get_data(atp_gsm_sw_id,gsm_port_nb,(UINT8 *) dummy_data_buffer, (UINT32) 0,&data_read,&data_left) != RV_OK) { ATP_SEND_TRACE("ATP/GSM : Could not get number of data to read from BT to GSM ",RV_TRACE_LEVEL_ERROR); } else { rvf_send_trace("ATP/GSM : data_left = ",22, (UINT32) data_left,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); if (data_left != 0) { rvf_send_trace("ATP/GSM : bti_data_ready_ind has been called by BT . Nb_Bytes = ",65, (UINT32) data_left ,RV_TRACE_LEVEL_DEBUG_LOW, ATP_USE_ID); bti_data_ready_ind(gsm_port_nb,(unsigned long) data_left); } else { port_array[gsm_port_nb]->atp_tx_data_activity = ATP_NOT_ACTIVE; ATP_SEND_TRACE("ATP/GSM : ATP is ready to send new data to GSM ." ,RV_TRACE_LEVEL_DEBUG_LOW); } } } /****************************************************************************** * Function name: atp_gsm_init_if * * Description : This function initialise the GSM/BT adaptor * * * * * Return : RV_OK * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ T_RV_RET atp_gsm_init_if(void) { UINT8 i; open_port_pending = ATP_GSM_OPEN_PORT_NOT_PENDING; atp_gsm_sw_id = ATP_INVALID_SWE_ID; initiator_id = ATP_INVALID_SWE_ID; initiator_port_nb = (T_ATP_PORT_NB) 0xFF; current_nb_port = 0; for (i=0;i<ATP_MAX_NB_OF_PORT_SUPPORTED_BY_GSM;i++) { port_array[i]=NULL; } return RV_OK; } /****************************************************************************** * Function name: bti_at_signal_change_req * * Description : This function is called by GSM to provide a new signal line status * to BT * * * Parameters : gsm_port_nb = number of the gsm port * dce_signal = signal value * ring_type_1 = voice, data or fax * ring_type_2 = not used * * Return : None * * History : 0.1 (01-Jan-2001) * ******************************************************************************/ void bti_at_signal_change_req (T_BTI_PORT_NB gsm_port_nb, T_BTI_AT_DCE_SIGNAL dce_signal, T_BTI_AT_RING_TYPE ring_type_1, T_BTI_AT_RING_TYPE ring_type_2) { T_ATP_PORT_SIGNAL old_signal,new_signal = 0; T_ATP_SIGNAL_CHANGE_MASK mask = 0 ; ATP_SEND_TRACE("ATP/GSM : bti_at_signal_change_req has been called by GSM ", RV_TRACE_LEVEL_DEBUG_LOW); atp_get_signal(atp_gsm_sw_id,gsm_port_nb,&old_signal); if ( (dce_signal & BTI_AT_RING_MASK) == BTI_AT_RING_ON) // RING is ON { if ( (old_signal & ATP_RI_UNMASK) == ATP_RI_0) // RING is ON and was previously OFF { T_ATP_RING_TYPE atp_ring_type; T_ATP_SW_NB sender_sw_nb; T_ATP_PORT_STRUCT * port_p; switch (ring_type_1) { /* Transparent data */ case BTI_AT_RING_Async: { atp_ring_type = ATP_DATA_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_OFF -> RING_ON (Transparent data) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } /* Non transparent data */ case BTI_AT_RING_RelAsync: { atp_ring_type = ATP_DATA_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_OFF -> RING_ON (Non-transparent data) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } /* Fax */ case BTI_AT_RING_Fax: { atp_ring_type = ATP_FAX_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_OFF -> RING_ON (Fax) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } /* Voice */ case BTI_AT_RING_Voice: { atp_ring_type = ATP_VOICE_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_OFF -> RING_ON (Voice) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } /* Not used */ default: { atp_ring_type = ATP_NO_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_OFF -> RING_ON (Meaningless) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } } // End of switch /* Get the pointer on the port structure */ if(atp_get_port(atp_gsm_sw_id,gsm_port_nb,&port_p,&sender_sw_nb) != RV_OK) { atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_SIGNAL,ATP_PARAM_ERROR,NULL); return; /* This port does not exist */ } if (atp_ring_type & port_p->port_info[(~sender_sw_nb)].ring_type) { new_signal |= ATP_RI_1; mask |= ATP_RI_UNMASK; } } } else { if ( (old_signal & ATP_RI_UNMASK) == ATP_RI_1) // RING is OFF and was previously ON { T_ATP_RING_TYPE atp_ring_type; T_ATP_SW_NB sender_sw_nb; T_ATP_PORT_STRUCT * port_p; switch (ring_type_1) { /* Transparent data */ case BTI_AT_RING_Async: { atp_ring_type = ATP_DATA_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_ON -> RING_OFF (Transparent data) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } /* Non transparent data */ case BTI_AT_RING_RelAsync: { atp_ring_type = ATP_DATA_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_ON -> RING_OFF (Non-transparent data) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } /* Fax */ case BTI_AT_RING_Fax: { atp_ring_type = ATP_FAX_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_ON -> RING_OFF (Fax) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } /* Voice */ case BTI_AT_RING_Voice: { atp_ring_type = ATP_VOICE_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_ON -> RING_OFF (Voice) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } /* Not used */ default: { atp_ring_type = ATP_NO_RING_TYPE; ATP_SEND_TRACE("ATP/GSM : RING_ON -> RING_OFF (Meaningless) " ,RV_TRACE_LEVEL_DEBUG_LOW); break; } } // End of switch /* Get the pointer on the port structure */ if(atp_get_port(atp_gsm_sw_id,gsm_port_nb,&port_p,&sender_sw_nb) != RV_OK) { atp_error_switch(ATP_ERROR_FAILED_TO_HANDLE_SIGNAL,ATP_PARAM_ERROR,NULL); return; /* This port does not exist */ } if (atp_ring_type & port_p->port_info[(~sender_sw_nb)].ring_type) { new_signal |= ATP_RI_0; mask |= ATP_RI_UNMASK; } } } if ( (dce_signal & BTI_AT_DCD_MASK) == BTI_AT_DCD_ON) // DCD is ON { if ( (old_signal & ATP_DCD_UNMASK) == ATP_DCD_0) // DCD is ON and was previously OFF { new_signal |= ATP_DCD_1; mask |= ATP_DCD_UNMASK; ATP_SEND_TRACE("ATP/GSM : DCD_OFF -> DCD_ON ", RV_TRACE_LEVEL_DEBUG_LOW); } } else { if ( (old_signal & ATP_DCD_UNMASK) == ATP_DCD_1) // DCD is OFF and was previously ON { new_signal |= ATP_DCD_0; mask |= ATP_DCD_UNMASK; ATP_SEND_TRACE("ATP/GSM : DCD_ON -> DCD_OFF ", RV_TRACE_LEVEL_DEBUG_LOW); } } if (mask != 0x00) { atp_set_signal(atp_gsm_sw_id,gsm_port_nb,new_signal,mask); } } /****************************************************************************** * Function name: atp_gsm_init_port * * Description : This function initialise the variable related to a port * * * * * Return : RV_OK * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ T_RV_RET atp_gsm_init_port(T_ATP_GSM_PORT_STRUCT * port_p) { port_p->cmd_status = CMD_NOT_PENDING; port_p->gsm_tx_data_left = 0; port_p->atp_tx_data_activity = ATP_NOT_ACTIVE; port_p->bt_max_payload = temp_bt_max_payload; return RV_OK; } /****************************************************************************** * Function name: atp_gsm_get_new_port_nb * * Description : Provide a new available port number if possible. Otherwise, return * error * * * * Return : RV_OK * * History : 0.1 (10-Jully-2000) * ******************************************************************************/ T_RV_RET atp_gsm_get_new_port_nb(UINT8 * port_nb) { UINT8 i; for(i=0;i<ATP_MAX_NB_OF_PORT_SUPPORTED_BY_GSM;i++) { if (port_array[i] == NULL) { *port_nb = i; return RV_OK; } } *port_nb = 0xFF; return RV_NOT_SUPPORTED; }