@@ -129,26 +129,29 @@ export enum Phy {
129129 LE_CODED , // = android.bluetooth.BluetoothDevice.PHY_LE_CODED,
130130 LE_ALL_SUPPORTED , // = android.bluetooth.le.ScanSettings.PHY_LE_ALL_SUPPORTED
131131}
132- function androidPhy ( mode : Phy ) {
133- switch ( mode ) {
134- case Phy . LE_1M :
135- return android . bluetooth . BluetoothDevice . PHY_LE_1M ;
136- case Phy . LE_CODED :
137- return android . bluetooth . BluetoothDevice . PHY_LE_CODED ;
138- default :
139- // PHY_LE_ALL_SUPPORTED
140- return android . bluetooth . le . ScanSettings . PHY_LE_ALL_SUPPORTED ;
141- }
142- }
143-
144- export function uuidToString ( uuid ) {
145- // uuid is returned lowercase
132+ // function androidPhy(mode: Phy) {
133+ // switch (mode) {
134+ // case Phy.LE_1M:
135+ // return android.bluetooth.BluetoothDevice.PHY_LE_1M;
136+ // case Phy.LE_CODED:
137+ // return android.bluetooth.BluetoothDevice.PHY_LE_CODED;
138+ // default:
139+ // // PHY_LE_ALL_SUPPORTED
140+ // return android.bluetooth.le.ScanSettings.PHY_LE_ALL_SUPPORTED;
141+ // }
142+ // }
143+
144+ const uuidRegexp = new RegExp ( '0000(.{4})-0000-1000-8000-00805f9b34fb' ) ;
145+ export function uuidToString ( uuid : android . os . ParcelUuid | string | java . util . UUID ) {
146146 const uuidStr = uuid . toString ( ) ;
147- const pattern = java . util . regex . Pattern . compile ( '0000(.{4})-0000-1000-8000-00805f9b34fb' , 2 ) ;
148- const matcher = pattern . matcher ( uuidStr ) ;
149- return matcher . matches ( ) ? matcher . group ( 1 ) : uuidStr ;
147+ if ( uuidStr . length !== 4 ) {
148+ const match = uuidRegexp . exec ( uuidStr ) ;
149+ if ( match ) {
150+ return match [ 1 ] ;
151+ }
152+ }
153+ return uuidStr ;
150154}
151-
152155// val must be a Uint8Array or Uint16Array or a string like '0x01' or '0x007F' or '0x01,0x02', or '0x007F,'0x006F''
153156export function arrayToNativeByteArray ( val ) {
154157 const length = val . length ;
@@ -984,87 +987,99 @@ declare interface WrapperResult {
984987 bluetoothGattService : android . bluetooth . BluetoothGattService ;
985988}
986989
987- function getGattDeviceServiceInfo ( gatt : android . bluetooth . BluetoothGatt ) {
990+ function getGattDeviceServiceInfo ( gatt : android . bluetooth . BluetoothGatt , args ?: DiscoverServicesOptions & { all ?: boolean } ) {
988991 const services = gatt . getServices ( ) ;
989992 const servicesJs = [ ] ;
990993 const BluetoothGattCharacteristic = android . bluetooth . BluetoothGattCharacteristic ;
994+ const serviceUUIDs = args . serviceUUIDs ;
995+ const all = args . all ;
991996 for ( let i = 0 ; i < services . size ( ) ; i ++ ) {
992- const service = services . get ( i ) ;
993- const characteristics = service . getCharacteristics ( ) ;
994- const characteristicsJs = [ ] ;
995- for ( let j = 0 ; j < characteristics . size ( ) ; j ++ ) {
996- const characteristic = characteristics . get ( j ) ;
997- const props = characteristic . getProperties ( ) ;
998- const descriptors = characteristic . getDescriptors ( ) ;
999- const descriptorsJs = [ ] ;
1000- for ( let k = 0 ; k < descriptors . size ( ) ; k ++ ) {
1001- const descriptor = descriptors . get ( k ) ;
1002- const descriptorJs = {
1003- UUID : uuidToString ( descriptor . getUuid ( ) ) ,
1004- value : descriptor . getValue ( ) , // always empty btw
997+ const service : android . bluetooth . BluetoothGattService = services . get ( i ) ;
998+ const serviceUUID = uuidToString ( service . getUuid ( ) ) ;
999+ console . log ( 'getGattDeviceServiceInfo' , service . getUuid ( ) . toString ( ) , serviceUUID , serviceUUIDs ) ;
1000+ if ( serviceUUIDs && serviceUUIDs . indexOf ( serviceUUID ) === - 1 ) {
1001+ continue ;
1002+ }
1003+ let characteristicsJs ;
1004+ if ( all === true ) {
1005+ const characteristics = service . getCharacteristics ( ) ;
1006+ characteristicsJs = [ ] ;
1007+ for ( let j = 0 ; j < characteristics . size ( ) ; j ++ ) {
1008+ const characteristic : android . bluetooth . BluetoothGattCharacteristic = characteristics . get ( j ) ;
1009+ const characteristicUUID = uuidToString ( characteristic . getUuid ( ) ) ;
1010+ const props = characteristic . getProperties ( ) ;
1011+ const descriptors = characteristic . getDescriptors ( ) ;
1012+ const descriptorsJs = [ ] ;
1013+ for ( let k = 0 ; k < descriptors . size ( ) ; k ++ ) {
1014+ const descriptor : android . bluetooth . BluetoothGattDescriptor = descriptors . get ( k ) ;
1015+ const descriptorJs = {
1016+ UUID : uuidToString ( descriptor . getUuid ( ) ) ,
1017+ value : descriptor . getValue ( ) , // always empty btw
1018+ permissions : null ,
1019+ } ;
1020+ const descPerms = descriptor . getPermissions ( ) ;
1021+ if ( descPerms > 0 ) {
1022+ descriptorJs . permissions = {
1023+ read : ( descPerms & BluetoothGattCharacteristic . PERMISSION_READ ) !== 0 ,
1024+ readEncrypted : ( descPerms & BluetoothGattCharacteristic . PERMISSION_READ_ENCRYPTED ) !== 0 ,
1025+ readEncryptedMitm : ( descPerms & BluetoothGattCharacteristic . PERMISSION_READ_ENCRYPTED_MITM ) !== 0 ,
1026+ write : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE ) !== 0 ,
1027+ writeEncrypted : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_ENCRYPTED ) !== 0 ,
1028+ writeEncryptedMitm : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_ENCRYPTED_MITM ) !== 0 ,
1029+ writeSigned : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_SIGNED ) !== 0 ,
1030+ writeSignedMitm : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_SIGNED_MITM ) !== 0 ,
1031+ } ;
1032+ }
1033+
1034+ if ( Trace . isEnabled ( ) ) {
1035+ CLog ( CLogTypes . info , `TNS_BluetoothGattCallback.onServicesDiscovered ---- pushing descriptor: ${ descriptor } ` ) ;
1036+ }
1037+ descriptorsJs . push ( descriptorJs ) ;
1038+ }
1039+
1040+ const characteristicJs = {
1041+ serviceUUID,
1042+ UUID : characteristicUUID ,
1043+ name : characteristicUUID , // there's no sep field on Android
1044+ properties : {
1045+ read : ( props & BluetoothGattCharacteristic . PROPERTY_READ ) !== 0 ,
1046+ write : ( props & BluetoothGattCharacteristic . PROPERTY_WRITE ) !== 0 ,
1047+ writeWithoutResponse : ( props & BluetoothGattCharacteristic . PROPERTY_WRITE_NO_RESPONSE ) !== 0 ,
1048+ notify : ( props & BluetoothGattCharacteristic . PROPERTY_NOTIFY ) !== 0 ,
1049+ indicate : ( props & BluetoothGattCharacteristic . PROPERTY_INDICATE ) !== 0 ,
1050+ broadcast : ( props & BluetoothGattCharacteristic . PROPERTY_BROADCAST ) !== 0 ,
1051+ authenticatedSignedWrites : ( props & BluetoothGattCharacteristic . PROPERTY_SIGNED_WRITE ) !== 0 ,
1052+ extendedProperties : ( props & BluetoothGattCharacteristic . PROPERTY_EXTENDED_PROPS ) !== 0 ,
1053+ } ,
1054+ descriptors : descriptorsJs ,
10051055 permissions : null ,
10061056 } ;
1007- const descPerms = descriptor . getPermissions ( ) ;
1008- if ( descPerms > 0 ) {
1009- descriptorJs . permissions = {
1010- read : ( descPerms & BluetoothGattCharacteristic . PERMISSION_READ ) !== 0 ,
1011- readEncrypted : ( descPerms & BluetoothGattCharacteristic . PERMISSION_READ_ENCRYPTED ) !== 0 ,
1012- readEncryptedMitm : ( descPerms & BluetoothGattCharacteristic . PERMISSION_READ_ENCRYPTED_MITM ) !== 0 ,
1013- write : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE ) !== 0 ,
1014- writeEncrypted : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_ENCRYPTED ) !== 0 ,
1015- writeEncryptedMitm : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_ENCRYPTED_MITM ) !== 0 ,
1016- writeSigned : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_SIGNED ) !== 0 ,
1017- writeSignedMitm : ( descPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_SIGNED_MITM ) !== 0 ,
1057+
1058+ // permissions are usually not provided, so let's not return them in that case
1059+ const charPerms = characteristic . getPermissions ( ) ;
1060+ if ( charPerms > 0 ) {
1061+ characteristicJs . permissions = {
1062+ read : ( charPerms & BluetoothGattCharacteristic . PERMISSION_READ ) !== 0 ,
1063+ readEncrypted : ( charPerms & BluetoothGattCharacteristic . PERMISSION_READ_ENCRYPTED ) !== 0 ,
1064+ readEncryptedMitm : ( charPerms & BluetoothGattCharacteristic . PERMISSION_READ_ENCRYPTED_MITM ) !== 0 ,
1065+ write : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE ) !== 0 ,
1066+ writeEncrypted : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_ENCRYPTED ) !== 0 ,
1067+ writeEncryptedMitm : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_ENCRYPTED_MITM ) !== 0 ,
1068+ writeSigned : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_SIGNED ) !== 0 ,
1069+ writeSignedMitm : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_SIGNED_MITM ) !== 0 ,
10181070 } ;
10191071 }
10201072
10211073 if ( Trace . isEnabled ( ) ) {
1022- CLog ( CLogTypes . info , `TNS_BluetoothGattCallback.onServicesDiscovered ---- pushing descriptor : ${ descriptor } ` ) ;
1074+ CLog ( CLogTypes . info , `TNS_BluetoothGattCallback.onServicesDiscovered ---- pushing characteristic : ${ JSON . stringify ( characteristicJs ) } for service: ${ serviceUUID } ` ) ;
10231075 }
1024- descriptorsJs . push ( descriptorJs ) ;
1025- }
1026-
1027- const characteristicJs = {
1028- serviceUUID : uuidToString ( service . getUuid ( ) ) ,
1029- UUID : uuidToString ( characteristic . getUuid ( ) ) ,
1030- name : uuidToString ( characteristic . getUuid ( ) ) , // there's no sep field on Android
1031- properties : {
1032- read : ( props & BluetoothGattCharacteristic . PROPERTY_READ ) !== 0 ,
1033- write : ( props & BluetoothGattCharacteristic . PROPERTY_WRITE ) !== 0 ,
1034- writeWithoutResponse : ( props & BluetoothGattCharacteristic . PROPERTY_WRITE_NO_RESPONSE ) !== 0 ,
1035- notify : ( props & BluetoothGattCharacteristic . PROPERTY_NOTIFY ) !== 0 ,
1036- indicate : ( props & BluetoothGattCharacteristic . PROPERTY_INDICATE ) !== 0 ,
1037- broadcast : ( props & BluetoothGattCharacteristic . PROPERTY_BROADCAST ) !== 0 ,
1038- authenticatedSignedWrites : ( props & BluetoothGattCharacteristic . PROPERTY_SIGNED_WRITE ) !== 0 ,
1039- extendedProperties : ( props & BluetoothGattCharacteristic . PROPERTY_EXTENDED_PROPS ) !== 0 ,
1040- } ,
1041- descriptors : descriptorsJs ,
1042- permissions : null ,
1043- } ;
1044-
1045- // permissions are usually not provided, so let's not return them in that case
1046- const charPerms = characteristic . getPermissions ( ) ;
1047- if ( charPerms > 0 ) {
1048- characteristicJs . permissions = {
1049- read : ( charPerms & BluetoothGattCharacteristic . PERMISSION_READ ) !== 0 ,
1050- readEncrypted : ( charPerms & BluetoothGattCharacteristic . PERMISSION_READ_ENCRYPTED ) !== 0 ,
1051- readEncryptedMitm : ( charPerms & BluetoothGattCharacteristic . PERMISSION_READ_ENCRYPTED_MITM ) !== 0 ,
1052- write : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE ) !== 0 ,
1053- writeEncrypted : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_ENCRYPTED ) !== 0 ,
1054- writeEncryptedMitm : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_ENCRYPTED_MITM ) !== 0 ,
1055- writeSigned : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_SIGNED ) !== 0 ,
1056- writeSignedMitm : ( charPerms & BluetoothGattCharacteristic . PERMISSION_WRITE_SIGNED_MITM ) !== 0 ,
1057- } ;
1058- }
1059-
1060- if ( Trace . isEnabled ( ) ) {
1061- CLog ( CLogTypes . info , `TNS_BluetoothGattCallback.onServicesDiscovered ---- pushing characteristic: ${ JSON . stringify ( characteristicJs ) } ` ) ;
1076+ characteristicsJs . push ( characteristicJs ) ;
10621077 }
1063- characteristicsJs . push ( characteristicJs ) ;
10641078 }
10651079
1080+
10661081 servicesJs . push ( {
1067- UUID : uuidToString ( service . getUuid ( ) ) ,
1082+ UUID : serviceUUID ,
10681083 characteristics : characteristicsJs ,
10691084 } ) ;
10701085 }
@@ -1732,8 +1747,10 @@ export class Bluetooth extends BluetoothCommon {
17321747 } ) ;
17331748 } ) ;
17341749 let services , mtu ;
1735- if ( args . autoDiscoverAll !== false ) {
1750+ if ( args . autoDiscoverAll === true ) {
17361751 services = ( await this . discoverAll ( { peripheralUUID : pUUID } ) ) ?. services ;
1752+ } else if ( args . serviceUUIDs ) {
1753+ services = ( await this . discoverServices ( { peripheralUUID : pUUID , serviceUUIDs :args . serviceUUIDs } ) ) ?. services ;
17371754 }
17381755 if ( ! ! args . auto2MegPhy ) {
17391756 await this . select2MegPhy ( { peripheralUUID : pUUID } ) ;
@@ -1864,7 +1881,7 @@ export class Bluetooth extends BluetoothCommon {
18641881 if ( Trace . isEnabled ( ) ) {
18651882 CLog (
18661883 CLogTypes . info ,
1867- `${ methodName } ---- got result peripheralUUID:${ args . peripheralUUID } serviceUUID:${ args . serviceUUID } characteristicUUID:${ args . characteristicUUID } status:${ status } `
1884+ `${ methodName } ---- got result peripheralUUID:${ pUUID } serviceUUID:${ sUUID } characteristicUUID:${ cUUID } status:${ status } `
18681885 ) ;
18691886 }
18701887 if ( UUID === pUUID && cUUID === args . characteristicUUID && sUUID === args . serviceUUID ) {
@@ -2453,7 +2470,7 @@ export class Bluetooth extends BluetoothCommon {
24532470 }
24542471
24552472 @prepareArgs
2456- public discoverServices ( args : DiscoverServicesOptions ) : Promise < { services : Service [ ] } > {
2473+ public discoverServices ( args : DiscoverServicesOptions & { all ?: boolean } ) : Promise < { services : Service [ ] } > {
24572474 const methodName = 'discoverServices' ;
24582475 if ( Trace . isEnabled ( ) ) {
24592476 CLog ( CLogTypes . info , methodName , args ) ;
@@ -2480,6 +2497,7 @@ export class Bluetooth extends BluetoothCommon {
24802497 if ( Trace . isEnabled ( ) ) {
24812498 CLog ( CLogTypes . info , methodName , pUUID , stateObject ) ;
24822499 }
2500+ const serviceUUIDs = args . serviceUUIDs ;
24832501 return this . addToGattQueue (
24842502 ( ) =>
24852503 new Promise ( ( resolve , reject ) => {
@@ -2499,7 +2517,7 @@ export class Bluetooth extends BluetoothCommon {
24992517 }
25002518 if ( UUID === pUUID ) {
25012519 if ( status === GATT_SUCCESS ) {
2502- resolve ( getGattDeviceServiceInfo ( gatt ) ) ;
2520+ resolve ( getGattDeviceServiceInfo ( gatt , args ) ) ;
25032521 clearListeners ( ) ;
25042522 } else {
25052523 onError (
@@ -2579,7 +2597,7 @@ export class Bluetooth extends BluetoothCommon {
25792597 }
25802598
25812599 public discoverAll ( args : DiscoverOptions ) {
2582- return this . discoverServices ( args ) ;
2600+ return this . discoverServices ( { ... args , all : true } ) ;
25832601 }
25842602
25852603 private disconnectListeners : DisconnectListener [ ] = [ ] ;
0 commit comments