Low-Energy Muon (LEM) Experiment  0.5.1
lemplug.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: lemplug.c
4  Created by: Andreas Suter
5 
6  Contents: ePowerSwitch M8 Device Driver (firmware tag = 0), and
7  ePowerSwitch M8+R2 Device Driver (firmware tag = 1)
8 
9 \********************************************************************/
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdarg.h>
14 #include <string.h>
15 #include <math.h>
16 #include <time.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <netdb.h>
22 #include <ctype.h>
23 
24 #include "midas.h"
25 
26 #define closesocket(s) close(s)
27 
28 #define LEMPLUG_MAX_READ 5
29 
30 #define LEMPLUG_SUCCESS 0
31 #define LEMPLUG_NOSUCCESS -1
32 #define LEMPLUG_STARTUP_ERROR -2
33 #define LEMPLUG_NO_HOST_ERROR -3
34 #define LEMPLUG_CONNECT_ERROR -4
35 
36 /*---- globals -----------------------------------------------------*/
37 
39 typedef struct {
40  int enable_log;
41  char log[2*NAME_LENGTH];
42  DWORD read_time;
43  char host[NAME_LENGTH];
44  int port;
45  char user_name[NAME_LENGTH];
46  char pwd[NAME_LENGTH];
49 
51 #define LEMPLUG_SETTINGS_STR "\
52 Enable Log = INT : 0\n\
53 Log = STRING : [64]\n\
54 Read Time = DWORD : 5\n\
55 Host = STRING : [32]\n\
56 Port = INT : 23\n\
57 User Name = STRING : [32]\n\
58 Pwd = STRING : [32]\n\
59 Firmware Tag = INT : 0\n\
60 "
61 
63 typedef struct {
65  float outlet_state[8];
66  char outlet_name[8][NAME_LENGTH];
68  INT(*bd) (INT cmd, ...);
69  void *bd_info;
70  HNDLE hkey;
73 } LEMPLUG_INFO;
74 
75 
76 /*---- base64 encoding routines ------------------------------------------*/
77 
78 char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
79 char request[10000], response[10000];
80 
81 /***************************************************************************/
88 void lemplug_base64_encode(char *s, char *d)
89 {
90  unsigned int t, pad;
91 
92  pad = 3 - strlen(s) % 3;
93  if (pad == 3)
94  pad = 0;
95  while (*s) {
96  t = (*s++) << 16;
97  if (*s)
98  t |= (*s++) << 8;
99  if (*s)
100  t |= (*s++) << 0;
101 
102  *(d + 3) = map[t & 63];
103  t >>= 6;
104  *(d + 2) = map[t & 63];
105  t >>= 6;
106  *(d + 1) = map[t & 63];
107  t >>= 6;
108  *(d + 0) = map[t & 63];
109 
110  d += 4;
111  }
112  *d = 0;
113  while (pad--)
114  *(--d) = '=';
115 }
116 
117 /***************************************************************************/
124 {
125  char *s;
126 
127  if (strlen(str) == 0)
128  return 0;
129 
130  s=str+strlen(str)-1; // go to the end of the string
131  for (;;) {
132  if (isspace(*s)) { // remove whitespace
133  *s='\0';
134  s--;
135  } else
136  break;
137  }
138 
139  return strlen(str);
140 }
141 
142 /***************************************************************************/
150 {
151  int fd;
152  char tt[64];
153  char str[10000];
154  time_t err_time;
155 
156  fd = open(info->dd_settings.log, O_CREAT | O_WRONLY | O_APPEND, 0644);
157 
158  if (fd>0) { // valid file descriptor
159  // get time
160  time(&err_time);
161  strcpy(tt, ctime(&err_time));
162  tt[strlen(tt)-1]='\0';
163 
164  sprintf(str, "----------------------------------------------\n");
165  write(fd, str, strlen(str));
166 
167  sprintf(str, "[%s]:\r\n%s\n", tt, log);
168  write(fd, str, strlen(str));
169 
170  close(fd);
171  }
172 }
173 
174 /***************************************************************************/
185 {
186  struct hostent *phe;
187  struct sockaddr_in bind_addr;
188  int sock;
189  int status;
190  int done = 0;
191  int err, i;
192 
193  err = 0;
194  do {
195  // open connection
196  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
197  perror("cannot create socket");
198  return LEMPLUG_NOSUCCESS;
199  }
200 
201  // compose remote address
202  memset(&bind_addr, 0, sizeof(bind_addr));
203  bind_addr.sin_family = AF_INET;
204  bind_addr.sin_addr.s_addr = 0;
205  bind_addr.sin_port = htons((unsigned short) info->dd_settings.port);
206 
207  phe = gethostbyname(info->dd_settings.host);
208  if (phe == NULL) {
209  perror("cannot get host name");
210  return LEMPLUG_NO_HOST_ERROR;
211  }
212  memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
213 
214  // connect to server
215  status = connect(sock, (void *) &bind_addr, sizeof(bind_addr));
216  if (status != 0) {
217  cm_msg(MINFO, "lemplug_cmd_0", "Cannot connect to host %s, port %d\n",
218  info->dd_settings.host, info->dd_settings.port);
219  return LEMPLUG_CONNECT_ERROR;
220  }
221 
222  // send request
223  send(sock, request, strlen(request), 0);
224  // receive response
225  memset(response, 0, sizeof(response));
226  i = recv(sock, response, sizeof(response), 0);
227 
228  if (i < 0) {
229  perror("Cannot receive response");
230  return LEMPLUG_NOSUCCESS;
231  }
232 
233  if (strstr(response, "303 See Other")) {
234  done = 1;
235  } else {
236  usleep(100000);
237  err++;
238  }
239 
240  if (err > 5) {
241  done = 1;
242  }
243 
244  // close connection
245  closesocket(sock);
246  } while (!done);
247 
248  return strlen(response);
249 }
250 
251 /***************************************************************************/
262 {
263  struct hostent *phe;
264  struct sockaddr_in bind_addr;
265  int sock;
266  int status;
267  int i, state;
268  int err;
269  int done = 0;
270  char *s, name[128];
271 
272  // open connection
273  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
274  perror("cannot create socket");
275  return LEMPLUG_NOSUCCESS;
276  }
277 
278  // compose remote address
279  memset(&bind_addr, 0, sizeof(bind_addr));
280  bind_addr.sin_family = AF_INET;
281  bind_addr.sin_addr.s_addr = 0;
282  bind_addr.sin_port = htons((unsigned short) info->dd_settings.port);
283 
284  phe = gethostbyname(info->dd_settings.host);
285  if (phe == NULL) {
286  perror("cannot get host name");
287  return LEMPLUG_NO_HOST_ERROR;
288  }
289  memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
290 
291  // connect to server
292  status = connect(sock, (void *) &bind_addr, sizeof(bind_addr));
293  if (status != 0) {
294  cm_msg(MINFO, "lemplug_read_0", "lemplug_read_0: Cannot connect to host %s, port %d\n",
295  info->dd_settings.host, info->dd_settings.port);
296  return LEMPLUG_CONNECT_ERROR;
297  }
298 
299  err = 0;
300  do {
301  // send request
302  send(sock, request, strlen(request), 0);
303  // receive response
304  memset(response, 0, sizeof(response));
305  i = recv(sock, response, sizeof(response), 0);
306 
307  if (i < 0) {
308  perror("Cannot receive response");
309  return -1;
310  }
311 
312  if (strstr(response, "cmd.js"))
313  done = 1;
314  else {
315  usleep(100000);
316  err++;
317  }
318 
319  if (err > 5)
320  done = 1;
321 
322  } while (!done);
323 
324  // close connection
325  closesocket(sock);
326 
327  if (err>5)
328  return LEMPLUG_NOSUCCESS;
329 
330  // extract names and status of the outlets (ugly code but it should work mostly ;-))
331  s = strstr(response, "display(");
332  if ((s == NULL) || strlen(response)<686)
333  return LEMPLUG_NOSUCCESS;
334 
335  s += 9; // shift pointer to the 1st socket name
336  for (i=0; i<8; i++) {
337  memset(name, 0, sizeof(name));
338  strncpy(name, s, 32);
340  snprintf(info->outlet_name[i], NAME_LENGTH, "lemplug%%%s", name);
341  s += 34;
342  sscanf(s, "%d", &state);
343  info->outlet_state[i] = (float)state;
344  s += 8;
345  }
346 
347  return strlen(response);
348 }
349 
350 /***************************************************************************/
361 {
362  struct hostent *phe;
363  struct sockaddr_in bind_addr;
364  int sock;
365  int status;
366  int i,j;
367  int err;
368  int done = 0;
369  char str[1024], *s;
370 
371  // open connection
372  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
373  perror("cannot create socket");
374  return LEMPLUG_NOSUCCESS;
375  }
376 
377  // compose remote address
378  memset(&bind_addr, 0, sizeof(bind_addr));
379  bind_addr.sin_family = AF_INET;
380  bind_addr.sin_addr.s_addr = 0;
381  bind_addr.sin_port = htons((unsigned short) info->dd_settings.port);
382 
383  phe = gethostbyname(info->dd_settings.host);
384  if (phe == NULL) {
385  perror("cannot get host name");
386  return LEMPLUG_NO_HOST_ERROR;
387  }
388  memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
389 
390  // connect to server
391  status = connect(sock, (void *) &bind_addr, sizeof(bind_addr));
392  if (status != 0) {
393  cm_msg(MINFO, "lemplug_cmd_1", "lemplug_cmd_1: Cannot connect to host %s, port %d\n",
394  info->dd_settings.host, info->dd_settings.port);
395  return LEMPLUG_CONNECT_ERROR;
396  }
397 
398  err = 0;
399  memset(response, 0, sizeof(response));
400  do {
401  // send request
402  send(sock, request, strlen(request), 0);
403  // receive response
404  memset(str, 0, sizeof(str));
405  i = recv(sock, str, sizeof(str), 0);
406 
407  if (i < 0) {
408  perror("Cannot receive response");
409  return -1;
410  }
411 
412  strcat(response, str);
413 
414  if (strstr(response, "</html>"))
415  done = 1;
416  else {
417  usleep(100000);
418  err++;
419  }
420 
421  if (err > 5)
422  done = 1;
423 
424  } while (!done);
425 
426  // close connection
427  closesocket(sock);
428 
429  if (err>5)
430  return LEMPLUG_NOSUCCESS;
431 
432  // everything looks fine, hence filter the content
433  for (i=1; i<=8; i++) {
434  sprintf(str, "M0:O%d=", i);
435  s = strstr(response, str);
436  if (s != 0) {
437  memset(str, 0, sizeof(str));
438  for (j=0; j<10; j++) {
439  if (*(s+j) == '\r')
440  break;
441  str[j] = *(s+j);
442  }
443  if (strstr(str, "Off"))
444  info->outlet_state[i-1] = 0.0;
445  else if (strstr(str, "On"))
446  info->outlet_state[i-1] = 1.0;
447  else
448  info->outlet_state[i-1] = 0.5;
449  }
450  }
451 
452  return strlen(response);
453 }
454 
455 /***************************************************************************/
466 {
467  struct hostent *phe;
468  struct sockaddr_in bind_addr;
469  int sock;
470  int status;
471  int i,j;
472  int err;
473  int done = 0;
474  char str[1024], *s;
475 
476  // open connection
477  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
478  perror("cannot create socket");
479  return LEMPLUG_NOSUCCESS;
480  }
481 
482  // compose remote address
483  memset(&bind_addr, 0, sizeof(bind_addr));
484  bind_addr.sin_family = AF_INET;
485  bind_addr.sin_addr.s_addr = 0;
486  bind_addr.sin_port = htons((unsigned short) info->dd_settings.port);
487 
488  phe = gethostbyname(info->dd_settings.host);
489  if (phe == NULL) {
490  perror("cannot get host name");
491  return LEMPLUG_NO_HOST_ERROR;
492  }
493  memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
494 
495  // connect to server
496  status = connect(sock, (void *) &bind_addr, sizeof(bind_addr));
497  if (status != 0) {
498  cm_msg(MINFO, "lemplug_cmd_2", "lemplug_cmd_2: Cannot connect to host %s, port %d\n",
499  info->dd_settings.host, info->dd_settings.port);
500  return LEMPLUG_CONNECT_ERROR;
501  }
502 
503  err = 0;
504  memset(response, 0, sizeof(response));
505  do {
506  // send request
507  send(sock, request, strlen(request), 0);
508  // receive response
509  memset(str, 0, sizeof(str));
510  i = recv(sock, str, sizeof(str), 0);
511 
512  if (i < 0) {
513  perror("Cannot receive response");
514  return -1;
515  }
516 
517  strcat(response, str);
518 
519  if (strstr(response, "</html>"))
520  done = 1;
521  else {
522  usleep(100000);
523  err++;
524  }
525 
526  if (err > 5)
527  done = 1;
528 
529  } while (!done);
530 
531  // close connection
532  closesocket(sock);
533 
534  if (err>5)
535  return LEMPLUG_NOSUCCESS;
536 
537  // everything looks fine, hence filter the content
538  for (i=1; i<=8; i++) {
539  sprintf(str, "P0%d=", i);
540  s = strstr(response, str);
541  if (s != 0) {
542  memset(str, 0, sizeof(str));
543  for (j=0; j<10; j++) {
544  if (*(s+j) == '\r')
545  break;
546  str[j] = *(s+j);
547  }
548  if (strstr(str, "=0"))
549  info->outlet_state[i-1] = 0.0;
550  else if (strstr(str, "=1"))
551  info->outlet_state[i-1] = 1.0;
552  else
553  info->outlet_state[i-1] = 0.5;
554  }
555  }
556 
557  return strlen(response);
558 }
559 
560 /*---- device driver routines --------------------------------------*/
561 
575 INT lemplug_init(HNDLE hkey, void **pinfo, INT channels, INT(*bd) (INT cmd, ...))
576 {
577  int status, size;
578  HNDLE hDB, hkeydd;
580  char str[256];
581  char pwd[256];
582 
583  // allocate info structure
584  info = calloc(1, sizeof(LEMPLUG_INFO));
585  *pinfo = info;
586 
587  cm_get_experiment_database(&hDB, NULL);
588 
589  // create lemplug dd settings record
590  status = db_create_record(hDB, hkey, "DD", LEMPLUG_SETTINGS_STR);
591  if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
592  cm_msg(MERROR, "lemplug_init", "lemplug_init: Error creating Bruker DD record in ODB, status=%d", status);
593  cm_yield(0);
594  return FE_ERR_ODB;
595  }
596 
597  db_find_key(hDB, hkey, "DD", &hkeydd);
598  size = sizeof(info->dd_settings);
599  db_get_record(hDB, hkeydd, &info->dd_settings, &size, 0);
600 
601  // initialize driver
602  info->num_channels = channels;
603  info->bd = bd;
604  info->hkey = hkey;
605  info->startup_error = FALSE;
606  info->read_time_stamp = ss_time()-info->dd_settings.read_time;
607 
608  if (!bd)
609  return FE_ERR_ODB;
610 
611  // initialize bus driver
612  status = info->bd(CMD_INIT, info->hkey, &info->bd_info);
613 
614  if (status != SUCCESS) {
615  return status;
616  }
617 
618  // initialization of device
619  if (info->dd_settings.firmware_tag == 0) {
620  strcpy(request, "GET / HTTP/1.0\r\n");
621  strcat(request, "Host: lemplug\r\n");
622  strcat(request, "User-Agent: lemPlug/0.1\r\n");
623  strcat(request, "Accept: text/html, */*\r\n");
624  sprintf(str, "%s:%s", info->dd_settings.user_name, info->dd_settings.pwd);
625  lemplug_base64_encode(str, pwd);
626  sprintf(str, "Authorization: Basic %s\r\n", pwd);
627  strcat(request, str);
628  strcat(request, "\r\n");
629  } else if ((info->dd_settings.firmware_tag == 1) ||
630  (info->dd_settings.firmware_tag == 2)) {
631  // nothing to be done as long as the MD5 is not in place
632  cm_msg(MINFO, "lemplug_init", "lemplug_init: initialized ...");
633  cm_yield(0);
634 
635  return FE_SUCCESS;
636  } else {
637  cm_msg(MERROR, "lemplug_init", "lemplug_init: **ERROR** found unkown firmware tag: %d", info->dd_settings.firmware_tag);
638  info->startup_error = TRUE;
639  return FE_SUCCESS;
640  }
641 
642  if (info->dd_settings.enable_log)
643  lemplug_write_log(info, request);
644 
645  memset(response, 0, sizeof(response));
646 
647  status = lemplug_cmd_0(info);
648 
649  if (!status) {
650  cm_msg(MINFO, "lemplug_init", "lemplug_init: no response from lemplug");
651  cm_yield(0);
652  info->startup_error = TRUE;
653  return FE_SUCCESS;
654  }
655 
656  if (info->dd_settings.enable_log)
658 
659  cm_msg(MINFO, "lemplug_init", "lemplug_init: initialized ...");
660  cm_yield(0);
661 
662  return FE_SUCCESS;
663 }
664 
665 /*----------------------------------------------------------------------------*/
674 {
675  // call EXIT function of bus driver, usually closes device
676  info->bd(CMD_EXIT, info->bd_info);
677 
678  // free local variables
679  free(info);
680 
681  return FE_SUCCESS;
682 }
683 
684 /*----------------------------------------------------------------------------*/
694 INT lemplug_set(LEMPLUG_INFO *info, INT channel, float value)
695 {
696  char cmd[16];
697  char str[256];
698  char pwd[256];
699  int status;
700 
701  if (info->startup_error)
702  return FE_SUCCESS;
703 
704  if (info->dd_settings.firmware_tag == 0) {
705  // ePowerSwitch M8 switching command
706  sprintf(cmd, "P1%d=%d", channel+1, (int)value);
707 
708  // http command
709  strcpy(request, "POST /rack1.html HTTP/1.0\r\n");
710  strcat(request, "Host: lemplug\r\n");
711  strcat(request, "User-Agent: lemPlug/0.1\r\n");
712  strcat(request, "Accept: text/html, */*\r\n");
713  sprintf(str, "Content-Length: %d\r\n", (int)strlen(cmd));
714  strcat(request, str);
715  sprintf(str, "%s:%s", info->dd_settings.user_name, info->dd_settings.pwd);
716  lemplug_base64_encode(str, pwd);
717  sprintf(str, "Authorization: Basic %s\r\n", pwd);
718  strcat(request, str);
719  strcat(request, "\r\n");
720  strcat(request, cmd);
721 
722  if (info->dd_settings.enable_log)
723  lemplug_write_log(info, request);
724 
725  memset(response, 0, sizeof(response));
726 
727  status = lemplug_cmd_0(info);
728  } else if (info->dd_settings.firmware_tag == 1) {
729  if (value == 0.0) { // Off
730  sprintf(request, "GET /hidden.htm?M0:O%d=OFF HTTP/1.0\r\n", channel+1);
731  } else if (value == 1.0) { // On
732  sprintf(request, "GET /hidden.htm?M0:O%d=ON HTTP/1.0\r\n", channel+1);
733  } else {
734  cm_msg(MERROR, "lemplug_set", "lemplug_set: only values 0.0 and 1.0 are allowed, found %f", value);
735  return FE_SUCCESS;
736  }
737  strcat(request, "Host: lemplug\r\n");
738  strcat(request, "User-Agent: lemPlug/0.1\r\n");
739  strcat(request, "Accept: text/html, */*\r\n");
740  strcat(request, "\r\n");
741 
742  status = lemplug_cmd_1(info);
743  } else if (info->dd_settings.firmware_tag == 2) {
744  if (value == 0.0) { // Off
745  sprintf(request, "GET /hidden.htm?P0%d=0 HTTP/1.0\r\n", channel+1);
746  } else if (value == 1.0) { // On
747  sprintf(request, "GET /hidden.htm?P0%d=1 HTTP/1.0\r\n", channel+1);
748  } else {
749  cm_msg(MERROR, "lemplug_set", "lemplug_set: only values 0.0 and 1.0 are allowed, found %f", value);
750  return FE_SUCCESS;
751  }
752  strcat(request, "Host: lemplug\r\n");
753  strcat(request, "User-Agent: lemPlug/0.1\r\n");
754  strcat(request, "Accept: text/html, */*\r\n");
755  strcat(request, "\r\n");
756 
757  status = lemplug_cmd_2(info);
758  } else {
759  cm_msg(MERROR, "lemplug_get", "lemplug_get: **ERROR** found unkown firmware tag = %d", info->dd_settings.firmware_tag);
760  return FE_SUCCESS;
761  }
762 
763  if (info->dd_settings.enable_log)
765 
766  return FE_SUCCESS;
767 }
768 
769 /*----------------------------------------------------------------------------*/
781 INT lemplug_get(LEMPLUG_INFO *info, INT channel, float *pvalue)
782 {
783  int status;
784  char str[256];
785  char pwd[256];
786  char cmd[16];
787 
788  if (info->startup_error) {
789  *pvalue = LEMPLUG_STARTUP_ERROR;
790  return FE_SUCCESS;
791  }
792 
793  if ((channel == 0) && (ss_time()-info->read_time_stamp > info->dd_settings.read_time)) { // read state
794 
795  if (info->dd_settings.firmware_tag == 0) { // ePowerSwitch 8M
796  // construct command
797  strcpy(cmd, "R");
798 
799  strcpy(request, "GET /rack1.html HTTP/1.0\r\n");
800  strcat(request, "Host: lemplug\r\n");
801  strcat(request, "User-Agent: lemPlug/0.1\r\n");
802  strcat(request, "Accept: text/html, */*\r\n");
803  sprintf(str, "Content-Length: %d\r\n", (int)strlen(cmd));
804  strcat(request, str);
805  sprintf(str, "%s:%s", info->dd_settings.user_name, info->dd_settings.pwd);
806  lemplug_base64_encode(str, pwd);
807  sprintf(str, "Authorization: Basic %s\r\n", pwd);
808  strcat(request, str);
809  strcat(request, "\r\n");
810  strcat(request, cmd);
811 
812  status = lemplug_read_0(info);
813  } else if (info->dd_settings.firmware_tag == 1) { // ePowerSwitch 8M+ R2
814  strcpy(request, "GET /hidden.htm HTTP/1.0\r\n");
815  strcat(request, "Host: lemplug\r\n");
816  strcat(request, "User-Agent: lemPlug/0.1\r\n");
817  strcat(request, "Accept: text/html, */*\r\n");
818  strcat(request, "\r\n");
819 
820  status = lemplug_cmd_1(info);
821  } else if (info->dd_settings.firmware_tag == 2) { // ePowerSwitch 8M+ R1
822  strcpy(request, "GET /hidden.htm HTTP/1.0\r\n");
823  strcat(request, "Host: lemplug\r\n");
824  strcat(request, "User-Agent: lemPlug/0.1\r\n");
825  strcat(request, "Accept: text/html, */*\r\n");
826  strcat(request, "\r\n");
827 
828  status = lemplug_cmd_2(info);
829  } else {
830  cm_msg(MERROR, "lemplug_get", "lemplug_get: **ERROR** found unkown firmware tag = %d", info->dd_settings.firmware_tag);
831  return FE_SUCCESS;
832  }
833 
834  if (info->dd_settings.enable_log)
836 
837  info->read_time_stamp = ss_time();
838 
839  }
840 
841  ss_sleep(10);
842  *pvalue = info->outlet_state[channel];
843 
844  return FE_SUCCESS;
845 }
846 
847 /*----------------------------------------------------------------------------*/
858 INT lemplug_get_label(LEMPLUG_INFO *info, INT channel, char *name)
859 {
860  return FE_SUCCESS;
861 }
862 
863 /*---- device driver entry point -----------------------------------*/
864 
865 INT lemplug(INT cmd, ...)
866 {
867  va_list argptr;
868  HNDLE hKey;
869  INT channel, status;
870  DWORD flags;
871  float value, *pvalue;
872  char *name;
873  void *info, *bd;
874 
875  va_start(argptr, cmd);
876  status = FE_SUCCESS;
877 
878  switch (cmd) {
879  case CMD_INIT:
880  hKey = va_arg(argptr, HNDLE);
881  info = va_arg(argptr, void *);
882  channel = va_arg(argptr, INT);
883  flags = va_arg(argptr, DWORD);
884  bd = va_arg(argptr, void *);
885  status = lemplug_init(hKey, info, channel, bd);
886  break;
887 
888  case CMD_EXIT:
889  info = va_arg(argptr, void *);
890  status = lemplug_exit(info);
891  break;
892 
893  case CMD_SET:
894  info = va_arg(argptr, void *);
895  channel = va_arg(argptr, INT);
896  value = (float) va_arg(argptr, double); // floats are passed as double
897  status = lemplug_set(info, channel, value);
898  break;
899 
900  case CMD_GET:
901  info = va_arg(argptr, void *);
902  channel = va_arg(argptr, INT);
903  pvalue = va_arg(argptr, float *);
904  status = lemplug_get(info, channel, pvalue);
905  break;
906 
907  case CMD_GET_LABEL:
908  info = va_arg(argptr, void *);
909  channel = va_arg(argptr, INT);
910  name = va_arg(argptr, char *);
911  status = lemplug_get_label(info, channel, name);
912  break;
913 
914  default:
915  break;
916  }
917 
918  va_end(argptr);
919 
920  return status;
921 }
922 
923 /*------------------------------------------------------------------*/
char host[32]
host name of the ePowerSwitch M8
Definition: experim.h:9318
#define LEMPLUG_SETTINGS_STR
Initializing string for the struct LEMPLUG_SETTINGS.
Definition: lemplug.c:51
HNDLE hkey
ODB key for bus driver info.
Definition: lemplug.c:70
void lemplug_base64_encode(char *s, char *d)
Definition: lemplug.c:88
#define LEMPLUG_STARTUP_ERROR
Definition: lemplug.c:32
INFO info
Definition: vme_fe.c:206
#define LEMPLUG_CONNECT_ERROR
Definition: lemplug.c:34
void * bd_info
private info of bus driver
Definition: lemplug.c:69
char outlet_name[8][NAME_LENGTH]
name of the power outlets
Definition: lemplug.c:66
device specific information stored in the DD ODB
Definition: experim.h:9310
char user_name[32]
user name on the ePowerSwitch M8
Definition: experim.h:9320
INT lemplug_get(LEMPLUG_INFO *info, INT channel, float *pvalue)
Definition: lemplug.c:781
int port
communication port of the ePowerSwitch M8
Definition: lemplug.c:44
INT lemplug_exit(LEMPLUG_INFO *info)
Definition: lemplug.c:673
void lemplug_write_log(LEMPLUG_INFO *info, char *log)
Definition: lemplug.c:149
DWORD read_time_stamp
time stamp when the last reading took place
Definition: lemplug.c:72
INT lemplug_init(HNDLE hkey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
Definition: lemplug.c:575
int startup_error
flag indicating any satrtup error
Definition: lemplug.c:71
INT lemplug_cmd_1(LEMPLUG_INFO *info)
Definition: lemplug.c:360
INT lemplug_read_0(LEMPLUG_INFO *info)
Definition: lemplug.c:261
HNDLE hKey
Definition: write_summary.c:97
INT num_channels
number of channels
Definition: lemplug.c:67
INT lemplug_strip_whitespace(char *str)
Definition: lemplug.c:123
int enable_log
enable log tag
Definition: lemplug.c:40
INT lemplug_cmd_2(LEMPLUG_INFO *info)
Definition: lemplug.c:465
HNDLE hDB
Definition: write_summary.c:97
INT(* bd)(INT cmd,...)
bus driver entry function
Definition: lemplug.c:68
LEMPLUG_SETTINGS dd_settings
private settings of the device driver
Definition: lemplug.c:64
INT lemplug_set(LEMPLUG_INFO *info, INT channel, float value)
Definition: lemplug.c:694
char request[10000]
Definition: lemplug.c:79
This structure contains private variables for the device driver.
Definition: lemplug.c:63
char response[10000]
Definition: lemplug.c:79
int firmware_tag
firmware tag: 0 for ePowerSwitch M8 (old one), 1 for ePowerSwitch M8+R2
Definition: lemplug.c:47
#define LEMPLUG_NOSUCCESS
Definition: lemplug.c:31
float outlet_state[8]
current state of the power outlets
Definition: lemplug.c:65
char * map
Definition: lemplug.c:78
INT lemplug(INT cmd,...)
Definition: lemplug.c:865
DWORD read_time
time in (sec) how often to communicate with the ePowerSwitch M8
Definition: experim.h:9317
INT lemplug_cmd_0(LEMPLUG_INFO *info)
Definition: lemplug.c:184
char log[64]
name and path of the log-file
Definition: experim.h:9316
#define LEMPLUG_NO_HOST_ERROR
Definition: lemplug.c:33
char pwd[32]
password on the ePowerSwitch M8
Definition: experim.h:9321
INT lemplug_get_label(LEMPLUG_INFO *info, INT channel, char *name)
Definition: lemplug.c:858
#define closesocket(s)
Definition: lemplug.c:26