APN symbian手机上的接入点编程

特定接入点的查找/创建
1.   Overview

特定接入点的查找/创建应该是这样的一个过程。首先你从一个配置文件里面读出你要选择的AP的名字(一般情况下我们是知道要用那个接入点的,而且为 了方便配置一般也把它写到配置文件中去)。在得到这个名字后,我们就遍历机器上所有的接入点,查找是否有我们需要的,如果有我们就返回那个接入点的索引, 如果没有就要在设备上创建一个AP,创建这个AP的参数也存在配置文件中,成功创建后返回其索引以备后用。


2.   Code


// 从配置文件中读出接入点的名称

TBuf<64> apnConnName;

GetAPNnameFromConfig(apnConnName);

apnConnName.LowerCase();


// 遍历通信数据库,寻找对应的接入点的索引

TUint32 iapId(-1);

CCommsDatabase* commDb = CCommsDatabase::NewL();

CleanupStack::PushL(commDb);

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

TFileName iapName;

User::LeaveIfError(view->GotoFirstRecord());

do

{

    view->ReadTextL(TPtrC(COMMDB_NAME), iapName);

    iapName.LowerCase();

    if (!iapName.Compare(*apName))

    {

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

       break;

    }

}

While (KErrNone == view->GotoNextRecord());


CleanupStack::PopAndDestroy(2); // view, commDb

CleanupStack::PopAndDestroy(apName);

// 找到就返回

if (iapId != -1)

    return iapId;


// 没有找到就创建一个,从配置文件中读出参数

TInt apnDataBearer;

TBuf<64> apnAccessPointName;

TBool apnAuthentication;

TBuf<64> apnProxyNameAddr;

TInt apnProxyPortNumber;


GetAPNBearerFromConf(apnDataBearer);

GetAPNnameFromConf(apnAccessPointName);

GetAPNAuthFromConf(apnAuthentication);

GetAPNProxyNameFromConf(apnProxyNameAddr);

GetAPNProxyPortFromConf(apnProxyPortNumber);


//创建一个接入点

CApAccessPointItem* apn = CApAccessPointItem::NewLC();


apn->SetNamesL( apnConnName );

apn->SetBearerTypeL( (TApBearerType)apnDataBearer );

apn->WriteLongTextL( EApGprsAccessPointName, apnAccessPointName );


if( apnAuthentication )

{

    apn->WriteBool( EApGprsDisablePlainTextAuth, ETrue );

    apn->WriteBool( EApGprsDisablePlainTextAuth, ETrue );

}

else

{

    apn->WriteBool( EApGprsDisablePlainTextAuth, EFalse );

}


if( apnProxyNameAddr.Length() )

{

    apn->WriteLongTextL( EApProxyServerAddress, apnProxyNameAddr );

    apn->WriteUint( EApProxyPortNumber, (TUint)apnProxyPortNumber );

}


CCommsDatabase* commDb = CCommsDatabase::NewL();

CleanupStack::PushL( commDb );

CApDataHandler* handler = CApDataHandler::NewLC( *commDb );

TInt commErr = commDb ->BeginTransaction();

newApId = (TInt32)handler->CreateFromDataL( *apn );

commErr = commDb->CommitTransaction();


CleanupStack::PopAndDestroy( handler );

CleanupStack::PopAndDestroy( commDb );

CleanupStack::PopAndDestroy( apn );

return newApId;

/

 
 
 
1. Overview: The management interface for a network connection or subconnection. Provides clients with the following functionality:

     - Opening and closing the connection

     - Starting a connection, which means associating it with a new underlying interface

     - Attaching the RConnection instance to an existing interface

     - Stopping the connection, which means disassociating it from the underlying interface

     - Obtaining progress information and notification during connection start-up

     - Notifying when subconnections come up and go down

     - Notifying when there is a service change for the connection

     - Notifying when a given amount of data has been sent or received on a connection or subconnection

     - Reading CommDB fields specific to an active connection

     - ......

Note that several of the new functions are asynchronous. It is essential for these calls that the client ensures that the parameters they pass to the RConnection API remain in scope for the duration of the asynchronous call.


这个类就如同RFile一样,在你打开一个文件的使用的,你的首先用RFs,然后在用RFile,这里也是一样的道理,你首先的用 RSsocketServ去建立一个Session,然后用RConncetion来打开这个session被你所用。API也是对应 的,open/close, start(attach)/stop等等。


2. Methods

     - IMPORT_C TInt Open(RSocketServ &aSocketServer, TUint aConnectionType=KConnectionTypeDefault);

    - Opens a new RConnection instance.

打开一个Socket server的连接。


     - IMPORT_C void Start(TRequestStatus &aStatus)

    - Starts a connection asynchronously using the existing connection preferences in CommDb.

    - Note that this may or may not result in a dialog prompt, depending on the connection preference settings.


     - IMPORT_C void Start(TConnPref &aPref, TRequestStatus &aStatus);

    - Starts a connection asynchronously by overriding connection preference settings in CommDb.

    - The settings which can be overridden are: IAP Id, Network Id, Dialog Preference, Direction, Bearer Set.


     - IMPORT_C TInt Start();

    - Starts a connection synchronously using the connection preference settings in CommDb.

    - There is no overriding of settings (such as IAP Id, Network Id, Dialog Preference, Direction, Bearer Set).

    - This may or may not result in a dialog prompt, depending on the connection preference settings.


     - IMPORT_C TInt Start(TConnPref &aPref);

    - Starts a connection synchronously by overriding connection preference settings in CommDb.

    - The settings which can be overridden are: IAP Id, Network Id, Dialog Preference, Direction, Bearer Set.


start()有四个重载的方法,按同步和异步分类或是按用CommDb中存在的connection preference还是按照自己设置的分类。第一个是异步的,使用CommDb中存在的connection preference来连接,所以他不保证能够弹出对话框来。第二个也是异步的,但是他覆盖了CommDb中的connection preference的部分或是全部参数(可以设置的参数有5个:IAP Id, Network Id, Dialog Preference, Direction, Bearer Set;对应的类是Class TCommDbConnPref,其方法是:SetBearerSet(), SetDialogPreference(), SetDirection(), SetIapId(), SetNetId() 各种取值的范围参考SDK)。如果我们想同步选择的话就可以用第三个,其返回值表明连接是否成功,依然是用CommDb中存在的connection preference来连接,不保证能够弹出对话框来。第四个就是用自己设置的connection preference来连接的同步版本。所以方法是很周全的,根据自己的要求来选择。主要考虑是不是弹出对话框,还是slient的进行连接,是否自己有 特殊的链接属性设置等等。

 

     - IMPORT_C TInt Stop();

    - Stops the entire connection by disconnecting the underlying network interface immediately, regardless of whether other clients are using it or not.

    - IMPORT_C TInt GetIntSetting(const TDesC &aSettingName, TUint32 &aValue);

    - Pre-Condition An attached connection: as a result of performing either a Start() or an Attach()

    - Reads current CommDb settings for the active connection.

    - const TDesC &aSettingName The CommDb table name and field name to be accessed. Of the form "<table name>/<field name>" (for example "IAP/Id" or "ModemBearer/PortName").

    - TUint32 &aValue On return, the value of the table/field pair.


    - IMPORT_C TInt GetDesSetting(const TDesC &aSettingName, TDes8 &aValue);

    - IMPORT_C TInt GetDesSetting(const TDesC &aSettingName, TDes16 &aValue);


在我们调用的start之后,用户选择了接入点,我们就可以用上面的API来取得用户所选择的接入点的信息,可以是所选接入点的索引或是8/16位的名称。因为在start之前,我们可以设置IAP Id,这里用的是一个索引,所以一般我们用第一个API。

 

    - IMPORT_C void ProgressNotification(TNifProgressBuf &aProgress, TRequestStatus &aStatus, TUint aSelectedProgress=KConnProgressDefault);  

    - TNifProgressBuf &aProgress - A buffer to receive progress notification.

    - Requests asynchronous progress notification for the connection.


aProgress.iStage参数可以告诉我们现在的连接状态:KConnectionOpen, KConnectionClosed, KLinkLayerOpen, KLinkLayerClosed, KConnectionFailure等等(nifvar.h文件中)


    - IMPORT_C void Close();

    - Closes the connection.

          - The connection will not be dropped immediately: it will be dropped when there is no more data traffic on the connection. So if a client needs to graciously shutdown the connection, Close(), not Stop(), needs to be used after shutting down the socket.
 
 
//


3. Example

接入点选择的思路:首先应该有个配置文件定义了你要选择的接入点的名称,然后你根据这个名称在CommDb中去查找,如果找到了就取其索引就没问题 了。如果找不到就得创建一个APN,创建AP的参数可以在另一个配置文件中定义,成功创建后我们就知道了我们要的AP的索引了。然后在根据需要(同步或是 异步)来实现。

同步方法:

TInt CConnectionManager::SelectIAPSyn()

{

    iConnection.Stop();

    User::LeaveIfError(iConnection.Start());


    _LIT( KIAPIdSetting, "IAP//Id" );

    aConn.GetIntSetting( KIAPIdSetting, iIAPId);

    iConnection.ProgressNotification( iProgress, iStatus );

    SetActive();

    return iIAPId;

}


void CConnectionManager::RunL()

{

    switch ( iProgress().iStage )

    {

       case KConnectionClosed:

       case KLinkLayerClosed:

       {

       }

}


这里虽然也用的AO 但是是用来检测连接过程的,而不是选择连接的。

异步方法:

void CConnectionManager::SelectIAPAsyn()

{

    if ( !IsActive() )

    {

       iConnection.Stop();

       iConnection.Start( iStatus );

       SetActive();

       iIAPFlag = EFalse;  

       return;

    }

}


void CConnectionManager::RunL()

{

    if ( !iIAPFlag )

    {

       if ( KErrNone != iStatus.Int() )

       {

           iIAPFlag = EFalse;

           return iObserv.Event( KErrCouldNotConnect, ... )

       }

       iIAPFlag = ETrue;

       _LIT( KIAPIdSetting, "IAP//Id" );

       aConn.GetIntSetting( KIAPIdSetting, iIAPId);

       iObserv.Event( iIAPId, ...);

    }

}

异步方法有Preference:

void CConnectionManager::SelectIAPSynWithPref()

{

        TCommDbConnPref connectPref;

        connectPref.SetDialogPreference(ECommDbDialogPrefPrompt);

        connectPref.SetDirection(ECommDbConnectionDirectionOutgoing);

        connectPref.SetBearerSet(ECommDbBearerUnknown);

        iConnection.Stop();

    iConnection.Start(connectPref);

    _LIT(KIAPIdSetting, "IAP//Id");

    iConnection.GetIntSetting(KIAPIdSetting, iSelectedIap);

}

同步方法有Preference:

void CConnectionManager::SelectIAPAsynWithPref()

{

        TCommDbConnPref connectPref;

        connectPref.SetDialogPreference(ECommDbDialogPrefPrompt);

        connectPref.SetDirection(ECommDbConnectionDirectionOutgoing);

        connectPref.SetBearerSet(ECommDbBearerUnknown);

        iConnection.Stop();

        iConnection.Start(connectPref,iStatus);

}


void CConnectionManager::RunL()

{

    if ( !iIAPFlag )

    {

       if ( KErrNone != iStatus.Int() )

       {

           iIAPFlag = EFalse;

           return iObserv.Event( KErrCouldNotConnect, ... )

       }

       iIAPFlag = ETrue;

       _LIT( KIAPIdSetting, "IAP//Id" );

       aConn.GetIntSetting( KIAPIdSetting, iIAPId);

       iObserv.Event( iIAPId, ...);

    }

}


结合特定接入点的查找/创建我们在后台选择接入点进行连接:


void CConnectionManager::SelectIAPSynWithPref(Tint aIAPid)

{

        TCommDbConnPref connectPref;

connectPref.SetIapId( aIAPId );

        connectPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);

        connectPref.SetDirection(ECommDbConnectionDirectionOutgoing);

        iConnection.Stop();

        iConnection.Start(connectPref);

}

这种方法是在我们选定了接入点后不弹出接入点对话框自动进行连接的。通常的做法是我们第一个进行连接,弹出对话框,之后如果由于信号原因或是其他原因导致了接入点的丢失,我们就应该在进行连接,此时的连接完全是可以用隐性连接,不通知用户。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值