bool LocationInfo::parseClients(const Async::Config &cfg, const string &name) { string aprs_server_list(cfg.getValue(name, "APRS_SERVER_LIST")); stringstream clientStream(aprs_server_list); string client, host; int port; bool success = true; while (clientStream >> client) { if (!parseClientStr(host, port, client)) { print_error(name, "APRS_SERVER_LIST", aprs_server_list, "APRS_SERVER_LIST=euro.aprs2.net:14580"); success = false; } else { AprsTcpClient *client = new AprsTcpClient(loc_cfg, host, port); clients.push_back(client); } } clientStream.clear(); string status_server_list(cfg.getValue(name, "STATUS_SERVER_LIST")); clientStream.str(status_server_list); while (clientStream >> client) { if (!parseClientStr(host, port, client)) { print_error(name, "STATUS_SERVER_LIST", status_server_list, "STATUS_SERVER_LIST=aprs.echolink.org:5199"); success = false; } else { AprsUdpClient *client = new AprsUdpClient(loc_cfg, host, port); clients.push_back(client); } } return success; } /* LocationInfo::parseClients */
bool PttSerialPin::initialize(Async::Config &cfg, const std::string name) { string ptt_port; if (!cfg.getValue(name, "PTT_PORT", ptt_port)) { cerr << "*** ERROR: Config variable " << name << "/PTT_PORT not set\n"; return false; } serial = new Serial(ptt_port.c_str()); if (!serial->open()) { perror("open serial port"); return false; } if (!setPins(cfg, name)) { return false; } string ptt_pin_str; if (!cfg.getValue(name, "PTT_PIN", ptt_pin_str)) { cerr << "*** ERROR: Config variable " << name << "/PTT_PIN not set\n"; return false; } const char *ptr = ptt_pin_str.c_str(); int cnt; cnt = parsePttPin(name, ptr, ptt_pin1, ptt_pin1_rev); if (cnt == 0) { return false; } ptr += cnt; if (*ptr != 0) { if (parsePttPin(name, ptr, ptt_pin2, ptt_pin2_rev) == 0) { return false; } } return true; } /* PttSerialPin::initialize */
bool PttSerialPin::setPins(const Async::Config &cfg, const std::string &name) { std::string pins; if (!cfg.getValue(name, "SERIAL_SET_PINS", pins)) { return true; } std::string::iterator it(pins.begin()); while (it != pins.end()) { bool do_set = true; if (*it == '!') { do_set = false; ++it; } std::string pin_name(it, it+3); it += 3; if (pin_name == "RTS") { serial->setPin(Async::Serial::PIN_RTS, do_set); } else if (pin_name == "DTR") { serial->setPin(Async::Serial::PIN_DTR, do_set); } else { std::cerr << "*** ERROR: Illegal pin name \"" << pin_name << "\" for the " << name << "/SERIAL_SET_PINS configuration variable. " << "Accepted values are \"[!]RTS\" and/or \"[!]DTR\".\n"; return false; } } return true; } /* PttSerialPin::setPins */
bool SquelchEvDev::initialize(Async::Config& cfg, const std::string& rx_name) { if (!Squelch::initialize(cfg, rx_name)) { return false; } std::string devname; if (!cfg.getValue(rx_name, "EVDEV_DEVNAME", devname)) { std::cerr << "*** ERROR: Config variable " << rx_name << "/EVDEV_NAME not set\n"; return false; } string value; if (!cfg.getValue(rx_name, "EVDEV_OPEN", value)) { std::cerr << "*** ERROR: Config variable " << rx_name << "/EVDEV_OPEN not set\n"; return false; } SvxLink::splitStr(open_ev, value, ","); if (open_ev.size() != 3) { std::cerr << "*** ERROR: Wrong number of arguments for config variable " << rx_name << "/EVDEV_OPEN. There should be three: " << "type code value (e.g. 1,163,1)\n"; return false; } if (!cfg.getValue(rx_name, "EVDEV_CLOSE", value)) { std::cerr << "*** ERROR: Config variable " << rx_name << "/EVDEV_CLOSE not set\n"; return false; } SvxLink::splitStr(close_ev, value, ","); if (close_ev.size() != 3) { std::cerr << "*** ERROR: Wrong number of arguments for config variable " << rx_name << "/EVDEV_CLOSE. There should be three: " << "type code value (e.g. 1,163,0)\n"; return false; } if ((fd = open(devname.c_str(), O_RDONLY)) == -1) { cerr << "*** ERROR: Could not open event device " << devname << ": " << strerror(errno) << endl; return false; } watch = new FdWatch(fd, FdWatch::FD_WATCH_RD); assert(watch != 0); watch->activity.connect(slot(*this, &SquelchEvDev::readEvDevData)); // Print Device Name char name[256] = "Unknown"; ioctl(fd, EVIOCGNAME (sizeof (name)), name); cout << rx_name << ": EvDev Squelch: " << devname << "(" << name << ")\n"; return true; }
bool PttHidraw::initialize(Async::Config &cfg, const std::string name) { map<string, char> pin_mask; pin_mask["GPIO1"] = 0x01; pin_mask["GPIO2"] = 0x02; pin_mask["GPIO3"] = 0x04; pin_mask["GPIO4"] = 0x08; string hidraw_pin; if (!cfg.getValue(name, "HID_PTT_PIN", hidraw_pin) || hidraw_pin.empty()) { cerr << "*** ERROR: Config variable " << name << "/HID_PTT_PIN not set\n"; return false; } string hidraw_dev; if (!cfg.getValue(name, "HID_DEVICE", hidraw_dev) || hidraw_dev.empty()) { cerr << "*** ERROR: Config variable " << name << "/HID_DEVICE not set\n"; return false; } if ((fd = open(hidraw_dev.c_str(), O_WRONLY, 0)) < 0) { cerr << "*** ERROR: Can't open port " << hidraw_dev << endl; return false; } struct hidraw_devinfo hiddevinfo; if ((ioctl(fd, HIDIOCGRAWINFO, &hiddevinfo) != -1) && (hiddevinfo.vendor == 0x0d8c)) { cout << "--- Hidraw sound chip is "; if (hiddevinfo.product == 0x000c) { cout << "CM108"; } else if (hiddevinfo.product == 0x013c) { cout << "CM108A"; } else if (hiddevinfo.product == 0x000e) { cout << "CM109"; } else if (hiddevinfo.product == 0x013a) { cout << "CM119"; } else { cout << "unknown"; } cout << endl; } else { cerr << "*** ERROR: unknown/unsupported sound chip detected...\n"; return false; } if (hidraw_pin[0] == '!') { active_low = true; hidraw_pin.erase(0, 1); } map<string, char>::iterator it = pin_mask.find(hidraw_pin); if (it == pin_mask.end()) { cerr << "*** ERROR: Wrong value for " << name << "/HID_PIN=" << hidraw_pin << ", valid are GPIO1, GPIO2, GPIO3, GPIO4" << endl; return false; } pin = (*it).second; return true; } /* PttHidraw::initialize */
bool LocationInfo::parsePath(const Async::Config &cfg, const string &name) { // FIXME: Verify the path syntax! loc_cfg.path = cfg.getValue(name, "PATH"); return true; } /* LocationInfo::parsePath */
bool LocationInfo::parseStationHW(const Async::Config &cfg, const string &name) { float frequency = 0; bool success = true; if (!cfg.getValue(name, "FREQUENCY", frequency)) { print_error(name, "FREQUENCY", cfg.getValue(name, "FREQUENCY"), "FREQUENCY=438.875"); success = false; } else { loc_cfg.frequency = lrintf(1000.0 * frequency); } if (!cfg.getValue(name, "TX_POWER", 1U, numeric_limits<unsigned int>::max(), loc_cfg.power)) { print_error(name, "TX_POWER", cfg.getValue(name, "TX_POWER"), "TX_POWER=8"); success = false; } if (!cfg.getValue(name, "ANTENNA_GAIN", loc_cfg.gain, true)) { print_error(name, "ANTENNA_GAIN", cfg.getValue(name, "ANTENNA_GAIN"), "ANTENNA_GAIN=6"); success = false; } if (!parseAntennaHeight(loc_cfg, cfg.getValue(name, "ANTENNA_HEIGHT"))) { print_error(name, "ANTENNA_HEIGHT", cfg.getValue(name, "ANTENNA_HEIGHT"), "ANTENNA_HEIGHT=10m"); success = false; } if (!cfg.getValue(name, "ANTENNA_DIR", loc_cfg.beam_dir, true)) { print_error(name, "ANTENNA_DIR", cfg.getValue(name, "ANTENNA_DIR"), "ANTENNA_DIR=-1"); success = false; } if (!cfg.getValue(name, "TONE", loc_cfg.tone, true)) { print_error(name, "TONE", cfg.getValue(name, "TONE"), "TONE=0"); success = false; } int interval = 10; int max = numeric_limits<int>::max(); if (!cfg.getValue(name, "BEACON_INTERVAL", 10, max, interval, true)) { print_error(name, "BEACON_INTERVAL", cfg.getValue(name, "BEACON_INTERVAL"), "BEACON_INTERVAL=10"); success = false; } else { loc_cfg.interval = 60 * 1000 * interval; } loc_cfg.range = calculateRange(loc_cfg); return success; } /* LocationInfo::parseStationHW */
bool LocationInfo::initialize(const Async::Config &cfg, const std::string &cfg_name) { // check if already initialized if (LocationInfo::_instance->has_instance()) return false; bool init_ok = true; string value; LocationInfo::_instance = new LocationInfo(); value = cfg.getValue(cfg_name, "CALLSIGN"); if (value.find("EL-") != string::npos) { LocationInfo::_instance->loc_cfg.prefix = "L"; } else if (value.find("ER-") != string::npos) { LocationInfo::_instance->loc_cfg.prefix = "R"; } else { cerr << "*** ERROR: variable CALLSIGN must have a prefix (ER- or EL-)" << " to indicate that is an Echolink station.\n" << "Example: CALLSIGN=ER-DL1ABC\n"; return false; } if (value.erase(0,3).length() < 4) { cerr << "*** ERROR: variable CALLSIGN in section " << cfg_name << " is missing or wrong\nExample: CALLSIGN=ER-DL1ABC\n"; return false; } LocationInfo::_instance->loc_cfg.mycall = value; LocationInfo::_instance->loc_cfg.comment = cfg.getValue(cfg_name, "COMMENT"); init_ok &= LocationInfo::_instance->parsePosition(cfg, cfg_name); init_ok &= LocationInfo::_instance->parseStationHW(cfg, cfg_name); init_ok &= LocationInfo::_instance->parsePath(cfg, cfg_name); init_ok &= LocationInfo::_instance->parseClients(cfg, cfg_name); unsigned int iv = atoi(cfg.getValue(cfg_name, "STATISTICS_INTERVAL").c_str()); if (iv < 5 || iv > 60) { iv = 10; } LocationInfo::_instance->sinterval = iv; LocationInfo::_instance->startStatisticsTimer(iv*60000); if( !init_ok ) { delete LocationInfo::_instance; LocationInfo::_instance = NULL; } return init_ok; } /* LocationInfo::initialize */
WbRxRtlSdr::WbRxRtlSdr(Async::Config &cfg, const string &name) : auto_tune_enabled(true), m_name(name), xvrtr_offset(0) { //cout << "### Initializing WBRX " << name << endl; string rtl_type = "RtlTcp"; cfg.getValue(name, "TYPE", rtl_type); if (rtl_type == "RtlTcp") { string remote_host = "localhost"; cfg.getValue(name, "HOST", remote_host); int tcp_port = 1234; cfg.getValue(name, "PORT", tcp_port); //cout << "### HOST = " << remote_host << endl; //cout << "### PORT = " << tcp_port << endl; rtl = new RtlTcp(remote_host, tcp_port); } #ifdef HAS_RTLSDR_SUPPORT else if (rtl_type == "RtlUsb") { string dev_match = "0"; cfg.getValue(name, "DEV_MATCH", dev_match); //cout << "### DEV_MATCH = " << dev_match << endl; rtl = new RtlUsb(dev_match); } #endif else { cerr << "*** ERROR: Unknown WbRx type: " << rtl_type << endl; exit(1); } int sample_rate = 960000; cfg.getValue(name, "SAMPLE_RATE", sample_rate); //cout << "### SAMPLE_RATE = " << sample_rate << endl; rtl->setSampleRate(sample_rate); rtl->iqReceived.connect(iqReceived.make_slot()); rtl->readyStateChanged.connect( mem_fun(*this, &WbRxRtlSdr::rtlReadyStateChanged)); int fq_corr = 0; if (cfg.getValue(name, "FQ_CORR", fq_corr) && (fq_corr != 0)) { //cout << "### FQ_CORR = " << (int32_t)fq_corr << "ppm\n"; rtl->setFqCorr(fq_corr); } uint32_t center_fq = 0; if (cfg.getValue(name, "CENTER_FQ", center_fq)) { //cout << "### CENTER_FQ = " << center_fq << "Hz\n"; auto_tune_enabled = false; setCenterFq(center_fq); } cfg.getValue(name, "XVRTR_OFFSET", xvrtr_offset); float gain = 0.0f; if (cfg.getValue(name, "GAIN", gain)) { //cout << "### GAIN = " << gain << "dB\n"; rtl->setGainMode(1); int32_t int_gain = static_cast<int32_t>(10.0 * gain); rtl->setGain(int_gain); } bool peak_meter = false; cfg.getValue(name, "PEAK_METER", peak_meter); rtl->enableDistPrint(peak_meter); } /* WbRxRtlSdr::WbRxRtlSdr */
/** Initializing the sound card as linux/hidraw device For further information: http://dmkeng.com http://www.halicky.sk/om3cph/sb/CM108_DataSheet_v1.6.pdf http://www.ti.com/lit/ml/sllu093/sllu093.pdf http://www.ti.com/tool/usb-to-gpio */ bool SquelchHidraw::initialize(Async::Config& cfg, const std::string& rx_name) { if (!Squelch::initialize(cfg, rx_name)) { return false; } string devicename; if (!cfg.getValue(rx_name, "HID_DEVICE", devicename)) { cerr << "*** ERROR: Config variable " << devicename << "/HID_DEVICE not set" << endl; return false; } string sql_pin; if (!cfg.getValue(rx_name, "HID_SQL_PIN", sql_pin) || sql_pin.empty()) { cerr << "*** ERROR: Config variable " << rx_name << "/HID_SQL_PIN not set or invalid\n"; return false; } if ((sql_pin.size() > 1) && (sql_pin[0] == '!')) { active_low = true; sql_pin.erase(0, 1); } map<string, char> pin_mask; pin_mask["VOL_UP"] = 0x01; pin_mask["VOL_DN"] = 0x02; pin_mask["MUTE_PLAY"] = 0x04; pin_mask["MUTE_REC"] = 0x08; map<string, char>::iterator it = pin_mask.find(sql_pin); if (it == pin_mask.end()) { cerr << "*** ERROR: Invalid value for " << rx_name << "/HID_SQL_PIN=" << sql_pin << ", must be VOL_UP, VOL_DN, MUTE_PLAY, MUTE_REC" << endl; return false; } pin = (*it).second; if ((fd = open(devicename.c_str(), O_RDWR, 0)) < 0) { cout << "*** ERROR: Could not open event device " << devicename << " specified in " << rx_name << "/HID_DEVICE: " << strerror(errno) << endl; return false; } struct hidraw_devinfo hiddevinfo; if ((ioctl(fd, HIDIOCGRAWINFO, &hiddevinfo) != -1) && (hiddevinfo.vendor == 0x0d8c)) { cout << "--- Hidraw sound chip is "; if (hiddevinfo.product == 0x000c) { cout << "CM108"; } else if (hiddevinfo.product == 0x013c) { cout << "CM108A"; } else if (hiddevinfo.product == 0x000e) { cout << "CM109"; } else if (hiddevinfo.product == 0x013a) { cout << "CM119"; } else { cout << "unknown"; } cout << endl; } else { cout << "*** ERROR: unknown/unsupported sound chip detected...\n"; return false; } watch = new Async::FdWatch(fd, Async::FdWatch::FD_WATCH_RD); assert(watch != 0); watch->activity.connect(mem_fun(*this, &SquelchHidraw::hidrawActivity)); return true; }