Commit 158dd30f authored by captainwong's avatar captainwong

fix

parent b1dfcec1
...@@ -17,9 +17,6 @@ constexpr int TIMES = 100000; ...@@ -17,9 +17,6 @@ constexpr int TIMES = 100000;
char data[TIMES * 256]; char data[TIMES * 256];
static constexpr size_t MaxAdemcoId = 999999;
static constexpr size_t AdemcoIdSentinel = MaxAdemcoId + 1;
void ademcoPacketBench() void ademcoPacketBench()
{ {
printf("\nademcoPacketBench...\n"); printf("\nademcoPacketBench...\n");
......
...@@ -66,7 +66,7 @@ struct Session { ...@@ -66,7 +66,7 @@ struct Session {
event* timer = nullptr; event* timer = nullptr;
int id = 0; int id = 0;
std::string acct = {}; std::string acct = {};
size_t ademco_id = 0; AdemcoId ademco_id = 0;
uint16_t seq = 0; uint16_t seq = 0;
AdemcoPacket packet = {}; AdemcoPacket packet = {};
...@@ -97,7 +97,7 @@ void handle_ademco_msg(Session* session, bufferevent* bev) ...@@ -97,7 +97,7 @@ void handle_ademco_msg(Session* session, bufferevent* bev)
{ {
auto output = bufferevent_get_output(bev); auto output = bufferevent_get_output(bev);
switch (session->packet.id_.eid_) { switch (session->packet.id_.eid_) {
case AdemcoId::id_ack: case AdemcoMsgId::id_ack:
if (session->packet.seq_.value_ == session->seq) { if (session->packet.seq_.value_ == session->seq) {
if (++session->seq == 10000) { if (++session->seq == 10000) {
session->seq = 1; session->seq = 1;
......
...@@ -32,7 +32,7 @@ void test() ...@@ -32,7 +32,7 @@ void test()
EXPECT_EQ(cb_commited, strlen(raw)); EXPECT_EQ(cb_commited, strlen(raw));
EXPECT_EQ(ap.crc_.value_, 0xC5C3); EXPECT_EQ(ap.crc_.value_, 0xC5C3);
EXPECT_EQ(ap.len_.value_, 0x0053); EXPECT_EQ(ap.len_.value_, 0x0053);
EXPECT_EQ(ap.id_.eid_, AdemcoId::Enum::id_hb); EXPECT_EQ(ap.id_.eid_, AdemcoMsgId::Enum::id_hb);
EXPECT_EQ(ap.seq_.value_, 0); // 0 is not a valid seq, but... EXPECT_EQ(ap.seq_.value_, 0); // 0 is not a valid seq, but...
EXPECT_TRUE(strncmp("R000000", ap.rrcvr_.data_.data(), 7) == 0); EXPECT_TRUE(strncmp("R000000", ap.rrcvr_.data_.data(), 7) == 0);
EXPECT_TRUE(strncmp("L000000", ap.lpref_.data_.data(), 7) == 0); EXPECT_TRUE(strncmp("L000000", ap.lpref_.data_.data(), 7) == 0);
...@@ -64,11 +64,11 @@ void handle_network_data(const char* data_from_network) ...@@ -64,11 +64,11 @@ void handle_network_data(const char* data_from_network)
{ {
printf("parse ok:\n%s\n", ap.toString().data()); printf("parse ok:\n%s\n", ap.toString().data());
switch (ap.id_.eid_) { switch (ap.id_.eid_) {
case AdemcoId::id_ack: case AdemcoMsgId::id_ack:
// success // success
break; break;
case AdemcoId::id_hb: // event report case AdemcoMsgId::id_hb: // event report
// reply ack // reply ack
{ {
char ack[1024]; char ack[1024];
...@@ -107,8 +107,6 @@ int main() ...@@ -107,8 +107,6 @@ int main()
handle_network_data(data_from_network); handle_network_data(data_from_network);
handle_network_data("\n593F0034\"ACK\"0209R123ABCL456DEF#000001[]_09:00:00,04-18-2020\r"); handle_network_data("\n593F0034\"ACK\"0209R123ABCL456DEF#000001[]_09:00:00,04-18-2020\r");
char buff[1024]; char buff[1024];
AdemcoPacket ap; AdemcoPacket ap;
...@@ -118,8 +116,8 @@ int main() ...@@ -118,8 +116,8 @@ int main()
ap.make_ack(buff, sizeof(buff), 1, "861234567890", 123321); ap.make_ack(buff, sizeof(buff), 1, "861234567890", 123321);
handle_network_data(buff); handle_network_data(buff);
size_t ademco_id = 123456; // 主机标识 AdemcoId ademco_id = 123456; // 主机标识
size_t zone = 123; // 防区标识 AdemcoZone zone = 123; // 防区标识
auto evnt = EVENT_FIRE; // 事件码 auto evnt = EVENT_FIRE; // 事件码
ap.make_hb(buff, sizeof(buff), 1, nullptr, ademco_id, 0, evnt, zone); ap.make_hb(buff, sizeof(buff), 1, nullptr, ademco_id, 0, evnt, zone);
handle_network_data(buff); handle_network_data(buff);
......
...@@ -54,7 +54,7 @@ struct Buffer ...@@ -54,7 +54,7 @@ struct Buffer
SOCKET clientSock = INVALID_SOCKET; SOCKET clientSock = INVALID_SOCKET;
Buffer clientBuffer = {}; Buffer clientBuffer = {};
std::string clientAcct = {}; std::string clientAcct = {};
size_t clientAdemcoId = 0; AdemcoId clientAdemcoId = 0;
std::mutex mutex = {}; std::mutex mutex = {};
std::vector<ADEMCO_EVENT> evntsWaiting4Send = {}; std::vector<ADEMCO_EVENT> evntsWaiting4Send = {};
...@@ -151,11 +151,11 @@ int main(int argc, char** argv) ...@@ -151,11 +151,11 @@ int main(int argc, char** argv)
//printf("id=%s\n", ap.id_.data()); //printf("id=%s\n", ap.id_.data());
printf("C:%s\n", ap.toString().data()); printf("C:%s\n", ap.toString().data());
switch (ap.id_.eid_) { switch (ap.id_.eid_) {
case AdemcoId::id_ack: case AdemcoMsgId::id_ack:
// success // success
break; break;
case AdemcoId::id_null: // reply ack case AdemcoMsgId::id_null: // reply ack
{ {
char ack[1024]; char ack[1024];
auto len = ap.make_ack(ack, sizeof(ack), ap.seq_.value_, ap.acct_.acct(), ap.ademcoData_.ademco_id_); auto len = ap.make_ack(ack, sizeof(ack), ap.seq_.value_, ap.acct_.acct(), ap.ademcoData_.ademco_id_);
...@@ -164,8 +164,8 @@ int main(int argc, char** argv) ...@@ -164,8 +164,8 @@ int main(int argc, char** argv)
break; break;
} }
case AdemcoId::id_hb: // event report case AdemcoMsgId::id_hb: // event report
case AdemcoId::id_admcid: case AdemcoMsgId::id_admcid:
{ {
clientAcct = ap.acct_.acct(); clientAcct = ap.acct_.acct();
clientAdemcoId = ap.ademcoData_.ademco_id_; clientAdemcoId = ap.ademcoData_.ademco_id_;
......
...@@ -91,7 +91,7 @@ struct Client { ...@@ -91,7 +91,7 @@ struct Client {
int fd = 0; int fd = 0;
evbuffer* output = nullptr; evbuffer* output = nullptr;
std::string acct = {}; std::string acct = {};
size_t ademco_id = 0; AdemcoId ademco_id = 0;
uint16_t seq = 0; uint16_t seq = 0;
int type = -1; int type = -1;
MachineStatus status = MachineStatus::Arm; MachineStatus status = MachineStatus::Arm;
...@@ -141,10 +141,10 @@ int threads_to_handled_event = 0; ...@@ -141,10 +141,10 @@ int threads_to_handled_event = 0;
std::mutex mutex = {}; std::mutex mutex = {};
struct UserInput { struct UserInput {
char pwd[1024] = { 0 }; char pwd[1024] = { 0 };
int ademco_id = 0; AdemcoId ademco_id = 0;
int ev = 0; int ev = 0;
int gg = 0; AdemcoGG gg = 0;
int zone = 0; AdemcoZone zone = 0;
char xdata[1024] = { 0 }; char xdata[1024] = { 0 };
}userInput = {}; }userInput = {};
...@@ -222,7 +222,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou ...@@ -222,7 +222,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
EVENT_COM_PASSTHROUGH, 0, xdata); EVENT_COM_PASSTHROUGH, 0, xdata);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
context->worker_id, client.fd, client.acct.data(), client.ademco_id, context->worker_id, client.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());
} }
...@@ -231,7 +231,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou ...@@ -231,7 +231,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
EVENT_EXIT_SET_MODE, 0); EVENT_EXIT_SET_MODE, 0);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
context->worker_id, client.fd, client.acct.data(), client.ademco_id, context->worker_id, client.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());
} }
...@@ -262,7 +262,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou ...@@ -262,7 +262,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
EVENT_EXIT_SET_MODE, 0); EVENT_EXIT_SET_MODE, 0);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
context->worker_id, client.fd, client.acct.data(), client.ademco_id, context->worker_id, client.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());
} }
...@@ -297,7 +297,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou ...@@ -297,7 +297,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
EVENT_COM_PASSTHROUGH, 0, xdata); EVENT_COM_PASSTHROUGH, 0, xdata);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
context->worker_id, client.fd, client.acct.data(), client.ademco_id, context->worker_id, client.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());
} }
...@@ -308,7 +308,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou ...@@ -308,7 +308,7 @@ void handle_com_passthrough(ThreadContext* context, Client& client, evbuffer* ou
EVENT_EXIT_SET_MODE, 0); EVENT_EXIT_SET_MODE, 0);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
context->worker_id, client.fd, client.acct.data(), client.ademco_id, context->worker_id, client.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());
} }
...@@ -342,17 +342,17 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev) ...@@ -342,17 +342,17 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
int fd = (int)bufferevent_getfd(bev); int fd = (int)bufferevent_getfd(bev);
auto& client = context->clients[fd]; auto& client = context->clients[fd];
if (!disable_data_print) { if (!disable_data_print) {
printf("T#%d C#%d acct=%s ademco_id=%06zX :%s\n", printf("T#%d C#%d acct=%s ademco_id=%06X :%s\n",
context->worker_id, fd, client.acct.data(), client.ademco_id, context->packet.toString().data()); context->worker_id, fd, client.acct.data(), client.ademco_id, context->packet.toString().data());
} }
auto output = bufferevent_get_output(bev); auto output = bufferevent_get_output(bev);
switch (context->packet.id_.eid_) { switch (context->packet.id_.eid_) {
case AdemcoId::id_null: case AdemcoMsgId::id_null:
case AdemcoId::id_hb: case AdemcoMsgId::id_hb:
case AdemcoId::id_admcid: case AdemcoMsgId::id_admcid:
{ {
char buf[1024]; char buf[1024];
if (context->packet.id_.eid_ != AdemcoId::id_null) { if (context->packet.id_.eid_ != AdemcoMsgId::id_null) {
client.acct = context->packet.acct_.acct(); client.acct = context->packet.acct_.acct();
client.ademco_id = context->packet.ademcoData_.ademco_id_; client.ademco_id = context->packet.ademcoData_.ademco_id_;
if (ademco::isMachineTypeEvent(context->packet.ademcoData_.ademco_event_)) { if (ademco::isMachineTypeEvent(context->packet.ademcoData_.ademco_event_)) {
...@@ -364,7 +364,7 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev) ...@@ -364,7 +364,7 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
EVENT_COM_PASSTHROUGH, 0, xdata); EVENT_COM_PASSTHROUGH, 0, xdata);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
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());
} }
...@@ -389,7 +389,7 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev) ...@@ -389,7 +389,7 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
EVENT_COM_PASSTHROUGH, 0, xdata); EVENT_COM_PASSTHROUGH, 0, xdata);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
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());
} }
...@@ -401,7 +401,7 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev) ...@@ -401,7 +401,7 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
EVENT_COM_PASSTHROUGH, 0, xdata); EVENT_COM_PASSTHROUGH, 0, xdata);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
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());
} }
...@@ -416,7 +416,7 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev) ...@@ -416,7 +416,7 @@ void handle_ademco_msg(ThreadContext* context, bufferevent* bev)
context->packet.acct_.acct(), context->packet.ademcoData_.ademco_id_); context->packet.acct_.acct(), context->packet.ademcoData_.ademco_id_);
evbuffer_add(output, buf, n); evbuffer_add(output, buf, n);
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=%06X :%s\n",
context->worker_id, fd, client.acct.data(), client.ademco_id, context->packet.toString().data()); context->worker_id, fd, client.acct.data(), client.ademco_id, context->packet.toString().data());
} }
} }
...@@ -453,7 +453,7 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -453,7 +453,7 @@ void commandcb(evutil_socket_t, short, void* user_data)
userInput.gg, (ADEMCO_EVENT)userInput.ev, userInput.zone); userInput.gg, (ADEMCO_EVENT)userInput.ev, userInput.zone);
evbuffer_add(client.second.output, buf, n); evbuffer_add(client.second.output, buf, n);
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=%06X :%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().data()); context->packet.toString().data());
} }
...@@ -465,7 +465,7 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -465,7 +465,7 @@ void commandcb(evutil_socket_t, short, void* user_data)
userInput.gg, (ADEMCO_EVENT)userInput.ev, userInput.zone); userInput.gg, (ADEMCO_EVENT)userInput.ev, userInput.zone);
evbuffer_add(client.second.output, buf, n); evbuffer_add(client.second.output, buf, n);
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=%06X :%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().data()); context->packet.toString().data());
} }
...@@ -478,7 +478,7 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -478,7 +478,7 @@ void commandcb(evutil_socket_t, short, void* user_data)
userInput.gg, (ADEMCO_EVENT)userInput.ev, userInput.zone, xdata); userInput.gg, (ADEMCO_EVENT)userInput.ev, userInput.zone, xdata);
evbuffer_add(client.second.output, buf, n); evbuffer_add(client.second.output, buf, n);
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=%06X :%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().data()); context->packet.toString().data());
} }
...@@ -493,7 +493,7 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -493,7 +493,7 @@ void commandcb(evutil_socket_t, short, void* user_data)
userInput.gg, (ADEMCO_EVENT)userInput.ev, userInput.zone, xdata); userInput.gg, (ADEMCO_EVENT)userInput.ev, userInput.zone, xdata);
evbuffer_add(client.second.output, buf, n); evbuffer_add(client.second.output, buf, n);
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=%06X :%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());
} }
...@@ -507,7 +507,7 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -507,7 +507,7 @@ void commandcb(evutil_socket_t, short, void* user_data)
client.second.zones.clear(); client.second.zones.clear();
client.second.queryStage = QueryStage::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=%06X :%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());
} }
...@@ -522,12 +522,12 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -522,12 +522,12 @@ void commandcb(evutil_socket_t, short, void* user_data)
client.second.zones.clear(); client.second.zones.clear();
client.second.queryStage = QueryStage::WaitingSettingsMode2; client.second.queryStage = QueryStage::WaitingSettingsMode2;
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=%06X :%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 (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 (AdemcoGG gg = 1; gg <= 3; gg++) {
if (e == EVENT_DISARM) { if (e == EVENT_DISARM) {
auto xdata = makeXData(userInput.pwd, 6); auto xdata = makeXData(userInput.pwd, 6);
n = context->packet.make_hb(buf, sizeof(buf), client.second.nextSeq(), client.second.acct, client.second.ademco_id, gg, e, 0, xdata); n = context->packet.make_hb(buf, sizeof(buf), client.second.nextSeq(), client.second.acct, client.second.ademco_id, gg, e, 0, xdata);
...@@ -536,7 +536,7 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -536,7 +536,7 @@ void commandcb(evutil_socket_t, short, void* user_data)
} }
evbuffer_add(client.second.output, buf, n); evbuffer_add(client.second.output, buf, n);
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=%06X :%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().data()); context->packet.toString().data());
} }
...@@ -550,7 +550,7 @@ void commandcb(evutil_socket_t, short, void* user_data) ...@@ -550,7 +550,7 @@ void commandcb(evutil_socket_t, short, void* user_data)
} }
evbuffer_add(client.second.output, buf, n); evbuffer_add(client.second.output, buf, n);
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=%06X :%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().data()); context->packet.toString().data());
} }
...@@ -620,7 +620,7 @@ void accept_cb(evconnlistener* listener, evutil_socket_t fd, sockaddr* addr, int ...@@ -620,7 +620,7 @@ void accept_cb(evconnlistener* listener, evutil_socket_t fd, sockaddr* addr, int
printf("accpet TCP connection #%d from: %s:%d\n", (int)fd, str, sin->sin_port); printf("accpet TCP connection #%d from: %s:%d\n", (int)fd, str, sin->sin_port);
//evutil_make_socket_nonblocking(fd); //evutil_make_socket_nonblocking(fd);
static int worker_id = 0; static uint32_t worker_id = 0;
auto context = worker_thread_contexts[worker_id]; auto context = worker_thread_contexts[worker_id];
std::lock_guard<std::mutex> lg(context->mutex); std::lock_guard<std::mutex> lg(context->mutex);
auto bev = bufferevent_socket_new(context->base, fd, BEV_OPT_CLOSE_ON_FREE); auto bev = bufferevent_socket_new(context->base, fd, BEV_OPT_CLOSE_ON_FREE);
...@@ -637,7 +637,7 @@ void accept_cb(evconnlistener* listener, evutil_socket_t fd, sockaddr* addr, int ...@@ -637,7 +637,7 @@ void accept_cb(evconnlistener* listener, evutil_socket_t fd, sockaddr* addr, int
bufferevent_setcb(bev, readcb, nullptr, eventcb, context); bufferevent_setcb(bev, readcb, nullptr, eventcb, context);
bufferevent_enable(bev, EV_WRITE | EV_READ); bufferevent_enable(bev, EV_WRITE | EV_READ);
worker_id = (++worker_id) % thread_count; worker_id = (worker_id + 1) % thread_count;
} }
void accpet_error_cb(evconnlistener* listener, void* context) void accpet_error_cb(evconnlistener* listener, void* context)
...@@ -748,7 +748,7 @@ int main(int argc, char** argv) ...@@ -748,7 +748,7 @@ int main(int argc, char** argv)
sockaddr_in sin = { 0 }; sockaddr_in sin = { 0 };
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(port); sin.sin_port = htons((uint16_t)(port & 0xFFFF));
printf("using libevent %s\n", event_get_version()); printf("using libevent %s\n", event_get_version());
printf("%s is listening on port %d using %d threads, disable_data_print=%d\n", printf("%s is listening on port %d using %d threads, disable_data_print=%d\n",
...@@ -834,7 +834,7 @@ int main(int argc, char** argv) ...@@ -834,7 +834,7 @@ int main(int argc, char** argv)
int ret = 0; int ret = 0;
do { do {
printf("Input [event gg zone]:"); printf("Input [event gg zone]:");
ret = scanf("%d %d %d", &userInput.ev, &userInput.gg, &userInput.zone); ret = scanf("%d %hhd %d", &userInput.ev, &userInput.gg, &userInput.zone);
clear_stdin(); clear_stdin();
} while (ret != 3); } while (ret != 3);
{ {
...@@ -851,7 +851,7 @@ int main(int argc, char** argv) ...@@ -851,7 +851,7 @@ int main(int argc, char** argv)
int ret = 0; int ret = 0;
do { do {
printf("Input [ademco_id event gg zone]:"); printf("Input [ademco_id event gg zone]:");
ret = scanf("%d %d %d %d", &userInput.ademco_id, &userInput.ev, &userInput.gg, &userInput.zone); ret = scanf("%d %d %hhd %d", &userInput.ademco_id, &userInput.ev, &userInput.gg, &userInput.zone);
clear_stdin(); clear_stdin();
} while (ret != 4); } while (ret != 4);
{ {
...@@ -869,7 +869,7 @@ int main(int argc, char** argv) ...@@ -869,7 +869,7 @@ int main(int argc, char** argv)
int ret = 0; int ret = 0;
do { do {
printf("Input [ademco_id event gg zone xdata]:"); printf("Input [ademco_id event gg zone xdata]:");
ret = scanf("%d %d %d %d %s", &userInput.ademco_id, &userInput.ev, &userInput.gg, &userInput.zone, userInput.xdata); ret = scanf("%d %d %hhd %d %s", &userInput.ademco_id, &userInput.ev, &userInput.gg, &userInput.zone, userInput.xdata);
clear_stdin(); clear_stdin();
} while (ret != 5); } while (ret != 5);
{ {
...@@ -973,7 +973,7 @@ int main(int argc, char** argv) ...@@ -973,7 +973,7 @@ int main(int argc, char** argv)
void Client::printInfo() const void Client::printInfo() const
{ {
if (type == EVENT_I_AM_3_SECTION_MACHINE) { if (type == EVENT_I_AM_3_SECTION_MACHINE) {
printf(" fd=#%d acct=%s ademco_id=%zd type=%s\n", printf(" fd=#%d acct=%s ademco_id=%d type=%s\n",
fd, acct.data(), ademco_id, fd, acct.data(), ademco_id,
machineTypeToString(machineTypeFromAdemcoEvent((ADEMCO_EVENT)type))); machineTypeToString(machineTypeFromAdemcoEvent((ADEMCO_EVENT)type)));
printf(" status1: %d %s status2: %d %s status3: %d %s\n", printf(" status1: %d %s status2: %d %s status3: %d %s\n",
...@@ -981,7 +981,7 @@ void Client::printInfo() const ...@@ -981,7 +981,7 @@ void Client::printInfo() const
(int)status2, machineStatusToString(status2), (int)status2, machineStatusToString(status2),
(int)status3, machineStatusToString(status3)); (int)status3, machineStatusToString(status3));
} else { } else {
printf(" fd=#%d acct=%s ademco_id=%zd type=%s status=%d %s\n", printf(" fd=#%d acct=%s ademco_id=%d type=%s status=%d %s\n",
fd, acct.data(), ademco_id, fd, acct.data(), ademco_id,
machineTypeToString(machineTypeFromAdemcoEvent((ADEMCO_EVENT)type)), machineTypeToString(machineTypeFromAdemcoEvent((ADEMCO_EVENT)type)),
(int)status, machineStatusToString(status)); (int)status, machineStatusToString(status));
......
...@@ -104,6 +104,8 @@ enum ADEMCO_EVENT : uint32_t { ...@@ -104,6 +104,8 @@ enum ADEMCO_EVENT : uint32_t {
EVENT_WHAT_IS_YOUR_TYPE = 1798, // 索要主机类型 EVENT_WHAT_IS_YOUR_TYPE = 1798, // 索要主机类型
EVENT_SIGNAL_STRENGTH_CHANGED = 1799, // 主机信号强度变化 EVENT_SIGNAL_STRENGTH_CHANGED = 1799, // 主机信号强度变化
AdemcoEventSentinel = 10000,
// -------------------接警中心内部使用事件------------------------------ // -------------------接警中心内部使用事件------------------------------
EVENT_PRIVATE_EVENT_BASE = 0x00010000, EVENT_PRIVATE_EVENT_BASE = 0x00010000,
EVENT_CLEARMSG, // 清除报警信息 EVENT_CLEARMSG, // 清除报警信息
......
...@@ -21,19 +21,48 @@ enum class ParseResult ...@@ -21,19 +21,48 @@ enum class ParseResult
RESULT_DATA_ERROR, RESULT_DATA_ERROR,
}; };
typedef uint32_t AdemcoId;
typedef uint8_t AdemcoGG;
typedef uint32_t AdemcoZone;
//! 安定宝ID范围
constexpr AdemcoId AdemcoIdMin = 1;
constexpr AdemcoId AdemcoIdMax = 999999; // 兼容性考虑,最大安定宝 ID 为 0x0F423F
constexpr AdemcoId AdemcoIdSentinel = AdemcoIdMax + 1;
inline bool isValidAdemcoId(AdemcoId ademcoId) { return AdemcoIdMin <= ademcoId && ademcoId <= AdemcoIdMax; }
//! 防区号为0时表示主机自身
constexpr AdemcoZone Zone4MachineSelf = 0;
//! 主机防区号范围
constexpr AdemcoZone ZoneMin = 1;
//! 对任何主机类型,最大的防区号
constexpr AdemcoZone ZoneMax = 999;
constexpr AdemcoZone ZoneSentinel = ZoneMax + 1;
//! 对任何主机类型,防区号是否合法(可以包含0防区)
inline bool isValidZone(AdemcoZone zone) {
return Zone4MachineSelf <= zone && zone < ZoneSentinel;
}
//! 对任何主机类型,防区号是否合法(不可以包含0防区)
inline bool isValidZoneStrict(AdemcoZone zone) {
return ZoneMin <= zone && zone < ZoneSentinel;
}
//! 安定宝数据包 data 段 //! 安定宝数据包 data 段
struct AdemcoData struct AdemcoData
{ {
//! 数据 //! 数据
std::vector<char> data_ = {}; std::vector<char> data_ = {};
//! 安定宝ID //! 安定宝ID
size_t ademco_id_ = 0; AdemcoId ademco_id_ = 0;
//! 安定宝事件码 //! 安定宝事件码
ADEMCO_EVENT ademco_event_ = ADEMCO_EVENT::EVENT_INVALID_EVENT; ADEMCO_EVENT ademco_event_ = ADEMCO_EVENT::EVENT_INVALID_EVENT;
//! gg //! gg
unsigned char gg_ = 0; AdemcoGG gg_ = 0;
//! zone //! zone
size_t zone_ = 0; AdemcoZone zone_ = 0;
AdemcoData() { make(); } AdemcoData() { make(); }
...@@ -54,21 +83,21 @@ struct AdemcoData ...@@ -54,21 +83,21 @@ struct AdemcoData
return str; return str;
} }
void assignAdemcoId(size_t ademco_id) { void assignAdemcoId(AdemcoId ademco_id) {
char aid[7] = { 0 }; char aid[7] = { 0 };
snprintf(aid, sizeof(aid), "%06X", static_cast<int>(ademco_id % 1000000)); snprintf(aid, sizeof(aid), "%06X", static_cast<int>(ademco_id % AdemcoIdSentinel));
std::copy(aid, aid + 6, std::back_inserter(data_)); std::copy(aid, aid + 6, std::back_inserter(data_));
ademco_id_ = ademco_id; ademco_id_ = ademco_id;
} }
void assignAdemcoEvent(ADEMCO_EVENT ademco_event) { void assignAdemcoEvent(ADEMCO_EVENT ademco_event) {
char aev[5] = { 0 }; char aev[5] = { 0 };
snprintf(aev, sizeof(aev), "%04d", static_cast<int>(ademco_event % 10000)); snprintf(aev, sizeof(aev), "%04d", static_cast<int>(ademco_event % AdemcoEventSentinel));
std::copy(aev, aev + 4, std::back_inserter(data_)); std::copy(aev, aev + 4, std::back_inserter(data_));
ademco_event_ = ademco_event; ademco_event_ = ademco_event;
} }
void assignGG(size_t gg) { void assignGG(AdemcoGG gg) {
if (gg == 0xEE) { if (gg == 0xEE) {
data_.push_back('E'); data_.push_back('E');
data_.push_back('E'); data_.push_back('E');
...@@ -83,15 +112,15 @@ struct AdemcoData ...@@ -83,15 +112,15 @@ struct AdemcoData
gg_ = static_cast<unsigned char>(gg); gg_ = static_cast<unsigned char>(gg);
} }
void assignZone(size_t zone) { void assignZone(AdemcoZone zone) {
char z[4] = { 0 }; char z[4] = { 0 };
snprintf(z, sizeof(z), "%03d", static_cast<int>(zone % 1000)); snprintf(z, sizeof(z), "%03d", static_cast<int>(zone % ZoneSentinel));
std::copy(z, z + 3, std::back_inserter(data_)); std::copy(z, z + 3, std::back_inserter(data_));
zone_ = zone; zone_ = zone;
} }
//! 生成可用于网络传输的数据 //! 生成可用于网络传输的数据
void make(size_t ademco_id, size_t gg, ADEMCO_EVENT ademco_event, size_t zone) { void make(AdemcoId ademco_id, AdemcoGG gg, ADEMCO_EVENT ademco_event, AdemcoZone zone) {
if (EVENT_INVALID_EVENT == ademco_event) { make(); return; } if (EVENT_INVALID_EVENT == ademco_event) { make(); return; }
clear(); clear();
...@@ -111,7 +140,7 @@ struct AdemcoData ...@@ -111,7 +140,7 @@ struct AdemcoData
} }
//! 生成可用于网络传输的数据 //! 生成可用于网络传输的数据
void make(const char* acct, size_t gg, ADEMCO_EVENT ademco_event, size_t zone) { void make(const char* acct, AdemcoGG gg, ADEMCO_EVENT ademco_event, AdemcoZone zone) {
clear(); clear();
data_.clear(); data_.clear();
...@@ -165,12 +194,12 @@ struct AdemcoData ...@@ -165,12 +194,12 @@ struct AdemcoData
if (acct_len == 4) { if (acct_len == 4) {
if (*(p + 4) != '|') if (*(p + 4) != '|')
break; break;
ademco_id_ = detail::HexCharArrayToDec(p, 4); ademco_id_ = static_cast<AdemcoId>(detail::HexCharArrayToDec(p, 4) % AdemcoIdSentinel);
p += 5; p += 5;
} else if (acct_len == 6) { } else if (acct_len == 6) {
if (*(p + 6) != '|') if (*(p + 6) != '|')
break; break;
ademco_id_ = detail::HexCharArrayToDec(p, 6); ademco_id_ = static_cast<AdemcoId>(detail::HexCharArrayToDec(p, 6) % AdemcoIdSentinel);
p += 7; p += 7;
} else if (acct_len == 14) { // just ignore it } else if (acct_len == 14) { // just ignore it
if (*(p + 14) != '|') if (*(p + 14) != '|')
...@@ -182,7 +211,7 @@ struct AdemcoData ...@@ -182,7 +211,7 @@ struct AdemcoData
p += acct_len + 1; p += acct_len + 1;
} }
ademco_event_ = static_cast<ADEMCO_EVENT>(detail::NumCharArray2Dec(p, 4)); ademco_event_ = static_cast<ADEMCO_EVENT>(detail::NumCharArray2Dec(p, 4) % AdemcoEventSentinel);
p += 4; p += 4;
if (*p++ != ' ') if (*p++ != ' ')
break; break;
...@@ -192,14 +221,14 @@ struct AdemcoData ...@@ -192,14 +221,14 @@ struct AdemcoData
} else if (*p == 'C' && *(p + 1) == 'C') { } else if (*p == 'C' && *(p + 1) == 'C') {
gg_ = 0xCC; gg_ = 0xCC;
} else { } else {
gg_ = static_cast<unsigned char>((*p - '0') * 10 + (*(p + 1) - '0')); gg_ = static_cast<AdemcoGG>((*p - '0') * 10 + (*(p + 1) - '0'));
} }
p += 2; p += 2;
if (*p++ != ' ') if (*p++ != ' ')
break; break;
zone_ = detail::NumCharArray2Dec(p, 3); zone_ = static_cast<AdemcoZone>(detail::NumCharArray2Dec(p, 3) % ZoneSentinel);
std::copy(pack, pack + pack_len, std::back_inserter(data_)); std::copy(pack, pack + pack_len, std::back_inserter(data_));
return true; return true;
} while (0); } while (0);
...@@ -219,8 +248,8 @@ struct AdemcoData ...@@ -219,8 +248,8 @@ struct AdemcoData
// 2016-11-4 16:47:51 for compatibility of congwin fe100 protocal // 2016-11-4 16:47:51 for compatibility of congwin fe100 protocal
struct CongwinFe100Packet struct CongwinFe100Packet
{ {
char data_[32] = { 0 }; static constexpr size_t length = 31;
const int len_ = 31; char data_[length + 1] = { 0 };
bool fromAdemcoData(const AdemcoData* data) { bool fromAdemcoData(const AdemcoData* data) {
assert(data && data->valid()); assert(data && data->valid());
...@@ -228,10 +257,9 @@ struct CongwinFe100Packet ...@@ -228,10 +257,9 @@ struct CongwinFe100Packet
return false; return false;
} }
size_t acct = data->ademco_id_; auto acct = data->ademco_id_;
auto evnt = data->ademco_event_; auto evnt = data->ademco_event_;
//int gg = data->_gg; auto zone = data->zone_;
size_t zone = data->zone_;
int ndx = 0; int ndx = 0;
data_[ndx++] = '\n'; // LF data_[ndx++] = '\n'; // LF
...@@ -281,7 +309,7 @@ struct CongwinFe100Packet ...@@ -281,7 +309,7 @@ struct CongwinFe100Packet
data_[ndx++] = 'C'; // C data_[ndx++] = 'C'; // C
} }
ndx += sprintf(data_ + ndx, "%03d", static_cast<int>(zone % 10000)); ndx += sprintf(data_ + ndx, "%03d", static_cast<int>(zone % ZoneSentinel));
data_[ndx++] = ' '; data_[ndx++] = ' ';
data_[ndx++] = '\r'; data_[ndx++] = '\r';
...@@ -350,8 +378,8 @@ struct XData ...@@ -350,8 +378,8 @@ struct XData
data_ = tmp; data_ = tmp;
rawData_.resize(data_.size() + 4); rawData_.resize(data_.size() + 4);
rawData_[0] = '['; rawData_[0] = '[';
rawData_[1] = (data_.size() >> 8) & 0xFF; rawData_[1] = (char)((data_.size() >> 8) & 0xFF);
rawData_[2] = data_.size() & 0xFF; rawData_[2] = (char)(data_.size() & 0xFF);
memcpy(&rawData_[3], data_.data(), data_.size()); memcpy(&rawData_[3], data_.data(), data_.size());
rawData_.back() = ']'; rawData_.back() = ']';
} else { } else {
...@@ -688,7 +716,7 @@ static constexpr const char* AdemcoIds[ID_COUNT] = { ...@@ -688,7 +716,7 @@ static constexpr const char* AdemcoIds[ID_COUNT] = {
ID_REG_RSP, ID_REG_RSP,
}; };
struct AdemcoId struct AdemcoMsgId
{ {
enum Enum { enum Enum {
id_null, id_null,
...@@ -794,7 +822,7 @@ struct AdemcoPacket ...@@ -794,7 +822,7 @@ struct AdemcoPacket
static constexpr char LF = 0x0A; static constexpr char LF = 0x0A;
Crc16 crc_ = {}; Crc16 crc_ = {};
Length16 len_ = {}; Length16 len_ = {};
AdemcoId id_ = {}; AdemcoMsgId id_ = {};
AdemcoSeq seq_ = {}; AdemcoSeq seq_ = {};
Rrcvr rrcvr_ = {}; Rrcvr rrcvr_ = {};
Lpref lpref_ = {}; Lpref lpref_ = {};
...@@ -920,13 +948,13 @@ struct AdemcoPacket ...@@ -920,13 +948,13 @@ struct AdemcoPacket
// set acct to nullptr if you want to use ademco_id as acct // set acct to nullptr if you want to use ademco_id as acct
size_t make(char* pack, size_t pack_len, size_t make(char* pack, size_t pack_len,
AdemcoId::Enum id, AdemcoMsgId::Enum id,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
size_t ademco_id, AdemcoId ademco_id,
unsigned char gg, AdemcoGG gg,
ADEMCO_EVENT aevnt, ADEMCO_EVENT aevnt,
size_t zone, AdemcoZone zone,
XDataPtr xdata = {}) XDataPtr xdata = {})
{ {
assert(pack); assert(pack);
...@@ -946,9 +974,9 @@ struct AdemcoPacket ...@@ -946,9 +974,9 @@ struct AdemcoPacket
} }
// set acct to nullptr if you want to use ademco_id as acct // set acct to nullptr if you want to use ademco_id as acct
size_t make_null(char* pack, size_t pack_len, uint16_t seq, const char* acct, size_t ademco_id) size_t make_null(char* pack, size_t pack_len, uint16_t seq, const char* acct, AdemcoId ademco_id)
{ {
id_.eid_ = AdemcoId::Enum::id_null; id_.eid_ = AdemcoMsgId::Enum::id_null;
seq_ = seq; seq_ = seq;
rrcvr_.setDefault(); lpref_.setDefault(); rrcvr_.setDefault(); lpref_.setDefault();
acct ? acct_.setAcct(acct) : acct_.setAcct(ademco_id); acct ? acct_.setAcct(acct) : acct_.setAcct(ademco_id);
...@@ -964,14 +992,14 @@ struct AdemcoPacket ...@@ -964,14 +992,14 @@ struct AdemcoPacket
} }
// set acct to empty if you want to use ademco_id as acct // set acct to empty if you want to use ademco_id as acct
size_t make_null(char* pack, size_t pack_len, uint16_t seq, const std::string& acct, size_t ademco_id) { size_t make_null(char* pack, size_t pack_len, uint16_t seq, const std::string& acct, AdemcoId ademco_id) {
return make_null(pack, pack_len, seq, acct.empty() ? nullptr : acct.data(), ademco_id); return make_null(pack, pack_len, seq, acct.empty() ? nullptr : acct.data(), ademco_id);
} }
// set acct to nullptr if you want to use ademco_id as acct // set acct to nullptr if you want to use ademco_id as acct
size_t make_ack(char* pack, size_t pack_len, uint16_t seq, const char* acct, size_t ademco_id) size_t make_ack(char* pack, size_t pack_len, uint16_t seq, const char* acct, AdemcoId ademco_id)
{ {
id_.eid_ = AdemcoId::Enum::id_ack; id_.eid_ = AdemcoMsgId::Enum::id_ack;
seq_ = seq; seq_ = seq;
rrcvr_.setDefault(); lpref_.setDefault(); rrcvr_.setDefault(); lpref_.setDefault();
acct ? acct_.setAcct(acct) : acct_.setAcct(ademco_id); acct ? acct_.setAcct(acct) : acct_.setAcct(ademco_id);
...@@ -987,12 +1015,12 @@ struct AdemcoPacket ...@@ -987,12 +1015,12 @@ struct AdemcoPacket
} }
// set acct to nullptr if you want to use ademco_id as acct // set acct to nullptr if you want to use ademco_id as acct
size_t make_ack(char* pack, size_t pack_len, uint16_t seq, const std::string& acct, size_t ademco_id) { size_t make_ack(char* pack, size_t pack_len, uint16_t seq, const std::string& acct, AdemcoId ademco_id) {
return make_ack(pack, pack_len, seq, acct.empty() ? nullptr : acct.data(), ademco_id); return make_ack(pack, pack_len, seq, acct.empty() ? nullptr : acct.data(), ademco_id);
} }
size_t make_nak(char* pack, size_t pack_len, uint16_t seq, const std::string& acct, size_t ademco_id) { size_t make_nak(char* pack, size_t pack_len, uint16_t seq, const std::string& acct, AdemcoId ademco_id) {
id_.eid_ = AdemcoId::Enum::id_nak; id_.eid_ = AdemcoMsgId::Enum::id_nak;
seq_ = seq; seq_ = seq;
rrcvr_.setDefault(); lpref_.setDefault(); rrcvr_.setDefault(); lpref_.setDefault();
!acct.empty() ? acct_.setAcct(acct) : acct_.setAcct(ademco_id); !acct.empty() ? acct_.setAcct(acct) : acct_.setAcct(ademco_id);
...@@ -1011,13 +1039,13 @@ struct AdemcoPacket ...@@ -1011,13 +1039,13 @@ struct AdemcoPacket
size_t make_hb(char* pack, size_t pack_len, size_t make_hb(char* pack, size_t pack_len,
uint16_t seq, uint16_t seq,
const char* acct, const char* acct,
size_t ademco_id, AdemcoId ademco_id,
unsigned char gg, AdemcoGG gg,
ADEMCO_EVENT evnt, ADEMCO_EVENT evnt,
size_t zone, AdemcoZone zone,
XDataPtr xdata = {}) XDataPtr xdata = {})
{ {
id_.eid_ = AdemcoId::Enum::id_hb; id_.eid_ = AdemcoMsgId::Enum::id_hb;
seq_ = seq; seq_ = seq;
rrcvr_.setDefault(); lpref_.setDefault(); rrcvr_.setDefault(); lpref_.setDefault();
acct ? acct_.setAcct(acct) : acct_.setAcct(ademco_id); acct ? acct_.setAcct(acct) : acct_.setAcct(ademco_id);
...@@ -1037,10 +1065,10 @@ struct AdemcoPacket ...@@ -1037,10 +1065,10 @@ struct AdemcoPacket
size_t make_hb(char* pack, size_t pack_len, size_t make_hb(char* pack, size_t pack_len,
uint16_t seq, uint16_t seq,
const std::string& acct, const std::string& acct,
size_t ademco_id, AdemcoId ademco_id,
unsigned char gg, AdemcoGG gg,
ADEMCO_EVENT evnt, ADEMCO_EVENT evnt,
size_t zone, AdemcoZone zone,
XDataPtr xdata = {}) XDataPtr xdata = {})
{ {
return make_hb(pack, pack_len, seq, acct.empty() ? nullptr : acct.data(), ademco_id, gg, evnt, zone, xdata); return make_hb(pack, pack_len, seq, acct.empty() ? nullptr : acct.data(), ademco_id, gg, evnt, zone, xdata);
...@@ -1049,156 +1077,161 @@ struct AdemcoPacket ...@@ -1049,156 +1077,161 @@ struct AdemcoPacket
// parser // parser
ParseResult parse(const char* pack, size_t pack_len, size_t& cb_commited) { ParseResult parse(const char* pack, size_t pack_len, size_t& cb_commited) {
//AUTO_LOG_FUNCTION; //AUTO_LOG_FUNCTION;
do { try {
if (pack_len < 9) { do {
JLOG_INFO("AdemcoPacket::Parse pack_len {} < 9", pack_len); JLOG_HEX(pack, pack_len); if (pack_len < 9) {
return ParseResult::RESULT_NOT_ENOUGH; JLOG_INFO("AdemcoPacket::Parse pack_len {} < 9", pack_len); JLOG_HEX(pack, pack_len);
} return ParseResult::RESULT_NOT_ENOUGH;
}
// check LF // check LF
if (pack[0] != LF) { if (pack[0] != LF) {
JLOG_ERRO("AdemcoPacket::Parse pack[0] {:d} 0x{:02X} is not _LF", pack[0], pack[0]); JLOG_ERRO("AdemcoPacket::Parse pack[0] {:d} 0x{:02X} is not _LF", pack[0], pack[0]);
#ifdef _WIN32 #ifdef _WIN32
return ParseResult::RESULT_DATA_ERROR; return ParseResult::RESULT_DATA_ERROR;
#else #else
break; break;
#endif #endif
} }
clear(); clear();
// read crc & len // read crc & len
crc_.fromCharArray(pack + 1); crc_.fromCharArray(pack + 1);
len_.fromCharArray(pack + 5); len_.fromCharArray(pack + 5);
// read till CR // read till CR
size_t len_to_parse = 9 + len_.value_ + 1; // 1 for CR size_t len_to_parse = 9u + len_.value_ + 1; // 1 for CR
// check if packet is enough to parse // check if packet is enough to parse
if (pack_len < len_to_parse) { if (pack_len < len_to_parse) {
JLOG_ERRO("AdemcoPacket::Parse pack_len {} < len_to_parse {}", pack_len, len_to_parse); JLOG_ERRO("AdemcoPacket::Parse pack_len {} < len_to_parse {}", pack_len, len_to_parse);
return ParseResult::RESULT_NOT_ENOUGH; return ParseResult::RESULT_NOT_ENOUGH;
} }
// check CR // check CR
const char* id_pos = pack + 9; const char* id_pos = pack + 9;
const char* CR_pos = id_pos + len_.value_; const char* CR_pos = id_pos + len_.value_;
if (*CR_pos != CR) { if (*CR_pos != CR) {
JLOG_ERRO("AdemcoPacket::Parse ademco_len err!"); JLOG_ERRO("AdemcoPacket::Parse ademco_len err!");
break; break;
} }
// check ademco CRC // check ademco CRC
unsigned short crc_calc = detail::CalculateCRC(id_pos, len_.value_); unsigned short crc_calc = detail::CalculateCRC(id_pos, len_.value_);
if (crc_.value_ != crc_calc) { if (crc_.value_ != crc_calc) {
JLOG_ERRO("AdemcoPacket::Parse crc failed!"); JLOG_ERRO("AdemcoPacket::Parse crc failed!");
break; break;
} }
// id // id
if (*id_pos != '\"') { // find first " of "id". if (*id_pos != '\"') { // find first " of "id".
JLOG_ERRO("AdemcoPacket::Parse find left \" of \"id\" faild!"); JLOG_ERRO("AdemcoPacket::Parse find left \" of \"id\" faild!");
break; break;
} }
const char* p = id_pos + 1; // find last " of "id". const char* p = id_pos + 1; // find last " of "id".
while (p < CR_pos && *p != '\"') { p++; } if (p >= CR_pos) { break; } while (p < CR_pos && *p != '\"') { p++; } if (p >= CR_pos) { break; }
if (*p++ != '\"') { // " not found. if (*p++ != '\"') { // " not found.
JLOG_ERRO("AdemcoPacket::Parse find right \" of \"id\" faild!"); JLOG_ERRO("AdemcoPacket::Parse find right \" of \"id\" faild!");
break; break;
} }
if (!id_.checkAndSet(id_pos, p - id_pos)) { if (!id_.checkAndSet(id_pos, p - id_pos)) {
JLOG_ERRO("AdemcoPacket::Parse check id faild!"); JLOG_ERRO("AdemcoPacket::Parse check id faild!");
break; break;
} }
// seq (and Rrcvr, it may not exists) // seq (and Rrcvr, it may not exists)
const char* seq_pos = p; const char* seq_pos = p;
while (p < CR_pos && *p != 'R' && *p != 'L') { p++; } if (p >= CR_pos) { break; } while (p < CR_pos && *p != 'R' && *p != 'L') { p++; } if (p >= CR_pos) { break; }
if (p - seq_pos != 4) { if (p - seq_pos != 4) {
JLOG_ERRO("AdemcoPacket::Parse seq len != 4"); JLOG_ERRO("AdemcoPacket::Parse seq len != 4");
break; break;
} }
seq_.fromCharArray(seq_pos); seq_.fromCharArray(seq_pos);
if (*p == 'R') { // Rrcvr exists if (*p == 'R') { // Rrcvr exists
const char* rrcvr_pos = p; const char* rrcvr_pos = p;
while (p < CR_pos && *p != 'L' && *p != '#') { p++; } if (p >= CR_pos) { break; } while (p < CR_pos && *p != 'L' && *p != '#') { p++; } if (p >= CR_pos) { break; }
//ASSIGH_SEG_DATA(rrcvr); //ASSIGH_SEG_DATA(rrcvr);
rrcvr_.fromCharArray(rrcvr_pos, p - rrcvr_pos); rrcvr_.fromCharArray(rrcvr_pos, p - rrcvr_pos);
} else if (*p == 'L') { // Rrcvr not exists, pass } else if (*p == 'L') { // Rrcvr not exists, pass
// pass // pass
} else { } else {
JLOG_ERRO("AdemcoPacket::Parse Lpref and Rrcvr not found!"); JLOG_ERRO("AdemcoPacket::Parse Lpref and Rrcvr not found!");
break; break;
} }
// Lpref // Lpref
if (*p != 'L') { // L of Lpref not found. if (*p != 'L') { // L of Lpref not found.
JLOG_ERRO("AdemcoPacket::Parse Lpref not found!"); JLOG_ERRO("AdemcoPacket::Parse Lpref not found!");
break; break;
} }
const char* lpref_pos = p; const char* lpref_pos = p;
while (p < CR_pos && *p != '#') { p++; } if (p >= CR_pos) { break; } while (p < CR_pos && *p != '#') { p++; } if (p >= CR_pos) { break; }
lpref_.fromCharArray(lpref_pos, p - lpref_pos); lpref_.fromCharArray(lpref_pos, p - lpref_pos);
// acct // acct
if (*p++ != '#') { // # of #acct not found if (*p++ != '#') { // # of #acct not found
JLOG_ERRO("AdemcoPacket::Parse # of #acct not found!"); JLOG_ERRO("AdemcoPacket::Parse # of #acct not found!");
break;
}
const char* acct_pos = p;
while (p < CR_pos && *p != '[') {
if (!isalnum(*p)) { // acct must be alphanumeric
JLOG_ERRO("AdemcoPacket::Parse acct check isalnum failed!");
p = nullptr;
break; break;
} }
p++; const char* acct_pos = p;
} while (p < CR_pos && *p != '[') {
if (p == nullptr) { break; } if (!isalnum(*p)) { // acct must be alphanumeric
if (p >= CR_pos) { break; } JLOG_ERRO("AdemcoPacket::Parse acct check isalnum failed!");
acct_.setAcct(acct_pos, p - acct_pos); p = nullptr;
break;
}
p++;
}
if (p == nullptr) { break; }
if (p >= CR_pos) { break; }
acct_.setAcct(acct_pos, p - acct_pos);
// data // data
if (*p != '[') { // [ of [data] not found. if (*p != '[') { // [ of [data] not found.
JLOG_ERRO("AdemcoPacket::Parse [ of [data] not found!"); JLOG_ERRO("AdemcoPacket::Parse [ of [data] not found!");
break; break;
} }
const char* data_pos = p; const char* data_pos = p;
while (p < CR_pos && *p != ']') { p++; } if (p >= CR_pos) { break; } while (p < CR_pos && *p != ']') { p++; } if (p >= CR_pos) { break; }
if (*p != ']') { // ] of [data] not found. if (*p != ']') { // ] of [data] not found.
JLOG_ERRO("AdemcoPacket::Parse ] of [data] not found!"); JLOG_ERRO("AdemcoPacket::Parse ] of [data] not found!");
break; break;
} }
size_t ademco_data_len = ++p - data_pos; size_t ademco_data_len = ++p - data_pos;
if (!ademcoData_.parse(data_pos, ademco_data_len)) { if (!ademcoData_.parse(data_pos, ademco_data_len)) {
JLOG_ERRO("AdemcoPacket::Parse parse data failed!"); JLOG_ERRO("AdemcoPacket::Parse parse data failed!");
break; break;
} }
// [x...data...] // [x...data...]
if (*p == '[') { // xdata exists if (*p == '[') { // xdata exists
xdata_ = parseXData(p, CR_pos); xdata_ = parseXData(p, CR_pos);
if (!xdata_) { break; } if (!xdata_) { break; }
p += xdata_->rawSize(); p += xdata_->rawSize();
} }
if (*p != '_') { // _ of _timestamp not found. if (*p != '_') { // _ of _timestamp not found.
JLOG_ERRO("AdemcoPacket::Parse _ of _timestamp not found!"); JLOG_ERRO("AdemcoPacket::Parse _ of _timestamp not found!");
break; break;
} }
if (!timestamp_.parse(p, CR_pos - p)) { if (!timestamp_.parse(p, CR_pos - p)) {
JLOG_ERRO("AdemcoPacket::Parse parse timestamp failed!"); JLOG_ERRO("AdemcoPacket::Parse parse timestamp failed!");
break; break;
} }
p += timestamp_.length; p += timestamp_.length;
// check CR // check CR
if (p++ != CR_pos) { assert(0); break; } if (p++ != CR_pos) { assert(0); break; }
cb_commited = p - pack; cb_commited = p - pack;
return ParseResult::RESULT_OK; return ParseResult::RESULT_OK;
} while (0); } while (0);
} catch (std::exception& e) {
printf("AdemcoPacket::parse EXCEPTION: %s\n", e.what());
abort();
}
// dump data // dump data
JLOG_HEX(pack, pack_len); JLOG_HEX(pack, pack_len);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <iterator> #include <iterator>
#include "ademco_detail.h" #include "ademco_packet.h"
namespace hb namespace hb
{ {
...@@ -145,10 +145,6 @@ static constexpr MachineType AllMachineTypes[MachineTypeCount] = { ...@@ -145,10 +145,6 @@ static constexpr MachineType AllMachineTypes[MachineTypeCount] = {
IoT, IoT,
}; };
//! 防区号为0时表示主机自身
static constexpr uint16_t Zone4MachineSelf = 0;
//! 主机防区号范围
static constexpr uint16_t ZoneMin = 1;
//! 最大防区号根据型号不同而不同 //! 最大防区号根据型号不同而不同
static uint16_t zoneMax(MachineType type) { static uint16_t zoneMax(MachineType type) {
switch (type) { switch (type) {
...@@ -177,27 +173,15 @@ static uint16_t zoneMax(MachineType type) { ...@@ -177,27 +173,15 @@ static uint16_t zoneMax(MachineType type) {
break; break;
} }
} }
//! 对任何主机类型,最大的防区数量
static constexpr uint16_t MaxZoneCount = 1000;
//! 对任何主机类型,防区号是否合法(可以包含0防区)
static bool isValidZone(uint16_t zone) {
return Zone4MachineSelf <= zone && zone < MaxZoneCount;
}
//! 对任何主机类型,防区号是否合法(不可以包含0防区)
static bool isValidZoneStrict(uint16_t zone) {
return ZoneMin <= zone && zone < MaxZoneCount;
}
//! 防区号是否合法(可以包含0防区) //! 防区号是否合法(可以包含0防区)
static bool isValidZone(MachineType type, uint16_t zone) { static bool isValidZone(MachineType type, uint16_t zone) {
return Zone4MachineSelf <= zone && zone <= zoneMax(type); return ademco::Zone4MachineSelf <= zone && zone <= zoneMax(type);
} }
//! 防区号是否合法(不可以可以包含0防区) //! 防区号是否合法(不可以可以包含0防区)
static bool isValidZoneStrict(MachineType type, uint16_t zone) { static bool isValidZoneStrict(MachineType type, uint16_t zone) {
return ZoneMin <= zone && zone <= zoneMax(type); return ademco::ZoneMin <= zone && zone <= zoneMax(type);
} }
//! 主机是否具有半布防功能 //! 主机是否具有半布防功能
...@@ -1776,20 +1760,15 @@ struct WirelessAddress { ...@@ -1776,20 +1760,15 @@ struct WirelessAddress {
}; };
//! 防区号为0时表示主机(或分主机)自身
static constexpr uint16_t Zone4MachineSelf = 0;
//! 主机防区号范围1~999
static constexpr uint16_t ZoneMin = 1;
static constexpr uint16_t ZoneMax = 999;
//! 主机有线防区范围1~7 //! 主机有线防区范围1~7
static constexpr uint16_t ZoneMinWired = ZoneMin; constexpr ademco::AdemcoZone ZoneMinWired = 1;
static constexpr uint16_t ZoneMaxWired = 8; constexpr ademco::AdemcoZone ZoneMaxWired = 8;
//! 主机无线防区最小值 //! 主机无线防区最小值
static constexpr uint16_t ZoneMinWireless = ZoneMaxWired + 1; constexpr ademco::AdemcoZone ZoneMinWireless = 9;
static constexpr uint16_t ZoneMaxWireless = ZoneMax; constexpr ademco::AdemcoZone ZoneMaxWireless = 999;
//! 分主机防区号范围1~99 //! 分主机防区号范围1~99
static constexpr uint16_t ZoneMinSubMachine = 1; constexpr ademco::AdemcoZone ZoneMinSubMachine = 1;
static constexpr uint16_t ZoneMaxSubMachine = 99; constexpr ademco::AdemcoZone ZoneMaxSubMachine = 99;
//! 以2个字节表示的防区号 //! 以2个字节表示的防区号
...@@ -1841,9 +1820,9 @@ struct ZoneInfo { ...@@ -1841,9 +1820,9 @@ struct ZoneInfo {
//! 所有防区信息 //! 所有防区信息
struct AllZoneInfo { struct AllZoneInfo {
//! use extra 1 space, for convenience to use zone as index //! use extra 1 space, for convenience to use zone as index
ZoneInfo zones[ZoneMax + 1] = {}; ZoneInfo zones[ademco::ZoneSentinel] = {};
AllZoneInfo() { for (uint16_t i = 0; i <= ZoneMax; i++) { zones[i].zone = i; } } AllZoneInfo() { for (uint16_t i = 0; i < ademco::ZoneSentinel; i++) { zones[i].zone = i; } }
bool isUniqueAddr(WirelessAddress addr) const { bool isUniqueAddr(WirelessAddress addr) const {
for (const auto& z : zones) { if (z.addr == addr)return false; } for (const auto& z : zones) { if (z.addr == addr)return false; }
...@@ -1906,7 +1885,7 @@ struct Query { ...@@ -1906,7 +1885,7 @@ struct Query {
void setZone(ZoneAsTwoChar zone) { data[3] = zone.hi; data[4] = zone.lo; } void setZone(ZoneAsTwoChar zone) { data[3] = zone.hi; data[4] = zone.lo; }
static Query queryMachineStatus() { static Query queryMachineStatus() {
return queryZoneStatus(Zone4MachineSelf); return queryZoneStatus(ademco::Zone4MachineSelf);
} }
static Query queryZoneStatus(uint16_t zone) { static Query queryZoneStatus(uint16_t zone) {
...@@ -1918,7 +1897,7 @@ struct Query { ...@@ -1918,7 +1897,7 @@ struct Query {
} }
static Query querySubMachineStatus() { static Query querySubMachineStatus() {
return queryZoneStatusOfSubMachine(Zone4MachineSelf); return queryZoneStatusOfSubMachine(ademco::Zone4MachineSelf);
} }
static Query queryZoneStatusOfSubMachine(Char zone) { static Query queryZoneStatusOfSubMachine(Char zone) {
......
...@@ -5,13 +5,6 @@ ...@@ -5,13 +5,6 @@
namespace hb namespace hb
{ {
//! 安定宝ID范围
static constexpr size_t MinAdemcoId = 1;
static constexpr size_t MaxAdemcoId = 999999; // 兼容性考虑,最大安定宝 ID 为 0x0F423F
static constexpr size_t AdemcoIdSentinel = MaxAdemcoId + 1;
static constexpr bool isValidAdemcoId(size_t ademcoId) { return MinAdemcoId <= ademcoId && ademcoId <= MaxAdemcoId; }
/******** 结合 hb 与 ademco ******/ /******** 结合 hb 与 ademco ******/
//! 从事件码推出主机类型 //! 从事件码推出主机类型
...@@ -23,6 +16,7 @@ static common::MachineType machineTypeFromAdemcoEvent(ademco::ADEMCO_EVENT e) { ...@@ -23,6 +16,7 @@ static common::MachineType machineTypeFromAdemcoEvent(ademco::ADEMCO_EVENT e) {
case ademco::EVENT_I_AM_WIRE_MACHINE: return common::MachineType::Wired; case ademco::EVENT_I_AM_WIRE_MACHINE: return common::MachineType::Wired;
case ademco::EVENT_I_AM_WIFI_MACHINE: return common::MachineType::WiFi; case ademco::EVENT_I_AM_WIFI_MACHINE: return common::MachineType::WiFi;
case ademco::EVENT_I_AM_3_SECTION_MACHINE: return common::MachineType::ThreeSection; case ademco::EVENT_I_AM_3_SECTION_MACHINE: return common::MachineType::ThreeSection;
case ademco::EVENT_I_AM_IOT_MACHINE: return common::MachineType::IoT;
default: return common::MachineType::InvalidMachineType; default: return common::MachineType::InvalidMachineType;
} }
} }
......
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