Dear @rudhi.tx
yes, is possible.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
#include <signal.h>
#include <getopt.h>
#include <string.h>
#define LE_SCAN_PASSIVE 0x00
#define LE_SCAN_ACTIVE 0x01
/* These LE scan and inquiry parameters were chosen according to LE General
* Discovery Procedure specification.
*/
#define DISCOV_LE_SCAN_WIN 0x12
#define DISCOV_LE_SCAN_INT 0x12
#define BLE_SCAN_TIMEOUT 4
union U64to8
{
/* data */
uint64_t u64data;
char sdata[8];
uint8_t u8data[8];
};
union U32to8
{
/* data */
uint32_t u32data;
char sdata[4];
uint8_t u8data[4];
};
union U16to8
{
/* data */
uint16_t u16data;
char sdata[2];
uint8_t u8data[2];
};
typedef void (*ble_discovered_device_t)(const char* addr, const char* name);
// We use a mutex to make the BLE connections synchronous
// static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static int ble_scan_enable(int device_desc);
static int ble_scan_disable(int device_desc);
int address2string(const bdaddr_t *ba, char *str);
int main(int argc, char const *argv[])
{
inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, device_desc, len, flags;
int i;
char addr[19] = { 0 };
char addr_old[19] = { 0 };
char addr_res[19] = "B8:F0:09:8F:7F:B6";
char addr_conn[19];
char name[248] = { 0 };
int r, teste, ret, opt;
struct hci_filter new_filter;
socklen_t filter_size;
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
u_int8_t len_data, flagIDGateway, rssi;
union U64to8 xNameDevice;
union U32to8 xAlarm, xNCycle, xTS;
union U16to8 xNItem;
bdaddr_t bdaddr_teste;
/** Route adapter */
dev_id = hci_get_route(NULL);
//dev_id = hci_devid(addr);
printf("%d!\n", dev_id);
if (dev_id < 0)
{
perror("Error: No Bluetooth adapter found.");
exit(1);
}
/** Abertura de socket */
device_desc = hci_open_dev( dev_id );
printf("%d\n", device_desc);
if (dev_id < 0 || device_desc < 0) {
perror("opening socket");
exit(1);
}
/** Habilita Scan BLE */
ret = ble_scan_enable(device_desc);
if (ret != 0) {
fprintf(stderr, "ERROR: Scanning fail.\n");
return 1;
}
printf("Filtros ativos \n");
// new filter to only look for event packets
hci_filter_clear(&new_filter);
hci_filter_set_ptype(HCI_EVENT_PKT, &new_filter);
hci_filter_set_event(EVT_LE_META_EVENT, &new_filter);
if (setsockopt(device_desc, SOL_HCI, HCI_FILTER, &new_filter, sizeof(new_filter)) < 0) {
perror("Error setsockopt");
exit(1);
}
/** Scan BLE */
for (size_t i = 0; i < 1; i++){ // Loop
le_advertising_info *info;
evt_le_connection_complete *conn;
le_create_connection_cp *conn_cp;
evt_le_meta_event *meta;
while ((len = read(device_desc, buf, sizeof(buf))) < 0) {
printf("While: \n");
}
ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
len -= (1 + HCI_EVENT_HDR_SIZE);
meta = (void *) ptr;
info = (le_advertising_info *) (meta->data + 1);
memset(addr, 0, sizeof(addr));
address2string(&info->bdaddr, addr);
int xTesteString = (strncmp(addr, addr_res, 17)); // Compara com o MAC buscado
if(xTesteString == 0){
/** Printa o advertising*/
printf("Advertising:");
for (int k = 0; k < info->length; k++) {
printf("%x", info->data[k]);
}
//ret = ble_scan_disable(device_desc);
// if (ret < 0) {
// printf("ble_scan_disable = %d \n", ret);
// perror("Could not create connection");
// exit(1);
// }
printf("Connection ..\n");
/** Tenta conexão BLE com device */
uint16_t le_config_interval = htobs(0x08);
uint16_t le_config_window = htobs(0x08);
uint16_t le_config_initialization_filter = htobs(0x08);
uint8_t le_config_peer_bdaddr_type = LE_PUBLIC_ADDRESS;
bdaddr_t le_config_bdaddr = info->bdaddr;
uint8_t le_config_own_bdaddr_type = LE_PUBLIC_ADDRESS;
uint16_t le_config_min_interval = htobs(0x0006);
uint16_t le_config_max_interval = htobs(0x0010);
uint16_t le_config_latency = htobs(0x0000);
uint16_t le_config_supervision_timeout = htobs(0x0FA0);
uint16_t le_config_min_ce_length = htobs(0x0000);
uint16_t le_config_max_ce_length = htobs(0x0000);
uint16_t le_config_handle = 0;
int le_config_to = 250000;
ret = hci_le_create_conn(device_desc,le_config_interval,le_config_window,le_config_initialization_filter
,le_config_peer_bdaddr_type,le_config_bdaddr,le_config_own_bdaddr_type,le_config_min_interval,
le_config_max_interval,le_config_latency,le_config_supervision_timeout,le_config_min_ce_length,
le_config_max_ce_length,&le_config_handle,250000);
//ret = hci_create_connection(device_desc, &info->bdaddr, LE_PUBLIC_ADDRESS, 0, 0x01, &handle, 250000000);
if (ret < 0) {
ble_scan_disable(device_desc);
printf("ret = %d \n", ret);
perror("Could not create connection");
exit(1);
}
printf("Connection handle %d\n", le_config_handle);
}else{
printf("Other\n");
i--; // Se for diferente não sai do Loop
}
}
/** Scan Off */
ble_scan_disable(device_desc);
printf("\n Scan completed \n");
return 0;
}
static int ble_scan_enable(int device_desc) {
uint16_t interval = htobs(DISCOV_LE_SCAN_INT);
uint16_t window = htobs(DISCOV_LE_SCAN_WIN);
uint8_t own_address_type = 0x00;
uint8_t filter_policy = 0x00;
int ret = hci_le_set_scan_parameters(device_desc, LE_SCAN_ACTIVE, interval, window, own_address_type, filter_policy, 10000);
if (ret < 0) {
fprintf(stderr, "ERROR: Set scan parameters failed (are you root?).\n");
return 1;
}
ret = hci_le_set_scan_enable(device_desc, 0x01, 1, 10000);
if (ret < 0) {
fprintf(stderr, "ERROR: Enable scan failed.\n");
return 1;
}
return 0;
}
static int ble_scan_disable(int device_desc) {
if (device_desc == -1) {
fprintf(stderr, "ERROR: Could not disable scan, not enabled yet.\n");
return 1;
}
int result = hci_le_set_scan_enable(device_desc, 0x00, 1, 10000);
if (result < 0) {
fprintf(stderr, "ERROR: Disable scan failed.\n");
}
return result;
}
int address2string(const bdaddr_t *ba, char *str)
{
return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]);
}
Thank you very much!