FreeCalypso > hg > tcs211-fcmodem
diff chipsetsw/services/atp/atp_uart_handle_msg.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chipsetsw/services/atp/atp_uart_handle_msg.c Mon Jun 01 03:24:05 2015 +0000 @@ -0,0 +1,1058 @@ +/********************************************************************************/ +/* */ +/* File Name: atp_uart_handle_msg.c */ +/* */ +/* Purpose: This file contains the internal function related to */ +/* the ATP-UART interface and used to handle incoming */ +/* messages */ +/* */ +/* Note: None. */ +/* */ +/* Revision History: */ +/* 10/04/01 Pascal Pompei */ +/* - Create. */ +/* */ +/* (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved. */ +/* */ +/********************************************************************************/ +#include "atp/atp_i.h" +#include "atp/atp_uart_i.h" +#include "rvm/rvm_use_id_list.h" + + +/********************************************************************************/ +/* */ +/* Function Name: atp_uart_handle_msg */ +/* */ +/* Purpose: This function handles incoming messages available from */ +/* the mailbox dedicated to the ATP-UART interface. */ +/* */ +/* Input Parameters: None. */ +/* */ +/* Output Parameters: None. */ +/* */ +/* Global Parameters: None. */ +/* */ +/* Notes: The GSM protocol stack must be started first. */ +/* Nevertheless, note that incoming data calls are not */ +/* supported for now. Moreover, the AT Parser is alerted */ +/* that the call is terminated by receiving an 'Ok' or a */ +/* 'No Carrier' final result code only. At last, the GSM */ +/* protocol stack is initialized by invoking the */ +/* following AT commands: */ +/* ATE0 : Echo mode switched off, */ +/* AT+CFUN=1 : Set Phone Functionality (Full), */ +/* AT+COPS=0 : Operator Selection. */ +/* */ +/* Revision History: */ +/* 10/04/01 Pascal Pompei */ +/* - Create. */ +/* */ +/********************************************************************************/ +T_ATP_UART_ERROR_CODES atp_uart_handle_msg (void) +{ + /* Declare local variables. */ + UINT16 event_pending = 0x0000; + UINT32 in_buffer_size = 0x00000000; + BOOLEAN echo_mode_switched_off = FALSE; + BOOLEAN error_occurred = FALSE; + T_ATP_CALLBACK return_path = {0x00, \ + NULL}; + T_ATP_ENTITY_MODE mode = {CMD_SUPPORT_ON, \ + TXT_MODE, \ + COPY_ON}; + T_ATP_SW_ENTITY_NAME name = ATP_GSM_NAME; + +/********************** atp_uart_handle_msg function begins *********************/ + + /* First, wait until the COM port is activated. */ + while ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).com_port_handle == INVALID_HANDLE_VALUE) + { + + /* Wait for the next event(s) of interest. */ + event_pending = rvf_wait (ATP_UART_ALL_EVENT_FLAGS, + 0x00000000); + + /* If an expected event occurred, then get the associated message from */ + /* the mailbox dedicated to the ATP-UART interface. */ + if (event_pending & ATP_UART_EXPECTED_EVENT) + { + + /* Declare a local block variable. */ + T_RV_HDR *incoming_message_p = NULL; + + /* Get the incoming message from the mailbox dedicated to the */ + /* ATP-UART interface. */ + incoming_message_p = (T_RV_HDR *) rvf_read_mbox (ATP_UART_MAILBOX); + + /* Check whether the incoming message is valid. */ + if (incoming_message_p == NULL) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). Invalid event occurred "); + return (RVM_INTERNAL_ERR); + } + switch (incoming_message_p->msg_id) + { + + /* 'ATP-UART Open COM Port'. */ + case ATP_UART_OPEN_COM_PORT: + { + + /* Declare a local block variable. */ + UINT8 gsm_basic_init_p[] = {'A', 'T', 'E', '0', \ + ATP_CR_CHARACTER}; + + /* Open the COM port whose number and baud rate are */ + /* specified. If any error occurred, then call the */ + /* function used whenever any unrecoverable error */ + /* occurs and abort. */ + if (atp_uart_create_com_port ((unsigned char) (((T_ATP_UART_OPEN_COM_PORT *) (incoming_message_p))->com_port), \ + ((T_ATP_UART_OPEN_COM_PORT *) (incoming_message_p))->baud_rate) != RV_OK) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). Unable to activate the COM port "); + return (RVM_INTERNAL_ERR); + } + rvf_send_trace (" ATP-UART (handle_msg). COM port properly opened ", + 50, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Configure the GSM especially not to echo characters */ + /* during 'Command State' and 'Online Command State'. */ + /* If any error occurred, then call the function used */ + /* whenever any unrecoverable error occurs and abort. */ + if (atp_uart_write_com_port (gsm_basic_init_p, \ + sizeof (gsm_basic_init_p)) != RV_OK) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). GSM configuration failed "); + return (RVM_INTERNAL_ERR); + } + break; + } + + /* Unexpected message. */ + default: + { + rvf_send_trace (" ATP-UART (handle_msg). Unexpected message received ", + 53, + incoming_message_p->msg_id, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + } + (void) rvf_free_buf ((T_RVF_BUFFER *) (incoming_message_p)); + } + } + + /* Then, wait for the echo mode being switched off. */ + while (echo_mode_switched_off == FALSE) + { + + /* Wait for the next event(s) of interest. */ + event_pending = rvf_wait (ATP_UART_ALL_EVENT_FLAGS, + 0x00000001); + + /* If an expected event occurred, then get the associated message from */ + /* the mailbox dedicated to the ATP-UART interface. */ + if (event_pending & ATP_UART_EXPECTED_EVENT) + { + + /* Declare a local block variable. */ + T_RV_HDR *incoming_message_p = NULL; + + /* Get the incoming message from the mailbox dedicated to the */ + /* ATP-UART interface. */ + incoming_message_p = (T_RV_HDR *) rvf_read_mbox (ATP_UART_MAILBOX); + + /* Check whether the incoming message is valid. */ + if (incoming_message_p == NULL) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). Invalid event occurred "); + return (RVM_INTERNAL_ERR); + } + rvf_send_trace (" ATP-UART (handle_msg). Unexpected message received ", + 53, + incoming_message_p->msg_id, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + (void) rvf_free_buf ((T_RVF_BUFFER *) (incoming_message_p)); + } + + /* Now, attempt forwarding data to the AT Parser. Thus, initialize the */ + /* amount of data to be forwarded. */ + in_buffer_size = (UINT32) (ATP_UART_MAX_PACKET_SIZE - \ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left); + + /* Then, wait for data from the COM port. If any error occurred, then */ + /* abort. */ + if (atp_uart_read_com_port (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[(gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left]), \ + &in_buffer_size) == RV_OK) + { + + /* Declare local block variables. */ + UINT32 in_buffer_begin = 0x00000000; + UINT32 in_buffer_end = 0x00000000; + T_ATP_CMD *cmd_info_p = NULL; + T_ATP_CMD_NB cmd_nb = 0x0000; + T_ATP_CMD_TYPE cmd_type = UNKNOWN; + + /* Send every 'Text Command' to the AT Parser separately. */ + while (in_buffer_end < in_buffer_size) + { + + /* Skip leading <CR> and <LF> characters. */ + for (in_buffer_begin = in_buffer_end; + (in_buffer_begin < in_buffer_size) && \ + (((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin] == ATP_LF_CHARACTER) || \ + ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin] == ATP_CR_CHARACTER)); + in_buffer_begin++) + { + } + + /* Get the 'Text Command' length by searching for the ending */ + /* <CR> character. */ + for (in_buffer_end = in_buffer_begin; + (in_buffer_end < in_buffer_size) && \ + ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_end] != ATP_CR_CHARACTER); + in_buffer_end++) + { + } + + /* Abort whether no ending <CR> character found. */ + if ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_end] != ATP_CR_CHARACTER) + { + + /* Update the number of bytes left. */ + in_buffer_size -= in_buffer_begin; + + /* Defrag. */ + memcpy ((void *) ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p), + (void *) (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin])), + in_buffer_size); + + /* Update the number of bytes left. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left = in_buffer_size; + break; + } + + /* Otherwise, replace the ending <CR> character by NULL. */ + /* Indeed, such a 'Text Command' must be a NULL-terminated */ + /* string. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_end++] = '\x00'; + rvf_send_trace (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin]), + (UINT8) (in_buffer_end - in_buffer_begin - 0x01), + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Check whether the 'Text Command' is a final result code. */ + if ((atp_translate_txt_to_cmd (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin]), \ + UNKNOWN, \ + &cmd_type, \ + &cmd_nb, \ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id, \ + &cmd_info_p) == RV_OK) && \ + (cmd_type == RESULT_CODE)) + { + + /* If needed, de-allocate the command-related information. */ + if (cmd_info_p != NULL) + { + (void) rvf_free_buf ((T_RVF_BUFFER *) (cmd_info_p)); + } + + /* Check whether the 'Text Command' corresponds to the 'OK' */ + /* final result code. */ + if (cmd_nb == ATP_OK_NB) + { + rvf_send_trace (" ATP-UART (handle_msg). Echo mode switched off ", + 48, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* The echo mode is properly switched off. */ + echo_mode_switched_off = TRUE; + break; + } + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). Echo mode not switched off "); + return (RVM_INTERNAL_ERR); + } + + /* If needed, de-allocate the command-related information. */ + if (cmd_info_p != NULL) + { + (void) rvf_free_buf ((T_RVF_BUFFER *) (cmd_info_p)); + } + } + continue; + } + rvf_send_trace (" ATP-UART (handle_msg). Failed in getting data from the COM port ", + 66, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + } + + /* At last, initialize the remainder of the return path in order to receive */ + /* events from the AT parser. */ + return_path.addr_id = gbl_atp_uart_ctrl_blk_p->addr_id; + + /* Register the ATP-UART interface to the AT Parser. If any error occurred, */ + /* then call the function used whenever any unrecoverable error occurs and */ + /* abort. */ + if (atp_reg (name, \ + return_path, \ + mode, \ + &((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id)) != RV_OK) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). Registration failed "); + return (RVM_INTERNAL_ERR); + } + rvf_send_trace (" ATP-UART (handle_msg). Registration completed ", + 48, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Now, wait for the next events to be handled as long as no error occurs. */ + while (error_occurred == FALSE) + { + + /* Wait for the next event(s) of interest. */ + event_pending = rvf_wait (ATP_UART_ALL_EVENT_FLAGS, + 0x00000001); + + /* If an expected event occurred, then get the associated message from */ + /* the mailbox dedicated to the ATP-UART interface. */ + if (event_pending & ATP_UART_EXPECTED_EVENT) + { + + /* Declare a local block variable. */ + T_RV_HDR *incoming_message_p = NULL; + + /* Get the incoming message from the mailbox dedicated to the */ + /* ATP-UART interface. */ + incoming_message_p = (T_RV_HDR *) rvf_read_mbox (ATP_UART_MAILBOX); + + /* Check whether the incoming message is valid. */ + if (incoming_message_p == NULL) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). Invalid event occurred "); + return (RVM_INTERNAL_ERR); + } + switch (incoming_message_p->msg_id) + { + + /* 'ATP Open Port Indication'. */ + case ATP_OPEN_PORT_IND: + { + + /* Declare local block variables. */ + T_ATP_PORT_INFO gsm_port_info = {NOT_DEFINED_CONFIG, \ + ATP_NO_RING_TYPE, \ + ATP_ALL_THE_SIGNAL_UNMASK, \ + 0x0000}; + T_ATP_NO_COPY_INFO gsm_no_copy_info = {RVF_INVALID_MB_ID, \ + RVF_INVALID_MB_ID, \ + TX_HEADER_OFF, \ + 0x00, \ + 0x00, \ + RX_HEADER_OFF, \ + 0x00, \ + 0x00, \ + NORMAL_PACKET}; + T_ATP_CUSTOM_FROM_GSM_INFO *gsm_custom_info_p = NULL; + + rvf_send_trace (" ATP-UART (handle_msg). 'ATP Open Port Indication' received ", + 61, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_MEDIUM, + ATP_USE_ID); + + /* Set custom information associated with the pseudo */ + /* GSM Software Entity. If insufficient resources, then */ + /* call the function used whenever any unrecoverable */ + /* error occurs and abort. */ + if (rvf_get_buf (gbl_atp_uart_ctrl_blk_p->mb_id, \ + sizeof (T_ATP_CUSTOM_FROM_GSM_INFO), \ + (T_RVF_BUFFER **) (&gsm_custom_info_p)) == RVF_RED) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_MEMORY_ERR, + " ATP-UART (handle_msg). Insufficient resources "); + return (RVM_MEMORY_ERR); + } + gsm_custom_info_p->custom_type = ATP_FROM_GSM_INFO; + gsm_custom_info_p->optimal_gsm_max_packet_size = ATP_UART_MAX_PACKET_SIZE; + + /* Open the virtual modem port with the AT Parser. If */ + /* any error occurred, then de-allocate custom */ + /* information associated with the pseudo GSM Software */ + /* Entity, call the function used whenever any */ + /* unrecoverable error occurs and abort. */ + if (atp_open_port_rsp (((T_ATP_OPEN_PORT_IND *) (incoming_message_p))->initiator_id, \ + ((T_ATP_OPEN_PORT_IND *) (incoming_message_p))->initiator_port_nb, \ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id, \ + ATP_UART_GSM_PORT_NB, \ + gsm_port_info, \ + gsm_no_copy_info, \ + (T_ATP_CUSTOM_INFO *) (gsm_custom_info_p), \ + OPEN_PORT_OK) != RV_OK) + { + (void) rvf_free_buf ((T_RVF_BUFFER *) (gsm_custom_info_p)); + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). Unable to open the virtual modem port with the AT Parser "); + return (RVM_INTERNAL_ERR); + } + rvf_send_trace (" ATP-UART (handle_msg). Virtual modem port properly established with the AT Parser ", + 84, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* The virtual modem port opened with the AT Parser is */ + /* now properly initialized. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).virtual_modem_port_established = TRUE; + + /* If needed, de-allocate custom information contained */ + /* in the 'ATP Open Port Indication'. */ + if (((T_ATP_OPEN_PORT_IND *) incoming_message_p)->custom_info_p != NULL) + { + rvf_free_buf ((T_RVF_BUFFER *) (((T_ATP_OPEN_PORT_IND *) (incoming_message_p))->custom_info_p)); + } + break; + } + + /* 'ATP Text Command Ready'. */ + case ATP_TXT_CMD_RDY: + { + + /* Declare local block variables. */ + UINT8 txt_cmd_length = 0x00; + T_ATP_TXT_CMD_RDY *txt_cmd_rdy_p = (T_ATP_TXT_CMD_RDY *) (incoming_message_p); + + rvf_send_trace (" ATP-UART (handle_msg). 'ATP Text Command Ready' received ", + 59, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_MEDIUM, + ATP_USE_ID); + + /* If any error occurred, then abort. */ + if ((txt_cmd_rdy_p->port_nb != ATP_UART_GSM_PORT_NB) || \ + (txt_cmd_rdy_p->txt_cmd_p == NULL)) + { + rvf_send_trace (" ATP-UART (handle_msg). 'Text Command' transfer failed ", + 56, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + + /* Get the length of the 'Text Command'. Note that such */ + /* a 'Text Command' is a NULL-terminated string. */ + txt_cmd_length = (UINT8) (strlen (txt_cmd_rdy_p->txt_cmd_p)); + rvf_send_trace (txt_cmd_rdy_p->txt_cmd_p, + txt_cmd_length, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Forward the 'Text Command' to the COM port. If any */ + /* error occurred, then proceed. */ + txt_cmd_rdy_p->txt_cmd_p[txt_cmd_length] = ATP_CR_CHARACTER; + if (atp_uart_write_com_port ((UINT8 *) (txt_cmd_rdy_p->txt_cmd_p), \ + (txt_cmd_length + 0x00000001)) != RV_OK) + { + rvf_send_trace (" ATP-UART (handle_msg). 'Text Command' transfer failed ", + 56, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + } + + /* De-allocate the data buffer provided with the 'ATP */ + /* Command Ready'. */ + (void) rvf_free_buf ((T_RVF_BUFFER *) (txt_cmd_rdy_p->txt_cmd_p)); + break; + } + + /* 'ATP No Copy Data Ready'. */ + case ATP_NO_COPY_DATA_RDY: + { + + /* Declare a local block variable. */ + T_ATP_NO_COPY_DATA_RDY *no_copy_data_rdy_p = (T_ATP_NO_COPY_DATA_RDY *) (incoming_message_p); + + rvf_send_trace (" ATP-UART (handle_msg). 'ATP No Copy Data Ready' received ", + 59, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_MEDIUM, + ATP_USE_ID); + + /* If any error occurred, then abort. */ + if ((no_copy_data_rdy_p->port_nb != ATP_UART_GSM_PORT_NB) || \ + (no_copy_data_rdy_p->atp_buffer_p == NULL)) + { + rvf_send_trace (" ATP-UART (handle_msg). Data transfer to the COM port failed ", + 62, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + rvf_send_trace (" ATP-UART (handle_msg). Data size ", + 35, + no_copy_data_rdy_p->buffer_size, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Forward data to the COM port. If any error occurred, */ + /* then proceed. */ + if (atp_uart_write_com_port (no_copy_data_rdy_p->atp_buffer_p, \ + no_copy_data_rdy_p->buffer_size) != RV_OK) + { + rvf_send_trace (" ATP-UART (handle_msg). Data transfer to the COM port failed ", + 62, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + } + + /* De-allocate the data buffer provided with the 'ATP */ + /* No Copy Data Ready'. */ + (void) rvf_free_buf ((T_RVF_BUFFER *) (no_copy_data_rdy_p->atp_buffer_p)); + break; + } + + /* 'ATP Signal Changed'. */ + case ATP_SIGNAL_CHANGED: + { + + /* Declare a local block variable. */ + T_ATP_SIGNAL_CHANGED *signal_changed_p = (T_ATP_SIGNAL_CHANGED *) (incoming_message_p); + + rvf_send_trace (" ATP-UART (handle_msg). 'ATP Signal Changed' received ", + 55, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_MEDIUM, + ATP_USE_ID); + + /* If any error occurred, then abort. */ + if (signal_changed_p->port_nb != ATP_UART_GSM_PORT_NB) + { + rvf_send_trace (" ATP-UART (handle_msg). Invalid port number ", + 45, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + rvf_send_trace (" ATP-UART (handle_msg). Bit mask ", + 34, + signal_changed_p->signal, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Update the RS232 control signals associated with the */ + /* virtual modem port. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).control_signals = signal_changed_p->signal; + break; + } + + /* 'ATP Port Mode Changed'. */ + case ATP_PORT_MODE_CHANGED: + { + + /* Declare a local block variable. */ + T_ATP_PORT_MODE_CHANGED *port_mode_changed_p = (T_ATP_PORT_MODE_CHANGED *) (incoming_message_p); + + rvf_send_trace (" ATP-UART (handle_msg). 'ATP Port Mode Changed' received ", + 58, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_MEDIUM, + ATP_USE_ID); + + /* If any error occurred, then abort. */ + if (port_mode_changed_p->port_nb != ATP_UART_GSM_PORT_NB) + { + rvf_send_trace (" ATP-UART (handle_msg). Invalid port number ", + 45, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + rvf_send_trace (" ATP-UART (handle_msg). Mode ", + 30, + port_mode_changed_p->mode, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* If the virtual modem port is in 'Data' mode, then */ + /* send the escape sequence first. */ + if ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).virtual_modem_port_mode == ATP_PORT_DATA_MODE) + { + + /* Forward the escape sequence to the COM port. If */ + /* any error occurred, then call the function used */ + /* whenever any unrecoverable error occurs and */ + /* abort. */ + if (atp_uart_write_com_port ((UINT8 *) (ATP_ESCAPE_SEQUENCE), \ + (sizeof (ATP_ESCAPE_SEQUENCE) - 0x00000001)) != RV_OK) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_INTERNAL_ERR, + " ATP-UART (handle_msg). 'Escape sequence' not transmitted "); + return (RVM_INTERNAL_ERR); + } + rvf_send_trace (" ATP-UART (handle_msg). 'Escape sequence' properly transmitted ", + 64, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + } + + /* Update the mode of the virtual modem port. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).virtual_modem_port_mode = port_mode_changed_p->mode; + break; + } + + /* 'ATP Port Closed'. */ + case ATP_PORT_CLOSED: + { + rvf_send_trace (" ATP-UART (handle_msg). 'ATP Port Closed' received ", + 52, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_MEDIUM, + ATP_USE_ID); + + /* If any error occurred, then abort. */ + if (((T_ATP_PORT_CLOSED *) (incoming_message_p))->port_nb != ATP_UART_GSM_PORT_NB) + { + rvf_send_trace (" ATP-UART (handle_msg). Invalid port number ", + 45, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + + /* The virtual modem port opened with the AT Parser is */ + /* now closed. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).virtual_modem_port_established = FALSE; + break; + } + + /* 'ATP-UART Start GSM'. */ + case ATP_UART_START_GSM: + { + + /* Declare a local block variable. */ + UINT8 gsm_init_p[] = {'A', 'T', '+', 'C', 'F', 'U', 'N', '=', '1', ';', '+', 'C', 'O', 'P', 'S', '=', '0', \ + ATP_CR_CHARACTER}; + + rvf_send_trace (" ATP-UART (handle_msg). 'ATP-UART Start GSM' received ", + 55, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_MEDIUM, + ATP_USE_ID); + + /* If any error occurred, then abort. */ + if (atp_uart_write_com_port (gsm_init_p, \ + sizeof (gsm_init_p)) != RV_OK) + { + rvf_send_trace (" ATP-UART (handle_msg). Unable to start the GSM protocol stack ", + 64, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + break; + } + + /* Unexpected message. */ + default: + { + rvf_send_trace (" ATP-UART (handle_msg). Unexpected message received ", + 53, + incoming_message_p->msg_id, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + } + (void) rvf_free_buf ((T_RVF_BUFFER *) (incoming_message_p)); + } + + /* Now, if the flow control is activated, then proceed without getting */ + /* any data from the COM port. */ + if (((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).control_signals & ATP_RX_FLOW_UNMASK) == ATP_RX_FLOW_ON) + { + continue; + } + + /* Otherwise, attempt forwarding data to the AT Parser. Thus, */ + /* initialize the amount of data to be forwarded. */ + in_buffer_size = (UINT32) (ATP_UART_MAX_PACKET_SIZE - \ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left); + + /* Then, wait for data from the COM port. If any error occurred, then */ + /* abort. */ + if (atp_uart_read_com_port (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[(gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left]), \ + &in_buffer_size) != RV_OK) + { + rvf_send_trace (" ATP-UART (handle_msg). Failed in getting data from the COM port ", + 66, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + continue; + } + + /* Take new data into account. */ + in_buffer_size = (UINT32) ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left + \ + in_buffer_size); + + /* If no virtual modem port established with the AT Parser or if no */ + /* data pending for transmission to the AT Parser, then update the */ + /* number of bytes left and proceed. */ + if (((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).virtual_modem_port_established == FALSE) || \ + (in_buffer_size == 0x00000000)) + { + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left = in_buffer_size; + continue; + } + + /* Otherwise, re-initialize the number of bytes left. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left = 0x00000000; + rvf_send_trace (" ATP-UART (handle_msg). Get data from the COM port ", + 52, + in_buffer_size, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* At last, depending on the mode, transfert data from the COM port as */ + /* 'Text Command' or 'Data'. */ + if ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).virtual_modem_port_mode == ATP_PORT_CMD_MODE) + { + + /* Declare local block variables. */ + UINT32 in_buffer_begin = 0x00000000; + UINT32 in_buffer_end = 0x00000000; + T_ATP_CMD *cmd_info_p = NULL; + T_ATP_CMD_NB cmd_nb = 0x0000; + T_ATP_TXT_CMD txt_cmd_p = NULL; + T_ATP_CMD_TYPE cmd_type = UNKNOWN; + + /* Send every 'Text Command' to the AT Parser separately. */ + while (in_buffer_end < in_buffer_size) + { + + /* Skip leading <CR> and <LF> characters. */ + for (in_buffer_begin = in_buffer_end; + (in_buffer_begin < in_buffer_size) && \ + (((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin] == ATP_LF_CHARACTER) || \ + ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin] == ATP_CR_CHARACTER)); + in_buffer_begin++) + { + } + + /* Get the 'Text Command' length by searching for the ending */ + /* <CR> character. */ + for (in_buffer_end = in_buffer_begin; + (in_buffer_end < in_buffer_size) && \ + ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_end] != ATP_CR_CHARACTER); + in_buffer_end++) + { + } + + /* Abort whether no ending <CR> character found. */ + if ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_end] != ATP_CR_CHARACTER) + { + + /* Update the number of bytes left. */ + in_buffer_size -= in_buffer_begin; + + /* Defrag. */ + memcpy ((void *) ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p), + (void *) (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin])), + in_buffer_size); + + /* Update the number of bytes left. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left = in_buffer_size; + break; + } + + /* Otherwise, replace the ending <CR> character by NULL. */ + /* Indeed, such a 'Text Command' must be a NULL-terminated */ + /* string. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_end++] = '\x00'; + + /* Allocate memory in order to forward the 'Text Command' to */ + /* the AT Parser. If insufficient resources, then call the */ + /* function used whenever any unrecoverable error occurs and */ + /* abort. */ + if (rvf_get_buf (gbl_atp_uart_ctrl_blk_p->mb_id, \ + (in_buffer_end - in_buffer_begin), \ + (T_RVF_BUFFER **) (&txt_cmd_p)) == RVF_RED) + { + ATP_UART_UNRECOVERABLE_ERROR (RVM_MEMORY_ERR, + " ATP-UART (handle_msg). Insufficient resources "); + break; + } + + /* Copy the 'Text Command'. */ + memcpy ((void *) (txt_cmd_p), + (void *) (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_begin])), + (in_buffer_end - in_buffer_begin)); + rvf_send_trace (txt_cmd_p, + (UINT8) (in_buffer_end - in_buffer_begin - 0x01), + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Check whether the 'Text Command' is a final or an */ + /* unsolicited result code. */ + if ((atp_translate_txt_to_cmd (txt_cmd_p, \ + UNKNOWN, \ + &cmd_type, \ + &cmd_nb, \ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id, \ + &cmd_info_p) == RV_OK) && \ + (cmd_type == RESULT_CODE)) + { + + /* If the 'Text Command' corresponds to the 'Connect' final */ + /* result code, then turn the 'Data Carrier Detect' on */ + /* before sending it to the AT Parser (See ITU-T */ + /* Recommendation V.250 ter page 32). If any error */ + /* occurred, then de-allocate the 'Text Command' and abort. */ + if (cmd_nb == ATP_CONNECT_NB) + { + if (atp_set_signal ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id, \ + ATP_UART_GSM_PORT_NB, \ + ATP_DCD_1, \ + ATP_DCD_UNMASK) != RV_OK) + { + (void) rvf_free_buf ((T_RVF_BUFFER *) (txt_cmd_p)); + + /* If needed, de-allocate the command-related */ + /* information. */ + if (cmd_info_p != NULL) + { + (void) rvf_free_buf ((T_RVF_BUFFER *) (cmd_info_p)); + } + rvf_send_trace (" ATP-UART (handle_msg). 'Data Carrier Detect' not turned on ", + 61, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + rvf_send_trace (" ATP-UART (handle_msg). 'Data Carrier Detect' properly turned on ", + 66, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + } + } + + /* Otherwise, the 'Text Command' is recognized as a preliminary */ + /* result code. */ + else + { + cmd_type = PRELIMINARY_RESULT_CODE; + } + + /* If needed, de-allocate the command-related information. */ + if (cmd_info_p != NULL) + { + (void) rvf_free_buf ((T_RVF_BUFFER *) (cmd_info_p)); + } + + /* Forward the 'Text Command' to the AT Parser. If any error */ + /* occurred, then de-allocate the 'Text Command' and abort. */ + if (atp_send_txt_cmd ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id, \ + ATP_UART_GSM_PORT_NB, \ + cmd_type, \ + txt_cmd_p) != RV_OK) + { + (void) rvf_free_buf ((T_RVF_BUFFER *) (txt_cmd_p)); + rvf_send_trace (" ATP-UART (handle_msg). 'Text Command' failed ", + 47, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + break; + } + } + } + else + { + + /* Declare local block variables. */ + UINT8 no_carrier_count = 0x00; + UINT8 no_carrier_p[] = {ATP_CR_CHARACTER, \ + ATP_LF_CHARACTER, \ + 'N', 'O', ' ', 'C', 'A', 'R', 'R', 'I', 'E', 'R', \ + ATP_CR_CHARACTER, \ + ATP_LF_CHARACTER}; + UINT8 ok_count = 0x00; + UINT8 ok_p[] = {ATP_CR_CHARACTER, \ + ATP_LF_CHARACTER, \ + 'O', 'K', \ + ATP_CR_CHARACTER, \ + ATP_LF_CHARACTER}; + UINT32 in_buffer_count = 0x00000000; + UINT32 in_data_size = 0x00000000; + T_ATP_CMD_NB result_code_nb = ATP_MAX_NB_OF_RESULT_CODES; + + /* First, search for 'Ok' or 'No Carrier' final result codes. */ + for (in_buffer_count = 0x00000000, \ + in_data_size = in_buffer_size; + in_buffer_count < in_buffer_size; + in_buffer_count++) + { + + /* Search for an 'Ok' final result code. */ + if ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_count] == ok_p[ok_count]) + { + + /* 'Ok' final result code detected. */ + if (++ok_count == sizeof (ok_p)) + { + result_code_nb = ATP_OK_NB; + rvf_send_trace (" ATP-UART (handle_msg). 'Ok' final result code detected ", + 57, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Send the remainder to the AT Parser. */ + in_data_size = in_buffer_count - (sizeof (ok_p) - 0x00000001); + break; + } + } + else + { + ok_count = 0x00; + } + + /* Search for a 'No Carrier' final result code. */ + if ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_count] == no_carrier_p[no_carrier_count]) + { + + /* 'No Carrier' final result code detected. */ + if (++no_carrier_count == sizeof (no_carrier_p)) + { + result_code_nb = ATP_NO_CARRIER_NB; + rvf_send_trace (" ATP-UART (handle_msg). 'No Carrier' final result code detected ", + 65, + NULL_PARAM, + RV_TRACE_LEVEL_DEBUG_LOW, + ATP_USE_ID); + + /* Send the remainder to the AT Parser. */ + in_data_size = in_buffer_count - (sizeof (no_carrier_p) - 0x00000001); + break; + } + } + else + { + no_carrier_count = 0x00; + } + } + + /* Then, check for some bytes to be forwarded data to the AT */ + /* Parser. */ + if (in_data_size > 0x00000000) + { + + /* Forward data to the AT Parser. If any error occurred, then */ + /* proceed. */ + if (atp_send_data ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id, \ + ATP_UART_GSM_PORT_NB, \ + (void *) ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p), \ + in_data_size, \ + &((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left)) != RV_OK) + { + rvf_send_trace (" ATP-UART (handle_msg). Data transfer to the AT Parser failed ", + 63, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + } + + /* Update the number of bytes left. */ + in_data_size -= (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left; + in_buffer_size -= in_data_size; + + /* Check whether some bytes left to be sent to the AT Parser. */ + if ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left > 0x00000000) + { + + /* Defrag. */ + memcpy ((void *) ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p), + (void *) (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_data_size])), + in_buffer_size); + + /* Update the number of bytes left. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left = in_buffer_size; + continue; + } + } + + /* At last, check whether an 'Ok' or a 'No Carrier' final result */ + /* code was detected. */ + if (result_code_nb != ATP_MAX_NB_OF_RESULT_CODES) + { + + /* Turn the 'Data Carrier Detect' off before sending it to the */ + /* AT Parser (See ITU-T Recommendation V.250 ter page 37). */ + /* However, proceed whether any error occurred. */ + if (((atp_set_signal ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id, \ + ATP_UART_GSM_PORT_NB, \ + ATP_DCD_0, \ + ATP_DCD_UNMASK) != RV_OK) || \ + (atp_send_cmd ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).atp_id, \ + ATP_UART_GSM_PORT_NB, \ + RESULT_CODE, \ + result_code_nb, \ + NULL) != RV_OK))) + { + rvf_send_trace (" ATP-UART (handle_msg). Final result code not transmitted ", + 59, + NULL_PARAM, + RV_TRACE_LEVEL_WARNING, + ATP_USE_ID); + } + + /* Update the number of bytes left. */ + in_buffer_size -= in_buffer_count; + + /* Update the mode of the virtual modem port. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).virtual_modem_port_mode = ATP_PORT_CMD_MODE; + } + + /* If some data left, then defrag. */ + memcpy ((void *) ((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p), + (void *) (&((gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).in_buffer_p[in_buffer_count])), + in_buffer_size); + + /* Update the number of bytes left. */ + (gbl_atp_uart_ctrl_blk_p->conn_ctrl_blk).nb_bytes_left = in_buffer_size; + } + } + return (RVM_OK); + +} /********************* End of atp_uart_handle_msg function ********************/