GQ Electronics Technical Support Forum Active Users: / Visits Today:
Highest Active Users:
GQ Electronics Technical Support Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 GQ Electronics Forums
 2.GQ Geiger Muller Counter
 Logging to server: what return value is expected?

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

Screensize:
UserName:
Password:
Format Mode:
Format: BoldItalicizedUnderlineStrikethrough Align LeftCenteredAlign Right Horizontal Rule Insert HyperlinkInsert EmailInsert Image Insert CodeInsert QuoteInsert List Spell Checker
   
Message:

* HTML is OFF
* Forum Code is ON
Smilies
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Clown [:o)]
Black Eye [B)] Eight Ball [8] Frown [:(] Shy [8)]
Shocked [:0] Angry [:(!] Dead [xx(] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

   Insert an Image File
Check here to include your profile signature.
    

T O P I C    R E V I E W
mojo66 Posted - 06/17/2021 : 01:41:11
I'm writing a PHP script to run on my own http server, as a replacement to log2.asp. Everything works fine, but the device, a 500+, displays "Link server failed" or "WiFi data send failed". Does it expect a particular response from the http server?

Here is an example from access.log, first one is from using "Test Connection", the second is a regular periodic send.


192.168.1.240 - - [17/Jun/2021:11:28:48 +0200] "GET /geiger.php?AID=1&GID=1&CPM=22&ACPM=23.66&uSV=0.14 HTTP/1.1" 200 117
192.168.1.240 - - [17/Jun/2021:11:28:58 +0200] "AT+CIPCLOSE" 400 226
192.168.1.240 - - [17/Jun/2021:11:29:52 +0200] "GET /geiger.php?AID=1&GID=1&CPM=30&ACPM=23.66&uSV=0.19 HTTP/1.1" 200 117
192.168.1.240 - - [17/Jun/2021:11:30:12 +0200] "-" 408 -
26   L A T E S T    R E P L I E S    (Newest First)
EmfDev Posted - 09/20/2021 : 09:42:42
That is unfortunate, we will check this one to see if we can fix this issue and will try to add a port selection on the firmware.
ullix Posted - 09/19/2021 : 00:25:59
Indeed one can send AT commands to the counter via the Serial interface, which are internally redirected to the ESP8266. So I implemented it in GeigerLog.

I can now even set a port different from 80 with the AT command:
quote:
<AT+CIPSTART="TCP","10.0.0.20",8000>>

but there is no benefit, because the bug in the code is still resulting in a malformed, "Unsafe" request, preventing any decent server from accepting this request!

Issuing AT command '<AT+GMR>>' results in this answer:
quote:
'AT+GMR\r\r\nAT version:1.2.0.0(Jul 1 2016 20:04:45)\r\nSDK version:1.5.4.1(39cb9a32)\r\nAi-Thinker Technology Co. Ltd.\r\nDec 2 2016 14:21:16\r\nOK\r\nWIFI DISCONNECT\r\nWIFI CONNECTED\r\nWIFI GOT IP\r\n\n'
This tells me the counter's firmware uses the AT code from July 1, 2016, more than 5 years old, and, as we see, outdated!

Thus, at present there is no value using these AT commands.

Now I went and made my local Apache server "Unsafe" as described before, to allow the counter talk to this server on port 80. Of course only my local one, because I surely don't want any security issues on my public servers! Then I programmed some php code to forward the counter's request, converted into a safe form, to GeigerLog. GeigerLog has now a full web server built into it, and can read, serve, and interpret requests submitted by WiFi. (This version is not released yet; and, by the way, GeigerLog also has a WiFi client to interact with any device acting as a server.)

The next picture shows an example 2h segment out of an overnight run, generated with a GMC-500+ counter. Light blue is Tube#1 via a regular USB cable with a 1 sec cycle time of GeigerLog, brown is CPM from the WiFi output of the counter with its fastest setting of a 1 min "Period".



The CPM averages of the data shown are:

          [Unit]      Avg ±StdDev     Variance          Range  
CPM1st  : [CPM]    25.670 ±5.14         26.454         9 ... 44
CPM3rd  : [CPM]    25.414 ±5.42         29.346        12 ... 39
This is the same within statistics.

Obviously it can be made to work. But is seems absurd that I have to employ a full blown Apache server just to make a bug correction and port conversion!
EmfDev Posted - 09/17/2021 : 10:30:28
@ullix, you can send commands to the device like <AT>> and get the ESP8266 response. Similar to <GETVER>>.
If you send <AT>> to your unit, it will send it to the module, then read the response and will send it back to the terminal.
Any commands starting with AT will be sent directly to the WiFi Module. And any response that comes from it will be sent to terminal.
I dont think it is possible to communicate with it from the outside unless you have a standalone module and just talk to it directly.

@the_mike, that would be a good idea, I will send it to support and see what they think.
the_mike Posted - 09/17/2021 : 05:26:49
Hi @EmfDev

I'm mostly a quiet reader here now, but this issue here...
Don't you think it would be wiser to switch to an opensource-software for the counters?

This forum shows so many open issues which are only firmware-related, while the hardware would be capable of doing it..?

Especially here - I mean - c'mon, with the fixed port 80; not one single server-admin would allow a configuration for a publicly available sever to be configured the way it needs to be - bc your firmware-writers hardcoded port 80 into it?!
ullix Posted - 09/17/2021 : 00:02:06
@EmfDev: These AT commands are intended to be send to the ESP8266 by the C (C++?) code of your firmware. Can they be send to the counter from "outside"?

If so, how?
EmfDev Posted - 09/16/2021 : 10:48:20
Thank you for 5-Star quality testing and analysis @ullix we appreciate all your hard work, unfortunately, we are not able to test it.

Here is more of the protocol. You can do it by sending these commands to your device and check for OK in the response for each command. Check to see if there are some garbage being sent.

AT+CIPSTART="TCP",WEBSITE,80\r\n
AT+CIPMODE=1\r\n
AT+CIPSEND\r\n
GET /URL?AID=USERID&GID=COUNTERID&CPM=CPM&ACPM=ACPM&uSV=uSV HTTP/1.1\r\nHost: WEBSITE\r\nConnection: close\r\nAccept: */*\r\n\r\n

...wait for server reply.
ullix Posted - 09/16/2021 : 00:41:30
I think I have found the problem, which turns out to be a combination of a bug in the firmware plus a security issue at the Microsoft server.

This problem is not about finding the proper answer to be given by the server to the counter, but instead about the counter asking a proper request!

The key problem is that the Geiger counter forms a http request which is not fully in accordance with the IETF (Internet Engineering Task Force) rules: https://datatracker.ietf.org/doc/html/rfc7230#section-3.5

Specifically, the counter concludes its http request with a LF-only, while it should have send a CRLF.

A Microsoft ASP server accepts this, while an Apache server rejects it as a security issue (https://httpd.apache.org/security/vulnerabilities_24.html, scroll to: "important: Apache HTTP Request Parsing Whitespace Defects (CVE-2016-8743)")

An Apache server can be modified to accept such ill-formed requests by inserting
HttpProtocolOptions Unsafe
(the default is "HttpProtocolOptions Strict") into the Apache configuration file
apache2.conf


I tested this on my local Apache server, and it works. The GMC-500+ can now communicate with the Apache server at port 80. As long as the server sends a status 200 and not a 400, it needs nothing but an "ERR0" in the answer, but an "OK.ERR0", or even an "ERR0blahblah" does also do!

Though I am wondering how many server admins will enjoy explicitly converting their servers with worldwide access into an "Unsafe" condition?

One may assume that even Microsoft will eventually update their servers into a secure state. This would mean that all existing GQ counters with WiFi will then no longer be able to access the gmcmap website.

I suggest it is time to prepare for a firmware update of all WiFi counters. And while you are at it, provide an option to also select a optional Port!

Which may be a bit of a challenge, as each and every counter needs an update specific to its serial number! :-// Maybe another thing to reconsider!

This analysis comes for free. But you are also free to send a reward!

mojo66 Posted - 09/15/2021 : 14:58:19
Perhaps the device only sends garbage that leads to the server responding with 400 if it doesn't receive the "OK.ERR0" from the server. I'm pretty sure that if the server responds with "OK.ERR0" then the device is happy and no 400 code will be generated.

It's a weird protocol though and focusing on Microsoft crap only makes the situation worse. If they'd open-source their firmware, the community could step in and support proper operating systems. But those narrow-minded people will always argue that supporting Microsoft is enough. It's a slow process.
ullix Posted - 09/15/2021 : 00:59:43
@EmfDev: Thanks. If I am not mistaken the "AT" command is what you send to the ESP8266 chip in your firmware code. The ESP8266 usually works fine in the systems I have seen.

However, in the case of your counter this results in a request to web servers which is false. Tested on my Apache servers - local and on the web - it always results in these servers' answers of: "400 Bad request". Consistent with that, Apache's error logs say: "AH00566: request failed: malformed request line".

"Malformed" may be caused by a variety of things, most often by illegal characters in the TCP request or any other distortion of it. Your Microsoft ASP server for gmcmap may be programmed to cope with that, but the rest of world servers simply reject such a request.

Can you tell us how the ASP server has been adapted to a "malformed" request line?



EmfDev Posted - 09/14/2021 : 10:14:51
Hello, sorry as I thought I had posted an answer before. The website and URL from the device does matter and it can send to other servers. However looks like the port number cannot be changed. The protocol starts by connecting to server by AT+CIPSTART="TCP","WEBSITE",80. Then later on sends GET /URL?AID=USERID&GID=COUNTERID&CPM=CPM&ACPM=ACPM&uSV=uSV with Host: WEBSITE.
ullix Posted - 09/14/2021 : 01:37:30
It's been a while that I had asked the questions in Reply#15, and I am somewhat surprised to have not gotten any answer!

May I conclude that all my conclusions are true, and the GMC counters are explicitly designed to work with nothing but the GMCmap web site, and despite suggestions to the contrary, cannot be used to work with any other web server?
ullix Posted - 09/02/2021 : 01:26:38
This seemed such a trivial task that I became curious enough for some more tests. My conclusion:

The problem is not, what the server should answer on a contact by a counter, the question is why the counter can't even make contact to any web address, unless the web address is "www.gmcmap.com".

@ZLN and @EmfDev:

Is it true that the counter cannot interact with anything, unless it is "www.gmcmap.com"?
If it is not true, then how can one redirect the counter to a different web site?

Is it true that the counter cannot handle the setting of a port? E.g. I cannot even use "www.gmcmap.com:80". When I do, the counter fails to make a connection.
If it is not true, how can a specify a port number?

Since there is an option in the counter to configure the web server, is it true that this is only a fake option, and the address "www.gmcmap.com" is actually hardcoded internally, and anything I enter is ignored?
If it is not true, what different addresses are accepted?




ullix Posted - 09/02/2021 : 00:15:28
??? really, is that the insight: when I run a completely different framework, it does not matter what code is used on another framework?
mojo66 Posted - 08/31/2021 : 15:06:32
jlam is running his own web server, and therefore log2.asp is useless to him.

This whole thread is about running your own web server.
ullix Posted - 08/31/2021 : 01:28:15
quote:
log2.asp is irrelevant.

I am afraid this is absolutely NOT the case!

Do a simple test: Use a correct user ID and a correct counter ID, and enter a valid url in any browser. For privacy I use UUU for user and CCC for counter. Of course, I did the calls with my real IDs.

Using the correct "log2.asp":
h**p://www.gmcmap.com/log2.asp?AID=UUU&GID=CCC&CPM=15&ACPM=13.2&uSV=0.075
results in response: '\r\n<!--               sendmail.asp-->\r\n\r\nOK.ERR0'

while using the wrong "log.asp"
h**p://www.gmcmap.com/log.asp?AID=UUU&GID=CCC&CPM=15&ACPM=13.2&uSV=0.075
results in response: 'Error 10.ERR3'

Obviously clearly different responses!

The extension ".asp" indicates that the website is built with "Active Server Pages". Which, to state it simply, is Microsofts's version of php.

The "log.asp" and "log2.asp" are two different files on the server coding the actions and output of the server, and you get the same result ONLY if the two files are identical (symlink, hardlink) or have the exact same content. But see above, they are different files and have different content!

You didn't say what the filename of your php code is; I suppose this is "index.php". In this case you don't have to specify it in the url, because it is called automatically if not given. But if your file were "index2.php", you'd have to explicitly name it!

Adding the "OK" response to your script is very easy. Just add these two lines to the end of your php section:
http_response_code(200);
echo("OK.ERR0");
and the webpage looks like you want it. However, this would be wrong! To see why, view the page source. It is:
<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
OK.ERR0 </body>
</html>
You are creating a full web page, but this is not what "log2.asp" sends. Instead, your complete file content should look like this:
<?php
$date = date("U");
$cpm = htmlspecialchars($_GET["CPM"]);
$usv = htmlspecialchars($_GET["uSV"]);
$file = 'geiger.text';
$output = $date . ',' . $cpm . "," . $usv . PHP_EOL ;
file_put_contents($file, $output, FILE_APPEND | LOCK_EX);
http_response_code(200);
echo("\r\n<!--               sendmail.asp-->\r\n\r\nOK.ERR0");
?>
Note that there is no separate html code! Since I put this into file "index2.php", I need to call it (on my local server) like this:
h**p://localhost/index2.php?CPM=22&uSV=0.33

and on Firefox the page source now has the desired layout:
<!--               sendmail.asp-->

OK.ERR0
Keep in mind that there is no error checking in your php code; it will always respond with ok, even when it fails!
mojo66 Posted - 08/30/2021 : 17:11:34
log2.asp is irrelevant. I don't know why ullix and EmfDev insist on it. You can have any URL you like, especially when using the app that allows use of AT commands.

The problem is that you can't have any Port you like because port 80 is hardcoded. That means you have to give your webserver elevated privileges (at least on a professional OS. Yes that excludes Windows). The firmware is closed source, so we are at the mercies of the devs etc p.p.

I gave up on it, I don't have the time nor nerves to discuss why the firmware of an item that I own should be open source. It's simple: I won't recommend any products by GQ.

For completeness, I had this PHP script running for a while on port 80:


<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
<?php 
$date = date("U");
$cpm = htmlspecialchars($_GET["CPM"]);
$usv = htmlspecialchars($_GET["uSV"]);
$file = 'geiger.text';
$output = $date . ',' . $cpm . "," . $usv . PHP_EOL ;
file_put_contents($file, $output, FILE_APPEND | LOCK_EX);
?>
 </body>
</html>


It did work but that stupid error message would come up on the GMC on every transmit, and it had to run on port 80. Note that I don't know anything about PHP I just looked up the pieces I needed on some PHP reference site. Perhaps someone can come up with a patch that would reply with the "OK.ERR0" required to make the GMC happy.

But the PHP code was for testing anyway, I don't want to run Apache just to run 10 lines of PHP. Hence I've hacked together a piece of C code that basically does the same feel free to do with it what you like:


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include <netinet/in.h>
#include <sys/socket.h>
#import <arpa/inet.h>

#include <CoreFoundation/CoreFoundation.h>

void usage(void);
void callback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info);

int main(int argc, const char * argv[]) {

	int port, ch;
	char ofd; // TODO: set proper default path

	 port = 60999; // TODO: figure out a good default port
	
	 while ((ch = getopt(argc, argv, "p:o:")) != -1) {
		 switch (ch) {
			 case 'p':
				 port = atoi(optarg);
				 break;
			 case 'o':
				 ofd = open(optarg, O_APPEND);
			 case '?':
			 default:
				 usage();
		 }
	 }
	 argc -= optind;
	 argv += optind;

	// create socket address
	struct sockaddr_in	addr;
	socklen_t addrLen = sizeof(addr);
	memset(&addr, 0, addrLen);
	
	addr.sin_len			= addrLen;
	addr.sin_family 		= AF_INET;
	addr.sin_port			= htons(port);
	addr.sin_addr.s_addr	= INADDR_ANY;

	// create socket
	CFDataRef sockData			= CFDataCreate(kCFAllocatorDefault, (UInt8 *)&addr, addrLen);
	CFSocketSignature sockSig	= { PF_INET, SOCK_STREAM, IPPROTO_TCP, sockData };
	CFSocketRef sock			= CFSocketCreateWithSocketSignature(kCFAllocatorDefault, &sockSig, kCFSocketAcceptCallBack, callback , NULL);
	CFRelease(sockData);

	// add socket to current runloop
	CFRunLoopSourceRef sockRRL	= CFSocketCreateRunLoopSource(kCFAllocatorDefault, sock, 0);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), sockRRL, kCFRunLoopDefaultMode);
	CFRelease(sockRRL);
	
	printf("Listening to port %i.\n", port);

	// run forever
	CFRunLoopRun();
	return 0;
}

void usage(void) {
	
}

void callback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
	if (type != kCFSocketAcceptCallBack) {
		printf("WARNING: Received unexpected callback type %lu.\n", type);
		return;
	}
	
	// for kCFSocketAcceptCallBack:
	// address = sockaddr_in of the remote address to which s is connected
	// data = a pointer to a CFSocketNativeHandle
	
	// get host address (just for info)
	struct sockaddr_in *host = (struct sockaddr_in *) CFDataGetBytePtr(address);
	char *hostAddr = inet_ntoa(host->sin_addr);
	printf("Host %s connected.\n", hostAddr);
	
	// create read/write streams from socket
	CFReadStreamRef readStream;
	CFWriteStreamRef writeStream;
	CFSocketNativeHandle *h = (CFSocketNativeHandle*) data;
	CFStreamCreatePairWithSocket(kCFAllocatorDefault, *h, &readStream, &writeStream);
	
	// read into buffer
	int bufSize = 1024;
	UInt8 buf[bufSize];
	memset(buf, 0, bufSize);

	CFReadStreamOpen(readStream);
	CFIndex numBytesRead = CFReadStreamRead(readStream, buf, bufSize);

	printf("Read %li bytes: %s\n", numBytesRead, buf);

	CFReadStreamClose(readStream);
	CFRelease(readStream);
	
	// write response
	UInt8 response[] = "OK.ERR0";
	CFIndex respLen = 8;

	CFWriteStreamOpen(writeStream);
	CFIndex bytesWritten = CFWriteStreamWrite(writeStream, response, respLen);

	printf("Wrote %li bytes.\n", bytesWritten);
	
	CFWriteStreamClose(writeStream);
	CFRelease(writeStream);
	
	// write data to disk
}


I stopped work on it after I found out that the port is hardcoded. But the code does receive the data and replies properly.
EmfDev Posted - 08/26/2021 : 09:26:27
quote:
Originally posted by jlam

Thanks for the reply!

Ive updated my server script with the hidden elements, but now getting
192.168.1.249 - - [16/Aug/2021 13:56:24] "GET /log?AID=1&GID=1&CPM=23&ACPM=14.70&uSV=0.15 HTTP/1.1" 200 -
192.168.1.249 - - [16/Aug/2021 13:56:25] code 400, message Bad request syntax (AT+GSLP=0)
192.168.1.249 - - [16/Aug/2021 13:56:25] "AT+GSLP=0" 400 -


Have you had these responses as well?

Cheers



The get should use log2.asp instead of just log. It is in the example "GET /log?AID=1&GID=1&CPM=23&ACPM=14.70&uSV=0.15 HTTP/1.1" ==> "GET /log2.asp?AID=1&GID=1&CPM=23&ACPM=14.70&uSV=0.15 HTTP/1.1"
jlam Posted - 08/26/2021 : 03:23:08
Hey,

Thanks for your reply. This is just a listener I have running on one of my linux boxes. Those are the replies I get once the GMC submits a log result to it. I'm not sure using log2.asp is relevant, for example mojo66 uses geiger.php on his box.
ullix Posted - 08/17/2021 : 00:23:58
@jlam You get a code 400 when the server receives an invalid request from a client, i.e. you are sending the wrong thing! Make sure to really use log2.asp followed by the data string !

See the valid data examples in my post above.

What is this "AT+GSLP=0" intended for? I know it as a deep sleep command for an ESP microchip. Doesn't look relevant for dealing with the gmcmap server? I hope the gmcmap server does not respond to it?
EmfDev Posted - 08/16/2021 : 09:58:45
hi jlam, maybe try log2.asp
jlam Posted - 08/16/2021 : 05:58:17
Thanks for the reply!

I've updated my server script with the hidden elements, but now getting
192.168.1.249 - - [16/Aug/2021 13:56:24] "GET /log?AID=1&GID=1&CPM=23&ACPM=14.70&uSV=0.15 HTTP/1.1" 200 -
192.168.1.249 - - [16/Aug/2021 13:56:25] code 400, message Bad request syntax ('AT+GSLP=0')
192.168.1.249 - - [16/Aug/2021 13:56:25] "AT+GSLP=0" 400 -


Have you had these responses as well?

Cheers
ullix Posted - 08/15/2021 : 23:36:18
You can look at the server responses by using GeigerLog and its Map function (menu: Web -> Update Radiation World Maps ...).

And you could also send commands directly from a browser. From the GeigerLog code (IDs are fake):
Followings are valid data submission examples:
        h**p://www.GMCmap.com/log2.asp?AID=0230111&GID=0034021&CPM=15&ACPM=13.2&uSV=0.075
        h**p://www.GMCmap.com/log2.asp?AID=0230111&GID=0034021&CPM=15&ACPM=0&uSV=0
        h**p://www.GMCmap.com/log2.asp?AID=0230111&GID=0034021&CPM=15&ACPM=0&uSV=0
        h**p://www.GMCmap.com/log2.asp?AID=0230111&GID=0034021&CPM=15&ACPM=13.2
        h**p://www.GMCmap.com/log2.asp?AID=0230111&GID=0034021&CPM=15

Be aware that the server is returning some hidden code; look into the webpage source to see:
# possible gmcmap server responses:
    #   on proper credentials:                    b'\r\n<!--  sendmail.asp-->\r\n\r\nWarrning! Please update/confirm your location.<BR>OK.ERR0'
    #   on wrong credentials:                     b'\r\n<!--  sendmail.asp-->\r\n\r\nError! User not found.ERR1.'
    #   on proper userid but wrong counterid:     b'\r\n<!--  sendmail.asp-->\r\n\r\nError! Geiger Counter not found.ERR2.'
    #   something wrong in the data part of URL:  b'\r\n<!--  sendmail.asp-->\r\n\r\nError! Data Error!(CPM)ERR4.'


Not sure how the 500 responds to the hidden code. Note that the "OK" might be preceded by a warning!

jlam Posted - 08/15/2021 : 14:14:21
Hey! Mine is really not happy with that response, could you please share your php script?

Thanks :)
mojo66 Posted - 07/19/2021 : 06:38:02
quote:
Originally posted by EmfDev

Hi mojo66, I think it is OK.ERR0



I can confirm that replying with "OK.ERR0" does indeed make my GMC-500+ happy. Thanks!
EmfDev Posted - 06/28/2021 : 09:48:59
Hi mojo66, I think it is OK.ERR0
mojo66 Posted - 06/21/2021 : 21:07:27
So what should the http-server reply to make the 500+ happy?

GQ Electronics Technical Support Forum © Copyright since 2011 Go To Top Of Page
Generated in 0.09 sec. Snitz's Forums 2000