hamlib 0.4.0 → 0.4.2
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/index.d.ts +69 -0
- package/lib/index.js +19 -0
- package/lib/spectrum.d.ts +0 -2
- package/package.json +14 -4
- package/prebuilds/darwin-arm64/libhamlib.4.dylib +0 -0
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/darwin-x64/libhamlib.4.dylib +0 -0
- package/prebuilds/darwin-x64/node.napi.node +0 -0
- package/prebuilds/linux-arm64/libhamlib.so +0 -0
- package/prebuilds/linux-arm64/libhamlib.so.4 +0 -0
- package/prebuilds/linux-arm64/libhamlib.so.4.0.7 +0 -0
- package/prebuilds/linux-arm64/node.napi.node +0 -0
- package/prebuilds/linux-x64/libhamlib.so +0 -0
- package/prebuilds/linux-x64/libhamlib.so.4 +0 -0
- package/prebuilds/linux-x64/libhamlib.so.4.0.7 +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
- package/prebuilds/win32-x64/hamlib_shim.dll +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/spectrum.d.ts +2 -0
- package/spectrum.js +1 -0
- package/spectrum.mjs +2 -0
- package/src/hamlib.cpp +161 -12
- package/src/hamlib.h +3 -0
- package/src/shim/hamlib_shim.c +144 -0
- package/src/shim/hamlib_shim.h +42 -0
package/index.d.ts
CHANGED
|
@@ -378,6 +378,62 @@ interface SerialConfigOptions {
|
|
|
378
378
|
dcd_type: string[];
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
+
type HamlibConfigFieldType =
|
|
382
|
+
| 'string'
|
|
383
|
+
| 'combo'
|
|
384
|
+
| 'numeric'
|
|
385
|
+
| 'checkbutton'
|
|
386
|
+
| 'button'
|
|
387
|
+
| 'binary'
|
|
388
|
+
| 'int'
|
|
389
|
+
| 'unknown';
|
|
390
|
+
|
|
391
|
+
interface HamlibConfigFieldDescriptor {
|
|
392
|
+
token: number;
|
|
393
|
+
name: string;
|
|
394
|
+
label: string;
|
|
395
|
+
tooltip: string;
|
|
396
|
+
defaultValue: string;
|
|
397
|
+
type: HamlibConfigFieldType;
|
|
398
|
+
numeric?: {
|
|
399
|
+
min: number;
|
|
400
|
+
max: number;
|
|
401
|
+
step: number;
|
|
402
|
+
};
|
|
403
|
+
options?: string[];
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
type HamlibPortType =
|
|
407
|
+
| 'none'
|
|
408
|
+
| 'serial'
|
|
409
|
+
| 'network'
|
|
410
|
+
| 'device'
|
|
411
|
+
| 'packet'
|
|
412
|
+
| 'dtmf'
|
|
413
|
+
| 'ultra'
|
|
414
|
+
| 'rpc'
|
|
415
|
+
| 'parallel'
|
|
416
|
+
| 'usb'
|
|
417
|
+
| 'udp-network'
|
|
418
|
+
| 'cm108'
|
|
419
|
+
| 'gpio'
|
|
420
|
+
| 'gpion'
|
|
421
|
+
| 'other';
|
|
422
|
+
|
|
423
|
+
interface HamlibPortCaps {
|
|
424
|
+
portType: HamlibPortType;
|
|
425
|
+
serialRateMin?: number;
|
|
426
|
+
serialRateMax?: number;
|
|
427
|
+
serialDataBits?: number;
|
|
428
|
+
serialStopBits?: number;
|
|
429
|
+
serialParity?: string;
|
|
430
|
+
serialHandshake?: string;
|
|
431
|
+
writeDelay: number;
|
|
432
|
+
postWriteDelay: number;
|
|
433
|
+
timeout: number;
|
|
434
|
+
retry: number;
|
|
435
|
+
}
|
|
436
|
+
|
|
381
437
|
/**
|
|
382
438
|
* HamLib class - for controlling amateur radio devices
|
|
383
439
|
*/
|
|
@@ -856,6 +912,18 @@ declare class HamLib extends EventEmitter {
|
|
|
856
912
|
*/
|
|
857
913
|
getSupportedSerialConfigs(): SerialConfigOptions;
|
|
858
914
|
|
|
915
|
+
/**
|
|
916
|
+
* Get backend-specific configuration schema for the current rig model.
|
|
917
|
+
* This can be queried before opening the connection and is suitable for
|
|
918
|
+
* driving dynamic configuration UIs.
|
|
919
|
+
*/
|
|
920
|
+
getConfigSchema(): HamlibConfigFieldDescriptor[];
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* Get backend port capabilities and effective connection defaults.
|
|
924
|
+
*/
|
|
925
|
+
getPortCaps(): HamlibPortCaps;
|
|
926
|
+
|
|
859
927
|
// Power Control
|
|
860
928
|
|
|
861
929
|
/**
|
|
@@ -1543,6 +1611,7 @@ export { ConnectionInfo, ModeInfo, SupportedRigInfo, AntennaInfo, VFO, RadioMode
|
|
|
1543
1611
|
MemoryChannelInfo, SplitModeInfo, SplitStatusInfo, LevelType, FunctionType,
|
|
1544
1612
|
ScanType, VfoOperationType, SerialConfigParam, SerialBaudRate, SerialParity,
|
|
1545
1613
|
SerialHandshake, SerialControlState, PttType, DcdType, SerialConfigOptions,
|
|
1614
|
+
HamlibConfigFieldType, HamlibConfigFieldDescriptor, HamlibPortType, HamlibPortCaps,
|
|
1546
1615
|
SpectrumScopeInfo, SpectrumModeInfo, SpectrumAverageModeInfo, SpectrumLine,
|
|
1547
1616
|
SpectrumCapabilities, SpectrumSupportSummary, SpectrumConfig, SpectrumDisplayState,
|
|
1548
1617
|
ClockInfo, VfoInfo, HamLib };
|
package/lib/index.js
CHANGED
|
@@ -589,6 +589,25 @@ class HamLib extends EventEmitter {
|
|
|
589
589
|
return this._nativeInstance.getSupportedSerialConfigs();
|
|
590
590
|
}
|
|
591
591
|
|
|
592
|
+
/**
|
|
593
|
+
* Get backend-specific configuration schema for the selected rig model.
|
|
594
|
+
* This can be queried before opening the connection and is intended for
|
|
595
|
+
* dynamic configuration UIs.
|
|
596
|
+
* @returns {Array<Object>} List of config field descriptors
|
|
597
|
+
*/
|
|
598
|
+
getConfigSchema() {
|
|
599
|
+
return this._nativeInstance.getConfigSchema();
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Get backend port capabilities and effective connection defaults derived
|
|
604
|
+
* from Hamlib rig caps for the selected model.
|
|
605
|
+
* @returns {Object} Port type and default connection parameters
|
|
606
|
+
*/
|
|
607
|
+
getPortCaps() {
|
|
608
|
+
return this._nativeInstance.getPortCaps();
|
|
609
|
+
}
|
|
610
|
+
|
|
592
611
|
// Power Control
|
|
593
612
|
|
|
594
613
|
/**
|
package/lib/spectrum.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hamlib",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Node.js bindings for Hamlib rig control with official spectrum streaming support",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "lib/index.mjs",
|
|
@@ -12,9 +12,16 @@
|
|
|
12
12
|
"types": "./index.d.ts"
|
|
13
13
|
},
|
|
14
14
|
"./spectrum": {
|
|
15
|
-
"import": "./
|
|
16
|
-
"require": "./
|
|
17
|
-
"types": "./
|
|
15
|
+
"import": "./spectrum.mjs",
|
|
16
|
+
"require": "./spectrum.js",
|
|
17
|
+
"types": "./spectrum.d.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"typesVersions": {
|
|
21
|
+
"*": {
|
|
22
|
+
"spectrum": [
|
|
23
|
+
"spectrum.d.ts"
|
|
24
|
+
]
|
|
18
25
|
}
|
|
19
26
|
},
|
|
20
27
|
"gypfile": true,
|
|
@@ -38,6 +45,9 @@
|
|
|
38
45
|
"docs/",
|
|
39
46
|
"index.js",
|
|
40
47
|
"index.d.ts",
|
|
48
|
+
"spectrum.js",
|
|
49
|
+
"spectrum.mjs",
|
|
50
|
+
"spectrum.d.ts",
|
|
41
51
|
"binding.gyp",
|
|
42
52
|
"COPYING",
|
|
43
53
|
"README.md"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/spectrum.d.ts
ADDED
package/spectrum.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./lib/spectrum.js');
|
package/spectrum.mjs
ADDED
package/src/hamlib.cpp
CHANGED
|
@@ -40,6 +40,23 @@ struct RigListData {
|
|
|
40
40
|
Napi::Env env;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
struct RigConfigFieldDescriptor {
|
|
44
|
+
int token;
|
|
45
|
+
std::string name;
|
|
46
|
+
std::string label;
|
|
47
|
+
std::string tooltip;
|
|
48
|
+
std::string defaultValue;
|
|
49
|
+
int type;
|
|
50
|
+
double numericMin;
|
|
51
|
+
double numericMax;
|
|
52
|
+
double numericStep;
|
|
53
|
+
std::vector<std::string> options;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
struct RigConfigSchemaData {
|
|
57
|
+
std::vector<RigConfigFieldDescriptor> fields;
|
|
58
|
+
};
|
|
59
|
+
|
|
43
60
|
using namespace Napi;
|
|
44
61
|
|
|
45
62
|
Napi::FunctionReference NodeHamLib::constructor;
|
|
@@ -55,6 +72,31 @@ static std::string publicVfoToken(int vfo) {
|
|
|
55
72
|
return rawToken;
|
|
56
73
|
}
|
|
57
74
|
|
|
75
|
+
static const char* publicConfTypeName(int type) {
|
|
76
|
+
switch (type) {
|
|
77
|
+
case 0:
|
|
78
|
+
return "string";
|
|
79
|
+
case 1:
|
|
80
|
+
return "combo";
|
|
81
|
+
case 2:
|
|
82
|
+
return "numeric";
|
|
83
|
+
case 3:
|
|
84
|
+
return "checkbutton";
|
|
85
|
+
case 4:
|
|
86
|
+
return "button";
|
|
87
|
+
case 5:
|
|
88
|
+
return "binary";
|
|
89
|
+
case 6:
|
|
90
|
+
return "int";
|
|
91
|
+
default:
|
|
92
|
+
return "unknown";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static bool hasPositiveValue(int value) {
|
|
97
|
+
return value > 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
58
100
|
static int parseVfoString(Napi::Env env, const std::string& vfoToken) {
|
|
59
101
|
int vfo = shim_rig_parse_vfo(vfoToken.c_str());
|
|
60
102
|
if (vfo == SHIM_RIG_VFO_NONE) {
|
|
@@ -3832,6 +3874,8 @@ Napi::Function NodeHamLib::GetClass(Napi::Env env) {
|
|
|
3832
3874
|
NodeHamLib::InstanceMethod("setDcdType", & NodeHamLib::SetDcdType),
|
|
3833
3875
|
NodeHamLib::InstanceMethod("getDcdType", & NodeHamLib::GetDcdType),
|
|
3834
3876
|
NodeHamLib::InstanceMethod("getSupportedSerialConfigs", & NodeHamLib::GetSupportedSerialConfigs),
|
|
3877
|
+
NodeHamLib::InstanceMethod("getConfigSchema", & NodeHamLib::GetConfigSchema),
|
|
3878
|
+
NodeHamLib::InstanceMethod("getPortCaps", & NodeHamLib::GetPortCaps),
|
|
3835
3879
|
|
|
3836
3880
|
// Power Control
|
|
3837
3881
|
NodeHamLib::InstanceMethod("setPowerstat", & NodeHamLib::SetPowerstat),
|
|
@@ -4220,7 +4264,7 @@ Napi::Value NodeHamLib::GetSupportedSerialConfigs(const Napi::CallbackInfo& info
|
|
|
4220
4264
|
pttTypeOptions[5u] = Napi::String::New(env, "GPIO");
|
|
4221
4265
|
pttTypeOptions[6u] = Napi::String::New(env, "GPION");
|
|
4222
4266
|
pttTypeOptions[7u] = Napi::String::New(env, "NONE");
|
|
4223
|
-
configs.Set("
|
|
4267
|
+
configs.Set("ptt_type", pttTypeOptions);
|
|
4224
4268
|
|
|
4225
4269
|
// DCD type options
|
|
4226
4270
|
Napi::Array dcdTypeOptions = Napi::Array::New(env, 9);
|
|
@@ -4233,11 +4277,124 @@ Napi::Value NodeHamLib::GetSupportedSerialConfigs(const Napi::CallbackInfo& info
|
|
|
4233
4277
|
dcdTypeOptions[6u] = Napi::String::New(env, "GPIO");
|
|
4234
4278
|
dcdTypeOptions[7u] = Napi::String::New(env, "GPION");
|
|
4235
4279
|
dcdTypeOptions[8u] = Napi::String::New(env, "NONE");
|
|
4236
|
-
configs.Set("
|
|
4280
|
+
configs.Set("dcd_type", dcdTypeOptions);
|
|
4237
4281
|
|
|
4238
4282
|
return configs;
|
|
4239
4283
|
}
|
|
4240
4284
|
|
|
4285
|
+
int NodeHamLib::rig_config_callback(const shim_confparam_info_t* info, void* data) {
|
|
4286
|
+
RigConfigSchemaData* schema_data = static_cast<RigConfigSchemaData*>(data);
|
|
4287
|
+
|
|
4288
|
+
if (!schema_data || !info) {
|
|
4289
|
+
return 0;
|
|
4290
|
+
}
|
|
4291
|
+
|
|
4292
|
+
RigConfigFieldDescriptor field;
|
|
4293
|
+
field.token = info->token;
|
|
4294
|
+
field.name = info->name;
|
|
4295
|
+
field.label = info->label;
|
|
4296
|
+
field.tooltip = info->tooltip;
|
|
4297
|
+
field.defaultValue = info->dflt;
|
|
4298
|
+
field.type = info->type;
|
|
4299
|
+
field.numericMin = info->numeric_min;
|
|
4300
|
+
field.numericMax = info->numeric_max;
|
|
4301
|
+
field.numericStep = info->numeric_step;
|
|
4302
|
+
|
|
4303
|
+
for (int i = 0; i < info->combo_count; ++i) {
|
|
4304
|
+
field.options.emplace_back(info->combo_options[i]);
|
|
4305
|
+
}
|
|
4306
|
+
|
|
4307
|
+
schema_data->fields.push_back(field);
|
|
4308
|
+
return 1;
|
|
4309
|
+
}
|
|
4310
|
+
|
|
4311
|
+
Napi::Value NodeHamLib::GetConfigSchema(const Napi::CallbackInfo& info) {
|
|
4312
|
+
Napi::Env env = info.Env();
|
|
4313
|
+
RETURN_NULL_IF_RIG_HANDLE_INVALID();
|
|
4314
|
+
|
|
4315
|
+
RigConfigSchemaData schemaData{};
|
|
4316
|
+
int result = shim_rig_cfgparams_foreach(my_rig, rig_config_callback, &schemaData);
|
|
4317
|
+
|
|
4318
|
+
if (result != SHIM_RIG_OK) {
|
|
4319
|
+
Napi::Error::New(env, shim_rigerror(result)).ThrowAsJavaScriptException();
|
|
4320
|
+
return env.Null();
|
|
4321
|
+
}
|
|
4322
|
+
|
|
4323
|
+
Napi::Array schemaArray = Napi::Array::New(env, schemaData.fields.size());
|
|
4324
|
+
for (size_t i = 0; i < schemaData.fields.size(); ++i) {
|
|
4325
|
+
const RigConfigFieldDescriptor& descriptor = schemaData.fields[i];
|
|
4326
|
+
Napi::Object field = Napi::Object::New(env);
|
|
4327
|
+
field.Set("token", Napi::Number::New(env, descriptor.token));
|
|
4328
|
+
field.Set("name", Napi::String::New(env, descriptor.name));
|
|
4329
|
+
field.Set("label", Napi::String::New(env, descriptor.label));
|
|
4330
|
+
field.Set("tooltip", Napi::String::New(env, descriptor.tooltip));
|
|
4331
|
+
field.Set("defaultValue", Napi::String::New(env, descriptor.defaultValue));
|
|
4332
|
+
field.Set("type", Napi::String::New(env, publicConfTypeName(descriptor.type)));
|
|
4333
|
+
|
|
4334
|
+
if (descriptor.type == 2 || descriptor.type == 6) {
|
|
4335
|
+
Napi::Object numeric = Napi::Object::New(env);
|
|
4336
|
+
numeric.Set("min", Napi::Number::New(env, descriptor.numericMin));
|
|
4337
|
+
numeric.Set("max", Napi::Number::New(env, descriptor.numericMax));
|
|
4338
|
+
numeric.Set("step", Napi::Number::New(env, descriptor.numericStep));
|
|
4339
|
+
field.Set("numeric", numeric);
|
|
4340
|
+
}
|
|
4341
|
+
|
|
4342
|
+
if (!descriptor.options.empty()) {
|
|
4343
|
+
Napi::Array options = Napi::Array::New(env, descriptor.options.size());
|
|
4344
|
+
for (size_t optionIndex = 0; optionIndex < descriptor.options.size(); ++optionIndex) {
|
|
4345
|
+
options[static_cast<uint32_t>(optionIndex)] =
|
|
4346
|
+
Napi::String::New(env, descriptor.options[optionIndex]);
|
|
4347
|
+
}
|
|
4348
|
+
field.Set("options", options);
|
|
4349
|
+
}
|
|
4350
|
+
|
|
4351
|
+
schemaArray[static_cast<uint32_t>(i)] = field;
|
|
4352
|
+
}
|
|
4353
|
+
|
|
4354
|
+
return schemaArray;
|
|
4355
|
+
}
|
|
4356
|
+
|
|
4357
|
+
Napi::Value NodeHamLib::GetPortCaps(const Napi::CallbackInfo& info) {
|
|
4358
|
+
Napi::Env env = info.Env();
|
|
4359
|
+
RETURN_NULL_IF_RIG_HANDLE_INVALID();
|
|
4360
|
+
|
|
4361
|
+
shim_rig_port_caps_t caps{};
|
|
4362
|
+
int result = shim_rig_get_port_caps(my_rig, &caps);
|
|
4363
|
+
|
|
4364
|
+
if (result != SHIM_RIG_OK) {
|
|
4365
|
+
Napi::Error::New(env, shim_rigerror(result)).ThrowAsJavaScriptException();
|
|
4366
|
+
return env.Null();
|
|
4367
|
+
}
|
|
4368
|
+
|
|
4369
|
+
Napi::Object portCaps = Napi::Object::New(env);
|
|
4370
|
+
portCaps.Set("portType", Napi::String::New(env, caps.port_type));
|
|
4371
|
+
portCaps.Set("writeDelay", Napi::Number::New(env, caps.write_delay));
|
|
4372
|
+
portCaps.Set("postWriteDelay", Napi::Number::New(env, caps.post_write_delay));
|
|
4373
|
+
portCaps.Set("timeout", Napi::Number::New(env, caps.timeout));
|
|
4374
|
+
portCaps.Set("retry", Napi::Number::New(env, caps.retry));
|
|
4375
|
+
|
|
4376
|
+
if (hasPositiveValue(caps.serial_rate_min)) {
|
|
4377
|
+
portCaps.Set("serialRateMin", Napi::Number::New(env, caps.serial_rate_min));
|
|
4378
|
+
}
|
|
4379
|
+
if (hasPositiveValue(caps.serial_rate_max)) {
|
|
4380
|
+
portCaps.Set("serialRateMax", Napi::Number::New(env, caps.serial_rate_max));
|
|
4381
|
+
}
|
|
4382
|
+
if (hasPositiveValue(caps.serial_data_bits)) {
|
|
4383
|
+
portCaps.Set("serialDataBits", Napi::Number::New(env, caps.serial_data_bits));
|
|
4384
|
+
}
|
|
4385
|
+
if (hasPositiveValue(caps.serial_stop_bits)) {
|
|
4386
|
+
portCaps.Set("serialStopBits", Napi::Number::New(env, caps.serial_stop_bits));
|
|
4387
|
+
}
|
|
4388
|
+
if (caps.serial_parity[0] != '\0' && std::string(caps.serial_parity) != "Unknown") {
|
|
4389
|
+
portCaps.Set("serialParity", Napi::String::New(env, caps.serial_parity));
|
|
4390
|
+
}
|
|
4391
|
+
if (caps.serial_handshake[0] != '\0' && std::string(caps.serial_handshake) != "Unknown") {
|
|
4392
|
+
portCaps.Set("serialHandshake", Napi::String::New(env, caps.serial_handshake));
|
|
4393
|
+
}
|
|
4394
|
+
|
|
4395
|
+
return portCaps;
|
|
4396
|
+
}
|
|
4397
|
+
|
|
4241
4398
|
// Power Control Methods
|
|
4242
4399
|
Napi::Value NodeHamLib::SetPowerstat(const Napi::CallbackInfo& info) {
|
|
4243
4400
|
Napi::Env env = info.Env();
|
|
@@ -6156,11 +6313,7 @@ private:
|
|
|
6156
6313
|
|
|
6157
6314
|
Napi::Value NodeHamLib::SetConf(const Napi::CallbackInfo& info) {
|
|
6158
6315
|
Napi::Env env = info.Env();
|
|
6159
|
-
|
|
6160
|
-
if (!rig_is_open) {
|
|
6161
|
-
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
6162
|
-
return env.Null();
|
|
6163
|
-
}
|
|
6316
|
+
RETURN_NULL_IF_RIG_HANDLE_INVALID();
|
|
6164
6317
|
|
|
6165
6318
|
if (info.Length() < 2 || !info[0].IsString() || !info[1].IsString()) {
|
|
6166
6319
|
Napi::TypeError::New(env, "Expected (name: string, value: string)").ThrowAsJavaScriptException();
|
|
@@ -6212,11 +6365,7 @@ private:
|
|
|
6212
6365
|
|
|
6213
6366
|
Napi::Value NodeHamLib::GetConf(const Napi::CallbackInfo& info) {
|
|
6214
6367
|
Napi::Env env = info.Env();
|
|
6215
|
-
|
|
6216
|
-
if (!rig_is_open) {
|
|
6217
|
-
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
6218
|
-
return env.Null();
|
|
6219
|
-
}
|
|
6368
|
+
RETURN_NULL_IF_RIG_HANDLE_INVALID();
|
|
6220
6369
|
|
|
6221
6370
|
if (info.Length() < 1 || !info[0].IsString()) {
|
|
6222
6371
|
Napi::TypeError::New(env, "Expected (name: string)").ThrowAsJavaScriptException();
|
package/src/hamlib.h
CHANGED
|
@@ -99,6 +99,8 @@ class NodeHamLib : public Napi::ObjectWrap<NodeHamLib> {
|
|
|
99
99
|
Napi::Value SetDcdType(const Napi::CallbackInfo&);
|
|
100
100
|
Napi::Value GetDcdType(const Napi::CallbackInfo&);
|
|
101
101
|
Napi::Value GetSupportedSerialConfigs(const Napi::CallbackInfo&);
|
|
102
|
+
Napi::Value GetConfigSchema(const Napi::CallbackInfo&);
|
|
103
|
+
Napi::Value GetPortCaps(const Napi::CallbackInfo&);
|
|
102
104
|
|
|
103
105
|
// Power Control
|
|
104
106
|
Napi::Value SetPowerstat(const Napi::CallbackInfo&);
|
|
@@ -242,6 +244,7 @@ class NodeHamLib : public Napi::ObjectWrap<NodeHamLib> {
|
|
|
242
244
|
|
|
243
245
|
// Static callback helper for shim_rig_list_foreach
|
|
244
246
|
static int rig_list_callback(const shim_rig_info_t* info, void* data);
|
|
247
|
+
static int rig_config_callback(const shim_confparam_info_t* info, void* data);
|
|
245
248
|
|
|
246
249
|
void EmitSpectrumLine(const shim_spectrum_line_t& line);
|
|
247
250
|
void StopSpectrumStreamInternal();
|
package/src/shim/hamlib_shim.c
CHANGED
|
@@ -66,6 +66,19 @@ struct shim_list_adapter {
|
|
|
66
66
|
void* user_data;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
+
struct shim_cfg_adapter {
|
|
70
|
+
RIG* rig;
|
|
71
|
+
shim_rig_cfg_cb_t user_cb;
|
|
72
|
+
void* user_data;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
static void shim_copy_string(char* dest, size_t dest_size, const char* src) {
|
|
76
|
+
if (!dest || dest_size == 0) return;
|
|
77
|
+
if (!src) src = "";
|
|
78
|
+
strncpy(dest, src, dest_size - 1);
|
|
79
|
+
dest[dest_size - 1] = '\0';
|
|
80
|
+
}
|
|
81
|
+
|
|
69
82
|
static int shim_list_foreach_adapter(const struct rig_caps *caps, void *data) {
|
|
70
83
|
struct shim_list_adapter *adapter = (struct shim_list_adapter*)data;
|
|
71
84
|
shim_rig_info_t info;
|
|
@@ -85,6 +98,137 @@ SHIM_API int shim_rig_list_foreach(shim_rig_list_cb_t cb, void* data) {
|
|
|
85
98
|
return rig_list_foreach(shim_list_foreach_adapter, &adapter);
|
|
86
99
|
}
|
|
87
100
|
|
|
101
|
+
static int shim_cfg_foreach_adapter(const struct confparams* param, rig_ptr_t data) {
|
|
102
|
+
struct shim_cfg_adapter* adapter = (struct shim_cfg_adapter*)data;
|
|
103
|
+
const struct confparams* lookup;
|
|
104
|
+
shim_confparam_info_t info;
|
|
105
|
+
int i;
|
|
106
|
+
|
|
107
|
+
if (!adapter || !adapter->user_cb || !param) {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!adapter->rig || !param->name) {
|
|
112
|
+
return 1;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
lookup = rig_confparam_lookup(adapter->rig, param->name);
|
|
116
|
+
if (!lookup || lookup->token != param->token) {
|
|
117
|
+
return 1;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
memset(&info, 0, sizeof(info));
|
|
121
|
+
info.token = (int)param->token;
|
|
122
|
+
info.type = (int)param->type;
|
|
123
|
+
|
|
124
|
+
shim_copy_string(info.name, sizeof(info.name), param->name);
|
|
125
|
+
shim_copy_string(info.label, sizeof(info.label), param->label);
|
|
126
|
+
shim_copy_string(info.tooltip, sizeof(info.tooltip), param->tooltip);
|
|
127
|
+
shim_copy_string(info.dflt, sizeof(info.dflt), param->dflt);
|
|
128
|
+
|
|
129
|
+
if (param->type == RIG_CONF_NUMERIC || param->type == RIG_CONF_INT) {
|
|
130
|
+
info.numeric_min = param->u.n.min;
|
|
131
|
+
info.numeric_max = param->u.n.max;
|
|
132
|
+
info.numeric_step = param->u.n.step;
|
|
133
|
+
} else if (param->type == RIG_CONF_COMBO) {
|
|
134
|
+
for (i = 0; i < RIG_COMBO_MAX && i < SHIM_CONF_COMBO_MAX; ++i) {
|
|
135
|
+
if (!param->u.c.combostr[i] || !*param->u.c.combostr[i]) {
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
shim_copy_string(
|
|
140
|
+
info.combo_options[i],
|
|
141
|
+
sizeof(info.combo_options[i]),
|
|
142
|
+
param->u.c.combostr[i]
|
|
143
|
+
);
|
|
144
|
+
info.combo_count++;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return adapter->user_cb(&info, adapter->user_data);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
SHIM_API int shim_rig_cfgparams_foreach(hamlib_shim_handle_t h, shim_rig_cfg_cb_t cb, void* data) {
|
|
152
|
+
RIG* rig = (RIG*)h;
|
|
153
|
+
struct shim_cfg_adapter adapter;
|
|
154
|
+
|
|
155
|
+
if (!rig || !cb) {
|
|
156
|
+
return -RIG_EINVAL;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
adapter.rig = rig;
|
|
160
|
+
adapter.user_cb = cb;
|
|
161
|
+
adapter.user_data = data;
|
|
162
|
+
|
|
163
|
+
return rig_token_foreach(rig, shim_cfg_foreach_adapter, &adapter);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
static const char* shim_port_type_name(enum rig_port_e port_type) {
|
|
167
|
+
switch (port_type) {
|
|
168
|
+
case RIG_PORT_NONE: return "none";
|
|
169
|
+
case RIG_PORT_SERIAL: return "serial";
|
|
170
|
+
case RIG_PORT_NETWORK: return "network";
|
|
171
|
+
case RIG_PORT_DEVICE: return "device";
|
|
172
|
+
case RIG_PORT_PACKET: return "packet";
|
|
173
|
+
case RIG_PORT_DTMF: return "dtmf";
|
|
174
|
+
case RIG_PORT_ULTRA: return "ultra";
|
|
175
|
+
case RIG_PORT_RPC: return "rpc";
|
|
176
|
+
case RIG_PORT_PARALLEL: return "parallel";
|
|
177
|
+
case RIG_PORT_USB: return "usb";
|
|
178
|
+
case RIG_PORT_UDP_NETWORK: return "udp-network";
|
|
179
|
+
case RIG_PORT_CM108: return "cm108";
|
|
180
|
+
case RIG_PORT_GPIO: return "gpio";
|
|
181
|
+
case RIG_PORT_GPION: return "gpion";
|
|
182
|
+
default: return "other";
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
static const char* shim_serial_parity_name(enum serial_parity_e parity) {
|
|
187
|
+
switch (parity) {
|
|
188
|
+
case RIG_PARITY_NONE: return "None";
|
|
189
|
+
case RIG_PARITY_ODD: return "Odd";
|
|
190
|
+
case RIG_PARITY_EVEN: return "Even";
|
|
191
|
+
case RIG_PARITY_MARK: return "Mark";
|
|
192
|
+
case RIG_PARITY_SPACE: return "Space";
|
|
193
|
+
default: return "Unknown";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
static const char* shim_serial_handshake_name(enum serial_handshake_e handshake) {
|
|
198
|
+
switch (handshake) {
|
|
199
|
+
case RIG_HANDSHAKE_NONE: return "None";
|
|
200
|
+
case RIG_HANDSHAKE_XONXOFF: return "XONXOFF";
|
|
201
|
+
case RIG_HANDSHAKE_HARDWARE: return "Hardware";
|
|
202
|
+
default: return "Unknown";
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
SHIM_API int shim_rig_get_port_caps(hamlib_shim_handle_t h, shim_rig_port_caps_t* out_caps) {
|
|
207
|
+
RIG* rig = (RIG*)h;
|
|
208
|
+
const struct rig_caps* caps;
|
|
209
|
+
|
|
210
|
+
if (!rig || !out_caps || !rig->caps) {
|
|
211
|
+
return -RIG_EINVAL;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
caps = rig->caps;
|
|
215
|
+
memset(out_caps, 0, sizeof(*out_caps));
|
|
216
|
+
|
|
217
|
+
shim_copy_string(out_caps->port_type, sizeof(out_caps->port_type), shim_port_type_name(caps->port_type));
|
|
218
|
+
out_caps->serial_rate_min = caps->serial_rate_min;
|
|
219
|
+
out_caps->serial_rate_max = caps->serial_rate_max;
|
|
220
|
+
out_caps->serial_data_bits = caps->serial_data_bits;
|
|
221
|
+
out_caps->serial_stop_bits = caps->serial_stop_bits;
|
|
222
|
+
shim_copy_string(out_caps->serial_parity, sizeof(out_caps->serial_parity), shim_serial_parity_name(caps->serial_parity));
|
|
223
|
+
shim_copy_string(out_caps->serial_handshake, sizeof(out_caps->serial_handshake), shim_serial_handshake_name(caps->serial_handshake));
|
|
224
|
+
out_caps->write_delay = caps->write_delay;
|
|
225
|
+
out_caps->post_write_delay = caps->post_write_delay;
|
|
226
|
+
out_caps->timeout = caps->timeout;
|
|
227
|
+
out_caps->retry = caps->retry;
|
|
228
|
+
|
|
229
|
+
return RIG_OK;
|
|
230
|
+
}
|
|
231
|
+
|
|
88
232
|
SHIM_API const char* shim_rig_strstatus(int status) {
|
|
89
233
|
return rig_strstatus((enum rig_status_e)status);
|
|
90
234
|
}
|
package/src/shim/hamlib_shim.h
CHANGED
|
@@ -293,6 +293,44 @@ typedef struct {
|
|
|
293
293
|
int rig_type;
|
|
294
294
|
} shim_rig_info_t;
|
|
295
295
|
|
|
296
|
+
#define SHIM_CONF_NAME_MAX 64
|
|
297
|
+
#define SHIM_CONF_LABEL_MAX 128
|
|
298
|
+
#define SHIM_CONF_TOOLTIP_MAX 256
|
|
299
|
+
#define SHIM_CONF_DEFAULT_MAX 128
|
|
300
|
+
#define SHIM_CONF_COMBO_MAX 16
|
|
301
|
+
#define SHIM_CONF_COMBO_VALUE_MAX 64
|
|
302
|
+
#define SHIM_PORT_TYPE_MAX 32
|
|
303
|
+
#define SHIM_PARITY_MAX 32
|
|
304
|
+
#define SHIM_HANDSHAKE_MAX 32
|
|
305
|
+
|
|
306
|
+
typedef struct {
|
|
307
|
+
int token;
|
|
308
|
+
char name[SHIM_CONF_NAME_MAX];
|
|
309
|
+
char label[SHIM_CONF_LABEL_MAX];
|
|
310
|
+
char tooltip[SHIM_CONF_TOOLTIP_MAX];
|
|
311
|
+
char dflt[SHIM_CONF_DEFAULT_MAX];
|
|
312
|
+
int type;
|
|
313
|
+
double numeric_min;
|
|
314
|
+
double numeric_max;
|
|
315
|
+
double numeric_step;
|
|
316
|
+
int combo_count;
|
|
317
|
+
char combo_options[SHIM_CONF_COMBO_MAX][SHIM_CONF_COMBO_VALUE_MAX];
|
|
318
|
+
} shim_confparam_info_t;
|
|
319
|
+
|
|
320
|
+
typedef struct {
|
|
321
|
+
char port_type[SHIM_PORT_TYPE_MAX];
|
|
322
|
+
int serial_rate_min;
|
|
323
|
+
int serial_rate_max;
|
|
324
|
+
int serial_data_bits;
|
|
325
|
+
int serial_stop_bits;
|
|
326
|
+
char serial_parity[SHIM_PARITY_MAX];
|
|
327
|
+
char serial_handshake[SHIM_HANDSHAKE_MAX];
|
|
328
|
+
int write_delay;
|
|
329
|
+
int post_write_delay;
|
|
330
|
+
int timeout;
|
|
331
|
+
int retry;
|
|
332
|
+
} shim_rig_port_caps_t;
|
|
333
|
+
|
|
296
334
|
typedef struct {
|
|
297
335
|
int id;
|
|
298
336
|
char name[64];
|
|
@@ -331,6 +369,8 @@ typedef int (*shim_spectrum_cb_t)(void* handle, const shim_spectrum_line_t* line
|
|
|
331
369
|
|
|
332
370
|
/* Rig list callback: (info, data) -> int */
|
|
333
371
|
typedef int (*shim_rig_list_cb_t)(const shim_rig_info_t* info, void* data);
|
|
372
|
+
/* Rig config callback: (info, data) -> int */
|
|
373
|
+
typedef int (*shim_rig_cfg_cb_t)(const shim_confparam_info_t* info, void* data);
|
|
334
374
|
|
|
335
375
|
/* ===== Lifecycle functions ===== */
|
|
336
376
|
|
|
@@ -347,6 +387,8 @@ SHIM_API int shim_rig_get_debug(void);
|
|
|
347
387
|
SHIM_API const char* shim_rig_get_version(void);
|
|
348
388
|
SHIM_API int shim_rig_load_all_backends(void);
|
|
349
389
|
SHIM_API int shim_rig_list_foreach(shim_rig_list_cb_t cb, void* data);
|
|
390
|
+
SHIM_API int shim_rig_cfgparams_foreach(hamlib_shim_handle_t h, shim_rig_cfg_cb_t cb, void* data);
|
|
391
|
+
SHIM_API int shim_rig_get_port_caps(hamlib_shim_handle_t h, shim_rig_port_caps_t* out_caps);
|
|
350
392
|
SHIM_API const char* shim_rig_strstatus(int status);
|
|
351
393
|
|
|
352
394
|
/* ===== Port configuration (before open) ===== */
|