add wifi request ble characteristic
This commit is contained in:
@@ -16,6 +16,8 @@ final class BlePeripheralManager: NSObject, ObservableObject {
|
||||
static let serviceUUID = CBUUID(string: "A0B0C0D0-E0F0-4A0B-9C0D-0E0F1A2B3C4D")
|
||||
static let feedTxUUID = CBUUID(string: "A0B0C0D1-E0F0-4A0B-9C0D-0E0F1A2B3C4D")
|
||||
static let controlRxUUID = CBUUID(string: "A0B0C0D2-E0F0-4A0B-9C0D-0E0F1A2B3C4D")
|
||||
// Read/Notify: 1-byte value (0x00=OFF, 0x01=ON) that requests Glass to enable Wi‑Fi.
|
||||
static let wifiRequestTxUUID = CBUUID(string: "A0B0C0D3-E0F0-4A0B-9C0D-0E0F1A2B3C4D")
|
||||
private static let restoreIdentifier = "iris.ble.peripheral.v1"
|
||||
|
||||
@Published private(set) var bluetoothState: CBManagerState = .unknown
|
||||
@@ -30,6 +32,7 @@ final class BlePeripheralManager: NSObject, ObservableObject {
|
||||
@Published private(set) var droppedNotifyPackets: Int = 0
|
||||
@Published private(set) var lastNotifyAt: Date? = nil
|
||||
@Published private(set) var lastDataAt: Date? = nil
|
||||
@Published private(set) var wifiRequested: Bool = false
|
||||
|
||||
private let queue = DispatchQueue(label: "iris.ble.peripheral.queue")
|
||||
private lazy var peripheral = CBPeripheralManager(
|
||||
@@ -43,10 +46,13 @@ final class BlePeripheralManager: NSObject, ObservableObject {
|
||||
private var service: CBMutableService?
|
||||
private var feedTx: CBMutableCharacteristic?
|
||||
private var controlRx: CBMutableCharacteristic?
|
||||
private var wifiRequestTx: CBMutableCharacteristic?
|
||||
|
||||
private var subscribedCentralIds = Set<UUID>()
|
||||
private var centralMaxUpdateLength: [UUID: Int] = [:]
|
||||
private var lastReadValue: Data = Data()
|
||||
private var wifiRequestValue: Data = Data([0x00])
|
||||
private var wifiRequestNotifyPending: Bool = false
|
||||
|
||||
private struct PendingMessage {
|
||||
let msgId: UInt32
|
||||
@@ -101,11 +107,23 @@ final class BlePeripheralManager: NSObject, ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
func setWifiRequested(_ requested: Bool) {
|
||||
queue.async { [weak self] in
|
||||
guard let self else { return }
|
||||
let newValue = Data([requested ? 0x01 : 0x00])
|
||||
guard newValue != self.wifiRequestValue else { return }
|
||||
self.wifiRequestValue = newValue
|
||||
self.publish { self.wifiRequested = requested }
|
||||
self.flushWifiRequestNotifyIfPossible()
|
||||
}
|
||||
}
|
||||
|
||||
func copyUUIDsToPasteboard() {
|
||||
let text = """
|
||||
SERVICE_UUID=\(Self.serviceUUID.uuidString)
|
||||
FEED_TX_UUID=\(Self.feedTxUUID.uuidString)
|
||||
CONTROL_RX_UUID=\(Self.controlRxUUID.uuidString)
|
||||
WIFI_REQUEST_TX_UUID=\(Self.wifiRequestTxUUID.uuidString)
|
||||
"""
|
||||
#if canImport(UIKit)
|
||||
DispatchQueue.main.async {
|
||||
@@ -116,6 +134,18 @@ final class BlePeripheralManager: NSObject, ObservableObject {
|
||||
|
||||
private func ensureService() {
|
||||
guard peripheral.state == .poweredOn else { return }
|
||||
|
||||
if let existingService = service {
|
||||
let hasWifiChar = (existingService.characteristics ?? []).contains { $0.uuid == Self.wifiRequestTxUUID }
|
||||
if wifiRequestTx == nil || !hasWifiChar {
|
||||
stopAdvertising()
|
||||
peripheral.removeAllServices()
|
||||
service = nil
|
||||
feedTx = nil
|
||||
controlRx = nil
|
||||
wifiRequestTx = nil
|
||||
}
|
||||
}
|
||||
guard service == nil else { return }
|
||||
|
||||
let feedTx = CBMutableCharacteristic(
|
||||
@@ -130,11 +160,18 @@ final class BlePeripheralManager: NSObject, ObservableObject {
|
||||
value: nil,
|
||||
permissions: [.writeable]
|
||||
)
|
||||
let wifiRequestTx = CBMutableCharacteristic(
|
||||
type: Self.wifiRequestTxUUID,
|
||||
properties: [.notify, .read],
|
||||
value: nil,
|
||||
permissions: [.readable]
|
||||
)
|
||||
let service = CBMutableService(type: Self.serviceUUID, primary: true)
|
||||
service.characteristics = [feedTx, controlRx]
|
||||
service.characteristics = [feedTx, controlRx, wifiRequestTx]
|
||||
self.service = service
|
||||
self.feedTx = feedTx
|
||||
self.controlRx = controlRx
|
||||
self.wifiRequestTx = wifiRequestTx
|
||||
peripheral.add(service)
|
||||
}
|
||||
|
||||
@@ -278,6 +315,20 @@ final class BlePeripheralManager: NSObject, ObservableObject {
|
||||
publishNotifyQueueDepth()
|
||||
}
|
||||
|
||||
private func flushWifiRequestNotifyIfPossible() {
|
||||
guard let wifiRequestTx else { return }
|
||||
let hasSubscribers = !(wifiRequestTx.subscribedCentrals ?? []).isEmpty
|
||||
guard hasSubscribers else {
|
||||
wifiRequestNotifyPending = false
|
||||
return
|
||||
}
|
||||
if peripheral.updateValue(wifiRequestValue, for: wifiRequestTx, onSubscribedCentrals: nil) {
|
||||
wifiRequestNotifyPending = false
|
||||
} else {
|
||||
wifiRequestNotifyPending = true
|
||||
}
|
||||
}
|
||||
|
||||
private func enqueuePendingMessage(_ message: PendingMessage) {
|
||||
pendingMessages.append(message)
|
||||
enforceNotifyQueueLimits()
|
||||
@@ -334,6 +385,7 @@ extension BlePeripheralManager: CBPeripheralManagerDelegate {
|
||||
self.service = restoredMutableService
|
||||
self.feedTx = characteristics.first(where: { $0.uuid == Self.feedTxUUID }) as? CBMutableCharacteristic
|
||||
self.controlRx = characteristics.first(where: { $0.uuid == Self.controlRxUUID }) as? CBMutableCharacteristic
|
||||
self.wifiRequestTx = characteristics.first(where: { $0.uuid == Self.wifiRequestTxUUID }) as? CBMutableCharacteristic
|
||||
}
|
||||
|
||||
self.publish {
|
||||
@@ -362,6 +414,7 @@ extension BlePeripheralManager: CBPeripheralManagerDelegate {
|
||||
self.service = nil
|
||||
self.feedTx = nil
|
||||
self.controlRx = nil
|
||||
self.wifiRequestTx = nil
|
||||
return
|
||||
}
|
||||
self.ensureService()
|
||||
@@ -380,6 +433,12 @@ extension BlePeripheralManager: CBPeripheralManagerDelegate {
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
|
||||
if characteristic.uuid == Self.wifiRequestTxUUID {
|
||||
queue.async { [weak self] in
|
||||
self?.flushWifiRequestNotifyIfPossible()
|
||||
}
|
||||
return
|
||||
}
|
||||
guard characteristic.uuid == Self.feedTxUUID else { return }
|
||||
queue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
@@ -400,6 +459,9 @@ extension BlePeripheralManager: CBPeripheralManagerDelegate {
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) {
|
||||
if characteristic.uuid == Self.wifiRequestTxUUID {
|
||||
return
|
||||
}
|
||||
guard characteristic.uuid == Self.feedTxUUID else { return }
|
||||
queue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
@@ -420,17 +482,25 @@ extension BlePeripheralManager: CBPeripheralManagerDelegate {
|
||||
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
|
||||
queue.async { [weak self] in
|
||||
self?.flushPendingMessages()
|
||||
if let self, self.wifiRequestNotifyPending {
|
||||
self.flushWifiRequestNotifyIfPossible()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
|
||||
guard request.characteristic.uuid == Self.feedTxUUID else {
|
||||
peripheral.respond(to: request, withResult: .requestNotSupported)
|
||||
let maxLen = max(0, request.central.maximumUpdateValueLength)
|
||||
if request.characteristic.uuid == Self.feedTxUUID {
|
||||
request.value = maxLen > 0 ? lastReadValue.prefix(maxLen) : lastReadValue
|
||||
peripheral.respond(to: request, withResult: .success)
|
||||
return
|
||||
}
|
||||
let maxLen = max(0, request.central.maximumUpdateValueLength)
|
||||
request.value = maxLen > 0 ? lastReadValue.prefix(maxLen) : lastReadValue
|
||||
peripheral.respond(to: request, withResult: .success)
|
||||
if request.characteristic.uuid == Self.wifiRequestTxUUID {
|
||||
request.value = maxLen > 0 ? wifiRequestValue.prefix(maxLen) : wifiRequestValue
|
||||
peripheral.respond(to: request, withResult: .success)
|
||||
return
|
||||
}
|
||||
peripheral.respond(to: request, withResult: .requestNotSupported)
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
|
||||
|
||||
@@ -34,6 +34,16 @@ struct BleStatusView: View {
|
||||
ble.start()
|
||||
}
|
||||
|
||||
Toggle(isOn: Binding(get: { ble.wifiRequested }, set: { ble.setWifiRequested($0) })) {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("Request Wi-Fi (Glass)")
|
||||
.font(.headline)
|
||||
Text(ble.wifiRequested ? "On" : "Off")
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Connection")
|
||||
.font(.headline)
|
||||
@@ -86,7 +96,7 @@ struct BleStatusView: View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("UUIDs")
|
||||
.font(.headline)
|
||||
Text("Service: \(BlePeripheralManager.serviceUUID.uuidString)\nFEED_TX: \(BlePeripheralManager.feedTxUUID.uuidString)\nCONTROL_RX: \(BlePeripheralManager.controlRxUUID.uuidString)")
|
||||
Text("Service: \(BlePeripheralManager.serviceUUID.uuidString)\nFEED_TX: \(BlePeripheralManager.feedTxUUID.uuidString)\nCONTROL_RX: \(BlePeripheralManager.controlRxUUID.uuidString)\nWIFI_REQUEST_TX: \(BlePeripheralManager.wifiRequestTxUUID.uuidString)")
|
||||
.font(.caption)
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<application
|
||||
|
||||
@@ -25,6 +25,7 @@ public final class BleCentralClient {
|
||||
void onConnected();
|
||||
void onPing();
|
||||
void onFeedJson(String json);
|
||||
void onWifiRequest(boolean requested);
|
||||
}
|
||||
|
||||
private static final UUID CCCD_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
|
||||
@@ -46,6 +47,7 @@ public final class BleCentralClient {
|
||||
private boolean scanning = false;
|
||||
private BluetoothDevice lastDevice = null;
|
||||
private BluetoothGatt gatt = null;
|
||||
private BluetoothGattDescriptor pendingWifiCccd = null;
|
||||
private boolean subscribed = false;
|
||||
|
||||
private long lastNotificationAtMs = 0L;
|
||||
@@ -265,6 +267,7 @@ public final class BleCentralClient {
|
||||
if (scanning) return;
|
||||
|
||||
subscribed = false;
|
||||
pendingWifiCccd = null;
|
||||
stopLivenessCheck();
|
||||
lastNotificationAtMs = 0L;
|
||||
lastPingAtMs = 0L;
|
||||
@@ -347,6 +350,24 @@ public final class BleCentralClient {
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothGattCharacteristic wifiRequestTx = service.getCharacteristic(Constants.WIFI_REQUEST_TX_UUID);
|
||||
if (wifiRequestTx != null) {
|
||||
Log.i(Constants.TAG_BLE, "Found characteristic " + Constants.WIFI_REQUEST_TX_UUID_STR + " (WIFI_REQUEST_TX)");
|
||||
Log.i(Constants.TAG_BLE, "Enabling notifications for WIFI_REQUEST_TX");
|
||||
boolean wifiNotifOk = gatt.setCharacteristicNotification(wifiRequestTx, true);
|
||||
Log.i(Constants.TAG_BLE, "setCharacteristicNotification(WIFI_REQUEST_TX)=" + wifiNotifOk);
|
||||
|
||||
BluetoothGattDescriptor wifiCccd = wifiRequestTx.getDescriptor(CCCD_UUID);
|
||||
if (wifiCccd == null) {
|
||||
Log.w(Constants.TAG_BLE, "Missing WIFI_REQUEST_TX CCCD (0x2902)");
|
||||
} else {
|
||||
wifiCccd.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
|
||||
pendingWifiCccd = wifiCccd;
|
||||
}
|
||||
} else {
|
||||
Log.w(Constants.TAG_BLE, "Missing characteristic " + Constants.WIFI_REQUEST_TX_UUID_STR + " (WIFI_REQUEST_TX)");
|
||||
}
|
||||
|
||||
BluetoothGattCharacteristic feedTx = service.getCharacteristic(Constants.FEED_TX_UUID);
|
||||
if (feedTx == null) {
|
||||
closeGattInternal();
|
||||
@@ -358,7 +379,7 @@ public final class BleCentralClient {
|
||||
Log.i(Constants.TAG_BLE, "Enabling notifications for FEED_TX");
|
||||
|
||||
boolean notifOk = gatt.setCharacteristicNotification(feedTx, true);
|
||||
Log.i(Constants.TAG_BLE, "setCharacteristicNotification=" + notifOk);
|
||||
Log.i(Constants.TAG_BLE, "setCharacteristicNotification(FEED_TX)=" + notifOk);
|
||||
|
||||
BluetoothGattDescriptor cccd = feedTx.getDescriptor(CCCD_UUID);
|
||||
if (cccd == null) {
|
||||
@@ -368,7 +389,7 @@ public final class BleCentralClient {
|
||||
}
|
||||
cccd.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
|
||||
boolean writeOk = gatt.writeDescriptor(cccd);
|
||||
Log.i(Constants.TAG_BLE, "writeDescriptor(CCCD)=" + writeOk);
|
||||
Log.i(Constants.TAG_BLE, "writeDescriptor(FEED CCCD)=" + writeOk);
|
||||
if (!writeOk) {
|
||||
closeGattInternal();
|
||||
scheduleReconnect("CCCD write failed to start");
|
||||
@@ -380,61 +401,93 @@ public final class BleCentralClient {
|
||||
if (descriptor == null) return;
|
||||
if (!CCCD_UUID.equals(descriptor.getUuid())) return;
|
||||
|
||||
Log.i(Constants.TAG_BLE, "onDescriptorWrite CCCD status=" + status);
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
BluetoothGattCharacteristic ch = descriptor.getCharacteristic();
|
||||
UUID chUuid = ch != null ? ch.getUuid() : null;
|
||||
Log.i(Constants.TAG_BLE, "onDescriptorWrite CCCD status=" + status + " char=" + chUuid);
|
||||
|
||||
if (status != BluetoothGatt.GATT_SUCCESS) {
|
||||
if (Constants.FEED_TX_UUID.equals(chUuid)) {
|
||||
closeGattInternal();
|
||||
scheduleReconnect("CCCD write failed: " + status);
|
||||
return;
|
||||
}
|
||||
if (Constants.WIFI_REQUEST_TX_UUID.equals(chUuid)) {
|
||||
Log.w(Constants.TAG_BLE, "WIFI_REQUEST_TX CCCD write failed: " + status);
|
||||
pendingWifiCccd = null;
|
||||
return;
|
||||
}
|
||||
closeGattInternal();
|
||||
scheduleReconnect("CCCD write failed: " + status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Constants.FEED_TX_UUID.equals(chUuid)) {
|
||||
subscribed = true;
|
||||
lastNotificationAtMs = System.currentTimeMillis();
|
||||
lastPingAtMs = 0L;
|
||||
startLivenessCheck();
|
||||
if (callback != null) callback.onStatus("Connected", null, true);
|
||||
} else {
|
||||
closeGattInternal();
|
||||
scheduleReconnect("CCCD write failed: " + status);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCharacteristicChanged(UUID uuid, byte[] value) {
|
||||
if (!Constants.FEED_TX_UUID.equals(uuid)) return;
|
||||
lastNotificationAtMs = System.currentTimeMillis();
|
||||
|
||||
FeedReassembler.Result result = reassembler.onNotification(value, lastNotificationAtMs);
|
||||
if (result == null) {
|
||||
// Diagnostic: log occasionally so we can infer the framing coming from iPhone.
|
||||
if (lastNotificationAtMs - lastUnparsedLogAtMs > 1000L) {
|
||||
lastUnparsedLogAtMs = lastNotificationAtMs;
|
||||
String hint = "";
|
||||
if (value != null && value.length >= 9) {
|
||||
long msgId = ((long) (value[0] & 0xFF))
|
||||
| ((long) (value[1] & 0xFF) << 8)
|
||||
| ((long) (value[2] & 0xFF) << 16)
|
||||
| ((long) (value[3] & 0xFF) << 24);
|
||||
int type = value[4] & 0xFF;
|
||||
int idx = (value[5] & 0xFF) | ((value[6] & 0xFF) << 8);
|
||||
int cnt = (value[7] & 0xFF) | ((value[8] & 0xFF) << 8);
|
||||
hint = " msgId=" + (msgId & 0xFFFFFFFFL) + " type=" + type + " chunk=" + idx + "/" + cnt;
|
||||
if (pendingWifiCccd != null) {
|
||||
boolean wifiWriteOk = gatt.writeDescriptor(pendingWifiCccd);
|
||||
Log.i(Constants.TAG_BLE, "writeDescriptor(WIFI CCCD)=" + wifiWriteOk);
|
||||
if (!wifiWriteOk) {
|
||||
Log.w(Constants.TAG_BLE, "WIFI_REQUEST_TX CCCD write failed to start");
|
||||
pendingWifiCccd = null;
|
||||
}
|
||||
Log.d(Constants.TAG_FEED, "Unparsed notify len=" + (value != null ? value.length : 0) + hint + " hex=" + hexPrefix(value, 16));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.isPing) {
|
||||
Log.d(Constants.TAG_FEED, "PING");
|
||||
lastPingAtMs = lastNotificationAtMs;
|
||||
if (callback != null) callback.onPing();
|
||||
return;
|
||||
if (Constants.WIFI_REQUEST_TX_UUID.equals(chUuid)) {
|
||||
Log.i(Constants.TAG_BLE, "Subscribed to WIFI_REQUEST_TX");
|
||||
pendingWifiCccd = null;
|
||||
}
|
||||
if (result.jsonOrNull != null) {
|
||||
Log.i(Constants.TAG_FEED, "Reassembled JSON (" + result.jsonOrNull.length() + " bytes)");
|
||||
Log.i(Constants.TAG_FEED, "RAW_JSON_BEGIN");
|
||||
logLarge(Constants.TAG_FEED, result.jsonOrNull);
|
||||
Log.i(Constants.TAG_FEED, "RAW_JSON_END");
|
||||
if (callback != null) callback.onFeedJson(result.jsonOrNull);
|
||||
}
|
||||
|
||||
private void handleCharacteristicChanged(UUID uuid, byte[] value) {
|
||||
if (Constants.WIFI_REQUEST_TX_UUID.equals(uuid)) {
|
||||
boolean requested = value != null && value.length > 0 && (value[0] & 0xFF) != 0;
|
||||
Log.i(Constants.TAG_BLE, "WIFI_REQUEST_TX notify=" + requested + " raw=" + hexPrefix(value, 1));
|
||||
if (callback != null) callback.onWifiRequest(requested);
|
||||
} else if (Constants.FEED_TX_UUID.equals(uuid)) {
|
||||
lastNotificationAtMs = System.currentTimeMillis();
|
||||
|
||||
FeedReassembler.Result result = reassembler.onNotification(value, lastNotificationAtMs);
|
||||
if (result == null) {
|
||||
// Diagnostic: log occasionally so we can infer the framing coming from iPhone.
|
||||
if (lastNotificationAtMs - lastUnparsedLogAtMs > 1000L) {
|
||||
lastUnparsedLogAtMs = lastNotificationAtMs;
|
||||
String hint = "";
|
||||
if (value != null && value.length >= 9) {
|
||||
long msgId = ((long) (value[0] & 0xFF))
|
||||
| ((long) (value[1] & 0xFF) << 8)
|
||||
| ((long) (value[2] & 0xFF) << 16)
|
||||
| ((long) (value[3] & 0xFF) << 24);
|
||||
int type = value[4] & 0xFF;
|
||||
int idx = (value[5] & 0xFF) | ((value[6] & 0xFF) << 8);
|
||||
int cnt = (value[7] & 0xFF) | ((value[8] & 0xFF) << 8);
|
||||
hint = " msgId=" + (msgId & 0xFFFFFFFFL) + " type=" + type + " chunk=" + idx + "/" + cnt;
|
||||
}
|
||||
Log.d(Constants.TAG_FEED, "Unparsed notify len=" + (value != null ? value.length : 0) + hint + " hex=" + hexPrefix(value, 16));
|
||||
}
|
||||
} else if (result.isPing) {
|
||||
Log.d(Constants.TAG_FEED, "PING");
|
||||
lastPingAtMs = lastNotificationAtMs;
|
||||
if (callback != null) callback.onPing();
|
||||
} else if (result.jsonOrNull != null) {
|
||||
Log.i(Constants.TAG_FEED, "Reassembled JSON (" + result.jsonOrNull.length() + " bytes)");
|
||||
Log.i(Constants.TAG_FEED, "RAW_JSON_BEGIN");
|
||||
logLarge(Constants.TAG_FEED, result.jsonOrNull);
|
||||
Log.i(Constants.TAG_FEED, "RAW_JSON_END");
|
||||
if (callback != null) callback.onFeedJson(result.jsonOrNull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void closeGattInternal() {
|
||||
subscribed = false;
|
||||
pendingWifiCccd = null;
|
||||
stopLivenessCheck();
|
||||
handler.removeCallbacks(connectTimeoutRunnable);
|
||||
if (gatt != null) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package sh.nym.irisglass;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -92,6 +94,11 @@ public final class BleLinkService extends Service implements BleCentralClient.Ca
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWifiRequest(boolean requested) {
|
||||
setWifiEnabled(requested);
|
||||
}
|
||||
|
||||
private void maybeNudgeWinnerChanged(FeedEnvelope env) {
|
||||
if (env == null) return;
|
||||
|
||||
@@ -122,4 +129,11 @@ public final class BleLinkService extends Service implements BleCentralClient.Ca
|
||||
i.putExtra(Constants.EXTRA_WINNER_ID, winnerId);
|
||||
startService(i);
|
||||
}
|
||||
|
||||
private void setWifiEnabled(boolean enabled) {
|
||||
WifiManager wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
|
||||
if (wifiManager != null) {
|
||||
wifiManager.setWifiEnabled(enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,12 @@ public final class Constants {
|
||||
public static final String SERVICE_UUID_STR = "A0B0C0D0-E0F0-4A0B-9C0D-0E0F1A2B3C4D";
|
||||
public static final String FEED_TX_UUID_STR = "A0B0C0D1-E0F0-4A0B-9C0D-0E0F1A2B3C4D";
|
||||
public static final String CONTROL_RX_UUID_STR = "A0B0C0D2-E0F0-4A0B-9C0D-0E0F1A2B3C4D";
|
||||
public static final String WIFI_REQUEST_TX_UUID_STR = "A0B0C0D3-E0F0-4A0B-9C0D-0E0F1A2B3C4D";
|
||||
|
||||
public static final UUID SERVICE_UUID = UUID.fromString(SERVICE_UUID_STR);
|
||||
public static final UUID FEED_TX_UUID = UUID.fromString(FEED_TX_UUID_STR);
|
||||
public static final UUID CONTROL_RX_UUID = UUID.fromString(CONTROL_RX_UUID_STR);
|
||||
public static final UUID WIFI_REQUEST_TX_UUID = UUID.fromString(WIFI_REQUEST_TX_UUID_STR);
|
||||
|
||||
public static final String PERIPHERAL_NAME_HINT = "Aris";
|
||||
public static final String LEGACY_PERIPHERAL_NAME_HINT = "GlassNow";
|
||||
|
||||
Reference in New Issue
Block a user