📄 rc_server.cpp.svn-base
字号:
/* ------------------------------------------------------------------------- * rc_server.cpp - rc server functions * Copyright (C) 2008 Dimitar Atanasov <datanasov@deisytechbg.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ------------------------------------------------------------------------- */#include "common.h"#include "servers.h"using std::string;#define RC_MSG_LENGTH 1024typedef struct rc_msg{ rc_msg(char* buffer) : command(buffer) { } string command; string ip;} rc_msg_t;extern void delete_card(std::string &req, int KC_ID);void change_room_status(mysqlpp::Connection* conn, string ip, int room){ std::ostringstream str; str << "UPDATE RoomStatus SET OnLine_RC=" << "'" << (ctxt.rooms[ip]->status == 0 ? "FALSE" : "TRUE") << "'" << ", OnLine_RCDate=" << "'" << get_date_time << "'" << " WHERE RoomID=" << room; logger(INFO, "Room %d OnLine %s\n", room, ctxt.rooms[ip]->status == 0 ? "FALSE" : "TRUE"); mysqlpp::Query qr = conn->query(); mysqlpp::SimpleResult res = qr.execute(str.str().c_str());}void check_room_status(void*){ std::map<string, linked_ptr<room_status_t> >::iterator i = ctxt.rooms.begin(); time_t now = time(NULL); mysqlpp::Connection::thread_start(); BEGIN_DB()for(; i != ctxt.rooms.end(); i++) { pthread_mutex_lock(&i->second->lock); if(difftime(now, i->second->lastping)> 120) { i->second->status = 0; if(i->second->oldstatus != i->second->status) { i->second->oldstatus = i->second->status; i->second->lastchange = now; change_room_status(conn, i->first, i->second->room); } } pthread_mutex_unlock(&i->second->lock); } END_DB() mysqlpp::Connection::thread_end(); }void check_card_validity(void*){ using namespace std; mysqlpp::Connection::thread_start(); BEGIN_DB()ostringstream str; str << "SELECT HEX(KeyID) as HexKeyID FROM Keycard WHERE ValidityDateTime<='" << get_date_time << "' AND ValidityDateTime<>'0000-00-00 00:00:00'"; mysqlpp::StoreQueryResult res = qr.store(str.str().c_str()); for (size_t i = 0; i < res.num_rows(); ++i) { logger(INFO, "Deleting invalid card %s\n", res[i][0].c_str()); std::ostringstream req; req << "KD|KI" << res[i][0] << "|EI0|"; std::string _t = req.str(); delete_card(_t, 0); } END_DB() mysqlpp::Connection::thread_end(); }void set_temp(rc_msg_t* msg, uint16 tzone, uint16 season, uint16 actual, uint16 target, uint16 target_no_guest, uint16 mode, uint16 status){ map<string, linked_ptr<room_status_t> >::iterator i = ctxt.rooms.find(msg->ip); if (i == ctxt.rooms.end()) return; BEGIN_DB()std::ostringstream str; str << "SELECT TargetT,DefaultGuestT_EmptyRoom, Mode, DefaultFreeT, ActualT, Status FROM RoomTZone WHERE RoomID=" << ctxt.rooms[msg->ip]->room << " AND TZoneID=" << tzone+1; mysqlpp::StoreQueryResult res = qr.store(str.str().c_str()); if (res.num_rows()> 0) { { std::ostringstream update_q; update_q << "UPDATE RoomTZone SET ActualT=" << actual <<",Status="<< status <<" WHERE RoomID=" << ctxt.rooms[msg->ip]->room <<" AND TZoneID=" << tzone + 1; qr.exec(update_q.str().c_str()); } std::ostringstream temp_q; temp_q << "SELECT TargetT, ActualT, MODE,Status FROM RoomTZoneLog WHERE RoomID=" << ctxt.rooms[msg->ip]->room << " AND TZoneID=" << tzone + 1 << " ORDER BY ID DESC LIMIT 1"; mysqlpp::StoreQueryResult temp_res = qr.store(temp_q.str().c_str()); if(temp_res.num_rows()> 0) if(((target != (int) temp_res[0][0]) || (actual != (int)temp_res[0][1]) || (mode != (int) temp_res[0][2]) || ( status != (int) temp_res[0][3]))) { std::ostringstream insert_q; insert_q << "INSERT INTO RoomTZoneLog (RoomID, TZoneID, Date, TargetT, ActualT, Mode, Status) VALUES("<<ctxt.rooms[msg->ip]->room<<", "<<tzone+1<<", '" << get_date_time << "', "<<target << ", "<< actual <<", " << mode << ", " << status << ")"; qr.exec(insert_q.str().c_str()); } int targetT = target; int targetTnoGuest = target_no_guest; int seson = get_season(qr); bool bSend = false; { std::ostringstream guest_q; guest_q << "SELECT GuestNo FROM Room WHERE RoomID=" << ctxt.rooms[msg->ip]->room; mysqlpp::StoreQueryResult res2 = qr.store(guest_q.str().c_str()); if(target == 0) { bSend = true; if((int) res2[0][0] != 0) { targetT = res[0][0]; targetTnoGuest = res[0][1]; } else { targetT = res[0][3]; targetTnoGuest = res[0][3]; } } else { if((int) res2[0][0] != 0) { if(target != (int)res[0][0]) { std::ostringstream update_temp; update_temp << "UPDATE RoomTZone SET TargetT=" << target << " WHERE RoomID=" << ctxt.rooms[msg->ip]->room << " AND TZoneID=" << tzone + 1; qr.exec(update_temp.str().c_str()); bSend = false; } if(target_no_guest != (int)res[0][1] || mode != (int) res[0][2] || seson != season) { bSend = true; targetTnoGuest = res[0][1]; } } else { if(target_no_guest != (int)res[0][3] || mode != (int) res[0][2] || seson != season) { bSend = true; targetTnoGuest = res[0][3]; } } } if(bSend) { std::ostringstream udp_send; udp_send.fill('0'); udp_send << "CLMT:" << std::setw(2) << tzone << seson << std::setw(2) << targetT << std::setw(2) << targetTnoGuest << res[0][2] << "*"; send_to_rc(msg->ip, udp_send); } } } else logger(ERROR, "Unrecognized zone for room %d\n", ctxt.rooms[msg->ip]->room); END_DB() }void fail_set_temp(rc_msg_t* msg, uint16 aa, uint16 r){ map<string, linked_ptr<room_status_t> >::iterator i = ctxt.rooms.find(msg->ip); if (i == ctxt.rooms.end()) return; string reason; switch (r) { case 1: reason = "невалидна кл.зона"; break; case 2: reason = "липсва връзка към кл.зона"; break; case 3: reason = "неуспешна промяна на температурата"; break; case 4: reason = "невалидна температура"; break; case 5: reason = "невалиден режим на работа"; break; } std::ostringstream message; message << "Възникна проблем в климатичния контрол на стая " << ctxt.rooms[msg->ip]->room << " (кл. зона " << aa + 1 << ". Причина: " << reason; write_event(4, message);}void door_control(rc_msg_t* msg, uint16 nDoor, uint16 nSafe, uint16 nPanic, uint16 nR, uint16 nz1, uint16 nz2, uint16 nz3, uint16 nz4, uint16 nz5, uint16 nz6, uint16 ngreen, uint16 nred){ map<string, linked_ptr<room_status_t> >::iterator i = ctxt.rooms.find(msg->ip); if (i == ctxt.rooms.end()) return; BEGIN_DB()std::ostringstream str; str << "SELECT Bathroom,SafeOpen FROM RoomStatus WHERE RoomID=" << ctxt.rooms[msg->ip]->room; // std::cout<< str << std::endl; mysqlpp::StoreQueryResult res = qr.store(str.str().c_str()); string bathroom_panic, safe_open; if(res.num_rows()> 0) { bathroom_panic = res[0][0].c_str(); safe_open = res[0][1].c_str(); } else { bathroom_panic = "FALSE"; safe_open = "FALSE"; } std::ostringstream str_room_status; std::ostringstream str_access_control; string door = bool_to_str(nDoor); string safe = bool_to_str(nSafe); string panic = bool_to_str(nPanic); string r = bool_to_str(nR); string z1 = bool_to_str(nz1); string z2 = bool_to_str(nz2); string z3 = bool_to_str(nz3); string z4 = bool_to_str(nz4); string z5 = bool_to_str(nz5); string z6 = bool_to_str(nz6); string green = bool_to_str(ngreen); string red = bool_to_str(nred); str_room_status << "UPDATE RoomStatus SET DoorOpen='"<<door<<"', SafeOpen='"<<safe<<"', Bathroom='"<<panic<<"', Tampering='"<<r<<"', Zone1='"<<z1<<"', Zone2='"<<z2<<"', Zone3='"<<z3<<"', Zone4='"<<z4<<"', Zone5='"<<z5<<"', Zone6='"<<z6<<"', GreenIndic='"<<green<<"', RedIndic='"<<red<<"' WHERE RoomID="<< ctxt.rooms[msg->ip]->room; // std::cout<< str_room_status.str() << std::endl; qr.execute(str_room_status.str().c_str()); str_access_control << "INSERT INTO AccessControlLog (RoomID, Date, DoorOpen, SafeOpen, Bathroom, Tampering, Zone1, Zone2, Zone3, Zone4, Zone5, Zone6, GreenIndic, RedIndic) VALUES ("<<ctxt.rooms[msg->ip]->room<<", '"<<get_date_time<<"', '"<<door<<"', '"<<safe<<"', '"<< panic <<"', '"<<r<<"', '"<<z1<<"', '"<<z2<<"', '"<<z3<<"', '"<<z4<<"', '"<<z5<<"', '"<<z6<<"','"<<green<<"','"<<red<<"')"; // std::cout<< str_access_control.str() << std::endl; qr.execute(str_access_control.str().c_str()); if(!bathroom_panic.compare("FALSE") && bathroom_panic.compare(panic)) { std::ostringstream str_panic; str_panic << "Подаден е сигнал за паника от стая "<<ctxt.rooms[msg->ip]->room<<"!"; write_event(5, str_panic); } if(!safe_open.compare("FALSE") && safe_open.compare(safe)) { std::ostringstream str_panic; str_panic << "Прекъснат датчик за сейф от стая "<<ctxt.rooms[msg->ip]->room<<".Вероятна кражба!"; write_event(6, str_panic); } END_DB() }void fail_prog_card(rc_msg_t* msg, string ¶m, uint16 error){ map<string, linked_ptr<room_status_t> >::iterator i = ctxt.rooms.find(msg->ip); if (i == ctxt.rooms.end()) return; std::string message; pthread_mutex_lock(&ctxt.rooms[msg->ip]->lock); switch (error) { case 1: message = "няма достатъчно памет"; break; case 2: message = "грешка в паметта на контролера"; break; case 3: message = "невалидна чексума"; break; case 4: { message = "номерът вече съществува"; std::map<std::string, bool>::iterator some = ctxt.rooms[msg->ip]->key_map_send.begin(); for (; some != ctxt.rooms[msg->ip]->key_map_send.end(); some++) { char* n; if ((n = strcasestr(some->first.c_str(), param.c_str())) != NULL) { ctxt.rooms[msg->ip]->key_map_send.erase(some); break; } } break; } } pthread_cond_broadcast(&ctxt.rooms[msg->ip]->queue_not_empty); pthread_mutex_unlock(&ctxt.rooms[msg->ip]->lock); std::ostringstream str_err_msg; str_err_msg << "Неуспешно програмиране на карта 0x" << param << " за стая " << ctxt.rooms[msg->ip]->room << ". Причина: " << message; write_event(4, str_err_msg);}void ok_prog_card(rc_msg_t* msg, string& card){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -