FreeCalypso > hg > fc-magnetite
view src/g23m-aci/aci/dcm_utils.c @ 632:d968a3216ba0
new tangomdm build target
TCS211/Magnetite built for target leonardo runs just fine on the Tango-based
Caramel board, but a more proper tangomdm build target is preferable in order
to better market these Tango modems to prospective commercial customers. The
only differences are in GPIO and MCSI config:
* MCSI is enabled in the tangomdm build config.
* GPIO 1 is loudspeaker amplifier control on Leonardo, but on Tango platforms
it can be used for anything. On Caramel boards this GPIO should be
configured as an output driving high.
* GPIO 2 needs to be configured as Calypso input on Leonardo, but on Tango
platforms it can be used for anything. On Caramel boards this GPIO should be
configured as an output, either high or low is OK.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 04 Jan 2020 19:27:41 +0000 |
parents | 53929b40109c |
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); BOOL is_netdrop = FALSE ; //pinghua added patch for DCM open/close /*************************************************************************************** * 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; 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 is removed ,as case is returning before break so it is not needed */ /*lint +e527 */ case DCM_OPEN_CONN_REQ_MSG: dcm_open_conn_req_msg_p = (T_DCM_OPEN_CONN_REQ_MSG*)msg_p; psaDCM_open_conn_cnf(DCM_BUSY, dcm_open_conn_req_msg_p->conn_req.api_instance); return (DCM_BUSY); /* It is replaced with return in next line to avoid warning */ /*lint -e527 suppress Warning -- Unreachable */ /* break is removed ,as case is returning before break so it is not needed */ /*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] EQ 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 is removed ,as case is returning before break so it is not needed */ /*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; //pinghua DCM_OPEN_CLOSE patch 20080429 start T_P_CGREG_STAT status = (T_P_CGREG_STAT)0; USHORT lac, ci; TRACE_FUNCTION("DCM: dcm_process_close_conn_event()"); qAT_PercentCGREG(CMD_SRC_LCL, &status, &lac, &ci); TRACE_EVENT_P1("NOW NET STATA is %d", status); if(status>=P_CGREG_STAT_LIMITED ) { psaDCM_close_conn_cnf(DCM_NO_NETWORK, close_conn_p->close_req.api_instance); return DCM_NO_NETWORK; } // pinghua DCM_OPEN_CLOSE patch 20080429 end for (i=0; i < DCM_MAX_NUMBER_IPU; i++) { if( (dcm_env_ctrl_blk_p->ipu_list[i].api_instance EQ close_conn_p->close_req.api_instance) AND (dcm_env_ctrl_blk_p->ipu_list[i].row_state) ) { if(dcm_env_ctrl_blk_p->ipu_list[i].bearer_type EQ 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 EQ 1) { if(dcm_env_ctrl_blk_p->ipu_list[i].bearer_type EQ 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; } // pinghua DCM_OPEN_CLOSE patch 20080429 start here T_DCM_RET dcm_process_network_drop(T_DCM_CLOSE_CONN_REQ_MSG *close_conn_p ) { U8 i; U8 current_bearer_count; TRACE_FUNCTION("DCM: dcm_process_network_drop()"); for (i=0; i < DCM_MAX_NUMBER_IPU; i++) { if( (dcm_env_ctrl_blk_p->ipu_list[i].api_instance EQ close_conn_p->close_req.api_instance) AND (dcm_env_ctrl_blk_p->ipu_list[i].row_state) ) { if(dcm_env_ctrl_blk_p->ipu_list[i].bearer_type EQ 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 EQ 1) { if(dcm_env_ctrl_blk_p->ipu_list[i].bearer_type EQ DCM_BEARER_GPRS) { dcm_send_cgdeact_cmd(i); is_netdrop = TRUE ; // pinghua added DCM_OPEN_CLOSE patch } 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; } //pinghua DCM_OPEN_CLOSE patch 20080429 end /******************************************************************************* * 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 *******************************************************************************/ EXTERN T_ACI_WAP_STATES wap_state; T_DCM_RET dcm_process_open_conn_event(T_DCM_OPEN_CONN_REQ_MSG *open_conn_p) { U8 row_id, row_id_free; // pinghua DCM_OPEN_CLOSE patch 20080429 start T_P_CGREG_STAT status = (T_P_CGREG_STAT)0; USHORT lac, ci; TRACE_FUNCTION("DCM: dcm_process_open_conn_event()"); qAT_PercentCGREG(CMD_SRC_LCL, &status, &lac, &ci); TRACE_EVENT_P1("NOW NET STATA is %d", status); if(status>=P_CGREG_STAT_LIMITED ) { psaDCM_open_conn_cnf(DCM_NO_NETWORK, open_conn_p->conn_req.api_instance); return DCM_NO_NETWORK; } if( wap_state != Wap_Not_Init ) { // if(dcm_env_ctrl_blk_p->state[0]==DCM_CONN_ACTIVATED || // dcm_env_ctrl_blk_p->state[0]==DCM_CLOSING_CONN || dcm_env_ctrl_blk_p->state[0] ==DCM_ACTIVATING_CONN ) { psaDCM_open_conn_cnf(DCM_NOT_READY, open_conn_p->conn_req.api_instance); return DCM_NOT_READY; } } // pinghua DCM_OPEN_CLOSE patch 20080429 end /* 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 */ psaDCM_open_conn_cnf(DCM_NOT_READY, open_conn_p->conn_req.api_instance); return (DCM_NOT_READY); /* It is replaced with return in next line to avoid warning */ } /* 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 EQ open_conn_p->conn_req.api_instance) { /* send the negative confirmation to the IPU */ psaDCM_open_conn_cnf(DCM_ALREADY_ACTIVATED, open_conn_p->conn_req.api_instance); return( DCM_ALREADY_ACTIVATED ); /* It is replaced with return in next line to avoid warning */ } } else { /* get the first entry */ if (row_id_free EQ DCM_MAX_NUMBER_IPU) { row_id_free = row_id; } } } if (row_id_free EQ DCM_MAX_NUMBER_IPU) { /* send the negative confirmation to the IPU */ psaDCM_open_conn_cnf(DCM_NOT_READY, open_conn_p->conn_req.api_instance); return( DCM_NOT_READY ); /* It is replaced with return in next line to avoid warning */ } /* Check the bearer type */ /* check best one bearer */ if(open_conn_p->conn_req.bearer_select EQ DCM_BEARER_ANY) { T_CGATT_STATE cgatt_state; qAT_PlusCGATT(CMD_SRC_LCL,&cgatt_state); if(cgatt_state EQ 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 EQ DCM_BEARER_GSM OR open_conn_p->conn_req.bearer_select EQ 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 EQ 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 EQ 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 EQ 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 EQ 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 EQ 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 EQ 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 EQ DCM_BEARER_GPRS) strcpy((char*)dcm_env_ctrl_blk_p->ipu_list[row].apn, apn); else if (bearer_type EQ 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]; */ T_PDP_CONTEXT defCtxts[PDP_CONTEXT_CID_MAX]; SHORT cid_array[PDP_CONTEXT_CID_MAX]; UBYTE i; TRACE_FUNCTION("DCM: dcm_send_cgdcont_get_cmd()"); if(qAT_PlusCGDCONT(CMD_SRC_LCL,defCtxts,cid_array) NEQ 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] EQ 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; */ T_PDP_CONTEXT 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.pdp_apn,(char*)dcm_env_ctrl_blk_p->ipu_list[row].apn); strcpy(input_txt.pdp_type,"IP"); memset(&input_txt.pdp_addr,0,sizeof(T_NAS_ip)); input_txt.d_comp = PDP_CONTEXT_D_COMP_OMITTED; input_txt.h_comp = PDP_CONTEXT_H_COMP_OMITTED; if(sAT_PlusCGDCONT(CMD_SRC_LCL,dcm_env_ctrl_blk_p->ipu_list[row].cid, &input_txt) NEQ 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) NEQ 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) NEQ 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#"); /* reset the WAP-data if not done at call termination before */ sAT_PercentWAP(CMD_SRC_LCL,0); sAT_PercentWAP(CMD_SRC_LCL,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,PDP_CONTEXT_CID_INVALID}; TRACE_FUNCTION("DCM: dcm_send_cgdeact_cmd()"); /* Packet Counter */ sAT_PercentSNCNT(CMD_SRC_LCL,NAS_RESET_YES); qAT_PlusCGATT(CMD_SRC_LCL,&gprs_attach_state); TRACE_EVENT_P1("DCM: Attatch State %d",gprs_attach_state); #if 0 //// pinghua DCM_OPEN_CLOSE patch 20080429 if(gprs_attach_state NEQ 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; } #endif // // pinghua DCM_OPEN_CLOSE patch 20080429 end /* 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) { 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_NAS_ip pdp_address[MAX_CID]; SHORT cid_array[MAX_CID]; cid_array[0] = dcm_env_ctrl_blk_p->ipu_list[row].cid; cid_array[1] = PDP_CONTEXT_CID_INVALID; TRACE_FUNCTION("DCM: dcm_send_cgpaddr_cmd()"); memset(pdp_address , 0x00, sizeof(T_NAS_ip)*MAX_CID); /* prepare the AT command including some dynamic info like cid */ if(sAT_PlusCGPADDR(CMD_SRC_LCL,cid_array,pdp_address) NEQ 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].ip_address.ipv4_addr.a4, sizeof(NAS_SIZE_IPv4_ADDR)); 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) NEQ 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(CMD_SRC_LCL,0); sAT_PercentWAP(CMD_SRC_LCL,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 EQ 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) NEQ 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 EQ 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 EQ 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 EQ DCM_NEXT_CMD_READY_MSG) { //pinghua add one broken messaged indiction for net drop ! if(is_netdrop == TRUE ) { psaDCM_error_ind((T_DCM_STATUS_IND_MSG*)msg_p, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); } else psaDCM_close_conn_cnf(DCM_OK, dcm_env_ctrl_blk_p->ipu_list[row].api_instance); //end 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 EQ 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 EQ 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 OR host[0]>'9' OR host[0]<'0') return((ULONG)-1); tmp=(char *)host; c1 = atoi(tmp); addr = addr | c1 << 24; tmp = strstr(tmp, "."); if(!tmp) return((ULONG)-1); tmp++; c1 = atoi(tmp); addr = addr | c1 << 16; tmp = strstr(tmp, "."); if(!tmp) return((ULONG)-1); tmp++; c1 = atoi(tmp); addr = addr | c1 <<8 ; tmp = strstr(tmp, "."); if(!tmp) return((ULONG)-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 EQ -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(); } }