Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Bluetooth SPP reader problem

Posted on 2006-04-22
15
Medium Priority
?
502 Views
Last Modified: 2012-05-05
Hi Folks,

having an infuriating problem trying to read bluetooth serial port data in a midp application.  seems like the serial port is unreliable at best (although I assume that it is something to do with how I am handling it), but the upshot is that at the moment, I can't get any reliable data out of it at all.

Here is a function I use to try to get the data:

    public final static String readData(StreamConnection conn)
    {
   
        InputStream input = null;
        byte[] data = null;
        String result = "OK";
   
        try
        {
            input = conn.openInputStream();
     
            // Probably want to throw an exception if length is not greater then 0
            int length = input.read();
            data= new byte[length];
            length = 0;

            // Assemble data
            while (length != data.length)
            {
                int ch = input.read(data, length, data.length - length);
                if (ch == -1)
                {
                    throw new IOException("Can't read data");
                }
                length += ch;
            }
        }
        catch (IOException e)
        {
            result = e.toString();
        }
        finally
        {
            // close input stream      
            if (input != null)
            {
                try
                {
                    input.close();
                }
                catch (IOException e)
                {
                    result = e.toString();
                }
            }
        }
        if( result == "OK" ) result = data.toString();
        return new String( result );
    }  

I call it like:

        try
        {
            StreamConnection con = (StreamConnection) Connector.open(printerUrl);
            String cardData = readData( con );
            con .close();
        }

Right now, the function ALWAYS returns "Can't read data"

Any guidance on how I can get this thing working will be most appreciated!

Any suggestions at all, also very welcome :)

Regards,  Mike.
0
Comment
Question by:meverest
  • 9
  • 6
15 Comments
 
LVL 30

Expert Comment

by:Mayank S
ID: 16514889
BTW:

>> if( result == "OK" )

Should be if ( result.equals ( "OK" ) )
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16514894
>> int length = input.read();

Check the value of length there:

if ( length < 0 )
  throw new IOException ( "Can't read data" ) ;
0
 
LVL 37

Author Comment

by:meverest
ID: 16514953
Hi mayankeagle,

(thanks for the fast reply!)

I put:

if ( length < 0 )
  throw new IOException ( "length < 0" ) ;

but that seems to be never true.  Odd thing now is that sometimes i still get "Can't read data" returned as before, but ometimes, too, I get some data returned (but it is string representation of the bytes read, and not the ascii text that I expect to find)

I must be missing something serious....

Cheers.
 
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 30

Expert Comment

by:Mayank S
ID: 16514964
>> but it is string representation of the bytes read

Try result = new String ( data ) ; instead of data.toString () ;
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16514969
>> return new String( result );

Not needed, make it return result ;
0
 
LVL 37

Author Comment

by:meverest
ID: 16515053
Thanks mayankeagle!

Seems like I'm making some progress, and adding a few debug lines, I seem to be getting some indication that there is some problem with this:

            StreamConnection con = (StreamConnection) Connector.open(printerUrl);

Seems like maybe it doesn't close down properly sometimes - if I repeat the read process over and over, sometimes I get to the readData routine, other times it throws an exception at connector.open...

Unless you have some tips for me, I'll play with it a bit more and see what comes out.

Cheers.
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16515080
Do you call this from multiple threads? If so, try to synchronize it, also close the connection in a finally block:

synchronized ( this )
{
  StreamConnection con = null ;
  try
  {
    con = ( StreamConnection ) Connector.open ( printerUrl ) ;
    String cardData = readData ( con ) ;
  }
  finally
  {
    if ( con != null )
          con .close () ; // end if
  }
}

I'm not a J2ME expert, so I can't give you more tips on this, but hope this would help. Otherwise wait for more experts to comment.
0
 
LVL 37

Author Comment

by:meverest
ID: 16515164
Thanks very much for your help so far, mayankeagle.

I am at least able to get data that I need out of the serial port, but it is still strangely unreliable.  Sometimes I get all the data, sometimes exceptions on connector.open(), sometimes I get that "Cant read data" exception - I made it into:

            while (length != data.length)
            {
                int ch = input.read(data, length, data.length - length);
                if (ch == -1)
                {
                    throw new IOException("Can't read data:" + length + "");
                }
                length += ch;
            }

and discover that length is invariably zero.

Haven't tried out that synchronisation concept yet.  It is not called from different places, but it is possible that the device has data stacked up in the output buffer before connecting - not sure what implication that might have though...

Regards,  Mike.
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16515208
>> Haven't tried out that synchronisation concept yet.

Maybe try it once.

>> sometimes I get that "Cant read data" exception

Why not ignore that exception and instead just break out of the loop, to see what data is read:

if ( ch == -1 )
  break ; // end if

Then check what is there in result.
0
 
LVL 37

Author Comment

by:meverest
ID: 16517043
I'm getting highly variable results.

Sometimes 'length' comes back as zero, and thus no data is read.

Is there some way I can format the inputstream to flush anything that is there or keep a hold of it until i get data through - at the same time I need to make sure that there is some time-out capability so that I don't end up in a deadlock...

Cheers.
0
 
LVL 30

Accepted Solution

by:
Mayank S earned 2000 total points
ID: 16518720
I prefer reading in a do-while loop, like:

do
  int i = is.read () ;
while ( is.available () > 0 ) ;
0
 
LVL 37

Author Comment

by:meverest
ID: 16518817
Hello mayankeagle,

I think that I have almost got it.

It turns out that the client platform is too quick for the server, and only ever gets the first part of the whole data on first try.

Therefore, I have to make several shots at it to be sure to get it all:

                try
                {
                    input = swiperConn.openInputStream();
                     ByteArrayOutputStream buff = new ByteArrayOutputStream( );

                    // Probably want to throw an exception if length is not greater then 0
                    buff.write( input.read() );

                    while ( true )
                    {
                        cycle++;
                        int count = input.available();
                        if( count < 0 ) break;

                        for ( int i = 0; i < count; i++ )
                            buff.write( input.read() );

                        swipeData = buff.toString().trim();
                        parseData( swipeData );
                        if( swipeData.length() == length ) break;
                        length = swipeData.length();
                        if( cycle > 6 ) break;
                    }
                }
 
still not quite done, but at least I am getting more reliable results now.

I'll leave this open for just a bit longer, then I'll close it off and award the points - thanks!

Mike.

0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16518840
Try it in a do-while loop. First read, then check available () and re-loop.
0
 
LVL 37

Author Comment

by:meverest
ID: 16518907
Thanks for hanging in there with me.

Much appreciated! :)

Not sure what the advantage of do while instead of while(true) - i did it that way so that I can break it with more than one condition.

cheers!
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 16518948
do while will read first and then check the condition - so you make sure you wait for input to come to the input-stream instead of directly looping out.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
Suggested Courses
Course of the Month10 days, 16 hours left to enroll

572 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question