WifiP2pDnsSdServiceInfo.java revision 527ba07b637cedf206fec0d3b0cf92141700a23c
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.nsd.DnsSdTxtRecord;
2021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.text.TextUtils;
2121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
2221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.ArrayList;
2321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.HashMap;
2421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.List;
2521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.Map;
2621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
2721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff/**
288bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff * A class for storing Bonjour service information that is advertised
298bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff * over a Wi-Fi peer-to-peer setup.
308bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff *
318bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff * {@see android.net.wifi.p2p.WifiP2pManager#addLocalService}
328bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff * {@see android.net.wifi.p2p.WifiP2pManager#removeLocalService}
338bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff * {@see WifiP2pServiceInfo}
348bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff * {@see WifiP2pUpnpServiceInfo}
3521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff */
368bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriffpublic class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo {
3721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
3821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
3921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Bonjour version 1.
4021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @hide
4121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
4221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public static final int VERSION_1 = 0x01;
4321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
4421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
4521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Pointer record.
4621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @hide
4721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
4821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public static final int DNS_TYPE_PTR = 12;
4921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
5021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
5121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Text record.
5221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @hide
5321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
5421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public static final int DNS_TYPE_TXT = 16;
5521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
5621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
5721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * virtual memory packet.
5821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * see E.3 of the Wi-Fi Direct technical specification for the detail.<br>
5921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Key: domain name Value: pointer address.<br>
6021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
6121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private final static Map<String, String> sVmPacket;
6221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
6321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    static {
6421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sVmPacket = new HashMap<String, String>();
6521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sVmPacket.put("_tcp.local.", "c00c");
6621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sVmPacket.put("local.", "c011");
6721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sVmPacket.put("_udp.local.", "c01c");
6821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
6921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
7021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
7121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * This constructor is only used in newInstance().
7221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
7321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param queryList
7421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
758bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff    private WifiP2pDnsSdServiceInfo(List<String> queryList) {
7621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        super(queryList);
7721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
7821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
7921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
808bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * Create a Bonjour service information object.
8121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
8221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param instanceName instance name.<br>
8321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *  e.g) "MyPrinter"
848bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * @param serviceType service type.<br>
858bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     *  e.g) "_ipp._tcp"
86527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff     * @param txtMap TXT record with key/value pair in a map confirming to format defined at
878bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
8821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return Bonjour service information object
8921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
908bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff    public static WifiP2pDnsSdServiceInfo newInstance(String instanceName,
91527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff            String serviceType, Map<String, String> txtMap) {
928bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        if (TextUtils.isEmpty(instanceName) || TextUtils.isEmpty(serviceType)) {
9321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            throw new IllegalArgumentException(
948bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff                    "instance name or service type cannot be empty");
9521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
9621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
97527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff        DnsSdTxtRecord txtRecord = new DnsSdTxtRecord();
98527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff        if (txtMap != null) {
99527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff            for (String key : txtMap.keySet()) {
100527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff                txtRecord.set(key, txtMap.get(key));
101527ba07b637cedf206fec0d3b0cf92141700a23cIrfan Sheriff            }
10221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
10321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
10421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ArrayList<String> queries = new ArrayList<String>();
1058bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        queries.add(createPtrServiceQuery(instanceName, serviceType));
1068bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        queries.add(createTxtServiceQuery(instanceName, serviceType, txtRecord));
10721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
1088bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        return new WifiP2pDnsSdServiceInfo(queries);
10921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
11021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
11121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
11221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Create wpa_supplicant service query for PTR record.
11321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
11421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param instanceName instance name.<br>
11521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *  e.g) "MyPrinter"
1168bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * @param serviceType service type.<br>
1178bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     *  e.g) "_ipp._tcp"
11821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return wpa_supplicant service query.
11921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
12021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private static String createPtrServiceQuery(String instanceName,
1218bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff            String serviceType) {
12221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
12321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
12421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append("bonjour ");
1258bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        sb.append(createRequest(serviceType + ".local.", DNS_TYPE_PTR, VERSION_1));
12621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(" ");
12721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
12821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        byte[] data = instanceName.getBytes();
12921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(String.format("%02x", data.length));
13021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(WifiP2pServiceInfo.bin2HexStr(data));
13121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // This is the start point of this response.
13221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // Therefore, it indicates the request domain name.
13321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append("c027");
13421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sb.toString();
13521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
13621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
13721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
13821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Create wpa_supplicant service query for TXT record.
13921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
14021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param instanceName instance name.<br>
14121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *  e.g) "MyPrinter"
1428bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * @param serviceType service type.<br>
1438bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     *  e.g) "_ipp._tcp"
14421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param txtRecord TXT record.<br>
14521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return wpa_supplicant service query.
14621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
1478bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff    private static String createTxtServiceQuery(String instanceName,
1488bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff            String serviceType,
14921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            DnsSdTxtRecord txtRecord) {
15021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
15121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
15221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
15321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append("bonjour ");
15421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
1558bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        sb.append(createRequest((instanceName + "." + serviceType + ".local."),
15621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                DNS_TYPE_TXT, VERSION_1));
15721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(" ");
15821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        byte[] rawData = txtRecord.getRawData();
15921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (rawData.length == 0) {
16021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sb.append("00");
16121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        } else {
16221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sb.append(bin2HexStr(rawData));
16321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
16421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sb.toString();
16521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
16621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
16721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
16821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Create bonjour service discovery request.
16921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
17021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dnsName dns name
17121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dnsType dns type
17221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param version version number
17321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @hide
17421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
17521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    static String createRequest(String dnsName, int dnsType, int version) {
17621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
17721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
17821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
17921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * The request format is as follows.
18021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * ________________________________________________
18121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * |  Encoded and Compressed dns name (variable)  |
18221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * ________________________________________________
18321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * |   Type (2)           | Version (1) |
18421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
1858bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        if (dnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
18621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            dnsName = dnsName.toLowerCase();
18721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
18821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(compressDnsName(dnsName));
18921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(String.format("%04x", dnsType));
19021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(String.format("%02x", version));
19121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
19221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sb.toString();
19321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
19421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
19521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
19621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Compress DNS data.
19721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
19821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * see E.3 of the Wi-Fi Direct technical specification for the detail.
19921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
20021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dnsName dns name
20121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return compressed dns name
20221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
20321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private static String compressDnsName(String dnsName) {
20421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
20521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
20621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // The domain name is replaced with a pointer to a prior
20721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // occurrence of the same name in virtual memory packet.
20821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        while (true) {
20921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            String data = sVmPacket.get(dnsName);
21021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (data != null) {
21121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                sb.append(data);
21221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                break;
21321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
21421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            int i = dnsName.indexOf('.');
21521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (i == -1) {
21621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (dnsName.length() > 0) {
21721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(String.format("%02x", dnsName.length()));
21821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(WifiP2pServiceInfo.bin2HexStr(dnsName.getBytes()));
21921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
22021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                // for a sequence of labels ending in a zero octet
22121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                sb.append("00");
22221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                break;
22321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
22421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
22521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            String name = dnsName.substring(0, i);
22621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            dnsName = dnsName.substring(i + 1);
22721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sb.append(String.format("%02x", name.length()));
22821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sb.append(WifiP2pServiceInfo.bin2HexStr(name.getBytes()));
22921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
23021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sb.toString();
23121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
23221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff}
233