/ components / mdns / mdns_console.c
mdns_console.c
   1  // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
   2  //
   3  // Licensed under the Apache License, Version 2.0 (the "License");
   4  // you may not use this file except in compliance with the License.
   5  // You may obtain a copy of the License at
   6  
   7  //     http://www.apache.org/licenses/LICENSE-2.0
   8  //
   9  // Unless required by applicable law or agreed to in writing, software
  10  // distributed under the License is distributed on an "AS IS" BASIS,
  11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12  // See the License for the specific language governing permissions and
  13  // limitations under the License.
  14  #include <stdio.h>
  15  #include <string.h>
  16  #include "esp_console.h"
  17  #include "argtable3/argtable3.h"
  18  #include "mdns.h"
  19  
  20  static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
  21  static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
  22  
  23  static void mdns_print_results(mdns_result_t * results)
  24  {
  25      mdns_result_t * r = results;
  26      mdns_ip_addr_t * a = NULL;
  27      int i = 1, t;
  28      while (r) {
  29          printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
  30          if (r->instance_name) {
  31              printf("  PTR : %s\n", r->instance_name);
  32          }
  33          if (r->hostname) {
  34              printf("  SRV : %s.local:%u\n", r->hostname, r->port);
  35          }
  36          if (r->txt_count) {
  37              printf("  TXT : [%u] ", r->txt_count);
  38              for (t=0; t<r->txt_count; t++) {
  39                  printf("%s=%s; ", r->txt[t].key, r->txt[t].value);
  40              }
  41              printf("\n");
  42          }
  43          a = r->addr;
  44          while (a) {
  45              if (a->addr.type == ESP_IPADDR_TYPE_V6) {
  46                  printf("  AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
  47              } else {
  48                  printf("  A   : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
  49              }
  50              a = a->next;
  51          }
  52          r = r->next;
  53      }
  54  }
  55  
  56  static struct {
  57      struct arg_str *hostname;
  58      struct arg_int *timeout;
  59      struct arg_end *end;
  60  } mdns_query_a_args;
  61  
  62  static int cmd_mdns_query_a(int argc, char** argv)
  63  {
  64      int nerrors = arg_parse(argc, argv, (void**) &mdns_query_a_args);
  65      if (nerrors != 0) {
  66          arg_print_errors(stderr, mdns_query_a_args.end, argv[0]);
  67          return 1;
  68      }
  69  
  70      const char * hostname = mdns_query_a_args.hostname->sval[0];
  71      int timeout = mdns_query_a_args.timeout->ival[0];
  72  
  73      if (!hostname || !hostname[0]) {
  74          printf("ERROR: Hostname not supplied\n");
  75          return 1;
  76      }
  77  
  78      if (timeout <= 0) {
  79          timeout = 1000;
  80      }
  81  
  82      printf("Query A: %s.local, Timeout: %d\n", hostname, timeout);
  83  
  84      struct esp_ip4_addr addr;
  85      addr.addr = 0;
  86  
  87      esp_err_t err = mdns_query_a(hostname, timeout,  &addr);
  88      if (err) {
  89          if (err == ESP_ERR_NOT_FOUND) {
  90              printf("ERROR: Host was not found!\n");
  91              return 0;
  92          }
  93          printf("ERROR: Query Failed\n");
  94          return 1;
  95      }
  96  
  97      printf(IPSTR "\n", IP2STR(&addr));
  98  
  99      return 0;
 100  }
 101  
 102  static void register_mdns_query_a(void)
 103  {
 104      mdns_query_a_args.hostname = arg_str1(NULL, NULL, "<hostname>", "Hostname that is searched for");
 105      mdns_query_a_args.timeout = arg_int0("t", "timeout", "<timeout>", "Timeout for this query");
 106      mdns_query_a_args.end = arg_end(2);
 107  
 108      const esp_console_cmd_t cmd_init = {
 109          .command = "mdns_query_a",
 110          .help = "Query MDNS for IPv4",
 111          .hint = NULL,
 112          .func = &cmd_mdns_query_a,
 113          .argtable = &mdns_query_a_args
 114      };
 115  
 116      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
 117  }
 118  
 119  static int cmd_mdns_query_aaaa(int argc, char** argv)
 120  {
 121      int nerrors = arg_parse(argc, argv, (void**) &mdns_query_a_args);
 122      if (nerrors != 0) {
 123          arg_print_errors(stderr, mdns_query_a_args.end, argv[0]);
 124          return 1;
 125      }
 126  
 127      const char * hostname = mdns_query_a_args.hostname->sval[0];
 128      int timeout = mdns_query_a_args.timeout->ival[0];
 129  
 130      if (!hostname || !hostname[0]) {
 131          printf("ERROR: Hostname not supplied\n");
 132          return 1;
 133      }
 134  
 135      if (timeout <= 0) {
 136          timeout = 1000;
 137      }
 138  
 139      printf("Query AAAA: %s.local, Timeout: %d\n", hostname, timeout);
 140  
 141      struct esp_ip6_addr addr;
 142      memset(addr.addr, 0, 16);
 143  
 144      esp_err_t err = mdns_query_aaaa(hostname, timeout,  &addr);
 145      if (err) {
 146          if (err == ESP_ERR_NOT_FOUND) {
 147              printf("Host was not found!\n");
 148              return 0;
 149          }
 150          printf("ERROR: Query Failed\n");
 151          return 1;
 152      }
 153  
 154      printf(IPV6STR "\n", IPV62STR(addr));
 155  
 156      return 0;
 157  }
 158  
 159  static void register_mdns_query_aaaa(void)
 160  {
 161      mdns_query_a_args.hostname = arg_str1(NULL, NULL, "<hostname>", "Hostname that is searched for");
 162      mdns_query_a_args.timeout = arg_int0("t", "timeout", "<timeout>", "Timeout for this query");
 163      mdns_query_a_args.end = arg_end(2);
 164  
 165      const esp_console_cmd_t cmd_init = {
 166          .command = "mdns_query_aaaa",
 167          .help = "Query MDNS for IPv6",
 168          .hint = NULL,
 169          .func = &cmd_mdns_query_aaaa,
 170          .argtable = &mdns_query_a_args
 171      };
 172  
 173      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
 174  }
 175  
 176  static struct {
 177      struct arg_str *instance;
 178      struct arg_str *service;
 179      struct arg_str *proto;
 180      struct arg_int *timeout;
 181      struct arg_end *end;
 182  } mdns_query_srv_args;
 183  
 184  static int cmd_mdns_query_srv(int argc, char** argv)
 185  {
 186      int nerrors = arg_parse(argc, argv, (void**) &mdns_query_srv_args);
 187      if (nerrors != 0) {
 188          arg_print_errors(stderr, mdns_query_srv_args.end, argv[0]);
 189          return 1;
 190      }
 191  
 192      const char * instance = mdns_query_srv_args.instance->sval[0];
 193      const char * service = mdns_query_srv_args.service->sval[0];
 194      const char * proto = mdns_query_srv_args.proto->sval[0];
 195      int timeout = mdns_query_srv_args.timeout->ival[0];
 196  
 197      if (timeout <= 0) {
 198          timeout = 1000;
 199      }
 200  
 201      printf("Query SRV: %s.%s.%s.local, Timeout: %d\n", instance, service, proto, timeout);
 202  
 203      mdns_result_t * results = NULL;
 204      esp_err_t err = mdns_query_srv(instance, service, proto, timeout,  &results);
 205      if (err) {
 206          printf("ERROR: Query Failed\n");
 207          return 1;
 208      }
 209      if (!results) {
 210          printf("No results found!\n");
 211          return 0;
 212      }
 213      mdns_print_results(results);
 214      mdns_query_results_free(results);
 215      return 0;
 216  }
 217  
 218  static void register_mdns_query_srv(void)
 219  {
 220      mdns_query_srv_args.instance = arg_str1(NULL, NULL, "<instance>", "Instance to search for");
 221      mdns_query_srv_args.service = arg_str1(NULL, NULL, "<service>", "Service to search for (ex. _http, _smb, etc.)");
 222      mdns_query_srv_args.proto = arg_str1(NULL, NULL, "<proto>", "Protocol to search for (_tcp, _udp, etc.)");
 223      mdns_query_srv_args.timeout = arg_int0("t", "timeout", "<timeout>", "Timeout for this query");
 224      mdns_query_srv_args.end = arg_end(2);
 225  
 226      const esp_console_cmd_t cmd_init = {
 227          .command = "mdns_query_srv",
 228          .help = "Query MDNS for Service SRV",
 229          .hint = NULL,
 230          .func = &cmd_mdns_query_srv,
 231          .argtable = &mdns_query_srv_args
 232      };
 233  
 234      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
 235  }
 236  
 237  static struct {
 238      struct arg_str *instance;
 239      struct arg_str *service;
 240      struct arg_str *proto;
 241      struct arg_int *timeout;
 242      struct arg_end *end;
 243  } mdns_query_txt_args;
 244  
 245  static int cmd_mdns_query_txt(int argc, char** argv)
 246  {
 247      int nerrors = arg_parse(argc, argv, (void**) &mdns_query_txt_args);
 248      if (nerrors != 0) {
 249          arg_print_errors(stderr, mdns_query_txt_args.end, argv[0]);
 250          return 1;
 251      }
 252  
 253      const char * instance = mdns_query_txt_args.instance->sval[0];
 254      const char * service = mdns_query_txt_args.service->sval[0];
 255      const char * proto = mdns_query_txt_args.proto->sval[0];
 256      int timeout = mdns_query_txt_args.timeout->ival[0];
 257  
 258      printf("Query TXT: %s.%s.%s.local, Timeout: %d\n", instance, service, proto, timeout);
 259  
 260      if (timeout <= 0) {
 261          timeout = 5000;
 262      }
 263  
 264      mdns_result_t * results = NULL;
 265      esp_err_t err = mdns_query_txt(instance, service, proto, timeout,  &results);
 266      if (err) {
 267          printf("ERROR: Query Failed\n");
 268          return 1;
 269      }
 270      if (!results) {
 271          printf("No results found!\n");
 272          return 0;
 273      }
 274  
 275      mdns_print_results(results);
 276      mdns_query_results_free(results);
 277      return 0;
 278  }
 279  
 280  static void register_mdns_query_txt(void)
 281  {
 282      mdns_query_txt_args.instance = arg_str1(NULL, NULL, "<instance>", "Instance to search for");
 283      mdns_query_txt_args.service = arg_str1(NULL, NULL, "<service>", "Service to search for (ex. _http, _smb, etc.)");
 284      mdns_query_txt_args.proto = arg_str1(NULL, NULL, "<proto>", "Protocol to search for (_tcp, _udp, etc.)");
 285      mdns_query_txt_args.timeout = arg_int0("t", "timeout", "<timeout>", "Timeout for this query");
 286      mdns_query_txt_args.end = arg_end(2);
 287  
 288      const esp_console_cmd_t cmd_init = {
 289          .command = "mdns_query_txt",
 290          .help = "Query MDNS for Service TXT",
 291          .hint = NULL,
 292          .func = &cmd_mdns_query_txt,
 293          .argtable = &mdns_query_txt_args
 294      };
 295  
 296      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
 297  }
 298  
 299  static struct {
 300      struct arg_str *service;
 301      struct arg_str *proto;
 302      struct arg_int *timeout;
 303      struct arg_int *max_results;
 304      struct arg_end *end;
 305  } mdns_query_ptr_args;
 306  
 307  static int cmd_mdns_query_ptr(int argc, char** argv)
 308  {
 309      int nerrors = arg_parse(argc, argv, (void**) &mdns_query_ptr_args);
 310      if (nerrors != 0) {
 311          arg_print_errors(stderr, mdns_query_ptr_args.end, argv[0]);
 312          return 1;
 313      }
 314  
 315      const char * service = mdns_query_ptr_args.service->sval[0];
 316      const char * proto = mdns_query_ptr_args.proto->sval[0];
 317      int timeout = mdns_query_ptr_args.timeout->ival[0];
 318      int max_results = mdns_query_ptr_args.max_results->ival[0];
 319  
 320      if (timeout <= 0) {
 321          timeout = 5000;
 322      }
 323  
 324      if (max_results <= 0 || max_results > 255) {
 325          max_results = 255;
 326      }
 327  
 328      printf("Query PTR: %s.%s.local, Timeout: %d, Max Results: %d\n", service, proto, timeout, max_results);
 329  
 330      mdns_result_t * results = NULL;
 331      esp_err_t err = mdns_query_ptr(service, proto, timeout, max_results,  &results);
 332      if (err) {
 333          printf("ERROR: Query Failed\n");
 334          return 1;
 335      }
 336      if (!results) {
 337          printf("No results found!\n");
 338          return 0;
 339      }
 340  
 341      mdns_print_results(results);
 342      mdns_query_results_free(results);
 343      return 0;
 344  }
 345  
 346  static void register_mdns_query_ptr(void)
 347  {
 348      mdns_query_ptr_args.service = arg_str1(NULL, NULL, "<service>", "Service to search for (ex. _http, _smb, etc.)");
 349      mdns_query_ptr_args.proto = arg_str1(NULL, NULL, "<proto>", "Protocol to search for (_tcp, _udp, etc.)");
 350      mdns_query_ptr_args.timeout = arg_int0("t", "timeout", "<timeout>", "Timeout for this query");
 351      mdns_query_ptr_args.max_results = arg_int0("m", "max_results", "<max_results>", "Maximum results returned");
 352      mdns_query_ptr_args.end = arg_end(2);
 353  
 354      const esp_console_cmd_t cmd_init = {
 355          .command = "mdns_query_ptr",
 356          .help = "Query MDNS for Service",
 357          .hint = NULL,
 358          .func = &cmd_mdns_query_ptr,
 359          .argtable = &mdns_query_ptr_args
 360      };
 361  
 362      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
 363  }
 364  
 365  static struct {
 366      struct arg_str *hostname;
 367      struct arg_int *timeout;
 368      struct arg_int *max_results;
 369      struct arg_end *end;
 370  } mdns_query_ip_args;
 371  
 372  static int cmd_mdns_query_ip(int argc, char** argv)
 373  {
 374      int nerrors = arg_parse(argc, argv, (void**) &mdns_query_ip_args);
 375      if (nerrors != 0) {
 376          arg_print_errors(stderr, mdns_query_ip_args.end, argv[0]);
 377          return 1;
 378      }
 379  
 380      const char * hostname = mdns_query_ip_args.hostname->sval[0];
 381      int timeout = mdns_query_ip_args.timeout->ival[0];
 382      int max_results = mdns_query_ip_args.max_results->ival[0];
 383  
 384      if (!hostname || !hostname[0]) {
 385          printf("ERROR: Hostname not supplied\n");
 386          return 1;
 387      }
 388  
 389      if (timeout <= 0) {
 390          timeout = 1000;
 391      }
 392  
 393      if (max_results < 0 || max_results > 255) {
 394          max_results = 255;
 395      }
 396  
 397      printf("Query IP: %s.local, Timeout: %d, Max Results: %d\n", hostname, timeout, max_results);
 398  
 399      mdns_result_t * results = NULL;
 400      esp_err_t err = mdns_query(hostname, NULL, NULL, MDNS_TYPE_ANY, timeout, max_results, &results);
 401      if (err) {
 402          printf("ERROR: Query Failed\n");
 403          return 1;
 404      }
 405      if (!results) {
 406          printf("No results found!\n");
 407          return 0;
 408      }
 409      mdns_print_results(results);
 410      mdns_query_results_free(results);
 411  
 412      return 0;
 413  }
 414  
 415  static void register_mdns_query_ip(void)
 416  {
 417      mdns_query_ip_args.hostname = arg_str1(NULL, NULL, "<hostname>", "Hostname that is searched for");
 418      mdns_query_ip_args.timeout = arg_int0("t", "timeout", "<timeout>", "Timeout for this query");
 419      mdns_query_ip_args.max_results = arg_int0("m", "max_results", "<max_results>", "Maximum results returned");
 420      mdns_query_ip_args.end = arg_end(2);
 421  
 422      const esp_console_cmd_t cmd_init = {
 423          .command = "mdns_query_ip",
 424          .help = "Query MDNS for IP",
 425          .hint = NULL,
 426          .func = &cmd_mdns_query_ip,
 427          .argtable = &mdns_query_ip_args
 428      };
 429  
 430      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
 431  }
 432  
 433  static struct {
 434      struct arg_str *instance;
 435      struct arg_str *service;
 436      struct arg_str *proto;
 437      struct arg_int *timeout;
 438      struct arg_int *max_results;
 439      struct arg_end *end;
 440  } mdns_query_svc_args;
 441  
 442  static int cmd_mdns_query_svc(int argc, char** argv)
 443  {
 444      int nerrors = arg_parse(argc, argv, (void**) &mdns_query_svc_args);
 445      if (nerrors != 0) {
 446          arg_print_errors(stderr, mdns_query_svc_args.end, argv[0]);
 447          return 1;
 448      }
 449  
 450      const char * instance = mdns_query_svc_args.instance->sval[0];
 451      const char * service = mdns_query_svc_args.service->sval[0];
 452      const char * proto = mdns_query_svc_args.proto->sval[0];
 453      int timeout = mdns_query_svc_args.timeout->ival[0];
 454      int max_results = mdns_query_svc_args.max_results->ival[0];
 455  
 456      if (timeout <= 0) {
 457          timeout = 5000;
 458      }
 459  
 460      if (max_results < 0 || max_results > 255) {
 461          max_results = 255;
 462      }
 463  
 464      printf("Query SVC: %s.%s.%s.local, Timeout: %d, Max Results: %d\n", instance, service, proto, timeout, max_results);
 465  
 466      mdns_result_t * results = NULL;
 467      esp_err_t err = mdns_query(instance, service, proto, MDNS_TYPE_ANY, timeout, max_results,  &results);
 468      if (err) {
 469          printf("ERROR: Query Failed\n");
 470          return 1;
 471      }
 472      if (!results) {
 473          printf("No results found!\n");
 474          return 0;
 475      }
 476  
 477      mdns_print_results(results);
 478      mdns_query_results_free(results);
 479      return 0;
 480  }
 481  
 482  static void register_mdns_query_svc(void)
 483  {
 484      mdns_query_svc_args.instance = arg_str1(NULL, NULL, "<instance>", "Instance to search for");
 485      mdns_query_svc_args.service = arg_str1(NULL, NULL, "<service>", "Service to search for (ex. _http, _smb, etc.)");
 486      mdns_query_svc_args.proto = arg_str1(NULL, NULL, "<proto>", "Protocol to search for (_tcp, _udp, etc.)");
 487      mdns_query_svc_args.timeout = arg_int0("t", "timeout", "<timeout>", "Timeout for this query");
 488      mdns_query_svc_args.max_results = arg_int0("m", "max_results", "<max_results>", "Maximum results returned");
 489      mdns_query_svc_args.end = arg_end(2);
 490  
 491      const esp_console_cmd_t cmd_init = {
 492          .command = "mdns_query_svc",
 493          .help = "Query MDNS for Service TXT & SRV",
 494          .hint = NULL,
 495          .func = &cmd_mdns_query_svc,
 496          .argtable = &mdns_query_svc_args
 497      };
 498  
 499      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
 500  }
 501  
 502  static struct {
 503      struct arg_str *hostname;
 504      struct arg_str *instance;
 505      struct arg_end *end;
 506  } mdns_init_args;
 507  
 508  static int cmd_mdns_init(int argc, char** argv)
 509  {
 510      int nerrors = arg_parse(argc, argv, (void**) &mdns_init_args);
 511      if (nerrors != 0) {
 512          arg_print_errors(stderr, mdns_init_args.end, argv[0]);
 513          return 1;
 514      }
 515  
 516      ESP_ERROR_CHECK( mdns_init() );
 517  
 518      if (mdns_init_args.hostname->sval[0]) {
 519          ESP_ERROR_CHECK( mdns_hostname_set(mdns_init_args.hostname->sval[0]) );
 520          printf("MDNS: Hostname: %s\n", mdns_init_args.hostname->sval[0]);
 521      }
 522  
 523      if (mdns_init_args.instance->sval[0]) {
 524          ESP_ERROR_CHECK( mdns_instance_name_set(mdns_init_args.instance->sval[0]) );
 525          printf("MDNS: Instance: %s\n", mdns_init_args.instance->sval[0]);
 526      }
 527  
 528      return 0;
 529  }
 530  
 531  static void register_mdns_init(void)
 532  {
 533      mdns_init_args.hostname = arg_str0("h", "hostname", "<hostname>", "Hostname that the server will advertise");
 534      mdns_init_args.instance = arg_str0("i", "instance", "<instance>", "Default instance name for services");
 535      mdns_init_args.end = arg_end(2);
 536  
 537      const esp_console_cmd_t cmd_init = {
 538          .command = "mdns_init",
 539          .help = "Start MDNS Server",
 540          .hint = NULL,
 541          .func = &cmd_mdns_init,
 542          .argtable = &mdns_init_args
 543      };
 544  
 545      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_init) );
 546  }
 547  
 548  static int cmd_mdns_free(int argc, char** argv)
 549  {
 550      mdns_free();
 551      return 0;
 552  }
 553  
 554  static void register_mdns_free(void)
 555  {
 556      const esp_console_cmd_t cmd_free = {
 557          .command = "mdns_free",
 558          .help = "Stop MDNS Server",
 559          .hint = NULL,
 560          .func = &cmd_mdns_free,
 561          .argtable = NULL
 562      };
 563  
 564      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_free) );
 565  }
 566  
 567  static struct {
 568      struct arg_str *hostname;
 569      struct arg_end *end;
 570  } mdns_set_hostname_args;
 571  
 572  static int cmd_mdns_set_hostname(int argc, char** argv)
 573  {
 574      int nerrors = arg_parse(argc, argv, (void**) &mdns_set_hostname_args);
 575      if (nerrors != 0) {
 576          arg_print_errors(stderr, mdns_set_hostname_args.end, argv[0]);
 577          return 1;
 578      }
 579  
 580      if (mdns_set_hostname_args.hostname->sval[0] == NULL) {
 581          printf("ERROR: Bad arguments!\n");
 582          return 1;
 583      }
 584  
 585      ESP_ERROR_CHECK( mdns_hostname_set(mdns_set_hostname_args.hostname->sval[0]) );
 586      return 0;
 587  }
 588  
 589  static void register_mdns_set_hostname(void)
 590  {
 591      mdns_set_hostname_args.hostname = arg_str1(NULL, NULL, "<hostname>", "Hostname that the server will advertise");
 592      mdns_set_hostname_args.end = arg_end(2);
 593  
 594      const esp_console_cmd_t cmd_set_hostname = {
 595          .command = "mdns_set_hostname",
 596          .help = "Set MDNS Server hostname",
 597          .hint = NULL,
 598          .func = &cmd_mdns_set_hostname,
 599          .argtable = &mdns_set_hostname_args
 600      };
 601  
 602      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_set_hostname) );
 603  }
 604  
 605  static struct {
 606      struct arg_str *instance;
 607      struct arg_end *end;
 608  } mdns_set_instance_args;
 609  
 610  static int cmd_mdns_set_instance(int argc, char** argv)
 611  {
 612      int nerrors = arg_parse(argc, argv, (void**) &mdns_set_instance_args);
 613      if (nerrors != 0) {
 614          arg_print_errors(stderr, mdns_set_instance_args.end, argv[0]);
 615          return 1;
 616      }
 617  
 618      if (mdns_set_instance_args.instance->sval[0] == NULL) {
 619          printf("ERROR: Bad arguments!\n");
 620          return 1;
 621      }
 622  
 623      ESP_ERROR_CHECK( mdns_instance_name_set(mdns_set_instance_args.instance->sval[0]) );
 624      return 0;
 625  }
 626  
 627  static void register_mdns_set_instance(void)
 628  {
 629      mdns_set_instance_args.instance = arg_str1(NULL, NULL, "<instance>", "Default instance name for services");
 630      mdns_set_instance_args.end = arg_end(2);
 631  
 632      const esp_console_cmd_t cmd_set_instance = {
 633          .command = "mdns_set_instance",
 634          .help = "Set MDNS Server Istance Name",
 635          .hint = NULL,
 636          .func = &cmd_mdns_set_instance,
 637          .argtable = &mdns_set_instance_args
 638      };
 639  
 640      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_set_instance) );
 641  }
 642  
 643  static mdns_txt_item_t * _convert_items(const char **values, int count)
 644  {
 645      int i=0,e;
 646      const char * value = NULL;
 647      mdns_txt_item_t * items = (mdns_txt_item_t*) malloc(sizeof(mdns_txt_item_t) * count);
 648      if (!items) {
 649          printf("ERROR: No Memory!\n");
 650          goto fail;
 651  
 652      }
 653      memset(items, 0, sizeof(mdns_txt_item_t) * count);
 654  
 655      for (i=0; i<count; i++) {
 656          value = values[i];
 657          char * esign = strchr(value, '=');
 658          if (!esign) {
 659              printf("ERROR: Equal sign not found in '%s'!\n", value);
 660              goto fail;
 661          }
 662          int var_len = esign - value;
 663          int val_len = strlen(value) - var_len - 1;
 664          char * var = (char*)malloc(var_len+1);
 665          if (var == NULL) {
 666              printf("ERROR: No Memory!\n");
 667              goto fail;
 668          }
 669          char * val = (char*)malloc(val_len+1);
 670          if (val == NULL) {
 671              printf("ERROR: No Memory!\n");
 672              free(var);
 673              goto fail;
 674          }
 675          memcpy(var, value, var_len);
 676          var[var_len] = 0;
 677          memcpy(val, esign+1, val_len);
 678          val[val_len] = 0;
 679  
 680          items[i].key = var;
 681          items[i].value = val;
 682      }
 683  
 684      return items;
 685  
 686  fail:
 687      for (e=0;e<i;e++) {
 688          free((char *)items[e].key);
 689          free((char *)items[e].value);
 690      }
 691      free(items);
 692      return NULL;
 693  }
 694  
 695  static struct {
 696      struct arg_str *service;
 697      struct arg_str *proto;
 698      struct arg_int *port;
 699      struct arg_str *instance;
 700      struct arg_str *txt;
 701      struct arg_end *end;
 702  } mdns_add_args;
 703  
 704  static int cmd_mdns_service_add(int argc, char** argv)
 705  {
 706      int nerrors = arg_parse(argc, argv, (void**) &mdns_add_args);
 707      if (nerrors != 0) {
 708          arg_print_errors(stderr, mdns_add_args.end, argv[0]);
 709          return 1;
 710      }
 711  
 712      if (!mdns_add_args.service->sval[0] || !mdns_add_args.proto->sval[0] || !mdns_add_args.port->ival[0]) {
 713          printf("ERROR: Bad arguments!\n");
 714          return 1;
 715      }
 716      const char * instance = NULL;
 717      if (mdns_add_args.instance->sval[0] && mdns_add_args.instance->sval[0][0]) {
 718          instance = mdns_add_args.instance->sval[0];
 719          printf("MDNS: Service Instance: %s\n", instance);
 720      }
 721      mdns_txt_item_t * items = NULL;
 722      if (mdns_add_args.txt->count) {
 723          items = _convert_items(mdns_add_args.txt->sval, mdns_add_args.txt->count);
 724          if (!items) {
 725              printf("ERROR: No Memory!\n");
 726              return 1;
 727  
 728          }
 729      }
 730  
 731      ESP_ERROR_CHECK( mdns_service_add(instance, mdns_add_args.service->sval[0], mdns_add_args.proto->sval[0], mdns_add_args.port->ival[0], items, mdns_add_args.txt->count) );
 732      free(items);
 733      return 0;
 734  }
 735  
 736  static void register_mdns_service_add(void)
 737  {
 738      mdns_add_args.service = arg_str1(NULL, NULL, "<service>", "MDNS Service");
 739      mdns_add_args.proto = arg_str1(NULL, NULL, "<proto>", "IP Protocol");
 740      mdns_add_args.port = arg_int1(NULL, NULL, "<port>", "Service Port");
 741      mdns_add_args.instance = arg_str0("i", "instance", "<instance>", "Instance name");
 742      mdns_add_args.txt = arg_strn(NULL, NULL, "item", 0, 30, "TXT Items (name=value)");
 743      mdns_add_args.end = arg_end(2);
 744  
 745      const esp_console_cmd_t cmd_add = {
 746          .command = "mdns_service_add",
 747          .help = "Add service to MDNS",
 748          .hint = NULL,
 749          .func = &cmd_mdns_service_add,
 750          .argtable = &mdns_add_args
 751      };
 752  
 753      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_add) );
 754  }
 755  
 756  static struct {
 757      struct arg_str *service;
 758      struct arg_str *proto;
 759      struct arg_end *end;
 760  } mdns_remove_args;
 761  
 762  static int cmd_mdns_service_remove(int argc, char** argv)
 763  {
 764      int nerrors = arg_parse(argc, argv, (void**) &mdns_remove_args);
 765      if (nerrors != 0) {
 766          arg_print_errors(stderr, mdns_remove_args.end, argv[0]);
 767          return 1;
 768      }
 769  
 770      if (!mdns_remove_args.service->sval[0] || !mdns_remove_args.proto->sval[0]) {
 771          printf("ERROR: Bad arguments!\n");
 772          return 1;
 773      }
 774  
 775      ESP_ERROR_CHECK( mdns_service_remove(mdns_remove_args.service->sval[0], mdns_remove_args.proto->sval[0]) );
 776      return 0;
 777  }
 778  
 779  static void register_mdns_service_remove(void)
 780  {
 781      mdns_remove_args.service = arg_str1(NULL, NULL, "<service>", "MDNS Service");
 782      mdns_remove_args.proto = arg_str1(NULL, NULL, "<proto>", "IP Protocol");
 783      mdns_remove_args.end = arg_end(2);
 784  
 785      const esp_console_cmd_t cmd_remove = {
 786          .command = "mdns_service_remove",
 787          .help = "Remove service from MDNS",
 788          .hint = NULL,
 789          .func = &cmd_mdns_service_remove,
 790          .argtable = &mdns_remove_args
 791      };
 792  
 793      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_remove) );
 794  }
 795  
 796  static struct {
 797      struct arg_str *service;
 798      struct arg_str *proto;
 799      struct arg_str *instance;
 800      struct arg_end *end;
 801  } mdns_service_instance_set_args;
 802  
 803  static int cmd_mdns_service_instance_set(int argc, char** argv)
 804  {
 805      int nerrors = arg_parse(argc, argv, (void**) &mdns_service_instance_set_args);
 806      if (nerrors != 0) {
 807          arg_print_errors(stderr, mdns_service_instance_set_args.end, argv[0]);
 808          return 1;
 809      }
 810  
 811      if (!mdns_service_instance_set_args.service->sval[0] || !mdns_service_instance_set_args.proto->sval[0] || !mdns_service_instance_set_args.instance->sval[0]) {
 812          printf("ERROR: Bad arguments!\n");
 813          return 1;
 814      }
 815  
 816      ESP_ERROR_CHECK( mdns_service_instance_name_set(mdns_service_instance_set_args.service->sval[0], mdns_service_instance_set_args.proto->sval[0], mdns_service_instance_set_args.instance->sval[0]) );
 817      return 0;
 818  }
 819  
 820  static void register_mdns_service_instance_set(void)
 821  {
 822      mdns_service_instance_set_args.service = arg_str1(NULL, NULL, "<service>", "MDNS Service");
 823      mdns_service_instance_set_args.proto = arg_str1(NULL, NULL, "<proto>", "IP Protocol");
 824      mdns_service_instance_set_args.instance = arg_str1(NULL, NULL, "<instance>", "Instance name");
 825      mdns_service_instance_set_args.end = arg_end(2);
 826  
 827      const esp_console_cmd_t cmd_add = {
 828          .command = "mdns_service_instance_set",
 829          .help = "Set MDNS Service Instance Name",
 830          .hint = NULL,
 831          .func = &cmd_mdns_service_instance_set,
 832          .argtable = &mdns_service_instance_set_args
 833      };
 834  
 835      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_add) );
 836  }
 837  
 838  static struct {
 839      struct arg_str *service;
 840      struct arg_str *proto;
 841      struct arg_int *port;
 842      struct arg_end *end;
 843  } mdns_service_port_set_args;
 844  
 845  static int cmd_mdns_service_port_set(int argc, char** argv) {
 846      int nerrors = arg_parse(argc, argv, (void**) &mdns_service_port_set_args);
 847      if (nerrors != 0) {
 848          arg_print_errors(stderr, mdns_service_port_set_args.end, argv[0]);
 849          return 1;
 850      }
 851  
 852      if (!mdns_service_port_set_args.service->sval[0] || !mdns_service_port_set_args.proto->sval[0] || !mdns_service_port_set_args.port->ival[0]) {
 853          printf("ERROR: Bad arguments!\n");
 854          return 1;
 855      }
 856  
 857      ESP_ERROR_CHECK( mdns_service_port_set(mdns_service_port_set_args.service->sval[0], mdns_service_port_set_args.proto->sval[0], mdns_service_port_set_args.port->ival[0]) );
 858      return 0;
 859  }
 860  
 861  static void register_mdns_service_port_set(void)
 862  {
 863      mdns_service_port_set_args.service = arg_str1(NULL, NULL, "<service>", "MDNS Service");
 864      mdns_service_port_set_args.proto = arg_str1(NULL, NULL, "<proto>", "IP Protocol");
 865      mdns_service_port_set_args.port = arg_int1(NULL, NULL, "<port>", "Service Port");
 866      mdns_service_port_set_args.end = arg_end(2);
 867  
 868      const esp_console_cmd_t cmd_add = {
 869          .command = "mdns_service_port_set",
 870          .help = "Set MDNS Service port",
 871          .hint = NULL,
 872          .func = &cmd_mdns_service_port_set,
 873          .argtable = &mdns_service_port_set_args
 874      };
 875  
 876      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_add) );
 877  }
 878  
 879  static struct {
 880      struct arg_str *service;
 881      struct arg_str *proto;
 882      struct arg_str *txt;
 883      struct arg_end *end;
 884  } mdns_txt_replace_args;
 885  
 886  static int cmd_mdns_service_txt_replace(int argc, char** argv)
 887  {
 888      mdns_txt_item_t * items = NULL;
 889      int nerrors = arg_parse(argc, argv, (void**) &mdns_txt_replace_args);
 890      if (nerrors != 0) {
 891          arg_print_errors(stderr, mdns_txt_replace_args.end, argv[0]);
 892          return 1;
 893      }
 894  
 895      if (!mdns_txt_replace_args.service->sval[0] || !mdns_txt_replace_args.proto->sval[0]) {
 896          printf("ERROR: Bad arguments!\n");
 897          return 1;
 898      }
 899  
 900      if (mdns_txt_replace_args.txt->count) {
 901          items = _convert_items(mdns_txt_replace_args.txt->sval, mdns_txt_replace_args.txt->count);
 902          if (!items) {
 903              printf("ERROR: No Memory!\n");
 904              return 1;
 905  
 906          }
 907      }
 908      ESP_ERROR_CHECK( mdns_service_txt_set(mdns_txt_replace_args.service->sval[0], mdns_txt_replace_args.proto->sval[0], items, mdns_txt_replace_args.txt->count) );
 909      free(items);
 910      return 0;
 911  }
 912  
 913  static void register_mdns_service_txt_replace(void)
 914  {
 915      mdns_txt_replace_args.service = arg_str1(NULL, NULL, "<service>", "MDNS Service");
 916      mdns_txt_replace_args.proto = arg_str1(NULL, NULL, "<proto>", "IP Protocol");
 917      mdns_txt_replace_args.txt = arg_strn(NULL, NULL, "item", 0, 30, "TXT Items (name=value)");
 918      mdns_txt_replace_args.end = arg_end(2);
 919  
 920      const esp_console_cmd_t cmd_txt_set = {
 921          .command = "mdns_service_txt_replace",
 922          .help = "Replace MDNS service TXT items",
 923          .hint = NULL,
 924          .func = &cmd_mdns_service_txt_replace,
 925          .argtable = &mdns_txt_replace_args
 926      };
 927  
 928      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_txt_set) );
 929  }
 930  
 931  static struct {
 932      struct arg_str *service;
 933      struct arg_str *proto;
 934      struct arg_str *var;
 935      struct arg_str *value;
 936      struct arg_end *end;
 937  } mdns_txt_set_args;
 938  
 939  static int cmd_mdns_service_txt_set(int argc, char** argv)
 940  {
 941      int nerrors = arg_parse(argc, argv, (void**) &mdns_txt_set_args);
 942      if (nerrors != 0) {
 943          arg_print_errors(stderr, mdns_txt_set_args.end, argv[0]);
 944          return 1;
 945      }
 946  
 947      if (!mdns_txt_set_args.service->sval[0] || !mdns_txt_set_args.proto->sval[0] || !mdns_txt_set_args.var->sval[0]) {
 948          printf("ERROR: Bad arguments!\n");
 949          return 1;
 950      }
 951  
 952      ESP_ERROR_CHECK( mdns_service_txt_item_set(mdns_txt_set_args.service->sval[0], mdns_txt_set_args.proto->sval[0], mdns_txt_set_args.var->sval[0], mdns_txt_set_args.value->sval[0]) );
 953      return 0;
 954  }
 955  
 956  static void register_mdns_service_txt_set(void)
 957  {
 958      mdns_txt_set_args.service = arg_str1(NULL, NULL, "<service>", "MDNS Service");
 959      mdns_txt_set_args.proto = arg_str1(NULL, NULL, "<proto>", "IP Protocol");
 960      mdns_txt_set_args.var = arg_str1(NULL, NULL, "<var>", "Item Name");
 961      mdns_txt_set_args.value = arg_str1(NULL, NULL, "<value>", "Item Value");
 962      mdns_txt_set_args.end = arg_end(2);
 963  
 964      const esp_console_cmd_t cmd_txt_set = {
 965          .command = "mdns_service_txt_set",
 966          .help = "Add/Set MDNS service TXT item",
 967          .hint = NULL,
 968          .func = &cmd_mdns_service_txt_set,
 969          .argtable = &mdns_txt_set_args
 970      };
 971  
 972      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_txt_set) );
 973  }
 974  
 975  static struct {
 976      struct arg_str *service;
 977      struct arg_str *proto;
 978      struct arg_str *var;
 979      struct arg_end *end;
 980  } mdns_txt_remove_args;
 981  
 982  static int cmd_mdns_service_txt_remove(int argc, char** argv)
 983  {
 984      int nerrors = arg_parse(argc, argv, (void**) &mdns_txt_remove_args);
 985      if (nerrors != 0) {
 986          arg_print_errors(stderr, mdns_txt_remove_args.end, argv[0]);
 987          return 1;
 988      }
 989  
 990      if (!mdns_txt_remove_args.service->sval[0] || !mdns_txt_remove_args.proto->sval[0] || !mdns_txt_remove_args.var->sval[0]) {
 991          printf("ERROR: Bad arguments!\n");
 992          return 1;
 993      }
 994  
 995      ESP_ERROR_CHECK( mdns_service_txt_item_remove(mdns_txt_remove_args.service->sval[0], mdns_txt_remove_args.proto->sval[0], mdns_txt_remove_args.var->sval[0]) );
 996      return 0;
 997  }
 998  
 999  static void register_mdns_service_txt_remove(void)
1000  {
1001      mdns_txt_remove_args.service = arg_str1(NULL, NULL, "<service>", "MDNS Service");
1002      mdns_txt_remove_args.proto = arg_str1(NULL, NULL, "<proto>", "IP Protocol");
1003      mdns_txt_remove_args.var = arg_str1(NULL, NULL, "<var>", "Item Name");
1004      mdns_txt_remove_args.end = arg_end(2);
1005  
1006      const esp_console_cmd_t cmd_txt_remove = {
1007          .command = "mdns_service_txt_remove",
1008          .help = "Remove MDNS service TXT item",
1009          .hint = NULL,
1010          .func = &cmd_mdns_service_txt_remove,
1011          .argtable = &mdns_txt_remove_args
1012      };
1013  
1014      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_txt_remove) );
1015  }
1016  
1017  static int cmd_mdns_service_remove_all(int argc, char** argv)
1018  {
1019      mdns_service_remove_all();
1020      return 0;
1021  }
1022  
1023  static void register_mdns_service_remove_all(void)
1024  {
1025      const esp_console_cmd_t cmd_free = {
1026          .command = "mdns_service_remove_all",
1027          .help = "Remove all MDNS services",
1028          .hint = NULL,
1029          .func = &cmd_mdns_service_remove_all,
1030          .argtable = NULL
1031      };
1032  
1033      ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_free) );
1034  }
1035  
1036  void mdns_console_register(void)
1037  {
1038      register_mdns_init();
1039      register_mdns_free();
1040      register_mdns_set_hostname();
1041      register_mdns_set_instance();
1042      register_mdns_service_add();
1043      register_mdns_service_remove();
1044      register_mdns_service_instance_set();
1045      register_mdns_service_port_set();
1046      register_mdns_service_txt_replace();
1047      register_mdns_service_txt_set();
1048      register_mdns_service_txt_remove();
1049      register_mdns_service_remove_all();
1050  
1051      register_mdns_query_a();
1052      register_mdns_query_aaaa();
1053      register_mdns_query_txt();
1054      register_mdns_query_srv();
1055      register_mdns_query_ptr();
1056  
1057      register_mdns_query_ip();
1058      register_mdns_query_svc();
1059  }
1060