FreeCalypso > hg > themwi-rtp-mgr
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 } |