Ntrip client not receiving RTCM corrections - python

I'm searching for help understanding how to develope a complete and functional NTRIP Client in order to receive RTCM corrections.
I'm using Python 3.4, for now on Windows 7. Searching the net, I found some sample code and I used it to write a basic client. The problem is... it doesn't work.
I have access to a rtk correction service. The service is active and functioning.
This is a snippet of my code.
dummyNMEA = "$GPGGA,143741.356,7839.493,S,07627.626,W,0,00,,,M,,M,,*45"
username = my_username #username for RTCM correction service
password = my_password #password for RTCM correction service
port = 2101 #port for the service
'''Generate an encoding of the username:password for the service.
The string must be first encoded in ascii to be correctly parsed by the
base64.b64encode function.'''
pwd = base64.b64encode("{}:{}".format(username, password).encode('ascii'))
#The following decoding is necessary in order to remove the b' character that
#the ascii encoding add. Othrewise said character will be sent to the net and misinterpreted.
pwd = pwd.decode('ascii')
print("Header sending... \n")
header =\
"GET /mountpoint HTTP/1.1\r\n" +\
"Host my_host\r\n" +\
"Ntrip-Version: Ntrip/1.0\r\n" +\
"User-Agent: ntrip.py/0.1\r\n" +\
"Accept: */*" +\
"Connection: close\r\n" +\
"Authorization: Basic {}\r\n\r\n".format(pwd)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((my_host,int(port)))
s.send(header.encode('ascii'))
print("Waiting answer...\n")
data = s.recv(2048).decode('ascii')
print(data)
s.send(dummyNMEA.encode('ascii'))
data = s.recv(2048).decode('ascii')
print(data)
s.close()
Now, the code is partially funcitoning. The request goes to the rtk server and I am correctly authenticated. I receive the correct answer as from ntrip protocol:
ICY 200 OK
Server: "Server of the mountpoint"
Date: "The date"
After this, I have to send a NMEA GGA sentence, in order to start receiving the RTCM corrections. I created various dummy NMEA sentences with a generator and tested sending them. I send the sentence and.... nothing happens. I receive no answer from the server.
Somebody has some idea? Perhaps I do something wrong when encoding the sentence?
I read that perhaps I should send the NMEA sentence continuosly, but I'm new in Python programming and I am not sure how to do that with sockets.
English is not my mother language, so please excuse my errors :)
Thnak you everyone.

When you are sending the GGA is it a position that has coverage on your rtk correction service? I have done this before, sent dummy positions that are outside the network coverage and nothing was returned, not even an error message, just no corrections.
Cheers,
Steve.

You need to add '\r\n' to the end of the NMEA string.
dummyNMEA = "$GPGGA,143741.356,7839.493,S,07627.626,W,0,00,,,M,,M,,*45\r\n"

You have to create an Header for the NMEA as well.
dummyHeader = \
"Ntrip-GGA: {}\r\n".format(dummyNMEA)
Then you should get an answer.

Related

nfcpy retrieves the URL from a NFC tag. But how do I open the link?

What I want:
I want my Raspberry Pi to act as a NFC-reader that can trigger the URL record from a NFC tag.
My setup is a Raspberry Pi with a PN532 NFC HAT and nfcpy. I am using the example tagtool.py and right now I am able to scan the NFC-tag and then show the URL (+ some extra data)
But I want the system to run the URL which triggers a webhook on IFTTT (which then triggers a playlist on Spotify...)
What I have done so far:
I have used setup.py to install nfcpy and experimented a bit with the commands. But when I run the command
python3 tagtool.py --device tty:S0:pn532 -d nfc.ndef.UriRecord -l
It first returns this
[main] enable debug output for 'nfc.ndef.UriRecord'
[nfc.clf] searching for reader on path tty:S0:pn532
[nfc.clf] using PN532v1.6 at /dev/ttyS0
** waiting for a tag **
and then when I scan one of my NFC tags - which have a URL in URI Record - with the reader I get this message.
Type2Tag 'NXP NTAG213' ID=04EA530A3E4D80
NDEF Capabilities:
readable = yes
writeable = yes
capacity = 137 byte
message = 67 byte
NDEF Message:
record 1
type = 'urn:nfc:wkt:U'
name = ''
data = b'\x04maker.ifttt.com/trigger/Playlist_022/with/key/bVTin_XXEEEDDDDEEEEEE'
[main] *** RESTART ***
[nfc.clf] searching for reader on path tty:S0:pn532
[nfc.clf] using PN532v1.6 at /dev/ttyS0
** waiting for a tag **
As you can see the URL is right there under data (+b\x04 but without https:\ but I guess thats quite easy to change). So basically I just need to trigger it.
I read somewhere that I could use curlify so I have used the command 'pip3 install curlify' and made some changes to tagtool.py.
The original tagtool.py (which I believe is the most important part for what I am trying to do) looks like this
if tag.ndef:
print("NDEF Capabilities:")
print(" readable = %s" % ("no", "yes")[tag.ndef.is_readable])
print(" writeable = %s" % ("no", "yes")[tag.ndef.is_writeable])
print(" capacity = %d byte" % tag.ndef.capacity)
print(" message = %d byte" % tag.ndef.length)
if tag.ndef.length > 0:
print("NDEF Message:")
for i, record in enumerate(tag.ndef.records):
print("record", i + 1)
print(" type =", repr(record.type))
print(" name =", repr(record.name))
print(" data =", repr(record.data))
In the new tagtool2.py I have added this to the start of the document
import curlify
import requests
And then I have added this line
response = requests.get("https://repr(record.data)")
print(curlify.to_curl(response.request))
Which means it looks like this. And this is probably wrong in several ways:
if tag.ndef:
print("NDEF Capabilities:")
print(" readable = %s" % ("no", "yes")[tag.ndef.is_readable])
print(" writeable = %s" % ("no", "yes")[tag.ndef.is_writeable])
print(" capacity = %d byte" % tag.ndef.capacity)
print(" message = %d byte" % tag.ndef.length)
if tag.ndef.length > 0:
print("NDEF Message:")
for i, record in enumerate(tag.ndef.records):
print("record", i + 1)
print(" type =", repr(record.type))
print(" name =", repr(record.name))
print(" data =", repr(record.data))
response = requests.get("https://repr(record.data)")
print(curlify.to_curl(response.request))
Because when I try to trigger the URL with a NFC tag I get this message:
Type2Tag 'NXP NTAG213' ID=04EA530A3E4D80
NDEF Message:
record 1
type = 'urn:nfc:wkt:U'
name = ''
data = b'\x04maker.ifttt.com/trigger/Metal1/with/key/bVTin_XXEEEDDDDEEEEEE'
[urllib3.connectionpool] Starting new HTTPS connection (1): repr(record.data):443
[nfc.clf] HTTPSConnectionPool(host='repr(record.data)', port=443): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0xb579a650>: Failed to establish a new connection: [Errno -2] Name or service not known'))
Can anyone tell me what I am doing wrong? And if curlify is the right way to go?
What you are doing wrong is that the data stored in the NDEF message is encoded, you cannot just open a connection using the raw data you have to decode it first using the correct type. (as the encoded value has a Hex number in it)
It is also encoded in utf-8 so Python treats it as bytes not as a string type object.
So the type says it is a URI record type as you used 'nfc.ndef.UriRecord' (Don't know why call it urn instead)
So the Hex number \x04 means https://
Unfortunately I don't think anybody has written a decoder method for the NFC Uri specification only encoders.
Here is a link full spec for the NDEF URI record type
once you have replaced the Hex character in the data with the correct decoded value you will get the URL https://maker.ifttt.com/trigger/Metal1/with/key/bVTin_XXEEEDDDDEEEEEE
a simple example (where a stores the value instead of record.data)
import re
a = b'\x04maker.ifttt.com/trigger/Metal1/with/key/bVTin_XXEEEDDDDEEEEEE'
a_text = a.decode('utf-8')
x = re.sub('\x04', 'https://', a_text)
print(x)
requests.get(x)
Then you can use requests.get() on the decoded value
This turned out to be the simple but good solution for my needs.
if tag.ndef:
if tag.ndef.length > 0:
#print("NDEF Message:")
for i, record in enumerate(tag.ndef.records):
print(record.uri)
response = requests.get(record.uri)
print(curlify.to_curl(response.request))
I started out with a way more complicated solution. I am keeping it here if anybody runs into similar problems.
Since the first take, I have cleaned out some of the print() lines as well, and I know I can clean out some more lines, but I am keeping them here to make it easier to see whats happening.
Its especially worth noticing the y variable. I was left with an almost perfect URL, but I kept getting errors because of an extra ' at the end of the URL.
if tag.ndef:
if tag.ndef.length > 0:
for i, record in enumerate(tag.ndef.records):
print(repr(record.data))
print(str(record.data))
org_string = str(record.data)
mod_string = org_string[6:]
y = mod_string.rstrip(mod_string[-1])
w = "https://"
print(mod_string)
print(y)
print(w)
response = requests.get(w + y)
print(curlify.to_curl(response.request))
The code can be improved, but it works and it gives me this message and - more important - it triggers the URL on the NFC tag (I have scrambled the IFTTT webhook).
Type2Tag 'NXP NTAG215' ID=04722801E14103
b'\x04maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao'
b'\x04maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Aoo'
maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao'
maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao
https://
[urllib3.connectionpool] Starting new HTTPS connection (1): maker.ifttt.com:443
[urllib3.connectionpool] https://maker.ifttt.com:443 "GET maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao HTTP/1.1" 200 69
curl -X GET -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Connection: keep-alive' -H 'User-Agent: python-requests/2.21.0' https://maker.ifttt.com/trigger/python_test/with/key/bEDoi_gUT5x5uDsdsaR3Ao
[main] *** RESTART ***
[nfc.clf] searching for reader on path tty:S0:pn532
[nfc.clf] using PN532v1.6 at /dev/ttyS0
** waiting for a tag **

Trying to spoof an email address

I'm sure this has been asked, but I can't find anything to get mine to work.
I'm trying to send follow up emails to clients, but I want to spoof the email address so the from address is for my coworker. I read somewhere online that the from address in the header is simply a text field that can be edited, but I still cannot send the email.
import smtplib
email_to = '*****#gmail.com'
username = '*******#outlook.com'
password = '*********'
other_email = '*******#outlook.com'
mail = smtplib.SMTP('Outlook.com', 25)
mail.ehlo()
mail.starttls()
mail.login(username,password)
header = ('To:' + email_to + '\n' +'From: ' + other_email + '\n'
+ 'Subject: Python Project Test\n')
message = (header +
'\n\n This is a test message generated from a Python script. \n\n')
mail.sendmail(username, email_to, message)
mail.close()
print("Email sent successfully.")
I know this can be done, but can someone point me in the right direction? Is there any way for me to disguise my name in the from field as that of the email that is supposed to get this?
===================================
Also, for the sake of completion, here is the error I got:
Traceback (most recent call last):
File "C:\Users\*****\Desktop\email outlook.py", line 16, in <module>
mail.sendmail(username, email_to, message)
File "C:\Users\*****\AppData\Local\Programs\Python\Python36-32\lib\smtplib.py", line 887, in sendmail
raise SMTPDataError(code, resp)
smtplib.SMTPDataError: (550, b'5.7.60 SMTP; Client does not have permissions to send as this sender')
I was hoping if there was a way to make the other_name an alias of the username.
The very short version: This isn't going to work.
Once upon a time, it was reasonably possible to do what you are asking to do. In the old days, when the internet was small and spam did not exist, the receiving server would just trust you. You could just connect to mail.example.com and say you were sending on behalf of someone#example.org, and example.com would just believe you.
But those days are over and done with. Nowadays, SMTP servers are a lot less trusting. So let's go through the problems with your approach:
You are trying to route your email through outlook.com. outlook.com knows perfectly well that you are username and not other_email. If you want to send email as other_email, you need to authenticate as other_email.
You could connect directly to gmail.com, claim to be outlook.com, and try to send the email that way. But Gmail knows you're not outlook.com, because you're missing these things. So it will likely flag your message as spam, bounce it, or even* accept it and then discard it entirely.
You could fix (1) by changing your code, but because of (2), there's little point.
* I do not work on the Gmail team. I am guessing how Gmail would respond to this based solely on public information about how modern email servers are typically configured. YMMV.

Scapy: How to manipulate Host in http header?

I wrote this piece of code to get http header and set Host:
http_layer = packet.getlayer(http.HTTPRequest).fields
http_layer['Host'] = "newHostName"
return packet
After running the afforementioned code,the new host name has been set correctly, but the problem is that when I write the packet in pcap file, I still see the previous host in http fields,
Is there an absolute way to manipulate http_layer['Host'] ?
Any help would be appreciated.
Regards.
After all, found the answer.
The key is that scapy firstly parses HTTP Request and shows the dict of its fields. So when we try to assign a new field like Host, it changes the Host which it has already parsed and does not change the original field value.
So, this is the way to modify Host or any other respective fields:
str_headers = pkt['HTTP']['HTTP Request'].fields['Headers']
str_headers = str_headers.replace('Host: ' + pkt['HTTP']['HTTP Request'].fields['Host'], 'Host: ' + new_val)
pkt['HTTP']['HTTP Request'].fields['Headers'] = str_headers
return pkt

XMPP on Python responds to Gtalk but not to Hangouts

I was trying out a Gtalk bot using python and XMPP.
When I ping the bot using iChat application, I could receive the response back.
But when I ping using Hangouts, I am not able to receive the response message. But still I could see my message at server side logs.
# -- coding: utf-8 -
import xmpp
user="BOTUSERNAME#gmail.com"
password="PASSWORD"
server=('talk.google.com', 5223)
def message_handler(connect_object, message_node):
us = str(message_node.getFrom()).split('/')[0]
if us == 'REALUSERNAME#gmail.com':
us = us[0:4]
print str(message_node)
message = "Welcome to my first Gtalk Bot :) " + us
s= str(message_node.getBody()).replace("\n", "\t")
if s <> 'None' :
print "MESSAGE: " + s
connect_object.send(xmpp.Message( message_node.getFrom() ,message))
jid = xmpp.JID(user)
connection = xmpp.Client(jid.getDomain())
connection.connect(server)
result = connection.auth(jid.getNode(), password )
connection.RegisterHandler('message', message_handler)
connection.sendInitPresence()
while connection.Process(1):
pass
Is this something to do with gtalk moving out of XMPP support?
My Bot is still able to receive message but my Hangouts Application is not receiving response
I was able to fix the issue.
You need to add typ = 'chat' attribute to xmpp.Message
connect_object.send(xmpp.Message( message_node.getFrom() ,message, typ='chat' ))
Now my gTalkBot reponds to my message from hangouts & ichat client.
Many thanks to this stack overflow answer
If you have extended sleekxmpp.ClientXMPP, then you can ensure messages are sent to hangouts by added mtype='chat' to send_message()
bot = MyBot([...])
bot.send_message(mto=JID,mbody=MSG,mtype='chat')

Python Socket message are truncated

I created a bot which connect to the chan through socket like this
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((network,port))
irc = ssl.wrap_socket(socket)
Then i send some message when some actions are triggered, this works quite well but there is one messsage which is truncated, and my script don't return any error. Here is the code of this message :
def GimmeUrlInfos(channel,message):
link = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_#.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', message)
response = urllib2.urlopen(link[0])
html = BeautifulSoup(response.read())
urlTitle = html.find('title')
irc.send("PRIVMSG %s Link infos:" % (channel) + urlTitle.contents[0] + "\r\n" )
The script look in the message if there is a link inside, if yes beautifulSoup get the title of the HTML page. So it's returns something like: Link infos: THis is the Title of the Webpage you give in your message.
But it only returns
Link
at the channel. Is there some limitations or something ?
Here's my next guess, now that you've given us a little more information:
Your string looks like this:
PRIVMSG #mychannel Link infos: Title of Page\r\n
In IRC, arguments are split on spaces, except that an argument that starts with a colon can include spaces, and runs to the end of the line. So, your target is #mychannel, your message is Link, and the whole rest of the line is a bunch of extra arguments that are ignored.
To fix this, you want to send:
PRIVMSG #mychannel :Link infos: Title of Page\r\n
So, change your code like this:
irc.send("PRIVMSG %s :Link infos:" % (channel) + urlTitle.contents[0] + "\r\n" )
For more details on how messages are formatted in RFC, and on the PRIVMSG command, see 2.3.1 Message format in 'pseudo' BNF and 4.4.1 Private messages in RFC 1459.
It's hard to tell from your question, but I think you wanted to send something like this:
PRIVMSG #mychannel Link infos: Title of Page\r\n
… and actually only sent something like this:
PRIVMSG #mychannel Link
One possible explanation of this is that socket.send and SSLSocket.send don't necessarily send the entire string you give it. That's why they returns a number of bytes sent. If you want to block until it's able to send the whole string, use sendall instead.

Categories