blob: ca153be8148899b78725265ad67cd263548ac92a [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2001,2002,2003,2004,2005 Federico Montesino <fedemp@altern.org>
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16//
17// As a special exception, you may use this file as part of a free software
18// library without restriction. Specifically, if other files instantiate
19// templates or use macros or inline functions from this file, or you compile
20// this file and link it with other files to produce an executable, this
21// file does not by itself cause the resulting executable to be covered by
22// the GNU General Public License. This exception does not however
23// invalidate any other reasons why the executable file might be covered by
24// the GNU General Public License.
25//
26// This exception applies only to the code released under the name GNU
27// ccRTP. If you copy code from other releases into a copy of GNU
28// ccRTP, as the General Public License permits, the exception does
29// not apply to the code that you add in this way. To avoid misleading
30// anyone as to the status of such modified files, you must delete
31// this exception notice from them.
32//
33// If you write modifications of your own for GNU ccRTP, it is your choice
34// whether to permit this exception to apply to your modifications.
35// If you do not wish that, delete this exception notice.
36//
37
38/**
39 * @file control.cpp
40 *
41 * @short SDESItemsHolder, RTPSource and Participant classes implementation.
42 **/
43
44#include "private.h"
45#include <ccrtp/sources.h>
46
47#ifdef CCXX_NAMESPACES
48namespace ost {
49#endif
50
51#ifndef HAVE_GETTIMEOFDAY
52#ifdef WIN32
53int gettimeofday(struct timeval *tv_, void *tz_)
54{
55 // We could use _ftime(), but it is not available on WinCE.
56 // (WinCE also lacks time.h)
57 // Note also that the average error of _ftime is around 20 ms :)
58 DWORD ms = GetTickCount();
59 tv_->tv_sec = ms / 1000;
60 tv_->tv_usec = ms * 1000;
61 return 0;
62}
63#endif //WIN32
64#endif
65
66static void
67findusername(std::string &username);
68
69#ifndef WIN32
70static void
71findusername(std::string &username)
72{
73 // LOGNAME environment var has two advantages:
74 // 1) avoids problems of getlogin(3) and cuserid(3)
75 // 2) unlike getpwuid, takes into account user
76 // customization of the environment.
77 // Try both LOGNAME and USER env. var.
78 const char *user = Process::getEnv("LOGNAME");
79 if ( !user || !strcmp(user,"") )
80 user = Process::getEnv("USER");
81 if ( !user || !strcmp(user,"") )
82 username = Process::getUser();
83
84 if ( user )
85 username = user;
86 else
87 username = "";
88}
89
90#else
91
92static void
93findusername(std::string &username)
94{
95 unsigned long len = 0;
96 if ( GetUserName(NULL,&len) && (len > 0) ) {
97 char *n = new char[len];
98 GetUserName(n,&len);
99 username = n;
100 delete [] n;
101 } else {
102 username = "";
103 }
104}
105#endif // #ifndef WIN32
106
107void
108SDESItemsHolder::setItem(SDESItemType item, const std::string& val)
109{
110 if ( item > SDESItemTypeEND && item <= SDESItemTypeH323CADDR ) {
111 sdesItems[item] = val;
112 }
113}
114
115const std::string&
116SDESItemsHolder::getItem(SDESItemType type) const
117{
118 if ( type > SDESItemTypeEND && type <= SDESItemTypeH323CADDR ) {
119 return sdesItems[type];
120 } else
121 return sdesItems[SDESItemTypeCNAME];
122}
123
124SyncSource::SyncSource(uint32 ssrc) :
125state(stateUnknown), SSRC(ssrc), participant(NULL),
126networkAddress("0"), dataTransportPort(0), controlTransportPort(0)
127{}
128
129SyncSource::~SyncSource()
130{
131 activeSender = false;
132 state = statePrevalid;
133}
134
135Participant::Participant(const std::string& cname) : SDESItemsHolder()
136{
137 SDESItemsHolder::setItem(SDESItemTypeCNAME,cname);
138}
139
140Participant::~Participant()
141{}
142
143const size_t RTPApplication::defaultParticipantsNum = 11;
144
145RTPApplication& defaultApplication()
146{
147 // default application CNAME is automatically assigned.
148 static RTPApplication defApp("");
149
150 return defApp;
151}
152
153RTPApplication::RTPApplication(const std::string& cname) :
154SDESItemsHolder(), participants( new Participant* [defaultParticipantsNum] ),
155firstPart(NULL), lastPart(NULL)
156{
157 // guess CNAME, in the form of user@host_fqn
158 if ( cname.length() > 0 )
159 SDESItemsHolder::setItem(SDESItemTypeCNAME,cname);
160 else
161 findCNAME();
162}
163
164RTPApplication::~RTPApplication()
165{
166 ParticipantLink *p;
167 while ( NULL != firstPart ) {
168 p = firstPart;
169 firstPart = firstPart->getNext();
170#ifdef CCXX_EXCEPTIONS
171 try {
172#endif
173 delete p;
174#ifdef CCXX_EXCEPTIONS
175 } catch (...) {}
176#endif
177 }
178 lastPart = NULL;
179#ifdef CCXX_EXCEPTIONS
180 try {
181#endif
182 delete [] participants;
183#ifdef CCXX_EXCEPTIONS
184 } catch (...) {}
185#endif
186}
187
188// TODO: it should be implemented using the participant iterators
189const Participant*
190RTPApplication::getParticipant(const std::string& cname) const
191{
192 ParticipantLink* pl = firstPart;
193 while ( (NULL != pl) &&
194 ( pl->getParticipant()->getSDESItem(SDESItemTypeCNAME)
195 != cname) ) {
196 pl = pl->getNext();
197 }
198 if ( pl ) {
199 return pl->getParticipant();
200 } else {
201 return NULL;
202 }
203}
204
205void
206RTPApplication::addParticipant(Participant& part)
207{
208 ParticipantLink* pl = new ParticipantLink(part,NULL);
209 if ( NULL == firstPart )
210 firstPart = lastPart = pl;
211 else
212 lastPart->setNext(pl);
213 lastPart = pl;
214}
215
216void
217RTPApplication::removeParticipant(ParticipantLink* pl)
218{
219 if ( NULL == pl )
220 return;
221 if ( pl->getPrev() )
222 pl->getPrev()->setNext(pl->getNext());
223 if ( pl->getNext() )
224 pl->getNext()->setPrev(pl->getPrev());
225 delete pl;
226}
227
228void
229RTPApplication::findCNAME()
230{
231 // build string username@host_fqn
232 std::string username;
233 findusername(username);
234
235 // First create an InetHostAddress object, otherwise the
236 // object will be destructed and the hostname corrupted.
237 InetHostAddress iha;
238 const char *p = iha.getHostname();
239 // Returned hostname can be NULL
240 std::string hname;
241 if (p) hname = p;
242
243 setSDESItem(SDESItemTypeCNAME,
244 username + "@" + hname);
245}
246
247#ifdef CCXX_NAMESPACES
248}
249#endif
250
251/** EMACS **
252 * Local variables:
253 * mode: c++
254 * c-basic-offset: 4
255 * End:
256 */