LogicDevice.cpp 114 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652
  1. // LogicDevice.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include <cstring>
  4. #include <iostream>
  5. #include <chrono>
  6. #include <codecvt>
  7. #include "LogicDevice.h"
  8. #include <stddef.h> // 用于 offsetof
  9. #include "PacketAnalizer.h"
  10. #include "MessageInfo.h"
  11. #include "common_api.h"
  12. #include "LocalConfig.h"
  13. #include "Base64.h"
  14. #include "SystemLogger.hpp"
  15. #include "AsyncMsgHandler.h"
  16. #include "mqttclient.h"
  17. #include "LinuxEvent.h"
  18. #include "LogLocalHelper.h"
  19. #include "Log4CPP.h"
  20. //Log4CPP::Logger* gLogger = nullptr;
  21. void msgarrivd(void* client, message_data_t* message);
  22. std::string CurrentDateTime();
  23. //-------------Logic Device SysIF--------------------------
  24. LogicDeviceSysIF::LogicDeviceSysIF(void)
  25. {
  26. }
  27. LogicDeviceSysIF::~LogicDeviceSysIF(void)
  28. {
  29. }
  30. //init
  31. void LogicDeviceSysIF::SetLogicDevice(LogicDevice *p)
  32. {
  33. m_pLogicDev = p;
  34. //p->SetSysLogicDevice(this);
  35. };
  36. LogicDevice* LogicDeviceSysIF::GetLogicDevice()
  37. {
  38. return m_pLogicDev;
  39. }
  40. //Command In and Out
  41. //notify from lower layer
  42. RET_STATUS HW_ACTION LogicDeviceSysIF::CmdFromLogicDev(ResDataObject PARAM_IN *pCmd)
  43. {
  44. return RET_FAILED;
  45. };
  46. //notify to lower layer
  47. RET_STATUS SYSTEM_CALL LogicDeviceSysIF::CmdToLogicDev(ResDataObject PARAM_IN *pCmd)
  48. {
  49. if (m_pLogicDev)
  50. {
  51. return m_pLogicDev->CmdToLogicDev(pCmd);
  52. }
  53. return RET_NOSUPPORT;
  54. };
  55. const std::string SERVER_ADDRESS("127.0.0.1");
  56. /*
  57. string DEVICE_ID; //AS CLIENT_ID
  58. //const std::string CLIENT_ID("paho_cpp_async_subcribe");
  59. //const std::string TOPIC("hello");
  60. mqtt::async_client* m_pMqttClient = NULL; //MQTT 对象
  61. const int QOS = 1;
  62. const int N_RETRY_ATTEMPTS = 5;*/
  63. using namespace std;
  64. LogicDevice* g_pDPCDeviceObject = NULL;
  65. //string DEVICE_ID;
  66. //-------------Data Logic Device--------------------------
  67. LogicDevice::LogicDevice(void)
  68. {
  69. m_EvtNotify = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, false);
  70. uuid_t uuid;
  71. char uuid_str[37];
  72. uuid_generate_random(uuid);
  73. uuid_unparse(uuid, uuid_str);
  74. m_pDevInstance = new char[40];
  75. strncpy(m_pDevInstance, uuid_str, 40);
  76. m_pResErrorList = new ResDataObject();
  77. sem_init(&m_SemphRequest, 0, 0);
  78. sem_init(&m_SemphPublish, 0, 0);
  79. m_pDrvDPC = NULL;
  80. g_pDPCDeviceObject = this;
  81. m_pMqttConntion = nullptr;
  82. //m_strServer = "tcp://localhost:1883";
  83. m_strServer = SERVER_ADDRESS;// "192.168.2.225";
  84. m_strServerPort = "1883";
  85. m_bMqttUseSSL = false;
  86. m_strMqttUser = "";
  87. m_strMqttPassword = "";
  88. m_strEBusRoot = "";
  89. m_strCCOSDevicePath = "";
  90. m_pParent = nullptr;
  91. m_topicFilter = nullptr;
  92. m_pPacketReceivedQue = new MsgQueue<ResDataObject>();
  93. m_pPacketSendingQue = new MsgQueue<ResDataObject>();
  94. int x = 0;
  95. for ( x = 0; x < sizeof(szPad); x++)
  96. szPad[x] = 'A' + x % 26;
  97. szPad[x-1] = 0;
  98. memset(szPad2, 0, sizeof(szPad2));
  99. m_dwLastPacket = GetTickCount();
  100. string strLogPath = GetProcessDirectory() + R"(/Conf/log_config.xml)";
  101. string LogHost = (string)getRootpath();
  102. std::string moduleName = "LogicDevice";
  103. bool ret = initLogModule(
  104. LogHost, // 主机名(用于日志路径中的{host}占位符)
  105. moduleName, // 唯一模块名
  106. strLogPath, // 配置文件路径
  107. true // 是否输出到控制台(可选)
  108. );
  109. if (!ret) {
  110. std::cerr << "Log init failed!" << std::endl;
  111. }
  112. LogicDevice_SetLocalModuleName(moduleName);
  113. }
  114. LogicDevice::~LogicDevice(void)
  115. {
  116. delete []m_pDevInstance;
  117. delete m_pResErrorList;
  118. sem_destroy(&m_SemphRequest);
  119. sem_destroy(&m_SemphPublish);
  120. //m_EvtNotify = NULL;
  121. delete m_pPacketReceivedQue;
  122. delete m_pPacketSendingQue;
  123. }
  124. void LogicDevice::SetClientRootID(const char* pszEBusRoot, const char* pszCCOSRoot) {
  125. if (m_strClientID.length() > 0)
  126. {
  127. FINFO("Aready set RootID EBUS: [{$}] CCOS : [{$}] result m_strClientID [{$}]", pszEBusRoot, pszCCOSRoot, m_strClientID);
  128. return;
  129. }
  130. FINFO("Set RootID EBUS: [{$}] CCOS : [{$}]", pszEBusRoot, pszCCOSRoot);
  131. if (pszEBusRoot[0] == '/') {
  132. m_strEBusRoot = pszEBusRoot + 1;
  133. }
  134. else {
  135. m_strEBusRoot = pszEBusRoot;
  136. }
  137. char szKeys[256];
  138. strcpy(szKeys, pszEBusRoot);
  139. char* pt = szKeys;
  140. while (*pt != 0)
  141. {
  142. if (*pt == '/' || *pt == '{' || *pt == '}'|| *pt == '-')
  143. *pt = '_';
  144. pt++;
  145. }
  146. m_strClientID = CCOS_CLIENT_ID_PREFIX;
  147. if (szKeys[0] == '_')
  148. m_strClientID += (szKeys + 1);
  149. else
  150. m_strClientID += szKeys;
  151. if (pszCCOSRoot != nullptr)
  152. {
  153. std::cout << "LogicDevice::SetClientRootID [ Set CCOS path is" << pszCCOSRoot << "]" << std::endl;
  154. FINFO("Set CCOS path: {$}", pszCCOSRoot);
  155. m_strCCOSDevicePath = pszCCOSRoot;
  156. int nPos = m_strCCOSDevicePath.find('/');
  157. if (nPos != string::npos)
  158. {
  159. //CCOS/
  160. nPos = m_strCCOSDevicePath.find('/', nPos + 1);
  161. //CCOS/DEVICE/
  162. if (nPos != string::npos)
  163. {
  164. m_strCCOSRoot = m_strCCOSDevicePath.substr(0, nPos);
  165. //CCOS/DEVICE/Generator
  166. nPos = m_strCCOSDevicePath.find('/', nPos + 1);
  167. if (nPos != string::npos)
  168. {
  169. m_strAbstractPath = m_strCCOSDevicePath.substr(0, nPos);
  170. }
  171. }
  172. }
  173. FINFO("Set CCOS path: CCOSROOT {$} AbstractPath {$} ", m_strCCOSRoot, m_strAbstractPath);
  174. }
  175. FINFO("Set MQTT ClientName {$} @CCOSRoot {$}", m_strClientID, m_strCCOSDevicePath);
  176. SetName(m_strClientID.c_str());
  177. OnSetClientID();
  178. }
  179. void LogicDevice::OnSetClientID() {
  180. }
  181. void LogicDevice::SubscribeSelf() {
  182. if (m_strDevicePath.length() > 0 && m_strDevicePath[0] != '/') {
  183. m_strDevicePath = "/" + m_strDevicePath;
  184. }
  185. FINFO("{$} try Subscribe {$} use conn {$} ", m_strClientID, m_strEBusRoot, (UINT64)m_pMqttConntion);
  186. std::cout << "----***** " << m_strClientID << " [" << m_strEBusRoot << "] use conn " << (UINT64)m_pMqttConntion << endl;
  187. if (m_strEBusRoot.length() > 0) {
  188. SubscribeTopic(m_pMqttConntion, (m_strEBusRoot).c_str());
  189. }
  190. if (m_strCCOSDevicePath.length() > 0)
  191. {
  192. FINFO("CCOSDevice [{$}] ", m_strCCOSDevicePath + m_strDevicePath);
  193. SubscribeTopic(m_pMqttConntion, (m_strCCOSDevicePath + m_strDevicePath).c_str());
  194. //订阅
  195. }
  196. FINFO("AbstractPath [{$}] ", m_strAbstractPath);
  197. if (m_strAbstractPath.length() > 0)
  198. {
  199. SubscribeTopic(m_pMqttConntion, (m_strAbstractPath).c_str());
  200. if (m_strDevicePath.length() > 0)
  201. SubscribeTopic(m_pMqttConntion, (m_strAbstractPath + m_strDevicePath).c_str());
  202. }
  203. FINFO("CCOSRoot [{$}] ", m_strCCOSRoot);
  204. if (m_strCCOSRoot.length() > 0)
  205. {
  206. SubscribeTopic(m_pMqttConntion, (m_strCCOSRoot).c_str());
  207. //订阅
  208. }
  209. // 等待初始订阅完成(EBusRoot、CCOSDevice、Abstract等)
  210. FINFO("{$} Waiting for initial subscriptions to complete...", m_strClientID);
  211. const DWORD initialSubTimeoutMs = 5000;
  212. if (!WaitForSubscriptionComplete(m_pMqttConntion, initialSubTimeoutMs)) {
  213. FERROR("{$} Some initial subscriptions did not complete within timeout", m_strClientID);
  214. }
  215. // SUBACK收到后,等待Broker完成路由表更新
  216. // 延时可通过环境变量MQTT_BROKER_ROUTING_DELAY_MS配置,默认200ms
  217. WaitForBrokerRouting(m_strClientID.c_str());
  218. // 订阅Actions(内部也会等待SUBACK + Broker延时)
  219. SubscribeActions();
  220. }
  221. void LogicDevice::SubScribeTopic(const char* pszTopic, bool bSubscribe)
  222. {
  223. cout << "SubScribeTopic IN" << endl;
  224. if (bSubscribe)
  225. SubscribeTopic(m_pMqttConntion, pszTopic);
  226. else
  227. UnSubscribe(m_pMqttConntion, pszTopic);
  228. }
  229. void LogicDevice::NotifyDrvThread()
  230. {
  231. m_EvtNotify->SetEvent();
  232. }
  233. std::shared_ptr<LinuxEvent> LogicDevice::GetEvtHandle()
  234. {
  235. return m_EvtNotify;
  236. }
  237. //1. init part
  238. //void LogicDevice::SetSysLogicDevice(LogicDeviceSysIF *pLogic)
  239. //{
  240. // m_pSysLogic = pLogic;
  241. //}
  242. //void LogicDevice::SetLogHandle(Logger PARAM_IN *pLogger)
  243. //{
  244. // m_pLogger = pLogger;
  245. //}
  246. //
  247. //Logger *LogicDevice::GetLogHandle()
  248. //{
  249. // return m_pLogger;
  250. //}
  251. void LogicDevice::SetDrvDPC(DriverDPC *pDPC)
  252. {
  253. m_pDrvDPC = pDPC;
  254. }
  255. DriverDPC *LogicDevice::GetDrvDPC()
  256. {
  257. return m_pDrvDPC;
  258. }
  259. RET_STATUS LogicDevice::AddEbusChildren(LogicDevice* pChild, const char* szEbusDevPath)
  260. {
  261. if (szEbusDevPath == nullptr)
  262. return RET_FAILED;
  263. for (auto dev : m_subDevices) {
  264. if (dev->GetRootPath() == szEbusDevPath)
  265. return RET_SUCCEED;
  266. }
  267. m_subDevices.push_back(pChild);
  268. return RET_SUCCEED;
  269. }
  270. RET_STATUS LogicDevice::AddCcosChildren(LogicDevice* pChild, const char* szCcosDevPath)
  271. {
  272. if (szCcosDevPath == nullptr)
  273. return RET_FAILED;
  274. for (auto dev : m_subCcosDevices) {
  275. if (dev->GetCcosRootPath() == szCcosDevPath)
  276. return RET_SUCCEED;
  277. }
  278. m_subCcosDevices.push_back(pChild);
  279. return RET_SUCCEED;
  280. }
  281. LogicDevice* LogicDevice::GetEbusChild(const char* szEbusDevPath)
  282. {
  283. for (auto dev : m_subDevices) {
  284. if (dev->GetRootPath() == szEbusDevPath)
  285. return dev;
  286. }
  287. return nullptr;
  288. }
  289. LogicDevice* LogicDevice::GetCcosChild(const char* szCcosDevPath)
  290. {
  291. for (auto dev : m_subCcosDevices) {
  292. if (dev->GetCcosRootPath() == szCcosDevPath)
  293. return dev;
  294. }
  295. return nullptr;
  296. }
  297. void SYSTEM_CALL LogicDevice::CompleteInit()
  298. {
  299. FINFO("\n===============log begin : version:1.0.0.0 ===================\n");
  300. FINFO("{$}Connect MQTT Server {$}:{$}", m_strServer, m_strServerPort, m_strClientID);
  301. if (m_strClientID.length() <= 0)
  302. {
  303. FWARN("No Client name ......" );
  304. std::cout << "No Client name ......." << endl;
  305. return;
  306. }
  307. std::cout << "CompleteInit->NewConnection ......." << endl;
  308. m_pMqttConntion = NewConnection(m_strServer.c_str(), m_strServerPort.c_str(), m_strMqttUser.c_str(), m_strMqttPassword.c_str(), m_strClientID.c_str(),
  309. [this](ResDataObject* req, const char* topic, void* conn) {
  310. //这里只处理当前层次设备的请求,下一层的直接靠URI来路由
  311. //首先根据topic判断是请求我的,还是我请求的,请求我的topic 是 以 ROOT开头的URI
  312. // 发送给我的,如果需要应答,则需要调用Request返回Resp,否则直接调用,不返回应答
  313. // 消息处理如果耗时较长,则需要开线程来处理
  314. if (strncmp(topic, m_strEBusRoot.c_str(), m_strEBusRoot.length()) == 0 ||
  315. strncmp(topic, m_strCCOSDevicePath.c_str(), m_strCCOSDevicePath.length()) == 0)
  316. {
  317. //主题以ebus或者ccos开头,给我发的消息,进行处理
  318. ProcessSubscribeRequest(req);
  319. }
  320. else
  321. {
  322. //我主动订阅的外部模块的消息
  323. ProcessSubscribeMsg(req);
  324. }
  325. //CmdToLogicDev(req);
  326. });
  327. if (m_pMqttConntion != nullptr)
  328. {
  329. // 使用异步启动避免阻塞:Sync=false表示不等待线程启动完成
  330. // 如果Sync=true,会等待300秒直到线程设置m_RunFlag,可能导致启动卡顿
  331. StartThread(false); //启动Request线程(异步)
  332. SubscribeSelf();
  333. //DWORD dwThreadID = 0;
  334. //CreateThread(0, 0, Thread_Publish_Thread, this, 0, &dwThreadID);
  335. //FINFO("[{$}] Publish Thread id [{$}]", m_strClientID, dwThreadID);
  336. }
  337. }
  338. RET_STATUS LogicDevice::ProcessSubscribeRequest(ResDataObject* req) {
  339. PACKET_TYPE type = PacketAnalizer::GetPacketType(req);
  340. PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(req);
  341. switch (type) {
  342. case PACKET_TYPE_REQ:
  343. PacketAnalizer::GetPacketTransaction(req, m_strCurTransaction);
  344. ProcessRequest(req, cmd);//请求
  345. break;
  346. case PACKET_TYPE_RES:
  347. ProcessResponse(req, cmd);//应答
  348. break;
  349. case PACKET_TYPE_NOTIFY:
  350. ProcessNotify(req, cmd);
  351. //通知
  352. break;
  353. }
  354. return RET_FAILED;
  355. }
  356. RET_STATUS LogicDevice::ProcessSubscribeMsg(ResDataObject* pCmd)
  357. {
  358. ProcessSubscribeRequest(pCmd);
  359. return RET_SUCCEED;
  360. }
  361. RET_STATUS LogicDevice::ProcessRequest(ResDataObject* pCmd, PACKET_CMD cmd)
  362. {
  363. //Open命令
  364. if (cmd == PACKET_CMD_OPEN) {
  365. /* {
  366. "IDX": "40",
  367. "TYPE" : "0",
  368. "CMD" : "0",
  369. "HANDLE" :
  370. {
  371. "ROUTE": "1",
  372. "FLAGS" : "63",
  373. "LANG" : "en-US",
  374. "HANDLEID" : "0",
  375. "OWNERID" :
  376. {
  377. "EBUSID": "ImageSave",
  378. "MACHINEID" : "DESKTOP-FVD53H8",
  379. "PROCID" : "35408",
  380. "ADDR" : "2631366957696"
  381. },
  382. "DEVID":
  383. {
  384. "EBUSID": "ccosChannel",
  385. "MACHINEID" : "",
  386. "PROCID" : "0",
  387. "ADDR" : "0"
  388. }
  389. },
  390. "KEY": "\/ccosChannel"
  391. ResDataObject resRes, resResponse;
  392. ResDataObject resTopic;
  393. PacketAnalizer::GetContextTopic(pCmd, resTopic);
  394. if (cmd == PACKET_CMD_OPEN )
  395. {
  396. //std::cout << "publis " << (const char*)resTopic << "msg body" << resResponse.encode() << endl;
  397. PublishAction(&resResponse, (const char*)resTopic, m_pMqttConntion);
  398. return RET_SUCCEED;
  399. }
  400. if (cmd == PACKET_CMD_CLOSE)
  401. {
  402. //CLOSE 客户端主动断开
  403. }
  404. } */
  405. PacketArrived(pCmd);
  406. return RET_SUCCEED;
  407. }
  408. else if (cmd == PACKET_CMD_CLOSE)
  409. {
  410. ResDataObject resp;
  411. InnerOpenClose(*pCmd, resp, false);
  412. }
  413. else {
  414. PacketArrived(pCmd);
  415. }
  416. return RET_SUCCEED;
  417. }
  418. RET_STATUS LogicDevice::ProcessResponse(ResDataObject* pCmd, PACKET_CMD cmd)
  419. {
  420. return RET_SUCCEED;
  421. }
  422. RET_STATUS LogicDevice::ProcessNotify(ResDataObject* pCmd, PACKET_CMD cmd)
  423. {
  424. PacketArrived(pCmd);
  425. return RET_SUCCEED;
  426. }
  427. void LogicDevice::PacketArrived(ResDataObject* pRequest)
  428. {
  429. //m_pPacketReceivedQue->Lock();
  430. FINFO("PacketArrived msg [id: {$} ]: cmd {$} key: [{$}]", m_strClientID, (int)PacketAnalizer::GetPacketCmd(pRequest), PacketAnalizer::GetPacketKey(pRequest));
  431. //if (Thread_Lock(5000) != WAIT_OBJECT_0)
  432. //{
  433. // FERROR("PacketArrived Lock Timeout for msg [id: {$} ]: cmd {$} key: ", m_strClientID, (int)PacketAnalizer::GetPacketCmd(pRequest), PacketAnalizer::GetPacketKey(pRequest));
  434. // //GPRINTA_ERROR("OpenDev Lock Timeout for Dev[flag:%d]:%s", flags, pPath);
  435. // return ;
  436. //}
  437. m_pPacketReceivedQue->InQueue(*pRequest);
  438. FINFO("PacketArrived msg INTO QUEUE [id: {$} ]: cmd {$} key: [{$}]", m_strClientID, (int)PacketAnalizer::GetPacketCmd(pRequest), PacketAnalizer::GetPacketKey(pRequest));
  439. //SetEvent(m_EvtNotify);//notify to user
  440. long nLast = 0;
  441. int released = sem_post(&m_SemphRequest); // 释放信号量,通知等待的线程
  442. if (released <= 0)
  443. {
  444. FERROR("PacketArrived: sem_post failed, error code: {$}, description: {$}",
  445. errno, strerror(errno));
  446. }
  447. }
  448. bool LogicDevice::OnStartThread()
  449. {
  450. return true;
  451. }
  452. bool LogicDevice::OnEndThread()
  453. {
  454. return true;
  455. }
  456. //单一发送线程,暂时未用
  457. DWORD LogicDevice::Thread_Publish_Thread(void* pPara)
  458. {
  459. INT ret = 0;
  460. int waitevent = 0;
  461. LogicDevice* handle = (LogicDevice*)pPara;
  462. //prev work usleep(30000);
  463. FINFO("Thread Start [{$}]", handle->m_strClientID);
  464. while (!handle->m_ExitFlag->Wait(1))
  465. {
  466. //do work
  467. ResDataObject resSend;
  468. DWORD wait = handle->m_pPacketSendingQue->WaitForInQue(100);
  469. if (wait != WAIT_OBJECT_0)
  470. continue;
  471. bool bHasPacket = handle->m_pPacketSendingQue->DeQueue(resSend);
  472. if (bHasPacket)
  473. {
  474. PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&resSend);
  475. PACKET_TYPE type = PacketAnalizer::GetPacketType(&resSend);
  476. FINFO(" [{$}] Publish key [{$}] type [{$}] cmd [{$}] ", handle->m_strClientID, PacketAnalizer::GetPacketKey(&resSend), (int)type, (int)cmd);
  477. if (PACKET_CMD_NONE == cmd)
  478. {
  479. FDEBUG(" [{$}] Publish what packet {$} ", handle->m_strClientID, resSend.encode());
  480. }
  481. if (type == PACKET_TYPE_NOTIFY)
  482. {
  483. CcosDevFileHandle* pHandle = new CcosDevFileHandle;
  484. PacketAnalizer::UpdateNotifyHandle(resSend, *pHandle);
  485. FINFO("Notify Transaction: {$}", handle->m_strCurTransaction);
  486. PacketAnalizer::UpdatePacketTransaction(resSend, handle->m_strCurTransaction);
  487. PacketAnalizer::UpdateDeviceNotifyResponse(resSend, getLocalMachineId(), getLocalEbusId(), (UINT64)pthread_self(), (UINT64)handle->m_pMqttConntion);
  488. FDEBUG("Notify: {$}", resSend.encode());
  489. //printf("--> %s \n", pCmd->encode());
  490. PublishAction(&resSend, (handle->m_strEBusRoot + "/Notify").c_str(), handle->m_pMqttConntion);
  491. PublishAction(&resSend, (handle->m_strCCOSRoot + "/Notify/" + PacketAnalizer::GetPacketKey(&resSend)).c_str(), handle->m_pMqttConntion);
  492. delete pHandle;
  493. }
  494. else
  495. {
  496. ResDataObject resTopic;
  497. PacketAnalizer::GetPacketTopic(&resSend, resTopic);
  498. //PacketAnalizer::GetPacketTopicGetPacketTopic
  499. //PacketAnalizer::UpdatePacketTopic(&resResponse, resTopic);
  500. FINFO(" [{$}] Publish [{$}] type [{$}] cmd [{$}] to [{$}]", handle->m_strClientID, PacketAnalizer::GetPacketKey(&resSend), (int)type, (int)cmd, (const char*)resTopic);
  501. PublishAction(&resSend, (const char*)resTopic, handle->m_pMqttConntion);
  502. }
  503. }
  504. }
  505. return 0;
  506. }
  507. RET_STATUS LogicDevice::DevOpen(const char* pszDevUri, const char* pszGroup, ResDataObject& resRespons)
  508. {
  509. cout << "LogicDevice::DevOpen - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  510. << ", pszGroup: " << (pszGroup ? pszGroup : "nullptr") << endl;
  511. ResDataObject req, reqParam;
  512. reqParam = pszGroup;
  513. cout << "LogicDevice::DevOpen - Creating OPEN request. Command: PACKET_CMD_OPEN" << endl;
  514. PacketAnalizer::MakeRequest(req, pszDevUri, PACKET_CMD_OPEN, &reqParam);
  515. RET_STATUS ret = InnerOpenClose(req, resRespons, true);
  516. cout << "LogicDevice::DevOpen - InnerOpenClose returned: " << ret << endl;
  517. return ret;
  518. }
  519. RET_STATUS LogicDevice::DevClose(const char* pszDevUri, const char* pszGroup, ResDataObject& resRespons)
  520. {
  521. cout << "LogicDevice::DevClose - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  522. << ", pszGroup: " << (pszGroup ? pszGroup : "nullptr") << endl;
  523. ResDataObject req, reqParam;
  524. reqParam = pszGroup;
  525. cout << "LogicDevice::DevClose - Creating CLOSE request. Command: PACKET_CMD_CLOSE" << endl;
  526. PacketAnalizer::MakeRequest(req, pszDevUri, PACKET_CMD_CLOSE, &reqParam);
  527. RET_STATUS ret = InnerOpenClose(req, resRespons, false);
  528. cout << "LogicDevice::DevClose - InnerOpenClose returned: " << ret << endl;
  529. return ret;
  530. }
  531. /// <summary>
  532. /// Get device property
  533. /// </summary>
  534. RET_STATUS LogicDevice::DevGet(const char* pszDevUri, const char* pszProperty, ResDataObject& resRespons)
  535. {
  536. cout << "LogicDevice::DevGet - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  537. << ", pszProperty: " << (pszProperty ? pszProperty : "nullptr") << endl;
  538. ResDataObject req, reqParam;
  539. cout << "LogicDevice::DevGet - Creating GET request. Command: PACKET_CMD_GET, Property: " << (pszProperty ? pszProperty : "nullptr") << endl;
  540. PacketAnalizer::MakeRequest(req, pszProperty, PACKET_CMD_GET, &reqParam);
  541. RET_STATUS ret = Request(&req, &resRespons);
  542. cout << "LogicDevice::DevGet - Request returned: " << ret << endl;
  543. return ret;
  544. }
  545. /// <summary>
  546. /// Set device property
  547. /// </summary>
  548. RET_STATUS LogicDevice::DevSet(const char* pszDevUri, const char* pszProperty, const char* pszValueSet, ResDataObject& resRespons)
  549. {
  550. cout << "LogicDevice::DevSet - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  551. << ", pszProperty: " << (pszProperty ? pszProperty : "nullptr")
  552. << ", pszValueSet: " << (pszValueSet ? pszValueSet : "nullptr") << endl;
  553. ResDataObject req, reqParam;
  554. if (pszValueSet != nullptr && pszValueSet[0] != 0) {
  555. if (pszValueSet[0] == '{') {
  556. cout << "LogicDevice::DevSet - Decoding JSON value for property" << endl;
  557. reqParam.decode(pszValueSet);
  558. }
  559. else {
  560. cout << "LogicDevice::DevSet - Using raw value for property" << endl;
  561. reqParam = pszValueSet;
  562. }
  563. }
  564. else {
  565. cout << "LogicDevice::DevSet - No value provided for property" << endl;
  566. }
  567. cout << "LogicDevice::DevSet - Creating SET request. Command: PACKET_CMD_SET, Property: " << (pszProperty ? pszProperty : "nullptr") << endl;
  568. PacketAnalizer::MakeRequest(req, pszProperty, PACKET_CMD_SET, &reqParam);
  569. RET_STATUS ret = Request(&req, &resRespons);
  570. cout << "LogicDevice::DevSet - Request returned: " << ret << endl;
  571. return ret;
  572. }
  573. /// <summary>
  574. /// Update device property
  575. /// </summary>
  576. RET_STATUS LogicDevice::DevUpdate(const char* pszDevUri, const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons)
  577. {
  578. cout << "LogicDevice::DevUpdate - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  579. << ", pszProperty: " << (pszProperty ? pszProperty : "nullptr")
  580. << ", pszValueUpdate: " << (pszValueUpdate ? pszValueUpdate : "nullptr") << endl;
  581. ResDataObject req, reqParam;
  582. if (pszValueUpdate != nullptr && pszValueUpdate[0] != 0) {
  583. if (pszValueUpdate[0] == '{') {
  584. cout << "LogicDevice::DevUpdate - Decoding JSON value for update" << endl;
  585. reqParam.decode(pszValueUpdate);
  586. }
  587. else {
  588. cout << "LogicDevice::DevUpdate - Using raw value for update" << endl;
  589. reqParam = pszValueUpdate;
  590. }
  591. }
  592. else {
  593. cout << "LogicDevice::DevUpdate - No update value provided" << endl;
  594. }
  595. cout << "LogicDevice::DevUpdate - Creating UPDATE request. Command: PACKET_CMD_UPDATE, Property: " << (pszProperty ? pszProperty : "nullptr") << endl;
  596. PacketAnalizer::MakeRequest(req, pszProperty, PACKET_CMD_UPDATE, &reqParam);
  597. RET_STATUS ret = Request(&req, &resRespons);
  598. cout << "LogicDevice::DevUpdate - Request returned: " << ret << endl;
  599. return ret;
  600. }
  601. /// <summary>
  602. /// Add device property
  603. /// </summary>
  604. RET_STATUS LogicDevice::DevAdd(const char* pszDevUri, const char* pszProperty, const char* pszValueAdd, ResDataObject& resRespons)
  605. {
  606. cout << "LogicDevice::DevAdd - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  607. << ", pszProperty: " << (pszProperty ? pszProperty : "nullptr")
  608. << ", pszValueAdd: " << (pszValueAdd ? pszValueAdd : "nullptr") << endl;
  609. ResDataObject req, reqParam;
  610. if (pszValueAdd != nullptr && pszValueAdd[0] != 0) {
  611. if (pszValueAdd[0] == '{') {
  612. cout << "LogicDevice::DevAdd - Decoding JSON value for addition" << endl;
  613. reqParam.decode(pszValueAdd);
  614. }
  615. else {
  616. cout << "LogicDevice::DevAdd - Using raw value for addition" << endl;
  617. reqParam = pszValueAdd;
  618. }
  619. }
  620. else {
  621. cout << "LogicDevice::DevAdd - No value provided for addition" << endl;
  622. }
  623. cout << "LogicDevice::DevAdd - Creating ADD request. Command: PACKET_CMD_ADD, Property: " << (pszProperty ? pszProperty : "nullptr") << endl;
  624. PacketAnalizer::MakeRequest(req, pszProperty, PACKET_CMD_ADD, &reqParam);
  625. RET_STATUS ret = Request(&req, &resRespons);
  626. cout << "LogicDevice::DevAdd - Request returned: " << ret << endl;
  627. return ret;
  628. }
  629. /// <summary>
  630. /// Delete device property
  631. /// </summary>
  632. RET_STATUS LogicDevice::DevDel(const char* pszDevUri, const char* pszProperty, const char* pszValueDel, ResDataObject& resRespons)
  633. {
  634. cout << "LogicDevice::DevDel - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  635. << ", pszProperty: " << (pszProperty ? pszProperty : "nullptr")
  636. << ", pszValueDel: " << (pszValueDel ? pszValueDel : "nullptr") << endl;
  637. ResDataObject req, reqParam;
  638. if (pszValueDel != nullptr && pszValueDel[0] != 0) {
  639. if (pszValueDel[0] == '{') {
  640. cout << "LogicDevice::DevDel - Decoding JSON value for deletion" << endl;
  641. reqParam.decode(pszValueDel);
  642. }
  643. else {
  644. cout << "LogicDevice::DevDel - Using raw value for deletion" << endl;
  645. reqParam = pszValueDel;
  646. }
  647. }
  648. else {
  649. cout << "LogicDevice::DevDel - No value provided for deletion" << endl;
  650. }
  651. cout << "LogicDevice::DevDel - Creating DEL request. Command: PACKET_CMD_DEL, Property: " << (pszProperty ? pszProperty : "nullptr") << endl;
  652. PacketAnalizer::MakeRequest(req, pszProperty, PACKET_CMD_DEL, &reqParam);
  653. RET_STATUS ret = Request(&req, &resRespons);
  654. cout << "LogicDevice::DevDel - Request returned: " << ret << endl;
  655. return ret;
  656. }
  657. /// <summary>
  658. /// Execute device action
  659. /// </summary>
  660. RET_STATUS LogicDevice::DevAction(const char* pszDevUri, const char* pszActionName, const char* pszParams, ResDataObject& resRespons)
  661. {
  662. cout << "LogicDevice::DevAction - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  663. << ", pszActionName: " << (pszActionName ? pszActionName : "nullptr")
  664. << ", pszParams: " << (pszParams ? pszParams : "nullptr") << endl;
  665. ResDataObject req, reqParam;
  666. if (pszParams != nullptr && pszParams[0] != 0) {
  667. if (pszParams[0] == '{') {
  668. cout << "LogicDevice::DevAction - Decoding JSON parameters for action" << endl;
  669. reqParam.decode(pszParams);
  670. }
  671. else {
  672. cout << "LogicDevice::DevAction - Using raw parameters for action" << endl;
  673. reqParam = pszParams;
  674. }
  675. }
  676. else {
  677. cout << "LogicDevice::DevAction - No parameters provided for action" << endl;
  678. }
  679. cout << "LogicDevice::DevAction - Creating EXE request. Command: PACKET_CMD_EXE, Action: " << (pszActionName ? pszActionName : "nullptr") << endl;
  680. PacketAnalizer::MakeRequest(req, pszActionName, PACKET_CMD_EXE, &reqParam);
  681. ResDataObject resResult;
  682. RET_STATUS ret = Request(&req, &resResult);
  683. cout << "LogicDevice::DevAction - Request returned: " << ret << endl;
  684. PacketAnalizer::GetPacketContext(&resResult, resRespons);
  685. cout << "LogicDevice::DevAction - Extracted packet context to response" << endl;
  686. return ret;
  687. }
  688. /// <summary>
  689. /// Send message to device
  690. /// </summary>
  691. RET_STATUS LogicDevice::DevMessage(const char* pszDevUri, const char* pszTopic, const char* pszMessageValue, ResDataObject& resRespons)
  692. {
  693. cout << "LogicDevice::DevMessage - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  694. << ", pszTopic: " << (pszTopic ? pszTopic : "nullptr")
  695. << ", pszMessageValue: " << (pszMessageValue ? pszMessageValue : "nullptr") << endl;
  696. ResDataObject req, reqParam;
  697. if (pszMessageValue != nullptr && pszMessageValue[0] != 0) {
  698. if (pszMessageValue[0] == '{') {
  699. cout << "LogicDevice::DevMessage - Decoding JSON message value" << endl;
  700. reqParam.decode(pszMessageValue);
  701. }
  702. else {
  703. cout << "LogicDevice::DevMessage - Using raw message value" << endl;
  704. reqParam = pszMessageValue;
  705. }
  706. }
  707. else {
  708. cout << "LogicDevice::DevMessage - No message value provided" << endl;
  709. }
  710. cout << "LogicDevice::DevMessage - Creating MSG request. Command: PACKET_CMD_MSG, Topic: " << (pszTopic ? pszTopic : "nullptr") << endl;
  711. PacketAnalizer::MakeRequest(req, pszTopic, PACKET_CMD_MSG, &reqParam);
  712. RET_STATUS ret = Request(&req, &resRespons);
  713. cout << "LogicDevice::DevMessage - Request returned: " << ret << endl;
  714. return ret;
  715. }
  716. RET_STATUS LogicDevice::InnerOpenClose(ResDataObject& req, ResDataObject& resp, bool openOrClose)
  717. {
  718. if (openOrClose)
  719. {
  720. ResDataObject resContext;
  721. GetDeviceResource(&resp);
  722. LogicDevice::GetDeviceResource(&resp);
  723. PacketAnalizer::GetPacketTransaction(&req, m_strCurTransaction);
  724. if (PacketAnalizer::GetPacketContext(&req, resContext))
  725. {
  726. //如果有上线参数
  727. if (resContext.GetFirstOf("Online") >= 0)
  728. {
  729. FINFO("Got Online Request {$}", resContext.encode());
  730. int idx = resContext.GetFirstOf("Online");
  731. //如果有上线参数
  732. if (idx >= 0)
  733. {
  734. do
  735. {
  736. string wsName = resContext[idx].encode();
  737. FINFO("SubscribeGroupActions [{$}] ", wsName);
  738. SubscribeGroupActions(wsName, true);
  739. idx = resContext.GetNextOf("Online", idx);
  740. } while (idx >= 0);
  741. }
  742. resp.update("Online", m_rsOnlineGroup);
  743. }
  744. }
  745. }
  746. else
  747. {
  748. ResDataObject context;
  749. if (PacketAnalizer::GetPacketContext(&req, context))
  750. {
  751. int idx = context.GetFirstOf("Offline");
  752. //如果有上线参数
  753. if (idx >= 0)
  754. {
  755. do
  756. {
  757. string wsName = context[idx].encode();
  758. SubscribeGroupActions(wsName, false);
  759. idx = context.GetNextOf("Offline", idx);
  760. } while (idx >= 0);
  761. }
  762. resp.update("Online", m_rsOnlineGroup);
  763. }
  764. }
  765. return RET_SUCCEED;
  766. }
  767. bool LogicDevice::Exec(void)
  768. {
  769. struct timespec ts;
  770. clock_gettime(CLOCK_REALTIME, &ts);
  771. ts.tv_sec += 3;
  772. // 等待退出信号(3秒超时)
  773. DWORD dwRet = 0;
  774. dwRet = m_ExitFlag->Wait(3);
  775. if (dwRet == WAIT_OBJECT_0)
  776. {
  777. return false;
  778. }
  779. // 等待请求信号(3秒超时)
  780. int ret = sem_timedwait(&m_SemphRequest, &ts);
  781. if (ret == 0) {
  782. FDEBUG("[{$}] Got Packet Event ", m_strClientID);
  783. ResDataObject req;
  784. bool got = true;
  785. do {
  786. got = m_pPacketReceivedQue->DeQueue(req);
  787. if (got) {
  788. m_dwLastPacket = GetTickCount();
  789. PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&req);
  790. std::string keystr = PacketAnalizer::GetPacketKey(&req);
  791. FINFO(" {$} Got Request key {$} transaction {$}",
  792. m_strClientID, keystr, m_strCurTransaction);
  793. if (cmd == PACKET_CMD_OPEN) {
  794. ResDataObject resRes, resResponse;
  795. InnerOpenClose(req, resRes, true);
  796. PacketAnalizer::MakeOpenResponse(req, resResponse, resRes);
  797. resResponse.update("Online", m_rsOnlineGroup);
  798. PacketAnalizer::UpdatePacketTransaction(resResponse, m_strCurTransaction);
  799. ResDataObject resTopic;
  800. PacketAnalizer::GetContextTopic(&req, resTopic);
  801. PacketAnalizer::UpdatePacketTopic(&resResponse, resTopic, m_strClientID.c_str());
  802. if (keystr.substr(0, 4) == "CCOS") {
  803. PacketAnalizer::UpdatePacketKey(&resResponse, m_strCCOSDevicePath.c_str());
  804. }
  805. else {
  806. PacketAnalizer::UpdateDeviceNotifyResponse(resResponse,
  807. getLocalMachineId(),
  808. getLocalEbusId(),
  809. (uint64_t)getpid(),
  810. (uint64_t)m_pMqttConntion);
  811. }
  812. PublishAction(&resResponse, (const char*)resTopic, m_pMqttConntion);
  813. // 发送连接状态通知
  814. ResDataObject NotifyData;
  815. PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE,
  816. "ConnectionStatus", "1");
  817. PacketAnalizer::UpdatePacketTransaction(NotifyData, m_strCurTransaction);
  818. CmdFromLogicDev(&NotifyData);
  819. }
  820. else {
  821. PacketAnalizer::GetPacketTransaction(&req, m_strCurTransaction);
  822. ResDataObject resPacket;
  823. RET_STATUS retStatus = RET_FAILED;
  824. if (cmd == PACKET_CMD_EXE && keystr == "UpdateDeviceResource") {
  825. ResDataObject devRes;
  826. if ((retStatus = GetDeviceResource(&devRes)) == RET_SUCCEED) {
  827. LogicDevice::GetDeviceResource(&devRes);
  828. PacketAnalizer::UpdatePacketContext(resPacket, devRes);
  829. }
  830. }
  831. else {
  832. retStatus = Request(&req, &resPacket);
  833. }
  834. PacketAnalizer::MakeRetCode(retStatus, &resPacket);
  835. PacketAnalizer::CloneTransaction(&req, &resPacket);
  836. ResDataObject resTopic;
  837. PacketAnalizer::GetContextTopic(&req, resTopic);
  838. PacketAnalizer::UpdatePacketTopic(&resPacket, resTopic, m_strClientID.c_str());
  839. PublishAction(&resPacket, (const char*)resTopic, m_pMqttConntion);
  840. }
  841. }
  842. } while (got);
  843. // 检查心跳(10分钟无数据发送心跳)
  844. if (GetTickCount() - m_dwLastPacket > 600000) {
  845. m_dwLastPacket = GetTickCount();
  846. ResDataObject heartBeat;
  847. PacketAnalizer::MakeNotify(heartBeat, PACKET_CMD_ONLINE,
  848. "HeartBeat", m_strClientID.c_str());
  849. PublishAction(&heartBeat, "CCOS/DEVICE/HeartBeat", m_pMqttConntion);
  850. }
  851. return true;
  852. }
  853. // 检查心跳(即使没有请求)
  854. if (GetTickCount() - m_dwLastPacket > 600000) {
  855. m_dwLastPacket = GetTickCount();
  856. ResDataObject heartBeat;
  857. PacketAnalizer::MakeNotify(heartBeat, PACKET_CMD_ONLINE,
  858. "HeartBeat", m_strClientID.c_str());
  859. PublishAction(&heartBeat, "CCOS/DEVICE/HeartBeat", m_pMqttConntion);
  860. }
  861. return true;
  862. }
  863. void SYSTEM_CALL LogicDevice::CompleteUnInit()
  864. {
  865. StopThread();
  866. }
  867. int LogicDevice::GetDevice_Thread_Priority()
  868. {
  869. return THREAD_PRIORITY_NONE;
  870. }
  871. RET_STATUS LogicDevice::GetDeviceResource(ResDataObject PARAM_OUT *pDeviceResource)
  872. {
  873. //pDeviceResource->update("ClientType", DPC_UnitClient);
  874. GUID guid;
  875. string name;
  876. GetDeviceType(guid);
  877. guid_2_string(guid, name);
  878. pDeviceResource->update("DeviceType", name.c_str());
  879. //Get Unit Type (Unit GUID)
  880. if (pDeviceResource->GetFirstOf("LogicDevInstance")<0)
  881. {
  882. pDeviceResource->add("LogicDevInstance", m_pDevInstance);
  883. }
  884. ////
  885. size_t idx = (*pDeviceResource)["Attribute"].size();
  886. if (idx > 0)
  887. {
  888. int erroridx = (*pDeviceResource)["Attribute"].GetFirstOf("ErrorList");
  889. if (erroridx < 0)
  890. {
  891. (*pDeviceResource)["Attribute"].add("ErrorList", *m_pResErrorList);
  892. }
  893. else
  894. {
  895. (*pDeviceResource)["Attribute"]["ErrorList"] = *m_pResErrorList;
  896. }
  897. }
  898. else
  899. {
  900. ResDataObject Attribute;
  901. Attribute.add("ErrorList", *m_pResErrorList);
  902. pDeviceResource->add("Attribute", Attribute);
  903. }
  904. // (*pDeviceResource)["Action"].size();
  905. if (pDeviceResource->GetFirstOf("Action") < 0)
  906. {
  907. pDeviceResource->add("Action", m_Actions);
  908. }
  909. return RET_SUCCEED;
  910. }
  911. //notify from lower layer
  912. RET_STATUS LogicDevice::CmdFromLogicDev(ResDataObject *pCmd)
  913. {
  914. PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(pCmd);
  915. PACKET_TYPE type = PacketAnalizer::GetPacketType(pCmd);
  916. if (type == PACKET_TYPE_NOTIFY)
  917. {
  918. CcosDevFileHandle* pHandle = new CcosDevFileHandle;
  919. PacketAnalizer::UpdateNotifyHandle(*pCmd, *pHandle);
  920. FDEBUG("Notify Transaction: {$}", m_strCurTransaction);
  921. PacketAnalizer::UpdatePacketTransaction(*pCmd, m_strCurTransaction);
  922. ;
  923. //if (m_strEBusRoot.length() <= 0)
  924. //{
  925. // //FWARN("EBusRoot is null");
  926. //}
  927. PacketAnalizer::UpdateDeviceNotifyResponse(
  928. *pCmd,
  929. getLocalMachineId(),
  930. getLocalEbusId(),
  931. static_cast<uint64_t>(getpid()), // Linux 上获取进程 ID
  932. reinterpret_cast<uint64_t>(m_pMqttConntion) // 假设 m_pMqttConntion 在 Linux 上是指针类型
  933. );
  934. FDEBUG("[{$}] Notify: {$}", m_strClientID, pCmd->encode());
  935. //printf("--> %s \n", pCmd->encode());
  936. PacketAnalizer::UpdatePacketTopic(pCmd, (m_strEBusRoot + "/Notify").c_str(), m_strClientID.c_str());
  937. PublishAction(pCmd, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
  938. string strNotifyPath = "/Notify/" + PacketAnalizer::GetPacketKey(pCmd);
  939. PacketAnalizer::UpdatePacketTopic(pCmd, (m_strCCOSRoot + strNotifyPath).c_str(), m_strClientID.c_str());
  940. PublishAction(pCmd, (m_strCCOSDevicePath + strNotifyPath).c_str(), m_pMqttConntion);
  941. if (m_strAbstractPath.length() > 0)
  942. {
  943. PublishAction(pCmd, (m_strAbstractPath + strNotifyPath).c_str(), m_pMqttConntion);
  944. string realPath,devPath;
  945. devPath = m_strAbstractPath.substr(((string)"CCOS/DEVICE").length());
  946. for (int x = 0; x < m_rsOnlineGroup.size(); x++)
  947. {
  948. if ((int)m_rsOnlineGroup[x] == 1)
  949. {
  950. realPath = "CCOS/" +(string)m_rsOnlineGroup.GetKey(x) + devPath + strNotifyPath;
  951. PublishAction(pCmd, realPath.c_str(), m_pMqttConntion);
  952. }
  953. }
  954. } //m_pPacketSendingQue->InQueue(*pCmd);
  955. delete pHandle;
  956. }
  957. return RET_SUCCEED;
  958. /*
  959. if (pCmd && m_pSysLogic)
  960. {
  961. return m_pSysLogic->CmdFromLogicDev(pCmd);
  962. }
  963. //put log here
  964. return RET_FAILED;*/
  965. }
  966. std::wstring mb2wc_a(const char* mbstr) {
  967. if (!mbstr) return L"";
  968. try {
  969. // 使用C++11的codecvt进行UTF-8到wstring的转换
  970. std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
  971. return converter.from_bytes(mbstr);
  972. }
  973. catch (...) {
  974. // 如果转换失败,返回空宽字符串
  975. return L"";
  976. }
  977. }
  978. RET_STATUS HW_ACTION LogicDevice::AddErrorMessageUnicode(const char* DevInstance, const char* Code, int &Level, const wchar_t* ResInfo, const wchar_t* Description, int nMessageType)
  979. {
  980. string ResBase64, DesBase64;
  981. wstring wResUTF = ResInfo;
  982. wstring wDesUTF = Description;
  983. CBase64::Encode((const unsigned char *)wResUTF.c_str(), (unsigned long)wResUTF.size() * sizeof(wchar_t), ResBase64);
  984. CBase64::Encode((const unsigned char *)wDesUTF.c_str(), (unsigned long)wDesUTF.size() * sizeof(wchar_t), DesBase64);
  985. return AddErrorMessage(DevInstance, Code, Level, ResBase64.c_str(), DesBase64.c_str(), nMessageType);
  986. }
  987. RET_STATUS HW_ACTION LogicDevice::AddErrorMessage(const char* DevInstance, const char* Code, int &Level, const char* ResInfo, const char* Description, int nMessageType, const char* pAppId)
  988. {
  989. string ResBase64,DesBase64;
  990. cout << "ResInfo:" << ResInfo << endl;
  991. wstring wResUTF = mb2wc_a(ResInfo);
  992. wstring wDesUTF = mb2wc_a(Description);
  993. const unsigned char* resData = reinterpret_cast<const unsigned char*>(wResUTF.c_str());
  994. unsigned long resDataLen = wResUTF.size() * sizeof(wchar_t);
  995. const unsigned char* desData = reinterpret_cast<const unsigned char*>(wDesUTF.c_str());
  996. unsigned long desDataLen = wDesUTF.size() * sizeof(wchar_t);
  997. // 进行Base64编码
  998. CBase64::Encode(resData, resDataLen, ResBase64);
  999. CBase64::Encode(desData, desDataLen, DesBase64);
  1000. cout << "ResBase64:" << ResBase64 << endl;
  1001. return AddErrorMessageBase(DevInstance, Code, Level, ResInfo, Description, nMessageType, pAppId);
  1002. }
  1003. RET_STATUS LogicDevice::AddErrorMessageBase(const char* DevInstance, const char* Code, int &Level, const char* ResInfo, const char* Description, int nMessageType, const char* pAppId)
  1004. {
  1005. //int ret = 1;
  1006. if (Code == 0 || (string)ResInfo == "")
  1007. {
  1008. FERROR("Code or ResInfo is empty");
  1009. return RET_FAILED;
  1010. }
  1011. MessageInfo info;
  1012. info.CodeID = Code;
  1013. info.Type = nMessageType;
  1014. info.Level = Level;
  1015. info.Resouceinfo = ResInfo;
  1016. info.Description = Description;
  1017. string strDevInstanceCode = DevInstance;
  1018. strDevInstanceCode += Code;
  1019. for (size_t i = 0; i < m_pResErrorList->size(); i++)
  1020. {
  1021. string strInstancekey = m_pResErrorList->GetKey(i);
  1022. if (strInstancekey == strDevInstanceCode)
  1023. {
  1024. //for (size_t j = 0; j < (*m_pResErrorList)[DevInstance].size(); j++)
  1025. //{
  1026. // string strCodekey = (*m_pResErrorList)[DevInstance].GetKey(j);
  1027. // string strtype = (*m_pResErrorList)[DevInstance][strCodekey.c_str()]["Type"];
  1028. // if (strCodekey == (string)Code && atoi(strtype.c_str()) == nMessageType)
  1029. // {
  1030. //ret = 0;
  1031. FWARN("Same Code:%s with MessageType:%d already Exist", Code,nMessageType);
  1032. return RET_SUCCEED;
  1033. // }
  1034. //}
  1035. //ret = 2;
  1036. //break;
  1037. }
  1038. }
  1039. //if (ret==1)
  1040. {
  1041. ResDataObject NotifyData, ResNotify, ErrorInfo/*, tempInfo*/;
  1042. //info.GetResDataObject(tempInfo);
  1043. //ErrorInfo.update(Code, tempInfo);
  1044. info.GetResDataObject(ErrorInfo);
  1045. struct timeval tv;
  1046. struct tm* tm_info;
  1047. char TimeTag[30];
  1048. // 获取当前时间
  1049. gettimeofday(&tv, NULL);
  1050. // 转换为本地时间
  1051. tm_info = localtime(&tv.tv_sec);
  1052. // 格式化时间为字符串
  1053. snprintf(TimeTag, sizeof(TimeTag), "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
  1054. tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday,
  1055. tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec, tv.tv_usec / 1000);
  1056. ErrorInfo.add("CreationTime", TimeTag);
  1057. ErrorInfo.add("AppId", pAppId);
  1058. ErrorInfo.add("InstanceId", DevInstance);
  1059. if (nMessageType == ERRORTYPE)//只有错误会增加到错误列表中,警告通知上层即可
  1060. {
  1061. m_pResErrorList->update(strDevInstanceCode.c_str(), ErrorInfo);
  1062. }
  1063. ResNotify.update(strDevInstanceCode.c_str(), ErrorInfo);
  1064. PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_ADD, "ErrorList", ResNotify);
  1065. FWARN( "preposterror ErrorType:{$} {$}", nMessageType,NotifyData.encode());
  1066. CmdFromLogicDev(&NotifyData);
  1067. //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
  1068. }
  1069. //else if (ret == 2)
  1070. //{
  1071. // ResDataObject NotifyData, ResNotify, ErrorInfo, tempInfo;
  1072. // info.GetResDataObject(tempInfo);
  1073. // ErrorInfo.update(Code, tempInfo);
  1074. // if (nMessageType == ERRORTYPE)//只有错误会增加到错误列表中,警告通知上层即可
  1075. // {
  1076. // (*m_pResErrorList)[DevInstance].update(Code, tempInfo);
  1077. // }
  1078. // ResNotify.update(DevInstance, ErrorInfo);
  1079. // PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_ADD, "ErrorList", ResNotify);
  1080. // RES_FDEBUG(NotifyData, "preposterror RET:%d,ErrorType:%u", ret, nMessageType);
  1081. // CmdFromLogicDev(&NotifyData);
  1082. //}
  1083. //put log here
  1084. return RET_SUCCEED;
  1085. }
  1086. RET_STATUS LogicDevice::AddErrorMessage(const char* Code, int &Level, const char* ResInfo, int nMessageType, const char* pAppId)
  1087. {
  1088. AddErrorMessage(m_pDevInstance, Code, Level, ResInfo, "",nMessageType, pAppId);
  1089. //put log here
  1090. return RET_FAILED;
  1091. }
  1092. RET_STATUS LogicDevice::DelErrorMessage(const char* DevInstance, const char* Code, int &Level, const char* ResInfo, const char* Description, int nMessageType)
  1093. {
  1094. int index = -1;
  1095. bool m_bClearAll = false;
  1096. //trim empty code string
  1097. string CodeStr = Code;
  1098. if (CodeStr.size() == 0 || CodeStr == "0" || CodeStr == "")
  1099. {
  1100. CodeStr = "";
  1101. Code = CodeStr.c_str();
  1102. m_bClearAll = true;
  1103. }
  1104. //if ((string)Code == "0" || (string)Code == "")
  1105. //{
  1106. // m_bClearAll = true;
  1107. //}
  1108. string strDevInstanceCode = DevInstance;
  1109. strDevInstanceCode += Code;
  1110. if (m_bClearAll)
  1111. {
  1112. m_pResErrorList->clear();
  1113. }
  1114. else
  1115. {
  1116. MessageInfo info;
  1117. info.CodeID = Code;
  1118. info.Type = nMessageType;
  1119. info.Level = Level;
  1120. info.Resouceinfo = ResInfo;
  1121. info.Description = Description;
  1122. for (size_t i = 0; i < m_pResErrorList->size(); i++)
  1123. {
  1124. string strInstancekey = m_pResErrorList->GetKey(i);
  1125. if (strInstancekey == strDevInstanceCode)
  1126. {
  1127. //for (size_t j = 0; j < (*m_pResErrorList)[DevInstance].size(); j++)
  1128. //{
  1129. // string strCodekey = (*m_pResErrorList)[DevInstance].GetKey(j);
  1130. // string strtype = (*m_pResErrorList)[DevInstance][strCodekey.c_str()]["Type"];
  1131. // if (strCodekey == (string)Code && atoi(strtype.c_str()) == nMessageType)
  1132. // {
  1133. // index = (INT)j;
  1134. // break;
  1135. // }
  1136. //}
  1137. index = (int)i;
  1138. break;
  1139. }
  1140. }
  1141. }
  1142. MessageInfo info;
  1143. info.CodeID = Code;
  1144. info.Type = nMessageType;
  1145. info.Level = Level;
  1146. info.Resouceinfo = ResInfo;
  1147. info.Description = Description;
  1148. ResDataObject NotifyData, ResNotify, ErrorInfo/*, tempInfo*/;
  1149. //info.GetResDataObject(tempInfo);
  1150. //ErrorInfo.add(Code, tempInfo);
  1151. info.GetResDataObject(ErrorInfo);
  1152. ErrorInfo.add("InstanceId", DevInstance);
  1153. bool result = false;
  1154. if (index>=0)
  1155. {
  1156. //result = (*m_pResErrorList)[DevInstance].eraseOneOf(Code, index);
  1157. result = (*m_pResErrorList).eraseAllOf(strDevInstanceCode.c_str());
  1158. }
  1159. if (index >= 0 || m_bClearAll || nMessageType == WARNTYPE)
  1160. {
  1161. ResNotify.add(strDevInstanceCode.c_str(), ErrorInfo);
  1162. PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_DEL, "ErrorList", ResNotify);
  1163. FWARN( "pre Del error ErrorCode:{$} {$}", Code ,NotifyData.encode());
  1164. CmdFromLogicDev(&NotifyData);
  1165. //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
  1166. }
  1167. return RET_SUCCEED;
  1168. }
  1169. RET_STATUS LogicDevice::DelErrorMessage(const char* Code, int &Level, const char* ResInfo, int nMessageType)
  1170. {
  1171. DelErrorMessage(m_pDevInstance, Code, Level, ResInfo, "", nMessageType);
  1172. //put log here
  1173. return RET_FAILED;
  1174. }
  1175. RET_STATUS LogicDevice::EvtProcedure()
  1176. {
  1177. return RET_FAILED;
  1178. }
  1179. bool LogicDevice::CheckFeatureLicense(const char *pszFeatureId)
  1180. {
  1181. FERROR("NOT FINISHED YET");
  1182. return false;
  1183. }
  1184. RET_STATUS LogicDevice::IoSystemLog(int Level, const char* pCode, const char* pContext, size_t ContextSize, const char* pAppId)
  1185. {
  1186. std::string strResult = "";
  1187. //组Context包
  1188. //if (m_pLogger)
  1189. {
  1190. wstring wContect = mb2wc_a(pContext);
  1191. CBase64::Encode((const unsigned char*)wContect.c_str(), (unsigned long)wContect.size() * sizeof(wchar_t), strResult);
  1192. }
  1193. //Thread_Lock();
  1194. //if (NULL != fmt)
  1195. //{
  1196. // va_list marker = NULL;
  1197. // va_start(marker, fmt);
  1198. // size_t nLength = _vscprintf(fmt, marker) + 1;
  1199. // std::vector<char> vBuffer(nLength, '\0');
  1200. // int nWritten = vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker);
  1201. // if (nWritten > 0)
  1202. // {
  1203. // strResult = &vBuffer[0];
  1204. // }
  1205. // va_end(marker);
  1206. //}
  1207. //Thread_UnLock();
  1208. ResDataObject SysLogNode;
  1209. string guidstr;
  1210. GUID DeviceGuid;
  1211. //组Log包
  1212. if (GetDeviceType(DeviceGuid))
  1213. {
  1214. guid_2_string(DeviceGuid, guidstr);
  1215. SysLogNode.add("Module", guidstr.c_str());
  1216. SysLogNode.add("AppId", pAppId);
  1217. SysLogNode.add("ThreadId", GetCurrentThreadId());
  1218. if (pCode)
  1219. {
  1220. SysLogNode.add("BusinessKey", pCode);
  1221. }
  1222. else
  1223. {
  1224. SysLogNode.add("BusinessKey", "");
  1225. }
  1226. SysLogNode.add("IP", (const char*)getLocalIpAddress());
  1227. struct timeval tv;
  1228. struct tm* tm_info;
  1229. char TimeTag[30];
  1230. // 获取当前时间
  1231. gettimeofday(&tv, NULL);
  1232. // 转换为本地时间
  1233. tm_info = localtime(&tv.tv_sec);
  1234. // 格式化时间为字符串
  1235. snprintf(TimeTag, sizeof(TimeTag), "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
  1236. tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday,
  1237. tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec, tv.tv_usec / 1000);
  1238. SysLogNode.add("CreationTime", TimeTag);
  1239. string strLevel = SysLogLevel2str(Level);
  1240. SysLogNode.add("Level", strLevel.c_str());
  1241. SysLogNode.add("HostName", (const char*)getLocalMachineId());
  1242. SysLogNode.add("ProcessName", (const char*)GetModuleTitle());
  1243. SysLogNode.add("FreeText", strResult.c_str());
  1244. SysLogNode.add("Context", pCode);
  1245. ResDataObject NotifyData;
  1246. PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_MSG, "Syslog", SysLogNode);
  1247. CmdFromLogicDev(&NotifyData);
  1248. //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
  1249. }
  1250. else
  1251. {
  1252. FWARN("no Guid??");
  1253. return RET_FAILED;
  1254. }
  1255. //打印LOG
  1256. switch (Level)
  1257. {
  1258. case Syslog_Debug:
  1259. //RES_PRINTA_DEBUG(m_pLogger, SysLogNode, "SysLog");
  1260. FDEBUG("SysLog {$} ", SysLogNode.encode());
  1261. break;
  1262. case Syslog_Information:
  1263. ///RES_PRINTA_INFO(m_pLogger, SysLogNode, "SysLog");
  1264. FINFO("SysLog {$} ", SysLogNode.encode());
  1265. break;
  1266. case Syslog_Warning:
  1267. //RES_PRINTA_WARN(m_pLogger, SysLogNode, "SysLog");
  1268. FWARN("SysLog {$} ", SysLogNode.encode());
  1269. break;
  1270. case Syslog_Error:
  1271. //RES_PRINTA_ERROR(m_pLogger, SysLogNode, "SysLog");
  1272. FERROR("SysLog {$} ", SysLogNode.encode());
  1273. break;
  1274. case Syslog_Fatal:
  1275. //RES_PRINTA_FATAL(m_pLogger, SysLogNode, "SysLog");
  1276. FINFO("SysLog {$} ", SysLogNode.encode());
  1277. break;
  1278. default:
  1279. FINFO("SysLog {$} " ,SysLogNode.encode() );
  1280. break;
  1281. }
  1282. return RET_SUCCEED;
  1283. }
  1284. RET_STATUS LogicDevice::SystemLog(SYSLOGLEVEL Level,const char *pCode, const char* fmt, ...)
  1285. {
  1286. std::string strResult = "";
  1287. //组Context包
  1288. //if (m_pLogger)
  1289. //{
  1290. // m_pLogger->Thread_Lock();
  1291. // if (NULL != fmt)
  1292. // {
  1293. // va_list marker = NULL;
  1294. // va_start(marker, fmt);
  1295. // size_t nLength = _vscprintf(fmt, marker) + 1;
  1296. // std::vector<char> vBuffer(nLength, '\0');
  1297. // int nWritten = vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker);
  1298. // if (nWritten > 0)
  1299. // {
  1300. // strResult = &vBuffer[0];
  1301. // }
  1302. // va_end(marker);
  1303. // }
  1304. // m_pLogger->Thread_UnLock();
  1305. //}
  1306. //else
  1307. {
  1308. Thread_Lock();
  1309. if (fmt != NULL) {
  1310. va_list marker;
  1311. va_start(marker, fmt);
  1312. // 获取格式化字符串所需的大小(不包括终止符)
  1313. int nLength = vsnprintf(NULL, 0, fmt, marker);
  1314. if (nLength >= 0) {
  1315. std::vector<char> vBuffer(nLength + 1, '\0'); // +1 为终止符
  1316. vsnprintf(&vBuffer[0], vBuffer.size(), fmt, marker);
  1317. strResult = &vBuffer[0]; // 将缓冲区内容赋值给结果字符串
  1318. }
  1319. va_end(marker);
  1320. }
  1321. Thread_UnLock();
  1322. }
  1323. ResDataObject SysLogNode;
  1324. string guidstr;
  1325. GUID DeviceGuid;
  1326. //组Log包
  1327. if (GetDeviceType(DeviceGuid))
  1328. {
  1329. guid_2_string(DeviceGuid, guidstr);
  1330. SysLogNode.add("Module", guidstr.c_str());
  1331. SysLogNode.add("AppId", "");
  1332. SysLogNode.add("ThreadId", GetCurrentThreadId());
  1333. if (pCode)
  1334. {
  1335. SysLogNode.add("BusinessKey", pCode);
  1336. }
  1337. else
  1338. {
  1339. SysLogNode.add("BusinessKey", "");
  1340. }
  1341. SysLogNode.add("IP", (const char *)getLocalIpAddress());
  1342. struct timeval tv;
  1343. struct tm* tm_info;
  1344. char TimeTag[30];
  1345. // 获取当前时间
  1346. gettimeofday(&tv, NULL);
  1347. // 转换为本地时间
  1348. tm_info = localtime(&tv.tv_sec);
  1349. // 格式化时间为字符串
  1350. snprintf(TimeTag, sizeof(TimeTag), "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
  1351. tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday,
  1352. tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec, tv.tv_usec / 1000);
  1353. SysLogNode.add("CreationTime", TimeTag);
  1354. SysLogNode.add("Level", Level);
  1355. SysLogNode.add("HostName", (const char *)getLocalMachineId());
  1356. SysLogNode.add("ProcessName", (const char *)GetModuleTitle());
  1357. SysLogNode.add("FreeText", strResult.c_str());
  1358. ResDataObject NotifyData;
  1359. PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_MSG, "Syslog", SysLogNode);
  1360. CmdFromLogicDev(&NotifyData);
  1361. //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
  1362. if(m_pParent != nullptr)
  1363. NotifyParent(&NotifyData, "/Notify");
  1364. }
  1365. else
  1366. {
  1367. FERROR("no Guid??");
  1368. return RET_FAILED;
  1369. }
  1370. //打印LOG
  1371. switch (Level)
  1372. {
  1373. case Syslog_Debug:
  1374. //RES_PRINTA_DEBUG(m_pLogger, SysLogNode, "SysLog");
  1375. FDEBUG("SysLog {$}", SysLogNode.encode());
  1376. break;
  1377. case Syslog_Information:
  1378. //RES_PRINTA_INFO(m_pLogger, SysLogNode, "SysLog");
  1379. FINFO("SysLog {$}", SysLogNode.encode());
  1380. break;
  1381. case Syslog_Warning:
  1382. //RES_PRINTA_WARN(m_pLogger, SysLogNode, "SysLog");
  1383. FWARN("SysLog {$}", SysLogNode.encode());
  1384. break;
  1385. case Syslog_Error:
  1386. //RES_PRINTA_ERROR(m_pLogger, SysLogNode, "SysLog");
  1387. FERROR("SysLog {$}", SysLogNode.encode());
  1388. break;
  1389. case Syslog_Fatal:
  1390. //RES_PRINTA_FATAL(m_pLogger, SysLogNode, "SysLog");
  1391. FINFO("SysLog {$}", SysLogNode.encode());
  1392. break;
  1393. default:
  1394. FINFO( "SysLog {$}", SysLogNode.encode());
  1395. break;
  1396. }
  1397. return RET_SUCCEED;
  1398. }
  1399. /////////////////////////////////////////////////////////////////////////////
  1400. ccos_mqtt_connection* LogicDevice::CreateConnection(const char* pszClientID, ccos_mqtt_callback onmsg)
  1401. {
  1402. return nullptr;
  1403. }
  1404. std::string CurrentDateTime()
  1405. {
  1406. auto now = std::chrono::system_clock::now();
  1407. auto now_us = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch());
  1408. auto now_time_t = std::chrono::system_clock::to_time_t(now);
  1409. std::tm now_tm{};
  1410. localtime_r(&now_time_t, &now_tm); // 线程安全版本
  1411. char buf[64];
  1412. std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &now_tm);
  1413. std::string now_time_str = buf;
  1414. // 格式化微秒部分并追加
  1415. snprintf(buf, sizeof(buf), ".%06lld", static_cast<long long>(now_us.count() % 1000000));
  1416. now_time_str += buf;
  1417. return now_time_str;
  1418. }
  1419. static string CurrentDateTime2()
  1420. {
  1421. std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
  1422. char buf[100] = { 0 };
  1423. std::strftime(buf, sizeof(buf), " %Y-%m-%d %H:%M:%S ", std::localtime(&now));
  1424. return buf;
  1425. }
  1426. bool LogicDevice::GetActions(ResDataObject& resAction)
  1427. {
  1428. for (int x = 0; x < m_Actions.size(); x++)
  1429. {
  1430. resAction.update(m_Actions.GetKey(x), "");
  1431. }
  1432. return true;
  1433. }
  1434. void LogicDevice::NotifyParent(ResDataObject* NotifyData, const char* pszTopic, ccos_mqtt_connection* hConnection)
  1435. {
  1436. if (m_pParent != nullptr)
  1437. {
  1438. if (hConnection == nullptr)
  1439. {
  1440. hConnection = m_pParent->m_pMqttConntion;
  1441. }
  1442. PublishAction(NotifyData, (m_pParent->GetRootPath() + pszTopic).c_str(), hConnection);
  1443. }
  1444. }
  1445. const mqtt_qos_t MQTT_QOS = QOS2;
  1446. /// <summary>
  1447. /// 工作位设备组 上线或者下线,设备路径为 CCOS/Table/Detector
  1448. /// CCOS/Demo/Detector
  1449. /// </summary>
  1450. /// <param name="bOnline"></param>
  1451. void LogicDevice::SubscribeGroupActions(string wsName, int bOnline)
  1452. {
  1453. if (m_rsOnlineGroup.GetFirstOf(wsName.c_str()) >= 0)
  1454. {
  1455. int lastOnline = (int)m_rsOnlineGroup[wsName.c_str()];
  1456. if (bOnline == lastOnline)
  1457. {
  1458. FWARN("Group Abstract is already ? Online {$}", bOnline);
  1459. return;
  1460. }
  1461. }
  1462. if ( m_strAbstractPath.length() > 0)
  1463. {
  1464. std::string pszAction, gpPath;
  1465. int ret = 0;
  1466. int num = m_Actions.size();
  1467. FINFO("Group Device onLine or offLine {$}", bOnline);
  1468. gpPath = m_strAbstractPath;
  1469. gpPath.replace(0, string("CCOS/DEVICE").length(), "CCOS/" + wsName);
  1470. pszAction = gpPath + m_strDevicePath;
  1471. pszAction += "/Action/+";
  1472. SubScribeTopic(pszAction.c_str(), bOnline == 1);
  1473. if (bOnline)
  1474. {
  1475. FINFO("{$} Subscribe Device Group Action {$} ", m_strClientID, pszAction);
  1476. }
  1477. else
  1478. {
  1479. FINFO("{$} UnSubscribe Device Group Action {$} ", m_strClientID, pszAction);
  1480. }
  1481. //for (size_t i = 0; i < num; i++)
  1482. //{
  1483. // pszAction = gpPath + m_strDevicePath;
  1484. // pszAction += "/Action/";
  1485. // pszAction += (m_Actions.GetKey(i));
  1486. // SubScribeTopic(pszAction.c_str(), bOnline == 1);
  1487. // if (bOnline)
  1488. // {
  1489. // FINFO("{$} Subscribe Device Group Action {$} ", m_strClientID, pszAction);
  1490. // }
  1491. // else
  1492. // {
  1493. // FINFO("{$} UnSubscribe Device Group Action {$} ", m_strClientID, pszAction);
  1494. // }
  1495. //}
  1496. m_rsOnlineGroup.update(wsName.c_str(), bOnline);
  1497. }
  1498. else
  1499. {
  1500. FWARN("try Online but AbstractPath is none {$}", m_strClientID);
  1501. }
  1502. }
  1503. void SubscribeModule(ccos_mqtt_connection* pconn, string devuribBase)
  1504. {
  1505. string pszAction = devuribBase;
  1506. pszAction += "/Get/+";
  1507. SubscribeTopic(pconn, pszAction.c_str());
  1508. pszAction = devuribBase;
  1509. pszAction += "/Update/+";
  1510. SubscribeTopic(pconn, pszAction.c_str());
  1511. pszAction = devuribBase;
  1512. pszAction += "/Set/+";
  1513. SubscribeTopic(pconn, pszAction.c_str());
  1514. pszAction = devuribBase;
  1515. pszAction += "/Add/+";
  1516. SubscribeTopic(pconn, pszAction.c_str());
  1517. pszAction = devuribBase;
  1518. pszAction += "/Del/+";
  1519. SubscribeTopic(pconn, pszAction.c_str());
  1520. pszAction = devuribBase;
  1521. pszAction += "/Action/+";
  1522. SubscribeTopic(pconn, pszAction.c_str());
  1523. pszAction = devuribBase;
  1524. pszAction += "/Message/+";
  1525. SubscribeTopic(pconn, pszAction.c_str());
  1526. }
  1527. void LogicDevice::SubscribeActions()
  1528. {
  1529. FINFO("Begain");
  1530. if (nullptr == m_pMqttConntion)
  1531. return;
  1532. int num = m_Actions.size();
  1533. mqtt_client* pMqttClient = (mqtt_client*)std::get<MQTT_CLT_ID>(*m_pMqttConntion);
  1534. mqtt_topic_list* pTopicList = std::get<MQTT_TIPIC_LIST_ID>(*m_pMqttConntion);
  1535. {
  1536. ResDataObject res,resAction;
  1537. GetDeviceResource(&res);
  1538. std::cout << "LogicDevice::SubscribeActions GetDeviceResource" << res.encode() << endl;
  1539. resAction = res["Action"];
  1540. FINFO("Actions from deviceresource [{$}]", resAction.size());
  1541. for (int x = 0; x < resAction.size(); x++)
  1542. {
  1543. string action = (string)resAction.GetKey(x);
  1544. if (action.length() > 0)
  1545. {
  1546. FINFO("Action from DeviceResource [{$}]", action);
  1547. m_Actions.update(action.c_str(), "");
  1548. }
  1549. }
  1550. num = m_Actions.size();
  1551. }
  1552. std::string pszAction;
  1553. int ret = 0;
  1554. SubscribeModule(m_pMqttConntion, m_strEBusRoot.c_str());
  1555. FINFO("{$} Subscribe EBus Action {$} return {$} topic num {$}", m_strClientID, pszAction, ret, pTopicList->size());
  1556. if (m_strEBusRoot != m_strCCOSDevicePath)
  1557. {
  1558. pszAction = m_strCCOSDevicePath + m_strDevicePath;
  1559. SubscribeModule(m_pMqttConntion, pszAction.c_str());
  1560. FINFO("{$} Subscribe CCOS Action {$} return {$} topic num {$}", m_strClientID, pszAction, ret, pTopicList->size());
  1561. }
  1562. if (m_strAbstractPath.length() > 0)
  1563. {
  1564. pszAction = m_strAbstractPath + m_strDevicePath;
  1565. SubscribeModule(m_pMqttConntion, pszAction.c_str());
  1566. FINFO("{$} Subscribe Abstract Action {$} return {$} topic num {$}", m_strClientID, pszAction, ret, pTopicList->size());
  1567. }
  1568. //for (size_t i = 0; i < num; i++)
  1569. //{
  1570. // //订阅ebus的路径
  1571. // pszAction = m_strEBusRoot;
  1572. // pszAction += "/Action/";
  1573. // pszAction += (m_Actions.GetKey(i));
  1574. // SubscribeTopic(m_pMqttConntion, pszAction.c_str());
  1575. // FINFO("{$} Subscribe Action {$} return {$} topic num {$}", m_strClientID, pszAction, ret, pTopicList->size());
  1576. //
  1577. // //订阅CCOS设备路径
  1578. // if (m_strEBusRoot != m_strCCOSDevicePath)
  1579. // {
  1580. // pszAction = m_strCCOSDevicePath + m_strDevicePath;
  1581. // pszAction += "/Action/";
  1582. // pszAction += (m_Actions.GetKey(i));
  1583. // SubscribeTopic(m_pMqttConntion, pszAction.c_str());
  1584. // FINFO("{$} Subscribe Action {$} return {$} topic num {$}", m_strClientID, pszAction, ret, pTopicList->size());
  1585. // }
  1586. // //抽象设备路径要一直存在
  1587. // //订阅抽象设备路径
  1588. // if ( m_strAbstractPath.length() > 0)
  1589. // {
  1590. // pszAction = m_strAbstractPath + m_strDevicePath;
  1591. // pszAction += "/Action/";
  1592. // pszAction += (m_Actions.GetKey(i));
  1593. // SubscribeTopic(m_pMqttConntion, pszAction.c_str());
  1594. // FINFO("{$} Subscribe Action {$} return {$} topic num {$}", m_strClientID, pszAction, ret, pTopicList->size());
  1595. // }
  1596. //}
  1597. //pszAction = m_strEBusRoot;
  1598. //pszAction += "/Action/UpdateDeviceResource";
  1599. ////std::cout << "=====*******====== 【" << m_strClientID << "】 Subscribe Action " << pszAction << endl;
  1600. //pTopicList->push_back(pszAction);
  1601. //mqtt_subscribe(pMqttClient, pszAction.c_str(), MQTT_QOS, msgarrivd);
  1602. //FINFO("{$} Subscribe Action {$} return {$} topic num {$}", m_strClientID, pszAction, ret, pTopicList->size());
  1603. //*/
  1604. // 等待所有订阅完成:轮询检查ack_list,确保所有SUBACK都已收到
  1605. // 这比固定延时更可靠,能确保订阅真正生效后才继续
  1606. FINFO("{$} Waiting for all subscriptions to complete...", m_strClientID);
  1607. const DWORD subscribeTimeoutMs = 10000; // 10秒超时(可能有多个订阅)
  1608. if (!WaitForSubscriptionComplete(m_pMqttConntion, subscribeTimeoutMs)) {
  1609. FERROR("{$} Some subscriptions did not complete within timeout", m_strClientID);
  1610. } else {
  1611. FINFO("{$} All subscriptions ready", m_strClientID);
  1612. }
  1613. // SUBACK收到后,等待Broker完成内部路由表更新
  1614. // 延时可通过环境变量MQTT_BROKER_ROUTING_DELAY_MS配置,默认200ms
  1615. WaitForBrokerRouting(m_strClientID.c_str());
  1616. }
  1617. /*
  1618. void connlost(void* context, char* cause)
  1619. {
  1620. //连接中断
  1621. ccos_mqtt_connection* connection = (ccos_mqtt_connection*)context;
  1622. std::cout << "Connection Lost .....[" << std::get<CLINET_ID_ID>(*connection) <<"] why?" << endl;
  1623. printf("\nConnection lost\n");
  1624. printf(" cause: %s\n", cause);
  1625. std::cout << CurrentDateTime() << "MQTT Server Connection lost...." << endl;
  1626. }
  1627. void disconnected(void* context, MQTTProperties* props, enum MQTTReasonCodes rc)
  1628. {
  1629. ccos_mqtt_connection* connection = (ccos_mqtt_connection*)context;
  1630. std::cout << "Connection disconnected .....[" << std::get<CLINET_ID_ID>(*connection) << "] why?" << endl;
  1631. }
  1632. */
  1633. //发送成功
  1634. //void delivered(void* context, MQTTAsync_token dt)
  1635. //{
  1636. // printf("Message with token value %d delivery confirmed\n", dt);
  1637. // //deliveredtoken = dt;
  1638. //}
  1639. //void connlost(void* context, char* cause)
  1640. //{
  1641. // //printf("Connection 0X%08X Lost ...... ???? %s \n",, cause);
  1642. // //std::cout << "Connection Context [" << (UINT64)context << "] conn lost " << (cause==nullptr?"": cause) << endl;
  1643. //
  1644. // //连接中断
  1645. // ccos_mqtt_connection* connection = (ccos_mqtt_connection*)context;
  1646. // mqtt_client* client = (mqtt_client*)std::get<MQTT_CLT_ID>(*connection);
  1647. // std::cout << CurrentDateTime() << "Connection Lost 2 .....[" << std::get<CLINET_ID_ID>(*connection) << "] why? " << (cause == nullptr ? "" : cause) << endl;
  1648. // return;
  1649. //
  1650. // MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
  1651. // int rc;
  1652. //
  1653. // printf("Reconnecting\n");
  1654. // conn_opts.keepAliveInterval = 20;
  1655. // conn_opts.cleansession = 1;
  1656. // if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
  1657. // {
  1658. // printf("Failed to start connect, return code %d\n", rc);
  1659. // //finished = 1;
  1660. // }
  1661. //}
  1662. //重连成功
  1663. //void onReconnected(void* context, char* cause)
  1664. //{
  1665. // //printf("onReconnected 0X%08X Lost ...... ???? %s \n", (UINT64)context, cause);
  1666. // //std::cout << "onReconnected [" << (UINT64)context << "] conn " << (cause == nullptr ? "" : cause) << endl;
  1667. //
  1668. // ccos_mqtt_connection* connection = (ccos_mqtt_connection*)context;
  1669. // mqtt_client* client = (mqtt_client*)std::get<MQTT_CLT_ID>(*connection);
  1670. // MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
  1671. // mqtt_topic_list* pTopicList = std::get<MQTT_TIPIC_LIST_ID>(*connection);
  1672. // const char* client_id = std::get<CLINET_ID_ID>(*connection);
  1673. // int rc;
  1674. //
  1675. // //printf(" %s \n", std::get<CLINET_ID_ID>(*connection));
  1676. // std::cout << "[" << client_id << "] Successful reconnection Use context [" << (UINT64)context << "]" << endl;
  1677. // //cout << "Connected ok.. by TID [" << GetCurrentThreadId() << "]" << endl;
  1678. // // 重新订阅,暂不重新订阅,看看
  1679. //
  1680. // ///*
  1681. // //printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
  1682. // // "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
  1683. // //opts.onSuccess = onSubscribe;
  1684. // //opts.onFailure = onSubscribeFailure;
  1685. // //opts.context = client;
  1686. // auto it = pTopicList->begin();
  1687. // while(it != pTopicList->end())
  1688. // {
  1689. // rc = MQTTAsync_subscribe(client, (*it).c_str(), 1, &opts);
  1690. // printf("-------- [%s] re subscribe %s, return code %d\n", client_id, (*it).c_str(), rc);
  1691. // it++;
  1692. // }
  1693. // //*/
  1694. //
  1695. //}
  1696. //
  1697. ////MQTT 连接主动断开连接失败
  1698. //void onDisconnectFailure(void* context, MQTTAsync_failureData* response)
  1699. //{
  1700. // printf("Disconnect failed, rc %d\n", response->code);
  1701. // //disc_finished = 1;
  1702. //}
  1703. //
  1704. ////MQTT 连接主动断开连接成功
  1705. //void onDisconnect(void* context, MQTTAsync_successData* response)
  1706. //{
  1707. // //printf("Successful disconnection\n");
  1708. // //disc_finished = 1;
  1709. //}
  1710. //
  1711. //void onSubscribe(void* context, MQTTAsync_successData* response)
  1712. //{
  1713. // printf("Subscribe succeeded\n");
  1714. // //subscribed = 1;
  1715. //}
  1716. //
  1717. //void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
  1718. //{
  1719. // printf("Subscribe failed, rc %d\n", response->code);
  1720. // //finished = 1;
  1721. //}
  1722. //
  1723. //
  1724. //void onConnectFailure(void* context, MQTTAsync_failureData* response)
  1725. //{
  1726. // printf("Connect failed, rc %d\n", response->code);
  1727. // //finished = 1;
  1728. //}
  1729. //void onConnect(void* context, MQTTAsync_successData* response)
  1730. //{
  1731. //
  1732. // ccos_mqtt_connection* connection = (ccos_mqtt_connection*)context;
  1733. // mqtt_client* client = (mqtt_client*)std::get<MQTT_CLT_ID>(*connection);
  1734. //
  1735. // std::cout << "[" << std::get<CLINET_ID_ID>(*connection) << "] onConnect Context [" << (UINT64)context << "] " << endl;
  1736. //
  1737. // MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
  1738. // int rc;
  1739. //
  1740. // //printf("[%s] connect MQTT Successful connection\n", std::get< CLINET_ID_ID>(*connection));
  1741. // HANDLE hConnected = std::get< CONNECTED_HANDLE_ID>(*connection);
  1742. // if (hConnected != NULL)
  1743. // SetEvent(hConnected);
  1744. //
  1745. // /*
  1746. // printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
  1747. // "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
  1748. // opts.onSuccess = onSubscribe;
  1749. // opts.onFailure = onSubscribeFailure;
  1750. // opts.context = client;
  1751. // if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS)
  1752. // {
  1753. // printf("Failed to start subscribe, return code %d\n", rc);
  1754. // finished = 1;
  1755. // }*/
  1756. //}
  1757. //往指定主题发送Action包,携带参数,并指定答复的Topic,异步模式处理Resp,需要在对应连接的回调中处理
  1758. int PublishActionWithoutLock(string &message, const char* pszTopic, mqtt_client* pMqttClient, std::string client_id, mqtt_qos_t qos = MQTT_QOS);
  1759. void resubscribe_topic(void* client, void* reconnect_date)
  1760. {
  1761. mqtt_client* pClient = (mqtt_client*)client;
  1762. ccos_mqtt_connection* connection = (ccos_mqtt_connection*)pClient->mqtt_conn_context;
  1763. mqtt_topic_list* pTopicList = std::get<MQTT_TIPIC_LIST_ID>(*connection);
  1764. string client_id = std::get<CLINET_ID_ID>(*connection);
  1765. FWARN("Connection Reconneted ok. {$}, topic num :{$}", client_id, pTopicList->size());
  1766. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*connection);
  1767. pLock->Thread_Lock();
  1768. for_each(pTopicList->begin(),pTopicList->end(), [&pClient] (string str)-> void {
  1769. FWARN("Resubscribe {$}", str);
  1770. mqtt_subscribe(pClient, str.c_str(), MQTT_QOS, msgarrivd);
  1771. });
  1772. pLock->Thread_UnLock();
  1773. }
  1774. //MQTT消息抵达
  1775. //int msgarrvd(void* context, char* topicName, int topicLen, MQTTAsync_message* message)
  1776. void msgarrivd(void* client, message_data_t* message)
  1777. {
  1778. // 日志前缀:时间+线程ID
  1779. const auto logPrefix = CurrentDateTime() + " msgarrivd:: TID [" + std::to_string(GetCurrentThreadId()) + "] ";
  1780. std::cout << logPrefix << std::endl;
  1781. FINFO(logPrefix);
  1782. // 基础参数校验
  1783. if (!client || !message || !message->topic_name) return;
  1784. // 转换并校验客户端对象
  1785. auto* pClient = reinterpret_cast<mqtt_client*>(client);
  1786. if (!pClient || !pClient->mqtt_conn_context) {
  1787. std::cout << logPrefix << "Invalid client or connection context" << std::endl;
  1788. return;
  1789. }
  1790. // 转换并校验连接对象
  1791. ccos_mqtt_connection* connection = nullptr;
  1792. try {
  1793. connection = reinterpret_cast<ccos_mqtt_connection*>(pClient->mqtt_conn_context);
  1794. if (!connection) {
  1795. std::cout << logPrefix << "Connection is null" << std::endl;
  1796. return;
  1797. }
  1798. }
  1799. catch (...) {
  1800. std::cout << logPrefix << "Failed to cast connection context" << std::endl;
  1801. return;
  1802. }
  1803. // 获取并校验锁对象
  1804. CcosLock* pLock = nullptr;
  1805. try {
  1806. pLock = std::get<CONN_SEND_LOCK_ID>(*connection);
  1807. if (!pLock) {
  1808. std::cout << logPrefix << "Lock is null" << std::endl;
  1809. return;
  1810. }
  1811. }
  1812. catch (...) {
  1813. std::cout << logPrefix << "Failed to get lock from connection" << std::endl;
  1814. return;
  1815. }
  1816. // 加锁并二次校验
  1817. pLock->Thread_Lock();
  1818. auto* pLockTemp = std::get<CONN_SEND_LOCK_ID>(*connection);
  1819. if (!pLockTemp) {
  1820. pLock->Thread_UnLock();
  1821. return;
  1822. }
  1823. if (!pClient->mqtt_conn_context) {
  1824. pLock->Thread_UnLock();
  1825. std::cout << logPrefix << "Connection context became null during locking" << std::endl;
  1826. return;
  1827. }
  1828. // 获取客户端ID
  1829. std::string clientId;
  1830. try {
  1831. clientId = std::get<CLINET_ID_ID>(*connection);
  1832. }
  1833. catch (...) {
  1834. pLock->Thread_UnLock();
  1835. std::cout << logPrefix << "Failed to get client ID" << std::endl;
  1836. return;
  1837. }
  1838. // 获取MQTT客户端对象
  1839. void* mqttClient = nullptr;
  1840. try {
  1841. mqttClient = std::get<MQTT_CLT_ID>(*connection);
  1842. if (!mqttClient) {
  1843. pLock->Thread_UnLock();
  1844. std::cout << logPrefix << "MQTT client is null" << std::endl;
  1845. return;
  1846. }
  1847. }
  1848. catch (...) {
  1849. pLock->Thread_UnLock();
  1850. std::cout << logPrefix << "Failed to get MQTT client" << std::endl;
  1851. return;
  1852. }
  1853. // 处理主题名
  1854. std::string topic;
  1855. try {
  1856. const size_t topicLen = strlen(message->topic_name);
  1857. const size_t maxTopicLen = sizeof(message->topic_name) - 1;
  1858. topic = (topicLen > maxTopicLen) ?
  1859. std::string(message->topic_name, maxTopicLen) :
  1860. std::string(message->topic_name);
  1861. }
  1862. catch (...) {
  1863. pLock->Thread_UnLock();
  1864. std::cout << logPrefix << "Failed to process topic name" << std::endl;
  1865. return;
  1866. }
  1867. // 输出消息接收日志
  1868. std::cout << logPrefix << clientId << " Get Msg from " << topic << std::endl;
  1869. FINFO("[msgarrivd] {$} received message from topic: {$}, payload_len: {$}", clientId, topic, message->message->payloadlen);
  1870. // 校验消息数据
  1871. if (!message->message || !message->message->payload) {
  1872. pLock->Thread_UnLock();
  1873. std::cout << logPrefix << "Invalid message data" << std::endl;
  1874. return;
  1875. }
  1876. // 校验消息大小
  1877. const auto payloadLen = message->message->payloadlen;
  1878. if ((topic.length() >= MQTT_TOPIC_LEN_MAX && payloadLen > 16380) || payloadLen > 512 * 1024) {
  1879. pLock->Thread_UnLock();
  1880. std::cout << logPrefix << "Message too large: topic_len=" << topic.length()
  1881. << ", payload_len=" << payloadLen << std::endl;
  1882. return;
  1883. }
  1884. // 大消息提示
  1885. if (payloadLen > 16380) {
  1886. std::cout << logPrefix << clientId << " Get big Msg from " << topic
  1887. << " msg Len " << payloadLen << std::endl;
  1888. }
  1889. // 解码消息载荷
  1890. ResDataObject req;
  1891. try {
  1892. std::string payload(static_cast<const char*>(message->message->payload), payloadLen);
  1893. req.decode(payload.c_str());
  1894. FINFO("[msgarrivd] {$} decoded message successfully, KEY: {$}, TYPE: {$}, CMD: {$}",
  1895. clientId,
  1896. PacketAnalizer::GetPacketKey(&req),
  1897. (int)PacketAnalizer::GetPacketType(&req),
  1898. (int)PacketAnalizer::GetPacketCmd(&req));
  1899. }
  1900. catch (...) {
  1901. pLock->Thread_UnLock();
  1902. FERROR("[msgarrivd] {$} failed to decode message from topic: {$}", clientId, topic);
  1903. return;
  1904. }
  1905. // 处理消息钩子
  1906. void* pHook = nullptr;
  1907. try {
  1908. pHook = std::get<MSG_HOOK_ID>(*connection);
  1909. }
  1910. catch (...) {
  1911. pLock->Thread_UnLock();
  1912. return;
  1913. }
  1914. if (pHook) {
  1915. try {
  1916. auto* filter = reinterpret_cast<ccos_mqtt_msg_filter*>(pHook);
  1917. if (!filter) {
  1918. pLock->Thread_UnLock();
  1919. return;
  1920. }
  1921. auto func = std::get<FILTER_FUNC_ID>(*filter);
  1922. std::cout << logPrefix << clientId << " Got Hook Process " << topic << std::endl;
  1923. FINFO("[msgarrivd] {$} processing hook for topic: {$}", clientId, topic);
  1924. auto* pRequests = std::get<FILTER_RES_OBJ_ID>(*filter);
  1925. if (!pRequests) {
  1926. pLock->Thread_UnLock();
  1927. FWARN("[msgarrivd] {$} pRequests is null", clientId);
  1928. return;
  1929. }
  1930. FINFO("[msgarrivd] {$} checking {$} pending requests in hook", clientId, pRequests->size());
  1931. // 遍历请求处理钩子
  1932. for (int x = 0; x < pRequests->size(); x++) {
  1933. std::cout << logPrefix << clientId << " Hook Process Function " << topic << std::endl;
  1934. const std::string keyAction = pRequests->GetKey(x);
  1935. ResDataObject resObj = (*pRequests)[x];
  1936. auto hEvent = std::get<FILTER_HANDLE_ID>(*filter);
  1937. FINFO("[msgarrivd] {$} comparing: pending_key=[{$}] vs received_key=[{$}], msg_type={$}",
  1938. clientId, keyAction, PacketAnalizer::GetPacketKey(&req), (int)PacketAnalizer::GetPacketType(&req));
  1939. // 匹配钩子消息
  1940. if (PacketAnalizer::GetPacketType(&req) == PACKET_TYPE_RES &&
  1941. keyAction == PacketAnalizer::GetPacketKey(&req)) {
  1942. std::cout << logPrefix << clientId << " Got Hook Function Hooked.. " << topic << std::endl;
  1943. FINFO("[msgarrivd] {$} MATCHED! Hook triggered for key: {$}", clientId, keyAction);
  1944. // 打开事件(优先使用resObj,失败则用默认)
  1945. auto event = LinuxEvent::OpenEvent(std::string(resObj).c_str());
  1946. if (!event) event = hEvent;
  1947. // 设置响应对象
  1948. auto* pResponse = std::get<FILTER_RESPONS_OBJ_ID>(*filter);
  1949. if (pResponse) {
  1950. pResponse->add(keyAction.c_str(), req);
  1951. FINFO("[msgarrivd] {$} added response to pResponse for key: {$}", clientId, keyAction);
  1952. } else {
  1953. FWARN("[msgarrivd] {$} pResponse is null, cannot store response", clientId);
  1954. }
  1955. // 触发事件
  1956. if (event) {
  1957. try {
  1958. event->SetEvent();
  1959. FINFO("[msgarrivd] {$} event signaled successfully for key: {$}", clientId, keyAction);
  1960. }
  1961. catch (...) {
  1962. FERROR("[msgarrivd] {$} failed to signal event for key: {$}", clientId, keyAction);
  1963. }
  1964. } else {
  1965. FWARN("[msgarrivd] {$} event is null, cannot signal", clientId);
  1966. }
  1967. // 清理并退出
  1968. pRequests->eraseOneOf(keyAction.c_str(), 0);
  1969. FINFO("[msgarrivd] {$} erased request from pending list, key: {$}", clientId, keyAction);
  1970. pLock->Thread_UnLock();
  1971. return;
  1972. }
  1973. }
  1974. }
  1975. catch (...) {
  1976. FERROR("[msgarrivd] {$} exception in hook processing for topic: {$}", clientId, topic);
  1977. }
  1978. }
  1979. // 未命中钩子,继续处理
  1980. std::cout << logPrefix << clientId << " Go on Process " << topic << std::endl;
  1981. FINFO("[msgarrivd] {$} hook not matched, calling user callback for topic: {$}", clientId, topic);
  1982. pLock->Thread_UnLock();
  1983. // 调用用户回调
  1984. ccos_mqtt_callback onmsg = nullptr;
  1985. try {
  1986. onmsg = std::get<USER_MSG_CAKBCK_ID>(*connection);
  1987. }
  1988. catch (...) {
  1989. return;
  1990. }
  1991. if (onmsg) {
  1992. // 使用异步处理避免阻塞MQTT接收流程
  1993. try {
  1994. AsyncMsgHandler::getInstance().handleMessageAsync(onmsg, req, topic, connection);
  1995. std::cout << logPrefix << clientId << " 消息已提交到异步处理队列: " << topic << std::endl;
  1996. }
  1997. catch (const std::exception& e) {
  1998. std::cout << logPrefix << clientId << " 异步消息处理提交失败: " << e.what()
  1999. << ", Topic: " << topic << std::endl;
  2000. }
  2001. catch (...) {
  2002. std::cout << logPrefix << clientId << " 异步消息处理提交出现未知错误, Topic: "
  2003. << topic << std::endl;
  2004. }
  2005. }
  2006. else {
  2007. std::cout << logPrefix << "**** ----- **** USER_MSG_CAKBCK_ID is null "
  2008. << clientId << " When processing " << topic << std::endl;
  2009. }
  2010. }
  2011. void* MqttSendThreadFunc(void* pPara)
  2012. {
  2013. ccos_mqtt_connection* connection = (ccos_mqtt_connection*)pPara;
  2014. if (!connection) {
  2015. return NULL;
  2016. }
  2017. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*connection);
  2018. mqtt_msg_list* pList = std::get<MSG_LIST_ID>(*connection);
  2019. mqtt_client* pConn = (mqtt_client*)std::get<MQTT_CLT_ID>(*connection);
  2020. std::string client_id = std::get<CLINET_ID_ID>(*connection);
  2021. sem_t* hSemaphore = std::get<SEMAPHORE_HANDLE_ID>(*connection);
  2022. mqtt_topic_list* pTopicList = std::get<MQTT_TIPIC_LIST_ID>(*connection);
  2023. // 线程启动日志
  2024. std::cout << "[" << client_id << "] The MQTT sending thread is started" << std::endl;
  2025. while (std::get<THREAD_RUNNING_ID>(*connection)) {
  2026. struct timespec ts;
  2027. clock_gettime(CLOCK_REALTIME, &ts);
  2028. ts.tv_sec += 1;
  2029. // 等待信号量前的日志
  2030. //std::cout << "[" << client_id << "] Wait for the message semaphore..." << std::endl;
  2031. if (sem_timedwait(hSemaphore, &ts) == 0) {
  2032. std::cout << "[" << client_id << "] Received the message semaphore and ready to process the message" << std::endl;
  2033. pLock->Thread_Lock();
  2034. std::cout << "[" << client_id << "] Successfully obtained the sending lock" << std::endl;
  2035. if (pList->empty()) {
  2036. std::cout << "[" << client_id << "] The message list is empty, release the lock." << std::endl;
  2037. pLock->Thread_UnLock();
  2038. continue;
  2039. }
  2040. ResDataObject* pMsg = pList->front();
  2041. pList->pop_front();
  2042. pLock->Thread_UnLock();
  2043. std::cout << "[" << client_id << "] Get a message from the message list, the number of remaining messages: " << pList->size() << std::endl;
  2044. std::string m_strSendMessage;
  2045. for (int x = 0; x < pMsg->size(); x++) {
  2046. const char* pTopic = pMsg->GetKey(x);
  2047. m_strSendMessage = (std::string)(*pMsg)[pTopic];
  2048. std::cout<< CurrentDateTime() << " [" << client_id << "] Prepare to publish messages to the topic: " << pTopic
  2049. << ", Message length: " << m_strSendMessage.length() << "Byte" << std::endl;
  2050. PublishActionWithoutLock(m_strSendMessage, pTopic, pConn, client_id, pTopicList->size() <= 0 ? QOS2 : MQTT_QOS);
  2051. }
  2052. std::cout << "[" << client_id << "] The message processing is completed, and the message object has been released." << std::endl;
  2053. delete pMsg;
  2054. //std::cout << "[" << client_id << "] Release the sending lock" << std::endl;
  2055. }
  2056. else if (errno == ETIMEDOUT) {
  2057. //std::cout << "[" << client_id << "] The semaphore wait timed out, continue waiting." << std::endl;
  2058. continue;
  2059. }
  2060. else {
  2061. // 其他错误情况
  2062. std::cout << "[" << client_id << "] Semaphore wait error, error code: " << errno << std::endl;
  2063. continue;
  2064. }
  2065. }
  2066. return NULL;
  2067. }
  2068. // 安全遍历MQTT消息处理程序的宏
  2069. #define mqtt_list_for_each_entry_safe(pos, n, head, member) \
  2070. for (pos = container_of((head)->next, decltype(*pos), member), \
  2071. n = container_of(pos->member.next, decltype(*pos), member); \
  2072. &pos->member != (head); \
  2073. pos = n, n = container_of(n->member.next, decltype(*n), member))
  2074. // 通过成员指针获取包含结构的指针
  2075. #define container_of(ptr, type, member) ({ \
  2076. const typeof(((type*)0)->member)* __mptr = (ptr); \
  2077. (type*)((char*)__mptr - offsetof(type, member)); })
  2078. // 重连回调函数 - 实现自动重订阅
  2079. static void reconnect_handler(void* client, void* reconnect_data) {
  2080. mqtt_client_t* c = (mqtt_client_t*)client;
  2081. message_handlers_t* pos, * n;
  2082. ccos_mqtt_connection* connection = (ccos_mqtt_connection*)c->mqtt_conn_context;
  2083. // 遍历所有已订阅的主题并重新订阅
  2084. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*connection);
  2085. pLock->Thread_Lock();
  2086. /*mqtt_list_for_each_entry_safe(pos, n, &c->mqtt_msg_handler_list, list) {
  2087. mqtt_subscribe(c, pos->topic_filter, pos->qos, pos->handler);
  2088. }*/
  2089. pLock->Thread_UnLock();
  2090. }
  2091. mqtt_client_t* InnerConnect(ccos_mqtt_connection* connection) {
  2092. if (!connection) {
  2093. std::cerr << "[ERROR] Invalid connection context (nullptr)" << std::endl;
  2094. return nullptr;
  2095. }
  2096. //mqtt_log_init();
  2097. mqtt_client_t* client = NULL;
  2098. client = mqtt_lease();
  2099. mqtt_log_init();
  2100. if (!client) { // 修复:检查客户端指针是否有效
  2101. return nullptr;
  2102. }
  2103. std::get<MQTT_CLT_ID>(*connection) = client;
  2104. client->mqtt_conn_context = connection;
  2105. std::string& pszClientID = std::get<CLINET_ID_ID>(*connection);
  2106. // 使用本地副本存储连接参数
  2107. std::string host = SERVER_ADDRESS;
  2108. std::string port = "1883";
  2109. std::string username = "zskkcc";
  2110. std::string password = "zskk1234";
  2111. std::cout << "[CONFIG] Setting connection parameters:"
  2112. << "\n\tClient ID: " << pszClientID
  2113. << "\n\tHost: " << host
  2114. << "\n\tPort: " << port
  2115. << std::endl;
  2116. // 设置MQTT连接参数
  2117. mqtt_set_host(client, const_cast<char*>(host.c_str()));
  2118. mqtt_set_port(client, const_cast<char*>(port.c_str()));
  2119. mqtt_set_user_name(client, const_cast<char*>(username.c_str()));
  2120. mqtt_set_password(client, const_cast<char*>(password.c_str()));
  2121. mqtt_set_client_id(client, const_cast<char*>(pszClientID.c_str()));
  2122. mqtt_set_clean_session(client, 0);
  2123. mqtt_set_write_buf_size(client, 8192);
  2124. mqtt_set_read_buf_size(client, 8192);
  2125. mqtt_set_cmd_timeout(client, 2000);
  2126. mqtt_set_keep_alive_interval(client, 30);
  2127. //mqtt_subscribe();
  2128. //mqtt_set_reconnect_handler(pMqttClient, reconnect_handler);
  2129. int rc = 0;
  2130. const uint64_t timeout_ms = 10000; // 10秒超时
  2131. uint64_t start_time = GetTickCount();
  2132. int attempt_count = 0;
  2133. bool connected = false;
  2134. std::cout << "[CONNECT] Initiating connection (timeout: " << timeout_ms << "ms)..." << std::endl;
  2135. try {
  2136. while (true) {
  2137. attempt_count++;
  2138. uint64_t current_time = GetTickCount();
  2139. uint64_t elapsed = current_time - start_time;
  2140. // 检查超时
  2141. if (elapsed > timeout_ms) {
  2142. std::cerr << "[FATAL] Connection timeout after " << timeout_ms << "ms" << std::endl;
  2143. return nullptr;
  2144. }
  2145. std::cout << CurrentDateTime() << " [ATTEMPT #" << attempt_count << "] Trying MQTT connect..." << std::endl;
  2146. rc = mqtt_connect(client);
  2147. if (rc == MQTT_SUCCESS_ERROR) {
  2148. connected = true;
  2149. break;
  2150. }
  2151. std::cerr << "[ERROR] Connection failed (code: " << rc << "), Elapsed: " << elapsed << "ms" << std::endl;
  2152. // 计算等待时间
  2153. uint64_t remaining = timeout_ms - elapsed;
  2154. uint64_t wait_time = (remaining > 2000) ? 2000 : remaining;
  2155. if (wait_time > 0) {
  2156. std::cout << "[RETRY] Waiting " << wait_time << "ms before next attempt..." << std::endl;
  2157. usleep(wait_time * 1000);
  2158. }
  2159. }
  2160. if (connected) {
  2161. uint64_t total_time = GetTickCount() - start_time;
  2162. FINFO("[SUCCESS] Connected in {$}ms after {$} attempts", total_time, attempt_count);
  2163. // 等待CONNACK处理完成:mqtt_connect()是异步的,返回0只表示CONNECT包已发送
  2164. // 需要给MQTT内部线程一点时间处理CONNACK(通常几十毫秒内完成)
  2165. // 实际的订阅完成由WaitForSubscriptionComplete()保证,所以这里只需要短暂等待
  2166. const int connackDelayMs = 100;
  2167. FINFO("[MQTT] Waiting {$}ms for CONNACK processing...", connackDelayMs);
  2168. usleep(connackDelayMs * 1000);
  2169. FINFO("[MQTT] CONNACK wait complete, connection ready for subscriptions");
  2170. // 安全地设置连接上下文
  2171. try {
  2172. return client;
  2173. }
  2174. catch (const std::exception& e) {
  2175. FERROR("[ERROR] Failed to set connection context: {$}", e.what());
  2176. return nullptr;
  2177. }
  2178. }
  2179. }
  2180. catch (const std::exception& e) {
  2181. std::cerr << "[ERROR] Exception during connection: " << e.what() << std::endl;
  2182. return nullptr;
  2183. }
  2184. catch (...) {
  2185. std::cerr << "[ERROR] Unknown exception during connection" << std::endl;
  2186. return nullptr;
  2187. }
  2188. return nullptr;
  2189. }
  2190. ccos_mqtt_connection* LogicDevice::NewConnection(const char* pszServer,const char* pszServerPort, const char* pszUserName, const char* pszPassword, const char* pszClientID, ccos_mqtt_callback onmsg)
  2191. {
  2192. FINFO("TID {$} : {$} NewConnection {$}:{$} user: {$} password {$} ", GetCurrentThreadId(), pszClientID, pszServer, pszServerPort, pszUserName, pszPassword);
  2193. std::cout << "TID " << GetCurrentThreadId()
  2194. << " : " << pszClientID
  2195. << " NewConnection " << pszServer
  2196. << ":" << pszServerPort
  2197. << " user: " << pszUserName
  2198. << " password " << pszPassword
  2199. << std::endl;
  2200. //连接MQTT broker
  2201. DWORD dwTick = GetTickCount();
  2202. std::string clientIdStr(pszClientID ? pszClientID : "");
  2203. ccos_mqtt_connection* connection = new ccos_mqtt_connection;
  2204. try {
  2205. // 初始化元组字段
  2206. std::get<MQTT_TIPIC_LIST_ID>(*connection) = new mqtt_topic_list;
  2207. std::get<CLINET_ID_ID>(*connection) = pszClientID;
  2208. std::get<USER_MSG_CAKBCK_ID>(*connection) = onmsg;
  2209. CcosLock* pLock = new CcosLock();
  2210. std::get<CONN_SEND_LOCK_ID>(*connection) = pLock;
  2211. pLock->Thread_Lock();
  2212. ccos_mqtt_msg_filter* pfilter = new ccos_mqtt_msg_filter;
  2213. std::get<FILTER_FUNC_ID>(*pfilter) = nullptr;
  2214. std::get<FILTER_RES_OBJ_ID>(*pfilter) = new ResDataObject;
  2215. std::get<FILTER_RESPONS_OBJ_ID>(*pfilter) = new ResDataObject;
  2216. std::get<MSG_HOOK_ID>(*connection) = pfilter;
  2217. std::cout << "ALLOCATE Connection [" << (UINT64) connection << "] filter [" << (UINT64)pfilter << "] .. for " << pszClientID << endl;
  2218. mqtt_client* pMqttClient = InnerConnect(connection);
  2219. if (pMqttClient == nullptr)
  2220. {
  2221. pLock->Thread_UnLock();
  2222. throw std::runtime_error("InnerConnect failed");
  2223. }
  2224. std::get<MQTT_CLT_ID>(*connection) = pMqttClient;
  2225. std::get<MSG_LIST_ID>(*connection) = new mqtt_msg_list;
  2226. // 创建POSIX信号量
  2227. sem_t* semaphore = new sem_t;
  2228. if (sem_init(semaphore, 0, 0) != 0) {
  2229. pLock->Thread_UnLock();
  2230. delete semaphore;
  2231. throw std::runtime_error("Failed to initialize semaphore");
  2232. }
  2233. std::get<SEMAPHORE_HANDLE_ID>(*connection) = semaphore;
  2234. std::get<THREAD_RUNNING_ID>(*connection) = true;
  2235. // 创建发送线程
  2236. pthread_t threadId;
  2237. if (pthread_create(&threadId, NULL, MqttSendThreadFunc, connection) != 0) {
  2238. std::cerr << "Failed to create MQTT send thread" << std::endl;
  2239. std::get<THREAD_RUNNING_ID>(*connection) = false;
  2240. // 错误处理...
  2241. sem_destroy(semaphore);
  2242. delete semaphore;
  2243. pLock->Thread_UnLock();
  2244. throw std::runtime_error("Failed to initialize semaphore");
  2245. }
  2246. std::get<CONNECTED_HANDLE_ID>(*connection) = threadId;
  2247. std::cout << "MqttSendThreadFunc thread id [" << threadId << "]" << std::endl;
  2248. pLock->Thread_UnLock();
  2249. uint64_t dwWaitTick = GetTickCount() - dwTick;
  2250. std::cout << "MQTT " << pszClientID << " try ConnMqtt Succeeded. Use Time: "
  2251. << dwWaitTick << " ms" << std::endl;
  2252. return connection;
  2253. }
  2254. catch (const std::exception& e) {
  2255. std::cerr << "Exception in NewConnection: " << e.what() << std::endl;
  2256. // 清理资源
  2257. if (std::get<SEMAPHORE_HANDLE_ID>(*connection)) {
  2258. sem_destroy(std::get<SEMAPHORE_HANDLE_ID>(*connection));
  2259. delete std::get<SEMAPHORE_HANDLE_ID>(*connection);
  2260. }
  2261. delete std::get<MSG_LIST_ID>(*connection);
  2262. delete std::get<CONN_SEND_LOCK_ID>(*connection);
  2263. delete std::get<MQTT_TIPIC_LIST_ID>(*connection);
  2264. delete connection;
  2265. return nullptr;
  2266. }
  2267. }
  2268. //创建额外连接,需要提供回调函数
  2269. LOGICDEVICE_API ccos_mqtt_connection* NewConnection(const char* pszClientID, ccos_mqtt_callback onmsg, DWORD dwOpenTimeout, bool async)
  2270. {
  2271. DWORD dwTick = GetTickCount();
  2272. FINFO("TID {$} : {$} NewConnection2 {$}:{$} ", GetCurrentThreadId(), pszClientID, SERVER_ADDRESS, 1883);
  2273. //mqtt_client* pMqttClient = nullptr;
  2274. //pMqttClient = mqtt_lease();
  2275. ccos_mqtt_connection* connection = new ccos_mqtt_connection;
  2276. //HANDLE hConneted = CreateEvent(NULL, FALSE, FALSE, NULL);
  2277. //std::get<MQTT_CLT_ID>(*connection) = pMqttClient;
  2278. mqtt_topic_list* pTopicList = new std::list<string>;
  2279. std::get<MQTT_TIPIC_LIST_ID>(*connection) = pTopicList;
  2280. CcosLock* pLock = new CcosLock();
  2281. std::get<CONN_SEND_LOCK_ID>(*connection) = pLock;
  2282. pLock->Thread_Lock();
  2283. ccos_mqtt_msg_filter* pfilter = new ccos_mqtt_msg_filter;
  2284. std::get<FILTER_FUNC_ID>(*pfilter) = nullptr;
  2285. std::get<MSG_HOOK_ID>(*connection) = pfilter;
  2286. std::get<FILTER_RES_OBJ_ID>(*pfilter) = new ResDataObject;
  2287. std::get<FILTER_RESPONS_OBJ_ID>(*pfilter) = new ResDataObject;
  2288. std::cout << "ALLOCATE Connection 2 [" << (UINT64)connection << "] filter [" << (UINT64)pfilter << "] ..for " << pszClientID << endl;
  2289. std::get<CLINET_ID_ID>(*connection) = pszClientID;
  2290. std::get< USER_MSG_CAKBCK_ID>(*connection) = onmsg;
  2291. mqtt_client* pMqttClient = InnerConnect(connection);
  2292. if (pMqttClient == nullptr)
  2293. {
  2294. pLock->Thread_UnLock();
  2295. delete std::get<MQTT_TIPIC_LIST_ID>(*connection); // 删除 pTopicList
  2296. delete std::get<CONN_SEND_LOCK_ID>(*connection); // 删除 pLock
  2297. delete connection;
  2298. delete pfilter;
  2299. return nullptr;
  2300. }
  2301. std::get<MQTT_CLT_ID>(*connection) = pMqttClient;
  2302. //pMqttClient->mqtt_conn_context = connection;
  2303. //设置回调函数
  2304. //设置MQTT连接参数
  2305. //mqtt_set_resubscribe_handler(pMqttClient, resubscribe_topic);
  2306. /*
  2307. //连接Broker
  2308. int rc = 0;
  2309. dwTick = GetTickCount();
  2310. while (true)
  2311. {
  2312. rc = mqtt_connect(pMqttClient);
  2313. if (rc != MQTT_SUCCESS_ERROR)
  2314. {
  2315. if (GetTickCount() - dwTick > dwOpenTimeout)
  2316. {
  2317. FINFO(" TID {$} {$} Failed 2 to connect to the MQTT server... {$} return : ", GetCurrentThreadId(), pszClientID, rc);
  2318. pLock->Thread_UnLock();
  2319. delete connection;
  2320. delete pfilter;
  2321. return nullptr;
  2322. }
  2323. else
  2324. {
  2325. FINFO(" TID {$} {$} Failed 2 to connect to the MQTT server Try again 20ms later...... {$} return : ", GetCurrentThreadId(), pszClientID, rc);
  2326. //std::cout << CurrentDateTime() << " TID [" << GetCurrentThreadId() << "] Failed to connect to the MQTT server Try again 2s later..." << pszClientID << endl;
  2327. Sleep(20);
  2328. }
  2329. }
  2330. else
  2331. {
  2332. break;
  2333. }
  2334. }*/
  2335. DWORD dwWaitTick = GetTickCount() - dwTick;
  2336. FWARN("MQTT {$} try ConnMqtt Succecced Use Time ****** {$} ms*** wait: {$} ms*** TID ", pszClientID, GetTickCount() - dwTick, dwWaitTick, GetCurrentThreadId());
  2337. std::get<MSG_LIST_ID>(*connection) = new mqtt_msg_list;
  2338. // 创建POSIX信号量
  2339. sem_t* semaphore = new sem_t;
  2340. sem_init(semaphore, 0, 0);
  2341. std::get<SEMAPHORE_HANDLE_ID>(*connection) = semaphore;
  2342. std::get<THREAD_RUNNING_ID>(*connection) = true;
  2343. // 创建发送线程
  2344. std::cout << "Preapre create MqttSendThreadFunc" << std::endl;
  2345. pthread_t threadId;
  2346. if (pthread_create(&threadId, NULL, MqttSendThreadFunc, connection) != 0) {
  2347. std::cerr << "Failed to create MQTT send thread" << std::endl;
  2348. std::get<THREAD_RUNNING_ID>(*connection) = false;
  2349. // 错误处理...
  2350. sem_destroy(semaphore);
  2351. delete semaphore;
  2352. pLock->Thread_UnLock();
  2353. delete connection;
  2354. return nullptr;
  2355. }
  2356. std::get<CONNECTED_HANDLE_ID>(*connection) = threadId;
  2357. std::cout << "MqttSendThreadFunc thread id [" << threadId << "]" << std::endl;
  2358. pLock->Thread_UnLock();
  2359. std::cout << "MQTT " << pszClientID << " try ConnMqtt Succeeded. Use Time: "
  2360. << dwWaitTick << " ms" << std::endl;
  2361. return connection;
  2362. }
  2363. //重置连接
  2364. LOGICDEVICE_API void ResetConnection(ccos_mqtt_connection* hConnection)
  2365. {
  2366. if (hConnection == nullptr)
  2367. {
  2368. return;
  2369. }
  2370. FWARN(" Reset Mqtt Connection..", std::get<CLINET_ID_ID>(*hConnection));
  2371. std::cout << CurrentDateTime() << std::get<CLINET_ID_ID>(*hConnection) << " Close Mqtt Connection.." << endl;
  2372. mqtt_client* pconn = (mqtt_client*)std::get<MQTT_CLT_ID>(*hConnection);
  2373. if (pconn != nullptr) {
  2374. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*hConnection);
  2375. pLock->Thread_Lock();
  2376. //mqtt_do_reconnect(pconn);
  2377. mqtt_disconnect(pconn);
  2378. /*mqtt_set_resubscribe_handler(pconn, resubscribe_topic);
  2379. mqtt_connect(pconn);*/
  2380. mqtt_release(pconn);
  2381. pconn = InnerConnect(hConnection);
  2382. int rc = MQTT_SUCCESS_ERROR;// mqtt_connect(pconn);
  2383. if (pconn != nullptr)
  2384. {
  2385. //std::get<MQTT_CLT_ID>(*hConnection) = pconn;
  2386. //resubscribe_topic(pconn, pconn->mqtt_conn_context);
  2387. //FWARN("mqtt_connect ret {$} do mqtt resubscribe {$}", rc, std::get<CLINET_ID_ID>(*hConnection));
  2388. }
  2389. pLock->Thread_UnLock();
  2390. }
  2391. }
  2392. //关闭并释放连接
  2393. LOGICDEVICE_API void CloseConnection(ccos_mqtt_connection* hConnection)
  2394. {
  2395. if (!hConnection) return;
  2396. auto clientId = std::get<CLINET_ID_ID>(*hConnection);
  2397. std::cout << CurrentDateTime() << clientId << " Close Mqtt Connection.." << endl;
  2398. std::get<THREAD_RUNNING_ID>(*hConnection) = false;
  2399. sem_t* semaphore = std::get<SEMAPHORE_HANDLE_ID>(*hConnection);
  2400. if (semaphore) {
  2401. sem_post(semaphore); // 发送信号量唤醒线程
  2402. }
  2403. pthread_t sendThread = std::get<CONNECTED_HANDLE_ID>(*hConnection);
  2404. if (sendThread != 0) {
  2405. // 等待线程退出,超时时间设为1秒
  2406. struct timespec timeout;
  2407. clock_gettime(CLOCK_REALTIME, &timeout);
  2408. timeout.tv_sec += 1;
  2409. int joinResult = pthread_timedjoin_np(sendThread, nullptr, &timeout);
  2410. if (joinResult != 0) {
  2411. std::cerr << CurrentDateTime() << " " << clientId
  2412. << " Warning: Send thread did not exit in time, force cancel" << std::endl;
  2413. pthread_cancel(sendThread); // 超时后强制终止(最后的备选方案)
  2414. pthread_join(sendThread, nullptr);
  2415. }
  2416. std::get<CONNECTED_HANDLE_ID>(*hConnection) = 0; // 重置线程ID
  2417. }
  2418. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*hConnection);
  2419. if (nullptr != pLock)
  2420. pLock->Thread_Lock();
  2421. else
  2422. return;
  2423. mqtt_client* pMqttClient = static_cast<mqtt_client*>(std::get<MQTT_CLT_ID>(*hConnection));
  2424. if (pMqttClient) {
  2425. mqtt_disconnect(pMqttClient); // 断开连接
  2426. mqtt_release(pMqttClient); // 释放客户端实例
  2427. pMqttClient = NULL;
  2428. std::get<MQTT_CLT_ID>(*hConnection) = nullptr;
  2429. }
  2430. ccos_mqtt_msg_filter* pFilter = static_cast<ccos_mqtt_msg_filter*>(std::get<MSG_HOOK_ID>(*hConnection));
  2431. if (pFilter) {
  2432. std::cout << "Free Connection filter [" << (UINT64)pFilter << "] .." << std::endl;
  2433. // 释放filter内部的资源对象
  2434. delete std::get<FILTER_RES_OBJ_ID>(*pFilter);
  2435. delete std::get<FILTER_RESPONS_OBJ_ID>(*pFilter);
  2436. delete pFilter;
  2437. std::get<MSG_HOOK_ID>(*hConnection) = nullptr;
  2438. }
  2439. mqtt_msg_list* pMsgList = std::get<MSG_LIST_ID>(*hConnection);
  2440. if (pMsgList) {
  2441. // 清理剩余未发送的消息
  2442. while (!pMsgList->empty()) {
  2443. ResDataObject* pMsg = pMsgList->front();
  2444. pMsgList->pop_front();
  2445. delete pMsg; // 释放消息对象
  2446. }
  2447. delete pMsgList;
  2448. std::get<MSG_LIST_ID>(*hConnection) = nullptr;
  2449. }
  2450. if (semaphore) {
  2451. sem_destroy(semaphore); // 销毁信号量
  2452. delete semaphore;
  2453. std::get<SEMAPHORE_HANDLE_ID>(*hConnection) = nullptr;
  2454. }
  2455. mqtt_topic_list* pTopicList = std::get<MQTT_TIPIC_LIST_ID>(*hConnection);
  2456. if (pTopicList) {
  2457. pTopicList->clear(); // 清空列表
  2458. delete pTopicList;
  2459. std::get<MQTT_TIPIC_LIST_ID>(*hConnection) = nullptr;
  2460. }
  2461. if (pLock) {
  2462. pLock->Thread_UnLock(); // 确保锁被释放
  2463. delete pLock;
  2464. std::get<CONN_SEND_LOCK_ID>(*hConnection) = nullptr;
  2465. }
  2466. delete hConnection;
  2467. std::cout << CurrentDateTime() << clientId << " Close Mqtt Connection over.." << endl;
  2468. }
  2469. //主动订阅主题
  2470. LOGICDEVICE_API int SubscribeTopic(ccos_mqtt_connection* hConnection, const char* pszTopic, bool isShare)
  2471. {
  2472. std::cout << "SubscribeTopic called. Topic: " << (pszTopic ? pszTopic : "null")
  2473. << ", isShare: " << (isShare ? "true" : "false") << std::endl;
  2474. if (hConnection == nullptr)
  2475. {
  2476. std::cout << "SubscribeTopic error: hConnection is nullptr" << std::endl;
  2477. return 0;
  2478. }
  2479. mqtt_client* pMqttClient = (mqtt_client*)std::get<MQTT_CLT_ID>(*hConnection);
  2480. mqtt_topic_list* pTopicList = std::get<MQTT_TIPIC_LIST_ID>(*hConnection);
  2481. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*hConnection);
  2482. pLock->Thread_Lock();
  2483. pTopicList->push_back(std::string(pszTopic));
  2484. //pMqttClient->subscribe(pszTopic, 1, opts);
  2485. int rc = MQTT_SUCCESS_ERROR;
  2486. DWORD dwTick = GetTickCount();
  2487. int nTryTimes = 0;
  2488. do
  2489. {
  2490. if (pTopicList->size() < 1)
  2491. {
  2492. const char* topicToSubscribe = pTopicList->back().c_str();
  2493. int ret = mqtt_subscribe(pMqttClient, topicToSubscribe, MQTT_QOS, msgarrivd);
  2494. //int ret = mqtt_subscribe(pMqttClient, pszTopic, MQTT_QOS, msgarrivd);
  2495. FWARN("mqtt {$} Subscribe First {$} return {$} topic num {$}", std::get<CLINET_ID_ID>(*hConnection), pszTopic, ret, pTopicList->size());
  2496. std::cout << "mqtt [" << std::get<CLINET_ID_ID>(*hConnection) << " ]Subscribe First " << pszTopic << endl;
  2497. }
  2498. else
  2499. {
  2500. const char* topicToSubscribe = pTopicList->back().c_str();
  2501. int ret = mqtt_subscribe(pMqttClient, topicToSubscribe, MQTT_QOS, msgarrivd);
  2502. //int ret = mqtt_subscribe(pMqttClient, pszTopic, MQTT_QOS, msgarrivd);
  2503. FWARN("mqtt {$} Subscribe ReUse {$} topic num {$}", std::get<CLINET_ID_ID>(*hConnection), pszTopic, ret, pTopicList->size());
  2504. std::cout << CurrentDateTime() << " mqtt [" << std::get<CLINET_ID_ID>(*hConnection) << " ]Subscribe ReUse " << pszTopic << " ret: "<<ret <<endl;
  2505. }
  2506. if (rc != MQTT_SUCCESS_ERROR)
  2507. {
  2508. FWARN("try do mqtt reconnect ..");
  2509. //mqtt_do_reconnect(pMqttClient);
  2510. mqtt_disconnect(pMqttClient);
  2511. //mqtt_set_resubscribe_handler(pMqttClient, resubscribe_topic);
  2512. mqtt_release(pMqttClient);
  2513. pMqttClient = InnerConnect(hConnection);
  2514. int rc = MQTT_SUCCESS_ERROR;// mqtt_connect(pconn);
  2515. if (pMqttClient != nullptr)
  2516. {
  2517. //std::get<MQTT_CLT_ID>(*hConnection) = pMqttClient;
  2518. //resubscribe_topic(pMqttClient, pMqttClient->mqtt_conn_context);
  2519. FINFO("Reconnected successfully, connection ready for subscriptions");
  2520. }
  2521. // 移除2秒延时:InnerConnect已等待CONNACK,WaitForSubscriptionComplete会确保订阅完成
  2522. }
  2523. } while (rc != MQTT_SUCCESS_ERROR && GetTickCount() - dwTick < 100);
  2524. pLock->Thread_UnLock();
  2525. return 0;
  2526. }
  2527. // 等待订阅完成(轮询检查ack_list,确保SUBACK已收到)
  2528. LOGICDEVICE_API bool WaitForSubscriptionComplete(ccos_mqtt_connection* hConnection, DWORD timeoutMs)
  2529. {
  2530. if (hConnection == nullptr) {
  2531. FERROR("WaitForSubscriptionComplete: hConnection is nullptr");
  2532. return false;
  2533. }
  2534. mqtt_client_t* pMqttClient = (mqtt_client_t*)std::get<MQTT_CLT_ID>(*hConnection);
  2535. if (pMqttClient == nullptr) {
  2536. FERROR("WaitForSubscriptionComplete: pMqttClient is nullptr");
  2537. return false;
  2538. }
  2539. const std::string clientId = std::get<CLINET_ID_ID>(*hConnection);
  2540. FINFO("[WaitForSubscriptionComplete] {$} - Waiting for all subscriptions to complete (timeout: {$}ms)",
  2541. clientId, timeoutMs);
  2542. DWORD startTime = GetTickCount();
  2543. const DWORD pollIntervalMs = 10; // 每10ms轮询一次
  2544. int lastAckCount = -1;
  2545. while (GetTickCount() - startTime < timeoutMs) {
  2546. // 检查ack_handler_list中是否还有待处理的SUBACK
  2547. // mqtt_ack_handler_number记录了ack_list中的条目数量
  2548. int currentAckCount = pMqttClient->mqtt_ack_handler_number;
  2549. // 如果ack数量变化,输出日志
  2550. if (currentAckCount != lastAckCount) {
  2551. FINFO("[WaitForSubscriptionComplete] {$} - Pending ack count: {$}", clientId, currentAckCount);
  2552. lastAckCount = currentAckCount;
  2553. }
  2554. // 如果没有待处理的ack,说明所有订阅都已完成
  2555. if (currentAckCount == 0) {
  2556. DWORD elapsed = GetTickCount() - startTime;
  2557. FINFO("[WaitForSubscriptionComplete] {$} - All subscriptions completed in {$}ms",
  2558. clientId, elapsed);
  2559. return true;
  2560. }
  2561. // 短暂休眠后继续轮询
  2562. usleep(pollIntervalMs * 1000);
  2563. }
  2564. // 超时
  2565. int finalAckCount = pMqttClient->mqtt_ack_handler_number;
  2566. FERROR("[WaitForSubscriptionComplete] {$} - Timeout after {$}ms, still have {$} pending acks",
  2567. clientId, timeoutMs, finalAckCount);
  2568. return false;
  2569. }
  2570. // 等待Broker完成路由表更新 - 可配置延时
  2571. // 通过环境变量 MQTT_BROKER_ROUTING_DELAY_MS 配置,默认200ms
  2572. LOGICDEVICE_API DWORD WaitForBrokerRouting(const char* clientId)
  2573. {
  2574. static int brokerDelayMs = -1; // 静态变量,只读取一次环境变量
  2575. if (brokerDelayMs == -1) {
  2576. const char* envDelay = getenv("MQTT_BROKER_ROUTING_DELAY_MS");
  2577. if (envDelay != nullptr && atoi(envDelay) > 0) {
  2578. brokerDelayMs = atoi(envDelay);
  2579. FINFO("[WaitForBrokerRouting] Using custom delay from environment: {$}ms", brokerDelayMs);
  2580. } else {
  2581. brokerDelayMs = 100; // 默认100ms,足够Broker处理路由表更新
  2582. FINFO("[WaitForBrokerRouting] Using default delay: {$}ms (set MQTT_BROKER_ROUTING_DELAY_MS to customize)", brokerDelayMs);
  2583. }
  2584. }
  2585. if (clientId != nullptr) {
  2586. FINFO("[WaitForBrokerRouting] {$} - Waiting {$}ms for Broker to process subscription routing",
  2587. clientId, brokerDelayMs);
  2588. }
  2589. usleep(brokerDelayMs * 1000);
  2590. return brokerDelayMs;
  2591. }
  2592. //主题订阅取消
  2593. LOGICDEVICE_API int UnSubscribe(ccos_mqtt_connection* hConnection, const char* pszTopic)
  2594. {
  2595. if (hConnection == nullptr)
  2596. {
  2597. return 0;
  2598. }
  2599. mqtt_client* pMqttClient = (mqtt_client*)std::get<MQTT_CLT_ID>(*hConnection);
  2600. //if (!pMqttClient->is_connected()) {
  2601. // //FERROR( " MQTT connection lost at subscribe %s ", topic);
  2602. // return 0;
  2603. //}
  2604. //MQTTSubscribe_options opts = MQTTSubscribe_options_initializer;
  2605. //auto ret = pMqttClient->unsubscribe(pszTopic);
  2606. mqtt_topic_list* pTopicList = std::get<MQTT_TIPIC_LIST_ID>(*hConnection);
  2607. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*hConnection);
  2608. pLock->Thread_Lock();
  2609. //MQTTAsync_responseOptions resp;
  2610. pTopicList->remove(pszTopic);
  2611. int rc = MQTT_SUCCESS_ERROR;
  2612. DWORD dwTick = GetTickCount();
  2613. int nTryTimes = 0;
  2614. do
  2615. {
  2616. int ret = mqtt_unsubscribe(pMqttClient, pszTopic);
  2617. FWARN("mqtt {$} Unsubscribe {$} return {$}", std::get<CLINET_ID_ID>(*hConnection), pszTopic, ret);
  2618. } while (rc != MQTT_SUCCESS_ERROR && GetTickCount() - dwTick < 100);
  2619. pLock->Thread_UnLock();
  2620. return 2;
  2621. }
  2622. //往指定主题发送CCOS协议包整包,使用临时创建连接,仅发送,不接收
  2623. LOGICDEVICE_API int PublishMsg(ResDataObject* pCmd, const char* pszTopic, const char* pszSenderName, DWORD dwTimeout)
  2624. {
  2625. char pszClientID[256];
  2626. snprintf(pszClientID, sizeof(pszClientID), "TEMP_%s_%d_0X%08lX",
  2627. (pszSenderName == nullptr) ? "ANONYMOUS" : pszSenderName,
  2628. getpid(), GetCurrentThreadId());
  2629. ccos_mqtt_connection* connObj = NewConnection(pszClientID, [](ResDataObject*, const char*, void* conn) {
  2630. });
  2631. mqtt_client* pConn = (mqtt_client*)std::get<MQTT_CLT_ID>(*connObj);
  2632. PacketAnalizer::UpdatePacketTopic(pCmd, pszTopic, pszClientID);
  2633. //MQTTAsync_responseOptions resp = MQTTAsync_responseOptions_initializer;
  2634. string pLoad = pCmd->encode();
  2635. int rc = PublishActionWithoutLock(pLoad, pszTopic, pConn, pszSenderName);
  2636. std::cout << "CLT [" << pszClientID << "] at " << CurrentDateTime() << " Publish to [" << pszTopic << "] result " << rc << endl;
  2637. FDEBUG("CLT {$} Publish to {$} send result {$}", pszClientID, pszTopic, rc);
  2638. CloseConnection(connObj);
  2639. return rc;
  2640. }
  2641. //往指定主题发送CCOS协议包整包,使用已创建的连接发送
  2642. LOGICDEVICE_API int PublishAction(ResDataObject* pAction, const char* pszTopic, ccos_mqtt_connection* hConnection, DWORD dwTimeout)
  2643. {
  2644. if (hConnection == nullptr)
  2645. {
  2646. FDEBUG("Who ????? Publish to {$} Action Body: {$}", pszTopic, pAction->encode());
  2647. std::cout << CurrentDateTime() << "Who ????? " << "Publish to [" << pszTopic << "] Action Body: "<< pAction->encode() << endl; //<< pAction->encode()
  2648. return 0;
  2649. }
  2650. std::cout << CurrentDateTime()<<" " << std::get<CLINET_ID_ID>(*hConnection) << " Publish Action to [" << pszTopic << "] Action Body: " << endl; //<< pAction->encode()
  2651. string topic = pszTopic;
  2652. if (topic.length() <= 0)
  2653. {
  2654. FWARN("ignore empty topic packet {$}", pAction->encode());
  2655. return 2;
  2656. }
  2657. mqtt_client* pMqttClient = (mqtt_client*)std::get<MQTT_CLT_ID>(*hConnection);
  2658. //if (!pMqttClient->is_connected()) {
  2659. // //FERROR( " MQTT connection lost at subscribe %s ", topic);
  2660. // return 0;
  2661. //}
  2662. std::string client_id = std::get<CLINET_ID_ID>(*hConnection);
  2663. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*hConnection);
  2664. pLock->Thread_Lock();
  2665. FDEBUG("{$} Publish Action to {$} Action Body: {$}", std::get<CLINET_ID_ID>(*hConnection), pszTopic, pAction->encode());
  2666. //string org_publisher = PacketAnalizer::GetPacketPublisher(pAction);
  2667. //if(org_publisher.length() <= 0)
  2668. PacketAnalizer::UpdatePacketTopic(pAction, pszTopic, client_id.c_str() );
  2669. ResDataObject* pPacket = new ResDataObject();
  2670. mqtt_msg_list* pList = std::get<MSG_LIST_ID>(*hConnection);
  2671. pPacket->add(pszTopic, pAction->encode());
  2672. //FDEBUG(" {$} Try push packet to Send list: {$}", client_id, pPacket->encode());
  2673. pList->push_back(pPacket);
  2674. sem_post(std::get<SEMAPHORE_HANDLE_ID>(*hConnection));
  2675. std::cout << "try publish " << pAction->encode() << endl;
  2676. //pMqttClient->publish(pszTopic, pAction->encode());
  2677. /*
  2678. //pConn->publish(pszTopic, pCmd->encode());
  2679. std::cout << "try publish " << pAction->encode() << endl;
  2680. const char* pLoad = pAction->encode();
  2681. int len = strlen(pLoad);
  2682. //MQTTAsync_responseOptions resp;
  2683. //MQTTAsync_responseOptions resp = MQTTAsync_responseOptions_initializer;
  2684. mqtt_message_t msg;
  2685. memset(&msg, 0, sizeof(msg));
  2686. msg.payload = (void*)pLoad;
  2687. msg.qos = MQTT_QOS;
  2688. msg.payloadlen = len;
  2689. int rc = MQTT_SUCCESS_ERROR;
  2690. DWORD dwTick = GetTickCount();
  2691. int nTryTimes = 0;
  2692. do
  2693. {
  2694. rc = mqtt_publish(pMqttClient, pszTopic, &msg);
  2695. nTryTimes++;
  2696. if (rc != MQTT_SUCCESS_ERROR)
  2697. {
  2698. FINFO("try mqtt_publish ret {$} do mqtt reconnect .. {$}",rc, client_id);
  2699. //mqtt_do_reconnect(pMqttClient);
  2700. mqtt_disconnect(pMqttClient);
  2701. rc = mqtt_connect(pMqttClient);
  2702. if (rc == MQTT_SUCCESS_ERROR)
  2703. {
  2704. resubscribe_topic(pMqttClient, pMqttClient->mqtt_conn_context);
  2705. FINFO("mqtt_connect ret {$} do mqtt resubscribe {$}", rc, client_id);
  2706. }
  2707. Sleep(2);
  2708. }
  2709. } while (rc != MQTT_SUCCESS_ERROR && GetTickCount() - dwTick < dwTimeout);
  2710. //std::cout << "CLT [" << pszClientID << "] at " << CurrentDateTime() << " Publish to [" << pszTopic << "] result " << rc << endl;
  2711. FINFO("CLT {$} PublishAction to {$} send Times {$} result {$}", client_id, pszTopic, nTryTimes, rc);
  2712. //int rc = MQTTAsync_send(pMqttClient, pszTopic, len, pLoad, 0, 0, &resp);
  2713. //std::cout << "CLT [" << client_id << "] at " << CurrentDateTime() << " Use mqtt_client " << (UINT64)pMqttClient << " Publish to [" << pszTopic << "] Send result " << rc << endl;
  2714. if (rc < 0)
  2715. {
  2716. FERROR("{$} PublishAction failed {$} body: {$}", client_id, pszTopic, rc, pLoad);
  2717. //std::cout << " ErrorCode " << rc << " Send Msg : " << pLoad << endl;
  2718. pLock->Thread_UnLock();
  2719. return rc;
  2720. }*/
  2721. //MQTTResponse resp = MQTTClient_publish5(pMqttClient, pszTopic, strlen(pLoad), pLoad, 0, 0, NULL, NULL);
  2722. //std::cout << "CLT [" << client_id << "] at " << CurrentDateTime() << " Publish to [" << pszTopic << "] result " << resp.reasonCode << endl;
  2723. FDEBUG("CLT {$} PublishAction to {$} Send List has {$} packets ", client_id, pszTopic, pList->size());
  2724. pLock->Thread_UnLock();
  2725. return 2;
  2726. }
  2727. //往指定主题发送Action包,携带参数,并指定答复的Topic,异步模式处理Resp,需要在对应连接的回调中处理
  2728. int PublishActionWithoutLock(string& message, const char* pszTopic, mqtt_client* pMqttClient, std::string client_id, mqtt_qos_t qos)
  2729. {
  2730. const int dwTimeout = 500;
  2731. if (pMqttClient == nullptr)
  2732. {
  2733. FERROR("Who ????? Publish 2 to {$} Action {$} Body: {$}", pszTopic, message);
  2734. return 0;
  2735. }
  2736. FDEBUG("{$} Publish with qos[{$}] Action 2 to {$} Body: {$} ", client_id, (int)qos, pszTopic, message);
  2737. std::string messageCopy = message;
  2738. const char* pLoad = messageCopy.c_str();
  2739. int len = messageCopy.length();
  2740. mqtt_message_t msg;
  2741. memset(&msg, 0, sizeof(msg));
  2742. msg.payload = (void*)pLoad;
  2743. msg.payloadlen = len;
  2744. msg.qos = qos;
  2745. msg.retained = 0;
  2746. int rc = MQTT_SUCCESS_ERROR;
  2747. DWORD dwTick = GetTickCount();
  2748. int nTryTimes = 0;
  2749. do
  2750. {
  2751. rc = mqtt_publish(pMqttClient, pszTopic, &msg);
  2752. nTryTimes++;
  2753. if (rc != MQTT_SUCCESS_ERROR)
  2754. {
  2755. FWARN("try mqtt_publish ret {$} do mqtt reconnect .. {$}", rc, client_id);
  2756. //mqtt_do_reconnect(pMqttClient);
  2757. ccos_mqtt_connection* hConnection = (ccos_mqtt_connection*)pMqttClient->mqtt_conn_context;
  2758. mqtt_disconnect(pMqttClient);
  2759. /*mqtt_set_resubscribe_handler(pMqttClient, resubscribe_topic);
  2760. mqtt_connect(pMqttClient);*/
  2761. mqtt_release(pMqttClient);
  2762. pMqttClient = nullptr;
  2763. usleep(10000 * 1000);
  2764. pMqttClient = InnerConnect(hConnection);
  2765. //int rc = MQTT_SUCCESS_ERROR;// mqtt_connect(pconn);
  2766. if (pMqttClient != nullptr)
  2767. {
  2768. break;
  2769. //std::get<MQTT_CLT_ID>(*hConnection) = pMqttClient;
  2770. //resubscribe_topic(pMqttClient, hConnection);
  2771. //FWARN("mqtt_connect ret {$} do mqtt resubscribe {$}", rc, std::get<CLINET_ID_ID>(*hConnection));
  2772. }
  2773. }
  2774. } while (rc != MQTT_SUCCESS_ERROR && (nTryTimes <= 2 || GetTickCount() - dwTick < dwTimeout));
  2775. cout << CurrentDateTime() << " CLT " << client_id.c_str() << " PublishAction to " << pszTopic << " send Times " << nTryTimes << " result " << rc << endl;
  2776. FDEBUG("CLT {$} PublishAction to {$} send Times {$} result {$}", client_id, pszTopic, nTryTimes, rc);
  2777. if (rc < 0)
  2778. {
  2779. FERROR("{$} PublishAction {$} failed {$} body: {$}", client_id, pszTopic, rc, pLoad);
  2780. return rc;
  2781. }
  2782. return 2;
  2783. }
  2784. /*
  2785. /// <summary>
  2786. /// 往指定主题发送Action包,携带参数,并指定答复的Topic,同步等待resp,
  2787. /// 超时没收到应答返回失败,
  2788. /// 复用链接时须小心,该函数会接管回调函数,结束后恢复
  2789. /// </summary>
  2790. /// <param name="pAction">要发送的命令Action名</param>
  2791. /// <param name="pContext">命令携带的参数</param>
  2792. /// <param name="pszTopic">要发送的目标topic</param>
  2793. /// <param name="pszRespTopic">本次请求的应答接收Topic</param>
  2794. /// <param name="resObj">应答返回的参数结果</param>
  2795. /// <param name="dwWaitTime">等待超时时间</param>
  2796. /// <param name="hConnection">复用的MQTT链接句柄</param>
  2797. /// <param name="onmsg">复用的链接的消息处理函数</param>
  2798. /// <returns>成功返回2,其他返回错误码</returns>
  2799. LOGICDEVICE_API int ActionAndRespWithConnection(ccos_mqtt_connection* hConnection, const char* pAction, ResDataObject& req, ResDataObject* pContext, const char* pszTopic, const char* pszRespTopic,
  2800. ResDataObject& resObj, DWORD dwWaitTime)
  2801. {
  2802. std::cout << CurrentDateTime() << std::get<CLINET_ID_ID>(*hConnection) << "\nAction2 : " << pAction << " to " << pszTopic << endl;// << "\n Action Body: " << " Context " << pContext->encode() << endl << endl; //<< req.encode()
  2803. if (pszRespTopic != nullptr)
  2804. PacketAnalizer::UpdateContextTopic(pContext, pszRespTopic);
  2805. if (hConnection == nullptr)
  2806. {
  2807. return 0;
  2808. }
  2809. mqtt_client* pMqttClient = (mqtt_client*)std::get<MQTT_CLT_ID>(*hConnection);
  2810. //if (!pMqttClient->is_connected()) {
  2811. // //FERROR( " MQTT connection lost at subscribe %s ", topic);
  2812. // return 0;
  2813. //}
  2814. HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  2815. //SubscribeTopic()
  2816. auto action_func = [&resObj, pszRespTopic, pMqttClient, hConnection, hEvent](void* context, char* topicName, int topicLen, MQTTClient_message* message) {
  2817. string topic = topicName;//msg->get_topic().c_str();
  2818. if (strcmp(pszRespTopic, topic.c_str()) == 0) {
  2819. std::cout << CurrentDateTime() << std::get<CLINET_ID_ID>(*hConnection) << " get Right Resp by " << topic << endl;
  2820. //应答到了,处理
  2821. ResDataObject req;
  2822. req.decode((const char*)message->payload);
  2823. PacketAnalizer::GetPacketContext(&req, resObj);
  2824. SetEvent(hEvent);
  2825. //处理结束 将函数指针换回去
  2826. void* oldFuncPointer = std::get<MQTT_MSG_ARRIVED_ID>(*hConnection);
  2827. //pMqttClient->set_message_callback(*(mqtt::async_client::message_handler*)oldFuncPointer);
  2828. MQTTAsync_setCallbacks(pMqttClient, hConnection, connlost, msgarrvd, NULL);
  2829. }
  2830. else
  2831. {
  2832. //MQTTClient_messageArrived *orgfunc = (MQTTClient_messageArrived*)std::get<MQTT_MSG_ARRIVED_ID>(*hConnection);
  2833. (msgarrvd)(context, topicName, topicLen, message);
  2834. }
  2835. };
  2836. //接管回调
  2837. // pMqttClient->set_message_callback(action_func);
  2838. MQTTClient_setCallbacks(pMqttClient, hConnection, connlost, (MQTTClient_messageArrived*)&action_func, delivered);
  2839. //pMqttClient->subscribe(pszRespTopic, 1);
  2840. MQTTSubscribe_options opts = MQTTSubscribe_options_initializer;
  2841. MQTTProperties prop = MQTTProperties_initializer;
  2842. std::cout << "mqtt 【" << std::get<CLINET_ID_ID>(*hConnection) << " 】Subscribe " << pszTopic << endl;
  2843. //pMqttClient->subscribe(pszTopic, 1, opts);
  2844. MQTTClient_subscribe5(pMqttClient, pszTopic, 1, NULL, NULL);
  2845. PacketAnalizer::UpdatePacketTopic(&req, pszTopic, std::get<CLINET_ID_ID>(*hConnection));
  2846. //pMqttClient->publish(pszTopic, req.encode());
  2847. MQTTClient_message pubmsg = MQTTClient_message_initializer;
  2848. MQTTClient_message* m = NULL;
  2849. MQTTClient_deliveryToken dt;
  2850. MQTTProperty property;
  2851. property.identifier = MQTTPROPERTY_CODE_USER_PROPERTY;
  2852. property.value.data.data = "test user property";
  2853. property.value.data.len = (int)strlen(property.value.data.data);
  2854. property.value.value.data = "test user property value";
  2855. property.value.value.len = (int)strlen(property.value.value.data);
  2856. MQTTProperties properties = MQTTProperties_initializer;
  2857. MQTTProperties_add(&properties, &property);
  2858. //pConn->publish(pszTopic, pCmd->encode());
  2859. const char* pLoad = req.encode();
  2860. MQTTResponse resp = MQTTClient_publish5(pMqttClient, pszTopic, strlen(pLoad), pLoad, 0, 0, &properties, &dt);
  2861. std::cout << "CLT [" << std::get<CLINET_ID_ID>(*hConnection) << "] at " << CurrentDateTime() << " Publish x to [" << pszTopic << "] result " << resp.reasonCode << endl;
  2862. DWORD ret = WaitForSingleObject(hEvent, dwWaitTime);
  2863. if (ret == WAIT_OBJECT_0) {
  2864. //等到应答了
  2865. return 2;
  2866. }
  2867. return 0;
  2868. }
  2869. */
  2870. /// <summary>
  2871. /// 往指定主题发送Action包,携带参数,复用Resp的Topic,同步等待resp,超时没收到应答返回失败,
  2872. /// </summary>
  2873. /// <param name="hConnection"></param>
  2874. /// <param name="pAction"></param>
  2875. /// <param name="pContext"></param>
  2876. /// <param name="pszTopic"></param>
  2877. /// <param name="resObj"></param>
  2878. /// <param name="hEvent"></param>
  2879. /// <param name="dwWaitTime"></param>
  2880. /// <returns></returns>
  2881. LOGICDEVICE_API int ActionAndRespWithConnDefalt(ccos_mqtt_connection* hConnection, const char* pAction, ResDataObject& req, ResDataObject* pContext,
  2882. const char* pszTopic, ResDataObject& resObj, DWORD dwWaitTime)
  2883. {
  2884. // QoS=2消息握手需要时间(PUBLISH→PUBREC→PUBREL→PUBCOMP)
  2885. // 连续发送时增加50ms延时,避免握手状态冲突
  2886. const std::string client_id = std::get<CLINET_ID_ID>(*hConnection);
  2887. static std::map<std::string, DWORD> lastSendTime;
  2888. DWORD now = GetTickCount();
  2889. DWORD elapsed = (lastSendTime.count(client_id) > 0) ? (now - lastSendTime[client_id]) : 1000;
  2890. if (elapsed < 50) {
  2891. DWORD sleepMs = 50 - elapsed;
  2892. FINFO("[ActionAndRespWithConnDefalt] {$} - Sleeping {$}ms to avoid QoS handshake conflict", client_id, sleepMs);
  2893. usleep(sleepMs * 1000);
  2894. }
  2895. lastSendTime[client_id] = GetTickCount();
  2896. std::cout << CurrentDateTime() << std::get<CLINET_ID_ID>(*hConnection) << "\nAction : " << pAction << " to " << pszTopic << "\n Action Body: " << " Context " << pContext->encode() << endl << endl; //<< req.encode()
  2897. if (hConnection == nullptr)
  2898. {
  2899. return 0;
  2900. }
  2901. DWORD dwTick = GetTickCount();
  2902. mqtt_client* pMqttClient = (mqtt_client*)std::get<MQTT_CLT_ID>(*hConnection);
  2903. std::shared_ptr<LinuxEvent> hEvent = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, false);
  2904. ResDataObject resContext;
  2905. string strResObject;
  2906. char* pszPad = 0;
  2907. char* pszPad2 = 0;
  2908. auto func = [pAction, hConnection, &pszPad, &resObj, &pszPad2, dwTick, dwWaitTime](ResDataObject* rsp) -> bool {
  2909. FINFO("{$} try check action resp {$} compared with {$}", std::get<CLINET_ID_ID>(*hConnection), pAction, PacketAnalizer::GetPacketKey(rsp));
  2910. std::cout << CurrentDateTime() << std::get<CLINET_ID_ID>(*hConnection) << " try check action resp [" << pAction << "] compared with " << PacketAnalizer::GetPacketKey(rsp).c_str() << endl;
  2911. if (PacketAnalizer::GetPacketType(rsp) == PACKET_TYPE_RES &&
  2912. strcmp(pAction, PacketAnalizer::GetPacketKey(rsp).c_str()) == 0)
  2913. {
  2914. if (GetTickCount() - dwTick < dwWaitTime)
  2915. {
  2916. FDEBUG("ActionAndRespWithConnDefalt Packet Content {$} content {$}", PacketAnalizer::GetPacketKey(rsp), rsp->encode());
  2917. resObj = *rsp;
  2918. return true;
  2919. }
  2920. else
  2921. {
  2922. FWARN("ActionAndRespWithConnDefalt Packet Content {$} Timeout content {$}", PacketAnalizer::GetPacketKey(rsp), rsp->encode());
  2923. return false;
  2924. }
  2925. std::cout << " : " << PacketAnalizer::GetPacketKey(rsp) << " content " << rsp->encode() << endl;
  2926. }
  2927. FDEBUG("ActionAndRespWithConnDefalt what ? {$} content {$}", PacketAnalizer::GetPacketKey(rsp), rsp->encode());
  2928. std::cout << "ActionAndRespWithConnDefalt what ? " << PacketAnalizer::GetPacketKey(rsp) << endl;
  2929. return false;
  2930. };
  2931. CcosLock* pLock = std::get<CONN_SEND_LOCK_ID>(*hConnection);
  2932. pLock->Thread_Lock();
  2933. FDEBUG("{$} ActionAndRespWithConnDefalt {$} to Topic {$} body {$} ", std::get<CLINET_ID_ID>(*hConnection), pAction, pszTopic, pContext->encode());
  2934. ccos_mqtt_msg_filter* pfilter = (ccos_mqtt_msg_filter*)std::get<MSG_HOOK_ID>(*hConnection);
  2935. ResDataObject *resActions = std::get<FILTER_RES_OBJ_ID>(*pfilter);
  2936. resActions->add(pAction, pszTopic);
  2937. std::get<FILTER_HANDLE_ID>(*pfilter) = hEvent;
  2938. std::get<FILTER_FUNC_ID>(*pfilter) = func;
  2939. PacketAnalizer::UpdatePacketTopic(&req, pszTopic, std::get<CLINET_ID_ID>(*hConnection).c_str());
  2940. const char* pLoad = req.encode();
  2941. ResDataObject* pPacket = new ResDataObject();
  2942. mqtt_msg_list* pList = std::get<MSG_LIST_ID>(*hConnection);
  2943. pPacket->add(pszTopic, pLoad);
  2944. FDEBUG(" {$} Try push packet to Send list: {$}", client_id, pPacket->encode());
  2945. pList->push_back(pPacket);
  2946. sem_post(std::get<SEMAPHORE_HANDLE_ID>(*hConnection));
  2947. /*
  2948. mqtt_message_t msg;
  2949. memset(&msg, 0, sizeof(msg));
  2950. msg.payload = (void*)pLoad;
  2951. msg.qos = MQTT_QOS;
  2952. msg.payloadlen = strlen(pLoad);
  2953. //int rc = mqtt_publish(pMqttClient, pszTopic, &msg);
  2954. int rc = MQTT_SUCCESS_ERROR;
  2955. dwTick = GetTickCount();
  2956. int nTryTimes = 0;
  2957. do
  2958. {
  2959. rc = mqtt_publish(pMqttClient, pszTopic, &msg);
  2960. nTryTimes++;
  2961. if (rc != MQTT_SUCCESS_ERROR)
  2962. {
  2963. FINFO("try mqtt_publish ret {$} do mqtt reconnect 3.. {$}", rc, client_id);
  2964. //mqtt_do_reconnect(pMqttClient);
  2965. mqtt_disconnect(pMqttClient);
  2966. rc = mqtt_connect(pMqttClient);
  2967. if (rc == MQTT_SUCCESS_ERROR)
  2968. {
  2969. resubscribe_topic(pMqttClient, pMqttClient->mqtt_conn_context);
  2970. FINFO("mqtt_connect ret {$} do mqtt resubscribe {$}", rc, client_id);
  2971. }
  2972. Sleep(2);
  2973. }
  2974. } while (rc != MQTT_SUCCESS_ERROR && GetTickCount() - dwTick < 3);
  2975. if (nTryTimes >= 1)
  2976. FINFO("CLT {$} Publish to {$} send Times {$} result {$}", std::get<CLINET_ID_ID>(*hConnection), pszTopic, nTryTimes, rc);
  2977. */
  2978. pLock->Thread_UnLock();
  2979. dwTick = GetTickCount() - dwTick;
  2980. //FINFO("CLT {$} Publish to {$} Use TID {$} Use Time {$} result {$} ", std::get<CLINET_ID_ID>(*hConnection), pszTopic, GetCurrentThreadId(), dwTick, rc);
  2981. std::cout << "CLT [" << std::get<CLINET_ID_ID>(*hConnection) << "] at " << CurrentDateTime() << " Publish to [" << pszTopic << "] Use TID [" << GetCurrentThreadId() << "] Use Time[" << dwTick << "]ms" << endl;
  2982. dwTick = GetTickCount();
  2983. DWORD ret = hEvent->Wait(dwWaitTime);
  2984. if (ret) {
  2985. //等到应答了
  2986. dwTick = GetTickCount() - dwTick;
  2987. pLock->Thread_Lock();
  2988. ResDataObject* pResp = std::get<FILTER_RESPONS_OBJ_ID>(*pfilter);
  2989. for (int x = 0; x < pResp->size(); x++)
  2990. {
  2991. ResDataObject r = (*pResp)[x];
  2992. if (string(pAction) == string(pResp->GetKey(x)) && PacketAnalizer::GetPacketIdx(&req) == PacketAnalizer::GetPacketIdx(&r))
  2993. {
  2994. resObj = r;
  2995. pResp->eraseOneOf(pAction, x);
  2996. break;
  2997. }
  2998. }
  2999. pLock->Thread_UnLock();
  3000. std::cout << "CLT [" << std::get<CLINET_ID_ID>(*hConnection) << "] at " << CurrentDateTime() << " try [" << pszTopic << "] getresp ok Use Time[" << dwTick << "]ms" << endl;
  3001. FDEBUG("CLT {$} try {$} getresp ok Use Time {$}", std::get<CLINET_ID_ID>(*hConnection), pszTopic, dwTick);
  3002. //std::get<FILTER_RES_OBJ_ID>(*pfilter) = nullptr;
  3003. return 2;
  3004. }
  3005. //std::get<FILTER_FUNC_ID>(*pfilter) = nullptr;
  3006. //resObj.decode(strResObject.c_str());
  3007. FERROR("CLT {$} try {$} getresp timeout ", std::get<CLINET_ID_ID>(*hConnection), pszTopic );
  3008. std::cout << "CLT [" << std::get<CLINET_ID_ID>(*hConnection) << "] at " << CurrentDateTime() << "try [" << pszTopic << "] " << endl;
  3009. //std::get<FILTER_RES_OBJ_ID>(*pfilter) = nullptr;
  3010. return 0;
  3011. }
  3012. /// <summary>
  3013. /// 新建MQTT连接发送Ation并等待应答
  3014. /// </summary>
  3015. /// <param name="pAction"></param>
  3016. /// <param name="pContext"></param>
  3017. /// <param name="pszTopic"></param>
  3018. /// <param name="pszRespTopic"></param>
  3019. /// <param name="resObj"></param>
  3020. /// <param name="dwWaitTime"></param>
  3021. /// <param name="pszSenderName"></param>
  3022. /// <returns></returns>
  3023. LOGICDEVICE_API int ActionAndResp(const char* pAction, ResDataObject* pContext, const char* pszTopic, const char* pszRespTopic, ResDataObject& resObj,
  3024. DWORD dwWaitTime, const char* pszSenderName)
  3025. {
  3026. ResDataObject req;
  3027. if (pszRespTopic != nullptr)
  3028. PacketAnalizer::UpdateContextTopic(pContext, pszRespTopic);
  3029. //临时创建连接并发送和接收应答
  3030. char pszClientID[256];
  3031. snprintf(pszClientID, sizeof(pszClientID), "TEMP_%s_%d_0X%08lX",
  3032. (pszSenderName == nullptr) ? "ANONYMOUS" : pszSenderName,
  3033. getpid(), GetCurrentThreadId());
  3034. sem_t sem;
  3035. if (sem_init(&sem, 0, 0) != 0) {
  3036. return 0; // 如果初始化失败,返回0
  3037. }
  3038. std::cout << " ActionAndResp->NewConnection " << endl;
  3039. ccos_mqtt_connection* connObj = NewConnection(pszClientID, [&resObj, &sem](ResDataObject* req, const char* topic, void* conn) {
  3040. //应答到了,处理
  3041. PacketAnalizer::GetPacketContext(req, resObj);
  3042. sem_post(&sem);
  3043. });
  3044. ////发布消息,并等待应答
  3045. PublishAction(&req, pszTopic, connObj);
  3046. // 等待应答或超时
  3047. struct timespec ts;
  3048. clock_gettime(CLOCK_REALTIME, &ts);
  3049. ts.tv_sec += dwWaitTime / 1000; // 转换为秒
  3050. ts.tv_nsec += (dwWaitTime % 1000) * 1000000; // 转换为纳秒
  3051. // 等待信号量或者超时
  3052. int ret = 0;
  3053. while (ret == 0) {
  3054. ret = sem_timedwait(&sem, &ts); // 超时或者接收到信号量
  3055. if (ret == -1 && errno == ETIMEDOUT) {
  3056. // 超时
  3057. sem_destroy(&sem);
  3058. CloseConnection(connObj);
  3059. return 0; // 超时返回0
  3060. }
  3061. }
  3062. // 等到应答了
  3063. sem_destroy(&sem); // 销毁信号量
  3064. CloseConnection(connObj);
  3065. return 2; // 返回2表示应答成功
  3066. }