sct_protek608.c
Implements a protocol handler for the protek 608 multimeters which just allows us to read the display. It reports all elements of the display including the bar graph, it does not provide remote control of the multimeter. The protocol handler broadcasts a warning to all clients if the auto-off function is enabled. sct_rfamp.c This is a protocol handler for the Mirrortron 35V 7A AC Generator (ANSFR-83B). sinqhttpprot.c Copied the PSI script context http protocol handler. sct_orhvpsprot.c Ordela high voltage power supply protocol handler now catches unknown commands. sct_eurotherm_2000.tcl Eurotherm controller for the kowari load frame by Douglas Clowes. sct_lakeshore_3xx.tcl Latest update from Arndt. The two control loops are now independent, settletime and tolerance now work properly. common_instrument_dictionary.tcl Make instrument/status saveable. sct_orhvps_common.tcl Provides voltage ramping and implements the dhv1 command for the Ordela HVPS via the sct_orhpsprot.c protocol handler. hmm_configuration_common_1.tcl Adds new "histmem clockscale" subcommand to get and set the clock scale from the fat_clock_scale FAT parameter. You can now upload the FAT FRAME_BUFFER and FRAME_DUTYCYCLE parameters to the histogram memory. The veto commands are now "histmem veto on" and "histmem veto off". hmm_object.tcl The axis order for the histmem object has been restore to t,y,x sct_positmotor_common.tcl Code has been simplified. nxscripts_common_1.tcl Removed obsolete ::nexus::data function. TOF axis now correctly report time_of_flight instead of "time". plc_common_1.tcl Make PLC info saveable. scan_common_1.tcl SICS-385 The scan command should check the final scan variable value against he soft upper and lower limits, not against the hard limits. Make sure that the scan variable axis is saved. platypus, kowari, quokka hmm_configuration.tcl Use the HOR and VER entries in the new histmem_axes hash to select the horizontal and vertical axes for the histmem. kowari motor_configuration.tcl secondary_slit_configuration.tcl Flatten slits motor structure to match old layout in data files. quokka commands.tcl SICS-380 EApPosYmm -> EApPosY quokka detector.tcl Use new script context controller for Ordela HVPS quokka hmm_configuration.tcl Set detector height to 5.08*192 the same as the width quokka motor_configuration.tcl Code cleanup quokka positmotor_configuration.tcl Use new positmotor code. quokka aperture_configuration.tcl Added attenuation factor column to AttRotLookupTable quokka parameters.tcl SICS-380 Refactor nexus, remove redundant parameters. site_ansto.c Added the following protocols, Httpl, Protek608, aand RFAmp. scriptcontext.c SICS-386 SctActionHandler: set "send" string to NULL when a chain of scripts completes with state=idle. It turns out that if none of the scripts in the "read chain" call [sct send] each time the chain is executed, then SICS will hammer the device with calls to AsconWrite(). This can be avoided if SctActionHandler sets the 'send' string to NULL before "goto finish" in the idle state. This will be safer and still let you have chains with multiple [sct send] and read scripts. asyncprotocol.c Fix platypus memory leak. devser.c SICS-387 Started adding code to pass signals on to script context drivers. ascon.c AsconTask(): Make sure we return to the AsconIdle state when sending a command which expect no response, also only reconnect if there is a Timeout when there has been an error. r2888 | ffr | 2010-04-19 14:04:41 +1000 (Mon, 19 Apr 2010) | 90 lines
This commit is contained in:
committed by
Douglas Clowes
parent
aa6bb7f1da
commit
d9da95a5df
@@ -1,17 +1,21 @@
|
||||
/** @file OrdHVPS protocol handler for script-context based controllers.
|
||||
* Author: Ferdi Franceschini
|
||||
*
|
||||
* ffr This is a replacement for the orhvps.c controller which suffered from state lockups
|
||||
* The new driver will resend a command if it receives a NAK.
|
||||
* MJL 17/9/08 implement a special command mode to make life easier
|
||||
*
|
||||
TODO Make dhv1 object, refer to following cmd IO for scripting.
|
||||
sct_dhv1 transact "P x4"
|
||||
x4 6
|
||||
sct_dhv1 transact v
|
||||
ORDELA 2.10 07/24/00
|
||||
sct_dhv1 transact H
|
||||
56
|
||||
set msg [sct_dhv1 transact {h 57}]
|
||||
ACK
|
||||
sct_dhv1 transact H
|
||||
57
|
||||
* Examples
|
||||
sct_dhv1 transact "P x4"
|
||||
x4 6
|
||||
sct_dhv1 transact v
|
||||
ORDELA 2.10 07/24/00
|
||||
sct_dhv1 transact H
|
||||
56
|
||||
set msg [sct_dhv1 transact {h 57}]
|
||||
ACK
|
||||
sct_dhv1 transact H
|
||||
57
|
||||
|
||||
* TODO Remove globals and statics if we want to allow more controllers.
|
||||
*/
|
||||
@@ -84,6 +88,11 @@ int OrdHVPSWriteStart(Ascon *a) {
|
||||
case 'B': pcmdrspfmt="B%Bz-B%B%dz"; break; // Query if board disabled
|
||||
case 'l': pcmdrspfmt="l%Bz-%A"; break; // Re-enable a board
|
||||
case 'J': pcmdrspfmt="Jz-J%dz"; break; // Check jumper settings
|
||||
default:
|
||||
a->state = AsconIdle;
|
||||
AsconError(a, "Unknown command", 0);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
// Prepare the command string
|
||||
char *pcmd=cmd;
|
||||
|
||||
470
site_ansto/hardsup/sct_protek608.c
Normal file
470
site_ansto/hardsup/sct_protek608.c
Normal file
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
@file sct_protek.c
|
||||
@brief Protocol handler for Protek 608 multimeter
|
||||
|
||||
Reads the display bitmap and generates an ASCII string similar to the
|
||||
following,
|
||||
SD3:0.|SD4:1|SD5: |DUTY2:0|HOLD2:0|RANGE2:0|ZD2:0|DC2:0|SIGN2:0|AC2:0|CONT2:0|PW1:0|X1:0|B1:1|B0:1|B16:0|B8:0|B4:0|B2:0|DC1:1|SIGN1:1|AC1:0|LOBAT:0|MD5:0.|MD4:0|MD3:0|X2:0|X3:0|PLUS:0|MINUS:0|RS232C:1|AUTOOFF:0|X4:0|PULSE:0|STORE:0|AVG:0|MINUSPEAK:0|MIN:0|RECALL:0|REL:0|PLUSPEAK:0|MAX:0|GO/NG:0|REF:0|MINUSPER:0|PLUSPER:0|MD2:0|MD1:2|s1:0|DEGF1:0|Hz1:0|X5:0|F1:0|A1:0|OHM1:0|X6:0|DEGC1:0|S1:0|V1:1|k1:0|n1:0|m1:0|u1:0|M1:0|B8K:0|B16K:0|X7:0|X8:0|B4K:0|B2K:0|B1K:0|B512:0|B32:0|B64:0|B128:0|B256:0|M2:1|G2:0|m2:0|PERCENT2:0|k2:0|OHM2:1|V2:0|dBm2:0|X9:0|Hz2:0|A2:0|DEGK2:0|SD1:0|SD2:5|ROTSWITCH:0
|
||||
|
||||
NOTE: Multimeter must be connected via a moxa box
|
||||
|
||||
Author: Ferdi Franceschini (ffr@ansto.gov.au)
|
||||
TODO The letters I, S, and O are currently being returned as 1, 5, and 0.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ascon.h>
|
||||
#include <ascon.i>
|
||||
#include <dynstring.h>
|
||||
|
||||
#define ERRLEN 128
|
||||
#define CMDLEN 12
|
||||
#define LASTBYTENUM 42
|
||||
|
||||
/* @brief Returns '1' if bit is set otherwise '0' */
|
||||
#define GETBIT(MASK, BYTE) (MASK & BYTE ? '1' : '0')
|
||||
|
||||
/* @brief Interprets BYTE and returns a string of fields and values, eg "F1:v1|F2:v2" */
|
||||
#define SETFIELD(L1, L2, L3, L4, BYTE) (sprintf(field, "%s:%c|%s:%c|%s:%c|%s:%c", L1, GETBIT(0x8, BYTE), L2, GETBIT(0x4, BYTE), L3, GETBIT(0x2, BYTE), L4, GETBIT(0x1, BYTE)))
|
||||
|
||||
struct protekData {
|
||||
unsigned char defa, xcgb;
|
||||
int first;
|
||||
};
|
||||
|
||||
void protKill(void *private)
|
||||
{
|
||||
struct protekData *data = private;
|
||||
free(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Decodes a seven segment display bit pattern into an ASCII character
|
||||
* The point bit, x in xCGB, is ignored in an 8 segment bit pattern.
|
||||
*
|
||||
* @param DEFA bit pattern for the left half of a seven segment display
|
||||
* @param xCGB bit pattern fot the right half of the display, x is the point bit for an 8 segment pattern.
|
||||
* @return ASCII numeral '0' - '9', ' ' for a blank character, 'L' (eg in OL)
|
||||
* 'A', 'd', 'E', 'F', 'h', 'I', 'L', 'n', 'P', 'r', 'S', 't', or 'U' for Unknown
|
||||
*
|
||||
*/
|
||||
unsigned char segChar(unsigned char DEFA, unsigned char xCGB)
|
||||
{
|
||||
unsigned char num, DEFA0CGB;
|
||||
|
||||
DEFA0CGB = (DEFA << 4) | (0x7 & xCGB);
|
||||
switch (DEFA0CGB) {
|
||||
case 0x0:
|
||||
num = ' ';
|
||||
break;
|
||||
case 0xF5:
|
||||
//TODO O or zero
|
||||
num = '0';
|
||||
break;
|
||||
case 0x05:
|
||||
//TODO I or 1
|
||||
num = '1';
|
||||
break;
|
||||
case 0xD3:
|
||||
num = '2';
|
||||
break;
|
||||
case 0x97:
|
||||
num = '3';
|
||||
break;
|
||||
case 0x27:
|
||||
num = '4';
|
||||
break;
|
||||
case 0xB6:
|
||||
//TODO 5 or S
|
||||
num = '5';
|
||||
break;
|
||||
case 0xF6:
|
||||
num = '6';
|
||||
break;
|
||||
case 0x35:
|
||||
num = '7';
|
||||
break;
|
||||
case 0xF7:
|
||||
num = '8';
|
||||
break;
|
||||
case 0xB7:
|
||||
num = '9';
|
||||
break;
|
||||
case 0x77:
|
||||
num = 'A';
|
||||
break;
|
||||
case 0xC2:
|
||||
num = 'c';
|
||||
break;
|
||||
case 0xD7:
|
||||
num = 'd';
|
||||
break;
|
||||
case 0xF4:
|
||||
num = 'E';
|
||||
break;
|
||||
case 0x72:
|
||||
num = 'F';
|
||||
break;
|
||||
case 0x66:
|
||||
num = 'h';
|
||||
break;
|
||||
case 0xE0:
|
||||
num = 'L';
|
||||
break;
|
||||
case 0x46:
|
||||
num = 'n';
|
||||
break;
|
||||
case 0x73:
|
||||
num = 'P';
|
||||
break;
|
||||
case 0x42:
|
||||
num = 'r';
|
||||
break;
|
||||
case 0xE2:
|
||||
num = 't';
|
||||
break;
|
||||
default:
|
||||
num = 'U';
|
||||
break;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
/*
|
||||
* @brief Translates incoming bytes and generates the corresponding field of the status string
|
||||
*
|
||||
* @param byte, a character read from the protek multimeter
|
||||
* @param byteNum, the position of the character in the protek protocol
|
||||
* @param *str, translation of the byte into a "field:value" string where "value" is either an ASCII
|
||||
* character or a boolean represented as a '1' or '0' character and "field" is a label.
|
||||
* @return -1=ERROR, 0=NOTDONE, 1=DONE and str is set to translated bits
|
||||
*
|
||||
* The "switch" statement corresponds to the protocol table in the Protek 608 manual pg44
|
||||
* with the labels for the bits written in reverse order so that they match
|
||||
* the bit patterns we read from the multimeter
|
||||
*/
|
||||
int translateByte(struct protekData *data, char byte, int byteNum, char *str)
|
||||
{
|
||||
unsigned char num;
|
||||
char field[64]="";
|
||||
int gotSegChar=0;
|
||||
|
||||
switch (byteNum) {
|
||||
case 1: /* SD3 p7,C,G,B */
|
||||
data->xcgb = byte;
|
||||
break;
|
||||
case 2: /* SD3 D,E,F,A */
|
||||
data->defa= byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "SD3");
|
||||
break;
|
||||
case 3: /* SD4 p8,C,G,B */
|
||||
data->xcgb = byte;
|
||||
break;
|
||||
case 4: /* SD4 D,E,F,A */
|
||||
data->defa= byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "SD4");
|
||||
break;
|
||||
case 5: /* SD5 p9,C,G,B */
|
||||
data->xcgb = byte;
|
||||
break;
|
||||
case 6: /* SD5 D,E,F,A */
|
||||
data->defa= byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "SD5");
|
||||
break;
|
||||
case 7: /* bits 25-32 SUB UNIT DUTY2,HOLD2,RANGE2,ZD2 (ZENERDIODE) */
|
||||
SETFIELD("DUTY2", "HOLD2", "RANGE2", "ZD2", byte);
|
||||
break;
|
||||
case 8: /* bits 25-32 SUB UNIT DC2,SIGN2,AC2,CONT2 */
|
||||
SETFIELD("DC2", "SIGN2", "AC2", "CONT2", byte);
|
||||
break;
|
||||
case 9: /* BAR GRAPH PW1,x,B1,B0 */
|
||||
SETFIELD("PW1", "X1", "B1", "B0", byte);
|
||||
break;
|
||||
case 10: /* BAR GRAPH B16,B8,B4,B2 */
|
||||
SETFIELD("B16", "B8", "B4", "B2", byte);
|
||||
break;
|
||||
case 11: /* DC1,SIGN1,AC1,LOBAT */
|
||||
SETFIELD("DC1", "SIGN1", "AC1", "LOBAT", byte);
|
||||
break;
|
||||
case 12: /* MD5 D,E,F,A */
|
||||
data->defa = byte;
|
||||
break;
|
||||
case 13: /* MD5 p4,C,G,B */
|
||||
data->xcgb = byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "MD5");
|
||||
break;
|
||||
case 14: /* MD4 D,E,F,A */
|
||||
data->defa = byte;
|
||||
break;
|
||||
case 15: /* MD4 p3,C,G,B */
|
||||
data->xcgb = byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "MD4");
|
||||
break;
|
||||
case 16: /* MD3 D,E,F,A */
|
||||
data->defa = byte;
|
||||
break;
|
||||
case 17: /* MD3 p2,C,G,B */
|
||||
data->xcgb = byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "MD3");
|
||||
break;
|
||||
case 18: /* x,x,+,- */
|
||||
SETFIELD("X2", "X3", "PLUS", "MINUS", byte);
|
||||
break;
|
||||
case 19: /* RS232C,AUTOOFF,x,PULSE */
|
||||
SETFIELD("RS232C", "AUTOOFF", "X4", "PULSE", byte);
|
||||
break;
|
||||
case 20: /* STORE,AVG,MINUSPEAK,MIN */
|
||||
SETFIELD("STORE", "AVG", "MINUSPEAK", "MIN", byte);
|
||||
break;
|
||||
case 21: /* RECALL,REL,PLUSPEAK,MAX */
|
||||
SETFIELD("RECALL", "REL", "PLUSPEAK", "MAX", byte);
|
||||
break;
|
||||
case 22: /* GO/NG,REF,MINUSPER,PLUSPER */
|
||||
SETFIELD("GO/NG", "REF", "MINUSPER", "PLUSPER", byte);
|
||||
break;
|
||||
case 23: /* MD2 D,E,F,A */
|
||||
data->defa = byte;
|
||||
break;
|
||||
case 24: /* MD2 p1,C,G,B */
|
||||
data->xcgb = byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "MD2");
|
||||
break;
|
||||
case 25: /* MD1 D,E,F,A*/
|
||||
data->defa = byte;
|
||||
break;
|
||||
case 26: /* MD1 x,C,G,B */
|
||||
data->xcgb = byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "MD1");
|
||||
break;
|
||||
case 27: /* s1,DEGF1,Hz1,x */
|
||||
SETFIELD("s1", "DEGF1", "Hz1", "X5", byte);
|
||||
break;
|
||||
case 28: /* F1,A1,OHM1,x */
|
||||
SETFIELD("F1", "A1", "OHM1", "X6", byte);
|
||||
break;
|
||||
case 29: /* DEGC1,S1,V1,k1 */
|
||||
SETFIELD("DEGC1", "S1", "V1", "k1", byte);
|
||||
break;
|
||||
case 30: /* n1,m1,u1,M1 */
|
||||
SETFIELD("n1", "m1", "u1", "M1", byte);
|
||||
break;
|
||||
case 31: /* BAR GRAPH B8K,B16K,x,x */
|
||||
SETFIELD("B8K", "B16K", "X7", "X8", byte);
|
||||
break;
|
||||
case 32: /* BAR GRAPH B4K,B2K,B1K,B512 */
|
||||
SETFIELD("B4K", "B2K", "B1K", "B512", byte);
|
||||
break;
|
||||
case 33: /* BAR GRAPH B32,B64,B128,B256 */
|
||||
SETFIELD("B32", "B64", "B128", "B256", byte);
|
||||
break;
|
||||
case 34: /* BAR GRAPH M2,G2,m2,PERCENT2 */
|
||||
SETFIELD("M2", "G2", "m2", "PERCENT2", byte);
|
||||
break;
|
||||
case 35: /* bits 133-143 SUB UNIT k2,OHM2,V2,dBm2 */
|
||||
SETFIELD("k2", "OHM2", "V2", "dBm2", byte);
|
||||
break;
|
||||
case 36: /* bits 133-143 SUB UNIT x,Hz2,A2,DEGK2 */
|
||||
SETFIELD("X9", "Hz2", "A2", "DEGK2", byte);
|
||||
break;
|
||||
case 37: /* SD1 x,C,G,B */
|
||||
data->xcgb = byte;
|
||||
break;
|
||||
case 38: /* SD1 D,E,F,A */
|
||||
data->defa= byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "SD1");
|
||||
break;
|
||||
case 39: /* SD2 p6,C,G,B */
|
||||
data->xcgb = byte;
|
||||
break;
|
||||
case 40: /* SD2 D,E,F,A */
|
||||
data->defa= byte;
|
||||
gotSegChar=1;
|
||||
strcpy(field, "SD2");
|
||||
break;
|
||||
case 41:
|
||||
/* Last byte is undocumented but it seems to be the rotary switch position
|
||||
Positions range from 0 (V) to 8 (A).
|
||||
*/
|
||||
sprintf(field, "ROTSWITCH:%X", byte);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (field[0] != '\0') {
|
||||
if (gotSegChar) {
|
||||
num = segChar(data->defa, data->xcgb);
|
||||
if (num == 'U') {
|
||||
return -1;
|
||||
}
|
||||
if ((010 & data->xcgb) == 010) {
|
||||
sprintf(str, "%s:%c.", field, num);
|
||||
} else {
|
||||
sprintf(str, "%s:%c", field, num);
|
||||
}
|
||||
} else {
|
||||
strcpy(str,field);
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Constructs a status string from the display map sent by the Protek
|
||||
*
|
||||
* The multimeter sends two data packets per second bounded by '['(0x5B) and ']'(0x5D)
|
||||
* NOTE: Sometimes it sends 0x1D instead of 0x5D at the end of a packet
|
||||
*/
|
||||
int Protek608Reading(Ascon *a)
|
||||
{
|
||||
int ret, DS_AllocFailed = 0, transByteStatus = 0, transByteFailed = 0;
|
||||
int errNum = 0;
|
||||
char chr=0, field[64], errMsg[ERRLEN];
|
||||
struct protekData *data = a->private;
|
||||
|
||||
/* a->readState == 0 means we haven't yet seen the start of a packet (ie the '[')
|
||||
* a->readState > 0 is the current byte number
|
||||
*/
|
||||
while ( ( ret = AsconReadChar(a->fd, &chr) ) > 0) {
|
||||
a->start = DoubleTime();
|
||||
if (a->readState) {
|
||||
if (a->readState >= LASTBYTENUM) {
|
||||
a->readState = 0;
|
||||
a->state = AsconReadDone;
|
||||
data->first = 1;
|
||||
if (0 == DynStringConcatChar(a->rdBuffer, '\0')) {
|
||||
strcpy(errMsg, "PROTEK608: DynStringConcat or DynStringConcatChar failed:");
|
||||
errNum = ENOMEM;
|
||||
DS_AllocFailed = 1;
|
||||
break;
|
||||
}
|
||||
if (chr != ']' && chr != 0x1D) {
|
||||
snprintf(errMsg, ERRLEN, "PROTEK608: Unexpected value %X for last byte:", chr);
|
||||
AsconError(a, errMsg, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
transByteStatus = translateByte(a->private, chr, (a->readState)++, field);
|
||||
if (transByteStatus == 1) {
|
||||
if (data->first) {
|
||||
if ( 0== DynStringConcat(a->rdBuffer, field) ) {
|
||||
strcpy(errMsg, "PROTEK608: DynStringConcat or DynStringConcatChar failed:");
|
||||
errNum = ENOMEM;
|
||||
DS_AllocFailed = 1;
|
||||
break;
|
||||
}
|
||||
data->first=0;
|
||||
} else {
|
||||
if ( 0 == DynStringConcatChar(a->rdBuffer, '|') ) {
|
||||
strcpy(errMsg, "PROTEK608: DynStringConcat or DynStringConcatChar failed:");
|
||||
errNum = ENOMEM;
|
||||
DS_AllocFailed = 1;
|
||||
break;
|
||||
}
|
||||
if ( 0 == DynStringConcat(a->rdBuffer, field) ) {
|
||||
strcpy(errMsg, "PROTEK608: DynStringConcat or DynStringConcatChar failed:");
|
||||
errNum = ENOMEM;
|
||||
DS_AllocFailed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (transByteStatus == -1) {
|
||||
snprintf(errMsg, ERRLEN, "PROTEK608: Failed to translate %X in byte number %d:", chr, a->readState-1);
|
||||
errNum = 0;
|
||||
transByteFailed = 1;
|
||||
break;
|
||||
}
|
||||
} else if (chr == '[') {
|
||||
a->readState = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
AsconError(a, "PROTEK608: AsconReadChar failed:", errno);
|
||||
return 1;
|
||||
}
|
||||
if (DS_AllocFailed || transByteFailed) {
|
||||
a->state = AsconReadDone;
|
||||
a->readState = 0;
|
||||
data->first = 1;
|
||||
AsconError(a, errMsg, errNum);
|
||||
return 1;
|
||||
}
|
||||
if (a->timeout > 0) {
|
||||
if (DoubleTime() - a->start > a->timeout) {
|
||||
AsconError(a, "PROTEK608: read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Protocol handler for Protek 608 multimeter
|
||||
*
|
||||
* It overrides the AsconWriteStart and AsconReading states of the standard handler.
|
||||
* Available commands,
|
||||
* "STATE": Requests a state report
|
||||
*
|
||||
* NOTE: The multimeter is always sending a display map at 0.5 second intervals, the "STATE" command
|
||||
* simply forces a transition from the AsconWriteStart state to the AsconReadStart state.
|
||||
*/
|
||||
int Protek608ProtHandler(Ascon *a)
|
||||
{
|
||||
char *wrBuffArr, errMsg[ERRLEN];
|
||||
switch(a->state) {
|
||||
case AsconWriteStart:
|
||||
wrBuffArr = GetCharArray(a->wrBuffer);
|
||||
if (strncasecmp(wrBuffArr, "STATE", CMDLEN) != 0) {
|
||||
a->state = AsconIdle;
|
||||
snprintf(errMsg, ERRLEN, "PROTEK608: Unknown command %s", wrBuffArr);
|
||||
AsconError(a, errMsg, 0);
|
||||
return 0;
|
||||
}
|
||||
a->wrPos = 0;
|
||||
AsconReadGarbage(a->fd);
|
||||
a->state = AsconReadStart;
|
||||
return 1;
|
||||
break;
|
||||
case AsconReading:
|
||||
return Protek608Reading(a);
|
||||
break;
|
||||
default:
|
||||
return AsconStdHandler(a);
|
||||
}
|
||||
}
|
||||
|
||||
int AsconProtek608Init(Ascon *a, SConnection *con, int argc, char *argv[])
|
||||
{
|
||||
/* greater than one when reading data */
|
||||
a->readState = 0;
|
||||
struct protekData *data;
|
||||
a->private = data = (struct protekData *) malloc(sizeof(struct protekData));
|
||||
a->killPrivate = protKill;
|
||||
data->defa = 0;
|
||||
data->xcgb = 0;
|
||||
data->first = 1;
|
||||
return AsconStdInit(a,con, argc, argv);
|
||||
}
|
||||
|
||||
void AddProtek608Protocol()
|
||||
{
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("protek608");
|
||||
prot->init = AsconProtek608Init;
|
||||
prot->handler = Protek608ProtHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
}
|
||||
284
site_ansto/hardsup/sct_rfamp.c
Normal file
284
site_ansto/hardsup/sct_rfamp.c
Normal file
@@ -0,0 +1,284 @@
|
||||
/**
|
||||
* @brief Protocol handler for Mirrotron RF power supplies
|
||||
|
||||
Current should be ramped up in steps of 0.5A but it doesn't
|
||||
have to be ramped down.
|
||||
|
||||
Provides two commands (L)ist and (S)et
|
||||
eg,
|
||||
The following command lists status info from the RF Amp at address 3.
|
||||
sct_rfamp send L:3
|
||||
The reply string has the following form
|
||||
address=1|type=L|curr=00|freq=170|voltage=50|K3=1|K2=1|K1=1|O=1|CC=1|CV=0|H=1
|
||||
|
||||
The following command sets the current(I), frequency, switches(K1,K2,K3) and output(O).
|
||||
sct_rfamp send S:3:I=5:F=170:K3=0:K2=1:k1=0:O=1
|
||||
NOTE: The current is an integer which equals the desired current x10, ie 71 -> 7.1A
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <ascon.h>
|
||||
#include <ascon.i>
|
||||
#include <dynstring.h>
|
||||
|
||||
#define ERRLEN 128
|
||||
#define LASTBYTENUM 12
|
||||
#define NOTBOOLEAN(b) (b==1 || b==0 ? 0 : 1)
|
||||
#define MINCURRSPEC 0
|
||||
#define MAXCURRSPEC 71
|
||||
#define MINFREQ 170
|
||||
#define MAXFREQ 500
|
||||
|
||||
struct RFAmpData {
|
||||
int transactInProg;
|
||||
int targetCurrent;
|
||||
char rfCmd[16];
|
||||
};
|
||||
|
||||
void RFAmpKill(void *private)
|
||||
{
|
||||
struct RFAmpData *data = private;
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Translates ASCII command string into a properly formatted command for the RF amplifier
|
||||
*/
|
||||
int RFAmpWriteStart (Ascon *a)
|
||||
{
|
||||
char *dynStrBuffer, errMsg[ERRLEN], statusCmd[5];
|
||||
char ctype='X', address='0';
|
||||
unsigned char switches=0;
|
||||
int curr, freq, outOn, K1, K2, K3;
|
||||
int i, ret;
|
||||
struct RFAmpData *data = a->private;
|
||||
|
||||
curr=freq=outOn=K1=K2=K3=0;
|
||||
|
||||
dynStrBuffer = GetCharArray(a->wrBuffer);
|
||||
for (i=0; dynStrBuffer[i]; i++)
|
||||
dynStrBuffer[i]=toupper(dynStrBuffer[i]);
|
||||
|
||||
ret = sscanf(dynStrBuffer, " %c:%c:I=%d:F=%d:K3=%d:K2=%d:K1=%d:O=%d ", &ctype, &address, &curr, &freq, &K3, &K2, &K1, &outOn);
|
||||
if (ret==0) {
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP:Invalid command string %s", dynStrBuffer);
|
||||
a->state = AsconWriteDone;
|
||||
a->noResponse = 1;
|
||||
AsconError(a, errMsg, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (ctype) {
|
||||
case 'L':
|
||||
sprintf(data->rfCmd,"%c%c%c%c", 2, address, ctype, 3);
|
||||
DynStringReplace(a->wrBuffer, data->rfCmd,0);
|
||||
a->state = AsconWriting;
|
||||
a->noResponse = 0;
|
||||
a->wrPos = 0;
|
||||
return 1;
|
||||
break;
|
||||
case 'S':
|
||||
if (ret < 8) {
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP: Invalid command string %s", dynStrBuffer);
|
||||
a->state = AsconWriteDone;
|
||||
a->noResponse = 1;
|
||||
AsconError(a, errMsg, 0);
|
||||
return 1;
|
||||
}
|
||||
if (address < '1' || address > '9') {
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP: Invalid address %c, it should be between 1 and 9", address);
|
||||
a->state = AsconWriteDone;
|
||||
a->noResponse = 1;
|
||||
AsconError(a, errMsg, 0);
|
||||
return 1;
|
||||
}
|
||||
if (curr < MINCURRSPEC || curr > MAXCURRSPEC) {
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP: Invalid current specifier %d, it should be between %d and %d. NOTE:divide by 10 to convert to Amps", curr, MINCURRSPEC, MAXCURRSPEC);
|
||||
a->state = AsconWriteDone;
|
||||
a->noResponse = 1;
|
||||
AsconError(a, errMsg, 0);
|
||||
return 1;
|
||||
}
|
||||
if (freq < MINFREQ || freq > MAXFREQ) {
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP: Invalid frequency %d, it should be between %d and %d", freq, MINFREQ, MAXFREQ);
|
||||
a->state = AsconWriteDone;
|
||||
a->noResponse = 1;
|
||||
AsconError(a, errMsg, 0);
|
||||
return 1;
|
||||
}
|
||||
if (NOTBOOLEAN(K1) || NOTBOOLEAN(K2) || NOTBOOLEAN(K3) || NOTBOOLEAN(outOn)) {
|
||||
a->state = AsconWriteDone;
|
||||
a->noResponse = 1;
|
||||
AsconError(a, "ANSRFAMP: K1, K2, K3 and O must be boolean values (ie 1 or 0)", 0);
|
||||
return 1;
|
||||
}
|
||||
switches = (K3 << 3) | (K2 << 2) | (K1 << 1) | outOn;
|
||||
sprintf(data->rfCmd,"%c%c%c%02d%03d%c%c", 2, address, ctype, curr, freq, switches, 3);
|
||||
if (data->rfCmd[0] != 2 || data->rfCmd[9] != 3) {
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP: Failed to construct a valid packet for %s", dynStrBuffer);
|
||||
a->state = AsconWriteDone;
|
||||
a->noResponse = 1;
|
||||
AsconError(a, errMsg, 0);
|
||||
return 1;
|
||||
}
|
||||
sprintf(statusCmd,"%c%c%c%c", 2, address, 'L', 3);
|
||||
DynStringReplace(a->wrBuffer, statusCmd, 0);
|
||||
data->transactInProg = 1;
|
||||
data->targetCurrent = curr;
|
||||
a->state = AsconWriting;
|
||||
a->noResponse = 0;
|
||||
a->wrPos = 0;
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP: Unknown command type %c, allowed types are 'L' or 'S'", ctype);
|
||||
a->state = AsconWriteDone;
|
||||
a->noResponse = 1;
|
||||
AsconError(a, errMsg, 0);
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int RFAmpReading (Ascon *a)
|
||||
{
|
||||
int rdChRet, scanRet, GetReplyFailed=0, errNum=0;
|
||||
char chr, address, ctype, curr[3], freq[4], voltage[3], replyStr[128];
|
||||
unsigned char switches, opstate;
|
||||
unsigned char K3, K2, K1, outOn, CC, CV, heat;
|
||||
char errMsg[ERRLEN];
|
||||
struct RFAmpData *data = a->private;
|
||||
|
||||
switches=opstate=K3=K2=K1=outOn=CC=CV=heat=0;
|
||||
|
||||
// Start reading when byte = 2 and stop when 3
|
||||
while ( ( rdChRet = AsconReadChar(a->fd, &chr) ) > 0) {
|
||||
a->start = DoubleTime();
|
||||
if (a->readState) {
|
||||
if (a->readState >= LASTBYTENUM) {
|
||||
a->readState = 0;
|
||||
if (a->readState > LASTBYTENUM) {
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP: Packet larger than expected, size exceeds %d", LASTBYTENUM);
|
||||
GetReplyFailed = 1;
|
||||
break;
|
||||
}
|
||||
if (chr != 3) {
|
||||
snprintf(errMsg, ERRLEN, "ANSRFAMP: Unexpected value %X for packet end signal", chr);
|
||||
GetReplyFailed = 1;
|
||||
break;
|
||||
}
|
||||
if (0 == DynStringConcatChar(a->rdBuffer, '\0')) {
|
||||
strcpy(errMsg, "ANSRFAMP: DynStringConcatChar failed:");
|
||||
errNum = ENOMEM;
|
||||
GetReplyFailed = 1;
|
||||
break;
|
||||
}
|
||||
scanRet = sscanf(GetCharArray(a->rdBuffer), "%c%c%2s%3s%2s%c%c", &address, &ctype, curr, freq, voltage, &switches, &opstate);
|
||||
if (scanRet < 7) {
|
||||
strcpy(errMsg, "ANSRFAMP: Failed to parse reply");
|
||||
GetReplyFailed = 1;
|
||||
break;
|
||||
}
|
||||
if (data->transactInProg) {
|
||||
data->transactInProg = 0;
|
||||
if (abs(data->targetCurrent - atoi(curr)) <= 5) {
|
||||
DynStringReplace(a->wrBuffer, data->rfCmd,0);
|
||||
a->state = AsconWriting;
|
||||
a->noResponse = 1;
|
||||
a->wrPos = 0;
|
||||
} else {
|
||||
strcpy(errMsg, "ANSRFAMP: Step size should be <= 5 for current");
|
||||
GetReplyFailed = 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
K3 = (switches & 0x08) >> 3;
|
||||
K2 = (switches & 0x04) >> 2;
|
||||
K1 = (switches & 0x02) >> 1;
|
||||
outOn = switches & 0x01;
|
||||
CC = (opstate & 0x04) >> 2;
|
||||
CV = (opstate & 0x02) >> 1;
|
||||
heat = opstate & 0x01;
|
||||
snprintf(replyStr, 128, "address=%c|type=%c|curr=%s|freq=%s|voltage=%s|K3=%d|K2=%d|K1=%d|O=%d|CC=%d|CV=%d|H=%d", address, ctype, curr, freq, voltage, K3, K2, K1, outOn, CC, CV, heat);
|
||||
if (0 == DynStringReplace(a->rdBuffer, replyStr, 0)) {
|
||||
strcpy(errMsg, "ANSRFAMP: DynStringReplace failed:");
|
||||
errNum = ENOMEM;
|
||||
GetReplyFailed = 1;
|
||||
break;
|
||||
}
|
||||
a->state = AsconReadDone;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (0 == DynStringConcatChar(a->rdBuffer, chr)) {
|
||||
strcpy(errMsg, "ANSRFAMP: DynStringConcatChar failed:");
|
||||
errNum = ENOMEM;
|
||||
GetReplyFailed = 1;
|
||||
break;
|
||||
}
|
||||
a->readState++;
|
||||
} else if (chr == 2) {
|
||||
a->readState = 1;
|
||||
}
|
||||
}
|
||||
if (rdChRet < 0) {
|
||||
AsconError(a, "ANSRFAMP: AsconReadChar failed:", errno);
|
||||
return 1;
|
||||
}
|
||||
if (GetReplyFailed) {
|
||||
a->state = AsconReadDone;
|
||||
a->readState = 0;
|
||||
AsconError(a, errMsg, errNum);
|
||||
return 1;
|
||||
}
|
||||
if (a->timeout > 0) {
|
||||
if (DoubleTime() - a->start > a->timeout) {
|
||||
AsconError(a, "ANSRFAMP: read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int RFAmpProtHandler (Ascon *a)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (a->state) {
|
||||
case AsconWriteStart:
|
||||
ret = RFAmpWriteStart(a);
|
||||
return ret;
|
||||
break;
|
||||
case AsconReading:
|
||||
ret = RFAmpReading(a);
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
return AsconStdHandler(a);
|
||||
}
|
||||
}
|
||||
|
||||
int RFAmpInit(Ascon *a, SConnection *con, int argc, char *argv[])
|
||||
{
|
||||
struct RFAmpData *data;
|
||||
a->readState=0;
|
||||
a->private = data = (struct RFAmpData *) malloc(sizeof(struct RFAmpData));
|
||||
data->transactInProg = 0;
|
||||
data->targetCurrent = 0;
|
||||
data->rfCmd[0] = '\0';
|
||||
a->killPrivate = RFAmpKill;
|
||||
return AsconStdInit(a, con, argc, argv);
|
||||
}
|
||||
|
||||
void AddRFAmpProtocol()
|
||||
{
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("rfamp");
|
||||
prot->init = RFAmpInit;
|
||||
prot->handler = RFAmpProtHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
}
|
||||
245
site_ansto/hardsup/sinqhttpprot.c
Normal file
245
site_ansto/hardsup/sinqhttpprot.c
Normal file
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* This is an asynchronous protocol implementation for HTTP.
|
||||
* It includes special features to store binary data coming
|
||||
* from a SINQ http histogram memory in a sinqdata object.
|
||||
* Which has to be specified on initialisation.
|
||||
*
|
||||
* copyright: see file COPYRIGHT
|
||||
*
|
||||
* Mark Koennecke, June 2008
|
||||
*/
|
||||
#include <ascon.h>
|
||||
#include <ascon.i>
|
||||
#include <ghttp.h>
|
||||
#include <sicsdata.h>
|
||||
#include <HistMem.h>
|
||||
/*---------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
ghttp_request *request;
|
||||
char *userName;
|
||||
char *password;
|
||||
pSICSData binData;
|
||||
}HttpProt, *pHttpProt;
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int configRequest(Ascon *a){
|
||||
pHttpProt pHttp = (pHttpProt)a->private;
|
||||
pDynString request;
|
||||
char *uri = NULL;
|
||||
|
||||
request = CreateDynString(64,64);
|
||||
if(request == NULL){
|
||||
AsconError(a,"Out of memory", 122);
|
||||
return 0;
|
||||
}
|
||||
DynStringConcat(request,"http://");
|
||||
DynStringConcat(request,a->hostport);
|
||||
DynStringConcatChar(request,'/');
|
||||
DynStringConcat(request,GetCharArray(a->wrBuffer));
|
||||
uri = GetCharArray(request);
|
||||
|
||||
ghttp_clean(pHttp->request);
|
||||
ghttp_set_type(pHttp->request,ghttp_type_get);
|
||||
ghttp_set_header(pHttp->request,"connection", "keep-alive");
|
||||
if(ghttp_set_uri(pHttp->request,uri) < 0){
|
||||
AsconError(a,"Bad URL", a->state);
|
||||
return 0;
|
||||
}
|
||||
if(pHttp->userName != NULL && pHttp->password != NULL){
|
||||
ghttp_set_authinfo(pHttp->request,
|
||||
pHttp->userName, pHttp->password);
|
||||
}
|
||||
ghttp_set_sync(pHttp->request,ghttp_async);
|
||||
ghttp_prepare(pHttp->request);
|
||||
DeleteDynString(request);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static void handleReply(Ascon *a){
|
||||
char *pPtr = NULL, *pType = NULL;
|
||||
int len, i, *dataPtr = NULL;
|
||||
HistInt *hmData = NULL;
|
||||
pHttpProt pHttp = (pHttpProt)a->private;
|
||||
|
||||
pPtr = ghttp_get_body(pHttp->request);
|
||||
len = ghttp_get_body_len(pHttp->request);
|
||||
if(strstr(pPtr,"ERROR") != NULL){
|
||||
AsconError(a,pPtr, a->state);
|
||||
DynStringConcat(a->rdBuffer,pPtr);
|
||||
} else if(strstr(pPtr,"Authentication Error") != NULL){
|
||||
DynStringConcat(a->rdBuffer,pPtr);
|
||||
AsconError(a,pPtr, a->state);
|
||||
} else {
|
||||
pType = (char *)ghttp_get_header(pHttp->request,"Content-Type");
|
||||
if(strstr(pType,"sinqhm") == NULL){
|
||||
/* text data */
|
||||
for(i = 0; i < len; i++){
|
||||
DynStringConcatChar(a->rdBuffer, pPtr[i]);
|
||||
}
|
||||
} else {
|
||||
hmData = (HistInt *)pPtr;
|
||||
clearSICSData(pHttp->binData);
|
||||
len = len/sizeof(HistInt);
|
||||
dataPtr = getSICSDataPointer(pHttp->binData, 0, len);
|
||||
for(i = 0; i < len; i++){
|
||||
dataPtr[i] = htonl(hmData[i]);
|
||||
}
|
||||
assignSICSType(pHttp->binData, 0, len, INTTYPE);
|
||||
DynStringCopy(a->rdBuffer,"SICSDATA");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int HttpHandler(Ascon *a) {
|
||||
ghttp_status status;
|
||||
pHttpProt pHttp = (pHttpProt)a->private;
|
||||
int socke, selStat;
|
||||
fd_set rmask;
|
||||
struct timeval tmo = {0,0};
|
||||
|
||||
switch (a->state) {
|
||||
case AsconConnectStart:
|
||||
a->state = AsconConnecting;
|
||||
break;
|
||||
case AsconConnecting:
|
||||
a->state = AsconConnectDone; /* success */
|
||||
break;
|
||||
case AsconWriteStart:
|
||||
if(configRequest(a)){
|
||||
a->state = AsconWriting;
|
||||
}
|
||||
break;
|
||||
case AsconWriting:
|
||||
status = ghttp_process(pHttp->request);
|
||||
if(status == ghttp_error){
|
||||
ghttp_close(pHttp->request);
|
||||
configRequest(a);
|
||||
status = ghttp_process(pHttp->request);
|
||||
}
|
||||
if(status == ghttp_error){
|
||||
AsconError(a,"Server error", 123);
|
||||
DynStringConcat(a->rdBuffer,"Server error");
|
||||
a->state = AsconReadDone;
|
||||
} else {
|
||||
a->state = AsconWriteDone;
|
||||
}
|
||||
a->start = DoubleTime();
|
||||
DynStringClear(a->rdBuffer);
|
||||
break;
|
||||
case AsconReadStart:
|
||||
socke = ghttp_get_socket(pHttp->request);
|
||||
FD_ZERO(&rmask);
|
||||
FD_SET(socke,&rmask);
|
||||
selStat = select(socke+1,&rmask, NULL, NULL, &tmo);
|
||||
if(selStat != 0){
|
||||
status = ghttp_process(pHttp->request);
|
||||
a->state = AsconReading;
|
||||
} else {
|
||||
if(DoubleTime() > a->start + a->timeout){
|
||||
AsconError(a," read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
/* this to clear the line */
|
||||
ghttp_close(pHttp->request);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case AsconReading:
|
||||
status = ghttp_process(pHttp->request);
|
||||
switch(status){
|
||||
case ghttp_not_done:
|
||||
if(DoubleTime() > a->start + a->timeout){
|
||||
AsconError(a," read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
/* this to clear the line */
|
||||
ghttp_close(pHttp->request);
|
||||
}
|
||||
return 1;
|
||||
case ghttp_done:
|
||||
handleReply(a);
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
case ghttp_error:
|
||||
/*
|
||||
* A first error may not be an error but a
|
||||
* reconnect
|
||||
*/
|
||||
ghttp_close(pHttp->request);
|
||||
configRequest(a);
|
||||
status = ghttp_process(pHttp->request);
|
||||
if(status == ghttp_error){
|
||||
AsconError(a,"Server error", a->state);
|
||||
DynStringConcat(a->rdBuffer,"Server error");
|
||||
a->state = AsconReadDone;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return AsconStdHandler(a);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void killHttp(void *data){
|
||||
pHttpProt prot = (pHttpProt)data;
|
||||
if(prot == NULL){
|
||||
return;
|
||||
}
|
||||
if(prot->request != NULL){
|
||||
ghttp_close(prot->request);
|
||||
}
|
||||
if(prot->password != NULL){
|
||||
free(prot->password);
|
||||
}
|
||||
if(prot->userName != NULL){
|
||||
free(prot->userName);
|
||||
}
|
||||
free(prot);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int HttpProtInit(Ascon *a, SConnection *con,
|
||||
int argc, char *argv[]){
|
||||
pHttpProt pHttp = NULL;
|
||||
|
||||
pHttp = calloc(sizeof(HttpProt), 1);
|
||||
if(pHttp == NULL){
|
||||
SCWrite(con,"ERROR: out of memory in HttpProtInit", eError);
|
||||
return 0;
|
||||
}
|
||||
if(argc < 3){
|
||||
return 0;
|
||||
}
|
||||
a->hostport = strdup(argv[1]);
|
||||
pHttp->binData = (pSICSData)FindCommandData(pServ->pSics,
|
||||
argv[2], "SICSData");
|
||||
if(pHttp->binData == NULL){
|
||||
SCWrite(con,"ERROR: SICSData objct not found", eError);
|
||||
return 0;
|
||||
}
|
||||
if(argc > 3){
|
||||
a->timeout = atof(argv[3]);
|
||||
} else {
|
||||
a->timeout = 10.;
|
||||
}
|
||||
if(argc > 5){
|
||||
pHttp->userName = strdup(argv[4]);
|
||||
pHttp->password = strdup(argv[5]);
|
||||
}
|
||||
pHttp->request = ghttp_request_new();
|
||||
a->private = pHttp;
|
||||
a->killPrivate = killHttp;
|
||||
a->state = AsconConnectStart;
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void AddHttpProtocoll(){
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("sinqhttp");
|
||||
prot->init = HttpProtInit;
|
||||
prot->handler = HttpHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
}
|
||||
Reference in New Issue
Block a user