FreeCalypso > hg > fc-magnetite
view src/aci2/aci/dcm_utils.c @ 662:8cd8fd15a095
SIM speed enhancement re-enabled and made configurable
TI's original code supported SIM speed enhancement, but Openmoko had it
disabled, and OM's disabling of speed enhancement somehow caused certain
SIM cards to start working which didn't work before (OM's bug #666).
Because our FC community is much smaller in year 2020 than OM's community
was in their day, we are not able to find one of those #666-affected SIMs,
thus the real issue they had encountered remains elusive. Thus our
solution is to re-enable SIM speed enhancement and simply wait for if
and when someone runs into a #666-affected SIM once again. We provide
a SIM_allow_speed_enhancement global variable that allows SIM speed
enhancement to be enabled or disabled per session, and an /etc/SIM_spenh
file in FFS that allows it to enabled or disabled on a non-volatile
basis. SIM speed enhancement is now enabled by default.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 24 May 2020 05:02:28 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : DCM and TCPIP | Modul : ACI +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Description : This file contains Useful DCM (Data connection manager)functions. +----------------------------------------------------------------------------- */ /************************************ INCLUDES ********************************************/ #include "aci_all.h" #include "aci.h" #include "aci_cmh.h" #include "Gaci_cmh.h" #include "dcm.h" #include "dcm_utils.h" #include "dcm_state.h" #include "dcm_env.h" #include "dcm_f.h" #include "psa_dcm.h" #include "socket_api.h" #include "wap_aci.h" /**************************** LOCAL VARIABLE DEFINITION ************************************/ /**************************** EXTERN VARIABLE DEFINITION ***********************************/ EXTERN T_DCM_ENV_CTRL_BLK *dcm_env_ctrl_blk_p; /**************************** LOCAL FUCNTION DEFINITION ************************************/ LOCAL T_DCM_RET dcm_send_cgdcont_get_cmd(U8 row); LOCAL T_DCM_RET dcm_send_cgdcont_cmd(U8 row); LOCAL T_DCM_RET dcm_send_cgatt_cmd(U8 row); LOCAL T_DCM_RET dcm_send_cgdeact_cmd(U8 row); LOCAL T_DCM_RET dcm_send_cgpco_auth_cmd(U8 row); LOCAL T_DCM_RET dcm_send_cgpco_get_cmd(U8 row); LOCAL T_DCM_RET dcm_send_cgerep_cmd(U8 row); LOCAL T_DCM_RET dcm_send_cgpaddr_cmd(U8 current_row); LOCAL T_DCM_RET dcm_send_percentppp_cmd(U8 row); LOCAL T_DCM_RET dcm_send_sat_dn_cmd(U8 row); LOCAL T_DCM_RET dcm_send_percentppp_get_cmd(U8 row); LOCAL T_DCM_RET dcm_send_percentcal_get_cmd(UBYTE row); LOCAL T_DCM_RET dcm_send_sat_abort_cmd(U8 row); LOCAL ULONG dcm_ipaddr_htonl(ULONG horder_ipaddr); LOCAL void set_state_from_ctrl_blk(); /************************** EXTERN FUCNTION DEFINITION *********************************/ EXTERN T_DCM_RET dcm_handle_message (T_DCM_HDR *msg_p); EXTERN void psaTCPIP_Shutdown_Req(void); /*************************************************************************************** * Function : dcm_process_unwaited_events_state_intermediate_conn * Parameter : T_DCM_HDR * * -Pointer on the header of the message. * Return : T_DCM_RET * DCM_OK or DCM errors * Description : Function used in all intermediate states where events is unwaited, * but must be processed. ***************************************************************************************/ T_DCM_RET dcm_process_unwaited_events_state_intermediate_conn(T_DCM_HDR * msg_p) { T_DCM_OPEN_CONN_REQ_MSG * dcm_open_conn_req_msg_p; T_DCM_CLOSE_CONN_REQ_MSG * dcm_close_conn_req_msg_p; U8 current_row = dcm_env_ctrl_blk_p->current_row; TRACE_FUNCTION("DCM: dcm_process_unwaited_events_state_intermediate_conn()"); switch(msg_p->msg_id) { case DCM_ERROR_IND_MSG: return dcm_process_event_error_reception(msg_p); /*lint -e527 suppress Warning -- Unreachable */ break; /*lint +e527 */ case DCM_OPEN_CONN_REQ_MSG: dcm_open_conn_req_msg_p = (T_DCM_OPEN_CONN_REQ_MSG*)msg_p; return psaDCM_open_conn_cnf(DCM_BUSY, dcm_open_conn_req_msg_p->conn_req.api_instance); /*lint -e527 suppress Warning -- Unreachable */ break; /*lint +e527 */ case DCM_CLOSE_CONN_REQ_MSG: dcm_close_conn_req_msg_p = (T_DCM_CLOSE_CONN_REQ_MSG*)msg_p; // DCM CLOSE REQ have to be accepted in ACTVATING STATE if(dcm_env_ctrl_blk_p->state[0] == DCM_ACTIVATING_CONN) { dcm_process_close_conn_event(dcm_close_conn_req_msg_p); } else { psaDCM_close_conn_cnf(DCM_BUSY, dcm_close_conn_req_msg_p->close_req.api_instance); } return DCM_OK; /*lint -e527 suppress Warning -- Unreachable */ break; /*lint +e527 */ default: /* Ignore event - Stay in the same state. */ return DCM_UNKNOWN_EVENT; } } /* * Function used to close a connection (with PS and later with api_instance) * * The closing is always on demand of the IPU_id, or may be internally launched. * The closing of the connection begin by the closing of the port with the PS. * - Close the connection with the PS. * * @param T_DCM_CLOSE_CONN_REQ_MSG* * @return DCM_OK or DCM errors */ /*************************************************************************************** * Function : dcm_process_close_conn_event * Parameter : T_APPLI_USER * -Pointer on the header of the message. * Return : T_DCM_RET * DCM_OK or DCM errors * Description : Function used in all intermediate states where events is unwaited, * but must be processed. ***************************************************************************************/ T_DCM_RET dcm_process_close_conn_event(T_DCM_CLOSE_CONN_REQ_MSG *close_conn_p ) { U8 i; U8 current_bearer_count; TRACE_FUNCTION("DCM: dcm_process_close_conn_event()"); for (i=0; i < DCM_MAX_NUMBER_IPU; i++) { if( (dcm_env_ctrl_blk_p->ipu_list[i].api_instance == close_conn_p->close_req.api_instance) && (dcm_env_ctrl_blk_p->ipu_list[i].row_state) ) { if(dcm_env_ctrl_blk_p->ipu_list[i].bearer_type == DCM_BEARER_GPRS) { current_bearer_count = dcm_env_ctrl_blk_p->gprs_current_total_row; } else { current_bearer_count = dcm_env_ctrl_blk_p->gsm_current_total_row; } /* raise the flag that indicates a disconnection */ dcm_env_ctrl_blk_p->ipu_list[i].row_state = ROW_CLOSING; dcm_new_state(DCM_CLOSING_CONN , DCM_SUB_NO_ACTION); if(current_bearer_count == 1) { if(dcm_env_ctrl_blk_p->ipu_list[i].bearer_type == DCM_BEARER_GPRS) { dcm_send_cgdeact_cmd(i); } else { dcm_send_percentcal_get_cmd(i); } } else { psaDCM_close_conn_cnf(DCM_OK,close_conn_p->close_req.api_instance); /* free the row used */ dcm_free_row(i); set_state_from_ctrl_blk(); } } } return DCM_OK; } /******************************************************************************* * Function used to open a connection (with PS) * * The opening is always on demand of the IPU_id. * - Open the connection with the PS. * * @return DCM_OK or DCM errors *******************************************************************************/ T_DCM_RET dcm_process_open_conn_event(T_DCM_OPEN_CONN_REQ_MSG *open_conn_p) { U8 row_id, row_id_free; TRACE_FUNCTION("DCM: dcm_process_open_conn_event()"); /* check if the max number of IPU is reached */ if (( dcm_env_ctrl_blk_p->gsm_current_total_row + dcm_env_ctrl_blk_p->gprs_current_total_row ) >= DCM_MAX_NUMBER_IPU ) { /* Too many IPU_id opened */ /* send the negative confirmation to the IPU */ return psaDCM_open_conn_cnf(DCM_NOT_READY, open_conn_p->conn_req.api_instance); } /* if possible, get the next row */ for (row_id = 0, row_id_free = DCM_MAX_NUMBER_IPU; row_id < DCM_MAX_NUMBER_IPU; row_id++) { if (dcm_env_ctrl_blk_p->ipu_list[row_id].row_state) { /* send a negative confirmation whether the IPU already exists */ if (dcm_env_ctrl_blk_p->ipu_list[row_id].api_instance == open_conn_p->conn_req.api_instance) { /* send the negative confirmation to the IPU */ return psaDCM_open_conn_cnf(DCM_ALREADY_ACTIVATED, open_conn_p->conn_req.api_instance); } } else { /* get the first entry */ if (row_id_free == DCM_MAX_NUMBER_IPU) { row_id_free = row_id; } } } if (row_id_free == DCM_MAX_NUMBER_IPU) { /* send the negative confirmation to the IPU */ return psaDCM_open_conn_cnf(DCM_NOT_READY, open_conn_p->conn_req.api_instance); } /* Check the bearer type */ /* check best one bearer */ if(open_conn_p->conn_req.bearer_select == DCM_BEARER_ANY) { T_CGATT_STATE cgatt_state; qAT_PlusCGATT(CMD_SRC_LCL,&cgatt_state); if(cgatt_state == CGATT_STATE_ATTACHED) open_conn_p->conn_req.bearer_select = DCM_BEARER_GPRS; else open_conn_p->conn_req.bearer_select = DCM_BEARER_GSM; } /* If application doesn't give any connection parameters than use default */ if(open_conn_p->conn_req.bearer_select == DCM_BEARER_GSM OR open_conn_p->conn_req.bearer_select == DCM_BEARER_GPRS) { psaDCM_open_conn_cnf(DCM_INVALID_PARAMETER,open_conn_p->conn_req.api_instance); return DCM_INVALID_PARAMETER; } /* If application gives the necessary parameters for a connection use these */ else if(open_conn_p->conn_req.bearer_select == DCM_BEARER_AS_SPECIFIED) { dcm_env_ctrl_blk_p->ipu_list[row_id_free].bearer_handle = open_conn_p->conn_req.dcm_info_conn.bearer_handle; dcm_env_ctrl_blk_p->ipu_list[row_id_free].app_handle = open_conn_p->conn_req.dcm_info_conn.app_handle; dcm_env_ctrl_blk_p->ipu_list[row_id_free].bearer_type = open_conn_p->conn_req.dcm_info_conn.bearer_type; dcm_env_ctrl_blk_p->ipu_list[row_id_free].apn_valid = open_conn_p->conn_req.dcm_info_conn.apn_valid; if(dcm_env_ctrl_blk_p->ipu_list[row_id_free].apn_valid) { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row_id_free].apn, (char*)open_conn_p->conn_req.dcm_info_conn.apn); } else { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row_id_free].apn,""); } dcm_env_ctrl_blk_p->ipu_list[row_id_free].phone_number_valid = open_conn_p->conn_req.dcm_info_conn.phone_number_valid; if(dcm_env_ctrl_blk_p->ipu_list[row_id_free].phone_number_valid) { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row_id_free].phone_number, (char*)open_conn_p->conn_req.dcm_info_conn.phone_number); } else { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row_id_free].phone_number,""); } dcm_env_ctrl_blk_p->ipu_list[row_id_free].user_id_valid = open_conn_p->conn_req.dcm_info_conn.user_id_valid; if(dcm_env_ctrl_blk_p->ipu_list[row_id_free].user_id_valid) { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row_id_free].user_id, (char*)open_conn_p->conn_req.dcm_info_conn.user_id); } else { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row_id_free].user_id,""); } dcm_env_ctrl_blk_p->ipu_list[row_id_free].password_valid = open_conn_p->conn_req.dcm_info_conn.password_valid; if(dcm_env_ctrl_blk_p->ipu_list[row_id_free].password_valid) { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row_id_free].password, (char*)open_conn_p->conn_req.dcm_info_conn.password); } else { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row_id_free].password,""); } dcm_env_ctrl_blk_p->ipu_list[row_id_free].cid = open_conn_p->conn_req.dcm_info_conn.cid; dcm_env_ctrl_blk_p->ipu_list[row_id_free].ip_address = open_conn_p->conn_req.dcm_info_conn.ip_address; dcm_env_ctrl_blk_p->ipu_list[row_id_free].dns1 = open_conn_p->conn_req.dcm_info_conn.dns1; dcm_env_ctrl_blk_p->ipu_list[row_id_free].dns2 = open_conn_p->conn_req.dcm_info_conn.dns2; dcm_env_ctrl_blk_p->ipu_list[row_id_free].gateway = open_conn_p->conn_req.dcm_info_conn.gateway; dcm_env_ctrl_blk_p->ipu_list[row_id_free].auth_type = open_conn_p->conn_req.dcm_info_conn.auth_type; dcm_env_ctrl_blk_p->ipu_list[row_id_free].data_compr = open_conn_p->conn_req.dcm_info_conn.data_compr; dcm_env_ctrl_blk_p->ipu_list[row_id_free].header_compr = open_conn_p->conn_req.dcm_info_conn.header_compr; dcm_env_ctrl_blk_p->ipu_list[row_id_free].precedence = open_conn_p->conn_req.dcm_info_conn.precedence; dcm_env_ctrl_blk_p->ipu_list[row_id_free].delay = open_conn_p->conn_req.dcm_info_conn.delay; dcm_env_ctrl_blk_p->ipu_list[row_id_free].reliability = open_conn_p->conn_req.dcm_info_conn.reliability; dcm_env_ctrl_blk_p->ipu_list[row_id_free].peak_throughput = open_conn_p->conn_req.dcm_info_conn.peak_throughput; dcm_env_ctrl_blk_p->ipu_list[row_id_free].mean_throughput = open_conn_p->conn_req.dcm_info_conn.mean_throughput; dcm_env_ctrl_blk_p->ipu_list[row_id_free].shareable = open_conn_p->conn_req.dcm_info_conn.shareable; } dcm_env_ctrl_blk_p->ipu_list[row_id_free].api_instance = open_conn_p->conn_req.api_instance; /* keep the curretn row */ dcm_env_ctrl_blk_p->current_row = row_id_free; /* mark the row as used */ dcm_env_ctrl_blk_p->ipu_list[row_id_free].row_state = ROW_ASSIGNED; /* sum the total of actual rows */ if(dcm_env_ctrl_blk_p->ipu_list[row_id_free].bearer_type == DCM_BEARER_GPRS) { dcm_env_ctrl_blk_p->gprs_current_total_row++; } else { dcm_env_ctrl_blk_p->gsm_current_total_row++; } if(dcm_env_ctrl_blk_p->gprs_current_total_row > 1 OR dcm_env_ctrl_blk_p->gsm_current_total_row > 1) { psaDCM_open_conn_cnf(DCM_ALREADY_ACTIVATED,open_conn_p->conn_req.api_instance); return DCM_ALREADY_ACTIVATED; } set_gpf_tcpip_call(); /* DCM state change */ dcm_new_state(DCM_ACTIVATING_CONN,DCM_SUB_NO_ACTION); /* if GPRS: send first GPRS AT Command qAT_CGDCONT */ if(dcm_env_ctrl_blk_p->ipu_list[row_id_free].bearer_type == DCM_BEARER_GPRS) { dcm_send_cgdcont_get_cmd(dcm_env_ctrl_blk_p->current_row); } else /*send first GSM AT Command sAT_PercentPPP */ { dcm_send_percentppp_cmd(dcm_env_ctrl_blk_p->current_row); } return DCM_OK; } /******************************************************************************/ T_DCM_RET dcm_process_get_current_conn_event(T_DCM_GET_CURRENT_CONN_REQ_MSG *current_conn_p) { TRACE_FUNCTION("DCM: dcm_process_get_current_conn_event()"); if(dcm_env_ctrl_blk_p->ipu_list[dcm_env_ctrl_blk_p->current_row].row_state == ROW_ASSIGNED) { psaDCM_get_current_conn_cnf(DCM_OK, current_conn_p->current_conn_req.api_instance, dcm_env_ctrl_blk_p); } else { psaDCM_get_current_conn_cnf(DCM_NOT_READY, current_conn_p->current_conn_req.api_instance, dcm_env_ctrl_blk_p); } return DCM_OK; } /******************************************************************************/ T_DCM_RET dcm_process_unknown_event_in_idle(T_DCM_HDR* msg_p) { T_DCM_CLOSE_CONN_REQ_MSG *close_conn_req_p; T_DCM_RET ret; TRACE_FUNCTION("DCM: dcm_process_unknown_event_in_idle()"); if(msg_p == NULL) return DCM_INVALID_PARAMETER; switch(msg_p->msg_id) { case DCM_CLOSE_CONN_REQ_MSG : close_conn_req_p =(T_DCM_CLOSE_CONN_REQ_MSG *)msg_p; psaDCM_close_conn_cnf(DCM_UNKNOWN_EVENT, close_conn_req_p->close_req.api_instance); set_state_from_ctrl_blk(); ret = DCM_OK; break; default: ret = DCM_UNKNOWN_EVENT; break; } return ret; } /******************************************************************************/ T_DCM_RET dcm_free_row(U8 current_row) { TRACE_FUNCTION("DCM: dcm_free_row()"); /* Decrease the current number of IPU */ dcm_env_ctrl_blk_p->ipu_list[current_row].row_state = ROW_FREE; if(dcm_env_ctrl_blk_p->ipu_list[current_row].bearer_type == DCM_BEARER_GPRS) dcm_env_ctrl_blk_p->gprs_current_total_row--; else dcm_env_ctrl_blk_p->gsm_current_total_row--; /* clear the row in the structure of IP Users */ dcm_clear_ipu_info(current_row); return DCM_OK; } /* * Function used to store some IPU informations * * @param row to access [0, 256], * @param IPU id * @param bearer type * @param apn, mtu, pdp@, cid, user, password, dns1, dns2, gateway * @return DCM_OK or DCM errors */ T_DCM_RET dcm_store_ipu_info(U8 row, T_BEARER_TYPE bearer_type, char *apn, char *number, char *pdp_addr, U8 cid_used, char *user, char *password, U32 dns1, U32 dns2, U32 gateway) { TRACE_FUNCTION("DCM: dcm_store_ipu_info()"); if(bearer_type == DCM_BEARER_GPRS) strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].apn, apn); else if (bearer_type == DCM_BEARER_GSM) strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].phone_number,number); else return DCM_INVALID_PARAMETER; dcm_env_ctrl_blk_p->ipu_list[row].bearer_type = bearer_type; dcm_env_ctrl_blk_p->ipu_list[row].cid = cid_used; strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].user_id, user); strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].password, password); dcm_env_ctrl_blk_p->ipu_list[row].dns1 = dns1; dcm_env_ctrl_blk_p->ipu_list[row].dns2 = dns2; dcm_env_ctrl_blk_p->ipu_list[row].gateway = gateway; return DCM_OK; } /* resets parameters of a row */ T_DCM_RET dcm_clear_ipu_info(U8 row) { char empty[] = ""; TRACE_FUNCTION("DCM: dcm_clear_ipu_info()"); dcm_env_ctrl_blk_p->ipu_list[row].bearer_type = DCM_BEARER_NO; strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].apn, empty); strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].phone_number,empty); dcm_env_ctrl_blk_p->ipu_list[row].cid = 0; strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].user_id, empty); strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].password, empty); dcm_env_ctrl_blk_p->ipu_list[row].dns1 = 0; dcm_env_ctrl_blk_p->ipu_list[row].dns2 = 0; dcm_env_ctrl_blk_p->ipu_list[row].gateway = 0; return DCM_OK; } /* * Function used to send the <AT+CGDCONT=?> command * * This command is used to get the next Context IDentifier available in the PS. * This cid will be used very often in the suite * * @param row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ LOCAL T_DCM_RET dcm_send_cgdcont_get_cmd(U8 row) { T_GPRS_CONT_REC defCtxts[MAX_CID_PLUS_EINS]; SHORT cid_array[MAX_CID_PLUS_EINS]; UBYTE i; TRACE_FUNCTION("DCM: dcm_send_cgdcont_get_cmd()"); if(qAT_PlusCGDCONT(CMD_SRC_LCL, &defCtxts, cid_array) != AT_CMPL) { psaDCM_open_conn_cnf( DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); return DCM_OK; } else { for( i= 0; i < MAX_CID_PLUS_EINS ; i++) { if(cid_array[i] == dcm_env_ctrl_blk_p->ipu_list[row].cid) { TRACE_EVENT_P2("DCM: dcm cid is the same %d=%d", cid_array[i], dcm_env_ctrl_blk_p->ipu_list[row].cid); } } return dcm_send_cgdcont_cmd(row); } } /* * Function used to send the <AT+CGDCONT=cid, "IP", "apn", "", 0, 0> command * * This command is used to declare the PDP Context. * * @param row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ LOCAL T_DCM_RET dcm_send_cgdcont_cmd(U8 row) { T_GPRS_CONT_REC input_txt; TRACE_FUNCTION("DCM: dcm_send_cgdcont_cmd()"); TRACE_EVENT_P1("DCM: ipu_list[row].apn = %s",dcm_env_ctrl_blk_p->ipu_list[row].apn); strcpy(input_txt.apn,(char*)dcm_env_ctrl_blk_p->ipu_list[row].apn); strcpy(input_txt.pdp_type,"IP"); memset(input_txt.pdp_addr,'\0',MAX_PDP_ADDR_LEN); input_txt.d_comp = CGDCONT_D_COMP_OMITTED; input_txt.h_comp = CGDCONT_H_COMP_OMITTED; memset(&input_txt.qos,0,sizeof(T_QOS)); memset(&input_txt.min_qos,0,sizeof(T_QOS)); if(sAT_PlusCGDCONT(CMD_SRC_LCL,dcm_env_ctrl_blk_p->ipu_list[row].cid, &input_txt) != AT_CMPL) { psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); return DCM_OK; } else { dcm_send_cgatt_cmd(row); return DCM_OK; } } /* * Function used to send the <AT+CGATT=cid> command * * This command is used to force attachment to the network. * * @param row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ LOCAL T_DCM_RET dcm_send_cgatt_cmd(U8 row) { TRACE_FUNCTION("DCM: dcm_send_cgatt_cmd()"); /* prepare the AT command including some dynamic info like cid */ switch(sAT_PlusCGATT(CMD_SRC_LCL, CGATT_STATE_ATTACHED)) { case AT_FAIL: case AT_BUSY: psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); break; case AT_CMPL: dcm_send_cgpco_auth_cmd(row); break; case AT_EXCT: dcm_env_ctrl_blk_p->dcm_call_back = dcm_handle_message; dcm_new_state(DCM_ACTIVATING_CONN, DCM_SUB_WAIT_CGATT_CNF); break; default : break; } return DCM_OK; } /* * Function used to send the <AT%CGPCO=0, cid, "PAP, username, * password, 0.0.0.0, 0.0.0.0"> command * * This command is used to configure the PS to TCPIP over SNDCP * * @param row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ LOCAL T_DCM_RET dcm_send_cgpco_auth_cmd(U8 row) { CHAR dns[2]; strcpy(dns, ""); TRACE_FUNCTION("DCM: dcm_send_cgpco_auth_cmd()"); TRACE_EVENT_P2("DCM: user=%s, password=%s", dcm_env_ctrl_blk_p->ipu_list[row].user_id, dcm_env_ctrl_blk_p->ipu_list[row].password); if(sAT_PercentCGPCO(CMD_SRC_LCL,dcm_env_ctrl_blk_p->ipu_list[row].cid, ACI_PCO_AUTH_PROT_PAP, (char*)dcm_env_ctrl_blk_p->ipu_list[row].user_id, (char*)dcm_env_ctrl_blk_p->ipu_list[row].password, dns,dns) != AT_CMPL) { psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); return DCM_OK; } else { dcm_send_cgerep_cmd(row); return DCM_OK; } } /* * Function used to send the <AT+CGEREP=cid, 0> command * * This command is used to configure the PS to send EVENT to us * * @param row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ LOCAL T_DCM_RET dcm_send_cgerep_cmd(U8 row) { TRACE_FUNCTION("DCM: dcm_send_cgerep_cmd()"); /* prepare the AT command including some dynamic info like cid */ if (sAT_PlusCGEREP(CMD_SRC_LCL,CGEREP_MODE_BUFFER,CGEREP_BFR_CLEAR) != AT_CMPL) { psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); return DCM_OK; } else { strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].phone_number,"*98*1#"); dcm_send_sat_dn_cmd(row); return DCM_OK; } } /* * Function used to send the <AT+CGACT=cid, 0> command * * This command is used to deactivate the PDP decontext. * * @param row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ LOCAL T_DCM_RET dcm_send_cgdeact_cmd(U8 row) { T_CGATT_STATE gprs_attach_state; SHORT cids[MAX_CID_PLUS_EINS] = {GPRS_CID_1,INVALID_CID}; TRACE_FUNCTION("DCM: dcm_send_cgdeact_cmd()"); /* Packet Counter */ sAT_PercentSNCNT(CMD_SRC_LCL,SN_RESET_YES); qAT_PlusCGATT(CMD_SRC_LCL,&gprs_attach_state); TRACE_EVENT_P1("DCM: Attatch State %d",gprs_attach_state); if(gprs_attach_state != CGATT_STATE_ATTACHED) { psaDCM_close_conn_cnf(DCM_OK,dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); return DCM_OK; } /* GPRS BEARER CLOSING */ switch(sAT_PlusCGACT(CMD_SRC_LCL,CGACT_STATE_DEACTIVATED,cids)) { case AT_FAIL: case AT_BUSY: psaDCM_close_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); set_state_from_ctrl_blk(); break; case AT_CMPL: psaDCM_close_conn_cnf(DCM_OK, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); break; case AT_EXCT: dcm_new_state(DCM_CLOSING_CONN, DCM_SUB_WAIT_CGDEACT_CNF); dcm_env_ctrl_blk_p->dcm_call_back = dcm_handle_message; break; default : break; } return DCM_OK; } LOCAL T_DCM_RET dcm_send_sat_h_cmd(U8 row) { SHORT cid_array[1]; cid_array[0] = INVALID_CID; TRACE_FUNCTION("DCM: dcm_send_sat_h_cmd()"); switch(sAT_H(CMD_SRC_LCL)) { case AT_FAIL: case AT_BUSY: psaDCM_close_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); set_state_from_ctrl_blk(); break; case AT_CMPL: break; case AT_EXCT: dcm_new_state(DCM_CLOSING_CONN, DCM_SUB_WAIT_SATH_CNF); dcm_env_ctrl_blk_p->dcm_call_back = dcm_handle_message; break; default : break; } return DCM_OK; } /* * Function used to send the <AT+CGPADDR=cid> command * * This command is used to get back the pdp@ of the module * * @param row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ LOCAL T_DCM_RET dcm_send_cgpaddr_cmd(U8 row) { T_PDP_ADDRESS pdp_address[MAX_CID]; SHORT cid_array[MAX_CID]; cid_array[0] = dcm_env_ctrl_blk_p->ipu_list[row].cid; cid_array[1] =INVALID_CID; TRACE_FUNCTION("DCM: dcm_send_cgpaddr_cmd()"); memset(pdp_address , 0x00, sizeof(T_PDP_ADDRESS)*MAX_CID); /* prepare the AT command including some dynamic info like cid */ if(sAT_PlusCGPADDR(CMD_SRC_LCL,cid_array,pdp_address) != AT_CMPL) { psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); return DCM_OK; } else { memcpy(dcm_env_ctrl_blk_p->ipu_list[row].pdp_addr, pdp_address[0], sizeof(T_PDP_ADDRESS)); TRACE_EVENT_P1("DCM: PDP addr=%s",dcm_env_ctrl_blk_p->ipu_list[row].pdp_addr); dcm_send_cgpco_get_cmd(row); return DCM_OK; } } /* * Function used to send the <AT%CGPCO=1,1,,cid> command * * This command is used to get back the dns1, dns2 and gateway @ * * @param row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ LOCAL T_DCM_RET dcm_send_cgpco_get_cmd(U8 row) { TRACE_FUNCTION("DCM: dcm_send_cgpco_get_cmd()"); psaDCM_open_conn_cnf(DCM_OK, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_env_ctrl_blk_p->dcm_call_back = dcm_handle_message; dcm_new_state(DCM_CONN_ACTIVATED, DCM_SUB_NO_ACTION); return DCM_OK; } T_DCM_RET dcm_send_percentppp_cmd(U8 row) { TRACE_FUNCTION("DCM: dcm_send_percentppp_cmd()"); if(sAT_PercentPPP(CMD_SRC_LCL, A_PAP, (char*)dcm_env_ctrl_blk_p->ipu_list[row].user_id, (char*)dcm_env_ctrl_blk_p->ipu_list[row].password, USE_NO_PPP_FOR_AAA) != AT_CMPL) { psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); } else { // reset the WAP-data if not done at call termination before sAT_PercentWAP(0,0); sAT_PercentWAP(0,1); dcm_send_sat_dn_cmd(row); } return DCM_OK; } LOCAL T_DCM_RET dcm_send_sat_dn_cmd(U8 row) { TRACE_FUNCTION("DCM: dcm_send_sat_dn_cmd()"); switch(sAT_Dn(CMD_SRC_LCL, (char*)dcm_env_ctrl_blk_p->ipu_list[row].phone_number, D_CLIR_OVRD_Default, D_CUG_CTRL_NotPresent, D_TOC_Data)) { case AT_FAIL: case AT_BUSY: case AT_CMPL: psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); break; case AT_EXCT: dcm_env_ctrl_blk_p->dcm_call_back = dcm_handle_message; if(dcm_env_ctrl_blk_p->ipu_list[row].bearer_type == DCM_BEARER_GPRS) { dcm_new_state(DCM_ACTIVATING_CONN, DCM_SUB_WAIT_CGACT_CNF); } else { dcm_new_state(DCM_ACTIVATING_CONN, DCM_SUB_WAIT_SATDN_CNF); } break; default: break; } return DCM_OK; } LOCAL T_DCM_RET dcm_send_percentppp_get_cmd(U8 row) { ULONG dns1=0; ULONG dns2 =0; ULONG ipaddr = 0 ; TRACE_FUNCTION("DCM: dcm_send_percentppp_get_cmd()"); if(qAT_PercentPPP(CMD_SRC_LCL, &ipaddr,&dns1,&dns2) != AT_CMPL) { psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); } else { psaDCM_open_conn_cnf(DCM_OK, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_env_ctrl_blk_p->dcm_call_back = dcm_handle_message; dcm_new_state(DCM_CONN_ACTIVATED,DCM_SUB_NO_ACTION); } return DCM_OK; } /* * Function used to process the events and errors received from PS * * @param received message * @return DCM_OK or DCM errors */ T_DCM_RET dcm_process_event_error_reception(T_DCM_HDR * msg_p) { U8 row = dcm_env_ctrl_blk_p->current_row;; TRACE_FUNCTION("DCM: dcm_process_event_error_reception()"); /* check if this port number is really used by DCM */ if(dcm_env_ctrl_blk_p->ipu_list[row].row_state) { psaDCM_error_ind((T_DCM_STATUS_IND_MSG*)msg_p, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); /* We cannot use this function call here (set_state_from_ctrl_blk();) since this will execute reset_gpf_tcpip_call() immediately, but we need to evaulate this flag later on */ if((dcm_env_ctrl_blk_p->gsm_current_total_row + dcm_env_ctrl_blk_p->gprs_current_total_row ) > 0) { /* another active connection */ dcm_new_state(DCM_CONN_ACTIVATED, DCM_SUB_NO_ACTION); } else { dcm_new_state(DCM_IDLE, DCM_SUB_NO_ACTION); } } return DCM_OK; } /* * Function used to process the reception of the answer to AT+CGATT=... * * @param received message, and row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ T_DCM_RET dcm_process_cgatt_ans(T_DCM_HDR * msg_p, U8 row) { TRACE_FUNCTION("DCM: dcm_process_cgatt_ans()"); if(msg_p->msg_id == DCM_NEXT_CMD_READY_MSG) { /* send next AT command */ return dcm_send_cgpco_auth_cmd(row); } else { psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); return DCM_OK; } } /* * Function used to process the reception of the answer to AT+CGACT=... * * @param received message, and row in the IPU structure related to the actual command * @return DCM_OK or DCM errors */ T_DCM_RET dcm_process_cgact_ans(T_DCM_HDR * msg_p, U8 row) { TRACE_FUNCTION("DCM: dcm_process_cgact_ans()"); if (msg_p->msg_id == DCM_NEXT_CMD_READY_MSG) { return dcm_send_cgpaddr_cmd(row); } else { psaDCM_open_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); /*set_state_from_ctrl_blk();*/ /* We cannot use this function call here (set_state_from_ctrl_blk();) since this will execute reset_gpf_tcpip_call() immediately, but we need to evaulate this flag later on */ if((dcm_env_ctrl_blk_p->gsm_current_total_row + dcm_env_ctrl_blk_p->gprs_current_total_row ) > 0) { /* another active connection */ dcm_new_state(DCM_CONN_ACTIVATED, DCM_SUB_NO_ACTION); } else { dcm_new_state(DCM_IDLE, DCM_SUB_NO_ACTION); } return DCM_OK; } } T_DCM_RET dcm_process_cgdeact_ans(T_DCM_HDR * msg_p, U8 row) { TRACE_FUNCTION("DCM: dcm_process_cgdeact_ans()"); if(msg_p->msg_id == DCM_NEXT_CMD_READY_MSG) { psaDCM_close_conn_cnf(DCM_OK, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); } else { psaDCM_close_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_env_ctrl_blk_p->ipu_list[row].row_state = ROW_ASSIGNED; } set_state_from_ctrl_blk(); return DCM_OK; } T_DCM_RET dcm_process_sat_dn_ans(T_DCM_HDR * msg_p, U8 row) { TRACE_FUNCTION("DCM: dcm_process_sat_dn_ans()"); if(msg_p->msg_id == DCM_NEXT_CMD_READY_MSG) { return dcm_send_percentppp_get_cmd(row); } else { T_DCM_STATUS_IND_MSG * message = (T_DCM_STATUS_IND_MSG *)msg_p; /* We need to check if TCPIP has been already initialised successfully or not*/ if ( wap_state EQ TCPIP_Activation) { /* Make shure we shutdown TCPIP properly */ wap_state = TCPIP_Deactivation; psaTCPIP_Shutdown_Req(); } psaDCM_open_conn_cnf(message->result, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); return DCM_OK; } } T_DCM_RET dcm_process_sat_h_ans(T_DCM_HDR * msg_p, U8 row) { TRACE_FUNCTION("DCM: dcm_process_sat_h_ans()"); if(msg_p->msg_id == DCM_NEXT_CMD_READY_MSG) { psaDCM_close_conn_cnf(DCM_OK,dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); } else { psaDCM_close_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); } set_state_from_ctrl_blk(); return DCM_OK; } GLOBAL ULONG bytes2ipv4addr(UBYTE *host) { UBYTE c1; ULONG addr = 0; char *tmp; if (!host || host[0]>'9' || host[0]<'0') return -1; tmp=(char *)host; c1 = atoi(tmp); addr = addr | c1 << 24; tmp = strstr(tmp, "."); if(!tmp) return -1; tmp++; c1 = atoi(tmp); addr = addr | c1 << 16; tmp = strstr(tmp, "."); if(!tmp) return -1; tmp++; c1 = atoi(tmp); addr = addr | c1 <<8 ; tmp = strstr(tmp, "."); if(!tmp) return -1; tmp++; c1 = atoi(tmp); addr = addr | c1 ; return dcm_ipaddr_htonl(addr); } LOCAL ULONG dcm_ipaddr_htonl(ULONG horder_ipaddr) { return((U32)((((U32)(horder_ipaddr) & 0x000000ffU) << 24) | (((U32)(horder_ipaddr) & 0x0000ff00U) << 8) | (((U32)(horder_ipaddr) & 0x00ff0000U) >> 8) | (((U32)(horder_ipaddr) & 0xff000000U) >> 24))); } LOCAL T_DCM_RET dcm_send_percentcal_get_cmd(UBYTE row) { T_ACI_CAL_ENTR call_tab[MAX_CALL_NR]; UBYTE i; UBYTE count = 0; TRACE_FUNCTION("DCM: dcm_send_percentcal_get_cmd()"); if(qAT_PercentCAL(CMD_SRC_LCL, call_tab) EQ AT_CMPL) { for(i=0; i<MAX_CALL_NR; i++) { if(call_tab[i].index == -1) { count++; /* in other words no active call*/ if(count EQ (MAX_CALL_NR -1) ) { TRACE_EVENT("DCM: No active call"); psaDCM_close_conn_cnf(DCM_OK, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); } break; } switch(call_tab[i].status) { case CAL_STAT_Active: dcm_send_sat_h_cmd(row); break; case CAL_STAT_Dial: case CAL_STAT_Alerting: dcm_send_sat_abort_cmd(row); break; default: TRACE_EVENT("DCM: dcm_send_percentcal_get_cmd DEFAULT call status"); break; } } return DCM_OK; } return DCM_OK; } LOCAL T_DCM_RET dcm_send_sat_abort_cmd(U8 row) { TRACE_FUNCTION("DCM: dcm_send_sat_h_cmd()"); switch(sAT_Abort(CMD_SRC_LCL,AT_CMD_D)) { case AT_FAIL: case AT_BUSY: psaDCM_close_conn_cnf(DCM_NOT_READY, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); set_state_from_ctrl_blk(); break; case AT_CMPL: psaDCM_close_conn_cnf(DCM_OK,dcm_env_ctrl_blk_p->ipu_list[row].api_instance); dcm_free_row(row); set_state_from_ctrl_blk(); break; case AT_EXCT: dcm_new_state(DCM_CLOSING_CONN, DCM_SUB_WAIT_SATH_CNF); dcm_env_ctrl_blk_p->dcm_call_back = dcm_handle_message; break; default : break; } return DCM_OK; } /* This functions checks if antother conneciton is active and changes the DCM state corresponding */ LOCAL void set_state_from_ctrl_blk() { if((dcm_env_ctrl_blk_p->gsm_current_total_row + dcm_env_ctrl_blk_p->gprs_current_total_row ) > 0) { /* another active connection */ dcm_new_state(DCM_CONN_ACTIVATED, DCM_SUB_NO_ACTION); } else { dcm_new_state(DCM_IDLE, DCM_SUB_NO_ACTION); reset_gpf_tcpip_call(); } }