1 #include "UserLibSimulator.h"
3 #include "AlMar_mongoose-7-6.h"
7 static struct mg_mgr _mgr;
8 static pthread_t _mgr_thread;
9 static pthread_mutex_t _mgr_mutex=PTHREAD_MUTEX_INITIALIZER;
10 void* WssCheckSimulatorThread(
void* param);
12 #define MAX_AD_INPUTS 8
13 #define MAX_COUNTER_INPUTS 8
14 #define MAX_AD_OUTPUTS 8
15 #define MAX_PWM_OUTPUTS 8
21 int nDA,daValue[MAX_AD_OUTPUTS];
22 int nPWM,pWmValue[MAX_PWM_OUTPUTS],pwmPeriod[MAX_PWM_OUTPUTS];
29 int nAD,adValue[MAX_AD_INPUTS];
30 int nCounter,counterValue[MAX_COUNTER_INPUTS];
34 static struct ComputerState
38 } _computerStateThread,_computerStateUser;
41 void WssEventHandler(
struct mg_connection *conn,
int ev,
42 void *ev_data,
void *fn_data)
53 struct mg_tls_opts opts = {.ca = NULL};
54 mg_tls_init(conn, &opts);
60 struct mg_http_message *hm = (
struct mg_http_message *) ev_data;
61 mg_ws_upgrade(conn,hm,NULL);
66 printf(
"WS Open\n"); fflush(stdout);
67 *((
bool*) fn_data)=
true;
72 struct mg_ws_message *wm = (
struct mg_ws_message *) ev_data;
75 cJSON* json=cJSON_ParseWithLength(wm->data.ptr,wm->data.len);
76 pthread_mutex_lock(&_mgr_mutex);
79 _computerStateThread.in.changed=
true;
80 for (
int j=0;j<cJSON_GetArraySize(json);j++)
82 cJSON* item=cJSON_GetArrayItem(json,j);
84 const char* name=cJSON_GetStringValue(cJSON_GetObjectItem(item,
"name"));
85 const char* iotype=cJSON_GetStringValue(cJSON_GetObjectItem(item,
"iotype"));
86 if (iotype==NULL || strlen(iotype)==0)
88 if (strncmp(iotype,
"ad",2)==0)
90 int iAD=atoi(iotype+2);
91 if (iAD>=0 && iAD<_computerStateThread.in.nAD)
93 _computerStateThread.in.adValue[iAD]=cJSON_GetNumberValue(cJSON_GetObjectItem(item,
"value"));
98 else if (strncmp(iotype,
"di",2)==0)
100 int iDI=atoi(iotype+2);
101 if (cJSON_IsTrue(cJSON_GetObjectItem(item,
"value")))
102 _computerStateThread.in.dIn |= (1<<iDI);
104 _computerStateThread.in.dIn &= ~(1<<iDI);
109 pthread_mutex_unlock(&_mgr_mutex);
115 printf(
"WS Close\n"); fflush(stdout);
124 bool ProcessIsPresent(
const char* procName)
126 DWORD idProcess[1024];
129 if (! EnumProcesses(idProcess,1024*
sizeof(DWORD),&nProcesses))
133 nProcesses/=
sizeof(DWORD);
134 for (
int j=0;j<nProcesses && ! found;j++)
138 HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
140 FALSE, idProcess[j] );
148 char processName[1024];
150 if (count=GetProcessImageFileNameA(hProcess,processName,1024),count>0)
152 char* ptEnd=processName+count-strlen(procName);
153 if (strcmp(ptEnd,procName)==0 && ptEnd[-1]==
'\\' )
156 CloseHandle( hProcess );
163 int Simulator_ConnectWss(
const char* appName,
const char* userName,
const char* passwd,
const char* ip_address,
int port)
165 memset(&_computerStateThread,0,
sizeof(
struct ComputerState));
166 memset(&_computerStateUser,0,
sizeof(
struct ComputerState));
168 if (! ProcessIsPresent(
"MongooseWebServer.exe"))
170 printf(
"Simulator error: ejecute MongooseWebServer.exe antes de intentar la conexion\n"); fflush(stdout);
171 return CONNECT_ERROR_SERVER_NOT_RUNNING;
175 _computerStateThread.in.nAD=_computerStateUser.in.nAD=4;
178 struct mg_connection *c;
181 char s_url[256],user_pwd[256],user_pwd_base64[64+1];
182 #if MG_ENABLE_OPENSSL
183 sprintf(s_url,
"wss://%s:%d/Apps/%s/wss/%s/",ip_address,port,appName,userName);
185 sprintf(s_url,
"ws://%s:%d/Apps/%s/wss/%s/",ip_address,port,appName,userName);
187 sprintf(user_pwd,
"%s:%s",userName,passwd);
188 mg_base64_encode((
const unsigned char*) user_pwd,strlen(user_pwd),user_pwd_base64);
189 c = mg_ws_connect(&_mgr, s_url, WssEventHandler, &done,
"Authorization: Basic %.*s\r\n",64,user_pwd_base64);
192 for (tries=0;tries < 10 && (c && done ==
false); tries++)
194 mg_mgr_poll(&_mgr, 1000);
195 if (! done && time(NULL)-t > 2) {
196 printf(
"Simulator intentando conexion con %s\n",s_url); fflush(stdout);
197 c = mg_ws_connect(&_mgr, s_url, WssEventHandler, &done,
"Authorization: Basic %.*s\r\n",64,user_pwd_base64);
205 printf(
"Simulator conectado con %s\n",s_url); fflush(stdout);
206 pthread_create(&_mgr_thread,NULL,WssCheckSimulatorThread,NULL);
207 return CONNECT_IS_OK;
211 printf(
"Simulator no se puede conectar con %s. Compruebe configuracion\n",s_url); fflush(stdout);
212 return CONNECT_ERROR_SERVER_NOT_RESPONDING;
218 void* WssCheckSimulatorThread(
void* param)
222 mg_mgr_poll(&_mgr, 5);
223 pthread_mutex_lock(&_mgr_mutex);
224 if (_computerStateThread.in.changed)
226 _computerStateThread.in.changed=
false;
227 memcpy(&_computerStateUser.in,&_computerStateThread.in,
sizeof(
struct ComputerInputs));
229 if (_computerStateUser.out.changed)
231 cJSON* jsonOutput=cJSON_CreateObject();
232 if (_computerStateThread.out.dOut!=_computerStateUser.out.dOut)
234 cJSON_AddNumberToObject(jsonOutput,
"do",_computerStateUser.out.dOut);
236 _computerStateUser.out.changed=
false;
237 memcpy(&_computerStateThread.out,&_computerStateUser.out,
sizeof(
struct ComputerOutputs));
238 char* jsonTxt=cJSON_Print(jsonOutput);
239 for (
struct mg_connection *ptConn=_mgr.conns;ptConn!=NULL;ptConn=ptConn->next)
241 if (ptConn->is_client && ptConn->is_websocket)
243 mg_ws_send(ptConn,jsonTxt,strlen(jsonTxt)+1,WEBSOCKET_OP_TEXT);
248 cJSON_Delete(jsonOutput);
250 pthread_mutex_unlock(&_mgr_mutex);
254 int Simulator_ReadAD(
int ad_channel)
256 if (ad_channel<0 || ad_channel>=_computerStateUser.in.nAD)
259 pthread_mutex_lock(&_mgr_mutex);
260 v=_computerStateUser.in.adValue[ad_channel];
261 pthread_mutex_unlock(&_mgr_mutex);
266 int Simulator_ReadDI()
269 pthread_mutex_lock(&_mgr_mutex);
270 v=_computerStateUser.in.dIn;
271 pthread_mutex_unlock(&_mgr_mutex);
275 int Simulator_ReadDO()
278 pthread_mutex_lock(&_mgr_mutex);
279 v=_computerStateUser.out.dOut;
280 pthread_mutex_unlock(&_mgr_mutex);
284 void Simulator_WriteDO(
int value)
286 pthread_mutex_lock(&_mgr_mutex);
287 _computerStateUser.out.dOut=value;
288 _computerStateUser.out.changed=
true;
289 pthread_mutex_unlock(&_mgr_mutex);
294 void Simulator_Delay(
int value_ms)
299 HANDLE hTimers[N_MAX_TIMERS]={NULL,NULL,NULL,NULL};
301 VOID CALLBACK TimerCallback(PVOID lParam1,BOOLEAN timerOrWaitFired)
303 void (*userFn)() = (
void (*)()) lParam1;
307 int Simulator_SetTimerInterrupt(
int timer_number,
int tm_ms,
void (*Fn)())
309 if (timer_number<0 || timer_number>=N_MAX_TIMERS)
311 if (Fn==NULL && hTimers[timer_number]!=NULL)
313 DeleteTimerQueueTimer(NULL,hTimers[timer_number],NULL);
314 hTimers[timer_number]=NULL;
320 if(!CreateTimerQueueTimer( &hTimers[timer_number], NULL, (WAITORTIMERCALLBACK) TimerCallback,(PVOID) Fn, 0,tm_ms,WT_EXECUTEINTIMERTHREAD))
322 printf(
"CreateTimerQueueTimer failed (%d)\n", GetLastError());