Есть вот такая библиотека. Изращался с неким бриджем для работы 1С
с MQTT. Пользовал правда UDP протокол для связи. Типа запущал свою
приложуху сервером, который перенапралял UDP пакеты MQTT брокеру и
наоборот). Вместо UDP можно заюзать UART. А извращался потому как
это было еще во времена XP и совокупить библиотеку удалось только с
компилятором PellesC ;)
/******************************************************************************* служебная строка при запуске: mqservice.exe m24.cloudmqtt.com:13310 dazkzemv AWz0stwtWlNX qwert/bsz/90788555/inp сообщения, приходящие в 1C GSevent: 15,0,qwert/bsz/90788555/inp,f5dfdfdfdfdfdfdf337833 - приняты данные подписки 15,1,connection lost - нет соединения с mqtt сервером 15,2,MQTT connected - произошло соедиенеие с mqtt сервером 15,3,Service stopped - стоп сервиса команды из компа: mqttqwert/bsz/90788555/inp,f5dfdfdfdfdfdfdf337833 - опубликовать в топик mqttstop_mqttbr - завершение работы моста ответы на команды: mqtt0 - ок - команда выполнена mqtt1 - error - соединение с mqtt сервером потеряно, команда НЕ выполнена mqtt2 - error - неправильная команда, команда НЕ выполнена //mqtt3 - error (в программе SCGiga1C) - таймаут/в сети не найден мост, команда НЕ выполнена В SCGiga1C: команда: 15 - Опубликовать строку в топик MQTT сервера Giga.str_for_cmd = "holding/bsz/90788555/inp,data1,data2...." ; // строка c данными для публикации. До первой запятой - имя топика, остальное данные (не более 500 символов) error = Giga.cmd_to_simcon(ip_addr,15,0); // коды ошибок: 0 -OK 1- Потеряна связь с MQTT сервером 2 - Неверная строка 3 - Мост MQTT не найден в сети/не ответил в течении 300 мс *******************************************************************************/ #include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #include "windows.h" #include <time.h> #define IN_PORT 31203 // приемный порт mqttbr #define PORT_1C 31202 // UDP порт для 1C event #define VID 0x16c0 #define PID 0x05df #define MSGBUFSIZE 1024 char in_msgbuf[MSGBUFSIZE]; char out_msgbuf[MSGBUFSIZE]; struct sockaddr_in addr_in; struct sockaddr_in addr_out; int fd_in; int fd_out; #define QOS 0 MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; volatile int fl_connect=0; volatile int fl_stop=0; volatile int fl_msg=0; volatile MQTTClient_deliveryToken deliveredtoken; int cnt=0; char url[200]="tcp://"; void exit_err(int err) { // printf("\nPress any key..."); // getchar(); exit(err); } void delivered(void *context, MQTTClient_deliveryToken dt) { // printf("Message with token value %d delivery confirmed\n", dt); deliveredtoken = dt; } int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { int i; char* payloadptr; char* mb_ptr; // printf(" topic: %s\n", topicName); while(fl_msg) Sleep(10); // sprintf(out_msgbuf,"15,0,"); mb_ptr=out_msgbuf; *mb_ptr++ ='1'; *mb_ptr++ ='5'; *mb_ptr++ =','; *mb_ptr++ ='0'; *mb_ptr++ =','; payloadptr = topicName; while(1) { *mb_ptr++ =(*payloadptr++); if (*payloadptr==0) break; } *mb_ptr++ =','; payloadptr = message->payload; for(i=0; i<message->payloadlen; i++) { *mb_ptr++ =(*payloadptr++); } *mb_ptr++ =0; fl_msg=1; // printf("%s\n", out_msgbuf); MQTTClient_freeMessage(&message); MQTTClient_free(topicName); return 1; } void connlost(void *context, char *cause) { fl_connect=0; } #pragma warn (disable : 2134) DWORD WINAPI ThreadFunc(LPVOID p) { int addrlen = sizeof(addr_in); int nbytes; char* ptr; char topic[200]; while(1) { nbytes = recvfrom(fd_in, in_msgbuf, MSGBUFSIZE, 0, (struct sockaddr *) &addr_in, &addrlen); if (nbytes > 0) { in_msgbuf[nbytes]=0; // добавим конец строки if((in_msgbuf[0]=='m')&&(in_msgbuf[1]=='b')&&(in_msgbuf[2]=='g')&&(in_msgbuf[3]=='I')&&(in_msgbuf[4]=='G')&&(in_msgbuf[5]=='a')) // проверим сигнатуру "mbgIGa" { if(strstr(in_msgbuf,"mbgIGaSTOP") !=NULL) // проверим команду остановки сервиса "stop" { fl_stop=1; sprintf(in_msgbuf, "mbgIGa0"); } else { memmove(in_msgbuf, &in_msgbuf[6], nbytes-6+1); // Удалим сигнатуру "mbgIGa" ptr = strstr(in_msgbuf,","); if(ptr !=NULL) { *ptr=0; // заменим символ "," на 0 memcpy(topic, in_msgbuf, ptr-in_msgbuf+1); //printf("%s\n", topic); memmove(in_msgbuf, &in_msgbuf[ptr-in_msgbuf+1], nbytes-4+1-(ptr-in_msgbuf+1)); // //printf("%s\n", in_msgbuf); if (fl_connect!=0) { MQTTClient_publish(client, topic, strlen(in_msgbuf),in_msgbuf, 0, 0, NULL); sprintf(in_msgbuf, "mbgIGa0"); } else sprintf(in_msgbuf, "mbgIGa1"); // ошибка "нет связи" } else sprintf(in_msgbuf, "mbgIGa2"); // ошибка "некорректный топик"(нет разделителя ",") } nbytes = sendto( fd_in, in_msgbuf, strlen(in_msgbuf), 0, (struct sockaddr*) &addr_in, addrlen); } } } } int main(int argc, char* argv[]) { int i; FreeConsole(); // printf("%s\n",argv[0]); // exe // printf("%s\n",argv[1]); // сервер:порт // printf("%s\n",argv[2]); // топик // printf("%s\n",argv[3]); // ID // printf("%s\n",argv[4]); // login // printf("%s\n",argv[5]); // пароль // printf("\nPress any key..."); // getchar(); /////////////////////////// UDP init ///////////////////////////////////////////////// WSADATA wsaData; if (WSAStartup(0x0101, &wsaData)) { perror("Error WSAStartup"); exit_err(1); } fd_in = socket(AF_INET, SOCK_DGRAM, 0); // in socket if (fd_in < 0) { perror("Error IN socket"); exit_err(2); } int fd_out = socket(AF_INET, SOCK_DGRAM, 0); // out socket if (fd_out < 0) { perror("Error OUT socket"); exit_err(3); } u_int yes = 1; if (setsockopt(fd_in, SOL_SOCKET, SO_REUSEADDR, (char*) &yes, sizeof(yes)) < 0) { perror("Reusing ADDR failed"); exit_err(4); } memset(&addr_in, 0, sizeof(addr_in)); addr_in.sin_family = AF_INET; addr_in.sin_addr.s_addr = htonl(INADDR_ANY); // differs from sender addr_in.sin_port = htons(IN_PORT); // bind to receive address if (bind(fd_in, (struct sockaddr*) &addr_in, sizeof(addr_in)) < 0) { perror("bind"); exit_err(5); } memset(&addr_out, 0, sizeof(addr_out)); addr_out.sin_family = AF_INET; addr_out.sin_addr.s_addr = inet_addr("127.0.0.1"); addr_out.sin_port = htons(PORT_1C); HANDLE hThread; DWORD threadld; hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, &threadld ); if (hThread==NULL) { perror("Create thread error"); exit_err(6); } /////////////////////////////////////////////////////////////////////////////// HANDLE Test_Present = CreateMutex(NULL,TRUE,"mbsvs_Already_Present"); // защита от повторного запуска if(GetLastError() == ERROR_ALREADY_EXISTS) { //printf("MQService already running!\n"); exit_err(7); } if(argc<6) // если в командной строке меньше 6 аргументов { //printf("Bad arguments!\n"); exit_err(8); } strcat(url,argv[1]); // full URL // printf("client_id: %s\n ", url); MQTTClient_create(&client, url, argv[3], MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 60; conn_opts.cleansession = 1; conn_opts.username = argv[4]; conn_opts.password = argv[5]; conn_opts.connectTimeout = 5; MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered); fl_connect=0; sprintf(out_msgbuf,"15,4,service started"); sendto(fd_out, out_msgbuf , strlen(out_msgbuf ),0,(struct sockaddr*) &addr_out, sizeof(addr_out)); while(1) { if(fl_connect==0) { while(1) { //printf("Connect to server...\n"); if (MQTTClient_connect(client, &conn_opts) == MQTTCLIENT_SUCCESS) break; //printf("Connection error!\n"); sprintf(out_msgbuf,"15,1,server not connected"); sendto(fd_out, out_msgbuf , strlen(out_msgbuf ),0,(struct sockaddr*) &addr_out, sizeof(addr_out)); for (i=0;i<100;i++) { if(fl_stop) goto exit; Sleep(50); } } MQTTClient_subscribe(client, argv[2], QOS); //printf("Subscribed topic: %s\n", argv[2]); fl_connect=1; sprintf(out_msgbuf,"15,2,server connected"); sendto(fd_out, out_msgbuf , strlen(out_msgbuf ),0,(struct sockaddr*) &addr_out, sizeof(addr_out)); } else { if (fl_msg) { sendto(fd_out, out_msgbuf , strlen(out_msgbuf),0,(struct sockaddr*) &addr_out, sizeof(addr_out)); fl_msg=0; } else Sleep(10); } if(fl_stop) break; } exit: sprintf(out_msgbuf,"15,3,service stopped"); sendto(fd_out, out_msgbuf , strlen(out_msgbuf ),0,(struct sockaddr*) &addr_out, sizeof(addr_out)); MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); ReleaseMutex(Test_Present); CloseHandle(Test_Present); WSACleanup(); return (0); }