icom-wlan-node 0.1.0

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.
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AUDIO_RATE = exports.IcomAudio = void 0;
4
+ const IcomPackets_1 = require("../core/IcomPackets");
5
+ class IcomAudio {
6
+ constructor(sess) {
7
+ this.sess = sess;
8
+ this.sendSeq = 0;
9
+ this.sendSeqForTiming = 0; // Separate counter for drift compensation
10
+ this.isPttOn = false;
11
+ this.queue = []; // Public for PTT control to clear queue
12
+ this.volume = 1.0; // 0.0 ~ 2.0
13
+ this.running = false;
14
+ this.startTime = 0; // Absolute start time for drift compensation
15
+ this.FRAME_INTERVAL_MS = 20;
16
+ this.frameCount = 0;
17
+ this.debugInterval = 0;
18
+ this.debugIntervalStart = 0;
19
+ }
20
+ start() {
21
+ // Start continuous audio transmission with drift compensation
22
+ if (this.running)
23
+ return;
24
+ this.running = true;
25
+ this.startTime = performance.now();
26
+ this.sendSeqForTiming = 0;
27
+ this.frameCount = 0;
28
+ this.debugInterval = 0;
29
+ this.debugIntervalStart = 0;
30
+ this.scheduleSend();
31
+ }
32
+ scheduleSend() {
33
+ if (!this.running)
34
+ return;
35
+ const now = performance.now();
36
+ // Calculate ideal send time for next frame (with drift compensation)
37
+ const nextFrameIndex = this.sendSeqForTiming + 1;
38
+ const idealTime = this.startTime + (nextFrameIndex * this.FRAME_INTERVAL_MS);
39
+ const timeUntilSend = idealTime - now;
40
+ if (timeUntilSend <= 0) {
41
+ // We're at or past send time! Send immediately
42
+ this.sendFrame();
43
+ this.sendSeqForTiming++;
44
+ // Schedule next check immediately (tight loop for precision)
45
+ this.txTimer = setImmediate(() => this.scheduleSend());
46
+ }
47
+ else if (timeUntilSend <= 0.5) {
48
+ // Very close (within 0.5ms), tight loop with setImmediate
49
+ this.txTimer = setImmediate(() => this.scheduleSend());
50
+ }
51
+ else if (timeUntilSend <= 3) {
52
+ // Close (1-3ms), use minimal setTimeout
53
+ setTimeout(() => this.scheduleSend(), 0);
54
+ }
55
+ else {
56
+ // Further away, wait conservatively then tight loop
57
+ const waitTime = Math.max(1, Math.floor(timeUntilSend - 2));
58
+ setTimeout(() => this.scheduleSend(), waitTime);
59
+ }
60
+ }
61
+ sendFrame() {
62
+ let frame;
63
+ const hasData = this.queue.length > 0;
64
+ if (hasData) {
65
+ // Send audio from queue when available
66
+ frame = this.queue.shift();
67
+ }
68
+ else {
69
+ // Send silence when queue is empty
70
+ frame = new Int16Array(IcomPackets_1.TX_BUFFER_SIZE);
71
+ }
72
+ const buf = Buffer.alloc(IcomPackets_1.TX_BUFFER_SIZE * 2);
73
+ for (let i = 0; i < IcomPackets_1.TX_BUFFER_SIZE; i++)
74
+ buf.writeInt16LE(frame[i] ?? 0, i * 2);
75
+ const pkt = IcomPackets_1.AudioPacket.getTxAudioPacket(buf, 0, this.sess.localId, this.sess.remoteId, this.sendSeq);
76
+ this.sendSeq = (this.sendSeq + 1) & 0xffff;
77
+ this.sess.sendTracked(pkt);
78
+ // Debug: log timing info every 50 frames (~1 second)
79
+ this.frameCount++;
80
+ if (this.frameCount % 50 === 0 && hasData) {
81
+ const now = performance.now();
82
+ if (this.debugIntervalStart > 0) {
83
+ const elapsed = now - this.debugIntervalStart;
84
+ const avgInterval = elapsed / 50;
85
+ const drift = elapsed - (50 * this.FRAME_INTERVAL_MS);
86
+ console.log(`[AudioTiming] Avg: ${avgInterval.toFixed(2)}ms (target: ${this.FRAME_INTERVAL_MS}ms), drift: ${drift.toFixed(2)}ms, queue: ${this.queue.length}`);
87
+ }
88
+ this.debugIntervalStart = now;
89
+ }
90
+ }
91
+ stop() {
92
+ // Stop continuous audio transmission (only on disconnect)
93
+ this.running = false;
94
+ if (this.txTimer) {
95
+ clearImmediate(this.txTimer);
96
+ this.txTimer = undefined;
97
+ }
98
+ this.queue.length = 0;
99
+ this.isPttOn = false;
100
+ this.frameCount = 0;
101
+ this.debugInterval = 0;
102
+ }
103
+ // Add leading silence frames (like Java's front buffer)
104
+ addLeadingSilence(frameCount = 3) {
105
+ const silence = new Int16Array(IcomPackets_1.TX_BUFFER_SIZE);
106
+ for (let i = 0; i < frameCount; i++) {
107
+ this.queue.push(silence);
108
+ }
109
+ }
110
+ // Add trailing silence frames (like Java's tail buffer)
111
+ addTrailingSilence(frameCount = 5) {
112
+ const silence = new Int16Array(IcomPackets_1.TX_BUFFER_SIZE);
113
+ for (let i = 0; i < frameCount; i++) {
114
+ this.queue.push(silence);
115
+ }
116
+ }
117
+ // Push Float32 samples; they will be converted to 16-bit and sliced into 20ms frames
118
+ enqueueFloat32(samples, addLeadingBuffer = false) {
119
+ // Add leading silence buffer if requested (used at PTT start)
120
+ if (addLeadingBuffer && this.queue.length === 0) {
121
+ this.addLeadingSilence(3);
122
+ }
123
+ const out = new Int16Array(samples.length);
124
+ for (let i = 0; i < samples.length; i++) {
125
+ let x = Math.max(-1, Math.min(1, samples[i]));
126
+ out[i] = (x * this.volume * 32767) | 0;
127
+ }
128
+ this.enqueuePcm16(out);
129
+ }
130
+ enqueuePcm16(samples) {
131
+ // slice into TX_BUFFER_SIZE frames
132
+ for (let i = 0; i < samples.length; i += IcomPackets_1.TX_BUFFER_SIZE) {
133
+ const slice = samples.subarray(i, Math.min(samples.length, i + IcomPackets_1.TX_BUFFER_SIZE));
134
+ // Always create a new buffer to avoid issues with subarray views
135
+ const frame = new Int16Array(IcomPackets_1.TX_BUFFER_SIZE);
136
+ frame.set(slice);
137
+ this.queue.push(frame);
138
+ }
139
+ }
140
+ setVolume(multiplier) { this.volume = Math.max(0, multiplier); }
141
+ }
142
+ exports.IcomAudio = IcomAudio;
143
+ exports.AUDIO_RATE = IcomPackets_1.AUDIO_SAMPLE_RATE;
@@ -0,0 +1,14 @@
1
+ import { Session } from '../core/Session';
2
+ export declare class IcomCiv {
3
+ private sess;
4
+ civAddress: number;
5
+ supportTX: boolean;
6
+ private civSeq;
7
+ private idleTimer?;
8
+ private openTimer?;
9
+ constructor(sess: Session);
10
+ start(): void;
11
+ stop(): void;
12
+ sendOpenClose(open: boolean): void;
13
+ sendCivData(data: Buffer): void;
14
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IcomCiv = void 0;
4
+ const IcomPackets_1 = require("../core/IcomPackets");
5
+ const debug_1 = require("../utils/debug");
6
+ class IcomCiv {
7
+ constructor(sess) {
8
+ this.sess = sess;
9
+ this.civAddress = 0xA4;
10
+ this.supportTX = true;
11
+ this.civSeq = 0;
12
+ }
13
+ start() {
14
+ this.stop();
15
+ // keep-alive open/close
16
+ this.openTimer = setInterval(() => {
17
+ if (Date.now() - this.sess.lastReceivedTime > 2000) {
18
+ this.sendOpenClose(true);
19
+ }
20
+ }, 500);
21
+ }
22
+ stop() {
23
+ if (this.openTimer)
24
+ clearInterval(this.openTimer);
25
+ if (this.idleTimer)
26
+ clearInterval(this.idleTimer);
27
+ this.openTimer = undefined;
28
+ this.idleTimer = undefined;
29
+ }
30
+ sendOpenClose(open) {
31
+ const magic = open ? 0x04 : 0x00;
32
+ const pkt = IcomPackets_1.OpenClosePacket.toBytes(0, this.sess.localId, this.sess.remoteId, this.civSeq, magic);
33
+ this.civSeq = (this.civSeq + 1) & 0xffff;
34
+ (0, debug_1.dbg)(`CIV -> OpenClose ${open ? 'OPEN' : 'CLOSE'} seq=${this.civSeq - 1}`);
35
+ this.sess.sendTracked(pkt);
36
+ }
37
+ sendCivData(data) {
38
+ const pkt = IcomPackets_1.CivPacket.setCivData(0, this.sess.localId, this.sess.remoteId, this.civSeq, data);
39
+ this.civSeq = (this.civSeq + 1) & 0xffff;
40
+ (0, debug_1.dbg)(`CIV -> data len=${data.length} seq=${this.civSeq - 1}`);
41
+ this.sess.sendTracked(pkt);
42
+ }
43
+ }
44
+ exports.IcomCiv = IcomCiv;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * ICOM radio constants and mappings
3
+ * Based on FT8CN's IcomRigConstant.java
4
+ */
5
+ /**
6
+ * Operating modes supported by ICOM radios
7
+ * LSB:0, USB:1, AM:2, CW:3, RTTY:4, FM:5, WFM:6, CW_R:7, RTTY_R:8, DV:17
8
+ */
9
+ export declare const MODE_MAP: {
10
+ readonly LSB: 0;
11
+ readonly USB: 1;
12
+ readonly AM: 2;
13
+ readonly CW: 3;
14
+ readonly RTTY: 4;
15
+ readonly FM: 5;
16
+ readonly WFM: 6;
17
+ readonly CW_R: 7;
18
+ readonly RTTY_R: 8;
19
+ readonly DV: 23;
20
+ };
21
+ /**
22
+ * Connector data routing modes
23
+ * Based on ICOM's connector data mode settings
24
+ */
25
+ export declare const CONNECTOR_MODE_MAP: {
26
+ readonly MIC: 0;
27
+ readonly ACC: 1;
28
+ readonly USB: 2;
29
+ readonly WLAN: 3;
30
+ };
31
+ /**
32
+ * Default controller address (typically 0xE0 for PC/controller)
33
+ */
34
+ export declare const DEFAULT_CONTROLLER_ADDR = 224;
35
+ /**
36
+ * Helper function to get mode code from string
37
+ */
38
+ export declare function getModeCode(mode: keyof typeof MODE_MAP): number;
39
+ /**
40
+ * Helper function to get connector mode code from string
41
+ */
42
+ export declare function getConnectorModeCode(mode: keyof typeof CONNECTOR_MODE_MAP): number;
43
+ /**
44
+ * Helper function to get mode string from code
45
+ */
46
+ export declare function getModeString(code: number): string | undefined;
47
+ /**
48
+ * Helper function to get connector mode string from code
49
+ */
50
+ export declare function getConnectorModeString(code: number): string | undefined;
51
+ /**
52
+ * ICOM filter code to string mapping
53
+ * Common rigs use 0x01(FIL1), 0x02(FIL2), 0x03(FIL3)
54
+ */
55
+ export declare function getFilterString(code: number | undefined): string | undefined;
56
+ /**
57
+ * Meter alert thresholds
58
+ * Based on FT8CN's IcomRigConstant.java
59
+ */
60
+ export declare const METER_THRESHOLDS: {
61
+ /**
62
+ * SWR alert threshold (raw value)
63
+ * Alert when SWR ≥ 1.2 (raw value ≥ 120)
64
+ */
65
+ readonly SWR_ALERT: 120;
66
+ /**
67
+ * ALC maximum alert threshold (raw value)
68
+ * Alert when ALC > 120
69
+ */
70
+ readonly ALC_ALERT_MAX: 120;
71
+ /**
72
+ * Maximum ALC value for percentage calculation
73
+ */
74
+ readonly ALC_MAX: 255;
75
+ /**
76
+ * Maximum WLAN level value for percentage calculation
77
+ */
78
+ readonly WLAN_LEVEL_MAX: 255;
79
+ };
80
+ /**
81
+ * Period for meter polling during TX (milliseconds)
82
+ * Matches FT8CN's IComPacketTypes.METER_TIMER_PERIOD_MS
83
+ */
84
+ export declare const METER_TIMER_PERIOD_MS = 500;
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ /**
3
+ * ICOM radio constants and mappings
4
+ * Based on FT8CN's IcomRigConstant.java
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.METER_TIMER_PERIOD_MS = exports.METER_THRESHOLDS = exports.DEFAULT_CONTROLLER_ADDR = exports.CONNECTOR_MODE_MAP = exports.MODE_MAP = void 0;
8
+ exports.getModeCode = getModeCode;
9
+ exports.getConnectorModeCode = getConnectorModeCode;
10
+ exports.getModeString = getModeString;
11
+ exports.getConnectorModeString = getConnectorModeString;
12
+ exports.getFilterString = getFilterString;
13
+ /**
14
+ * Operating modes supported by ICOM radios
15
+ * LSB:0, USB:1, AM:2, CW:3, RTTY:4, FM:5, WFM:6, CW_R:7, RTTY_R:8, DV:17
16
+ */
17
+ exports.MODE_MAP = {
18
+ LSB: 0x00, // Lower Side Band (下边带)
19
+ USB: 0x01, // Upper Side Band (上边带)
20
+ AM: 0x02, // Amplitude Modulation (调幅)
21
+ CW: 0x03, // Continuous Wave (连续波/莫尔斯码)
22
+ RTTY: 0x04, // Radio Teletype (频移键控)
23
+ FM: 0x05, // Frequency Modulation (调频)
24
+ WFM: 0x06, // Wide FM (宽带调频)
25
+ CW_R: 0x07, // CW Reverse (反向连续波)
26
+ RTTY_R: 0x08, // RTTY Reverse (反向频移键控)
27
+ DV: 0x17 // Digital Voice (数字语音, decimal 23)
28
+ };
29
+ /**
30
+ * Connector data routing modes
31
+ * Based on ICOM's connector data mode settings
32
+ */
33
+ exports.CONNECTOR_MODE_MAP = {
34
+ MIC: 0x00, // Microphone input
35
+ ACC: 0x01, // ACC (Accessory) port
36
+ USB: 0x02, // USB audio
37
+ WLAN: 0x03 // WLAN (network) audio
38
+ };
39
+ /**
40
+ * Default controller address (typically 0xE0 for PC/controller)
41
+ */
42
+ exports.DEFAULT_CONTROLLER_ADDR = 0xe0;
43
+ /**
44
+ * Helper function to get mode code from string
45
+ */
46
+ function getModeCode(mode) {
47
+ return exports.MODE_MAP[mode];
48
+ }
49
+ /**
50
+ * Helper function to get connector mode code from string
51
+ */
52
+ function getConnectorModeCode(mode) {
53
+ return exports.CONNECTOR_MODE_MAP[mode];
54
+ }
55
+ /**
56
+ * Helper function to get mode string from code
57
+ */
58
+ function getModeString(code) {
59
+ const entry = Object.entries(exports.MODE_MAP).find(([_, value]) => value === code);
60
+ return entry?.[0];
61
+ }
62
+ /**
63
+ * Helper function to get connector mode string from code
64
+ */
65
+ function getConnectorModeString(code) {
66
+ const entry = Object.entries(exports.CONNECTOR_MODE_MAP).find(([_, value]) => value === code);
67
+ return entry?.[0];
68
+ }
69
+ /**
70
+ * ICOM filter code to string mapping
71
+ * Common rigs use 0x01(FIL1), 0x02(FIL2), 0x03(FIL3)
72
+ */
73
+ function getFilterString(code) {
74
+ if (code === undefined)
75
+ return undefined;
76
+ if (code === 0x01)
77
+ return 'FIL1';
78
+ if (code === 0x02)
79
+ return 'FIL2';
80
+ if (code === 0x03)
81
+ return 'FIL3';
82
+ return 'FIL' + code;
83
+ }
84
+ /**
85
+ * Meter alert thresholds
86
+ * Based on FT8CN's IcomRigConstant.java
87
+ */
88
+ exports.METER_THRESHOLDS = {
89
+ /**
90
+ * SWR alert threshold (raw value)
91
+ * Alert when SWR ≥ 1.2 (raw value ≥ 120)
92
+ */
93
+ SWR_ALERT: 120,
94
+ /**
95
+ * ALC maximum alert threshold (raw value)
96
+ * Alert when ALC > 120
97
+ */
98
+ ALC_ALERT_MAX: 120,
99
+ /**
100
+ * Maximum ALC value for percentage calculation
101
+ */
102
+ ALC_MAX: 255,
103
+ /**
104
+ * Maximum WLAN level value for percentage calculation
105
+ */
106
+ WLAN_LEVEL_MAX: 255
107
+ };
108
+ /**
109
+ * Period for meter polling during TX (milliseconds)
110
+ * Matches FT8CN's IComPacketTypes.METER_TIMER_PERIOD_MS
111
+ */
112
+ exports.METER_TIMER_PERIOD_MS = 500;
@@ -0,0 +1,155 @@
1
+ import { IcomRigOptions, RigEventEmitter, IcomMode, ConnectorDataMode, SetModeOptions, QueryOptions, SwrReading, AlcReading, WlanLevelReading, LevelMeterReading } from '../types';
2
+ import { IcomCiv } from './IcomCiv';
3
+ import { IcomAudio } from './IcomAudio';
4
+ export declare class IcomControl {
5
+ private ev;
6
+ private sess;
7
+ private civSess;
8
+ private audioSess;
9
+ civ: IcomCiv;
10
+ audio: IcomAudio;
11
+ private options;
12
+ private rigName;
13
+ private macAddress;
14
+ private tokenTimer?;
15
+ private civAssembleBuf;
16
+ private meterTimer?;
17
+ private loginReady;
18
+ private civReady;
19
+ private audioReady;
20
+ private resolveLoginReady;
21
+ private resolveCivReady;
22
+ private resolveAudioReady;
23
+ constructor(options: IcomRigOptions);
24
+ get events(): RigEventEmitter;
25
+ connect(): Promise<void>;
26
+ disconnect(): Promise<void>;
27
+ sendCiv(data: Buffer): void;
28
+ /**
29
+ * Set PTT (Push-To-Talk) state
30
+ * @param on - true to key transmitter, false to unkey
31
+ */
32
+ setPtt(on: boolean): Promise<void>;
33
+ /**
34
+ * Set operating frequency
35
+ * @param hz - Frequency in Hz
36
+ */
37
+ setFrequency(hz: number): Promise<void>;
38
+ /**
39
+ * Set operating mode
40
+ * @param mode - Operating mode (LSB, USB, AM, CW, RTTY, FM, WFM, CW_R, RTTY_R, DV)
41
+ * @param options - Mode options (dataMode for digital modes like USB-D)
42
+ * @example
43
+ * // Set USB mode
44
+ * await rig.setMode('USB');
45
+ * // Set USB-D (data mode) for FT8
46
+ * await rig.setMode('USB', { dataMode: true });
47
+ */
48
+ setMode(mode: IcomMode | number, options?: SetModeOptions): Promise<void>;
49
+ /**
50
+ * Read current operating frequency
51
+ * @param options - Query options (timeout in ms, default 3000)
52
+ * @returns Frequency in Hz, or null if timeout/error
53
+ * @example
54
+ * const hz = await rig.readOperatingFrequency({ timeout: 5000 });
55
+ * console.log(`Frequency: ${hz} Hz`);
56
+ */
57
+ readOperatingFrequency(options?: QueryOptions): Promise<number | null>;
58
+ /**
59
+ * Read current operating mode and filter
60
+ * @returns { mode: number, filter?: number } or null
61
+ */
62
+ readOperatingMode(options?: QueryOptions): Promise<{
63
+ mode: number;
64
+ filter?: number;
65
+ modeName?: string;
66
+ filterName?: string;
67
+ } | null>;
68
+ /**
69
+ * Read current transmit frequency (when TX)
70
+ */
71
+ readTransmitFrequency(options?: QueryOptions): Promise<number | null>;
72
+ /**
73
+ * Read transceiver state (TX/RX) via 0x1A 0x00 0x48
74
+ * Note: Java comments mark this as not recommended; use with caution.
75
+ */
76
+ readTransceiverState(options?: QueryOptions): Promise<'TX' | 'RX' | 'UNKNOWN' | null>;
77
+ /**
78
+ * Read band edge data (0x02). Format may vary by rig; returns raw data bytes after command.
79
+ */
80
+ readBandEdges(options?: QueryOptions): Promise<Buffer | null>;
81
+ /**
82
+ * Read SWR (Standing Wave Ratio) meter
83
+ * @param options - Query options (timeout in ms, default 3000)
84
+ * @returns SWR reading with raw value, calculated SWR, and alert status
85
+ * @example
86
+ * const swr = await rig.readSWR({ timeout: 2000 });
87
+ * if (swr) {
88
+ * console.log(`SWR: ${swr.swr.toFixed(2)} ${swr.alert ? '⚠️ HIGH' : '✓'}`);
89
+ * }
90
+ */
91
+ readSWR(options?: QueryOptions): Promise<SwrReading | null>;
92
+ /**
93
+ * Read ALC (Automatic Level Control) meter
94
+ * @param options - Query options (timeout in ms, default 3000)
95
+ * @returns ALC reading with raw value, percent, and alert status
96
+ * @example
97
+ * const alc = await rig.readALC({ timeout: 2000 });
98
+ * if (alc) {
99
+ * console.log(`ALC: ${alc.percent.toFixed(1)}% ${alc.alert ? '⚠️ HIGH' : '✓'}`);
100
+ * }
101
+ */
102
+ readALC(options?: QueryOptions): Promise<AlcReading | null>;
103
+ /**
104
+ * Get WLAN connector audio level setting
105
+ * @param options - Query options (timeout in ms, default 3000)
106
+ * @returns WLAN level reading with raw value and percent
107
+ * @example
108
+ * const level = await rig.getConnectorWLanLevel({ timeout: 2000 });
109
+ * if (level) {
110
+ * console.log(`WLAN Level: ${level.percent.toFixed(1)}%`);
111
+ * }
112
+ */
113
+ getConnectorWLanLevel(options?: QueryOptions): Promise<WlanLevelReading | null>;
114
+ /**
115
+ * Read generic level meter (CI-V 0x15/0x02), raw 0-255.
116
+ * Many rigs return two bytes and the low byte is the level.
117
+ */
118
+ getLevelMeter(options?: QueryOptions): Promise<LevelMeterReading | null>;
119
+ /**
120
+ * Set WLAN connector audio level
121
+ * @param level - Audio level (0-255)
122
+ */
123
+ setConnectorWLanLevel(level: number): Promise<void>;
124
+ /**
125
+ * Set connector data routing mode
126
+ * @param mode - Data routing mode (MIC, ACC, USB, WLAN)
127
+ * @example
128
+ * // Route audio to WLAN
129
+ * await rig.setConnectorDataMode('WLAN');
130
+ */
131
+ setConnectorDataMode(mode: ConnectorDataMode | number): Promise<void>;
132
+ private static isReplyOf;
133
+ /**
134
+ * Extract meter data from CI-V response frame
135
+ * CI-V format: FE FE [ctr] [rig] [cmd] [subcmd] [data0] [data1] FD
136
+ * @param frame - CI-V response buffer
137
+ * @returns Parsed BCD integer value, or null if invalid
138
+ */
139
+ private static extractMeterData;
140
+ private static matchCommand;
141
+ private static matchCommandFrame;
142
+ private waitForCiv;
143
+ static parseIcomFreqFromReply(frame: Buffer): number | null;
144
+ sendAudioFloat32(samples: Float32Array, addLeadingBuffer?: boolean): void;
145
+ sendAudioPcm16(samples: Int16Array): void;
146
+ private onData;
147
+ private onCivData;
148
+ private processCivPayload;
149
+ private waitForCivFrame;
150
+ private static isMeterReply;
151
+ private startMeterPolling;
152
+ private stopMeterPolling;
153
+ private onAudioData;
154
+ private sendConnectionRequest;
155
+ }