Android NFC java.io.IOException: Transceive failed - android

I am working on an android application which can read and write on an NFC tag.
I have no problem reading a tag which I already wrote something on, but when I use a blank tag I have difficulties reading the UID of the tag in the HEX code.
I am using mifare classic tags and I read the UID directly in the hex with the readblock method. The strange thing is, it works perfectly on debugger mode where I get the UID. But when I am trying without debbuger I get the following exception:
java.io.IOException: Transceive failed
Here's my method to read into the tag :
static String getUID(Intent intent) {
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareClassic mc = MifareClassic.get(tagFromIntent);
try {
mc.connect();
Log.i("connect", "ok");
} catch (IOException e) {
// TODO Auto-generated catch block
Log.i("connect", "nok");
e.printStackTrace();
}
try {
boolean secA = mc.authenticateSectorWithKeyA(0, mc.KEY_DEFAULT);
Log.i("secA", "ok");
} catch (IOException e) {
Log.i("secA", "nok");
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
boolean secB = mc.authenticateSectorWithKeyB(0, mc.KEY_DEFAULT);
Log.i("secB", "ok");
} catch (IOException e) {
Log.i("secB", "nok");
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] uidBytes = null;
try {
uidBytes = mc.readBlock(0);
Log.i("bytes", "ok");
} catch (IOException e) {
Log.i("bytes", "nok");
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mc.close();
Log.i("close", "ok");
} catch (IOException e) {
Log.i("close", "nok");
// TODO Auto-generated catch block
e.printStackTrace();
}
if (uidBytes != null) {
String uid = HexToString(uidBytes);
return uid;
}
else { return "Repasser le tag";}
}
I have no idea how to fix this, since it works in debug mode.

This code works for me. you have to check the authentication before you can read a block.
MifareClassic mif = MifareClassic.get(detectedTag);
int ttype = mif.getType();
Log.d(TAG, "MifareClassic tag type: " + ttype);
int tsize = mif.getSize();
Log.d(TAG, "tag size: " + tsize);
int s_len = mif.getSectorCount();
Log.d(TAG, "tag sector count: " + s_len);
int b_len = mif.getBlockCount();
Log.d(TAG, "tag block count: " + b_len);
try {
mif.connect();
if (mif.isConnected()){
for(int i=0; i< s_len; i++){
boolean isAuthenticated = false;
if (mif.authenticateSectorWithKeyA(i, MifareClassic.KEY_MIFARE_APPLICATION_DIRECTORY)) {
isAuthenticated = true;
} else if (mif.authenticateSectorWithKeyA(i, MifareClassic.KEY_DEFAULT)) {
isAuthenticated = true;
} else if (mif.authenticateSectorWithKeyA(i,MifareClassic.KEY_NFC_FORUM)) {
isAuthenticated = true;
} else {
Log.d("TAG", "Authorization denied ");
}
if(isAuthenticated) {
int block_index = mif.sectorToBlock(i);
byte[] block = mif.readBlock(block_index);
String s_block = NfcUtils.ByteArrayToHexString(block);
Log.d(TAG, s_block);
}
}
}
mif.close();
} catch (IOException e) {
e.printStackTrace();
}

May be There is Authentication Issue.
You can Authenticate this in this Way....
if (mfc.authenticateSectorWithKeyA(sectorNumber,
MifareClassic.KEY_MIFARE_APPLICATION_DIRECTORY)) {
Log.d("TAG", "Authorized sector with MAD key");
} else if (mfc.authenticateSectorWithKeyA(
sectorNumber, MifareClassic.KEY_DEFAULT)) {
Log.d("TAG",
"Authorization granted to sector with DEFAULT key");
} else if (mfc
.authenticateSectorWithKeyA(sectorNumber,
MifareClassic.KEY_NFC_FORUM)) {
Log.d("TAG",
"Authorization granted to sector with NFC_FORUM key");
} else {
Log.d("TAG", "Authorization denied ");
return false;
}
Here SectorNumber is : The sector you want to authenticate. eg:0,1,2....15 for mifare Classic 1K
When Authentication is done Then you can read or write.

Related

Android VpnService block packets

Edit:- i'm able to start the internet using vpn.The other issues is that now i'm receiving packets in my service in this piece of code of my VpnService.But i can't think of a proper way to block particular website.I've tried using name resolution using InnetAddress but that's not giving the expected result :
**#Override
public void run()
{
Log.i(TAG, "Started");
FileChannel vpnInput = new FileInputStream(vpnFileDescriptor).getChannel();
FileChannel vpnOutput = new FileOutputStream(vpnFileDescriptor).getChannel();
try
{
ByteBuffer bufferToNetwork = null;
boolean dataSent = true;
boolean dataReceived;
while (!Thread.interrupted())
{
if (dataSent)
bufferToNetwork = ByteBufferPool.acquire();
int readBytes = vpnInput.read(bufferToNetwork);
if (readBytes > 0)
{
dataSent = true;
bufferToNetwork.flip();
Packet packet = new Packet(bufferToNetwork);
Log.e("loggg packet",packet.toString());
if (packet.isUDP())
{
deviceToNetworkUDPQueue.offer(packet);
}
else if (packet.isTCP())
{
deviceToNetworkTCPQueue.offer(packet);
}
else
{
Log.w(TAG, "Unknown packet type");
dataSent = false;
}
}
else
{
dataSent = false;
}
ByteBuffer bufferFromNetwork = networkToDeviceQueue.poll();
if (bufferFromNetwork != null)
{
bufferFromNetwork.flip();
vpnOutput.write(bufferFromNetwork);
dataReceived = true;
ByteBufferPool.release(bufferFromNetwork);
}
else
{
dataReceived = false;
}
if (!dataSent && !dataReceived)
Thread.sleep(10);
}
}
catch (InterruptedException e)
{
Log.i(TAG, "Stopping");
}
catch (IOException e)
{
Log.w(TAG, e.toString(), e);
}
finally
{
closeResources(vpnInput, vpnOutput);
}
}**
I'm receiving a packet in this format:
Packet{ip4Header=IP4Header{version=4, totalLength=40, protocol=TCP, headerChecksum=14192, sourceAddress=10.0.8.1, destinationAddress=216.58.196.100}, tcpHeader=TCPHeader{sourcePort=39217, destinationPort=443, sequenceNumber=800911985, acknowledgementNumber=823271551, headerLength=20, window=29596, checksum=32492, flags= ACK}, payloadSize=0}
I'm using THIS CODE for starter and unable to block packets.
Apps like greyshirts no root firewall and mobiwool no root firewall works perfectly and they are also vpn based.Any suggestion is most welcomed.

Hold and Unhold sip call using the PJSIP

I developing VOIP android application that make and receive the sip call.I Build the pjsip lilbrary as described in "http://trac.pjsip.org/repos/wiki/Getting-Started/Android".
1. Hold
MainActivity.prm.setOptions(pjsua_call_flag.PJSUA_CALL_UPDATE_CONTACT
.swigValue());
try {
MainActivity.currentCall.setHold(MainActivity.prm);
} catch (Exception e) {
e.printStackTrace();
}
I found this code on pjsip documentation,but this code does not work for put a call on Hold.There is no error message return.
2.Unhold
MainActivity.prm = new CallOpParam(true);
MainActivity.prm.getOpt().setFlag(1);
try {
MainActivity.currentCall.reinvite(MainActivity.prm);
} catch (Exception e) {
e.printStackTrace();
}
Thanks.
Here is my code for hold and unHold:
public void setHold(boolean hold) {
if ((localHold && hold) || (!localHold && !hold)) return;
if(currentCall == null) return;
CallOpParam param = new CallOpParam(true);
try {
if (hold) {
currentCall.setHold(param);
localHold = true;
} else {
CallSetting opt = param.getOpt();
opt.setAudioCount(1);
opt.setVideoCount(0);
opt.setFlag(pjsua_call_flag.PJSUA_CALL_UNHOLD.swigValue());
currentCall.reinvite(param);
localHold = false;
}
} catch (Exception e) {}
}
I hope it's helpful.

set bluetooth authentication PIN when listening from adapter

I'm making an app that needs to connect with a bluetooth device and get data from it... that device is set as master, so I needed to implement a Thread, where I listenUsingRfcommWithServiceRecord and wait for a connection from it:
public AcceptThread(Context context, String serverName, UUID myUUID) {
this.context = context;
BluetoothServerSocket tmp = null;
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(serverName, myUUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
Then on run I run the code socket = mmServerSocket.accept(5000) to wait until it starts pairing with the device:
public void run() {
BluetoothSocket socket = null;
while (true) {
try {
socket = mmServerSocket.accept(5000);
} catch (IOException e) {
Log.e(TAG,"IOException: " + e);
}
// If a connection was accepted
if (socket != null) {
// Manage the connection
ManageConnectedSocket manageConnectedSocket = new ManageConnectedSocket(socket);
manageConnectedSocket.run();
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
}
break;
}
}
}
The Device asks for an authentication PIN, and I need to have an automatic procedure... for that I though of implementing a broadcast receiver to know when the device is asked to par with another device:
IntentFilter filter = new IntentFilter(ACTION_PAIRING_REQUEST);
context.registerReceiver(mPairReceiver, filter);
and receive it:
private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_PAIRING_REQUEST.equals(action)) {
Log.e(TAG,"ACTION_PAIRING_REQUEST");
setBluetoothPairingPin(device);
}
}
};
In my setBluetoothPairingPin method I receive a BluetoothDevice object :
public void setBluetoothPairingPin(BluetoothDevice device) {
byte[] pinBytes = convertPinToBytes("0000");
try {
Log.e(TAG, "Try to set the PIN");
Method m = device.getClass().getMethod("setPin", byte[].class);
m.invoke(device, pinBytes);
Log.e(TAG, "Success to add the PIN.");
try {
device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, false);
Log.e(TAG, "Success to setPairingConfirmation.");
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
}
The problem is that I can't know when my socket receives information, and consecutively, can't know what is my BluetoothDevice to set Pairing Pin before it's connected...
Can someone help me on how to surpass this? Or is there other way to put the pin authentication when I'm listenning from BluetoothServerSocket?
If I'm not explaining correctly, please let me know...
Thanks in advance
With the help from this and this, I was able to make work for me...
My confusion was with the method setBluetoothPairingPin that I couldn't understand that the ACTION_PAIRING_REQUEST is actually called when the device is being starting to pairing, and that is when the PIN is asked from the user... so invoking BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);, and changing a bit of the set pairing method I manage to make it work...
Here's my final code:
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_PAIRING_REQUEST.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String PIN = "0000";
byte[] pin = new byte[0];
try {
pin = (byte[]) BluetoothDevice.class.getMethod("convertPinToBytes", String.class).invoke(BluetoothDevice.class, PIN);
BluetoothDevice.class.getMethod("setPin", byte[].class).invoke(device, pin);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}

How to retrieve the 'last sync' time for an account?

Is it possible to retrieve the time an account was last synchronized, like the system Settings->Accounts&Sync app does? I'm using Android 2.2.
Looking at the 2.2 source for AccountSyncSettings.java, I see the status is retrieved using:
SyncStatusInfo status = ContentResolver.getSyncStatus(account, authority);
but SyncStatusInfo and getSyncStatus don't seem to be part of the public API (marked with #hide). Is there some other way to get at this info?
You can use reflection to achieve this purpose.Here is my code to implement this
private long getLasySyncTime() {
long result = 0;
try {
Method getSyncStatus = ContentResolver.class.getMethod(
"getSyncStatus", Account.class, String.class);
if (mAccount != null && mSyncAdapter != null) {
Object status = getSyncStatus.invoke(null, mAccount,
mSyncAdapter.authority);
Class<?> statusClass = Class
.forName("android.content.SyncStatusInfo");
boolean isStatusObject = statusClass.isInstance(status);
if (isStatusObject) {
Field successTime = statusClass.getField("lastSuccessTime");
result = successTime.getLong(status);
TLog.d(WeixinSetting.class, "get last sync time %d", result);
}
}
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
TLog.d(WeixinSetting.class, e.getMessage() + e.getCause().getMessage());
} catch (IllegalArgumentException e) {
} catch (ClassNotFoundException e) {
} catch (NoSuchFieldException e) {
} catch (NullPointerException e) {
}
return result;
}
The Settings app uses ContentResolver.getSyncStatus(account, authority). However, this is not part of the public API. You can use it, but it could break with any future release.

simple geocoding example

I'm implementing a simple Geo-coding example where user enters an address and gets its latitude and longitude.
addr = Area_edtxt.getText().toString();
try {
list_addr = gc.getFromLocationName(addr, 1);
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("Location lookup failed", e.getMessage());
}
if (list_addr != null && list_addr.size() > 0 ){
latitude = list_addr.get(0).getLatitude();
longitude = list_addr.get(0).getLongitude();
latitude_edtxt.setText(latitude.toString());
longitude_edtxt.setText(longitude.toString());
}else {
latitude_edtxt.setText("Address not found");
}
but shows me error : Unable to open stack trace file '/data/anr/traces.txt' : Permission denied.
For a quick try you could use an AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
private class GeocodeTask extends AsyncTask<String, Integer, List> {
protected Long doInBackground(String... address) {
try {
return gc.getFromLocationName(address[0], 1)
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("Location lookup failed", e.getMessage());
}
}
protected void onPostExecute(List result) {
if (list_addr != null && list_addr.size() > 0 ){
latitude = list_addr.get(0).getLatitude();
longitude = list_addr.get(0).getLongitude();
latitude_edtxt.setText(latitude.toString());
longitude_edtxt.setText(longitude.toString());
}else {
latitude_edtxt.setText("Address not found");
}
}
}
new GeocodeTask().execute(addr);

Categories

Resources