CoreBluetooth For Central (6)
Explore >> BLE Device’s Services
Explore Services From Device
前半段了解如何連線至BLE週邊,接下來要看看BLE週邊提供什麼樣的服務類型,服務(Service)類型中會提供屬性(Characteristics),透過屬性(Characteristics)才能真正的與BLE週邊溝通,結構如官網的圖片:
所以我們要在已線連成功之後尋訪該週邊能提供什麼樣的服務(Service)類型,其中服務類型可以從Bluetooth協會中來了解已經被定義的類型,已經被定義的就能由規範好的溝通方式與週邊溝通,像0x180D
UUID則是心跳表所代表的服務類型。
當你得知服務類型時,就能從規範中理解與服務溝通時會提供很多溝通管道,而這個溝通管道叫做Characteristics
,這個有屬性觀念,會有唯讀
、寫入
、通知
、讀寫
,當然它有一堆UUID碼當做溝通的識別碼,現在我們要先來列舉週邊提供什麼樣的服務(Service)。
連線成功後,CoreBluetooth會引發centralManager:didConnectPeripheral:
告知已經連線成功,此時我們需要利用CoreBluetooth Framework開始進行Service的尋訪:
//-----------start----------- -(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { NSLog(@"Connect To Peripheral with name: %@\nwith UUID:%@\n",peripheral.name,peripheral.identifier.UUIDString); peripheral.delegate=self;//連線成功後會回傳CBPeripheral,並邊要設定Delegate才能對後續的操作有所反應 [peripheral discoverServices:nil];//一定要執行"discoverService"功能去尋找可用的Service } //------------end------------
連線成功取得Peripheral後,必需要立即設定Delegate,之後尋訪Service後才能有所反應,現在要執行尋訪Service的Method:
//-----------start----------- [peripheral discoverServices:nil]; //沒有指定要尋訪的Service UUID時,傳入nil //------------end------------
接下來CoreBluetooth會開始動作,有反應時會引發peripheral:didDiscoverServices:
Delegate,在Delegate發生時我們也要利用它來尋訪Characteristics
,如此才能再引發peripheral:didDiscoverCharacteristicsForService:
得知已能使用的Characteristics
,下面範例會將Service的UUID內容印出,同時也執行尋訪Characteristics
的功能(還未處理該Delegate):
//-----------start----------- - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error { NSLog(@"didDiscoverServices:\n"); if( peripheral.identifier == NULL ) return; // zach ios6 added if (!error) { NSLog(@"====%@\n",peripheral.name); NSLog(@"=========== %ld of service for UUID %@ ===========\n",peripheral.services.count,peripheral.identifier.UUIDString); for (CBService *p in peripheral.services){ NSLog(@"Service found with UUID: %@\n", p.UUID); [peripheral discoverCharacteristics:nil forService:p]; } } else { NSLog(@"Service discovery was unsuccessfull !\n"); } } //------------end------------
上面程式內容會將Service類別印出來,不過在實作前需要有BLE週邊,範例使用的是Polar H7
心跳表來當連線的週邊,如果再配合CoreBluetooth For Central (4)所學到的內容,將centralManager:didDiscoverPeripheral:advertisementData:RSSI:
內容修改一下,讓程式當抓到Polar H7
週邊時自動進行連線:
//-----------start----------- - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { NSLog(@"peripheral\n%@\n",peripheral); NSLog(@"advertisementData\n%@\n",advertisementData); NSLog(@"RSSI\n%@\n",RSSI); NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey]; NSLog(@"localName:%@",localName); //if ([peripheral.name length] && [peripheral.name rangeOfString:@"DannySimpleBLE"].location != NSNotFound) { if ([localName length] && [localName rangeOfString:@"Polar"].location != NSNotFound) { //抓到週邊後就立即停子Scan [CM stopScan]; NSLog(@"stopScan"); connectPeripheral = peripheral; [CM connectPeripheral:peripheral options:nil]; NSLog(@"connect to %@",peripheral.name); } } //------------end------------
執行結果如下:
2015-01-26 17:14:29.554 BluetoothLE-Explore[8404:6929832] UpdateState:PoweredOn 2015-01-26 17:14:30.511 BluetoothLE-Explore[8404:6929832] Scan And Connect 2015-01-26 17:14:30.578 BluetoothLE-Explore[8404:6929832] peripheral <CBPeripheral: 0x14d807b0, identifier = 8DC3DD90-0C17-1AB9-90FE-E9130DD07B81, name = Polar H7 000607, state = disconnected> 2015-01-26 17:14:30.580 BluetoothLE-Explore[8404:6929832] advertisementData { kCBAdvDataIsConnectable = 1; kCBAdvDataManufacturerData = <6b00031c 00>; kCBAdvDataServiceUUIDs = ( "Heart Rate" ); kCBAdvDataTxPowerLevel = 0; } 2015-01-26 17:14:30.580 BluetoothLE-Explore[8404:6929832] RSSI -64 2015-01-26 17:14:30.581 BluetoothLE-Explore[8404:6929832] localName:(null) 2015-01-26 17:14:30.581 BluetoothLE-Explore[8404:6929832] peripheral <CBPeripheral: 0x14e3cea0, identifier = 8DC3DD90-0C17-1AB9-90FE-E9130DD07B81, name = Polar H7 000607, state = disconnected> 2015-01-26 17:14:30.582 BluetoothLE-Explore[8404:6929832] advertisementData { kCBAdvDataIsConnectable = 1; kCBAdvDataLocalName = "Polar H7 000607"; kCBAdvDataManufacturerData = <6b00031c 00>; kCBAdvDataServiceUUIDs = ( "Heart Rate" ); kCBAdvDataTxPowerLevel = 0; } 2015-01-26 17:14:30.582 BluetoothLE-Explore[8404:6929832] RSSI -64 2015-01-26 17:14:30.583 BluetoothLE-Explore[8404:6929832] localName:Polar H7 000607 2015-01-26 17:14:30.583 BluetoothLE-Explore[8404:6929832] stopScan 2015-01-26 17:14:30.584 BluetoothLE-Explore[8404:6929832] connect to Polar H7 000607 2015-01-26 17:14:30.683 BluetoothLE-Explore[8404:6929832] connected 2015-01-26 17:14:30.683 BluetoothLE-Explore[8404:6929832] Connect To Peripheral with name: Polar H7 000607 with UUID:8DC3DD90-0C17-1AB9-90FE-E9130DD07B81 2015-01-26 17:14:31.120 BluetoothLE-Explore[8404:6929832] didDiscoverServices: 2015-01-26 17:14:31.121 BluetoothLE-Explore[8404:6929832] ====Polar H7 000607 2015-01-26 17:14:31.121 BluetoothLE-Explore[8404:6929832] =========== 4 of service for UUID 8DC3DD90-0C17-1AB9-90FE-E9130DD07B81 =========== 2015-01-26 17:14:31.122 BluetoothLE-Explore[8404:6929832] Service found with UUID: Heart Rate 2015-01-26 17:14:31.123 BluetoothLE-Explore[8404:6929832] Service found with UUID: Device Information 2015-01-26 17:14:31.123 BluetoothLE-Explore[8404:6929832] Service found with UUID: Battery 2015-01-26 17:14:31.124 BluetoothLE-Explore[8404:6929832] Service found with UUID: 6217FF49-AC7B-547E-EECF-016A06970BA9
從執行結果看到Service found with UUID:...
顯示有蠻多Service提供,其中Heart Rate
這項是可以取得目前心跳的資訊,接下來再承上面的範例,再加上將每個Service中的Characteristics
屬性列出來,如果你要這麼做,就要處理引發peripheral:didDiscoverCharacteristicsForService
的內容,架構如下:
//-----------start----------- -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { : : : } //------------end------------
加上處理的程式,程式將每個Service中包含的Characteristics屬性列出來:
//-----------start----------- -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { CBService *s = [peripheral.services objectAtIndex:(peripheral.services.count - 1)]; //NSLog(@"=========== Service UUID %s ===========\n",[NSUUID UUID] ini); if (!error) { NSLog(@"=========== %d Characteristics of %@ service ",service.characteristics.count,service.UUID); //以下針對service提供的Characteristics一一尋訪並列出 for(CBCharacteristic *c in service.characteristics){ NSLog(@" %@ \n",c.UUID); // CBService *s = [peripheral.services objectAtIndex:(peripheral.services.count - 1)]; if(service.UUID == NULL || s.UUID == NULL) return; // zach ios6 added } NSLog(@"=== Finished set notification ===\n"); } else { NSLog(@"Characteristic discorvery unsuccessfull !\n"); } } //------------end------------
執行結果如下:
2015-01-26 17:39:42.464 BluetoothLE-Explore[8424:6934992] UpdateState:PoweredOn 2015-01-26 17:39:44.112 BluetoothLE-Explore[8424:6934992] Scan And Connect 2015-01-26 17:39:48.112 BluetoothLE-Explore[8424:6934992] stopScan 2015-01-26 17:39:48.113 BluetoothLE-Explore[8424:6934992] connectPeripheral == NULL 2015-01-26 17:39:54.913 BluetoothLE-Explore[8424:6934992] Scan And Connect 2015-01-26 17:39:54.935 BluetoothLE-Explore[8424:6934992] peripheral <CBPeripheral: 0x16d4de10, identifier = 8DC3DD90-0C17-1AB9-90FE-E9130DD07B81, name = Polar H7 000607, state = disconnected> 2015-01-26 17:39:54.936 BluetoothLE-Explore[8424:6934992] advertisementData { kCBAdvDataIsConnectable = 1; kCBAdvDataLocalName = "Polar H7 000607"; kCBAdvDataManufacturerData = <6b000300 00>; kCBAdvDataServiceUUIDs = ( "Heart Rate" ); kCBAdvDataTxPowerLevel = 0; } 2015-01-26 17:39:54.937 BluetoothLE-Explore[8424:6934992] RSSI -57 2015-01-26 17:39:54.937 BluetoothLE-Explore[8424:6934992] localName:Polar H7 000607 2015-01-26 17:39:54.938 BluetoothLE-Explore[8424:6934992] stopScan 2015-01-26 17:39:54.938 BluetoothLE-Explore[8424:6934992] connect to Polar H7 000607 2015-01-26 17:39:55.025 BluetoothLE-Explore[8424:6934992] connected 2015-01-26 17:39:55.025 BluetoothLE-Explore[8424:6934992] Connect To Peripheral with name: Polar H7 000607 with UUID:8DC3DD90-0C17-1AB9-90FE-E9130DD07B81 2015-01-26 17:39:55.407 BluetoothLE-Explore[8424:6934992] didDiscoverServices: 2015-01-26 17:39:55.408 BluetoothLE-Explore[8424:6934992] ====Polar H7 000607 2015-01-26 17:39:55.408 BluetoothLE-Explore[8424:6934992] =========== 4 of service for UUID 8DC3DD90-0C17-1AB9-90FE-E9130DD07B81 =========== 2015-01-26 17:39:55.409 BluetoothLE-Explore[8424:6934992] Service found with UUID: Heart Rate 2015-01-26 17:39:55.410 BluetoothLE-Explore[8424:6934992] Service found with UUID: Device Information 2015-01-26 17:39:55.410 BluetoothLE-Explore[8424:6934992] Service found with UUID: Battery 2015-01-26 17:39:55.411 BluetoothLE-Explore[8424:6934992] Service found with UUID: 6217FF49-AC7B-547E-EECF-016A06970BA9 2015-01-26 17:39:55.527 BluetoothLE-Explore[8424:6934992] =========== 2 Characteristics of Heart Rate service 2015-01-26 17:39:55.528 BluetoothLE-Explore[8424:6934992] 2A37 2015-01-26 17:39:55.529 BluetoothLE-Explore[8424:6934992] 2A38 2015-01-26 17:39:55.529 BluetoothLE-Explore[8424:6934992] === Finished set notification === 2015-01-26 17:39:55.768 BluetoothLE-Explore[8424:6934992] =========== 7 Characteristics of Device Information service 2015-01-26 17:39:55.769 BluetoothLE-Explore[8424:6934992] System ID 2015-01-26 17:39:55.769 BluetoothLE-Explore[8424:6934992] Model Number String 2015-01-26 17:39:55.769 BluetoothLE-Explore[8424:6934992] Serial Number String 2015-01-26 17:39:55.770 BluetoothLE-Explore[8424:6934992] Firmware Revision String 2015-01-26 17:39:55.770 BluetoothLE-Explore[8424:6934992] Hardware Revision String 2015-01-26 17:39:55.770 BluetoothLE-Explore[8424:6934992] Software Revision String 2015-01-26 17:39:55.771 BluetoothLE-Explore[8424:6934992] Manufacturer Name String 2015-01-26 17:39:55.771 BluetoothLE-Explore[8424:6934992] === Finished set notification === 2015-01-26 17:39:55.887 BluetoothLE-Explore[8424:6934992] =========== 1 Characteristics of Battery service 2015-01-26 17:39:55.888 BluetoothLE-Explore[8424:6934992] Battery Level 2015-01-26 17:39:55.888 BluetoothLE-Explore[8424:6934992] === Finished set notification === 2015-01-26 17:39:56.007 BluetoothLE-Explore[8424:6934992] =========== 1 Characteristics of 6217FF49-AC7B-547E-EECF-016A06970BA9 service 2015-01-26 17:39:56.008 BluetoothLE-Explore[8424:6934992] 6217FF4A-B07D-5DEB-261E-2586752D942E 2015-01-26 17:39:56.008 BluetoothLE-Explore[8424:6934992] === Finished set notification ===
以Heart Rate service
來說明,它提供了2A37
、2A38
的屬性,從Bluetooth Characteristics查詢到:
AssignedNumber | Specification Name |
---|---|
2A38 | Body Sensor Location |
2A37 | Heart Rate Measurement |
2A38
來設定目前心跳表的所在位置,2A37
則是讀取心跳的資料,其中有一些細節過程依照規格的表示方式去做讀、寫取得資訊與設定就能取得Polar H7
提供的心跳資料。
不管如何要先知道Service的類型後再去尋得Characteristic的屬性,在CoreBluetooth使用上這兩種是互相配合使用的,後面的介紹中仍然會以Polar H7
為範例繼續了解如何與它來進行溝通。