Android Tv遥控器加密协议和具体添加方式

dongle加密协议规范与演示

一、通信端点:03

二、PID/VID

PID:0xB006
VID:0x1006

三、加密协议

1、 主机检测到 Dongle 插入,一秒钟后每隔 5 秒钟发送查询命令(只发送 5 次):

0x0D+0x43+0x57+0x52+0x55+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+crc8(Byte1-Byte18)
Dongle 答复:
0x0D+0x44+0x44+0x49+0x4e+0x47+0x4B+0x45+0x20+0x52+0x45+0x4d+0x4F+0x54+0x45+0x00+0x00+0x00+0x00+crc8(Byte1-Byte18)

2、 加密过程

主机收到 Dongle 答复后,生成两组 6 个随机数用作校验比如
unsigned char ramdom_tbl1[6] = {0x33, 0x44, 0x55, 0x31, 0x4e, 0xb9};
unsigned char ramdom_tbl2[6] = {0x88, 0x25, 0x4e, 0x99, 0xa7, 0xc7};
然后把第一组随机数组异或一组固定的数据
byte xor_table1[6] = {0xA8, 0x25, 0x3f, 0x97, 0x4e, 0xb9};
for(int i = 0; i < 6; i++){Data[i] = ramdom_tbl1 [i]^xor_table1[i];
}
主机把 Data 数组组合成加密数据包发送给 Dongle,格式如下:
0x0D+0x53+data[0]+data[1]+data[2]+data[3]+data[4]+data[5]+ ramdom_tbl2 [0]+ramdom_tbl2 [1]+ ramdom_tbl2 [2]+ ramdom_tbl2 [3]+ ramdom_tbl2 [4]+ramdom_tbl2 [5]+0x00+0x00+0x00+0x00+0x00+ crc8(Byte1-Byte18)
Dongle 收到加密验证代码后,会把收到第一组数据异或 xor_table1 恢复原值,然后把 ramdom 的数据跟 Dongle 的 Mac 地址进行相加,只保留低 8 位(溢出丢弃),得到的数据再跟一组固定数据进行异或计算得到 encrypt_tbl [6];
 byte Xor_table2[6] = {0x1c, 0xab, 0x17, 0x95, 0x3e, 0x9f};
Mac 地址的数据同样会进行异或 xor_table2 的计算得到 mac[6];Dongle 的回包格式即为
0x0D+0x54+encrypt[0]+ encrypt[1]+ encrypt[2]+ encrypt[3]+ encrypt[4]+encrypt[5]+mac[0]+mac[1]+mac[2]+mac[3]+mac[4]+mac[5]+0x00+0x00+0x00+0x00+0x00+crc8(Byte1-Byte18)
主机收到 Dongle 的回包后,把加密数据以及 Dongle 的 Mac 地址异或 xor_table2恢复回来,然后判断 encrypt 数据是否跟 ramdom_tbl1 跟 mac 数组各元素的和相等,如果都符合,则验证通过,不符合则验证失败。

四、示例

1、 原始数据

byte ramdom_tbl1[6] = {0x33, 0x44, 0x55, 0x31, 0x4e, 0xb9};
byte ramdom_tbl2[6] = {0x88, 0x25, 0x4e, 0x99, 0xa7, 0xc7};
byte xor_tbl1[6] = {0xA8, 0x25, 0x3f, 0x97, 0x4e, 0xb9};
byte xor_tbl2[6] = {0x1c, 0xab, 0x17, 0x95, 0x3e, 0x9f};
byte mac[6] = {0x13, 0x32, 0xbc, 0x55, 0x33, 0x55};

2、 交互过程

Master 发送:
0x0D+0x43+0x57+0x52+0x55+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x00+0x5d
Dongle 答复:
0x0D+0x44+0x44+0x49+0x4e+0x47+0x4B+0x45+0x20+0x52+0x45+0x4d+0x4F+0x54+0x45+0x00+0x00+0x00+0x00+0x9b
Master 发送:
0x0d+0x53+0x9b+0x61+0x6a+0xa6+0x00+0x00+0x88+0x25+0x4e+0x99+0xa7+0xc7+0x00+0x00+0x00+0x00+0x00+0xee
Dongle 答复:
0x0d+0x54+0x5a+0xdd+0x06+0x13+0xbf+0x91+0x0f+0x99+0xab+0xc0+0x0d+0xca+0x00+0x00+0x00+0x00+0x00+0xfb

五、CRC 校验算法

    public static byte getCrc(byte[] data, int offset, int length) {byte crc = 0;for (int i = offset; i < length; i++) {crc = (byte) (crc + data[i]);for (int j = 0; j < 8; j++) {if ((crc & 0x80) == 0) {crc = (byte) (crc << 1);} else {crc = (byte) ((crc << 1) ^ 0x31);}}}return crc;}

我是在androidFramework中去处理加密,目的是加密协议校验通过的遥控器可以操作电视。

下面就是具体的代码实现;通过插拔dongle开始进行处理;
可以在PhoneWindowManager中的interceptKeyBeforeDispatching方法调用isKeyEventAvailable方法做拦截处理
package com.android.internal.policy.impl;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.IUsbManager;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.InputDevice;
import android.view.KeyEvent;public class UsbDeviceManager extends BroadcastReceiver {private static final String TAG = "UsbDeviceManager";public static final char[] HEX = "0123456789ABCDEF".toCharArray();public static final int VID = 4310;public static final int PID = 45062;private final Context mContext;private final Object mLock = new Object();private final SparseArray<Device> mDevices = new SparseArray<Device>();public UsbDeviceManager(Context context) {mContext = context;IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_BOOT_COMPLETED);filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);filter.addAction("com.toptech.action.REQUEST_MAC_ADDRESS");mContext.registerReceiver(this, filter);}protected UsbManager getUsbManager() {return (UsbManager) mContext.getSystemService(Context.USB_SERVICE);}protected void onBootCompleted() {Log.d(TAG, "UsbDeviceManager - onBootCompleted.");UsbManager usbManager = getUsbManager();if (usbManager == null) {return;}HashMap<String, UsbDevice> devices = usbManager.getDeviceList();if (devices == null || devices.isEmpty()) {return;}for (UsbDevice usbDevice : devices.values()) {onUsbDeviceAdded(usbDevice);}}protected void onUsbDeviceAdded(UsbDevice usbDevice) {if (usbDevice == null) {return;}Device device = new Device(usbDevice);Log.d(TAG, "UsbDeviceManager - onUsbDeviceAdded: " + usbDevice + " >>> name: " + device.name());checkDevice(device);synchronized (mLock) {mDevices.put(usbDevice.getDeviceId(), device);}}protected void onUsbDeviceRemoved(UsbDevice usbDevice) {if (usbDevice == null) {return;}Log.d(TAG, "UsbDeviceManager - onUsbDeviceRemoved: " + usbDevice);Device device = mDevices.get(usbDevice.getDeviceId());if (device == null) {return;}device.status.set(Device.STATUS_REMOVED);synchronized (mLock) {mDevices.remove(usbDevice.getDeviceId());}}protected boolean checkPermission(UsbDevice device) {UsbManager usbManager = getUsbManager();if (usbManager == null) {return false;}if (device == null) {return false;}return usbManager.hasPermission(device);}protected boolean grantPermission(UsbDevice device) {if (device == null) {return false;}if (checkPermission(device)) {return true;}IBinder binder = ServiceManager.getService(Context.USB_SERVICE);IUsbManager manager = IUsbManager.Stub.asInterface(binder);final int uid = Binder.getCallingUid();try {manager.grantDevicePermission(device, uid);manager.setDevicePackage(device, mContext.getPackageName(), UserHandle.getUserId(uid));} catch (Exception e) {return false;}return checkPermission(device);}protected void checkDevice(Device device) {UsbManager usbManager = getUsbManager();if (usbManager == null) {return;}if (device == null) {return;}UsbDevice usbDevice = device.device();if (usbDevice.getVendorId() == VID && usbDevice.getProductId() == PID) {UsbDeviceConnection usbConnection = usbManager.openDevice(usbDevice);if (usbConnection == null) {device.status.set(Device.STATUS_INVALID);return;}UsbInterface usbInterface = getUsbInterface(usbDevice);if (usbInterface == null) {device.status.set(Device.STATUS_INVALID);return;}if (!usbConnection.claimInterface(usbInterface, true)) {device.status.set(Device.STATUS_INVALID);return;}if (!checkPermission(usbDevice)) {if (!grantPermission(usbDevice)) {Log.w(TAG, "Grant permission failed.");device.status.set(Device.STATUS_INVALID);return;}}new DeviceCheckThread(device, usbConnection, usbInterface).start();} else {device.status.set(Device.STATUS_CHECKED);}}protected Device getUsbDevice(String name) {if (TextUtils.isEmpty(name)) {return null;}synchronized (mLock) {for (int i = 0, j = mDevices.size(); i < j; i++) {Device device = mDevices.valueAt(i);if (name.equals(device.name())) {return device;}}}return null;}protected String getMacAddress(int vendorId, int productId) {synchronized (mLock) {for (int i = 0, j = mDevices.size(); i < j; i++) {Device device = mDevices.valueAt(i);if (device.device().getVendorId() == vendorId && device.device().getProductId() == productId) {if (TextUtils.isEmpty(device.mac())) {continue;}return device.mac();}}}return null;}public boolean isKeyEventAvailable(KeyEvent event) {if (event == null) {return false;}InputDevice device = event.getDevice();if (device.getVendorId() == 0 && device.getProductId() == 0) {return true;}Device usbDevice = getUsbDevice(device.getName());if (usbDevice == null) {return true;}return usbDevice.status() == Device.STATUS_CHECKED;}@Overridepublic void onReceive(Context context, Intent intent) {final String action = intent.getAction();Log.d(TAG, "action: " + action);if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {onBootCompleted();return;}if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {onUsbDeviceAdded((UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE));return;}if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {onUsbDeviceRemoved((UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE));return;}if ("com.toptech.action.REQUEST_MAC_ADDRESS".equals(action)) {Bundle extras = intent.getExtras();if (extras == null || extras.isEmpty()) {return;}int vendorId = extras.getInt("VendorId", 0);int productId = extras.getInt("ProductId", 0);if (vendorId == 0 && productId == 0) {return;}Log.d(TAG, "Request mac address -> vid: " + vendorId + ", pid: " + productId);String macAddress = getMacAddress(vendorId, productId);if (TextUtils.isEmpty(macAddress)) {return;}IBinder binder = extras.getBinder("Messenger");if (binder == null) {return;}Bundle result = new Bundle();result.putString("MacAddress", macAddress);Message message = Message.obtain();message.what = 0;message.obj = result;Messenger messenger = new Messenger(binder);try {messenger.send(message);} catch (RemoteException e) {e.printStackTrace();}return;}}private static UsbInterface getUsbInterface(UsbDevice device) {if (device == null) {return null;}for (int i = 0, j = device.getInterfaceCount(); i < j; i++) {UsbInterface usbInterface = device.getInterface(i);if (getInput(usbInterface) == null) {continue;}if (getOutput(usbInterface) == null) {continue;}return usbInterface;}return null;}private static UsbEndpoint getInput(UsbInterface usbInterface) {for (int i = 0; i < usbInterface.getEndpointCount(); ++i) {UsbEndpoint end = usbInterface.getEndpoint(i);if (end.getDirection() == UsbConstants.USB_DIR_IN) {return end;}}return null;}private static UsbEndpoint getOutput(UsbInterface usbInterface) {for (int i = 0; i < usbInterface.getEndpointCount(); ++i) {UsbEndpoint end = usbInterface.getEndpoint(i);if (end.getDirection() == UsbConstants.USB_DIR_OUT) {return end;}}return null;}private static List<String> getUsbPaths() {File directory = new File("/sys/bus/usb/devices");File[] files = directory.listFiles();if (files == null || files.length == 0) {return Collections.emptyList();}List<String> paths = new ArrayList<String>();for (File file : files) {String name = file.getName();if (TextUtils.isEmpty(name)) {continue;}if (!name.matches("\\d+-\\d+")) {continue;}String realPath;try {realPath = file.getCanonicalPath();} catch (IOException e) {continue;}paths.add(realPath);}return paths;}private static String getUsbDevicePath(File event) {if (event == null || !event.exists()) {return null;}Scanner scanner;try {scanner = new Scanner(event);while (scanner.hasNextLine()) {String line = scanner.nextLine();if (line.startsWith("DEVNAME=")) {return line.replace("DEVNAME=", "/dev/");}}} catch (FileNotFoundException e) {return null;}return null;}private static Map<String, String> getUsbDevices() {Map<String, String> devices = new HashMap<String, String>();List<String> paths = getUsbPaths();for (String path : paths) {File file = new File(path);if (!file.exists()) {continue;}File event = new File(file, "uevent");String devicePath = getUsbDevicePath(event);if (TextUtils.isEmpty(devicePath)) {continue;}devices.put(path, devicePath);}return devices;}private static String getUsbDevicePath(UsbDevice device) {if (device == null) {return null;}final String name = device.getDeviceName();if (TextUtils.isEmpty(name)) {return null;}Map<String, String> devices = getUsbDevices();if (devices == null || devices.isEmpty()) {return null;}for (String path : devices.keySet()) {if (name.equals(devices.get(path))) {return path;}}return null;}private static void send(UsbDeviceConnection connection, UsbEndpoint out, byte[] data) {if (connection == null || out == null) {return;}if (data == null || data.length == 0) {return;}String hex = bytesToHex(data);Log.d(TAG, "request: " + hex);try {connection.bulkTransfer(out, data, data.length, 0);} catch (Exception e) {Log.e(TAG, "send error.", e);}}private static byte[] read(UsbDeviceConnection connection, UsbEndpoint in, int timeout, int retry) {if (connection == null || in == null) {return null;}byte[] data = new byte[in.getMaxPacketSize()];for (int i = retry; i > 0; i--) {int length;try {length = connection.bulkTransfer(in, data, data.length, timeout);if (length <= 0) {continue;}} catch (Exception e) {continue;}String hex = bytesToHex(data, length);Log.d(TAG, "response: " + hex);return Arrays.copyOf(data, length);}return null;}public static String bytesToHex(byte[] bytes) {return bytesToHex(bytes, bytes.length);}public static String bytesToHex(byte[] bytes, int length) {char[] hexChars = new char[bytes.length * 2];for (int j = 0; j < Math.min(length, bytes.length); j++) {int v = bytes[j] & 0xFF;hexChars[j * 2] = HEX[v >>> 4];hexChars[j * 2 + 1] = HEX[v & 0x0F];}return new String(hexChars);}public static byte[] hex2Byte(String hex) {String[] parts = hex.split(" ");byte[] bytes = new byte[parts.length];for (int i = 0; i < parts.length; i++) {bytes[i] = (byte) Integer.parseInt(parts[i], 16);}return bytes;}public static boolean allEquals(byte[] bytes, byte value) {if (bytes == null || bytes.length == 0) {return false;}for (int i = 0; i < bytes.length; i++) {if (bytes[i] != value) {return false;}}return true;}public static String randomHexString(int length) {StringBuffer result = new StringBuffer();Random random = new Random();try {for (int i = 0; i < length; i++) {String hexString = Integer.toHexString(random.nextInt(255));if (hexString.length() == 1) {result.append("0");}result.append(hexString).append(" ");}return result.toString();} catch (Exception e) {e.printStackTrace();}return null;}public static byte getCrc(byte[] data, int offset, int length) {byte crc = 0;for (int i = offset; i < length; i++) {crc = (byte) (crc + data[i]);for (int j = 0; j < 8; j++) {if ((crc & 0x80) == 0) {crc = (byte) (crc << 1);} else {crc = (byte) ((crc << 1) ^ 0x31);}}}return crc;}private static String read(File file) {if (file == null || !file.exists()) {return null;}StringBuilder builder = new StringBuilder();Scanner scanner;try {scanner = new Scanner(file);while (scanner.hasNextLine()) {builder.append(scanner.nextLine()).append('\n');}builder.deleteCharAt(builder.length() - 1);} catch (FileNotFoundException e) {return null;}if (scanner != null) {scanner.close();}return builder.toString();}public static void write(File file, String content) {if (file == null) {return;}FileWriter writer;try {writer = new FileWriter(file);writer.write(content);writer.flush();} catch (IOException e) {return;}if (writer != null) {try {writer.close();} catch (IOException e) {e.printStackTrace();}}}class DeviceCheckThread extends Thread {final Device device;final UsbDeviceConnection usbConnection;final UsbInterface usbInterface;final UsbEndpoint in;final UsbEndpoint out;public DeviceCheckThread(Device device, UsbDeviceConnection usbConnection, UsbInterface usbInterface) {this.device = device;this.usbConnection = usbConnection;this.usbInterface = usbInterface;this.in = getInput(usbInterface);this.out = getOutput(usbInterface);}public boolean checkDevice(UsbDeviceConnection usbConnection, UsbEndpoint in, UsbEndpoint out) {if (usbConnection == null || in == null || out == null) {return false;}final byte[] xor_table1 = { (byte) 0xA8, (byte) 0x25, (byte) 0x3f, (byte) 0x97, (byte) 0x4e, (byte) 0xb9 };final byte[] xor_table2 = { (byte) 0x1c, (byte) 0xab, (byte) 0x17, (byte) 0x95, (byte) 0x3e, (byte) 0x9f };final byte[] random_table1 = hex2Byte(randomHexString(6));final byte[] random_table2 = hex2Byte(randomHexString(6));// Step 1{byte[] request = new byte[20];Arrays.fill(request, (byte) 0x00);request[0] = (byte) 0x0D;request[1] = (byte) 0x43;request[2] = (byte) 0x57;request[3] = (byte) 0x52;request[4] = (byte) 0x55;send(usbConnection, out, request);}// Step 2{byte[] response = read(usbConnection, in, 500, 3);if (response == null || response.length == 0) {Log.w(TAG, "Check device -> step 2: none response.");return false;}if (response.length < 2 || response[0] != (byte) 0x0D || response[1] != (byte) 0x44) {Log.w(TAG, "Check device -> step 2: invalid response.");return false;}byte[] request = new byte[20];Arrays.fill(request, (byte) 0x00);request[0] = (byte) 0x0D;request[1] = (byte) 0x53;request[2] = (byte) (random_table1[0] ^ xor_table1[0]);request[3] = (byte) (random_table1[1] ^ xor_table1[1]);request[4] = (byte) (random_table1[2] ^ xor_table1[2]);request[5] = (byte) (random_table1[3] ^ xor_table1[3]);request[6] = (byte) (random_table1[4] ^ xor_table1[4]);request[7] = (byte) (random_table1[5] ^ xor_table1[5]);request[8] = random_table2[0];request[9] = random_table2[1];request[10] = random_table2[2];request[11] = random_table2[3];request[12] = random_table2[4];request[13] = random_table2[5];request[19] = getCrc(request, 1, request.length - 1);send(usbConnection, out, request);}// Step 3{byte[] response = read(usbConnection, in, 500, 3);if (response == null || response.length == 0) {Log.w(TAG, "Check device -> step 3: none response.");return false;}if (response.length < 14 || response[0] != (byte) 0x0D || response[1] != (byte) 0x54) {Log.w(TAG, "Check device -> step 3: invalid response.");return false;}byte[] data = Arrays.copyOfRange(response, 2, 2 + 6);byte[] mac = Arrays.copyOfRange(response, 8, 8 + 6);byte[] data_xor = new byte[data.length];for (int i = 0; i < data.length; i++) {data_xor[i] = (byte) (data[i] ^ xor_table2[i]);}byte[] mac_xor = new byte[mac.length];for (int i = 0; i < mac.length; i++) {mac_xor[i] = (byte) (mac[i] ^ xor_table2[i]);}byte[] encrypt_xor = new byte[6];for (int i = 0; i < encrypt_xor.length; i++) {encrypt_xor[i] = (byte) (mac_xor[i] + random_table1[i]);}if (Arrays.equals(data_xor, encrypt_xor)) {Log.i(TAG, "Check device succeed.");return true;} else {Log.w(TAG, "Check device failed.");return false;}}}public String requestMacAddress(UsbDeviceConnection usbConnection, UsbEndpoint in, UsbEndpoint out) {if (usbConnection == null || in == null || out == null) {return null;}final byte[] mac = new byte[6];Arrays.fill(mac, (byte) 0x00);// Step 1{byte[] request = new byte[9];Arrays.fill(request, (byte) 0x00);request[0] = (byte) 0x0D;request[1] = (byte) 0xDB;request[2] = (byte) 0x61;request[3] = (byte) 0xBB;request[4] = (byte) 0x01;send(usbConnection, out, request);}// Step 2{byte[] response = read(usbConnection, in, 500, 3);if (response == null || response.length == 0) {Log.w(TAG, "Request mac address -> step 2: none response.");return null;}if (response.length < 3 || response[0] != (byte) 0x0D || response[1] != (byte) 0xDC || response[2] != (byte) 0x71) {Log.w(TAG, "Request mac address -> step 2: invalid response.");return null;}if (response.length < 9) {Log.w(TAG, "Request mac address -> step 2: invalid length.");return null;} else {for (int i = 0; i < mac.length; i++) {mac[i] = response[3 + i];}if (allEquals(mac, (byte) 0x00)) {Log.w(TAG, "Request mac address -> step 2: invalid data.");return null;}Log.d(TAG, "Check mac address: " + bytesToHex(mac));}byte[] request = new byte[9];Arrays.fill(request, (byte) 0x00);request[0] = (byte) 0x0D;request[1] = (byte) 0xDB;request[2] = (byte) 0x62;for (int i = 0; i < mac.length; i++) {request[i + 3] = mac[i];}send(usbConnection, out, request);}// Step 3{byte[] response = read(usbConnection, in, 500, 3);if (response == null || response.length == 0) {Log.w(TAG, "Request mac address -> step 3: none response.");return null;}if (response.length < 3 || response[0] != (byte) 0x0D || response[1] != (byte) 0xDC || response[2] != (byte) 0x72) {Log.w(TAG, "Request mac address -> step 3: invalid response.");return null;}if (response.length < 5 || response[3] != (byte) 0x06 || response[4] != (byte) 0x06) {Log.w(TAG, "Request mac address -> step 3: check failed.");return null;}}return bytesToHex(mac);}@Overridepublic void run() {try {device.status.set(Device.STATUS_CHECKING);if (checkDevice(usbConnection, in, out)) {if (device.status() != Device.STATUS_REMOVED) {device.status.set(Device.STATUS_CHECKED);}while (device.status() != Device.STATUS_REMOVED) {String mac = requestMacAddress(usbConnection, in, out);if (TextUtils.isEmpty(mac)) {try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}continue;}device.mac.set(mac);if (!TextUtils.isEmpty(device.path())) {File file = new File(device.path(), "mac");write(file, mac);}break;}} else {if (device.status() != Device.STATUS_REMOVED) {device.status.set(Device.STATUS_INVALID);}}} finally {try {usbConnection.releaseInterface(usbInterface);usbConnection.close();} catch (Exception e) {}}}}static class Device {public static final int STATUS_IDLE     = 0;public static final int STATUS_CHECKING = 1;public static final int STATUS_CHECKED  = 2;public static final int STATUS_INVALID  = 3;public static final int STATUS_REMOVED  = 4;final AtomicInteger status = new AtomicInteger(STATUS_IDLE);final AtomicReference<String> mac = new AtomicReference<String>();final UsbDevice device;final String path;final String manufacturer;final String product;public Device(UsbDevice device) {this.device = device;path = getUsbDevicePath(device);if (TextUtils.isEmpty(path)) {manufacturer = null;product = null;} else {manufacturer = read(new File(path, "manufacturer"));product = read(new File(path, "product"));}}public String path() {return path;}public String manufacturer() {return manufacturer;}public String product() {return product;}public String name() {if (TextUtils.isEmpty(manufacturer) || TextUtils.isEmpty(product)) {return null;}return manufacturer + " " + product;}public int status() {return status.get();}public String mac() {return mac.get();}public UsbDevice device() {return device;}}}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部