CommDB - Quirks and Weirdness!
Login to reply to this topic.
Thu, 2005-05-12 15:47
Joined: 2003-10-08
Forum posts: 106
Hi all,
      We are working on an automatic IAP Selector to bypass the selection dialog for HTTP connections. Using the CommDB Tables, Views, etc. .. we access the IAP Ids and use the same to connect. All works fine till then.
   We are using RGenericAgent on Symbian 6.1 and RConnection on Symbian 7.0s. Both seem to show the same behaviour. If the Access Points are completed deleted and then the settings are retrieved again from the Operator ... or a new access point is created .. the connection code keeps failing (Symbian 6.1 - The connection is not even attempted & on Symbian 7.0s the popup dialog starts appearing during the call to RConnection::Start()). The weird bit is that if I keep pressing Cancel for the pop-up dialog; it does eventually find the working IAP and connect to it. So, the RConnection code is working as required but it seems some setting in the CommDB now makes the popup appear everytime!!
 My query is whether the CommDB Ids etc, get corrupted when all settings are deleted? Has anyone else had the same experience?
Could anyone please shed some light on this?

Thanks in advance!

Regards,
Varun


Fri, 2005-05-13 08:42
Joined: 2004-07-28
Forum posts: 1379
It's annoying.  Basically, the record is maked as deleted, but not actually removed until some point later.

You are looking up the IAP ID you wish to connect to?  Or are you dialing the "default" IAP?

In one of my apps, I use code like this:

Code:
void CGatewayConnection::CheckGlobalCommsTableL()
{
CCommsDatabase* pDB = CCommsDatabase::NewL(EDatabaseTypeIAP);
CleanupStack::PushL(pDB);

CCommsDbConnectionPrefTableView* pPrefView = pDB->
OpenConnectionPrefTableInRankOrderLC(ECommDbConnectionDirectionOutgoing);

pPrefView->GotoFirstRecord();

CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref pref;
pPrefView->ReadConnectionPreferenceL(pref);

TUint32 id = pref.iBearer.iIapId;

CCommsDbTableView* pIAPView = pDB->OpenViewMatchingUintLC(TPtrC(IAP), TPtrC(COMMDB_ID), id);

TInt nErr = pIAPView->GotoFirstRecord();

if(nErr != KErrNone)
{
//CEikonEnv::Static()->InfoWinL(_L("Record is deleted"), KNullDesC);

CleanupStack::PopAndDestroy(pIAPView);

pIAPView = NULL;

pIAPView = pDB->OpenTableLC(TPtrC(IAP));

nErr = pIAPView->GotoFirstRecord();

TInt nRecordId = 0;
if(nErr == KErrNone)
{
TUint32 id = 0;
TRAPD(err, pIAPView->ReadUintL(TPtrC(COMMDB_ID), id));
if(err == KErrNone)
{
nRecordId = id;
}
}

//
// Record is deleted - sort it out
pref.iBearer.iIapId = nRecordId;
pPrefView->UpdateBearerL(pref.iBearer);
iFirstRun = ETrue;
iAppUi->PropertyStoreManager()->DeleteEntry(KFirstRunPropName);
}
else
{
//CEikonEnv::Static()->InfoWinL(_L("Record is there"), KNullDesC);
}

CleanupStack::PopAndDestroy(pIAPView);
CleanupStack::PopAndDestroy(pPrefView);
CleanupStack::PopAndDestroy(pDB);
}

This looks up the "default" IAP ID, and makes sure the record really does exist.  If not, sorts it out.

Basically, you're looking at doing something similar.

didster

Fri, 2005-05-13 09:48
Joined: 2003-10-08
Forum posts: 106
Quote
It's annoying. Basically, the record is maked as deleted, but not actually removed until some point later.

You are looking up the IAP ID you wish to connect to? Or are you dialing the "default" IAP?

Actually, I am retrieving all the available IAPs from the CommDB using the OUTGOING_GPRS table. The code is as follows :-

Code:
/* Reads IAP Entries from the CommDB */
void CIAPManager::LoadIAPInformationL()
{
  /* Reset the list */
  iIAPList.Reset();

  /* open the IAP communications database */
  CCommsDatabase* commDB = CCommsDatabase::NewL(EDatabaseTypeIAP);
  /* push onto cleanupstack */
  CleanupStack::PushL(commDB);
 
  /* initialize the view */
  CCommsDbTableView* commDBView = commDB->OpenTableLC( TPtrC(OUTGOING_GPRS) );
 
  /* open the AP utils */
  CApUtils* apUtils = CApUtils::NewLC(*commDB);
 
  /* go to the first record */
  User::LeaveIfError(commDBView->GotoFirstRecord());
 
  /* iterate thru all the records and add to the list */
  do {

     /* read the interface type - PPP or SLIP,
      * PPP means a dial-up ISP, so skip it.
      */
     HBufC* ifName = commDBView->ReadLongTextLC( TPtrC(SERVICE_IF_NETWORKS) );
     
     /* check if it is PPP */
     TInt isNotPPP = ifName->Compare(_L("PPP"));
     /* pop and destroy the buffer */
     CleanupStack::PopAndDestroy(ifName);

     /* only process if non-dialup */
     if( isNotPPP ) {
        TIAPEntry iapEntry;

        /* read the entry id */
        TUint32 entryId;
        commDBView->ReadUintL(TPtrC(COMMDB_ID), entryId);
        /* convert to IAP id */
        TUint32 convertedId = entryId;
        TRAPD(dummyErr, entryId = apUtils->IapIdFromWapIdL(convertedId));
        iapEntry.iId = entryId;

        /* read the name */
        HBufC* iapName = commDBView->ReadLongTextLC( TPtrC(COMMDB_NAME) );
        /* copy to our name holder */
        if( iapName->Length() > iapEntry.iName.MaxLength() ) {
           iapEntry.iName.Copy(iapName->Ptr(), iapEntry.iName.MaxLength());
        }
        else {
           iapEntry.iName.Copy(*iapName);
        }
        /* pop and destroy the buffer */
        CleanupStack::PopAndDestroy(iapName);

        /* append to the array */
        User::LeaveIfError(iIAPList.Append(iapEntry));
     }

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

  /* pop and destroy the IAP utilities */
  CleanupStack::PopAndDestroy(apUtils);

  /* pop and destroy the IAP View */
  CleanupStack::PopAndDestroy(commDBView);

  /* pop and destroy the database */
  CleanupStack::PopAndDestroy(commDB);

  return;
}

Could I be doing something wrong in the same? I am using the same code for both Symbian 6.1 and Symbian 7.0s. I then iterate thru the list and try connecting to each one-by-one.

Regards,
Varun

Tue, 2005-05-17 12:10
Joined: 2003-10-08
Forum posts: 106
Hello again,
                Thanks, didster! The problem is solved now! Mo more popup! The code I was using to retrieve the IAP Ids was returning the wrong ones! My assumption is that the OUTGOING_GPRS table was returning some kind of internal CommDB Record Id rather than the connection Id. I am now using the code didster has specified above to get the Connection Preferences table and using the Id from there. But a new problem has arisen.  Roll Eyes
     The retrieval ALWAYS returns only a single IAP! It seems to be the right one as the connection goes thru and the upload takes place as needed. The issue is that I also need to display the names of the IAPs to allow the user to select one explicitly if needed! I have two other IAPs available .. GPRS and MMS; but they never show up in the listings.
   The code is the pretty much the same as the one didster has specified above. What could be wrong? Has anyone else had the same experience?

Thanks in advance!

Regards,
Varun

Tue, 2005-05-17 12:13
Joined: 2004-07-28
Forum posts: 1379
On your 7.0s emulator, open a command prompt and change to \epoc32\release\winscw\udeb

and run ceddump.exe

You will get a file called cedout.cfg in \epoc32\winscw\c

Could you put that file up here please

Don't foget, the code I put up here is for dialing the _default_ IAP.  The IAP id is returned from the prefs table, then a record set is opened from the IAP table containg just that one record.

So... Smiley

didster

Tue, 2005-05-17 12:36
Joined: 2003-10-08
Forum posts: 106
Cheezy Aaah ok! That explains it!

I can only test the code on the actual device due to some dependencies, so my emulator CommDB is still setup with the usual Ethernet & RAS connections. But I did try the dump and saw that there is only one IAP in the Connection Preferences table. Oh Well!  Huh

Is there any way for me to retrieve the IAP list using my previous code and then either crosscheck/map it to the right IAP/Connection Ids?

Thanks again!

Regards,
Varun

Tue, 2005-05-17 13:11
Joined: 2004-07-28
Forum posts: 1379
You should just be able to replace the OpenViewMatchingUintLC call with a OpenViewLC to open the entire record set.

didster

Tue, 2005-05-17 14:10
Joined: 2003-10-08
Forum posts: 106
Quote
You should just be able to replace the OpenViewMatchingUintLC call with a OpenViewLC to open the entire record set.

True, but isn't that similar to what I was doing before? Except that I was using the OUTGOING_GPRS table. What I have noticed is that the COMMDB_ID Field is not the actual IAP connection ID which can be passed to RGenericAgent. Since the Connection Pref table allows us to get the actual iBearer.iIAPid, it is mapping correctly to what needs to be passed down for auto-connection without pop-up.

Basically, in my experience the COMMDB_ID does not map to the correct IAP Connection ID. The dump of the CommDB on the emulator showed that each Table in the DB can contain a COMMDB_ID which is unique within the table but not globally in the CommDB.

Will the IAP table in lieu of the OUTGOING_GPRS table (in my old code) work?

Regards,
Varun

Thu, 2005-05-19 14:07
Joined: 2004-07-28
Forum posts: 1379
Have you actually tried using COMMDB_ID?

didster

Thu, 2005-05-19 14:16
Joined: 2003-10-08
Forum posts: 106
Quote from: didster
Have you actually tried using COMMDB_ID?

Yes I have. It works perfectly until the IAP Settings are deleted and then requested again from the Operator. Then, the pop-up dialog starts appearing again on a call to RGenericAgent::StartOutgoing() and RConnection::Start(). I tried using the WAP_ACCESS_POINT table too; and the COMMDB_IDs gotten from there exhibit the same behaviour!

Only the Connection Preferences table returns an always working IAP; but it only returns one! I need all available GPRS IAPs. 

I am now using the CApSelect & CApDataHandler and testing those classes to see if they can work.

Regards,
Varun

Mon, 2005-07-11 12:53
Joined: 2005-06-15
Forum posts: 17
Hi

Have you solved your problem. I have a similar issue on 6600. (This does not happen on 6630).

This is my scenario, when my application starts and if the required APN is not defined then I define it and start the GPRS connection automatically(using RGenericAgent->StartOutgoing). This works fine.

But for some reson the APN is deleted manually and then the application is started again. This time I am able to define the APN again and add to OUTGOING_GPRS table. But RGenericAgent->Open() fails.

Note: Each time I start testing the phone, I hard reset it (*#7370#).

Can you please share your thoughts with me on this issue. (This is really urgent, I have tried looking into various forums and posts. I would really appreciate an early response)

---
As a side note - I tried the making the call asynchronous by calling this method from a class exteding from CActive. I call the default CActive(EPriorityHigh) and add this object to the schedular. But my RunL method is never called.

iNetAgent.StartOutgoing(*iOverrides, this->iStatus);
SetActive(); //instead of User::waitForRequest(status);
-----

Thanks
Venkatesh
Mon, 2005-07-11 12:59
Joined: 2004-07-28
Forum posts: 1379
I do it like this.  Each time before I "dial" the APN, I call this function:

Code:
void CGatewayConnection::CheckGlobalCommsTableL()
{
CCommsDatabase* pDB = CCommsDatabase::NewL(EDatabaseTypeIAP);
CleanupStack::PushL(pDB);

CCommsDbConnectionPrefTableView* pPrefView = pDB->
OpenConnectionPrefTableInRankOrderLC(ECommDbConnectionDirectionOutgoing);

pPrefView->GotoFirstRecord();

CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref pref;
pPrefView->ReadConnectionPreferenceL(pref);

TUint32 id = pref.iBearer.iIapId;

CCommsDbTableView* pIAPView = pDB->OpenViewMatchingUintLC(TPtrC(IAP), TPtrC(COMMDB_ID), id);

TInt nErr = pIAPView->GotoFirstRecord();

if(nErr != KErrNone)
{
//CEikonEnv::Static()->InfoWinL(_L("Record is deleted"), KNullDesC);

CleanupStack::PopAndDestroy(pIAPView);

pIAPView = NULL;

pIAPView = pDB->OpenTableLC(TPtrC(IAP));

nErr = pIAPView->GotoFirstRecord();

TInt nRecordId = 0;
if(nErr == KErrNone)
{
TUint32 id = 0;
TRAPD(err, pIAPView->ReadUintL(TPtrC(COMMDB_ID), id));
if(err == KErrNone)
{
nRecordId = id;
}
}

//
// Record is deleted - sort it out
pref.iBearer.iIapId = nRecordId;
pPrefView->UpdateBearerL(pref.iBearer);
iFirstRun = ETrue;
iAppUi->PropertyStoreManager()->DeleteEntry(KFirstRunPropName);
}
else
{
//CEikonEnv::Static()->InfoWinL(_L("Record is there"), KNullDesC);
}

CleanupStack::PopAndDestroy(pIAPView);
CleanupStack::PopAndDestroy(pPrefView);
CleanupStack::PopAndDestroy(pDB);
}

What this does, is looks to see if the record pointed to by the global comms DB pref table is indeed still there.  If not, it changes it so the next time you "dial" your APN, the system will prompt you again.

You could adapt this function to maybe search through the APN's looking for the one you wish to use, and change the table accordingly.

didster

Tue, 2005-07-12 19:55
Joined: 2005-06-15
Forum posts: 17
Thanks a lot Didster,

It works. - This works fine for p900.

But on 6600 the following scenario fails
1) I hard reset the phone (*#7370#)
2)  Start my application - which figures that the apn's are not available - so we create the apn
3) Then call the method below
4) The network connection is established and works
5) I exit the application.
6) Goto the Network Settings and delete all the APN's
7) Start the phone again.
Cool After StartOutgoing(); the User::WaitForRequest() never returns. The APN gets created though.

This problem seems to go away if I create 2 APN's with same GprsAccessPointName (OurgoingGprs table COMMS_DB name) but different (IAP table COMMS_DB) name.


----------------------

Didster's code with a little modification

iapid is the ID you want from the IAP table...

CCommsDbConnectionPrefTableView* pPrefView = pDB->OpenConnectionPrefTableInRankOrderLC(ECommDbConnectionDirectionOutgoing);
  CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref pref;

  TInt PrefErr = pPrefView->GotoFirstRecord();
  if (iapid != 0) {
    pref.iRanking = 1;
    pref.iDirection = ECommDbConnectionDirectionOutgoing;
    pref.iDialogPref = ECommDbDialogPrefDoNotPrompt;
    pref.iBearer.iBearerSet = ECommDbBearerGPRS;
    pref.iBearer.iIapId = iapid;

    if (PrefErr == KErrNone) {
      pPrefView->ReadConnectionPreferenceL(pref);
      pref.iBearer.iIapId = iapid;
      pref.iBearer.iBearerSet = ECommDbBearerGPRS;
      pPrefView->UpdateBearerL(pref.iBearer);
      pPrefView->ChangeConnectionPreferenceRankL(1);
      pPrefView->UpdateDialogPrefL(ECommDbDialogPrefDoNotPrompt);
    } else {
      TRAPD(result, pPrefView->InsertConnectionPreferenceL(pref));
    }
  }

Thu, 2006-01-12 08:36
Joined: 2005-01-10
Forum posts: 11
 pPrefView->UpdateBearerL(pref.iBearer);
when i use the code , return KErrArgument, why?
KErrArgument(The specified IAP (aPref.iBearer.iIapId) cannot be used, as it does not fall in the bearer set defined by aPref.iBearer.iBearerSet and have the same direction as aPref.iDirection.
)

copyright 2003-2009 NewLC SARL