Merge branch 'main' into routingOpt

This commit is contained in:
callebtc
2025-07-13 17:20:49 +02:00
43 changed files with 746 additions and 738 deletions
@@ -132,16 +132,16 @@ class BluetoothConnectionManager(
try {
isActive = true
// Setup GATT server first
setupGattServer()
// Start power manager and services
connectionScope.launch {
powerManager.start()
// Setup GATT server after power manager is ready
setupGattServer()
delay(500) // Ensure GATT server is ready
delay(300) // Brief delay to ensure GATT server is ready
startAdvertising()
delay(200)
delay(100)
if (powerManager.shouldUseDutyCycle()) {
Log.i(TAG, "Using power-aware duty cycling")
@@ -472,10 +472,15 @@ class BluetoothConnectionManager(
}
if (characteristic.uuid == CHARACTERISTIC_UUID) {
Log.d(TAG, "Server: Received packet from ${device.address}, size: ${value.size} bytes")
val packet = BitchatPacket.fromBinaryData(value)
if (packet != null) {
val peerID = String(packet.senderID).replace("\u0000", "")
Log.d(TAG, "Server: Parsed packet type ${packet.type} from $peerID")
delegate?.onPacketReceived(packet, peerID, device)
} else {
Log.w(TAG, "Server: Failed to parse packet from ${device.address}, size: ${value.size} bytes")
Log.w(TAG, "Server: Packet data: ${value.joinToString(" ") { "%02x".format(it) }}")
}
if (responseNeeded) {
@@ -520,48 +525,47 @@ class BluetoothConnectionManager(
// Proper cleanup sequencing to prevent race conditions
gattServer?.let { server ->
Log.d(TAG, "Cleaning up existing GATT server")
connectionScope.launch {
// Give time for pending callbacks to complete
delay(100)
try {
server.close()
} catch (e: Exception) {
Log.w(TAG, "Error closing existing GATT server: ${e.message}")
}
}
// Create new server after cleanup delay
connectionScope.launch {
delay(200) // Allow previous server to fully close
if (!isActive) {
Log.d(TAG, "Service inactive, skipping GATT server creation")
return@launch
}
gattServer = bluetoothManager.openGattServer(context, serverCallback)
// Create characteristic with notification support
characteristic = BluetoothGattCharacteristic(
CHARACTERISTIC_UUID,
BluetoothGattCharacteristic.PROPERTY_READ or
BluetoothGattCharacteristic.PROPERTY_WRITE or
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or
BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ or
BluetoothGattCharacteristic.PERMISSION_WRITE
)
val descriptor = BluetoothGattDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"),
BluetoothGattDescriptor.PERMISSION_READ or BluetoothGattDescriptor.PERMISSION_WRITE
)
characteristic?.addDescriptor(descriptor)
val service = BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY)
service.addCharacteristic(characteristic)
gattServer?.addService(service)
Log.i(TAG, "GATT server setup complete")
// Small delay to ensure cleanup is complete
Thread.sleep(100)
if (!isActive) {
Log.d(TAG, "Service inactive, skipping GATT server creation")
return
}
// Create new server
gattServer = bluetoothManager.openGattServer(context, serverCallback)
// Create characteristic with notification support
characteristic = BluetoothGattCharacteristic(
CHARACTERISTIC_UUID,
BluetoothGattCharacteristic.PROPERTY_READ or
BluetoothGattCharacteristic.PROPERTY_WRITE or
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or
BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ or
BluetoothGattCharacteristic.PERMISSION_WRITE
)
val descriptor = BluetoothGattDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"),
BluetoothGattDescriptor.PERMISSION_READ or BluetoothGattDescriptor.PERMISSION_WRITE
)
characteristic?.addDescriptor(descriptor)
val service = BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY)
service.addCharacteristic(characteristic)
gattServer?.addService(service)
Log.i(TAG, "GATT server setup complete")
}
@Suppress("DEPRECATION")
@@ -898,10 +902,15 @@ class BluetoothConnectionManager(
override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
val value = characteristic.value
Log.d(TAG, "Client: Received packet from ${gatt.device.address}, size: ${value.size} bytes")
val packet = BitchatPacket.fromBinaryData(value)
if (packet != null) {
val peerID = String(packet.senderID).replace("\u0000", "")
Log.d(TAG, "Client: Parsed packet type ${packet.type} from $peerID")
delegate?.onPacketReceived(packet, peerID, gatt.device)
} else {
Log.w(TAG, "Client: Failed to parse packet from ${gatt.device.address}, size: ${value.size} bytes")
Log.w(TAG, "Client: Packet data: ${value.joinToString(" ") { "%02x".format(it) }}")
}
}
}
@@ -70,10 +70,10 @@ class BluetoothMeshService(private val context: Context) {
while (isActive) {
try {
delay(10000) // 10 seconds
val debugInfo = getDebugStatus()
Log.d(TAG, "=== PERIODIC DEBUG STATUS ===")
Log.d(TAG, debugInfo)
Log.d(TAG, "=== END DEBUG STATUS ===")
if (isActive) { // Double-check before logging
val debugInfo = getDebugStatus()
Log.d(TAG, "=== PERIODIC DEBUG STATUS ===\n$debugInfo\n=== END DEBUG STATUS ===")
}
} catch (e: Exception) {
Log.e(TAG, "Error in periodic debug logging: ${e.message}")
}
@@ -287,7 +287,7 @@ class BluetoothMeshService(private val context: Context) {
* Start the mesh service
*/
fun startServices() {
// Prevent double starts
// Prevent double starts (defensive programming)
if (isActive) {
Log.w(TAG, "Mesh service already active, ignoring duplicate start request")
return
@@ -302,9 +302,7 @@ class BluetoothMeshService(private val context: Context) {
// Send initial announcements after services are ready
serviceScope.launch {
delay(1000)
if (isActive) { // Check if still active
sendBroadcastAnnounce()
}
sendBroadcastAnnounce()
}
} else {
Log.e(TAG, "Failed to start Bluetooth services")