1 /*
2 * Copyright (c) 2004-2006 Maxim Sobolev <sobomax@FreeBSD.org>
3 * Copyright (c) 2006-2015 Sippy Software, Inc., http://www.sippysoft.com
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28
29 #include <sys/types.h>
30 #include <netinet/in.h>
31 #include <stdlib.h>
32
33 #include "rtpp_defines.h"
34 #include "rtpp_cfg_stable.h"
35 #include "rtpp_types.h"
36 #include "rtpp_refcnt.h"
37 #include "rtpp_weakref.h"
38 #include "rtpp_hash_table.h"
39 #include "rtp.h"
40 #include "rtp_packet.h"
41 #include "rtpp_proc.h"
42 #include "rtpp_proc_servers.h"
43 #include "rtpp_server.h"
44 #include "rtpp_stream.h"
45 #include "rtpp_netaddr.h"
46
47 struct foreach_args {
48 double dtime;
49 struct sthread_args *sender;
50 struct rtpp_proc_rstats *rsp;
51 struct rtpp_weakref_obj *rtp_streams_wrt;
52 struct rtpp_weakref_obj *rtcp_streams_wrt;
53 };
54
55 static int
process_rtp_servers_foreach(void * dp,void * ap)56 process_rtp_servers_foreach(void *dp, void *ap)
57 {
58 struct foreach_args *fap;
59 struct rtpp_server *rsrv;
60 struct rtp_packet *pkt;
61 int len;
62 struct rtpp_stream *rsop;
63
64 fap = (struct foreach_args *)ap;
65 /*
66 * This method does not need us to bump ref, since we are in the
67 * locked context of the rtpp_hash_table, which holds its own ref.
68 */
69 rsrv = (struct rtpp_server *)dp;
70 rsop = CALL_METHOD(fap->rtp_streams_wrt, get_by_idx, rsrv->stuid);
71 if (rsop == NULL) {
72 return (RTPP_WR_MATCH_CONT);
73 }
74 for (;;) {
75 pkt = CALL_SMETHOD(rsrv, get, fap->dtime, &len);
76 if (pkt == NULL) {
77 if (len == RTPS_EOF) {
78 CALL_SMETHOD(rsop, finish_playback, rsrv->sruid);
79 CALL_SMETHOD(rsop->rcnt, decref);
80 return (RTPP_WR_MATCH_DEL);
81 } else if (len != RTPS_LATER) {
82 /* XXX some error, brag to logs */
83 }
84 break;
85 }
86 if (CALL_SMETHOD(rsop, issendable) == 0) {
87 /* We have a packet, but nowhere to send it, drop */
88 rtp_packet_free(pkt);
89 continue;
90 }
91 CALL_SMETHOD(rsop, send_pkt, fap->sender, pkt);
92 fap->rsp->npkts_played.cnt++;
93 }
94 CALL_SMETHOD(rsop->rcnt, decref);
95 return (RTPP_WR_MATCH_CONT);
96 }
97
98 void
rtpp_proc_servers(struct cfg * cf,double dtime,struct sthread_args * sender,struct rtpp_proc_rstats * rsp)99 rtpp_proc_servers(struct cfg *cf, double dtime, struct sthread_args *sender,
100 struct rtpp_proc_rstats *rsp)
101 {
102 struct foreach_args fargs;
103
104 fargs.dtime = dtime;
105 fargs.sender = sender;
106 fargs.rsp = rsp;
107 fargs.rtp_streams_wrt = cf->stable->rtp_streams_wrt;
108 fargs.rtcp_streams_wrt = cf->stable->rtcp_streams_wrt;
109
110 CALL_METHOD(cf->stable->servers_wrt, foreach, process_rtp_servers_foreach,
111 &fargs);
112 }
113