mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-12 00:40:28 +00:00
feat: Update project version to 42 and enhance advertisement handling in BLE service
This commit is contained in:
Binary file not shown.
BIN
ios/Runner.ipa
BIN
ios/Runner.ipa
Binary file not shown.
@@ -489,7 +489,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 41;
|
CURRENT_PROJECT_VERSION = 42;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -511,7 +511,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 41;
|
CURRENT_PROJECT_VERSION = 42;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
@@ -530,7 +530,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 41;
|
CURRENT_PROJECT_VERSION = 42;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
@@ -547,7 +547,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 41;
|
CURRENT_PROJECT_VERSION = 42;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
@@ -679,7 +679,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 41;
|
CURRENT_PROJECT_VERSION = 42;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -702,7 +702,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 41;
|
CURRENT_PROJECT_VERSION = 42;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>41</string>
|
<string>42</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSBluetoothAlwaysUsageDescription</key>
|
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||||
|
|||||||
@@ -245,6 +245,25 @@ class AppProvider with ChangeNotifier {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// When an advertisement is received (PUSH_CODE_ADVERT 0x80)
|
||||||
|
// This may be sent by the radio for existing contacts instead of PUSH_CODE_NEW_ADVERT (0x8A)
|
||||||
|
connectionProvider.onAdvertReceived = (publicKey) {
|
||||||
|
debugPrint('📡 [AppProvider] Advertisement received: ${publicKey.sublist(0, 6).map((b) => b.toRadixString(16).padLeft(2, '0')).join(':')}...');
|
||||||
|
// Check if this is an existing contact that might have updated location
|
||||||
|
final contact = contactsProvider.findContactByKey(publicKey);
|
||||||
|
if (contact != null) {
|
||||||
|
debugPrint(' Existing contact "${contact.advName}" - triggering contact sync for updates');
|
||||||
|
// Trigger a contact sync to get the updated contact information
|
||||||
|
Future.delayed(const Duration(milliseconds: 100), () {
|
||||||
|
if (connectionProvider.deviceInfo.isConnected) {
|
||||||
|
connectionProvider.getContacts();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
debugPrint(' New contact - waiting for PUSH_CODE_NEW_ADVERT (0x8A) with full details');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// When a message is sent (RESP_CODE_SENT received)
|
// When a message is sent (RESP_CODE_SENT received)
|
||||||
connectionProvider.onMessageSent = (messageId, expectedAckTag, suggestedTimeoutMs) {
|
connectionProvider.onMessageSent = (messageId, expectedAckTag, suggestedTimeoutMs) {
|
||||||
debugPrint('📤 [AppProvider] Message sent - Message ID: $messageId, ACK tag: $expectedAckTag');
|
debugPrint('📤 [AppProvider] Message sent - Message ID: $messageId, ACK tag: $expectedAckTag');
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
Function(int channelIdx, String channelName)? onChannelInfoReceived;
|
Function(int channelIdx, String channelName)? onChannelInfoReceived;
|
||||||
Function(Uint8List publicKeyPrefix, int tag, Uint8List responseData)?
|
Function(Uint8List publicKeyPrefix, int tag, Uint8List responseData)?
|
||||||
onBinaryResponse;
|
onBinaryResponse;
|
||||||
|
Function(Uint8List publicKey)? onAdvertReceived;
|
||||||
Function(Uint8List publicKey)? onPathUpdated;
|
Function(Uint8List publicKey)? onPathUpdated;
|
||||||
Function(Uint8List publicKeyPrefix, int permissions, bool isAdmin, int tag)?
|
Function(Uint8List publicKeyPrefix, int permissions, bool isAdmin, int tag)?
|
||||||
onLoginSuccess;
|
onLoginSuccess;
|
||||||
@@ -262,10 +263,14 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_bleService.onContactReceived = (contact) {
|
_bleService.onContactReceived = (contact) {
|
||||||
|
debugPrint('📥 [Provider] Contact received (0x8A): "${contact.advName}"');
|
||||||
|
debugPrint(' Forwarding to AppProvider via onContactReceived callback');
|
||||||
onContactReceived?.call(contact);
|
onContactReceived?.call(contact);
|
||||||
};
|
};
|
||||||
|
|
||||||
_bleService.onContactsComplete = (contacts) {
|
_bleService.onContactsComplete = (contacts) {
|
||||||
|
debugPrint('📥 [Provider] Contacts sync complete: ${contacts.length} contacts');
|
||||||
|
debugPrint(' Forwarding to AppProvider via onContactsComplete callback');
|
||||||
onContactsComplete?.call(contacts);
|
onContactsComplete?.call(contacts);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -286,8 +291,14 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_bleService.onTelemetryReceived = (publicKey, lppData) {
|
_bleService.onTelemetryReceived = (publicKey, lppData) {
|
||||||
|
debugPrint('📥 [Provider] Telemetry response (0x8B) received');
|
||||||
|
debugPrint(
|
||||||
|
' Public key: ${publicKey.sublist(0, 6).map((b) => b.toRadixString(16).padLeft(2, '0')).join(':')}...',
|
||||||
|
);
|
||||||
|
debugPrint(' LPP data: ${lppData.length} bytes');
|
||||||
// Mark ping as successful if this was a ping request
|
// Mark ping as successful if this was a ping request
|
||||||
_pingTracker.markPingSuccessful(publicKey);
|
_pingTracker.markPingSuccessful(publicKey);
|
||||||
|
debugPrint(' Forwarding to AppProvider via onTelemetryReceived callback');
|
||||||
onTelemetryReceived?.call(publicKey, lppData);
|
onTelemetryReceived?.call(publicKey, lppData);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -362,11 +373,10 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
debugPrint(
|
debugPrint(
|
||||||
' Public key: ${publicKey.sublist(0, 6).map((b) => b.toRadixString(16).padLeft(2, '0')).join(':')}...',
|
' Public key: ${publicKey.sublist(0, 6).map((b) => b.toRadixString(16).padLeft(2, '0')).join(':')}...',
|
||||||
);
|
);
|
||||||
debugPrint(
|
// Forward to AppProvider to trigger contact update
|
||||||
' Note: Waiting for PUSH_CODE_NEW_ADVERT (0x8A) with full contact details',
|
// The radio may send only PUSH_CODE_ADVERT (0x80) for existing contacts
|
||||||
);
|
// instead of PUSH_CODE_NEW_ADVERT (0x8A), so we need to handle this
|
||||||
// The companion radio will automatically send PUSH_CODE_NEW_ADVERT if manual_add_contacts=0
|
onAdvertReceived?.call(publicKey);
|
||||||
// which will trigger onContactReceived callback and add/update the contact
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_bleService.onPathUpdated = (publicKey) {
|
_bleService.onPathUpdated = (publicKey) {
|
||||||
|
|||||||
@@ -409,11 +409,13 @@ class BleResponseHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle Advert push
|
/// Handle Advert push (0x80) - basic advertisement with public key only
|
||||||
void _handleAdvert(BufferReader reader) {
|
void _handleAdvert(BufferReader reader) {
|
||||||
try {
|
try {
|
||||||
final publicKey = FrameParser.parseAdvert(reader);
|
final publicKey = FrameParser.parseAdvert(reader);
|
||||||
if (publicKey != null) {
|
if (publicKey != null) {
|
||||||
|
final shortKey = publicKey.sublist(0, 8).map((b) => b.toRadixString(16).padLeft(2, '0')).join('');
|
||||||
|
debugPrint(' ✅ [Advert 0x80] From node: $shortKey... (public key only, no location data)');
|
||||||
onAdvertReceived?.call(publicKey);
|
onAdvertReceived?.call(publicKey);
|
||||||
}
|
}
|
||||||
debugPrint(' ✅ [Advert] Parsed successfully');
|
debugPrint(' ✅ [Advert] Parsed successfully');
|
||||||
@@ -856,14 +858,20 @@ class BleResponseHandler {
|
|||||||
debugPrint(' 🧹 [Echo] Cleaned up ${toRemove.length} old trackers');
|
debugPrint(' 🧹 [Echo] Cleaned up ${toRemove.length} old trackers');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle NewAdvert push
|
/// Handle NewAdvert push (0x8A) - full contact info with location
|
||||||
void _handleNewAdvert(BufferReader reader) {
|
void _handleNewAdvert(BufferReader reader) {
|
||||||
try {
|
try {
|
||||||
final contact = FrameParser.parseContact(reader);
|
final contact = FrameParser.parseContact(reader);
|
||||||
debugPrint(' ✅ [NewAdvert] Parsed successfully: ${contact.advName}');
|
debugPrint(' ✅ [NewAdvert 0x8A] Parsed successfully: ${contact.advName}');
|
||||||
debugPrint(
|
debugPrint(
|
||||||
' outPathLen: ${contact.outPathLen} (${contact.pathDescription})',
|
' outPathLen: ${contact.outPathLen} (${contact.pathDescription})',
|
||||||
);
|
);
|
||||||
|
if (contact.advLat != 0 || contact.advLon != 0) {
|
||||||
|
final location = contact.advertLocation;
|
||||||
|
if (location != null) {
|
||||||
|
debugPrint(' 📍 Location: ${location.latitude}, ${location.longitude}');
|
||||||
|
}
|
||||||
|
}
|
||||||
onContactReceived?.call(contact);
|
onContactReceived?.call(contact);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint(' ❌ [NewAdvert] Parsing error: $e');
|
debugPrint(' ❌ [NewAdvert] Parsing error: $e');
|
||||||
|
|||||||
@@ -122,15 +122,19 @@ class MeshCoreBleService {
|
|||||||
|
|
||||||
// Response handler callbacks
|
// Response handler callbacks
|
||||||
_responseHandler.onContactReceived = (contact) {
|
_responseHandler.onContactReceived = (contact) {
|
||||||
|
debugPrint('🔔 [BleService] onContactReceived - "${contact.advName}" - forwarding to ConnectionProvider');
|
||||||
onContactReceived?.call(contact);
|
onContactReceived?.call(contact);
|
||||||
};
|
};
|
||||||
_responseHandler.onContactsComplete = (contacts) {
|
_responseHandler.onContactsComplete = (contacts) {
|
||||||
|
debugPrint('🔔 [BleService] onContactsComplete - ${contacts.length} contacts - forwarding to ConnectionProvider');
|
||||||
onContactsComplete?.call(contacts);
|
onContactsComplete?.call(contacts);
|
||||||
};
|
};
|
||||||
_responseHandler.onMessageReceived = (message) {
|
_responseHandler.onMessageReceived = (message) {
|
||||||
|
debugPrint('🔔 [BleService] onMessageReceived - forwarding to ConnectionProvider');
|
||||||
onMessageReceived?.call(message);
|
onMessageReceived?.call(message);
|
||||||
};
|
};
|
||||||
_responseHandler.onTelemetryReceived = (publicKey, lppData) {
|
_responseHandler.onTelemetryReceived = (publicKey, lppData) {
|
||||||
|
debugPrint('🔔 [BleService] onTelemetryReceived - ${lppData.length} bytes - forwarding to ConnectionProvider');
|
||||||
onTelemetryReceived?.call(publicKey, lppData);
|
onTelemetryReceived?.call(publicKey, lppData);
|
||||||
};
|
};
|
||||||
_responseHandler.onSelfInfoReceived = (selfInfo) {
|
_responseHandler.onSelfInfoReceived = (selfInfo) {
|
||||||
@@ -160,9 +164,11 @@ class MeshCoreBleService {
|
|||||||
onLoginFail?.call(publicKeyPrefix);
|
onLoginFail?.call(publicKeyPrefix);
|
||||||
};
|
};
|
||||||
_responseHandler.onAdvertReceived = (publicKey) {
|
_responseHandler.onAdvertReceived = (publicKey) {
|
||||||
|
debugPrint('🔔 [BleService] onAdvertReceived - forwarding to ConnectionProvider');
|
||||||
onAdvertReceived?.call(publicKey);
|
onAdvertReceived?.call(publicKey);
|
||||||
};
|
};
|
||||||
_responseHandler.onPathUpdated = (publicKey) {
|
_responseHandler.onPathUpdated = (publicKey) {
|
||||||
|
debugPrint('🔔 [BleService] onPathUpdated - forwarding to ConnectionProvider');
|
||||||
onPathUpdated?.call(publicKey);
|
onPathUpdated?.call(publicKey);
|
||||||
};
|
};
|
||||||
_responseHandler.onMessageSent =
|
_responseHandler.onMessageSent =
|
||||||
|
|||||||
Reference in New Issue
Block a user