2013-12-19 2 views
24

목표Bluez : 서비스/gatt 서버 예를 광고 하시겠습니까?

저는 리눅스를 실행하는 간단한 장치를 개발 중입니다. 그것은 가능한 BLE이며, 현재 bluez 5.8을 사용하고 있습니다.

iPhone을 사용하여이 장치에서 작업을 실행하고 싶습니다. 이미 작동 무엇

는 :

  • 나는 아이폰 장치 "를 참조하십시오"할 수 있습니다.
  • iPhone도 장치에 연결됩니다.

I 설정 리눅스에서이 같은 블루투스 장치 (this question 덕분에) :

# activate bluetooth 
hciconfig hci0 up            
# set advertise data: "hello world" 
hcitool -i hci0 cmd 0x08 0x0008 48 45 4c 4c 4f 57 4f 52 4c 44 
# start advertising as connectable 
hciconfig hci0 leadv 0 

아이폰 OS 코드는 간단하다 :

- (int) scanForPeripherals 
{ 
    if (self->centralManager.state != CBCentralManagerStatePoweredOn) { 
     return -1; 
    } 
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey, nil]; 
    [self.centralManager scanForPeripheralsWithServices:nil options:options]; 
    return 0; 
} 

- (void)centralManagerDidUpdateState:(CBCentralManager *)central 
{ 
    if (central.state == CBCentralManagerStatePoweredOn) { 
     NSLog(@"Starting scan"); 
     [self scanForPeripherals]; 
    } 
} 

- (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 
{ 
    NSLog(@"didDiscoverPeripheral"); 
    /* 
    * Retain the peripheral to avoid the error: 
    * CoreBluetooth[WARNING]: state = connecting> is being dealloc'ed while connecting 
    */ 
    self.activePeripheral = peripheral; 
    [centralManager connectPeripheral:peripheral options:nil]; 
} 

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral 
{ 
    NSLog(@"Connected to peripheral"); 

    /* discover all services */ 
    [peripheral discoverServices:nil]; 
} 

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error 
{ 
    NSLog(@"Discovered services"); 
    for (CBService *service in peripheral.services) { 
     NSLog(@"Discovered service %@", service); 
    } 
} 

아이폰에이 코드를 실행, I 이 로그를 얻으십시오 :

2013-12-19 12:53:22.609 Test2[18518:60b] Starting scan 
2013-12-19 12:53:29.945 Test2[18518:60b] didDiscoverPeripheral 
2013-12-19 12:53:31.230 Test2[18518:60b] Connected to peripheral 

아이폰은 잘 연결되지만 어떤 서비스도 보지 못한다.

내가

  • 을 잃었 내가 간단한 BLE 서비스을 광고해야하지만 나는 bluez에서이 작업을 수행하는 방법에 대한 문서를 찾을 수 없습니다.
  • 내가 광고 할 서비스에 대한 읽기/쓰기 특성을 받기 위해서는 서버가 필요하다고 생각합니다. bluez에서 plugins/gatt-example.c 파일을 보았지만 사용할 방법은 전혀 모른다. 문서가 없다.

내가이 질문을 보았다 '고 미리 말씀 아마해야? Creating a gatt server,하지만 답변 (예를 들어 너무 많은 의문을 제기 여기서 bluez에 대한 GATT API를 인 GATT 데이터베이스를 설정하는 방법을 읽기에 등록하는 방법/이벤트를 기록)

편집 : 명령을 내가 사용하는 일부 데이터를 광고하기 위해 BLE 장치를-설정하지만, 아이폰 OS는 연결이 을 받아 들였다는 것을보고합니다. bluez의 어떤 부분이 들어오는 연결을 허용합니까?

+0

맞아요, GATT 서버가 필요합니다. 실행 한 명령은 광고 패킷을 브로드 캐스트하기 위해 하드웨어를 설정했지만 연결 대상은 시작하지 않습니다. 불행히도 나는 아직 GATT 서버를 설치하는 방법을 알아 내지 못해서 내가 당신을 도울 수 없다 ... –

+0

@TimTisdall 나는이 명령이 서버를 설정하지 않는다는 것을 안다. 그리고 이것은 누가 블루투스 연결을 수락합니까? 이 질문을 분명하게하기 위해 내 게시물을 편집했습니다. –

+0

내 생각 엔 커널에 연결을 설정하는 것이 있지만 추측에 불과합니다. –

답변

16

결국 모든 질문에 대한 답변을 발견했습니다. 난 단지 설정까지 BLE 장치를 일부 데이터를 광고하기 위해 사용

명령을하지만, 아이폰 OS는 연결이 허용됩니다보고 :

나는 마지막 질문에 대답하는 것으로 시작됩니다. bluez의 어떤 부분이 들어오는 연결을 허용합니까?

이 사람은 저에게 대답하여 입니다.

요약 : BLE 연결은 커널에 의해 HCI 수준에서 허용됩니다. 사용자 공간에서 그 연결을 사용하려면 ATC 채널 ID (4)와 함께 l2cap 소켓을 사용해야합니다.

Bleno has a good example of using an L2CAP socket. L2CAP 소켓 작동 방법

은 다음과 같이 기본적으로 :

/* create L2CAP socket, and bind it to the local adapter */ 
l2cap_socket = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); 

hci_device_id = hci_get_route(NULL); 
hci_socket = hci_open_dev(hci_device_id); 
memset(&l2cap_address, sizeof(l2cap_address)); 
l2cap_address.l2_family = AF_BLUETOOTH; 
l2cap_address.l2_bdaddr = hci_device_address; 
l2cap_address.l2_cid = htobs(ATT_CID); 

bind(l2cap_socket, (struct sockaddr*)&l2cap_address, sizeof(l2cap_address)); 
listen(l2cap_socket, 1); 

while (1) { 
    /* now select and accept() client connections. */ 
    select(l2cap_socket + 1, &afds, NULL, NULL, &tv); 
    client_socket = accept(l2cap_socket, (struct sockaddr *)&l2cap_address, &len); 

    /* you can now read() what the client sends you */ 
    int ret = read(client_socket, buffer, sizeof(buffer)); 
    printf("data len: %d\n", ret); 
    for (i = 0; i < ret; i++) { 
    printf("%02x", ((int)buffer[i]) & 0xff); 
    } 
    printf("\n"); 
    close(client_socket); 
} 

어떻게 서비스를 광고?

이전 질문에 대한 대답이 필요하다는 것을 깨달았습니다. 당신이 L2CAP 소켓을 통해 데이터를 읽을 수있게되면 당신의 안드로이드 전화 gatt.discoverServices(), 다음 작은 프로그램이 위의 읽을 않는 경우

, 다 (즉, 수신), 예를 들어, 더 의미 : 기본적으로

10 0100 ffff 0028 

의미 :

10: READ_BY_GROUP 
0100: from handle 0001 
ffff: to handle ffff 
0028: with UUID 2800 

이 요청은 모든 BLE 주변 장치가 서비스 목록을 요청하는 방식입니다.

그런 다음 GATT 프로토콜에 따라 형식이 지정된 장치 목록에서이 요청에 응답 할 수 있습니다.

또 다시 see the implementation of this in Bleno입니다.

+0

GATT 서비스를 Bluez와 함께 사용할 수있게 되었습니까? 나는 같은 것을 성취하려고 노력하고있다. – Michael

4

정말 가깝습니다.

당신의 아이폰 OS 코드를 사용하여 장치의 서비스를 확인하려면 discoverServices 호출하기 전에, 당신의 didConnectPeripheral

peripheral.delegate = self; 

를 추가하려고합니다. 나는 Apple documentation에서 그것을 얻었고 나를 위해 문제를 해결했습니다. 헤더 파일의 인터페이스 선언에 CBPeripheralDelegate을 추가하는 것을 잊지 마십시오. 그것이 없으면 didDiscoverServices은 절대로 호출되지 않을 것입니다.

소스에서 BlueZ를 ./configure --enable-maintainer-mode으로 컴파일하여 gatt-example 서비스 플러그인을 실행할 수있었습니다. 당신이 bluetoothd -nd을 시작하는 경우 그럼 당신은 출력의 상단에

src/plugin.c:add_plugin() Loading gatt_example plugin 

같은 것을 볼 수 있습니다, 다음

attrib/gatt-service.c:gatt_service_add() New service: handle 0x0009, UUID a002, 4 attributes 
src/attrib-server.c:attrib_db_add_new() handle=0x0009 
attrib/gatt-service.c:gatt_service_add() New characteristic: handle 0x000a 
src/attrib-server.c:attrib_db_add_new() handle=0x000a 

은 그 시점에서, 내 iOS 앱이 BlueZ peripheral을 볼 수 있었다, 연결 (hciconfig hci0 leadv 이후)의 서비스를 발견 할 수 있습니다.

+0

공유해 주셔서 감사합니다. '--enable-maintainer-mode'를 사용하여 bluez을 컴파일하지 않았지만, 연결이 허용됩니다. bluez 코드를 (과도하게) 읽은 후에는 bluez의 서비스 발견 부분에서 연결을 허용한다고 생각합니다 (src/sdpd-server.c 참조). –

+0

예'gatt-example' 플러그인을 활성화하기 전에 동일한 동작을 보았습니다. 이것은 연결이 먼저 승인 된 후 서비스 발견이 발생하기 때문입니다. 'gatt-example' 플러그인이'bluetoothd'에 포함되어 있지 않으면, 아이폰은 여전히 ​​광고 패킷을보고 연결할 수는 있지만 서비스를 찾을 수는 없습니다. '--enable-maintainer-mode'는'gatt-example' 플러그인을'Makefile.plugins'을 수정하지 않고 빌드에 포함시키는 지름길입니다. – Gabriel

+0

두 가지 빠른 질문이 있습니다. a) bluez에서 서비스 및 속성을 어디에서 구성 할 수 있습니까? b) 속성이 쓰기 가능한 경우, bluez는이 정보를 ios 앱이 작성한 값으로 처리하기 위해이 정보를 "저장"(또는 일종의 콜백)합니다. –

관련 문제