Sending byte array from android native service to app - android

Im trying to return a byte array from an android native service(C++) to an android application using AIDL. Im calculating the byte array from two files and trying to split the final array at the client side using the length of byte array of one file.For Eg resultFinal= lengthof privKey + privKey + pubKey
std::ifstream _privKey("/etc/myPrivkey", std::ios::in | std::ios::binary);
std::vector<uint8_t> _privKeyContents((std::istreambuf_iterator<char>(_privKey)), std::istreambuf_iterator<char>());
std::ifstream _pubKey("/etc/myPubkey", std::ios::in | std::ios::binary);
std::vector<uint8_t> _pubKeyContents((std::istreambuf_iterator<char>(_pubKey)), std::istreambuf_iterator<char>());
vector<uint8_t> certFinal;
uint8_t keysize=_privKeyContents.size(); Verified this and the keysize is 161
resultFinal.insert(resultFinal.begin(),_pubKeyContents.begin(), _pubKeyContents.end());
resultFinal.insert(resultFinal.begin(),_privKeyContents.begin(), _privKeyContents.end());
resultFinal.insert(resultFinal.begin(),keysize);
I assume at the client side the first element of the byte array will be the size of the _privKeyContents and using that
value i can split the byte array in to two. I was expecting the first element of the byte array to be 161 but instead im getting -95
Can someone help me to identify the issue ? or Is my approach is wrong ? Please let me know if there any other input needed from my end
Thanks In advance
Ps: I dont have much idea about C++.

Related

IOException: write failed: EINVAL (Invalid argument) on UVC FileOutputStream in Kotlin

I'm trying to write Android Camera stream frames to the UVC Buffer using FileOutputStream. For context: the UVC Driver is working on the device and it has a custom built kernel.
I get 24 frames per second using imageAnalyzer:
imageAnalyzer = ImageAnalysis.Builder()
.setTargetAspectRatio(screenAspectRatio)
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888)
...
imageAnalysis.setAnalyzer(cameraExecutor) { image ->
val buffer = image.planes[0].buffer
val data = buffer.toByteArray()
...
}
Then based on UVC Specifications I build the header of the frame:
val header = ByteBuffer.allocate(26)
val frameSize = image.width * image.height * ImageFormat.getBitsPerPixel(image.format) / 8
val EOH = 0x01
val ERR = 0x00
val STI = 0x01
val REST = 0x00
val SRC = 0x00
val PTS = (System.currentTimeMillis() - referenceTime) * 10000
val endOfFrame = 0x01
val FID = (frameId).toByte()
Add all of the above to the header
header.putInt(frameSize)
header.putShort(image.width.toShort())
header.putShort(image.height.toShort())
header.put(image.format.toByte())
header.put(((EOH shl 7) or (ERR shl 6) or (STI shl 5) or (REST shl 4) or SRC).toByte())
header.putLong(PTS)
header.put(endOfFrame.toByte())
header.put(FID)
Open the FileOutputStream and try to write the header and the image:
val uvcFileOutputStream = FileOutputStream("/dev/video3", true)
uvcFileOutputStream.write(header.toByteArray() + data)
uvcFileOutputStream.close()
Tried to tweak the header/payload but I'm still getting the same error:
java.io.IOException: write failed: EINVAL (Invalid argument)
at libcore.io.IoBridge.write(IoBridge.java:654)
at java.io.FileOutputStream.write(FileOutputStream.java:401)
at java.io.FileOutputStream.write(FileOutputStream.java:379)
What could I be doing wrong? is the header format wrong?
I don't know the answer directly, but I was curious to look and have some findings. I focused on the Kotlin part, as I don't know about UVC and because I suspect the problem to be there.
Huge assumption
Since there's no link to the specification I just found this source:
https://www.usb.org/document-library/video-class-v15-document-set
within the ZIP I looked at USB_Video_Payload_Frame_Based_1.5.pdf
Page 9, Section 2.1 Payload Header
I'm basing all my findings on this, so if I got this wrong, everything else is. It could still lead to a solution though if you validated the same things.
Finding 1: HLE is wrong
HLE is the length of the header, not the image data. You're putting the whole image size there (all the RGB byte data). Table 2-1 describes PTS and SCR bits control whether PTS and SCR are present. This means that if they're 0 in BFH then the header is shorter. This is why HLE is either 2, 6, 12.
Confirmation source + the fact that the field is 1 byte long (each row of Table 2-1 is 1 byte/8 bits) which means the header can be only up to 255 bytes long.
Finding 2: all the header is misaligned
Since your putting HLE with putInt, you're writing 4 bytes, from this point on, everything is messed up in the header, the flags depend on image size, etc.
Finding 3: SCR and PTS flag inconsistencies
Assuming I was wrong about 1 and 2. You're still setting the SRC and PTS bit to 0, but pushing a long (8 bytes).
Finding 4: wrong source
Actually, something is really off at this point, so I looked at your referenced GitHub ticket and found a better example of what your code represents:
Sadly, I was unable to match up what your header structure is, so I'm going to assume that you are implementing something very similar to what I was looking at, because all PDFs had pretty much the same header table.
Finding 5: HLE is wrong or missing
Assuming you need to start with the image size, the HLE is still wrong because it's the image format's type, not in connection with SCR and PTS flags.
Finding 6: BFH is missing fields
If you're following one of these specs, the BFH is always one byte with 8 bits. This is confirmed by how the shls are putting it together in your code and the descriptions of each flag (flag = true|false / 1/0).
Finding 7: PTS is wrong
Multiplying something that is millisecond precise by 10000 looks strange. The doc says "at most 450 microseconds", if you're trying to convert between ms and us, I think the multiplier would be just 1000. Either way it is only an int (4 bytes) large, definitely not a long.
Finding 8: coding assistant?
I have a feeling after reading all this, that Copilot, ChatGPT or other generator wrote your original code. This sound confirmed by you looking for a reputable source.
Finding 9: reputable source example
If I were you I would try to find a working example of this in GitHub, using keyword search like this: https://github.com/search?q=hle+pts+sti+eoh+fid+scr+bfh&type=code the languages don't really matter since these are binary file/stream formats, so regardless of language they should be produced and read the same way.
Finding 10: bit order
Have a look at big endian / little endian byte order. If you look at Table 2-1 in the PDF I linked you can see which bit should map to which byte. You can specify the order you need easily on the buffer BEFORE writing to it, by the looks of the PDF it is header.order(ByteOrder.LITTLE_ENDIAN). I think conventionally 0 is the lowest bit and 31 is the highest. I can't cite a source on this, I seem to remember from uni. Bit 0 should be the 2^0 component (1) and bit 7 is the 2^7 (128). Reversing it would make things much harder to compute and comprehend. So PTS [7:0] means that byte is the lowest 8 bits of the 32 bit PTS number.
If you link to your specification source, I can revise what I wrote, but likely will find very similar guesses.

FIDO2 - Get Authenticator Info issue

I am developing Android authenticator.I am getting {-125,0,1,4} byte array from webauthn client after pairing. When I decoding this array
-125 (0x83) - MSG
1 (0x01) - length of the data
4 (0x04) - AuthenticatorGetInfo
I am not sure about 0 in this array. Please let me know is there any meaning for this 0.
For this request, I am sending response as CBOR data.
00a60182684649444f5f325f30665532465f563202816b686d61632d73656372657403506435323965353235383533343133663304a462726bf5627570f564706c6174f469636c69656e7450696ef505190400069f01ff
I am notifying above data by using Fido Status as follows.
for (byte[] frame : response.toFrames(mMTU)) {
getFidoStatus().setValue(frame);
mGattServer.notifyCharacteristicChanged(device, getFidoStatus(), true);
}
After that I am not getting any request/response from webauthn client. I am sending KEEPALIVE(0x82) command with value PROCESSING(0x01) for every kKeepAliveMillis(500ms). Is there any issue with my implementation?
Please help me to proceed this. Thanks in advance.
This speciciation fully explains for you
https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-client-to-authenticator-protocol-v2.0-id-20180227.html#ble-framing-fragmentation
CMD is 0x83 (MSG)
Length of DATA is 2 bytes: HLEN byte and LLEN byte.
In your case, length of DATA is 0x0001 (= 1). The DATA is 0x04

How can I visualize PCM data

I have a PCM datafile that I know is valid. I can play it, edit it into pieces, etc. and it will always play, as well as the individual pieces.
But when I try to translate it into shorts from bytes
bytes[i] | (bytes[i+1] << 8)
The file is 16 bit, single channel and 44100 sampling. I don't see anything that looks like a wave file visually.
As a test I record led among silencer with one very loud sound in the middle. Still the chart I made from my intake looked like every other chart when I try this. Am I somehow doing this wrong? Or misunderstanding what I'm reading/attempting?
All am looking to do is detect a very low threshold to find a word gap.
Thanks
My psychic powers suggest this is a big-endian vs little-endian thing.
If the source file stores samples in big-endian, this is likely what you want:
(bytes[i] << 8) | (bytes[i+1])
For what it's worth, WAV files are little-endian.
Other possibilities include:
I don't see your code, but maybe your code is only incrementing i by 1 instead of 2 on every loop iteration. (A common mistake I've made in my own code).
signed types or casting. Be explicit how you do the bit operations with respect to signed vs. unsigned. I'm not sure if "bytes" is an array of "unsigned char" or "char". Nor am I sure if "char" defaults to signed or unsigned. This might be better:
unsigned char b1 = (unsigned char)(bytes[i]);
unsigned char b2 = (unsigned char)(bytes[i+1]);
short sample = (short)((b1 << 8) | (b2));

libpd on android: read [adc~] into buffer

I developed an Android app with libpd ( [adc~]->[*~ 0.5]->[dac~]). The app works fine. I get the voice from mic in my earpiece.
My questions are:
How can i catch the data from [adc~] into buffer array?
I want to send this buffer over network to another device and load it into [dac~].
How can i load the buffer array into [dac~]?
This action should be done in real/near time. Writefs~ and readfs~ to a disk don't fullfill.
well, a buffer in Pd is called [table].
first thing you need to is to instantiate a named table with agiven size.
e.g. the following will create a table named "foo" of 44100 samples length (1sec if you are running at 44.1kHz)
[table foo 44100]
you can write signals into that table with [tabwrite~] (which will start writing whenever it receives a [bang()
[adc~ 1]
|
| [bang(
| /
|/
[tabwrite~ foo]
and to read a signal from a table, use...[tabread~], or [tabplay~], or [tabread4~], or [tabosc~], or...
[bang(
|
[tabplay~ foo]
|
[dac~]

FFT audio input

I want to apply FFT on a signal recorded by AudioRecorder and saved to a wav file. the FFT i am using has a Complex[] input parameter. I am confused, is there a difference between converting from bytes to comlex dividing by 32768, and converting by just adding 0 to the imaginary part and leaving the real part as a byte?
Edit:
public Complex[] convertToComplex(byte[] file)
{
int size= file.length;
double[]x=new double[size];
Complex[]data= new Complex[size];
for(int i=0;i<size;i++)
{
x[i]=file[i]/32768.0;
data[i]=new Complex(x[i],0);
// Log.d("tag", "indice"+i+":"+data[i]);
}
return data;
}
If you are working with audio with a bit depth of 16 bits (each sample has 16 bits), then each byte will only have half of a sample.What you need to do is cast your bytes to 16 bit samples then divide the resulting number by 32768 (This is the magnitude of the smallest number a 2's complement 16 bit number can store i.e 2^15) to get the actual audio sample which is a number between -1 and 1.You will then convert this number to a complex number by setting it's imaginary component to 0.
A small C# sample can be seen below (indicative code):
byte[] myAudioBytes = readAudio();
int numBytes = myAudioBytes.Length;
var myAudioSamples = new List<short>();
for( int i = 0; i < numBytes; i = i + 2)
{
//Cast to 16 bit audio and then add sample
short sample = (short) ((myAudioBytes[i] << 8 | myAudioBytes[i + 1]) / 32768 );
myAudioSamples.Add(sample);
}
//Change real audio to Complex audio
var complexAudio = new Complex[myAudioSamples.Length];
int i = 0;
foreach(short sample in myAudioSamples)
complexAudio[i++] = new Complex(){ Real = sample, Imaginary = 0 };
//Now you can proceed to getting the FFT of your Audio here
Hope the code has guided you on how you should handle your audio.
Generalized FFT functions like working with arrays of complex inputs and outputs. So, for input, you might need to create an array of complex numbers which conform to the Complex data structure that the FFT library wants. This will probably consist of a real and an imaginary component for each. Just set the imaginary portion to 0. The real portion is probably a signed floating point number that is expected to fall between -1.0..1.0, so you are on the right track with dividing integer PCM samples. However, when you wrote "converting bytes", that raised a red flag. These are probably signed, little endian, 16-bit integer PCM samples, so be sure to cast them accordingly before dividing by 32768 (but this is Java, so types will be enforced a bit more stringently anyway).

Categories

Resources