All Downloads are FREE. Search and download functionalities are using the official Maven repository.

android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 14-robolectric-10818077
Show newest version
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net.wifi.p2p.nsd;

import android.net.wifi.p2p.WifiP2pDevice;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * A class for a response of bonjour service discovery.
 *
 * @hide
 */
public class WifiP2pDnsSdServiceResponse extends WifiP2pServiceResponse {

    /**
     * DNS query name.
     * e.g)
     * for PTR
     * "_ipp._tcp.local."
     * for TXT
     * "MyPrinter._ipp._tcp.local."
     */
    private String mDnsQueryName;

    /**
     * Service instance name.
     * e.g) "MyPrinter"
     * This field is only used when the dns type equals to
     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_PTR}.
     */
    private String mInstanceName;

    /**
     * DNS Type.
     * Should be {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_PTR} or
     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
     */
    private int mDnsType;

    /**
     * DnsSd version number.
     * Should be {@link WifiP2pDnsSdServiceInfo#VERSION_1}.
     */
    private int mVersion;

    /**
     * Txt record.
     * This field is only used when the dns type equals to
     * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
     */
    private final HashMap mTxtRecord = new HashMap();

    /**
     * Virtual memory packet.
     * see E.3 of the Wi-Fi Direct technical specification for the detail.
* The spec can be obtained from wi-fi.org * Key: pointer Value: domain name.
*/ private final static Map sVmpack; static { sVmpack = new HashMap(); sVmpack.put(0x0c, "_tcp.local."); sVmpack.put(0x11, "local."); sVmpack.put(0x1c, "_udp.local."); } /** * Returns query DNS name. * @return DNS name. */ public String getDnsQueryName() { return mDnsQueryName; } /** * Return query DNS type. * @return DNS type. */ public int getDnsType() { return mDnsType; } /** * Return bonjour version number. * @return version number. */ public int getVersion() { return mVersion; } /** * Return instance name. * @return */ public String getInstanceName() { return mInstanceName; } /** * Return TXT record data. * @return TXT record data. */ public Map getTxtRecord() { return mTxtRecord; } @Override public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("serviceType:DnsSd(").append(mServiceType).append(")"); sbuf.append(" status:").append(Status.toString(mStatus)); sbuf.append(" srcAddr:").append(mDevice.deviceAddress); sbuf.append(" version:").append(String.format("%02x", mVersion)); sbuf.append(" dnsName:").append(mDnsQueryName); sbuf.append(" TxtRecord:"); for (String key : mTxtRecord.keySet()) { sbuf.append(" key:").append(key).append(" value:").append(mTxtRecord.get(key)); } if (mInstanceName != null) { sbuf.append(" InsName:").append(mInstanceName); } return sbuf.toString(); } /** * This is only used in framework. * @param status status code. * @param dev source device. * @param data RDATA. * @hide */ protected WifiP2pDnsSdServiceResponse(int status, int tranId, WifiP2pDevice dev, byte[] data) { super(WifiP2pServiceInfo.SERVICE_TYPE_BONJOUR, status, tranId, dev, data); if (!parse()) { throw new IllegalArgumentException("Malformed bonjour service response"); } } /** * Parse DnsSd service discovery response. * * @return {@code true} if the operation succeeded */ private boolean parse() { /* * The data format from Wi-Fi Direct spec is as follows. * ________________________________________________ * | encoded and compressed dns name (variable) | * ________________________________________________ * | dnstype(2byte) | version(1byte) | * ________________________________________________ * | RDATA (variable) | */ if (mData == null) { // the empty is OK. return true; } DataInputStream dis = new DataInputStream(new ByteArrayInputStream(mData)); mDnsQueryName = readDnsName(dis); if (mDnsQueryName == null) { return false; } try { mDnsType = dis.readUnsignedShort(); mVersion = dis.readUnsignedByte(); } catch (IOException e) { e.printStackTrace(); return false; } if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR) { String rData = readDnsName(dis); if (rData == null) { return false; } if (rData.length() <= mDnsQueryName.length()) { return false; } mInstanceName = rData.substring(0, rData.length() - mDnsQueryName.length() -1); } else if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) { return readTxtData(dis); } else { return false; } return true; } /** * Read dns name. * * @param dis data input stream. * @return dns name */ private String readDnsName(DataInputStream dis) { StringBuffer sb = new StringBuffer(); // copy virtual memory packet. HashMap vmpack = new HashMap(sVmpack); if (mDnsQueryName != null) { vmpack.put(0x27, mDnsQueryName); } try { while (true) { int i = dis.readUnsignedByte(); if (i == 0x00) { return sb.toString(); } else if (i == 0xc0) { // refer to pointer. String ref = vmpack.get(dis.readUnsignedByte()); if (ref == null) { //invalid. return null; } sb.append(ref); return sb.toString(); } else { byte[] data = new byte[i]; dis.readFully(data); sb.append(new String(data)); sb.append("."); } } } catch (IOException e) { e.printStackTrace(); } return null; } /** * Read TXT record data. * * @param dis * @return true if TXT data is valid */ private boolean readTxtData(DataInputStream dis) { try { while (dis.available() > 0) { int len = dis.readUnsignedByte(); if (len == 0) { break; } byte[] data = new byte[len]; dis.readFully(data); String[] keyVal = new String(data).split("="); if (keyVal.length != 2) { return false; } mTxtRecord.put(keyVal[0], keyVal[1]); } return true; } catch (IOException e) { e.printStackTrace(); } return false; } /** * Creates DnsSd service response. * This is only called from WifiP2pServiceResponse * * @param status status code. * @param dev source device. * @param data DnsSd response data. * @return DnsSd service response data. * @hide */ static WifiP2pDnsSdServiceResponse newInstance(int status, int transId, WifiP2pDevice dev, byte[] data) { if (status != WifiP2pServiceResponse.Status.SUCCESS) { return new WifiP2pDnsSdServiceResponse(status, transId, dev, null); } try { return new WifiP2pDnsSdServiceResponse(status, transId, dev, data); } catch (IllegalArgumentException e) { e.printStackTrace(); } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy