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 IS_CONTAINS_USER(const user_iter & u) : user(u) {}
41 bool operator()(varType notifier) const
43 return notifier.GetUser() == user;
46 const user_iter & user;
48 //-----------------------------------------------------------------------------
49 //-----------------------------------------------------------------------------
50 //-----------------------------------------------------------------------------
51 BASE_PLUGIN * GetPlugin()
53 return pc.GetPlugin();
55 //-----------------------------------------------------------------------------
56 //-----------------------------------------------------------------------------
57 //-----------------------------------------------------------------------------
58 PING_SETTINGS::PING_SETTINGS()
62 //-----------------------------------------------------------------------------
63 int PING_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
66 vector<PARAM_VALUE>::const_iterator pvi;
68 pv.param = "PingDelay";
69 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
70 if (pvi == s.moduleParams.end())
72 errorStr = "Parameter \'PingDelay\' not found.";
73 printfd(__FILE__, "Parameter 'PingDelay' not found\n");
76 if (ParseIntInRange(pvi->value[0], 5, 3600, &pingDelay))
78 errorStr = "Cannot parse parameter \'PingDelay\': " + errorStr;
79 printfd(__FILE__, "Canot parse parameter 'PingDelay'\n");
85 //-----------------------------------------------------------------------------
86 int PING_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
88 if (str2x(str.c_str(), *val))
90 errorStr = "Incorrect value \'" + str + "\'.";
93 if (*val < min || *val > max)
95 errorStr = "Value \'" + str + "\' out of range.";
100 //-----------------------------------------------------------------------------
105 onAddUserNotifier(*this),
106 onDelUserNotifier(*this)
108 pthread_mutex_init(&mutex, NULL);
110 //-----------------------------------------------------------------------------
113 pthread_mutex_destroy(&mutex);
115 //-----------------------------------------------------------------------------
116 const string PING::GetVersion() const
118 return "Pinger v.1.01";
120 //-----------------------------------------------------------------------------
121 void PING::SetSettings(const MODULE_SETTINGS & s)
125 //-----------------------------------------------------------------------------
126 int PING::ParseSettings()
128 int ret = pingSettings.ParseSettings(settings);
130 errorStr = pingSettings.GetStrError();
133 //-----------------------------------------------------------------------------
134 void PING::SetUsers(USERS * u)
138 //-----------------------------------------------------------------------------
139 const string & PING::GetStrError() const
143 //-----------------------------------------------------------------------------
148 users->AddNotifierUserAdd(&onAddUserNotifier);
149 users->AddNotifierUserDel(&onDelUserNotifier);
153 pinger.SetDelayTime(pingSettings.GetPingDelay());
156 if (pthread_create(&thread, NULL, Run, this))
158 errorStr = "Cannot start thread.";
159 printfd(__FILE__, "Cannot start thread\n");
165 //-----------------------------------------------------------------------------
168 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
175 //5 seconds to thread stops itself
176 for (int i = 0; i < 25; i++)
184 //after 5 seconds waiting thread still running. now kill it
187 printfd(__FILE__, "kill PING thread.\n");
188 if (pthread_kill(thread, SIGINT))
190 errorStr = "Cannot kill PING thread.";
191 printfd(__FILE__, "Cannot kill PING thread.\n");
194 printfd(__FILE__, "PING killed\n");
197 users->DelNotifierUserAdd(&onAddUserNotifier);
198 users->DelNotifierUserDel(&onDelUserNotifier);
200 list<user_iter>::iterator users_iter;
201 users_iter = usersList.begin();
202 while (users_iter != usersList.end())
204 UnSetUserNotifiers(*users_iter);
210 //-----------------------------------------------------------------------------
211 bool PING::IsRunning()
215 //-----------------------------------------------------------------------------
216 void * PING::Run(void * d)
218 PING * ping = (PING*)d;
219 ping->isRunning = true;
220 list<user_iter>::iterator iter;
224 while (ping->nonstop)
226 iter = ping->usersList.begin();
228 STG_LOCKER lock(&ping->mutex, __FILE__, __LINE__);
229 while (iter != ping->usersList.end())
231 if ((*iter)->property.ips.ConstData().OnlyOneIP())
233 ip = (*iter)->property.ips.ConstData()[0].ip;
234 if (ping->pinger.GetIPTime(ip, &t) == 0)
237 (*iter)->UpdatePingTime(t);
242 ip = (*iter)->GetCurrIP();
245 if (ping->pinger.GetIPTime(ip, &t) == 0)
248 (*iter)->UpdatePingTime(t);
255 for (int i = 0; i < 100; i++)
259 usleep((10000*ping->pingSettings.GetPingDelay())/3 + 50000);
263 ping->isRunning = false;
266 //-----------------------------------------------------------------------------
267 uint16_t PING::GetStartPosition() const
271 //-----------------------------------------------------------------------------
272 uint16_t PING::GetStopPosition() const
276 //-----------------------------------------------------------------------------
277 void PING::SetUserNotifiers(user_iter u)
279 CHG_CURRIP_NOTIFIER_PING ChgCurrIPNotifier(*this, u);
280 CHG_IPS_NOTIFIER_PING ChgIPNotifier(*this, u);
282 ChgCurrIPNotifierList.push_front(ChgCurrIPNotifier);
283 ChgIPNotifierList.push_front(ChgIPNotifier);
285 u->AddCurrIPAfterNotifier(&(*ChgCurrIPNotifierList.begin()));
286 u->property.ips.AddAfterNotifier(&(*ChgIPNotifierList.begin()));
288 //-----------------------------------------------------------------------------
289 void PING::UnSetUserNotifiers(user_iter u)
292 IS_CONTAINS_USER<CHG_CURRIP_NOTIFIER_PING> IsContainsUserCurrIP(u);
293 IS_CONTAINS_USER<CHG_IPS_NOTIFIER_PING> IsContainsUserIP(u);
295 list<CHG_CURRIP_NOTIFIER_PING>::iterator currIPter;
296 list<CHG_IPS_NOTIFIER_PING>::iterator IPIter;
298 currIPter = find_if(ChgCurrIPNotifierList.begin(),
299 ChgCurrIPNotifierList.end(),
300 IsContainsUserCurrIP);
302 if (currIPter != ChgCurrIPNotifierList.end())
304 currIPter->GetUser()->DelCurrIPAfterNotifier(&(*currIPter));
305 ChgCurrIPNotifierList.erase(currIPter);
307 // --- CurrIP end ---
310 IPIter = find_if(ChgIPNotifierList.begin(),
311 ChgIPNotifierList.end(),
314 if (IPIter != ChgIPNotifierList.end())
316 IPIter->GetUser()->property.ips.DelAfterNotifier(&(*IPIter));
317 ChgIPNotifierList.erase(IPIter);
321 //-----------------------------------------------------------------------------
322 void PING::GetUsers()
324 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
327 int h = users->OpenSearch();
330 printfd(__FILE__, "users->OpenSearch() error\n");
334 while (users->SearchNext(h, &u) == 0)
336 usersList.push_back(u);
338 if (u->property.ips.ConstData().OnlyOneIP())
340 pinger.AddIP(u->property.ips.ConstData()[0].ip);
344 uint32_t ip = u->GetCurrIP();
352 users->CloseSearch(h);
354 //-----------------------------------------------------------------------------
355 void PING::AddUser(user_iter u)
357 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
360 usersList.push_back(u);
362 //-----------------------------------------------------------------------------
363 void PING::DelUser(user_iter u)
365 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
367 UnSetUserNotifiers(u);
369 list<user_iter>::iterator users_iter;
370 users_iter = usersList.begin();
372 while (users_iter != usersList.end())
374 if (u == *users_iter)
376 usersList.erase(users_iter);
382 //-----------------------------------------------------------------------------
383 void CHG_CURRIP_NOTIFIER_PING::Notify(const uint32_t & oldIP, const uint32_t & newIP)
385 ping.pinger.DelIP(oldIP);
388 ping.pinger.AddIP(newIP);
391 //-----------------------------------------------------------------------------
392 void CHG_IPS_NOTIFIER_PING::Notify(const USER_IPS & oldIPS, const USER_IPS & newIPS)
394 if (oldIPS.OnlyOneIP())
396 ping.pinger.DelIP(oldIPS[0].ip);
399 if (newIPS.OnlyOneIP())
401 ping.pinger.AddIP(newIPS[0].ip);
404 //-----------------------------------------------------------------------------
405 void ADD_USER_NONIFIER_PING::Notify(const user_iter & user)
409 //-----------------------------------------------------------------------------
410 void DEL_USER_NONIFIER_PING::Notify(const user_iter & user)
414 //-----------------------------------------------------------------------------