822 lines
22 KiB
C
822 lines
22 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.c>
|
|
#include <dynstring.h>
|
|
#include "commandlog.h"
|
|
#include "protocol.h"
|
|
#include <json/json.h>
|
|
|
|
#define MAXMSG 1024
|
|
#define INIT_STR_SIZE 256
|
|
#define STR_RESIZE_LENGTH 256
|
|
#define NUMPROS 6
|
|
#define PROLISTLEN 7
|
|
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;
|
|
|
|
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;
|
|
|
|
/* alternate implementation of protocol list if data hiding in
|
|
* Protocol struct via CreateProtocol does not work
|
|
* static char *pPros[] = {
|
|
* "default",
|
|
* "outcodes",
|
|
* "sycamore"
|
|
* NULL };
|
|
* static int iNumPros = 3
|
|
*/
|
|
|
|
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 SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut);
|
|
int SCWriteJSON_String(SConnection *pCon, char *pBuffer, int iOut);
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
pProtocol CreateProtocol(void)
|
|
{
|
|
int i, iNumPros = NUMPROS;
|
|
char *pPros[] = {"default",
|
|
"normal",
|
|
"withcode",
|
|
"sycamore",
|
|
"json",
|
|
"act",
|
|
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);
|
|
}
|
|
if(pOld->pProList)
|
|
{
|
|
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[]){
|
|
commandContext comCon;
|
|
char buffer[1024];
|
|
char *command;
|
|
int status;
|
|
|
|
if(argc < 3){
|
|
SCWrite(pCon,"ERROR: insufficient arguments to 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;
|
|
}
|
|
strncpy(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;
|
|
}
|
|
SCPushContext2(pCon,comCon);
|
|
status = InterpExecute(pSics,pCon,command);
|
|
if (command != buffer) free(command);
|
|
SCPopContext(pCon);
|
|
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(SicsInterp *pSics){
|
|
pProtocol pNew = NULL;
|
|
pNew = CreateProtocol();
|
|
if(NULL!= pNew)
|
|
{
|
|
AddCommand(pSics,"Protocol",ProtocolAction,DeleteProtocol,pNew);
|
|
AddCommand(pSics,"contextdo",ContextDo,NULL,NULL);
|
|
}
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int ProtocolOptions(SConnection* pCon, pProtocol pPro)
|
|
{
|
|
int i;
|
|
char pBuffer[80];
|
|
for(i=0;i<pPro->iNumPros;i++)
|
|
{
|
|
sprintf(pBuffer,"Protocol[%d] = %s",i,pPro->pProList[i]);
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int ProtocolHelp(SConnection* pCon, Protocol* pPro)
|
|
{
|
|
SCWrite(pCon,
|
|
"Usage: protocol {help|list|options|reset} | set protocolName",
|
|
eStatus);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName)
|
|
{
|
|
int proID;
|
|
if(!SCVerifyConnection(pCon))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* 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 1: /* normal (connection start default) */
|
|
SCSetWriteFunc(pCon,SCNormalWrite);
|
|
break;
|
|
|
|
case 2: /* outcodes */
|
|
SCSetWriteFunc(pCon,SCWriteWithOutcode);
|
|
break;
|
|
|
|
case 3: /* sycamore */
|
|
SCSetWriteFunc(pCon,SCWriteSycamore);
|
|
break;
|
|
case 4: /* json */
|
|
SCSetWriteFunc(pCon,SCWriteJSON_String);
|
|
break;
|
|
case 5:
|
|
SCSetWriteFunc(pCon,SCACTWrite);
|
|
break;
|
|
case 0: /* default = psi_sics */
|
|
default:
|
|
SCSetWriteFunc(pCon,pPro->defaultWriter);
|
|
break;
|
|
}
|
|
pCon->iProtocolID = 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)
|
|
{
|
|
pCon->iProtocolID = 0;
|
|
return 1;
|
|
}
|
|
|
|
/* lazy initialisation of defaultWriter since connection is verified */
|
|
if(0==pPro->isDefaultSet)
|
|
{
|
|
pPro->defaultWriter = SCGetWriteFunc(pCon);
|
|
pPro->isDefaultSet = 1;
|
|
pCon->iProtocolID = 0;
|
|
}
|
|
strncpy(pProName, pPro->pProList[pCon->iProtocolID], len);
|
|
return 1;
|
|
#if 0
|
|
Index = pCon->iProtocolID;
|
|
|
|
/* check list of protocols for valid name */
|
|
switch(Index)
|
|
{
|
|
case 0: /* default = psi_sics */
|
|
case 1: /* normal (connection start default) */
|
|
case 2: /* outcodes */
|
|
case 3: /* sycamore */
|
|
case 4: /* json */
|
|
case 5: /* 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",
|
|
eStatus);
|
|
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;
|
|
pCon->iProtocolID = 0;
|
|
}
|
|
return pPro->isDefaultSet;
|
|
}
|
|
/*---------------------------------------------------------------------*/
|
|
void sycformat(char *tag, OutCode msgFlag, pDynString msgString, pDynString msgOut) {
|
|
DynStringConcat(msgOut," ");
|
|
switch (msgFlag) {
|
|
eEvent:
|
|
break;
|
|
eFinish:
|
|
break;
|
|
default:
|
|
DynStringConcat(msgOut,tag);
|
|
DynStringConcat(msgOut,"={");
|
|
DynStringConcat(msgOut,GetCharArray(msgString));
|
|
DynStringConcat(msgOut,"}");
|
|
break;
|
|
}
|
|
}
|
|
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
|
|
{
|
|
int iRet;
|
|
char pBueffel[MAXMSG], *pBufferFrom, *pBufferTo;
|
|
long taskID = 0;
|
|
/* char pPrefix[40];*/
|
|
pDynString pMsg = NULL;
|
|
pDynString pMsgString = NULL;
|
|
commandContext comCon;
|
|
|
|
|
|
if (strlen(pBuffer) == 0) {
|
|
return 0;
|
|
}
|
|
/* Strip \r and \n */
|
|
for (pBufferFrom=pBufferTo=pBuffer; ; pBufferFrom++) {
|
|
if (*pBufferFrom == '\r' || *pBufferFrom == '\n')
|
|
continue;
|
|
*pBufferTo = *pBufferFrom;
|
|
if (*pBufferTo == '\0')
|
|
break;
|
|
pBufferTo++;
|
|
}
|
|
|
|
if(!SCVerifyConnection(pCon))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* log it for any case */
|
|
if(pCon->pSock)
|
|
{
|
|
iRet = pCon->pSock->sockid;
|
|
}
|
|
else
|
|
{
|
|
iRet = 0;
|
|
}
|
|
sprintf(pBueffel,"Next line intended for socket: %d",iRet);
|
|
SICSLogWrite(pBueffel,eInternal);
|
|
SICSLogWrite(pBuffer,iOut);
|
|
|
|
/* write to commandlog if user or manager privilege */
|
|
if(SCGetRights(pCon) <= usUser)
|
|
{
|
|
WriteToCommandLogId(NULL,iRet,pBuffer);
|
|
}
|
|
|
|
/* put it into the interpreter if present */
|
|
if(SCinMacro(pCon))
|
|
{
|
|
InterpWrite(pServ->pSics,pBuffer);
|
|
/* print it to client if error message */
|
|
/* FIXME should report errors via sycamore
|
|
if((iOut== eError) || (iOut == eWarning) )
|
|
iRet = SCDoSockWrite(pCon,GetCharArray(pMsgOut));*/
|
|
}
|
|
else /* not in interpreter, normal logic */
|
|
{
|
|
comCon = SCGetContext(pCon);
|
|
|
|
/* Return 0 without dying if no message data */
|
|
if(pBuffer == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
taskID = comCon.transID;
|
|
|
|
pMsg = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
|
pMsgString = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
|
pBueffel[0] = '\0';
|
|
|
|
sprintf(pBueffel,"[con%4.4d:",(int)pCon->ident); /* field 1: connID */
|
|
DynStringConcat(pMsg,pBueffel);
|
|
sprintf(pBueffel,"t%6.6d:",(int)taskID); /* field 2: taskID */
|
|
DynStringConcat(pMsg,pBueffel);
|
|
/* deviceID */
|
|
DynStringConcat(pMsg,comCon.deviceID);
|
|
DynStringConcatChar(pMsg,':');
|
|
|
|
/* msgFlag */
|
|
switch(iOut) {
|
|
case 5: /* eValue */
|
|
DynStringConcat(pMsg,"out");
|
|
break;
|
|
default:
|
|
DynStringConcat(pMsg,pCode[iOut]);
|
|
break;
|
|
}
|
|
DynStringConcatChar(pMsg,']');
|
|
if (iOut == eStart){
|
|
DynStringConcat(pMsgString, comCon.deviceID);
|
|
}
|
|
|
|
if (iOut == eEvent) {
|
|
DynStringConcat(pMsgString, " type=");
|
|
/* Default type to VALUECHANGE if conEventType not set */
|
|
if (-1 == pCon->conEventType)
|
|
DynStringConcat(pMsgString, pEventType[0]);
|
|
else
|
|
DynStringConcat(pMsgString, pEventType[pCon->conEventType]);
|
|
/* DynStringConcat(pMsgString, " status=");
|
|
DynStringConcat(pMsgString, pStatus[pCon->conStatus]);*/
|
|
DynStringConcat(pMsgString,",");
|
|
}
|
|
DynStringConcat(pMsgString," ");
|
|
DynStringConcat(pMsgString,pBuffer);
|
|
sycformat(comCon.deviceID, iOut, pMsgString, pMsg);
|
|
|
|
/* is this really to be printed ? */
|
|
if(iOut < pCon->iOutput)
|
|
{
|
|
if (pMsg != NULL)
|
|
DeleteDynString(pMsg);
|
|
return 0;
|
|
}
|
|
/* first the socket */
|
|
/*strcat(pMsg, pBueffel);*/
|
|
iRet = SCDoSockWrite(pCon,GetCharArray(pMsg));
|
|
SCWriteToLogFiles(pCon,GetCharArray(pMsg));
|
|
}
|
|
if (pMsg != NULL)
|
|
DeleteDynString(pMsg);
|
|
return 1;
|
|
}
|
|
|
|
/* 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 (is_error(msg_json)) { linenum = __LINE__; goto reporterr; }
|
|
/* field 1: connID */
|
|
json_object_object_add(msg_json, "con", json_object_new_int(pCon->ident));
|
|
/* 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 (is_error(tmp_json)) { 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 (is_error(tmp_json)) { 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 && !is_error(tmp_json))
|
|
json_object_put(tmp_json);
|
|
if (msg_json != NULL && !is_error(msg_json))
|
|
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 */
|
|
if(pCon->pSock)
|
|
{
|
|
iRet = pCon->pSock->sockid;
|
|
}
|
|
else
|
|
{
|
|
iRet = 0;
|
|
}
|
|
sprintf(pBueffel,"Next line intended for socket: %d",iRet);
|
|
SICSLogWrite(pBueffel,eInternal);
|
|
SICSLogWrite(pBuffer,iOut);
|
|
|
|
/* write to commandlog if user or manager privilege */
|
|
if(SCGetRights(pCon) <= usUser)
|
|
{
|
|
if(pCon->iMacro != 1)
|
|
{
|
|
WriteToCommandLogId(NULL,iRet,pBuffer);
|
|
}
|
|
else
|
|
{
|
|
if(iOut == eError || iOut == eWarning)
|
|
{
|
|
WriteToCommandLogId(NULL,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,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,json_object_to_json_string(my_object));
|
|
iRet = 0;
|
|
} else {
|
|
iRet = SCDoSockWrite(pCon,json_object_to_json_string(my_object));
|
|
SCWriteToLogFiles(pCon,pBuffer);
|
|
}
|
|
}
|
|
if (tmp_json != NULL && !is_error(tmp_json))
|
|
json_object_put(tmp_json);
|
|
if (my_object != NULL && !is_error(my_object))
|
|
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(pCon->iProtocolID)
|
|
{
|
|
case 0: /* default = psi_sics */
|
|
case 1: /* normal (connection start default) */
|
|
case 2: /* outcodes */
|
|
case 3: /* sycamore */
|
|
case 4: /* json */
|
|
return strdup(pPro->pProList[pCon->iProtocolID]);
|
|
break;
|
|
default:
|
|
return strdup("invalid");
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------*/
|
|
int GetProtocolID(SConnection* pCon)
|
|
{
|
|
if(NULL!=pCon)
|
|
{
|
|
return pCon->iProtocolID;
|
|
}
|
|
return -1;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
writeFunc GetProtocolWriteFunc(SConnection *pCon){
|
|
if(pCon != NULL){
|
|
switch(pCon->iProtocolID){
|
|
case 2: /* outcodes */
|
|
return SCWriteWithOutcode;
|
|
break;
|
|
case 3: /* sycamore */
|
|
return SCWriteSycamore;
|
|
break;
|
|
case 4: /* json */
|
|
return SCWriteJSON_String;
|
|
break;
|
|
case 5:
|
|
return SCACTWrite;
|
|
break;
|
|
default:
|
|
return SCNormalWrite;
|
|
break;
|
|
}
|
|
}
|
|
return SCNormalWrite;
|
|
}
|