#pragma once #include "ZJ_ACS.h" #include "ZJ_ACSclient.h" #include "ZJ_ACSserver.h" #include "iostream" #include "fstream" #ifdef WIN32 #include #include #else #include #include #include #include #include #endif #ifndef WIN32 #include #endif #define far typedef void far *LPVOID; unsigned long long GetTimeStamp() { unsigned long long stampNow = 0; time_t timer; timer = time(NULL); stampNow = timer; return stampNow; } void Inver2byte(uint8* Src, int num) { int t = 0; for (int i = 0; i < num / 2; i++) { t = Src[2 * i]; Src[2 * i] = Src[2 * i + 1]; Src[2 * i + 1] = t; } } char *GB2312ToUtf8(const char *chrGbk, int rtuno) { #ifdef WIN32 int len = MultiByteToWideChar(CP_ACP, 0, chrGbk, -1, NULL, 0); wchar_t* wstr = new wchar_t[len + 1]; memset(wstr, 0, len + 1); MultiByteToWideChar(CP_ACP, 0, chrGbk, -1, wstr, len); len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len + 1]; memset(str, 0, len + 1); WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); if (wstr) delete[] wstr; #else size_t wlen = 0; size_t allLen = 0; char *inbuf = (char*)chrGbk; size_t inlen = strlen(inbuf); size_t outlen = allLen = inlen * 4; char *unicode = new char[outlen]; char* outbuf = (char*)unicode; char* from_charset = "gb2312"; char* to_charset = "utf-8"; iconv_t cd; char** pin = &inbuf; char** pout = &outbuf; cd = iconv_open(to_charset, from_charset); if (cd == 0) kprintf(10, rtuno, 4, "rds change charset iconv false!"); memset(outbuf, 0, outlen); if (iconv(cd, pin, &inlen, pout, &outlen) == -1){ kprintf(10, rtuno, 4, "rds change charset iconv false!inlen=%d,outlen=%d,Msg=%s\n", inlen, (int)outlen, inbuf); } wlen = allLen - outlen + 1; //Inver2byte((uint8*)(unicode), 2 * wlen); char * str = unicode; iconv_close(cd); #endif return str; } char *Utf8ToGB2312(const char *chrUtf8, int rtuno) { #ifdef WIN32 int len = MultiByteToWideChar(CP_UTF8, 0, chrUtf8, -1, NULL, 0); wchar_t* wstr = new wchar_t[len + 1]; memset(wstr, 0, len + 1); MultiByteToWideChar(CP_UTF8, 0, chrUtf8, -1, wstr, len); len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len + 1]; memset(str, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); if (wstr) delete[] wstr; #else size_t wlen = 0; size_t allLen = 0; char *inbuf = (char*)chrUtf8; size_t inlen = strlen(inbuf); size_t outlen = allLen = inlen * 4; char *unicode = new char[outlen]; char* outbuf = (char*)unicode; char* from_charset = "utf-8"; char* to_charset = "gb2312"; iconv_t cd; char** pin = &inbuf; char** pout = &outbuf; cd = iconv_open(to_charset, from_charset); if (cd == 0) kprintf(10, rtuno, 4, "rds change charset iconv false!"); memset(outbuf, 0, outlen); if (iconv(cd, pin, &inlen, pout, &outlen) == -1){ kprintf(10, rtuno, 4, "rds change charset iconv false!inlen=%d,outlen=%d,Msg=%s\n", inlen, (int)outlen, inbuf); } wlen = allLen - outlen + 1; //Inver2byte((uint8*)(unicode + 1), 2 * wlen); char * str = unicode; iconv_close(cd); #endif return str; } bool is_str_utf8(const char* str) { unsigned int nBytes = 0;//UFT8可用1-6个字节编码,ASCII用一个字节 unsigned char chr = *str; bool bAllAscii = true; for (unsigned int i = 0; str[i] != '\0'; ++i){ chr = *(str + i); //判断是否ASCII编码,如果不是,说明有可能是UTF8,ASCII用7位编码,最高位标记为0,0xxxxxxx if (nBytes == 0 && (chr & 0x80) != 0){ bAllAscii = false; } if (nBytes == 0) { //如果不是ASCII码,应该是多字节符,计算字节数 if (chr >= 0x80) { if (chr >= 0xFC && chr <= 0xFD){ nBytes = 6; } else if (chr >= 0xF8){ nBytes = 5; } else if (chr >= 0xF0){ nBytes = 4; } else if (chr >= 0xE0){ nBytes = 3; } else if (chr >= 0xC0){ nBytes = 2; } else{ return false; } nBytes--; } } else{ //多字节符的非首字节,应为 10xxxxxx if ((chr & 0xC0) != 0x80){ return false; } //减到为零为止 nBytes--; } } //违返UTF8编码规则 if (nBytes != 0) { return false; } if (bAllAscii){ //如果全部都是ASCII, 也是UTF8 return true; } return true; } unsigned int seprocess(LPVOID septr) { CZJACS* rtxpPara = NULL; rtxpPara = (CZJACS*)septr; rtxpPara->strCallback.iotprotocols = rtxpPara; rtxpPara->strCallback.rtuno = rtxpPara->iotpLink->GetRtuNo(); rtxpPara->restfulServer(); } unsigned int rxprocess(LPVOID rxptr) { CZJACS* rtxpPara = NULL; rtxpPara = (CZJACS*)rxptr; sint32 rtuno = rtxpPara->iotpLink->GetRtuNo(); while (rtxpPara->rxflag) { if (rtxpPara->subscribeflag == true || rtxpPara->subscribeflag2 == true) { if (rtxpPara->subscribeflag == true) { rtxpPara->PostSubscribe(1024); } if (rtxpPara->subscribeflag2 == true) { rtxpPara->PostSubscribe(255); } } SeSleep(500); } return 0; } unsigned int txprocess(LPVOID txptr) { CZJACS* rtxpPara = NULL; rtxpPara = (CZJACS*)txptr; sint32 rtuno = rtxpPara->iotpLink->GetRtuNo(); while (rtxpPara->txflag) { S_RAWCMD rawcmd; while (rtxpPara->iotpCmdMem->GetCmdNum(rtuno) > 0) { if (rtxpPara->iotpCmdMem->GetACmd(rtuno, &rawcmd) == 0) break; rtxpPara->PrintLog(LOG_INFORMATION, "收到%d号终端控制命令", rtuno); uint8 len = 0; ST_TRACK_ADDR m_cmdaddr; //处理外部命令,通过此变量保存外部命令地址信息 m_cmdaddr = rawcmd.src; switch (rawcmd.type) { case DC_K_CMD_DOOPER: //遥控 { S_DO_CTL *cmdinfo; cmdinfo = (S_DO_CTL *)(&rawcmd.data); uint16 ykno = (uint16)cmdinfo->ptAddr;//遥控号 int i; switch (cmdinfo->funcCode) { case DC_K_CTL_DOSEL://选择 //直接返校 rawcmd.type = DC_K_CMDRET_DOOPER; rawcmd.len = sizeof(cmdinfo); rawcmd.src = m_cmdaddr; cmdinfo->retCode = 1; rtxpPara->iotpCmdMem->RptAResult(rtuno, rawcmd); break; case DC_K_CTL_DOEXE://执行 { uint16 ykvalue; ykvalue = cmdinfo->ctlVal; if (ykno == 1 && ykvalue == 1) //远程开门 { rtxpPara->RemoteOpened(); } } break; case DC_K_CTL_DODEL://撤消 break; } } break; case DC_K_CMD_AOOPER: break; default: //对其它的下发命令不处理 break; } rtxpPara->iotpCmdMem->DelACmd(rtuno); } SeSleep(500); } return 0; } CZJACS::CZJACS() { rxflag = false; txflag = false; } CZJACS::~CZJACS() { if (rxflag == true) { rxflag = false; SeSleep(10); SE_EndThread(rxthread); } if (txflag == true) { txflag = false; SeSleep(10); SE_EndThread(txthread); } if (seflag == true) { seflag = false; SeSleep(10); SE_EndThread(sethread); } if (subid_Verification != -1) { string id; id = std::to_string(subid_Verification); DeleteSubscribe(id); } if (subid_Alarm != -1) { string id; id = std::to_string(subid_Alarm); DeleteSubscribe(id); } } void CZJACS::Init(S_PROTOCOLCFG* pcfg) { PRawCtrl = pcfg->PRawCtrl; pCmdMem = pcfg->pCmdMem; pRtu = pcfg->pRtu; pLink = pcfg->pLink; iotPRawCtrl = pcfg->PRawCtrl; iotpRxBuf = pcfg->pRxBuf; iotpTxBuf = pcfg->pTxBuf; iotpCmdMem = pcfg->pCmdMem; iotpRtu = pcfg->pRtu; iotpLink = pcfg->pLink; rxflag = true; txflag = true; seflag = true; subscribeflag = false; subscribeflag2 = false; subid_Alarm = -1; subid_Verification = -1; PrintLog(LOG_INFORMATION, "启动INIT !"); ReadIni(); PrintLog(LOG_INFORMATION, "启动readini完成 !"); if (rxflag) { rxthread = SE_CreateThread((PTHREAD_FUNC_DEF)rxprocess, this, 100); } PrintLog(LOG_INFORMATION, "启动rx线程 !"); if (txflag) { txthread = SE_CreateThread((PTHREAD_FUNC_DEF)txprocess, this, 100); } PrintLog(LOG_INFORMATION, "启动tx线程 !"); if (seflag) { sethread = SE_CreateThread((PTHREAD_FUNC_DEF)seprocess, this, 100); } PrintLog(LOG_INFORMATION, "启动服务端线程 !"); //开启restful服务,接受并处理推送消息 // strCallback.iotprotocols = this; // strCallback.rtuno = iotpLink->GetRtuNo(); // restfulServer(); } void CZJACS::restfulServer() { //restful服务的部分 std::string port; port = std::to_string(client_port); RestfulServer restServer; int ret = 1; while (ret == 1) { PrintLog(LOG_INFORMATION, "建立restful服务端。。。"); restServer.Start(port, &strCallback); restServer.Close(); PrintLog(LOG_ERROR, "restful服务端退出。。。"); SeSleep(5000); } } //创建订阅 int CZJACS::PostSubscribe(int type) { int status = 0; sint32 rtuno = iotpLink->GetRtuNo(); char tmp_header[128] = { 0 }; sprintf(tmp_header, "Content-Type:application/json\r\n"); string startmic_header = tmp_header; string urls = server_urls + "/LAPI/V1.0/System/Event/Subscription"; string body; string callback; Json::Value bodysender; bodysender["AddressType"] = 0; bodysender["IPAddress"] = client_ip; bodysender["Port"] = client_port; #ifdef WIN32 long long a = 4294967295; bodysender["Duration"] = a; #else bodysender["Duration"] = 4294967295; #endif bodysender["Type"] = type; if (type == 1024) { bodysender["SubscribePersonCondition"]["LibIDNum"] = 65535; bodysender["SubscribePersonCondition"]["LibIDList"][0]; } Json::FastWriter bodywrite; body = bodywrite.write(bodysender); status = Fclient::Sendreq(urls, startmic_header, body, callback, 1); if (callback.size() <= 0) { if (type == 1024){ PrintLog(LOG_ERROR, "创建人员核验订阅返回为空!"); } else{ PrintLog(LOG_ERROR, "创建门磁告警订阅返回为空!"); } return 0; } Json::Reader reader(Json::Features::strictMode()); Json::Value callback_result; if (reader.parse(callback, callback_result)) { string result = callback_result["Response"]["ResponseString"].asString(); string status = callback_result["Response"]["StatusString"].asString(); int flag = result.compare("Succeed"); if (!flag) { if (type == 1024) { subid_Verification = callback_result["Response"]["Data"]["ID"].asInt(); PrintLog(LOG_INFORMATION, "创建人员核验订阅成功!订阅id为 %d ", subid_Verification); subscribeflag = false; } else { int subid_Alarm = callback_result["Response"]["Data"]["ID"].asInt(); PrintLog(LOG_INFORMATION, "创建门磁告警订阅成功!订阅id为 %d ", subid_Alarm); subscribeflag2 = false; } } else { if (type == 1024) { PrintLog(LOG_ERROR, "创建人员核验订阅失败!返回错误:%s ", status.c_str()); } else { PrintLog(LOG_ERROR, "创建门磁告警订阅失败!返回错误:%s ", status.c_str()); } } } return 1; } //删除订阅 int CZJACS::DeleteSubscribe(string id) { int status = 0; sint32 rtuno = iotpLink->GetRtuNo(); char tmp_header[128] = { 0 }; sprintf(tmp_header, "Content-Type:application/json\r\n"); string stopmic_header = tmp_header; string urls = server_urls + "/LAPI/V1.0/System/Event/Subscription/" + id; string body; string callback; Json::Value bodysender; Json::FastWriter bodywrite; body = bodywrite.write(bodysender); status = Fclient::Sendreq(urls, stopmic_header, body, callback, 2); if (callback.size() <= 0) { PrintLog(LOG_ERROR, "删除订阅返回为空!"); return 0; } Json::Reader reader(Json::Features::strictMode()); Json::Value callback_result; if (reader.parse(callback, callback_result)) { string result = callback_result["Response"]["ResponseString"].asString(); string status = callback_result["Response"]["StatusString"].asString(); int flag = result.compare("Succeed"); if (!flag) { PrintLog(LOG_INFORMATION, "删除订阅成功!订阅id为 %d ", atoi(id.c_str())); } else { PrintLog(LOG_ERROR, "删除订阅失败!返回错误:%s ", status.c_str()); } } return 1; } //远程开门 int CZJACS::RemoteOpened() { int status = 0; sint32 rtuno = iotpLink->GetRtuNo(); char tmp_header[128] = { 0 }; sprintf(tmp_header, "Content-Type:application/json\r\n"); string start_header = tmp_header; string urls = server_urls + "/LAPI/V1.0/PACS/Controller/RemoteOpened"; string body; string callback; Json::Value bodysender; Json::FastWriter bodywrite; body = bodywrite.write(bodysender); status = Fclient::Sendreq(urls, start_header, body, callback, 3); if (callback.size() <= 0) { PrintLog(LOG_ERROR, "开门控制返回结果为空!"); return 0; } Json::Reader reader(Json::Features::strictMode()); Json::Value openresult; if (reader.parse(callback, openresult)) { string result = openresult["Response"]["ResponseString"].asString(); string status = openresult["Response"]["StatusString"].asString(); int flag = result.compare("Succeed"); if (!flag) { PrintLog(LOG_INFORMATION, "开门控制下控成功!"); } else { PrintLog(LOG_ERROR, "开门控制下控失败!返回错误:%s ", status.c_str()); } } return 1; } void CZJACS::ReadIni() { char filename[512]; CReadConf readconf; char* pWorkPath = getenv("SEROOT"); if (pWorkPath != NULL) sprintf(filename, "%s%s", pWorkPath, "/cfg/ZJ_ACS.ini"); int face_flag, door_flag; char urls_tmp[128]; char ip_tmp[128]; char port_tmp[128]; string head_tmp = "http://"; readconf.ReadString("LoginInfo", "server_urls", urls_tmp, filename, "192.168.2.65:80"); readconf.ReadString("LoginInfo", "client_ip", ip_tmp, filename, "192.168.2.45"); client_port=readconf.ReadLong("LoginInfo", "client_port", filename, "6666"); face_flag = readconf.ReadLong("LoginInfo", "face_flag", filename, "0"); door_flag = readconf.ReadLong("LoginInfo", "door_flag", filename, "0"); if (face_flag == 1) { subscribeflag = true; } if (door_flag == 1) { subscribeflag2 = true; } server_urls = head_tmp + urls_tmp; client_ip = ip_tmp; } sint32 CZJACS::TxProc() { return 1; } sint32 CZJACS::RxProc() { return 1; } #if defined(WIN32) extern "C" __declspec(dllexport) #else extern "C" #endif CProtocol *CreateProtocol(char *defpara) { return (CProtocol*)(new CZJACS()); } /* #ifdef __unix extern "C" CProtocol* CreateProtocol(char *defpara) #else extern "C" __declspec(dllexport) CProtocol* CreateProtocol(char *defpara) #endif { CProtocol *pEpv = new CZJACS; return pEpv; } */