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.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. extern int timeout;
  26. static char *my_inet_ntop(int family, struct sockaddr *addr, char *dest, int dest_len) {
  27. struct sockaddr_in *addr_v4 = (struct sockaddr_in *)addr;
  28. struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)addr;
  29. switch (family) {
  30. case AF_INET:
  31. return (char *)inet_ntop(AF_INET, &addr_v4->sin_addr, dest, dest_len);
  32. break;
  33. case AF_INET6:
  34. return (char *)inet_ntop(AF_INET6, &addr_v6->sin6_addr, dest, dest_len);
  35. break;
  36. default:
  37. memset(dest, 0, dest_len);
  38. strcpy(dest, "unknown");
  39. return dest;
  40. }
  41. }
  42. int connect_client(int socktype, const char *hostname, const char *service) {
  43. struct addrinfo hints, *res;
  44. int n;
  45. memset(&hints, 0, sizeof(struct addrinfo));
  46. hints.ai_family = ai_family;
  47. hints.ai_socktype = socktype;
  48. d("Connecting to server %s port %s\n", hostname, service);
  49. n = getaddrinfo(hostname, service, &hints, &res);
  50. if (n < 0) {
  51. fprintf(stderr, "ERROR: getaddrinfo(%s): %s\n", hostname, gai_strerror(n));
  52. return -1;
  53. }
  54. int sockfd = -1;
  55. struct addrinfo *ressave = res;
  56. char str_addr[INET6_ADDRSTRLEN] = { 0 };
  57. while (res) {
  58. sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  59. if (sockfd > -1) {
  60. my_inet_ntop(res->ai_family, res->ai_addr, str_addr, sizeof(str_addr));
  61. if (do_connect(sockfd, res->ai_addr, res->ai_addrlen, timeout * 1000) < 0) {
  62. fprintf(stderr, "ERROR: Cant connect to server %s port %s (addr=%s) | %s\n",
  63. hostname, service, str_addr, strerror(errno));
  64. close(sockfd);
  65. sockfd = -1;
  66. } else {
  67. break; // connected
  68. }
  69. } else {
  70. fprintf(stderr, "ERROR: Could not create socket: %s\n", strerror(errno));
  71. sleep(1); // 1 second between socket creation (after error)
  72. return -1;
  73. }
  74. res = res->ai_next;
  75. }
  76. freeaddrinfo(ressave);
  77. if (sockfd < 0)
  78. return -1;
  79. if (socktype == SOCK_STREAM) {
  80. int flag = 1;
  81. setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
  82. }
  83. d("Connected to server %s port %s (addr=%s fd=%d).\n",
  84. hostname, service, str_addr, sockfd);
  85. set_sock_nonblock(sockfd);
  86. return sockfd;
  87. }