How to read MSISDN from sim card by SIM_IO? - android

I need to read MSISDN in android, but we must use .c to finish it.
I open a socket to send RIL_REQUEST_SIM_IO to ril. Here is the log.
D/RILC ( 106): [0004]> SIM_IO (cmd=0xB2,efid=0x6F40,path=3F007F10,1,4,30,(null),pin2=(null),aid=(null))
...
D/RILC ( 106): [0004]< SIM_IO {sw1=0x90,sw2=0x0,ffffffffffffffffffffffffffff0891684125205260f5ffffffffff}
Did I use the right parameters (P1 = 1, P2 = 4, P3 = 30)?
And how can I get the mobile phone number by response?
Thank you!☺

What is your confusion here? You wanted to know what you told the card? All this information is in ISO 7816-4 and a few other specs, but here's the details of what you did:
You sent a read record command to the SIM (0xB2)
You asked for the Path:
3F00 -> (MF)
7F10 -> (DF_TELECOMM)
6F40 -> (MSISDN)
You set parameters:
P1 (record) = 1 (record 1)
P2 (reference control) = 4 (this mean use record number set in P1)
P3 (Le meaning bytes to read) = 30 (bytes)
and you got back success (SW stands for status word, you got SW1/SW2 = 0x9000 which means success) and the data (0xffffffffffffffffffffffffffff0891684125205260f5ffffffffff)
Checkout E.164 on parsing your MSISDN.

the data (0xffffffffffffffffffffffffffff0891684125205260f5ffffffffff) yes it contains MSISDN
----08 = means the Length of dial no
----91 = means MSISDN Internatioal dial No
the rest (684125205260f5) value u nid to swap it side by side of each 1 byte. example 68 swap 86, 41 swap 14...so on then u will got the MSISDNnumber.

In case it helps some1 later on:
Encoding can be found on TS 51.011. File is called EF_MSISDN. Its identifier is 6F40.
MSISDN is preceded by its length, then the TON/NPI. It is also in a BCD inverted format

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.

Pic16F688 has no stable readings via buletooth

I have spent much time trying to find out where is my mistakes while Im flashing the PIC16F688. The Pic has successfully flashed using PicKit2. Im using the Pic to convert analog pressure sensor to digital output and sending the data via Bluetooth, but the Bluetooth is not receiving stable numbers of data. The data is consist of 4 character decimal number that is between 0 and 1023.
The problem is that the Bluetooth can't wait at specific number and keep reading it, instead, it is reading the 4 digits in random.
I think my mistake is within the configuration of internal oscillator.
I'm attaching my code, the code is written to configure the flexiforce sensor circuit that outputs analog voltage up to 5v, and then the pic duty is to convert it to digital as I mentioned above.
it might be my wiring is not correct, please If you could help out with this one
and what configuration "at edit project" do I need to choose for Mikro PRO software?
I used "Bluetooth terminal" app to see my data asynchronous from Bluetooth.
Thank you.
char *temp = "0000";
unsigned int adc_value;
char uart_rd; int i;
void main()
{
OSCCON = 0x77;
ANSEL = 0b00000100;
CMCON0 = 0X07;
TRISA = 0b00001100;
UART1_Init(9600);
Delay_ms(100);
while (1)
{
adc_value = ADC_Read(2);
temp[0] = adc_value/1000+48;
temp[1] = (adc_value/100)%10+48;
temp[2] = (adc_value/10)%10+48;
temp[3] = adc_value%10+48;
for (i=0;i<4; i++)
UART1_Write(temp[i]);
UART1_Write(13);
Delay_ms(1000);
}
}
You can use itoa function to convert ADC integer value to characters for sending over UART. If there is error in calculation then you wont get appropriate value. Below code snippet for your reference :
while (1)
{
adc_value = ADC_Read(2);
itoa(adc_value, temp, 10);
for (i=0;i<4; i++)
UART1_Write(temp[i]);
UART1_Write(13);
Delay_ms(1000);
}
Please check Baud Rate you have configured at both ends is same or not. If baudrate mismatches then you will get Random value at Bluetooth Terminal where you are reading values.
What i would suggest, if you have a logic analyser, hook it up. If you don't recalculate your oscillator speed with the datasheet. It could just be that the internal oscillator is not accurate enough. What also works, is to write a function in assembly that waits a known time (by copy-pasting a lot of NOPs and using this to blink a led. Then start a stopwatch and count, say, 100 blinks. This is what i used to do before i had a logic analyser. (They are quite cheep on ebay).

Sending data from arduino through bluetooth serial

I’m currently trying to design a controller that would communicate through Bluetooth to an android phone (Galaxy Nexus). I’m facing a few challenges. Also, I don’t have much practical programming experience.
At the core of the controller resides an Arduino microcontroller who scans the state of 8 digital pins and six analogue pins (10 bits) and sends the data through serial, to an HC-05 Bluetooth chip.
The android phone should then read the serial information sent through Bluetooth and either transmit the packet to another phone - That will take me a while to implement as I know very little of how the internet works - or analyse and interpret it for further action to be taken
What I’m asking for are insight as to the best way to go about doing this. Now what does best mean?
We’ll I want it to be real time so when I press a button or a combination of bottoms, boom, the android phone takes action fast enough for a human not to perceive a delay.
Then I want to be able to associate the information the phone reads in the serial buffer to the corresponding button or analogue pin. In case there is an error or to avoid that they fall out of sync
Here is what I have so far. I have not tested this code yet, partly because I’m still learning how to program the android part of this project, partly because I want some feedback as to whether I’m being silly or this is actually an effective way to go about doing this:
//Initialization
/*
This Program has three functions:
1) Scan 8 digital pins and compile their state in a single byte ( 8 bits)
2) Scans 6 Analogue inputs corresponding to the joysticks and triggers
3) Send this info as packets through seril --> Bluetooth
*/
#include <SoftwareSerial.h>// import the serial software library
#define A = 2
#define B = 3
#define X = 4
#define Y = 5
#define LB = 6
#define RB = 7
#define LJ = 8
#define RJ = 9
#define RX = 10
#define TX = 11
//Pin 12 and 13 are unused for now
SoftwareSerial Bluetooth(RX,TX); //Setup software serial using the defined constants
// declare other variables
byte state = B00000000
void setup() {
//Setup code here, to run once:
//Setup all digital pin inputs
pinMode(A,INPUT);
pinMode(B,INPUT);
pinMode(X,INPUT);
pinMode(Y,INPUT);
pinMode(LB,INPUT);
pinMode(RB,INPUT);
pinMode(LJ,INPUT);
pinMode(RJ,INPUT);
//Setup all analogue pin inputs
//setup serial bus and send validation message
Bluetooth.begin(9600);
Bluetooth.println("The controller has successfuly connected to the phone")
}
void loop() {
//Main code here, to run repeatedly:
//Loop to sum digital inputs in a byte, left shift the byte every time by 1 and add that if the pin is high
for(byte pin = 2, b = B00000001; pin < 10; pin++, b = b << 1){ if (digitalRead(pin)== HIGH) state += b; }
//Send digital state byte to serial
Bluetooth.write(state);
//Loop to read analgue pin 0 to 5 and send it to serial
for( int pin = 0, testByte = 0x8000; pin < 6 ; pin++, testByte = testByte >> 1) { Bluetooth.write(analogRead(pin)+testByte); }
}
//Adding some validation would be wise. How would I go about doing that?
// Could add a binary value of 1000_0000_0000_0000, 0100_0000_0000_0000, 0010_0000_0000_0000 ... so on and then use a simple AND statement at the other end to veryfy what analogue reading the info came from
// so say the value for analgue is 1023 and came from analgue pin 1 I would have 0100_0011_1111_1111 now using an bitwise && I could check it against 0100_0000_0000_0000 if the result is 0100_0000_0000_0000 then I know this is the analogu reading from pin 1
//could easily implement a test loop with a shiting bit on the android side
Is it pointless for me to be doing bit shifts like this? Ultimately, if I’m not mistaken, all data is sent as bytes ( 8 bits packets) so will the Bluetooth.write(analogRead(pin)+testByte) actually send two bytes or will it truncate the int data? how will it be broken down and how can I recuperate it on the android end?
How would you go about implementing this? Any insights or words of advice?
It's great that you are learning this! Some suggestions:
Your code will be easier to read, understand and maintain if you space it out a bit, particularly by adding newlines...
void loop() {
//Main code here, to run repeatedly:
//Loop to sum digital inputs in a byte,
//left shift the byte every time by 1 and add that if the pin is high
for( byte pin = 2, b = B00000001; pin < 10; pin++, b = b << 1) {
if (digitalRead(pin)== HIGH)
state += b;
}
//Send digital state byte to serial
Bluetooth.write(state);
//Loop to read analgue pin 0 to 5 and send it to serial
for( int pin = 0, testByte = 0x8000; pin < 6 ; pin++, testByte = testByte >> 1) {
Bluetooth.write(analogRead(pin)+testByte);
}
}
Also, you can use the shift operators with values other than one. so instead of keeping a shift mask that you then add in, you just use the a simple variable. A more classic way to do what you expressing in the first looop would be something like this:
#define PIN_OFFSET 2
for ( int i=0; i < 8; i++) {
if (digitalRead( i+PIN_OFFSET)== HIGH)
state += (1 << i);
}
The second loop could be done similarly:
for( int pin = 0; pin < 6; pin++) {
short testByte = 0x8000 >> pin;
short result = analogRead(pin) + testByte;
Bluetooth.write( result >> 8);
Bluetooth.write( result & 0xFF);
}
Note that the Bluetooth.write() call sends a byte, so this code sends first the most significant byte, then the least.
Lastly, you probably want to zero your state variable at be beginning of loop() -- otherwise, once a bit is set it will never get cleared.
You may want to think about what you are sending to the phone. It will be binary data, and that can be difficult to deal with -- how do you know the start and end, and often a value will be misinterpretted as a control character messing you up big time. Consider changing it into a formatted, human readable string, with a newline at the end.
I hope that helps.
The Arduino end of this is more than fast enough to do what you want to do and you need not worry in the slightest about minimising the number of bytes you send out from the micro to the phone when you're talking about such a tiny amount of data. I'm not quite clear what you're sending to the phone; are you wanting a different value for each button so when a button is pressed it sends out something like:
Button Was Pressed, Button Number (Two bytes)
And if it's an analogue value:
Analogue Value Read, Analogue Value MSB, Analogue Value LSB (assuming the analogue value is greater than eight bits
I don't know the Arduino code you're using, but my suspicion is that this line:
Bluetooth.write(analogRead(pin)+testByte)
Would send one byte which is the addition of the analogue value and whatever testByte is.
Would you be able to post a link to the documentation for this API?
Any delay with all this will come at the phone end. Please don't concern yourself in the slightest about trying to save a byte or two at the Arduino end! (I'm currently doing a project with a Cortex M3 sending data via a Bluetooth module to Android phones and we're shipping several k of data around. I know from this experience the difference between two and twenty bytes is not of consequence in terms of delay.)
It may be good for you to opt for ready available bluetooth terminal apps for your android handset. On Google play, few apps are:
1) https://play.google.com/store/apps/details?id=arduino.bluetooth.terminal&hl=en
2) https://play.google.com/store/apps/details?id=com.sena.bterm&hl=en
(and few more are availble on Google play).This will help you to focus only on controller side development.

Polar Wearlink Bluetooth packet

i am looking at the code of a project called MyTracks:
http://code.google.com/r/jrgert-polar-bluetooth/source/browse/MyTracks/src/com/google/android/apps/mytracks/services/sensors/PolarMessageParser.java?r=ebc01faf49550bc9801633ff38bb3b8ddd6f5698
Now I am having problems with the method isValid(byte[] buffer). I don´t understand what exactly is he checking here. We want to know if the first byte in the array is the header containing 0xFE. I don´t quite understand the following lines :
boolean goodHdr = ((buffer[0] & 0xFF) == 0xFE);
boolean goodChk = ((buffer[2] & 0xFF) == (0xFF - (buffer[1] & 0xFF)));
return goodHdr && goodChk;
any ideas?
Ewoks is correct, refer to this blog post:
http://ww.telent.net/2012/5/3/listening_to_a_polar_bluetooth_hrm_in_linux
"Digging into src/com/google/android/apps/mytracks/services/sensors/PolarMessageParser.java we find a helpful comment revealing that, notwithstanding Polar's ridiculous stance on giving out development info (they don't, is the summary) the Wearlink packet format is actually quite simple.
Polar Bluetooth Wearlink packet example
Hdr - Len - Chk - Seq - Status - HeartRate - RRInterval_16-bits
FE - 08 - F7 - 06 - F1 - 48 - 03 64
where
Hdr always = 254 (0xFE),
Chk = 255 - Len
Seq range 0 to 15
Status = Upper nibble may be battery voltage
bit 0 is Beat Detection flag."
&0xff simply converts signed byte to unsigned int for doing the comparison
First line is checking is received buffer are starting with 0xFE as it should be with this Polar Wearable.
Second line is checking if length byte is correct as well because it's value by specification is 255-value writen is size byte..
This together is super simple verification that messages are correct (more complicated implementation would include CRC or other verification methods). cheers

How do you send an extended-ascii AT-command (CCh) from Android bluetooth to a serial device?

This one really has me banging my head. I'm sending alphanumeric data from an Android app, through the BluetoothChatService, to a serial bluetooth adaptor connected to the serial input of a radio transceiver.
Everything works fine except when I try to configure the radio on-the-fly with its AT-commands. The AT+++ (enter command mode) is received OK, but the problem comes with the extended-ascii characters in the next two commands: Changing the radio destination address (which is what I'm trying to do) requires CCh 10h (plus 3 hex radio address bytes), and exiting the command mode requires CCh ATO.
I know the radio can be configured OK because I've done it on an earlier prototype with the serial commands from PIC basic, and it also can be configured by entering the commands directly from hyperterm. Both these methods somehow convert that pesky CCh into a form the radio understands.
I've have tried just about everything an Android noob could possibly come up with to finagle the encoding such as:
private void command_address() {
byte[] addrArray = {(byte) 0xCC, 16, 36, 65, 21, 13};
CharSequence addrvalues = EncodingUtils.getString(addrArray, "UTF-8");
sendMessage((String) addrvalues);
}
but no matter what, I can't seem to get that high-order byte (CCh/204/-52) to behave as it should. All other (< 127) bytes, command or data, transmit with no problem. Any help here would be greatly appreciated.
-Dave
Welll ... turns out the BluetoothChat code re-creates the byte array with message.getBytes() before sending to the service. (after all, being chat code it would normally source only regular ascii strings) As others on this site have pointed out, getBytes() can create encoding issues in some cases. So, for purposes of sending these extended-ascii commands, I don't mess with strings and just send the byte array to the service with
private void sendCommand(byte[] cmd) {
mChatService.write(cmd);
}
The so-called command array is first initialized with placeholders for the hex radio address elements
byte[] addrArray = {(byte) 0xCC, 16, 0, 0, 0, 13};
and then filled in with the help of the conversion method
radioArray = HexStringToByteArray(radioAddr1);
which can be found here: HexStringToByteArray#stackoverflow

Categories

Resources