videohubctrl can be used to control Blackmagic Design Videohub SDI router device over the network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

net.c 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * === Network functions ===
  3. *
  4. * Blackmagic Design Videohub control application
  5. * Copyright (C) 2014 Unix Solutions Ltd.
  6. * Written by Georgi Chorbadzhiyski
  7. *
  8. * Released under MIT license.
  9. * See LICENSE-MIT.txt for license terms.
  10. *
  11. */
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14. #include <unistd.h>
  15. #include <string.h>
  16. #include <sys/errno.h>
  17. #include <sys/socket.h>
  18. #include <netinet/in.h>
  19. #include <netinet/tcp.h>
  20. #include <arpa/inet.h>
  21. #include "data.h"
  22. #include "net.h"
  23. #include "libfuncs/libfuncs.h"
  24. int ai_family = AF_UNSPEC;
  25. static char *my_inet_ntop(int family, struct sockaddr *addr, char *dest, int dest_len) {
  26. struct sockaddr_in *addr_v4 = (struct sockaddr_in *)addr;
  27. struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)addr;
  28. switch (family) {
  29. case AF_INET:
  30. return (char *)inet_ntop(AF_INET, &addr_v4->sin_addr, dest, dest_len);
  31. break;
  32. case AF_INET6:
  33. return (char *)inet_ntop(AF_INET6, &addr_v6->sin6_addr, dest, dest_len);
  34. break;
  35. default:
  36. memset(dest, 0, dest_len);
  37. strcpy(dest, "unknown");
  38. return dest;
  39. }
  40. }
  41. int connect_client(int socktype, const char *hostname, const char *service) {
  42. struct addrinfo hints, *res;
  43. int n;
  44. memset(&hints, 0, sizeof(struct addrinfo));
  45. hints.ai_family = ai_family;
  46. hints.ai_socktype = socktype;
  47. v("Connecting to server %s port %s\n", hostname, service);
  48. n = getaddrinfo(hostname, service, &hints, &res);
  49. if (n < 0) {
  50. fprintf(stderr, "ERROR: getaddrinfo(%s): %s\n", hostname, gai_strerror(n));
  51. return -1;
  52. }
  53. int sockfd = -1;
  54. struct addrinfo *ressave = res;
  55. char str_addr[INET6_ADDRSTRLEN] = { 0 };
  56. while (res) {
  57. sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  58. if (sockfd > -1) {
  59. my_inet_ntop(res->ai_family, res->ai_addr, str_addr, sizeof(str_addr));
  60. if (do_connect(sockfd, res->ai_addr, res->ai_addrlen, 1000) < 0) {
  61. fprintf(stderr, "ERROR: Cant connect to server %s port %s (addr=%s) | %s\n",
  62. hostname, service, str_addr, strerror(errno));
  63. close(sockfd);
  64. sockfd = -1;
  65. } else {
  66. break; // connected
  67. }
  68. } else {
  69. fprintf(stderr, "ERROR: Could not create socket: %s\n", strerror(errno));
  70. sleep(1); // 1 second between socket creation (after error)
  71. return -1;
  72. }
  73. res = res->ai_next;
  74. }
  75. freeaddrinfo(ressave);
  76. if (sockfd < 0)
  77. return -1;
  78. if (socktype == SOCK_STREAM) {
  79. int flag = 1;
  80. setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
  81. }
  82. v("Connected to server %s port %s (addr=%s fd=%d).\n",
  83. hostname, service, str_addr, sockfd);
  84. set_sock_nonblock(sockfd);
  85. return sockfd;
  86. }