Community
cancel
Showing results for 
Search instead for 
Did you mean: 
akham2
Novice
1,014 Views

is there any way to register a service through the terminal? (Bluetooth)

Hi,

I'm wondering if I can register a bluetooth service (with spicific port number and UUID) manually using the terminal?. I saw in the bluetooth manual of Intel Edison that I can perform this using a test written in Python. I tried to use sdp_record_register through my sketch code and it didn't work for me. My idea is to register the service manually and then use the same port number to listen for the incoming data. Any suggestions please?

Best regards,

Abdulrahman Khamis

example for listening on an RFCOMM port:

# include

# include

# include

# include

# include

int main(int argc, char **argv)

{

struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };

char buf[1024] = { 0 };

int s, client, bytes_read;

socklen_t opt = sizeof(rem_addr);

// allocate socket

s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

// bind socket to port 1 of the first available

// local bluetooth adapter

loc_addr.rc_family = AF_BLUETOOTH;

loc_addr.rc_bdaddr = *BDADDR_ANY;

loc_addr.rc_channel = (uint8_t) 11; // I will use the same number to register the service

bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));

// put socket into listening mode

listen(s, 1);

// accept one connection

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

ba2str( &rem_addr.rc_bdaddr, buf );

fprintf(stderr, "accepted connection from %s\n", buf);

memset(buf, 0, sizeof(buf));

// read data from the client

bytes_read = read(client, buf, sizeof(buf));

if( bytes_read > 0 ) {

printf("received [%s]\n", buf);

}

// close connection

close(client);

close(s);

}

Tags (1)
5 Replies
Pedro_M_Intel
Employee
97 Views

Hello Eng_akhamis,

What exactly do you want to achieve, I mean, you want to register a device manually and then you want to use an OBEX based profile to receive files, is that it? Or do you want to receive data as if it was a serial port as a continuous stream?

I mean, you can in fact pair, connect, and set the board to do both things from terminal but I'm not sure what's your final goal and maybe I'd give a more complex answer than I should if I don't know enough of your problem. So in simple terms, what is the objective of your project?

Peter.

akham2
Novice
97 Views

Mr. Intel_Peter,

Thanks for all your responses. Let explain my goal first :

I have an android device and Intel Edison with Arduino breakboard. I built an android app to connect to a bluetooth device and send text messages ( String data type ). My goal is to make Edison accept the connection request and receive the data using a code similar to this:

int main(int argc, char **argv)

{

struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };

char buf[1024] = { 0 };

int s, client, bytes_read;

socklen_t opt = sizeof(rem_addr);

// allocate socket

s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

// bind socket to port 1 of the first available

// local bluetooth adapter

loc_addr.rc_family = AF_BLUETOOTH;

loc_addr.rc_bdaddr = *BDADDR_ANY;

loc_addr.rc_channel = (uint8_t) 12;

bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));

// put socket into listening mode

listen(s, 1);

// accept one connection

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

ba2str( &rem_addr.rc_bdaddr, buf );

fprintf(stderr, "accepted connection from %s\n", buf);

memset(buf, 0, sizeof(buf));

// read data from the client

bytes_read = read(client, buf, sizeof(buf));

if( bytes_read > 0 ) {

printf("received [%s]\n", buf);

}

// close connection

close(client);

close(s);

return 0;

}

form https://people.csail.mit.edu/albert/bluez-intro/x502.html RFCOMM sockets

The problem is, Android doesn't make bluetooth connections using a port number. It searches for a specific UUID that specify the service. Since the above code doesn't specify and register the service with an UUID linked to port number 12 ( loc_addr.rc_channel = (uint8_t) 12; ), I have to add some code to advertise the service. So I added this:

void register_service(){

//Serial.println("hi ");

uint32_t service_uuid_int[] = { 0, 0, 0, 0x77FE183EA9D911E5ACA9C2AE1D5D46B0};

uint8_t rfcomm_channel = 11;

const char *service_name = "Edison";

const char *service_dsc = "An experiment about bluetooth";

const char *service_prov = "Abdul";

uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid;

sdp_list_t *l2cap_list = 0,

*rfcomm_list = 0,

*root_list = 0,

*proto_list = 0,

*access_proto_list = 0;

sdp_data_t *channel = 0, *psm = 0;

sdp_record_t *record = sdp_record_alloc();

// set the general service ID

sdp_uuid128_create( &svc_uuid, &service_uuid_int );

sdp_set_service_id( record, svc_uuid );

// 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 );

// set rfcomm information

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 );

// attach protocol information to service record

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, service_dsc);

int err = 0;

sdp_session_t *session = 0;

// connect to the local SDP server, register the service record, and

// disconnect

session = sdp_connect( ptrAny, ptrLoc, SDP_RETRY_IF_BUSY );

err = sdp_record_register(session, record, 0);

lcd.clear();

lcd.print("Stop here");

// 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 );

}

This function should do the work but unfortunately it doesn't. If you can notice I use an lcd to debug the sketch. When the sketch comes to err = sdp_record_register(session, record, 0); it doesn't proceed and untill now I don't know why. So I was looking for and trying many solutions and through my searching I found a reasonable solution but there are some parts of it that are unclear for me. I was reading the bluetooth guide http://download.intel.com/support/edison/sb/edisonbluetooth_331704004.pdf http://download.intel.com/support/edison/sb/edisonbluetooth_331704004.pdf on page 30 this:

"BlueZ provides a set a Python scripts (in the test folder) that interact with the bluetoothd daemon using the exposed D-Bus API, so it is possible to use these scripts, and get the same results as when using bluetoothctl."

.

and on page 48 CH 6.7 Serial Port Profile (SPP) : They used a Python script (SPP-loopback.py) to make a virtual serial port for communication. The script ( as I can understand after reading the script) can advertise the service with an UUID and specific port number.

This makes me ask a few questions and I really appreciate your help:

1 - Are the scripts written in Python just tests or I can use them as a major part of my projects?

2 - Can I make...

Pedro_M_Intel
Employee
97 Views

Sorry for the delay in my response.

1. You could use the Python scripts as a main part of your project but they would require a big amount of modification in order to set them to work appropriately. So, that's an option, another option is to set it manually and implement it on your code. You can see in how to manually set an SPP connection, why don't you give it a look, it might be of your interest.

2. Yes, that's called system service. I did a brief explanation in how to create one in , check it out, the example is in C but the main idea can be translated to any programming language.

3. This one is a bit more difficult to answer. Please correct me if I'm wrong, what you mean is that you are establishing the connection to certain port, then you leave it running on the background and then you want to listen to the same port? If so, then yes, you are correct, you can make the code listen to the same port; I mean when you create an SPP connection, it is basically a "serial port" so you can send and receive data from it. In fact in the last line is to read what you are currently receiving.

4. .

Peter.

P.S.: I modified your post to make the code look a little bit more easy to read.

akham2
Novice
97 Views

Thank you so much Mr. Peter I really appreciate your help. That was really helpful for me. Finally, the pure arduino sketch ( without Python ) worked after a little modification. The problem was not in the code. I just needed to modify bluetooth.service file ( I added -C after bluetoothd) and boom it worked.

Best regrads,

Abdulrahman Khamis

Pedro_M_Intel
Employee
97 Views

I'm glad to hear that your project is now working, I hope I was of help. If you ever have any other issues or doubts, don't hesitate to come back to the community, we'll do our best to help you!

Peter.

Reply