view src/cs/services/etm/etm_at.c @ 600:8f50b202e81f

board preprocessor conditionals: prep for more FC hw in the future This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and all preprocessor conditionals throughout the code base that tested for it, replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These new symbols are specified as follows: CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by Mother Mychaela under the FreeCalypso trademark. This family will include modem products (repackagings of the FCDEV3B, possibly with RFFE or even RF transceiver changes), and also my desired FreeCalypso handset product. CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products (which will be firmware-compatible with the FCDEV3B if they use TI Rita transceiver, or will require a different fw build if we switch to one of Silabs Aero transceivers), but not the handset product. Right now this CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize everything dealing with MCSI. At the present moment the future of FC hardware evolution is still unknown: it is not known whether we will ever have any beyond-FCDEV3B hardware at all (contingent on uncertain funding), and if we do produce further FC hardware designs, it is not known whether they will retain the same FIC modem core (triband), if we are going to have a quadband design that still retains the classic Rita transceiver, or if we are going to switch to Silabs Aero II or some other transceiver. If we produce a quadband modem that still uses Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination, and the current fcdev3b build target will be renamed to fcmodem. OTOH, if that putative quadband modem will be Aero-based, then it will require a different fw build target, the fcdev3b target will stay as it is, and the two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM, but will have different RF_FAM numbers. But no matter which way we are going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B in places like ACI, and the present change clears the way for future evolution.
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 01 Apr 2019 01:05:24 +0000
parents 945cf7f506b2
children
line wrap: on
line source

/********************************************************************************
 * Enhanced TestMode (ETM)
 * @file	etm_at.c (Support for AT-commands)
 *
 * @author	Kim T. Peteren (ktp@ti.com)
 * @version 0.2
 *


 *
 * History:
 *
 * 	Date       	Modification
 *  ------------------------------------
 *  16/06/2003	Creation
 *  06/11/2003  Small updates 
 *  18/02/2004  Major updating, the event handling has been updated
 *
 *
 * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved
 *********************************************************************************/

//#include "aci_msg.h"

#include "etm/etm.h"          
#include "etm/etm_api.h"
#include "etm/etm_at.h"
#include "etm/etm_trace.h"

#include "rv/rv_general.h"
#include "rvf/rvf_api.h"

#include "atp/atp_env.h"  // FixMe
#include "atp/atp_i.h"    // FixMe    
//#include "atp/atp_general.h"  // FixMe

#include "atp/atp_api.h"
#include "atp/atp_messages.h" 

#include <string.h>

// Defined in aci_msg.h
extern T_XAT_SYNC_MESSAGE;
extern SYNC_PORT_NUM;
extern ASYNC_PORT_NUM;
extern T_RAT_CALLBACK_MESSAGE;


/******************************************************************************
 * Globals
 *****************************************************************************/

static T_ATP_SW_ENTITY_NAME  ETM_AT_ADAPTER      = "ETMATA"; // max 5 caracter
static T_ATP_SW_ENTITY_ID    etm_at_id;     
static T_ATP_PORT_NB         etm_at_to_aaa_port  = 0x01;     // equal to SYNC_PORT_NUM

static T_ATP_SW_ENTITY_NAME  aaa_name            = "AAA";     // ACIA ADAPTER
//static T_ATP_SW_ENTITY_NAME  aaa_name            = "GSM";     // GSM ADAPTER
static T_ATP_SW_ENTITY_ID    aaa_entity_id;
static T_ATP_ENTITY_MODE     aaa_mode;       

static T_ATP_CALLBACK etm_at_return_path;
static T_ATP_ENTITY_MODE etm_at_mode;

//extern T_ETM_ENV_CTRL_BLK *etm_env_ctrl_blk;

static int etm_at_initialized  = 0;
static int etm_at_event_status = 0;

static char etm_at_latest_cmd[9] = { 0 };


/******************************************************************************
 * Internal prototypes 
 *****************************************************************************/

int  etm_at_init(void);
int  etm_at_reg_req(void);
int  etm_at_open_port_req(void);
//T_RV_HDR *etm_at_wait_for_atp_event (UINT16 event_code);
int etm_at_atp_txt_cmd_rdy( T_ATP_TXT_CMD_RDY *msg);
void etm_at_callback_for_ATP(void *event_from_atp_p);


/******************************************************************************
 * AT commands List 
 *****************************************************************************/

struct at_async_trans_s {
//    const short index;  // index for ...
    const char *name;   // parameter
};

static struct at_async_trans_s at_cmd[] =
{
    {  "TEST"  },
    {  "atd"   },
    {  NULL    }
};


int at_cmd_search(char *at_string)
{
    struct at_async_trans_s *at_p = at_cmd;
    int size, error;

    size = strlen(at_string);
    tr_etm(TgTrCore, "ETM CORE: _cmd_search: at_string size(%d)", size);

    if (size > 8)
        strncpy(&etm_at_latest_cmd[0], at_string, 8);
    else
        strncpy(&etm_at_latest_cmd[0], at_string, size);

//    if ((etm_at_latest_cmd[2]== '+') || (etm_at_latest_cmd[2] == '%'))
//        return ETM_OK;
    
    while (at_p->name) {
        error = strncmp(&etm_at_latest_cmd[0], at_p->name, strlen(at_p->name));
        if (error == 0)
            strcpy(&etm_at_latest_cmd[0], at_p->name);
        tr_etm(TgTrCore, "ETM CORE: _cmd_search: AT list(%s)", at_p->name);
        at_p++;
    }

    tr_etm(TgTrCore, "ETM CORE: _cmd_search: text(%s)", &etm_at_latest_cmd[0]);

    return ETM_OK;
}


/******************************************************************************
 * AT command to ACI
 *****************************************************************************/

int etm_at_adapter(char *command)
{
    int error;
    T_ATP_TXT_CMD txt_cmd_p = NULL;
       
    if (!etm_at_initialized){
        if ((etm_at_init() == ETM_OK) && (etm_at_event_status == ETM_OK)) {
            // read etm_at_event_status
            tr_etm(TgTrCore, "ETM CORE: _at_adapter: initialization - OK");
            etm_at_initialized = 1;
        }
        else {
            tr_etm(TgTrCore, "ETM CORE: _at_adapter: initialization - FAILED");
            return ETM_FATAL;
        }
    }

    // Creating ETM_AT data buffer, will be fread by atp_send_txt_cmd()
    if ((txt_cmd_p = etm_malloc(strlen(command)+1)) == NULL)
        return ETM_NOMEM;

    strcpy(txt_cmd_p, command);

    // Find AT command
    //at_cmd_search(command);

    // Send AT command to AAA
    if ((error = atp_send_txt_cmd(etm_at_id, etm_at_to_aaa_port, AT_CMD, txt_cmd_p)) != RV_OK) {
        tr_etm(TgTrCore, "ETM CORE: _at_adapter: send_txt_cmd - FAILED");
        return ETM_FATAL;
    }

    return ETM_OK;
}


/******************************************************************************
 * ETM AT Adapter Initialization
 *****************************************************************************/

int etm_at_init(void)
{
    int error;

    // Check if ATP has been started if NOT 
    // Turn ATP module ON - necessary for RVM 
    if (atp_swe_state != ATP_STARTED)
        if (atp_start() != RV_OK)
            return ETM_FATAL;
   
 
    // Registration of ETM_AT to ATP  
    if ((error = etm_at_reg_req()) != ETM_OK) {
        tr_etm(TgTrCore, "ETM CORE: _at_init: Registration ERROR(%d)", error); 
       return error;    
    }    

    // Open a port to ACI adapter
    if ((error = etm_at_open_port_req()) != ETM_OK) {
        tr_etm(TgTrCore, "ETM CORE: _at_init: Open port ERROR(%d)", error);
        return error;
    }

    return ETM_OK;
}


// Register of ETM AT adapter with ATP.

int etm_at_reg_req(void)
{
    int result;

     // Registration of ETM_AT in ATP
    etm_at_return_path.addr_id        = NULL; // mailbox identifier - unused when callback mechanism in use
    etm_at_return_path.callback_func  = etm_at_callback_for_ATP;  // Pointer to callback fn ...

    // Set modes supported by SWE 
    etm_at_mode.cmd_mode         = TXT_MODE;  // INTERPRETED_MODE/TXT_MODE
    etm_at_mode.cp_mode          = COPY_OFF;
    etm_at_mode.cmd_support_mode = CMD_SUPPORT_ON;

    // Registration of ETM_AT to ATP
    if ((result = (atp_reg(ETM_AT_ADAPTER, etm_at_return_path, etm_at_mode, &etm_at_id)))
        != RV_OK) {
        tr_etm(TgTrCore, "ETM CORE: _at_reg_req: ERROR(%d)", result);
        return ETM_RV_FATAL;    
    }

    // Check ETM_AT Registration
    if ((result = (atp_reg_info(ETM_AT_ADAPTER, &etm_at_id, &etm_at_mode)))
        != RV_OK){
        tr_etm(TgTrCore, "ETM CORE: _at_reg_req: FAILED");
        return ETM_RV_NOT_SUPPORTED;
    }

    return ETM_OK;
}


// Open a port with ATP.

int etm_at_open_port_req(void)
{
    int result;
    T_ATP_NO_COPY_INFO etm_no_copy_info;
    T_ATP_PORT_INFO etm_port_info;
    T_ATP_CUSTOM_INFO *cust_info_p = NULL;
//    T_RV_HDR *message_p;
    T_RVF_MB_ID etm_mb_id;

    if (rvf_get_mb_id("ETM_PRIM", &etm_mb_id) != RVF_OK) {
        tr_etm(TgTrCore, "ETM CORE: _at_open_port_req: Memory bank ETM does not exist!");
        return ETM_RV_FATAL;
    }
         
	/* Test header and trailer removal from ATP so: trailers and headers equal 0 */
	etm_no_copy_info.tx_mb		    = etm_mb_id;   /* MB used by ATP is from ETM */ 
	etm_no_copy_info.rx_mb		    = etm_mb_id;   /* MB used by ATP is from ETM */
	etm_no_copy_info.rx_head_mode   = RX_HEADER_OFF;
    etm_no_copy_info.rx_head_size   = 0x00;
    etm_no_copy_info.rx_trail_size  = 0x00;
	etm_no_copy_info.tx_head_mode   = TX_HEADER_OFF;
    etm_no_copy_info.tx_head_size   = 0x00;
    etm_no_copy_info.tx_trail_size  = 0x00;
	etm_no_copy_info.packet_mode    = NORMAL_PACKET;     /* No L2CAP packet... */

    //  Port info 
    etm_port_info.port_config = NOT_DEFINED_CONFIG;
    etm_port_info.ring_type   = ATP_NO_RING_TYPE;
    etm_port_info.signal_mask = (T_ATP_SIGNAL_MASK) ATP_ALL_THE_SIGNAL_UNMASK; /* Get all signal changed event */
    etm_port_info.dce_mask[0] = 0x0000; /* No requirement in term of DCE */ 

    // Test AA Adapter Registration
    if (atp_reg_info(aaa_name, &aaa_entity_id, &aaa_mode) != RV_OK) {
        tr_etm(TgTrCore, "ETM CORE: _at_open_port_req: AAA is not registered to ATP");
        return ETM_RV_NOT_SUPPORTED;
    }

    // Open a virtual port between ETM AT adapter and ACI adapter 
    if ((result = atp_open_port_rqst(etm_at_id, aaa_entity_id, etm_at_to_aaa_port, 
                                     etm_port_info, etm_no_copy_info, cust_info_p)) != RV_OK) {
        tr_etm(TgTrCore, "ETM CORE: _at_open_port_req: FAILED");
        return ETM_RV_FATAL;
    }

    // etm_at_callback_for_ATP should receive event: ATP_OPEN_PORT_CFM 
    rvf_wait(0xffff, 100); // Timeout 100 ticks
    tr_etm(TgTrCore, "ETM CORE: _at_open_port_req: STATUS(%d)", etm_at_event_status);

    return ETM_OK;
}


/******************************************************************************
 * Close Port
 *****************************************************************************/

int etm_at_port_close_req(void)
{ 
    int error;

    error = atp_close_port(etm_at_id, etm_at_to_aaa_port);
    if (error != RV_OK) {
    tr_etm(TgTrCore, "ETM CORE: _at_port_close_req: FAILED");
        return ETM_FATAL;
    }        
    
    // etm_at_callback_for_ATP should receive event: ATP_PORT_CLOSED 
    rvf_wait(0xffff, 100); // Timeout 100 ticks
    tr_etm(TgTrCore, "ETM CORE: _at_open_port_req: STATUS(%d)", etm_at_event_status);

    etm_at_initialized = 0;
    return ETM_OK;
}


/******************************************************************************
 * Callback function for ATP
 *****************************************************************************/

//   PURPOSE : Decipher and route incoming messages from ATP.

void etm_at_callback_for_ATP(void *event_from_atp_p)
{
	// This function is ATP context.
	
//    tr_etm(TgTrEtmLow,"ETM: CORE: etm_at_callback_for_ATP: recv. event (0x%x)", ((T_RV_HDR *) event_from_atp_p)->msg_id);

    // What type of event?
    switch (((T_RV_HDR *) event_from_atp_p)->msg_id)
    {
    case ATP_CMD_RDY:
        tr_etm(TgTrCore,"ETM CORE: _at_callback_for_AT: UNSUPPORTED"); 
        break;
    case ATP_OPEN_PORT_CFM:
        if (((T_ATP_OPEN_PORT_CFM *) event_from_atp_p)->result == OPEN_PORT_OK) {
            tr_etm(TgTrCore, "ETM CORE: _at_callback_for_ATP: rev. event ATP_OPEN_PORT_CFM - OPEN_PORT_OK");
//            tr_etm(TgTrCore, "ETM CORE: _at_callback_for_ATP: rev. event ATP_OPEN_PORT_CFM - Port Number (%d)",
//                   ((T_ATP_OPEN_PORT_CFM *) event_from_atp_p)->initiator_port_nb);
        }
        else {
            tr_etm(TgTrCore, "ETM CORE: _at_callback_for_ATP: rev. event ATP_OPEN_PORT_CFM - OPEN_PORT_NOK");
            etm_at_event_status = ETM_FATAL;
        }
//            tr_etm(TgTrCore, "ETM CORE: _at_callback_for_ATP: rev. event ATP_OPEN_PORT_CFM - Port Number (%d)",
//                   ((T_ATP_OPEN_PORT_CFM *) event_from_atp_p)->initiator_port_nb);
        break;
    case ATP_TXT_CMD_RDY:
        etm_at_atp_txt_cmd_rdy((T_ATP_TXT_CMD_RDY *) event_from_atp_p);
        break;
    case ATP_PORT_CLOSED:
        tr_etm(TgTrCore, "ETM CORE: _at_callback_for_ATP: rev. event ATP_PORT_CLOSED");
        break;
    case ATP_OPEN_PORT_IND:
        tr_etm(TgTrCore, "ETM CORE: _at_callback_for_ATP: rev. event ATP_OPEN_PORT_IND");
        break;
    default:
        tr_etm(TgTrCore, "ETM CORE: _at_callback_for_ATP: rev. unknown event(0x%x)- UNSUPPORTED", 
               ((T_RV_HDR *) event_from_atp_p)->msg_id);
    }
    
    /* Free memmory that is allocated within ATP */
    etm_free(event_from_atp_p);
}      


// This is called when the result of the AT cmd is received 
// (in a primetive) from the ATP entity.
int etm_at_atp_txt_cmd_rdy(T_ATP_TXT_CMD_RDY *msg)
{
/* Send reply to PC
   The status type depend of the event from ATP module: 
       last_result = 0, means more data is sent to HOST (PC)
       last_result = 1, means last data is sent to HOST (PC)
       last_result = 2, means data is not sent to HOST (PC)  */

    T_ETM_PKT  *pkt;
    char *text, last_result = 1;
    int error = 0, length;

    if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL) {
        rvf_dump_mem();
        return ETM_NOMEM;
    }
    
    // Init. of return packet
    pkt->mid    = ETM_CORE;
    pkt->status = ETM_OK;
    pkt->size   = 0;
    pkt->index  = 0;
    etm_pkt_put8(pkt, 'G'); // 'G' is indcator for AT command respons


    tr_etm(TgTrCore, "ETM CORE: _at_atp_txt_cmd_rdy: ATP_TXT_CMD_RDY with cmd_type(%d)",
           msg->cmd_type);
 
    switch (msg->cmd_type){
    case AT_CMD:                                                   // Type: 0
    case CUSTOM_CMD:                                               // Type: 4
    case CMD_ABORT:                                                // Type: 5
    case UNKNOWN:                  error = ETM_MESSAGE; break;     // Type: 6
    case PRELIMINARY_RESULT_CODE:  last_result = 0;     break;     // Type: 7
//    case INFORMATION_TXT:          last_result = 0;     break;     // Type: 3
    case RESULT_CODE:              last_result = 1;     break;     // Type: 1
    case UNSOLICITED_RESULT:       last_result = 2;     break;     // Type: 2
    default:
        tr_etm(TgTrCore,"ETM CORE: _at_atp_txt_cmd_rdy: cmd_tpye(%d) - FAILED", msg->cmd_type); 
        error = ETM_NOSYS;
    }

    if (last_result == 2) 
        goto etm_at_atp_txt_cmd_rdy_end;
    
    text = ((char *) msg->txt_cmd_p);
    length = strlen(text);
    etm_pkt_putdata(pkt, text, length);
    tr_etm(TgTrCore, "ETM CORE: _at_atp_txt_cmd_rdy: text(%s) length(%d)", text, length);

    // Status will be set to ETM_OK_MORE when more data is send.
    // Add one because of string length is also returned as part of the result
    pkt->status = (last_result ? ETM_OK : -ETM_OK_MORE);

    if (error < 0) {
//        tr_etm(TgTrCore,"ETM CORE: _at_atp_txt_cmd_rdy: ERROR(%d)", error); 
        pkt->status = -error;
    }

    etm_pkt_send(pkt);

etm_at_atp_txt_cmd_rdy_end:
    etm_free(pkt);

    return ETM_OK;
}


/******************************************************************************
 * ETM AT - Main Task 
 *****************************************************************************/

// Structur of protocol data dl-link: |target|at_cmd|
int etm_at(T_ETM_PKT *pkt, char *buf)
{
    int error = ETM_NOSYS;
    int sw_entity;

//    sw_entity = *buf++;

    // FIXME pkt should be use in etm_at_adapter()
    error = etm_at_adapter((char *) buf);

#if 0 
    switch (sw_entity) {
    case GSM: 
  
        break;
    case BLUE: 
        //error = etm_at_blue(*buf++); 
        break;
    default:
        tr_etm(TgTrCore,"ETM CORE: _at: ERROR(%d)", error); 
        error = ETM_NOSYS; 
    }
#endif

    return error;
}