/*---------------------------------------------------------------------------
lscsupport.c

Communication routines for LakeShore equipment
  
Markus Zolliker, July 2006
----------------------------------------------------------------------------

there is no error return value, eab->errCode is used. On success, eab->errCode
is not changed, i.e. an existing errCode is not overwritten.
*/

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fortify.h>
#include "sics.h"
#include "oxinst.h"

/*----------------------------------------------------------------------------*/
int LscHandler(void *object)
{
  int iret, l;
  EaseBase *eab = EaseBaseCast(object);

  if (eab->state < EASE_idle)
    goto quit;
  if (availableNetRS232(eab->ser) || availableRS232(eab->ser)) {
    eab->msg[0] = '\0';
    l = sizeof(eab->ans);
    iret = readRS232TillTerm(eab->ser, eab->ans, &l);
    if (eab->state != EASE_expect && eab->state != EASE_lost) {
      if (iret == 1) {
        ParPrintf(eab, eError, "unexpected answer: %s", eab->ans);
      }
      goto quit;
    }
    if (iret == 1) {
      ParPrintf(eab, -2, "ans: %s", eab->ans);
      if (strncmp(eab->ans, "0,123", 5) == 0 && eab->state == EASE_lost) {      /* response to LOCK? */
        EaseWrite(eab, "*IDN?");
        goto quit;
      } else if (eab->state == EASE_lost) {
        goto quit;
      } else if (strncmp(eab->cmd, "*IDN?", 5) == 0) {
        if (strcmp(eab->ans, eab->version) == 0) {
          /* we are still connected with the same device */
        } else if (*eab->version == '\0') {
          strlcpy(eab->version, eab->ans, sizeof(eab->version));
        } else {                /* version (and therefore device) changed */
          eab->errCode = EASE_DEV_CHANGED;
          eab->state = EASE_idle;
          goto error;
        }
        eab->state = EASE_idle;
        goto quit;
      } else {
        /* eab->tmo = 120; do not know why this is needed */
      }
    }
    if (iret != 1) {
      eab->errCode = iret;
      eab->state = EASE_idle;
      goto error;
    }
    eab->state = EASE_read;
  } else if (eab->state == EASE_expect) {
    if (time(NULL) > eab->cmdtime + eab->tmo) {
      eab->state = EASE_lost;
    }
  } else if (eab->state == EASE_lost) {
    if (time(NULL) > eab->cmdtime) {
      EaseWrite(eab, "LOCK?");
      eab->state = EASE_lost;
    }
  }
  goto quit;
error:
  /* EaseWriteError(eab); */
quit:
  return EaseHandler(eab);
}
