homebridge 2.0.0-beta.30 → 2.0.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +267 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +92 -0
- package/dist/api.js.map +1 -1
- package/dist/bridgeService.d.ts +4 -2
- package/dist/bridgeService.d.ts.map +1 -1
- package/dist/bridgeService.js +1 -3
- package/dist/bridgeService.js.map +1 -1
- package/dist/childBridgeFork.d.ts +29 -2
- package/dist/childBridgeFork.d.ts.map +1 -1
- package/dist/childBridgeFork.js +294 -4
- package/dist/childBridgeFork.js.map +1 -1
- package/dist/childBridgeService.d.ts +19 -0
- package/dist/childBridgeService.d.ts.map +1 -1
- package/dist/childBridgeService.js +38 -3
- package/dist/childBridgeService.js.map +1 -1
- package/dist/externalPortService.d.ts +27 -6
- package/dist/externalPortService.d.ts.map +1 -1
- package/dist/externalPortService.js +73 -7
- package/dist/externalPortService.js.map +1 -1
- package/dist/index.d.ts +47 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/ipcService.d.ts +20 -0
- package/dist/ipcService.d.ts.map +1 -1
- package/dist/ipcService.js.map +1 -1
- package/dist/logger.d.ts +6 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +8 -0
- package/dist/logger.js.map +1 -1
- package/dist/matter/index.d.ts +123 -0
- package/dist/matter/index.d.ts.map +1 -0
- package/dist/matter/index.js +19 -0
- package/dist/matter/index.js.map +1 -0
- package/dist/matter/matterAccessoryCache.d.ts +96 -0
- package/dist/matter/matterAccessoryCache.d.ts.map +1 -0
- package/dist/matter/matterAccessoryCache.js +192 -0
- package/dist/matter/matterAccessoryCache.js.map +1 -0
- package/dist/matter/matterBehaviors.d.ts +194 -0
- package/dist/matter/matterBehaviors.d.ts.map +1 -0
- package/dist/matter/matterBehaviors.js +665 -0
- package/dist/matter/matterBehaviors.js.map +1 -0
- package/dist/matter/matterConfigValidator.d.ts +81 -0
- package/dist/matter/matterConfigValidator.d.ts.map +1 -0
- package/dist/matter/matterConfigValidator.js +240 -0
- package/dist/matter/matterConfigValidator.js.map +1 -0
- package/dist/matter/matterErrorHandler.d.ts +106 -0
- package/dist/matter/matterErrorHandler.d.ts.map +1 -0
- package/dist/matter/matterErrorHandler.js +495 -0
- package/dist/matter/matterErrorHandler.js.map +1 -0
- package/dist/matter/matterLogFormatter.d.ts +19 -0
- package/dist/matter/matterLogFormatter.d.ts.map +1 -0
- package/dist/matter/matterLogFormatter.js +144 -0
- package/dist/matter/matterLogFormatter.js.map +1 -0
- package/dist/matter/matterNetworkMonitor.d.ts +68 -0
- package/dist/matter/matterNetworkMonitor.d.ts.map +1 -0
- package/dist/matter/matterNetworkMonitor.js +249 -0
- package/dist/matter/matterNetworkMonitor.js.map +1 -0
- package/dist/matter/matterServer.d.ts +656 -0
- package/dist/matter/matterServer.d.ts.map +1 -0
- package/dist/matter/matterServer.js +1690 -0
- package/dist/matter/matterServer.js.map +1 -0
- package/dist/matter/matterServerHelpers.d.ts +81 -0
- package/dist/matter/matterServerHelpers.d.ts.map +1 -0
- package/dist/matter/matterServerHelpers.js +323 -0
- package/dist/matter/matterServerHelpers.js.map +1 -0
- package/dist/matter/matterSharedTypes.d.ts +170 -0
- package/dist/matter/matterSharedTypes.d.ts.map +1 -0
- package/dist/matter/matterSharedTypes.js +52 -0
- package/dist/matter/matterSharedTypes.js.map +1 -0
- package/dist/matter/matterStorage.d.ts +128 -0
- package/dist/matter/matterStorage.d.ts.map +1 -0
- package/dist/matter/matterStorage.js +415 -0
- package/dist/matter/matterStorage.js.map +1 -0
- package/dist/matter/matterTypes.d.ts +745 -0
- package/dist/matter/matterTypes.d.ts.map +1 -0
- package/dist/matter/matterTypes.js +174 -0
- package/dist/matter/matterTypes.js.map +1 -0
- package/dist/server.d.ts +23 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +385 -7
- package/dist/server.js.map +1 -1
- package/dist/user.d.ts +1 -0
- package/dist/user.d.ts.map +1 -1
- package/dist/user.js +3 -0
- package/dist/user.js.map +1 -1
- package/package.json +16 -15
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matter.js Log Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats Matter.js library logs to match the homebridge log format and color scheme.
|
|
5
|
+
* This ensures consistent logging output across Homebridge and Matter.js.
|
|
6
|
+
*/
|
|
7
|
+
import { Diagnostic } from '@matter/general';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { Logger } from '../logger.js';
|
|
10
|
+
/**
|
|
11
|
+
* Create a custom log formatter that matches the homebridge format.
|
|
12
|
+
* Format: [timestamp] [Matter:Facility] message
|
|
13
|
+
* Timestamp format matches system locale (via toLocaleString()).
|
|
14
|
+
*
|
|
15
|
+
* Log level color mapping:
|
|
16
|
+
* - Matter DEBUG/INFO → gray (Homebridge debug)
|
|
17
|
+
* - Matter NOTICE → no color (Homebridge info)
|
|
18
|
+
* - Matter WARN → yellow (Homebridge warn)
|
|
19
|
+
* - Matter ERROR/FATAL → red (Homebridge error)
|
|
20
|
+
*/
|
|
21
|
+
export function createHomebridgeLogFormatter() {
|
|
22
|
+
// Capture timestamp setting once when formatter is created
|
|
23
|
+
const timestampEnabled = Logger.isTimestampEnabled();
|
|
24
|
+
return (diagnostic) => {
|
|
25
|
+
// Check if this is a Matter.js log message
|
|
26
|
+
if (typeof diagnostic === 'object' && diagnostic !== null) {
|
|
27
|
+
const msg = diagnostic;
|
|
28
|
+
// If it's a log message with the expected structure
|
|
29
|
+
if (msg.now && msg.facility && msg.values) {
|
|
30
|
+
// Format facility as [Matter:FacilityName] in cyan color
|
|
31
|
+
const facility = formatCyan(`[Matter/${msg.facility}]`);
|
|
32
|
+
// Extract the message text from values
|
|
33
|
+
let messageText = formatMessageValues(msg.values);
|
|
34
|
+
// Trim excessively long messages from verbose facilities like MessageChannel
|
|
35
|
+
if (msg.facility === 'MessageChannel' && messageText.length > 200) {
|
|
36
|
+
messageText = `${messageText.substring(0, 200)} [trimmed...]`;
|
|
37
|
+
}
|
|
38
|
+
// Apply color based on Matter log level
|
|
39
|
+
// Matter DEBUG/INFO → gray (Homebridge debug)
|
|
40
|
+
// Matter NOTICE → no color (Homebridge info)
|
|
41
|
+
// Matter WARN → yellow (Homebridge warn)
|
|
42
|
+
// Matter ERROR/FATAL → red (Homebridge error)
|
|
43
|
+
let coloredMessage = messageText;
|
|
44
|
+
if (msg.level !== undefined) {
|
|
45
|
+
const levelStr = String(msg.level).toLowerCase();
|
|
46
|
+
if (levelStr === 'debug' || levelStr === 'info') {
|
|
47
|
+
// Homebridge debug style
|
|
48
|
+
coloredMessage = chalk.gray(messageText);
|
|
49
|
+
}
|
|
50
|
+
else if (levelStr === 'warn') {
|
|
51
|
+
// Homebridge warn style
|
|
52
|
+
coloredMessage = chalk.yellow(messageText);
|
|
53
|
+
}
|
|
54
|
+
else if (levelStr === 'error' || levelStr === 'fatal') {
|
|
55
|
+
// Homebridge error style
|
|
56
|
+
coloredMessage = chalk.red(messageText);
|
|
57
|
+
}
|
|
58
|
+
// For 'notice' or anything else, leave it uncolored (Homebridge info style)
|
|
59
|
+
}
|
|
60
|
+
// Check if timestamps are enabled (respects --no-timestamp flag)
|
|
61
|
+
if (timestampEnabled) {
|
|
62
|
+
// Format timestamp to match Homebridge format using toLocaleString() in white
|
|
63
|
+
const timestamp = formatHomebridgeTimestamp(msg.now);
|
|
64
|
+
return `${timestamp} ${facility} ${coloredMessage}`;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// No timestamp
|
|
68
|
+
return `${facility} ${coloredMessage}`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Fallback for non-message diagnostics
|
|
73
|
+
return String(diagnostic);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Format a date object to Homebridge timestamp format.
|
|
78
|
+
* Uses toLocaleString() to match the main logger's format and respect system locale/timezone.
|
|
79
|
+
* Returns the timestamp in white color to match main logger.
|
|
80
|
+
*/
|
|
81
|
+
function formatHomebridgeTimestamp(date) {
|
|
82
|
+
const timestamp = `[${date.toLocaleString()}]`;
|
|
83
|
+
return chalk.white(timestamp);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Format text in cyan color using chalk
|
|
87
|
+
*/
|
|
88
|
+
function formatCyan(text) {
|
|
89
|
+
return chalk.cyan(text);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Format the message values array into a readable string
|
|
93
|
+
*/
|
|
94
|
+
function formatMessageValues(values) {
|
|
95
|
+
if (!Array.isArray(values)) {
|
|
96
|
+
return String(values);
|
|
97
|
+
}
|
|
98
|
+
return values
|
|
99
|
+
.map((value) => {
|
|
100
|
+
if (value === null) {
|
|
101
|
+
return 'null';
|
|
102
|
+
}
|
|
103
|
+
if (value === undefined) {
|
|
104
|
+
return 'undefined';
|
|
105
|
+
}
|
|
106
|
+
// Matter.js uses lazy logging - call functions to get the actual message
|
|
107
|
+
if (typeof value === 'function') {
|
|
108
|
+
try {
|
|
109
|
+
return String(value());
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return String(value);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (typeof value === 'object') {
|
|
116
|
+
// Check if this is a Matter.js Diagnostic object
|
|
117
|
+
// These objects store their actual value in a symbol property
|
|
118
|
+
const diagnosticValue = Diagnostic.valueOf(value);
|
|
119
|
+
if (diagnosticValue !== undefined) {
|
|
120
|
+
// Recursively format the diagnostic value
|
|
121
|
+
return formatMessageValues([diagnosticValue]);
|
|
122
|
+
}
|
|
123
|
+
// Special handling for Error objects
|
|
124
|
+
if (value instanceof Error) {
|
|
125
|
+
const errorDetails = {
|
|
126
|
+
...value, // Include any custom properties first
|
|
127
|
+
name: value.name,
|
|
128
|
+
message: value.message,
|
|
129
|
+
stack: value.stack,
|
|
130
|
+
};
|
|
131
|
+
return JSON.stringify(errorDetails, null, 2);
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
return JSON.stringify(value);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return String(value);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return String(value);
|
|
141
|
+
})
|
|
142
|
+
.join(' ');
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=matterLogFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterLogFormatter.js","sourceRoot":"","sources":["../../src/matter/matterLogFormatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export interface NetworkStatus {
|
|
2
|
+
isOnline: boolean;
|
|
3
|
+
interfaces: string[];
|
|
4
|
+
primaryInterface?: string;
|
|
5
|
+
lastCheck: Date;
|
|
6
|
+
consecutiveFailures: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class MatterNetworkMonitor {
|
|
9
|
+
private static instance;
|
|
10
|
+
private status;
|
|
11
|
+
private checkInterval;
|
|
12
|
+
private callbacks;
|
|
13
|
+
private checkIntervalMs;
|
|
14
|
+
private isMonitoring;
|
|
15
|
+
private stabilityCounter;
|
|
16
|
+
private readonly STABILITY_THRESHOLD;
|
|
17
|
+
private constructor();
|
|
18
|
+
static getInstance(): MatterNetworkMonitor;
|
|
19
|
+
/**
|
|
20
|
+
* Start monitoring network connectivity
|
|
21
|
+
*/
|
|
22
|
+
startMonitoring(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Stop monitoring
|
|
25
|
+
*/
|
|
26
|
+
stopMonitoring(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Check network status
|
|
29
|
+
*/
|
|
30
|
+
private checkNetworkStatus;
|
|
31
|
+
/**
|
|
32
|
+
* Get active network interfaces
|
|
33
|
+
*/
|
|
34
|
+
private getActiveInterfaces;
|
|
35
|
+
/**
|
|
36
|
+
* Test network connectivity with optimizations
|
|
37
|
+
*
|
|
38
|
+
* Races multiple DNS servers to return as soon as any succeeds,
|
|
39
|
+
* providing faster connectivity checks and better redundancy.
|
|
40
|
+
*/
|
|
41
|
+
private testConnectivity;
|
|
42
|
+
/**
|
|
43
|
+
* Handle network recovery
|
|
44
|
+
*/
|
|
45
|
+
private handleNetworkRecovery;
|
|
46
|
+
/**
|
|
47
|
+
* Register a callback for network status changes
|
|
48
|
+
*/
|
|
49
|
+
onStatusChange(callback: (status: NetworkStatus) => void): void;
|
|
50
|
+
/**
|
|
51
|
+
* Remove a status change callback
|
|
52
|
+
*/
|
|
53
|
+
removeStatusChangeCallback(callback: (status: NetworkStatus) => void): void;
|
|
54
|
+
/**
|
|
55
|
+
* Notify all listeners of status change
|
|
56
|
+
*/
|
|
57
|
+
private notifyStatusChange;
|
|
58
|
+
/**
|
|
59
|
+
* Get current network status
|
|
60
|
+
*/
|
|
61
|
+
getStatus(): NetworkStatus;
|
|
62
|
+
/**
|
|
63
|
+
* Check if network is healthy
|
|
64
|
+
*/
|
|
65
|
+
isHealthy(): boolean;
|
|
66
|
+
}
|
|
67
|
+
export declare const networkMonitor: MatterNetworkMonitor;
|
|
68
|
+
//# sourceMappingURL=matterNetworkMonitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterNetworkMonitor.d.ts","sourceRoot":"","sources":["../../src/matter/matterNetworkMonitor.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,EAAE,IAAI,CAAA;IACf,mBAAmB,EAAE,MAAM,CAAA;CAC5B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB;IAC7C,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,SAAS,CAAkD;IACnE,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAI;IAExC,OAAO;IASP,MAAM,CAAC,WAAW,IAAI,oBAAoB;IAO1C;;OAEG;IACH,eAAe,IAAI,IAAI;IA4BvB;;OAEG;IACH,cAAc,IAAI,IAAI;IAStB;;OAEG;YACW,kBAAkB;IAgDhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;;;;OAKG;YACW,gBAAgB;IAiE9B;;OAEG;YACW,qBAAqB;IAcnC;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAI/D;;OAEG;IACH,0BAA0B,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAI3E;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,SAAS,IAAI,aAAa;IAI1B;;OAEG;IACH,SAAS,IAAI,OAAO;CAGrB;AAGD,eAAO,MAAM,cAAc,sBAAqC,CAAA"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/* global NodeJS */
|
|
2
|
+
/**
|
|
3
|
+
* Matter Network Monitor
|
|
4
|
+
*
|
|
5
|
+
* Monitors network connectivity and handles recovery
|
|
6
|
+
*/
|
|
7
|
+
import { Socket } from 'node:net';
|
|
8
|
+
import { networkInterfaces } from 'node:os';
|
|
9
|
+
import { Logger } from '../logger.js';
|
|
10
|
+
import { errorHandler, MatterErrorType } from './matterErrorHandler.js';
|
|
11
|
+
const log = Logger.withPrefix('Matter/Network');
|
|
12
|
+
export class MatterNetworkMonitor {
|
|
13
|
+
static instance;
|
|
14
|
+
status;
|
|
15
|
+
checkInterval = null;
|
|
16
|
+
callbacks = new Set();
|
|
17
|
+
checkIntervalMs = 30000; // Check every 30 seconds
|
|
18
|
+
isMonitoring = false;
|
|
19
|
+
stabilityCounter = 0;
|
|
20
|
+
STABILITY_THRESHOLD = 3;
|
|
21
|
+
constructor() {
|
|
22
|
+
this.status = {
|
|
23
|
+
isOnline: true,
|
|
24
|
+
interfaces: [],
|
|
25
|
+
lastCheck: new Date(),
|
|
26
|
+
consecutiveFailures: 0,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
static getInstance() {
|
|
30
|
+
if (!MatterNetworkMonitor.instance) {
|
|
31
|
+
MatterNetworkMonitor.instance = new MatterNetworkMonitor();
|
|
32
|
+
}
|
|
33
|
+
return MatterNetworkMonitor.instance;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Start monitoring network connectivity
|
|
37
|
+
*/
|
|
38
|
+
startMonitoring() {
|
|
39
|
+
if (this.isMonitoring) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.isMonitoring = true;
|
|
43
|
+
log.debug('Starting Matter network monitoring');
|
|
44
|
+
// Initial check (fire-and-forget with error handling)
|
|
45
|
+
this.checkNetworkStatus().catch((error) => {
|
|
46
|
+
log.debug('Error during initial network check:', error);
|
|
47
|
+
});
|
|
48
|
+
// Set up periodic checks
|
|
49
|
+
this.checkInterval = setInterval(() => {
|
|
50
|
+
// Fire-and-forget with error handling
|
|
51
|
+
this.checkNetworkStatus().catch((error) => {
|
|
52
|
+
log.debug('Error during periodic network check:', error);
|
|
53
|
+
});
|
|
54
|
+
}, this.checkIntervalMs);
|
|
55
|
+
// Register recovery callback with error handler
|
|
56
|
+
errorHandler.registerRecoveryCallback(MatterErrorType.NETWORK, async () => this.handleNetworkRecovery());
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Stop monitoring
|
|
60
|
+
*/
|
|
61
|
+
stopMonitoring() {
|
|
62
|
+
if (this.checkInterval) {
|
|
63
|
+
clearInterval(this.checkInterval);
|
|
64
|
+
this.checkInterval = null;
|
|
65
|
+
}
|
|
66
|
+
this.isMonitoring = false;
|
|
67
|
+
log.debug('Stopped Matter network monitoring');
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check network status
|
|
71
|
+
*/
|
|
72
|
+
async checkNetworkStatus() {
|
|
73
|
+
try {
|
|
74
|
+
// Get network interfaces
|
|
75
|
+
const interfaces = this.getActiveInterfaces();
|
|
76
|
+
// Test connectivity with a simple port check
|
|
77
|
+
const isOnline = await this.testConnectivity();
|
|
78
|
+
const previousStatus = this.status.isOnline;
|
|
79
|
+
this.status = {
|
|
80
|
+
isOnline,
|
|
81
|
+
interfaces: interfaces.map(i => i.name),
|
|
82
|
+
primaryInterface: interfaces[0]?.name,
|
|
83
|
+
lastCheck: new Date(),
|
|
84
|
+
consecutiveFailures: isOnline ? 0 : this.status.consecutiveFailures + 1,
|
|
85
|
+
};
|
|
86
|
+
// Notify listeners if status changed
|
|
87
|
+
if (previousStatus !== isOnline) {
|
|
88
|
+
this.notifyStatusChange();
|
|
89
|
+
if (!isOnline) {
|
|
90
|
+
this.stabilityCounter = 0;
|
|
91
|
+
log.warn('Matter network connectivity lost');
|
|
92
|
+
await errorHandler.handleError(new Error('Network connectivity lost'), 'network-monitor');
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
this.stabilityCounter = 0;
|
|
96
|
+
log.info('Matter network connectivity restored');
|
|
97
|
+
errorHandler.resetErrorCount(MatterErrorType.NETWORK);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else if (isOnline) {
|
|
101
|
+
// Increment stability counter when consistently online
|
|
102
|
+
this.stabilityCounter = Math.min(this.stabilityCounter + 1, this.STABILITY_THRESHOLD);
|
|
103
|
+
}
|
|
104
|
+
// Log warnings for repeated failures
|
|
105
|
+
if (this.status.consecutiveFailures > 3) {
|
|
106
|
+
log.error(`Network has been offline for ${this.status.consecutiveFailures} consecutive checks`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
log.debug('Error checking network status:', error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get active network interfaces
|
|
115
|
+
*/
|
|
116
|
+
getActiveInterfaces() {
|
|
117
|
+
const interfaces = [];
|
|
118
|
+
for (const [name, addrs] of Object.entries(networkInterfaces())) {
|
|
119
|
+
if (!addrs) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
for (const addr of addrs) {
|
|
123
|
+
// Skip internal (loopback) and non-IPv4 addresses
|
|
124
|
+
if (!addr.internal && addr.family === 'IPv4') {
|
|
125
|
+
interfaces.push({ name, address: addr.address });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return interfaces;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Test network connectivity with optimizations
|
|
133
|
+
*
|
|
134
|
+
* Races multiple DNS servers to return as soon as any succeeds,
|
|
135
|
+
* providing faster connectivity checks and better redundancy.
|
|
136
|
+
*/
|
|
137
|
+
async testConnectivity() {
|
|
138
|
+
// If we recently had a successful check, skip the test
|
|
139
|
+
const timeSinceLastCheck = Date.now() - (this.status.lastCheck?.getTime() || 0);
|
|
140
|
+
if (this.status.isOnline && timeSinceLastCheck < 5000 && this.stabilityCounter >= this.STABILITY_THRESHOLD) {
|
|
141
|
+
log.debug('Skipping connectivity test - recent successful check');
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
const servers = [
|
|
145
|
+
{ host: '1.1.1.1', port: 53 }, // Cloudflare DNS
|
|
146
|
+
{ host: '8.8.8.8', port: 53 }, // Google DNS
|
|
147
|
+
{ host: '9.9.9.9', port: 53 }, // Quad9 DNS
|
|
148
|
+
];
|
|
149
|
+
// Test a single server
|
|
150
|
+
const testServer = (server) => {
|
|
151
|
+
return new Promise((resolve) => {
|
|
152
|
+
const socket = new Socket();
|
|
153
|
+
const timeout = 2000;
|
|
154
|
+
const cleanup = () => socket.destroy();
|
|
155
|
+
socket.setTimeout(timeout);
|
|
156
|
+
socket.once('connect', () => {
|
|
157
|
+
cleanup();
|
|
158
|
+
resolve(true);
|
|
159
|
+
});
|
|
160
|
+
socket.once('error', () => {
|
|
161
|
+
cleanup();
|
|
162
|
+
resolve(false);
|
|
163
|
+
});
|
|
164
|
+
socket.once('timeout', () => {
|
|
165
|
+
cleanup();
|
|
166
|
+
resolve(false);
|
|
167
|
+
});
|
|
168
|
+
socket.connect(server.port, server.host);
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
// Race all servers - return true as soon as ANY succeeds
|
|
172
|
+
try {
|
|
173
|
+
const racePromises = servers.map(async (server) => {
|
|
174
|
+
const success = await testServer(server);
|
|
175
|
+
if (success) {
|
|
176
|
+
// If this server succeeded, return true immediately
|
|
177
|
+
return { success: true };
|
|
178
|
+
}
|
|
179
|
+
// Otherwise, never resolve (let other promises continue racing)
|
|
180
|
+
return new Promise(() => { });
|
|
181
|
+
});
|
|
182
|
+
// Add a timeout promise to ensure we don't wait forever
|
|
183
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
184
|
+
setTimeout(() => resolve({ success: false }), 3000);
|
|
185
|
+
});
|
|
186
|
+
const result = await Promise.race([...racePromises, timeoutPromise]);
|
|
187
|
+
return result.success;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
log.debug('Error during connectivity test:', error);
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Handle network recovery
|
|
196
|
+
*/
|
|
197
|
+
async handleNetworkRecovery() {
|
|
198
|
+
log.info('Attempting network recovery...');
|
|
199
|
+
// Force a network check
|
|
200
|
+
await this.checkNetworkStatus();
|
|
201
|
+
if (this.status.isOnline) {
|
|
202
|
+
log.info('Network is online, recovery successful');
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
log.warn('Network still offline, will retry');
|
|
206
|
+
throw new Error('Network recovery failed');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Register a callback for network status changes
|
|
211
|
+
*/
|
|
212
|
+
onStatusChange(callback) {
|
|
213
|
+
this.callbacks.add(callback);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Remove a status change callback
|
|
217
|
+
*/
|
|
218
|
+
removeStatusChangeCallback(callback) {
|
|
219
|
+
this.callbacks.delete(callback);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Notify all listeners of status change
|
|
223
|
+
*/
|
|
224
|
+
notifyStatusChange() {
|
|
225
|
+
for (const callback of this.callbacks) {
|
|
226
|
+
try {
|
|
227
|
+
callback(this.status);
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
log.debug('Error in network status callback:', error);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get current network status
|
|
236
|
+
*/
|
|
237
|
+
getStatus() {
|
|
238
|
+
return { ...this.status };
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Check if network is healthy
|
|
242
|
+
*/
|
|
243
|
+
isHealthy() {
|
|
244
|
+
return this.status.isOnline && this.status.consecutiveFailures === 0;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Export singleton instance
|
|
248
|
+
export const networkMonitor = MatterNetworkMonitor.getInstance();
|
|
249
|
+
//# sourceMappingURL=matterNetworkMonitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterNetworkMonitor.js","sourceRoot":"","sources":["../../src/matter/matterNetworkMonitor.ts"],"names":[],"mappings":"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"}
|