/**
   * Create a Bonjour service information object.
   *
   * @param instanceName instance name.<br>
   *     e.g) "MyPrinter"
   * @param serviceType service type.<br>
   *     e.g) "_ipp._tcp"
   * @param txtMap TXT record with key/value pair in a map confirming to format defined at
   *     http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
   * @return Bonjour service information object
   */
  public static WifiP2pDnsSdServiceInfo newInstance(
      String instanceName, String serviceType, Map<String, String> txtMap) {
    if (TextUtils.isEmpty(instanceName) || TextUtils.isEmpty(serviceType)) {
      throw new IllegalArgumentException("instance name or service type cannot be empty");
    }

    DnsSdTxtRecord txtRecord = new DnsSdTxtRecord();
    if (txtMap != null) {
      for (String key : txtMap.keySet()) {
        txtRecord.set(key, txtMap.get(key));
      }
    }

    ArrayList<String> queries = new ArrayList<String>();
    queries.add(createPtrServiceQuery(instanceName, serviceType));
    queries.add(createTxtServiceQuery(instanceName, serviceType, txtRecord));

    return new WifiP2pDnsSdServiceInfo(queries);
  }
  /**
   * Create wpa_supplicant service query for TXT record.
   *
   * @param instanceName instance name.<br>
   *     e.g) "MyPrinter"
   * @param serviceType service type.<br>
   *     e.g) "_ipp._tcp"
   * @param txtRecord TXT record.<br>
   * @return wpa_supplicant service query.
   */
  private static String createTxtServiceQuery(
      String instanceName, String serviceType, DnsSdTxtRecord txtRecord) {

    StringBuffer sb = new StringBuffer();
    sb.append("bonjour ");

    sb.append(
        createRequest((instanceName + "." + serviceType + ".local."), DNS_TYPE_TXT, VERSION_1));
    sb.append(" ");
    byte[] rawData = txtRecord.getRawData();
    if (rawData.length == 0) {
      sb.append("00");
    } else {
      sb.append(bin2HexStr(rawData));
    }
    return sb.toString();
  }