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 Sheriff
2121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.io.ByteArrayInputStream;
2221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.io.DataInputStream;
2321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.io.IOException;
2421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.HashMap;
2521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.Map;
2621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
2721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff/**
2821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * A class for a response of bonjour service discovery.
2921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff *
3021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff * @hide
3121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */
328bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriffpublic class WifiP2pDnsSdServiceResponse extends WifiP2pServiceResponse {
3321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
3421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
3521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * DNS query name.
3621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * e.g)
3721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * for PTR
3821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * "_ipp._tcp.local."
3921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * for TXT
4021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * "MyPrinter._ipp._tcp.local."
4121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
4221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private String mDnsQueryName;
4321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
4421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
4521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Service instance name.
4621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * e.g) "MyPrinter"
4721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * This field is only used when the dns type equals to
488bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_PTR}.
4921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
5021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private String mInstanceName;
5121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
5221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
5321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * DNS Type.
548bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * Should be {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_PTR} or
558bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
5621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
5721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private int mDnsType;
5821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
5921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
608bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * DnsSd version number.
618bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * Should be {@link WifiP2pDnsSdServiceInfo#VERSION_1}.
6221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
6321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private int mVersion;
6421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
6521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
6621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Txt record.
6721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * This field is only used when the dns type equals to
688bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
6921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
70527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff    private final HashMap<String, String> mTxtRecord = new HashMap<String, String>();
7121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
7221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
7321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Virtual memory packet.
7421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * see E.3 of the Wi-Fi Direct technical specification for the detail.<br>
7521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * The spec can be obtained from wi-fi.org
7621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Key: pointer Value: domain name.<br>
7721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
7821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private final static Map<Integer, String> sVmpack;
7921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
8021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    static {
8121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sVmpack = new HashMap<Integer, String>();
8221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sVmpack.put(0x0c, "_tcp.local.");
8321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sVmpack.put(0x11, "local.");
8421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sVmpack.put(0x1c, "_udp.local.");
8521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
8621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
8721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
8821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Returns query DNS name.
8921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return DNS name.
9021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
9121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public String getDnsQueryName() {
9221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return mDnsQueryName;
9321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
9421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
9521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
9621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Return query DNS type.
9721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return DNS type.
9821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
9921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public int getDnsType() {
10021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return mDnsType;
10121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
10221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
10321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
10421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Return bonjour version number.
10521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return version number.
10621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
10721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public int getVersion() {
10821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return mVersion;
10921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
11021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
11121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
11221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Return instance name.
11321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return
11421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
11521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public String getInstanceName() {
11621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return mInstanceName;
11721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
11821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
11921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
12021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Return TXT record data.
12121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return TXT record data.
12221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
123527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff    public Map<String, String> getTxtRecord() {
12421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return mTxtRecord;
12521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
12621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
12721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    @Override
12821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public String toString() {
12921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sbuf = new StringBuffer();
1308bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        sbuf.append("serviceType:DnsSd(").append(mServiceType).append(")");
13121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sbuf.append(" status:").append(Status.toString(mStatus));
13221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sbuf.append(" srcAddr:").append(mDevice.deviceAddress);
13321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sbuf.append(" version:").append(String.format("%02x", mVersion));
13421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sbuf.append(" dnsName:").append(mDnsQueryName);
135527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff        sbuf.append(" TxtRecord:");
136527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff        for (String key : mTxtRecord.keySet()) {
137527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff            sbuf.append(" key:").append(key).append(" value:").append(mTxtRecord.get(key));
13821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
13921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mInstanceName != null) {
14021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sbuf.append(" InsName:").append(mInstanceName);
14121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
14221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sbuf.toString();
14321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
14421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
14521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
14621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * This is only used in framework.
14721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param status status code.
14821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dev source device.
14921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param data RDATA.
15021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @hide
15121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
1528bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff    protected WifiP2pDnsSdServiceResponse(int status,
15321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            int tranId, WifiP2pDevice dev, byte[] data) {
15421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR,
15521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                status, tranId, dev, data);
15621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (!parse()) {
15721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            throw new IllegalArgumentException("Malformed bonjour service response");
15821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
15921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
16021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
16121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
1628bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * Parse DnsSd service discovery response.
16321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
16421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return {@code true} if the operation succeeded
16521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
16621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean parse() {
16721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
16821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * The data format from Wi-Fi Direct spec is as follows.
16921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * ________________________________________________
17021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * |  encoded and compressed dns name (variable)  |
17121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * ________________________________________________
17221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * |       dnstype(2byte)      |  version(1byte)  |
17321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * ________________________________________________
17421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * |              RDATA (variable)                |
17521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
17621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mData == null) {
17721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            // the empty is OK.
17821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return true;
17921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
18021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
18121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(mData));
18221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
18321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mDnsQueryName = readDnsName(dis);
18421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mDnsQueryName == null) {
18521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
18621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
18721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
18821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        try {
18921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mDnsType = dis.readUnsignedShort();
19021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mVersion = dis.readUnsignedByte();
19121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        } catch (IOException e) {
19221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            e.printStackTrace();
19321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
19421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
19521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
1968bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR) {
19721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            String rData = readDnsName(dis);
19821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (rData == null) {
19921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                return false;
20021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
20121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (rData.length() <= mDnsQueryName.length()) {
20221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                return false;
20321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
20421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
20521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mInstanceName = rData.substring(0,
20621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    rData.length() - mDnsQueryName.length() -1);
2078bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        } else if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
208527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff            return readTxtData(dis);
20921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        } else {
21021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
21121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
21221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
21321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
21421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
21521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
21621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
21721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Read dns name.
21821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
21921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dis data input stream.
22021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return dns name
22121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
22221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private String readDnsName(DataInputStream dis) {
22321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
22421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
22521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // copy virtual memory packet.
22621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        HashMap<Integer, String> vmpack = new HashMap<Integer, String>(sVmpack);
22721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mDnsQueryName != null) {
22821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            vmpack.put(0x27, mDnsQueryName);
22921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
23021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        try {
23121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            while (true) {
23221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                int i = dis.readUnsignedByte();
23321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (i == 0x00) {
23421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    return sb.toString();
23521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                } else if (i == 0xc0) {
23621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    // refer to pointer.
23721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    String ref = vmpack.get(dis.readUnsignedByte());
23821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (ref == null) {
23921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        //invalid.
24021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        return null;
24121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
24221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(ref);
24321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    return sb.toString();
24421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                } else {
24521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    byte[] data = new byte[i];
24621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    dis.readFully(data);
24721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(new String(data));
24821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(".");
24921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
25021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
25121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        } catch (IOException e) {
25221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            e.printStackTrace();
25321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
25421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return null;
25521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
25621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
25721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
25821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Read TXT record data.
25921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
26021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dis
261527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff     * @return true if TXT data is valid
26221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
263527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff    private boolean readTxtData(DataInputStream dis) {
26421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        try {
26521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            while (dis.available() > 0) {
26621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                int len = dis.readUnsignedByte();
26721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (len == 0) {
26821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
26921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
27021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                byte[] data = new byte[len];
27121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                dis.readFully(data);
27221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                String[] keyVal = new String(data).split("=");
27321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (keyVal.length != 2) {
274527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff                    return false;
27521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
276527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff                mTxtRecord.put(keyVal[0], keyVal[1]);
27721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
278527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff            return true;
27921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        } catch (IOException e) {
28021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            e.printStackTrace();
28121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
282527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff        return false;
28321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
28421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
28521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
2868bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * Creates DnsSd service response.
28721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *  This is only called from WifiP2pServiceResponse
28821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
28921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param status status code.
29021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dev source device.
2918bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * @param data DnsSd response data.
2928bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * @return DnsSd service response data.
29321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @hide
29421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
2958bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff    static WifiP2pDnsSdServiceResponse newInstance(int status,
29621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            int transId, WifiP2pDevice dev, byte[] data) {
29721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (status != WifiP2pServiceResponse.Status.SUCCESS) {
2988bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff            return new WifiP2pDnsSdServiceResponse(status,
29921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    transId, dev, null);
30021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
30121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        try {
3028bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff            return new WifiP2pDnsSdServiceResponse(status,
30321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    transId, dev, data);
30421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        } catch (IllegalArgumentException e) {
30521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            e.printStackTrace();
30621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
30721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return null;
30821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
30921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff}
310