- use dig for resolving host names - ascon.c: fix terminator parsing - property callback: change property before callback - logger.c:default for logger period must be the old value instead of 1 - add frappy type history writing - increase max. logreader line length - HIPNONE returns "null" with json protocol - encode strings properly in formatNameValue - fix memory leak in json2tcl - scriptcontext: do not show debug messages when script starts with underscore or when the "send" property is empty - scriptcontext: remove args for action timestamp - scriptcontext: "que" function will replace an already queued action, e.g. for 'halt - introduced updatestatus script
675 lines
19 KiB
C
675 lines
19 KiB
C
/*--------------------------------------------------------------------------
|
|
ANSTO Protocol Command Object
|
|
Paul Hathaway, November, 2004
|
|
Copyright: See copyright.txt
|
|
----------------------------------------------------------------------------*/
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <conman.h>
|
|
#include <obdes.h>
|
|
#include <sics.h>
|
|
#include <conman.h>
|
|
#include <fupa.h>
|
|
#include <splitter.h>
|
|
#include <outcode.h>
|
|
#include <dynstring.h>
|
|
#include "protocol.h"
|
|
#include <json-c/json.h>
|
|
|
|
#define MAXMSG 1024
|
|
#define INIT_STR_SIZE 256
|
|
#define STR_RESIZE_LENGTH 256
|
|
#define NUMPROS 6
|
|
#define PROLISTLEN 8
|
|
typedef struct __Protocol {
|
|
pObjectDescriptor pDes; /* required as first field */
|
|
char *name; /* protocol handler name */
|
|
char *version; /* protocol version string */
|
|
int iNumPros; /* number of valid protocols? */
|
|
writeFunc defaultWriter; /* default write function */
|
|
int isDefaultSet;
|
|
char *pProList[PROLISTLEN]; /* list of valid protocols? */
|
|
} Protocol;
|
|
/*================================================================================================
|
|
WARNING: These two char arrays may replicate things defined elsewhere. They may be out of
|
|
sync with the rest of SIS. Keep in mind.....
|
|
==================================================================================================*/
|
|
|
|
char *pEventType[] = {
|
|
"VALUECHANGE", /* 0 */
|
|
"MOTDRIVE", /* 1 */
|
|
"MONITOR", /* 2 */
|
|
"ROTSTART", /* 3 */
|
|
"ROTMOVE", /* 4 */
|
|
"SCANEND", /* 5 */
|
|
"SCANSTART", /* 6 */
|
|
"SCANPOINT", /* 7 */
|
|
"WLCHANGE", /* 8 */
|
|
"REFLECTIONDONE", /* 9 */
|
|
"COUNTSTART", /* 10 */
|
|
"COUNTEND", /* 11 */
|
|
"FILELOADED", /* 12 */
|
|
"MOTEND", /* 13 */
|
|
"BATCHSTART", /* 14 */
|
|
"BATCHAREA", /* 15 */
|
|
"BATCHEND", /* 16 */
|
|
"DRIVSTAT", /* 17 */
|
|
"STATUS", /* 18 */
|
|
"POSITION" /* 19 Motor position events, ffr */
|
|
};
|
|
|
|
char *pStatus[] = {
|
|
"UNSET",
|
|
"OKOK", /* 1 */
|
|
"HWIdle", /* 2 */
|
|
"HWBusy", /* 3 */
|
|
"HWFault", /* 4 */
|
|
"HWPosFault", /* 5 */
|
|
"HWCrash", /* 6 */
|
|
"NOMEMORY", /* 7 */
|
|
"HWNoBeam", /* 8 */
|
|
"HWPause", /* 9 */
|
|
"HWWarn", /* 10 */
|
|
"HWRedo", /* 11 */
|
|
};
|
|
|
|
typedef struct __Protocol *pProtocol;
|
|
|
|
pProtocol CreateProtocol(void);
|
|
static int ProtocolOptions(SConnection * pCon, pProtocol pPro);
|
|
static int ProtocolHelp(SConnection * pCon, Protocol * pPro);
|
|
static int ProtocolSet(SConnection * pCon, Protocol * pPro,
|
|
char *pProName);
|
|
static int ProtocolList(SConnection * pCon, Protocol * pPro);
|
|
int ProtocolAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[]);
|
|
static int EnumChoice(char *pList[], int iLength, char *pInput);
|
|
static int InitDefaultProtocol(SConnection * pCon, Protocol * pPro);
|
|
|
|
/* Signatures for protocol writers implemented in this file */
|
|
int SCWriteJSON_String(SConnection * pCon, char *pBuffer, int iOut);
|
|
/* Signatures for protocols from conman.c*/
|
|
extern int SCAllWrite(SConnection * self, char *buffer, int iOut);
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
pProtocol CreateProtocol(void)
|
|
{
|
|
int i, iNumPros = NUMPROS;
|
|
char *pPros[] = { "default",
|
|
"normal",
|
|
"withcode",
|
|
"json",
|
|
"act",
|
|
"all",
|
|
NULL
|
|
};
|
|
pProtocol pNew = NULL;
|
|
|
|
pNew = (pProtocol) malloc(sizeof(Protocol));
|
|
if (!pNew) {
|
|
return NULL;
|
|
}
|
|
pNew->pDes = CreateDescriptor("Protocol");
|
|
if (!pNew->pDes) {
|
|
free(pNew);
|
|
return NULL;
|
|
}
|
|
|
|
pNew->name = strdup("protocol");
|
|
pNew->version = strdup("1.0");
|
|
pNew->iNumPros = iNumPros;
|
|
// pNew->pProList = (char *)malloc(sizeof(pPros));
|
|
for (i = 0; i < iNumPros; i++) {
|
|
pNew->pProList[i] = strdup(pPros[i]);
|
|
}
|
|
pNew->pProList[i] = NULL;
|
|
pNew->isDefaultSet = 0;
|
|
|
|
return pNew;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void DeleteProtocol(void *self)
|
|
{
|
|
int i;
|
|
pProtocol pOld = (pProtocol) self;
|
|
|
|
if (NULL == pOld) {
|
|
return;
|
|
}
|
|
if (pOld->name) {
|
|
free(pOld->name);
|
|
}
|
|
if (pOld->pDes) {
|
|
DeleteDescriptor(pOld->pDes);
|
|
}
|
|
if (pOld->version) {
|
|
free(pOld->version);
|
|
}
|
|
i = 0;
|
|
while (NULL != pOld->pProList[i]) {
|
|
free(pOld->pProList[i]);
|
|
i++;
|
|
}
|
|
|
|
free(pOld);
|
|
}
|
|
|
|
/*------------------------------------------------------------------*/
|
|
static int ContextDo(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
SConnection *comCon = NULL;
|
|
char buffer[1024];
|
|
char *command;
|
|
int status;
|
|
|
|
if (argc < 3) {
|
|
SCWrite(pCon, "ERROR: insufficient arguments to contextdo", eError);
|
|
return 0;
|
|
}
|
|
|
|
comCon = SCCopyConnection(pCon);
|
|
if (comCon == NULL) {
|
|
SCWrite(pCon, "ERROR: out of memory in contextdo", eError);
|
|
return 0;
|
|
}
|
|
status = Tcl_GetInt(pSics->pTcl, argv[1], &comCon->transID);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer, 1023, "ERROR: failed to convert %s to transaction ID",
|
|
argv[1]);
|
|
SCWrite(pCon, buffer, eError);
|
|
return 0;
|
|
}
|
|
strlcpy(comCon->deviceID, argv[2], SCDEVIDLEN);
|
|
memset(buffer, 0, sizeof(buffer));
|
|
command = Arg2Tcl(argc - 2, &argv[2], buffer, sizeof buffer);
|
|
if (!command) {
|
|
SCWrite(pCon, "ERROR: no more memory", eError);
|
|
return 0;
|
|
}
|
|
if(comCon->transID > 100000) {
|
|
SCPrintf(comCon,eLog,"COMSTART %d", comCon->transID);
|
|
}
|
|
status = InterpExecute(pSics, comCon, command);
|
|
if(comCon->transID > 100000) {
|
|
SCPrintf(comCon,eLog,"COMEND %d", comCon->transID);
|
|
}
|
|
if (command != buffer)
|
|
free(command);
|
|
SCDeleteConnection(comCon);
|
|
return status;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int InstallProtocol(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pProtocol pNew = NULL;
|
|
pNew = CreateProtocol();
|
|
if (NULL == pNew) {
|
|
SCWrite(pCon, "No memory to create Protocol", eError);
|
|
return 0;
|
|
}
|
|
AddCommand(pSics, "Protocol", ProtocolAction, DeleteProtocol, pNew);
|
|
AddCommand(pSics, "contextdo", ContextDo, NULL, NULL);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
void MakeProtocol(void)
|
|
{
|
|
pProtocol pNew = NULL;
|
|
pNew = CreateProtocol();
|
|
if (NULL != pNew) {
|
|
AddCommand(pServ->pSics, "Protocol", ProtocolAction, DeleteProtocol, pNew);
|
|
AddCommand(pServ->pSics, "contextdo", ContextDo, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int ProtocolOptions(SConnection * pCon, pProtocol pPro)
|
|
{
|
|
int i;
|
|
char pBuffer[80];
|
|
for (i = 0; i < pPro->iNumPros; i++) {
|
|
snprintf(pBuffer,sizeof(pBuffer)-1, "Protocol[%d] = %s", i, pPro->pProList[i]);
|
|
SCWrite(pCon, pBuffer, eValue);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int ProtocolHelp(SConnection * pCon, Protocol * pPro)
|
|
{
|
|
SCWrite(pCon,
|
|
"Usage: protocol {help|list|options|reset} | set protocolName",
|
|
eValue);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int ProtocolSet(SConnection * pCon, Protocol * pPro, char *pProName)
|
|
{
|
|
SConnection *pMaster = NULL;
|
|
|
|
int proID;
|
|
if (!SCVerifyConnection(pCon)) {
|
|
return 0;
|
|
}
|
|
pMaster = SCfindMaster(pCon);
|
|
assert(pMaster != NULL);
|
|
|
|
/* lazy initialisation of defaultWriter since connection is verified */
|
|
InitDefaultProtocol(pCon, pPro);
|
|
|
|
/* Do not die if no data */
|
|
if (NULL == pProName) {
|
|
return 0;
|
|
}
|
|
|
|
/* check list of protocols for valid name and assign functions based */
|
|
/* on match of pProName */
|
|
proID = EnumChoice(pPro->pProList, pPro->iNumPros, pProName);
|
|
switch (proID) {
|
|
case -1: /* invalid */
|
|
return 0;
|
|
break;
|
|
|
|
case PROTNORM: /* normal (connection start default) */
|
|
SCSetWriteFunc(pMaster, SCNormalWrite);
|
|
SCSetWriteFunc(pCon, SCNormalWrite);
|
|
break;
|
|
|
|
case PROTCODE: /* outcodes */
|
|
SCSetWriteFunc(pMaster, SCWriteWithOutcode);
|
|
SCSetWriteFunc(pCon, SCWriteWithOutcode);
|
|
break;
|
|
|
|
case PROTJSON: /* json */
|
|
SCSetWriteFunc(pCon, SCWriteJSON_String);
|
|
SCSetWriteFunc(pMaster, SCWriteJSON_String);
|
|
break;
|
|
case PROTACT: /* ACT */
|
|
SCSetWriteFunc(pMaster, SCACTWrite);
|
|
SCSetWriteFunc(pCon, SCACTWrite);
|
|
break;
|
|
case PROTALL:
|
|
SCSetWriteFunc(pMaster, SCAllWrite);
|
|
SCSetWriteFunc(pCon, SCAllWrite);
|
|
break;
|
|
case PROTSICS: /* default = psi_sics */
|
|
default:
|
|
SCSetWriteFunc(pMaster, pPro->defaultWriter);
|
|
SCSetWriteFunc(pCon, pPro->defaultWriter);
|
|
break;
|
|
}
|
|
SCSetProtocolID(pCon,proID);
|
|
SCSetProtocolID(pMaster,proID);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
int ProtocolGet(SConnection * pCon, void *pData, char *pProName, int len)
|
|
{
|
|
int Index;
|
|
Protocol *pPro = (Protocol *) pData;
|
|
if (!SCVerifyConnection(pCon)) {
|
|
return 0;
|
|
}
|
|
|
|
if (pData == NULL) {
|
|
SCSetProtocolID(pCon,0);
|
|
return 1;
|
|
}
|
|
|
|
/* lazy initialisation of defaultWriter since connection is verified */
|
|
if (0 == pPro->isDefaultSet) {
|
|
pPro->defaultWriter = SCGetWriteFunc(pCon);
|
|
pPro->isDefaultSet = 1;
|
|
SCSetProtocolID(pCon,0);
|
|
}
|
|
strlcpy(pProName, pPro->pProList[SCGetProtocolID(pCon)], len);
|
|
return 1;
|
|
#if 0
|
|
Index = SCGetProtocolID(pCon);
|
|
|
|
/* check list of protocols for valid name */
|
|
switch (Index) {
|
|
case PROTSICS: /* default = psi_sics */
|
|
case PROTNORM: /* normal (connection start default) */
|
|
case PROTCODE: /* outcodes */
|
|
case PROTJSON: /* json */
|
|
case PROTACT: /* act */
|
|
pProName = pPro->pProList[Index];
|
|
return 1;
|
|
break;
|
|
default:
|
|
return 0;
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int ProtocolList(SConnection * pCon, Protocol * pPro)
|
|
{
|
|
SCWrite(pCon,
|
|
"Usage: protocol {help|list|options|reset} | set protocolName",
|
|
eValue);
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int ProtocolAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
int iRet;
|
|
char **argx;
|
|
FuPaResult PaRes;
|
|
pProtocol pPro = NULL;
|
|
|
|
const int iNumCmds = 5;
|
|
FuncTemplate CommandTemplate[] = {
|
|
{"help", 0, {0, 0}},
|
|
{"list", 0, {0, 0}},
|
|
{"options", 0, {0, 0}},
|
|
{"set", 1, {FUPATEXT}},
|
|
{"reset", 0, {0, 0}},
|
|
{NULL}
|
|
};
|
|
|
|
assert(pCon != NULL);
|
|
assert(pSics != NULL);
|
|
pPro = (pProtocol) pData;
|
|
assert(pPro != NULL);
|
|
|
|
/* You need to have User level access rights to use this facility */
|
|
if (!SCMatchRights(pCon, usSpy)) {
|
|
return 0;
|
|
}
|
|
|
|
/* parse function args */
|
|
argtolower(argc, argv);
|
|
argx = &argv[1];
|
|
iRet =
|
|
EvaluateFuPa((pFuncTemplate) & CommandTemplate, iNumCmds, argc - 1,
|
|
argx, &PaRes);
|
|
|
|
/* if invalid (iRet < 0) then default to "help" command */
|
|
|
|
switch (iRet) {
|
|
case 1: /* list */
|
|
iRet = ProtocolList(pCon, pPro);
|
|
break;
|
|
case 2: /* options */
|
|
iRet = ProtocolOptions(pCon, pPro);
|
|
break;
|
|
case 3: /* set */
|
|
iRet = ProtocolSet(pCon, pPro, PaRes.Arg[0].text);
|
|
break;
|
|
case 4: /* reset */
|
|
iRet = ProtocolSet(pCon, pPro, "default");
|
|
break;
|
|
case 0: /* help */
|
|
default:
|
|
iRet = ProtocolHelp(pCon, pPro);
|
|
break;
|
|
}
|
|
return iRet;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int EnumChoice(char *pList[], int iLength, char *pInput)
|
|
{
|
|
int i;
|
|
int iRet = -1;
|
|
|
|
for (i = 0; i < iLength; i++) {
|
|
if (0 == strcmp(pInput, pList[i])) {
|
|
iRet = i;
|
|
break;
|
|
}
|
|
}
|
|
return iRet;
|
|
}
|
|
|
|
/*----------------------------------*/
|
|
static int InitDefaultProtocol(SConnection * pCon, Protocol * pPro)
|
|
{
|
|
if (NULL == pCon) {
|
|
return 0;
|
|
}
|
|
|
|
/* lazy initialisation of defaultWriter since connection is verified */
|
|
if (0 == pPro->isDefaultSet) {
|
|
pPro->defaultWriter = SCGetWriteFunc(pCon);
|
|
pPro->isDefaultSet = 1;
|
|
SCSetProtocolID(pCon,PROTSICS);
|
|
}
|
|
return pPro->isDefaultSet;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Only work for hipadaba commands, hlist, hset, hget, hnotify
|
|
* A multiline string (ie have crnl) will be converted to an array.
|
|
* Strings with '=' will be converted to name value pairs
|
|
*/
|
|
struct json_object *mkJSON_Object(SConnection * pCon, char *pBuffer,
|
|
int iOut)
|
|
{
|
|
int linenum = __LINE__;
|
|
char pBueffel[MAXMSG], *pBufferFrom, *pBufferTo;
|
|
long taskID = 0;
|
|
struct json_object *msg_json = NULL, *tmp_json = NULL;
|
|
|
|
commandContext comCon;
|
|
char pError[256];
|
|
pError[0] = '\0';
|
|
|
|
/*
|
|
if (strlen(pBuffer) == 0) {
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
if (!SCVerifyConnection(pCon)) {
|
|
return 0;
|
|
}
|
|
comCon = SCGetContext(pCon);
|
|
|
|
/* Return 0 without dying if no message data */
|
|
if (pBuffer == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
build the Tcl-command to execute for formatting the
|
|
data into a sycamore string
|
|
*/
|
|
taskID = comCon.transID;
|
|
|
|
pBueffel[0] = '\0';
|
|
msg_json = json_object_new_object();
|
|
if (msg_json == NULL) {
|
|
linenum = __LINE__;
|
|
goto reporterr;
|
|
}
|
|
/* field 1: connID */
|
|
json_object_object_add(msg_json, "con",
|
|
json_object_new_int(SCGetIdent(pCon)));
|
|
/* field 2: taskID */
|
|
json_object_object_add(msg_json, "trans", json_object_new_int(taskID));
|
|
/* deviceID */
|
|
json_object_object_add(msg_json, "object",
|
|
json_object_new_string(comCon.deviceID));
|
|
|
|
/* msgFlag */
|
|
switch (iOut) {
|
|
case 5: /* eValue */
|
|
json_object_object_add(msg_json, "flag",
|
|
json_object_new_string("out"));
|
|
break;
|
|
default:
|
|
json_object_object_add(msg_json, "flag",
|
|
json_object_new_string(pCode[iOut]));
|
|
break;
|
|
}
|
|
if (iOut == eHdbValue || iOut == eHdbEvent) {
|
|
tmp_json = json_tokener_parse(pBuffer);
|
|
if (strcmp(pBuffer, "null") != 0) {
|
|
if (tmp_json == NULL) {
|
|
tmp_json = json_object_new_string(pBuffer);
|
|
}
|
|
if (tmp_json == NULL) {
|
|
linenum = __LINE__;
|
|
goto reporterr;
|
|
}
|
|
}
|
|
} else {
|
|
/* Strip \r and \n */
|
|
for (pBufferFrom = pBufferTo = pBuffer;; pBufferFrom++) {
|
|
if (*pBufferFrom == '\r' || *pBufferFrom == '\n')
|
|
continue;
|
|
pBufferTo = pBufferFrom;
|
|
if (*pBufferTo == '\0')
|
|
break;
|
|
pBufferTo++;
|
|
}
|
|
tmp_json = json_object_new_string(pBuffer);
|
|
if (tmp_json == NULL) {
|
|
linenum = __LINE__;
|
|
goto reporterr;
|
|
}
|
|
}
|
|
json_object_object_add(msg_json, "data", tmp_json);
|
|
return msg_json;
|
|
|
|
reporterr:
|
|
SCSetWriteFunc(pCon, SCNormalWrite);
|
|
snprintf(pError, 256, "{\"ERROR\": \"%s:%d Error making json object\"}",
|
|
__FILE__, linenum);
|
|
SCWrite(pCon, pError, eError);
|
|
SCSetWriteFunc(pCon, SCWriteJSON_String);
|
|
cleanup:
|
|
if (tmp_json != NULL)
|
|
json_object_put(tmp_json);
|
|
if (msg_json != NULL)
|
|
json_object_put(msg_json);
|
|
return NULL;
|
|
}
|
|
|
|
int SCWriteJSON_String(SConnection * pCon, char *pBuffer, int iOut)
|
|
{
|
|
struct json_object *my_object = NULL, *tmp_json = NULL;
|
|
char pBueffel[MAXMSG], errBuff[MAXMSG];
|
|
int iRet, errLen = MAXMSG;
|
|
|
|
/*
|
|
if (strlen(pBuffer) == 0)
|
|
return 1;
|
|
*/
|
|
|
|
/* log it for any case */
|
|
iRet = SCGetSockHandle(pCon);
|
|
|
|
/* write to commandlog if user or manager privilege */
|
|
if (SCGetRights(pCon) <= usUser && !SCinMacro(pCon)) {
|
|
Log(INFO,"com","sock%03.3d:%s",iRet, pBuffer);
|
|
} else {
|
|
Log(DEBUG,"com","sock%03.3d:%s", iRet, pBuffer);
|
|
}
|
|
|
|
if (SCinMacro(pCon)) {
|
|
InterpWrite(pServ->pSics, pBuffer);
|
|
/* print it to client if error message */
|
|
if ((iOut == eError) || (iOut == eWarning)) {
|
|
tmp_json = json_object_new_string(pBuffer);
|
|
iRet = SCDoSockWrite(pCon, (char *)json_object_to_json_string(tmp_json));
|
|
}
|
|
} else {
|
|
if ((my_object = mkJSON_Object(pCon, pBuffer, iOut)) == NULL) {
|
|
snprintf(errBuff, errLen, "failed to make JSON object from, %s",
|
|
pBuffer);
|
|
tmp_json = json_object_new_string(errBuff);
|
|
my_object = json_object_new_object();
|
|
json_object_object_add(my_object, "ERROR", tmp_json);
|
|
SCDoSockWrite(pCon, (char *)json_object_to_json_string(my_object));
|
|
iRet = 0;
|
|
} else {
|
|
iRet = SCDoSockWrite(pCon, (char *)json_object_to_json_string(my_object));
|
|
}
|
|
}
|
|
if (tmp_json != NULL )
|
|
json_object_put(tmp_json);
|
|
if (my_object != NULL )
|
|
json_object_put(my_object);
|
|
return iRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
/* Protocol API */
|
|
char *GetProtocolName(SConnection * pCon)
|
|
{
|
|
pProtocol pPro;
|
|
pSicsInterp pSics;
|
|
|
|
if (!SCVerifyConnection(pCon)) {
|
|
return NULL;
|
|
}
|
|
|
|
pSics = GetInterpreter();
|
|
if (!pSics)
|
|
return NULL;
|
|
|
|
pPro = FindCommandData(pSics, "protocol", "Protocol");
|
|
if (!pPro)
|
|
return NULL;
|
|
|
|
InitDefaultProtocol(pCon, pPro);
|
|
|
|
/* check list of protocols for valid name */
|
|
switch (SCGetProtocolID(pCon)) {
|
|
case PROTSICS: /* default = psi_sics */
|
|
case PROTNORM: /* normal (connection start default) */
|
|
case PROTCODE: /* outcodes */
|
|
case PROTJSON: /* json */
|
|
case PROTACT: /* act */
|
|
return strdup(pPro->pProList[SCGetProtocolID(pCon)]);
|
|
break;
|
|
default:
|
|
return strdup("invalid");
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------*/
|
|
int GetProtocolID(SConnection * pCon)
|
|
{
|
|
return SCGetProtocolID(pCon);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
writeFunc GetProtocolWriteFunc(SConnection * pCon)
|
|
{
|
|
if (pCon != NULL) {
|
|
switch (SCGetProtocolID(pCon)) {
|
|
case PROTCODE: /* outcodes */
|
|
return SCWriteWithOutcode;
|
|
break;
|
|
case PROTJSON: /* json */
|
|
return SCWriteJSON_String;
|
|
break;
|
|
case PROTACT:
|
|
return SCACTWrite;
|
|
break;
|
|
default:
|
|
return SCNormalWrite;
|
|
break;
|
|
}
|
|
}
|
|
return SCNormalWrite;
|
|
}
|