#define ident "1A04" #ifdef VAXC #module EL755_Utility ident #endif #ifdef __DECC #pragma module EL755_Utility ident #endif /* ** +--------------------------------------------------------------+ ** | Paul Scherrer Institute | ** | Department ASQ | ** | | ** | This software may be used freely by non-profit organizations.| ** | It may be copied provided that the name of P.S.I. and of the | ** | author is included. Neither P.S.I. nor the author assume any | ** | responsibility for the use of this software outside of P.S.I.| ** +--------------------------------------------------------------+ ** ** Module Name . . . . . . . . : TAS_SRC:[PSI.LIB.SINQ]EL755_Utility.C ** ** Author . . . . . . . . . . : D. Maden ** Date of creation . . . . . . : Sep 1998 ** ** To compile this module, use: $ import tasmad $ define/group sinq_c_tlb mad_lib:sinq_c.tlb $ cc /debug /noopt /obj=[]EL755_Utility - tas_src:[psi.lib.sinq]EL755_Utility + - sinq_c_tlb/lib ** To include this module in SINQ.OLB, use: $ import tasmad $ define/group sinq_c_tlb mad_lib:sinq_c.tlb $ $ define/group sinq_olb mad_lib:sinq_dbg.olb $ @tasmad_disk:[mad.lib.sinq]sinq_olb EL755_Utility debug $ $ define/group sinq_olb mad_lib:sinq.olb $ @tasmad_disk:[mad.lib.sinq]sinq_olb EL755_Utility ** ** Updates: ** 1A01 8-Sep-1998 DM. Initial version. **============================================================================ ** The entry points included in this module are described below. Prototypes ** can be defined via: ** ** #include ** ** EL755_AddCallStack - Add a routine name to the call stack. ** EL755_Close - Close a connection to an EL755 controller. ** EL755_Config - Configure a connection to an EL755 controller. ** EL755_ErrInfo - Return detailed status from last operation. ** EL755_GetCurrents - Get the actual settings of the EL755 currents. ** EL755_Open - Open a connection to an EL755 controller. ** EL755_PutOffline - Put the EL755 off-line. ** EL755_PutOnline - Put the EL755 on-line. ** EL755_SendTillSameStr - Repeatedly send a command to EL755 controller ** until the same reply is received twice. ** EL755_SendTillSameVal - Repeatedly send a command to EL755 controller ** until the first token of the reply is the ** same fl.pnt. value twice in succession. ** EL755_SetCurrent - Set the EL755 current. **--------------------------------------------------------------------- ** int EL755_AddCallStack (&info_pntr, &name) ** ------------------ ** Input Args: ** struct EL755info *info_pntr - Pointer to structure returned by ** EL755_Open. Note that the type of the pointer ** is "struct EL755info". ** char *name - The name of the routine to be added to the call stack. ** Output Args: ** none ** Modified Args: ** none ** Return status: ** True if no problems detected, otherwise False and EL755_errcode ** is set to indicate the nature of the problem as follows: ** EL755__NOT_OPEN --> there is no connection open to the EL755, ** i.e. info_pntr is NULL. ** EL755__FORCED_CLOSED --> the connection has been force-closed ** (probably as a result of an error ** on another device on the same host). ** EL755__NO_SOCKET --> The connection has no socket - probably ** it was closed after a previous error. ** Note that EL755_errcode may have been set prior to the call to ** EL755_AddCallStack. In this case, the routine simply returns False. ** Routines called: ** None ** Description: ** The routine is designed to simplify the building of the call-stack ** which is available to the user via EL755_ErrInfo if an error occurs. ** It is intended for internal use only. ** ** If an error has aready occurred prior to the call to EL755_AddCallStack ** (i.e. EL755_errcode is non-zero), the routine simply returns False ** to prevent redundant information being added to the stack. ** ** Otherwise, the caller's name is added to the stack and basic checks ** are made of the EL755info structure. **--------------------------------------------------------------------- ** int EL755_Close (&handle, force_flag) ** ----------- ** Input Args: ** int force_flag - if non-zero, all connections using the same socket ** will also be closed (this gets AsynSrv_Close to ** actually close the socket and is needed for error ** recovery operations). ** Output Args: ** none ** Modified Args: ** void **handle - The pointer to the structure returned by EL755_Open. ** On return, the pointer is set to NULL. ** Return status: ** True always (error returns from close and free are not checked). ** Routines called: ** Socket library, "close" and memory release routine, "free". ** Description: ** The routine calls AsynSrv_Close to close the connection to the RS232C ** server. If 'force_flag' is non-zero, all other connections to the ** RS232C server which use the same socket will also be closed. ** ** The 'force_flag' can be useful in error recovery situations. The AsynSrv ** utility operates by only opening a socket for each separate combination ** of host/port. Hence, if several connections are open to a server, ** then calling EL755_Close doesn't actually close the socket until all ** connections have been closed. In the situation where an error has been ** detected, it is often desirable to close and re-open the socket as part ** of the recovery procedure. Calling EL755_Close with 'force_flag' ** non-zero will force the socket to be closed and will mark all other ** connections using this socket so that they will be informed of the ** event when they next call an AsynSrv routine. ** ** Note: The force-close action is effected by the AsynSrv package. A ** force-close will thus also close any connections to other ** RS-232-C devices (e.g. EL734 motors) on the same server. **------------------------------------------------------------------------- ** void EL755_Config (&handle, &par_id, par_val, ...) ** ------------ ** Input Args: ** char* par_id - Text string identifying the next argument (see below). ** NULL indicates the end of the argument list. ** par_val - The value to set for the argument. The type of the ** argument can depend on par_id. ** Output Args: ** none ** Modified Args: ** void **handle - The pointer to the structure returned by EL755_Open. ** It is used to hold the config info for the connection. ** Return status: ** True if no problems detected, otherwise False and EL755_errcode ** is set to indicate the nature of the problem. Values of Errcode set by ** EL755_Config are (other values may be set by the called routines): ** EL755__BAD_PAR --> Unrecognised par_id or msecTmo < 100 or ** msecTmo > 999'999 or bad eot or .. ** Routines called: ** EL755_AddCallStack ** Description: ** The routine sets values in the EL755info data structure and may modify ** the state of the temperature controller. Values which may be taken by ** par_id (par_id is case-insensitive) and the corresponding variable ** type of par_val are: ** ** "msecTmo" int The time-out response for commands sent to ** the EL755. The valid range is 100 to ** 999'999. Default is 3'000. ** "eot" char* The expected terminators in responses to ** commands sent to the EL755. The first ** character specifies the number of ** terminators (max=3). Default is "1\n". ** "index" int The DAC index in the range 1 to 8 to be ** referenced via this EL755info structure. **------------------------------------------------------------------------- ** void EL755_ErrInfo (&entry_txt_ptr, &errcode, &my_errno, &vaxc_errno) ** ------------- ** Input Args: ** None ** Output Args: ** char **entry_txt_ptr - Pointer to a text string giving the call stack ** at the time that the error was detected. ** int *errcode - An internal error code indicating the detected error. ** int *my_errno - Saved value of errno. ** int *vaxc_errno - Saved value of vaxc$errno (OpenVMS only). ** Modified Args: ** none ** Return status: ** none ** Routines called: ** none ** Description: ** Returns detailed status of the last operation. Once an error has been ** detected, the error status is frozen until this routine has been called. **------------------------------------------------------------------------- ** int EL755_GetCurrents (&handle, &soll, &ist) ** ----------------- ** ** Input Args: ** void **handle - The pointer to the structure returned by EL755_Open ** Output Args: ** float *soll - the requested current. ** float *ist - the actual current. This may me different to *soll ** since the controller ramps to a new current. ** Modified Args: ** none ** Return status: ** True if no problems detected, otherwise False and EL755_ErrInfo ** can be called to identify the problem. Values of Errcode set by ** EL755_GetCurrents are (other values may be set by the called ** routines): ** EL755__BAD_ASYNSRV --> Call to AsynSrv_SendCmnds failed. Use ** AsynSrv_ErrInfo to get more details. ** EL755__BAD_ILLG --> The response to the "I" command was probably not ** two numbers. This could happen if there is ** noise on the RS232C connection to the EL755. ** EL755__BAD_TMO --> Time-out error ("?TMO" - this gets generated ** by the RS232C server). ** EL755__OFFLINE --> The EL755 is offline ("?OF"). ** EL755__TOO_MANY --> The command was repeated too many times ** and never received the same response ** on 2 consecutive occasions. ** ** If an error is detected, *soll and *ist are undefined. ** Routines called: ** EL755_AddCallStack, AsynSrv_SendCmnds ** Description: ** EL755_Getcurrents sends an "I" command to the controller to obtain the ** currents. The command is repeated until the "soll" value is twice the ** same. ** Note: If the power supply is off or not connected (response is ** "?power-supply OFF", then no error is indicated and *soll=*ist=0.0 ** is returned. **------------------------------------------------------------------------- ** int EL755_Open (&handle, host, port, chan, indx) ** ---------- ** Input Args: ** char *host - Name of host offering the TCP/IP service. ** int port - Number of TCP/IP port of TCP/IP server. ** int chan - RS-232-C Channel number on the TCP/IP server. ** int indx - The DAC index in the range 1 to 8. This selects which ** of the 8 outputs from the EL755 are to be used. ** Output Args: ** void *handle - A pointer to a structure of type EL755info needed for ** subsequent calls to EL755_??? routines. ** Modified Args: ** none ** Return status: ** True if no problems detected, otherwise False. If False, EL755_ErrInfo ** can be called to identify the problem. Values of Errcode set by ** EL755_Open are (other values may be set by the called routines): ** EL755__BAD_MALLOC --> Call to "malloc" failed ** EL755__BAD_SOCKET --> Call to AsynSrv_Open failed. Use ** AsynSrv_ErrInfo to get more details. ** EL755__BAD_TMO --> Time-out error ("?TMO" - this gets ** generated by the RS232C server). ** EL755__BAD_OFL --> Connection to EL755 broken ("?OFL"). ** This can get generated by RS232C_SRV ** if, for example, the connection is via ** a terminal server and the terminal ** server loses power. ** EL755__BAD_DEV --> Device doesn't seem to be an EL755. The ** response to the "ID\r" command was bad. ** EL755__BAD_ILLG --> Some other unrecognised response. This ** should never occur, of course! ** EL755__BAD_ASYNSRV --> Call to AsynSrv_SendCmnds failed. Use ** AsynSrv_ErrInfo to get more details. ** Routines called: ** "calloc" - memory allocation routine. ** AsynSrv_Open ** AsynSrv_Close - called if an error detected after connection opened. ** EL755_Config ** EL755_SendTillSameStr ** Description: ** The routine opens a TCP/IP connection to a server offering the ** "RS-232-C" service for an EL755 Controller. "RMT 1", "ECHO 0" and ** "ID" commands are sent to ensure the device is an EL755 controller. **------------------------------------------------------------------------- ** int EL755_PutOffline (&handle) ** ---------------- ** Send "ECHO 1" and "RMT 0" commands to EL755 server. ** Input Args: ** void **handle - The pntr to the structure returned by EL755_Open. ** Output Args: ** none ** Modified Args: ** none ** Return status: ** True if no problems detected, otherwise False and errcode (see ** EL755_ErrInfo) is set to indicate the nature of the problem. ** Values of Errcode set by EL755_PutOffline are (other values may be set ** by the called routines): ** EL755__BAD_ASYNSRV --> An error occurred in AsynSrv_Utility. ** Call AsynSrv_ErrInfo for more info. ** EL755__BAD_ILLG --> an unrecognised response. This ** should never occur, of course! ** Routines called: ** EL755_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply ** Description: ** The routine calls AsynSrv_SendCmnds to execute "RMT 1", "ECHO 1" ** and "RMT 0" commands. The replies are checked. **------------------------------------------------------------------------- ** int EL755_PutOnline (&handle, echo) ** --------------- ** Send "RMT 1" and "ECHO x" commands to EL755 server. ** Input Args: ** void **handle - The pntr to the structure returned by EL755_Open. ** int echo - The value for the ECHO command. ** Output Args: ** none ** Modified Args: ** none ** Return status: ** True if no problems detected, otherwise False and errcode (see ** EL755_ErrInfo) is set to indicate the nature of the problem. ** Values of Errcode set by EL755_PutOnline are (other values may be set ** by the called routines): ** EL755__BAD_PAR --> "echo" is not 0, 1 or 2. ** EL755__BAD_ASYNSRV --> An error occurred in AsynSrv_Utility. ** Call AsynSrv_ErrInfo for more info. ** EL755__BAD_ILLG --> an unrecognised response. This ** should never occur, of course! ** Routines called: ** EL755_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply ** Description: ** The routine calls AsynSrv_SendCmnds to execute "RMT 1" and "ECHO x" ** commands. The replies are checked. **------------------------------------------------------------------------- ** int EL755_SendTillSameStr (&handle, &cmnd, &rply, rply_len) ** --------------------- ** Input Args: ** char *cmnd - The command to be sent (incl. terminators). ** int rply_len - The size of . ** Output Args: ** char *rply - The response to . ** Modified Args: ** void **handle - The pointer to the structure returned by EL755_Open. ** Return status: ** True if no problems detected, otherwise False. If False, EL755_ErrInfo ** can be called to identify the problem. Values of Errcode set by ** EL755_SendTillSameStr are (other values may be set by the called routines): ** EL755__BAD_ASYNSRV --> Call to AsynSrv_SendCmnds failed. Use ** AsynSrv_ErrInfo to get more details. ** EL755__BAD_ILLG --> The response to the "I" command was probably not ** two numbers. This could happen if there is ** noise on the RS232C connection to the EL755. ** EL755__BAD_TMO --> Time-out error ("?TMO" - this gets ** generated by the RS232C server). ** EL755__BAD_CMD --> Bad command ("?syntax failure") ** EL755__BAD_OFL --> Connection to EL755 broken ("?OFL"). ** This can get generated by RS232C_SRV ** if, for example, the connection is via ** a terminal server and the terminal ** server loses power. ** EL755__TOO_MANY --> The command was repeated too many times ** and never received the same response ** on 2 consecutive occasions. ** EL755__OFFLINE --> The EL755 is offline ("?OF"). ** Routines called: ** EL755_AddCallStack, EL755_ErrorLog, AsynSrv_SendCmnds, AsynSrv_GetReply ** Description: ** The routine sends the specified command to the EL755 Controller and ** reads the response. The command is repeated up to 5 times until the same ** response is received twice in succession. ** Note: ** The error EL755__TOO_MANY could indicate that is not big enough ** to hold the complete reply. **------------------------------------------------------------------------- ** int EL755_SendTillSameVal (&handle, &cmnd, &val) ** --------------------- ** Input Args: ** char *cmnd - The command to be sent (incl. terminators). ** Output Args: ** float *val - The response to . ** Modified Args: ** void **handle - The pointer to the structure returned by EL755_Open. ** Return status: ** True if no problems detected, otherwise False. If False, EL755_ErrInfo ** can be called to identify the problem. Values of Errcode set by ** EL755_SendTillSameVal are (other values may be set by the called ** routines): ** EL755__BAD_ASYNSRV --> Call to AsynSrv_SendCmnds failed. Use ** AsynSrv_ErrInfo to get more details. ** EL755__BAD_ILLG --> The response to the "I" command was probably not ** two numbers. This could happen if there is ** noise on the RS232C connection to the EL755. ** EL755__BAD_TMO --> Time-out error ("?TMO" - this gets ** generated by the RS232C server). ** EL755__BAD_CMD --> Bad command ("?syntax failure") ** EL755__BAD_OFL --> Connection to EL755 broken ("?OFL"). ** This can get generated by RS232C_SRV ** if, for example, the connection is via ** a terminal server and the terminal ** server loses power. ** EL755__TOO_MANY --> The command was repeated too many times ** and never received the same response ** on 2 consecutive occasions. ** EL755__OFFLINE --> The EL755 is offline ("?OF"). ** Routines called: ** EL755_AddCallStack, EL755_ErrorLog, AsynSrv_SendCmnds, AsynSrv_GetReply ** Description: ** The routine sends the specified command to the EL755 Controller and ** reads the response. The command is repeated up to 5 times until the ** first token is the same fl.pnt value twice in succession. ** Note 1: ** The error EL755__TOO_MANY could indicate that is not big enough ** to hold the complete reply. ** Note 2: If the power supply is off or not connected (response is ** "?power-supply OFF") then a zero value is returned and the ** return status is True **------------------------------------------------------------------------- ** int EL755_SetCurrent (&handle, soll) ** ---------------- ** ** Input Args: ** void **handle - The pointer to the structure returned by EL755_Open ** float soll - the requested current. ** Output Args: ** none ** Modified Args: ** none ** Return status: ** True if no problems detected, otherwise False and EL755_ErrInfo ** can be called to identify the problem. Values of Errcode set by ** EL755_SetCurrent are (other values may be set by the called ** routines): ** EL755__TURNED_OFF --> The EL755 power supply on this channel is ** turned off ("?power-supply OFF"). ** EL755__OUT_OF_RANGE --> The set value is out of ** range ("?value out of range"). ** EL755__TOO_LARGE --> The set value is too ** large ("?current limitation"). ** EL755__BAD_ILLG --> the response to the first "I" command was ** not null (indicating that the command was ** rejected) or the response to the second ** "I" command was probably not two numbers. ** This could happen if there is noise ** on the RS232C connection to the EL755. ** Routines called: ** EL755_SendTillSameStr, EL755_GetCurrests ** Description: ** EL755_SetCurrent sends an "I" command to the controller to set the ** current for the DAC index selected for the handle. An "I" is sent ** to check that the value was sent correctly. ** Note: If the power supply is off or not connected (response is ** "?power-supply OFF") and soll == 0.0, then return status is True. **============================================================================*/ /* **--------------------------------------------------------------------------- ** Global Definitions */ #include #include #include #include #include #include #include #include #include #include #ifdef __VMS #include #else #include #endif /*-----------------------------------------------------------------*/ #include #include #include #define True 1 #define False 0 #define NIL '\0' /*-------------------------------------------------------------------------- ** Global Variables */ static int EL755_call_depth = 0; static char EL755_routine[5][64]; static int EL755_errcode = 0; static int EL755_errno, EL755_vaxc_errno; /* **--------------------------------------------------------------------------- ** EL755_AddCallStack: Add a routine name to the call stack. ** This allows EL755_ErrInfo to generate a ** trace-back in case of error. */ int EL755_AddCallStack( /* ================== */ struct EL755info *pntr, char *name) { if (EL755_errcode != 0) return False; if (EL755_call_depth < 5) { StrJoin(EL755_routine[EL755_call_depth], sizeof(EL755_routine[0]), name, ""); EL755_call_depth++; } if (pntr == NULL) { EL755_errcode = EL755__NOT_OPEN; return False; } if (pntr->asyn_info.skt <= 0) { memset(pntr->from_host.msg_size, '0', sizeof(pntr->from_host.msg_size)); EL755_errcode = (pntr->asyn_info.skt < 0) ? EL755__FORCED_CLOSED : EL755__NO_SOCKET; return False; } return True; } /* **--------------------------------------------------------------------------- ** EL755_Close: Close a connection to an EL755 controller. */ int EL755_Close( /* =========== */ void **handle, int force_flag) { struct EL755info *info_ptr; char buff[4]; info_ptr = (struct EL755info *) *handle; if (info_ptr == NULL) return True; if (info_ptr->asyn_info.skt != 0) { if (info_ptr->asyn_info.skt > 0) { AsynSrv_Close(*handle, force_flag); } } free(*handle); *handle = NULL; return True; } /* **--------------------------------------------------------------------------- ** EL755_Config: Configure a connection to an EL755 controller. */ int EL755_Config( /* ============ */ void **handle, ...) { struct EL755info *info_ptr; char buff[80], rply[256], my_txt[16]; va_list ap; /* Pointer to variable args */ char *txt_ptr; int intval, my_txt_l; /*---------------------------------------------- */ info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_Config")) return False; /*---------------------------------------------- */ va_start(ap, handle); /* Set up var arg machinery */ txt_ptr = va_arg(ap, char *); /* Get pntr to first parameter ident */ while (txt_ptr != NULL) { my_txt_l = sizeof(my_txt); StrEdit(my_txt, txt_ptr, "lowercase", &my_txt_l); /*------------------------------------*/ if (strcmp(my_txt, "msectmo") == 0) { intval = va_arg(ap, int); if ((intval < 100) || (intval > 999999)) { EL755_errcode = EL755__BAD_PAR; return False; } sprintf(buff, "%04d", intval / 100); /* Convert to ASCII as .. ** .. deci-secs */ memcpy(info_ptr->asyn_info.tmo, buff, 4); /*------------------------------------*/ } else if (strcmp(my_txt, "eot") == 0) { txt_ptr = va_arg(ap, char *); if (txt_ptr == NULL) { EL755_errcode = EL755__BAD_PAR; return False; } memcpy(info_ptr->asyn_info.eot, "\0\0\0\0", 4); switch (txt_ptr[0]) { case '3': info_ptr->asyn_info.eot[3] = txt_ptr[3]; case '2': info_ptr->asyn_info.eot[2] = txt_ptr[2]; case '1': info_ptr->asyn_info.eot[1] = txt_ptr[1]; case '0': info_ptr->asyn_info.eot[0] = txt_ptr[0]; break; default: EL755_errcode = EL755__BAD_PAR; return False; } /*------------------------------------*/ } else if (strcmp(txt_ptr, "index") == 0) { intval = va_arg(ap, int); if ((intval < 1) || (intval > 8)) { EL755_errcode = EL755__BAD_PAR; return False; } info_ptr->index = intval; /*------------------------------------*/ } else { EL755_errcode = EL755__BAD_PAR; return False; } /*------------------------------------*/ txt_ptr = va_arg(ap, char *); /* Get pntr to next parameter ident */ } if (EL755_errcode == 0) EL755_call_depth--; return True; } /* ** ------------------------------------------------------------------------- ** EL755_ErrInfo: Return detailed status from last operation. */ void EL755_ErrInfo( /* ============= */ char **entry_txt, int *errcode, int *my_errno, int *vaxc_errno) { int i, j, k; char buff[80]; int asyn_errcode, asyn_errno, asyn_vaxerrno; char *asyn_errtxt; if (EL755_call_depth <= 0) { strcpy(EL755_routine[0], "EL755_no_error_detected"); *errcode = 0; *my_errno = 0; *vaxc_errno = 0; } else { if (EL755_call_depth > 1) { /* Concatenate the names */ for (i = 1; i < EL755_call_depth; i++) { strcat(EL755_routine[0], "/"); StrJoin(EL755_routine[0], sizeof(EL755_routine), EL755_routine[0], EL755_routine[i]); } } *errcode = EL755_errcode; *my_errno = EL755_errno; *vaxc_errno = EL755_vaxc_errno; switch (EL755_errcode) { case EL755__BAD_ASYNSRV: strcpy(buff, "/EL755__BAD_ASYNSRV"); break; case EL755__BAD_CMD: case EL755__BAD_DEV: strcpy(buff, "/EL755__BAD_DEV"); break; case EL755__BAD_ILLG: strcpy(buff, "/EL755__BAD_ILLG"); break; case EL755__BAD_MALLOC: strcpy(buff, "/EL755__BAD_MALLOC"); break; case EL755__BAD_OFL: strcpy(buff, "/EL755__BAD_OFL"); break; case EL755__BAD_PAR: strcpy(buff, "/EL755__BAD_PAR"); break; case EL755__BAD_SOCKET: strcpy(buff, "/EL755__BAD_SOCKET"); break; case EL755__BAD_TMO: strcpy(buff, "/EL755__BAD_TMO"); break; case EL755__FORCED_CLOSED: strcpy(buff, "/EL755__FORCED_CLOSED"); break; case EL755__NOT_OPEN: strcpy(buff, "/EL755__NOT_OPEN"); break; case EL755__NO_SOCKET: strcpy(buff, "/EL755__NO_SOCKET"); break; case EL755__OFFLINE: strcpy(buff, "/EL755__OFFLINE"); break; case EL755__OUT_OF_RANGE: strcpy(buff, "/EL755__OUT_OF_RANGE"); break; case EL755__OVFLOW: strcpy(buff, "/EL755__OVFLOW"); break; case EL755__TOO_LARGE: strcpy(buff, "/EL755__TOO_LARGE"); break; case EL755__TOO_MANY: strcpy(buff, "/EL755__TOO_MANY"); break; case EL755__TURNED_OFF: strcpy(buff, "/EL755__TURNED_OFF"); break; default: sprintf(buff, "/EL755__unknown_err_code: %d", EL755_errcode); } StrJoin(EL755_routine[0], sizeof(EL755_routine), EL755_routine[0], buff); } AsynSrv_ErrInfo(&asyn_errtxt, &asyn_errcode, &asyn_errno, &asyn_vaxerrno); if (asyn_errcode != 0) { strcat(EL755_routine[0], "/"); StrJoin(EL755_routine[0], sizeof(EL755_routine), EL755_routine[0], asyn_errtxt); } *entry_txt = EL755_routine[0]; EL755_call_depth = 0; EL755_errcode = 0; } /* **--------------------------------------------------------------------------- ** EL755_GetCurrents: Get currents from EL755. */ int EL755_GetCurrents( /* ================= */ void **handle, float *soll, float *ist) { int iret; char cmnd[32]; struct EL755info *info_ptr; /*---------------------------------------------- */ *soll = *ist = 0.0; info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_GetCurrents")) return False; /*---------------------------------------------- ** Send I command to get EL755 currents. Repeat until ** first value is same 2 times consecutively. */ sprintf(cmnd, "I %d\r", info_ptr->index); iret = EL755_SendTillTwoVals(handle, cmnd, soll, ist); if (!iret) return False; if (EL755_errcode == 0) EL755_call_depth--; return True; } /* **--------------------------------------------------------------------------- ** EL755_Open: Open a connection to an EL755 controller. */ int EL755_Open( /* ========== */ void **handle, char *host, int port, int chan, int indx) { int status, i; char tmo_save[4]; char *rply_ptr0, *rply_ptr1, *rply_ptr2; struct EL755info *my_handle; /*-------------------------------------------------------- ** Initialise the error info stack and pre-set the ** routine name (in case of error). */ EL755_errcode = EL755_errno = EL755_vaxc_errno = 0; strcpy(EL755_routine[0], "EL755_Open"); EL755_call_depth = 1; /*-------------------------------------------------------- ** Assume trouble */ *handle = NULL; /*-------------------------------------------------------- ** Reserve space for the data we need to store. */ my_handle = (struct EL755info *) calloc(1, sizeof(*my_handle)); if (my_handle == NULL) { EL755_errcode = EL755__BAD_MALLOC; /* calloc failed!! */ return False; } /*-------------------------------------------------------- ** Set up the connection */ StrJoin(my_handle->asyn_info.host, sizeof(my_handle->asyn_info.host), host, ""); my_handle->asyn_info.port = port; my_handle->asyn_info.chan = chan; status = AsynSrv_Open(&my_handle->asyn_info); if (!status) { EL755_errcode = EL755__BAD_SOCKET; GetErrno(&EL755_errno, &EL755_vaxc_errno); /* Save errno info */ EL755_ErrorLog("EL755_Open/AsynSrv_Open", "Failed to make connection."); free(my_handle); return False; } memcpy(tmo_save, my_handle->asyn_info.tmo, 4); status = EL755_Config((void *) &my_handle, "msecTmo", 100, /* Set a short time-out initially since ** there should be no reason for the RMT, ** ECHO or ID commands to take very long. */ "eot", "1\r", "index", indx, NULL); if (!status) { /* Some error occurred in EL755_Config - should be impossible! */ AsynSrv_Close(&my_handle->asyn_info, False); free(my_handle); return False; } /* ** Now ensure that there's an EL755 connected to the line. The first ** "RMT 1" command can fail due to pending characters in the EL755 ** input buffer causing the command to be corrupted. The response is ** ignored for this reason. */ status = AsynSrv_SendCmnds(&my_handle->asyn_info, &my_handle->to_host, &my_handle->from_host, "RMT 1\r", /* Try to put EL755 on-line */ "RMT 1\r", /* Try again in case type-ahead chars corrupted .. ** .. the first attempt. */ "ECHO 0\r", /* And turn off echoing */ NULL); status = AsynSrv_SendCmnds(&my_handle->asyn_info, &my_handle->to_host, &my_handle->from_host, "RMT 1\r", "ECHO 0\r", "ID\r", NULL); if (!status) { /* Some error occurred in AsynSrv_SendCmnds. */ AsynSrv_Close(&my_handle->asyn_info, False); free(my_handle); EL755_errcode = EL755__BAD_ASYNSRV; return False; } rply_ptr0 = AsynSrv_GetReply(&my_handle->asyn_info, &my_handle->from_host, NULL); rply_ptr1 = AsynSrv_GetReply(&my_handle->asyn_info, &my_handle->from_host, rply_ptr0); rply_ptr2 = AsynSrv_GetReply(&my_handle->asyn_info, &my_handle->from_host, rply_ptr1); if ((rply_ptr0 == NULL) || (rply_ptr1 == NULL) || (rply_ptr2 == NULL)) { /* Some error occurred in AsynSrv_GetReply. */ EL755_AddCallStack(my_handle, "NULL response"); AsynSrv_Close(&my_handle->asyn_info, False); EL755_errcode = EL755__BAD_DEV; free(my_handle); return False; } if (rply_ptr0[0] != '\0') { EL755_AddCallStack(my_handle, rply_ptr0); AsynSrv_Close(&my_handle->asyn_info, False); /* Bad response! */ EL755_errcode = EL755__BAD_DEV; free(my_handle); return False; } if (rply_ptr1[0] != '\0') { EL755_AddCallStack(my_handle, rply_ptr1); AsynSrv_Close(&my_handle->asyn_info, False); /* Bad response! */ EL755_errcode = EL755__BAD_DEV; free(my_handle); return False; } if (strncmp(rply_ptr2, "EL755 MAGST", 11) != 0) { EL755_AddCallStack(my_handle, rply_ptr2); AsynSrv_Close(&my_handle->asyn_info, False); /* Bad response! */ EL755_errcode = EL755__BAD_DEV; free(my_handle); return False; } /* The device seems to be an EL755! */ memcpy(my_handle->asyn_info.tmo, tmo_save, 4); /* Restore time-out */ /* ** The connection is complete. Pass the data structure ** back to the caller as a handle. */ *handle = my_handle; if (EL755_errcode == 0) EL755_call_depth--; return True; } /* **--------------------------------------------------------------------------- ** EL755_PutOffline: put the EL755 off-line */ int EL755_PutOffline( /* ================ */ void **handle) { int status; struct EL755info *info_ptr; char *rply_ptr0, *rply_ptr1, *rply_ptr2; char buff[132]; /*---------------------------------------------- */ info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_PutOffline")) return False; /*---------------------------------------------- ** The problem which this routine has is that the EL755 ** may already be off-line. The following is, therefore, ** rather pedantic for most cases which occur in practice. */ status = AsynSrv_SendCmnds(&info_ptr->asyn_info, &info_ptr->to_host, &info_ptr->from_host, "RMT 1\r", "RMT 1\r", "ECHO 1\r", "RMT 0\r", NULL); if (!status) { EL755_errcode = EL755__BAD_ASYNSRV; return False; } status = AsynSrv_SendCmnds(&info_ptr->asyn_info, &info_ptr->to_host, &info_ptr->from_host, "RMT\r", "", NULL); if (!status) { EL755_errcode = EL755__BAD_ASYNSRV; return False; } rply_ptr0 = AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL); rply_ptr1 = AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, rply_ptr0); if ((rply_ptr0 == NULL) || (rply_ptr1 == NULL)) { EL755_AddCallStack(info_ptr, "NULL response"); EL755_errcode = EL755__BAD_ILLG; return False; } if ((strcmp(rply_ptr0, "RMT") == 0) && (strcmp(rply_ptr1, "\n0") == 0)) { EL755_call_depth--; return True; } if (strcmp(rply_ptr0, "?OF") == 0) { EL755_errcode = EL755__OFFLINE; } else if (strcmp(rply_ptr0, "?OFL") == 0) { EL755_errcode = EL755__BAD_OFL; } else if (strcmp(rply_ptr0, "?syntax failure") == 0) { EL755_errcode = EL755__BAD_CMD; } else if (strncmp(rply_ptr0, "?TMO", 4) == 0) { EL755_errcode = EL755__BAD_TMO; } else { sprintf(buff, "Cmnd=\"RMT.\" Rply0=\"%.10s\" Rply1=\"%.10s\"", rply_ptr0, rply_ptr1); MakePrintable(buff, sizeof(buff), buff); EL755_AddCallStack(info_ptr, buff); sprintf(buff, "Unrecognised responses to RMT command: \"%s\" \"%s\"", rply_ptr0, rply_ptr1); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); EL755_errcode = EL755__BAD_ILLG; } return False; } /* **--------------------------------------------------------------------------- ** EL755_PutOnline: put the EL755 on-line */ int EL755_PutOnline( /* =============== */ void **handle, int echo) { int status, my_echo; struct EL755info *info_ptr; char cmnd0[10], buff[132]; char *rply_ptr; /*---------------------------------------------- */ info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_PutOnline")) return False; /*---------------------------------------------- */ if ((echo != 0) && (echo != 1)) { EL755_errcode = EL755__BAD_PAR; return False; } /*---------------------------------------------- ** The problem which this routine has is that the state ** of the EL755 is not known. The following is, therefore, ** rather pedantic for most cases which occur in practice. */ sprintf(cmnd0, "ECHO %d\r", echo); status = AsynSrv_SendCmnds(&info_ptr->asyn_info, &info_ptr->to_host, &info_ptr->from_host, "RMT 1\r", "RMT 1\r", cmnd0, NULL); if (!status) { EL755_errcode = EL755__BAD_ASYNSRV; return False; } status = AsynSrv_SendCmnds(&info_ptr->asyn_info, &info_ptr->to_host, &info_ptr->from_host, "ECHO\r", NULL); if (!status) { EL755_errcode = EL755__BAD_ASYNSRV; return False; } rply_ptr = AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL); if (rply_ptr == NULL) { EL755_AddCallStack(info_ptr, "NULL response"); EL755_errcode = EL755__BAD_ILLG; return False; } if ((echo == 1) && (strcmp(rply_ptr, "ECHO") == 0)) { EL755_call_depth--; return True; } else if ((echo == 0) && (sscanf(rply_ptr, "%d", &my_echo) == 1) && (my_echo == echo)) { EL755_call_depth--; return True; } if (strcmp(rply_ptr, "?OF") == 0) { EL755_errcode = EL755__OFFLINE; } else if (strcmp(rply_ptr, "?OFL") == 0) { EL755_errcode = EL755__BAD_OFL; } else if (strcmp(rply_ptr, "?syntax failure") == 0) { EL755_errcode = EL755__BAD_CMD; } else if (strncmp(rply_ptr, "?TMO", 4) == 0) { EL755_errcode = EL755__BAD_TMO; } else { sprintf(buff, "Cmnd=\"ECHO.\" Rply=\"%.10s\"", rply_ptr); MakePrintable(buff, sizeof(buff), buff); EL755_AddCallStack(info_ptr, buff); sprintf(buff, "Unrecognised response to ECHO command: \"%s\"", rply_ptr); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); EL755_errcode = EL755__BAD_ILLG; } return False; } /* **--------------------------------------------------------------------------- ** EL755_SendTillSameStr: Repeat a command until we get the same ** response on 2 successive occasions. ** ** This routine is intended for internal use only! ** If too many retries, EL755_errcode is set to EL755__TOO_MANY. */ int EL755_SendTillSameStr( /* ===================== */ void **handle, char *cmnd, char *rply, int rply_len) { int iret, i, j, n_ovfl; struct EL755info *info_ptr; char *rply_ptr; char buff[132]; char replies[6][64]; /*---------------------------------------------- */ info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_SendTillSameStr")) return False; /*---------------------------------------------- ** Send command. Do it in a ** loop until we get the same response twice to guard ** against RS-232-C problems with the EL755. */ i = n_ovfl = 0; StrJoin(rply, rply_len, "#", ""); while (i < 6) { iret = AsynSrv_SendCmnds(&info_ptr->asyn_info, &info_ptr->to_host, &info_ptr->from_host, cmnd, NULL); if (!iret) { EL755_errcode = EL755__BAD_ASYNSRV; return False; } rply_ptr = AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL); if (rply_ptr == NULL) { EL755_AddCallStack(info_ptr, "NULL response"); EL755_errcode = EL755__BAD_ILLG; return False; } if (strncmp(rply_ptr, "?TMO", 4) == 0) { EL755_errcode = EL755__BAD_TMO; return False; } if (strcmp(rply_ptr, "?OF") == 0) { EL755_errcode = EL755__OFFLINE; return False; } if (strcmp(rply_ptr, "?OFL") == 0) { EL755_errcode = EL755__BAD_OFL; return False; } if (strcmp(rply_ptr, "?syntax failure") == 0) { EL755_errcode = EL755__BAD_CMD; return False; } if (strcmp(rply_ptr, "?OV") == 0) { /* Check for overflow. This seems ** to be an EL755 problem which ** needs fixing. In the meantime, ** just force a repeat. */ sprintf(buff, "Warning -- \"?OV\" received in response to \"%s\".", cmnd); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); n_ovfl++; if (n_ovfl > 10) { EL755_errcode = EL755__TOO_MANY; return False; } } else { n_ovfl = 0; if (strncmp(rply, rply_ptr, rply_len) == 0) break; StrJoin(rply, rply_len, rply_ptr, ""); MakePrintable(replies[i], sizeof(replies[0]), rply_ptr); i++; } } if (strncmp(rply, rply_ptr, rply_len) != 0) { EL755_errcode = EL755__TOO_MANY; return False; } if (i > 1) { sprintf(buff, "Warning -- %d retries needed for Cmnd = \"%s\".", (i - 1), cmnd); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); for (j = 0; j < i; j++) fprintf(stderr, " %d: \"%s\"\n", j, replies[j]); } if (EL755_errcode != 0) return False; EL755_call_depth--; return True; } /* **--------------------------------------------------------------------------- ** EL755_SendTillSameVal: Repeat a command until we get the same ** response value on 2 successive occasions. ** ** This routine is intended for internal use only! ** If too many retries, EL755_errcode is set to EL755__TOO_MANY. */ int EL755_SendTillSameVal( /* ===================== */ void **handle, char *cmnd, float *val) { int iret, i, n_ovfl, cnt; struct EL755info *info_ptr; float last_val; char *rply_ptr, *tok; char buff[132]; /*---------------------------------------------- */ info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_SendTillSameVal")) return False; /*---------------------------------------------- ** Send command. Do it in a ** loop until we get the same response twice to guard ** against RS-232-C problems with the EL755. */ i = n_ovfl = 0; *val = 9999.999; last_val = *val - 1.0; while (i < 6) { iret = AsynSrv_SendCmnds(&info_ptr->asyn_info, &info_ptr->to_host, &info_ptr->from_host, cmnd, NULL); if (!iret) { EL755_errcode = EL755__BAD_ASYNSRV; return False; } rply_ptr = AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL); if (rply_ptr == NULL) { EL755_AddCallStack(info_ptr, "NULL response"); EL755_errcode = EL755__BAD_ILLG; return False; } if (strcmp(rply_ptr, "?OV") == 0) { /* Check for overflow. This seems ** to be an EL755 problem which ** needs fixing. In the meantime, ** just force a repeat. */ sprintf(buff, "Warning -- \"?OV\" received in response to \"%s\".", cmnd); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); n_ovfl++; if (n_ovfl > 10) { EL755_errcode = EL755__TOO_MANY; return False; } } else { n_ovfl = 0; if (strcmp(rply_ptr, "?OF") == 0) { EL755_errcode = EL755__OFFLINE; return False; } if (strcmp(rply_ptr, "?OFL") == 0) { EL755_errcode = EL755__BAD_OFL; return False; } if (strcmp(rply_ptr, "?syntax failure") == 0) { EL755_errcode = EL755__BAD_CMD; return False; } if (strcmp(rply_ptr, "?power-supply OFF") == 0) { /* If off, return 0 */ *val = 0.0; EL755_call_depth--; return True; } else { tok = strtok(rply_ptr, " "); if ((tok == NULL) || (sscanf(tok, "%f%n", val, &cnt) != 1) || (cnt != strlen(tok))) { EL755_AddCallStack(info_ptr, rply_ptr); EL755_errcode = EL755__BAD_ILLG; return False; } if (*val == last_val) break; last_val = *val; } i++; } } if (last_val != *val) { EL755_errcode = EL755__TOO_MANY; return False; } if (i > 1) { sprintf(buff, "Warning -- %d retries needed for Cmnd = \"%s\".", (i - 1), cmnd); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); } if (EL755_errcode != 0) return False; EL755_call_depth--; return True; } /* **--------------------------------------------------------------------------- ** EL755_SendTillTwoVals: Repeat a command until we get 2 fl.pt. ** values and the first is the same on 2 ** successive occasions. ** ** This routine is intended for internal use only! It is ** intended to read the Soll- and Ist-currents where the ** Soll-value should be the same but the Ist-value could be ** changing as the power supply ramps to a new value. ** If too many retries, EL755_errcode is set to EL755__TOO_MANY. */ int EL755_SendTillTwoVals( /* ===================== */ void **handle, char *cmnd, float *val0, float *val1) { int iret, i, n_ovfl, cnt0, cnt1; struct EL755info *info_ptr; float last_val; char *rply_ptr, *tok0, *tok1; char buff[132]; /*---------------------------------------------- */ info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_SendTillTwoVals")) return False; /*---------------------------------------------- ** Send command. Do it in a ** loop until we get the same response twice to guard ** against RS-232-C problems with the EL755. */ i = n_ovfl = 0; *val0 = 9999.999; last_val = *val0 - 1.0; while (i < 6) { iret = AsynSrv_SendCmnds(&info_ptr->asyn_info, &info_ptr->to_host, &info_ptr->from_host, cmnd, NULL); if (!iret) { EL755_errcode = EL755__BAD_ASYNSRV; return False; } rply_ptr = AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL); if (rply_ptr == NULL) { EL755_AddCallStack(info_ptr, "NULL response"); EL755_errcode = EL755__BAD_ILLG; return False; } if (strcmp(rply_ptr, "?OV") == 0) { /* Check for overflow. This seems ** to be an EL755 problem which ** needs fixing. In the meantime, ** just force a repeat. */ sprintf(buff, "Warning -- \"?OV\" received in response to \"%s\".", cmnd); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); n_ovfl++; if (n_ovfl > 10) { EL755_errcode = EL755__TOO_MANY; return False; } } else { n_ovfl = 0; if (strcmp(rply_ptr, "?OF") == 0) { EL755_errcode = EL755__OFFLINE; return False; } if (strcmp(rply_ptr, "?OFL") == 0) { EL755_errcode = EL755__BAD_OFL; return False; } if (strcmp(rply_ptr, "?syntax failure") == 0) { EL755_errcode = EL755__BAD_CMD; return False; } if (strcmp(rply_ptr, "?power-supply OFF") == 0) { /* If off, return 0 */ *val0 = 0.0; *val1 = 0.0; EL755_call_depth--; return True; } else { tok0 = strtok(rply_ptr, " "); tok1 = strtok(NULL, " "); if ((tok0 == NULL) || (tok1 == NULL) || (sscanf(tok0, "%f%n", val0, &cnt0) != 1) || (sscanf(tok1, "%f%n", val1, &cnt1) != 1) || (cnt0 != strlen(tok0)) || (cnt1 != strlen(tok1))) { EL755_AddCallStack(info_ptr, rply_ptr); EL755_errcode = EL755__BAD_ILLG; return False; } if (*val0 == last_val) break; last_val = *val0; } i++; } } if (last_val != *val0) { EL755_errcode = EL755__TOO_MANY; return False; } if (i > 1) { sprintf(buff, "Warning -- %d retries needed for Cmnd = \"%s\".", (i - 1), cmnd); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); } if (EL755_errcode != 0) return False; EL755_call_depth--; return True; } /* **--------------------------------------------------------------------------- ** EL755_SetCurrent: Sets current via EL755. */ int EL755_SetCurrent( /* ================ */ void **handle, float soll) { int i, iret; float my_soll, my_ist; char cmnd[32], cmnd0[32], buff[132], buff1[132]; struct EL755info *info_ptr; /*---------------------------------------------- */ info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_SetCurrent")) return False; /*---------------------------------------------- ** Send I command to set EL755 current and I command ** to read back the set value. ** Repeat until set value is correct. */ sprintf(cmnd, "I %d %.4f\r", info_ptr->index, soll); sprintf(cmnd0, "I %d\r", info_ptr->index); i = 0; my_soll = soll + 1.0; while ((i < 6) && (fabs(soll - my_soll) > 0.01)) { iret = EL755_SendTillSameStr(handle, cmnd, buff, sizeof(buff)); if (!iret) return False; if (buff[0] == NIL) { /* We should get a null response */ iret = EL755_SendTillSameVal(handle, cmnd0, &my_soll); if (!iret) return False; } else if (strcmp(buff, "?value out of range") == 0) { EL755_errcode = EL755__OUT_OF_RANGE; return False; } else if (strcmp(buff, "?current limitation") == 0) { EL755_errcode = EL755__TOO_LARGE; return False; } else if (strcmp(buff, "?power-supply OFF") == 0) { if (soll == 0.0) { /* Suppress error if trying to set zero and .. power supply is off! */ if (EL755_errcode != 0) return False; EL755_call_depth--; return True; } else { EL755_errcode = EL755__TURNED_OFF; return False; } } else { sprintf(buff1, "Cmnd=\"%s\" Rply=\"%.10s\"", cmnd, buff); MakePrintable(buff1, sizeof(buff1), buff1); EL755_AddCallStack(info_ptr, buff1); EL755_errcode = EL755__BAD_ILLG; return False; } i++; } if (fabs(soll - my_soll) > 0.01) { EL755_errcode = EL755__TOO_MANY; return False; } if (i > 1) { sprintf(buff, "Warning -- %d retries needed for Cmnd = \"%s\".", (i - 1), cmnd); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); } if (EL755_errcode != 0) return False; EL755_call_depth--; return True; } /* **--------------------------------------------------------------------------- ** EL755_Send sends a command to the EL755 and gets a reply ** ** This routine is intended for internal use only! */ int EL755_Send( /* ===================== */ void **handle, char *cmnd, char *rply, int rply_len) { int iret, i, j, n_ovfl; struct EL755info *info_ptr; char *rply_ptr; char buff[132]; char replies[6][64]; /*---------------------------------------------- */ info_ptr = (struct EL755info *) *handle; if (!EL755_AddCallStack(info_ptr, "EL755_SendTillSameStr")) return False; /*---------------------------------------------- ** Send command. */ i = n_ovfl = 0; StrJoin(rply, rply_len, "#", ""); iret = AsynSrv_SendCmnds(&info_ptr->asyn_info, &info_ptr->to_host, &info_ptr->from_host, cmnd, NULL); if (!iret) { EL755_errcode = EL755__BAD_ASYNSRV; return False; } rply_ptr = AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL); if (rply_ptr == NULL) { EL755_AddCallStack(info_ptr, "NULL response"); EL755_errcode = EL755__BAD_ILLG; return False; } if (strncmp(rply_ptr, "?TMO", 4) == 0) { EL755_errcode = EL755__BAD_TMO; return False; } if (strcmp(rply_ptr, "?OF") == 0) { EL755_errcode = EL755__OFFLINE; return False; } if (strcmp(rply_ptr, "?OFL") == 0) { EL755_errcode = EL755__BAD_OFL; return False; } if (strcmp(rply_ptr, "?syntax failure") == 0) { EL755_errcode = EL755__BAD_CMD; return False; } if (strcmp(rply_ptr, "?OV") == 0) { /* Check for overflow. This seems ** to be an EL755 problem which ** needs fixing. In the meantime, ** just force a repeat. */ sprintf(buff, "Warning -- \"?OV\" received in response to \"%s\".", cmnd); MakePrintable(buff, sizeof(buff), buff); EL755_ErrorLog(EL755_routine[EL755_call_depth - 1], buff); n_ovfl++; if (n_ovfl > 10) { EL755_errcode = EL755__TOO_MANY; return False; } } else { n_ovfl = 0; if (strncmp(rply, rply_ptr, rply_len) == 0) { return False; } StrJoin(rply, rply_len, rply_ptr, ""); MakePrintable(replies[i], sizeof(replies[0]), rply_ptr); i++; } if (EL755_errcode != 0) return False; EL755_call_depth--; return True; } /*-------------------------------------------- End of EL755_Utility.C =======*/