- Installed json protocol
SKIPPED: psi/libpsi.a psi/tecs/libtecsl.a
This commit is contained in:
222
protocol.c
222
protocol.c
@ -16,11 +16,13 @@
|
||||
#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 5
|
||||
#define PROLISTLEN 6
|
||||
typedef struct __Protocol {
|
||||
pObjectDescriptor pDes; /* required as first field */
|
||||
char *name; /* protocol handler name */
|
||||
@ -28,7 +30,7 @@ typedef struct __Protocol {
|
||||
int iNumPros; /* number of valid protocols? */
|
||||
writeFunc defaultWriter; /* default write function */
|
||||
int isDefaultSet;
|
||||
char *pProList[5]; /* list of valid protocols? */
|
||||
char *pProList[PROLISTLEN]; /* list of valid protocols? */
|
||||
} Protocol;
|
||||
|
||||
char *pEventType[]={
|
||||
@ -85,8 +87,6 @@ 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 ProtocolGet(SConnection* pCon, Protocol* pPro, char *pProName,
|
||||
int *pIndex);
|
||||
static int ProtocolList(SConnection* pCon, Protocol* pPro);
|
||||
int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
@ -95,15 +95,17 @@ 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 = 4;
|
||||
char *pPros[5] = {"default",
|
||||
int i, iNumPros = NUMPROS;
|
||||
char *pPros[] = {"default",
|
||||
"normal",
|
||||
"withcode",
|
||||
"sycamore",
|
||||
"json",
|
||||
NULL
|
||||
};
|
||||
pProtocol pNew = NULL;
|
||||
@ -276,7 +278,9 @@ static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName)
|
||||
case 3: /* sycamore */
|
||||
SCSetWriteFunc(pCon,SCWriteSycamore);
|
||||
break;
|
||||
|
||||
case 4: /* json */
|
||||
SCSetWriteFunc(pCon,SCWriteJSON_String);
|
||||
break;
|
||||
case 0: /* default = psi_sics */
|
||||
default:
|
||||
SCSetWriteFunc(pCon,pPro->defaultWriter);
|
||||
@ -288,9 +292,10 @@ static int ProtocolSet(SConnection* pCon, Protocol* pPro, char *pProName)
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int ProtocolGet(SConnection* pCon, Protocol* pPro, char *pProName,
|
||||
int *pIndex)
|
||||
int ProtocolGet(SConnection* pCon, void* pData, char *pProName, int len)
|
||||
{
|
||||
int Index;
|
||||
Protocol *pPro = (Protocol *)pData;
|
||||
if(!SCVerifyConnection(pCon))
|
||||
{
|
||||
return 0;
|
||||
@ -303,24 +308,27 @@ static int ProtocolGet(SConnection* pCon, Protocol* pPro, char *pProName,
|
||||
pPro->isDefaultSet = 1;
|
||||
pCon->iProtocolID = 0;
|
||||
}
|
||||
|
||||
*pIndex = (int)malloc(sizeof(int));
|
||||
*pIndex = pCon->iProtocolID;
|
||||
strncpy(pProName, pPro->pProList[pCon->iProtocolID], len);
|
||||
return 1;
|
||||
#if 0
|
||||
Index = pCon->iProtocolID;
|
||||
|
||||
/* check list of protocols for valid name */
|
||||
switch(*pIndex)
|
||||
switch(Index)
|
||||
{
|
||||
case 0: /* default = psi_sics */
|
||||
case 1: /* normal (connection start default) */
|
||||
case 2: /* outcodes */
|
||||
case 3: /* sycamore */
|
||||
pProName = strdup(pPro->pProList[*pIndex]);
|
||||
case 4: /* json */
|
||||
pProName = pPro->pProList[Index];
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -351,10 +359,10 @@ int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
{NULL}
|
||||
};
|
||||
|
||||
assert(pCon);
|
||||
assert(pSics);
|
||||
assert(pCon != NULL);
|
||||
assert(pSics != NULL);
|
||||
pPro = (pProtocol)pData;
|
||||
assert(pPro);
|
||||
assert(pPro != NULL);
|
||||
|
||||
/* You need to have User level access rights to use this facility */
|
||||
if(!SCMatchRights(pCon,usSpy))
|
||||
@ -427,8 +435,6 @@ static int InitDefaultProtocol(SConnection* pCon, Protocol *pPro)
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
void sycformat(char *tag, OutCode msgFlag, pDynString msgString, pDynString msgOut) {
|
||||
char typePrefix[] = "type.";
|
||||
char statusPrefix[] = "status.";
|
||||
DynStringConcat(msgOut," ");
|
||||
switch (msgFlag) {
|
||||
eEvent:
|
||||
@ -445,19 +451,13 @@ void sycformat(char *tag, OutCode msgFlag, pDynString msgString, pDynString msgO
|
||||
}
|
||||
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
|
||||
{
|
||||
int i, iPtr, iRet;
|
||||
int bDevIDdone = 0;
|
||||
int bFlagDone = 0;
|
||||
int iRet;
|
||||
char pBueffel[MAXMSG], *pBufferFrom, *pBufferTo;
|
||||
long taskID = 0;
|
||||
/* char pPrefix[40];*/
|
||||
pDynString pMsg = NULL;
|
||||
pDynString pMsgString = NULL;
|
||||
SicsInterp *pSics;
|
||||
TokenList *pList = NULL;
|
||||
TokenList *pCurrent;
|
||||
commandContext comCon;
|
||||
char *savedTclResult = NULL;
|
||||
|
||||
|
||||
if (strlen(pBuffer) == 0) {
|
||||
@ -517,11 +517,6 @@ int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
build the Tcl-command to execute for formatting the
|
||||
data into a sycamore string
|
||||
*/
|
||||
pSics = GetInterpreter();
|
||||
taskID = comCon.transID;
|
||||
|
||||
pMsg = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
||||
@ -552,9 +547,14 @@ int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
|
||||
|
||||
if (iOut == eEvent) {
|
||||
DynStringConcat(pMsgString, " type=");
|
||||
DynStringConcat(pMsgString, pEventType[pCon->conEventType]);
|
||||
/* 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);
|
||||
@ -577,6 +577,163 @@ int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
|
||||
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)
|
||||
{
|
||||
sprintf(pBueffel,"To sock %d :",iRet);
|
||||
WriteToCommandLog(pBueffel,pBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(iOut == eError || iOut == eWarning)
|
||||
{
|
||||
sprintf(pBueffel,"To sock %d :",iRet);
|
||||
WriteToCommandLog(pBueffel,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)
|
||||
@ -604,6 +761,7 @@ char * GetProtocolName(SConnection* pCon)
|
||||
case 1: /* normal (connection start default) */
|
||||
case 2: /* outcodes */
|
||||
case 3: /* sycamore */
|
||||
case 4: /* json */
|
||||
return strdup(pPro->pProList[pCon->iProtocolID]);
|
||||
break;
|
||||
default:
|
||||
|
Reference in New Issue
Block a user