Dear Joshua,
inside the e-puck svn repository there are many examples of bluetooth usage in
C.
I join you some source code in attachment as well, that could inspire you.
btcom.c and .h are functions to be used with your e-puck c code, while
ircomTest.cpp works on a pc
with bluetooth and linux. If you want to check the context, these files are
originally distributed in libIrcom,
a software library available on the e-puck website.
Most importantly, do not forget to compile your code with libbluetooth. The
e-puck is a bluetooth
device just like a phone or a computer: any documentation related to
establishing a socket in a bluetooth
connection should be useful.
I hope this helps,
cheers,
alexandre campo.
PS : i put the gna mailing list in CC in case anybody wants to comment on this,
or in case it could
be useful to somebody else.
On Fri, 11 Dec 2009 07:51:14 +0800
"Joshua Wong" <[email protected]> wrote:
> Would like to check with you if you have any idea about epuck Bluetooth in C
> programming?
>
>
> Would hope if you can help me out.
>
> Thanks a lot!
>
> Joshua
>
/*
Copyright 2007 Olivier Dedriche, Mouhcine Zekkri, Alexandre Campo.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BTCOM_C
#define BTCOM_C
#include "btcom.h"
#include <e_uart_char.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Don't forget to initialize hardware before using it when debugging. Library to use on the e-puck
// maximum size of messages is set to 255 bytes
void btcomSendStringStatic (char* buffer)
{
e_send_uart1_char(buffer, sizeof(*buffer) - 1);
while(e_uart1_sending());
}
void btcomSendString (char* buffer)
{
e_send_uart1_char(buffer, strlen(buffer));
while(e_uart1_sending());
}
void btcomSendInt (long int x)
{
char msg[BTCOM_MAX_MESSAGE_LENGTH];
sprintf (msg, "%ld", x);
btcomSendString(msg);
}
void btcomSendFloat (double x)
{
char msg[BTCOM_MAX_MESSAGE_LENGTH];
sprintf (msg, "%lf", x);
btcomSendString(msg);
}
void btcomSendChar (char c)
{
e_send_uart1_char(&c, 1);
while(e_uart1_sending());
}
void btcomWaitForCommand (char trigger)
{
char msg;
do
{
e_getchar_uart1 (&msg);
}
while (msg != trigger);
// sleep a bit
long int count;
for(count = 0; count < 1000000; count++)
asm("nop");
}
// BTCOM_C
#endif
/*
Copyright 2007 Olivier Dedriche, Mouhcine Zekkri, Alexandre Campo.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BTCOM_H
#define BTCOM_H
#define BTCOM_MAX_MESSAGE_LENGTH 256
void btcomSendStringStatic (char* buffer);
void btcomSendString (char* buffer);
void btcomSendInt (long int x);
void btcomSendFloat (double x);
void btcomSendChar (char c);
void btcomWaitForCommand (char trigger);
// BTCOM_H
#endif
/*
Copyright 2007 Alexandre Campo, Alvaro Gutierrez, Valentin Longchamp.
This file is part of libIrcom.
libIrcom is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License.
libIrcom is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with libIrcom. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <regex.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
unsigned int crc16(char *data_p, unsigned int length);
void connect_to_epuck(int sock);
void get_bluetooth_devices(int sock);
int connect_to_epuck_MAC(char* MAC);
int write_to_epuck(int sock1, char* string, int size);
int read_from_epuck(int sock1, unsigned char* string, int size);
char* get_mac_from_number(char* number);
#define POLY 0x8408 /* 1021H bit reversed */
typedef struct devices {
int num;
char *name;
char *address;
struct devices *next;
}devices;
devices *list_dev;
unsigned int crc16(char *data_p, unsigned int length){
unsigned char i;
unsigned int data;
unsigned int crc = 0xffff;
if (length == 0)
return (~crc);
do
{
for (i=0, data=(unsigned int)0xff & *data_p++;
i < 8;
i++, data >>= 1)
{
if ((crc & 0x0001) ^ (data & 0x0001))
crc = (crc >> 1) ^ POLY;
else crc >>= 1;
}
} while (--length);
crc = ~crc;
data = crc;
crc = (crc << 8) | (data >> 8 & 0xff);
return (crc);
}
void connect_to_epuck(int sock){
struct sockaddr_rc loc_addr = { 0 };
int num;
sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
printf("Which one do you want to connect to ? ");
scanf("%d",&num);
while(list_dev->num != num){
if (list_dev->next != NULL) list_dev = list_dev->next;
}
str2ba(list_dev->address, &loc_addr.rc_bdaddr );
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_channel = (uint8_t) 1;
printf("Connect to the e-puck %i\n", num);
connect(sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
}
void get_bluetooth_devices(int sock){
printf("Searching for BT devices ... \n");
devices* current_dev;
inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, len, flags;
int i,j;
char addr[19] = { 0 };
char name[248] = { 0 };
regex_t preg;
const char *str_regex = "e-puck_[0-9]{4}";
dev_id = hci_get_route(NULL);
sock = hci_open_dev( dev_id );
if (dev_id < 0 || sock < 0) {
perror("opening socket");
exit(1);
}
len = 8;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
if( num_rsp < 0 ) perror("hci_inquiry");
for (i = 0, j = 0; i < num_rsp; i++) {
ba2str(&(ii+i)->bdaddr, addr);
memset(name, 0, sizeof(name));
if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name), name, 0) < 0)
strcpy(name, "[unknown]");
const char *str_request = name;
regcomp (&preg, str_regex, REG_NOSUB | REG_EXTENDED);
if(regexec (&preg, str_request, 0, NULL, 0) == 0 ){
if (j == 0){
list_dev = (devices*)malloc(sizeof(devices));
list_dev->name = (char*) malloc(20*sizeof(char));
list_dev->address = (char*) malloc(20*sizeof(char));
list_dev->num = j;
strcpy(list_dev->name, name);
strcpy(list_dev->address, addr);
list_dev->next = NULL;
current_dev=list_dev;
}else{
current_dev->next = (devices*)malloc(sizeof(devices));
current_dev->next->name = (char*) malloc(20*sizeof(char));
current_dev->next->address = (char*) malloc(20*sizeof(char));
current_dev = current_dev->next;
current_dev->num = j;
strcpy(current_dev->name, name);
strcpy(current_dev->address, addr);
current_dev->next=NULL;
}
printf("%i %s %s\n", current_dev->num, current_dev->address, current_dev->name);
j++;
}
}
free(ii);
close(sock);
}
int connect_to_epuck_MAC(char* MAC){
struct sockaddr_rc loc_addr = { 0 };
int sock1 = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
str2ba(MAC, &loc_addr.rc_bdaddr);
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_channel = (uint8_t) 1;
printf("Connect to the e-puck %s with socket %d\n", MAC, sock1);
if(connect(sock1, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) == -1)
return -1;
else
return sock1;
}
int write_to_epuck(int sock1, char* string, int size){
int bytes_written=0;
bytes_written = write(sock1, string, size);
return bytes_written;
}
int read_from_epuck(int sock1, unsigned char* string, int size){
int bytes_read=0;
bytes_read = read(sock1, string, size);
return bytes_read;
}
char* get_mac_from_number(char* number){
FILE* rfcomm;
int size = 1024;
char *text = (char *)malloc(size);
char temp[100] = { 0 };
int err=0, match=0;
regex_t preg;
strcpy(temp,"rfcomm");
strcat(temp, number);
strcat(temp,"\\{device (([0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}));\\}");
const char *str_regex = temp;
rfcomm = fopen("/etc/bluetooth/rfcomm.conf","r");
fread(text, 1, size, rfcomm);
const char *str_request = text;
err = regcomp (&preg, str_regex, REG_EXTENDED);
if (err == 0)
{
size_t nmatch = 1;
regmatch_t *pmatch = NULL;
nmatch = preg.re_nsub;
pmatch = (regmatch_t*) malloc (sizeof (*pmatch) * nmatch);
if (pmatch)
{
match = regexec (&preg, str_request, nmatch, pmatch, 0);
regfree (&preg);
if (match == 0)
{
char *macAddress = NULL;
int start = pmatch[1].rm_so;
int end = pmatch[1].rm_eo;
size_t size = end - start;
macAddress = (char*) malloc (sizeof (*macAddress) * (size + 1));
if (macAddress)
{
strncpy (macAddress, &str_request[start], size);
macAddress[size] = '\0';
}
return macAddress;
}else{
printf("Error : device not found in rfcomm.conf\nType ./debug_interface to get help\n");
return "1";
}
}
}
return "1";
}
int main(int argc, char **argv)
{
unsigned char buf[6000] = { 0 };
int socket[12][2] = {{0}};
char *macAddress;
char number[12][5] = {{0}};
char tmp[1] = {0};
int i;
if(argc >= 2) {
for(i=0 ; i<argc-1; ++i)
strcpy(number[i], argv[i+1]);
}else{
printf("Specify the number of the epuck\n");
exit(EXIT_FAILURE);
}
// create the sockets for every specified e-puck
for(i=0 ; i<argc-1; ++i)
{
macAddress = get_mac_from_number(number[i]);
if (macAddress == "1") exit(EXIT_FAILURE);
socket[i][0] = atoi(number[i]);
socket[i][1] = connect_to_epuck_MAC(macAddress);
if (socket[i][1] == -1)
{
printf("Error while creating the socket for e-puck %d\n",socket[i][0]);
exit(EXIT_FAILURE);
}
}
printf("Press enter to start\n");
scanf("%c",&tmp[0]);
for (i = 0; i < argc - 1; i++)
{
// send start command to e-puck
write_to_epuck(socket[i][1], "s", 1);
}
// read message from e-puck, if any
while(1)
{
for (i = 0; i < argc - 1; i++)
{
int n = read_from_epuck(socket[i][1], buf, sizeof(buf));
buf[n] = '\0';
if (n > 0)
std::cout << buf;
}
usleep(2500);
}
for (i = 0; i < argc - 1; i++)
{
close(socket[i][1]);
}
return 0;
}
_______________________________________________
E-puck-user mailing list
[email protected]
https://mail.gna.org/listinfo/e-puck-user