MTK手机App开发过去开发总是使用while循环嵌套来获取数据,而现在我们使用消息机制来完成Socket上网。本篇博客借手机里的天气应用来系统介绍MTK手机App连接上网所需要经历的步骤。
GPRS负责为Socket联网进行网络注册,这一部分负责和手机的apn交互,为Socket联网拿到account_id。
mtk_network_gprs.h
#ifndef _MTK_NETWORK_GPRS_H_
#define _MTK_NETWORK_GPRS_H_
#include "mtk_network_def.h"
extern void mtk_network_gprs_reg( E_MTK_NETWORK_MODE net_mode );
extern void mtk_network_gprs_dereg( void );
#endif
mtk_network_gprs.c
#if defined (__MTK_NETWORK_SUPPORT__)
#include "mtk_network_config.h"
#include "mtk_network_socket.h"
#include "mtk_network_debug.h"
#include "mtk_network_gprs.h"
#include "mtk_network_def.h"
#include "kal_release.h"
#include "kal_trace.h"
#include "kal_debug.h"
#include "cbm_api.h"
#include "cbm_consts.h"
/**** Data Acccount related *****/
#include "DtcntSrvGprot.h"
#include "DtcntSrvIprot.h"
#include "DataAccountGProt.h"
/**** Data Account End *****/
#include "NwUsabSrvGprot.h"
#include "MMIDataType.h"
extern S_MTK_NETWORK_NW_STAT nw_stat;
extern S_MTK_NETWORK_SOC_STAT soc_stat;
static kal_int32 mtk_network_2_mi( kal_int32 y )
{
if( y <= 0 )
{
return 1;
}
return 2 * mtk_network_2_mi( y - 1 );
}
dtcnt_apptype_enum mtk_network_gprs_net_mode( E_MTK_NETWORK_MODE net_mode )
{
switch( net_mode )
{
case E_MTK_NETWORKMODE_NET:
if ( g_mtk_network_vm_mode == DTCNT_APPTYPE_MRE_NAME )
{
return ( 0x0800 | DTCNT_APPTYPE_SKIP_CSD );
}
else if ( g_mtk_network_vm_mode == DTCNT_APPTYPE_VRE_NAME )
{
return ( 0x0800 );
}
break;
case E_MTK_NETWORKMODE_NONE:
case E_MTK_NETWORKMODE_WAP:
case E_MTK_NETWORKMODE_AUTO:
default:
if ( g_mtk_network_vm_mode == DTCNT_APPTYPE_MRE_NAME )
{
return ( 0x0400 | DTCNT_APPTYPE_SKIP_CSD );
}
else if ( g_mtk_network_vm_mode == DTCNT_APPTYPE_VRE_NAME )
{
return ( 0x0400 );
}
break;
}
}
BOOL mtk_network_dtcnt_get_apn(U32 account_id, S8 *dest, U8 len)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
srv_dtcnt_prof_str_info_qry_struct acct_data;
extern MMI_BOOL srv_dtcnt_get_apn(U32 acc_id,
srv_dtcnt_prof_str_info_qry_struct *out_apn,
srv_dtcnt_account_enum acc_idx);
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if( !mtk_network_is_mmi_feature_open )
{
return MMI_FALSE;
}
acct_data.dest_len = len;
acct_data.dest = (S8*)dest;
return srv_dtcnt_get_apn(account_id, &acct_data, SRV_DTCNT_ACCOUNT_PRIMARY);
}
void mtk_network_gprs_reg_profile( E_MTK_NETWORK_MODE net_mode )
{
kal_uint32 account_id = 0; //输出 内部判断网络账号 out
srv_dtcnt_result_enum result;
cbm_sim_id_enum sim_id; //少一个0
dtcnt_apptype_enum netMode;
wchar_t *pApn;
kal_int32 iIndex; //(kal_int32)SRV_DTCNT_PROF_MAX_ACCOUNT_NUM;
mtk_network_debug( 2, "GPRS PROFILE REGISTER ACCOUNTID START!");
//全局变量初始化
nw_stat.nw_net_mode = (kal_int8)net_mode;
//本地变量初始化
memset(&(nw_stat.data_account_profile), 0, sizeof(srv_dtcnt_store_prof_data_struct));
nw_stat.data_account_profile.prof_type = SRV_DTCNT_BEARER_GPRS;
nw_stat.data_account_profile.prof_data = &(nw_stat.profile_gprs);
nw_stat.data_account_profile.prof_fields = SRV_DTCNT_PROF_FIELD_ALL;
memset(&(nw_stat.profile_gprs), 0, sizeof(srv_dtcnt_prof_gprs_struct));
nw_stat.profile_gprs.prof_common_header.acct_type = SRV_DTCNT_PROF_TYPE_USER_CONF;
nw_stat.profile_gprs.prof_common_header.acc_id = account_id;
netMode = mtk_network_gprs_net_mode(net_mode);
switch( net_mode )
{
case E_MTK_NETWORKMODE_NET:
pApn = L"cmnet";
nw_stat.profile_gprs.APN = (const U8 *)"cmnet";
nw_stat.profile_gprs.prof_common_header.AccountName = (const U8 *)L"USER_NET";
break;
case E_MTK_NETWORKMODE_NONE:
case E_MTK_NETWORKMODE_WAP:
case E_MTK_NETWORKMODE_AUTO:
default:
pApn = L"cmwap";
nw_stat.profile_gprs.APN = (const U8 *)"cmwap";
nw_stat.profile_gprs.prof_common_header.AccountName = (const U8 *)L"USER_WAP";
break;
}
//选择sim卡
for( sim_id = CBM_SIM_ID_SIM1; sim_id < CBM_SIM_ID_TOTAL; sim_id++ )
{
iIndex = mtk_network_2_mi( (kal_int32)sim_id );
if( srv_nw_usab_is_usable ((mmi_sim_enum)iIndex) )
{
nw_stat.nw_sim_id = ( kal_int8 )iIndex;
break;
}
}
mtk_network_debug( 2, "SIMID CHOOSE START!" );
mtk_network_debug( 2, "cbm_sim_id_enum simid = %d !", sim_id );
mtk_network_debug( 2, "mmi_sim_enum simid = %d !", nw_stat.nw_sim_id );
mtk_network_debug( 2, "sim card apn = %s !", nw_stat.profile_gprs.APN );
mtk_network_debug( 2, "SIMID CHOOSE STOP!" );
nw_stat.profile_gprs.prof_common_header.sim_info = (srv_dtcnt_sim_type_enum)(sim_id+1);
result = srv_dtcnt_store_add_prof(&(nw_stat.data_account_profile), &(account_id));//
if(result == SRV_DTCNT_RESULT_STORE_FULL)
{
mtk_network_debug( 2, "GPRS PROFILE REGISTER ACCOUNTID ADD RESULT FULL THEN QRY!" );
iIndex = (kal_int32)SRV_DTCNT_PROF_MAX_ACCOUNT_NUM;
memset(&(nw_stat.qry_prof), 0, sizeof(srv_dtcnt_store_prof_data_struct));
nw_stat.qry_prof.prof_type = SRV_DTCNT_BEARER_GPRS;
nw_stat.qry_prof.prof_data = &(nw_stat.prof_gprs);
nw_stat.qry_prof.prof_fields = SRV_DTCNT_PROF_FIELD_ALL;
while(iIndex--)
{
if(srv_dtcnt_acct_is_read_only(iIndex))
{
mtk_network_debug( 2, "count %d account is read only continue !", iIndex );
continue;
}
memset(&(nw_stat.prof_gprs), 0, sizeof(srv_dtcnt_prof_gprs_struct));
result = srv_dtcnt_store_qry_prof(iIndex, &(nw_stat.qry_prof));
if(result == SRV_DTCNT_RESULT_SUCCESS)
{
mtk_network_debug( 2, "GPRS PROFILE REGISTER ACCOUNTID QRY RESULT SUCCESS !" );
nw_stat.data_account_profile.prof_fields = SRV_DTCNT_PROF_FIELD_ALL;
result = srv_dtcnt_store_update_prof(iIndex, &(nw_stat.data_account_profile));
if(result == SRV_DTCNT_RESULT_SUCCESS)
{
nw_stat.profile_id = iIndex;
nw_stat.nw_account_id = cbm_encode_data_account_id(iIndex, sim_id, 1, KAL_FALSE);
nw_stat.account_status = 1;
mtk_network_debug( 2, "profile account index = %d !", iIndex);
mtk_network_debug( 2, "account id = %d !", nw_stat.nw_account_id);
mtk_network_debug( 2, "GPRS PROFILE REGISTER ACCOUNTID STOP!");
mtk_network_commit_status(E_MTK_NETWORK_GPRS_SUCCESS);
return;//SUCCESS
}
}
}
mtk_network_debug( 2, "GPRS PROFILE REGISTER ACCOUNTID ADD RESULT FAIL THEN RETURN!" );
//return;//FAIL
}
else if (result == SRV_DTCNT_RESULT_SUCCESS)
{
mtk_network_debug( 2, "GPRS PROFILE REGISTER ACCOUNTID ADD RESULT SUCCESS!" );
nw_stat.profile_id = account_id;
nw_stat.nw_account_id = cbm_encode_data_account_id(account_id, sim_id, 1, KAL_FALSE);
nw_stat.account_status = 1;
mtk_network_debug( 2, "profile account index = %d !", account_id );
mtk_network_debug( 2, "account id = %d !", nw_stat.nw_account_id);
mtk_network_debug( 2, "GPRS PROFILE REGISTER ACCOUNTID STOP!");
mtk_network_commit_status(E_MTK_NETWORK_GPRS_SUCCESS);
return;//SUCCESS
}
mtk_network_commit_status ( E_MTK_NETWORK_GPRS_FAIL );
return;//DEFAULT FAIL
}
void mtk_network_gprs_reg( E_MTK_NETWORK_MODE net_mode )
{
kal_int32 iIndex;
kal_int32 acc_id;
wchar_t apn_name[100];
wchar_t *pApn = NULL;
wchar_t *pApn_l = NULL;
kal_int8 plmn[6+1];
CHAR tmp[20];
cbm_app_info_struct app_info;
cbm_sim_id_enum sim_id;//少一个0
dtcnt_apptype_enum netMode;
extern S32 mmi_wcsnicmp(const WCHAR *str_src, const WCHAR *str_dst, U32 count );
extern MMI_BOOL srv_sim_ctrl_get_home_plmn(mmi_sim_enum sim, CHAR *out_plmn_buffer, U32 buffer_size);
nw_stat.nw_net_mode = (kal_int8)net_mode;
netMode = mtk_network_gprs_net_mode(net_mode);
switch( net_mode )
{
case E_MTK_NETWORKMODE_NET:
pApn = L"cmnet";
pApn_l = L"uninet";
break;
case E_MTK_NETWORKMODE_NONE:
case E_MTK_NETWORKMODE_WAP:
case E_MTK_NETWORKMODE_AUTO:
default:
pApn = L"cmwap";
pApn_l = L"uniwap";
break;
}
#ifdef WIN32
if( !mtk_network_is_tcpip_open )
{
mtk_network_debug( 2, "GPRS TCPIP IS CLOSED!" );
mtk_network_commit_status ( E_MTK_NETWORK_GPRS_FAIL );
return;
}
nw_stat.account_status = cbm_get_valid_account_id( CBM_GPRS,
&(nw_stat.nw_account_id) );
mtk_network_debug( 2, "GPRS REGISTER ACCOUNTID START!" );
mtk_network_debug( 2, "account id = %d!", nw_stat.nw_account_id );
mtk_network_debug( 2, "GPRS REGISTER ACCOUNTID STOP!");
if( nw_stat.account_status == CBM_ERROR )
{
mtk_network_commit_status ( E_MTK_NETWORK_GPRS_FAIL );
return;
}
mtk_network_commit_status(E_MTK_NETWORK_GPRS_SUCCESS);
nw_stat.account_status = 1;
return;
#endif
mtk_network_debug( 2, "GPRS REGISTER ACCOUNTID START!");
for( sim_id = CBM_SIM_ID_SIM1; sim_id < CBM_SIM_ID_TOTAL; sim_id++ )
{
iIndex = mtk_network_2_mi( (kal_int32)sim_id );
if( srv_nw_usab_is_usable ((mmi_sim_enum)iIndex) )
{
nw_stat.nw_sim_id = ( kal_int8 )iIndex;
break;
}
}
mtk_network_debug( 2, "cbm_sim_id_enum simid = %d !", sim_id );
mtk_network_debug( 2, "mmi_sim_enum simid = %d !", nw_stat.nw_sim_id );
if ( MMI_TRUE == srv_sim_ctrl_get_home_plmn(
(mmi_sim_enum)( nw_stat.nw_sim_id ), ( CHAR * )plmn, sizeof( plmn ) ) )
{
mtk_network_debug( 2, "home plmn = %s !", plmn );
}
else
{
mtk_network_debug( 2, "PLMN BAD THEN RETURN!" );
mtk_network_commit_status ( E_MTK_NETWORK_GPRS_FAIL );
return;
}
memset( &app_info, 0, sizeof(app_info) );
app_info.app_icon_id = 0;//GetRootTitleIcon(IMG_GLOBAL_OK);
app_info.app_str_id = 0;//STR_ID_AVK;
app_info.app_type = (kal_uint64)netMode;//DTCNT_APPTYPE_MRE_WAP;
#if defined (__TCPIP__)
if( CBM_OK == cbm_register_app_id_with_app_info(
&app_info, &( nw_stat.nw_app_id ) ) )
{
mtk_network_debug( 2, "appid = %d !", nw_stat.nw_app_id );
}
#endif
for (iIndex = 0; iIndex < SRV_DTCNT_PROF_MAX_ACCOUNT_NUM; iIndex++ )
{
memset(apn_name, 0, 20);
//获取apn
if ( MMI_FALSE == mtk_network_dtcnt_get_apn((U32)iIndex, (S8 *)apn_name, 20) )
{
mtk_network_debug( 2, "profile account index = %d, continue !", iIndex );
continue;
}
//记录apn
memset( tmp, 0, 20);
mmi_wcs_to_asc(tmp, apn_name);
mtk_network_debug( 2, "profile account index = %d, its apn = %s !", iIndex, tmp);
//获取accountid 当3611A 3611B打开平台后此处需要修改
if ( UNICOM_CMCC_PROCESS == g_mtk_network_process )
{
//(VX2232)11B数据账户不分移动联通的情况
if( memcmp(plmn, "46002", 5) == 0 || memcmp(plmn, "46000", 5) == 0 )//移动卡流程
{
if( mmi_wcsnicmp(apn_name, pApn, 6 ) == 0 )//移动流程
{
break;
}
}
else if( memcmp(plmn, "46001", 5) == 0 )//联通卡流程
{
if ( mmi_wcsnicmp(apn_name, pApn_l, 7 ) == 0 )//先联通流程
{
break;
}
else if ( mmi_wcsnicmp(apn_name, pApn, 6 ) == 0 )//后移动流程
{
break;
}
}
}
else if ( UNICOM_UNICOM_PROCESS == g_mtk_network_process )
{
//(VX2232)在10A平台正常处理数据账户,这一个分支为了防止10A的意外与下一分支分离
//关闭联通移动分离,无论11B 10A等平台均使用正常的数据账户
if( memcmp(plmn, "46002", 5) == 0 || memcmp(plmn, "46000", 5) == 0 )//移动卡流程
{
if( mmi_wcsnicmp(apn_name, pApn, 6 ) == 0 )//移动流程
{
break;
}
}
else if( memcmp(plmn, "46001", 5) == 0 )//联通卡流程
{
if ( mmi_wcsnicmp(apn_name, pApn_l, 7 ) == 0 )//联通流程
{
break;
}
}
}
}//for循环结束
if( iIndex == SRV_DTCNT_PROF_MAX_ACCOUNT_NUM )
{
//此处可以创建数据账户 不过由于各种原因最好不要创建
if( mtk_network_is_profile_create_open )
{
mtk_network_commit_status ( E_MTK_NETWORK_GPRS_WAIT );
mtk_network_debug( 2, "GPRS REGISTER ACCOUNTID STOP RESULT FULL THEN CLEATE PROFILE!" );
mtk_network_gprs_reg_profile(net_mode);
return;
}
mtk_network_debug( 2, "GPRS REGISTER ACCOUNTID STOP RESULT BADACCOUNT!" );
mtk_network_commit_status ( E_MTK_NETWORK_GPRS_FAIL );
return;
}
nw_stat.nw_account_id = cbm_encode_data_account_id(
iIndex, sim_id, nw_stat.nw_app_id, KAL_FALSE );
nw_stat.account_status = 1;
mtk_network_debug( 2, "profile account index = %d !", iIndex );
mtk_network_debug( 2, "sim card apn = %s !", tmp );
mtk_network_debug( 2, "account id = %d !", nw_stat.nw_account_id );
mtk_network_debug( 2, "GPRS REGISTER ACCOUNTID STOP!");
mtk_network_commit_status(E_MTK_NETWORK_GPRS_SUCCESS);
return;
}
void mtk_network_gprs_dereg( void )
{
if( nw_stat.nw_app_id > 0 )
{
if ( cbm_deregister_app_id( nw_stat.nw_app_id ) )
{
mtk_network_debug( 2, "DEREGISTERAPPID OK!");
}
}
if( mtk_network_is_profile_create_open )
{
if ( nw_stat.account_status == 1 )
{
if( nw_stat.profile_id > 0 )
{
srv_dtcnt_store_delete_prof( (nw_stat.profile_id), KAL_TRUE, NULL, NULL );
mtk_network_debug( 2, "GPRS DEREGISTER PROFILE OK!");
}
}
}
}
#endif
Socket在获取到accountid之后就可以进行平时开发中的socket处理了,这里多说几句Tips,正规socket使用soc_create,soc_setsockopt,get_hostbyname,soc_connect,连接成功服务器进行soc_send、soc_recv, 最后停止持续任务进行soc_close。这里很多同事打开,收发一次数据,关闭一蹴而就,这样太浪费socket句柄资源和浪费了socket-tcp长连接的优势,那样开关使用还不如封装下UDP,只要将安全数据收发封装好,和一次性使用socket开关同样的效果,而且属于扩展能力,而不是浪费能力。Socket组件目标通过使用MTK消息机制实现Socket联网功能。而不是使用Timer。
mtk_network_socket.h
#ifndef _MTK_NETWORK_SOCKET_H_
#define _MTK_NETWORK_SOCKET_H_
#if 1 /*引用*/
#include "mtk_network_gprs.h"
#include "kal_release.h"
#include "mtk_network_config.h"
#include "mtk_network_def.h"
/**** Data Acccount related *****/
#include "DtcntSrvGprot.h"
#include "DtcntSrvIprot.h"
#include "DataAccountGProt.h"
/**Data Account End **/
#endif
#if 1 /*结构*/
//宏
#define MTK_NETWORK_MAX_SOCKADDR_LEN (28) //MAX_SOCK_ADDR_LEN
/*枚举*/
typedef enum
{
E_MTK_NETWORK_START, //0 网络启动
E_MTK_NETWORK_GPRS_REG, //1 注册网络资源
E_MTK_NETWORK_GPRS_WAIT, //2 等待网络资源
E_MTK_NETWORK_GPRS_SUCCESS, //3 网络资源注册成功
E_MTK_NETWORK_DNS_GET, //4 获取服务器IP解析
E_MTK_NETWORK_DNS_WAIT, //5 等待服务器IP解析
E_MTK_NETWORK_DNS_SUCCESS, //6 服务器IP解析成功
E_MTK_NETWORK_SOC_CREATE, //7 初始化连接
E_MTK_NETWORK_SOC_CONNECT, //8 请求服务器连接
E_MTK_NETWORK_SOC_BIDE, //9 等待服务器连接
E_MTK_NETWORK_SOC_INIT, //10 服务器连接成功,此时可发送初始化数据(手动)
E_MTK_NETWORK_SOC_SEND, //11 发送数据至服务器
E_MTK_NETWORK_SOC_RECV, //12 接收服务器数据
E_MTK_NETWORK_SOC_WAIT, //13 等待服务器空闲
E_MTK_NETWORK_SOC_BLOCK, //14 服务被占用,请等待
E_MTK_NETWORK_GPRS_FAIL, //15 注册网络资源失败
E_MTK_NETWORK_DNS_FAIL, //16 服务器IP解析失败
E_MTK_NETWORK_SOC_FAIL, //17 SOCKET失败
E_MTK_NETWORK_CONN_FAIL, //18 服务器连接失败
E_MTK_NETWORK_UPDATE_FAIL, //19 收发消息失败
E_MTK_NETWORK_STOP //20 网络停止
} E_MTK_NETWORK_STEP;
//结构体
//内部 1 SIM_INFO -> ACCOUNT_ID
typedef struct
{
kal_int8 nw_sim_moved_stat; //是否被移除
kal_int8 nw_sim_legality; //是否合法
kal_int8 nw_service_type; //服务商
kal_int8 nw_sim_id; //sim卡
kal_int8 nw_net_mode; //联网方式
kal_uint8 nw_app_id; //应用id
kal_uint32 nw_account_id; //网络账号
kal_int8 account_status;
kal_int32 profile_id; //输出 用户可以忽略
srv_dtcnt_store_prof_data_struct data_account_profile; //输出 网络账户详细配置信息
srv_dtcnt_prof_gprs_struct profile_gprs; //输出 网络账户GPRS详细配置信息
srv_dtcnt_store_prof_data_struct qry_prof; //输出 申请网络账户详细配置信息
srv_dtcnt_prof_gprs_struct prof_gprs; //输出 申请网络账户GPRS详细配置信息
}S_MTK_NETWORK_NW_STAT;
//内部 2 DNS -> SOC信息
typedef struct
{
sockaddr_struct addr; //soc addr
kal_uint16 port; //端口//IP地址 不同平台应该注意大小端问题
kal_int8 soc_id; //soc_id
E_MTK_NETWORK_STEP soc_step; //soc step
}S_MTK_NETWORK_SOC_STAT;
#endif
#if 1
/************************************************************************ * 内存控制 ************************************************************************/
extern void* mtk_network_malloc( kal_int32 size );
extern void mtk_network_free( void* block );
/************************************************************************ * Timer * Timer 控制SOC联网步骤 * 它修改网络状态变量,通知用户 ************************************************************************/
//以下timer很底层,很精准,socket禁用
extern kal_timerid mtk_network_start_timer( kal_char* timer_name,
kal_uint32 count, kal_timer_func_ptr callback );
extern void mtk_network_stop_timer( kal_timerid timer_id );
/*Socket*/
//封装过来简化接口
extern kal_uint8* mtk_network_get_host_name( void );
extern E_MTK_NETWORK_STEP mtk_network_get_status( void );
extern void mtk_network_commit_status( E_MTK_NETWORK_STEP macro );
extern kal_int8 mtk_network_client_open (
const kal_char* host_name,
kal_uint16 port,
E_MTK_NETWORK_MODE net_mode
);
extern kal_int32 mtk_network_recv( kal_int8 soc_id, void* recv_buf, kal_int32 buf_len );
extern kal_int32 mtk_network_send( kal_int8 soc_id, void* send_buf,
kal_int32 send_size );
extern void mtk_network_client_close( kal_int8 soc_id );
#endif
#endif
mtk_network_socket.c
#ifdef __MTK_NETWORK_SUPPORT__
#include "mtk_network_config.h"
#include "mtk_network_gprs.h"
#include "mtk_network_socket.h"
#include "mtk_network_debug.h"
#include "mtk_network_def.h"
#include "kal_release.h"
#include "kal_trace.h"
#include "kal_debug.h"
#include "MMIDataType.h"
#include "med_utility.h"
//#include "soc_api.h"
//#include "EventsGprot.h"
S_MTK_NETWORK_NW_STAT nw_stat;
S_MTK_NETWORK_SOC_STAT soc_stat;
extern void mmi_frm_set_protocol_event_handler(U16 eventID, PsIntFuncPtr funcPtr, MMI_BOOL isMultiHandler);
extern void mmi_frm_clear_protocol_event_handler(U16 eventID, PsIntFuncPtr funcPtr);
void mtk_network_commit_status( E_MTK_NETWORK_STEP macro )
{
soc_stat.soc_step = macro;
mtk_network_proc_info( soc_stat.soc_id, macro );
}
#if 1
void* mtk_network_malloc( kal_int32 size )
{
return med_ext_smalloc( size );
}
void mtk_network_free( void* block )
{
if( block == NULL )
{
return;
}
med_ext_sfree( ( address_t )block );
}
#endif
#if 1
/************************************************************************ * Timer * Timer 控制SOC联网步骤 * 它修改网络状态变量,通知用户 ************************************************************************/
kal_timerid mtk_network_start_timer( kal_char* timer_name,
kal_uint32 count, kal_timer_func_ptr callback )
{
kal_timerid timer_id = NULL;
timer_id = kal_create_timer( timer_name );
kal_set_timer( timer_id, callback, NULL,
count, 1 );
return timer_id;
}
void mtk_network_stop_timer( kal_timerid timer_id )
{
kal_cancel_timer( timer_id );
}
E_MTK_NETWORK_STEP mtk_network_get_status( void )
{
return soc_stat.soc_step;
}
kal_uint8* mtk_network_get_host_name( void )
{
return soc_stat.addr.addr;
}
kal_uint8 mtk_network_read_write_notify_callback( void* inMsg )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
app_soc_notify_ind_struct *soc_notify =
(app_soc_notify_ind_struct*) inMsg;
kal_int32 ret = 0;
kal_bool is_ready = KAL_FALSE;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if( soc_notify->socket_id != soc_stat.soc_id )
{
return 0;
}
mtk_network_debug( 5, "SOCKETCALLBACK_SIGDETECT = %d !", soc_notify->event_type );
switch (soc_notify->event_type)
{
case SOC_WRITE:
mtk_network_commit_status(E_MTK_NETWORK_SOC_SEND);
break;
case SOC_READ:
/* Check if socket is ready for reading */
is_ready = mtk_network_soc_ready_for_read( soc_stat.soc_id );
if(is_ready)
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_RECV);
}
else
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL);
}
/* Close the socket */
break;
case SOC_CONNECT:
/* send data */
if(soc_notify->result != 0)
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_SEND);
/* enable the socket reading */
}
else
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL);
}
break;
case SOC_CLOSE:
mtk_network_commit_status(E_MTK_NETWORK_STOP);
break;
}
//取消消息注册
mmi_frm_clear_protocol_event_handler(
MSG_ID_APP_SOC_NOTIFY_IND,
( PsIntFuncPtr )mtk_network_read_write_notify_callback );
return 1;
}
kal_uint8 mtk_network_connect_notify_callback( void* inMsg )
{
app_soc_get_host_by_name_ind_struct* dns_ind =
(app_soc_get_host_by_name_ind_struct*)inMsg;
if( dns_ind->account_id != nw_stat.nw_account_id )
{
// 如果注册函数为mmi_true(系统不堵塞调用,轮训调用),
// 此处返回0说明系统调用错了回调,回去调用其他的回调.
// 然后再次产生消息,遍历到这个并且是这个回调,OK处理完毕
// 返回1表示回调正确并且受到了处理
return 0;
}
if (dns_ind && dns_ind->result == FALSE)
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL); //???
return 1;
}
memset(&(soc_stat.addr), 0x00, sizeof(soc_stat.addr));
memcpy(soc_stat.addr.addr, dns_ind->addr, dns_ind->addr_len);
soc_stat.addr.addr_len = dns_ind->addr_len;
soc_stat.addr.port = 80;
soc_stat.addr.sock_type = SOC_SOCK_STREAM;
mtk_network_debug(1, "WAIT:IP:%d.%d.%d.%d",
soc_stat.addr.addr[0],soc_stat.addr.addr[1],
soc_stat.addr.addr[2], soc_stat.addr.addr[3] );
mtk_network_commit_status(E_MTK_NETWORK_DNS_SUCCESS);
mtk_network_commit_status(E_MTK_NETWORK_SOC_CONNECT);
switch (mtk_network_soc_connect( soc_stat.soc_id, &(soc_stat.addr)))
{
case SOC_WOULDBLOCK:
mtk_network_commit_status(E_MTK_NETWORK_SOC_BIDE);
case SOC_ALREADY:
case SOC_SUCCESS:
mmi_frm_set_protocol_event_handler(
MSG_ID_APP_SOC_NOTIFY_IND,
(PsIntFuncPtr)mtk_network_read_write_notify_callback, MMI_TRUE);
break;
default:
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL); //???
break;
}
mmi_frm_clear_protocol_event_handler(
MSG_ID_APP_SOC_GET_HOST_BY_NAME_IND,
mtk_network_connect_notify_callback );
return 1;
}
/*Socket*/
//封装过来简化接口
kal_int8 mtk_network_client_open (
const kal_char* host_name,
kal_uint16 port,
E_MTK_NETWORK_MODE net_mode
)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_int8 ret = 0;
kal_int8 soc_id = -1;
kal_uint8 option = 0;
kal_int8 result;
kal_uint8 addr_buf[4];
kal_uint8 addr_len = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
memset(&nw_stat, 0, sizeof(S_MTK_NETWORK_NW_STAT));
memset(&soc_stat, 0, sizeof(S_MTK_NETWORK_SOC_STAT));
mtk_network_commit_status(E_MTK_NETWORK_GPRS_REG);
mtk_network_gprs_reg( net_mode );//init nw_soc
if( nw_stat.account_status < 1 )
{
return -5;
}
mtk_network_commit_status(E_MTK_NETWORK_SOC_CREATE);
/* Create socket */
soc_id = mtk_network_soc_create(
SOC_PF_INET, SOC_SOCK_STREAM,
0, MOD_MMI, nw_stat.nw_account_id );
mtk_network_debug( 1, "SOCKET ID CREATED START!");
mtk_network_debug( 1, "socketid = %d !", soc_id );
mtk_network_debug( 1, "SOCKET ID CREATED STOP!");
if ( soc_id < 0 )
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL);
return -1;
}
soc_stat.soc_id = soc_id;
option = SOC_READ | SOC_WRITE | SOC_ACCEPT | SOC_CONNECT | SOC_CLOSE;
result = mtk_network_soc_setsockopt(soc_id, SOC_ASYNC, &option, sizeof(kal_uint8));
option = KAL_TRUE;
result = mtk_network_soc_setsockopt(soc_id, SOC_NBIO, &option, sizeof(option));
switch( net_mode )
{
case E_MTK_NETWORKMODE_NET:
break;
case E_MTK_NETWORKMODE_NONE:
case E_MTK_NETWORKMODE_WAP:
case E_MTK_NETWORKMODE_AUTO:
default:
#if defined( WIN32 )
soc_stat.addr.addr[0] = 10;
soc_stat.addr.addr[1] = 10;
soc_stat.addr.addr[2] = 0;
soc_stat.addr.addr[3] = 6;
soc_stat.addr.addr_len = 4;
soc_stat.addr.port = 8080;
#else
soc_stat.addr.addr[0] = 10;
soc_stat.addr.addr[1] = 0;
soc_stat.addr.addr[2] = 0;
soc_stat.addr.addr[3] = 172;
soc_stat.addr.addr_len = 4;
soc_stat.addr.port = 80 ;
#endif
mtk_network_debug(1, "OK:IP:%d.%d.%d.%d",
soc_stat.addr.addr[0],soc_stat.addr.addr[1],
soc_stat.addr.addr[2], soc_stat.addr.addr[3] );
goto DONT_DNS;
}
mtk_network_commit_status(E_MTK_NETWORK_DNS_GET);
ret = mtk_network_soc_gethostbyname(
KAL_FALSE,
MOD_MMI,//???
100, //???
host_name,
addr_buf,
&addr_len,
0, //???
nw_stat.nw_account_id
);
if (ret == SOC_SUCCESS) // success
{
soc_stat.addr.addr[0] = addr_buf[0];
soc_stat.addr.addr[1] = addr_buf[1];
soc_stat.addr.addr[2] = addr_buf[2];
soc_stat.addr.addr[3] = addr_buf[3];
soc_stat.addr.addr_len = addr_len;
soc_stat.addr.port = port;
soc_stat.addr.sock_type = SOC_SOCK_STREAM;
mtk_network_debug( 1, "OK:IP:%d.%d.%d.%d\n",
soc_stat.addr.addr[0],soc_stat.addr.addr[1],
soc_stat.addr.addr[2], soc_stat.addr.addr[3] );
mtk_network_commit_status(E_MTK_NETWORK_DNS_SUCCESS);
}
else if (ret == SOC_WOULDBLOCK) // block ???
{
mtk_network_commit_status(E_MTK_NETWORK_DNS_WAIT);
mmi_frm_set_protocol_event_handler(
MSG_ID_APP_SOC_GET_HOST_BY_NAME_IND,
( PsIntFuncPtr )mtk_network_connect_notify_callback, MMI_TRUE );
return soc_id;
}
else // error
{
mtk_network_commit_status(E_MTK_NETWORK_DNS_FAIL);
return -3;
}
DONT_DNS:
mtk_network_commit_status(E_MTK_NETWORK_SOC_CONNECT);
/* socket connect */
result = mtk_network_soc_connect( soc_id, &(soc_stat.addr) );
mtk_network_debug( 5, "CONNECT_SIGDETECT = %d !", result );
if (result == SOC_SUCCESS)
{
mmi_frm_set_protocol_event_handler(
MSG_ID_APP_SOC_NOTIFY_IND,
(PsIntFuncPtr)mtk_network_read_write_notify_callback,
MMI_TRUE);
}
else if (result == SOC_WOULDBLOCK) //???
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_BIDE);
mmi_frm_set_protocol_event_handler(MSG_ID_APP_SOC_NOTIFY_IND,
(PsIntFuncPtr)mtk_network_read_write_notify_callback, MMI_TRUE);
}
else
{
mtk_network_commit_status(E_MTK_NETWORK_CONN_FAIL);
return -4;
}
return soc_id;
}
kal_int32 mtk_network_recv( kal_int8 soc_id, void* recv_buf, kal_int32 buf_len )
{
kal_int32 ret = -1;
ret = mtk_network_soc_recv( soc_id, recv_buf, buf_len, 0 );//
mtk_network_debug( 5, "RECV_SIGDETECT = %d !", ret );
/*if( ret == SOC_PIPE )//网络信号差或者account_id内部宏值异常 { mtk_network_commit_status(E_MTK_NETWORK_SOC_WAIT ); mmi_frm_set_protocol_event_handler(MSG_ID_APP_SOC_NOTIFY_IND, (PsIntFuncPtr)mtk_network_read_write_notify_callback, MMI_TRUE); } else */
if (ret < 0 && ret != SOC_WOULDBLOCK)
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL);//...//error handling
}
else if( ret > 0 )
{
//默认下一步 继续接收
mtk_network_commit_status(E_MTK_NETWORK_SOC_RECV);
}
else if( ret == SOC_WOULDBLOCK )//却是堵塞
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_WAIT );
mmi_frm_set_protocol_event_handler(MSG_ID_APP_SOC_NOTIFY_IND,
(PsIntFuncPtr)mtk_network_read_write_notify_callback, MMI_TRUE);
}
else if( ret == 0 )//这一步 到不了KD
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_SEND);
}
return ret;
}
kal_int32 mtk_network_send( kal_int8 soc_id, void* send_buf,
kal_int32 send_size )
{
kal_int32 result;
result = mtk_network_soc_send( soc_id, send_buf, send_size , 0 );
mtk_network_debug( 5, "SEND_SIGDETECT = %d !", result );
if( result == SOC_WOULDBLOCK )
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_WAIT );
mmi_frm_set_protocol_event_handler(MSG_ID_APP_SOC_NOTIFY_IND,
(PsIntFuncPtr)mtk_network_read_write_notify_callback, MMI_TRUE);
}
else if( result < 0 )
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL);
}
else if( result < send_size )
{
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL);
}
else if( result == send_size)
{
//默认下一步 继续发送
//mtk_network_commit_status(E_MTK_NETWORK_SOC_SEND);
}
return result;
}
void mtk_network_client_close( kal_int8 soc_id )
{
kal_int8 ret = 0;
if( soc_id < 0 )
{
return;
}
mmi_frm_clear_protocol_event_handler(
MSG_ID_APP_SOC_GET_HOST_BY_NAME_IND,
( PsIntFuncPtr )mtk_network_connect_notify_callback );
mmi_frm_clear_protocol_event_handler(
MSG_ID_APP_SOC_NOTIFY_IND,
( PsIntFuncPtr )mtk_network_read_write_notify_callback );
ret = mtk_network_soc_close( soc_id );
if( ret < 0 )
{
mtk_network_commit_status( E_MTK_NETWORK_SOC_FAIL );
}
mtk_network_gprs_dereg();
mtk_network_commit_status( E_MTK_NETWORK_STOP );
//memset(&nw_stat, 0, sizeof(S_MTK_NETWORK_NW_STAT));
//memset(&soc_stat, 0, sizeof(S_MTK_NETWORK_SOC_STAT));
}
#endif
#endif
HTTP内部一直有一个Timer在循环检测Socket部件的工作状态,Socket网络连接建立成功之后,HTTP通过调用Socket的收发接口实现HTTP协议规定的get、post等功能。此处的HTTP可以开始get和终止,甚至可以暂停和恢复get过程。HTTP和Socket是两个独立的模块,Socket连接成功之后会保持连接,HTTP在需要的时候获取数据,其实数据保存在了MTK底层的buf-帧中。不需要的时候shutdown。这里的HTTP实现了Session的功能,每发起一次get将会创建一个连接,这在各种平台的HTTP模块功能中是通行的,在MTK平台上进行资源限制,只允许存在这一个HTTPget实例,不允许存在第二个。
mtk_network_http.h
#ifndef _MTK_NETWORK_HTTP_H_
#define _MTK_NETWORK_HTTP_H_
#include "MMIDataType.h"
#include "mtk_network_def.h"
#if 1 //使用外部接口声明
extern void (*gui_start_timer)(S32 count, void(*callback)(void));
extern void (*gui_cancel_timer)( void(*callback)(void));
#endif
#if 1 //本地类型对外声明
typedef enum
{
E_MTK_NETWORK_HTTP_OPEN = 0,
E_MTK_NETWORK_HTTP_HEADER = 1,
E_MTK_NETWORK_HTTP_BODY = 2,
E_MTK_NETWORK_HTTP_NETRESTART = 3,
E_MTK_NETWORK_HTTP_WITHRANGE = 4,
E_MTK_NETWORK_HTTP_CLOSE = 5
}E_MTK_NETWORK_HTTP_ERROR;
typedef struct MTK_NETWORK_HTTPHEADER_
{
U32 Content_Length;
U32 Header_Lenth;
U32 readn;//每次读到的数据
E_MTK_NETWORK_HTTP_ERROR http_errno;//
}MTK_NETWORK_HTTPHEADER;
#endif
#if 1 //本地变量对外声明
typedef void (*FUNC_mtk_network_recv_callback)( void* http_body_buf );
extern MTK_NETWORK_HTTPHEADER http_header; //可以依此判断http_getter状态
#endif
extern S32 mtk_network_http_get(
const char* hostName,
U16 port,
const char* lParam,
FUNC_mtk_network_recv_callback callBack,
E_MTK_NETWORK_MODE netWorkMode,
U32 dnsTimeOut, //S
U32 socRwTimeOut, //S
U32 timeOutReStartNum //
);
extern S32 mtk_network_http_post(
void
);
extern void mtk_network_http_pause( void );
extern void mtk_network_http_resume( void );
extern void mtk_network_http_shutdown( void );
extern void mtk_network_http_end( void );
#endif
mtk_network_http.c
#ifdef __MTK_NETWORK_SUPPORT__
#include "MMIDataType.h"
#include "kal_release.h"
#include "kal_trace.h"
#include "kal_debug.h"
#include "stdlib.h"
#include "mtk_network_socket.h"
#include "mtk_network_config.h"
#include "mtk_network_debug.h"
#include "mtk_network_http.h"
#include "mtk_network_def.h"
#define BUF_SIZE 1024
#define TIMER_OUT_TIME 100
U32 g_range_pos;
E_MTK_NETWORK_MODE g_net_mode;
static S8 g_net_working;
static S8 socket_id;
static char* g_send_buffer;
static char* g_recv_buffer;//保险起见分开,根据内部实现这两个BUF可以合并为一个。
static char* g_host_name;
static char* g_param;
static char* m_new_param;
static S32 buffer_pos;
static U32 g_dns_time_out;
static U32 g_dns_time_pos;
static U32 g_soc_rw_time_out;
static U32 g_soc_rw_time_pos;
static U32 g_restart_num;
static U16 g_port;
static kal_timerid proc_timer;
static kal_timer_func_ptr mtk_network_recv_cb;
static FUNC_mtk_network_recv_callback recvCallBack;//外部
MTK_NETWORK_HTTPHEADER http_header;
static char* mtk_network_http_upper( char chr )
{
static char upp_chr;
upp_chr = chr;
if( chr >= 'a' && chr <= 'z' )
{
upp_chr = chr - 'a' + 'A';
}
return &upp_chr;
}
static char* mtk_network_http_lower( char chr )
{
static char low_chr;
low_chr = chr;
if( chr >= 'A' && chr <= 'Z' )
{
low_chr = chr - 'A' + 'a';
}
return &low_chr;
}
//在原字符串中查找目标字符串 忽略大小写
static char* mtk_network_http_strstr( char* src, char* dst )
{
char* fst_chr;
char* dst_chr;
char* up_chr;
char* low_chr;
S32 dst_len;
S32 i;
if( src == NULL || dst == NULL )
{
return NULL;
}
dst_len = strlen( dst );
dst_chr = dst;
fst_chr = src;
while( *fst_chr != '\0' )
{
low_chr = mtk_network_http_lower( *dst_chr );
up_chr = mtk_network_http_upper( *dst_chr );
if( *low_chr != *fst_chr &&
*up_chr != *fst_chr )
{
fst_chr++;
continue;
}
i = 1;
while( *(fst_chr + i ) != '\0' &&
*( dst_chr + i ) != '\0' )
{
low_chr = mtk_network_http_lower( *(dst_chr+i) );
up_chr = mtk_network_http_upper( *(dst_chr+i) );
if( *(fst_chr + i) == *low_chr ||
*(fst_chr + i) == *up_chr )
{
i++;
continue;
}
break;
}
if( i == dst_len )
{
return fst_chr;
}
fst_chr++;
}
return NULL;
}
void mtk_network_http_restart()
{
if ( g_restart_num > 0 )
{
//重启
g_restart_num--;
mtk_network_debug( 5, "NETWORK RESTART COUNTS!" );
mtk_network_debug( 5, "network restart counts = %d !", g_restart_num );
mtk_network_debug( 5, "NETWORK RESTART COUNTS!" );
g_dns_time_pos = 0;
g_soc_rw_time_pos = 0;
buffer_pos = 0;
mtk_network_client_close( socket_id );
mtk_network_commit_status( E_MTK_NETWORK_START );
return;
}
mtk_network_http_end();
}
void mtk_network_http_speed( void )
{
static S32 lstTime = 0;
static S32 curRead = 0;
U32 iTick;
S32 curTime;
kal_get_time( &iTick );
curTime = (S32)kal_ticks_to_milli_secs(iTick);
if( curTime - lstTime < 1000 )
{
curRead += http_header.readn;
}
else
{
mtk_network_debug( 6, "MtkNetWorkSpeed: %d KB/S", curRead >> 10 );
curRead = 0;
lstTime = curTime;
}
}
void staticRecvHeaderParseAndCheckout( void* recv_buf )//内部解析Header
{
//解析header
char* content_pos = NULL;
char* pRecvChr = NULL;
char statusStr[10];
S32 statusValue;
mtk_network_debug( 4, "%s", recv_buf );
if ( http_header.http_errno == E_MTK_NETWORK_HTTP_BODY ) //1 ContentLength OK 2 Chuncked 3 other
{
mtk_network_http_speed();//计算网速
recvCallBack( recv_buf );
return;
}
mtk_network_debug( 3, "HTTP HEADER PARSE START!");
memset(m_new_param, 0, BUF_SIZE);
pRecvChr = strstr ( recv_buf, "HTTP" );
if ( pRecvChr == NULL )
{
goto NETWORK_RESTART;
}
//Http Status
statusStr[0] = pRecvChr[9];
statusStr[1] = pRecvChr[10];
statusStr[2] = pRecvChr[11];
statusStr[3] = '\0';
statusValue = (S32)atoi( statusStr );
if ( statusValue == 302 || statusValue == 301 )//公司页面
{
int i = 0;
char* url_pos;
//判断是不是联通劫持页面
content_pos = /*strstr*/mtk_network_http_strstr(recv_buf,"www.ishwap.com");
if( content_pos != NULL )
{
//忽略,不处理//重新开始联网
//content_pos += 7;
//strcpy(g_param, m_new_param);
mtk_network_debug( 3, "LIANTONG CHANGEPAGE RESTART\n");
goto NETWORK_RESTART;
}
url_pos = /*strstr*/mtk_network_http_strstr(recv_buf, "Location:");
if(url_pos == NULL)
{
goto NETWORK_RESTART;
}
url_pos += sizeof("Location:");
if( *url_pos == ' ' )
{
url_pos++;
}
i = 0;
while((*url_pos != '\r')&&(*url_pos != '\n'))
{
m_new_param[i] = *(url_pos++);
i++;
}
m_new_param[i] = '\0';
mtk_network_debug( 3, "302 LOCATION START!" );
mtk_network_debug( 3, "Location: %s\n", m_new_param);
mtk_network_debug( 3, "302 LOCATION STOP!" );
strcpy(g_param, m_new_param);
//公司中转处理成功,重启网络
goto WITHRANGE;
}
else if ( statusValue <= 300 && statusValue >= 200 )
{
char content_str[32];
int i = 0;
//判断 服务器是否连接错误
content_pos = /*strstr*/mtk_network_http_strstr( recv_buf, "Failed to get Host IP Address for the WebServer, WebServer not exsisted, or cannot be accessed now" );
if( content_pos != NULL )
{
goto NETWORK_RESTART;
}
//判断是不是移动中转页面 默认数据足够,如果收到的数据不够多,那么会有风险
content_pos = strstr( recv_buf, "<onevent type=\"onenterforward\">" );
if( content_pos != NULL )
{
mtk_network_debug( 3, "PARSE CHINAMOBILE CHANGEPAGE!" );
#if 1
content_pos = /*strstr*/mtk_network_http_strstr( content_pos, "t=" );
if( content_pos == NULL )
{
goto NETWORK_RESTART;
}
i = 0;
m_new_param[i++] = '&';
while( *content_pos != '\"')
{
m_new_param[i++] = *content_pos++;
}
m_new_param[i] = '\0';
strcat( g_param, m_new_param );
#endif
mtk_network_debug( 3, "PARSE HEADER:CHINAMOBILE_STEP START!\n");
mtk_network_debug( 3, "g_host_name:%s\n", g_host_name );
mtk_network_debug( 3, "t_param:%s\n", m_new_param);
mtk_network_debug( 3, "g_param:%s\n", g_param );
mtk_network_debug( 3, "g_param+100:%s\n", g_param + 100 );
mtk_network_debug( 3, "g_param+200:%s\n", g_param + 200 );
mtk_network_debug( 3, "PARSE HEADER:CHINAMOBILE_STEP STOP!\n");
//移动中转处理成功,重启网络
goto NETWORK_RESTART;
}
content_pos = /*strstr*/mtk_network_http_strstr( recv_buf, "Content-Length" );
if ( content_pos == NULL )
{
content_pos = /*strstr*/mtk_network_http_strstr( recv_buf, "Transfer-Encoding" );
if ( content_pos == NULL )
{
goto NETWORK_RESTART;
}
else//chunked
{
goto NETWORK_RESTART;
}
}
while(*content_pos != '\r' && *content_pos != '\n' && i < 31 )
{
if(*content_pos >= '0' && *content_pos <= '9')
{
content_str[i++] = *content_pos;
}
content_pos++;
}
content_str[i] = 0;
http_header.Content_Length = atoi(content_str);
mtk_network_debug( 3, "Header:Content-Length = %d", http_header.Content_Length );
///r/n/r/n
content_pos = strstr( recv_buf, "\r\n\r\n" );
content_pos += 4;
http_header.http_errno = E_MTK_NETWORK_HTTP_BODY;
http_header.Header_Lenth = (U32)(content_pos - (char*)recv_buf );
http_header.readn -= http_header.Header_Lenth;
mtk_network_debug( 3, "HTTP HEADER PARSE STOP BODY!");
recvCallBack( content_pos );
return;
}
else
{
goto NETWORK_RESTART;
}
NETWORK_RESTART:
http_header.http_errno = E_MTK_NETWORK_HTTP_NETRESTART;
recvCallBack( NULL );
mtk_network_http_restart();
mtk_network_debug( 3, "HTTP HEADER PARSE STOP RESTART!");
return;
WITHRANGE:
http_header.http_errno = E_MTK_NETWORK_HTTP_WITHRANGE;
mtk_network_http_restart();
mtk_network_debug( 3, "HTTP HEADER PARSE STOP RESTART!");
return;
}
void mtk_network_process( void )
{
kal_int32 ret = -1;
E_MTK_NETWORK_STEP nw_status;
nw_status = mtk_network_get_status();
gui_cancel_timer(mtk_network_process);
gui_start_timer( TIMER_OUT_TIME, mtk_network_process );
switch(nw_status)
{
case E_MTK_NETWORK_START://打开网络
socket_id = (S8)mtk_network_client_open( g_host_name, g_port, g_net_mode );
if( socket_id < 0 )
{
mtk_network_commit_status( E_MTK_NETWORK_SOC_FAIL );
}
break;
case E_MTK_NETWORK_GPRS_REG:
case E_MTK_NETWORK_GPRS_WAIT:
case E_MTK_NETWORK_GPRS_SUCCESS:
case E_MTK_NETWORK_DNS_SUCCESS:
case E_MTK_NETWORK_DNS_GET:
break;
case E_MTK_NETWORK_SOC_CREATE:
case E_MTK_NETWORK_SOC_CONNECT:
break;
case E_MTK_NETWORK_DNS_WAIT:
case E_MTK_NETWORK_SOC_BIDE:
g_dns_time_pos++;
if ( g_dns_time_pos < g_dns_time_out )//pics
{
break;
}
mtk_network_http_restart();
break;
case E_MTK_NETWORK_SOC_WAIT:
g_soc_rw_time_pos++;
if ( g_soc_rw_time_pos < g_soc_rw_time_out )//pics
{
break;
}
mtk_network_http_restart();
break;
case E_MTK_NETWORK_SOC_INIT:
case E_MTK_NETWORK_GPRS_FAIL:
case E_MTK_NETWORK_DNS_FAIL:
case E_MTK_NETWORK_SOC_FAIL:
case E_MTK_NETWORK_CONN_FAIL:
mtk_network_http_restart();
break;
case E_MTK_NETWORK_SOC_SEND:
{
g_soc_rw_time_pos = 0;
if( buffer_pos == 0 )
{
kal_uint8* buf;
buf = mtk_network_get_host_name();
switch( g_net_mode )
{
case E_MTK_NETWORKMODE_NET:
{
switch( http_header.http_errno )
{
case E_MTK_NETWORK_HTTP_OPEN:
case E_MTK_NETWORK_HTTP_NETRESTART:
//ERROR kal_sprintf( g_send_buffer, "GET %s %s\r\nHost: %d.%d.%d.%d\r\n%s\r\n",
kal_sprintf( g_send_buffer, "GET http://%s%s %s\r\nHost: %d.%d.%d.%d\r\n%s\r\n",
g_host_name,
g_param,
"HTTP/1.1",
buf[0], buf[1], buf[2], buf[3],
"User-Agent: */*\r\nAccept: */*\r\nConnection: keep-Alive\r\nAccept-Encoding: deflate\r\nAccept-Language: zh-cn\r\n"
);
break;
case E_MTK_NETWORK_HTTP_WITHRANGE:
//kal_sprintf( g_send_buffer, "GET %s %s\r\nHost: %d.%d.%d.%d\r\nRANGE: bytes=%d-\r\n%s\r\n",
kal_sprintf( g_send_buffer, "GET http://%s%s %s\r\nHost: %d.%d.%d.%d\r\nRANGE: bytes=%d-\r\n%s\r\n",
g_host_name,
g_param,
"HTTP/1.1",
buf[0], buf[1], buf[2], buf[3],
g_range_pos,
"User-Agent: */*\r\nAccept: */*\r\nConnection: keep-Alive\r\nAccept-Encoding: deflate\r\nAccept-Language: zh-cn\r\n"
);
break;
case E_MTK_NETWORK_HTTP_HEADER:
case E_MTK_NETWORK_HTTP_BODY:
case E_MTK_NETWORK_HTTP_CLOSE:
default:
break;
}
}
break;
case E_MTK_NETWORKMODE_AUTO:
case E_MTK_NETWORKMODE_WAP:
case E_MTK_NETWORKMODE_NONE:
default:
{
switch( http_header.http_errno )
{
case E_MTK_NETWORK_HTTP_OPEN:
case E_MTK_NETWORK_HTTP_NETRESTART:
kal_sprintf( g_send_buffer, "GET %s %s\r\nHost: %d.%d.%d.%d\r\nX-Online-Host:%s\r\nAccept:*/*\r\n\r\n",
g_param,
"HTTP/1.1",
buf[0], buf[1], buf[2], buf[3],
g_host_name
);
break;
case E_MTK_NETWORK_HTTP_WITHRANGE:
kal_sprintf( g_send_buffer, "GET %s %s\r\nHost: %d.%d.%d.%d\r\nRANGE: bytes=%d-\r\nX-Online-Host:%s\r\nAccept:*/*\r\n\r\n",
g_param,
"HTTP/1.1",
buf[0], buf[1], buf[2], buf[3],
g_range_pos,
g_host_name
);
break;
case E_MTK_NETWORK_HTTP_HEADER:
case E_MTK_NETWORK_HTTP_BODY:
case E_MTK_NETWORK_HTTP_CLOSE:
default:
break;
}
}
break;
}
mtk_network_debug( 3, "SEND PACKAGE START!");
mtk_network_debug( 3, "%s", g_send_buffer );
mtk_network_debug( 3, "%s", g_send_buffer + 100 );
mtk_network_debug( 3, "SEND PACKAGE STOP!");
}
ret = mtk_network_send( socket_id, g_send_buffer, strlen(g_send_buffer) );
if( ret < (S32)strlen(g_send_buffer) )
{
buffer_pos = ret;
break;
}
buffer_pos = 0;
//发送完毕提交消息
mtk_network_commit_status(E_MTK_NETWORK_SOC_RECV);
}
break;
case E_MTK_NETWORK_SOC_RECV:
g_soc_rw_time_pos = 0;
memset( g_recv_buffer, 0, BUF_SIZE );
ret = mtk_network_recv( socket_id, g_recv_buffer, BUF_SIZE - 14 );
if( ret == 0 )
{
mtk_network_commit_status( E_MTK_NETWORK_STOP );
}
else if( ret > 0 )
{
http_header.readn = (U32)ret;
staticRecvHeaderParseAndCheckout( g_recv_buffer );
}
break;
case E_MTK_NETWORK_STOP:
mtk_network_http_end();
break;
default:
break;
}
return;
}
S32 mtk_network_http_get(
const char* hostName,
U16 port,
const char* lParam,
FUNC_mtk_network_recv_callback callBack,
E_MTK_NETWORK_MODE netWorkMode,
U32 dnsTimeOut, //S
U32 socRwTimeOut, //S
U32 timeOutReStartNum //
)
{
E_MTK_NETWORK_STEP status;
//防止重复调用模块
status = mtk_network_get_status( );
if ( status > E_MTK_NETWORK_START &&
status < E_MTK_NETWORK_STOP )
{
return 1;
}
if( g_net_working == 1 )
{
return 1;
}//保险
mtk_network_debug(5, "#42DsC = %s", mtk_network_http_strstr( "aBcDeFGd#42DsCfVg", "#42dSc" ) );
mtk_network_debug(5, "#42DsC = %s", mtk_network_http_strstr( "aBcDeFGd#42DsCfVg", "#42Sc" ) );
//初始化buf内容模块
g_send_buffer = (char*)mtk_network_malloc( BUF_SIZE );
if( g_send_buffer == NULL )
{
return -1;
}
g_recv_buffer = (char*)mtk_network_malloc( BUF_SIZE );
if( g_recv_buffer == NULL )
{
mtk_network_free(g_send_buffer);
g_send_buffer = NULL;
return -1;
}
g_host_name = (char*)mtk_network_malloc( 64 );
if( g_host_name == NULL )
{
mtk_network_free(g_recv_buffer);
g_recv_buffer = NULL;
mtk_network_free(g_send_buffer);
g_send_buffer = NULL;
return -1;
}
g_param = (char*)mtk_network_malloc( BUF_SIZE );
if( g_param == NULL )
{
mtk_network_free(g_host_name);
g_host_name = NULL;
mtk_network_free(g_recv_buffer);
g_recv_buffer = NULL;
mtk_network_free(g_send_buffer);
g_send_buffer = NULL;
return -1;
}
m_new_param = (char*)mtk_network_malloc( BUF_SIZE );
if( m_new_param == NULL )
{
mtk_network_free(g_param);
g_param = NULL;
mtk_network_free(g_host_name);
g_host_name = NULL;
mtk_network_free(g_recv_buffer);
g_recv_buffer = NULL;
mtk_network_free(g_send_buffer);
g_send_buffer = NULL;
return -1;
}
kal_sprintf( g_host_name, "%s", hostName );
kal_sprintf( g_param, "%s", lParam );
//变量初始化模块
g_range_pos = 0;//默认值 0
recvCallBack = callBack;
buffer_pos = 0;
g_dns_time_out = dnsTimeOut * 1000 / TIMER_OUT_TIME;
g_dns_time_pos = 0;
g_soc_rw_time_out = socRwTimeOut * 1000 / TIMER_OUT_TIME;
g_soc_rw_time_pos = 0;
g_restart_num = timeOutReStartNum;
g_port = port;
g_net_working = 1;
#ifdef WIN32
g_net_mode = E_MTK_NETWORKMODE_NET;
#else
g_net_mode = netWorkMode;
#endif
memset( &http_header, 0, sizeof( MTK_NETWORK_HTTPHEADER ) );
mtk_network_commit_status( E_MTK_NETWORK_START );//去掉IF判断
gui_start_timer( TIMER_OUT_TIME, mtk_network_process );
return 0;
}
S32 mtk_network_http_post(
void
)
{
return 0;
}
void mtk_network_http_pause( void )
{
gui_cancel_timer(mtk_network_process);
}
void mtk_network_http_resume( void )
{
gui_start_timer( TIMER_OUT_TIME, mtk_network_process );
}
void mtk_network_http_shutdown( void )
{
mtk_network_http_end();
}
void mtk_network_http_end( void )
{
if( g_send_buffer == NULL ||
g_recv_buffer == NULL ||
g_host_name == NULL ||
g_param == NULL ||
m_new_param == NULL )
{
return;
}//保险
if( g_net_working == 1 )
{
g_net_working = 0;
//return;
}
gui_cancel_timer(mtk_network_process);
mtk_network_free( g_send_buffer );
g_send_buffer = NULL;
mtk_network_free( g_recv_buffer );
g_recv_buffer = NULL;
mtk_network_free( g_host_name );
g_host_name = NULL;
mtk_network_free( g_param );
g_param = NULL;
mtk_network_free( m_new_param );
m_new_param = NULL;
mtk_network_client_close( socket_id );
}
#endif
Parser需要的工作是调用了http的get和判断状态并且解析获取到的数据。
mtk_network_parse.h
#ifndef _MTK_NETWORK_PARSE_H_
#define _MTK_NETWORK_PARSE_H_
#include "PixtelDataTypes.h"
#include "MMIDataType.h"
#include "mtk_network_def.h"
extern void (*gui_start_timer)(S32 count, void(*callback)(void));
extern void (*gui_cancel_timer)( void(*callback)(void));
#define MTK_IDLE_WEATHER_BUFSIZE 24
typedef struct _MTK_IDLE_WEATHER_INFO_
{
U8 status1 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 status2 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 figure1 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 figure2 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 direction1 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 direction2 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 power1 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 power2 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 temperature1[ MTK_IDLE_WEATHER_BUFSIZE ];
U8 temperature2[ MTK_IDLE_WEATHER_BUFSIZE ];
U8 tgd1 [ MTK_IDLE_WEATHER_BUFSIZE ];
U8 tgd2 [ MTK_IDLE_WEATHER_BUFSIZE ];
} MTK_IDLE_WEATHER_INFO;
extern MTK_IDLE_WEATHER_INFO weather_info;
extern S32 mtk_network_http_weather_parse(
const char* hostName,
U16 port,
const char* lParam,
E_MTK_NETWORK_MODE netWorkMode,
U32 dnsTimeOut, //s
U32 socRwTimeOut, //s
U32 timeOutReStartNum //
);
//马上停止
extern void mtk_network_http_parse_shutdown( void );
extern BOOL mtk_is_parse_stop( void );
extern BOOL mtk_is_parse_ok( void );
#endif
mtk_network_parse.c
#include "mmi_frm_gprot.h"
#include "MMIDataType.h"
#include "conversions.h"
#include "assert.h"
#include "string.h"
#include "kal_debug.h"
#include "kal_trace.h"
#include "mtk_network_socket.h"
#include "mtk_network_debug.h"
#include "mtk_network_def.h"
#include "mtk_network_parse.h"
#include "mtk_network_http.h"
MTK_IDLE_WEATHER_INFO weather_info;
static S32 mtk_parse_step = 0;
U32 isParseOk;//可以以此判断下载状态
#define TAG_LEN 128
//白天的气象
#define STATUS_ONE "<status1>"
//夜间的气象
#define STATUS_TWO "<status2>"
//白天的气象
#define FIGURE_ONE "<figure1>"
//夜间的气象
#define FIGURE_TWO "<figure2>"
//白天的风向
#define DIRECTION_ONE "<direction1>"
//夜间的风向
#define DIRECTION_TWO "<direction2>"
//白天的风速
#define POWER_ONE "<power1>"
//夜间的风速
#define POWER_TWO "<power2>"
//白天的温度
#define TEMPERATURE_ONE "<temperature1>"
//夜间的温度
#define TEMPERATURE_TWO "<temperature2>"
//白天的体感度
#define TGD_ONE "<tgd1>"
//夜间的体感度
#define TGD_TWO "<tgd2>"
BOOL mtk_is_parse_stop( void )
{
if ( E_MTK_NETWORK_STOP == mtk_network_get_status() )
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL mtk_is_parse_ok( void )
{
if ( 1 == isParseOk )
{
return TRUE;
}
else
{
return FALSE;
}
}
//返回tag对后边的地址
char* mtk_network_http_pase_string( char* aim_buf, const char* src_buf, const char* tag_buf,
U32 aim_buf_size, U32 tag_len )
{
kal_int32 i = 0;
U32 aim_len = 0;
char* start_pos = NULL;
char* stop_pos = NULL;
char tmp_tag_buf[TAG_LEN];
memset( tmp_tag_buf, 0 , TAG_LEN );
for( i = tag_len - 1; i > 0 ; i-- )
{
tmp_tag_buf[i + 1] = tag_buf[i];
}
tmp_tag_buf[ 1 ] = '/';
tmp_tag_buf[ 0 ] = '<';
//strstr utf-8可以,不可用于wcs
start_pos = strstr( src_buf, tag_buf );
if( start_pos == NULL )
{
return NULL;
}
start_pos += tag_len;
stop_pos = strstr( start_pos, tmp_tag_buf );
if( stop_pos == NULL )
{
return NULL;
}
aim_len = (U32)(stop_pos - start_pos);
memset( tmp_tag_buf, 0 , TAG_LEN );
memcpy( tmp_tag_buf, start_pos, aim_len );
mmi_chset_utf8_to_ucs2_string(aim_buf, 16, tmp_tag_buf );
return stop_pos + tag_len + 1;
}
void mtk_network_http_parse_callback( void* http_body_buf )
{
char* buf_pos = NULL;
if ( http_body_buf == NULL ||
http_header.http_errno != E_MTK_NETWORK_HTTP_BODY ||
isParseOk == 1 )
{
mtk_parse_step = 0;
return;
}
buf_pos = http_body_buf;
switch( mtk_parse_step )
{
case 0:
buf_pos = mtk_network_http_pase_string( weather_info.status1, buf_pos, STATUS_ONE,
MTK_IDLE_WEATHER_BUFSIZE, strlen(STATUS_ONE) );
mtk_network_debug( 3, "status1 = %s", weather_info.status1 );
if( buf_pos == NULL )
{
mtk_network_debug( 3, "MTK_IDLE_WEATHER_PARSE 0 NOT OK CONTINUE!" );
return;
}
mtk_parse_step++;
case 1:
buf_pos = mtk_network_http_pase_string( weather_info.status2, buf_pos, STATUS_TWO,
MTK_IDLE_WEATHER_BUFSIZE, strlen(STATUS_TWO) );
mtk_network_debug( 3, "status2 = %s", weather_info.status2 );
if( buf_pos == NULL )
{
mtk_network_debug( 3, "MTK_IDLE_WEATHER_PARSE 1 NOT OK CONTINUE!" );
return;
}
mtk_parse_step++;
case 2:
buf_pos = mtk_network_http_pase_string( weather_info.temperature1, buf_pos, TEMPERATURE_ONE,
MTK_IDLE_WEATHER_BUFSIZE, strlen(TEMPERATURE_ONE) );
mtk_network_debug( 3, "temperature1 = %s", (weather_info.temperature1) );
if( buf_pos == NULL )
{
mtk_network_debug( 3, "MTK_IDLE_WEATHER_PARSE 2 NOT OK CONTINUE!" );
return;
}
mtk_parse_step++;
case 3:
buf_pos = mtk_network_http_pase_string( weather_info.temperature2, buf_pos, TEMPERATURE_TWO,
MTK_IDLE_WEATHER_BUFSIZE, strlen(TEMPERATURE_TWO) );
mtk_network_debug( 3, "temperature2 = %s", (weather_info.temperature2) );
if( buf_pos == NULL )
{
mtk_network_debug( 3, "MTK_IDLE_WEATHER_PARSE 3 NOT OK RESTART!" );
mtk_network_commit_status(E_MTK_NETWORK_SOC_FAIL);
mtk_parse_step = 0;
return;
}
default://parse ok
mtk_parse_step = 0;
isParseOk = 1;
break;
}
/* buf_pos = mtk_network_http_pase_string( weather_info.status1, http_body_buf, STATUS_ONE, MTK_IDLE_WEATHER_BUFSIZE, strlen(STATUS_ONE) ); buf_pos = mtk_network_http_pase_string( weather_info.status2, http_body_buf, STATUS_TWO, MTK_IDLE_WEATHER_BUFSIZE, strlen(STATUS_TWO) ); buf_pos = mtk_network_http_pase_string( weather_info.figure1, buf_pos, FIGURE_ONE, MTK_IDLE_WEATHER_BUFSIZE, strlen(FIGURE_ONE) ); buf_pos = mtk_network_http_pase_string( weather_info.figure2, buf_pos, FIGURE_TWO, MTK_IDLE_WEATHER_BUFSIZE, strlen(FIGURE_TWO) ); buf_pos = mtk_network_http_pase_string( weather_info.direction1, buf_pos, DIRECTION_ONE, MTK_IDLE_WEATHER_BUFSIZE, strlen(DIRECTION_ONE) ); buf_pos = mtk_network_http_pase_string( weather_info.direction2, buf_pos, DIRECTION_TWO, MTK_IDLE_WEATHER_BUFSIZE, strlen(DIRECTION_TWO) ); buf_pos = mtk_network_http_pase_string( weather_info.power1, buf_pos, POWER_ONE, MTK_IDLE_WEATHER_BUFSIZE, strlen(POWER_ONE) ); buf_pos = mtk_network_http_pase_string( weather_info.power2, buf_pos, POWER_TWO, MTK_IDLE_WEATHER_BUFSIZE, strlen(POWER_TWO) ); buf_pos = mtk_network_http_pase_string( weather_info.temperature1, buf_pos, TEMPERATURE_ONE, MTK_IDLE_WEATHER_BUFSIZE, strlen(TEMPERATURE_ONE) ); kal_prompt_trace( MOD_NIL, "temperature1 = %d", weather_info.temperature1 ); buf_pos = mtk_network_http_pase_string( weather_info.temperature2, buf_pos, TEMPERATURE_TWO, MTK_IDLE_WEATHER_BUFSIZE, strlen(TEMPERATURE_TWO) ); kal_prompt_trace( MOD_NIL, "temperature2 = %d", weather_info.temperature2 ); buf_pos = mtk_network_http_pase_string( weather_info.tgd1, buf_pos, TGD_ONE, MTK_IDLE_WEATHER_BUFSIZE, strlen(TGD_ONE) ); buf_pos = mtk_network_http_pase_string( weather_info.tgd2, buf_pos, TGD_TWO, MTK_IDLE_WEATHER_BUFSIZE, strlen(TGD_TWO) ); */
mtk_network_debug( 3, "MTK_IDLE_WEATHER_PARSE OK TO SHUTDOWN!" );
mtk_network_http_parse_shutdown();
}
S32 mtk_network_http_weather_parse(
const char* hostName,
U16 port,
const char* lParam,
E_MTK_NETWORK_MODE netWorkMode,
U32 dnsTimeOut,
U32 socRwTimeOut,
U32 timeOutReStartNum //
)
{
S32 http_status;
E_MTK_NETWORK_STEP status;
//防止重复调用模块
status = mtk_network_get_status( );
if ( status > E_MTK_NETWORK_START &&
status < E_MTK_NETWORK_STOP )
{
return 1;
}
isParseOk = 0;
mtk_parse_step = 0;
memset( &weather_info, 0, sizeof(MTK_IDLE_WEATHER_INFO) );
http_status = mtk_network_http_get(
hostName,
port,
lParam,
mtk_network_http_parse_callback,
netWorkMode,
dnsTimeOut,
socRwTimeOut,
timeOutReStartNum
);
if ( http_status > 0 )
{
mtk_network_debug( 3, "PARSE NETWORK IS WORKING AND RETURN!" );
return 1;
}
if ( http_status < 0 )
{
mtk_network_debug( 3, "PARSE NETWORK OPEN FAILED SHUTDOWN AND RETURN!" );
return -1;
}
mtk_network_debug( 3, "PARSE NETWORK OPEN SUCCESS!" );
return 0;
}
void mtk_network_http_parse_shutdown( void )
{
mtk_network_http_shutdown();
}
Downloader的工作过程和Parser的工作过程是相同的,仅仅功能不同,Downloader实现从服务器下载文件和断点续传。UI层可以通过调用isdownstop判断连接是否还在,通过调用isdownok判断文件是否下载完整。
mtk_network_download.h
#ifndef _MTK_NETWORK_DOWNLOAD_H_
#define _MTK_NETWORK_DOWNLOAD_H_
#include "MMIDataType.h"
#include "mtk_network_def.h"
extern void (*gui_start_timer)(S32 count, void(*callback)(void));
extern void (*gui_cancel_timer)( void(*callback)(void));
typedef enum MTK_NETWORK_DOWN_MODE_
{
MTK_NETWORK_DOWN_AUTO,//默认新创建
MTK_NETWORK_DOWN_CREATE,
MTK_NETWORK_DOWN_RESUME,
MTK_NETWORK_DOWN_OTHER
}MTK_NETWORK_DOWN_MODE;
extern U32 nPersent;//可以以此判断下载状态
extern S32 mtk_network_http_down(
const char* hostName,
U16 port,
const char* lParam,
const wchar_t* saveFile,
MTK_NETWORK_DOWN_MODE netDownMode,
E_MTK_NETWORK_MODE netWorkMode,
U32 dnsTimeOut, //s
U32 socRwTimeOut, //s
U32 timeOutReStartNum //
);
//马上停止
extern void mtk_network_http_down_shutdown( void );
extern BOOL mtk_is_download_stop( void );
extern BOOL mtk_is_download_ok( void );
#endif
mtk_network_download.c
#ifdef __MTK_NETWORK_SUPPORT__
#include "mtk_network_download.h"
#include "mtk_network_socket.h"
#include "mtk_network_debug.h"
#include "mtk_network_http.h"
#include "mtk_network_def.h"
#include "FileManagerGProt.h"
#include "FileMgrSrvGProt.h"
#include "conversions.h"
#include "Fs_errcode.h"
#include "Fs_func.h"
#include "Fs_type.h"
#include "assert.h"
#include "string.h"
#include "kal_debug.h"
#include "kal_trace.h"
#include "kal_release.h"
#include "MMIDataType.h"
#include "mmi_frm_gprot.h"
#define MTK_DOWNLOAD_FILENAME_LEN 256
#define MTK_DOWNLOAD_FILE_INFO_NAME L".info"
extern U32 g_range_pos;
U32 nPersent;
static BOOL g_tcard_detect;
static wchar_t *g_save_file;
static wchar_t *g_info_file;
static MTK_NETWORK_DOWN_MODE http_down_mode;
static U32 nBufPos;
static FS_HANDLE fp;
static U32 content_length;
BOOL mtk_is_download_stop( void )
{
if ( E_MTK_NETWORK_STOP == mtk_network_get_status() )
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL mtk_is_download_ok( void )
{
if ( 100 == nPersent )
{
return TRUE;
}
else
{
return FALSE;
}
}
void mtk_network_http_down_load_yes_callback( void* http_body_buf )
{
U32 writen;
U32 readn;
if( g_save_file == NULL || g_info_file == NULL )
{
mtk_network_debug(3, "DOWNLOAD USELESS CALLBACK, RETURN!");
return;
}
if( http_body_buf == NULL &&
http_header.http_errno == E_MTK_NETWORK_HTTP_NETRESTART )
{
switch ( http_down_mode )
{
case MTK_NETWORK_DOWN_AUTO:
case MTK_NETWORK_DOWN_CREATE:
{
nBufPos = 0;
fp = FS_Open((WCHAR *)g_save_file, FS_CREATE_ALWAYS);
if ( fp < 0 )
{
mtk_network_debug( 3, "DOWNLOAD CALLBACK FILE CREATE FAILED BUT OK TO CONTINUE!" );
break;
}
FS_Close( fp );
}
break;
case MTK_NETWORK_DOWN_RESUME:
case MTK_NETWORK_DOWN_OTHER:
default:
break;
}
}
if ( http_body_buf == NULL ||
http_header.http_errno != E_MTK_NETWORK_HTTP_BODY )
{
return;
}
readn = http_header.readn;
//检测一次T卡容量
if( g_tcard_detect == FALSE )
{
g_tcard_detect = TRUE;
}
switch ( http_down_mode )
{
case MTK_NETWORK_DOWN_RESUME:
case MTK_NETWORK_DOWN_OTHER:
case MTK_NETWORK_DOWN_AUTO:
case MTK_NETWORK_DOWN_CREATE:
default:
fp = FS_Open((WCHAR *)g_save_file,FS_READ_WRITE);
if ( fp < 0 )
{
mtk_network_debug(3, "DOWNLOAD CALLBACK WRITE SAVE FILE FAILED AND SHUTDOWN!");
mtk_network_http_down_shutdown();
return;
}
FS_Seek( fp, 0, FS_FILE_END );
FS_Write( fp, http_body_buf, readn, &writen );
FS_Close( fp );
break;
}
nBufPos += readn;
switch ( http_down_mode )
{
case MTK_NETWORK_DOWN_RESUME:
case MTK_NETWORK_DOWN_OTHER:
if( content_length <= 0 )
{
content_length = http_header.Content_Length;
}
//content_length = content_length > http_header.Content_Length ? content_length : http_header.Content_Length;
g_range_pos = nBufPos;//保存成功后更新下这个g_range_pos,以免断网问题影响
fp = FS_Open((WCHAR *)g_info_file, FS_READ_WRITE);
if ( fp < 0 )
{
mtk_network_debug(3, "DOWNLOAD CALLBACK WRITE INFO FILE FAILED AND SHUTDOWN!");
mtk_network_http_down_shutdown();
return;
}
FS_Write( fp, &nBufPos, sizeof(U32), &writen );
FS_Write( fp, &content_length, sizeof(U32), &writen );
FS_Close( fp );
break;
case MTK_NETWORK_DOWN_AUTO:
case MTK_NETWORK_DOWN_CREATE:
content_length = http_header.Content_Length;
default:
break;
}
nPersent = ( nBufPos * 100 / content_length );
if ( nPersent == 100 )
{
mtk_network_debug( 3, "MTK_NETWORK_DOWNLOAD OK TO SHUTDOWN!" );
FS_Delete(g_info_file);
mtk_network_http_down_shutdown();
}
}
S32 mtk_network_http_down (
const char* hostName,
U16 port,
const char* lParam,
const wchar_t* saveFile,
MTK_NETWORK_DOWN_MODE netDownMode,
E_MTK_NETWORK_MODE netWorkMode,
U32 dnsTimeOut,
U32 socRwTimeOut,
U32 timeOutReStartNum //
)
{
S32 http_status;
E_MTK_NETWORK_STEP status;
//防止重复调用模块
status = mtk_network_get_status( );
if ( status > E_MTK_NETWORK_START &&
status < E_MTK_NETWORK_STOP )
{
return 1;
}
g_save_file = (wchar_t*)mtk_network_malloc( MTK_DOWNLOAD_FILENAME_LEN );
if( g_save_file == NULL )
{
return -1;
}
g_info_file = (wchar_t*)mtk_network_malloc( MTK_DOWNLOAD_FILENAME_LEN );
if( g_info_file == NULL )
{
mtk_network_free(g_save_file);
g_save_file = NULL;
return -1;
}
http_down_mode = netDownMode;
g_tcard_detect = FALSE;
content_length = 0;
nPersent = 0;
nBufPos = 0;
mmi_ucs2cpy( (S8*)g_save_file, (const S8*)saveFile );
mmi_ucs2cpy( (S8*)g_info_file, (const S8*)saveFile );
mmi_ucs2cat( (S8*)g_info_file, (const S8*)MTK_DOWNLOAD_FILE_INFO_NAME );
switch ( netDownMode )
{
case MTK_NETWORK_DOWN_RESUME:
case MTK_NETWORK_DOWN_OTHER:
{
U32 infoFileSize = 0;
U32 infoBufPos = 0;
U32 readn;
//判断文件是否存在
if ( FS_FILE_NOT_FOUND == FS_CheckFile( g_save_file ) ||
FS_FILE_NOT_FOUND == FS_CheckFile( g_info_file ) )
{
//创建需要下载的文件
fp = FS_Open((WCHAR *)g_save_file,FS_CREATE_ALWAYS);
if ( fp < 0 )
{
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
return -1;
}
FS_Close( fp );
//创建记录文件
fp = FS_Open((WCHAR *)g_info_file,FS_CREATE_ALWAYS);
if ( fp < 0 )
{
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
return -1;
}
FS_Close( fp );
break;
}
//读取文件大小
fp = FS_Open((WCHAR *)g_save_file, FS_READ_ONLY );
if ( fp < 0 )
{
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
return -1;
}
if ( FS_NO_ERROR != FS_GetFileSize( fp, &nBufPos ) )
{
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
return -1;
}
FS_Close( fp );
//比较文件大小
fp = FS_Open((WCHAR *)g_info_file, FS_READ_ONLY );
if ( fp < 0 )
{
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
return -1;
}
if( FS_NO_ERROR != FS_Read( fp, &infoBufPos, sizeof(U32), &readn ) )
{
mtk_network_debug( 3, "LAST DOWNLOAD BUFPOS ERROR! SO REFRESH!");
FS_Close( fp );
nBufPos = 0;
break;
}
if( FS_NO_ERROR != FS_Read( fp, &infoFileSize, sizeof(U32), &readn ) )
{
mtk_network_debug( 3, "LAST DOWNLOAD FILESIZE ERROR! SO REFRESH!");
FS_Close( fp );
nBufPos = 0;
break;
}
FS_Close( fp );
if( nBufPos != infoBufPos )
{
mtk_network_debug( 3, "LAST DOWNLOAD ERROR! SO REFREASH!");
nBufPos = 0;
break;
}
else if ( nBufPos == 0 || infoBufPos == 0 )
{
mtk_network_debug( 3, "LAST DOWNLOAD EMPTY! SO REFREASH!");
nBufPos = 0;
break;
}
nPersent = ( nBufPos * 100 / infoFileSize );
content_length = infoFileSize;
mtk_network_debug( 3, "DOWNLOAD DUAN DIAN XUCHUAN OPEN SUCCESS!" );
}
break;
case MTK_NETWORK_DOWN_AUTO:
case MTK_NETWORK_DOWN_CREATE:
default:
nPersent = 0;
nBufPos = 0;
fp = FS_Open((WCHAR *)g_save_file,FS_CREATE_ALWAYS);
if ( fp < 0 )
{
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
return -1;
}
FS_Close( fp );
mtk_network_debug( 3, "DOWNLOAD NEW CREATE OPEN SUCCESS!" );
break;
}
http_status = mtk_network_http_get(
hostName,
port,
lParam,
mtk_network_http_down_load_yes_callback,
netWorkMode,
dnsTimeOut,
socRwTimeOut,
timeOutReStartNum
);
if ( http_status > 0 )
{
mtk_network_debug( 3, "DOWNLOAD NETWORK IS WORKING AND RETURN!" );
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
return 1;
}
if ( http_status < 0 )
{
mtk_network_debug( 3, "DOWNLOAD NETWORK OPEN FAILED AND RETURN!" );
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
return -1;
}
switch ( netDownMode )
{
case MTK_NETWORK_DOWN_RESUME:
case MTK_NETWORK_DOWN_OTHER:
g_range_pos = nBufPos;
// 传入已经下载的字节数
// 服务器将从此长度之后的位置开始发回数据
break;
case MTK_NETWORK_DOWN_AUTO:
case MTK_NETWORK_DOWN_CREATE:
default:
break;
}
mtk_network_debug(3, "DOWNLOAD NETWORK OPEN SUCCESS!" );
return 0;
}
void mtk_network_http_down_shutdown( void )
{
if( g_save_file == NULL ||
g_info_file == NULL )
{
return;
}
//断点续传 步骤判断
mtk_network_free(g_save_file);
g_save_file = NULL;
mtk_network_free(g_info_file);
g_info_file = NULL;
mtk_network_http_shutdown();
}
#endif
mtk_network_debug.h
#ifndef _MTK_NETWORK_DEBUG_H_
#define _MTK_NETWORK_DEBUG_H_
#include "kal_release.h"
extern kal_int32 mtk_network_debug( kal_int32 im_level, const kal_char *fmt, ... );
extern kal_int32 mtk_network_proc_info( kal_int32 soc_id, kal_int32 step );
#endif
mtk_network_debug.c
#if defined (__MTK_NETWORK_SUPPORT__)
#include "mtk_network_config.h"
#include "mtk_network_debug.h"
#include "FileManagerGProt.h"
#include "FileMgrSrvGProt.h"
#include "conversions.h"
#include "Fs_errcode.h"
#include "Fs_func.h"
#include "Fs_type.h"
#include "kal_trace.h"
#include "kal_debug.h"
#include "stdarg.h"
#include "string.h"
#include "MMIDataType.h"
#include "mmi_frm_gprot.h"
#define MAX_SIZE 1024 + 256
static kal_char g_mtk_network_debug_buf[MAX_SIZE];
static WCHAR* mtk_network_debug_get_log(WCHAR *dir_name, WCHAR *file_name)
{
static WCHAR tflash_path[256];
CHAR fs_drv[2];
fs_drv[0] = (CHAR)FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE);
fs_drv[1] = 0;
mmi_asc_to_wcs(tflash_path, fs_drv);
mmi_wcscat(tflash_path, L":\\");
if(dir_name)
{
mmi_wcscat(tflash_path, dir_name);
mmi_wcscat(tflash_path, L"\\");
}
if(file_name)
{
mmi_wcscat(tflash_path, file_name);
}
return tflash_path;
}
static S8 mtk_network_debug_get_tcard(void)
{
if (FS_NO_ERROR == FS_GetDevStatus((kal_uint32)FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE), FS_MOUNT_STATE_ENUM))
{
S8 drive = (S8)FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE);
if ((drive >= 'A') && (drive <= 'Z'))
{
return drive;
}
}
return 0;
}
static S32 mtk_network_debug_tcard_detect(U64 size_required) // 无T卡返回-1, 容量不足返回-2, 正常返回1
{
U8 drv_letter = (U8)FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE);
drv_letter = mtk_network_debug_get_tcard();
if( drv_letter == 0 )
{
return -1;
}
if(MMI_FALSE == srv_fmgr_drv_is_valid(drv_letter))
{
return -1;
}
if(srv_fmgr_drv_check_free_size(drv_letter, size_required) < 0)
{
return -2;
}
return 1;
}
static WCHAR* mtk_network_debug_set_file(WCHAR *dir_name, WCHAR *file_name)
{
WCHAR* log_file;
if( mtk_network_debug_tcard_detect(MAX_SIZE) < 0 )
{
return NULL;
}
log_file = mtk_network_debug_get_log( dir_name, file_name );
FS_Close( FS_Open( log_file, FS_CREATE_ALWAYS ) );
return log_file;
}
kal_int32 mtk_network_debug_save( void )
{
static kal_int32 init_file = 0;
static WCHAR* log_name;
FS_HANDLE fp;
U32 writen;
U32 readn;
if( 0 == init_file )
{
log_name = mtk_network_debug_set_file( L"IdleWeather", L"MtkNetWorkLog.txt" );
if ( log_name == NULL )
{
mtk_network_debug( 5, "MTKNETWORK TCARD ERROR!" );
return -1;
}
init_file = 1;
}
fp = FS_Open( log_name, FS_READ_WRITE );
if ( fp < 0 )
{
mtk_network_debug( 5, "MTKNETWORK LOGFILE ERROR!" );
return -1;
}
readn = strlen(g_mtk_network_debug_buf);
FS_Seek( fp, 0, FS_FILE_END );
FS_Write( fp, g_mtk_network_debug_buf, readn, &writen );
FS_Close( fp );
return 0;
}
//im_level 0 PROC 1 SOCKET 2 GPRS 3 HTTP,发送,下载,解析 4 RECV 5 OTHER 6 关闭
//7 debug net speed
//8
kal_int32 mtk_network_debug( kal_int32 im_level, const kal_char *fmt, ... )
{
va_list args;
kal_bool m_print = KAL_FALSE;
switch ( g_mtk_network_debug_level )
{
case MTK_NETWORK_DEBUG_LEVEL_ZER:
if ( im_level <= 0 ){ m_print = KAL_TRUE; }
break;
case MTK_NETWORK_DEBUG_LEVEL_ONE:
if ( im_level <= 1 ){ m_print = KAL_TRUE; }
break;
case MTK_NETWORK_DEBUG_LEVEL_TWO:
if ( im_level <= 2 ){ m_print = KAL_TRUE; }
break;
case MTK_NETWORK_DEBUG_LEVEL_THR:
if ( im_level <= 3 ){ m_print = KAL_TRUE; }
break;
case MTK_NETWORK_DEBUG_LEVEL_FOR:
if ( im_level <= 4 ){ m_print = KAL_TRUE; }
break;
case MTK_NETWORK_DEBUG_LEVEL_FIV:
if ( im_level <= 5 ){ m_print = KAL_TRUE; }
break;
case MTK_NETWORK_DEBUG_LEVEL_SIX:
if ( im_level == 6 ){ m_print = KAL_TRUE; }
break;
case MTK_NETWORK_DEBUG_LEVEL_SEV:
default:
break;
}
if ( KAL_FALSE == m_print )
{
return 0;
}
memset( g_mtk_network_debug_buf, 0, MAX_SIZE );
va_start( args, fmt );
vsprintf( g_mtk_network_debug_buf, fmt, args );
va_end( args );
#if defined (WIN32) //ERROR
strcat( g_mtk_network_debug_buf, "\r\n" );
printf( g_mtk_network_debug_buf );
#else
kal_prompt_trace( MOD_NIL, g_mtk_network_debug_buf );
#endif
if( mtk_network_is_debug_save )
{
mtk_network_debug_save();
}
return 1;
}
kal_int32 mtk_network_proc_info( kal_int32 soc_id, kal_int32 step )
{
char* str = NULL;
if ( 0 == g_mtk_network_proc_info )
{
mtk_network_debug( 0, "MTK_NETWORK, SOCKETID %d, MACRO %d", soc_id, step );
return 1;
}
switch( step )
{
case E_MTK_NETWORK_START: //0 网络启动
str = "MTK_NETWORK_START";
break;
case E_MTK_NETWORK_GPRS_REG: //1 获取网络信息
str = "MTK_NETWORK_GPRS_REG";
break;
case E_MTK_NETWORK_GPRS_WAIT: //2 等待网络信息
str = "MTK_NETWORK_GPRS_WAIT";
break;
case E_MTK_NETWORK_GPRS_SUCCESS: //3 注册网络资源
str = "MTK_NETWORK_GPRS_SUCCESS";
break;
case E_MTK_NETWORK_DNS_GET: //4 获取服务器IP解析
str = "MTK_NETWORK_DNS_REG";
break;
case E_MTK_NETWORK_DNS_WAIT: //5 等待服务器IP解析
str = "MTK_NETWORK_DNS_WAIT";
break;
case E_MTK_NETWORK_DNS_SUCCESS: //6 服务器IP解析成功
str = "MTK_NETWORK_DNS_SUCCESS";
break;
case E_MTK_NETWORK_SOC_CREATE: //7 初始化连接
str = "MTK_NETWORK_SOCKET_CREATE";
break;
case E_MTK_NETWORK_SOC_CONNECT: //8 请求服务器连接
str = "MTK_NETWORK_SOCKET_CONNECT";
break;
case E_MTK_NETWORK_SOC_BIDE: //9 等待服务器连接
str = "MTK_NETWORK_SOCKET_BIDE";
break;
case E_MTK_NETWORK_SOC_INIT: //10 服务器连接成功,此时可发送初始化数据(手动)//意外
str = "MTK_NETWORK_SOCKET_INIT";
break;
case E_MTK_NETWORK_SOC_SEND: //11 发送数据至服务器
str = "MTK_NETWORK_SOCKET_SEND";
break;
case E_MTK_NETWORK_SOC_RECV: //12 接收服务器数据
str = "MTK_NETWORK_SOCKET_RECV";
break;
case E_MTK_NETWORK_SOC_WAIT: //13 等待服务器空闲
str = "MTK_NETWORK_SOCKET_WAIT";
break;
case E_MTK_NETWORK_SOC_BLOCK: //14 服务被占用,请等待 // 空宏 = 13
str = "MTK_NETWORK_SOCKET_BLOCK";
break;
case E_MTK_NETWORK_GPRS_FAIL: //15 注册网络资源失败
str = "MTK_NETWORK_GPRS_FAIL";
break;
case E_MTK_NETWORK_DNS_FAIL: //16 服务器IP解析失败
str = "MTK_NETWORK_DNS_FAIL";
break;
case E_MTK_NETWORK_SOC_FAIL: //17 SOCKET失败
str = "MTK_NETWORK_SOCKET_FAIL";
break;
case E_MTK_NETWORK_CONN_FAIL: //18 服务器连接失败
str = "MTK_NETWORK_CONNECT_FAIL";
break;
case E_MTK_NETWORK_UPDATE_FAIL: //19 收发消息失败
str = "MTK_NETWORK_UPDATE_MSG_FAIL";
break;
case E_MTK_NETWORK_STOP: //20 网络停止
str = "MTK_NETWORK_STOP";
break;
default:
str = "MTK_NETWORK_MACRO_ERROR";
break;
}
mtk_network_debug( 0, "MTK_NETWORK, SOCKETID %d, MACRO %d, NAME %s",
soc_id, step, str );
return 1;
}
#endif
mtk_network_def.h
#ifndef _MTK_NETWORK_DEF_H_
#define _MTK_NETWORK_DEF_H_
//联网模式
typedef enum
{
E_MTK_NETWORKMODE_AUTO, //自动模式 WAP
E_MTK_NETWORKMODE_WAP, //cmwap模式
E_MTK_NETWORKMODE_NET, //cmnet模式
E_MTK_NETWORKMODE_NONE //自动模式
} E_MTK_NETWORK_MODE;
#endif
mtk_network_config.h
#ifndef _MTK_NETWORK_CONFIG_H_
#define _MTK_NETWORK_CONFIG_H_
#include "DataAccountGProt.h"
/**************************PROCESS******************************/
//已知 UNICOM_UNICOM_PROCESS 5210A
//已知 UNICOM_CMCC_PROCESS 5211B 5211C
//未知 其他 3611A 3611B
//配置方式:插移动联通双卡,开启联通单卡模式。请修改config.c
/**************************PROCESS******************************/
typedef enum
{
UNICOM_UNICOM_PROCESS,
UNICOM_CMCC_PROCESS,
}E_MTK_NETWORK_PROCESS;
/**************************V_M******************************/
//已知 DTCNT_APPTYPE_VRE_NAME 5210A
//已知 DTCNT_APPTYPE_MRE_NAME 5211B 5211C 3611A 3611B
//未知 其他
//配置方式:搜索DTCNT_APPTYPE_MRE_WAP。请修改config.c
/**************************V_M******************************/
typedef enum
{
DTCNT_APPTYPE_MRE_NAME,
DTCNT_APPTYPE_VRE_NAME,
}E_MTK_NETWORK_VM_NAME;
/**************************调试等级******************************/
//7个级别
/**************************调试等级******************************/
typedef enum
{
MTK_NETWORK_DEBUG_LEVEL_ZER, //0 联网流程
MTK_NETWORK_DEBUG_LEVEL_ONE, //1 +SOCKET信息
MTK_NETWORK_DEBUG_LEVEL_TWO, //2 +GPRS信息
MTK_NETWORK_DEBUG_LEVEL_THR, //3 +HTTP,发送,下载,解析
MTK_NETWORK_DEBUG_LEVEL_FOR, //4 +接收
MTK_NETWORK_DEBUG_LEVEL_FIV, //5 +其他
MTK_NETWORK_DEBUG_LEVEL_SIX, //6 仅网速探测
MTK_NETWORK_DEBUG_LEVEL_SEV //7 关闭
}E_MTK_NETWORK_DEBUG_LEVEL;
/**************************流程******************************/
//是否开启联网流程信息
/**************************流程******************************/
typedef enum
{
MTK_NETWORK_PROC_INFO_CLOSE,//0 关闭
MTK_NETWORK_PROC_INFO_OPEN, //1 开启
}E_MTK_NETWORK_PROC_INFO;
/**************************变量声明******************************/
//请FAE修改
/**************************变量声明******************************/
extern E_MTK_NETWORK_PROC_INFO g_mtk_network_proc_info;
extern E_MTK_NETWORK_PROCESS g_mtk_network_process;
extern E_MTK_NETWORK_VM_NAME g_mtk_network_vm_mode;
extern E_MTK_NETWORK_DEBUG_LEVEL g_mtk_network_debug_level;
extern kal_bool mtk_network_is_profile_create_open;
extern kal_bool mtk_network_is_mmi_feature_open;
extern kal_bool mtk_network_is_tcpip_open;
extern kal_bool mtk_network_is_debug_save;
#endif
mtk_network_config.c
#if defined (__MTK_NETWORK_SUPPORT__)
#include "mtk_network_socket.h"
#include "mtk_network_config.h"
#include "mtk_network_def.h"
E_MTK_NETWORK_DEBUG_LEVEL g_mtk_network_debug_level = MTK_NETWORK_DEBUG_LEVEL_SEV;
E_MTK_NETWORK_PROC_INFO g_mtk_network_proc_info = MTK_NETWORK_PROC_INFO_CLOSE;
E_MTK_NETWORK_VM_NAME g_mtk_network_vm_mode = DTCNT_APPTYPE_MRE_NAME;
E_MTK_NETWORK_PROCESS g_mtk_network_process = UNICOM_CMCC_PROCESS;
//请关闭创建profile
kal_bool mtk_network_is_profile_create_open = KAL_FALSE;
//仅调试时开启保存文件
kal_bool mtk_network_is_debug_save = KAL_FALSE;
#if defined (__MMI_GPRS_FEATURES__)
kal_bool mtk_network_is_mmi_feature_open = KAL_TRUE;
#else
kal_bool mtk_network_is_mmi_feature_open = KAL_FALSE;
#endif
#if defined (__TCPIP__)
kal_bool mtk_network_is_tcpip_open = KAL_TRUE;
#else
kal_bool mtk_network_is_tcpip_open = KAL_FALSE;
#endif
#endif
MtkTimer包含GUITimer、StackTimer、MMITimer、kal_timer、event_timer等,其中kal_timer精度最高,甚至能够中断系统调用,stacktimer和event_timer需要注册event,但是可以忽略屏幕关闭,guitiger是最常用的timer,在屏幕关闭后不运行。他们适用于不同的场合,具有不同的用途。
mtk_timer.h
#ifndef _MTK_TIMER_H_
#define _MTK_TIMER_H_
//返回TimerId
extern U32 MtkStartTimer( U32 delay, FuncPtr funcPtr );
extern U32 MtkStartNoAlignTimer( U32 delay, FuncPtr funcPtr );
extern U32 MtkStartArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg );
extern U32 MtkStartNoAlignArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg );
extern void MtkStopTimer( U32 timerId );
extern void MtkEvshedTimerHandler( void *dataPtr );
extern MMI_BOOL MtkIsTimerExist( U32 timerId );
extern U32 MtkStartDrTimer( U32 delay, FuncPtr funcPtr );
extern U32 MtkStartDrArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg );
extern void MtkStopDrTimer( U32 timerId );
//均为具有延迟误差的 均为一次调用的
extern U32 MMIStartTimer( U32 delay, FuncPtr funcPtr );
extern U32 MMIStartArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg );
extern void MMIStopTimer( U32 timerid );
extern MMI_BOOL MMIIsMyTimerExist( U32 timerid );
#endif
mtk_timer.c
#if defined (__MTK_NETWORK_SUPPORT__)
#include "stack_timer.h"
#include "event_shed.h"
#include "FileManagerGProt.h"
#include "FileMgrSrvGProt.h"
#include "Fs_errcode.h"
#include "Fs_func.h"
#include "Fs_type.h"
#include "med_utility.h"
#include "kal_release.h"
#include "kal_trace.h"
#include "kal_debug.h"
#include "stdarg.h"
#include "string.h"
#include "assert.h"
#include "conversions.h"
#include "MMITimer.h"
#include "MMIDataType.h"
#define TICKS_20_MSEC (KAL_TICKS_1_SEC/50.0)
#define TICKS_5_MSEC (KAL_TICKS_1_SEC/200.0)
#define EVENTID(id) (id >> 20)
#define DRTIMERACCUR (36)
//GuiTimer直接使用此回调函数作为Timer标志,StopArgTimer需要将函数名用(PsFuncPtr/oslTimerFuncPtr)强转为void(void)类型。
typedef struct {
eventid id;
U16 type;
PsFuncPtr cb;
void* arg;
} s_event;
typedef enum
{
EVENTNOALIGN,
EVENTALIGN,
EVENTMAX
} E_EVENT;
typedef struct list
{
s_event event[MTK_NETWORK_TIMER_NUM]; /* timer items */
struct list *next; /* point to the next TIMERTABLE data */
} s_list;
typedef struct table
{
s_list list;
U32 size;
U32 used;
} s_table;
static s_table table;
static event_scheduler *e_sch[EVENTMAX];
//delayMode
void MtkEventInitEx( U8 delayMode[EVENTMAX], U8 delaySleepMode[EVENTMAX] )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
s_list *p_list;
s_list *pp_list;
U32 i;
static CHAR *name[EVENTMAX] = {"EvnetNoAlign", "EvnetAlign"};
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
p_list = table.list.next;
pp_list = NULL;
while ( p_list != NULL )
{
pp_list = p_list->next;
met_net_free(p_list);
p_list = pp_list;
}
/* reset g_timer_talbe */
memset( &table, 0, sizeof(s_table) );
table.size = MTK_NETWORK_TIMER_NUM;
table.used = 0;
/* Initiate the clock time callback function. */
for (i = 0; i < EVENTMAX; i++)
{
e_sch[i] = evshed_create( name[i], MOD_MMI, delayMode[i], delaySleepMode[i]);
evshed_set_index( e_sch[i], ( g_met_net_timer_default_index + i ) );
}
}
void MtkEventInit( )
{
static U8 inited = 0;
/*困惑点*/
/*这两个决定了延迟误差类型,前者无视睡眠模式,后者仅仅睡眠模式*/
static U8 delay[EVENTMAX] = {0, 0};
static U8 delaySleep[EVENTMAX] = {0, 254};
/*鉴于设计方式,初始化必须为1次*/
if ( 1 == inited )
{
return;
}
MtkEventInitEx( delay, delaySleep );
inited = 1;
}
void MtkEventActive( void )
{
s_table *pTable = &table;
s_list *pList = &table.list;
if( pTable->used < pTable->size )
{
return;
}
do
{
if (pList->next == NULL)
{
pList->next = met_net_malloc(sizeof(s_list));
memset(pList->next, 0, sizeof(s_list));
pTable->size += MTK_NETWORK_TIMER_NUM;
pList = pList->next;
break;
}
pList = pList->next;
} while ( pList != NULL );
}
void MtkEventRelease( void )
{
s_table *pTable = &table;
s_list *p_list = table.list.next;
s_list *pp_list;
if ( pTable->used > 0 )
{
return;
}
if ( pTable->size <= MTK_NETWORK_TIMER_NUM )
{
return;
}
while ( p_list != NULL )
{
pp_list = p_list->next;
met_net_free(p_list);
p_list = pp_list;
}
}
static void MtkEventCallBack( void *param )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
extern MMI_BOOL IsInNVRAMProcedure(void);
extern S32 mmi_frm_invoke_post_event(void);
extern void mmi_frm_fetch_msg_from_extQ_to_circularQ(void);
s_event *pEvent = (s_event *)param;
PsFuncPtr pFuncExpiry = pEvent->cb;
void *arg = pEvent->arg;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
met_net_log( 7, "Event %d CallBack.", EVENTID((U32)pEvent->id) );
memset( pEvent, 0, sizeof(s_event) ); /* clear */
table.used--;
if (pFuncExpiry)
{
pFuncExpiry(arg);
}
MtkEventRelease();
/* 困惑点 Invoke post event */
if (IsInNVRAMProcedure() == MMI_FALSE)
{
mmi_frm_invoke_post_event();
}
mmi_frm_fetch_msg_from_extQ_to_circularQ();
}
static U32 MtkEventSetEx( U32 Duration, PsFuncPtr FuncExpiry, void *funcArg, U16 align )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U32 i = 0;
s_table *pTable;
s_list *pList;
U32 delay = 0, secs = 0, msecs = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (FuncExpiry == NULL)
{
met_net_log( 7, "Event CallBack Is Null." );
return -1;
}
MtkEventInit();
secs = Duration / 1000;
msecs = Duration % 1000;
if( secs > 0 )
{
delay = kal_secs_to_ticks(secs);
}
if( msecs > 0 )
{
delay += kal_milli_secs_to_ticks(msecs);
}
if ( delay == 0 )
{
/* Cause by by rounding. If expire immediately, MoDIS boot-up failure because MMI keeps running and block NVRAM task */
delay = (U32)TICKS_5_MSEC;
}
i = 0;
pTable = &table;
pList = &table.list;
MtkEventActive();
do
{
if (pList->event[i].id == NULL)
{
break;
}
i++;
if (i >= MTK_NETWORK_TIMER_NUM)
{
pList = pList->next;
i = 0;
}
} while (pList != NULL);
if (pList == NULL)
{
met_net_log( 7, "EventList Error." );
return -1;
}
pList->event[i].id = evshed_set_event( e_sch[align], MtkEventCallBack, (void*)&(pList->event[i]), delay );
pList->event[i].type = align;
pList->event[i].cb = FuncExpiry;
pList->event[i].arg = funcArg;
pTable->used++;
met_net_log( 7, "Event %d Open.", EVENTID((U32)pList->event[i].id) );
return (U32)pList->event[i].id;
}
static void MtkEventCancel( U32 EvnetId )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U32 i = 0;
s_table *pTable = &table;
s_list *pList = &table.list;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
do
{
if ( pList->event[i].id != NULL && pList->event[i].id == (eventid)EvnetId )
{
evshed_cancel_event(e_sch[pList->event[i].type], &(pList->event[i].id));
pTable->used--;
memset( &(pList->event[i]), 0, sizeof(s_event));
break;
}
i++;
if (i >= MTK_NETWORK_TIMER_NUM )
{
pList = pList->next;
i = 0;
}
} while (pList != NULL);
MtkEventRelease();
met_net_log( 7, "Event %d Cancel.", EVENTID(EvnetId) );
}
MMI_BOOL MtkEventIsExist( U32 eventId )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
s_table *pTable = &table;
s_list* pList = &table.list;
U32 i = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
do
{
if (pList->event[i].id == (eventid)eventId)
{
return MMI_TRUE;
}
i++;
if (i >= MTK_NETWORK_TIMER_NUM )
{
pList = pList->next;
i = 0;
}
} while (pList != NULL);
return MMI_FALSE;
}
void MtkEvshedTimerHandler( void *dataPtr )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U32 i;
MMI_BOOL is_applib_timer = MMI_TRUE;
kal_uint16 index;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
MtkEventInit();
index = evshed_get_index((ilm_struct*)dataPtr);
for (i = 0; i < EVENTMAX; i++)
{
if (index == (g_met_net_timer_default_index+i))
{
evshed_timer_handler(e_sch[i]);
is_applib_timer = MMI_FALSE;
}
}
if (is_applib_timer)
{
extern void applib_timer_hdlr(stack_timer_struct *timer_ptr);
applib_timer_hdlr((stack_timer_struct*)(((ilm_struct*)dataPtr)->local_para_ptr));
}
}
U32 MtkStartTimer( U32 delay, FuncPtr funcPtr )
{
return (U32)MtkEventSetEx( delay, (PsFuncPtr)funcPtr, NULL, EVENTALIGN );
}
U32 MtkStartNoAlignTimer( U32 delay, FuncPtr funcPtr )
{
return (U32)MtkEventSetEx( delay, (PsFuncPtr)funcPtr, NULL, EVENTNOALIGN );
}
U32 MtkStartArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg )
{
return (U32)MtkEventSetEx( delay, (PsFuncPtr)funcPtr, arg, EVENTALIGN );
}
U32 MtkStartNoAlignArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg )
{
return (U32)MtkEventSetEx( delay, (PsFuncPtr)funcPtr, arg, EVENTNOALIGN );
}
void MtkStopTimer( U32 timerId )
{
MtkEventCancel( timerId );
}
MMI_BOOL MtkIsTimerExist( U32 timerId )
{
return MtkEventIsExist(timerId);
}
/*第二版Timer*/
typedef struct
{
U32 Id;
PsFuncPtr cb;
void* arg;
S32 delay;
S32 lTime;
} s_timer;
//Timer组
typedef struct task
{
s_timer timer[MTK_NETWORK_TIMER_NUM];
struct task *next;
} s_task;
//调度
typedef struct _sch_
{
s_task list;
U32 size;
U32 used;
} s_ch;
static s_ch scheduler;
void MtkInitDrTimer( void )
{
s_task *p_list;
s_task *pp_list;
static S32 inited = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if ( inited == 1 )
{
return;
}
p_list = scheduler.list.next;
pp_list = NULL;
while ( p_list != NULL )
{
pp_list = p_list->next;
met_net_free(p_list);
p_list = pp_list;
}
/* reset g_timer_talbe */
memset( &scheduler, 0, sizeof(s_ch) );
scheduler.size = MTK_NETWORK_TIMER_NUM;
scheduler.used = 0;
inited = 1;
}
void MtkActiveDrTimer( void )
{
s_ch *pTable = &scheduler;
s_task *pList = &scheduler.list;
if( pTable->used < pTable->size )
{
return;
}
do
{
if (pList->next == NULL)
{
pList->next = met_net_malloc(sizeof(s_task));
memset(pList->next, 0, sizeof(s_task));
pTable->size += MTK_NETWORK_TIMER_NUM;
pList = pList->next;
break;
}
pList = pList->next;
} while ( pList != NULL );
}
void MtkReleaseDrTimer( void )
{
s_ch *pTable = &scheduler;
s_task *p_list = scheduler.list.next;
s_task *pp_list;
if ( pTable->used > 0 )
{
return;
}
if ( pTable->size <= MTK_NETWORK_TIMER_NUM )
{
return;
}
while ( p_list != NULL )
{
pp_list = p_list->next;
met_net_free(p_list);
p_list = pp_list;
}
}
void MtkDrTimerHandler( void )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U32 i;
U32 iTick;
S32 curTime;
s_ch *pTable = &scheduler;
s_task *pList = &scheduler.list;
PsFuncPtr funcPtr;
void* arg;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
kal_get_time( &iTick );
curTime = (S32)kal_ticks_to_milli_secs(iTick);
i = 0;
do
{
if ( pList->timer[i].cb != NULL &&
curTime - pList->timer[i].lTime >= pList->timer[i].delay )
{
met_net_log( 7, "Timer %d CallBack.", pList->timer[i].Id );
funcPtr = pList->timer[i].cb;
arg = pList->timer[i].arg;
memset( &(pList->timer[i]), 0, sizeof(s_timer));
pTable->used--;
funcPtr(arg);//CallBack
}
i++;
if (i >= MTK_NETWORK_TIMER_NUM )
{
pList = pList->next;
i = 0;
}
} while (pList != NULL);
gui_start_timer( DRTIMERACCUR, MtkDrTimerHandler );
if ( pTable->used > 0 )
{
return;
}
MtkReleaseDrTimer();
gui_cancel_timer(MtkDrTimerHandler);
}
//默认 100ms Timer
U32 MtkStartDrTimerEx( U32 delay, PsFuncPtr funcPtr, void* arg )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U32 i;
U32 pos;
U32 iTick;
S32 curTime;
s_ch *pTable;
s_task *pList;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (funcPtr == NULL)
{
met_net_log( 7, "DrTimer CallBack Null." );
return -1;
}
MtkInitDrTimer();
if ( delay <= 0 )
{
delay = 100;
}
i = 0;
pos = 0;
pTable = &scheduler;
pList = &scheduler.list;
MtkActiveDrTimer();
do
{
if ( pList->timer[i].cb == NULL )//
{
break;
}
i++;pos++;
if (i >= MTK_NETWORK_TIMER_NUM)
{
pList = pList->next;
i = 0;
}
} while (pList != NULL);
if (pList == NULL)
{
met_net_log( 7, "DrTimer Error." );
return -1;
}
kal_get_time( &iTick );
curTime = (S32)kal_ticks_to_milli_secs(iTick);
pList->timer[i].Id = pos;
pList->timer[i].cb = funcPtr;
pList->timer[i].arg = arg;
pList->timer[i].lTime = curTime;
pList->timer[i].delay = delay;
pTable->used++;
met_net_log( 7, "DrTimer %d Open.", pos );
gui_start_timer( DRTIMERACCUR, MtkDrTimerHandler );
return pos;
}
U32 MtkStartDrTimer( U32 delay, FuncPtr funcPtr )
{
return MtkStartDrTimerEx( delay, (PsFuncPtr)funcPtr, NULL );
}
U32 MtkStartDrArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg )
{
return MtkStartDrTimerEx( delay, funcPtr, arg );
}
void MtkStopDrTimer( U32 timerId )
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U32 i = 0;
s_ch *pTable = &scheduler;
s_task *pList = &scheduler.list;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
do
{
if ( pList->timer[i].Id == timerId )
{
pTable->used--;
memset( &(pList->timer[i]), 0, sizeof(s_timer));
break;
}
i++;
if (i >= MTK_NETWORK_TIMER_NUM )
{
pList = pList->next;
i = 0;
}
} while (pList != NULL);
met_net_log( 7, "DrTimer %d Cancel.", timerId );
if ( pTable->used > 0 )
{
return;
}
MtkReleaseDrTimer();
gui_cancel_timer(MtkDrTimerHandler);
}
static U16 g_timer_id;
void MMIInitTimer( void )
{
static kal_int32 inited = 0;
if ( inited == 1 )
{
return;
}
g_timer_id = g_met_net_base_timer;
inited = 1;
}
U32 MMIStartTimer( U32 delay, FuncPtr funcPtr )
{
extern void StartTimer(U16 timerid, U32 delay, FuncPtr funcPtr);
extern MMI_BOOL IsMyTimerExist(U16 nTimerId);
MMIInitTimer();
while(1)
{
if( !IsMyTimerExist(g_timer_id) )
{
break;
}
g_timer_id++;
}
StartTimer( g_timer_id, delay, funcPtr );
met_net_log( 7, "Timer %d Open.", g_timer_id );
return (U32)g_timer_id++;
}
U32 MMIStartNoAlignTimer( U32 delay, FuncPtr funcPtr )
{
extern void StartNonAlignTimer(U16 timerid, U32 delay, FuncPtr funcPtr);
MMIInitTimer();
while(1)
{
if( !IsMyTimerExist(g_timer_id) )
{
break;
}
g_timer_id++;
}
StartNonAlignTimer( g_timer_id, delay, funcPtr );
met_net_log( 7, "NoAlignTimer %d Open.", g_timer_id );
return (U32)g_timer_id++;
}
U32 MMIStartArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg )
{
extern void StartTimerEx(U16 timerid, U32 delay, oslTimerFuncPtr funcPtr, void* arg);
MMIInitTimer();
while(1)
{
if( !IsMyTimerExist(g_timer_id) )
{
break;
}
g_timer_id++;
}
StartTimerEx( g_timer_id, delay, (oslTimerFuncPtr)funcPtr, arg );
met_net_log( 7, "ArgTimer %d Open.", g_timer_id );
return (U32)g_timer_id++;
}
U32 MMIStartNoAlignArgTimer( U32 delay, PsFuncPtr funcPtr, void* arg )
{
extern void StartNonAlignTimerEx(U16 timerid, U32 delay, oslTimerFuncPtr funcPtr, void* arg);
MMIInitTimer();
while(1)
{
if( !IsMyTimerExist(g_timer_id) )
{
break;
}
g_timer_id++;
}
StartNonAlignTimerEx( g_timer_id, delay, (oslTimerFuncPtr)funcPtr, arg );
met_net_log( 7, "NoAlignArgTimer %d Open.", g_timer_id );
return (U32)g_timer_id++;
}
void MMIStopTimer( U32 timerid )
{
extern void StopTimer(U16 timerid);
met_net_log( 7, "Timer %d Close.", timerid );
StopTimer((U16)timerid);
}
MMI_BOOL MMIIsMyTimerExist( U32 timerid )
{
return IsMyTimerExist((U16)timerid);
}
#endif