1. Download our Official Android App: Forums for Android!

Apps Bluetooth: Linux( in C ) with Android connection

Discussion in 'Android Development' started by CIocan Cosmin, Jul 26, 2016.

  1. CIocan Cosmin

    CIocan Cosmin Lurker
    Thread Starter
    Rank:
    None
    Points:
    5
    Posts:
    1
    Joined:
    Jul 26, 2016

    Jul 26, 2016
    1
    0
    5
    I am trying to connect my raspberry pi, which runs some form of debian jessie, to my android phone. I implemented the server side on the raspberry and the client side on the android phone. I already tested my android code with another app that had implemented the server side and I was able to send a couple of bytes from phone to phone. The problem is that after trying to implement the server side on the raspberry pi, it just isn't able to connect.

    Server code on the raspberry pi:

    #include <fstream>
    #include "/usr/include/stdint.h"
    #include "/usr/include/bluez-5.31/lib/bluetooth.h"
    #include "/usr/include/bluez-5.31/lib/hci.h"
    #include "/usr/include/bluez-5.31/lib/hci_lib.h"
    #include "/usr/include/bluez-5.31/lib/rfcomm.h"

    std::eek:fstream fout("output.txt");

    int main(int argc, char **argv)
    {
    fout << "marker 0" << std::endl;

    struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
    char source[18] = "50:F0:D3:40:42:55";
    bdaddr_t tmp1 = {};
    str2ba( source, &tmp1 );
    rem_addr.rc_family = AF_BLUETOOTH;
    rem_addr.rc_bdaddr = tmp1;
    rem_addr.rc_channel = 1;

    char buf[1024] = { 0 };
    int s, client, bytes_read;
    unsigned int opt = sizeof(rem_addr);

    //allocate socket
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
    if( s == -1 ) fout << "socket error" << std::endl;

    //bind socket to port 1 of the first available adapter

    bdaddr_t tmp2 = {0,0,0,0,0,0};

    loc_addr.rc_family = AF_BLUETOOTH;
    loc_addr.rc_bdaddr = tmp2;
    loc_addr.rc_channel = 1;

    int error_check = bind(s, (struct sockaddr* )&loc_addr, sizeof(loc_addr));
    if( error_check == -1 ) fout << "binding error" << std::endl;

    //put socket into listening mode

    error_check = 0;
    error_check = listen(s, 1);
    if( error_check == -1 ) fout << "listening error" << std::endl;

    //accept one connection
    client = accept(s, (struct sockaddr *)&rem_addr, &opt);


    ba2str( &rem_addr.rc_bdaddr, buf );
    fprintf( stderr, "accepter connection from %s\n", buf);
    memset( buf, 0, sizeof(buf));

    //read data from the client
    bytes_read = recv(client, buf, sizeof(buf), 0);
    if( bytes_read > 0 )
    {
    fout << buf[0];
    }

    //close connection
    //close(client);
    //close(s);
    return 0;
    }

    I tried to figure out what was going on when i ran the program and i saw that socket(), bind() and listen() were not returning with an error. I also saw that the program was paused when accept() was called. From what i can tell this means that the program is waiting for an incoming connection request which is the normal behaviour. But still, the program doesn't go any farther than the line with accept() when I try to connect my phone.

    Client code on the android phone:

    public class MainActivity extends AppCompatActivity {

    @override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (!mBluetoothAdapter.isEnabled()) {
    System.exit(1);
    }

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    Object[] pairedDev = pairedDevices.toArray();
    ArrayAdapter<String> mArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 0);
    /*if (pairedDevices.size() > 0) {
    for (BluetoothDevice device : pairedDevices) {
    mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    }
    }
    ListView listView = (ListView) findViewById(R.id.PairedDevicesListView);
    listView.setAdapter(mArrayAdapter);*/
    ConnectThread connectThread = new ConnectThread((BluetoothDevice) pairedDev[0]);
    connectThread.run();
    connectThread.cancel();
    }

    public void buttonOnClick(View v)
    {
    Button button = (Button) v;

    }

    @override
    protected void onResume() {
    super.onResume();
    }

    @override
    protected void onStart() {
    super.onStart();
    }

    @override
    protected void onPause() {
    super.onPause();
    }

    @override
    protected void onStop() {
    super.onStop();
    }

    @override
    protected void onDestroy() {
    super.onDestroy();
    }

    @override
    protected void onRestart() {
    super.onRestart();
    }


    private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) {
    BluetoothSocket tmp = null;
    mmDevice = device;

    try {
    tmp = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    } catch (IOException e) { }
    mmSocket = tmp;
    }

    public void run() {
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    mBluetoothAdapter.cancelDiscovery();

    try {
    mmSocket.connect();
    } catch (IOException connectException) {
    try {
    mmSocket.close();
    System.exit(1);
    } catch (IOException closeException) { //System.exit(1);
    }
    return;
    }

    // Do work to manage the connection (in a separate thread)
    // manageConnectedSocket(mmSocket);
    byte[] bytes = new byte[1];
    bytes[0] = 6;
    ConnectedThread connectedThread = new ConnectedThread(mmSocket);
    connectedThread.write(bytes);
    }

    /** Will cancel an in-progress connection, and close the socket */
    public void cancel() {
    try {
    mmSocket.close();
    } catch (IOException e) { }
    }
    }

    private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
    mmSocket = socket;
    InputStream tmpIn = null;
    OutputStream tmpOut = null;

    // Get the input and output streams, using temp objects because
    // member streams are final
    try {
    tmpIn = socket.getInputStream();
    tmpOut = socket.getOutputStream();
    } catch (IOException e) { }

    mmInStream = tmpIn;
    mmOutStream = tmpOut;
    }

    public void run() {
    byte[] buffer = new byte[1024]; // buffer store for the stream
    int bytes; // bytes returned from read()

    // Keep listening to the InputStream until an exception occurs
    while (true) {
    try {
    // Read from the InputStream
    bytes = mmInStream.read(buffer);
    // Send the obtained bytes to the UI activity
    // mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
    } catch (IOException e) {
    break;
    }
    }
    }

    /* Call this from the main activity to send data to the remote device */
    public void write(byte[] bytes) {
    try {
    mmOutStream.write(bytes);
    } catch (IOException e) { }
    }

    /* Call this from the main activity to shutdown the connection */
    public void cancel() {
    try {
    mmSocket.close();
    } catch (IOException e) { }
    }
    }
    }
    When I connected the two phones I was using a random UUID but since there was no option to enter a UUID in the c code of the raspberry I presumed it was the standard UUID that most devices have: "00001101-0000-1000-8000-00805F9B34FB"; or at least that's what I understood. You can assume that pairedDev[0] is the right one(the raspberry) since I already tested this out.
     

    Advertisement

  2. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,307
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,307
    10,420
    1,988
    Male
    Software developer
    South West of England
    You need to run your server in a debugging tool of some kind, allowing you to set breakpoints, step through the code etc.

    If memory serves, there are tools available, like GDB and DDD. I used the latter in a previous programming life, and I recall it was very good.

    Coding an empty catch block like this is not good, as you're throwing away any exception. You must either log, handle, or re-throw a caught exception.

    Code (Text):
    1.  
    2. try {
    3. tmp = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    4. } catch (IOException e) { }
    5.  
     

Share This Page

Loading...