Discussion Board

Results 1 to 14 of 14
  1. #1
    Registered User
    Join Date
    Feb 2007
    Posts
    39

    Help with CActive

    Hi !

    I'm facing a problem with a CActive-derived object. I'm trying to listen at a commport and when data is available to write it on a second one. I'm using RComm::NotifyDataAvailable(TRequestStatus &aStatus) to wait on data arrival.

    here is my code :

    Code:
    //CSerialDataObserver.h
    
    class CSerialDataObserver : public CActive
    {
    public:
    	// C++ constructor
    	CSerialDataObserver();
    	static CSerialDataObserver* NewL( CDebug* deb);
    	static CSerialDataObserver* NewLC( CDebug* deb);
    	// Second-phase constructor
    	void ConstructL( CDebug* deb);
    	// Cancel and destroy
    	~CSerialDataObserver();
    
    public: // New functions
    	// Function for making the initial request
    	void StartL();
    
    private: // From CActive
    	// Handle completion
    	void RunL();
    	
    	// How to cancel me
    	void DoCancel();
    	
    	// Override to handle leaves from RunL(). Default implementation causes
    	// the active scheduler to panic.
    	//TInt RunError(TInt aError);
    
    private:
    	RCommServ m_iWriterServ;
    	RComm m_iWriter;
    	RCommServ m_iReaderServ;
    	RComm m_iReader;
    };
    
    
    
    
    //CSerialDataObserver.cpp
    
    #include "SerialDataObserver.h"
    
    CSerialDataObserver::CSerialDataObserver() : 
    CActive(EPriorityStandard)
    {
    }
    
    CSerialDataObserver* CSerialDataObserver::NewL( CDebug* deb){
        CSerialDataObserver* self = NewLC( deb);
        CleanupStack::Pop( self );
        return( self ) ;
    }
    CSerialDataObserver* CSerialDataObserver::NewLC( CDebug* deb){
    	CSerialDataObserver* self = new ( ELeave ) CSerialDataObserver(  );
        CleanupStack::PushL( self );
        self->ConstructL(deb);
        return self;
    }
    
    void CSerialDataObserver::ConstructL(CDebug* deb)
    {
    	m_deb = deb;
    	
    	User::LeaveIfError(m_iWriterServ.Connect());
    	User::LeaveIfError(m_iReaderServ.Connect());
    	User::LeaveIfError(m_iWriterServ.LoadCommModule(_L("ECACM")));
    	User::LeaveIfError(m_iReaderServ.LoadCommModule(_L("DATAPORT")));
    	
    	User::LeaveIfError(m_iWriter.Open(m_iWriterServ,_L("ACM::0"),ECommShared));
    	User::LeaveIfError(m_iReader.Open(m_iReaderServ,_L("DATAPORT::0"),ECommShared));
    
    	CActiveScheduler::Add(this);				// Add to scheduler
    }
    
    CSerialDataObserver::~CSerialDataObserver()
    {
    	Cancel(); // Cancel any request, if outstanding
    	m_iWriter.Close();
    	m_iReader.Close();
    	m_iWriterServ.Close();		
    	m_iReaderServ.Close();	
    }
    
    void CSerialDataObserver::DoCancel()
    {
    	m_iReader.NotifyDataAvailableCancel();
    }
    
    void CSerialDataObserver::StartL()
    {
    	Cancel();						// Cancel any request, just to be sure
    	m_iReader.NotifyDataAvailable(iStatus);
    	SetActive();					// Tell scheduler a request is active
    }
    
    void CSerialDataObserver::RunL()
    {
    	TCmdBuf aDes;
    	TRequestStatus status;
    	
    	m_iReader.ReadOneOrMore(status,aDes);
    	User::After(100000);
    	if(status != KErrNone)
    		m_iReader.ReadCancel();
    	
    	m_iWriter.Write(status,aDes);
    		
    	m_iReader.NotifyDataAvailable(iStatus);	// Set for 1 sec later
    	SetActive();					// Tell scheduler a request is active
    }
    I am working in a thread, where I create an activescheduler and a cleanup stack.

    The creation of the object and the call to StartL() works perfectly. But then it's over, the RunL() method is never called...(I tested the RComm::NotifyDataAvailable() and it works perfectly).

    any idea ?

  2. #2
    Regular Contributor
    Join Date
    Oct 2003
    Location
    Spain
    Posts
    329

    Re: Help with CActive

    Hi,

    did you call CActiveScheduler::Start() before requesting the asynchronous service?

    It could be the cause.

    Bye

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

    Re: Help with CActive

    Actually the problem is the User::After(100000);

    You need to implement a state machine to decide whether or not you are reading or writing then just swap between the two states

    Don't use User::After, it blocks the current thread and stops the active scheduler running

  4. #4
    Regular Contributor
    Join Date
    Jan 2007
    Posts
    155

    Re: Help with CActive

    How can User::After() be causing a problem when that call is inside RunL() and the problem is that RunL() isn't being called in the first place?

    If you do get your RunL() to be called you have another problem because you are using a locally declared TRequestStatus.

    We see so many people on here who create a separate thread in which to put a single active object. Don't use threads unless you need to. Just use multiple active objects in the same main thread, your life will be much easier.

    As has already been mentioned, are you starting the active scheduler? If you don't use a separate thread then you don't have to worry creating and starting an active scheduler.

  5. #5
    Regular Contributor
    Join Date
    Mar 2006
    Posts
    81

    Re: Help with CActive

    How can User::After() be causing a problem when that call is inside RunL() and the problem is that RunL() isn't being called in the first place?
    I think Paul is simply pointing out that the code inside the RunL() is wrong anyway.

    Another reason why RunL() might not get called is if the port hasn't received any data. Are you sure that you are actually getting data on the port!?

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

    Re: Help with CActive

    I misread it, you are right,

    I would go with the active scheduler not being started.

    Also I noticed in the runl, the parameter to the async call is a local variable

  7. #7
    Registered User
    Join Date
    Feb 2007
    Posts
    39

    Re: Help with CActive

    I tried to start the active Scheduler but my thread is stuck just after the call.

    btw the RunL() is never called for the moment ...

    For the User::After() you're right I can get rid of it, cause if the runL function is called the reason is that there is something to read so the readoneormore will return (the timeout stuff is useless).

    About the thread : It's my first program on Symbian and I didn't know much about the differences between Active objects and Threads. My thread is mainly used to avoid UI blocking, therefore as I am using the PC/phone USB serial interface so of the function of the RComm API does not work (e.g. the RComm::QueryreceiveBuffer() returns always 0)

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

    Re: Help with CActive

    I suggest you work through the workbook (http://www.forum.nokia.com/info/sw.n..._0_en.pdf.html) to understand how the active scheduler works.

    It is not stuck, that is the way its supposed to work.



    You need to call startl before call CActiveScheduler::Wait

  9. #9
    Registered User
    Join Date
    Feb 2007
    Posts
    39

    Re: Help with CActive

    thx for the link !

    I put my Active Object in the main thread and it works perfectly ! I think that i'll get rid of this thread which is the origin of many problems !

  10. #10
    Registered User
    Join Date
    Jan 2007
    Posts
    15

    Re: Help with CActive

    Hi!

    I'm trying to make a application that connects PC and Phone via USB cable and comunicate through Serial Port, and I cannot send data from PC to Device on the same port that I'm using for reading data comming from Device.

    When you connect the phone with the PC with USB cable the cable driver makes 2 Virtual COM ports.

    On which port do you send data to the Device?

    Thanks!

  11. #11
    Registered User
    Join Date
    Oct 2007
    Posts
    42

    Re: Help with CActive

    Hello everybody,

    I am getting the same problem as wagonli.
    That is after submitting request of port.NotifyDataAvailable()
    my code does not enter in RunL() of Active object when there is
    data available. I am also working on single thread. I have also tried code posted by wagonli but it does not works.
    Can anyone please help to resolve it.

  12. #12
    Registered User
    Join Date
    Oct 2007
    Posts
    42

    Re: Help with CActive

    If anyone have any suggestions to above question then please
    reply to above.

  13. #13
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,791

    Re: Help with CActive

    "Code snippet"
    Quote Originally Posted by avibatbha
    port.NotifyDataAvailable()
    obviously does not even compile, how could anyone comment it?

  14. #14
    Registered User
    Join Date
    Oct 2007
    Posts
    42

    Re: Help with CActive

    wizard_hu sir,

    I have written it by mistake, it is actually port.NotifyDataAvailable(iStatus) & it compiles well.
    The code is almost same as posted by wagonli above & my RunL() method is not being called when data is available on the port.

Similar Threads

  1. Replies: 2
    Last Post: 2007-02-01, 18:02
  2. CActive and cancel
    By yaront in forum Symbian
    Replies: 0
    Last Post: 2005-01-27, 14:29
  3. Cancelling CActive and RunL
    By yaront in forum Symbian
    Replies: 3
    Last Post: 2005-01-12, 08:45
  4. CActiveScheduler & CActive Objects
    By Kalderas in forum Symbian
    Replies: 0
    Last Post: 2003-08-07, 12:33
  5. Two CActive object conflict ?
    By rbwilliams2 in forum Symbian
    Replies: 0
    Last Post: 2003-03-26, 20:52

Posting Permissions

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