121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff/* 221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Copyright (C) 2012 The Android Open Source Project 321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License"); 521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * you may not use this file except in compliance with the License. 621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * You may obtain a copy of the License at 721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * http://www.apache.org/licenses/LICENSE-2.0 921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 1021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Unless required by applicable law or agreed to in writing, software 1121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS, 1221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * See the License for the specific language governing permissions and 1421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * limitations under the License. 1521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 1621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 1721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffpackage android.net.wifi.p2p.nsd; 1821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 1921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.WifiP2pDevice; 2021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.os.Parcel; 2121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.os.Parcelable; 2221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 2321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.io.ByteArrayInputStream; 2421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.io.DataInputStream; 2521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.io.IOException; 2621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.ArrayList; 2721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.Arrays; 2821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.List; 2921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 3021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff/** 3121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * The class for a response of service discovery. 3221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 3321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @hide 3421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 3521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffpublic class WifiP2pServiceResponse implements Parcelable { 3621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 3721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff private static int MAX_BUF_SIZE = 1024; 3821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 3921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 4021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Service type. It's defined in table63 in Wi-Fi Direct specification. 4121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 4221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff protected int mServiceType; 4321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 4421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 4521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Status code of service discovery response. 4621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * It's defined in table65 in Wi-Fi Direct specification. 4721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @see Status 4821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 4921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff protected int mStatus; 5021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 5121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 5221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Service transaction ID. 5321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * This is a nonzero value used to match the service request/response TLVs. 5421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 5521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff protected int mTransId; 5621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 5721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 5821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Source device. 5921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 6021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff protected WifiP2pDevice mDevice; 6121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 6221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 6321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Service discovery response data based on the requested on 6421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * the service protocol type. The protocol format depends on the service type. 6521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 6621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff protected byte[] mData; 6721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 6821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 6921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 7021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * The status code of service discovery response. 7121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Currently 4 status codes are defined and the status codes from 4 to 255 7221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * are reserved. 7321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 7421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * See Wi-Fi Direct specification for the detail. 7521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 7621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public static class Status { 7721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** success */ 7821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public static final int SUCCESS = 0; 7921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 8021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** the service protocol type is not available */ 8121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public static final int SERVICE_PROTOCOL_NOT_AVAILABLE = 1; 8221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 8321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** the requested information is not available */ 8421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public static final int REQUESTED_INFORMATION_NOT_AVAILABLE = 2; 8521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 8621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** bad request */ 8721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public static final int BAD_REQUEST = 3; 8821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 8921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** @hide */ 9021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public static String toString(int status) { 9121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff switch(status) { 9221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff case SUCCESS: 9321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return "SUCCESS"; 9421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff case SERVICE_PROTOCOL_NOT_AVAILABLE: 9521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return "SERVICE_PROTOCOL_NOT_AVAILABLE"; 9621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff case REQUESTED_INFORMATION_NOT_AVAILABLE: 9721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return "REQUESTED_INFORMATION_NOT_AVAILABLE"; 9821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff case BAD_REQUEST: 9921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return "BAD_REQUEST"; 10021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff default: 10121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return "UNKNOWN"; 10221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 10321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 10421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 10521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** not used */ 10621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff private Status() {} 10721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 10821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 10921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 11021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Hidden constructor. This is only used in framework. 11121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 11221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @param serviceType service discovery type. 11321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @param status status code. 11421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @param transId transaction id. 11521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @param device source device. 11621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @param data query data. 11721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 11821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff protected WifiP2pServiceResponse(int serviceType, int status, int transId, 11921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff WifiP2pDevice device, byte[] data) { 12021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff mServiceType = serviceType; 12121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff mStatus = status; 12221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff mTransId = transId; 12321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff mDevice = device; 12421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff mData = data; 12521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 12621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 12721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 12821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Return the service type of service discovery response. 12921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 13021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @return service discovery type.<br> 13121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * e.g) {@link WifiP2pServiceInfo#SERVICE_TYPE_BONJOUR} 13221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 13321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public int getServiceType() { 13421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return mServiceType; 13521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 13621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 13721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 13821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Return the status code of service discovery response. 13921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 14021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @return status code. 14121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @see Status 14221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 14321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public int getStatus() { 14421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return mStatus; 14521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 14621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 14721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 14821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Return the transaction id of service discovery response. 14921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 15021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @return transaction id. 15121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @hide 15221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 15321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public int getTransactionId() { 15421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return mTransId; 15521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 15621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 15721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 15821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Return response data. 15921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 16021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * <pre>Data format depends on service type 16121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 16221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @return a query or response data. 16321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 16421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public byte[] getRawData() { 16521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return mData; 16621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 16721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 16821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 16921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Returns the source device of service discovery response. 17021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 17121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * <pre>This is valid only when service discovery response. 17221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 17321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @return the source device of service discovery response. 17421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 17521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public WifiP2pDevice getSrcDevice() { 17621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return mDevice; 17721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 17821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 17921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** @hide */ 18021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public void setSrcDevice(WifiP2pDevice dev) { 18121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (dev == null) return; 18221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff this.mDevice = dev; 18321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 18421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 18521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 18621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 18721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Create the list of WifiP2pServiceResponse instance from supplicant event. 18821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 18921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * <pre>The format is as follows. 19021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * P2P-SERV-DISC-RESP <address> <update indicator> <response data> 19121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * e.g) P2P-SERV-DISC-RESP 02:03:7f:11:62:da 1 0300000101 19221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 19321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @param supplicantEvent wpa_supplicant event string. 19421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @return if parse failed, return null 19521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @hide 19621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 19721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public static List<WifiP2pServiceResponse> newInstance(String supplicantEvent) { 19821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 19921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff List<WifiP2pServiceResponse> respList = new ArrayList<WifiP2pServiceResponse>(); 20021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff String[] args = supplicantEvent.split(" "); 20121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (args.length != 4) { 20221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return null; 20321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 20421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff WifiP2pDevice dev = new WifiP2pDevice(); 20521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff String srcAddr = args[1]; 20621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dev.deviceAddress = srcAddr; 20721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff //String updateIndicator = args[2];//not used. 20821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff byte[] bin = hexStr2Bin(args[3]); 20921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (bin == null) { 21021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return null; 21121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 21221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 21321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bin)); 21421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff try { 21521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff while (dis.available() > 0) { 21621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /* 21721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Service discovery header is as follows. 21821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * ______________________________________________________________ 21921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * | Length(2byte) | Type(1byte) | TransId(1byte)}| 22021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * ______________________________________________________________ 22121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * | status(1byte) | vendor specific(variable) | 22221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 22321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff // The length equals to 3 plus the number of octets in the vendor 22421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff // specific content field. And this is little endian. 22521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int length = ((dis.readByte() & 0xff) + 22621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff ((dis.readByte() & 0xff) << 8)) - 3; 22721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int type = dis.readUnsignedByte(); 22821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff byte transId = dis.readByte(); 22921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int status = dis.readUnsignedByte(); 23021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (length < 0) { 23121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return null; 23221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 23321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (length == 0) { 23421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (status == Status.SUCCESS) { 23521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff respList.add(new WifiP2pServiceResponse(type, status, 23621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff transId, dev, null)); 23721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 23821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff continue; 23921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 24021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (length > MAX_BUF_SIZE) { 24121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dis.skip(length); 24221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff continue; 24321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 24421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff byte[] data = new byte[length]; 24521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dis.readFully(data); 24621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 24721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff WifiP2pServiceResponse resp; 24821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (type == WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR) { 2498bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff resp = WifiP2pDnsSdServiceResponse.newInstance(status, 25021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff transId, dev, data); 25121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } else if (type == WifiP2pServiceInfo.SERVICE_TYPE_UPNP) { 25221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff resp = WifiP2pUpnpServiceResponse.newInstance(status, 25321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff transId, dev, data); 25421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } else { 25521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff resp = new WifiP2pServiceResponse(type, status, transId, dev, data); 25621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 25721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (resp != null && resp.getStatus() == Status.SUCCESS) { 25821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff respList.add(resp); 25921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 26021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 26121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return respList; 26221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } catch (IOException e) { 26321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff e.printStackTrace(); 26421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 26521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 26621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (respList.size() > 0) { 26721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return respList; 26821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 26921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return null; 27021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 27121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 27221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** 27321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * Converts hex string to byte array. 27421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * 27521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @param hex hex string. if invalid, return null. 27621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @return binary data. 27721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */ 27821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff private static byte[] hexStr2Bin(String hex) { 27921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int sz = hex.length()/2; 28021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff byte[] b = new byte[hex.length()/2]; 28121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 28221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff for (int i=0;i<sz;i++) { 28321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff try { 28421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff b[i] = (byte)Integer.parseInt(hex.substring(i*2, i*2+2), 16); 28521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } catch (Exception e) { 28621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff e.printStackTrace(); 28721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return null; 28821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 28921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 29021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return b; 29121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 29221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 29321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff @Override 29421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public String toString() { 29521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff StringBuffer sbuf = new StringBuffer(); 29621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff sbuf.append("serviceType:").append(mServiceType); 29721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff sbuf.append(" status:").append(Status.toString(mStatus)); 29821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff sbuf.append(" srcAddr:").append(mDevice.deviceAddress); 29921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff sbuf.append(" data:").append(mData); 30021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return sbuf.toString(); 30121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 30221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 30321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff @Override 30421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public boolean equals(Object o) { 30521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (o == this) { 30621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return true; 30721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 30821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (!(o instanceof WifiP2pServiceResponse)) { 30921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return false; 31021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 31121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 31221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff WifiP2pServiceResponse req = (WifiP2pServiceResponse)o; 31321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 31421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return (req.mServiceType == mServiceType) && 31521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff (req.mStatus == mStatus) && 31621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff equals(req.mDevice.deviceAddress, mDevice.deviceAddress) && 31721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff Arrays.equals(req.mData, mData); 31821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 31921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 32021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff private boolean equals(Object a, Object b) { 32121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (a == null && b == null) { 32221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return true; 32321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } else if (a != null) { 32421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return a.equals(b); 32521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 32621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return false; 32721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 32821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 32921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff @Override 33021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public int hashCode() { 33121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int result = 17; 33221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff result = 31 * result + mServiceType; 33321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff result = 31 * result + mStatus; 33421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff result = 31 * result + mTransId; 33521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff result = 31 * result + (mDevice.deviceAddress == null ? 33621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 0 : mDevice.deviceAddress.hashCode()); 33721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff result = 31 * result + (mData == null ? 0 : mData.hashCode()); 33821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return result; 33921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 34021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 34121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** Implement the Parcelable interface {@hide} */ 34221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public int describeContents() { 34321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return 0; 34421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 34521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 34621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** Implement the Parcelable interface {@hide} */ 34721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public void writeToParcel(Parcel dest, int flags) { 34821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dest.writeInt(mServiceType); 34921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dest.writeInt(mStatus); 35021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dest.writeInt(mTransId); 35121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dest.writeParcelable(mDevice, flags); 35221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (mData == null || mData.length == 0) { 35321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dest.writeInt(0); 35421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } else { 35521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dest.writeInt(mData.length); 35621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff dest.writeByteArray(mData); 35721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 35821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 35921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 36021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff /** Implement the Parcelable interface {@hide} */ 36121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public static final Creator<WifiP2pServiceResponse> CREATOR = 36221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff new Creator<WifiP2pServiceResponse>() { 36321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public WifiP2pServiceResponse createFromParcel(Parcel in) { 36421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 36521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int type = in.readInt(); 36621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int status = in.readInt(); 36721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int transId = in.readInt(); 36821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff WifiP2pDevice dev = (WifiP2pDevice)in.readParcelable(null); 36921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff int len = in.readInt(); 37021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff byte[] data = null; 37121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (len > 0) { 37221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff data = new byte[len]; 37321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff in.readByteArray(data); 37421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 37521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff if (type == WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR) { 3768bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff return WifiP2pDnsSdServiceResponse.newInstance(status, 37721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff transId, dev, data); 37821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } else if (type == WifiP2pServiceInfo.SERVICE_TYPE_UPNP) { 37921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return WifiP2pUpnpServiceResponse.newInstance(status, 38021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff transId, dev, data); 38121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 38221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return new WifiP2pServiceResponse(type, status, transId, dev, data); 38321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 38421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff 38521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff public WifiP2pServiceResponse[] newArray(int size) { 38621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff return new WifiP2pServiceResponse[size]; 38721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff } 38821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff }; 38921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff} 390