* change interface to QRZ XML service version 1.33
This commit is contained in:
David Freese 2019-02-01 23:32:29 -06:00
parent aeed471d89
commit 044dd29fa7
5 changed files with 118 additions and 77 deletions

View file

@ -23,7 +23,7 @@
#include <string>
bool request_reply(const std::string& node, const std::string& service,
bool network_query(const std::string& node, const std::string& service,
const std::string& request, std::string& reply, double timeout = 0.0);
bool fetch_http(const std::string& url, std::string& reply, double timeout = 0.0);
bool fetch_http_gui(const std::string& url, std::string& reply, double timeout = 0.0);

View file

@ -29,7 +29,7 @@
//std::string strSQSO
const char *szSQSO = "\
State/Province, ST/PR, County/City/District, CCD\n\
NONE,--,---------------\n\
NIL,--,none\n\
Alaska,AK,AK1st (SE),SE\n\
,AK,AK2nd (NW),NW\n\
,AK,AK3rd (SC),SC\n\

View file

@ -61,7 +61,7 @@
using namespace std;
string qrzhost = "xml.qrz.com"; //"online.qrz.com";
string qrzhost = "xmldata.qrz.com";
string qrzSessionKey;
string qrzalert;
string qrzerror;
@ -124,11 +124,11 @@ QRZ *qCall = 0;
void print_query(const string &name, const string &s)
{
LOG_VERBOSE("%s query:\n%s\n", name.c_str(), s.c_str());
LOG_VERBOSE("%s query:\n%s", name.c_str(), s.c_str());
}
void print_data(const string &name, const string &s) {
LOG_VERBOSE("%s data:\n%s\n", name.c_str(), s.c_str());
LOG_VERBOSE("%s data:\n%s", name.c_str(), s.c_str());
}
void clear_Lookup()
@ -155,6 +155,10 @@ void clear_Lookup()
bool parseSessionKey(const string& sessionpage)
{
if (sessionpage.find("Bad Request") != string::npos) {
return false;
}
IrrXMLReader* xml = createIrrXMLReader(new IIrrXMLStringReader(sessionpage));
TAG tag=QRZ_IGNORE;
while(xml && xml->read()) {
@ -205,7 +209,7 @@ bool parseSessionKey(const string& sessionpage)
bool parse_xml(const string& xmlpage)
{
print_data("QTH.com", xmlpage);
print_data("xmldata.qrz.com", xmlpage);
IrrXMLReader* xml = createIrrXMLReader(new IIrrXMLStringReader(xmlpage));
@ -321,24 +325,17 @@ bool getSessionKey(string& sessionpage)
{
string detail;
detail = "GET /bin/xml?username=";
detail = "GET /xml/current/?username=";
detail += progdefaults.QRZusername;
detail += ";password=";
detail += progdefaults.QRZuserpassword;
detail += ";version=";
detail += ";agent=";
detail += PACKAGE_NAME;
detail += "/";
detail += "-";
detail += PACKAGE_VERSION;
detail += " HTTP/1.0\n";
detail += "Host: ";
detail += qrzhost;
detail += "\n";
detail += "Connection: close\n";
detail += "\n";
detail += "\r\n";
print_query("QRZ session key", detail);
return request_reply(qrzhost, "http", detail, sessionpage, 5.0);
return network_query(qrzhost, "http", detail, sessionpage, 5.0);
}
bool QRZGetXML(string& xmlpage)
@ -348,17 +345,11 @@ bool QRZGetXML(string& xmlpage)
detail += qrzSessionKey;
detail += ";callsign=";
detail += callsign;
detail += " HTTP/1.0\n";
detail += "Host: ";
detail += qrzhost;
detail += "\n";
detail += "Connection: close\n";
detail += "\n";
detail += "\r\n";
// return request_reply(qrzhost, "http", detail, xmlpage, 5.0);
print_query("QRZ data", detail);
bool res = request_reply(qrzhost, "http", detail, xmlpage, 5.0);
bool res = network_query(qrzhost, "http", detail, xmlpage, 5.0);
LOG_VERBOSE("result = %d", res);
return res;
}
@ -528,22 +519,25 @@ void QRZAlert()
string qrznote;
if (!qrzalert.empty()) {
qrznote.append("QRZ alert notice:\n");
qrznote.append("QRZ alert:\n");
qrznote.append(qrzalert);
qrznote.append("\n");
qrzalert.clear();
}
if (!qrzerror.empty()) {
qrznote.append("QRZ error notice:\n");
qrznote.append(qrzalert);
qrznote.append("QRZ error:\n");
qrznote.append(qrzerror);
qrzerror.clear();
}
string notes;
if (!progdefaults.clear_notes) notes.assign(inpNotes->value());
else notes.clear();
if (!qrznote.empty()) notes.append("\n").append(qrznote);
inpNotes->value(notes.c_str());
if (!qrznote.empty()) {
if (!notes.empty()) notes.append("\n");
notes.append(qrznote);
inpNotes->value(notes.c_str());
}
}
bool QRZLogin(string& sessionpage)
@ -573,12 +567,12 @@ void QRZquery()
ok = QRZLogin(qrzpage);
if (ok)
ok = QRZGetXML(qrzpage);
if (!ok) { // change to negative for MS not getting on first try
if (qrzSessionKey.empty())
ok = QRZLogin(qrzpage);
if (ok)
ok = QRZGetXML(qrzpage);
}
// if (!ok) { // change to negative for MS not getting on first try
// if (qrzSessionKey.empty())
// ok = QRZLogin(qrzpage);
// if (ok)
// ok = QRZGetXML(qrzpage);
// }
if (ok) {
parse_xml(qrzpage);
if (!qrzalert.empty() || !qrzerror.empty())
@ -783,8 +777,8 @@ bool HAMCALLget(string& htmlpage)
url.erase(0, p+2);
size_t len = url.length();
if (url[len-1]=='/') url.erase(len-1, 1);
return request_reply(url, service, url_detail, htmlpage, 5.0);
// return request_reply("www.hamcall.net", "http", url_detail, htmlpage, 5.0);
return network_query(url, service, url_detail, htmlpage, 5.0);
// return network_query("www.hamcall.net", "http", url_detail, htmlpage, 5.0);
}
void HAMCALLquery()
@ -823,10 +817,11 @@ bool HAMQTH_get_session_id()
HAMQTH_session_id.clear();
if (!fetch_http(url, retstr, 5.0)) {
printf("fetch_http( %s, retstr, 5.0) failed\n", url.c_str());
LOG_ERROR("fetch_http( %s, retstr, 5.0) failed\n", url.c_str());
return false;
}
printf("%s\n", retstr.c_str());
LOG_VERBOSE("url: %s", url.c_str());
LOG_VERBOSE("reply: %s\n", retstr.c_str());
p1 = retstr.find("<error>");
if (p1 != string::npos) {
p2 = retstr.find("</error>");
@ -1139,10 +1134,10 @@ void CALLSIGNquery()
switch (DB_XML_query = static_cast<qrz_xmlquery_t>(progdefaults.QRZXML)) {
case QRZNET:
LOG_INFO("%s","Request sent to\nqrz.com...");
LOG_INFO("%s","Request sent to qrz.com...");
break;
case HAMCALLNET:
LOG_INFO("%s","Request sent to\nwww.hamcall.net...");
LOG_INFO("%s","Request sent to www.hamcall.net...");
break;
case QRZCD:
if (!qCall)

View file

@ -39,16 +39,23 @@
#include "gettext.h"
#include "debug.h"
#define LOG_QRZ_DEBUG 1
using namespace std;
bool request_reply(const string& node, const string& service, const string& request, string& reply, double timeout)
bool network_query(const string& node, const string& service, const string& request, string& reply, double timeout)
{
if (LOG_QRZ_DEBUG)
LOG_INFO("\n\
node: %s\n\
service: %s",
node.c_str(), service.c_str() );
LOG_VERBOSE("\n\
========================================================================\n\
node: %s\n\
service: %s\n\
========================================================================",
node.c_str(), service.c_str() );
node: %s\n\
service: %s",
node.c_str(), service.c_str() );
try {
Socket s(Address(node.c_str(), service.c_str()));
@ -57,29 +64,28 @@ node.c_str(), service.c_str() );
s.set_timeout(timeout);
if (s.send(request) != request.length()) {
LOG_ERROR("\n\
======================== SEND TIMED OUT ================================\n\
%s\n\
========================================================================",
LOG_ERROR("************ SEND TIMED OUT ************\n\
%s",
request.c_str());
reply = "Send timed out";
return false;
}
LOG_VERBOSE("\n\
=============================== SENT ===================================\n\
%s\n\
========================================================================",
request.c_str());
if (LOG_QRZ_DEBUG)
LOG_INFO("sent:\n'%s'", request.c_str());
LOG_VERBOSE("sent:\n'%s'", request.c_str());
if (s.recv(reply) == 0) {
LOG_ERROR("Reply time out");
reply = "Reply timed out";
return false;
}
LOG_VERBOSE("\n\
============================== REPLY ===================================\n\
%s\n\
========================================================================",
reply.c_str());
if (LOG_QRZ_DEBUG)
LOG_INFO("reply:\n%s", reply.c_str());
LOG_VERBOSE("reply:\n%s", reply.c_str());
}
catch (const SocketException& e) {
reply = e.what();
@ -109,7 +115,7 @@ bool fetch_http(const string& url, string& reply, double timeout)
.append("Host: ").append(http_host).append("\r\n")
.append("Connection: close\r\n\r\n");
return request_reply( http_host, "http", request, reply, timeout);
return network_query( http_host, "http", request, reply, timeout);
}
struct fetch_data_t {

View file

@ -24,6 +24,10 @@
#include <sys/types.h>
#include <FL/Fl.H>
#define LOG_QRZ_DEBUG 1
#ifndef __MINGW32__
# include <sys/socket.h>
# include <netdb.h>
@ -403,6 +407,8 @@ const addr_info_t* Address::get(size_t n) const
for (size_t i = 0; i < n; i++)
p = p->ai_next;
# ifndef NDEBUG
if (LOG_QRZ_DEBUG)
LOG_INFO("Found address %s", get_str(p).c_str());
LOG_DEBUG("Found address %s", get_str(p).c_str());
# endif
return p;
@ -425,6 +431,8 @@ const addr_info_t* Address::get(size_t n) const
addr.ai_addrlen = sizeof(saddr);
addr.ai_addr = (struct sockaddr*)&saddr;
# ifndef NDEBUG
if (LOG_QRZ_DEBUG)
LOG_INFO("Found address %s", get_str(&addr).c_str());
LOG_DEBUG("Found address %s", get_str(&addr).c_str());
# endif
return &addr;
@ -622,16 +630,30 @@ void Socket::open(const Address& addr)
for (anum = 0; anum < n; anum++) {
info = address.get(anum);
LOG_DEBUG("\n\
Address %s\n\
Family %s\n\
Sock type %d\n\
Protocol %d",
if (LOG_QRZ_DEBUG)
LOG_INFO("\n\
Address %s\n\
Family %s\n\
Sock type %s\n\
Protocol %s",
address.get_str(info).c_str(),
(info->ai_family == AF_INET6 ? "AF_INET6" :\
(info->ai_family == AF_INET ? "AF_INET" : "unknown")),
info->ai_socktype,
info->ai_protocol);
(info->ai_socktype == SOCK_STREAM ? "stream" : "dgram"),
(info->ai_protocol == IPPROTO_TCP ? "tcp" :
(info->ai_protocol == IPPROTO_UDP ? "udp" : "unknown protocol")));
LOG_DEBUG("\n\
Address %s\n\
Family %s\n\
Sock type %s\n\
Protocol %s",
address.get_str(info).c_str(),
(info->ai_family == AF_INET6 ? "AF_INET6" :\
(info->ai_family == AF_INET ? "AF_INET" : "unknown")),
(info->ai_socktype == SOCK_STREAM ? "stream" : "dgram"),
(info->ai_protocol == IPPROTO_TCP ? "tcp" :
(info->ai_protocol == IPPROTO_UDP ? "udp" : "unknown protocol")));
if (info->ai_family == AF_INET) ainfo = info;
}
@ -928,13 +950,13 @@ int Socket::connect(void)
connected_flag = true;
return errno;
}
if (errno == EWOULDBLOCK || errno == EINPROGRESS || errno == EALREADY) {
LOG_INFO("Connect attempt to %s : %d, %s",
if (errno == EWOULDBLOCK || errno == EINPROGRESS || errno == EALREADY) {
LOG_INFO("Connect attempt to %s : %d, %s",
address.get_str(ainfo).c_str(),
errno, strerror(errno));
return errno;
}
LOG_ERROR("Connect to %s failed: %d, %s",
LOG_ERROR("Connect to %s failed: %d, %s",
address.get_str(ainfo).c_str(),
errno, strerror(errno));
throw SocketException(errno, "connect");
@ -952,6 +974,8 @@ bool Socket::connect1(void)
{
connected_flag = false;
#ifndef NDEBUG
if (LOG_QRZ_DEBUG)
LOG_INFO("Connecting to %s", address.get_str(ainfo).c_str());
LOG_DEBUG("Connecting to %s", address.get_str(ainfo).c_str());
#endif
if (::connect(sockfd, ainfo->ai_addr, ainfo->ai_addrlen) == -1) {
@ -1099,16 +1123,32 @@ size_t Socket::recv(string& buf)
{
size_t n = 0;
ssize_t r;
int tout = timeout.tv_sec * 1000 + (timeout.tv_usec / 1000);
int msec = tout;
try {
while ((r = recv(buffer, BUFSIZ)) > 0) {
buf.reserve(buf.length() + r);
r = ::recv(sockfd, buffer, BUFSIZ, 0);
while (r <= 0 && tout > 0) {
MilliSleep(10);
tout -= 10;
r = ::recv(sockfd, buffer, BUFSIZ, 0);
}
if (r == 0) {
LOG_VERBOSE("%s", "REQ TIMED OUT: shutdown socket");
shutdown(sockfd, SHUT_RD);
return 0;
}
buf.clear();
while (r > 0 && tout > 0) {
buf.append(buffer, r);
n += r;
r = ::recv(sockfd, buffer, BUFSIZ, 0);
tout -= 10;
MilliSleep(10);
}
} catch (SocketException &e) {
throw e;
}
LOG_VERBOSE("Response took %d msec", msec - tout);
return n;
}