1 
2 #include "RoomInfo.h"
3 #include "WebConference.h"
4 
5 #include <string.h>
6 #include "log.h"
7 
8 void ConferenceRoomParticipant::updateAccess(const struct timeval& now) {
9   memcpy(&last_access_time, &now, sizeof(struct timeval));
10 }
11 
12 bool ConferenceRoomParticipant::expired(const struct timeval& now) {
13   if (Finished != status)
14     return false;
15 
16   if (WebConferenceFactory::ParticipantExpiredDelay < 0)
17     return false;
18 
19   struct timeval diff;
20   timersub(&now,&last_access_time,&diff);
21   return (diff.tv_sec > 0) &&
22     (unsigned int)diff.tv_sec > (unsigned int)WebConferenceFactory::ParticipantExpiredDelay;
23 }
24 
25 AmArg ConferenceRoomParticipant::asArgArray() {
26   AmArg res;
27   res.push(AmArg(localtag.c_str()));
28   res.push(AmArg(number.c_str()));
29   res.push(AmArg((int)status));
30   res.push(AmArg(last_reason.c_str()));
31   res.push(AmArg((int)muted));
32   res.push(AmArg(participant_id));
33   return res;
34 }
35 
36 void ConferenceRoomParticipant::setMuted(int mute) {
37   muted = mute;
38 }
39 
40 void ConferenceRoomParticipant::updateStatus(ConferenceRoomParticipant::ParticipantStatus
41 					     new_status,
42 					     const string& reason,
43 					     struct timeval& now) {
44   status = new_status;
45   last_reason = reason;
46   updateAccess(now);
47 }
48 
49 ConferenceRoom::ConferenceRoom()
50   : expiry_time(0)
51 {
52   gettimeofday(&last_access_time, NULL);
53 }
54 
55 void ConferenceRoom::cleanExpired() {
56   struct timeval now;
57   gettimeofday(&now, NULL);
58   bool is_updated = false;
59 
60   list<ConferenceRoomParticipant>::iterator it=participants.begin();
61   while (it != participants.end()) {
62     if (it->expired(now)) {
63       participants.erase(it);
64       it=participants.begin();
65       is_updated = true;
66     } else
67       it++;
68   }
69 
70   if (is_updated)
71     memcpy(&last_access_time, &now, sizeof(struct timeval));
72 }
73 
74 AmArg ConferenceRoom::asArgArray() {
75   cleanExpired();
76   AmArg res;
77   res.assertArray(0); // make array from it
78 
79   for (list<ConferenceRoomParticipant>::iterator it=participants.begin();
80        it != participants.end(); it++) {
81     res.push(it->asArgArray());
82   }
83   return res;
84 }
85 
86 vector<string> ConferenceRoom::participantLtags() {
87   cleanExpired();
88   vector<string> res;
89   for (list<ConferenceRoomParticipant>::iterator it=participants.begin();
90        it != participants.end(); it++) {
91     res.push_back(it->localtag);
92   }
93   return res;
94 }
95 
96 void ConferenceRoom::newParticipant(const string& localtag,
97 				    const string& number,
98 				    const string& participant_id) {
99   gettimeofday(&last_access_time, NULL);
100 
101   if (!participant_id.empty()) {
102     // search for participant with id and localtag empty
103     for (list<ConferenceRoomParticipant>::iterator it=participants.begin();
104 	 it != participants.end(); it++) {
105       if (it->participant_id == participant_id && it->localtag.empty()) {
106 	DBG("found invited participant with ID '%s'\n", participant_id.c_str());
107 	it->localtag = localtag;
108 	it->number = number;
109 	return;
110       }
111     }
112 
113   }
114 
115   participants.push_back(ConferenceRoomParticipant());
116   participants.back().localtag = localtag;
117   participants.back().number = number;
118   participants.back().participant_id = participant_id;
119 }
120 
121 bool ConferenceRoom::hasParticipant(const string& localtag) {
122   for (list<ConferenceRoomParticipant>::iterator it =
123 	 participants.begin(); it != participants.end();it++) {
124     if (it->localtag == localtag)
125       return true;
126   }
127 
128   return false;
129 }
130 
131 bool ConferenceRoom::hasInvitedParticipant(const string& participant_id) {
132   for (list<ConferenceRoomParticipant>::iterator it =
133 	 participants.begin(); it != participants.end();it++) {
134     if (it->participant_id == participant_id)
135       return true;
136   }
137   return false;
138 }
139 
140 void ConferenceRoom::setMuted(const string& localtag, int mute) {
141   gettimeofday(&last_access_time, NULL);
142 
143   for (list<ConferenceRoomParticipant>::iterator it =participants.begin();
144        it != participants.end();it++)
145     if (it->localtag == localtag) {
146       it->setMuted(mute);
147       break;
148     }
149 }
150 
151 bool ConferenceRoom::updateStatus(const string& part_tag,
152 				  ConferenceRoomParticipant::ParticipantStatus newstatus,
153 				  const string& reason) {
154   gettimeofday(&last_access_time, NULL);
155 
156   bool res = false;
157   for (list<ConferenceRoomParticipant>::iterator it=participants.begin();
158        it != participants.end(); it++) {
159     if (it->localtag == part_tag) {
160       it->updateStatus(newstatus, reason, last_access_time);
161       res = true;
162       break;
163     }
164   }
165 
166   cleanExpired();
167   return res;
168 }
169 
170 bool ConferenceRoom::expired() {
171   struct timeval now;
172   gettimeofday(&now, NULL);
173   return expired(now);
174 }
175 
176 bool ConferenceRoom::expired(const struct timeval& now) {
177   if (!participants.empty())
178     return false;
179 
180   if (WebConferenceFactory::RoomExpiredDelay < 0)
181     return false;
182 
183   struct timeval diff;
184   timersub(&now,&last_access_time,&diff);
185   return (diff.tv_sec > 0) &&
186     (unsigned int)diff.tv_sec > (unsigned int)WebConferenceFactory::RoomExpiredDelay;
187 }
188 
189 bool ConferenceRoom::hard_expired(const struct timeval& now) {
190   return expiry_time && (now.tv_sec > expiry_time);
191 }
192