-
-
Notifications
You must be signed in to change notification settings - Fork 1
Error Handling & Debugging
Latisha. edited this page Dec 27, 2024
·
1 revision
enum BLEError: Error {
case deviceNotFound
case connectionFailed(String)
case serviceDiscoveryFailed
case characteristicNotFound
case timeout(operation: String)
case invalidState(String)
var description: String {
switch self {
case .deviceNotFound:
return "Device not found or out of range"
case .connectionFailed(let reason):
return "Connection failed: \(reason)"
case .serviceDiscoveryFailed:
return "Failed to discover required services"
case .characteristicNotFound:
return "Required characteristic not found"
case .timeout(let operation):
return "Operation timed out: \(operation)"
case .invalidState(let state):
return "Invalid state: \(state)"
}
}
}
enum ParserError: Error {
case invalidParameters
case parserCreationFailed(dc_status_t)
case datetimeRetrievalFailed(dc_status_t)
case sampleProcessingFailed(dc_status_t)
case invalidData(String)
}
enum DeviceError: Error {
case unsupportedDevice
case firmwareOutdated
case lowBattery
case busyState
case unauthorized
}
- Device Not Found
func troubleshootDeviceNotFound() -> [String] {
var checklist = [String]()
// Check Bluetooth state
if centralManager.state != .poweredOn {
checklist.append("Enable Bluetooth")
}
// Check device name
if let name = deviceName, name.isEmpty {
checklist.append("Verify device name")
}
// Check range
if let rssi = lastRSSI, rssi < -80 {
checklist.append("Move closer to device")
}
return checklist
}
- Connection Failures
func troubleshootConnection() async -> Bool {
// Check authorization
guard CBCentralManager.authorization == .allowedAlways else {
throw BLEError.unauthorized
}
// Verify device state
guard peripheral.state != .connected else {
try await disconnect()
}
// Attempt connection
do {
try await connect()
return true
} catch {
logError("Connection failed: \(error)")
return false
}
}
- Data Transfer Issues
func troubleshootTransfer() {
// Monitor transfer rate
let transferRate = calculateTransferRate()
if transferRate < minimumRate {
logWarning("Slow transfer rate: \(transferRate)")
}
// Check packet loss
let lossRate = calculatePacketLoss()
if lossRate > maxLossRate {
logError("High packet loss: \(lossRate)%")
}
}
public class Logger {
public static let shared = Logger()
private var isEnabled = true
private var minLevel: LogLevel = .debug
public enum LogLevel: Int {
case debug = 0
case info = 1
case warning = 2
case error = 3
var prefix: String {
switch self {
case .debug: return "🔍 DEBUG"
case .info: return "ℹ️ INFO"
case .warning: return "⚠️ WARN"
case .error: return "❌ ERROR"
}
}
}
public func log(_ message: String,
level: LogLevel = .debug,
file: String = #file,
function: String = #function) {
guard isEnabled && level.rawValue >= minLevel.rawValue else {
return
}
let timestamp = dateFormatter.string(from: Date())
let fileName = (file as NSString).lastPathComponent
print("\(level.prefix) [\(timestamp)] [\(fileName)] \(message)")
}
}
// Log levels
logDebug("Starting device scan")
logInfo("Device connected: \(deviceName)")
logWarning("Slow transfer rate detected")
logError("Failed to parse dive data: \(error)")
// Detailed logging
func logTransferStats() {
Logger.shared.log("""
Transfer Statistics:
- Bytes transferred: \(bytesTransferred)
- Transfer rate: \(transferRate) bytes/sec
- Packet loss: \(packetLoss)%
- Duration: \(duration) seconds
""",
level: .info
)
}
- State Monitor
class StateMonitor {
static func dumpState() {
print("=== System State ===")
print("BLE State: \(centralManager.state)")
print("Connected: \(connectedDevice != nil)")
print("Services: \(discoveredServices.count)")
print("Buffer Size: \(receivedData.count)")
print("==================")
}
}
- Packet Inspector
class PacketInspector {
static func inspectPacket(_ data: Data) {
print("Packet Size: \(data.count) bytes")
print("Hex: \(data.hexDescription)")
print("ASCII: \(data.asciiDescription)")
if data.count >= 2 {
let header = data.prefix(2)
print("Header: \(header.hexDescription)")
}
}
}
- Performance Monitor
class PerformanceMonitor {
private var timestamps: [String: Date] = [:]
func start(_ operation: String) {
timestamps[operation] = Date()
}
func end(_ operation: String) {
guard let startTime = timestamps[operation] else { return }
let duration = Date().timeIntervalSince(startTime)
logInfo("\(operation) took \(duration) seconds")
}
}
- Connection Debugging
func debugConnection() {
// Enable detailed logging
Logger.shared.setMinLevel(.debug)
Logger.shared.setShowRawData(true)
// Monitor state changes
centralManager.$state
.sink { state in
logDebug("BLE State changed: \(state)")
}
.store(in: &cancellables)
// Monitor connection events
peripheral.delegate = self
}
- Data Transfer Debugging
func debugTransfer() {
// Monitor chunks
func didReceiveData(_ data: Data) {
logDebug("""
Received chunk:
- Size: \(data.count)
- First bytes: \(data.prefix(4).hexDescription)
- Buffer size: \(receivedData.count)
""")
}
}
- Parser Debugging
func debugParsing(_ data: Data) {
// Validate structure
guard data.count >= minSize else {
logError("Invalid data size: \(data.count)")
return
}
// Check markers
let hasStartMarker = data.first == frameMarker
let hasEndMarker = data.last == frameMarker
logDebug("Markers: start=\(hasStartMarker), end=\(hasEndMarker)")
// Validate checksum
let checksumValid = validateChecksum(data)
logDebug("Checksum valid: \(checksumValid)")
}