视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
symbian网络连接网络IAP(InternetAccessPoint)缺省选择及Com
2020-11-09 07:31:29 责编:小采
文档

屏蔽对话框 RConnection gConnection; gConnection.Open(iSocketServ); TCommDbConnPref pref; pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); // 联网时不出现对话框 TUint32 iapId; // 该值应该是确实对应的查询结果 iapId = GetAPNL(_L("cmnet

屏蔽对话框

RConnection gConnection;

gConnection.Open(iSocketServ);

TCommDbConnPref pref;

pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); // 联网时不出现对话框

TUint32 iapId; // 该值应该是确实对应的查询结果

iapId = GetAPNL(_L("cmnet"), NULL);

RDebug::Print(_L("## %d : "), iapId);

pref.SetIapId(iapId);

pref.SetBearerSet(ECommDbBearerUnknown);

pref.SetDirection(ECommDbConnectionDirectionOutgoing);

gConnection.Start(pref); // 同步创建隐藏 IAP 选择框的网络连接

……

TUint32 CSocketsEngine::GetAPNL(const TDesC& aApn, RFileLogger* iLogger)

{

__UHEAP_MARK;

CCommsDatabase* db = CCommsDatabase::NewL(EDatabaseTypeIAP);

CleanupStack::PushL(db);

//get apn's name

TBuf<32> name;

TUint32 id = 0;

{

CCommsDbTableView* view = db->OpenTableLC(TPtrC(OUTGOING_WCDMA));

TInt err = view->GotoFirstRecord();

while (err == KErrNone)

{

TBuf<32> apn;

view->ReadUintL(TPtrC(COMMDB_ID), id); //接入点ID

view->ReadTextL(TPtrC(COMMDB_NAME), name);//连接名称

view->ReadTextL(TPtrC(GPRS_APN), apn); //接入点名称,可以通过这个字段判断接入点是CMWAP还是CMNET

apn.LowerCase();

if (apn.Compare(aApn) == 0)

{

// LOG_FORMAT((_L("Finded APN id = %d, name = %S"), id, &name));

break;

}

err = view->GotoNextRecord();

}

if (err != KErrNone)

{

CleanupStack::PopAndDestroy(view);

CleanupStack::PopAndDestroy(db);

User::Leave(KErrNotFound);

}

CleanupStack::PopAndDestroy(view);

}

{

CCommsDbTableView* view = db->OpenTableLC(TPtrC(IAP));

TInt err = view->GotoFirstRecord();

while (err == KErrNone)

{

TBuf<32> name2;

view->ReadUintL(TPtrC(COMMDB_ID), id); //接入点ID

view->ReadTextL(TPtrC(COMMDB_NAME), name2);//连接名称

// LOG_FORMAT((_L("id = %d name = %S "), id, &name2));

if (!name.Compare(name2))

{

// LOG_FORMAT((_L("Finded APN id = %d, name = %S"), id, &name));

break;

}

err = view->GotoNextRecord();

}

CleanupStack::PopAndDestroy(view);

}

CleanupStack::PopAndDestroy(db);

__UHEAP_MARKEND;

return id;

}

在 Symbian 平台上开发网络相关应用时,经常会碰到在需要连接网络时,出现一个 IAP 选择框,里面包含了当前手机中的网络接入点配置,通常这些配置点包含了 cmnet 、 cmwap 和 wifi 等不同接入方式。这些具体的不同接入方式,对于普通手机用户来说,稍微有那么一点“深奥”,与其让用户做不知所措的选择,倒不如事先就选择好某种接入方式,作为缺省配置,而不让用户产生选择的烦恼。

要对手机做网络连接的缺省配置,则必需先了解如何获取和修改手机中网络连接相关的配置属性。在 Symbain OS 中,这些配置属性都是通过 CommDb 模块存储的。 CommDb 模块上基于 Symbian OS 的 DBMS 数据库系统,其中存放了不同类型的数据表,典型的如 IAPs 、 GPRS 、 Modems 、 Locations 和 WAP Setting 等。

由上可知, CommDb 是数据库系统,在 Symbian OS 中,提供对数据库的访问类,数据库连接类 CCommsDatabase 和表操作类CCommsDbTableView 。打开数据库并获取某张表的一般操作如下:

CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);

CleanupStack::PushL(commDb);

CCommsDbTableView* commView = commDb->OpenTableLC(TPtrC(NETWORK));

// 通过表 commView 获取改表的各字段值

CleanupStack::PopAndDestroy(2);

而需要控制应用软件网络连接时不弹出 IAP 选择框,那就需要在创建 Symbian RSocket

对象时指定已存在的连接对象,调用 RSocket 方法:

TInt Open(RSocketServ &aServer, TUint addrFamily, TUint sockType, TUint protocol, RConnection &aConnection)

其中的 RConnection 对象参数是已经存在的连接对象。进而得出,要控制

用软件网络连接时不弹出 IAP 选择框,前提是创建初始 RConnection 对象连接时,不弹出IAP 选择框,该机制可方便地如下方法实现:

RConnection gConnection;

TCommDbConnPref pref;

TUint32 iapId = 2; // 该值应该是确实对应的查询结果

pref.SetIapId(iapId);

pref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt ); // 联网时不出现对话框

pref.SetBearerSet(ECommDbBearerPSD);

pref.SetDirection(ECommDbConnectionDirectionOutgoing );

gConnection.Start(pref); // 同步创建隐藏 IAP 选择框的网络连接

在上述 TCommDbConnPref 对象属性中,最重要的就是 iapId 值的确定,因为其他属性值都是固定的,只有该值是变化的,针对不同名称、不同接入方式的网络接入点,其 iapId 是不一样,该值体现在 CommDb 数据库中的 IAP 表中,按如下方法得到:

TUint32 iapId;

CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);

CleanupStack::PushL(commDb);

CCommsDbTableView* commView = commDb->OpenTableLC(TPtrC(IAP));

if(commView-> GotoFirstRecord() == KErrNone)

commView ->ReadUintL(TPtrC(COMMDB_ID), iapId);

// 可以继续遍历 commView 表中的其他记录

CleanupStack::PopAndDestroy(2);

但是,通过 IAP 表,无法得出相应的 iapId 所对应的网络接入点 (IAP) ,其真正的接入方

式 (APN) 为 CMNET 还是 CMWAP ,而这些属性又是存储在另一张表中 OUTGOING_WCDMA 或者 OUTGOING_GPRS 。

TUint32 fakeIapId;

TBuf apnName;

CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);

CleanupStack::PushL(commDb);

CCommsDbTableView* commView = commDb->OpenTableLC(TPtrC(OUTGOING_GPRS));

if(commView-> GotoFirstRecord() == KErrNone)

{

commView->ReadTextL((TPtrC)GPRS_APN, testname);

commView->ReadUintL(TPtrC(COMMDB_ID), fakeIapId);

// 可以继续遍历 commView 表中的其他记录

}

CleanupStack::PopAndDestroy(2);

通过上述操作,可获得手机网络配置的 APN 名称及对应的 fakeIapId (这里称之为 fake ,是因为该 IapId 与 IAP 表中的 IapId 有差异,而真正起作用的是 IAP 表中的 IapId 值)。 APN 值就包含了 GPRS 网络的两种不同接入方式 CMNET 和 CMWAP 。

通过表 OUTGOING_GPRS 得到了手机中真正使用 CMNET 或者 CMWAP 的记录,但其 IapId 不是真正需要的 IapId ;通过表 IAP能得到手机网络连接是真正的 IapId 值,但不能确定其底层具体的接入方式是 CMNET 还是 CMWAP 。现在的问题就说,如何把两张表联合起来?

这其中就用到了 OUTGOING_GPRS 表中的 COMMDB_ID 字段和 IAP 表中的 IAP_SERVICE 字段,通过这两个字段,可将两张表联合。

void SetDefaultIap(TInt aIapType, TUint32 &aIapId)

{

TInt ret = KErrNone;

TBuf apnName;

TBuf<10> defApn;

TUint32 fakeIapId;

aIapId = 0;

if(aIapType == 0)

defApn = _L("cmnet");

else if(aIapType == 1)

defApn = _L("cmwap");

else if(aIapType == 2) // 模拟器

defApn = _L("Winsock");

TRAP(ret,

{

CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);

CleanupStack::PushL(commDb); CCommsDbTableView* commView = commDb->OpenTableLC(TPtrC(OUTGOING_WCDMA));

if (commView->GotoFirstRecord() == KErrNone)

{

do

{

commView->ReadTextL((TPtrC)GPRS_APN, apnName);

commView->ReadUintL(TPtrC(COMMDB_ID), fakeIapId);

if (apnName.Find(defApn) >= 0) // 不区分大小写

{

CCommsDbTableView* pIAPView = commDb->OpenViewMatchingUintLC(TPtrC(IAP), TPtrC(IAP_SERVICE), fakeIapId);

TInt nErr = pIAPView->GotoFirstRecord();

if(nErr == KErrNone)

{

pIAPView->ReadUintL(TPtrC(COMMDB_ID), fakeIapId);

aIapId = fakeIapId;

CleanupStack::PopAndDestroy(); //pIAPView

break;

}

CleanupStack::PopAndDestroy(); //pIAPView

}

}while(commView->GotoNextRecord() == KErrNone);

}

CleanupStack::PopAndDestroy(2);

});

}

备注:

1. 虽然Open C提供了简单的获取IAP表及当然活动连接的方法,但其无法控制在需要网络连接时不弹出IAP选择框,而这个目前只能通过CommDB操作来完成


2. 导出模拟器 commdb 的方法:

在 dos 下,进入 $EPOCROOT$/epoc32/release/winscw/udeb 下,运行 ceddump.exe ;成功后在 $EPOCROOT$/Epoc32/wins/c 下,有 cedout.cfg 文件产生,该文件就是手机网络属性配置。

3. 附表(模拟器):

## IAP

##

[IAP]

ADD_SECTION

# COMMDB_ID = 3

Name=Winsock

IAPServiceType=OutgoingGPRS

IAPService=2

IAPBearerType=LANBearer

IAPBearer=2

IAPNetwork=3

IAPNetworkWeighting=0

Location=4

FIELD_COUNT=8

END_ADD

## OutgoingGPRS

##

[OutgoingGPRS]

ADD_SECTION

# COMMDB_ID = 2

Name=Winsock Service

APN=Winsock

PDPType=IPV4

ReqPrecedence=0

ReqDelay=0

ReqReliability=0

ReqPeakThroughput=0

ReqMeanThroughput=0

MinPrecedence=0

MinDelay=0

MinReliability=0

MinPeakThroughput=0

MinMeanThroughput=0

DataCompression=FALSE

HeaderCompression=FALSE

AnonymousAccess=FALSE

IfNetworks=tcp,udp,icmp,icmp6

IfPromptForAuth=FALSE

AuthRetries=0

IpAddrFromServer=FALSE

IpDNSAddrFromServer=FALSE

Ip6DNSAddrFromServer=FALSE

EnableLCPExtension=FALSE

DisablePlainTextAuth=FALSE

GprsAccessPointType=2

QosWarningTimeout=-1

FIELD_COUNT=26

END_ADD


下载本文
显示全文
专题