Code Monkey home page Code Monkey logo

rn-contact-tracing's Introduction

RN-Contact-Tracing

NPM version License CI


WIP Library - Don't Use in Production


About

This is a react-native library for tracing close contact between 2 mobile devices by exchanging ephemeral tokens over BLE (Bluetooth Low Energy).

The library will do the following:

  1. Advertise message with specific service_uuid and generated ephemeral token
  2. Scan for for BLE signals with a specific service_uuid and store the relevant scanned data into local device storage
  3. Provide simple API for JS to init these tasks in background and retrieve the scanned tokens
  4. Integrate with a module that will provide ephemerally encrypted tokens (might be optional part of the lib)

There is a chance this lib will be updated after Google & Apple will release the full Contact Tracing API solution.

Challanges

  1. iOS limitation of using ble while the app in the background - link 
  2. Estimate the distance between 2 devices without violating user's privacy, using the data we can send over the ble

Working plan

Functionality Android iOS
Scan in foreground
Advertise in foreground
Scan in background TODO
Advertise in background TODO
Save scanned data into local DB
Return scanned data to JS
Pass scannng & advertising configuration from JS (intervals..)
Integration with tokens provider TODO TODO
Tests TODO TODO
Features for rssi calibration (GPS, Proximity) WIP TODO

Getting started

Example Project

The Example project can be used as a reference of how to use the rn-contact-tracing API and as a helpful tool to fine-tune the scanning/advertising configuration

How to run the example project

npm install
cd example/ios
pod install
For Android - npm run android 
For iOS - npm run ios

In Android - Click on Request Location Permission button

Installation

yarn add rn-contact-tracing

or

npm install rn-contact-tracing --save

Android - Steps to manually link the library

android/settings.gradle

include ':rn-contact-tracing'
project(':rn-contact-tracing').projectDir = new File(rootProject.projectDir, '../node_modules/rn-contact-tracing/lib/android')

android/app/build.gradle

dependencies {
   ...
   implementation project(":rn-contact-tracing")
}

android/app/src/main/.../MainApplication.java

On top, where imports are:

    import moh.gov.il.specialble.SpecialBlePackage;

Add the RNLocationPackage class to your list of exported packages.

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.asList(
            List<ReactPackage> packages = new PackageList(this).getPackages();
            ...
            packages.add(new SpecialBlePackage());
            ...
    );
}

Supported Platforms

  • iOS 10+
  • Android API 21+

Methods

Summary


Details

setConfig(config)

   SpecialBle.setConfig(config);

Sets configuration options that will be used in scanning & advertising tasks.

Parameters:

Name Type Required Description
config object Yes See below.

Supported options:

  • serviceUUID - the ServiceUUID which identify the BLE broadcast you are going to advertise and scan for.
  • scanDuration - scanning duration in milisec
  • scanInterval - the time in milisec between every scan
  • advertiseDuration - advertising duration in milisec (up to 180000ms)
  • advertiseInterval - the time in milisec between every advertising
  • token - temporary token to advertise (for testing)

For Android

  • advertiseTXPowerLevel - advertise TX power level docs
  • scanMatchMode - match mode for Bluetooth LE scan filters hardware match docs
  • notificationTitle - the title of the foreground service notification
  • notificationContent - the content of the foreground service notification

getConfig(callback)

   SpecialBle.getConfig((config) => {
    ....
   })

Gets the scanning & advertising configuration options that are currently defined in the library


startBLEService(config)

SpecialBle.startBLEService(config);

Starts BLE background task scanning for a specific - config is optional


stopBLEService()

SpecialBle.stopBLEService();

Stops the background service and all the tasks the service executing


startBLEScan(config)

SpecialBle.startBLEScan(config);

Starts BLE scanning in foreground - config is optional


stopBLEScan()

SpecialBle.stopBLEScan();

Starts BLE scanning


advertise(config)

SpecialBle.advertise(config);

Starts BLE advertising in foreground - config is optional


stopAdvertise()

SpecialBle.stopAdvertise();

Stops BLE advertising


getScansByKey(token, callback)

 SpecialBle.getScansByKey(token, (scans) => {
    ...
 })

Get list of scans events for a specific token, each object contains:

  • scan_id - unique id
  • scan_timestamp - epoch time of the scan event in
  • public_key - token key
  • scan_address - scaned device address
  • scan_rssi - rssi strength
  • scan_tx - tx strength
  • scan_protocol - the protocol used to scan the data (currently GAP/GATT)

getAllDevices()

 SpecialBle.getAllDevices((devices) => {
       setDevices(devices)
   })

Get list of unique devices that were scanned, each object contains:

  • device_first_timestamp - epoch time of the first scan event
  • device_last_timestamp - epoch time of the last scan event
  • public_key - token key
  • device_address - scaned device address
  • device_rssi - rssi strongest value
  • device_tx - tx strongest value
  • device_protocol - the protocol used to scan the data (currently GAP/GATT)

exportAllScansCsv()

 SpecialBle.exportAllScansCsv();

Export the full Scans events DB to csv file


exportAllDevicesCsv()

SpecialBle.exportAllDevicesCsv();

Export the full Devices DB to csv file


cleanDevicesDB()

SpecialBle.cleanDevicesDB();

Clear all scanned devices


cleanScansDB()

SpecialBle.cleanScansDB();

Clear all scans


Events from Native to JS

  • scanningStatus - event can be true/false
  • advertisingStatus - event can be true/false
  • foundDevice - event has 2 params: {event.device_name, event.device_address}
  • error - {event.error_message}

Why did we build this lib?

Due to COVID-19 pandemic, several groups and health authorities released apps that will help to identify and notify people that are at risk of exposure.

Some of these apps are written with RN and based on tracking user location which is not enough such as Hamagen, and they willing to add BLE based functionality.

There are lots of great libs that expose ble functionality for RN, i.e react-native-ble-plx & react-native-ble-manager but we wanted reduce the amount of dependancies as much as possible and exectue very specfic BLE functionality in background.

In addition, we looked at several great apps written for the same purpose in native, but each one of them is not written in a way that we could use as a stand-alone library. OpenTrace) - includes the full business logic (UI..) that we don't want to use. DP^3T Project - include cryptography logic that we prefer to replace

Privacy (what do we advertise and save to DB)

TBD

References

rn-contact-tracing's People

Contributors

amitmilstein avatar buttershub avatar codeagainstcovid avatar edwardigates avatar eitanschwartz avatar github-sheriff avatar gran33 avatar hagairotshild avatar jacobbarr1986 avatar oferdavidyan avatar tzufitltaboola avatar yonirimon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rn-contact-tracing's Issues

Collecting data for distance estimation ("RSSI calibration")

Hey fellows,

I work on collecting data for estimating distance using
BLE rssi, devices metadata, gyro data.

AKA "RSSI calibration".

I aim to do it in scale by collecting data using an application that measures distance with sound.

https://github.com/A4Vision/estimate-distance/

Hope we'll work together down the roadmap

If you happen to have more time than me for this goal, and you wish to advance
in the direction I purpose, feel free to contact me. Available on the phone (Oren and Yossi have my number).

getAllDevices() results in null

Hi,

I tried to create a sample app (below). I tried to write the minimal thing that wouldn't result in exceptions and might work. Unfortunately, when I load my code on two devices with both Location and Bluetooth permissions enabled, neither device picks up on the presence of the other device. There are no exceptions from this code initially, but after a few minutes, the app crashes for no apparent reason.

import React, { useState, useEffect } from "react";
import { Text } from "react-native";
import SpecialBle, { requestLocationPermission, checktLocationPermission } from "rn-contact-tracing";

const SERVICE_UUID = "00000000-0000-1000-8000-00805F9B34FB";

/*
const ScanMatchMode = [
    {value: 1, label: 'MATCH_MODE_AGGRESSIVE'},
    {value: 2, label: 'SCAN_MODE_LOW_LATENCY'},
];

const AdvertiseMode = [
    {value: 0, label: 'ADVERTISE_MODE_LOW_POWER'},
    {value: 1, label: 'ADVERTISE_MODE_BALANCED'},
    {value: 2, label: 'ADVERTISE_MODE_LOW_LATENCY'},
];

const AdvertiseTXPower = [
    {value: 0, label: 'ADVERTISE_TX_POWER_ULTRA_LOW'},
    {value: 1, label: 'ADVERTISE_TX_POWER_LOW'},
    {value: 2, label: 'ADVERTISE_TX_POWER_MEDIUM'},
    {value: 3, label: 'ADVERTISE_TX_POWER_HIGH'},
];
*/

const BluetoothScreen = () => {
    const [permissions, setPermissions] = useState({location: false, ignoreBatteryOpt: false});
    const [config, setConfig] = useState({
        serviceUUID: SERVICE_UUID,
        scanDuration: 10000,
        scanInterval: 10000,
        advertiseInterval: 10000,
        advertiseDuration: 10000,
        scanMatchMode: 1,
        advertiseMode: 2,
        advertiseTXPowerLevel: 1,
        notificationTitle: "Bluetooth",
        notificationContent: "Bluetooth",
        notificationLargeIconPath: "",
        notificationSmallIconPath: "",
        token: "default_token"
    });

    async function checkPermissions() {
        let isGranted = await checktLocationPermission();
        let ignoreBatteryOpt = await SpecialBle.isBatteryOptimizationDeactivated();
        setPermissions({...permissions, ...{location: isGranted, ignoreBatteryOpt: ignoreBatteryOpt}});
    }

    useEffect(() => {
        (async () => {
            console.log("module:", SpecialBle);

            console.log("permissions");
            await checkPermissions();

            console.log("database");
            await SpecialBle.writeContactsToDB(null);

            console.log("set config");
            await SpecialBle.setConfig(config);

            console.log("start ble service");
            await SpecialBle.startBLEService();

            console.log("advertise");
            await SpecialBle.advertise();

            console.log("start scan");
            await SpecialBle.startBLEScan();

            console.log("get all devices");
            await SpecialBle.getAllDevices(devices => {
                console.log(devices);
            });
        })();
    }, []);

    return (<Text>Bluetooth</Text>);
};

export default BluetoothScreen;
 LOG  module: {"advertise": [Function fn], "cleanDevicesDB": [Function fn], "cleanScansDB": [Function fn], "deleteDatabase": [Function fn], "exportAdvertiseAsCSV": [Function fn], "exportAllContactsAsCsv": [Function fn], "exportAllDevicesCsv": [Function fn], "exportAllScansCsv": [Function fn], "exportScansByKeyAsCSV": [Function fn], "exportScansDataAsCSV": [Function fn], "fetchInfectionDataByConsent": [Function fn], "getAllDevices": [Function fn], "getAllScans": [Function fn], "getConfig": [Function fn], "getConstants": [Function anonymous], "getScansByKey": [Function fn], "isBatteryOptimizationDeactivated": [Function fn], "match": [Function fn], "requestToDisableBatteryOptimization": [Function fn], "setConfig": [Function fn], "setPublicKeys": [Function fn], "startBLEScan": [Function fn], "startBLEService": [Function fn], "stopAdvertise": [Function fn], "stopBLEScan": [Function fn], "stopBLEService": [Function fn], "writeContactsToDB": [Function fn]}
 LOG  permissions
 LOG  database
 LOG  set config
 LOG  start ble service
 LOG  advertise
 LOG  start scan
 LOG  get all devices
 LOG  null

Rename wix component

This repository started it's life under Wix Incubator git repository at https://github.com/wix-incubator git (Thanks Wix Engineering for that).

We moved it under the MohGovIL account on June 25th (also see #80). To complete the transition we still need to replace wix strings in the code to BLE as to reduce confusion about the origin of this component.

Terminology

the term public key is not accurate
we should use the term token to tempID

App working but i see nothing in results

i have installed the exemple app on 3 different devices, Samsung A30, Samsung Galaxy, and Huawei Y7, i started the advertiser and the scan, but i cannot see anything in results even tho the bluetooth is activated and the application has been running in a while now

Example App not Working on Android

Hello, i have already deploy the example app on a few Android devices. I am running the app following the example.gif configurations. But on Results tab i can't see anything. Could you please provide me some feedback? Thanking you in advance.

New version

There is any way to add as a dependency the new version of plugin. I have realized that the version in npm is not the same that there is in git. Thanks!

Error handling in Android

We need to define an Error event that will be thrown to JS.
What kind of errors we might have:

  • No location permission
  • Bluetooth/location turned off - I guess we also need to listen on ACTION_STATE_CHANGED & PROVIDERS_CHANGED
  • All the errors we might get when turning on Advertise - in onStartFailure (we might want to ignore the ADVERTISE_FAILED_ALREADY_STARTED error)
  • All the errors we might get when turning on Scanning

Integrate methods used by NHS (non Exposure Notification API) for successful iOS background scanning

Given the TODO status of the iOS background scanning and advertising, I have been looking for a solution to allow for background iOS operations, without the need for the Apple Exposure Notification API (since it is locked to official government use only).

This article unpacks how the current NHS app can run iOS-to-Android and iOS-to-iOS in the background.

Code for this can be found here: https://github.com/nhsx/COVID-19-app-iOS-BETA

I will deeper into how rn-contact-tracing is currently accessing Bluetooth, as opposed to the NHS app above, and possibly make suggestions/ PR for getting this behaviour into rn-contact-tracing.

Do you guys think this is on the right track?

Not able to add dependency

facing the below issue while adding the dependency rn-contact-tracing:
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] postinstall: rm -rf ../node_modules
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] postinstall script.

tried both ways for adding dependency:
yarn add rn-contact-tracing and npm install rn-contact-tracing --save

No scans records found after night when application is off

Samsung S9+,LG G7

Scan
Interval - 5000ms
Duration - 55000ms

Advertise
Interval - 1800000ms
Duration - 10000

Samsung
Match mode - Aggressive
Advertise mode - balanced
Advertise tx power - low
LG
Match mode - Aggressive
Advertise mode - Low Power
Advertise tx power - Ultra

Split devDependencies into dependencies & devDependencies in package.json

Currently only devDependencies is used to declare dependencies in package.json file at:

"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/runtime": "^7.9.2",
"@react-native-community/blur": "^3.4.1",
"@react-native-community/datetimepicker": "^2.1.0",
"@react-native-community/eslint-config": "^1.0.0",
"@react-native-community/netinfo": "^5.6.2",
"@react-navigation/bottom-tabs": "^5.2.6",
"@react-navigation/native": "^5.1.5",
"babel-jest": "^25.2.6",
"eslint": "^6.8.0",
"jest": "^25.2.7",
"metro-react-native-babel-preset": "^0.59.0",
"react": "^16.9.0",
"react-native": "^0.61.5",
"react-native-gesture-handler": "^1.5.0",
"react-native-reanimated": "^1.4.0",
"@react-navigation/stack": "^5.2.11",
"@react-native-community/masked-view": "^0.1.9",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.5.0",
"react-native-ui-lib": "^5.6.0",
"react-test-renderer": "16.9.0",
"shelljs": "^0.8.3",
"@react-native-firebase/app": "^6.7.1",
"@react-native-firebase/crashlytics": "^6.7.1"
}

By splitting into dependencies and devDependencies it will reduce the packages installed when package install with --production argument ( or environment variable NODE_ENV=production declared ) which will install only packages declared in dependencies (for example: eslint & jest are probably devDependencies which are used only in testing/CI )

[Suggestion] QR code for shops

Users: allow to scan QR codes that will be placed at the entrance of the shop.

Shops: Generate unique QR codes to be printed and placed on its entrance.

Obviously I am not familiar with Hamagen 2.0 performance, however, I think it's a good idea that will contribute in two aspects:

  1. Assistance in the tracking of COVID-19 users.

  2. Decrease false-alarm rate - Hamagen 2.0 uses Bluetooth signal power and GPS to locate the user path and proximity to other users. Unfourtantly, GPS is not accurate enough and is limited in closed spaces and Bluetooth signal power might not be reliable since it is affected by many factors such as environment, phone types, etc. (I am speaking from experience as a former digital communication engineer, for more details see https://www.technologyreview.com/2020/04/22/1000353/bluetooth-contact-tracing-needs-bigger-better-data/). This will result in a lot of false alarms.
    For example, assume the following scenario: there are 2 persons, one is inside a store and the second is in the street outside or in a store nearby. If one of the persons is sick it might result in a false alarm for the second user because Bluetooth signal power might be high enough and GPS location will be inaccurate (closed space). This false alarm could be avoided by using QR codes which will help differentiate between the locations.

People already suggested using QR-codes in shops to improve app accuracy - see MohGovIL/hamagen-react-native#193. (I am reposting because I believe this suggestion is more relevant for this repo's issues).

Logger

Background
The algorithm people need real data in order to develop the proximity algorithm based on rssi.

Requirements v1
The app should use the rn-contact library - example project
The app should send and receive BLE packets in background every 100ms The data will include: Time stamp, device name, Data, Bssid, Rssi - just add in rn-contact params for interval ad the needed data
The data should be written in local db - done
The user will be able to extract a csv file and download it to device storage - extract to JS already done - they just need to push it to some file with JS

Requirements v2
Right after the packet was received sample the following sensors:
Location:long lat
Proximity
Rotation vector
Accelerometer
Battery level

Write it to db

Extract it to csv

Add build.config flavors

We have 2 different build.config:

  1. Demo/Development/Calibration - one of the names
  2. Release

the differences between these 2 configurations are:

  1. in Release, we should not bring any dependencies in Gradle (besides google services)
  2. in Release we have different functionality onScanResult (we will not measure GPS location, we will get is as part of the ble message).

Update or remove ios fastlane example code

The current fastlane example code uses a private repo (left over from an early development effort) at example/ios/fastlane/Matchfile.

The example isn't in use since may (632fd11) ... so we should either update the example or just remove it.

Google+apply Exposure Notifications

Can you consider using Google+apply Exposure Notifications?
From what I read, it's not efficient to use other BLE solution. The Google+apply solution is the only one that will keep bluetooth running in the background, and not go to sleep. I understand you don't want to give up GPS ability but it looks like other countries that refused to use it from the some reason are now going back to this solution after other options turned out to be ineffective.

Remove postinstall script "rm -rf ../node_modules"

From package.json:

"postinstall": "rm -rf ../node_modules",

it's harmful and not needed, why it's here?
if someone do (projects contain node_modules directory)

cd ./projects/
git clone --depth 1 https://github.com/MohGovIL/rn-contact-tracing/
cd rn-contact-tracing
yarn install

The node_modules in projects directory will be removed, which don't related to this repo at all.

Multiple phone open with the application, application cant see all phone

work with 6 phones
Samsung S9+,Samsung 6Ege,Samsung 6, LG G7,LG G6, LG G4
All identify by all using device BT
open the application on all devices
Scan - interval 55000, Duration 5000
Advertise - interval 50000, Duration 10000
not all phobe visible to all in the application result
LG4 - scan results - samsung6,samsung 9 and LG7
LG6 - scan results - samsung 6, LGG7,LGG4 and samsung S9
LG G7- scan results - samsung 6, LGG4 and Samsung S9
Samsung Galaxy 9+ - samsung 6, LGG4,LGG7
Samsung 6 - LGG4,Samsung S9, and LGG7
Samsung S6edge - samsung 6'LG G4'Samsung s9and LG G7

!
IMG_0012

Battery hogging on iOS

I noticed in the last few days a big drop in battery life on my iPhone 11 Pro Max.
After looking today in the battery screen image
Noticed המגן at the top of the list in both by activity and by battery usage.

Error running in Android

I am testing this library for a COVID-19 related project. After installing it and trying to run the project in Android device returns the following error:

Where:
Build file '/home/mlopez/git/RapidApp/node_modules/rn-contact->tracing/android/build.gradle' line: 104

What went wrong:
A problem occurred configuring project ':rn-contact-tracing'.
Cannot get property 'username' on null object`

I have noticed that in the package.json of the library an author is not specified but if you add it manually the app runs correctly. Am I doing something wrong?

Server side reference

I have set up the client-side successfully and the application is working perfectly fine. I need a server-side reference in order to set up the backend functionality for my application. A reference to a server-side set up will be of great help in developing my application. Any help is highly appreciated.

What is the typical worflow for usage

Hi Everyone,
Sorry if this is really obvious but i was wondering if someone can please explain what the typical workflow for this module should be? for instance

  1. Should all the installed mobile apps start scanning on the first screen based on a setInterval? The example app allows the user to initiate the scanning but that is just one use case.
  2. Should it scan and then advertise? and then repeat?
  3. When app is in the background what is the process to handle scanning?

My use case is for health contact tracing and i was just wondering how to setup using best practice.

Unable to develop a feasible server for the solution

Apologies for raising this as an issue, I am actively seeking assistance with designing server architecture for this.

What I have done so far:

  • app is running smoothly and all the exposed methods are tested.
  • I am able to send epoch keys to the server when a user consensually wants to share his positive data.
  • I am able to receive those keys on all clients when clients request server data.
  • I am accurately getting the results of the contact.

What is the issue that I am facing?

  • When sending all users positive data to all clients, I will be facing heavy egress data charges.
  • I am unable to come up with a server design to reduce those charges.

My questions-

  • Since there is a production-ready application for this, I want to understand how was this obstacle removed.
  • Is there a way to send some epoch keys to the server while requesting the server DB data to reduce the amount of data sent to all the clients? Some type of keys on which the server can filter the data.

I appreciate any response and request to redirect this question to the proper channel where questions can be asked.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.