pyserial: How is data being read? - python

I am trying to setup a simple program to read from COM port on my windows. It is connected to a CAN bus(USB interface). I set up the serial configs correctly and know that the port is open. However I am unable to understand the output read.
Here is what I have:
>>> ser.write('v')
1L
>>> ser.write('0x7f3')
5L
>>> ser.write('0x7e1300323f351')
15L
WHat are the 1L, 5L and 15L? Some length of bytes read? How can I see what data is really being received then?
I also tried r= ser.read() and then tried to display it by typing print r.decode("hex")
thanks
EDITED:
I have also used the RealTerm Software to perform sanity check. I have send a "V" and it returns a version string. However I tried the same from my python program( ser.write("V"). I see nothing when I print the response got from read(). Please help

Related

Is there some special encoding required when sending ASCII commands over Serial (USB-RS232) port in Python3.8?

Firstly, I have also researched an seen that this question is answered alot of places, but the answers don't work for me.
I am trying to send ASCII command over serial port to a PCBA and then attempting to receive the response.
HW setup:
Computer
USB-RS232 Cable
PCBA
SW:
Python 3.8
I have sent commands over RS232 terminals (realterm) and they work perfectly (LED turns on) but can't implement the same with python. The command in question is "led_r_on".
And yes, I get "COM5 is open" prompt, meaning COM5 is alive.
Thanks for helps!
code as follows:
import serial
import time
from time import sleep
from serial import Serial
port = 'COM5'
baud = 115200
ser = serial.Serial(port, baud, timeout=2)
if ser.isOpen():
print(ser.name + ' is open...')
sleep(1)
ser.write(b'led_r_on')
print(ser.readline(1000))
Since you didn't give any information on the pcba you are using. I will just assume, that you are missing some kind of end delimiter in your bytesequence. Now there are many ways of ending a transmission over serial. The most frequent ones I ran across are these two:b'led_r_on\r\n' or just b'led_r_on\n'. Try changing your bytes in the ser.write() function to this. If that does not work you might need to use this: b'led_r_on\x04' this will send the EOT (End of Transmission) ASCII character. But I don't think this will be needed.

Parse Data received from Pyserial read into string

I am reading data from a serial port using python (pyserial) I am able to read the data but when I try using it, it seems like this $*%\xff\x06$*%\xff\x02 referred to few resources on stack overflow and found that it needs to be decoded, I tried decoding it to ascii using processed = (binascii.b2a_qp(raw))using the binascii library but received the following output $*%=FF=00$*%=FF=08 I have also tried decoding the same to UTF-8 but still no success. Any suggestions about how to process the input received from the read() function. I also tried using the readline() but the program then goes blank or infinite execution seems there is no EOL marker in the serial output.
The Demo Code snip is as follows :
with serial.Serial('/dev/cu.usbserial-Device',9600) as ser:
ser.flushInput()
ser.flushOutput()
ser.write('S')
inputVal=[]
while(len(inputVal)<10000):
val = ser.read(10)
inputVal.append(binascii.b2a_qp(val))
Any suggestions ? Thanks in advance.
You can try to encode whilst writing to the serial port.
ser.write(str.encode('S\r')
While, to read, I would use something like
a = ser.readline()
b = v.rstrip()
c = b.decode('utf-8')

Unable to read from the Serial Port using PySerial

This is my function. i am trying to send the word sensors to the COM Port and then get back the result.
def serialportcommunication():
ser = serial.Serial(
port='COM5',
baudrate=115200
)
print('Writing SENSORS command to COM7')
ser.write(b"sensors")
time.sleep(4)
print('Reading 10 bytes from serial buffer')
read_val = ser.read(size=10)
print(read_val)
print('Done printing output')
Output I get of the code above:
Writing SENSORS command to COM7
Reading 10 bytes from serial buffer
b'sensors\r\n '
Done printing output
If I execute the command "sensors" to the COM Port using a Terminal Program like Putty, I get a wall of text from my target device (the sample output is shown below, I had to white out most of the output though).
This text I am reading back, I want to read it in Python using teh command above of ser.read(size = ??), but I don't read anything back.
How to read it back?
MY SCREENSHOT FROM USING PUTTY
Resolved in comments:
Do you have to hit Enter when typing the command manually? Then you need to do the same here - ser.write(b"sensors\r") (or maybe \n, or \r\n). – jasonharper
Yes, when i enter the command in Putty, I to hit enter. Thank you thank you. I added the '\n in the end and it works now!!!! – Neil Dey

Python - Data Sent Over Socket Appears Different on Client and Server

I've got a client/server program where the client sends plaintext to the server which then runs AES encryption and returns the ciphertext. I'm using the following algorithm for the encryption/decryption:
http://anh.cs.luc.edu/331/code/aes.py
When I get the results back from the encryption and print them on the server-side I see mostly gibberish in the terminal. I can save to a file immediately and get something along these lines:
tgâY†Äô®Ø8ί6ƒlÑÝ%ŠIç°´>§À¥0Ð
I can see that this is the correct output because if I immediately decrypt it on the server, I get the original plaintext back. If I run this through the socket, send it back to the client, and print(), I get something more like this:
\rtg\xe2Y\x86\x8f\xc4\xf4\xae\xd88\xce\xaf6\x83l\xd1\xdd%\x8aI\xe7\xb0\xb4>\xa7\xc0\x18\xa50\xd0
There's an obvious difference here. I'm aware that the \x represents a hex value. If I save on the client-side, the resulting text file still contains all \x instances (i.e., it looks exactly like what I displayed directly above). What must I do to convert this into the same kind of output that I'm seeing in the first example? From what I have seen so far, it seems that this is unicode and I'm having trouble...
Relevant code from server.py
key = aes.generateRandomKey(keysizes[len(key)%3])
encryptedText = aes.encryptData(key, text)
f = open("serverTest.txt", "w")
f.write(encryptedText)
f.close()
print(encryptedText)
decryptedText = aes.decryptData(key, encryptedText)
print(decryptedText)
conn.sendall(encryptedText)
Relevant code from client.py
cipherText = repr(s.recv(16384))[1:-1]
s.close()
cipherFile = raw_input("Enter the filename to save the ciphertext: ")
print(cipherText)
f = open(cipherFile, "w")
f.write(cipherText)
Edit: To put this simply, I need to be able to send that data to the client and have it display in the same way as it shows up on the server. I feel like there's something I can do with decoding, but everything I've tried so far doesn't work. Ultimately, I'll have to send from the client back to the server, so I'm sure the fix here will also work for that, assuming I can read it from the file correctly.
Edit2: When sending normally (as in my code above) and then decoding on the client-side with "string-escape", I'm getting identical output to the terminal on both ends. The file output also appears to be the same. This issue is close to being resolved, assuming I can read this in and get the correct data sent back to the server for decrypting.
Not sure I fully understood what you're up to, but one difference between client and server is that on the client you're getting the repr for the byte string, while on the server you print the byte string directly.
(if I got the issue right) I'd suggest replacing
repr(s.recv(16384))[1:-1]
with a plain
s.recv(16384)

Raw load found, how to access?

To start off, I have read through other raw answers pertaining to scapy on here, however none have been useful, maybe I am just doing something wrong and thats what has brought me here today.
So, for starters, I have a pcap file, which started corrupted with some retransmissions, to my belief I have gotten it back to gether correctly.
It contains Radiotap header, IEEE 802.11 (dot11), logical-link control, IPv4, UDP, and DNS.
To my understanding, the udp packets being transmitted hold this raw data, however, do to a some recent quirks, maybe the raw is in Radiotap/raw.
Using scapy, I'm iterating through the packets, and when a packet with the Raw layer is found, I am using the .show() function of scapy to view it.
As such, I can see that there is a raw load available
###[ Raw ]###
\load \
|###[ Raw ]###
| load = '#\x00\x00\x00\xff\xff\xff\xff\xff\xff\x10h?'
So, I suppose my question is, how can I capture this payload to receive whatever this may be, To my knowledge the load is supposed to be an image file, however I have trouble believing such, so I assume I have misstepped somewhere.
Here is the code I'm using to achieve the above result
from scapy.all import *
from scapy.utils import *
pack = rdpcap('/home/username/Downloads/new.pcap')
for packet in pack:
if packet.getlayer(Raw):
print '[+] Found Raw' + '\n'
l = packet.getlayer(Raw)
rawr = Raw(l)
rawr.show()
Any help, or insight for further reading would be appreciated, I am new to scapy and no expert in packet dissection.
*Side note, previously I had tried (using separate code and server) to replay the packets and send them to myself, to no avail. However I feel thats due to my lack of knowledge in receipt of UDP packets.
UPDATES - I have now tested my pcap file with a scapy reassembler, and I've confirmed I have no fragmented packets, or anything of the sort, so I assume all should go smoothly...
Upon opening my pcap in wireshark, I can see that there are retransmissions, but I'm not sure how much that will affect my goals since no fragmentation occurred?
Also, I have tried the getlayer(Raw).load, if I use print on it I get some gibberish to the screen, I'm assuming its the data to my would-be-image, however I need to now get it into a usable format.
You can do:
data = packet[Raw].load
You should be able to access the field in this way:
l = packet.getlayer(Raw).load
Using Scapy’s interactive shell I was successful doing this:
pcap = rdpcap('sniffed_packets.pcap')
s = pcap.sessions()
for key, value in s.iteritems():
# Looking for telnet sessions
if ':23' in key:
for v in value:
try:
v.getlayer(Raw).load
except AttributeError:
pass
If you are trying to get the load part of the packet only, you can try :
def handle_pkt(pkt):
if TCP in pkt and pkt[TCP].dport == 5201:
#print("got a packet")
print(pkt[IP])
load_part = pkt[IP].load
print("Load#",load_part)
pkt.show2()
sys.stdout.flush()

Categories

Resources