blob: 32543110ac622cd0544b85b03f4365db842080a2 [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
Alexandre Lisionddd731e2014-01-31 11:50:08 -050047NAMESPACE_COMMONCPP
Emeric Vigier2f625822012-08-06 11:09:52 -040048
49static void
50findusername(std::string &username);
51
Alexandre Lisionddd731e2014-01-31 11:50:08 -050052#ifndef _MSWINDOWS_
Emeric Vigier2f625822012-08-06 11:09:52 -040053static void
54findusername(std::string &username)
55{
56 // LOGNAME environment var has two advantages:
57 // 1) avoids problems of getlogin(3) and cuserid(3)
58 // 2) unlike getpwuid, takes into account user
59 // customization of the environment.
60 // Try both LOGNAME and USER env. var.
61 const char *user = Process::getEnv("LOGNAME");
62 if ( !user || !strcmp(user,"") )
63 user = Process::getEnv("USER");
64 if ( !user || !strcmp(user,"") )
65 username = Process::getUser();
66
67 if ( user )
68 username = user;
69 else
70 username = "";
71}
72
73#else
74
75static void
76findusername(std::string &username)
77{
78 unsigned long len = 0;
79 if ( GetUserName(NULL,&len) && (len > 0) ) {
80 char *n = new char[len];
81 GetUserName(n,&len);
82 username = n;
83 delete [] n;
84 } else {
85 username = "";
86 }
87}
88#endif // #ifndef WIN32
89
90void
91SDESItemsHolder::setItem(SDESItemType item, const std::string& val)
92{
93 if ( item > SDESItemTypeEND && item <= SDESItemTypeH323CADDR ) {
94 sdesItems[item] = val;
95 }
96}
97
98const std::string&
99SDESItemsHolder::getItem(SDESItemType type) const
100{
101 if ( type > SDESItemTypeEND && type <= SDESItemTypeH323CADDR ) {
102 return sdesItems[type];
103 } else
104 return sdesItems[SDESItemTypeCNAME];
105}
106
107SyncSource::SyncSource(uint32 ssrc) :
108state(stateUnknown), SSRC(ssrc), participant(NULL),
109networkAddress("0"), dataTransportPort(0), controlTransportPort(0)
110{}
111
112SyncSource::~SyncSource()
113{
114 activeSender = false;
115 state = statePrevalid;
116}
117
118Participant::Participant(const std::string& cname) : SDESItemsHolder()
119{
120 SDESItemsHolder::setItem(SDESItemTypeCNAME,cname);
121}
122
123Participant::~Participant()
124{}
125
126const size_t RTPApplication::defaultParticipantsNum = 11;
127
128RTPApplication& defaultApplication()
129{
130 // default application CNAME is automatically assigned.
131 static RTPApplication defApp("");
132
133 return defApp;
134}
135
136RTPApplication::RTPApplication(const std::string& cname) :
137SDESItemsHolder(), participants( new Participant* [defaultParticipantsNum] ),
138firstPart(NULL), lastPart(NULL)
139{
140 // guess CNAME, in the form of user@host_fqn
141 if ( cname.length() > 0 )
142 SDESItemsHolder::setItem(SDESItemTypeCNAME,cname);
143 else
144 findCNAME();
145}
146
147RTPApplication::~RTPApplication()
148{
149 ParticipantLink *p;
150 while ( NULL != firstPart ) {
151 p = firstPart;
152 firstPart = firstPart->getNext();
153#ifdef CCXX_EXCEPTIONS
154 try {
155#endif
156 delete p;
157#ifdef CCXX_EXCEPTIONS
158 } catch (...) {}
159#endif
160 }
161 lastPart = NULL;
162#ifdef CCXX_EXCEPTIONS
163 try {
164#endif
165 delete [] participants;
166#ifdef CCXX_EXCEPTIONS
167 } catch (...) {}
168#endif
169}
170
171// TODO: it should be implemented using the participant iterators
172const Participant*
173RTPApplication::getParticipant(const std::string& cname) const
174{
175 ParticipantLink* pl = firstPart;
176 while ( (NULL != pl) &&
177 ( pl->getParticipant()->getSDESItem(SDESItemTypeCNAME)
178 != cname) ) {
179 pl = pl->getNext();
180 }
181 if ( pl ) {
182 return pl->getParticipant();
183 } else {
184 return NULL;
185 }
186}
187
188void
189RTPApplication::addParticipant(Participant& part)
190{
191 ParticipantLink* pl = new ParticipantLink(part,NULL);
192 if ( NULL == firstPart )
193 firstPart = lastPart = pl;
194 else
195 lastPart->setNext(pl);
196 lastPart = pl;
197}
198
199void
200RTPApplication::removeParticipant(ParticipantLink* pl)
201{
202 if ( NULL == pl )
203 return;
204 if ( pl->getPrev() )
205 pl->getPrev()->setNext(pl->getNext());
206 if ( pl->getNext() )
207 pl->getNext()->setPrev(pl->getPrev());
208 delete pl;
209}
210
211void
212RTPApplication::findCNAME()
213{
214 // build string username@host_fqn
215 std::string username;
216 findusername(username);
217
218 // First create an InetHostAddress object, otherwise the
219 // object will be destructed and the hostname corrupted.
220 InetHostAddress iha;
221 const char *p = iha.getHostname();
222 // Returned hostname can be NULL
223 std::string hname;
224 if (p) hname = p;
225
226 setSDESItem(SDESItemTypeCNAME,
227 username + "@" + hname);
228}
229
Alexandre Lisionddd731e2014-01-31 11:50:08 -0500230END_NAMESPACE
Emeric Vigier2f625822012-08-06 11:09:52 -0400231
232/** EMACS **
233 * Local variables:
234 * mode: c++
235 * c-basic-offset: 4
236 * End:
237 */