Commit 4b2c6f0d authored by captainwong's avatar captainwong

timer

parent 5acc9a41
...@@ -78,11 +78,15 @@ constexpr Char com::QueryMoreSensorLostSettingsRequest::data[]; ...@@ -78,11 +78,15 @@ constexpr Char com::QueryMoreSensorLostSettingsRequest::data[];
#endif #endif
enum class QueryZoneStage { enum class QueryStage {
None, None,
WaitingSettingsMode, WaitingSettingsMode,
QueryingZones, QueryingZones,
QueryingLostConfig, QueryingLostConfig,
WaitingSettingsMode2,
QueryingTimer,
}; };
struct ZonePropertyAndLostConfig { struct ZonePropertyAndLostConfig {
...@@ -102,7 +106,7 @@ struct Client { ...@@ -102,7 +106,7 @@ struct Client {
MachineStatus status2 = MachineStatus::Arm; MachineStatus status2 = MachineStatus::Arm;
MachineStatus status3 = MachineStatus::Arm; MachineStatus status3 = MachineStatus::Arm;
std::map<size_t, ZonePropertyAndLostConfig> zones = {}; std::map<size_t, ZonePropertyAndLostConfig> zones = {};
QueryZoneStage queryZoneStage = QueryZoneStage::None; QueryStage queryStage = QueryStage::None;
uint16_t nextSeq() { if (++seq == 10000) { seq = 1; } return seq; } uint16_t nextSeq() { if (++seq == 10000) { seq = 1; } return seq; }
}; };
...@@ -130,6 +134,8 @@ std::vector<ThreadContext*> worker_thread_contexts = {}; ...@@ -130,6 +134,8 @@ std::vector<ThreadContext*> worker_thread_contexts = {};
#define COMMAND_Y_AEGZX ((ADEMCO_EVENT)(EVENT_INVALID_EVENT + 3)) #define COMMAND_Y_AEGZX ((ADEMCO_EVENT)(EVENT_INVALID_EVENT + 3))
// Z // Z
#define COMMAND_Z_QUERY_ZONE ((ADEMCO_EVENT)(EVENT_INVALID_EVENT + 4)) #define COMMAND_Z_QUERY_ZONE ((ADEMCO_EVENT)(EVENT_INVALID_EVENT + 4))
// F
#define COMMAND_F_QUERY_TIMER ((ADEMCO_EVENT)(EVENT_INVALID_EVENT + 5))
// events will be sent to all clients // events will be sent to all clients
...@@ -160,6 +166,7 @@ void op_usage() ...@@ -160,6 +166,7 @@ void op_usage()
"X: Like C, with xdata: [ademco_id event gg zone xdata]\n" "X: Like C, with xdata: [ademco_id event gg zone xdata]\n"
"Y: Like X, with xdata, but xdata is hex: [ademco_id event gg zone xdata], example: [1 1704 0 0 EBAB3FA176]\n" "Y: Like X, with xdata, but xdata is hex: [ademco_id event gg zone xdata], example: [1 1704 0 0 EBAB3FA176]\n"
"Z: Query Zone info: [ademco_id]\n" "Z: Query Zone info: [ademco_id]\n"
"F: Query Machine Timer: [ademco_id]\n"
"\n" "\n"
"I: Print clients info\n" "I: Print clients info\n"
"P: Toggle enable/disable data print\n" "P: Toggle enable/disable data print\n"
...@@ -193,7 +200,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou ...@@ -193,7 +200,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
{ {
com::A2R resp; memcpy(resp.data, xdata.data(), xdata.size()); resp.len = xdata.size() & 0xFF; com::A2R resp; memcpy(resp.data, xdata.data(), xdata.size()); resp.len = xdata.size() & 0xFF;
com::A2R::ZoneAndProperties zps; bool hasMore = false; com::A2R::ZoneAndProperties zps; bool hasMore = false;
if (client.queryZoneStage == QueryZoneStage::QueryingZones && resp.parse(zps, hasMore)) { if (client.queryStage == QueryStage::QueryingZones && resp.parse(zps, hasMore)) {
for (const auto& zp : zps) { for (const auto& zp : zps) {
ZonePropertyAndLostConfig zplc; ZonePropertyAndLostConfig zplc;
zplc.prop = zp.prop; zplc.prop = zp.prop;
...@@ -211,7 +218,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou ...@@ -211,7 +218,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
} else { // 开始索要防区失联设置 } else { // 开始索要防区失联设置
com::AC req; com::AC req;
xdata = makeXData((const char*)req.data, req.len); xdata = makeXData((const char*)req.data, req.len);
client.queryZoneStage = QueryZoneStage::QueryingLostConfig; client.queryStage = QueryStage::QueryingLostConfig;
} }
auto n = context->packet.make_hb(buf, sizeof(buf), client.nextSeq(), client.acct, client.ademco_id, 0, auto n = context->packet.make_hb(buf, sizeof(buf), client.nextSeq(), client.acct, client.ademco_id, 0,
...@@ -253,7 +260,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou ...@@ -253,7 +260,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
com::ADR resp; memcpy(resp.data, xdata.data(), xdata.size()); resp.len = xdata.size() & 0xFF; com::ADR resp; memcpy(resp.data, xdata.data(), xdata.size()); resp.len = xdata.size() & 0xFF;
bool hasMore = false; bool hasMore = false;
std::vector<size_t> zones; std::vector<size_t> zones;
if (client.queryZoneStage == QueryZoneStage::QueryingLostConfig && resp.parse(zones, hasMore)) { if (client.queryStage == QueryStage::QueryingLostConfig && resp.parse(zones, hasMore)) {
for (const auto& zone : zones) { for (const auto& zone : zones) {
auto& z = client.zones[zone]; auto& z = client.zones[zone];
client.zones[zone].tamper_enabled = true; client.zones[zone].tamper_enabled = true;
...@@ -352,9 +359,9 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev) ...@@ -352,9 +359,9 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
} else if (context->packet.ademcoData_.ademco_event_ == EVENT_COM_PASSTHROUGH) { } else if (context->packet.ademcoData_.ademco_event_ == EVENT_COM_PASSTHROUGH) {
handle_com_passthrough(context, client, output); handle_com_passthrough(context, client, output);
break; break;
} else if (context->packet.ademcoData_.ademco_event_ == EVENT_ENTER_SET_MODE && } else if (context->packet.ademcoData_.ademco_event_ == EVENT_ENTER_SET_MODE) {
client.queryZoneStage == QueryZoneStage::WaitingSettingsMode) { if (client.queryStage == QueryStage::WaitingSettingsMode) {
client.queryZoneStage = QueryZoneStage::QueryingZones; client.queryStage = QueryStage::QueryingZones;
com::A1 req; com::A1 req;
auto xdata = makeXData((const char*)req.data, req.len); auto xdata = makeXData((const char*)req.data, req.len);
auto n = context->packet.make_hb(buf, sizeof(buf), client.nextSeq(), client.acct, client.ademco_id, 0, auto n = context->packet.make_hb(buf, sizeof(buf), client.nextSeq(), client.acct, client.ademco_id, 0,
...@@ -365,6 +372,20 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev) ...@@ -365,6 +372,20 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
context->worker_id, fd, client.acct.data(), client.ademco_id, context->worker_id, fd, client.acct.data(), client.ademco_id,
context->packet.toString(detail::ToStringOption::ALL_CHAR_AS_HEX).data()); context->packet.toString(detail::ToStringOption::ALL_CHAR_AS_HEX).data());
} }
} else if (client.queryStage == QueryStage::WaitingSettingsMode2) {
client.queryStage = QueryStage::QueryingTimer;
com::A5 req;
auto xdata = makeXData((const char*)req.data, req.len);
auto n = context->packet.make_hb(buf, sizeof(buf), client.nextSeq(), client.acct, client.ademco_id, 0,
EVENT_COM_PASSTHROUGH, 0, xdata);
evbuffer_add(output, buf, n);
if (!disable_data_print) {
printf("T#%d S#%d acct=%s ademco_id=%06zX :%s\n",
context->worker_id, fd, client.acct.data(), client.ademco_id,
context->packet.toString(detail::ToStringOption::ALL_CHAR_AS_HEX).data());
}
}
} }
} }
...@@ -463,13 +484,27 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -463,13 +484,27 @@ void commandcb(evutil_socket_t, short, void* user_data)
EVENT_ENTER_SET_MODE, 0); EVENT_ENTER_SET_MODE, 0);
evbuffer_add(client.second.output, buf, n); evbuffer_add(client.second.output, buf, n);
client.second.zones.clear(); client.second.zones.clear();
client.second.queryZoneStage = QueryZoneStage::WaitingSettingsMode; client.second.queryStage = QueryStage::WaitingSettingsMode;
if (!disable_data_print) { if (!disable_data_print) {
printf("T#%d S#%d acct=%s ademco_id=%06zX :%s\n", printf("T#%d S#%d acct=%s ademco_id=%06zX :%s\n",
context->worker_id, client.second.fd, client.second.acct.data(), client.second.ademco_id, context->worker_id, client.second.fd, client.second.acct.data(), client.second.ademco_id,
context->packet.toString(ademco::detail::ToStringOption::ALL_CHAR_AS_HEX).data()); context->packet.toString(ademco::detail::ToStringOption::ALL_CHAR_AS_HEX).data());
} }
} else if (e == COMMAND_F_QUERY_TIMER) { // F
if (client.second.ademco_id != userInput.ademco_id) {
continue;
}
n = context->packet.make_hb(buf, sizeof(buf), client.second.nextSeq(), client.second.acct, client.second.ademco_id, 0,
EVENT_ENTER_SET_MODE, 0);
evbuffer_add(client.second.output, buf, n);
client.second.zones.clear();
client.second.queryStage = QueryStage::WaitingSettingsMode2;
if (!disable_data_print) {
printf("T#%d S#%d acct=%s ademco_id=%06zX :%s\n",
context->worker_id, client.second.fd, client.second.acct.data(), client.second.ademco_id,
context->packet.toString(ademco::detail::ToStringOption::ALL_CHAR_AS_HEX).data());
}
} else if (client.second.type == EVENT_I_AM_3_SECTION_MACHINE && (e == EVENT_ARM || e == EVENT_DISARM)) { } else if (client.second.type == EVENT_I_AM_3_SECTION_MACHINE && (e == EVENT_ARM || e == EVENT_DISARM)) {
for (int gg = 1; gg <= 3; gg++) { for (int gg = 1; gg <= 3; gg++) {
if (e == EVENT_DISARM) { if (e == EVENT_DISARM) {
...@@ -842,6 +877,22 @@ int main(int argc, char** argv) ...@@ -842,6 +877,22 @@ int main(int argc, char** argv)
break; break;
} }
case 'F':
{
int ret = 0;
do {
printf("Input [ademco_id]:");
ret = scanf("%d", &userInput.ademco_id);
clear_stdin();
} while (ret != 1);
{
std::lock_guard<std::mutex> lg(mutex);
commands.push_back(COMMAND_F_QUERY_TIMER);
threads_to_handled_event = thread_count;
}
fire_command();
break;
}
case 'I': case 'I':
......
...@@ -398,6 +398,8 @@ static const char* zonePropertyToStringEn(ZoneProperty zp) { ...@@ -398,6 +398,8 @@ static const char* zonePropertyToStringEn(ZoneProperty zp) {
namespace com namespace com
{ {
#include <pshpack1.h>
//! 读取主机账号 //! 读取主机账号
struct ReadMachineAcctRequest { struct ReadMachineAcctRequest {
static constexpr Char len = 7; static constexpr Char len = 7;
...@@ -636,13 +638,25 @@ struct ZoneOpResponse { ...@@ -636,13 +638,25 @@ struct ZoneOpResponse {
}; };
typedef ZoneOpResponse A4R; typedef ZoneOpResponse A4R;
struct Timepoint {
Char hour = 0xFF, minute = 0xFF;
};
struct Timer {
Timepoint armAt = {}, disarmAt = {};
};
//! 主机定时器,一共2组 //! 主机定时器,一共2组
struct MachineTimer { union MachineTimer {
struct Timepoint { Char hour = 0; Char minute = 0; }; Timer timer[2]; // 8byte
struct Timer { Timepoint armAt = {}; Timepoint disarmAt = {}; }; Char data[8];
Timer data[2] = {}; // 8byte MachineTimer() { memset(data, 0xFF, 8); }
}; };
static_assert(sizeof(MachineTimer) == 8, "sizeof(MachineTimer) must be 8"); static_assert(sizeof(MachineTimer) == 8, "sizeof(MachineTimer) must be 8");
static inline bool isValidMachineTimer(const Timer& t) {
return 0 <= t.armAt.hour && t.armAt.hour < 24 &&
0 <= t.armAt.minute && t.armAt.minute < 60 &&
0 <= t.disarmAt.hour && t.disarmAt.hour < 24 &&
0 <= t.disarmAt.minute && t.disarmAt.minute < 60;
}
//! 获取主机定时器 EB AB 3F A5 7A //! 获取主机定时器 EB AB 3F A5 7A
struct MachineTimerRequest { struct MachineTimerRequest {
...@@ -656,8 +670,8 @@ struct MachineTimerResponse { ...@@ -656,8 +670,8 @@ struct MachineTimerResponse {
static constexpr Char len = 7 + sizeof(MachineTimer); // 15 static constexpr Char len = 7 + sizeof(MachineTimer); // 15
// 0 1 2 3 4 5 a1ah a1am a1dh a1dm a2ah a2am a2dh a2dm sum // 0 1 2 3 4 5 a1ah a1am a1dh a1dm a2ah a2am a2dh a2dm sum
Char data[len] = { 0xEB, 0xBA, 0x3F, 0x0F, 0xCC, 0xA6, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00 }; Char data[len] = { 0xEB, 0xBA, 0x3F, 0x0F, 0xCC, 0xA6, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00 };
MachineTimer getTimer() const { MachineTimer t; memcpy(&t, &data[6], sizeof(MachineTimer)); return t; } MachineTimer getTimer() const { MachineTimer t; memcpy(&t.data, &data[6], sizeof(MachineTimer)); return t; }
void setTimer(const MachineTimer& t) { memcpy(&data[6], &t, sizeof(MachineTimer)); sum(this); } void setTimer(const MachineTimer& t) { memcpy(&data[6], &t.data, sizeof(MachineTimer)); sum(this); }
}; };
typedef MachineTimerResponse A6R; typedef MachineTimerResponse A6R;
...@@ -666,7 +680,7 @@ struct SetMachineTimerRequest { ...@@ -666,7 +680,7 @@ struct SetMachineTimerRequest {
static constexpr Char len = 6 + sizeof(MachineTimer); // 14 static constexpr Char len = 6 + sizeof(MachineTimer); // 14
// 0 1 2 3 4 a1ah a1am a1dh a1dm a2ah a2am a2dh a2dm sum // 0 1 2 3 4 a1ah a1am a1dh a1dm a2ah a2am a2dh a2dm sum
Char data[len] = { 0xEB, 0xCB, 0x3F, 0x0E, 0xA7, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00 }; Char data[len] = { 0xEB, 0xCB, 0x3F, 0x0E, 0xA7, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00 };
MachineTimer getTimer() const { MachineTimer t; memcpy(&t, &data[5], sizeof(MachineTimer)); return t; } MachineTimer getTimer() const { MachineTimer t; memcpy(&t.data, &data[5], sizeof(MachineTimer)); return t; }
void setTimer(const MachineTimer& t) { memcpy(&data[5], &t, sizeof(MachineTimer)); sum(this); } void setTimer(const MachineTimer& t) { memcpy(&data[5], &t, sizeof(MachineTimer)); sum(this); }
}; };
typedef SetMachineTimerRequest A7; typedef SetMachineTimerRequest A7;
...@@ -1030,6 +1044,8 @@ struct ResponseParser { ...@@ -1030,6 +1044,8 @@ struct ResponseParser {
} }
}; };
#include <poppack.h>
} // namespace com } // namespace com
} // namespace common } // namespace common
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment