comparison librtpalloc/simple_client.c @ 6:191d58f5c24f

librtpalloc: port the simple client
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 27 May 2024 21:10:01 +0000
parents
children
comparison
equal deleted inserted replaced
5:4a5560ef0807 6:191d58f5c24f
1 /*
2 * The library function implemented in this C module provides a
3 * simple interface for obtaining a single RTP endpoint from
4 * themwi-rtp-mgr. This "simple client" option is suitable only
5 * for command line utilities, not for daemon processes!
6 */
7
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <sys/un.h>
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <strings.h>
16
17 #include <themwi/rtp/rtp_alloc_if.h>
18 #include <themwi/rtp/rtp_alloc_resp.h>
19 #include <themwi/rtp/rtp_alloc_simple.h>
20
21 static const char ctrl_socket_pathname[] = "/var/gsm/rtp_alloc_socket";
22
23 static void
24 fill_sockaddr_un(pathname, sunp, lenp)
25 char *pathname;
26 struct sockaddr_un *sunp;
27 unsigned *lenp;
28 {
29 /* local socket binding voodoo copied from osmocon */
30 sunp->sun_family = AF_UNIX;
31 strncpy(sunp->sun_path, pathname, sizeof(sunp->sun_path));
32 sunp->sun_path[sizeof(sunp->sun_path) - 1] = '\0';
33 /* we use the same magic that X11 uses in Xtranssock.c for
34 * calculating the proper length of the sockaddr */
35 #if defined(BSD44SOCKETS) || defined(__UNIXWARE__)
36 sunp->sun_len = strlen(sunp->sun_path);
37 #endif
38 #if defined(BSD44SOCKETS) || defined(SUN_LEN)
39 *lenp = SUN_LEN(sunp);
40 #else
41 *lenp = strlen(sunp->sun_path) +
42 offsetof(struct sockaddr_un, sun_path) + 1;
43 #endif
44 }
45
46 static void
47 close_fds(resp)
48 struct rtp_alloc_resp_wrap *resp;
49 {
50 unsigned n;
51
52 for (n = 0; n < resp->num_fd; n++)
53 close(resp->fd_buf[n]);
54 }
55
56 int rtp_alloc_simple(int ep_type, struct rtp_alloc_simple *out)
57 {
58 struct sockaddr_un sa;
59 unsigned sa_len;
60 int ctrl_fd, rc;
61 struct rtp_alloc_req req;
62 struct rtp_alloc_resp_wrap resp;
63 unsigned expect_num_fd;
64
65 switch (ep_type) {
66 case RTP_ALLOC_TYPE_GSM:
67 case RTP_ALLOC_TYPE_PSTN:
68 expect_num_fd = 2;
69 break;
70 case RTP_ALLOC_TYPE_GSM2PSTN:
71 case RTP_ALLOC_TYPE_GSM2GSM:
72 expect_num_fd = 4;
73 break;
74 default:
75 fprintf(stderr,
76 "rtp_alloc_simple() error: unknown EP type %d\n",
77 ep_type);
78 return(-1);
79 }
80 ctrl_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
81 if (ctrl_fd < 0) {
82 perror("socket(AF_UNIX, SOCK_SEQPACKET, 0)");
83 return(-1);
84 }
85 fill_sockaddr_un(ctrl_socket_pathname, &sa, &sa_len);
86 rc = connect(ctrl_fd, (struct sockaddr *) &sa, sa_len);
87 if (rc < 0) {
88 perror(ctrl_socket_pathname);
89 close(ctrl_fd);
90 return(-1);
91 }
92 bzero(&req, sizeof req);
93 req.ep_type = ep_type;
94 rc = send(ctrl_fd, &req, sizeof req, 0);
95 if (rc < 0) {
96 perror("send to RTP allocator socket");
97 close(ctrl_fd);
98 return(-1);
99 }
100 rc = collect_rtpmgr_resp(ctrl_fd, 0, &resp);
101 if (rc < 0) {
102 perror("recvmsg from RTP allocator socket");
103 close(ctrl_fd);
104 return(-1);
105 }
106 close(ctrl_fd);
107 if (resp.resp_len != sizeof(struct rtp_alloc_resp)) {
108 fprintf(stderr,
109 "error: response packet from themwi-rtp-mgr has wrong length (%u bytes)\n",
110 resp.resp_len);
111 close_fds(&resp);
112 return(-1);
113 }
114 if (resp.resp.res != RTP_ALLOC_OK) {
115 fprintf(stderr, "themwi-rtp-mgr returned error %u\n",
116 resp.resp.res);
117 close_fds(&resp);
118 return(-1);
119 }
120 if (resp.num_fd != expect_num_fd) {
121 fprintf(stderr,
122 "error: themwi-rtp-mgr returned %u descriptors instead of expected %u\n",
123 resp.num_fd, expect_num_fd);
124 close_fds(&resp);
125 return(-1);
126 }
127 switch (ep_type) {
128 case RTP_ALLOC_TYPE_GSM:
129 out->gsm_rtp_fd = resp.fd_buf[0];
130 out->gsm_rtcp_fd = resp.fd_buf[1];
131 break;
132 case RTP_ALLOC_TYPE_PSTN:
133 out->pstn_rtp_fd = resp.fd_buf[0];
134 out->pstn_rtcp_fd = resp.fd_buf[1];
135 break;
136 case RTP_ALLOC_TYPE_GSM2PSTN:
137 case RTP_ALLOC_TYPE_GSM2GSM:
138 out->gsm_rtp_fd = resp.fd_buf[0];
139 out->gsm_rtcp_fd = resp.fd_buf[1];
140 out->pstn_rtp_fd = resp.fd_buf[2];
141 out->pstn_rtcp_fd = resp.fd_buf[3];
142 }
143 bcopy(&resp.resp.gsm_addr, &out->gsm_addr,
144 sizeof(struct sockaddr_storage));
145 bcopy(&resp.resp.pstn_addr, &out->pstn_addr,
146 sizeof(struct sockaddr_storage));
147 return(0);
148 }