Commit 4b2c6f0d authored by captainwong's avatar captainwong

timer

parent 5acc9a41
......@@ -78,11 +78,15 @@ constexpr Char com::QueryMoreSensorLostSettingsRequest::data[];
#endif
enum class QueryZoneStage {
enum class QueryStage {
None,
WaitingSettingsMode,
QueryingZones,
QueryingLostConfig,
WaitingSettingsMode2,
QueryingTimer,
};
struct ZonePropertyAndLostConfig {
......@@ -102,7 +106,7 @@ struct Client {
MachineStatus status2 = MachineStatus::Arm;
MachineStatus status3 = MachineStatus::Arm;
std::map<size_t, ZonePropertyAndLostConfig> zones = {};
QueryZoneStage queryZoneStage = QueryZoneStage::None;
QueryStage queryStage = QueryStage::None;
uint16_t nextSeq() { if (++seq == 10000) { seq = 1; } return seq; }
};
......@@ -130,6 +134,8 @@ std::vector<ThreadContext*> worker_thread_contexts = {};
#define COMMAND_Y_AEGZX ((ADEMCO_EVENT)(EVENT_INVALID_EVENT + 3))
// Z
#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
......@@ -160,6 +166,7 @@ void op_usage()
"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"
"Z: Query Zone info: [ademco_id]\n"
"F: Query Machine Timer: [ademco_id]\n"
"\n"
"I: Print clients info\n"
"P: Toggle enable/disable data print\n"
......@@ -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::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) {
ZonePropertyAndLostConfig zplc;
zplc.prop = zp.prop;
......@@ -211,7 +218,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
} else { // 开始索要防区失联设置
com::AC req;
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,
......@@ -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;
bool hasMore = false;
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) {
auto& z = client.zones[zone];
client.zones[zone].tamper_enabled = true;
......@@ -352,9 +359,9 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
} else if (context->packet.ademcoData_.ademco_event_ == EVENT_COM_PASSTHROUGH) {
handle_com_passthrough(context, client, output);
break;
} else if (context->packet.ademcoData_.ademco_event_ == EVENT_ENTER_SET_MODE &&
client.queryZoneStage == QueryZoneStage::WaitingSettingsMode) {
client.queryZoneStage = QueryZoneStage::QueryingZones;
} else if (context->packet.ademcoData_.ademco_event_ == EVENT_ENTER_SET_MODE) {
if (client.queryStage == QueryStage::WaitingSettingsMode) {
client.queryStage = QueryStage::QueryingZones;
com::A1 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,
......@@ -365,6 +372,20 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
context->worker_id, fd, client.acct.data(), client.ademco_id,
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)
EVENT_ENTER_SET_MODE, 0);
evbuffer_add(client.second.output, buf, n);
client.second.zones.clear();
client.second.queryZoneStage = QueryZoneStage::WaitingSettingsMode;
client.second.queryStage = QueryStage::WaitingSettingsMode;
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 (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)) {
for (int gg = 1; gg <= 3; gg++) {
if (e == EVENT_DISARM) {
......@@ -842,6 +877,22 @@ int main(int argc, char** argv)
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':
......
......@@ -398,6 +398,8 @@ static const char* zonePropertyToStringEn(ZoneProperty zp) {
namespace com
{
#include <pshpack1.h>
//! 读取主机账号
struct ReadMachineAcctRequest {
static constexpr Char len = 7;
......@@ -636,13 +638,25 @@ struct ZoneOpResponse {
};
typedef ZoneOpResponse A4R;
struct Timepoint {
Char hour = 0xFF, minute = 0xFF;
};
struct Timer {
Timepoint armAt = {}, disarmAt = {};
};
//! 主机定时器,一共2组
struct MachineTimer {
struct Timepoint { Char hour = 0; Char minute = 0; };
struct Timer { Timepoint armAt = {}; Timepoint disarmAt = {}; };
Timer data[2] = {}; // 8byte
union MachineTimer {
Timer timer[2]; // 8byte
Char data[8];
MachineTimer() { memset(data, 0xFF, 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
struct MachineTimerRequest {
......@@ -656,8 +670,8 @@ struct MachineTimerResponse {
static constexpr Char len = 7 + sizeof(MachineTimer); // 15
// 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 };
MachineTimer getTimer() const { MachineTimer t; memcpy(&t, &data[6], sizeof(MachineTimer)); return t; }
void setTimer(const MachineTimer& t) { memcpy(&data[6], &t, sizeof(MachineTimer)); sum(this); }
MachineTimer getTimer() const { MachineTimer t; memcpy(&t.data, &data[6], sizeof(MachineTimer)); return t; }
void setTimer(const MachineTimer& t) { memcpy(&data[6], &t.data, sizeof(MachineTimer)); sum(this); }
};
typedef MachineTimerResponse A6R;
......@@ -666,7 +680,7 @@ struct SetMachineTimerRequest {
static constexpr Char len = 6 + sizeof(MachineTimer); // 14
// 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 };
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); }
};
typedef SetMachineTimerRequest A7;
......@@ -1030,6 +1044,8 @@ struct ResponseParser {
}
};
#include <poppack.h>
} // namespace com
} // 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