FreeCalypso > hg > fc-magnetite
view src/g23m-aci/aci/dcm_utils.c @ 673:62a5285e014a
Lorekeeping: allow tpudrv-leonardo.lib on Leonardo/Tango
Back in 2015 the Mother's idea was to produce a FreeCalypso development
board that would be a clone of TI Leonardo, including the original
quadband RFFE; one major additional stipulation was that this board
needed to be able to run original unmodified TCS211-20070608 firmware
with all blobs intact, with only minimal binary patches to main.lib
and tpudrv.lib. The necessary patched libs were produced at that time
in the tcs211-patches repository.
That plan was changed and we produced FCDEV3B instead, with Openmoko's
triband RFFE instead of Leonardo quadband, but when FC Magnetite started
in 2016, a TPUDRV_blob= provision was still made, allowing the possibility
of patching OM's tpudrv.lib for a restored Leonardo RFFE.
Now in 2020 we have FC Tango which is essentially a verbatim clone of
Leonardo core, including the original quadband RFFE. We have also
deblobbed our firmware so much that we have absolutely no real need
for a blob version of tpudrv.lib - but I thought it would be neat to put
the ancient TPUDRV_blob= mechanism (classic config) to its originally
intended use, just for the heck of it.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 May 2020 03:55:36 +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(); } }