6 #include "../../../user.h"
28 //-----------------------------------------------------------------------------
29 //-----------------------------------------------------------------------------
30 //-----------------------------------------------------------------------------
32 //-----------------------------------------------------------------------------
33 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
35 // ëÌÁÓÓ ÄÌÑ ÐÏÉÓËÁ ÀÚÅÒÁ × ÓÐÉÓËÅ ÎÏÔÉÆÉËÁÔÏÒÏ×
36 template <typename varType>
37 class IS_CONTAINS_USER: public binary_function<varType, user_iter, bool>
40 bool operator()(varType notifier, user_iter user) const
42 return notifier.GetUser() == user;
45 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
48 BASE_PLUGIN * GetPlugin()
50 return pc.GetPlugin();
52 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
54 //-----------------------------------------------------------------------------
55 PING_SETTINGS::PING_SETTINGS()
60 //-----------------------------------------------------------------------------
61 int PING_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
64 vector<PARAM_VALUE>::const_iterator pvi;
66 pv.param = "PingDelay";
67 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
68 if (pvi == s.moduleParams.end())
70 errorStr = "Parameter \'PingDelay\' not found.";
71 printfd(__FILE__, "Parameter 'PingDelay' not found\n");
74 if (ParseIntInRange(pvi->value[0], 5, 3600, &pingDelay))
76 errorStr = "Cannot parse parameter \'PingDelay\': " + errorStr;
77 printfd(__FILE__, "Canot parse parameter 'PingDelay'\n");
83 //-----------------------------------------------------------------------------
84 int PING_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
86 if (str2x(str.c_str(), *val))
88 errorStr = "Incorrect value \'" + str + "\'.";
91 if (*val < min || *val > max)
93 errorStr = "Value \'" + str + "\' out of range.";
98 //-----------------------------------------------------------------------------
101 pthread_mutex_init(&mutex, NULL);
104 //-----------------------------------------------------------------------------
107 pthread_mutex_destroy(&mutex);
109 //-----------------------------------------------------------------------------
110 const string PING::GetVersion() const
112 return "Pinger v.1.01";
114 //-----------------------------------------------------------------------------
115 void PING::SetSettings(const MODULE_SETTINGS & s)
119 //-----------------------------------------------------------------------------
120 int PING::ParseSettings()
122 int ret = pingSettings.ParseSettings(settings);
124 errorStr = pingSettings.GetStrError();
127 //-----------------------------------------------------------------------------
128 void PING::SetUsers(USERS * u)
132 //-----------------------------------------------------------------------------
133 const string & PING::GetStrError() const
137 //-----------------------------------------------------------------------------
142 onAddUserNotifier.SetPinger(this);
143 onDelUserNotifier.SetPinger(this);
144 users->AddNotifierUserAdd(&onAddUserNotifier);
145 users->AddNotifierUserDel(&onDelUserNotifier);
149 pinger.SetDelayTime(pingSettings.GetPingDelay());
152 if (pthread_create(&thread, NULL, Run, this))
154 errorStr = "Cannot start thread.";
155 printfd(__FILE__, "Cannot start thread\n");
161 //-----------------------------------------------------------------------------
164 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
171 //5 seconds to thread stops itself
172 for (int i = 0; i < 25; i++)
180 //after 5 seconds waiting thread still running. now kill it
183 printfd(__FILE__, "kill PING thread.\n");
184 if (pthread_kill(thread, SIGINT))
186 errorStr = "Cannot kill PING thread.";
187 printfd(__FILE__, "Cannot kill PING thread.\n");
190 printfd(__FILE__, "PING killed\n");
193 users->DelNotifierUserAdd(&onAddUserNotifier);
194 users->DelNotifierUserDel(&onDelUserNotifier);
196 list<user_iter>::iterator users_iter;
197 users_iter = usersList.begin();
198 while (users_iter != usersList.end())
200 UnSetUserNotifiers(*users_iter);
206 //-----------------------------------------------------------------------------
207 bool PING::IsRunning()
211 //-----------------------------------------------------------------------------
212 void * PING::Run(void * d)
214 PING * ping = (PING*)d;
215 ping->isRunning = true;
216 list<user_iter>::iterator iter;
220 while (ping->nonstop)
222 iter = ping->usersList.begin();
224 STG_LOCKER lock(&ping->mutex, __FILE__, __LINE__);
225 while (iter != ping->usersList.end())
227 if ((*iter)->property.ips.ConstData().OnlyOneIP())
229 ip = (*iter)->property.ips.ConstData()[0].ip;
230 if (ping->pinger.GetIPTime(ip, &t) == 0)
233 (*iter)->UpdatePingTime(t);
238 ip = (*iter)->GetCurrIP();
241 if (ping->pinger.GetIPTime(ip, &t) == 0)
244 (*iter)->UpdatePingTime(t);
251 for (int i = 0; i < 100; i++)
255 usleep((10000*ping->pingSettings.GetPingDelay())/3 + 50000);
259 ping->isRunning = false;
262 //-----------------------------------------------------------------------------
263 uint16_t PING::GetStartPosition() const
267 //-----------------------------------------------------------------------------
268 uint16_t PING::GetStopPosition() const
272 //-----------------------------------------------------------------------------
273 void PING::SetUserNotifiers(user_iter u)
275 CHG_CURRIP_NOTIFIER_PING ChgCurrIPNotifier;
276 CHG_IPS_NOTIFIER_PING ChgIPNotifier;
278 ChgCurrIPNotifier.SetPinger(this);
279 ChgCurrIPNotifier.SetUser(u);
280 ChgCurrIPNotifierList.push_front(ChgCurrIPNotifier);
282 ChgIPNotifier.SetPinger(this);
283 ChgIPNotifier.SetUser(u);
284 ChgIPNotifierList.push_front(ChgIPNotifier);
286 u->AddCurrIPAfterNotifier(&(*ChgCurrIPNotifierList.begin()));
287 u->property.ips.AddAfterNotifier(&(*ChgIPNotifierList.begin()));
289 //-----------------------------------------------------------------------------
290 void PING::UnSetUserNotifiers(user_iter u)
293 IS_CONTAINS_USER<CHG_CURRIP_NOTIFIER_PING> IsContainsUserCurrIP;
294 IS_CONTAINS_USER<CHG_IPS_NOTIFIER_PING> IsContainsUserIP;
296 list<CHG_CURRIP_NOTIFIER_PING>::iterator currIPter;
297 list<CHG_IPS_NOTIFIER_PING>::iterator IPIter;
299 currIPter = find_if(ChgCurrIPNotifierList.begin(),
300 ChgCurrIPNotifierList.end(),
301 bind2nd(IsContainsUserCurrIP, u));
303 if (currIPter != ChgCurrIPNotifierList.end())
305 currIPter->GetUser()->DelCurrIPAfterNotifier(&(*currIPter));
306 ChgCurrIPNotifierList.erase(currIPter);
308 // --- CurrIP end ---
311 IPIter = find_if(ChgIPNotifierList.begin(),
312 ChgIPNotifierList.end(),
313 bind2nd(IsContainsUserIP, u));
315 if (IPIter != ChgIPNotifierList.end())
317 IPIter->GetUser()->property.ips.DelAfterNotifier(&(*IPIter));
318 ChgIPNotifierList.erase(IPIter);
322 //-----------------------------------------------------------------------------
323 void PING::GetUsers()
325 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
328 int h = users->OpenSearch();
331 printfd(__FILE__, "users->OpenSearch() error\n");
335 while (users->SearchNext(h, &u) == 0)
337 usersList.push_back(u);
339 if (u->property.ips.ConstData().OnlyOneIP())
341 pinger.AddIP(u->property.ips.ConstData()[0].ip);
345 uint32_t ip = u->GetCurrIP();
353 users->CloseSearch(h);
355 //-----------------------------------------------------------------------------
356 void PING::AddUser(user_iter u)
358 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
361 usersList.push_back(u);
363 //-----------------------------------------------------------------------------
364 void PING::DelUser(user_iter u)
366 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
368 UnSetUserNotifiers(u);
370 list<user_iter>::iterator users_iter;
371 users_iter = usersList.begin();
373 while (users_iter != usersList.end())
375 if (u == *users_iter)
377 usersList.erase(users_iter);
383 //-----------------------------------------------------------------------------
384 void CHG_CURRIP_NOTIFIER_PING::Notify(const uint32_t & oldIP, const uint32_t & newIP)
386 ping->pinger.DelIP(oldIP);
389 ping->pinger.AddIP(newIP);
392 //-----------------------------------------------------------------------------
393 void CHG_IPS_NOTIFIER_PING::Notify(const USER_IPS & oldIPS, const USER_IPS & newIPS)
395 if (oldIPS.OnlyOneIP())
397 ping->pinger.DelIP(oldIPS[0].ip);
400 if (newIPS.OnlyOneIP())
402 ping->pinger.AddIP(newIPS[0].ip);
405 //-----------------------------------------------------------------------------
406 void ADD_USER_NONIFIER_PING::Notify(const user_iter & user)
410 //-----------------------------------------------------------------------------
411 void DEL_USER_NONIFIER_PING::Notify(const user_iter & user)
415 //-----------------------------------------------------------------------------