- Added Sycamore protocol and command context to SICS
- Added sinfo to SICS - Added driver for TCP/IP Astrium velocity selector - Added driver for TCP/IP Astrium chopper controller SKIPPED: psi/amor2t.c psi/amorstat.c psi/dornier2.c psi/ecb.c psi/el734hp.c psi/fowrite.c psi/libpsi.a psi/make_gen psi/nextrics.c psi/pardef.c psi/pimotor.c psi/pipiezo.c psi/polterwrite.c psi/psi.c psi/scontroller.c psi/serial.c psi/tasinit.c psi/tasscan.c psi/tcpdocho.c psi/tcpdornier.c psi/tricssupport.c psi/velodornier.c
This commit is contained in:
616
protocol.c
Normal file
616
protocol.c
Normal file
@ -0,0 +1,616 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
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 "protocol.h"
|
||||
|
||||
#define MAXMSG 1024
|
||||
#define INIT_STR_SIZE 256
|
||||
#define STR_RESIZE_LENGTH 256
|
||||
|
||||
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[5]; /* 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 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[]);
|
||||
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);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pProtocol CreateProtocol(void)
|
||||
{
|
||||
int i, iNumPros = 4;
|
||||
char *pPros[5] = {"default",
|
||||
"normal",
|
||||
"withcode",
|
||||
"sycamore",
|
||||
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 command[1024];
|
||||
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(command,1023,"ERROR: failed to convert %s to transaction ID", argv[1]);
|
||||
SCWrite(pCon,command,eError);
|
||||
return 0;
|
||||
}
|
||||
strncpy(comCon.deviceID,argv[2],SCDEVIDLEN);
|
||||
memset(command,0,1024*sizeof(char));
|
||||
Arg2Text(argc-2,&argv[2],command,1023);
|
||||
|
||||
SCPushContext2(pCon,comCon);
|
||||
status = InterpExecute(pSics,pCon,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;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
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 0: /* default = psi_sics */
|
||||
default:
|
||||
SCSetWriteFunc(pCon,pPro->defaultWriter);
|
||||
break;
|
||||
}
|
||||
pCon->iProtocolID = proID;
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int ProtocolGet(SConnection* pCon, Protocol* pPro, char *pProName,
|
||||
int *pIndex)
|
||||
{
|
||||
if(!SCVerifyConnection(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;
|
||||
}
|
||||
|
||||
*pIndex = (int)malloc(sizeof(int));
|
||||
*pIndex = pCon->iProtocolID;
|
||||
|
||||
/* check list of protocols for valid name */
|
||||
switch(*pIndex)
|
||||
{
|
||||
case 0: /* default = psi_sics */
|
||||
case 1: /* normal (connection start default) */
|
||||
case 2: /* outcodes */
|
||||
case 3: /* sycamore */
|
||||
pProName = strdup(pPro->pProList[*pIndex]);
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
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);
|
||||
assert(pSics);
|
||||
pPro = (pProtocol)pData;
|
||||
assert(pPro);
|
||||
|
||||
/* You need to have User level access rights to use this facility */
|
||||
if(!SCMatchRights(pCon,usUser))
|
||||
{
|
||||
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;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
|
||||
{
|
||||
int i, iPtr, iRet;
|
||||
int bDevIDdone = 0;
|
||||
int bFlagDone = 0;
|
||||
char pBueffel[MAXMSG];
|
||||
long taskID = 0;
|
||||
/* char pPrefix[40];*/
|
||||
pDynString pMsg = NULL;
|
||||
pDynString pMsgOut = NULL;
|
||||
pDynString parseCmd = NULL;
|
||||
SicsInterp *pSics;
|
||||
TokenList *pList = NULL;
|
||||
TokenList *pCurrent;
|
||||
commandContext comCon;
|
||||
char *savedTclResult = NULL;
|
||||
|
||||
/* For calling sycParse from interpreter */
|
||||
char **argv = NULL;
|
||||
int argc;
|
||||
char *parser = "sycformat ";
|
||||
char batchName[50];
|
||||
strcpy(batchName,"::ansto::batch::next");
|
||||
CommandList *pCommand = NULL;
|
||||
|
||||
if(!SCVerifyConnection(pCon))
|
||||
{
|
||||
DeleteDynString(parseCmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
comCon = SCGetContext(pCon);
|
||||
|
||||
if (strcmp(comCon.deviceID, batchName) == 0) {
|
||||
DeleteDynString(parseCmd);
|
||||
return 1;
|
||||
}
|
||||
/* Return 0 without dying if no message data */
|
||||
if(pBuffer == NULL)
|
||||
{
|
||||
DeleteDynString(parseCmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
build the Tcl-command to execute for formatting the
|
||||
data into a sycamore string
|
||||
*/
|
||||
pSics = GetInterpreter();
|
||||
taskID = comCon.transID;
|
||||
taskID = taskID % 1000000;
|
||||
|
||||
pMsg = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
||||
pBueffel[0] = '\0';
|
||||
|
||||
sprintf(pBueffel,"con%4.4d",pCon->ident); /* field 1: connID */
|
||||
DynStringConcat(pMsg,pBueffel);
|
||||
sprintf(pBueffel," t%6.6d",taskID); /* field 2: taskID */
|
||||
DynStringConcat(pMsg,pBueffel);
|
||||
DynStringConcatChar(pMsg,' ');
|
||||
/* 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,' ');
|
||||
DynStringConcat(pMsg, " { ");
|
||||
DynStringConcat(pMsg, comCon.deviceID);
|
||||
DynStringConcat(pMsg, " } {");
|
||||
if (iOut == eStart){
|
||||
DynStringConcat(pMsg, comCon.deviceID);
|
||||
}
|
||||
parseCmd = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
||||
DynStringCopy(parseCmd, parser);
|
||||
DynStringConcat(parseCmd,GetCharArray(pMsg));
|
||||
DynStringConcat(parseCmd,pBuffer);
|
||||
|
||||
if (iOut == eEvent) {
|
||||
DynStringConcat(parseCmd, " type.");
|
||||
DynStringConcat(parseCmd, pEventType[pCon->conEventType]);
|
||||
DynStringConcat(parseCmd, " status.");
|
||||
DynStringConcat(parseCmd, pStatus[pCon->conStatus]);
|
||||
}
|
||||
DynStringConcatChar(parseCmd, '}');
|
||||
savedTclResult = strdup(Tcl_GetStringResult(pSics->pTcl));
|
||||
Tcl_Eval(pSics->pTcl, GetCharArray(parseCmd));
|
||||
pMsgOut = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH);
|
||||
DynStringCopy(pMsgOut, (char *)Tcl_GetStringResult(pSics->pTcl));
|
||||
if(savedTclResult != NULL){
|
||||
Tcl_SetResult(pSics->pTcl,savedTclResult,TCL_VOLATILE);
|
||||
free(savedTclResult);
|
||||
}
|
||||
|
||||
/* 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(GetCharArray(pMsgOut),iOut);
|
||||
|
||||
/* write to commandlog if user or manager privilege */
|
||||
if(SCGetRights(pCon) <= usUser)
|
||||
{
|
||||
sprintf(pBueffel,"To sock %d :",iRet);
|
||||
WriteToCommandLog(pBueffel,GetCharArray(pMsgOut));
|
||||
}
|
||||
|
||||
/* put it into the interpreter if present */
|
||||
if(SCinMacro(pCon))
|
||||
{
|
||||
InterpWrite(pSics,pBuffer);
|
||||
iRet = SCDoSockWrite(pCon,GetCharArray(pMsgOut));
|
||||
}
|
||||
else /* not in interpreter, normal logic */
|
||||
{
|
||||
/* is this really to be printed ? */
|
||||
if(iOut < pCon->iOutput)
|
||||
{
|
||||
DeleteDynString(parseCmd);
|
||||
DeleteDynString(pMsg);
|
||||
DeleteDynString(pMsgOut);
|
||||
return 0;
|
||||
}
|
||||
/* first the socket */
|
||||
/*strcat(pMsg, pBueffel);*/
|
||||
iRet = SCDoSockWrite(pCon,GetCharArray(pMsgOut));
|
||||
SCWriteToLogFiles(pCon,GetCharArray(pMsgOut));
|
||||
}
|
||||
if(pMsgOut != NULL){
|
||||
DeleteDynString(pMsgOut);
|
||||
}
|
||||
DeleteDynString(parseCmd);
|
||||
DeleteDynString(pMsg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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 */
|
||||
return strdup(pPro->pProList[pCon->iProtocolID]);
|
||||
break;
|
||||
default:
|
||||
return strdup("invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------*/
|
||||
int GetProtocolID(SConnection* pCon)
|
||||
{
|
||||
if(NULL!=pCon)
|
||||
{
|
||||
return pCon->iProtocolID;
|
||||
}
|
||||
return -1;
|
||||
}
|
Reference in New Issue
Block a user