×

Discussion Board

Results 1 to 9 of 9
  1. #1
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    107

    WLANInfoApi async use

    Hello,

    I was trying to use WLAN Info API in order to constantly monitor WLAN activity (new networks, signal strenght, etc...).

    For this I thought of constantly calling GetScanResults(iStatus, *iScanInfo) like this:
    Code:
    void CWLANInfo::RunL()
    {
    	//If error occurs then it is the job of RunError to treat it
     	User::LeaveIfError(iStatus.Int());
    	
    	if(!IsActive())
    	{
    		iWLANMgmtClient->GetScanResults(iStatus, *iScanInfo);
    		SetActive();
    	}
    }
    The problem is that I don't have a CancelRequest function for the call to GetScanResults. I think the guys from Nokia missed this.

    In a function that the user calls to start the process I have this code:
    Code:
    CWLANInfo::GetWLANAPIInfoL()
    {
    ...
     //Stop any current Active Object activity and get current info
     Cancel();
     error = iWLANMgmtClient->GetScanResults(*iScanInfo);
     ...
     Restart the active job
     if(!IsActive()) //It shouldn't be active at this point
     {
     iWLANMgmtClient->GetScanResults(iStatus, *iScanInfo);
     SetActive();
     }
     ...
    }
    On the line in red there is a big problem when user makes second call because the wlanmgmtclient was never stoped in DoCancel (the api doesn't provide a function to stop the request) but only my active object was stoped(by the call to Cancel()).
    What happen in the second call to this function is that the phone hangs up (N95) and I have to restart it.

    I would like to know if you know any solution or I am doing something wrong. May be I don't understand very well Active Objects and I miss something, please tell me so.

    I will try using a RTimer and in RunL function to call the synchronous version of iWLANMgmtClient->GetScanResults. I see this as the only way to continuously monitor network activity.

    Btw... I am using notifications
    Code:
    //ConstructL
    iWLANMgmtClient = CWlanMgmtClient::NewL();
    iWLANMgmtClient->ActivateNotificationsL(*this);
    but I've noticed that events about new networks don't come if I only call GetScanResults once. Even in the API (.h file) says this:
    Code:
    /**
     * New networks have been detected during scan.
     */
    virtual void NewNetworksDetected() {};
    which translates (for me) in "you should continuosly scan to detect new networks". Am I wrong about this?

    I've tried to use RConnectionMonitor also but it doesn't give me the BSSID. If it does please tell me how as it behaves much better than this WLAN Info API.

    Thanks,
    Omar

  2. #2
    Super Contributor
    Join Date
    Nov 2004
    Location
    Wiltshire, UK
    Posts
    3,644

    Re: WLANInfoApi async use

    Did you see the CancelNotifications in the MWlanMgmtInterface class?

    The API does not continously scan for wifi connections for obvious reasons, it scans using a predefined interval so the list will only show the last set of connections.
    Download Symbian OS now! [url]http://developer.symbian.org[/url]

  3. #3
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    107

    Re: WLANInfoApi async use

    Of course I've seen that function. But it clearly says that this will only cancel notifications, not active requests.

    Am I wrong?

    I mean this request:
    Code:
    iWLANMgmtClient->GetScanResults(iStatus, *iScanInfo);
    I am doing a request, not waiting for a notification which is completly diferent. That is handled by functions such as:

    Code:
    void CWLANInfo::ConnectionStateChanged( TWlanConnectionMode aNewState )
    and not by the Active Object (in the RunL) as the Async request.

    I hope it is clear what I mean. If I am wrong please correct me.

    Thanks,
    Omar

  4. #4
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    107

    Re: WLANInfoApi async use

    I am now using the RTimer aproach in which I am calling the synchronous function:
    Code:
    iWLANMgmtClient->GetScanResults(*iScanInfo);
    each time the timer expires.

    Whenever I need the WLAN information I just take it from the iScanInfo object. The problem is that when I call the function that gets me the WLAN Info it crashes randomly; the program simply exits (without any error) or the phone restarts (using Nokia N95).

    This is the RunL that gets called each time the timer expires:
    Code:
    void CWLANInfo::RunL()
    {
    	//If error occurs then it is the job of RunError to treat it
    	User::LeaveIfError(iStatus.Int());
    
    	TTime time1, time2;
    	time1.HomeTime();
    
    	//Timer has ended... monitor new info
    	iMutex.Wait();
    	TInt error = iWLANMgmtClient->GetScanResults(*iScanInfo);
    	iMutex.Signal();
    	User::LeaveIfError(error);
    
    	time2.HomeTime();
    	TInt64 micros = time2.MicroSecondsFrom(time1).Int64();
    
    	//Reset the timer
    	if(!IsActive())
    	{
    		iTimer.After(iStatus, KTimerInterval);
    		SetActive();
    	}
    }
    I am using a RMutex(iMutex) in order to synchronize the access to the iScanInfo object so that the following function can retrieve the information while iScanInfo is not affected by Runl:

    Code:
    /**
     * This function is used to list WLAN Info with WLAN Info API
     */
    TBuf<512> CWLANInfo::GetWLANAPIInfoL()
    {
    	TBuf<512> infoBuff;
    	TInt securityMode;
    	TInt i=1, k;
    	TBuf<36> bss;
    
    	_LIT(KNetwork, "Network ");
    	_LIT(KNEWLine, "\n");
    	_LIT(KSeparator, " - ");
    	_LIT(KBSSIDFormat, "%02X:");
    	_LIT(KSSIDUnknown, "SSID Unknown");
    
    	//Lock to use iScanInfo
    	iMutex.Wait();
    
    	infoBuff.Zero();
    	for(iScanInfo->First(); !iScanInfo->IsDone(); iScanInfo->Next() )
    	{
    		infoBuff.Append(KNetwork);
    		infoBuff.AppendNum(i);
    		infoBuff.Append(KSeparator);
    		i++;
    		securityMode=iScanInfo->SecurityMode();
    
    		if(securityMode==EwlanConnectionSecurityOpen)
    		{
    			infoBuff.Append(_L("Open"));
    			infoBuff.Append(KSeparator);
    		}
    
    		else if(securityMode==EwlanConnectionSecurityWep)
    		{
    			infoBuff.Append(_L("WEP"));
    			infoBuff.Append(KSeparator);
    		}
    		else if(securityMode==EwlanConnectionSecurity802d1x)
    		{
    			infoBuff.Append(_L("802d1x"));
    			infoBuff.Append(KSeparator);
    		}
    
    		else if(securityMode==EwlanConnectionSecurityWpa)
    		{
    			infoBuff.Append(_L("WPA"));
    			infoBuff.Append(KSeparator);
    		}
    
    		//In general if the least significant bit of the capbility field 
    		//is 1 then the network is of "Infrastructure Type" or else if the 
    		//capability field is 0 then the network is of "Ad-hoc type"
    
    		TUint16 capability=iScanInfo->Capability();
    
    		TInt pad(1);
    		TInt lanType=capability & pad;
    
    		if(lanType==1)
    			infoBuff.Append(_L("Infrastructure"));
    		else
    			infoBuff.Append(_L("Ad-hoc"));
    		infoBuff.Append(KSeparator);
    
    		//Retrieve BSSID
    		TWlanBssid bssid;
    		iScanInfo->Bssid( bssid );
    		bss.Zero();
    		for(k = 0; k < bssid.Length(); k++)
    			bss.AppendFormat(KBSSIDFormat, bssid[k]);
    		//remove last :
    		bss.Delete(bss.Length()-1, 1);
    		infoBuff.Append(bss);
    		infoBuff.Append(KSeparator);
    
    		//Get transmision level
    		TInt8 rxLevel = iScanInfo->RXLevel();
    		infoBuff.AppendNum(rxLevel);
    		infoBuff.Append(KSeparator);
    		
    		//Get SSID
    		TBuf8<36> ssid;
    		TInt err;
    		err = GetSSID(iScanInfo, ssid);
    		if(err== KErrNone)
    		{
    			bss.Zero();
    			bss.Copy(ssid);
    			infoBuff.Append(bss);
    		}
    		else
    			infoBuff.Append(KSSIDUnknown);
    		infoBuff.Append(KNEWLine);
    	}
    
    	//Unlock the mutex
    	iMutex.Signal();
    
    	return infoBuff;
    }
    And this is the function that handles the Leave in RunL:
    Code:
    TInt CWLANInfo::RunError(TInt aError)
    {
    	// There was an error retrieving current wlan info.
    	
    	if(iObserver)
    	{
    		iObserver->HandleWLANInfoErrorL(aError);
    	}
    
    	Cancel();
    
    	//Reset the timer
    	if(!IsActive())
    	{
    		iTimer.After(iStatus, KTimerInterval);
    		SetActive();
    	}
    
    	return KErrNone;
    }
    Where can it be the problem for the crash? It happens randomly and only when I call this function.


    Any advice or idea would help.

    Thanks,
    Omar

  5. #5
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    107

    Re: WLANInfoApi async use

    I am still waiting for a solution if anyone has an idea.

    Thanks,
    Omar

  6. #6
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    107

    Re: WLANInfoApi async use

    I discovered where is the problem but I still don't know what is the problem (I think it has something to do with CBufFlat). Maybe someone can help. I'll try to explain what happens.

    The program uses an active object to detect some GPS position change (in RunL()) which in turn calls my AddLogL() function (here is where the problem is).

    In the same program I have another active object that continuosly scans the wireless networks using WLAN Info API. In the RunL function I get the WLAN information and store it in a TBuf:
    Code:
    void CWLANInfo::RunL()
    {
    ...
    iWLANMgmtClient->GetScanResults(*iScanInfo);
    CopyWLANInfo();
    ...
    }
    
    void CWLANInfo::CopyWLANInfo()
    {
    ... //some code here that puts information from iScanInfo like:
    iWLANBuf.Append(KXMLWLANStrengthTag);
    TInt8 rxLevel = iScanInfo->RXLevel();
    ...
    iWLANTempBuf.Copy(iWLANBuf);
    }
    Now in the AddLog() function I call a function(GetWLANInfo) that returns the data from iWLANTempBuf:
    Code:
    void CNetworkEngine::AddLogL(TReal aLatitude, TReal aLongitude)
    {
    	CBufFlat *buf = CBufFlat::NewL(2);
    	CleanupStack::PushL(buf);
    	TBuf<1024> data;
    	HBufC8 *dataPtr;
    
    	buf->Reset();
    	buf->InsertL(0, KXMLInfoTag);
    
    	//Insert GPS Information
    	TBuf8<36> glat, glon;
    	TRealFormat rFormat(20, 10);
    	glat.Num(aLatitude, rFormat);
    	glon.Num(aLongitude, rFormat);
    
    	buf->InsertL(buf->Size(), KXMLGPSTag);
    	buf->InsertL(buf->Size(), KXMLLatitudeTag);
    	buf->InsertL(buf->Size(), glat);
    	buf->InsertL(buf->Size(), KXMLLatitudeEndTag);
    	buf->InsertL(buf->Size(), KXMLLongitudeTag);
    	buf->InsertL(buf->Size(), glon);
    	buf->InsertL(buf->Size(), KXMLLongitudeEndTag);
    	buf->InsertL(buf->Size(), KXMLGPSEndTag);
    
    	if(iWLANInfo)
    	{
    		//Insert WLAN Information
    		buf->InsertL(buf->Size(), KXMLWLANTag);
    
    		iWLANInfo->GetWLANInfo(data);
                    if(iNetworkEngineObserver)
    		     iNetworkEngineObserver->HandleWLANMessageL(data);
    //		dataPtr = SenXmlUtils::ToUtf8LC(data);
    //		buf->InsertL(buf->Size(), dataPtr->Des());
    //		CleanupStack::PopAndDestroy(dataPtr);
    //		dataPtr = NULL;
    
    		buf->InsertL(buf->Size(), KXMLWLANEndTag);
    	}
    
    	if(iGSMInfo)
    	{
    		//Insert GSM Information
    		buf->InsertL(buf->Size(), KXMLGSMTag);
    		GetGSMInfoParsedL(data);
    		dataPtr = SenXmlUtils::ToUtf8LC(data);
    		buf->InsertL(buf->Size(), dataPtr->Des());
    		CleanupStack::PopAndDestroy(dataPtr);
    		dataPtr = NULL;
    		buf->InsertL(buf->Size(), KXMLGSMEndTag);
    	}
    
    	buf->InsertL(buf->Size(), KXMLInfoEndTag);
    	iFileLogger->Write(buf->Ptr(0));
    
    	buf->Reset();
    	CleanupStack::PopAndDestroy(buf);
    }

    The problem is on the commented red lines, when I try to use the information obtained from the GetWLANInfo function and add it to the CBufFlat object. As it can be seen I can use the data and display it (on the HandleWLANMessageL function).

    If I uncomment the commented red lines I get the old problem: application exits without any panic or error code, or phone crashes and restarts.

    It is very strange because I am using the same procedure(as you can see in the code) for the iGSMInfo object (which is another Active object that retrieves GSM information) and it works great with that.

  7. #7
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    107

    Re: WLANInfoApi async use

    I appologies for all the messages on this thread, finally I've found that the problem was from the logger on this line:
    Code:
    iFileLogger->Write(buf->Ptr(0));
    The logger used a constant (KFileLoggerBufferLength) that was set to 400 for the maximum lenght of its buffer (used to write to a file):
    Code:
    void CFileLogger::WriteL(const TDesC16& aText)
    {
        iLogBuffer.Copy(aText);
        DoWrite();
    }
    
    void CFileLogger::DoWrite()
    {
            ...
    	iFile.Write(iLogBuffer);
            ...
    }
    On the SDK says that the Copy function raises the "11" panic code if the TDesC passed to copy is greater than the holder string.

    What annoyes me is that I didn't get any panic code in my program, it simply exited each time.

    Anyway, problem solved.

  8. #8
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    107

    Re: WLANInfoApi async use

    Ok... so after more tests I've discovered that the logger wasn't actually my problem, in areas where there are multiple networks and hidden networks the phone still crashes (application exits without error messages or phone restarts).

    To find out where is the problem I made a little tracer and I here are the messages on the moment of crash:

    Code:
    Before LBSPositionUpdatedL
    Begin CNetworkEngine::AddLog
    Before WLANInfo::GetWLANInfo
    After WLANInfo::GetWLANInfo
    Begin CNetworkEngine::Write
    End CNetworkEngine::Log and Write
    After LBSPositionUpdatedL
    Before WLANInfo::RunL
    Before WLANInfo::CopyWLANInfo
    //HERE IT CRASHES ... file ends
    This is the same file for a normal operation:
    Code:
    Before LBSPositionUpdatedL
    Begin CNetworkEngine::AddLog
    Before WLANInfo::GetWLANInfo
    After WLANInfo::GetWLANInfo
    Begin CNetworkEngine::Write
    End CNetworkEngine::Log and Write
    After LBSPositionUpdatedL
    Before WLANInfo::RunL
    Before WLANInfo::CopyWLANInfo
    After WLANInfo::CopyWLANInfo
    After WLANInfo::RunL
    Before WLANInfo::RunL
    Before WLANInfo::CopyWLANInfo
    After WLANInfo::CopyWLANInfo
    After WLANInfo::RunL
    Before WLANInfo::RunL
    ... //more
    So it is clear that my code crashes on CopyWLANInfo that as described before is this:
    Code:
    void CWLANInfo::CopyWLANInfo()
    {
    #if traceon
    	_LIT(KBefore, "Before WLANInfo::CopyWLANInfo\n");
    	if(iTraceLogger)
    		iTraceLogger->WriteL(KBefore);
    #endif
    	
    	iWLANBuf.Zero();
    	TInt securityMode;
    	TInt i=1, k;
    	TBuf<KSSIDLenght> bss;
    
    	_LIT(KOPEN, "Open");
    	_LIT(KWEP, "WEP");
    	_LIT(K802, "802d1x");
    	_LIT(KWPA, "WPA");
    	_LIT(KINFRA, "Infrastructure");
    	_LIT(KADHOC, "Ad-hoc");
    	_LIT(KBSSIDFormat, "%02X:");
    	_LIT(KSSIDUnknown, "SSID Unknown");
    
    	if(iWLANMgmtClient == NULL || iScanInfo == NULL)
    		return;
    
    	for(iScanInfo->First(); !iScanInfo->IsDone(); iScanInfo->Next() )
    	{
    		iWLANBuf.AppendFormat(KXMLWNETTag, i);
    		i++;
    
    		iWLANBuf.Append(KXMLWLANSecurityTag);
    		securityMode=iScanInfo->SecurityMode();
    		if(securityMode==EwlanConnectionSecurityOpen)
    			iWLANBuf.Append(KOPEN);
    		else if(securityMode==EwlanConnectionSecurityWep)
    			iWLANBuf.Append(KWEP);
    		else if(securityMode==EwlanConnectionSecurity802d1x)
    			iWLANBuf.Append(K802);
    		else if(securityMode==EwlanConnectionSecurityWpa)
    			iWLANBuf.Append(KWPA);
    		iWLANBuf.Append(KXMLWLANSecurityEndTag);
    
    		//In general if the least significant bit of the capbility field 
    		//is 1 then the network is of "Infrastructure Type" or else if the 
    		//capability field is 0 then the network is of "Ad-hoc type"
    		iWLANBuf.Append(KXMLWLANTypeTag);
    		TUint16 capability=iScanInfo->Capability();
    		TInt pad(1);
    		TInt lanType=capability & pad;
    
    		if(lanType==1)
    			iWLANBuf.Append(KINFRA);
    		else
    			iWLANBuf.Append(KADHOC);
    		iWLANBuf.Append(KXMLWLANTypeEndTag);
    
    		//Retrieve BSSID
    		iWLANBuf.Append(KXMLBSSIDTag);
    		TWlanBssid bssid;
    		iScanInfo->Bssid( bssid );
    		bss.Zero();
    		for(k = 0; k < bssid.Length(); k++)
    			bss.AppendFormat(KBSSIDFormat, bssid[k]);
    		//remove last :
    		bss.Delete(bss.Length()-1, 1);
    		iWLANBuf.Append(bss);
    		iWLANBuf.Append(KXMLBSSIDEndTag);
    
    
    		//Get SSID
    		iWLANBuf.Append(KXMLSSIDTag);
    		TBuf8<128> ssid;
    		TInt err;
    		err = GetSSID(iScanInfo, ssid);
    		if(err == KErrNone)
    		{
    			bss.Zero();
    			bss.Copy(ssid);
    			iWLANBuf.Append(bss);
    		}
    		else
    			iWLANBuf.Append(KSSIDUnknown);
    		iWLANBuf.Append(KXMLSSIDEndTag);
    
    		//Get transmision level
    		iWLANBuf.Append(KXMLWLANStrengthTag);
    		TInt8 rxLevel = iScanInfo->RXLevel();
    		iWLANBuf.AppendNum(rxLevel);
    		iWLANBuf.Append(KXMLWLANStrengthEndTag);
    
    		iWLANBuf.Append(KXMLWNETEndTag);
    	}
    
    	iWLANTempBuf.Copy(iWLANBuf);
    	
    #if traceon
    	_LIT(KAfter, "After WLANInfo::CopyWLANInfo\n");
    	if(iTraceLogger)
    		iTraceLogger->WriteL(KAfter);
    #endif
    }
    Any ideas?

    Ar least someone know why an application might crash without any error message (like Kern ERR or smth similar) or why the phone restarts?

    Thanks,
    Omar

  9. #9
    Regular Contributor
    Join Date
    Mar 2008
    Posts
    107

    Re: WLANInfoApi async use

    Ok, so the answer was actually very simple...

    I was getting a Panic and that's why I wasn't seeing anything on the phone.

    Solution:

    1. Use RBuf everywhere (is on the heap, not stack)
    2. Use big size for maximum size (around 8KB)
    3. Test before Append/Copy or anything else that causes a Panic. This is really a big pain in the ...

    I was expecting a little bit more support, but anyways...

    Problem closed.
    Last edited by omarfr; 2008-05-22 at 21:46. Reason: completing

Similar Threads

  1. Why no cancel API for async RConnection::Start(TConnPref& , TRequestStatus&) ?
    By wlm_justek in forum Symbian Networking & Messaging (Closed)
    Replies: 0
    Last Post: 2007-05-21, 02:58
  2. Replies: 6
    Last Post: 2006-12-21, 10:44
  3. Client Server Async
    By Zaibach in forum Symbian
    Replies: 2
    Last Post: 2006-10-27, 10:06
  4. Replies: 8
    Last Post: 2006-03-02, 10:21
  5. Replies: 3
    Last Post: 2004-05-28, 14:44

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×