UDP problem on S60 over WLan. Please help.
Login to reply to this topic.
dim, 2009-06-14 12:59
Joined: 2009-05-27
Forum posts: 3

Hi, I am trying to use UDP to send messages in a small mobile network. The aim is to have the messages be broadcast to everyone on the network (ie. 255.255.255.255). I want to be able to use the same class for both sending and receiving the messages, instead of a separate server and separate client class.

Currently I am using active objects to schedule the read and write parts. I cannot, for the life of me, manage to send UDP packets over the network. I have no idea where I am going wrong. I have tried changing the broadcast addr to 0.0.0.0 - didn't work. Then setting the socket 'SendTo()' address to 255.255.255.255 and the 'Recv()' address to 0.0.0.0 (after reading some wiki howto for python networking) - didn't work. I thought maybe it was the set up of the socket. so i switched between using socket.connect and socket.bind commands - still didn't work. HELP! Below is the code I am using:

#include "Management/Broadcast/BroadcastManager.h"

const TUint KSocketBufferSize = 256;
const TInt KTimeOut = 50000000; 

CBroadcastManager::CBroadcastManager( CLogger& aLog, RSocketServ& aSocketServer, RConnection& aConnection) 
									: CActive( CActive::EPriorityStandard )
	{
	iLog = &aLog;
	iSocketServer = &aSocketServer;
	iConnection = &aConnection;
	iLog->LogL(_L("Constructed broadcast manager"));
	}

void CBroadcastManager::ConstructL()
	{
	iBroadcastStatus = EBroadcastStarted;
	
	iLog->LogL(_L("Creating Timer active object"));
    iTimeOut = KTimeOut;
    iTimer = CBroadcastTimeOut::NewL(EPriorityHigh, *this);
    
    iLog->LogL(_L("Adding broadcast manager to the scheduler"));
	CActiveScheduler::Add(this); // Add to scheduler
	
	iLog->LogL(_L("Opening UDP socket"));
	TRAPD(err, iBroadcastSocket.Open(*iSocketServer, KAfInet, KSockDatagram, KProtocolInetUdp, *iConnection) );
	if(err != KErrNone)
	{
		iLog->LogNumL(_L("Error opening broadcast socket"), err );
	}
	
	iLog->LogL(_L("Creating read and write active objects"));
	iBroadcastRead = CBroadcastRead::NewL(iBroadcastSocket, *iLog);
	iBroadcastWrite = CBroadcastWrite::NewL(iBroadcastSocket, *iLog);
	
	iLog->LogL(_L("Finished constructing broadcast manager"));
	}

CBroadcastManager::~CBroadcastManager()
	{
		iBroadcastSocket.CancelAll();
		delete iBroadcastRead;
		delete iBroadcastWrite;
		delete iTimer;
		iBroadcastSocket.Close();
	}

void CBroadcastManager::DoCancel()
// Cancel asychronous requests
    {
    iTimer->Cancel();

    // Cancel appropriate request to socket
    switch (iBroadcastStatus)
        {
		case EBroadcastConnecting:
			iBroadcastSocket.CancelConnect();
			break;
		default:
			break;
        }
    }

/*
 Connect to an Socket by IP address    
*/
EXPORT_C void CBroadcastManager::ConnectL(TUint32 aAddr)
    {
    iLog->LogL(_L("Connecting to address"));
    // port number for test purposes - may need to be changed
    iAddress.SetPort(7000);
    iAddress.SetAddress(aAddr); 
    iAddress.SetFamily( KAfInet );
    
    iLog->LogL(_L("Connecting/binding broadcast socket to address"));
    //iBroadcastSocket.SetLocalPort(7000);
    TInt err = iBroadcastSocket.Connect(iAddress, iStatus));
 //   TInt err = iBroadcastSocket.Bind(iAddress));

    
    iBroadcastStatus = EBroadcastConnecting;
    iLog->LogL(_L("Setting active and timer"));
    SetActive();
    iTimer->After(iTimeOut);
    }

/*
Exported function wrapping call to iBroadcastWrite: writes character to socket
*/
EXPORT_C void CBroadcastManager::Write(TChar aChar)
    {
     /* 
    In this simple implementation, if iBroadcastWrite is already active, ignore call.
    Full implementation would buffer data 
    */
    if ((iBroadcastStatus == EBroadcastConnected) && !iBroadcastWrite->IsActive()) {
        iLog->LogL(_L("Issuing SendTo to broadcast socket on 255.255.255.255"));
			iBroadcastWrite->IssueSendTo(KInetAddrBroadcast, aChar);
    }
    }
/*
Exported function wrapping call to iBroadcastRead: reads character from socket
*/  
EXPORT_C void CBroadcastManager::Read()
    {
	if ((iBroadcastStatus == EBroadcastConnected)&&(!iBroadcastRead->IsActive())) {
	    iLog->LogL(_L("Reading charachters from broadcast socket on 0.0.0.0"));
			iBroadcastRead->IssueRecvFrom(KInetAddrAny);
	}
    }

/*
 Active object request complete handler.
 iBroadcastStatus flags what request was made, so its
 completion can be handled appropriately
*/
void CBroadcastManager::RunL()
    {
    // Cancel TimeOut timer before completion
    iTimer->Cancel(); 
    _LIT(KConnecting,"\n<CBroadcastManager> Connecting\n");
    _LIT(KConnectionFailed,"\n<CBroadcastManager> Connection failed");
    _LIT(KDNSFailed,"\n<CBroadcastManager> DNS lookup failed");
    _LIT(KTimedOut,"\n<CBroadcastManager> Timed out\n");
    _LIT(KDomainName,"\nDomain name = ");
    _LIT(KIPAddress,"\nIP address = ");
    
    switch(iBroadcastStatus)
        {
    case EBroadcastConnecting:
        // IP connection request
        if (iStatus == KErrNone)
        // Connection completed sucessfully
            {
            iLog->LogL(KConnecting);
            iBroadcastStatus = EBroadcastConnected;
            Read(); //Start iBroadcastRead Active object 
            }
        else
            {
            iBroadcastStatus = EBroadcastConnectFailed;
            iLog->LogNumL(KConnectionFailed, iStatus.Int());
            }
        break;
    case EBroadcastTimedOut:
        // Timeout request
    	iLog->LogNumL(KTimedOut, KErrTimedOut);
        break;
    default:
    	break;
        };
    }

/*
 Implements MTimeOutNotify: called when timeout expired
*/
void CBroadcastManager::TimerExpired()
    {
    Cancel();
    
    iBroadcastStatus = EBroadcastTimedOut;
    TRequestStatus* status = &iStatus;   
    
    SetActive();
    User::RequestComplete(status, EBroadcastTimedOut);
    }

/*
 Shutdown connection request
*/
EXPORT_C void CBroadcastManager::Stop()
    {
    _LIT(KETerminate,"\n<CBroadcastManager> Terminating\n");

    iLog->LogL(KETerminate);

    switch (iBroadcastStatus)
        {
		case EBroadcastConnected:
			// Stop live connection
			iBroadcastRead->Cancel();
			iBroadcastWrite->Cancel();
			break;
		case EBroadcastConnecting:
		default:
			break;
        }
    }


#include "Management/Broadcast/BroadcastRead.h"


void CBroadcastRead::ConstructL(RSocket& aSocket, CLogger& aLog)
	{
	iBroadcastSocket = &aSocket;
    iLog = &aLog;
    CActiveScheduler::Add(this);
	}

/*
 Cancel asychronous read request
*/
void CBroadcastRead::DoCancel()
    {
    iBroadcastSocket->CancelRead();
    }

/*
 Active object request complete handler
*/
void CBroadcastRead::RunL()
    {
    if (iStatus == KErrNone)
        // Character has been read from socket
        {
        
			iLog->LogL(_L("Received broadcast message "));
			
			_LIT(KDot,".");
			iLog->LogL(KDot);
			
			TBuf16<1> Buffer;
			Buffer.Copy(iBuffer);
			iLog->LogL(Buffer);
			
			IssueRecvFrom(KInetAddrAny);
        }
    else
        {
			// Error: pass it up to user interface
			_LIT(KCEchoReadError,"\CBroadcastRead error");
			iLog->LogNumL(KCEchoReadError, iStatus.Int());
        }   
    }

void CBroadcastRead::IssueRecvFrom(TUint32 aAddr)
    {
    
    iAddress.SetPort(7000);
    iAddress.SetAddress(aAddr); 
    iAddress.SetFamily( KAfInet );

    iBroadcastSocket->RecvFrom(iBuffer,iAddress,NULL,iStatus);
    SetActive();
    };


#include "Management/Broadcast/BroadcastWrite.h"

// 50 seconds time-out
const TInt KTimeOut = 50000000; 

void CBroadcastWrite::ConstructL(RSocket& aSocket, CLogger& aLog)
	{
	iBroadcastSocket = &aSocket;
	iLog = &aLog;
    CActiveScheduler::Add(this);

    iTimeOut = KTimeOut; 
    iTimer = CBroadcastTimeOut::NewL(10, *this);
    iWriteStatus = EWaiting;
	}

/*
Cancels asychronous write request
*/
void CBroadcastWrite::DoCancel()
    {   
    iBroadcastSocket->CancelWrite();
    };

/*
 Implements MTimeOutNotify: called when timeout expired
*/
void CBroadcastWrite::TimerExpired()
    {
    Cancel();
    iWriteStatus = ETimedOut;
    TRequestStatus* status = &iStatus; 
    
    SetActive();
    User::RequestComplete(status, ETimedOut);
    }

/*
 Active object request complete handler
*/
void CBroadcastWrite::RunL()
    {
    if (iStatus == KErrNone)
        {
        _LIT(KWriteOperationTimedOut,"\nWrite operation timed out");
        switch(iWriteStatus)
            {
			// Character has been written to socket
			case ESending:
				// Cancel TimeOut timer
				iTimer->Cancel(); 
				iWriteStatus = EWaiting;
				break;
			// Request timed out
			case ETimedOut:
				iLog->LogNumL(KWriteOperationTimedOut, KErrTimedOut);
				break;
			default:
				break;
            };
        }
    else 
        {
        // Error: pass it up to user interface
        _LIT(KCEchoWriteError,"\CBroadcastWrite error");
        iLog->LogNumL(KCEchoWriteError, iStatus.Int());
        }
    }

void CBroadcastWrite::IssueSendTo(TUint32 aAddr, const TChar &aChar)
    {
    // Set up buffer
    iBuffer.SetLength(0);
    iBuffer.Append(aChar);
    
    iAddress.SetPort(7000);
    iAddress.SetAddress(aAddr); 
    iAddress.SetFamily( KAfInet );
    
    iLog->LogL(_L("Sending broadcast message "));
    iBroadcastSocket->SendTo(iBuffer,iAddress,NULL,iStatus);
    
    // Request timeout
    iTimer->After(iTimeOut);
    
    iWriteStatus = ESending;
    SetActive();
    };


lun, 2009-06-15 15:12
Joined: 2009-05-27
Forum posts: 3

Ok, i have been testing the code with different IP addresses. If I put in the localhost address (127.0.0.1) the program works and I am able to send and recieve multiple messages. But if I change the IP address to 255.255.255.255 or 0.0.0.0 or a combination of these I get no messages received. Can anyone give me some advice as to what I am doing wrong?

I am using two Nokia N80's over WLan as test devices.

Thanks in advance!


copyright 2003-2009 NewLC SARL