Skip to content

Commit

Permalink
Merge pull request #135 from appcelerator-modules/develop
Browse files Browse the repository at this point in the history
develop to master merge pr
  • Loading branch information
aakash-jain-axway committed Mar 23, 2021
2 parents 29a6cee + 49b9448 commit d05292d
Show file tree
Hide file tree
Showing 75 changed files with 6,728 additions and 1,786 deletions.
2 changes: 1 addition & 1 deletion Jenkinsfile
Expand Up @@ -2,7 +2,7 @@
library 'pipeline-library'

buildModule {
sdkVersion = '9.2.1.GA'
sdkVersion = '9.3.1.GA'
npmPublish = false // By default it'll do github release on master anyways too
iosLabels = 'osx && xcode-12'
androidBuildToolsVersion = '30.0.2'
Expand Down
210 changes: 180 additions & 30 deletions README.md
Expand Up @@ -6,11 +6,10 @@
- Central can scan nearby peripheral, connect and exchange data with the peripherals
- Central can subscribe with peripheral to get latest updates for peripheral
- Act as BLE Peripheral:
- Peripheral can advertise services, connect and exchange data with multiple central. This feature
is currently available on iOS platform only.
- Peripheral can advertise services, connect and exchange data with multiple central.
- Use L2CAP Channel:
- L2CAP is introduced with IOS 11, its used to transfer large amount of data between central and
peripheral at real time. This feature is currently available on iOS platform only.
- L2CAP is introduced with IOS 11 and Android 10, its used to transfer large amount of data between central and
peripheral at real time.
- Main use case addressed by this module is Exchange of Data and Communicating with Central and
Peripherals that supports Bluetooth Low Energy.

Expand Down Expand Up @@ -79,6 +78,21 @@ The BLE variable is a reference to the Module object.
</ti:app>
```

- Set the ``` <module> ``` element in tiapp.xml, such as this:
- Edit the `plist` with following `uses-permission` element to the ios plist section, if your are adding iBeacon Scan
```
<ti:app>
<ios>
<plist>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow Location permission</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Allow Location permission</string>
</plist>
</ios>
</ti:app>
```

- Set the ``` <module> ``` element in tiapp.xml, such as this:
```
<modules>
Expand Down Expand Up @@ -115,8 +129,8 @@ The BLE variable is a reference to the Module object.
centralManager.connectPeripheral({
peripheral: peripheral,
options: {
[BLE.CONNECT_PERIPHERAL_OPTIONS_KEY_NOTIFY_ON_CONNECTION]: true,
[BLE.CONNECT_PERIPHERAL_OPTIONS_KEY_NOTIFY_ON_DISCONNECTION]: true
[BLE.CONNECT_PERIPHERAL_OPTIONS_KEY_NOTIFY_ON_CONNECTION]: true,
[BLE.CONNECT_PERIPHERAL_OPTIONS_KEY_NOTIFY_ON_DISCONNECTION]: true
}
});
```
Expand All @@ -141,14 +155,14 @@ The BLE variable is a reference to the Module object.
service: service
});
```

result will be return in `didDiscoverCharacteristics` event

```
connectedPeripheral.addEventListener('didDiscoverCharacteristics', function (e) {});
```
```
- Use `subscribeToCharacteristic` and `unsubscribeFromCharacteristic` to subscribe or unsubscribe
```
```
peripheral.subscribeToCharacteristic({
characteristic: charactersticObject
});
Expand All @@ -165,7 +179,7 @@ The BLE variable is a reference to the Module object.
- As the module currently provides support to act only as central for the Android, hence to test the example application, user can use any heart-rate peripheral
or the peripheral simulator in order to do the connection and data-exchange with the central.

## Follow basic steps to create Central application and use Channel for communication: (iOS Only)
## Follow basic steps to create Central application and use Channel for communication:

- Use `initCentralManager` to create Central Manager
```
Expand All @@ -186,8 +200,8 @@ or the peripheral simulator in order to do the connection and data-exchange with
centralManager.connectPeripheral({
peripheral: peripheral,
options: {
[BLE.CONNECT_PERIPHERAL_OPTIONS_KEY_NOTIFY_ON_CONNECTION]: true,
[BLE.CONNECT_PERIPHERAL_OPTIONS_KEY_NOTIFY_ON_DISCONNECTION]: true
[BLE.CONNECT_PERIPHERAL_OPTIONS_KEY_NOTIFY_ON_CONNECTION]: true,
[BLE.CONNECT_PERIPHERAL_OPTIONS_KEY_NOTIFY_ON_DISCONNECTION]: true
}
});
```
Expand All @@ -213,16 +227,16 @@ or the peripheral simulator in order to do the connection and data-exchange with
service: service
});
```

result will be return in `didDiscoverCharacteristics` event

```
connectedPeripheral.addEventListener('didDiscoverCharacteristics', function (e) {});
```
```

- Use `subscribeToCharacteristic` and `unsubscribeFromCharacteristic` to subscribe or unsubscribe

```
```
peripheral.subscribeToCharacteristic({
characteristic: charactersticObject
});
Expand Down Expand Up @@ -255,7 +269,7 @@ or the peripheral simulator in order to do the connection and data-exchange with
if (e.errorCode !== null) {
alert('Error while opening channel' + e.errorCode + '/' + e.errorDomain + '/' + e.errorDescription);
return;
}
}
channel = e.channel;
channel.addEventListener('onDataReceived', function (e) {
var data = e.data;
Expand All @@ -268,7 +282,7 @@ or the peripheral simulator in order to do the connection and data-exchange with

- Use `write` function from channel to write values

```
```
var newBuffer = Ti.createBuffer({ value: 'hello world' });
channel.write({
data: newBuffer
Expand All @@ -287,7 +301,7 @@ or the peripheral simulator in order to do the connection and data-exchange with
channel.close();
```

# Act As Peripheral Application (iOS Only)
# Act As Peripheral Application

## Follow basic steps to create Peripheral application:

Expand All @@ -298,12 +312,14 @@ or the peripheral simulator in order to do the connection and data-exchange with
```

- Use `createMutableCharacteristic` to create charracteristic

```
charProperties = [ BLE.CHARACTERISTIC_PROPERTIES_READ, BLE.CHARACTERISTIC_PROPERTIES_WRITE_WITHOUT_RESPONSE, BLE.CHARACTERISTIC_PROPERTIES_NOTIFY ];
charPermissions = [ BLE.CHARACTERISTIC_PERMISSION_READABLE, BLE.CHARACTERISTIC_PERMISSION_WRITEABLE ];
var characteristic = BLE.createMutableCharacteristic({
uuid: characteristicUUID,
properties: [ BLE.CHARACTERISTIC_PROPERTIES_READ, BLE.CHARACTERISTIC_PROPERTIES_WRITE_WITHOUT_RESPONSE, BLE.CHARACTERISTIC_PROPERTIES_NOTIFY ],
permissions: [ BLE.CHARACTERISTIC_PERMISSION_READABLE, BLE.CHARACTERISTIC_PERMISSION_WRITEABLE ]
properties: charProperties,
permissions: charPermissions
});
```

Expand All @@ -318,8 +334,9 @@ or the peripheral simulator in order to do the connection and data-exchange with
```

- Once `peripheralManager` is in `BLE.MANAGER_STATE_POWERED_ON` state, start advertising using `startAdvertising`

```
var name = IOS ? 'BLE-Sample' : true;
peripheralManager.startAdvertising({
localName: name,
serviceUUIDs: servicesUUIDs
Expand All @@ -342,6 +359,11 @@ or the peripheral simulator in order to do the connection and data-exchange with
peripheralManager.stopAdvertising();
```

- Use `closePeripheral` to close the peripheral after it is done with the peripheral operations. (Android only)
```
peripheralManager.closePeripheral();
```

## Follow basic steps to create Peripheral application which use channels for communication:

- Use `initPeripheralManager` to create Peripheral Manager
Expand All @@ -351,7 +373,7 @@ or the peripheral simulator in order to do the connection and data-exchange with
```

- Use `createMutableCharacteristic` to create charracteristic

```
var characteristic = BLE.createMutableCharacteristic({
uuid: BLE.CBUUID_L2CAPPSM_CHARACTERISTIC_STRING,
Expand All @@ -376,7 +398,7 @@ or the peripheral simulator in order to do the connection and data-exchange with
peripheralManager.publishL2CAPChannel({
encryptionRequired: false
});
peripheralManager.startAdvertising({
localName: name,
serviceUUIDs: servicesUUIDs
Expand Down Expand Up @@ -409,23 +431,146 @@ or the peripheral simulator in order to do the connection and data-exchange with
```
- Use `write` function from channel to write values

```
```
var newBuffer = Ti.createBuffer({ value: 'hello world' });
channel.write({
data: newBuffer
});
```

- Use `close` function to close channel

```
channel.close();
```

- Use `stopAdvertising` to stop advertising
```
peripheralManager.stopAdvertising();
```

- Use `closePeripheral` to close the peripheral after it is done with the peripheral operations. (Android only)
```
peripheralManager.closePeripheral();
```
# iBeacon Application (iOS Only)

## Follow basic steps to adverstise iBeacon:

- Use `initPeripheralManager` to create Peripheral Manager

```
var peripheralManager = BLE.initPeripheralManager();
```

- Use `createBeaconRegion` to create BeaconRegion

```
var beaconRegion = BLE.createBeaconRegion({
uuid: '135C8F13-6A2D-46ED-AA71-FB956FC23742',
major: 1,
minor: 100,
identifier: 'com.appcelerator.BluetoothLowEnergy.beacon'
});
```
- Once `peripheralManager` is in `BLE.MANAGER_STATE_POWERED_ON` state, start advertising using `startAdvertisingBeaconRegion`
```
peripheralManager.startAdvertisingBeaconRegion({
beaconRegion: beaconRegion
});
```

## Follow basic steps to create iBeacon Scanner application:

- Edit the `plist` with following `uses-permission` element to the ios plist section
```
<ti:app>
<ios>
<plist>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow Location permission</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Allow Location permission</string>
</plist>
</ios>
</ti:app>
```

- Use `initPeripheralManager` to create Region Manager

```
var regionManager = BLE.createRegionManager();
```
- Use `requestWhenInUseAuthorization` to request location permission
```
regionManager.requestWhenInUseAuthorization();
```

- Use `createBeaconRegion` to create BeaconRegion
```
var beaconRegion = BLE.createBeaconRegion({
uuid: '135C8F13-6A2D-46ED-AA71-FB956FC23742',
major: 1,
minor: 100,
identifier: 'com.appcelerator.BluetoothLowEnergy.beacon'
});
```

- Once `regionManager` is in `BLE.LOCATION_MANAGER_AUTHORIZATION_STATUS_AUTHORIZED_WHEN_IN_USE | BLE.LOCATION_MANAGER_AUTHORIZATION_STATUS_AUTHORIZED_ALWAYS` state, use `startRegionMonitoring` to start monitoring and start ranging using `startRangingBeaconsInRegion`
```
regionManager.startRegionMonitoring({
beaconRegion: beaconRegion
});
regionManager.startRangingBeaconsInRegion({
beaconRegion: beaconRegion
});
```

- Get ranged beacons from `didRangeBeacons` event and check `proximity` and `accuracy` to check beacon location

```
var didRangeBeacons = (e) => {
var becaons = e.beacons;
if (becaons.length === 0) {
alert('No beacon in range');
return;
}
var proximity = becaons[0].proximity;
var accuracy = becaons[0].accuracy;
switch (proximity) {
case BLE.BEACON_PROXIMITY_UNKNOWN:
alert('Beacon Location : UNKNOWN');
break;
case BLE.BEACON_PROXIMITY_IMMEDIATE:
alert('Beacon Location : IMMEDIATE (approx. ' + accuracy + 'm)');
break;
case BLE.BEACON_PROXIMITY_NEAR:
alert('Beacon Location : NEAR (approx. ' + accuracy + 'm)');
break;
case BLE.BEACON_PROXIMITY_FAR:
alert('Beacon Location : FAR (approx. ' + accuracy + 'm)');
break;
default:
alert('Beacon Location : UNKNOWN');
break;
}
};
regionManager.addEventListener('didRangeBeacons', didRangeBeacons);
```
- Use `stopRegionMonitoring` to stop monitoring and stop ranging using `stopRangingBeaconsInRegion`

```
regionManager.stopRegionMonitoring({
beaconRegion: beaconRegion
});
regionManager.stopRangingBeaconsInRegion({
beaconRegion: beaconRegion
});
```

## Read Data from TiBuffer
- you can access bytes from TiBuffer using:

Expand All @@ -438,6 +583,7 @@ or the peripheral simulator in order to do the connection and data-exchange with

- Please see the `example/` folder.
- Please see the `example/ImageTransferUsingChannelStream` folder for how to use channel stream API's to transfer bigger data like images.
- Please see the `example/beacon` folder for iBeacon sample.

## Observations

Expand All @@ -447,6 +593,10 @@ or the peripheral simulator in order to do the connection and data-exchange with
- It is observed with certain fitness watches (may be other BLE hardware too) that upon connecting them with android-central application, the connection gets auto-disconnected after certain period of time(ranging from immediately to up-to 50s or more).
The fix is to first pair your peripheral-device(watch or any other hardware) with android device via Settings->Bluetooth screen and then do the connection procedure from central-application.

### iOS

- Beacon do not have background support

## Building

Simply run `appc run -p ios --build-only` and `appc run -p android --build-only` which will compile and package your module.
Expand All @@ -459,4 +609,4 @@ Axway

## License

Copyright (c) 2020 by Axway, Inc. Please see the LICENSE file for further details.
Copyright (c) 2020 by Axway, Inc. Please see the LICENSE file for further details.
2 changes: 1 addition & 1 deletion android/manifest
Expand Up @@ -2,7 +2,7 @@
# this is your module manifest and used by Titanium
# during compilation, packaging, distribution, etc.
#
version: 1.0.0
version: 1.1.0
apiversion: 4
architectures: arm64-v8a armeabi-v7a x86 x86_64
description: Provides BluetoothLowEnergy module for Titanium applications.
Expand Down

0 comments on commit d05292d

Please sign in to comment.