Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bluethooth test
/*
* Reference:
* http://stackoverflow.com/questions/3255406/trouble-connecting-android-bluetooth-client-socket-to-ubuntu-server-socket
* */
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sco.h>
#include <bluetooth/sdp_lib.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/l2cap.h>
/*
* C++ disallows taking addresses of temporaries. See
* http://stackoverflow.com/questions/9751710/c-c-warning-address-of-temporary-with-bdaddr-any-bluetooth-library
* */
bdaddr_t my_bdaddr_any = {0, 0, 0, 0, 0, 0};
bdaddr_t my_bdaddr_local = {0, 0, 0, 0xff, 0xff, 0xff};
sdp_session_t* register_service(uint8_t rfcomm_channel)
{
// Adapted from http://www.btessentials.com/examples/bluez/sdp-register.c
uint32_t svc_uuid_int[] = { 0x01110000, 0x00100000, 0x80000080, 0xFB349B5F };
const char *service_name = "Roto-Rooter Data Router";
const char *svc_dsc = "An experimental plumbing router";
const char *service_prov = "Roto-Rooter";
uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid, svc_class_uuid;
sdp_list_t *l2cap_list = 0,
*rfcomm_list = 0,
*root_list = 0,
*proto_list = 0,
*access_proto_list = 0,
*svc_class_list = 0,
*profile_list = 0;
sdp_data_t *channel = 0;
sdp_profile_desc_t profile;
sdp_record_t record = { 0 };
sdp_session_t *session = 0;
// set the general service ID
sdp_uuid128_create( &svc_uuid, &svc_uuid_int );
sdp_set_service_id( &record, svc_uuid );
char str[256] = "";
sdp_uuid2strn(&svc_uuid, str, 256);
printf("Registering UUID %s\n", str);
// set the service class
sdp_uuid16_create(&svc_class_uuid, SERIAL_PORT_SVCLASS_ID);
svc_class_list = sdp_list_append(0, &svc_class_uuid);
sdp_set_service_classes(&record, svc_class_list);
// set the Bluetooth profile information
sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
profile.version = 0x0100;
profile_list = sdp_list_append(0, &profile);
sdp_set_profile_descs(&record, profile_list);
// make the service record publicly browsable
sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
root_list = sdp_list_append(0, &root_uuid);
sdp_set_browse_groups( &record, root_list );
// set l2cap information
sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
l2cap_list = sdp_list_append( 0, &l2cap_uuid );
proto_list = sdp_list_append( 0, l2cap_list );
// register the RFCOMM channel for RFCOMM sockets
sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
rfcomm_list = sdp_list_append( 0, &rfcomm_uuid );
sdp_list_append( rfcomm_list, channel );
sdp_list_append( proto_list, rfcomm_list );
access_proto_list = sdp_list_append( 0, proto_list );
sdp_set_access_protos( &record, access_proto_list );
// set the name, provider, and description
sdp_set_info_attr(&record, service_name, service_prov, svc_dsc);
// connect to the local SDP server, register the service record,
// and disconnect
session = sdp_connect(&my_bdaddr_any, &my_bdaddr_local, SDP_RETRY_IF_BUSY);
sdp_record_register(session, &record, 0);
// cleanup
sdp_data_free( channel );
sdp_list_free( l2cap_list, 0 );
sdp_list_free( rfcomm_list, 0 );
sdp_list_free( root_list, 0 );
sdp_list_free( access_proto_list, 0 );
sdp_list_free( svc_class_list, 0 );
sdp_list_free( profile_list, 0 );
return session;
}
int main(int argc, char **argv)
{
int port = 3;
sdp_session_t* session = register_service(port);
struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read = -1;
socklen_t opt = sizeof(rem_addr);
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
printf("socket() returned %d\n", s);
// bind socket to port 1 of the first available
// local bluetooth adapter
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = my_bdaddr_any;
loc_addr.rc_channel = (uint8_t) port;
int r;
r = bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
printf("bind() on channel %d returned %d\n", port, r);
// put socket into listening mode
r = listen(s, 1);
printf("listen() returned %d\n", r);
//sdpRegisterL2cap(port);
// accept one connection
printf("calling accept()\n");
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
printf("accept() returned %d\n", client);
ba2str( &rem_addr.rc_bdaddr, buf );
fprintf(stderr, "accepted connection from %s\n", buf);
do {
// read data from the client
memset(buf, 0, sizeof(buf));
bytes_read = read(client, buf, sizeof(buf));
if( bytes_read > 0 ) {
printf("received [%s]\n", buf);
}
} while (bytes_read > 0);
// close connection
close(client);
close(s);
sdp_close( session );
return 0;
}
package org.twbbs.chyen.android.BluetoothTest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.UUID;
public class BluetoothTest extends Activity {
private TextView tMac;
private TextView tStatus;
private Button bSearch;
private Button bSend;
private ListView lResult;
private EditText eMessage;
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter myBluetoothAdapter;
private ArrayAdapter<String> BTArrayAdapter;
private ArrayList<Object> BTResultMac;
private CountDownTimer scanTimer;
private BluetoothSocket btSocket;
private OutputStream os;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tMac = (TextView) findViewById(R.id.Mac);
tStatus = (TextView) findViewById(R.id.Status);
bSearch = (Button) findViewById(R.id.Search);
bSend = (Button) findViewById(R.id.Send);
lResult = (ListView) findViewById(R.id.Result);
eMessage = (EditText) findViewById(R.id.Message);
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bSend.setEnabled(false);
if(myBluetoothAdapter == null) {
bSearch.setEnabled(false);
eMessage.setEnabled(false);
tStatus.setText("Status: not supported");
} else {
if(!myBluetoothAdapter.isEnabled())
startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), REQUEST_ENABLE_BT);
tStatus.setText("Status: BlueTooth Enabled");
BTArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
BTResultMac = new ArrayList<Object>();
lResult.setAdapter(BTArrayAdapter);
}
lResult.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
BluetoothDevice device = myBluetoothAdapter.getRemoteDevice((String) BTResultMac.get(pos));
if(myBluetoothAdapter.isDiscovering()){
myBluetoothAdapter.cancelDiscovery();
bSearch.setEnabled(true);
}
try {
btSocket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.d("Exception", "socket create failed: " + e.getMessage() + ".");
}
tStatus.setText("Status: Connecting...");
try {
btSocket.connect();
} catch (IOException e) {
e.printStackTrace(System.err);
Log.d("Exception", "Connection failure.");
tStatus.setText("Status: Connecting Failed");
return;
}
tStatus.setText("Status: Connecting finished");
tMac.setText("Mac: " + BTResultMac.get(pos));
bSend.setEnabled(true);
try {
os = btSocket.getOutputStream();
} catch (IOException e) {
Log.e("Exception", "Unable to get output stream of bluetooth socket");
e.printStackTrace(System.err);
}
}
});
}
public void SearchClick(View view){
BTArrayAdapter.clear();
BTResultMac.clear();
myBluetoothAdapter.startDiscovery();
registerReceiver(bReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
tStatus.setText("Status: Discovering...");
bSearch.setEnabled(false);
scanTimer = new CountDownTimer(15000,1000){
@Override
public void onTick(long millisUntilFinished) {}
@Override
public void onFinish(){
bSearch.setEnabled(true);
myBluetoothAdapter.cancelDiscovery();
tStatus.setText("Status: Search Finished");
bSearch.setEnabled(true);
}
};
scanTimer.start();
}
public void SendClick(View arg0) {
if (os != null) {
try {
String content = eMessage.getText().toString();
if(content.length() > 0) {
os.write(content.getBytes());
eMessage.setText("");
} else {
btSocket.close();
os = null;
bSend.setEnabled(false);
}
} catch (IOException e) {
Log.e("Exception", "Failed to write messages");
e.printStackTrace(System.err);
}
}
}
final BroadcastReceiver bReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
BTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
BTArrayAdapter.notifyDataSetChanged();
BTResultMac.add(device.getAddress());
}
}
};
}
g++ -g -Wall -Wextra bluetooth.cpp -lbluetooth
# or gcc -g -Wall -Wextra bluetooth.cpp -lbluetooth
@DavideBiasin

This comment has been minimized.

Copy link

@DavideBiasin DavideBiasin commented Apr 19, 2016

Hello! Great program! I tested it on my pc and my mobile phone and it work very well!!
But when I trying to install it on my raspberry pi, compiling without errors but when I run the program it tell me "segmentation fault". With debug I found that this problem is in the row : sdp_record_register(session, &record, 0); 93 number line of c++ program. Can You say me what can I do to work also in my raspberry pi?
Thank you very much!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.