GPSD giving mode 0 in libgpsmm - c++

I'm trying to use the C++ integration with GPSD on a Pi. If I run GPSMON I can verify that I have a full fix without issue, however in my C++ program I am getting a fix with mode 0, which means "MODE UPDATE NOT SEEN YET".
The program isn't erroring out at the socket connection, so I'm not sure what's causing the disconnect.

I suppose you are using libgps and libgpsmm. Your problem may be caused by a version incompatibility between gpsd daemon and libgps.
I.e. the client (libgps) may speak a different version of the "API protocol" gpsd_json than the gpsd daemon.
This may happen if you decided to build/link a static version of libgps -- which does not exactly match the version number of gpsd. Or if your client runs on a diffent machine than gpsd server.
I ran into same problem and it took me valuable time to figure out the reason:
JSON parser in libgps is designed badly. It ignores/discards JSON objects which contain name/value pairs, which are not known a priori.
So whole TPV messages from gpsd may be discarded and your client implementation shows no error message, neither libgps functions return an error code. Too bad.
Here it is (json.c, line 296+, #2016-07-27):
if (cursor->attribute == NULL) {
json_debug_trace((1,
"Unknown attribute name '%s' (attributes begin with '%s').\n",
attrbuf, attrs->attribute));
/* don't update end here, leave at attribute start */
return JSON_ERR_BADATTR;
}
And here (libgps_json.c, line 27+, #2016-07-27):
static int json_tpv_read(const char *buf, struct gps_data_t *gpsdata, const char **endptr)
{
const struct json_attr_t json_attrs_1[] = {
{"class", t_check, .dflt.check = "TPV"},
{"device", t_string, .addr.string = gpsdata->dev.path, .len = sizeof(gpsdata->dev.path)},
{"time", t_time, .addr.real = &gpsdata->fix.time, .dflt.real = NAN},
...
Use _gpsmm->enable_debug( level, stderr ) with level>=6 and compile libgps, libgpsmm with define CLIENTDEBUG_ENABLE to get the debug trace output.
git repositiory of gpsd sources tells us dates of recent incompatible changes on the gpsd_json protocol:
git commits:
2016-04-07 Add "status" to TPV for DGPS notification
2016-01-04 Address Savannah bug #46804: JSON satellite view parsing is somewhat broken.
2015-04-04 Add client-library parsing of PPS precision.
2015-01-24 In client library, "dip" member was missing from ATT parsing.
Releases:
3.11 23-Aug-2014
3.12 22-Feb-2015 incompatible
3.13 26-Feb-2015
3.14 14-Mar-2015
3.15 03-Jun-2015 incompatible
3.16 08-Jan-2016 incompatible
3.17 xx-xxx-xxxx incompatible
Do gpsd developers not care about client-server compatibility across versions? What about shared libgps library binary API/ABI stability then?
It is missing versioning functions. Very unsafe also.
(Look at the comment git comment on the 2015-04-04 change mentioned above: Data is currently discarded, pending the next gps_data_t structure break.)

Related

Creating ECDSA keys with OpenSSL 3 (migration problem)

I need to create ECDSA keys and used old OpenSSL code until now, which dosn't compile any more under OpenSSL3, there are now lots of deprecation errors. I invested now several days with search & try, but I can't solve it. I am trying the simple example [https://fm4dd.com/openssl/eckeycreate.shtm][1], but already the first lines create these errors:
WorkerThread.cpp(34,2): error C4996: 'ERR_load_BIO_strings': Since OpenSSL 3.0
WorkerThread.cpp(47,19): error C4996: 'EC_KEY_new_by_curve_name': Since OpenSSL 3.0
WorkerThread.cpp(54,2): error C4996: 'EC_KEY_free': Since OpenSSL 3.0
So the first idea would be to eliminate these compiler errors somehow. I found the switches
#define OPENSSL_API_COMPAT 30000
#define OPENSSL_NO_DEPRECATED
but they create even more errors, because now suddenly even the EC_KEY is unknown to the compiler. No solution.
So there stays the hard way to try to migrate the code somehow to OpenSSL3, because there seems to be no example code in the whole internet for simply creating an ECDSA key with OpenSSL3, and extract the private and public part. But just changing single functions with an OpenSSL3 matching function doesn't solve it, because the whole concept changes (switching from low level API to high level, with a completely different programming model).
I have tried fiddling around with lots of examples, but it looks like my programming task that seems so simple is a very complicated thing. Any help is appreciated, but I want to stay in C/C++ because my application is performance critical.
Environment: MS Win10, MS Visual Studio 2019, latest OpenSSL 3
[1]: https://fm4dd.com/openssl/eckeycreate.shtm
WorkerThread.cpp(34,2): error C4996: 'ERR_load_BIO_strings': Since OpenSSL 3.0
You don't need to call any of those initialisation functions. Just remove them from your code. They are not needed with any version of OpenSSL from 1.1.0 onwards.
In the example, all of the code for getting an EC_GROUP, creating an EC_KEY, generating a key, setting the OPENSSL_EC_NAMED_CURVE flag and assigning it to an EVP_PKEY can be completely removed. Replace it with a simple call to EVP_EC_gen(). See the man page here:
https://www.openssl.org/docs/man3.0/man3/EVP_EC_gen.html
E.g. all of that code can be replaced with something like
pkey = EVP_EC_gen("secp521r1");
if (pkey == NULL) {
BIO_printf(outbio, "Error generating the ECC key.");
abort();
}

Unable to display children:Attribute not found: value

I keep on getting this error when trying to view objects in the Debugger in PyCharm:
Unable to display children:Attribute not found: value
I have deduced that it is an error with Pycharm itself, not my code
(I get the same error on multiple scripts, but no error on with an older version of Pycharm on 2 different computers)
I'm on PyCharm Community 2017.3.4
Any ideas for workarounds, other than installing an older version?
I am finding similar issues. I too think there is something up with PyCharm it does not work as expected or previous version as you mention. I also found Pyscripter to debug as expected.
In some instances I would rely on the result object, result[0] or result.getOutput(0) to pass to next tool. Instead one can use a variable for the "output" or use the string (name) directly as input for the next tool.
For example,
facility_staging_polygons = os.path.join(outGDB, 'facility_staging_polygons\Polygon_1')
result = arcpy.MakeFeatureLayer_management(facility_staging_polygons, 'facility_staging_polygons_Layer')
# Process: Update Attributes
arcpy.AddField_management('facility_staging_polygons_Layer', "area_calc", "LONG")

handling errors from unrar DLL

If you run the command-line version of unrar it logs out vital information when an archive fails to extract.
I'm trying to do the same thing with the unrar DLL.
I've already had to make some changes to the DLL source code to support registering my own callback to handle extraction progress properly.
Now I want to handle error reporting properly.
There is really no documentation on using unrar source.
So I have a working callback function that can be called
CommandData *Cmd
Cmd->ErrorCallback(ERAR_BAD_DATA, Arc.FileName, ArcFileName);
The function works great if I call it next to my progress DLL (so I know the callback works), but I just can't figure out where the errors are being handled.
Specifically I'm after handling the code ERAR_BAD_DATA which I found is handled in extract.cpp ... but that code just doesn't seem to get run.
I also found some calls to RarErrorToDll ... I put the callback there too, nothing.
Any help would be hugely appreciated.
for a bit of context, this is what I was previously doing to catch errors.
bool archiveCorrupt = false;
while((read_header_code = RARReadHeader(archive_data, &header_data)) == 0)
{
process_file_code = RARProcessFile(archive_data, RAR_EXTRACT, m_output_dir, NULL);
if(process_file_code)
{
qDebug() << "Error extracting volume!"
<< header_data.ArcName << " "
<< " with error: " << process_file_code;
archiveCorrupt = true;
break;
}
}
The reason this approach doesn't work is that the error code process_file_code tells you what went wrong, but the archive name in header_data.ArcName is the archive that the file started in, not necessarily where the corruption was. I'm dealing with multi-part archives where one large file will span multiple archives ... so I need to know which archive(s) is corrupt, not just the archive the file started in.
EDIT:
Here is a link to the unrar source code
So I've discovered a place in extract.cpp line 670 that I can place the callback and it does return an error code to my app.
ErrHandler.SetErrorCode(RARX_CRC);
#ifdef RARDLL
Cmd->ErrorCallback(RARX_CRC, Arc.FileName, ArcFileName);
However, this has the same issue as before, where it returns the error at the end of processing the file extracting, rather than at the place where the CRC fails.
If I run the unrar command-line app that you can download from the rarlabs site, it seems to handle it properly and returns the correct error. I can't find text for those errors anywhere in the unrar source, so I can only assume that the unrar source doesn't actually build the unrar app they publish on their site.
Extracting from SL - Cinematic Guitars.part02.rar
... SL - Cinematic Guitars/Cinematic Guitars/Samples/Cinematic Guitars_001.nkx 16%
SL - Cinematic Guitars/Cinematic Guitars/Samples/Cinematic Guitars_001.nkx : packed data CRC failed in volume SL - Cinematic Guitars.part02.rar
I eventually found the answer, after lots of trial and error.
My issue was, I was comparing an old command line version of unrar to the newer source code when looking for the error messages.
The error message has changed in the new source code and is now
packed data checksum error in volume
This is defined in loclang.hpp and called from uiconsole.cpp in the function uiMsgStore:Msg when the error code is UIERROR_CHECKSUMPACKED
This gets called from volume.cpp on line 25
I have added my callback here, and it catches the error perfectly.
I hope this helps someone else if they ever have the misfortune of having to hack unrar source code.

Setting useUnsafeHeaderParsing for C++ WinHttp

I'm trying to reach a web page on an embedded device.
I'm using WinHttp on Win32.
When trying to read response I get error
ERROR_WINHTTP_INVALID_SERVER_RESPONSE
12152
The server response cannot be parsed.
But when I captured with WireShark I can see that response is coming.
So to test I wrote a simple C# program.
GetResponse was throwing exception
The server committed a protocol violation. Section=ResponseHeader
Detail=CR must be followed by LF
So according to below solution I set useUnsafeHeaderParsing to true. And it worked fine.
HttpWebRequestError: The server committed a protocol violation. Section=ResponseHeader Detail=CR must be followed by LF
Since I can't use C# I need to find a way to set useUnsafeHeaderParsing to true for WinHttp with win32 C++
Many thanks
I've briefly looked into the option flags of WinHttpSetOption and found the following entry:
WINHTTP_OPTION_UNSAFE_HEADER_BLOCKING
This option is reserved for internal use and should not be called.
Since the option looks linke an on/off switch I would try to do the following:
BOOL bResult;
BOOL bOption = FALSE;
bResult = WinHttpSetOption(hInternet,
WINHTTP_OPTION_UNSAFE_HEADER_BLOCKING,
&bOption,
sizeof(bOption));
if (bResult == FALSE)
{
/* handle error with GetLastError() */
}
Well but as MSDN says it's reserved for internal use and therefore the function may change in the future (or has already changed in the past). But it's worth a try... Good Luck!
Looks like the name of the option must have changed since then: with the current SDK it's WINHTTP_OPTION_UNSAFE_HEADER_PARSING. Also, I verified (by examining the Assembly code directly) that:
the option must be DWORD-sized
the value of the option doesn't matter, as long as it's nonzero
you can only enable unsafe parsing; trying to disable (by setting the option value to zero) causes an error to be returned
Obviously, since this undocumented, it's subject to change.

Timed Indexed Color sets in CPN Tools that results in Unhandled Exception Error

I am using CPN Tools to model a distributed system. CPN Tools uses CPN ML an extension of SML. The project homepage is: cpntools.org
I started with a simple model and when I try to make a particular indexed color set timed, I get an "Internal error". There is another indexed colorset within my Petri-net model that is timed and works correctly. I am not sure how I can troubleshoot since I don't understand the error message. Could you help me interpret the error message or give me some hints on what I could be doing wrong?
The model is:
http://imgur.com/JUjPRHK
The declarations of the model are:
http://imgur.com/DvvpyvH
The error message is:
Internal error: Compile error when generating code. Caught error.../compiler/TopLevel/interact/evalloop.sml:296.17-296.20../compiler/TopLevel/interact/evalloop.sml:44.55../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
structure CPN`TransitionID1413873858 = struct ... end (* see simulator debug info for full code *)
simglue.sml:884.12-884.43
"
Thank you~
I know this is an old question, but I run in the same problem and wasted too much time on this, so maybe it will help someone else in the future.
I didn't understand exactly the reason for this, but it seems the problem appears when you play with time values on an arch that ends to a transition (I was updating an integer value to the current time, using IntInf.toInt(time())). Now, if I move the code on the outgoing arch of that transition (that is: the one that ends in a place) there is no error.