-
-
Save DavideBiasin/222488b3b77e2e4739d103af37eb98a7 to your computer and use it in GitHub Desktop.
Bluethooth test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | |
} | |
} | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
g++ -g -Wall -Wextra bluetooth.cpp -lbluetooth | |
# or gcc -g -Wall -Wextra bluetooth.cpp -lbluetooth |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment