#if defined(_MSC_VER)||defined(__MINGW32__) # define _CRT_SECURE_NO_WARNINGS 1 # include #endif #if defined(__linux__) # include # include # include # define INVALID_HANDLE_VALUE -1 #endif #include #include "pipeproto.h" #include "mypipe.h" /* Data per DLL load */ /* The following structure is completely specific for your DLL. In this example several things are stored: */ typedef struct localData { /* Handle to pipe to which data is written */ mypipe_t handle; /* Range of ChannelIDs, which should be processed */ unsigned int from,to; /* Buffer for data which should be written to DLL */ unsigned int h; unsigned char wbuf[8100]; } localDataT,*localDataP; enum { DECSTPV2_DUMMY = 0x00, /* Data messages */ DECSTPV2_D4 = 0x01, DECSTPV2_D8 = 0x02, DECSTPV2_D16 = 0x03, DECSTPV2_D32 = 0x04, DECSTPV2_D64 = 0x05, /* special messages */ DECSTPV2_VERSION = 0x06, DECSTPV2_MERR = 0x07, DECSTPV2_GERR = 0x08, DECSTPV2_FLAG = 0x09, DECSTPV2_USER = 0x0A, DECSTPV2_TIME = 0x0B, DECSTPV2_TRIG = 0x0C, DECSTPV2_FREQ = 0x0D, DECSTPV2_XSYNC = 0x0E, /* FLAGS (!) for MARK and TS */ DECSTPV2_TS = 0x20, DECSTPV2_MARK = 0x40, /* error */ DECSTPV2_ILLEGAL = 0xFF }; static const char *MsgTypes[] = { " DUMMY", " D4", " D8", " D16", " D32", " D64", " VERS", " MERR", " GERR", " FLAG", " USER", " TIME", " TRIG", " FREQ", " XSYNC" }; static void process(SPipeProtoInfo *info,localDataP data,unsigned char *buffer,int len) { uint32_t adr,d; int t,h; unsigned char *b=buffer; char *outb,*outs; if (buffer==NULL) { /* If the processing function is called with an empty buffer, it is an indication, that the data should be flushed */ if (data->handle != INVALID_HANDLE_VALUE) mypipe_write(data->handle,data->wbuf,data->h); data->h=0; return; } b=buffer; /* b[0..7] is timestamp */ t=b[8]&0x1F; /* get address of message Bit 31..16 is master number, bit 15..0 is channel number */ adr =b[12];adr<<=8; adr|=b[11];adr<<=8; adr|=b[10];adr<<=8; adr|=b[9]; if (adrfrom || adr>data->to) return; h=data->h; outb=(char *)(data->wbuf+h); if (t>= sizeof(MsgTypes)/sizeof(const char *)) { outb+=sprintf(outb,"Illegal message type 0x%x\n",t); } else { SPipeProtoCycleInfo cycle; outs=outb; outb+=sprintf(outb,"%s",MsgTypes[t]); t=b[8]; if (t&DECSTPV2_MARK) outb+=sprintf(outb,"_M"); if (t&DECSTPV2_TS) outb+=sprintf(outb,"_TS"); if ( (t&DECSTPV2_MARK) == 0) outb+=sprintf(outb," "); if ( (t&DECSTPV2_TS) == 0) outb+=sprintf(outb," "); outb+=sprintf(outb," adr 0x%08x data ",adr); switch(t&0x1f) { case DECSTPV2_D4: outb+=sprintf(outb,"0x%x",b[13]); cycle.type = PIPE_LOG_TYPE_WRITE|PIPE_LOG_TYPE_WITHADDRESS|PIPE_LOG_TYPE_WITHDATA; cycle.address = adr; cycle.datasize = 1; cycle.data[0] = b[13]; PIPE_LogCycle(info,b,&cycle); break; case DECSTPV2_D8: outb+=sprintf(outb,"0x%02x",b[13]); cycle.type = PIPE_LOG_TYPE_WRITE|PIPE_LOG_TYPE_WITHADDRESS|PIPE_LOG_TYPE_WITHDATA; cycle.address = adr; cycle.datasize = 1; cycle.data[0] = b[13]; PIPE_LogCycle(info,b,&cycle); break; case DECSTPV2_D16: d=b[14];d<<=8; d|=b[13]; outb+=sprintf(outb,"0x%04x",d); cycle.type = PIPE_LOG_TYPE_WRITE|PIPE_LOG_TYPE_WITHADDRESS|PIPE_LOG_TYPE_WITHDATA; cycle.address = adr; cycle.datasize = 2; cycle.data[0] = b[13]; cycle.data[1] = b[14]; PIPE_LogCycle(info,b,&cycle); break; case DECSTPV2_D32: d=b[16];d<<=8; d|=b[15];d<<=8; d|=b[14];d<<=8; d|=b[13]; outb+=sprintf(outb,"0x%08x",d); cycle.type = PIPE_LOG_TYPE_WRITE|PIPE_LOG_TYPE_WITHADDRESS|PIPE_LOG_TYPE_WITHDATA; cycle.address = adr; cycle.datasize = 4; cycle.data[0] = b[13]; cycle.data[1] = b[14]; cycle.data[2] = b[15]; cycle.data[3] = b[16]; PIPE_LogCycle(info,b,&cycle); break; case DECSTPV2_D64: d=b[20];d<<=8; d|=b[19];d<<=8; d|=b[18];d<<=8; d|=b[17]; outb+=sprintf(outb,"0x%08x",d); d=b[16];d<<=8; d|=b[15];d<<=8; d|=b[14];d<<=8; d|=b[13]; outb+=sprintf(outb,"%08x",d); cycle.type = PIPE_LOG_TYPE_WRITE|PIPE_LOG_TYPE_WITHADDRESS|PIPE_LOG_TYPE_WITHDATA; cycle.address = adr; cycle.datasize = 8; cycle.data[0] = b[13]; cycle.data[1] = b[14]; cycle.data[2] = b[15]; cycle.data[3] = b[16]; cycle.data[4] = b[17]; cycle.data[5] = b[18]; cycle.data[6] = b[19]; cycle.data[7] = b[20]; PIPE_LogCycle(info,b,&cycle); break; } PIPE_LogCustom(info,b,PIPE_LOG_TYPE_STRING,(uint8_t *)outs,(int)(outb - outs)); outb+=sprintf(outb,"\n"); } h = (int)(outb - ((char *)data->wbuf)); if (h >= 7168) { if (data->handle != INVALID_HANDLE_VALUE) mypipe_write(data->handle,data->wbuf,h); h=0; } data->h=h; } /* called when DLL is unloaded * Parameters * info : Structure for calling functions inside T32 * data : Pointer to structure which holds local data for this DLL. */ static void exitDll(SPipeProtoInfo *info,localDataP data) { mypipe_t handle; handle = data->handle; /* close pipe */ if (handle!=INVALID_HANDLE_VALUE) mypipe_close(handle); /* Free data, which was allocated int "PIPE_Interface" */ free(data); } /* * Parameters * info : Structure for calling functions inside T32 * argc : numbers of parameters stored in "argv" * argv : array of pointers to "NUL" terminated command line parameters * * This function should allocate space to store local configuration data * for one DLL load. * It additionally should do all initialization which is necessary. */ int PIPE_Init(SPipeProtoInfo *info,int argc, char **argv) { mypipe_t handle; char pipeName[256]; /* char command[1000]; */ localDataP localdata; uint32_t from,to; handle=INVALID_HANDLE_VALUE; if (argc!=2 && argc!=4) { PIPE_Puts(info,"usage: pproto [ ]"); return 1; } #if defined(_MSC_VER)||defined(__MINGW32__) /* extract pipe name from command line parameters */ sprintf(pipeName,"//./pipe/%s",argv[1]); #endif #if defined(__linux__) /* extract pipe name from command line parameters */ sprintf(pipeName,"/tmp/%s",argv[1]); #endif /* extract range from command line parameters, if a range was given */ from=0; to=0xFFFFFFFF; if (argc==4) { from=strtoul(argv[2],NULL,0); to=strtoul(argv[3],NULL,0); } /* Start application which opens and reads from pipe */ /* sprintf(command,"os ./pread.exe //./pipe/%s",argv[1]); PIPE_Command(info, command); Sleep(500); */ /* Open PIPE for writing data to it */ if (mypipe_open_write(&handle,pipeName)) { PIPE_Printf(info,"Can not open %s for writing",pipeName); // return 2; } else PIPE_Printf(info,"Opened pipe %s",pipeName); /* create data set for this invocation of the DLL and store configuration data into it. */ localdata=(localDataP)malloc(sizeof(localDataT)); localdata->handle=handle; localdata->from=from; localdata->to=to; localdata->h=0; /* Register callbacks, use "data" as localdata for the callbacks */ /* * Parameters for PIPE_RegisterCallback: * info : Pointer to "SPipeProtoInfo" structure * type : Type of function to register * callback : Pointer to function which will be called. * flags : optional flags (currently always 0). */ PIPE_RegisterCallback(info, PIPE_PROCESS_CALLBACK, process, localdata, 0); PIPE_RegisterCallback(info, PIPE_EXIT_CALLBACK , exitDll, localdata, 0); return 0; }