| Reply | « Previous Thread | Next Thread » |
|
Based on btpointtopoint example
I try to do a sequence with bt device. 1st connect 2nd sendcommand Both phases work great when calling them separately from GUI menu, but latter doesn't go through if I try doing them in one automatic sequence. What seems to be the problem? |
|
Can we see ur sample code?
|
|
Here is RunL(), ConnectL(), ConnectToServerL() and Quit() functions.
Calling ConnectL and Quit in a sequence doesn't work when started from single menu object, but works if both are called from different menu object. What connectL does is same than in btpointtopoint example. void CMessageClient::RunL() { if (iStatus != KErrNone) { switch (iState) { case EGettingDevice: if (iStatus = KErrCancel) { User::Leave(iStatus.Int()); } break; case EGettingService: case EGettingConnection: case EDisconnecting: iState = EWaitingToGetDevice; iSendingSocket.Close(); iSocketServer.Close(); User::Leave(iStatus.Int()); break; case EWaitingToSend: User::Leave(iStatus.Int()); break; default: Panic(EBTPointToPointInvalidLogicState); break; } } else { switch (iState) { case EGettingDevice: // found a device now search for a suitable service iState = EGettingService; iStatus = KRequestPending; // this means that the RunL can not be called until // this program does something to iStatus iServiceSearcher->FindServiceL(iStatus); SetActive(); break; case EGettingService: iState = EGettingConnection; ConnectToServerL(); break; case EGettingConnection: iState = EWaitingToSend; break; case EWaitingToSend: break; case EDisconnecting: iState = EWaitingToGetDevice; iSendingSocket.Close(); iSocketServer.Close(); break; default: Panic(EBTPointToPointInvalidLogicState); break; }; } } void CMessageClient::ConnectL() { if (iState == EWaitingToGetDevice && !IsActive()) { iState = EGettingDevice; iServiceSearcher->SelectDeviceByDiscoveryL(iStatus); SetActive(); } else { User::Leave(KErrInUse); } } void CMessageClient::ConnectToServerL() { User::LeaveIfError(iSocketServer.Connect()); User::LeaveIfError(iSendingSocket.Open(iSocketServer, _L("RFCOMM"))); TBTSockAddr address; address.SetBTAddr(iServiceSearcher->BTDevAddr()); address.SetPort(iServiceSearcher->Port()); iSendingSocket.Connect(address, iStatus); User::WaitForRequest(iStatus); SetActive(); } //This is supposed to send guit command to other device void CMessageClient::QuitL() { _LIT8(KCommand, "1800000006quit\r\n"); delete iMessage; iMessage = NULL; iMessage = KCommand().Alloc(); if (iState != EWaitingToSend) { User::Leave(KErrDisconnected); } else if (IsActive()) { User::Leave(KErrInUse); } iState = EDisconnecting; iSendingSocket.Write(*iMessage, iStatus); User::WaitForRequest(iStatus); SetActive(); } |
|
Did you do ur code like this?:
MenuHandler() { ConnectL(); QuitL(); } if this what u did,. its not possible.. because the ConnectL() function is asynchronous.. When the compiler executes the COnnectL() function, it returns quickly and executes the next line, in this case QuitL().. But while the ConnectL function returns, it is still processing the RunL() function in a separate thread. so its lyk u executed the ConnectL() and QuitL() function simultaneeously which is wrong.. so if it is still processing the RunL() function and then you called QuitL(), it will be trapped by the compiler... My explanation is blurry, but anyway, if you want the QuitL() function to be called as soon as the ConnectL(), put the line QuitL(); in the RunL()... RunL() { ... ... ... iState = EGettingConnection; ConnectToServerL(); break; case EGettingConnection: iState = EWaitingToSend; QuitL(); break; case EWaitingToSend: break; ... ... ... }
Last edited by ayulo : 2004-06-29 at 12:18.
|
|
Yes thanks. I think I have to do own state for every command I want to send.
Little more thinking to do. PinkLemon |
|
Yes,
You have to have a state that is readable and logical. But basically thats just it. You must call the commands after the RunL() function completes. |
| Reply | « Previous Thread | Next Thread » |
| Thread Tools | Search this Thread |
|---|---|