WhatsApp video as Gif sharing on Android programatically - android

How can i convert a mp4 video file to a WhatsApp gif file (it's simple showed as gif inside app UI but internally is a specific mp4 format) to be use in android share intent, being recognized as this type of media by whatsapp chat app???
I search a lot but i can't find any information from WhatsApp docs (they don't have this kind of doc anyway) or any dev with the same problem as i.
WHAT I HAVE:
I have discovered that at beginning of whatsapp "gif" mp4 files is present a loop value if you read they on hex editor, all files have this. Remove this value make whatsapp receive as regular video (not sharing as gif).
How can i add this value using ffmpeg encoding? (editing my mp4 files manually with this value corrupt the files, maybe i have to fix some mp4 header index that i don't know yet...)
FIRST 80 BYTES in hexadecimal (from beginning to start of "moov" atom from mp4 structure):
00 00 00 1C 66 74 79 70 6D 70 34 32 00 00 00 01 6D 70 34 31 6D 70 34 32 69 73 6F 6D 00 00 00 18 62 65 61 6D 01 00 00 00 01 00 00 00 00 00 00 00 05 00 00 00 00 00 00 0C 6C 6F 6F 70 00 00 00 00 00 00 00 08 77 69 64 65 00 00 04 9F 6D 6F 6F 76
A short mp4 file generated by WhatsApp that internally (at app) was showed as a Gif (with different UI):
https://www.dropbox.com/s/kpynmx1bg3z76lz/VID-20171024-WA0009.mp4?dl=0

"...The problem is that I can't edit another MP4 file to add this atom
without corrupt the file.
Test this small_VC1edit.mp4 in WhatsApp. If it does what you want then read on...
To make a playable MP4 :
Using original small.mp4 as an editing example (download file and open with a hex editor).
1) In a blank byte array, add the first 72 bytes of the shown WhatsApp-style MP4 header.
00 00 00 1C 66 74 79 70 6D 70 34 32 00 00 00 01 6D 70 34 31 6D 70 34 32 69 73 6F 6D 00 00 00 18 62 65 61 6D 01 00 00 00 01 00 00 00 00 00 00 00 05 00 00 00 00 00 00 0C 6C 6F 6F 70 00 00 00 00 00 00 00 08 77 69 64 65
You've shown 80 bytes but the last 8 bytes are not needed yet (also four of those eight byte's values must be different for your output file).
2) Calculate the deltas.
Note the (new) WhatsApp header is 72 bytes (before moov atom).
Note the (original) Small.mp4 has 160 bytes of header (before moov atom).
So just use this logic (a or b):
a) If WhatsApp header is bigger than input MP4 :
delta = ( WhatsApp_header - input_MP4_header)
b) If input MP4 header is bigger than WhatsApp :
delta = ( input_MP4_header - WhatsApp_header )
So for the input small.mp4 which has 160 header bytes (is followed next by 4 bytes of moov's SIZE (as 00 00 0D 83) and then follows another 4 bytes now of moov's NAME (as 6D 6F 6F 76 or utf-8 text of "moov").
We can say : 160 MP4 bytes - 72 WhatsApp bytes = Delta of 88.
If you delete these original 160 bytes and replace them with the shorter 72 WhatsApp bytes, they'll be 88 less bytes which must now be accounted for in the another section of MOOV data. That section is the STCO atom.
3) Update the STCO atom with new offsets:
In small.mp4 the STCO atom begins at offset 1579 (as 73 74 63 6F). The previous 4 bytes (offsets: 1575 to 1578) are stco's SIZE bytes (as 00 00 00 B8) which is decimal value 184. This total SIZE of bytes length includes accounting for those 4 SIZE bytes too.
Skip 12 bytes from the starting byte 73 of the stco's NAME bytes 73 74 63... so skip these:
73 74 63 6F 00 00 00 00 00 00 00 2A
Now you reach point to sequentially update every 32-bit integer (4 bytes) of offsets with the new delta value. But how many offsets to update?
atomEditTotal = ( (stco_SIZE - 16) / 4); //gives 42 //PS: Minus by 16 is to trim off non-offset bytes.
So there are 42 entries to edit. Our Delta as 88 so for each integer we read value, minus it by 88, then write it back new value at same place, repeat another 41 times (using While loop with an if condition to break; the loop).
For testing, given a corrupt file, if you edit the first entry it should be enough to show frame 1 of video (if non-audio file).
PS: After editing the STCO offsets of small.mp4, just delete its starting 160 bytes and join/concat those remaining MP4 bytes to the back/end of the 72 byte WhatsApp header. Save array as new file and test.

Related

APDU commands to get data from NFC tag using ISODEP

I am trying to read the information stored on my German Sparkasse Girocard. My app successfully recognizes the (ISODEP) tag. To read the stored information, I need to send a sequence of APDU commands, but I am not sure which.
From my understanding I need to send a SELECT command first:
byte[] SELECT = {
(byte) 0x00, // CLA Class
(byte) 0xA4, // INS Instruction
(byte) 0x04, // P1 Parameter 1
(byte) 0x00, // P2 Parameter 2
(byte) 0x09, // Lc
(byte) 0xD2,0x76,0x00,0x00,0x25,0x47,0x41,0x01,0x00, // AID
(byte) 0x00 //Le
};
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
IsoDep tag = IsoDep.get(tagFromIntent);
tag.connect();
byte[] result = tag.transceive(SELECT);
text.setText(Integer.toHexString(result[0]) + ", " + Integer.toHexString(result[1]));
The status response should be 9000 if it works. I am getting 6F44 which indicates that there was some sort of error (I think). I am also not quite sure if I am using the correct AID, but it has also not worked using others, which I thought could be correct.
What is my error and which commands do I have to send to retrieve the data?
Thanks in advance.
Getting data from an EMV card (e.g. Girocard, Mastercard, Visacard) is more a "question and answer" puzzle - you are asking the card, get a response, analyze the data and ask the next question.
The analyzing part is done here by using the "TLV Utilities" from emvlab.org (https://emvlab.org/tlvutils/).
To get more information about the Application Identifier ("AID"s) see the complete list at: https://www.eftlab.com/knowledge-base/211-emv-aid-rid-pix/.
Here is an example of reading a German Girocard (mine is from a "Volksbank"):
Step 1: ask the card which applications are on the card using the "select PPSE" command. The 2 bytes at the end "90 00" say that the answer is successfull:
selectPpseCommand: 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
selectPpseResponse: 6F 67 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 55 BF 0C 52 61 19 4F 09 A0 00 00 00 59 45 43 01 00 87 01 01 9F 0A 08 00 01 05 01 00 00 00 00 61 1A 4F 0A A0 00 00 03 59 10 10 02 80 01 87 01 01 9F 0A 08 00 01 05 01 00 00 00 00 61 19 4F 09 D2 76 00 00 25 47 41 01 00 87 01 01 9F 0A 08 00 01 05 01 00 00 00 00 90 00
Parsed response:
6F File Control Information (FCI) Template
84 Dedicated File (DF) Name
325041592E5359532E4444463031
A5 File Control Information (FCI) Proprietary Template
BF0C File Control Information (FCI) Issuer Discretionary Data
61 Application Template
4F Application Identifier (AID) – card
A00000005945430100
87 Application Priority Indicator
01
9F0A Unknown tag
0001050100000000
61 Application Template
4F Application Identifier (AID) – card
A0000003591010028001
87 Application Priority Indicator
01
9F0A Unknown tag
0001050100000000
61 Application Template
4F Application Identifier (AID) – card
D27600002547410100
87 Application Priority Indicator
01
9F0A Unknown tag
0001050100000000
There are 3 applications with 3 different AIDs available on the card:
A00000005945430100: Zentraler Kreditausschuss (ZKA) Germany Girocard Electronic Cash
A0000003591010028001: Euro Alliance of Payment Schemes s.c.r.l. – EAPS Belgium Girocard EAPS ZKA (Germany)
D27600002547410100: ZKA Germany Girocard ATM
Step 2: Now I'm reading the first AID using the "Select AID" command - the AID is 18 characters = 9 bytes long:
selectAidCommand: 00 A4 04 00 09 A0 00 00 00 59 45 43 01 00 00
selectAidResponse: 6F 47 84 09 A0 00 00 00 59 45 43 01 00 A5 3A 50 08 67 69 72 6F 63 61 72 64 87 01 01 9F 38 06 9F 02 06 9F 1D 02 5F 2D 04 64 65 65 6E BF 0C 1A 9F 4D 02 19 0A 9F 6E 07 02 80 00 00 30 30 00 9F 0A 08 00 01 05 01 00 00 00 00 90 00
Parsed response:
6F File Control Information (FCI) Template
84 Dedicated File (DF) Name
A00000005945430100
A5 File Control Information (FCI) Proprietary Template
50 Application Label
g i r o c a r d
87 Application Priority Indicator
01
9F38 Processing Options Data Object List (PDOL)
9F02 06
9F1D 02
5F2D Language Preference
d e e n
BF0C File Control Information (FCI) Issuer Discretionary Data
9F4D Log Entry
190A
9F6E Unknown tag
02800000303000
9F0A Unknown tag
0001050100000000
Step 3: get the processing options to read the card details
This is the first "tricky" point as it is not easy how to explain to get the right data for your card/AID. In the above response there is a section for the Processing Options Data Object List (PDOL) the card is requesting and the length of the fields - here we do have 2 fields with a length of 6 and 2 bytes, in total 8 bytes. The 8 bytes are just 8 "x00"s with the "header" 83 08, so the complete length is 10 bytes = x0A:
9F38 Processing Options Data Object List (PDOL)
9F02 06
9F1D 02
A more detailed explanation can be found here: https://stackoverflow.com/a/20810855/8166854
getProcessingOptionsCommand: 80 A8 00 00 0A 83 08 00 00 00 00 00 01 00 00 00
getProcessingOptionsResponse: 77 1E 82 02 19 80 94 18 18 01 01 00 20 01 01 00 20 04 04 00 08 05 05 01 08 07 07 01 08 03 03 01
Parsed response:
77 Response Message Template Format 2
82 Application Interchange Profile
1980
94 Application File Locator (AFL)
18010100 20010100 20040400 08050501 08070701 08030301
The most important part for the next step is the "Application File Locator (AFL)" - we need to read the file system with the data that are coded in these 4 byte blocks.
Step 4: read the records from the card
This is the part where I get lost when trying to read the card. You need to get the SFI and RECORD from the first 3 bytes of an AFL block and run a read record command. The following command reads the 4th sector of the AFL list - the command may work or not with your card and if it works you may get different data from your card.
WARNING: providing the response data to an internet form may reveal data like account number or
credit card number - my response is masked so the account number is not 1111111111:
readRecordCommand: 00 B2 05 0C 00
readRecordResponse: 70 38 5F 24 03 21 12 31 5A 0A 67 26 42 89 11 11 11 11 11 7F 5F 34 01 02 5F 28 02 02 80 9F 07 02 FF C0 9F 0D 05 FC 40 A4 80 00 9F 0E 05 00 10 18 00 00 9F 0F 05 FC 40 A4 98 00 90 00
Parsed response:
70 EMV Proprietary Template
5F24 Application Expiration Date
211231
5A Application Primary Account Number (PAN)
6726428911111111117F
5F34 Application Primary Account Number (PAN) Sequence Number
02
5F28 Issuer Country Code
0280
9F07 Application Usage Control
FFC0
9F0D Issuer Action Code – Default
FC40A48000
9F0E Issuer Action Code – Denial
0010180000
9F0F Issuer Action Code – Online
FC40A49800
I strongly recommend that you use a library for the steps 3 and 4; I'm using
https://github.com/devnied/EMV-NFC-Paycard-Enrollment
for this.
This is just a basic explanation for the first steps but now you get some useful responds from your card - good luck for your next steps.
A complete Android example app for the above mentioned library is here (disclaimer: I'm the author):
https://github.com/AndroidCrypto/Android-EMV-NFC-Paycard-Example

Reading Mifare Classic returns strange characters

When reading a MIFARE card with Android and converting the data to UTF-8 I get strange characters like �.
I'm trying to build an application that can read some kind of ID card we're using. The problem now is that I get weird characters between words and some words are split between blocks so how can I safely get a word I'm looking for?
For instance my readings is something like this:
43224���19032019��
at block 2 sektor 2 bindex :8
and with splitting where rest of the number starting with 19 is at a new block:
�me Name���M���19
at block 1 sektor 1 bindex :4
930402���NO934951
at block 2 sektor 1 bindex :4
c5 42 4e 49 44 00 07 4f 4f 4f 4f 4f 4f 00 4b 42 "Åbnid" "OOOOOO" "KB"
44 44 44 20 44 44 44 44 44 00 82 4d 00 c9 31 39 "DDD DDDDD" "M" "19"
39 34 34 33 34 32 00 d0 4e 4f 39 36 36 36 35 31 "944342" "NO966651"
00 00 00 00 00 00 70 f7 88 00 00 00 00 00 00 00
30 32 32 20 20 41 53 00 d3 54 4f 54 41 4c 20 4b "022" "AS" "Total k"
4f 4e 54 52 4f 4c 4c 20 41 53 20 00 c9 30 32 38 "ONTROLL AS" "028"
37 30 34 33 33 00 c9 32 30 32 31 30 32 31 31 00 "70433" "20210211"
00 00 00 00 00 00 70 f7 88 00 00 00 00 00 00 00
This is how I read from the card:
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareClassic mfc = MifareClassic.get(tagFromIntent);
Here is my code I use for reading inside a for loop:
data = mfc.readBlock(bIndex + block);
and then for converting data to UTF8 for printing I use:
public String convertByteArrayToUTF8(byte[] bytes){
String encoded = null;
try {
encoded = new String(bytes, StandardCharsets.UTF_8);
}
catch (Exception e){
encoded = new String(bytes, Charset.defaultCharset());
}
return encoded;
}
I've tried with ASCII, UTF-16 etc with no luck.
First of all LOL for the question heading. I was in the same situation when I was a newbie. There is no tutorial online that provides you the exact code to read data from a Mifare classic card.
First understand the memory structure of the Mifare cards.
The memory of Mifare Classic divided into sectors, which are also divided into blocks of 16 bytes.
The MIFARE Classic 1K card has 16 sectors, each of which are divided into four blocks. If we do the math, we can figure out how the memory structure would be like: 16 bytes (1 block) * 4 blocks * 16 sectors = 1024 bytes.
The MIFARE Classic 4K card has 40 sectors, 32 of which are divided into four blocks and the remaining 8 are divided into 16 blocks. 16 bytes (1 block) * 4 blocks * 32 sectors + 16 bytes (1 block) * 16 blocks * 8 sectors = 4096 bytes. The memory structure is as follows:
The number on the blocks indicates its index. Each sector is protected by the site key written in the last block of the sector. For example, block 3 contains the site key for sector 1 and block 7 for sector 2. The last block in each sector also contains access conditions information such as “write”, “read” and “read & write”. The following figure demonstrates how the last block consists of:
Moreover, the data written in the card is binary i.e; 0 & 1.
Now, the steps you need to follow to read the data are:
step1: check whether the device support NFC or not.
step2: check if the device has NXP chip (especially for reading Mifare classic cards).
step3: instantiate the NFC manager and NFC adpater & define the techlist of card that you want to read.
step4: ask permission to access device NFC.
step5: create a intent to detect card and specify the MIME type you want to read(in most cases it is all MIME types).
step6: enable and disable foreground dispatch of adapter in onResume() and onPause() so that your app gets the priority to read the card when your activity is in foreground.
step7: When card comes in contact to device, you can get the tag information from intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
step8: read the card information i.e; card type, tech list etc..
step9: to read the data in the card you need to connect to the card via tag info retrieved above.
step10: iterate through all the sectors. Authenticate each sector with the default key
//https://developer.android.com/reference/android/nfc/tech/MifareClassic.html#authenticateSectorWithKeyA(int,%20byte[])
step11: on successful authentication read the binary data in the blocks of each sector.
step12: convert the binary data to string data so that we can read it.
step13: That's all, do whatever you want to do with the data.
surprise! get the complete working code at my github repositiory here:
https://github.com/codes29/RFIDReader
Note: I empathised how you feeling as a newbie and got this task where there is no proper tutorial for the same. So I updated my code that I wrote after a lot of struggle for days.
Here's the sample that you'll get after successful authentication and reading the data. The card that I scanned is empty as per now. But if there is data here then it'll surely be here instead of 0's.
Cheers! Happy coding bro!
So the data on your tag (excluding the sector trailers looks somewhat like that:
C5 42 4E 49 44 00 07 4F 4F 4F 4F 4F 4F 00 4B 42 ÅBNID..OOOOOO.KB
44 44 44 20 44 44 44 44 44 00 82 4D 00 C9 31 39 DDD DDDDD.‚M.É19
39 34 34 33 34 32 00 D0 4E 4F 39 36 36 36 35 31 944342.ÐNO966651
30 32 32 20 20 41 53 00 D3 54 4F 54 41 4C 20 4B 022 AS.ÓTOTAL K
4F 4E 54 52 4F 4C 4C 20 41 53 20 00 C9 30 32 38 ONTROLL AS .É028
37 30 34 33 33 00 C9 32 30 32 31 30 32 31 31 00 70433.É20210211.
This seems to be some form of structured data. Simply converting the whole binary blob into a UTF-8 (or ASCII) encoded string doesn't make much sense. Instead, you will need to reverse engineer the way that the data is structured (or, even better, you try to obtain the specification from the system manufacturer).
From what I can see, it looks as if that data consisted of multiple null-terminated strings embedded into some compact (Tag)-Length-Value format. The first byte seems to be the tag(?) + length, so we have
C5 Length = 5
42 4E 49 44 00 "BNID"
07 Length = 7
4F 4F 4F 4F 4F 4F 00 "OOOOOO"
4B Length = 11
42 44 44 44 20 44 44 44 44 44 00 "KBDDD DDDDD"
82 Length = 2
4D 00 "M"
C9 Length = 9
31 39 39 34 34 33 34 32 00 "19944342"
D0 Length = 16
4E 4F 39 36 36 36 35 31 30 32 32 20 20 41 53 00 "NO966651022 AS"
D3 Length = 19
54 4F 54 41 4C 20 4B 4F 4E 54 52 4F 4C 4C 20 41 53 20 00 "TOTAL KONTROLL AS "
C9 Length = 9
30 32 38 37 30 34 33 33 00 "02870433"
C9 Length = 9
32 30 32 31 30 32 31 31 00 "20210211"
The first byte could, for instance, be split into tag and length like this: TTTL LLLL (upper 3 bits encode the tag, lower 5 bits encode the length of the following value). This would give the following tags
0x6 for "BNID", "19944342", "NO966651022 AS", "TOTAL KONTROLL AS ", "02870433", and "20210211"
0x0 for "OOOOOO"
0x2 for "KBDDD DDDDD"
0x4 for "M"
Hence, the split between tag and length might also be TTLL LLLL (upper 2 bits encode the tag, lower 6 bits encode the length of the following value).
Unfortunately, the format doesn't resemble any of the popular formats that I'm aware of. So you could just continue your reverse engineering by comparing multiple different cards and by deriving meaning from the values.
So far, in order to decode the above, you would start by reading the first byte, extract the length from that byte, cut that amount of follow-up bytes and convert them into a string (based on the sample that you provided, ASCII encoding should do). You can then continue with the next byte, extract the length information from it, ...

Stream h264 to javafx possibly using javacv/ffmpeg

I'm really stuck on getting a video stream to play on a java fx project.
-- Short version:
I'm streaming h264/avcc flavor video from an android phone to a desktop computer. However javafx doesn't have an easy solution for displaying stream. I'm attempting to use javacv / ffmpeg in an attempt to make this work. However I am getting errors from ffmpeg.
1) Is there a better way to display streaming video on javafx?
2) Do you have a sample project or good tutorial for javacv ffmpegframegrabber?
3) I think I may be missing some small detail in mycode but Im not sure what i would be.
-- Longer Version:
1) On the android end Im getting video using mediarecorder. In order to get the sps/pps info I record and save a small movie to the device and then parse the sps and pps data.
2) Next, on the android, I split up the nalus to meet MTU req and send them over a udp connection to my desktop
3)On my desktop I reassmble the nalus( or trash them if they loose data) and feed those to an input stream that I gave to the framegreabber constructor.
-- The Code and Logs:
The errors are long and numerous depending on the flavor I feed it. Here are two separate examples which are usually repeated at great length
[h264 # 0000020225907a40] non-existing PPS 0 referenced
[h264 # 0000020225907a40] decode_slice_header error
[h264 # 0000020225907a40] no frame!
[h264 # 00000163d8637a40] illegal aspect ratio
[h264 # 00000163d8637a40] pps_id 3412 out of range
[AVBSFContext # 00000163e28a0e00] Invalid NAL unit 0, skipping.
!! One big caveat that I am aware off is that I have not implemented timestamps
which I created on the android device when feeding ffmpeg. I think it should still show distorted images without this though
Because I have spent all day guessing and trying I have several "flavors" of data I have shoved through. I am only showing the first section of each nal which I believe if correct would at least show a garbage image as long as my sps and pps are right
sps: 67 80 80 1E E9 01 68 22 FD C0 36 85 09 A8
pps: 68 06 06 E2
Below is annex B style.
These were each prefixed with either 00 00 01 and 00 00 00 01
Debug transfer 65 B8 40 0B E5 B8 7B 80 5B 85
Debug transfer 41 E2 20 7A 74 34 3B D6 BE FA
Debug transfer 41 E4 40 2F 01 E0 0C 06 EE 91
Debug transfer 41 E6 60 3E A1 20 5A 02 3C 6D
Debug transfer 41 E8 80 13 B0 B9 82 C3 03 F4
Debug transfer 41 EC C0 1B A3 0C 28 F1 B0 C8
Debug transfer 41 EE E0 1F CE 07 30 EE 05 06
Debug transfer 41 F1 00 08 ED 80 9C 20 09 73
Debug transfer 41 F3 20 09 E9 00 86 60 21 C3
VideoDecoderaddPacket type: 24
Debug transfer 67 80 80 1E E9 01 68 22 FD C0
Debug transfer 68 06 06 E2
Debug transfer 65 B8 20 00 9F 80 78 00 12 8A
Debug transfer 41 E2 20 09 F0 1E 40 7B 0C E0
Debug transfer 41 E4 40 09 F0 29 30 D6 00 AE
Debug transfer 41 E6 60 09 F1 48 31 80 99 40
[h264 # 000001c771617a40] non-existing PPS 0 referenced
Here I tried Avcc style. You can see the first line is the combination of the sps pps followed by idr and then repeated non idr
Debug transfer 18 00 0E 67 80 80 1E E9 01 68
Debug transfer 00 02 4A 8F 65 B8 20 00 9F C5
Debug transfer 00 02 2F DA 41 E2 20 09 E8 0F
Debug transfer 00 02 2C 34 41 E4 40 09 F4 20
Debug transfer 00 02 4D 92 41 E6 60 09 FC 2B
Debug transfer 00 02 47 02 41 E8 80 09 F0 72
Debug transfer 00 02 52 50 41 EA A0 09 EC 0F
Debug transfer 00 02 58 8A 41 EC C0 09 FC 6F
Debug transfer 00 02 55 F9 41 EE E0 09 FC 6E
Debug transfer 00 02 4D 79 41 F1 00 09 F0 3E
Debug transfer 00 02 4D B6 41 F3 20 09 E8 64
The following class is where I try to get javacv/ffmpeg to show the video. I dont think its an ideal solution and am researching canvasfram as a replacement to the image view.
public class ImageDecoder {
private final static String TAG = "ImageDecoder ";
private ImageDecoder(){
}
public static void streamImageToImageView(
final ImageView view,
final InputStream inputStream,
final String format,
final int frameRate,
final int bitrate,
final String preset,
final int numBuffers
)
{
System.out.println("Image Decoder Starting...");
try( final FrameGrabber grabber = new
FFmpegFrameGrabber(inputStream))
{
final Java2DFrameConverter converter = new Java2DFrameConverter();
grabber.setFrameNumber(frameRate);
grabber.setFormat(format);
grabber.setVideoBitrate(bitrate);
grabber.setVideoOption("preset", preset);
grabber.setNumBuffers(numBuffers);
System.out.println("Image Decoder waiting on grabber.start...");
grabber.start(); //---- this call is blocking the loop
System.out.println("Image Decoder Looping---------------------------
-------- hit stop");
while(!Thread.interrupted()){
//System.out.println("Image Decoder Looping");
final Frame frame = grabber.grab();
if (frame != null){
final BufferedImage bufferedImage =
converter.convert(frame);
if (bufferedImage != null){
Platform.runLater(() ->
view.setImage(SwingFXUtils.toFXImage(bufferedImage, null)));
}else{
System.out.println("no buf im");
}
}else{
System.out.println("no fr");
Thread.currentThread().interrupt();
}
}
}catch (Exception e){
System.out.print(TAG + e);
}
}
}
Any help is greatly appreciated.
So I had two problems.
The first was that my sps pps parsing method had a mistake. Notice the 2nd and 3rd bytes are same
The second was I accidentally over sized a buffer and created large 0x00 padded areas which emulated start codes.
This was a big project for me and I want to help other. Please visit my website where I wrote a lengthy multi-part discussion about streaming h264

Google wallet status is 'Unknown' after successfull 'Compute Crytographic Checksum' via Android isoDep.transceive

I'm still trying to emulate a point of sale (POS) system and complete a transaction with Google wallet.
I've gotten further with great answers on stack overflow.
See Android isoDep.transceive on Generate AC command always returns 6D00 unsupported
Even though every step of the communication from the POS and Google Wallet is successful, I can't get past Google wallet stating
"Status unknown, Check with cashier to see if the payment was successful".
I just need Google wallet to state "Status pending" just like at McDonalds (in the US).
I actually don't care if the whole transaction processes and clears my bank.
I'm new to transaction processing and it seems like I'm missing a fundamental step.
Any ideas would be greatly appreciated.
The following are the successful steps.
Step 1 Select Proximity Payment System Environment (2PAY.SYS.DDF01)
Send = 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
Response = 6f2f 840e 325041592e5359532e4444463031 a51d bf0c1a61184f07a00000 00041010870101500a4d 617374657243617264 9000 (Success)
Step 2 Select Payment Service
Send = 00 A4 04 00 07 A0 00 00 00 04 10 10 00
Response = 6f1e 8407 a0000000041010 a513 500a 4d617374657243617264 870101 9f11 01 01 9000 (Success)
Step 3 Get Processing Options
Send = 80 a8 00 00 02 83 00 00
Response = 770a 8202 0000 9404 08010100 9000 (Success)
Step 4 Read Record
Send = 00 B2 01 0C 00
Response = 70 7c 9f 6c 02
00 01 9f 62 06
00 00 00 00 00
38 9f 63 06 00
00 00 00 03 c6
56 29 42 35 33
39 36 XX XX XX
XX 31 XX XX 39
XX XX XX XX 5e
20 2f 5e 31 34
30 37 31 30 31
34 30 31 30 30
30 30 30 30 30
30 30 30 9f 64
01 04 9f 65 02
00 38 9f 66 02
03 c6 9f 6b 13
53 96 XX XX 1X
X9 XX XX d1 40
71 01 40 10 00
00 00 00 0f 9f
67 01 04 9f 69
0f 9f 6a 04 9f
7e 01 9f 02 06
5f 2a 02 9f 1a
02 9000 (Success)
Step 5 Compute Crytographic Checksum
Send = 80 2A 8E 80 0F 00 00 00 12 00 00 00 00 00 01 00 08 40 08 40 00
Response = 77 0f 9f 61 02 XX XX 9f 60 02 XX XX 9f 36 02 20 fa 9000 (Success)
The "PayPass – M/Chip Transaction Processing" specification states
"After the completion of the COMPUTE CRYPTOGRAPHIC CHECKSUM response, the
PayPass card can be removed from the PayPass reader."
So I assumed POS to Google Wallet communication was done, but Google Wallet seems to need more information.
So I assumed POS to Google Wallet communication was done, but Google Wallet seems to need more information.
Correct. Google Wallet retrieves information about transactions trough the card issuer's online backend system (at least that was the case with pre 2.0 version of GW, but I would assume that's still the case). Thus if you do not perform a real transaction (one that runs through the Master Card network), Google Wallet has no means to retrieve details about the transaction for the online backend.

Decoding a binary file

I am using the following code to read a structured binary file
FileInputStream objIS = new FileInputStream("/sdcard/waverider.usr");
DataInputStream objBR = new DataInputStream(objIS);
objwVer = objBR.readShort();
objwSVer = objBR.readShort();
objNoWaypoints = objBR.readShort();
System.out.println(objwVer);
System.out.println(objwSVer);
System.out.println(objNoWaypoints);
objIS.close();
This produces the result:
512
0
8706
The result I am after is
2
0
546
That is what I get with VB.net using:
objwVer = objBR.ReadInt16
objwSVer = objBR.ReadInt16
objNoWaypoints = objBR.ReadInt16
The binary file is as follow:
02 00 00 00 22 02 00 00 4b a9 c8 ff b2 2d 33 00
00 00 00 00 04 00 00 00 48 6f 6d 65 00 00 00 00
1c 68 53 0d 10 27 00 00 00 00 01 00 7e 8c c8 ff
Am I missing something here
9d 33 33 00 00 00 00 00 06 00 00 00
Your problem is that
your file is written in little endian byte order but your code is expecting big endian byte order.
Your stream is encoded in little-endian and DataInputStream only supports big-endian.
You could use ByteBuffer instead, which allows to parse little-endian formatted stream: http://developer.android.com/reference/java/nio/ByteOrder.html#LITTLE_ENDIAN
try JBBP framework, it is android compatible and its JBBPBitInputStream allows read data in different byte and bit order
new JBBPBitInputStream(in).readInt(JBBPByteOrder.LITTLE_ENDIAN);

Categories

Resources