1 /*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2015 Wei Jiang
5 * Copyright (c) 2015-2017 Josh Blum
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23 #include "SoapyHackRF.hpp"
24 #include <SoapySDR/Registry.hpp>
25
26 static std::map<std::string, SoapySDR::Kwargs> _cachedResults;
27
find_HackRF(const SoapySDR::Kwargs & args)28 static std::vector<SoapySDR::Kwargs> find_HackRF(const SoapySDR::Kwargs &args)
29 {
30 SoapyHackRFSession Sess;
31
32 std::vector<SoapySDR::Kwargs> results;
33
34 hackrf_device_list_t *list;
35
36 list =hackrf_device_list();
37
38 if (list->devicecount > 0) {
39
40 for (int i = 0; i < list->devicecount; i++) {
41
42 hackrf_device* device = NULL;
43 uint8_t board_id = BOARD_ID_INVALID;
44 read_partid_serialno_t read_partid_serialno;
45
46 hackrf_device_list_open(list, i, &device);
47
48 SoapySDR::Kwargs options;
49
50 if (device!=NULL) {
51
52 hackrf_board_id_read(device, &board_id);
53
54 options["device"] = hackrf_board_id_name((hackrf_board_id) board_id);
55
56 char version_str[100];
57
58 hackrf_version_string_read(device, &version_str[0], 100);
59
60 options["version"] = version_str;
61
62 hackrf_board_partid_serialno_read(device, &read_partid_serialno);
63
64 char part_id_str[100];
65
66 sprintf(part_id_str, "%08x%08x", read_partid_serialno.part_id[0], read_partid_serialno.part_id[1]);
67
68 options["part_id"] = part_id_str;
69
70 char serial_str[100];
71 sprintf(serial_str, "%08x%08x%08x%08x", read_partid_serialno.serial_no[0],
72 read_partid_serialno.serial_no[1], read_partid_serialno.serial_no[2],
73 read_partid_serialno.serial_no[3]);
74 options["serial"] = serial_str;
75
76 //generate a displayable label string with trimmed serial
77 size_t ofs = 0;
78 while (ofs < sizeof(serial_str) and serial_str[ofs] == '0') ofs++;
79 char label_str[100];
80 sprintf(label_str, "%s #%d %s", options["device"].c_str(), i, serial_str+ofs);
81 options["label"] = label_str;
82
83 //filter based on serial and idx
84 const bool serialMatch = args.count("serial") == 0 or args.at("serial") == options["serial"];
85 const bool idxMatch = args.count("hackrf") == 0 or std::stoi(args.at("hackrf")) == i;
86 if (serialMatch and idxMatch)
87 {
88 results.push_back(options);
89 _cachedResults[serial_str] = options;
90 }
91
92 hackrf_close(device);
93 }
94
95 }
96
97 }
98
99 hackrf_device_list_free(list);
100
101 //fill in the cached results for claimed handles
102 for (const auto &serial : HackRF_getClaimedSerials())
103 {
104 if (_cachedResults.count(serial) == 0) continue;
105 if (args.count("serial") != 0 and args.at("serial") != serial) continue;
106 results.push_back(_cachedResults.at(serial));
107 }
108
109 return results;
110 }
111
make_HackRF(const SoapySDR::Kwargs & args)112 static SoapySDR::Device *make_HackRF(const SoapySDR::Kwargs &args)
113 {
114 return new SoapyHackRF(args);
115 }
116
117 static SoapySDR::Registry register_hackrf("hackrf", &find_HackRF, &make_HackRF, SOAPY_SDR_ABI_VERSION);
118