hamlib 0.1.2 → 0.1.3
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/Readme.md +367 -163
- package/index.d.ts +299 -1
- package/lib/binary-loader.js +3 -3
- package/lib/index.js +237 -0
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/hamlib.node +0 -0
- package/prebuilds/linux-arm64/hamlib.node +0 -0
- package/prebuilds/linux-x64/hamlib.node +0 -0
- package/src/hamlib.cpp +1128 -1
- package/src/hamlib.h +48 -0
package/src/hamlib.cpp
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
#include "hamlib.h"
|
|
2
2
|
#include <string>
|
|
3
|
+
#include <vector>
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
// Structure to hold rig information for the callback
|
|
6
|
+
struct RigListData {
|
|
7
|
+
std::vector<Napi::Object> rigList;
|
|
8
|
+
Napi::Env env;
|
|
9
|
+
};
|
|
5
10
|
|
|
6
11
|
using namespace Napi;
|
|
7
12
|
|
|
@@ -430,6 +435,1002 @@ Napi::Value NodeHamLib::GetConnectionInfo(const Napi::CallbackInfo & info) {
|
|
|
430
435
|
return obj;
|
|
431
436
|
}
|
|
432
437
|
|
|
438
|
+
// Memory Channel Management
|
|
439
|
+
Napi::Value NodeHamLib::SetMemoryChannel(const Napi::CallbackInfo & info) {
|
|
440
|
+
Napi::Env env = info.Env();
|
|
441
|
+
|
|
442
|
+
if (!rig_is_open) {
|
|
443
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
444
|
+
return env.Null();
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (info.Length() < 2 || !info[0].IsNumber() || !info[1].IsObject()) {
|
|
448
|
+
Napi::TypeError::New(env, "Expected (channelNumber: number, channelData: object)").ThrowAsJavaScriptException();
|
|
449
|
+
return env.Null();
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
int channel_num = info[0].As<Napi::Number>().Int32Value();
|
|
453
|
+
Napi::Object chanObj = info[1].As<Napi::Object>();
|
|
454
|
+
|
|
455
|
+
// Create channel structure
|
|
456
|
+
channel_t chan;
|
|
457
|
+
memset(&chan, 0, sizeof(chan));
|
|
458
|
+
|
|
459
|
+
chan.channel_num = channel_num;
|
|
460
|
+
chan.vfo = RIG_VFO_MEM;
|
|
461
|
+
|
|
462
|
+
// Extract frequency
|
|
463
|
+
if (chanObj.Has("frequency")) {
|
|
464
|
+
chan.freq = chanObj.Get("frequency").As<Napi::Number>().DoubleValue();
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Extract mode
|
|
468
|
+
if (chanObj.Has("mode")) {
|
|
469
|
+
std::string modeStr = chanObj.Get("mode").As<Napi::String>().Utf8Value();
|
|
470
|
+
chan.mode = rig_parse_mode(modeStr.c_str());
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Extract bandwidth
|
|
474
|
+
if (chanObj.Has("bandwidth")) {
|
|
475
|
+
chan.width = chanObj.Get("bandwidth").As<Napi::Number>().Int32Value();
|
|
476
|
+
} else {
|
|
477
|
+
chan.width = RIG_PASSBAND_NORMAL;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Extract channel description
|
|
481
|
+
if (chanObj.Has("description")) {
|
|
482
|
+
std::string desc = chanObj.Get("description").As<Napi::String>().Utf8Value();
|
|
483
|
+
strncpy(chan.channel_desc, desc.c_str(), sizeof(chan.channel_desc) - 1);
|
|
484
|
+
chan.channel_desc[sizeof(chan.channel_desc) - 1] = '\0';
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Extract TX frequency for split operation
|
|
488
|
+
if (chanObj.Has("txFrequency")) {
|
|
489
|
+
chan.tx_freq = chanObj.Get("txFrequency").As<Napi::Number>().DoubleValue();
|
|
490
|
+
chan.split = RIG_SPLIT_ON;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Extract CTCSS tone
|
|
494
|
+
if (chanObj.Has("ctcssTone")) {
|
|
495
|
+
chan.ctcss_tone = chanObj.Get("ctcssTone").As<Napi::Number>().Int32Value();
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
int retcode = rig_set_channel(my_rig, RIG_VFO_MEM, &chan);
|
|
499
|
+
if (retcode != RIG_OK) {
|
|
500
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
501
|
+
return env.Null();
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return Napi::Number::New(env, retcode);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
Napi::Value NodeHamLib::GetMemoryChannel(const Napi::CallbackInfo & info) {
|
|
508
|
+
Napi::Env env = info.Env();
|
|
509
|
+
|
|
510
|
+
if (!rig_is_open) {
|
|
511
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
512
|
+
return env.Null();
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (info.Length() < 1 || !info[0].IsNumber()) {
|
|
516
|
+
Napi::TypeError::New(env, "Expected channel number").ThrowAsJavaScriptException();
|
|
517
|
+
return env.Null();
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
int channel_num = info[0].As<Napi::Number>().Int32Value();
|
|
521
|
+
bool read_only = true;
|
|
522
|
+
|
|
523
|
+
if (info.Length() >= 2 && info[1].IsBoolean()) {
|
|
524
|
+
read_only = info[1].As<Napi::Boolean>().Value();
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Create channel structure
|
|
528
|
+
channel_t chan;
|
|
529
|
+
memset(&chan, 0, sizeof(chan));
|
|
530
|
+
chan.channel_num = channel_num;
|
|
531
|
+
chan.vfo = RIG_VFO_MEM;
|
|
532
|
+
|
|
533
|
+
int retcode = rig_get_channel(my_rig, RIG_VFO_MEM, &chan, read_only);
|
|
534
|
+
if (retcode != RIG_OK) {
|
|
535
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
536
|
+
return env.Null();
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Create result object
|
|
540
|
+
Napi::Object result = Napi::Object::New(env);
|
|
541
|
+
result.Set("channelNumber", Napi::Number::New(env, chan.channel_num));
|
|
542
|
+
result.Set("frequency", Napi::Number::New(env, chan.freq));
|
|
543
|
+
result.Set("mode", Napi::String::New(env, rig_strrmode(chan.mode)));
|
|
544
|
+
result.Set("bandwidth", Napi::Number::New(env, chan.width));
|
|
545
|
+
result.Set("description", Napi::String::New(env, chan.channel_desc));
|
|
546
|
+
|
|
547
|
+
if (chan.split == RIG_SPLIT_ON) {
|
|
548
|
+
result.Set("txFrequency", Napi::Number::New(env, chan.tx_freq));
|
|
549
|
+
result.Set("split", Napi::Boolean::New(env, true));
|
|
550
|
+
} else {
|
|
551
|
+
result.Set("split", Napi::Boolean::New(env, false));
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (chan.ctcss_tone > 0) {
|
|
555
|
+
result.Set("ctcssTone", Napi::Number::New(env, chan.ctcss_tone));
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return result;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
Napi::Value NodeHamLib::SelectMemoryChannel(const Napi::CallbackInfo & info) {
|
|
562
|
+
Napi::Env env = info.Env();
|
|
563
|
+
|
|
564
|
+
if (!rig_is_open) {
|
|
565
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
566
|
+
return env.Null();
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
if (info.Length() < 1 || !info[0].IsNumber()) {
|
|
570
|
+
Napi::TypeError::New(env, "Expected channel number").ThrowAsJavaScriptException();
|
|
571
|
+
return env.Null();
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
int channel_num = info[0].As<Napi::Number>().Int32Value();
|
|
575
|
+
|
|
576
|
+
int retcode = rig_set_mem(my_rig, RIG_VFO_CURR, channel_num);
|
|
577
|
+
if (retcode != RIG_OK) {
|
|
578
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
579
|
+
return env.Null();
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return Napi::Number::New(env, retcode);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// RIT/XIT Control
|
|
586
|
+
Napi::Value NodeHamLib::SetRit(const Napi::CallbackInfo & info) {
|
|
587
|
+
Napi::Env env = info.Env();
|
|
588
|
+
|
|
589
|
+
if (!rig_is_open) {
|
|
590
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
591
|
+
return env.Null();
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (info.Length() < 1 || !info[0].IsNumber()) {
|
|
595
|
+
Napi::TypeError::New(env, "Expected RIT offset in Hz").ThrowAsJavaScriptException();
|
|
596
|
+
return env.Null();
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
shortfreq_t rit_offset = info[0].As<Napi::Number>().Int32Value();
|
|
600
|
+
|
|
601
|
+
int retcode = rig_set_rit(my_rig, RIG_VFO_CURR, rit_offset);
|
|
602
|
+
if (retcode != RIG_OK) {
|
|
603
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
604
|
+
return env.Null();
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return Napi::Number::New(env, retcode);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
Napi::Value NodeHamLib::GetRit(const Napi::CallbackInfo & info) {
|
|
611
|
+
Napi::Env env = info.Env();
|
|
612
|
+
|
|
613
|
+
if (!rig_is_open) {
|
|
614
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
615
|
+
return env.Null();
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
shortfreq_t rit_offset;
|
|
619
|
+
int retcode = rig_get_rit(my_rig, RIG_VFO_CURR, &rit_offset);
|
|
620
|
+
if (retcode != RIG_OK) {
|
|
621
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
622
|
+
return env.Null();
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return Napi::Number::New(env, rit_offset);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
Napi::Value NodeHamLib::SetXit(const Napi::CallbackInfo & info) {
|
|
629
|
+
Napi::Env env = info.Env();
|
|
630
|
+
|
|
631
|
+
if (!rig_is_open) {
|
|
632
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
633
|
+
return env.Null();
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (info.Length() < 1 || !info[0].IsNumber()) {
|
|
637
|
+
Napi::TypeError::New(env, "Expected XIT offset in Hz").ThrowAsJavaScriptException();
|
|
638
|
+
return env.Null();
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
shortfreq_t xit_offset = info[0].As<Napi::Number>().Int32Value();
|
|
642
|
+
|
|
643
|
+
int retcode = rig_set_xit(my_rig, RIG_VFO_CURR, xit_offset);
|
|
644
|
+
if (retcode != RIG_OK) {
|
|
645
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
646
|
+
return env.Null();
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
return Napi::Number::New(env, retcode);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
Napi::Value NodeHamLib::GetXit(const Napi::CallbackInfo & info) {
|
|
653
|
+
Napi::Env env = info.Env();
|
|
654
|
+
|
|
655
|
+
if (!rig_is_open) {
|
|
656
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
657
|
+
return env.Null();
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
shortfreq_t xit_offset;
|
|
661
|
+
int retcode = rig_get_xit(my_rig, RIG_VFO_CURR, &xit_offset);
|
|
662
|
+
if (retcode != RIG_OK) {
|
|
663
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
664
|
+
return env.Null();
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return Napi::Number::New(env, xit_offset);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
Napi::Value NodeHamLib::ClearRitXit(const Napi::CallbackInfo & info) {
|
|
671
|
+
Napi::Env env = info.Env();
|
|
672
|
+
|
|
673
|
+
if (!rig_is_open) {
|
|
674
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
675
|
+
return env.Null();
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// Clear both RIT and XIT by setting them to 0
|
|
679
|
+
int ritCode = rig_set_rit(my_rig, RIG_VFO_CURR, 0);
|
|
680
|
+
int xitCode = rig_set_xit(my_rig, RIG_VFO_CURR, 0);
|
|
681
|
+
|
|
682
|
+
if (ritCode != RIG_OK && ritCode != -RIG_ENAVAIL) {
|
|
683
|
+
Napi::Error::New(env, rigerror(ritCode)).ThrowAsJavaScriptException();
|
|
684
|
+
return env.Null();
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if (xitCode != RIG_OK && xitCode != -RIG_ENAVAIL) {
|
|
688
|
+
Napi::Error::New(env, rigerror(xitCode)).ThrowAsJavaScriptException();
|
|
689
|
+
return env.Null();
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
return Napi::Boolean::New(env, true);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// Scanning Operations
|
|
696
|
+
Napi::Value NodeHamLib::StartScan(const Napi::CallbackInfo & info) {
|
|
697
|
+
Napi::Env env = info.Env();
|
|
698
|
+
|
|
699
|
+
if (!rig_is_open) {
|
|
700
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
701
|
+
return env.Null();
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
705
|
+
Napi::TypeError::New(env, "Expected scan type (VFO, MEM, PROG, etc.)").ThrowAsJavaScriptException();
|
|
706
|
+
return env.Null();
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
std::string scanTypeStr = info[0].As<Napi::String>().Utf8Value();
|
|
710
|
+
scan_t scanType;
|
|
711
|
+
|
|
712
|
+
if (scanTypeStr == "VFO") {
|
|
713
|
+
scanType = RIG_SCAN_VFO;
|
|
714
|
+
} else if (scanTypeStr == "MEM") {
|
|
715
|
+
scanType = RIG_SCAN_MEM;
|
|
716
|
+
} else if (scanTypeStr == "PROG") {
|
|
717
|
+
scanType = RIG_SCAN_PROG;
|
|
718
|
+
} else if (scanTypeStr == "DELTA") {
|
|
719
|
+
scanType = RIG_SCAN_DELTA;
|
|
720
|
+
} else if (scanTypeStr == "PRIO") {
|
|
721
|
+
scanType = RIG_SCAN_PRIO;
|
|
722
|
+
} else {
|
|
723
|
+
Napi::TypeError::New(env, "Invalid scan type").ThrowAsJavaScriptException();
|
|
724
|
+
return env.Null();
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
int channel = 0;
|
|
728
|
+
if (info.Length() >= 2 && info[1].IsNumber()) {
|
|
729
|
+
channel = info[1].As<Napi::Number>().Int32Value();
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
int retcode = rig_scan(my_rig, RIG_VFO_CURR, scanType, channel);
|
|
733
|
+
if (retcode != RIG_OK) {
|
|
734
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
735
|
+
return env.Null();
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
return Napi::Number::New(env, retcode);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
Napi::Value NodeHamLib::StopScan(const Napi::CallbackInfo & info) {
|
|
742
|
+
Napi::Env env = info.Env();
|
|
743
|
+
|
|
744
|
+
if (!rig_is_open) {
|
|
745
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
746
|
+
return env.Null();
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
int retcode = rig_scan(my_rig, RIG_VFO_CURR, RIG_SCAN_STOP, 0);
|
|
750
|
+
if (retcode != RIG_OK) {
|
|
751
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
752
|
+
return env.Null();
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
return Napi::Number::New(env, retcode);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// Level Controls
|
|
759
|
+
Napi::Value NodeHamLib::SetLevel(const Napi::CallbackInfo & info) {
|
|
760
|
+
Napi::Env env = info.Env();
|
|
761
|
+
|
|
762
|
+
if (!rig_is_open) {
|
|
763
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
764
|
+
return env.Null();
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
if (info.Length() < 2 || !info[0].IsString() || !info[1].IsNumber()) {
|
|
768
|
+
Napi::TypeError::New(env, "Expected (levelType: string, value: number)").ThrowAsJavaScriptException();
|
|
769
|
+
return env.Null();
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
std::string levelTypeStr = info[0].As<Napi::String>().Utf8Value();
|
|
773
|
+
double levelValue = info[1].As<Napi::Number>().DoubleValue();
|
|
774
|
+
|
|
775
|
+
// Map level type strings to hamlib constants
|
|
776
|
+
setting_t levelType;
|
|
777
|
+
if (levelTypeStr == "AF") {
|
|
778
|
+
levelType = RIG_LEVEL_AF;
|
|
779
|
+
} else if (levelTypeStr == "RF") {
|
|
780
|
+
levelType = RIG_LEVEL_RF;
|
|
781
|
+
} else if (levelTypeStr == "SQL") {
|
|
782
|
+
levelType = RIG_LEVEL_SQL;
|
|
783
|
+
} else if (levelTypeStr == "RFPOWER") {
|
|
784
|
+
levelType = RIG_LEVEL_RFPOWER;
|
|
785
|
+
} else if (levelTypeStr == "MICGAIN") {
|
|
786
|
+
levelType = RIG_LEVEL_MICGAIN;
|
|
787
|
+
} else if (levelTypeStr == "IF") {
|
|
788
|
+
levelType = RIG_LEVEL_IF;
|
|
789
|
+
} else if (levelTypeStr == "APF") {
|
|
790
|
+
levelType = RIG_LEVEL_APF;
|
|
791
|
+
} else if (levelTypeStr == "NR") {
|
|
792
|
+
levelType = RIG_LEVEL_NR;
|
|
793
|
+
} else if (levelTypeStr == "PBT_IN") {
|
|
794
|
+
levelType = RIG_LEVEL_PBT_IN;
|
|
795
|
+
} else if (levelTypeStr == "PBT_OUT") {
|
|
796
|
+
levelType = RIG_LEVEL_PBT_OUT;
|
|
797
|
+
} else if (levelTypeStr == "CWPITCH") {
|
|
798
|
+
levelType = RIG_LEVEL_CWPITCH;
|
|
799
|
+
} else if (levelTypeStr == "KEYSPD") {
|
|
800
|
+
levelType = RIG_LEVEL_KEYSPD;
|
|
801
|
+
} else if (levelTypeStr == "NOTCHF") {
|
|
802
|
+
levelType = RIG_LEVEL_NOTCHF;
|
|
803
|
+
} else if (levelTypeStr == "COMP") {
|
|
804
|
+
levelType = RIG_LEVEL_COMP;
|
|
805
|
+
} else if (levelTypeStr == "AGC") {
|
|
806
|
+
levelType = RIG_LEVEL_AGC;
|
|
807
|
+
} else if (levelTypeStr == "BKINDL") {
|
|
808
|
+
levelType = RIG_LEVEL_BKINDL;
|
|
809
|
+
} else if (levelTypeStr == "BALANCE") {
|
|
810
|
+
levelType = RIG_LEVEL_BALANCE;
|
|
811
|
+
} else if (levelTypeStr == "VOXGAIN") {
|
|
812
|
+
levelType = RIG_LEVEL_VOXGAIN;
|
|
813
|
+
} else if (levelTypeStr == "VOXDELAY") {
|
|
814
|
+
levelType = RIG_LEVEL_VOXDELAY;
|
|
815
|
+
} else if (levelTypeStr == "ANTIVOX") {
|
|
816
|
+
levelType = RIG_LEVEL_ANTIVOX;
|
|
817
|
+
} else {
|
|
818
|
+
Napi::TypeError::New(env, "Invalid level type").ThrowAsJavaScriptException();
|
|
819
|
+
return env.Null();
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
// Create value union
|
|
823
|
+
value_t val;
|
|
824
|
+
val.f = levelValue;
|
|
825
|
+
|
|
826
|
+
int retcode = rig_set_level(my_rig, RIG_VFO_CURR, levelType, val);
|
|
827
|
+
if (retcode != RIG_OK) {
|
|
828
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
829
|
+
return env.Null();
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
return Napi::Number::New(env, retcode);
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
Napi::Value NodeHamLib::GetLevel(const Napi::CallbackInfo & info) {
|
|
836
|
+
Napi::Env env = info.Env();
|
|
837
|
+
|
|
838
|
+
if (!rig_is_open) {
|
|
839
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
840
|
+
return env.Null();
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
844
|
+
Napi::TypeError::New(env, "Expected level type string").ThrowAsJavaScriptException();
|
|
845
|
+
return env.Null();
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
std::string levelTypeStr = info[0].As<Napi::String>().Utf8Value();
|
|
849
|
+
|
|
850
|
+
// Map level type strings to hamlib constants
|
|
851
|
+
setting_t levelType;
|
|
852
|
+
if (levelTypeStr == "AF") {
|
|
853
|
+
levelType = RIG_LEVEL_AF;
|
|
854
|
+
} else if (levelTypeStr == "RF") {
|
|
855
|
+
levelType = RIG_LEVEL_RF;
|
|
856
|
+
} else if (levelTypeStr == "SQL") {
|
|
857
|
+
levelType = RIG_LEVEL_SQL;
|
|
858
|
+
} else if (levelTypeStr == "RFPOWER") {
|
|
859
|
+
levelType = RIG_LEVEL_RFPOWER;
|
|
860
|
+
} else if (levelTypeStr == "MICGAIN") {
|
|
861
|
+
levelType = RIG_LEVEL_MICGAIN;
|
|
862
|
+
} else if (levelTypeStr == "SWR") {
|
|
863
|
+
levelType = RIG_LEVEL_SWR;
|
|
864
|
+
} else if (levelTypeStr == "ALC") {
|
|
865
|
+
levelType = RIG_LEVEL_ALC;
|
|
866
|
+
} else if (levelTypeStr == "STRENGTH") {
|
|
867
|
+
levelType = RIG_LEVEL_STRENGTH;
|
|
868
|
+
} else if (levelTypeStr == "RAWSTR") {
|
|
869
|
+
levelType = RIG_LEVEL_RAWSTR;
|
|
870
|
+
} else if (levelTypeStr == "RFPOWER_METER") {
|
|
871
|
+
levelType = RIG_LEVEL_RFPOWER_METER;
|
|
872
|
+
} else if (levelTypeStr == "COMP_METER") {
|
|
873
|
+
levelType = RIG_LEVEL_COMP_METER;
|
|
874
|
+
} else if (levelTypeStr == "VD_METER") {
|
|
875
|
+
levelType = RIG_LEVEL_VD_METER;
|
|
876
|
+
} else if (levelTypeStr == "ID_METER") {
|
|
877
|
+
levelType = RIG_LEVEL_ID_METER;
|
|
878
|
+
} else if (levelTypeStr == "TEMP_METER") {
|
|
879
|
+
levelType = RIG_LEVEL_TEMP_METER;
|
|
880
|
+
} else {
|
|
881
|
+
Napi::TypeError::New(env, "Invalid level type").ThrowAsJavaScriptException();
|
|
882
|
+
return env.Null();
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
value_t val;
|
|
886
|
+
int retcode = rig_get_level(my_rig, RIG_VFO_CURR, levelType, &val);
|
|
887
|
+
if (retcode != RIG_OK) {
|
|
888
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
889
|
+
return env.Null();
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
// Return the appropriate value based on the level type
|
|
893
|
+
if (levelType == RIG_LEVEL_STRENGTH || levelType == RIG_LEVEL_RAWSTR) {
|
|
894
|
+
return Napi::Number::New(env, val.i);
|
|
895
|
+
} else {
|
|
896
|
+
return Napi::Number::New(env, val.f);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
Napi::Value NodeHamLib::GetSupportedLevels(const Napi::CallbackInfo & info) {
|
|
901
|
+
Napi::Env env = info.Env();
|
|
902
|
+
|
|
903
|
+
if (!rig_is_open) {
|
|
904
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
905
|
+
return env.Null();
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
setting_t levels = my_rig->state.has_get_level | my_rig->state.has_set_level;
|
|
909
|
+
Napi::Array levelArray = Napi::Array::New(env);
|
|
910
|
+
uint32_t index = 0;
|
|
911
|
+
|
|
912
|
+
// Check each level type
|
|
913
|
+
if (levels & RIG_LEVEL_AF) levelArray[index++] = Napi::String::New(env, "AF");
|
|
914
|
+
if (levels & RIG_LEVEL_RF) levelArray[index++] = Napi::String::New(env, "RF");
|
|
915
|
+
if (levels & RIG_LEVEL_SQL) levelArray[index++] = Napi::String::New(env, "SQL");
|
|
916
|
+
if (levels & RIG_LEVEL_RFPOWER) levelArray[index++] = Napi::String::New(env, "RFPOWER");
|
|
917
|
+
if (levels & RIG_LEVEL_MICGAIN) levelArray[index++] = Napi::String::New(env, "MICGAIN");
|
|
918
|
+
if (levels & RIG_LEVEL_IF) levelArray[index++] = Napi::String::New(env, "IF");
|
|
919
|
+
if (levels & RIG_LEVEL_APF) levelArray[index++] = Napi::String::New(env, "APF");
|
|
920
|
+
if (levels & RIG_LEVEL_NR) levelArray[index++] = Napi::String::New(env, "NR");
|
|
921
|
+
if (levels & RIG_LEVEL_PBT_IN) levelArray[index++] = Napi::String::New(env, "PBT_IN");
|
|
922
|
+
if (levels & RIG_LEVEL_PBT_OUT) levelArray[index++] = Napi::String::New(env, "PBT_OUT");
|
|
923
|
+
if (levels & RIG_LEVEL_CWPITCH) levelArray[index++] = Napi::String::New(env, "CWPITCH");
|
|
924
|
+
if (levels & RIG_LEVEL_KEYSPD) levelArray[index++] = Napi::String::New(env, "KEYSPD");
|
|
925
|
+
if (levels & RIG_LEVEL_NOTCHF) levelArray[index++] = Napi::String::New(env, "NOTCHF");
|
|
926
|
+
if (levels & RIG_LEVEL_COMP) levelArray[index++] = Napi::String::New(env, "COMP");
|
|
927
|
+
if (levels & RIG_LEVEL_AGC) levelArray[index++] = Napi::String::New(env, "AGC");
|
|
928
|
+
if (levels & RIG_LEVEL_BKINDL) levelArray[index++] = Napi::String::New(env, "BKINDL");
|
|
929
|
+
if (levels & RIG_LEVEL_BALANCE) levelArray[index++] = Napi::String::New(env, "BALANCE");
|
|
930
|
+
if (levels & RIG_LEVEL_VOXGAIN) levelArray[index++] = Napi::String::New(env, "VOXGAIN");
|
|
931
|
+
if (levels & RIG_LEVEL_VOXDELAY) levelArray[index++] = Napi::String::New(env, "VOXDELAY");
|
|
932
|
+
if (levels & RIG_LEVEL_ANTIVOX) levelArray[index++] = Napi::String::New(env, "ANTIVOX");
|
|
933
|
+
if (levels & RIG_LEVEL_STRENGTH) levelArray[index++] = Napi::String::New(env, "STRENGTH");
|
|
934
|
+
if (levels & RIG_LEVEL_RAWSTR) levelArray[index++] = Napi::String::New(env, "RAWSTR");
|
|
935
|
+
if (levels & RIG_LEVEL_SWR) levelArray[index++] = Napi::String::New(env, "SWR");
|
|
936
|
+
if (levels & RIG_LEVEL_ALC) levelArray[index++] = Napi::String::New(env, "ALC");
|
|
937
|
+
if (levels & RIG_LEVEL_RFPOWER_METER) levelArray[index++] = Napi::String::New(env, "RFPOWER_METER");
|
|
938
|
+
if (levels & RIG_LEVEL_COMP_METER) levelArray[index++] = Napi::String::New(env, "COMP_METER");
|
|
939
|
+
if (levels & RIG_LEVEL_VD_METER) levelArray[index++] = Napi::String::New(env, "VD_METER");
|
|
940
|
+
if (levels & RIG_LEVEL_ID_METER) levelArray[index++] = Napi::String::New(env, "ID_METER");
|
|
941
|
+
if (levels & RIG_LEVEL_TEMP_METER) levelArray[index++] = Napi::String::New(env, "TEMP_METER");
|
|
942
|
+
|
|
943
|
+
return levelArray;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// Function Controls
|
|
947
|
+
Napi::Value NodeHamLib::SetFunction(const Napi::CallbackInfo & info) {
|
|
948
|
+
Napi::Env env = info.Env();
|
|
949
|
+
|
|
950
|
+
if (!rig_is_open) {
|
|
951
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
952
|
+
return env.Null();
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
if (info.Length() < 2 || !info[0].IsString() || !info[1].IsBoolean()) {
|
|
956
|
+
Napi::TypeError::New(env, "Expected (functionType: string, enable: boolean)").ThrowAsJavaScriptException();
|
|
957
|
+
return env.Null();
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
std::string funcTypeStr = info[0].As<Napi::String>().Utf8Value();
|
|
961
|
+
bool enable = info[1].As<Napi::Boolean>().Value();
|
|
962
|
+
|
|
963
|
+
// Map function type strings to hamlib constants
|
|
964
|
+
setting_t funcType;
|
|
965
|
+
if (funcTypeStr == "FAGC") {
|
|
966
|
+
funcType = RIG_FUNC_FAGC;
|
|
967
|
+
} else if (funcTypeStr == "NB") {
|
|
968
|
+
funcType = RIG_FUNC_NB;
|
|
969
|
+
} else if (funcTypeStr == "COMP") {
|
|
970
|
+
funcType = RIG_FUNC_COMP;
|
|
971
|
+
} else if (funcTypeStr == "VOX") {
|
|
972
|
+
funcType = RIG_FUNC_VOX;
|
|
973
|
+
} else if (funcTypeStr == "TONE") {
|
|
974
|
+
funcType = RIG_FUNC_TONE;
|
|
975
|
+
} else if (funcTypeStr == "TSQL") {
|
|
976
|
+
funcType = RIG_FUNC_TSQL;
|
|
977
|
+
} else if (funcTypeStr == "SBKIN") {
|
|
978
|
+
funcType = RIG_FUNC_SBKIN;
|
|
979
|
+
} else if (funcTypeStr == "FBKIN") {
|
|
980
|
+
funcType = RIG_FUNC_FBKIN;
|
|
981
|
+
} else if (funcTypeStr == "ANF") {
|
|
982
|
+
funcType = RIG_FUNC_ANF;
|
|
983
|
+
} else if (funcTypeStr == "NR") {
|
|
984
|
+
funcType = RIG_FUNC_NR;
|
|
985
|
+
} else if (funcTypeStr == "AIP") {
|
|
986
|
+
funcType = RIG_FUNC_AIP;
|
|
987
|
+
} else if (funcTypeStr == "APF") {
|
|
988
|
+
funcType = RIG_FUNC_APF;
|
|
989
|
+
} else if (funcTypeStr == "TUNER") {
|
|
990
|
+
funcType = RIG_FUNC_TUNER;
|
|
991
|
+
} else if (funcTypeStr == "XIT") {
|
|
992
|
+
funcType = RIG_FUNC_XIT;
|
|
993
|
+
} else if (funcTypeStr == "RIT") {
|
|
994
|
+
funcType = RIG_FUNC_RIT;
|
|
995
|
+
} else if (funcTypeStr == "LOCK") {
|
|
996
|
+
funcType = RIG_FUNC_LOCK;
|
|
997
|
+
} else if (funcTypeStr == "MUTE") {
|
|
998
|
+
funcType = RIG_FUNC_MUTE;
|
|
999
|
+
} else if (funcTypeStr == "VSC") {
|
|
1000
|
+
funcType = RIG_FUNC_VSC;
|
|
1001
|
+
} else if (funcTypeStr == "REV") {
|
|
1002
|
+
funcType = RIG_FUNC_REV;
|
|
1003
|
+
} else if (funcTypeStr == "SQL") {
|
|
1004
|
+
funcType = RIG_FUNC_SQL;
|
|
1005
|
+
} else if (funcTypeStr == "ABM") {
|
|
1006
|
+
funcType = RIG_FUNC_ABM;
|
|
1007
|
+
} else if (funcTypeStr == "BC") {
|
|
1008
|
+
funcType = RIG_FUNC_BC;
|
|
1009
|
+
} else if (funcTypeStr == "MBC") {
|
|
1010
|
+
funcType = RIG_FUNC_MBC;
|
|
1011
|
+
} else if (funcTypeStr == "AFC") {
|
|
1012
|
+
funcType = RIG_FUNC_AFC;
|
|
1013
|
+
} else if (funcTypeStr == "SATMODE") {
|
|
1014
|
+
funcType = RIG_FUNC_SATMODE;
|
|
1015
|
+
} else if (funcTypeStr == "SCOPE") {
|
|
1016
|
+
funcType = RIG_FUNC_SCOPE;
|
|
1017
|
+
} else if (funcTypeStr == "RESUME") {
|
|
1018
|
+
funcType = RIG_FUNC_RESUME;
|
|
1019
|
+
} else if (funcTypeStr == "TBURST") {
|
|
1020
|
+
funcType = RIG_FUNC_TBURST;
|
|
1021
|
+
} else {
|
|
1022
|
+
Napi::TypeError::New(env, "Invalid function type").ThrowAsJavaScriptException();
|
|
1023
|
+
return env.Null();
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
int retcode = rig_set_func(my_rig, RIG_VFO_CURR, funcType, enable ? 1 : 0);
|
|
1027
|
+
if (retcode != RIG_OK) {
|
|
1028
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1029
|
+
return env.Null();
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
return Napi::Number::New(env, retcode);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
Napi::Value NodeHamLib::GetFunction(const Napi::CallbackInfo & info) {
|
|
1036
|
+
Napi::Env env = info.Env();
|
|
1037
|
+
|
|
1038
|
+
if (!rig_is_open) {
|
|
1039
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1040
|
+
return env.Null();
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
1044
|
+
Napi::TypeError::New(env, "Expected function type string").ThrowAsJavaScriptException();
|
|
1045
|
+
return env.Null();
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
std::string funcTypeStr = info[0].As<Napi::String>().Utf8Value();
|
|
1049
|
+
|
|
1050
|
+
// Map function type strings to hamlib constants (same as SetFunction)
|
|
1051
|
+
setting_t funcType;
|
|
1052
|
+
if (funcTypeStr == "FAGC") {
|
|
1053
|
+
funcType = RIG_FUNC_FAGC;
|
|
1054
|
+
} else if (funcTypeStr == "NB") {
|
|
1055
|
+
funcType = RIG_FUNC_NB;
|
|
1056
|
+
} else if (funcTypeStr == "COMP") {
|
|
1057
|
+
funcType = RIG_FUNC_COMP;
|
|
1058
|
+
} else if (funcTypeStr == "VOX") {
|
|
1059
|
+
funcType = RIG_FUNC_VOX;
|
|
1060
|
+
} else if (funcTypeStr == "TONE") {
|
|
1061
|
+
funcType = RIG_FUNC_TONE;
|
|
1062
|
+
} else if (funcTypeStr == "TSQL") {
|
|
1063
|
+
funcType = RIG_FUNC_TSQL;
|
|
1064
|
+
} else if (funcTypeStr == "SBKIN") {
|
|
1065
|
+
funcType = RIG_FUNC_SBKIN;
|
|
1066
|
+
} else if (funcTypeStr == "FBKIN") {
|
|
1067
|
+
funcType = RIG_FUNC_FBKIN;
|
|
1068
|
+
} else if (funcTypeStr == "ANF") {
|
|
1069
|
+
funcType = RIG_FUNC_ANF;
|
|
1070
|
+
} else if (funcTypeStr == "NR") {
|
|
1071
|
+
funcType = RIG_FUNC_NR;
|
|
1072
|
+
} else if (funcTypeStr == "AIP") {
|
|
1073
|
+
funcType = RIG_FUNC_AIP;
|
|
1074
|
+
} else if (funcTypeStr == "APF") {
|
|
1075
|
+
funcType = RIG_FUNC_APF;
|
|
1076
|
+
} else if (funcTypeStr == "TUNER") {
|
|
1077
|
+
funcType = RIG_FUNC_TUNER;
|
|
1078
|
+
} else if (funcTypeStr == "XIT") {
|
|
1079
|
+
funcType = RIG_FUNC_XIT;
|
|
1080
|
+
} else if (funcTypeStr == "RIT") {
|
|
1081
|
+
funcType = RIG_FUNC_RIT;
|
|
1082
|
+
} else if (funcTypeStr == "LOCK") {
|
|
1083
|
+
funcType = RIG_FUNC_LOCK;
|
|
1084
|
+
} else if (funcTypeStr == "MUTE") {
|
|
1085
|
+
funcType = RIG_FUNC_MUTE;
|
|
1086
|
+
} else if (funcTypeStr == "VSC") {
|
|
1087
|
+
funcType = RIG_FUNC_VSC;
|
|
1088
|
+
} else if (funcTypeStr == "REV") {
|
|
1089
|
+
funcType = RIG_FUNC_REV;
|
|
1090
|
+
} else if (funcTypeStr == "SQL") {
|
|
1091
|
+
funcType = RIG_FUNC_SQL;
|
|
1092
|
+
} else if (funcTypeStr == "ABM") {
|
|
1093
|
+
funcType = RIG_FUNC_ABM;
|
|
1094
|
+
} else if (funcTypeStr == "BC") {
|
|
1095
|
+
funcType = RIG_FUNC_BC;
|
|
1096
|
+
} else if (funcTypeStr == "MBC") {
|
|
1097
|
+
funcType = RIG_FUNC_MBC;
|
|
1098
|
+
} else if (funcTypeStr == "AFC") {
|
|
1099
|
+
funcType = RIG_FUNC_AFC;
|
|
1100
|
+
} else if (funcTypeStr == "SATMODE") {
|
|
1101
|
+
funcType = RIG_FUNC_SATMODE;
|
|
1102
|
+
} else if (funcTypeStr == "SCOPE") {
|
|
1103
|
+
funcType = RIG_FUNC_SCOPE;
|
|
1104
|
+
} else if (funcTypeStr == "RESUME") {
|
|
1105
|
+
funcType = RIG_FUNC_RESUME;
|
|
1106
|
+
} else if (funcTypeStr == "TBURST") {
|
|
1107
|
+
funcType = RIG_FUNC_TBURST;
|
|
1108
|
+
} else {
|
|
1109
|
+
Napi::TypeError::New(env, "Invalid function type").ThrowAsJavaScriptException();
|
|
1110
|
+
return env.Null();
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
int state;
|
|
1114
|
+
int retcode = rig_get_func(my_rig, RIG_VFO_CURR, funcType, &state);
|
|
1115
|
+
if (retcode != RIG_OK) {
|
|
1116
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1117
|
+
return env.Null();
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
return Napi::Boolean::New(env, state != 0);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
Napi::Value NodeHamLib::GetSupportedFunctions(const Napi::CallbackInfo & info) {
|
|
1124
|
+
Napi::Env env = info.Env();
|
|
1125
|
+
|
|
1126
|
+
if (!rig_is_open) {
|
|
1127
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1128
|
+
return env.Null();
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
setting_t functions = my_rig->state.has_get_func | my_rig->state.has_set_func;
|
|
1132
|
+
Napi::Array funcArray = Napi::Array::New(env);
|
|
1133
|
+
uint32_t index = 0;
|
|
1134
|
+
|
|
1135
|
+
// Check each function type
|
|
1136
|
+
if (functions & RIG_FUNC_FAGC) funcArray[index++] = Napi::String::New(env, "FAGC");
|
|
1137
|
+
if (functions & RIG_FUNC_NB) funcArray[index++] = Napi::String::New(env, "NB");
|
|
1138
|
+
if (functions & RIG_FUNC_COMP) funcArray[index++] = Napi::String::New(env, "COMP");
|
|
1139
|
+
if (functions & RIG_FUNC_VOX) funcArray[index++] = Napi::String::New(env, "VOX");
|
|
1140
|
+
if (functions & RIG_FUNC_TONE) funcArray[index++] = Napi::String::New(env, "TONE");
|
|
1141
|
+
if (functions & RIG_FUNC_TSQL) funcArray[index++] = Napi::String::New(env, "TSQL");
|
|
1142
|
+
if (functions & RIG_FUNC_SBKIN) funcArray[index++] = Napi::String::New(env, "SBKIN");
|
|
1143
|
+
if (functions & RIG_FUNC_FBKIN) funcArray[index++] = Napi::String::New(env, "FBKIN");
|
|
1144
|
+
if (functions & RIG_FUNC_ANF) funcArray[index++] = Napi::String::New(env, "ANF");
|
|
1145
|
+
if (functions & RIG_FUNC_NR) funcArray[index++] = Napi::String::New(env, "NR");
|
|
1146
|
+
if (functions & RIG_FUNC_AIP) funcArray[index++] = Napi::String::New(env, "AIP");
|
|
1147
|
+
if (functions & RIG_FUNC_APF) funcArray[index++] = Napi::String::New(env, "APF");
|
|
1148
|
+
if (functions & RIG_FUNC_TUNER) funcArray[index++] = Napi::String::New(env, "TUNER");
|
|
1149
|
+
if (functions & RIG_FUNC_XIT) funcArray[index++] = Napi::String::New(env, "XIT");
|
|
1150
|
+
if (functions & RIG_FUNC_RIT) funcArray[index++] = Napi::String::New(env, "RIT");
|
|
1151
|
+
if (functions & RIG_FUNC_LOCK) funcArray[index++] = Napi::String::New(env, "LOCK");
|
|
1152
|
+
if (functions & RIG_FUNC_MUTE) funcArray[index++] = Napi::String::New(env, "MUTE");
|
|
1153
|
+
if (functions & RIG_FUNC_VSC) funcArray[index++] = Napi::String::New(env, "VSC");
|
|
1154
|
+
if (functions & RIG_FUNC_REV) funcArray[index++] = Napi::String::New(env, "REV");
|
|
1155
|
+
if (functions & RIG_FUNC_SQL) funcArray[index++] = Napi::String::New(env, "SQL");
|
|
1156
|
+
if (functions & RIG_FUNC_ABM) funcArray[index++] = Napi::String::New(env, "ABM");
|
|
1157
|
+
if (functions & RIG_FUNC_BC) funcArray[index++] = Napi::String::New(env, "BC");
|
|
1158
|
+
if (functions & RIG_FUNC_MBC) funcArray[index++] = Napi::String::New(env, "MBC");
|
|
1159
|
+
if (functions & RIG_FUNC_AFC) funcArray[index++] = Napi::String::New(env, "AFC");
|
|
1160
|
+
if (functions & RIG_FUNC_SATMODE) funcArray[index++] = Napi::String::New(env, "SATMODE");
|
|
1161
|
+
if (functions & RIG_FUNC_SCOPE) funcArray[index++] = Napi::String::New(env, "SCOPE");
|
|
1162
|
+
if (functions & RIG_FUNC_RESUME) funcArray[index++] = Napi::String::New(env, "RESUME");
|
|
1163
|
+
if (functions & RIG_FUNC_TBURST) funcArray[index++] = Napi::String::New(env, "TBURST");
|
|
1164
|
+
|
|
1165
|
+
return funcArray;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
// Split Operations
|
|
1169
|
+
Napi::Value NodeHamLib::SetSplitFreq(const Napi::CallbackInfo & info) {
|
|
1170
|
+
Napi::Env env = info.Env();
|
|
1171
|
+
|
|
1172
|
+
if (!rig_is_open) {
|
|
1173
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1174
|
+
return env.Null();
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
if (info.Length() < 1 || !info[0].IsNumber()) {
|
|
1178
|
+
Napi::TypeError::New(env, "Expected TX frequency").ThrowAsJavaScriptException();
|
|
1179
|
+
return env.Null();
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
freq_t tx_freq = info[0].As<Napi::Number>().DoubleValue();
|
|
1183
|
+
|
|
1184
|
+
int retcode = rig_set_split_freq(my_rig, RIG_VFO_CURR, tx_freq);
|
|
1185
|
+
if (retcode != RIG_OK) {
|
|
1186
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1187
|
+
return env.Null();
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
return Napi::Number::New(env, retcode);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
Napi::Value NodeHamLib::GetSplitFreq(const Napi::CallbackInfo & info) {
|
|
1194
|
+
Napi::Env env = info.Env();
|
|
1195
|
+
|
|
1196
|
+
if (!rig_is_open) {
|
|
1197
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1198
|
+
return env.Null();
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
freq_t tx_freq;
|
|
1202
|
+
int retcode = rig_get_split_freq(my_rig, RIG_VFO_CURR, &tx_freq);
|
|
1203
|
+
if (retcode != RIG_OK) {
|
|
1204
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1205
|
+
return env.Null();
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
return Napi::Number::New(env, tx_freq);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
Napi::Value NodeHamLib::SetSplitMode(const Napi::CallbackInfo & info) {
|
|
1212
|
+
Napi::Env env = info.Env();
|
|
1213
|
+
|
|
1214
|
+
if (!rig_is_open) {
|
|
1215
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1216
|
+
return env.Null();
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
1220
|
+
Napi::TypeError::New(env, "Expected TX mode string").ThrowAsJavaScriptException();
|
|
1221
|
+
return env.Null();
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
std::string modeStr = info[0].As<Napi::String>().Utf8Value();
|
|
1225
|
+
rmode_t tx_mode = rig_parse_mode(modeStr.c_str());
|
|
1226
|
+
|
|
1227
|
+
pbwidth_t tx_width = RIG_PASSBAND_NORMAL;
|
|
1228
|
+
if (info.Length() >= 2 && info[1].IsNumber()) {
|
|
1229
|
+
tx_width = info[1].As<Napi::Number>().Int32Value();
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
int retcode = rig_set_split_mode(my_rig, RIG_VFO_CURR, tx_mode, tx_width);
|
|
1233
|
+
if (retcode != RIG_OK) {
|
|
1234
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1235
|
+
return env.Null();
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
return Napi::Number::New(env, retcode);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
Napi::Value NodeHamLib::GetSplitMode(const Napi::CallbackInfo & info) {
|
|
1242
|
+
Napi::Env env = info.Env();
|
|
1243
|
+
|
|
1244
|
+
if (!rig_is_open) {
|
|
1245
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1246
|
+
return env.Null();
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
rmode_t tx_mode;
|
|
1250
|
+
pbwidth_t tx_width;
|
|
1251
|
+
int retcode = rig_get_split_mode(my_rig, RIG_VFO_CURR, &tx_mode, &tx_width);
|
|
1252
|
+
if (retcode != RIG_OK) {
|
|
1253
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1254
|
+
return env.Null();
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
Napi::Object result = Napi::Object::New(env);
|
|
1258
|
+
result.Set("mode", Napi::String::New(env, rig_strrmode(tx_mode)));
|
|
1259
|
+
result.Set("width", Napi::Number::New(env, tx_width));
|
|
1260
|
+
return result;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
Napi::Value NodeHamLib::SetSplit(const Napi::CallbackInfo & info) {
|
|
1264
|
+
Napi::Env env = info.Env();
|
|
1265
|
+
|
|
1266
|
+
if (!rig_is_open) {
|
|
1267
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1268
|
+
return env.Null();
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
if (info.Length() < 1 || !info[0].IsBoolean()) {
|
|
1272
|
+
Napi::TypeError::New(env, "Expected boolean split enable state").ThrowAsJavaScriptException();
|
|
1273
|
+
return env.Null();
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
bool split_enabled = info[0].As<Napi::Boolean>().Value();
|
|
1277
|
+
|
|
1278
|
+
vfo_t tx_vfo = RIG_VFO_B;
|
|
1279
|
+
if (info.Length() >= 2 && info[1].IsString()) {
|
|
1280
|
+
std::string vfoStr = info[1].As<Napi::String>().Utf8Value();
|
|
1281
|
+
if (vfoStr == "VFO-A") {
|
|
1282
|
+
tx_vfo = RIG_VFO_A;
|
|
1283
|
+
} else if (vfoStr == "VFO-B") {
|
|
1284
|
+
tx_vfo = RIG_VFO_B;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
split_t split = split_enabled ? RIG_SPLIT_ON : RIG_SPLIT_OFF;
|
|
1289
|
+
int retcode = rig_set_split_vfo(my_rig, RIG_VFO_CURR, split, tx_vfo);
|
|
1290
|
+
if (retcode != RIG_OK) {
|
|
1291
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1292
|
+
return env.Null();
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
return Napi::Number::New(env, retcode);
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
Napi::Value NodeHamLib::GetSplit(const Napi::CallbackInfo & info) {
|
|
1299
|
+
Napi::Env env = info.Env();
|
|
1300
|
+
|
|
1301
|
+
if (!rig_is_open) {
|
|
1302
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1303
|
+
return env.Null();
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
split_t split;
|
|
1307
|
+
vfo_t tx_vfo;
|
|
1308
|
+
int retcode = rig_get_split_vfo(my_rig, RIG_VFO_CURR, &split, &tx_vfo);
|
|
1309
|
+
if (retcode != RIG_OK) {
|
|
1310
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1311
|
+
return env.Null();
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
Napi::Object result = Napi::Object::New(env);
|
|
1315
|
+
result.Set("enabled", Napi::Boolean::New(env, split == RIG_SPLIT_ON));
|
|
1316
|
+
|
|
1317
|
+
std::string vfoStr = "VFO-CURR";
|
|
1318
|
+
if (tx_vfo == RIG_VFO_A) {
|
|
1319
|
+
vfoStr = "VFO-A";
|
|
1320
|
+
} else if (tx_vfo == RIG_VFO_B) {
|
|
1321
|
+
vfoStr = "VFO-B";
|
|
1322
|
+
}
|
|
1323
|
+
result.Set("txVfo", Napi::String::New(env, vfoStr));
|
|
1324
|
+
|
|
1325
|
+
return result;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
// VFO Operations
|
|
1329
|
+
Napi::Value NodeHamLib::VfoOperation(const Napi::CallbackInfo & info) {
|
|
1330
|
+
Napi::Env env = info.Env();
|
|
1331
|
+
|
|
1332
|
+
if (!rig_is_open) {
|
|
1333
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1334
|
+
return env.Null();
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
1338
|
+
Napi::TypeError::New(env, "Expected VFO operation string").ThrowAsJavaScriptException();
|
|
1339
|
+
return env.Null();
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
std::string vfoOpStr = info[0].As<Napi::String>().Utf8Value();
|
|
1343
|
+
|
|
1344
|
+
vfo_op_t vfo_op;
|
|
1345
|
+
if (vfoOpStr == "CPY") {
|
|
1346
|
+
vfo_op = RIG_OP_CPY;
|
|
1347
|
+
} else if (vfoOpStr == "XCHG") {
|
|
1348
|
+
vfo_op = RIG_OP_XCHG;
|
|
1349
|
+
} else if (vfoOpStr == "FROM_VFO") {
|
|
1350
|
+
vfo_op = RIG_OP_FROM_VFO;
|
|
1351
|
+
} else if (vfoOpStr == "TO_VFO") {
|
|
1352
|
+
vfo_op = RIG_OP_TO_VFO;
|
|
1353
|
+
} else if (vfoOpStr == "MCL") {
|
|
1354
|
+
vfo_op = RIG_OP_MCL;
|
|
1355
|
+
} else if (vfoOpStr == "UP") {
|
|
1356
|
+
vfo_op = RIG_OP_UP;
|
|
1357
|
+
} else if (vfoOpStr == "DOWN") {
|
|
1358
|
+
vfo_op = RIG_OP_DOWN;
|
|
1359
|
+
} else if (vfoOpStr == "BAND_UP") {
|
|
1360
|
+
vfo_op = RIG_OP_BAND_UP;
|
|
1361
|
+
} else if (vfoOpStr == "BAND_DOWN") {
|
|
1362
|
+
vfo_op = RIG_OP_BAND_DOWN;
|
|
1363
|
+
} else if (vfoOpStr == "LEFT") {
|
|
1364
|
+
vfo_op = RIG_OP_LEFT;
|
|
1365
|
+
} else if (vfoOpStr == "RIGHT") {
|
|
1366
|
+
vfo_op = RIG_OP_RIGHT;
|
|
1367
|
+
} else if (vfoOpStr == "TUNE") {
|
|
1368
|
+
vfo_op = RIG_OP_TUNE;
|
|
1369
|
+
} else if (vfoOpStr == "TOGGLE") {
|
|
1370
|
+
vfo_op = RIG_OP_TOGGLE;
|
|
1371
|
+
} else {
|
|
1372
|
+
Napi::TypeError::New(env, "Invalid VFO operation").ThrowAsJavaScriptException();
|
|
1373
|
+
return env.Null();
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
int retcode = rig_vfo_op(my_rig, RIG_VFO_CURR, vfo_op);
|
|
1377
|
+
if (retcode != RIG_OK) {
|
|
1378
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1379
|
+
return env.Null();
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
return Napi::Number::New(env, retcode);
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
// Antenna Selection
|
|
1386
|
+
Napi::Value NodeHamLib::SetAntenna(const Napi::CallbackInfo & info) {
|
|
1387
|
+
Napi::Env env = info.Env();
|
|
1388
|
+
|
|
1389
|
+
if (!rig_is_open) {
|
|
1390
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1391
|
+
return env.Null();
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
if (info.Length() < 1 || !info[0].IsNumber()) {
|
|
1395
|
+
Napi::TypeError::New(env, "Expected antenna number").ThrowAsJavaScriptException();
|
|
1396
|
+
return env.Null();
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
ant_t antenna = info[0].As<Napi::Number>().Int32Value();
|
|
1400
|
+
value_t option = {0}; // Additional option parameter
|
|
1401
|
+
|
|
1402
|
+
int retcode = rig_set_ant(my_rig, RIG_VFO_CURR, antenna, option);
|
|
1403
|
+
if (retcode != RIG_OK) {
|
|
1404
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1405
|
+
return env.Null();
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
return Napi::Number::New(env, retcode);
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
Napi::Value NodeHamLib::GetAntenna(const Napi::CallbackInfo & info) {
|
|
1412
|
+
Napi::Env env = info.Env();
|
|
1413
|
+
|
|
1414
|
+
if (!rig_is_open) {
|
|
1415
|
+
Napi::TypeError::New(env, "Rig is not open!").ThrowAsJavaScriptException();
|
|
1416
|
+
return env.Null();
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
ant_t antenna = RIG_ANT_CURR;
|
|
1420
|
+
value_t option;
|
|
1421
|
+
ant_t antenna_curr;
|
|
1422
|
+
ant_t antenna_tx;
|
|
1423
|
+
ant_t antenna_rx;
|
|
1424
|
+
|
|
1425
|
+
int retcode = rig_get_ant(my_rig, RIG_VFO_CURR, antenna, &option, &antenna_curr, &antenna_tx, &antenna_rx);
|
|
1426
|
+
if (retcode != RIG_OK) {
|
|
1427
|
+
Napi::Error::New(env, rigerror(retcode)).ThrowAsJavaScriptException();
|
|
1428
|
+
return env.Null();
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
return Napi::Number::New(env, antenna_curr);
|
|
1432
|
+
}
|
|
1433
|
+
|
|
433
1434
|
Napi::Function NodeHamLib::GetClass(Napi::Env env) {
|
|
434
1435
|
auto ret = DefineClass(
|
|
435
1436
|
env,
|
|
@@ -444,12 +1445,53 @@ Napi::Function NodeHamLib::GetClass(Napi::Env env) {
|
|
|
444
1445
|
NodeHamLib::InstanceMethod("getMode", & NodeHamLib::GetMode),
|
|
445
1446
|
NodeHamLib::InstanceMethod("getStrength", & NodeHamLib::GetStrength),
|
|
446
1447
|
|
|
1448
|
+
// Memory Channel Management
|
|
1449
|
+
NodeHamLib::InstanceMethod("setMemoryChannel", & NodeHamLib::SetMemoryChannel),
|
|
1450
|
+
NodeHamLib::InstanceMethod("getMemoryChannel", & NodeHamLib::GetMemoryChannel),
|
|
1451
|
+
NodeHamLib::InstanceMethod("selectMemoryChannel", & NodeHamLib::SelectMemoryChannel),
|
|
1452
|
+
|
|
1453
|
+
// RIT/XIT Control
|
|
1454
|
+
NodeHamLib::InstanceMethod("setRit", & NodeHamLib::SetRit),
|
|
1455
|
+
NodeHamLib::InstanceMethod("getRit", & NodeHamLib::GetRit),
|
|
1456
|
+
NodeHamLib::InstanceMethod("setXit", & NodeHamLib::SetXit),
|
|
1457
|
+
NodeHamLib::InstanceMethod("getXit", & NodeHamLib::GetXit),
|
|
1458
|
+
NodeHamLib::InstanceMethod("clearRitXit", & NodeHamLib::ClearRitXit),
|
|
1459
|
+
|
|
1460
|
+
// Scanning Operations
|
|
1461
|
+
NodeHamLib::InstanceMethod("startScan", & NodeHamLib::StartScan),
|
|
1462
|
+
NodeHamLib::InstanceMethod("stopScan", & NodeHamLib::StopScan),
|
|
1463
|
+
|
|
1464
|
+
// Level Controls
|
|
1465
|
+
NodeHamLib::InstanceMethod("setLevel", & NodeHamLib::SetLevel),
|
|
1466
|
+
NodeHamLib::InstanceMethod("getLevel", & NodeHamLib::GetLevel),
|
|
1467
|
+
NodeHamLib::InstanceMethod("getSupportedLevels", & NodeHamLib::GetSupportedLevels),
|
|
1468
|
+
|
|
1469
|
+
// Function Controls
|
|
1470
|
+
NodeHamLib::InstanceMethod("setFunction", & NodeHamLib::SetFunction),
|
|
1471
|
+
NodeHamLib::InstanceMethod("getFunction", & NodeHamLib::GetFunction),
|
|
1472
|
+
NodeHamLib::InstanceMethod("getSupportedFunctions", & NodeHamLib::GetSupportedFunctions),
|
|
1473
|
+
|
|
1474
|
+
// Split Operations
|
|
1475
|
+
NodeHamLib::InstanceMethod("setSplitFreq", & NodeHamLib::SetSplitFreq),
|
|
1476
|
+
NodeHamLib::InstanceMethod("getSplitFreq", & NodeHamLib::GetSplitFreq),
|
|
1477
|
+
NodeHamLib::InstanceMethod("setSplitMode", & NodeHamLib::SetSplitMode),
|
|
1478
|
+
NodeHamLib::InstanceMethod("getSplitMode", & NodeHamLib::GetSplitMode),
|
|
1479
|
+
NodeHamLib::InstanceMethod("setSplit", & NodeHamLib::SetSplit),
|
|
1480
|
+
NodeHamLib::InstanceMethod("getSplit", & NodeHamLib::GetSplit),
|
|
447
1481
|
|
|
1482
|
+
// VFO Operations
|
|
1483
|
+
NodeHamLib::InstanceMethod("vfoOperation", & NodeHamLib::VfoOperation),
|
|
448
1484
|
|
|
1485
|
+
// Antenna Selection
|
|
1486
|
+
NodeHamLib::InstanceMethod("setAntenna", & NodeHamLib::SetAntenna),
|
|
1487
|
+
NodeHamLib::InstanceMethod("getAntenna", & NodeHamLib::GetAntenna),
|
|
449
1488
|
|
|
450
1489
|
NodeHamLib::InstanceMethod("close", & NodeHamLib::Close),
|
|
451
1490
|
NodeHamLib::InstanceMethod("destroy", & NodeHamLib::Destroy),
|
|
452
1491
|
NodeHamLib::InstanceMethod("getConnectionInfo", & NodeHamLib::GetConnectionInfo),
|
|
1492
|
+
|
|
1493
|
+
// Static method to get supported rig models
|
|
1494
|
+
NodeHamLib::StaticMethod("getSupportedRigs", & NodeHamLib::GetSupportedRigs),
|
|
453
1495
|
});
|
|
454
1496
|
constructor = Napi::Persistent(ret);
|
|
455
1497
|
constructor.SuppressDestruct();
|
|
@@ -474,3 +1516,88 @@ bool NodeHamLib::isNetworkAddress(const char* path) {
|
|
|
474
1516
|
return false;
|
|
475
1517
|
}
|
|
476
1518
|
|
|
1519
|
+
// Static callback function for rig_list_foreach
|
|
1520
|
+
int NodeHamLib::rig_list_callback(const struct rig_caps *caps, void *data) {
|
|
1521
|
+
RigListData *rig_data = static_cast<RigListData*>(data);
|
|
1522
|
+
|
|
1523
|
+
// Create rig info object
|
|
1524
|
+
Napi::Object rigInfo = Napi::Object::New(rig_data->env);
|
|
1525
|
+
rigInfo.Set(Napi::String::New(rig_data->env, "rigModel"),
|
|
1526
|
+
Napi::Number::New(rig_data->env, caps->rig_model));
|
|
1527
|
+
rigInfo.Set(Napi::String::New(rig_data->env, "modelName"),
|
|
1528
|
+
Napi::String::New(rig_data->env, caps->model_name ? caps->model_name : ""));
|
|
1529
|
+
rigInfo.Set(Napi::String::New(rig_data->env, "mfgName"),
|
|
1530
|
+
Napi::String::New(rig_data->env, caps->mfg_name ? caps->mfg_name : ""));
|
|
1531
|
+
rigInfo.Set(Napi::String::New(rig_data->env, "version"),
|
|
1532
|
+
Napi::String::New(rig_data->env, caps->version ? caps->version : ""));
|
|
1533
|
+
rigInfo.Set(Napi::String::New(rig_data->env, "status"),
|
|
1534
|
+
Napi::String::New(rig_data->env, rig_strstatus(caps->status)));
|
|
1535
|
+
|
|
1536
|
+
// Determine rig type string
|
|
1537
|
+
const char* rigType = "Unknown";
|
|
1538
|
+
switch (caps->rig_type & RIG_TYPE_MASK) {
|
|
1539
|
+
case RIG_TYPE_TRANSCEIVER:
|
|
1540
|
+
rigType = "Transceiver";
|
|
1541
|
+
break;
|
|
1542
|
+
case RIG_TYPE_HANDHELD:
|
|
1543
|
+
rigType = "Handheld";
|
|
1544
|
+
break;
|
|
1545
|
+
case RIG_TYPE_MOBILE:
|
|
1546
|
+
rigType = "Mobile";
|
|
1547
|
+
break;
|
|
1548
|
+
case RIG_TYPE_RECEIVER:
|
|
1549
|
+
rigType = "Receiver";
|
|
1550
|
+
break;
|
|
1551
|
+
case RIG_TYPE_PCRECEIVER:
|
|
1552
|
+
rigType = "PC Receiver";
|
|
1553
|
+
break;
|
|
1554
|
+
case RIG_TYPE_SCANNER:
|
|
1555
|
+
rigType = "Scanner";
|
|
1556
|
+
break;
|
|
1557
|
+
case RIG_TYPE_TRUNKSCANNER:
|
|
1558
|
+
rigType = "Trunk Scanner";
|
|
1559
|
+
break;
|
|
1560
|
+
case RIG_TYPE_COMPUTER:
|
|
1561
|
+
rigType = "Computer";
|
|
1562
|
+
break;
|
|
1563
|
+
case RIG_TYPE_OTHER:
|
|
1564
|
+
rigType = "Other";
|
|
1565
|
+
break;
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
rigInfo.Set(Napi::String::New(rig_data->env, "rigType"),
|
|
1569
|
+
Napi::String::New(rig_data->env, rigType));
|
|
1570
|
+
|
|
1571
|
+
// Add to list
|
|
1572
|
+
rig_data->rigList.push_back(rigInfo);
|
|
1573
|
+
|
|
1574
|
+
return 1; // Continue iteration (returning 0 would stop)
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
// Static method to get supported rig models
|
|
1578
|
+
Napi::Value NodeHamLib::GetSupportedRigs(const Napi::CallbackInfo& info) {
|
|
1579
|
+
Napi::Env env = info.Env();
|
|
1580
|
+
|
|
1581
|
+
// Load all backends to ensure we get the complete list
|
|
1582
|
+
rig_load_all_backends();
|
|
1583
|
+
|
|
1584
|
+
// Prepare data structure for callback with proper initialization
|
|
1585
|
+
RigListData rigData{std::vector<Napi::Object>(), env};
|
|
1586
|
+
|
|
1587
|
+
// Call hamlib function to iterate through all supported rigs
|
|
1588
|
+
int result = rig_list_foreach(rig_list_callback, &rigData);
|
|
1589
|
+
|
|
1590
|
+
if (result != RIG_OK) {
|
|
1591
|
+
Napi::Error::New(env, "Failed to retrieve supported rig list").ThrowAsJavaScriptException();
|
|
1592
|
+
return env.Null();
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
// Convert std::vector to Napi::Array
|
|
1596
|
+
Napi::Array rigArray = Napi::Array::New(env, rigData.rigList.size());
|
|
1597
|
+
for (size_t i = 0; i < rigData.rigList.size(); i++) {
|
|
1598
|
+
rigArray[i] = rigData.rigList[i];
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
return rigArray;
|
|
1602
|
+
}
|
|
1603
|
+
|