1
0
mirror of https://github.com/netdata-be/libnodave synced 2025-10-13 00:42:50 +08:00
libnodave/ibhsim5.c
2012-06-01 10:15:12 +02:00

929 lines
28 KiB
C

/*
Part of Libnodave, a free communication libray for Siemens S7 300/400.
This program simulates the IBHLink MPI-Ethernet-Adapter from IBH-Softec.
www.ibh-softec.de
(C) Thomas Hergenhahn (thomas.hergenhahn@web.de) 2002.
Libnodave is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Libnodave is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Visual; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include "log2.h"
#define ThisModule "IBHtest : "
#define uc unsigned char
#include "nodave.h"
#include "ibhsamples6.c"
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include "accepter.c"
#include "simProperties.c"
#define bSize 1256
#define us unsigned short
#define debug 12
extern int daveDebug;
#define daveDebugAnalyze 0x40000
void analyze(daveConnection * dc);
/*
many bytes. hopefully enough to serve any read request.
*/
uc dummyRes[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,
12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,12,13,14,1,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,
12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,12,13,14,1,
5,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,5,16,1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,12,13,14,1,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,
12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,12,13,14,1,
5,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,5,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,};
/*
a read callback function
*/
uc * dummyRead (int area, int DBnumber, int start, int len, int * res) {
printf("User callback should deliver pointer to %d bytes from %s %d beginning at %d.\n",
len, daveAreaName(area),DBnumber,start);
*res=0;
return dummyRes;
};
void myWrite (int area, int DBnumber, int start, int len, int * res, uc*bytes) {
printf("User callback1 should write %d bytes to %s %d beginning at %d.\n",
len, daveAreaName(area),DBnumber,start);
printf("User callback 1.\n");
*res=0;
start=start/8;
memcpy(dummyRes+start,bytes,len);
printf("User callback done.\n");
fflush(stdout);
};
int handleTime(PDU *p1, PDU *p2){
if (p1->param[6]==1) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x87,0x01,0x01, 0x00,0x00,0,0,};
printf("Get time from CPU.\n");
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, CpuTimeStamp, sizeof(CpuTimeStamp));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if (p1->param[6]==2) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x87,0x02,0x01, 0x00,0x00,0,0,};
printf("Set CPU time.\n");
memcpy(CpuTimeStamp, p1->data+4,sizeof(CpuTimeStamp));
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, CpuTimeStamp, sizeof(CpuTimeStamp));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else {
printf("Cannot handle this\n");
return 0;
}
}
int handleBlocks(PDU *p1, PDU *p2){
printf("Block handling Commands(%d) ???? ????\n",p1->param[6]);
if (p1->param[6]==1) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x83,0x01,0x00, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, blockList, sizeof(blockList));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if (p1->param[6]==2) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x83,0x02,0x00, 0x00,0x00,0x00,0x00,};
uc da[]={0x0a,0x0,0x0,0x0,};
uc SDBs[]={0x00,0x01,0x22,0x11,0x00,0x02,0x22,0x11};
printf("List Blocks of type %s\n",daveBlockName(p1->data[5]));
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
if(p1->data[5]==0x42) {
_daveAddUserData(p2, SDBs, sizeof(SDBs));
} else {
_daveAddData(p2, da, sizeof(da));
}
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if (p1->param[6]==3) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x83,0x03,0x00, 0x00,0x00,0xd2,0x09,};
uc da[]={0x0a,0x0,0x0,0x0,};
printf("get Block info/header %s\n",daveBlockName(p1->data[5]));
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddData(p2, da, sizeof(da));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else {
printf("Cannot handle this\n");
return 0;
}
}
int handleReadProgram(PDU *p1, PDU *p2){
uc pa[]={
0x1D,0x00,0x01,0x00,0x00,0x00,0x00,0x07,0x07,0x30,0x30,0x30,0x30,0x30,0x37,0x32,
};
printf("Program block readout.\n");
_daveInitPDUheader(p2,3);
_daveAddParam(p2, pa, sizeof(pa));
// if(daveDebug & daveDebugPDU)
_daveDumpPDU(p2);
return 1;
}
typedef struct __ls {
uc * content;
int gotlen;
int totlen;
int number;
int PDUnumber;
int typ;
} loadStruct;
//#define ploaderror
int handleLoadProgram(daveConnection *dc,PDU *p1, PDU *p2,int PDUnumber, uc*resp, loadStruct * ls){
int n;
uc pa[]={
0x1A
};
uc pa2[]={
0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x5F,0x30,0x38,0x30,0x30,0x30,0x30,0x31,0x50,
};
#ifndef ploaderror
printf("Program block load.\n");
_daveInitPDUheader(p2,3);
_daveAddParam(p2, pa, sizeof(pa));
ls->typ=p1->param[11];
printf("block type %s. ",daveBlockName(ls->typ));
ls->number=atol((char*)p1->param+12);
ls->PDUnumber=1;
printf("number: %d\n",ls->number);
p1->param[26]=0;
ls->totlen=atol((char*)p1->param+20);
ls->gotlen=0;
printf("total size: %d\n",ls->totlen);
ls->content=(uc*)malloc(ls->totlen);
resp[22]=PDUnumber % 256; // test!
resp[21]=PDUnumber / 256; // test!
_daveDumpPDU(p2);
write(dc->iface->fd.rfd,resp,resp[2]+8);
_daveInitPDUheader(p2,1);
pa2[11]=ls->typ;
n=ls->number;
pa2[16]=0x30+(n %10);
n/=10;
pa2[15]=0x30+(n %10);
n/=10;
pa2[14]=0x30+(n %10);
n/=10;
pa2[13]=0x30+(n %10);
_daveAddParam(p2, pa2, sizeof(pa2));
#else
_daveInitPDUheader(p2,2);
p2->header[10]=0xD2;
p2->header[11]=0x09;
#endif
// _daveAddParam(p2, pa, sizeof(pa));
// if(daveDebug & daveDebugPDU)
/*
resp[22]=PDUnumber % 256; // test!
resp[21]=PDUnumber / 256; // test!
*/
_daveDumpPDU(p2);
write(dc->iface->fd.rfd,resp,resp[2]+8);
/*
dc->AnswLen=_daveReadIBHPacket(dc->iface, dc->msgIn);
analyze(dc);
// _daveDump("I sent:",resp,resp[2]+8);
LOG1(ThisModule);
_daveDump("epacket 1", dc->msgIn, dc->AnswLen);
dc->AnswLen=_daveReadIBHPacket(dc->iface, dc->msgIn);
analyze(dc);
// _daveDump("I sent:",resp,resp[2]+8);
LOG1(ThisModule);
_daveDump("epacket 2", dc->msgIn, dc->AnswLen);
dc->AnswLen=_daveReadIBHPacket(dc->iface, dc->msgIn);
analyze(dc);
// _daveDump("I sent:",resp,resp[2]+8);
LOG1(ThisModule);
_daveDump("epacket 3", dc->msgIn, dc->AnswLen);
dc->AnswLen=_daveReadIBHPacket(dc->iface, dc->msgIn);
analyze(dc);
// _daveDump("I sent:",resp,resp[2]+8);
LOG1(ThisModule);
_daveDump("epacket 4", dc->msgIn, dc->AnswLen);
*/
return 0;
}
int handleContLoadProgram(daveConnection *dc,PDU *p1, PDU *p2,int PDUnumber, uc*resp, loadStruct * ls){
int n;
uc pa2[]={
0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x5F,0x30,0x38,0x30,0x30,0x30,0x30,0x34,0x50,
};
uc pa3[]={
// 0x1C,0x00,0x84,0x04,0x00,0x00,0x00,0x00,0x09,0x5F,0x30,0x38,0x30,0x30,0x30,0x30,0x34,0x50,
0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x5F,0x30,0x38,0x30,0x30,0x30,0x30,0x34,0x50,
};
printf("total size: %d have %d\n",ls->totlen,ls->gotlen);
ls->gotlen +=p1->dlen-4;
printf("total size: %d have %d\n",ls->totlen,ls->gotlen);
n=ls->number;
pa2[16]=0x30+(n %10);
n/=10;
pa2[15]=0x30+(n %10);
n/=10;
pa2[14]=0x30+(n %10);
n/=10;
pa2[13]=0x30+(n %10);
pa2[11]=ls->typ;
n=ls->number;
pa3[16]=0x30+(n %10);
n/=10;
pa3[15]=0x30+(n %10);
n/=10;
pa3[14]=0x30+(n %10);
n/=10;
pa3[13]=0x30+(n %10);
pa3[11]=ls->typ;
if (p1->param[1]==1) {
_daveAddParam(p2, pa2, sizeof(pa2));
return 1;
}
else {
_daveAddParam(p2, pa3, sizeof(pa3));
return 1;
}
}
int handleEndLoadProgram(daveConnection *dc,PDU *p1, PDU *p2,int PDUnumber, uc*resp, loadStruct * ls){
uc pa[]={
0x1C
};
printf("Program block readout.\n");
_daveInitPDUheader(p2,3);
_daveAddParam(p2, pa, sizeof(pa));
// if(daveDebug & daveDebugPDU)
_daveDumpPDU(p2);
return 1;
}
int handleContinueReadProgram(PDU *p1, PDU *p2){
uc pa[]={
0x1E,0x00
};
uc da[]={
0x00,0x48,0x00,0xFB, 0x70,0x70,0x00,0x0A, 0x11,0x0B,0x00,0x01, 0x00,0x00,0x00,0x48,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x0E,0x45,0x00,0x00, 0x00,0x00,0x0E,0x45,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x24, 0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x00,0x01,0x7F,0xFF, 0x00,0x00,0x22,0x00, 0x00,0x01,0x00,0xC0,
};
printf("Program block readout.\n");
_daveInitPDUheader(p2,3);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddData(p2, da, sizeof(da));
// if(daveDebug & daveDebugPDU)
_daveDumpPDU(p2);
return 1;
}
int handleEndReadProgram(PDU *p1, PDU *p2){
uc pa[]={
0x1F
};
printf("Program block readout.\n");
_daveInitPDUheader(p2,3);
_daveAddParam(p2, pa, sizeof(pa));
// if(daveDebug & daveDebugPDU)
_daveDumpPDU(p2);
return 1;
}
int handleSZL(int number, int index, PDU *p2){
if ((number==292) && (index==0)) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, SZL_292_0, sizeof(SZL_292_0));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if ((number==274) && (index==512)) { /* read order code (MLFB) */
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, SZL_274_512, sizeof(SZL_274_512));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if ((number==0) && (index==0)) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, SZL_0_0, sizeof(SZL_0_0));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if ((number==25) && (index==0)) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, SZL_25_0, sizeof(SZL_25_0));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if ((number==273) && (index==1)) { /* read order code (MLFB) */
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, SZL_273_1, sizeof(SZL_273_1));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if (number==305) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
switch (index) {
case 1: _daveAddUserData(p2, SZL_305_1, sizeof(SZL_305_1)); break;
case 2: _daveAddUserData(p2, SZL_305_2, sizeof(SZL_305_1)); break;
case 3: _daveAddUserData(p2, SZL_305_3, sizeof(SZL_305_1)); break;
case 4: _daveAddUserData(p2, SZL_305_4, sizeof(SZL_305_1)); break;
case 5: _daveAddUserData(p2, SZL_305_5, sizeof(SZL_305_1)); break;
case 6: _daveAddUserData(p2, SZL_305_6, sizeof(SZL_305_1)); break;
case 7: _daveAddUserData(p2, SZL_305_7, sizeof(SZL_305_1)); break;
case 8: _daveAddUserData(p2, SZL_305_8, sizeof(SZL_305_1)); break;
case 9: _daveAddUserData(p2, SZL_305_9, sizeof(SZL_305_1)); break;
}
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if (number==306) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
switch (index) {
case 1: _daveAddUserData(p2, SZL_306_1, sizeof(SZL_306_1)); break;
case 2: _daveAddUserData(p2, SZL_306_2, sizeof(SZL_306_2)); break;
case 4: _daveAddUserData(p2, SZL_306_4, sizeof(SZL_306_4)); break;
}
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if ((number==0xD91) && (index==0)) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, SZL_3473_0, sizeof(SZL_3473_0));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if ((number==1060) && (index==0)) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
if (runStop == runModeRun)
_daveAddUserData(p2, SZL_1060_0, sizeof(SZL_1060_0));
else if (runStop == runModeStop)
_daveAddUserData(p2, SZL_1060_0S, sizeof(SZL_1060_0S));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else if ((number==1316) && (index==20480)) {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0x00,0x00,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddUserData(p2, SZL_1316_20480, sizeof(SZL_1316_20480));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
} else {
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x84,0x01,0x01, 0x00,0x00,0xD4,0x01,};
uc da[]={0x0a,0x0,0x0,0x0,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddData(p2, da, sizeof(da));
if(daveDebug & daveDebugPDU)_daveDumpPDU(p2);
return 1;
}
}
int handleSystemMessage(PDU * p1,PDU * p2) {
int number;
int index;
if (
(p1->param[1]==1) &&
(p1->param[2]==18) &&
(p1->param[3]==4) &&
(p1->param[4]==17) &&
(p1->param[5]=='D')
) {
number=0x100*(p1->data[4])+p1->data[5];
index=0x100*(p1->data[6])+p1->data[7];
printf("SZL read ID: %04X index: %d\n",number,index);
return handleSZL(number,index,p2);
} else if (
(p1->param[1]==1) &&
(p1->param[2]==18) &&
(p1->param[3]==4) &&
(p1->param[4]==17) &&
(p1->param[5]=='C')
) {
printf("Block functions\n");
return handleBlocks(p1,p2);
}
else if (
(p1->param[1]==1) &&
(p1->param[2]==18) &&
(p1->param[3]==4) &&
(p1->param[4]==17) &&
(p1->param[5]=='G')
) {
printf("Time System ????\n");
return handleTime(p1,p2);
} else if (
(p1->param[1]==1) &&
(p1->param[2]==18) &&
(p1->param[3]==8) &&
(p1->param[4]==18) &&
(p1->param[5]=='A')
) {
if(p1->param[6]==16) {
printf("Forces ???? ????\n");
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x81,0x10,0x00, 0x00,0x00,0xD0,0x02,};
uc da[]={0,4,0,4,1,0,0,1,16,1,0,0};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddData(p2, da, sizeof(da));
_daveDumpPDU(p2);
return 1;
} else if(p1->param[6]==12) {
printf("Erase ???? ????\n");
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x81,0x12,0x00, 0x00,0x00,0x0,0x0,};
uc da[]={0x0a,0x0,0x0,0x0,};
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddData(p2, da, sizeof(da));
_daveDumpPDU(p2);
return 1;
} else {
printf("Programmer Commands(%d) ???? ????\n",p1->param[6]);
uc pa[]={0x00,0x01,0x12,0x08,0x12,0x81,0x10,0x00, 0x00,0x00,0xD0,0x04,};
uc da[]={0x0a,0x0,0x0,0x0,};
pa[6]=p1->param[6];
_daveInitPDUheader(p2,7);
_daveAddParam(p2, pa, sizeof(pa));
_daveAddData(p2, da, sizeof(da));
_daveDumpPDU(p2);
return 1;
}
}
printf("Cannot handle this!\n");
return 0;
};
int handleNegociate(PDU * p1,PDU * p2) {
uc pa[]={0xF0,0x0,0x0,0x1, 0x00,0x01,0x00,0xF0};
davePut16At(pa, 6, simMaxPDUlength);
_daveInitPDUheader(p2,3);
_daveAddParam(p2, pa, sizeof(pa));
return 1;
};
int handleStop(PDU * p1,PDU * p2) {
uc pa[]={0x29};
runStop=runModeStop;
_daveInitPDUheader(p2,3);
_daveAddParam(p2, pa, sizeof(pa));
return 1;
};
int handleRun(PDU * p1,PDU * p2, loadStruct * ls) {
uc pa[]={0x28};
runStop=runModeRun;
_daveInitPDUheader(p2,3);
_daveAddParam(p2, pa, sizeof(pa));
return 1;
};
int gpacketNumber=0;
uc r5[]={
0xff,0x07,0x13,0x00,0x00,0x00,0xc2,0x02, 0x14,0x14,0x03,0x00,0x00,0x22,0x0c,0xd0,
0x04,0x00,0x80,0x00,0x02,0x00,0x02,0x01,0x00,0x01,0x00,
};
void _daveSendIBHNetAck2(daveConnection * dc) {
// 0xff,0x07,0x05,0x02,0x82,0x00,0x00,0x00, 0x14,0x00,0x03,0x01,0x09,
IBHpacket * p;
uc ack[13],c;
us d;
memcpy(ack, dc->msgIn, sizeof(ack));
p= (IBHpacket*) ack;
d=p->sFlags; p->sFlags=p->rFlags; p->rFlags=d;
c=p->ch1; p->ch1=p->ch2; p->ch2=c; // certainly nonsense, but I cannot test it
c=ack[9]; // at the moment, and because it DID work,
ack[9]=ack[10];
ack[10]=c; // I'll leave it as it is.
p->len=sizeof(ack)-sizeof(IBHpacket);
ack[11]=1;
ack[12]=9;
// LOG2("Sending net level ack for number: %d\n",p->packetNumber);
if (daveDebug & daveDebugMPI){
_daveDump("I send ack", ack,sizeof(ack));
}
_daveWriteIBH(dc->iface, ack,sizeof(ack));
}
loadStruct lost;
void analyze(daveConnection * dc) {
IBHpacket * p2;
MPIheader2 * m2;
uc resp[2000];
int PDUnumber;
int haveResp=0;
PDU p1,pr;
IBHpacket * p= (IBHpacket*) dc->msgIn;
dc->needAckNumber=-1; // Assume no ack
/*
printf("Channel: %d\n",p->ch1);
printf("Channel: %d\n",p->ch2);
printf("Length: %d\n",p->len);
printf("Number: %d\n",p->packetNumber);
printf("sFlags: %04x rFlags:%04x\n",p->sFlags,p->rFlags);
*/
if (p->rFlags==0x82) {
MPIheader * pm= (MPIheader*) (dc->msgIn+sizeof(IBHpacket));
if (daveDebug & daveDebugAnalyze){
printf("srcconn: %d\n",pm->src_conn);
printf("dstconn: %d\n",pm->dst_conn);
printf("MPI: %d\n",pm->MPI);
printf("MPI len: %d\n",pm->len);
printf("MPI func:%d\n",pm->func);
}
if (pm->func==0xf1) {
if (daveDebug & daveDebugAnalyze){
printf("0xf1:PDU transport, MPI packet number: %d\n",pm->packetNumber);
}
dc->needAckNumber=pm->packetNumber;
dc->PDUstartI=sizeof(IBHpacket)+sizeof(MPIheader);
_daveSetupReceivedPDU(dc, &p1);
PDUnumber=p1.header[5]+256*p1.header[4];
_daveDumpPDU(&p1);
// construct response:
pr.header=resp+sizeof(IBHpacket)+sizeof(MPIheader2);
p2= (IBHpacket*) resp;
p2->ch1=p->ch2;
p2->ch2=p->ch1;
p2->packetNumber=0;
p2->sFlags=0;
p2->rFlags=0x2c2;
m2= (MPIheader2*) (resp+sizeof(IBHpacket));
m2->src_conn=pm->src_conn;
m2->dst_conn=pm->dst_conn;
m2->MPI=pm->MPI;
m2->xxx1=0;
m2->xxx2=0;
m2->xx22=0x22;
m2->packetNumber=gpacketNumber;
gpacketNumber++;
if (p1.param[0]==daveFuncRead) {
_daveHandleRead(&p1,&pr);
haveResp=1;
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else if (p1.param[0]==daveFuncWrite) {
printf("before _daveHandleWrite() %p\n",m2);
_daveHandleWrite(&p1,&pr);
printf("after _daveHandleWrite() %p\n",m2);
fflush(stdout);
haveResp=1;
// m2->func=0xf1; //!! guessed
printf("after _daveHandleWrite()\n");
fflush(stdout);
m2->len=pr.hlen+pr.plen+pr.dlen+2;
printf("after _daveHandleWrite()\n");
fflush(stdout);
p2->len=m2->len+7;
printf("after _daveHandleWrite()\n");
fflush(stdout);
} else if (p1.param[0]==240) {
printf("PDU function code: %d, negociate PDU len\n",p1.param[0]);
// _daveDump("packet:",dc->msgIn,dc->msgIn[2]+8);
handleNegociate(&p1,&pr);
dc->packetNumber=0;
haveResp=1;
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else if (p1.param[0]==0x28) {
printf("PDU function code: %d, run CPU\n",p1.param[0]);
// _daveDump("packet:",dc->msgIn,dc->msgIn[2]+8);
handleRun(&p1,&pr,&lost);
// dc->packetNumber=0;
haveResp=1;
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else if (p1.param[0]==0x29) {
printf("PDU function code: %d, stop CPU\n",p1.param[0]);
// _daveDump("packet:",dc->msgIn,dc->msgIn[2]+8);
handleStop(&p1,&pr);
dc->packetNumber=0;
haveResp=1;
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else if (p1.param[0]==0x1d) {
handleReadProgram(&p1,&pr);
haveResp=1;
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else if (p1.param[0]==0x1e) {
handleContinueReadProgram(&p1,&pr);
haveResp=1;
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else if (p1.param[0]==0x1f) {
handleEndReadProgram(&p1,&pr);
haveResp=1;
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else if (p1.param[0]==0x1a) {
handleLoadProgram(dc, &p1,&pr,PDUnumber,resp, &lost);
haveResp=1;
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
// PDUnumber=lost.PDUnumber;
} else if (p1.param[0]==0x1b) {
haveResp=handleContLoadProgram(dc, &p1,&pr,PDUnumber,resp, &lost);
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else if (p1.param[0]==0x1c) {
handleEndLoadProgram(dc, &p1,&pr,PDUnumber,resp, &lost);
haveResp=0;
} else if (p1.param[0]==0) {
printf("PDU function code: %d, system Messaga ?\n",p1.param[0]);
_daveSendMPIAck2(dc);
// _daveDump("packet:",b,b[2]+8);
haveResp=handleSystemMessage(&p1,&pr);
// pr.header[4]=p1.header[4]; // give the PDU a number
// pr.header[5]=p1.header[5]; // give the PDU a number
m2->func=0xf1; //!! guessed
m2->len=pr.hlen+pr.plen+pr.dlen+2;
p2->len=m2->len+7;
} else {
printf("Unsupported PDU function code: %d\n",p1.param[0]);
}
}
if (pm->func==0xb0) {
// printf("Ackknowledge for packet number: %d\n",*(dc->msgIn+15));
}
if (pm->func==0xe0) {
printf("Connect to MPI: %d\n",pm->MPI);
memcpy(resp, r5, sizeof(r5));
resp[8]=pm->src_conn;
resp[9]=pm->src_conn;
resp[10]=pm->MPI;
resp[11]=7; //????
haveResp=1;
}
}
if (((p->rFlags==0x82) /*||(p->sFlags==0x82)*/)&&(p->packetNumber)&&(p->len)) {
// printf("before _daveSendIBHNetAck()\n");
fflush(stdout);
_daveSendIBHNetAck2(dc);
}
if (haveResp) {
// printf("have response\n");
resp[22]=PDUnumber % 256; // test!
resp[21]=PDUnumber / 256; // test!
write(dc->iface->fd.rfd,resp,resp[2]+8);
_daveDump("I sent:",resp,resp[2]+8);
fflush(stdout);
}
};
typedef struct _portInfo {
int fd;
}portInfo;
#define mymemcmp _daveMemcmp
void *portServer(void *arg)
{
int waitCount, res, pcount, r2;
_daveOSserialType s;
daveInterface * di;
daveConnection * dc;
portInfo * pi=(portInfo *) arg;
LOG2(ThisModule "portMy fd is:%d\n",
pi->fd);
FLUSH;
waitCount= 0;
// daveDebug=daveDebugAll;
pcount=0;
s.rfd=pi->fd;
s.wfd=pi->fd;
di=daveNewInterface(s,"IF",0,daveProtoMPI_IBH,daveSpeed187k);
di->timeout=900000;
dc=daveNewConnection(di,0,0,0);
di->timeout=1900000;
while (waitCount < 1000) {
dc->AnswLen=_daveReadIBHPacket(dc->iface, dc->msgIn);
if (dc->AnswLen>0) {
res=dc->AnswLen;
if (daveDebug & daveDebugPacket) {
LOG2(ThisModule "%d ", pcount);
_daveDump("packet", dc->msgIn, dc->AnswLen);
}
waitCount = 0;
analyze(dc);
r2=2*res;
if(r2==sizeof(cha0)) {
if (0==mymemcmp(cha0, dc->msgIn, res)) {
LOG1(ThisModule "found challenge 0, write response 0\n");
write(pi->fd, res0, sizeof(res0));
}
}
if(r2==sizeof(cha1)) {
if (0==mymemcmp(cha1, dc->msgIn, res)) {
LOG1(ThisModule "found challenge 1, write response 1\n");
write(pi->fd, res1, sizeof(res1));
}
}
if(r2==sizeof(cha2)) {
if (0==mymemcmp(cha2, dc->msgIn, res)) {
LOG1(ThisModule "found challenge 2, write response 2\n");
write(pi->fd, res2, sizeof(res2));
}
}
if(r2==sizeof(cha3)) {
if (0==mymemcmp(cha3, dc->msgIn, res)) {
LOG1(ThisModule "found challenge 3, write response 3\n");
res3[8]=dc->msgIn[8];
write(pi->fd, res3, sizeof(res3));
}
}
if(r2==sizeof(cha8)) {
if (0==mymemcmp(cha8, dc->msgIn, res)) {
LOG1(ThisModule "found challenge 8, write response 7\n");
res7[8]=dc->msgIn[8];
res7[9]=dc->msgIn[9];
res7[10]=dc->msgIn[10];
write(pi->fd, res7, sizeof(res7));
}
}
if(r2==sizeof(cha11)) {
if (0==mymemcmp(cha11, dc->msgIn, res)) {
LOG1(ThisModule "found challenge 11, response 10\n");
res10[8]=dc->msgIn[8];
res10[9]=dc->msgIn[9];
// res10[10]=dc->msgIn[10];
// res10[32]=dc->msgIn[28];
// res10[34]=dc->msgIn[30];
// sendMPIAck2(dc->msgIn, pi->fd, ackPacketNumber);
//// dc->needAckNumber=0;
//// _daveSendMPIAck2(dc);
//// write(pi->fd, res10, sizeof(res10));
}
}
pcount++;
} else {
waitCount++;
}
}
LOG1(ThisModule "portserver: I closed my fd.\n");
FLUSH;
return NULL;
}
/*
This waits in select for a file descriptor from accepter and starts a new child server
with this file descriptor.
*/
int PID;
int main(int argc, char **argv)
{
portInfo pi;
fd_set FDS;
int filedes[2], res, newfd;
pthread_attr_t attr;
pthread_t ac, ps;
accepter_info ai;
PID=getpid();
if (argc<2) {
printf("Usage: ibhtest port\n");
printf("Example: ibhtest 1099 (used by IBHNetLink)\n");
return -1;
}
readCallBack=dummyRead;
writeCallBack=myWrite;
pipe(filedes);
ai.port = atol(argv[1]);
LOG2(ThisModule "Main serv: %d\n", ai.port);
LOG2(ThisModule "Main serv: Accepter pipe fd: %d\n", ai.fd);
ai.fd = filedes[1];
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
res=pthread_create(&ac, &attr, accepter, &ai /*&filedes[1] */ );
do {
FD_ZERO(&FDS);
FD_SET(filedes[0], &FDS);
LOG2(ThisModule "Main serv: about to select on %d\n",
filedes[0]);
FLUSH;
if (select(filedes[0] + 1, &FDS, NULL, &FDS, NULL) > 0) {
LOG1(ThisModule "Main serv: about to read\n");
res = read(filedes[0], &pi.fd, sizeof(pi.fd));
ps=0;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
res=pthread_create(&ps, &attr, portServer, &pi);
if(res) {
LOG2(ThisModule
"Main serv: create error:%s\n", strerror(res));
close(newfd);
usleep(100000);
}
}
}
while (1);
return 0;
}
/*
Changes:
14/07/2003 give a hint about usage
02/01/2005 fixed argc, it's 2 if there is 1 argument.
03/06/2005 removed byteswap.h, it is not needed.
*/