Nokia 6600 BT Send needs delay

Login to reply to this topic.
Mon, 2004-11-29 11:53
Joined: 2004-06-13
Forum posts: 21
Hy everybody,

       I've implemented, based on the PointToPoint example in the Series 60 SDK, a simple Bluetooth chat. Everything works just fine. The problem is that in such an application two sends are relatively deffered from one another (at least 1 sec). When I tried to modify the application and do something basicly simple, like making 10 repeated sends, everything breaks down. Here is what I do:

CSender::StartSending()
   {
       iCount = 0;
       TPckg<TInt> countPckgDes(iCount);
       iClientSocket.Send(countPckgDes, 0, iStatus);
       SetActive();
   }

CSender::RunL()
   {
   if (iStatus == KErrDisconnected)
       {
       asyncBtCallBack.AppendToLogL(_L("Disconnected"));
       return;
       }
   else if (iStatus == KErrAbort)
       {
       asyncBtCallBack.AppendToLogL(_L("Aborted"));
       return;
       }
   else if (iStatus != KErrNone)
       {
       asyncBtCallBack.AppendToLogL(_L("Receiver Error"));
       return;
   }

   ++ iCount;
   if(iCount < 10)
       {
       TPckg<TInt> countPckgDes(iCount);
       iClientSocket.Send(countPckgDes, 0, iStatus);
       SetActive();
       }
   }

At the receiver end, I receive only the first 7 bytes and after that my phone server application, which is sending, gets killed.

My guess is that RunL() gets called, not when the data was actually sent through the bluetooth radio, but when the data is copied in some bluetooth sending buffer, so i'm sending data a lot faster than the BT hardware can send. I'm sure of this, because if I do a small delay in RunL() before the next send, everything works fine. What should I do to solve this? Smiley  I thought of 2 things, but I don't know exactly how to do it :

1) can I somehow get the sending status from the clientSocket. I tried to poll it with the following code, but it didn't work:

   TInt socketOptionInt;
   TPckg<TInt> socketOptionPckgInt(socketOptionInt);
   clientSocket.GetOpt(KSOSelectPoll, KSOLSocket, socketOptionPckgInt);
   if( ! (socketOptionInt & KSockSelectWrite) )
       {
       return;
       }

   Also iStatus is always KErrNone, so it doesn't help me.

2) I've seen in the API something about blocking sockets. I don't know exactly what they are, and I couldn't find in the SDK either, but could they mean that a send would return only after the data was actually sent? Also I don't know how this "blocking" sockets should behave with asynchronous ActiveObjects.

I've found on the forums two similar posts: one about generic TCP/IP sockets, in which repetead sends blocked, and one about RecvOneOrMore() on BT sockets in Nokia 6600 which, like in my case, needed some delay to complete.

Thanks a lot in advance

Thu, 2004-12-02 09:11
Joined: 2003-12-08
Forum posts: 14
Nokia 6600 BT Send needs delay
What you need to do is move
Code:
++ iCount;
if(iCount < 10)
{
TPckg<TInt> countPckgDes(iCount);
iClientSocket.Send(countPckgDes, 0, iStatus);
SetActive();
}

into the iStatus != KErrNone part of RunL.

That's the part that gets called when the previous data has been sent without problems (and that means you don't need to guess some random delay).
Thu, 2004-12-02 10:42
Joined: 2004-06-13
Forum posts: 21
Nokia 6600 BT Send needs delay
Yes, as you can see I always do this test (iStatus != KErrNone), but unfortunately it is allways false, so no error is reported this way. I need to get the status of the send operation in some other way, perhaps using HCI, or some GetOpt() that I haven't discovered yet. If anyone has any idea please reply. Thanks a lot.
Thu, 2004-12-02 13:52
Joined: 2003-12-08
Forum posts: 14
Nokia 6600 BT Send needs delay
Uh, right. Read that too early in the morning and misread it.

Tried just using the RSocket::Write method instead of send to see if that makes any difference?

Now that i read the whole thing i'm at a loss on what the problem is. Probably something really small and simple yet so typically annoying to find.

If i were you, i'd just move things around (like the TPckg to be a class member), try out the RSocket::Write style etc. Sorry i can't be of more use.
Thu, 2004-12-02 15:01
Joined: 2004-06-13
Forum posts: 21
Nokia 6600 BT Send needs delay
Indeed I can see why you recommend that the TPckg variable should be a member variable, so that it doesn't go out of scope while Send completes (in other words it shouldn't be a temporary object, but should provide a stable address). Anyway, i did this too, although the wrapped data, iCount, was already a class member. I have also tried with Write, but unfortunately none of this worked. Anyway thanks for your sugestions Vesa.
Fri, 2004-12-03 12:50
Joined: 2004-06-13
Forum posts: 21
Nokia 6600 BT Send needs delay
Well I have installed Series 60 SDK 2.1, and now it works. Very strange although, because now even if I rebuild the project with the old Series 60 v2.0 SDK, it still works; so my advice to you would be to upgrade Smiley
Wed, 2004-12-15 14:33
Joined: 2004-06-13
Forum posts: 21
Nokia 6600 BT Send needs delay
Well after some debugging I must confess that indeed one fault had the fact that the TPckg used for sending was an automatic variable, so making it a class member was the solution to my problem (I still had the problem on SDK v 2.1) so thanks a lot Vesa.
        But anyway, I remember that I have seen lots of examples (in books and also in documents from Nokia) where sending was done in this way: just before Send wrap the data into some automatic TPckg object and pass it to the asynchronous (Send() in this case) method.
        But if I am wrong, and this is a bad practice, please reply and let me know which is the "standard" way. Because I don't like that for every class member that I would pass to some async method I should also declare a corresponding TPkg member.
Thu, 2004-12-16 04:48
Joined: 2004-10-17
Forum posts: 85
Nokia 6600 BT Send needs delay
johnny,

I am not sure what btpoint2point example you looked at to create your application because the RunL() and SendMessageL() functions of that example are nothing like the ones you wrote in your original post.

The btpoint2point example uses RSocket::Write() to send the message. And I am not sure how you came up with TPckg since there is no such thing in the example... The example uses HBufC8* iMessage to construct the message...
Fri, 2004-12-17 10:16
Joined: 2004-06-13
Forum posts: 21
Nokia 6600 BT Send needs delay
e_dawg,

Very good !!! I bet you are also an expert on the helloworld example. Keep on the good job.
Sat, 2004-12-18 05:21
Joined: 2004-10-17
Forum posts: 85
Nokia 6600 BT Send needs delay
Quote from: johnny
Well after some debugging I must confess that indeed one fault had the fact that the TPckg used for sending was an automatic variable, so making it a class member was the solution to my problem

TPckg does not own the data it is passed. It points to it. Therefore the fact that your TPckg object is an automatic one is OK. Even if it goes out of scope at the end of the if block, iClientSocket.Send should still be pointing at iCount not at the TPckg object itself.  

The fact that making the TPckg object a class member solved your problem doesn't make any sense. It probably hid your problem somehow. Based on how TPckg works, you shouldn't have to make it a class member which is probably why you never see it used that way in books and documents.

Maybe you could try the () operator to return a reference to the object TPckg points to.

Quote from: johnny
But if I am wrong, and this is a bad practice, please reply and let me know which is the "standard" way. Because I don't like that for every class member that I would pass to some async method I should also declare a corresponding TPkg member.

Like I said, I can't see how it is a bad practice although I can see that you have issues with being snarky which will get you nowhere in life.

Good luck!
Sat, 2004-12-18 11:41
Anonymous (not verified)
Forum posts: 2043
Nokia 6600 BT Send needs delay
Quote
TPckg does not own the data it is passed. It points to it. Therefore the fact that your TPckg object is an automatic one is OK. Even if it goes out of scope at the end of the if block, iClientSocket.Send should still be pointing at iCount not at the TPckg object itself.

Wrong! Wrong!

1) TPckg creates a descriptor pointing to data.

2) Socket Send passes a pointer to descriptor to socket server.

The TPckg going out of scope is definitely a big problem!
Sat, 2004-12-18 16:37
Joined: 2004-10-17
Forum posts: 85
Nokia 6600 BT Send needs delay
Guest,

Information on TPckg, TPckgC and TPckgBuf is kinda limited. Therefore, my understanding of it might be wrong, but what you are saying surely doesn't make sense. All the server wants is the pointer to the object so it can read/write to that object. If what you are suggesting was true, there would be useless, meaningless objects pointing to objects that already exist such as

  iCount << TPckg << ServerSideobject

As you can see the TPckg indirection is redundant.

What TPckg does is create a type-safe pointer to the original object -iCount- and pass it to the server side. When you call Socket::Send, -not sure if this is true but- it probably creates its own pointer to point to iCount. In this case TPckg is just a messanger. It is not needed after Socket::Send is called. Even if TPckg object disappears after the Socket::Send call, that's OK since server already has the address of iCount at that point.

Then you might ask "Why do we use a middleman -TPckg- to pass a pointer to iCount?".. Well like I said, TPckg is type-safe, and that's just how Symbian wanted to do it.

What you are suggesting makes sense for a TPckgBuf object since TPckgBuf actually creates a copy of the original object. If TPckgBuf went out of scope, then that would be a problem.

I could be wrong, but this makes a lot more sense than what you are suggesting.
Mon, 2004-12-20 09:19
Anonymous (not verified)
Forum posts: 2043
Nokia 6600 BT Send needs delay
The RSocket Send/Recv pass the address of the descriptor (in addition to address of TRequestStatus and TSockXfrLength).

Thats the way it is, whether it makes sense or not.
Tue, 2004-12-21 10:37
Joined: 2004-09-10
Forum posts: 12
Nokia 6600 BT Send needs delay
Hi johnny!

I have the same freaking problem as you do: when sending data very fast over bluetooth RSocket does not call RunL or return from User::WaitForRequest(). First I used Write function, now I use Send with the last parameter showing exactly how much data was sent (it always equals to the buffer size I pass to this function  Shocked even if I pass 30000 bytes - which is not logical).

One solution I found out for nokia 6600 is deviding all of your data on 100 bytes buffers and send them one by one - socket never stuck, but the speed cannot exceed 10kB/s. And... It didn't work on 6630, 'cause the last is twice faster. But it worked if I devided initial data on 40 bytes buffers. But it is a bullshit to do things like that Angry !!!

So, right now I'm out of ideas! I come to your initial idea to put a sleep after sending some amount of data - but with this one still will come to 10kB/s speed (with the maximum of 60-100kB/s that I've reached on 6600). So, no difference if you devide packets manually or put a delay - both suck!

If anyone from Symbian or Nokia reads this, plzzzz, tell us all how we should work with RSocket and Bluetooth?Huh!!!!  Huh:  Huh:  Huh:

Thank you for your time
!

Vigen

Tue, 2004-12-21 12:30
Joined: 2004-06-13
Forum posts: 21
Nokia 6600 BT Send needs delay
Hy everybody,

       After some time I have discovered 3 main problems with Bluetooth on my Nokia 6600:
       1) Send() doesn't quite work with automatic TPckgs, although here I agree with e_dawg that it should work, but anyway one could always use member TPckgs and get around this.
       2) Asynchronous Send() is strange: if I pass packets bigger than 512 bytes, after some time Send() hangs, and RunL() doesn't get called. So perhaps there is a maximum limitation on the size of the packages that BT can handle (if anyone knows how to get this constant, pls reply Smiley ). For larger packages Send() hangs even quicker. However I can send 1MB of data with 256 bytes packages. But in this way my transfer rate is about 9KB/s (72 Kb/s), which is so far from the theoretical 1Mb/s. BTW VigenIssahhanjan, were you able to send with 60-100kB/s Huh If you did, please tell me how you did it, because I really need a bigger transfer rate, even if it means to use synchronous Sends(). I haven't tested synchronous Send(), to see if I can get better transfer rates, I was happy my async Send() worked !!!
      3) The last problem is very strange and has to deal more with AO I believe. Thus, in the following code:
Code:

++ iCount;
if(iCount < 10)
{
// iPckgdCount refers to iCount
iClientSocket.Send(iPckgdCount, 0, iStatus);
SetActive();
// ++ iCount;
}
if I move ++ iCount after SetActive(), so after the async service, I get the following output:
1
2
2
4
5
5
7
... etc
So it looks like a race condition between ++ iCount and RunL(). But as I understand AO and Symbian, I have "cooperative multitasking", so I can not get preempted not even by RunL(), am I right? Perhaps I'm not, especially since in every code examples the asynchronous method call followed by SetActive() are the last code in every method.
Tue, 2004-12-21 12:56
Joined: 2004-09-10
Forum posts: 12
Nokia 6600 BT Send needs delay
johnny, to achieve that speed I used this function:
Code:
void SendTo(const TDesC8& aDesc,TSockAddr& anAddr,TUint flags,TRequestStatus& aStatus,TSockXfrLength& aLen);
with SetActive(). Here you on RunL you get the length of the sent data (aLen must be some class member Wink ). And this length is usually the total Length() of aDesc. So, the protocol does not have any overhead of calling Send(..) several times - it just sends the whole aDesc at once. There comes the maximum speed allowed by the Bluetooth Protocol. But, as I wrote, I still had the same problem you have: after some kilobytes of data it all hanged and RunL wasnot called anymore. Sad

512 bytes were also too big for me (i don't know why Huh: )! The preffered size was 100 bytes for nokia 6600...
And one more thing: laptop client recieves the data by 666 (freaking number!!!!!) bytes everytime. So, I guess, the maximum you can send at once without stucking the bluetooth is 666 byte. So, your number - 512 - is in the allowed range. Cheezy But, it didn't work for me.

Vigen

  • Login to reply to this topic.