How to manage several Serial messages in processing - io

I am reading the UID of my RFID card and storing it in a variable called myUID.
After that I am authorizing to the card with the factory key and read block number 4 (which has been written to earlier) and store it in a string readBlock.
On the Arduino, I print out the variables onto the serial interface like so.
Serial.println(myUID);
Serial.println(readBlock);
On the client side, I use a Java program that reads in serial data. My program uses the Processing Library.
Serial mySerial;
PrintWriter output;
void setup() {
output = createWriter( "data.txt" );
mySerial = new Serial( this, Serial.list()[0], 9600 );
mySerial.bufferUntil('\n');
}
void draw(){
while (mySerial.available() > 0) {
String inBuffer = mySerial.readString();
if (inBuffer != null)
output.println(inBuffer);
}
}
void keyPressed() { // Press a key to save the data
output.flush(); // Write the remaining data
output.close(); // Finish the file
exit(); // Stop the program
}
Now my data.txt is expected to look like
xxx xxx xxx xxx (uid of card)
00 00 00 00 00 00 00 00 ... (read block from card)
but looks like
237 63 58 1
07
37 37 95
37
97 98 50 54 37 5
4 55 102 55 52
45 98
I have tried several things like readStringUntil('\n'); in the Processing Library but without success.

For everyone interested, I have fixed the problem myself with many hours of searching Google, so maybe this will help someone in the future:
I could fix it with this code:
import processing.serial.*;
int count = 0;
String input = "";
String fileName = dataPath("SET FILEPATH HERE");
Serial mySerial;
import java.io.*;
void setup() {
mySerial = new Serial(this, Serial.list()[0], 9600);
mySerial.bufferUntil('\n');
File f = new File(fileName);
if (f.exists()) {
f.delete();
}
}
void draw(){}
// listen to serial events happening
void serialEvent(Serial mySerial){
input = mySerial.readStringUntil('\n');
write(input, count);
count++;
}
// function for writing the data to the file
void write(String inputString, int counter) {
// should new data be appended or replace any old text in the file?
boolean append = false;
// just for my purpose, because I have got two lines of serial which need to get written to the file
//(Line 1: UID of card, Line 2: Read block of card)
if(counter < 2){
append = true;
}
else{
count = 0;
}
try {
File file = new File("D:/xampp/htdocs/pizza/src/rfid/data.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file, append);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
pw.write(inputString + '\n');
pw.close();
}
catch(IOException ioe) {
System.out.println("Exception ");
ioe.printStackTrace();
}
}

Related

Properly parse MAC Address

When I use tools such as snmp-walk or snmp-get to query an OID with a return type of MacAddress, It'll always parse the data as a HexString and display it properly. Even when they don't have the MIBs loaded it'll still works.
bash#snmpwalk -v 2c -c public 10.1.2.3 1.3.6.1.4.1.14179.2.2.1.1
SNMPv2-SMI::enterprises.14179.2.2.1.1.1.16.189.24.206.212.64 = Hex-STRING: 10 BD 18 CE D4 40
SNMPv2-SMI::enterprises.14179.2.2.1.1.1.100.233.80.151.114.192 = Hex-STRING: 64 E9 50 97 72 C0
However, I can't seem to get the same result from Lextm.SharpSnmpLib (11.2.0). Data types of MacAddress don't get decoded correctly and it's a manual process to convert it to a proper MAC.
public void WalkTable()
{
const string baseOid = "1.3.6.1.4.1.14179.2.2.1.1"; //The entire table
const string community = "public";
var ep = new IPEndPoint(IPAddress.Parse("10.1.2.3"), 161);
var results = new List<Variable>();
Messenger.Walk(VersionCode.V2, ep, new OctetString(community), new ObjectIdentifier(baseOid), results, 60000, WalkMode.WithinSubtree);
foreach(var v in results)
Console.WriteLine(v.Data.ToString());
}
Am I doing something wrong or is this just how the library works?
You are outputting the MAC Address as ASCII instead of Hex. Here's a quick method I put together that will detect non-ascii characters and output as hex if any are found.
public void WalkTable()
{
const string baseOid = "1.3.6.1.4.1.14179.2.2.1.1"; //The entire table
const string community = "public";
var ep = new IPEndPoint(IPAddress.Parse("10.1.2.3"), 161);
var results = new List<Variable>();
Messenger.Walk(VersionCode.V2, ep, new OctetString(community), new ObjectIdentifier(baseOid), results, 60000, WalkMode.WithinSubtree);
foreach(var v in results)
//If the result is an OctetString, check for ascii, otherwise use ToString()
Console.WriteLine(v.Data.TypeCode.ToString()=="OctetString" ? DecodeOctetString(v.Data.ToBytes()) : v.Data.ToString())
}
}
public string DecodeOctetString(byte[] raw)
{
//First 2 bytes are the Type, so remove them
byte[] bytes = new byte[raw.Length - 2];
Array.Copy(raw, 2, bytes, 0, bytes.Length);
//Check if there are any non-ascii characters
bool ascii = true;
foreach (char c in Encoding.UTF8.GetString(bytes))
{
if (c >= 128)
{
ascii = false;
}
}
//If it's all ascii, return as ascii, else convert to hex
return ascii ? Encoding.ASCII.GetString(bytes) : BitConverter.ToString(bytes);
}

How to filter on Apache Edgent and also show the values which were filtered?

I am using Apache Edgent (Java framework) to poll values from a HCSR04 ultrasonic sensor on a Raspberry Pi every 3 seconds. I use a filter to not get values from 50cm to 80cm.
UltrasonicStream sensor = new UltrasonicStream();
DirectProvider dp = new DirectProvider();
Topology topology = dp.newTopology();
TStream<Double> tempReadings = topology.poll(sensor, 3, TimeUnit.SECONDS);
TStream<Double> filteredReadings = tempReadings.filter(reading -> reading < 50 || reading > 80);
System.out.println("filter added: tempReadings.filter(reading -> reading < 50 || reading > 80);");
filteredReadings.print();
dp.submit(topology);
I want to show some message when the values are filtered. When the values do not match with my filter I can poll them, but when they match I am not returning, that is ok. However, I want just to show that a value was filtered using Apache Edgent libraries. I know that I can do something on the public double get() method, but I wonder if I could do this trick with some method of the Apache Edgent.
public class UltrasonicStream implements Supplier {
private static final long serialVersionUID = -6511218542753341056L;
private static GpioPinDigitalOutput sensorTriggerPin;
private static GpioPinDigitalInput sensorEchoPin;
private static final GpioController gpio = GpioFactory.getInstance();
private double currentDistance = -1.0;
/**
* The HCSR04 Ultrasonic sensor is connected on the physical pin 16 and 18 which
* correspond to the GPIO 04 and 05 of the WiringPi library.
*/
public UltrasonicStream() {
// Trigger pin as OUTPUT
sensorTriggerPin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04);
// Echo pin as INPUT
sensorEchoPin = gpio.provisionDigitalInputPin(RaspiPin.GPIO_05, PinPullResistance.PULL_DOWN);
}
/**
* This is the override method of the Supplier interface from Apache Edgent
*/
#Override
public Double get() {
try {
System.out.print("Distance in centimeters: ");
currentDistance = getDistance();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return currentDistance;
}
/**
* Retrieve the distance measured by the HCSR04 Ultrasonic sensor connected on a
* Raspberry Pi 3+B
*
* #return the distance in centimeters
* #throws InterruptedException
*/
public double getDistance() throws InterruptedException {
double distanceCM = -1;
try {
// Thread.sleep(2000);
sensorTriggerPin.high(); // Make trigger pin HIGH
Thread.sleep((long) 0.01);// Delay for 10 microseconds
sensorTriggerPin.low(); // Make trigger pin LOW
// Wait until the ECHO pin gets HIGH
while (sensorEchoPin.isLow()) {
}
// Store the current time to calculate ECHO pin HIGH time.
long startTime = System.nanoTime();
// Wait until the ECHO pin gets LOW
while (sensorEchoPin.isHigh()) {
}
// Store the echo pin HIGH end time to calculate ECHO pin HIGH time.
long endTime = System.nanoTime();
distanceCM = ((((endTime - startTime) / 1e3) / 2) / 29.1);
// Printing out the distance in centimeters
// System.out.println("Distance: " + distanceCM + " centimeters");
return distanceCM;
} catch (InterruptedException e) {
e.printStackTrace();
}
return distanceCM;
}
}
You can use TStream.split() to create two streams: one whose tuples match your filter predicate and one for those that don't. You can then do whatever you want with either stream. e.g. TStream.peek(t -> System.out.println("excluded: " + t)), or TStream.print(...)
I implemented like this:
UltrasonicStream sensor = new UltrasonicStream();
DirectProvider dp = new DirectProvider();
Topology topology = dp.newTopology();
TStream<Double> tempReadings = topology.poll(sensor, 3, TimeUnit.SECONDS);
TStream<Double> filteredReadings = tempReadings.filter(reading -> {
boolean threshold = reading < 20 || reading > 80;
if (!threshold) {
System.out.println(String.format("Threshold reached: %s cm", reading));
}
return threshold;
});
filteredReadings.print();
dp.submit(topology);

Error 0x6f00 in Sign Method in javacard 2.2.1

I wrote this code and I debug it with jcIDE. I have a error 0x6f00 in line signature.sign('''). I sent apdu "00 80 00 00 04 01 02 03 04" for signing operation
.
My key is RSA -1024
RSAPrivateKey thePrivateKey = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_1024, NO_EXTERNAL_ACCESS);
RSAPublicKey thePublickKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_1024, NO_EXTERNAL_ACCESS);
public void generatesignature(APDU apdu)
{
if(!Pin.isValidated())
ISOException.throwIt (ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
byte[] buffer=apdu.getBuffer();
// data field of the command APDU
short numdata=(short) buffer[ISO7816.OFFSET_LC];
byte p1=(byte)buffer[ISO7816.OFFSET_P1];
thePrivateKey=(RSAPrivateKey)PrivateKeyArray[p1];
thePublickKey=(RSAPublicKey)PublicKeyArray[p1];
// receive data starting from the offset
// ISO.OFFSET_CDATA
short inputlength= (short) apdu.setIncomingAndReceive();
// it is an error if the number of data bytes
// read does not match the number in Lc byte
if (inputlength == 0)
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
try
{
//convert input to hash
MessageDigest digest=MessageDigest.getInstance(MessageDigest.ALG_SHA,false );
short hashlength=digest.doFinal(buffer,ISO7816.OFFSET_CDATA,numdata,Input_Hash,(short)0);
Signature signature=Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1,false);
signature.init(thePrivateKey,Signature.MODE_SIGN);
short hashlength=signature.sign(Input_Hash,(short)0,hashlength,Input_Sign, (short)0);
Util.arrayCopy(Input_Sign,(short)0, buffer, (short)0, signLength);
apdu.setOutgoingAndSend((short)0, ((short)signLength));
}
catch (CryptoException c) {
short reason = c.getReason();
ISOException.throwIt(reason); // for check
}
}
Can everybody help me?exactly in line short hashlength=signature.sign(Input_Hash,(short)0,hashlength,Input_Sign, (short)0);
I have problem. I use catch but code never go in catch.
my result in apdutool on real gemalto 2.2.1 card
byte[] buffer=apdu.getBuffer();
short numdata=(short) buffer[ISO7816.OFFSET_LC];
short inputlength= (short) apdu.setIncomingAndReceive();
if (inputlength == 0)
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
//sign
Signature signature=Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1,false);
signature.init(thePrivateKey,Signature.MODE_SIGN);
signLength=signature.sign(buffer,(short)(ISO7816.OFFSET_CDATA & 0xFF), inputlength, buffer, (short)(0));
apdu.setOutgoingAndSend((short)0,signLength);

display bytes greater than 0x7f

I'd like to connect my program to a serial port & to show the received data from the serial port. I successfully did that, but I have a problem.
I'd like to convert the string shown in the window into a stream of bits
I followed How could I get the bits from a string in c#?
& my problem is what to do to show a byte like 0xAA, it's greater than 7f the maximum value of the ascii characters
I'm developing a program using C# language, I'd like to connect it to a serial port & to show the received data from the serial port,I successfully did that, but I have a problem, I'd like to convert the string shown in the window into a stream of bits I followed How could I get the bits from a string in C#?
& my problem is what to do to show a byte like 0xAA, it's greater than 7f the maximum value of the ASCII characters
public partial class mm_dig_ctrl : Form
{
public mm_dig_ctrl()
{
InitializeComponent();
if (!MySerP.IsOpen)
{
MySerP.Open();
TB_Port_Status.Text = "Port is Opened";
}
else
{
TB_Port_Status.Text = "Port is Busy";
}
MySerP.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(DataReceivedHandler);
}
public delegate void AddDataDelegate(String rxstring);
public AddDataDelegate myDelegate;
private void mm_dig_ctrl_Load(object sender, EventArgs e)
{
this.myDelegate = new AddDataDelegate(AddDataMethod);
}
public void AddDataMethod(String myString)
{
TBRX_Read.AppendText(myString);
}
private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
String rxstring,to_show;
rxstring = MySerP.ReadExisting();
to_show = GetBits(rxstring);
TBRX_Read.Invoke(this.myDelegate, new object[] { to_show });
//TBRX_Read.Text += rxstring;
}
public string GetBits(string input)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in input)
{
sb.Append(Convert.ToString(b, 16));
}
return sb.ToString();
}
'

JList updating with live captured packets info (using jNetPcap) is causing list blanking

I am coding app which is capturing packet from 2 NI Cards at the same time in specific thread for them.
I am using jnetPcap and I am getting captured packet in jpackethanler's method nextPacket i need to show info from the current packet in JList but when I use simply defaultListModel and i write model1.addElement(packetinfo) then JList randomly goes in blank.
My code :
new Thread(){
#Override
public void run(){
StringBuilder errbuf = new StringBuilder(); // For any error msgs
int snaplen = 64 * 1024; // Capture all packets, no trucation
int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
int timeout = 10 * 1000; // 10 seconds in millis
Pcap pcap1 =
Pcap.openLive(Variables.getDevice1().getName(), snaplen, flags, timeout, errbuf);
if (pcap1 == null) {
System.err.printf("Error while opening device for capture: "
+ errbuf.toString());
return;
}
PcapPacketHandler<String> jpacketHandler1 = new PcapPacketHandler<String>() {
int count = 1;
#Override
public void nextPacket(PcapPacket packet, String user) {
// ALL PACKETS FROM DEVICE 1 HERE
int packetSize = packet.size();
int packetCount = count++;
String desc = String.format("No.: %15d | HDRSize : %-4d", packetCount,packetSize);
device1Model.addElement(desc); // this adds desc to JLIST
}
};
pcap1.loop(Pcap.LOOP_INFINITE, jpacketHandler1, "");
pcap1.close();
}
}.start();
What do change to be more smooth and at the same time there will be no packet looses. Because i need to catch every packet for right function of app.
Thank You.

Resources