feat(companion): implement ble
This commit is contained in:
2
aris/packages/ble/.eslintrc.js
Normal file
2
aris/packages/ble/.eslintrc.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// @generated by expo-module-scripts
|
||||
module.exports = require('expo-module-scripts/eslintrc.base.js');
|
||||
32
aris/packages/ble/README.md
Normal file
32
aris/packages/ble/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# @aris/ble
|
||||
|
||||
BLE peripheral module for the Aris companion app.
|
||||
|
||||
# API documentation
|
||||
|
||||
- [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/example.com/)
|
||||
- [Documentation for the main branch](https://docs.expo.dev/versions/unversioned/sdk/example.com/)
|
||||
|
||||
# Installation in managed Expo projects
|
||||
|
||||
For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects — it is likely to be included in an upcoming Expo SDK release.
|
||||
|
||||
# Installation in bare React Native projects
|
||||
|
||||
For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
|
||||
|
||||
### Add the package to your npm dependencies
|
||||
|
||||
```
|
||||
npm install @aris/ble
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Configure for iOS
|
||||
|
||||
Run `npx pod-install` after installing the npm package.
|
||||
|
||||
# Contributing
|
||||
|
||||
Contributions are very welcome! Please refer to guidelines described in the [contributing guide]( https://github.com/expo/expo#contributing).
|
||||
7
aris/packages/ble/expo-module.config.json
Normal file
7
aris/packages/ble/expo-module.config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"platforms": ["apple"],
|
||||
"apple": {
|
||||
"modules": ["ArisBleModule"],
|
||||
"appDelegateSubscribers": ["ArisBleAppDelegateSubscriber"]
|
||||
}
|
||||
}
|
||||
35
aris/packages/ble/package.json
Normal file
35
aris/packages/ble/package.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@aris/ble",
|
||||
"version": "0.1.0",
|
||||
"description": "BLE peripheral module for the Aris companion app.",
|
||||
"author": "Iris",
|
||||
"homepage": "https://example.com",
|
||||
"main": "build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"default": "./build/index.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "expo-module build",
|
||||
"clean": "expo-module clean",
|
||||
"lint": "expo-module lint",
|
||||
"test": "expo-module test",
|
||||
"prepare": "expo-module prepare",
|
||||
"prepublishOnly": "expo-module prepublishOnly",
|
||||
"expo-module": "expo-module"
|
||||
},
|
||||
"keywords": ["react-native", "expo", "ble"],
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"expo-module-scripts": "^5.0.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
}
|
||||
7
aris/packages/ble/src/index.ts
Normal file
7
aris/packages/ble/src/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export { Ble, defaultBleState } from "./native";
|
||||
export { BleBluetoothState } from "./types";
|
||||
export type {
|
||||
BleNativeModuleEvents,
|
||||
BleStatePayload,
|
||||
BleUuids,
|
||||
} from "./types";
|
||||
90
aris/packages/ble/src/native.ts
Normal file
90
aris/packages/ble/src/native.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { NativeModule, requireNativeModule } from "expo";
|
||||
import { Platform } from "react-native";
|
||||
import type { EventSubscription } from "expo-modules-core";
|
||||
|
||||
import {
|
||||
BleBluetoothState,
|
||||
type BleNativeModuleEvents,
|
||||
type BleStatePayload,
|
||||
type BleUuids,
|
||||
} from "./types";
|
||||
|
||||
declare class ArisBleNativeModule extends NativeModule<BleNativeModuleEvents> {
|
||||
start: () => void;
|
||||
stop: () => void;
|
||||
setAdvertisingEnabled: (enabled: boolean) => void;
|
||||
setWifiRequested: (requested: boolean) => void;
|
||||
sendOpaque: (payload: string, msgType?: number) => void;
|
||||
getState: () => BleStatePayload;
|
||||
serviceUUID: string;
|
||||
feedTxUUID: string;
|
||||
controlRxUUID: string;
|
||||
wifiRequestTxUUID: string;
|
||||
}
|
||||
|
||||
const isSupported = Platform.OS === "ios";
|
||||
|
||||
const nativeModule = isSupported
|
||||
? requireNativeModule<ArisBleNativeModule>("ArisBle")
|
||||
: null;
|
||||
|
||||
export const defaultBleState: BleStatePayload = {
|
||||
bluetoothState: BleBluetoothState.Unknown,
|
||||
advertisingEnabled: true,
|
||||
isAdvertising: false,
|
||||
isSubscribed: false,
|
||||
subscribedCount: 0,
|
||||
lastMsgIdSent: 0,
|
||||
lastPingAt: null,
|
||||
lastCommand: null,
|
||||
notifyQueueDepth: 0,
|
||||
droppedNotifyPackets: 0,
|
||||
lastNotifyAt: null,
|
||||
lastDataAt: null,
|
||||
wifiRequested: false,
|
||||
};
|
||||
|
||||
const emptyUuids: BleUuids = {
|
||||
serviceUUID: "",
|
||||
feedTxUUID: "",
|
||||
controlRxUUID: "",
|
||||
wifiRequestTxUUID: "",
|
||||
};
|
||||
|
||||
type BleApi = {
|
||||
isSupported: boolean;
|
||||
start: () => void;
|
||||
stop: () => void;
|
||||
setAdvertisingEnabled: (enabled: boolean) => void;
|
||||
setWifiRequested: (requested: boolean) => void;
|
||||
sendOpaque: (payload: string, msgType?: number) => void;
|
||||
getState: () => BleStatePayload;
|
||||
addStateListener: (
|
||||
listener: (state: BleStatePayload) => void,
|
||||
) => EventSubscription | undefined;
|
||||
getUuids: () => BleUuids;
|
||||
};
|
||||
|
||||
export const Ble: BleApi = {
|
||||
isSupported,
|
||||
start: () => nativeModule?.start?.(),
|
||||
stop: () => nativeModule?.stop?.(),
|
||||
setAdvertisingEnabled: (enabled: boolean) =>
|
||||
nativeModule?.setAdvertisingEnabled?.(enabled),
|
||||
setWifiRequested: (requested: boolean) =>
|
||||
nativeModule?.setWifiRequested?.(requested),
|
||||
sendOpaque: (payload: string, msgType?: number) =>
|
||||
nativeModule?.sendOpaque?.(payload, msgType),
|
||||
getState: () => nativeModule?.getState?.() ?? { ...defaultBleState },
|
||||
addStateListener: (listener: (state: BleStatePayload) => void) =>
|
||||
nativeModule?.addListener("onStateChange", listener),
|
||||
getUuids: (): BleUuids =>
|
||||
nativeModule
|
||||
? {
|
||||
serviceUUID: nativeModule.serviceUUID,
|
||||
feedTxUUID: nativeModule.feedTxUUID,
|
||||
controlRxUUID: nativeModule.controlRxUUID,
|
||||
wifiRequestTxUUID: nativeModule.wifiRequestTxUUID,
|
||||
}
|
||||
: emptyUuids,
|
||||
};
|
||||
39
aris/packages/ble/src/types.ts
Normal file
39
aris/packages/ble/src/types.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
export const BleBluetoothState = {
|
||||
Unknown: "Unknown",
|
||||
Resetting: "Resetting",
|
||||
Unsupported: "Unsupported",
|
||||
Unauthorized: "Unauthorized",
|
||||
PoweredOff: "Powered Off",
|
||||
PoweredOn: "Powered On",
|
||||
Other: "Other",
|
||||
} as const;
|
||||
|
||||
export type BleBluetoothState =
|
||||
(typeof BleBluetoothState)[keyof typeof BleBluetoothState];
|
||||
|
||||
export type BleStatePayload = {
|
||||
bluetoothState: BleBluetoothState;
|
||||
advertisingEnabled: boolean;
|
||||
isAdvertising: boolean;
|
||||
isSubscribed: boolean;
|
||||
subscribedCount: number;
|
||||
lastMsgIdSent: number;
|
||||
lastPingAt: number | null;
|
||||
lastCommand: string | null;
|
||||
notifyQueueDepth: number;
|
||||
droppedNotifyPackets: number;
|
||||
lastNotifyAt: number | null;
|
||||
lastDataAt: number | null;
|
||||
wifiRequested: boolean;
|
||||
};
|
||||
|
||||
export type BleUuids = {
|
||||
serviceUUID: string;
|
||||
feedTxUUID: string;
|
||||
controlRxUUID: string;
|
||||
wifiRequestTxUUID: string;
|
||||
};
|
||||
|
||||
export type BleNativeModuleEvents = {
|
||||
onStateChange: (state: BleStatePayload) => void;
|
||||
};
|
||||
9
aris/packages/ble/tsconfig.json
Normal file
9
aris/packages/ble/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
// @generated by expo-module-scripts
|
||||
{
|
||||
"extends": "expo-module-scripts/tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"outDir": "./build"
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["**/__mocks__/*", "**/__tests__/*", "**/__rsc_tests__/*"]
|
||||
}
|
||||
Reference in New Issue
Block a user