Simply saying I have rough time trying to prepare proper FINS Command to PLC.
Topology:
PC (with Java app) IP: 10.1.0.57
OMRON CS1 PLC IP: 10.1.0.50
Now trying to prepare message for D0100 address. Message looks like this:
80 00 02 00 32 00 00 39 00 01 01 01 82 00 64 00 00 01
So:
ICF: 0x80
RSV: 0x00
GCT: 0x20
DNA: 0x00
DA1: 0x32 (50(dec) which is last octet of PLC IP)
DA2: 0x00
SNA: 0x00
SA1: 0x39 (57(dec) which is last octet of PC IP)
SA2: 0x00
SID: 0x01 (I am increasing this val in every new read)
COMMAND CODE: 0x01 0x01 (read Memory value)
MEM: 0x82
ADDR: 0x00 0x64 (100dec)
BIT: 0x00 (whole address)
LEN: 0x00 0x01 (1 address)
According to the doc everything seems to be ok, but the answer which I am receving has 16 bytes and it looks like this:
70 73 78 83 00 00 00 08 00 00 00 03 00 00 00 03
Socket is crashing after 2nd read try.
EDIT:
I managed to add FINS Header at the beginning of message:
46 49 4e 53 00 00 00 1a 00 00 00 02 00 00 00 00
Which should be:
0x46: F
0x49: I
0x4e: N
0x53: S
0x00 0x00 0x00 0x1a: 26 - message length
0x00 0x00 0x00 0x02 &
0x00 0x00 0x00 0x00 - part of the response which I got on the beginning. Not sure at all if correct...
Now Socket is not crushing but, if I am trying to read anything there is no data.
What I am missing? Where I should look to troublshoot the problem? I don't have direct access to PLC, but I can see data flow in OPC Server on the same PC.
Thanks in advance.
Adam
Ok, so the answer was pretty simple...
Last part of Host Link Header must represent IP of PC, if you are trying to connect to OMRON PLC via Network:
46 49 4e 53 00 00 00 1a 00 00 00 02 00 00 00 39
0x39 is 57dec, so last octet of my PC IP.
After that change everything is working!
Related
I am trying to uplaod an applet that i made onto a real smart card. I tried with Simulators like JCWDE and CREF and it worjed perfectly.
But with my smart card, even though the system (i'm using the GlobalPlatformPro tool to load via the gp -load command) recongnizes the card, it always displays this errors for each operation i want to do and i don't know how to solve it.
This is the result with GlobalPlateform (with -d -v options) :
C:\Java>gp -load javacard -d -v
GlobalPlatformPro 18.09.14-0-gb439b52
Running on Windows 10 10.0 amd64, Java 1.8.0_291 by Oracle Corporation
# Detected readers from JNA2PCSC
[ ] JAVACOS Virtual Contact Reader 0
[ ] JAVACOS Virtual Contactless Reader 1
[*] OMNIKEY AG Smart Card Reader USB 0
SCardConnect("OMNIKEY AG Smart Card Reader USB 0", T=*) -> T=0, 3B7D9400005744290830869312C090111E1A
SCardBeginTransaction("OMNIKEY AG Smart Card Reader USB 0")
Reader: OMNIKEY AG Smart Card Reader USB 0
ATR: 3B7D9400005744290830869312C090111E1A
More information about your card:
http://smartcard-atr.appspot.com/parse?ATR=3B7D9400005744290830869312C090111E1A
A>> T=0 (4+0000) 00A40400 00
A<< (0018+2) (16ms) 6F108408A000000003000000A5049F6501FF 9000
[DEBUG] GlobalPlatform - Auto-detected ISD: A000000003000000
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
A>> T=0 (4+0008) 80500000 08 007D0897841EECAB 00
A<< (0000+2) (31ms) 6D00
INITIALIZE UPDATE failed: 0x6D00 (Invalid INStruction)
This the result with PyAptduTool :
Select CardManager begin...
Select CardManager successful.
Download Cap begin...
Download Cap successful.
Install Applet begin...
Install Applet successful.
Select Applet begin...
Select Applet successful.
I tried with gpj and this is the output :
Found card in terminal: OMNIKEY AG Smart Card Reader USB 0
ATR: 3B 7D 94 00 00 57 44 29 08 30 86 93 12 C0 90 11 24 1F
DEBUG: Command APDU: 00 A4 04 00 07 A0 00 00 01 51 00 00
DEBUG: Response APDU: 6A 82
Failed to select Security Domain GP211 A0 00 00 01 51 00 00 , SW: 6A 82
DEBUG: Command APDU: 00 A4 04 00 08 A0 00 00 00 18 43 4D 00
DEBUG: Response APDU: 6A 82
Failed to select Security Domain GemaltoXpressPro A0 00 00 00 18 43 4D 00 , SW: 6A 82
DEBUG: Command APDU: 00 A4 04 00 08 A0 00 00 00 03 00 00 00
DEBUG: Response APDU: 6F 10 84 08 A0 00 00 00 03 00 00 00 A5 04 9F 65 01 FF 90 00
Successfully selected Security Domain OP201a A0 00 00 00 03 00 00 00
DEBUG: Command APDU: 80 50 00 00 08 6A 40 39 0E 99 CC 40 D0
DEBUG: Response APDU: 6D 00
javax.smartcardio.CardException: Wrong initialize update, SW: 6D 00
at net.sourceforge.gpj.cardservices.GlobalPlatformService.openSecureChannel(Unknown Source)
at net.sourceforge.gpj.cardservices.GlobalPlatformService.main(Unknown Source)
Background
I have recently just started to learn networking and google's protocol buffers to build a communication between my java client to a python server. Sending message from my python server to java client works perfect, but the reverse way (from java to python) was always failed.
Problem
After checking the length of message from both sides, I have found the receiver(python) missing some of the bytes transferred by the java code,
java side:
12 28 08 0b 12 24 15 00 00 80 3f 1a 1b 09 00 00 00 00 00 00 f0 3f 11 00 00 00 00 00 00 f0 3f 19 00 00 00 00 00 00 f0 3f 22 00
python side:
12 28 08 0b 12 24 15 00 00 80 3f 1a 1b 09 00 00 00 00 00 00 f0 3f 11 00 00 00 00 00 00 f0 3f
As you can see, the last 10 bytes is missing. I could not figure out the problem.
Codes
The following is my java code,
// Both Message and UPDATEs are message types I defined in my .proto file
Message message = Message.newBuilder()
.setUpdate(UPDATEs.newBuilder()
.setTimeStamp(11)
.addUpdates(state))
.build();
//System.out.println(message.toString());
System.out.println(message.toByteArray().length); // result -> 42
//System.out.println(byteArrayToHex(message.toByteArray()));
try {
OutputStream outputStream = socket.getOutputStream();
message.writeDelimitedTo(outputStream);
System.out.println("Sending finished.");
} catch (IOException e) {
System.err.println("SteerCommunicator_sendCarData(OutputStream output): " + e.toString());
System.exit(0);
}
and my python code,
def server_loop():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Listening at port {}".format(PORT)
try:
server.bind(("localhost", PORT))
except:
print "Unable to listen on the Port" + PORT
sys.exit()
server.listen(10)
while True:
client_socket, addr = server.accept()
print "Received Message from Client {}:{}".format(addr[0],str(addr[1]))
msg = client_socket.recv(1024)
print len(msg) # result -> 32
Any ideas?
If the diagnosis that the stream is not being flushed is correct, then here is the solution:
try (OutputStream outputStream = socket.getOutputStream()) {
message.writeDelimitedTo(outputStream);
System.out.println("Sending finished.");
} catch (IOException e) {
// SEE NOTES!!
System.err.println("blah blah" + e.toString());
System.exit(0);
}
Explanation: by using try-with-resources, we ensure that the resource is always closed as the block exits, no matter how it exits. This has two benefits:
It ensures that the stream is flushed
It ensures that you don't leak the resource (i.e. the associated FileDescriptor). Resource leaks can cause various unrelated I/O activity to fail ... later on ... if the GC doesn't get a chance to clean up the mess first.
NOTES:
Calling System.exit(...) in the depths of your code is a bad idea. It preempts other possible approaches to recovery, and makes your code harder to extend and/or reuse.
If you catch and report an exception, you should also report the stacktrace ... somewhere.
A better strategy would be to declare IOException as thrown by the enclosing method, and catch / report / recover at a higher level.
I have an applet installed on a JavaCard. I want to delete this applet through over the air(OTA) message by sending APDU commands. following are the APDU command I send through card reader to delete th applet:
1) A4 04 00 00
2) ExAuth 00 02 00 01 00 404142434445464748494A4B4C4D4E4F
3) 80 E4 00 00 0D 4F 0B A0 00 00 00 00 01 02 03 03 01 02
4) 80 E4 00 00 0D 4F 0B A0 00 00 00 00 01 02 03 03 00 00
I have followed this :
https://adywicaksono.wordpress.com/2008/05/21/understanding-gsm-0348/
But I have not been able to delete the applet as there is some error everytime.
Thank You.
Under my assumption that your JavaCard is using the Global Platform framework (which almost every JavaCard does) you need to perform the following steps:
Select CardManager
Authenticate
Delete the applet
You probably succeeded the first step, although selecting the Cardmanager by its AID is the better way to go. The second step looks a bit weird to me from what you posted. The third step looks good as well.
To authenticate there are diffrent protocols, e.g. SCP01, SCP02, etc. SCP02 is the de facto standard for modern cards. Then of course you also need the right keys to authenticate, for most cards delivired there are the default keys that you already have. The exact procedure is explained in the Global Platform specification. A sample log from my tool looks like this:
=> 00 A4 04 00 08 A0 00 00 01 51 00 00 00 00 .........Q....
(9407 usec)
<= 6F 64 84 08 A0 00 00 01 51 00 00 00 A5 58 9F 65 od......Q....X.e
01 FF 9F 6E 06 47 91 23 47 41 00 73 49 06 07 2A ...n.G.#GA.sI..*
86 48 86 FC 6B 01 60 0B 06 09 2A 86 48 86 FC 6B .H..k.`...*.H..k
02 02 02 63 09 06 07 2A 86 48 86 FC 6B 03 64 0B ...c...*.H..k.d.
06 09 2A 86 48 86 FC 6B 04 02 55 65 0B 06 09 2B ..*.H..k..Ue...+
85 10 86 48 64 02 01 03 66 0C 06 0A 2B 06 01 04 ...Hd...f...+...
01 2A 02 6E 01 02 90 00 .*.n....
Status: No Error
cm> set-key 255/1/DES-ECB/404142434445464748494a4b4c4d4e4f 255/2/DES-ECB/404142434445464748494a4b4c4d4e4f 255/3/DES-ECB/404142434445464748494a4b4c4d4e4f
cm> init-update 255
=> 80 50 00 00 08 7D 62 4D F4 89 F6 07 E3 00 .P...}bM......
(55368 usec)
<= 00 00 42 87 00 17 97 93 24 74 FF 02 00 01 3C 2B ..B.....$t....<+
97 86 B8 3B 57 0A D0 9F 82 BF AD C2 90 00 ...;W.........
Status: No Error
cm> ext-auth plain
=> 84 82 00 00 10 EA 1A 9D A0 24 E6 00 9E F8 84 96 .........$......
1A 77 71 46 B4 .wqF.
(56879 usec)
<= 90 00 ..
Status: No Error
cm> delete ff4563686f4170706c6574
=> 80 E4 00 00 0D 4F 0B FF 45 63 68 6F 41 70 70 6C .....O..EchoAppl
65 74 00 et.
(956894 usec)
<= 00 90 00 ...
Status: No Error
As you don't want to perform all the cryptographic protocol by yourself there are tools out there, that do the job for you. The best freeware tool in my opinion is GlobalPlatformPro from Martin Paljek. Beware that there are plenty other tools that might be deprecated.
In order to perform remote application management on SIM you need to have OTA keys of SIM card and OTA platform to construct appropriate GSM 03.48 and 03.40 APDU commands to exchange secure data packets with SIM. SIM carries out authentication of mobile user in mobile networks and neither GSM nor OTA keys of SIM cards never shared by mobile operators to 3rd parties.
MNOs have OTA platform which maintains relational database to keep MSISDN-ICCID-OTA Keys(KiK,KiD and KiC) triplet. Apart from OTA keys, SPI, TAR and CNTR values as part of each SIM card profile is kept in OTA platform to generate GSM 03.48 packet. So to perform any applet provisioning (instal, update delete) generally secure data content must be encrypted with KiC and KiD.
I have one server listening on port and ip and a client which will connect to this server.
DataInputStream meterin=new DataInputStream(socket.getInputStream);
DataOutputStream modemds=new DataOutputStream(modems.getOutputStream);
now server is sending some data here:(CA F0 00 00 00 00 00 00 00 3A).But when I read this as
int c;
byte bt[]=new byte[11]
c=meterin.read(bt,0,11)`
System.out.println("bytes"+c) // it is returning 10 bytes
modemds.write(bt,0,c)
but at client i am getting.
(CA F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00).
which is more than 10 bytes even it is reading 10 bytes upwards.
You cannot assume the read will fill the buffer. See readFully() for an alternative, or else loop until you get all the data you need.
With some assumptions and fFrom the code it looks like you are reading the data from server and then relaying it to another listener or what you call as client. So on the client side code please check if the receiving buffer is initialized to more than the data being sent .. that would then lead to adding additional bytes in output. If that is the case, use System.arrayCopy to copy out the actual bytes from the receiving buffer (assuming the client code is java).
I am using energy meter. How to that meter data reading and writing code in Java?
It will be power line node to send and transferring the data it will be convert the concentrator in RS232 to display in serial port. Windows using Java.
Output example in reading meter value is:
A 00 09 14 03 81 0C 03 10 03 00 30 B0 03 3A 00 :.........0°.:.
09 14 03 81 02 03 10 03 00 30 B1 2D 3A 00 09 14 ........0±-:...
03 81 02 03 10 03 00 04 B0 FA 3A 00 09 14 5C 81 .......°ú:...\
02 03 10 03 00 04 B0 FA
For reading and writing data to a serial port under windows i recomend using rxtx
http://rxtx.qbang.org/wiki/index.php/Main_Page
There are samples for reading and writing:
http://rxtx.qbang.org/wiki/index.php/Using_RXTX
There is a com api from oracle, but the actual version has only implementations for Solaris SPARC, Solaris x86, and Linux x86
http://www.oracle.com/technetwork/java/index-jsp-141752.html
I used an older version for windows, but it is hard to find and has some shortcommings (e.g. didn't found ports above com4 without 'helping', has problems with spaces in path to dll and so on)