FreeCalypso > hg > fc-magnetite
view src/cs/services/atp/atp_uart_handle_msg.c @ 95:48792a467305
doc/C139-Howto improved a bit
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 03 Oct 2016 17:41:24 +0000 |
parents | 945cf7f506b2 |
children |
line wrap: on
line source
/********************************************************************************/ /* */ /* 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 ********************/