WifiP2pDnsSdServiceInfo.java revision 8bf825f48fde77cb2feb8720aac17093581bb085
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"
868bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * @param txtRecord TXT record as 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,
918bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff            String serviceType, DnsSdTxtRecord txtRecord) {
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
9721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (txtRecord == null) {
9821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            txtRecord = new DnsSdTxtRecord();
9921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
10021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
10121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ArrayList<String> queries = new ArrayList<String>();
1028bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        queries.add(createPtrServiceQuery(instanceName, serviceType));
1038bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        queries.add(createTxtServiceQuery(instanceName, serviceType, txtRecord));
10421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
1058bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        return new WifiP2pDnsSdServiceInfo(queries);
10621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
10721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
10821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
10921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Create wpa_supplicant service query for PTR record.
11021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
11121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param instanceName instance name.<br>
11221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *  e.g) "MyPrinter"
1138bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * @param serviceType service type.<br>
1148bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     *  e.g) "_ipp._tcp"
11521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return wpa_supplicant service query.
11621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
11721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private static String createPtrServiceQuery(String instanceName,
1188bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff            String serviceType) {
11921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
12021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
12121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append("bonjour ");
1228bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        sb.append(createRequest(serviceType + ".local.", DNS_TYPE_PTR, VERSION_1));
12321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(" ");
12421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
12521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        byte[] data = instanceName.getBytes();
12621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(String.format("%02x", data.length));
12721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(WifiP2pServiceInfo.bin2HexStr(data));
12821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // This is the start point of this response.
12921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // Therefore, it indicates the request domain name.
13021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append("c027");
13121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sb.toString();
13221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
13321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
13421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
13521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Create wpa_supplicant service query for TXT record.
13621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
13721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param instanceName instance name.<br>
13821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *  e.g) "MyPrinter"
1398bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     * @param serviceType service type.<br>
1408bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff     *  e.g) "_ipp._tcp"
14121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param txtRecord TXT record.<br>
14221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return wpa_supplicant service query.
14321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
1448bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff    private static String createTxtServiceQuery(String instanceName,
1458bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff            String serviceType,
14621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            DnsSdTxtRecord txtRecord) {
14721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
14821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
14921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
15021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append("bonjour ");
15121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
1528bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        sb.append(createRequest((instanceName + "." + serviceType + ".local."),
15321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                DNS_TYPE_TXT, VERSION_1));
15421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(" ");
15521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        byte[] rawData = txtRecord.getRawData();
15621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (rawData.length == 0) {
15721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sb.append("00");
15821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        } else {
15921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sb.append(bin2HexStr(rawData));
16021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
16121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sb.toString();
16221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
16321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
16421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
16521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Create bonjour service discovery request.
16621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
16721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dnsName dns name
16821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dnsType dns type
16921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param version version number
17021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @hide
17121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
17221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    static String createRequest(String dnsName, int dnsType, int version) {
17321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
17421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
17521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
17621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * The request format is as follows.
17721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * ________________________________________________
17821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * |  Encoded and Compressed dns name (variable)  |
17921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * ________________________________________________
18021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * |   Type (2)           | Version (1) |
18121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
1828bf825f48fde77cb2feb8720aac17093581bb085Irfan Sheriff        if (dnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
18321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            dnsName = dnsName.toLowerCase();
18421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
18521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(compressDnsName(dnsName));
18621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(String.format("%04x", dnsType));
18721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        sb.append(String.format("%02x", version));
18821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
18921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sb.toString();
19021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
19121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
19221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
19321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Compress DNS data.
19421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
19521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * see E.3 of the Wi-Fi Direct technical specification for the detail.
19621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
19721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param dnsName dns name
19821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return compressed dns name
19921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
20021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private static String compressDnsName(String dnsName) {
20121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
20221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
20321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // The domain name is replaced with a pointer to a prior
20421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        // occurrence of the same name in virtual memory packet.
20521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        while (true) {
20621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            String data = sVmPacket.get(dnsName);
20721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (data != null) {
20821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                sb.append(data);
20921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                break;
21021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
21121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            int i = dnsName.indexOf('.');
21221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (i == -1) {
21321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (dnsName.length() > 0) {
21421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(String.format("%02x", dnsName.length()));
21521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(WifiP2pServiceInfo.bin2HexStr(dnsName.getBytes()));
21621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
21721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                // for a sequence of labels ending in a zero octet
21821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                sb.append("00");
21921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                break;
22021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
22121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
22221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            String name = dnsName.substring(0, i);
22321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            dnsName = dnsName.substring(i + 1);
22421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sb.append(String.format("%02x", name.length()));
22521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            sb.append(WifiP2pServiceInfo.bin2HexStr(name.getBytes()));
22621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
22721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return sb.toString();
22821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
22921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff}
230