diff --git a/site_ansto/hardsup/camera.h b/site_ansto/hardsup/camera.h index b42631f9..8ac6602e 100644 --- a/site_ansto/hardsup/camera.h +++ b/site_ansto/hardsup/camera.h @@ -62,7 +62,7 @@ TR(ECA_MLTI_OFF, "take multi off") \ TR(ECA_GET_STATUS, "get status") \ TR(ECA_GET_STATE, "get state") \ - TE(ECA_CFG, "send configuration") + TE(ECA_CFG, "update camera settings, file configuration and meta data") #define CAMERA_MSGS_TABLE \ TR(ECA_START, "StartTime") \ diff --git a/site_ansto/hardsup/cameradriver.c b/site_ansto/hardsup/cameradriver.c index 67911681..0a1c75df 100644 --- a/site_ansto/hardsup/cameradriver.c +++ b/site_ansto/hardsup/cameradriver.c @@ -8,6 +8,8 @@ * * Copyright: see file Copyright.txt */ +#include +#include #include #include #include @@ -17,8 +19,12 @@ #include #include "camera.h" +#define NAMELEN 32 +#define IFMTLEN 4 #define ERRLEN 256 #define MSGLEN 512 +#define MAX_META_COUNT 32 +#define MAX_SCANVAR_COUNT 16 enum camstates {idle, acquiring, processing, saving}; #define CAMDRIV_ERRTABLE \ @@ -85,10 +91,20 @@ static char *flipcmdstr[] = {FLIP_TABLE, NULL}; #undef TR #undef TE -// Camera get/set commands: ['status', 'info', 'state', 'camera', 'meta', 'file'] -#define ECMDSTART 0 -#define EGETSTART 100 -#define ESETSTART 200 +#define UPDATE_SETTINGS_CFG 1 +#define CLEAR_META_CFG 2 +#define UPDATE_META_CFG 4 +#define UPDATE_SCANVAR_CFG 8 +#define UPDATE_FILE_CFG 16 + +typedef struct { + char path[MSGLEN]; + char basename[MSGLEN]; + long startnumber; + char imageformat[IFMTLEN]; + char experimentdetail[MSGLEN]; +} filecfg_t; + typedef struct { float clockMHz; float bin; @@ -105,18 +121,17 @@ typedef struct { float shopt; float shclt; int updatecfg; + filecfg_t file; + char meta_list[MAX_META_COUNT][MSGLEN]; + char scanvar_list[MAX_SCANVAR_COUNT][NAMELEN]; + pDummy scanvar_dummy[MAX_SCANVAR_COUNT]; + pIDrivable pscanvar[MAX_SCANVAR_COUNT]; + int meta_count; + int scanvar_count; } camcfg_t; typedef struct { - char path[MSGLEN]; - char basename[MSGLEN]; - int startnumber; - char imageformat[MSGLEN]; - char experimentdetail[MSGLEN]; - int updatecfg; -} filecfg_t; - -typedef struct { + pObjectDescriptor pDes; int debug; char *asynq; camsm_t state_machine; @@ -124,8 +139,8 @@ typedef struct { int status; enum errcodes camError; camcfg_t camera; -/* filecfg_t file;*/ pAsyncUnit asyncUnit; + SicsInterp *pSics; } CamObj; /* Camera communications and protocol handlers */ @@ -134,6 +149,21 @@ static int cb_state_timer(void *ctx, int mode); static int cb_getstate(pAsyncTxn txn); static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal); +/* if emsg == NULL conversion OK else if emsg == num not an integer else emsg == error message */ +long getlong(char *num, char *emsg) { + long val = 0; + char *endptr; + errno = 0; + emsg = NULL; + + val = strtol(num, &endptr, 10); + if ( (errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0) ) + emsg = strerror(errno); + if (endptr == num) + emsg = num; + + return val; +} static void CAM_Notify(void* context, int event) { CamObj *self = (CamObj *) context; @@ -215,10 +245,10 @@ static int CamGetStatus(CounterDriver *cntrData, float *fControl) { * \param ev_sym, input event */ static void run_sm(CamObj *self, enum event_codes ev_sym) { - char sscur[SSLEN+1], ssnext[SSLEN+1], esout[ESLEN+1], message[MSGLEN+1]; + char *sscur, *ssnext, *esout, message[MSGLEN+1]; if (self->debug) { - strncpy(sscur, strstate(self->state_machine.Sc), SSLEN); + sscur = strstate(self->state_machine.Sc); snprintf(message, MSGLEN, "DEBUG:(run_sm) Scurr:%s Ei:%s", sscur,event_names[ev_sym]); SICSLogWrite(message, eLog); @@ -227,9 +257,9 @@ static void run_sm(CamObj *self, enum event_codes ev_sym) { camdriv_input(self, &self->state_machine, ev_sym); if (self->debug) { - strncpy(ssnext, strstate(self->state_machine.Sc), SSLEN); - strncpy(esout, strevent(self->state_machine.Eo), ESLEN); - snprintf(message, MSGLEN, "DEBUG:(run_sm) Snext:%s Eo:%s", ssnext,esout); + ssnext = strstate(self->state_machine.Sc), SSLEN; + esout = strevent(self->state_machine.Eo), ESLEN; + snprintf(message, MSGLEN, "DEBUG:(run_sm) Snext:%s Eo:%s", ssnext, esout); SICSLogWrite(message, eLog); } } @@ -277,7 +307,7 @@ static int CamHalt(CounterDriver *cntrData) { } return 1; } -/* TODO what should the counter data be set to? Total intensity? */ +/* FIXME what should the counter data be set to? Total intensity? */ static int CamReadValues(CounterDriver *cntrData) { int status, iReplyLen=MSGLEN; char *cmd="TODO ", pReply[MSGLEN]; @@ -358,7 +388,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case CLOCK: if (fVal > 0) { camdriv->camera.clockMHz = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -366,7 +396,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case BIN: if (fVal > 0) { camdriv->camera.bin = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -374,7 +404,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case SIZE: if (fVal > 0) { camdriv->camera.size = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -382,7 +412,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case GAIN: if (fVal > 0) { camdriv->camera.gain = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -399,7 +429,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case INVFV: case INVFHV: camdriv->camera.flip = flip; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; break; default: return 0; @@ -409,7 +439,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case XSTART: if (fVal > 0) { camdriv->camera.xstart = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -417,7 +447,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case YSTART: if (fVal > 0) { camdriv->camera.ystart = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -425,7 +455,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case XEND: if (fVal > 0) { camdriv->camera.xend = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -433,7 +463,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case YEND: if (fVal > 0) { camdriv->camera.yend = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -441,19 +471,19 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case EXPOSURE: if (fVal > 0) { camdriv->camera.exposure = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } break; case TEMP: camdriv->camera.temp = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; break; case THRESH: if (fVal > 0) { camdriv->camera.thresh = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -461,7 +491,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case SHOPT: if (fVal > 0) { camdriv->camera.shopt = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -469,7 +499,7 @@ static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) { case SHCLT: if (fVal > 0) { camdriv->camera.shclt = fVal; - camdriv->camera.updatecfg = 1; + camdriv->camera.updatecfg |= UPDATE_SETTINGS_CFG; } else { return 0; } @@ -569,7 +599,6 @@ static int CamSend(CounterDriver *cntrData, char *pText, char *pReply, int iRepl static int cb_shotcmd(pAsyncTxn txn) { CamObj *self = (CamObj *) txn->cntx; char *resp = txn->inp_buf, message[MSGLEN+1]; - enum event_codes cd_sym; if (self->debug) { snprintf(message, MSGLEN, "DEBUG:(cb_shotcmd) Camera reply: %s", resp); @@ -587,30 +616,44 @@ static int cb_shotcmd(pAsyncTxn txn) { * it should be fed back into the state transition function. */ int camdriv_out(void *me, event_t Eo) { - int len, feedback = 0; + int i, len, pend=0; char cmd[MSGLEN]="", logmsg[MSGLEN+1]=""; - float clock; + float clock, fVal; CamObj *self = (CamObj *)me; if (Eo.ca) { /* send command to camera */ + if (self->debug) { + snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:Eo.ca): ev=%s, output=%s\n", + event_names[Eo.ca], event_signatures[Eo.ca]); + SICSLogWrite(logmsg, eLog); + } switch (Eo.ca) { case ECA_TK_SHOT: len = strlen(event_signatures[ECA_TK_SHOT]); strncpy(cmd, event_signatures[ECA_TK_SHOT], len); + len = strlen(cmd); + AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); break; case ECA_MLTI_ON: len = strlen(event_signatures[ECA_MLTI_ON]); strncpy(cmd, event_signatures[ECA_MLTI_ON], len); + len = strlen(cmd); + AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); break; case ECA_MLTI_OFF: len = strlen(event_signatures[ECA_MLTI_OFF]); strncpy(cmd, event_signatures[ECA_MLTI_OFF], len); + len = strlen(cmd); + AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); break; case ECA_CFG: - if(self->camera.updatecfg) { + /* TODO Should we retry sending a command if AsyncUnitSendTxn fails? + * The driver should abort the shot and then try to send the + * configuration the next time a shot is taken. */ + if( (self->camera.updatecfg & UPDATE_SETTINGS_CFG) == UPDATE_SETTINGS_CFG) { clock = self->camera.clockMHz; - sprintf(cmd, + snprintf(cmd, MSGLEN, "set camera,clock=%.*fmhz,bin=%dx,size=%d,gain=%dxhs,flip=%s,xstart=%d,ystart=%d,xend=%d,yend=%d,exposure=%f,temperature=%f,threshold=%d,shutteropentime=%d,shutterclosetime=%d", clock>=1 ? 0 : 1, clock, (int)self->camera.bin, (int)self->camera.size, (int)self->camera.gain, flipcmdstr[self->camera.flip], @@ -620,7 +663,59 @@ int camdriv_out(void *me, event_t Eo) { (int)self->camera.shclt ); len = strlen(cmd); - self->camera.updatecfg = 0; + self->camera.updatecfg &= ~UPDATE_SETTINGS_CFG; + if (self->debug) { + snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:UPDATE_SETTINGS_CFG): cmd=%s\n", cmd); + SICSLogWrite(logmsg, eLog); + } + AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); + } + if( (self->camera.updatecfg & CLEAR_META_CFG) == CLEAR_META_CFG) { + snprintf(cmd, MSGLEN, "clear meta"); + len = strlen(cmd); + if (self->debug) { + snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:CLEAR_META_CFG): cmd=%s\n", cmd); + SICSLogWrite(logmsg, eLog); + } + AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); + } + if( (self->camera.updatecfg & UPDATE_META_CFG) == UPDATE_META_CFG) { + //TODO concatenate the meta_list into a comma separated string and send it in MSGLEN chunks. + for (i=0; i < self->camera.meta_count && pend < MSGLEN; i++) { + pend = sprintf(cmd, "set meta,"); + pend += snprintf(&cmd[pend], MSGLEN, "%s", self->camera.meta_list[i]); + len = strlen(cmd); + if (self->debug) { + snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:UPDATE_META_CFG): cmd=%s\n", cmd); + SICSLogWrite(logmsg, eLog); + } + AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); + } + } + if( (self->camera.updatecfg & UPDATE_SCANVAR_CFG) == UPDATE_SCANVAR_CFG) { + pend = sprintf(cmd, "set meta"); + //TODO Send in MSGLEN chunks even though the string may never exceed MSGLEN + for (i=0; i < self->camera.scanvar_count && pend < MSGLEN; i++) { + fVal = self->camera.pscanvar[i]->GetValue(self->camera.scanvar_dummy[i], pServ->dummyCon); + pend += snprintf(&cmd[pend], MSGLEN, ",%s=%f", self->camera.scanvar_list[i], fVal); + } + len = strlen(cmd); + if (self->debug) { + snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:UPDATE_SCANVAR_CFG): cmd=%s\n", cmd); + SICSLogWrite(logmsg, eLog); + } + AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); + } + if( (self->camera.updatecfg & UPDATE_FILE_CFG) == UPDATE_FILE_CFG) { + snprintf(cmd, MSGLEN, "set file,path=%s,basename=%s,startnumber=%ld,imageformat=%s,experimentdetail=%s", + self->camera.file.path, self->camera.file.basename, self->camera.file.startnumber, self->camera.file.imageformat,self->camera.file.experimentdetail); + len = strlen(cmd); + if (self->debug) { + snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:UPDATE_FILE_CFG): cmd=%s\n", cmd); + SICSLogWrite(logmsg, eLog); + } + AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); + self->camera.updatecfg &= ~UPDATE_FILE_CFG; } break; default: @@ -628,12 +723,6 @@ int camdriv_out(void *me, event_t Eo) { SICSLogWrite(logmsg, eLogError); return -1; } - AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN); - if (self->debug) { - snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:Eo.ca): ev=%s, output=%s\n", - event_names[Eo.ca], event_signatures[Eo.ca]); - SICSLogWrite(logmsg, eLog); - } return -1; } if (Eo.cm) { @@ -650,6 +739,11 @@ int camdriv_out(void *me, event_t Eo) { } if (Eo.dr) { /* send msg to SICS */ + if (self->debug) { + snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out): ev=%s, output=%s\n", + event_names[Eo.dr], event_signatures[Eo.dr]); + SICSLogWrite(logmsg, eLog); + } switch (Eo.dr) { case EDR_IDLE: self->status = HWIdle; @@ -665,11 +759,6 @@ int camdriv_out(void *me, event_t Eo) { SICSLogWrite(logmsg, eLogError); return -1; } - if (self->debug) { - snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out): ev=%s, output=%s\n", - event_names[Eo.dr], event_signatures[Eo.dr]); - SICSLogWrite(logmsg, eLog); - } return -1; } if (Eo.cl) { @@ -709,7 +798,7 @@ static int cb_state_timer(void *ctx, int mode) { static int cb_getstate(pAsyncTxn txn) { CamObj *self = (CamObj *) txn->cntx; char *resp = txn->inp_buf, message[MSGLEN+1]; - int len = txn->inp_idx, ret=1, time_rem, time_tot; + int ret=1, time_rem, time_tot; enum event_codes ca_sym, cm_sym; @@ -731,9 +820,182 @@ static int cb_getstate(pAsyncTxn txn) { return ret; } +/* Auxiliary Camera Driver commands */ +int cmd_code(char **cmd_list, char *cmd) { + int i; + for (i=0; cmd_list[i] != NULL; i++) + if (strcasecmp(cmd_list[i], cmd) == 0) + return i; + return -1; +} + +int file_cmd(CamObj *camdriv, SConnection *pCon, char *subcmd, char *data) { + int i, subcmd_code, retval = 1; + long numval; + enum file_subcmd_codes {PATH, BASENAME, IMAGEFMT, STARTNUM, EXPDETAIL}; + char *file_subcmd_names[] = {"path", "name", "format", "startnumber", "detail", NULL}; + char *glemsg = NULL, emsg[MSGLEN]; + + if ( (subcmd_code = cmd_code(file_subcmd_names, subcmd)) == -1) { + return 0; + } + switch (subcmd_code) { + case PATH: + snprintf(camdriv->camera.file.path, MSGLEN, "%s", data); + break; + case BASENAME: + snprintf(camdriv->camera.file.basename, MSGLEN, "%s", data); + break; + case STARTNUM: + numval = getlong(data, glemsg); + if (glemsg == NULL) { + camdriv->camera.file.startnumber = numval; + } else if (glemsg == data) { + snprintf(emsg, MSGLEN, "CAM:(file_cmd) %s is not an integer", data); + SCWrite(pCon, emsg, eError); + retval = 0; + } else { + snprintf(emsg, MSGLEN, "CAM:(file_cmd) %s", glemsg); + SCWrite(pCon, emsg, eError); + retval = 0; + } + break; + case IMAGEFMT: + if (strcasecmp(data, "tif") == 0) { + for (i=0; data[i]; i++) { + data[i] = tolower(data[i]); + } + snprintf(camdriv->camera.file.imageformat, IFMTLEN, "%s", data); + } else { + retval = 0; + } + break; + case EXPDETAIL: + snprintf(camdriv->camera.file.experimentdetail, MSGLEN, "%s", data); + break; + default: + retval = 0; + } + return retval; +} +/** + * \brief Auxiliary command interface which gets around type and string length + * limitations of the CountAction command. + */ +int CamAuxCmd(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { + char *cmd = NULL; + char message[MSGLEN]; + enum auxcmd_codes {CLEAR_META, META, FILECMD, SCANVAR, MOTOR}; + char *auxcmd_names[] = {"clearmeta", "meta", "file", "scanvar", "motor", NULL}; + int i, code, retval = 1, pend=0; + CamObj *camdriv = (CamObj *)pData; + CommandList *pCom = NULL; + pIDrivable pDriv = NULL; + pDummy pDumData = NULL; + + if (argc < 2) { + snprintf(message, MSGLEN, "CAM: You must specify a command"); + SCWrite(pCon, message, eError); + return 0; + } + if ( (code = cmd_code(auxcmd_names, argv[1])) == -1 ) { + snprintf(message, MSGLEN, "CAM: %s is not a valid command", argv[1]); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + switch (code) { + case CLEAR_META: + camdriv->camera.meta_count = 0; + camdriv->camera.scanvar_count = 0; + camdriv->camera.updatecfg |= CLEAR_META_CFG; + camdriv->camera.updatecfg &= ~UPDATE_META_CFG; + camdriv->camera.updatecfg &= ~UPDATE_SCANVAR_CFG; + break; + case META: + if (argc < 3) { + snprintf(message, MSGLEN, "CAM: Insufficient arguments, the META command requires name=val data"); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + if (camdriv->camera.meta_count < MAX_META_COUNT) { + for (i=2; i < argc; i++) { + pend += snprintf(&(camdriv->camera.meta_list[camdriv->camera.meta_count][pend]), MSGLEN, "%s ", argv[i]); + } + camdriv->camera.meta_count++; + camdriv->camera.updatecfg |= UPDATE_META_CFG; + } else { + goto END; + } + break; + case SCANVAR: + case MOTOR: + if (argc < 3) { + snprintf(message, MSGLEN, "CAM: Insufficient arguments, the MOTOR/SCANVAR command requires the name of something you can drive like a motor or environment control"); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + if (camdriv->camera.scanvar_count < MAX_SCANVAR_COUNT) { + pCom = FindCommand(pSics, argv[2]); + if (!pCom) { + snprintf(message, MSGLEN, "CAM: There is no command object for a driveable with this name %s", argv[2]); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + pDumData = (pDummy) pCom->pData; + if (!pDumData) { + snprintf(message, MSGLEN, "CAM: There is no data for the command object of a driveable with this name %s", argv[2]); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + pDriv = (pIDrivable) pDumData->pDescriptor->GetInterface(pDumData, DRIVEID); + if (!pDriv) { + snprintf(message, MSGLEN, "CAM: %s is not a driveable object", argv[2]); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + camdriv->camera.scanvar_dummy[camdriv->camera.scanvar_count] = pDumData; + camdriv->camera.pscanvar[camdriv->camera.scanvar_count] = pDriv; + snprintf(camdriv->camera.scanvar_list[camdriv->camera.scanvar_count++], NAMELEN, "%s", argv[2]); + camdriv->camera.updatecfg |= UPDATE_SCANVAR_CFG; + } else { + snprintf(message, MSGLEN, "CAM: Exceeded maximum number (%d) of driveable objects", MAX_SCANVAR_COUNT); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + break; + case FILECMD: + if (argc < 4) { + snprintf(message, MSGLEN, "CAM: Insufficient arguments for the FILE command"); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + if (file_cmd(camdriv, pCon, argv[2], argv[3])) + camdriv->camera.updatecfg |= UPDATE_FILE_CFG; + else { + snprintf(message, MSGLEN, "CAM: Failed to create camera file configuration"); + SCWrite(pCon, message, eError); + retval = 0; + goto END; + } + break; + } +END: + if (cmd != NULL) + free(cmd); + return retval; +} + pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) { - char msg[ERRLEN], cmd[MSGLEN], reply[MSGLEN]; - int len, reply_len; + char msg[ERRLEN], cmd[MSGLEN], auxcmd[NAMELEN]; + int len; state_t start_state = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE}; pCounterDriver pCntDriv = NULL; @@ -741,6 +1003,7 @@ pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) { pNewCam = (CamObj *) malloc(sizeof(CamObj)); memset(pNewCam, 0, sizeof(CamObj)); + pNewCam->pDes = CreateDescriptor("CameraCommandObject"); STset(&pNewCam->state_machine.Sc, start_state); EVclr(&pNewCam->state_machine.Eo); pNewCam->state_machine.output_fn = camdriv_out; @@ -749,8 +1012,14 @@ pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) { pNewCam->status = HWIdle; pNewCam->camError = ENONE; pNewCam->debug = 1; - pNewCam->camera.updatecfg = 1; + pNewCam->camera.updatecfg = 0; + pNewCam->camera.meta_count = 0; + pNewCam->camera.scanvar_count = 0; + pNewCam->camera.file.startnumber = 1; + snprintf(pNewCam->camera.file.imageformat, IFMTLEN, "tif"); + pNewCam->camera.file.experimentdetail[0] = '\0'; pNewCam->asynq = strdup(asynq); + pNewCam->pSics = pServ->pSics; if (!AsyncUnitCreate(asynq, &pNewCam->asyncUnit)) { snprintf(msg, ERRLEN, "CAM:AsyncQueue %s has not been defined", asynq); @@ -783,5 +1052,8 @@ pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) { len = strlen(event_signatures[ECA_GET_STATE]); strncpy(cmd, event_signatures[ECA_GET_STATE], len); NetWatchRegisterTimerPeriodic(&pNewCam->state_timer, 2000, 500, cb_state_timer, pNewCam); + + snprintf(auxcmd, NAMELEN, "%s_cmd", name); + AddCommand(pNewCam->pSics, auxcmd, CamAuxCmd, NULL, pNewCam); return pCntDriv; }