FreeCalypso > hg > themwi-rtp-mgr
comparison rtp-mgr/ctrl_prot.c @ 2:247f4bbde24c
rtp-mgr: daemon ported over
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 27 May 2024 19:42:19 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:560a3765ab30 | 2:247f4bbde24c |
---|---|
1 /* | |
2 * In this module we implement our control socket protocol. | |
3 */ | |
4 | |
5 #include <sys/types.h> | |
6 #include <sys/socket.h> | |
7 #include <sys/uio.h> | |
8 #include <netinet/in.h> | |
9 #include <stdio.h> | |
10 #include <stdint.h> | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
13 #include <strings.h> | |
14 #include <syslog.h> | |
15 #include <unistd.h> | |
16 #include <themwi/rtp/rtp_alloc_if.h> | |
17 #include "struct.h" | |
18 #include "select.h" | |
19 | |
20 extern struct bind_range_cfg bind_range_gsm, bind_range_pstn; | |
21 | |
22 static void | |
23 free_rtp_end(roe) | |
24 struct rtp_one_end *roe; | |
25 { | |
26 close(roe->rtp_fd); | |
27 close(roe->rtcp_fd); | |
28 } | |
29 | |
30 static void | |
31 close_fds(fd_list, num_fd) | |
32 int *fd_list, num_fd; | |
33 { | |
34 int i; | |
35 | |
36 for (i = 0; i < num_fd; i++) | |
37 close(fd_list[i]); | |
38 } | |
39 | |
40 void | |
41 ctrl_message_handler(fd) | |
42 { | |
43 struct rtp_alloc_req req; | |
44 struct rtp_alloc_resp resp; | |
45 struct rtp_one_end rtp_gsm, rtp_pstn; | |
46 struct iovec iov; | |
47 struct msghdr msg; | |
48 int fd_out[4], num_fd, *fd_bufptr; | |
49 union { | |
50 char buf[CMSG_SPACE(sizeof fd_out)]; | |
51 struct cmsghdr align; | |
52 } cmsgu; | |
53 struct cmsghdr *cmsg; | |
54 int rc; | |
55 | |
56 /* receive request */ | |
57 rc = recv(fd, &req, sizeof req, 0); | |
58 if (rc < sizeof req) { | |
59 syslog(LOG_DEBUG, "ctrl connection closing"); | |
60 close(fd); | |
61 FD_CLR(fd, &select_for_read); | |
62 return; | |
63 } | |
64 /* start preparing response */ | |
65 bzero(&resp, sizeof resp); | |
66 resp.transact_ref = req.transact_ref; | |
67 switch (req.ep_type) { | |
68 case RTP_ALLOC_TYPE_GSM: | |
69 case RTP_ALLOC_TYPE_PSTN: | |
70 case RTP_ALLOC_TYPE_GSM2PSTN: | |
71 case RTP_ALLOC_TYPE_GSM2GSM: | |
72 break; | |
73 default: | |
74 resp.res = RTP_ALLOC_ERR_PARAM; | |
75 error_resp: send(fd, &resp, sizeof resp, 0); | |
76 return; | |
77 } | |
78 /* allocate resources */ | |
79 if (req.ep_type & RTP_ALLOC_DO_GSM1) { | |
80 rc = get_rtp_port_pair(&rtp_gsm, &bind_range_gsm); | |
81 if (rc < 0) { | |
82 syslog(LOG_ERR, | |
83 "unable to get local port pair on GSM side"); | |
84 resp.res = RTP_ALLOC_ERR_RSRC; | |
85 goto error_resp; | |
86 } | |
87 } | |
88 if (req.ep_type & RTP_ALLOC_DO_PSTN) { | |
89 rc = get_rtp_port_pair(&rtp_pstn, &bind_range_pstn); | |
90 if (rc < 0) { | |
91 syslog(LOG_ERR, | |
92 "unable to get local port pair on PSTN side"); | |
93 if (req.ep_type & RTP_ALLOC_DO_GSM1) | |
94 free_rtp_end(&rtp_gsm); | |
95 resp.res = RTP_ALLOC_ERR_RSRC; | |
96 goto error_resp; | |
97 } | |
98 } | |
99 if (req.ep_type & RTP_ALLOC_DO_GSM2) { | |
100 rc = get_rtp_port_pair(&rtp_pstn, &bind_range_gsm); | |
101 if (rc < 0) { | |
102 syslog(LOG_ERR, | |
103 "unable to get 2nd local port pair on GSM side"); | |
104 free_rtp_end(&rtp_gsm); | |
105 resp.res = RTP_ALLOC_ERR_RSRC; | |
106 goto error_resp; | |
107 } | |
108 } | |
109 /* finish ordinary body of response */ | |
110 resp.res = RTP_ALLOC_OK; | |
111 if (req.ep_type & RTP_ALLOC_DO_GSM1) | |
112 bcopy(&rtp_gsm.bound_addr, &resp.gsm_addr, | |
113 sizeof(struct sockaddr_in)); | |
114 if (req.ep_type & (RTP_ALLOC_DO_PSTN | RTP_ALLOC_DO_GSM2)) | |
115 bcopy(&rtp_pstn.bound_addr, &resp.pstn_addr, | |
116 sizeof(struct sockaddr_in)); | |
117 iov.iov_base = &resp; | |
118 iov.iov_len = sizeof resp; | |
119 /* file descriptor passing voodoo */ | |
120 switch (req.ep_type) { | |
121 case RTP_ALLOC_TYPE_GSM: | |
122 num_fd = 2; | |
123 fd_out[0] = rtp_gsm.rtp_fd; | |
124 fd_out[1] = rtp_gsm.rtcp_fd; | |
125 break; | |
126 case RTP_ALLOC_TYPE_PSTN: | |
127 num_fd = 2; | |
128 fd_out[0] = rtp_pstn.rtp_fd; | |
129 fd_out[1] = rtp_pstn.rtcp_fd; | |
130 break; | |
131 case RTP_ALLOC_TYPE_GSM2PSTN: | |
132 case RTP_ALLOC_TYPE_GSM2GSM: | |
133 num_fd = 4; | |
134 fd_out[0] = rtp_gsm.rtp_fd; | |
135 fd_out[1] = rtp_gsm.rtcp_fd; | |
136 fd_out[2] = rtp_pstn.rtp_fd; | |
137 fd_out[3] = rtp_pstn.rtcp_fd; | |
138 } | |
139 bzero(&msg, sizeof msg); | |
140 msg.msg_iov = &iov; | |
141 msg.msg_iovlen = 1; | |
142 msg.msg_control = cmsgu.buf; | |
143 msg.msg_controllen = CMSG_SPACE(sizeof(int) * num_fd); | |
144 cmsg = CMSG_FIRSTHDR(&msg); | |
145 cmsg->cmsg_level = SOL_SOCKET; | |
146 cmsg->cmsg_type = SCM_RIGHTS; | |
147 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fd); | |
148 fd_bufptr = (int *) CMSG_DATA(cmsg); | |
149 bcopy(fd_out, fd_bufptr, sizeof(int) * num_fd); | |
150 sendmsg(fd, &msg, 0); | |
151 close_fds(fd_out, num_fd); | |
152 } |