00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <iostream>
00018 #include <cstdlib>
00019 #include <cstring>
00020 #include <cstdio>
00021 #include <errno.h>
00022 #include <sys/socket.h>
00023 #include <fcntl.h>
00024 #include <netinet/in.h>
00025 #include <sys/stat.h>
00026 #include <sys/shm.h>
00027
00028 #ifdef linux
00029 # include <sys/vfs.h>
00030 # include <sys/statvfs.h>
00031 # include <sys/sysinfo.h>
00032 #else
00033 # include <sys/param.h>
00034 # include <sys/mount.h>
00035 # ifdef CONFIG_CYGWIN
00036 # include <sys/statfs.h>
00037 # else // if !CONFIG_CYGWIN
00038 # include <sys/sysctl.h>
00039 # endif // !CONFIG_CYGWIN
00040 #endif
00041
00042 #include "zmserver.h"
00043
00044
00045 #define ZM_PROTOCOL_VERSION "6"
00046
00047
00048 #define MAX_IMAGE_SIZE (2048*1536*3)
00049
00050 #define ADD_STR(list,s) list += s; list += "[]:[]";
00051
00052
00053 #define ERROR_TOKEN_COUNT "Invalid token count"
00054 #define ERROR_MYSQL_QUERY "Mysql Query Error"
00055 #define ERROR_MYSQL_ROW "Mysql Get Row Error"
00056 #define ERROR_FILE_OPEN "Cannot open event file"
00057 #define ERROR_INVALID_MONITOR "Invalid Monitor"
00058 #define ERROR_INVALID_POINTERS "Cannot get shared memory pointers"
00059 #define ERROR_INVALID_MONITOR_FUNCTION "Invalid Monitor Function"
00060 #define ERROR_INVALID_MONITOR_ENABLE_VALUE "Invalid Monitor Enable Value"
00061
00062 MYSQL g_dbConn;
00063 string g_zmversion = "";
00064 string g_password = "";
00065 string g_server = "";
00066 string g_database = "";
00067 string g_webPath = "";
00068 string g_user = "";
00069 string g_webUser = "";
00070 string g_binPath = "";
00071
00072 time_t g_lastDBKick = 0;
00073
00074 void loadZMConfig(const string &configfile)
00075 {
00076 cout << "loading zm config from " << configfile << endl;
00077 FILE *cfg;
00078 char line[512];
00079 char val[250];
00080
00081 if ( (cfg = fopen(configfile.c_str(), "r")) == NULL )
00082 {
00083 fprintf(stderr,"Can't open %s\n", configfile.c_str());
00084 exit(1);
00085 }
00086
00087 while ( fgets( line, sizeof(line), cfg ) != NULL )
00088 {
00089 char *line_ptr = line;
00090
00091 size_t chomp_len = strcspn( line_ptr, "\r\n" );
00092 line_ptr[chomp_len] = '\0';
00093
00094
00095 size_t white_len = strspn( line_ptr, " \t" );
00096 line_ptr += white_len;
00097
00098
00099 if ( *line_ptr == '\0' || *line_ptr == '#' )
00100 continue;
00101
00102
00103 char *temp_ptr = line_ptr+strlen(line_ptr)-1;
00104 while ( *temp_ptr == ' ' || *temp_ptr == '\t' )
00105 {
00106 *temp_ptr-- = '\0';
00107 temp_ptr--;
00108 }
00109
00110
00111 temp_ptr = strchr( line_ptr, '=' );
00112 if ( !temp_ptr )
00113 {
00114 fprintf(stderr,"Invalid data in %s: '%s'\n", configfile.c_str(), line );
00115 continue;
00116 }
00117
00118
00119 char *name_ptr = line_ptr;
00120 char *val_ptr = temp_ptr+1;
00121
00122
00123 do
00124 {
00125 *temp_ptr = '\0';
00126 temp_ptr--;
00127 }
00128 while ( *temp_ptr == ' ' || *temp_ptr == '\t' );
00129
00130
00131 white_len = strspn( val_ptr, " \t" );
00132 val_ptr += white_len;
00133
00134 strncpy( val, val_ptr, strlen(val_ptr)+1 );
00135 if ( strcasecmp( name_ptr, "ZM_DB_HOST" ) == 0 ) g_server = val;
00136 else if ( strcasecmp( name_ptr, "ZM_DB_NAME" ) == 0 ) g_database = val;
00137 else if ( strcasecmp( name_ptr, "ZM_DB_USER" ) == 0 ) g_user = val;
00138 else if ( strcasecmp( name_ptr, "ZM_DB_PASS" ) == 0 ) g_password = val;
00139 else if ( strcasecmp( name_ptr, "ZM_PATH_WEB" ) == 0 ) g_webPath = val;
00140 else if ( strcasecmp( name_ptr, "ZM_PATH_BIN" ) == 0 ) g_binPath = val;
00141 else if ( strcasecmp( name_ptr, "ZM_WEB_USER" ) == 0 ) g_webUser = val;
00142 else if ( strcasecmp( name_ptr, "ZM_VERSION" ) == 0 ) g_zmversion = val;
00143 }
00144 fclose(cfg);
00145 }
00146
00147 void connectToDatabase(void)
00148 {
00149 if (!mysql_init(&g_dbConn))
00150 {
00151 cout << "Error: Can't initialise structure: " << mysql_error(&g_dbConn) << endl;
00152 exit(mysql_errno(&g_dbConn));
00153 }
00154
00155 if (!mysql_real_connect(&g_dbConn, g_server.c_str(), g_user.c_str(),
00156 g_password.c_str(), 0, 0, 0, 0))
00157 {
00158 cout << "Error: Can't connect to server: " << mysql_error(&g_dbConn) << endl;
00159 exit(mysql_errno( &g_dbConn));
00160 }
00161
00162 if (mysql_select_db(&g_dbConn, g_database.c_str()))
00163 {
00164 cout << "Error: Can't select database: " << mysql_error(&g_dbConn) << endl;
00165 exit(mysql_errno(&g_dbConn));
00166 }
00167 }
00168
00169 void kickDatabase(bool debug)
00170 {
00171 if (time(NULL) < g_lastDBKick + DB_CHECK_TIME)
00172 return;
00173
00174 if (debug)
00175 cout << "Kicking database connection" << endl;
00176
00177 g_lastDBKick = time(NULL);
00178
00179 if (mysql_query(&g_dbConn, "SELECT NULL;") == 0)
00180 {
00181 MYSQL_RES *res = mysql_store_result(&g_dbConn);
00182 if (res)
00183 mysql_free_result(res);
00184 return;
00185 }
00186
00187 cout << "Lost connection to DB - trying to reconnect" << endl;
00188
00189
00190 mysql_close(&g_dbConn);
00191 connectToDatabase();
00192 }
00193
00194 ZMServer::ZMServer(int sock, bool debug)
00195 {
00196 if (debug)
00197 cout << "Using server protocol version '" << ZM_PROTOCOL_VERSION << "'\n";
00198
00199 m_sock = sock;
00200 m_debug = debug;
00201
00202
00203 char buf[100];
00204 m_shmKey = 0x7a6d2000;
00205 string setting = getZMSetting("ZM_SHM_KEY");
00206
00207 if (setting != "")
00208 sscanf(setting.c_str(), "%x", &m_shmKey);
00209 if (m_debug)
00210 {
00211 snprintf(buf, sizeof(buf), "0x%x", m_shmKey);
00212 cout << "Shared memory key is: " << buf << endl;
00213 }
00214
00215
00216 setting = getZMSetting("ZM_EVENT_IMAGE_DIGITS");
00217 int eventDigits = atoi(setting.c_str());
00218 snprintf(buf, sizeof(buf), "%%0%dd-capture.jpg", eventDigits);
00219 m_eventFileFormat = buf;
00220 if (m_debug)
00221 cout << "Event file format is: " << m_eventFileFormat << endl;
00222
00223
00224 snprintf(buf, sizeof(buf), "%%0%dd-analyse.jpg", eventDigits);
00225 m_analyseFileFormat = buf;
00226 if (m_debug)
00227 cout << "Analyse file format is: " << m_analyseFileFormat << endl;
00228
00229 getMonitorList();
00230 }
00231
00232 ZMServer::~ZMServer()
00233 {
00234 if (m_debug)
00235 cout << "ZMServer destroyed\n";
00236 }
00237
00238 void ZMServer::tokenize(const string &command, vector<string> &tokens)
00239 {
00240 string token = "";
00241 tokens.clear();
00242 string::size_type startPos = 0;
00243 string::size_type endPos = 0;
00244
00245 while((endPos = command.find("[]:[]", startPos)) != string::npos)
00246 {
00247 token = command.substr(startPos, endPos - startPos);
00248 tokens.push_back(token);
00249 startPos = endPos + 5;
00250 }
00251
00252
00253 if (endPos != command.length())
00254 {
00255 token = command.substr(startPos);
00256 tokens.push_back(token);
00257 }
00258 }
00259
00260 void ZMServer::processRequest(char* buf, int nbytes)
00261 {
00262 #if 0
00263
00264 char len[9];
00265 memcpy(len, buf, 8);
00266 len[8] = '\0';
00267 int dataLen = atoi(len);
00268 #endif
00269
00270 buf[nbytes] = '\0';
00271 string s(buf+8);
00272 vector<string> tokens;
00273 tokenize(s, tokens);
00274
00275 if (tokens.size() == 0)
00276 return;
00277
00278 if (m_debug)
00279 cout << "Processing: '" << tokens[0] << "'" << endl;
00280
00281 if (tokens[0] == "HELLO")
00282 handleHello();
00283 else if (tokens[0] == "GET_SERVER_STATUS")
00284 handleGetServerStatus();
00285 else if (tokens[0] == "GET_MONITOR_STATUS")
00286 handleGetMonitorStatus();
00287 else if (tokens[0] == "GET_EVENT_LIST")
00288 handleGetEventList(tokens);
00289 else if (tokens[0] == "GET_EVENT_DATES")
00290 handleGetEventDates(tokens);
00291 else if (tokens[0] == "GET_EVENT_FRAME")
00292 handleGetEventFrame(tokens);
00293 else if (tokens[0] == "GET_ANALYSE_FRAME")
00294 handleGetAnalyseFrame(tokens);
00295 else if (tokens[0] == "GET_LIVE_FRAME")
00296 handleGetLiveFrame(tokens);
00297 else if (tokens[0] == "GET_FRAME_LIST")
00298 handleGetFrameList(tokens);
00299 else if (tokens[0] == "GET_CAMERA_LIST")
00300 handleGetCameraList();
00301 else if (tokens[0] == "GET_MONITOR_LIST")
00302 handleGetMonitorList();
00303 else if (tokens[0] == "DELETE_EVENT")
00304 handleDeleteEvent(tokens);
00305 else if (tokens[0] == "DELETE_EVENT_LIST")
00306 handleDeleteEventList(tokens);
00307 else if (tokens[0] == "RUN_ZMAUDIT")
00308 handleRunZMAudit();
00309 else if (tokens[0] == "SET_MONITOR_FUNCTION")
00310 handleSetMonitorFunction(tokens);
00311 else
00312 send("UNKNOWN_COMMAND");
00313 }
00314
00315 bool ZMServer::send(const string s) const
00316 {
00317
00318 uint32_t len = s.size();
00319 char buf[9];
00320 sprintf(buf, "%8d", len);
00321 int status = ::send(m_sock, buf, 8, MSG_NOSIGNAL);
00322 if (status == -1)
00323 return false;
00324
00325
00326 status = ::send(m_sock, s.c_str(), s.size(), MSG_NOSIGNAL);
00327 if ( status == -1 )
00328 return false;
00329 else
00330 return true;
00331 }
00332
00333 bool ZMServer::send(const string s, const unsigned char *buffer, int dataLen) const
00334 {
00335
00336 uint32_t len = s.size();
00337 char buf[9];
00338 sprintf(buf, "%8d", len);
00339 int status = ::send(m_sock, buf, 8, MSG_NOSIGNAL);
00340 if (status == -1)
00341 return false;
00342
00343
00344 status = ::send(m_sock, s.c_str(), s.size(), MSG_NOSIGNAL);
00345 if ( status == -1 )
00346 return false;
00347
00348
00349 status = ::send(m_sock, buffer, dataLen, MSG_NOSIGNAL);
00350 if ( status == -1 )
00351 return false;
00352
00353 return true;
00354 }
00355
00356 void ZMServer::sendError(string error)
00357 {
00358 string outStr("");
00359 ADD_STR(outStr, string("ERROR - ") + error);
00360 send(outStr);
00361 }
00362
00363 void ZMServer::handleHello()
00364 {
00365
00366
00367 string outStr("");
00368 ADD_STR(outStr, "OK");
00369 ADD_STR(outStr, ZM_PROTOCOL_VERSION);
00370 send(outStr);
00371 }
00372
00373 long long ZMServer::getDiskSpace(const string &filename, long long &total, long long &used)
00374 {
00375 struct statfs statbuf;
00376 bzero(&statbuf, sizeof(statbuf));
00377 long long freespace = -1;
00378
00379 total = used = -1;
00380
00381
00382
00383
00384
00385 if ((statfs(filename.c_str(), &statbuf) == 0) &&
00386 (statbuf.f_blocks > 0) &&
00387 (statbuf.f_bsize > 0))
00388 {
00389 total = statbuf.f_blocks;
00390 total *= statbuf.f_bsize;
00391 total = total >> 10;
00392
00393 freespace = statbuf.f_bavail;
00394 freespace *= statbuf.f_bsize;
00395 freespace = freespace >> 10;
00396
00397 used = total - freespace;
00398 }
00399
00400 return freespace;
00401 }
00402
00403 void ZMServer::handleGetServerStatus(void)
00404 {
00405 string outStr("");
00406 ADD_STR(outStr, "OK")
00407
00408
00409 string status = runCommand(g_binPath + "/zmdc.pl check");
00410 ADD_STR(outStr, status)
00411
00412
00413 double loads[3];
00414 if (getloadavg(loads, 3) == -1)
00415 {
00416 ADD_STR(outStr, "Unknown")
00417 }
00418 else
00419 {
00420 char buf[30];
00421 sprintf(buf, "%0.2lf", loads[0]);
00422 ADD_STR(outStr, buf)
00423 }
00424
00425
00426 char buf[15];
00427 long long total, used;
00428 string eventsDir = g_webPath + "/events/";
00429 getDiskSpace(eventsDir, total, used);
00430 sprintf(buf, "%d%%", (int) ((100.0 / ((float) total / used))));
00431 ADD_STR(outStr, buf)
00432
00433 send(outStr);
00434 }
00435
00436 void ZMServer::handleGetEventList(vector<string> tokens)
00437 {
00438 string outStr("");
00439
00440 if (tokens.size() != 4)
00441 {
00442 sendError(ERROR_TOKEN_COUNT);
00443 return;
00444 }
00445
00446 string monitor = tokens[1];
00447 bool oldestFirst = (tokens[2] == "1");
00448 string date = tokens[3];
00449
00450 if (m_debug)
00451 cout << "Loading events for monitor: " << monitor << ", date: " << date << endl;
00452
00453 ADD_STR(outStr, "OK")
00454
00455 MYSQL_RES *res;
00456 MYSQL_ROW row;
00457
00458 string sql("SELECT E.Id, E.Name, M.Id AS MonitorID, M.Name AS MonitorName, E.StartTime, "
00459 "E.Length, M.Width, M.Height, M.DefaultRate, M.DefaultScale "
00460 "from Events as E inner join Monitors as M on E.MonitorId = M.Id ");
00461
00462 if (monitor != "<ANY>")
00463 {
00464 sql += "WHERE M.Name = '" + monitor + "' ";
00465
00466 if (date != "<ANY>")
00467 sql += "AND DATE(E.StartTime) = DATE('" + date + "') ";
00468 }
00469 else
00470 {
00471 if (date != "<ANY>")
00472 sql += "WHERE DATE(E.StartTime) = DATE('" + date + "') ";
00473 }
00474
00475 if (oldestFirst)
00476 sql += "ORDER BY E.StartTime ASC";
00477 else
00478 sql += "ORDER BY E.StartTime DESC";
00479
00480 if (mysql_query(&g_dbConn, sql.c_str()))
00481 {
00482 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
00483 sendError(ERROR_MYSQL_QUERY);
00484 return;
00485 }
00486
00487 res = mysql_store_result(&g_dbConn);
00488 int eventCount = mysql_num_rows(res);
00489
00490 if (m_debug)
00491 cout << "Got " << eventCount << " events" << endl;
00492
00493 char str[10];
00494 sprintf(str, "%d", eventCount);
00495 ADD_STR(outStr, str)
00496
00497 for (int x = 0; x < eventCount; x++)
00498 {
00499 row = mysql_fetch_row(res);
00500 if (row)
00501 {
00502 ADD_STR(outStr, row[0])
00503 ADD_STR(outStr, row[1])
00504 ADD_STR(outStr, row[2])
00505 ADD_STR(outStr, row[3])
00506 row[4][10] = 'T';
00507 ADD_STR(outStr, row[4])
00508 ADD_STR(outStr, row[5])
00509 }
00510 else
00511 {
00512 cout << "Failed to get mysql row" << endl;
00513 sendError(ERROR_MYSQL_ROW);
00514 return;
00515 }
00516 }
00517
00518 mysql_free_result(res);
00519
00520 send(outStr);
00521 }
00522
00523 void ZMServer::handleGetEventDates(vector<string> tokens)
00524 {
00525 string outStr("");
00526
00527 if (tokens.size() != 3)
00528 {
00529 sendError(ERROR_TOKEN_COUNT);
00530 return;
00531 }
00532
00533 string monitor = tokens[1];
00534 bool oldestFirst = (tokens[2] == "1");
00535
00536 if (m_debug)
00537 cout << "Loading event dates for monitor: " << monitor << endl;
00538
00539 ADD_STR(outStr, "OK")
00540
00541 MYSQL_RES *res;
00542 MYSQL_ROW row;
00543
00544 string sql("SELECT DISTINCT DATE(E.StartTime) "
00545 "from Events as E inner join Monitors as M on E.MonitorId = M.Id ");
00546
00547 if (monitor != "<ANY>")
00548 sql += "WHERE M.Name = '" + monitor + "' ";
00549
00550 if (oldestFirst)
00551 sql += "ORDER BY E.StartTime ASC";
00552 else
00553 sql += "ORDER BY E.StartTime DESC";
00554
00555 if (mysql_query(&g_dbConn, sql.c_str()))
00556 {
00557 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
00558 sendError(ERROR_MYSQL_QUERY);
00559 return;
00560 }
00561
00562 res = mysql_store_result(&g_dbConn);
00563 int dateCount = mysql_num_rows(res);
00564
00565 if (m_debug)
00566 cout << "Got " << dateCount << " dates" << endl;
00567
00568 char str[10];
00569 sprintf(str, "%d", dateCount);
00570 ADD_STR(outStr, str)
00571
00572 for (int x = 0; x < dateCount; x++)
00573 {
00574 row = mysql_fetch_row(res);
00575 if (row)
00576 {
00577 ADD_STR(outStr, row[0])
00578 }
00579 else
00580 {
00581 cout << "Failed to get mysql row" << endl;
00582 sendError(ERROR_MYSQL_ROW);
00583 return;
00584 }
00585 }
00586
00587 mysql_free_result(res);
00588
00589 send(outStr);
00590 }
00591
00592 void ZMServer::handleGetMonitorStatus(void)
00593 {
00594 string outStr("");
00595 ADD_STR(outStr, "OK")
00596
00597
00598 MYSQL_RES *res;
00599 MYSQL_ROW row;
00600
00601 string sql("SELECT id, name, type, device, channel, function, enabled "
00602 "FROM Monitors;");
00603 if (mysql_query(&g_dbConn, sql.c_str()))
00604 {
00605 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
00606 sendError(ERROR_MYSQL_QUERY);
00607 return;
00608 }
00609
00610 res = mysql_store_result(&g_dbConn);
00611
00612
00613 int monitorCount = mysql_num_rows(res);
00614
00615 if (m_debug)
00616 cout << "Got " << monitorCount << " monitors" << endl;
00617
00618 char str[10];
00619 sprintf(str, "%d", monitorCount);
00620 ADD_STR(outStr, str)
00621
00622 for (int x = 0; x < monitorCount; x++)
00623 {
00624 row = mysql_fetch_row(res);
00625 if (row)
00626 {
00627 string id = row[0];
00628 string type = row[2];
00629 string device = row[3];
00630 string channel = row[4];
00631 string function = row[5];
00632 string enabled = row[6];
00633 string name = row[1];
00634 string events = "";
00635 string zmcStatus = "";
00636 string zmaStatus = "";
00637 getMonitorStatus(id, type, device, channel, function,
00638 zmcStatus, zmaStatus, enabled);
00639 MYSQL_RES *res2;
00640 MYSQL_ROW row2;
00641
00642 string sql2("SELECT count(if(Archived=0,1,NULL)) AS EventCount "
00643 "FROM Events AS E "
00644 "WHERE MonitorId = " + id);
00645
00646 if (mysql_query(&g_dbConn, sql2.c_str()))
00647 {
00648 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
00649 sendError(ERROR_MYSQL_QUERY);
00650 return;
00651 }
00652
00653 res2 = mysql_store_result(&g_dbConn);
00654 if (mysql_num_rows(res2) > 0)
00655 {
00656 row2 = mysql_fetch_row(res2);
00657 if (row2)
00658 events = row2[0];
00659 else
00660 {
00661 cout << "Failed to get mysql row" << endl;
00662 sendError(ERROR_MYSQL_ROW);
00663 return;
00664 }
00665 }
00666
00667 ADD_STR(outStr, id)
00668 ADD_STR(outStr, name)
00669 ADD_STR(outStr, zmcStatus)
00670 ADD_STR(outStr, zmaStatus)
00671 ADD_STR(outStr, events)
00672 ADD_STR(outStr, function)
00673 ADD_STR(outStr, enabled)
00674
00675 mysql_free_result(res2);
00676 }
00677 else
00678 {
00679 cout << "Failed to get mysql row" << endl;
00680 sendError(ERROR_MYSQL_ROW);
00681 return;
00682 }
00683 }
00684
00685 mysql_free_result(res);
00686
00687 send(outStr);
00688 }
00689
00690 string ZMServer::runCommand(string command)
00691 {
00692 string outStr("");
00693 FILE *fd = popen(command.c_str(), "r");
00694 char buffer[100];
00695
00696 while (fgets(buffer, sizeof(buffer), fd) != NULL)
00697 {
00698 outStr += buffer;
00699 }
00700 pclose(fd);
00701 return outStr;
00702 }
00703
00704 void ZMServer::getMonitorStatus(string id, string type, string device, string channel,
00705 string function, string &zmcStatus, string &zmaStatus,
00706 string enabled)
00707 {
00708 zmaStatus = "";
00709 zmcStatus = "";
00710
00711 string command(g_binPath + "/zmdc.pl status");
00712 string status = runCommand(command);
00713
00714 if (enabled == "0")
00715 zmaStatus = device + "(" + channel + ") [-]";
00716 else if (status.find("'zma -m " + id + "' running") != string::npos)
00717 zmaStatus = device + "(" + channel + ") [R]";
00718 else
00719 zmaStatus = device + "(" + channel + ") [S]";
00720
00721 if (type == "Local")
00722 {
00723 if (enabled == "0")
00724 zmcStatus = function + " [-]";
00725 else if (status.find("'zmc -d "+ device + "' running") != string::npos)
00726 zmcStatus = function + " [R]";
00727 else
00728 zmcStatus = function + " [S]";
00729 }
00730 else
00731 {
00732 if (enabled == "0")
00733 zmcStatus = function + " [-]";
00734 else if (status.find("'zmc -m " + id + "' running") != string::npos)
00735 zmcStatus = function + " [R]";
00736 else
00737 zmcStatus = function + " [S]";
00738 }
00739 }
00740
00741 void ZMServer::handleGetEventFrame(vector<string> tokens)
00742 {
00743 static unsigned char buffer[MAX_IMAGE_SIZE];
00744 char str[100];
00745
00746 if (tokens.size() != 4)
00747 {
00748 sendError(ERROR_TOKEN_COUNT);
00749 return;
00750 }
00751
00752 string monitorID(tokens[1]);
00753 string eventID(tokens[2]);
00754 int frameNo = atoi(tokens[3].c_str());
00755
00756 if (m_debug)
00757 cout << "Getting frame " << frameNo << " for event " << eventID
00758 << " on monitor " << monitorID << endl;
00759
00760 string outStr("");
00761
00762 ADD_STR(outStr, "OK")
00763
00764
00765 string filepath("");
00766 filepath = g_webPath + "/events/" + monitorID + "/" + eventID + "/";
00767 sprintf(str, m_eventFileFormat.c_str(), frameNo);
00768 filepath += str;
00769
00770 FILE *fd;
00771 int fileSize = 0;
00772 if ((fd = fopen(filepath.c_str(), "r" )))
00773 {
00774 fileSize = fread(buffer, 1, sizeof(buffer), fd);
00775 fclose(fd);
00776 }
00777 else
00778 {
00779 cout << "Can't open " << filepath << ": " << strerror(errno) << endl;
00780 sendError(ERROR_FILE_OPEN + string(" - ") + filepath + " : " + strerror(errno));
00781 return;
00782 }
00783
00784 if (m_debug)
00785 cout << "Frame size: " << fileSize << endl;
00786
00787
00788 sprintf(str, "%d", fileSize);
00789 ADD_STR(outStr, str)
00790
00791
00792 send(outStr, buffer, fileSize);
00793 }
00794
00795 void ZMServer::handleGetAnalyseFrame(vector<string> tokens)
00796 {
00797 static unsigned char buffer[MAX_IMAGE_SIZE];
00798 char str[100];
00799
00800 if (tokens.size() != 4)
00801 {
00802 sendError(ERROR_TOKEN_COUNT);
00803 return;
00804 }
00805
00806 string monitorID(tokens[1]);
00807 string eventID(tokens[2]);
00808 int frameNo = atoi(tokens[3].c_str());
00809
00810 if (m_debug)
00811 cout << "Getting anaylse frame " << frameNo << " for event " << eventID
00812 << " on monitor " << monitorID << endl;
00813
00814
00815 MYSQL_RES *res;
00816 MYSQL_ROW row = NULL;
00817
00818 string sql("");
00819 sql += "SELECT FrameId FROM Frames ";
00820 sql += "WHERE EventID = " + eventID + " ";
00821 sql += "AND Type = 'Alarm' ";
00822 sql += "ORDER BY FrameID";
00823
00824 if (mysql_query(&g_dbConn, sql.c_str()))
00825 {
00826 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
00827 sendError(ERROR_MYSQL_QUERY);
00828 return;
00829 }
00830
00831 res = mysql_store_result(&g_dbConn);
00832 int frameCount = mysql_num_rows(res);
00833 int frameID;
00834
00835
00836 if (frameNo == 0 || frameNo < 0 || frameNo > frameCount)
00837 frameNo = (frameCount / 2) + 1;
00838
00839
00840 for (int x = 0; x < frameNo; x++)
00841 {
00842 row = mysql_fetch_row(res);
00843 }
00844
00845 if (row)
00846 {
00847 frameID = atoi(row[0]);
00848 }
00849 else
00850 {
00851 cout << "Failed to get mysql row" << endl;
00852 sendError(ERROR_MYSQL_ROW);
00853 return;
00854 }
00855
00856 string outStr("");
00857
00858 ADD_STR(outStr, "OK")
00859
00860
00861 string filepath("");
00862 filepath = g_webPath + "/events/" + monitorID + "/" + eventID + "/";
00863 sprintf(str, m_analyseFileFormat.c_str(), frameID);
00864 filepath += str;
00865
00866 FILE *fd;
00867 int fileSize = 0;
00868 if ((fd = fopen(filepath.c_str(), "r" )))
00869 {
00870 fileSize = fread(buffer, 1, sizeof(buffer), fd);
00871 fclose(fd);
00872 }
00873 else
00874 {
00875 cout << "Can't open " << filepath << ": " << strerror(errno) << endl;
00876 sendError(ERROR_FILE_OPEN + string(" - ") + filepath + " : " + strerror(errno));
00877 return;
00878 }
00879
00880 if (m_debug)
00881 cout << "Frame size: " << fileSize << endl;
00882
00883
00884 sprintf(str, "%d", fileSize);
00885 ADD_STR(outStr, str)
00886
00887
00888 send(outStr, buffer, fileSize);
00889 }
00890
00891 void ZMServer::handleGetLiveFrame(vector<string> tokens)
00892 {
00893 static unsigned char buffer[MAX_IMAGE_SIZE];
00894 char str[100];
00895
00896
00897
00898
00899
00900 kickDatabase(m_debug);
00901
00902 if (tokens.size() != 2)
00903 {
00904 sendError(ERROR_TOKEN_COUNT);
00905 return;
00906 }
00907
00908 int monitorID = atoi(tokens[1].c_str());
00909
00910 if (m_debug)
00911 cout << "Getting live frame from monitor: " << monitorID << endl;
00912
00913 string outStr("");
00914
00915 ADD_STR(outStr, "OK")
00916
00917
00918 sprintf(str, "%d", monitorID);
00919 ADD_STR(outStr, str)
00920
00921
00922 MONITOR *monitor;
00923 if (m_monitors.find(monitorID) != m_monitors.end())
00924 monitor = m_monitors[monitorID];
00925 else
00926 {
00927 sendError(ERROR_INVALID_MONITOR);
00928 return;
00929 }
00930
00931
00932 if (monitor->shared_data == NULL || monitor->shared_images == NULL)
00933 {
00934 sendError(ERROR_INVALID_POINTERS);
00935 return;
00936 }
00937
00938
00939 int dataSize = getFrame(buffer, sizeof(buffer), monitor);
00940
00941 if (m_debug)
00942 cout << "Frame size: " << dataSize << endl;
00943
00944 if (dataSize == 0)
00945 {
00946
00947 outStr = "";
00948 ADD_STR(outStr, "WARNING - No new frame available");
00949 send(outStr);
00950 return;
00951 }
00952
00953
00954 ADD_STR(outStr, monitor->status)
00955
00956
00957 sprintf(str, "%d", dataSize);
00958 ADD_STR(outStr, str)
00959
00960
00961 send(outStr, buffer, dataSize);
00962 }
00963
00964 void ZMServer::handleGetFrameList(vector<string> tokens)
00965 {
00966 string eventID;
00967 string outStr("");
00968
00969 if (tokens.size() != 2)
00970 {
00971 sendError(ERROR_TOKEN_COUNT);
00972 return;
00973 }
00974
00975 eventID = tokens[1];
00976
00977 if (m_debug)
00978 cout << "Loading frames for event: " << eventID << endl;
00979
00980 ADD_STR(outStr, "OK")
00981
00982 MYSQL_RES *res;
00983 MYSQL_ROW row;
00984
00985 string sql("");
00986 sql += "SELECT Type, Delta FROM Frames ";
00987 sql += "WHERE EventID = " + eventID + " ";
00988 sql += "ORDER BY FrameID";
00989
00990 if (mysql_query(&g_dbConn, sql.c_str()))
00991 {
00992 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
00993 sendError(ERROR_MYSQL_QUERY);
00994 return;
00995 }
00996
00997 res = mysql_store_result(&g_dbConn);
00998 int frameCount = mysql_num_rows(res);
00999
01000 if (m_debug)
01001 cout << "Got " << frameCount << " frames" << endl;
01002
01003 char str[10];
01004 sprintf(str, "%d\n", frameCount);
01005 ADD_STR(outStr, str)
01006
01007 for (int x = 0; x < frameCount; x++)
01008 {
01009 row = mysql_fetch_row(res);
01010 if (row)
01011 {
01012 ADD_STR(outStr, row[0])
01013 ADD_STR(outStr, row[1])
01014 }
01015 else
01016 {
01017 cout << "Failed to get mysql row" << endl;
01018 sendError(ERROR_MYSQL_ROW);
01019 return;
01020 }
01021 }
01022
01023 mysql_free_result(res);
01024
01025 send(outStr);
01026 }
01027
01028 void ZMServer::handleGetCameraList(void)
01029 {
01030 string outStr("");
01031
01032 ADD_STR(outStr, "OK")
01033
01034 MYSQL_RES *res;
01035 MYSQL_ROW row;
01036
01037 string sql("");
01038 sql += "SELECT DISTINCT M.Name FROM Events AS E ";
01039 sql += "INNER JOIN Monitors AS M ON E.MonitorId = M.Id;";
01040
01041 if (mysql_query(&g_dbConn, sql.c_str()))
01042 {
01043 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
01044 sendError(ERROR_MYSQL_QUERY);
01045 return;
01046 }
01047
01048 res = mysql_store_result(&g_dbConn);
01049 int monitorCount = mysql_num_rows(res);
01050 char str[10];
01051 sprintf(str, "%d", monitorCount);
01052 ADD_STR(outStr, str)
01053
01054 for (int x = 0; x < monitorCount; x++)
01055 {
01056 row = mysql_fetch_row(res);
01057 if (row)
01058 {
01059 ADD_STR(outStr, row[0])
01060 }
01061 else
01062 {
01063 cout << "Failed to get mysql row" << endl;
01064 sendError(ERROR_MYSQL_ROW);
01065 return;
01066 }
01067 }
01068
01069 mysql_free_result(res);
01070
01071 send(outStr);
01072 }
01073
01074 void ZMServer::handleGetMonitorList(void)
01075 {
01076 string outStr("");
01077
01078 ADD_STR(outStr, "OK")
01079
01080 MYSQL_RES *res;
01081 MYSQL_ROW row;
01082
01083 string sql("");
01084 sql += "SELECT Id, Name, Width, Height, Palette FROM Monitors ORDER BY Id";
01085
01086 if (mysql_query(&g_dbConn, sql.c_str()))
01087 {
01088 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
01089 sendError(ERROR_MYSQL_QUERY);
01090 return;
01091 }
01092
01093 res = mysql_store_result(&g_dbConn);
01094 int monitorCount = mysql_num_rows(res);
01095
01096 if (m_debug)
01097 cout << "Got " << monitorCount << " monitors" << endl;
01098
01099 char str[10];
01100 sprintf(str, "%d", monitorCount);
01101 ADD_STR(outStr, str)
01102
01103 for (int x = 0; x < monitorCount; x++)
01104 {
01105 row = mysql_fetch_row(res);
01106 if (row)
01107 {
01108 ADD_STR(outStr, row[0])
01109 ADD_STR(outStr, row[1])
01110 ADD_STR(outStr, row[2])
01111 ADD_STR(outStr, row[3])
01112 ADD_STR(outStr, row[4])
01113
01114 if (m_debug)
01115 {
01116 cout << "id: " << row[0] << endl;
01117 cout << "name: " << row[1] << endl;
01118 cout << "width: " << row[2] << endl;
01119 cout << "height: " << row[3] << endl;
01120 cout << "palette: " << row[4] << endl;
01121 cout << "-------------------" << endl;
01122 }
01123 }
01124 else
01125 {
01126 cout << "Failed to get mysql row" << endl;
01127 sendError(ERROR_MYSQL_ROW);
01128 return;
01129 }
01130 }
01131
01132 mysql_free_result(res);
01133
01134 send(outStr);
01135 }
01136
01137 void ZMServer::handleDeleteEvent(vector<string> tokens)
01138 {
01139 string eventID;
01140 string outStr("");
01141
01142 if (tokens.size() != 2)
01143 {
01144 sendError(ERROR_TOKEN_COUNT);
01145 return;
01146 }
01147
01148 eventID = tokens[1];
01149
01150 if (m_debug)
01151 cout << "Deleting event: " << eventID << endl;
01152
01153 ADD_STR(outStr, "OK")
01154
01155 string sql("");
01156 sql += "DELETE FROM Events WHERE Id = " + eventID;
01157
01158 if (mysql_query(&g_dbConn, sql.c_str()))
01159 {
01160 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
01161 sendError(ERROR_MYSQL_QUERY);
01162 return;
01163 }
01164
01165
01166 string command(g_binPath + "/zmaudit.pl &");
01167 system(command.c_str());
01168 send(outStr);
01169 }
01170
01171 void ZMServer::handleDeleteEventList(vector<string> tokens)
01172 {
01173 string eventList("");
01174 string outStr("");
01175
01176 vector<string>::iterator it = tokens.begin();
01177 it++;
01178 while (it != tokens.end())
01179 {
01180 if (eventList == "")
01181 eventList = (*it);
01182 else
01183 eventList += "," + (*it);
01184
01185 it++;
01186 }
01187
01188 if (m_debug)
01189 cout << "Deleting events: " << eventList << endl;
01190
01191 string sql("");
01192 sql += "DELETE FROM Events WHERE Id IN (" + eventList + ")";
01193
01194 if (mysql_query(&g_dbConn, sql.c_str()))
01195 {
01196 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
01197 sendError(ERROR_MYSQL_QUERY);
01198 return;
01199 }
01200
01201 ADD_STR(outStr, "OK")
01202 send(outStr);
01203 }
01204
01205 void ZMServer::handleRunZMAudit(void)
01206 {
01207 string outStr("");
01208
01209
01210 string command(g_binPath + "/zmaudit.pl &");
01211
01212 if (m_debug)
01213 cout << "Running command: " << command << endl;
01214
01215 system(command.c_str());
01216
01217 ADD_STR(outStr, "OK")
01218 send(outStr);
01219 }
01220
01221 void ZMServer::getMonitorList(void)
01222 {
01223 m_monitors.clear();
01224
01225 string sql("SELECT Id, Name, Width, Height, ImageBufferCount, MaxFPS, Palette, ");
01226 sql += " Type, Function, Enabled, Device, Controllable, TrackMotion ";
01227 sql += "FROM Monitors";
01228
01229 MYSQL_RES *res;
01230 MYSQL_ROW row;
01231
01232 if (mysql_query(&g_dbConn, sql.c_str()))
01233 {
01234 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
01235 return;
01236 }
01237
01238 res = mysql_store_result(&g_dbConn);
01239 int monitorCount = mysql_num_rows(res);
01240
01241 if (m_debug)
01242 cout << "Got " << monitorCount << " monitors" << endl;
01243
01244 for (int x = 0; x < monitorCount; x++)
01245 {
01246 row = mysql_fetch_row(res);
01247 if (row)
01248 {
01249 MONITOR *m = new MONITOR;
01250 m->mon_id = atoi(row[0]);
01251 m->name = row[1];
01252 m->width = atoi(row[2]);
01253 m->height = atoi(row[3]);
01254 m->image_buffer_count = atoi(row[4]);
01255 m->palette = atoi(row[6]);
01256 m->type = row[7];
01257 m->function = row[8];
01258 m->enabled = atoi(row[9]);
01259 m->device = row[10];
01260 m->controllable = atoi(row[11]);
01261 m->trackMotion = atoi(row[12]);
01262 m_monitors[m->mon_id] = m;
01263
01264 initMonitor(m);
01265 }
01266 else
01267 {
01268 cout << "Failed to get mysql row" << endl;
01269 return;
01270 }
01271 }
01272
01273 mysql_free_result(res);
01274 }
01275
01276 void ZMServer::initMonitor(MONITOR *monitor)
01277 {
01278 void *shm_ptr;
01279
01280 monitor->shared_data = NULL;
01281 monitor->shared_images = NULL;
01282
01283 if (monitor->palette == 1)
01284 monitor->frame_size = monitor->width * monitor->height;
01285 else
01286 monitor->frame_size = monitor->width * monitor->height * 3;
01287
01288 int shared_data_size;
01289
01290 if (g_zmversion == "1.22.2")
01291 shared_data_size = sizeof(SharedData) +
01292 sizeof(TriggerData_old) +
01293 ((monitor->image_buffer_count) * (sizeof(struct timeval))) +
01294 ((monitor->image_buffer_count) * monitor->frame_size);
01295 else
01296 shared_data_size = sizeof(SharedData) +
01297 sizeof(TriggerData) +
01298 ((monitor->image_buffer_count) * (sizeof(struct timeval))) +
01299 ((monitor->image_buffer_count) * monitor->frame_size);
01300
01301 int shmid;
01302
01303 if ((shmid = shmget((m_shmKey & 0xffffff00) | monitor->mon_id,
01304 shared_data_size, SHM_R)) == -1)
01305 {
01306 cout << "Failed to shmget for monitor: " << monitor->mon_id << endl;
01307 monitor->status = "Error";
01308 switch(errno)
01309 {
01310 case EACCES: cout << "EACCES - no rights to access segment\n"; break;
01311 case EEXIST: cout << "EEXIST - segment already exists\n"; break;
01312 case EINVAL: cout << "EINVAL - size < SHMMIN or size > SHMMAX\n"; break;
01313 case ENFILE: cout << "ENFILE - limit on open files has been reached\n"; break;
01314 case ENOENT: cout << "ENOENT - no segment exists for the given key\n"; break;
01315 case ENOMEM: cout << "ENOMEM - couldn't reserve memory for segment\n"; break;
01316 case ENOSPC: cout << "ENOSPC - shmmni or shmall limit reached\n"; break;
01317 }
01318
01319 return;
01320 }
01321
01322 shm_ptr = shmat(shmid, 0, SHM_RDONLY);
01323
01324
01325 if (shm_ptr == NULL)
01326 {
01327 cout << "Failed to shmat for monitor: " << monitor->mon_id << endl;
01328 monitor->status = "Error";
01329 return;
01330 }
01331
01332 monitor->shared_data = (SharedData*)shm_ptr;
01333
01334 if (g_zmversion == "1.22.2")
01335 monitor->shared_images = (unsigned char*) shm_ptr +
01336 sizeof(SharedData) +
01337 sizeof(TriggerData_old) +
01338 ((monitor->image_buffer_count) * sizeof(struct timeval));
01339 else
01340 monitor->shared_images = (unsigned char*) shm_ptr +
01341 sizeof(SharedData) +
01342 sizeof(TriggerData) +
01343 ((monitor->image_buffer_count) * sizeof(struct timeval));
01344 }
01345
01346 int ZMServer::getFrame(unsigned char *buffer, int bufferSize, MONITOR *monitor)
01347 {
01348 (void) bufferSize;
01349
01350
01351 if (monitor->shared_data->last_write_index == monitor->last_read)
01352 return 0;
01353
01354
01355 if (monitor->shared_data->last_write_index < 0 ||
01356 monitor->shared_data->last_write_index >= monitor->image_buffer_count)
01357 return 0;
01358
01359 monitor->last_read = monitor->shared_data->last_write_index;
01360
01361 switch (monitor->shared_data->state)
01362 {
01363 case IDLE:
01364 monitor->status = "Idle";
01365 break;
01366 case PREALARM:
01367 monitor->status = "Pre Alarm";
01368 break;
01369 case ALARM:
01370 monitor->status = "Alarm";
01371 break;
01372 case ALERT:
01373 monitor->status = "Alert";
01374 break;
01375 case TAPE:
01376 monitor->status = "Tape";
01377 break;
01378 default:
01379 monitor->status = "Unknown";
01380 break;
01381 }
01382
01383 unsigned char *data = monitor->shared_images +
01384 monitor->frame_size * monitor->last_read;
01385
01386
01387
01388 memcpy(buffer, data, monitor->frame_size);
01389
01390
01391 return monitor->frame_size;
01392 }
01393
01394 string ZMServer::getZMSetting(const string &setting)
01395 {
01396 string result;
01397 string sql("SELECT Name, Value FROM Config ");
01398 sql += "WHERE Name = '" + setting + "'";
01399
01400 MYSQL_RES *res;
01401 MYSQL_ROW row;
01402
01403 if (mysql_query(&g_dbConn, sql.c_str()))
01404 {
01405 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
01406 return "";
01407 }
01408
01409 res = mysql_store_result(&g_dbConn);
01410 row = mysql_fetch_row(res);
01411 if (row)
01412 {
01413 result = row[1];
01414 }
01415 else
01416 {
01417 cout << "Failed to get mysql row" << endl;
01418 result = "";
01419 }
01420
01421 if (m_debug)
01422 cout << "getZMSetting: " << setting << " Result: " << result << endl;
01423
01424 mysql_free_result(res);
01425
01426 return result;
01427 }
01428
01429 void ZMServer::handleSetMonitorFunction(vector<string> tokens)
01430 {
01431 string outStr("");
01432
01433 if (tokens.size() != 4)
01434 {
01435 sendError(ERROR_TOKEN_COUNT);
01436 return;
01437 }
01438
01439 string monitorID(tokens[1]);
01440 string function(tokens[2]);
01441 string enabled(tokens[3]);
01442
01443
01444 if (m_monitors.find(atoi(monitorID.c_str())) == m_monitors.end())
01445 {
01446 sendError(ERROR_INVALID_MONITOR);
01447 return;
01448 }
01449
01450 if (function != FUNCTION_NONE && function != FUNCTION_MONITOR &&
01451 function != FUNCTION_MODECT && function != FUNCTION_NODECT &&
01452 function != FUNCTION_RECORD && function != FUNCTION_MOCORD)
01453 {
01454 sendError(ERROR_INVALID_MONITOR_FUNCTION);
01455 return;
01456 }
01457
01458 if (enabled != "0" && enabled != "1")
01459 {
01460 sendError(ERROR_INVALID_MONITOR_ENABLE_VALUE);
01461 return;
01462 }
01463
01464 if (m_debug)
01465 cout << "User input validated OK" << endl;
01466
01467
01468
01469 MONITOR *monitor = m_monitors[atoi(monitorID.c_str())];
01470 string oldFunction = monitor->function;
01471 string newFunction = function;
01472 int oldEnabled = monitor->enabled;
01473 int newEnabled = atoi(enabled.c_str());
01474 monitor->function = newFunction;
01475 monitor->enabled = newEnabled;
01476
01477 if (m_debug)
01478 cout << "SetMonitorFunction MonitorId: " << monitorID << endl <<
01479 " oldEnabled: " << oldEnabled << endl <<
01480 " newEnabled: " << newEnabled << endl <<
01481 " oldFunction: " << oldFunction << endl <<
01482 " newFunction: " << newFunction << endl;
01483
01484 if ( newFunction != oldFunction || newEnabled != oldEnabled)
01485 {
01486 string sql("UPDATE Monitors ");
01487 sql += "SET Function = '" + function + "', ";
01488 sql += "Enabled = '" + enabled + "' ";
01489 sql += "WHERE Id = '" + monitorID + "'";
01490
01491 if (mysql_query(&g_dbConn, sql.c_str()))
01492 {
01493 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
01494 sendError(ERROR_MYSQL_QUERY);
01495 return;
01496 }
01497
01498 if (m_debug)
01499 cout << "Monitor function SQL update OK" << endl;
01500
01501 string status = runCommand(g_binPath + "/zmdc.pl check");
01502
01503
01504 if (RUNNING.compare(0, RUNNING.size(), status, 0, RUNNING.size()) == 0)
01505 {
01506 if (m_debug)
01507 cout << "Monitor function Refreshing daemons" << endl;
01508
01509 bool restart = (oldFunction == FUNCTION_NONE) ||
01510 (newFunction == FUNCTION_NONE) ||
01511 (newEnabled != oldEnabled);
01512
01513 if (restart)
01514 zmcControl(monitor, RESTART);
01515 else
01516 zmcControl(monitor, "");
01517 zmaControl(monitor, RELOAD);
01518 }
01519 else
01520 if (m_debug)
01521 cout << "zm daemons are not running" << endl;
01522 }
01523 else
01524 cout << "Not updating monitor function as identical to existing configuration" << endl;
01525
01526 ADD_STR(outStr, "OK")
01527 send(outStr);
01528 }
01529
01530 void ZMServer::zmcControl(MONITOR *monitor, const string &mode)
01531 {
01532 string zmcArgs = "";
01533 string sql = "";
01534 sql += "SELECT count(if(Function!='None',1,NULL)) as ActiveCount ";
01535 sql += "FROM Monitors ";
01536
01537 if (monitor->type == "Local" )
01538 {
01539 sql += "WHERE Device = '" + monitor->device + "'";
01540 zmcArgs = "-d " + monitor->device;
01541 }
01542 else
01543 {
01544 sql += "WHERE Id = '" + monitor->getIdStr() + "'";
01545 zmcArgs = "-m " + monitor->mon_id;
01546 }
01547
01548 if (mysql_query(&g_dbConn, sql.c_str()))
01549 {
01550 fprintf(stderr, "%s\n", mysql_error(&g_dbConn));
01551 sendError(ERROR_MYSQL_QUERY);
01552 return;
01553 }
01554
01555 MYSQL_RES *res;
01556 MYSQL_ROW row;
01557 int activeCount;
01558
01559 res = mysql_store_result(&g_dbConn);
01560 row = mysql_fetch_row(res);
01561
01562 if (row)
01563 activeCount = atoi(row[0]);
01564 else
01565 {
01566 sendError(ERROR_MYSQL_QUERY);
01567 return;
01568 }
01569
01570 if (!activeCount)
01571 runCommand(g_binPath + "/zmdc.pl stop zmc " + zmcArgs);
01572 else
01573 {
01574 if (mode == RESTART)
01575 runCommand(g_binPath + "/zmdc.pl stop zmc " + zmcArgs);
01576
01577 runCommand(g_binPath + "/zmdc.pl start zmc " + zmcArgs);
01578 }
01579 }
01580
01581 void ZMServer::zmaControl(MONITOR *monitor, const string &mode)
01582 {
01583 int zmOptControl = atoi(getZMSetting("ZM_OPT_CONTROL").c_str());
01584 int zmOptFrameServer = atoi(getZMSetting("ZM_OPT_FRAME_SERVER").c_str());
01585
01586 if (monitor->function == FUNCTION_MODECT ||
01587 monitor->function == FUNCTION_RECORD ||
01588 monitor->function == FUNCTION_MOCORD ||
01589 monitor->function == FUNCTION_NODECT)
01590 {
01591 if (mode == RESTART)
01592 {
01593 if (zmOptControl)
01594 runCommand(g_binPath + "/zmdc.pl stop zmtrack.pl -m " + monitor->getIdStr());
01595
01596 runCommand(g_binPath + "/zmdc.pl stop zma -m " + monitor->getIdStr());
01597
01598 if (zmOptFrameServer)
01599 runCommand(g_binPath + "/zmdc.pl stop zmf -m " + monitor->getIdStr());
01600 }
01601
01602 if (zmOptFrameServer)
01603 runCommand(g_binPath + "/zmdc.pl start zmf -m " + monitor->getIdStr());
01604
01605 runCommand(g_binPath + "/zmdc.pl start zma -m " + monitor->getIdStr());
01606
01607 if (zmOptControl && monitor->controllable && monitor->trackMotion &&
01608 ( monitor->function == FUNCTION_MODECT || monitor->function == FUNCTION_MOCORD) )
01609 runCommand(g_binPath + "/zmdc.pl start zmtrack.pl -m " + monitor->getIdStr());
01610
01611 if (mode == RELOAD)
01612 runCommand(g_binPath + "/zmdc.pl reload zma -m " + monitor->getIdStr());
01613 }
01614 else
01615 {
01616 if (zmOptControl)
01617 runCommand(g_binPath + "/zmdc.pl stop zmtrack.pl -m " + monitor->getIdStr());
01618
01619 runCommand(g_binPath + "/zmdc.pl stop zma -m " + monitor->getIdStr());
01620
01621 if (zmOptFrameServer)
01622 runCommand(g_binPath + "/zmdc.pl stop zmf -m " + monitor->getIdStr());
01623 }
01624 }