#include "proto.h" #include #include #include /************************************************************************** FlexRay 1.0 Protocol (written by Christian Schraml @ Lauterbach GmbH) 1.0: - 11 and 24bits CRC - Fibex XML file to paste the appropiate strings - Paste the extracted XML Datas into a *.flx file - .flx file improves speed and flexibility - Chart display function *************************************************************************/ ///////////////////////////////////////////////// // Definition of the types // ///////////////////////////////////////////////// typedef unsigned char Boolean; //! Definition for the variable in which the entered baudrate is stored typedef struct { int baudrate; int chanFlx; char msg[256][80]; unsigned int repError; unsigned int id[256]; unsigned int off[256]; unsigned int rep[256]; unsigned int lineCount; } flexRayParameters; //! Definition of the variables for the level 1 output typedef struct { protoTime timestamp; unsigned char fiveBits; unsigned int id; unsigned char payLen; unsigned char headCrc; unsigned char crcErr; unsigned char cyCount; unsigned char dataByte[254]; //!< Limit this value if you want to optimize the code and don't need the fullrange unsigned long crc; unsigned int error; unsigned int cycle; } stageOneEntry; //! Definition of the variables for the level 2 output typedef struct { protoTime timestamp; unsigned int id; unsigned char payLen; unsigned char cyCount; unsigned char crcErr; unsigned int error; unsigned int cycle; unsigned char dataByte[8]; //Only 8 bytes stored as a kind of preview } stageTwoEntry; ///////////////////////////////////////////////// //! Every function except PROTO_Init is defined static because they are only used intern ///////////////////////////////////////////////// ///////////////////////////////////////////////// //! Stage one: analyzing raw trace date ///////////////////////////////////////////////// static protoSizeT PROTOAPI processStageOne(protoContext context, protoPtr arrayOut, protoSizeT arrayOutSize, protoPtr arrayIn, protoSizeT arrayInSize, protoPtr localdata) { ///////////////////////////////////////////////// //! Definition of the variables ///////////////////////////////////////////////// #define BP chan[0] #define BM chan[1] long pos = 0, //!baudrate; //!< Recieves the entered baudrate protoWord64 construct=0, crc24, init24; //!< Values used to enable CRC(24bit) calculation float flexClock = frequency /1000000.0 * 128.0; //!< Calculates the difference between timestamp and bit duration protoSizeT index=0; // Counts the amount of stored files unsigned int byte=0, // Counts the amount of read bytes in one transmission chan[2], prevBit, //!< Value of the stored bit actBit, //!< Value of the signal i, input=0, //!< Both are important for the data output amBy, amCrc=0, //!< Value used to enable CRC(both) calculation crc11,init11, //!< Values used to enable CRC(11bit) calculation amBit=0, storeId=0, //!< Storage of the frame ID storeHead=0, //!< Storage of the head crc storePayLen=0, //!< Storage of the payload length err, //!< Variable to mark an error oldCyc = 0, newCyc, //!< Used to detect a new cycle channel = ((flexRayParameters *) localdata)->chanFlx; //!< Recieves the entered channel (A or B) unsigned char storeFive=0, //!< Storage of the first five bits storePay=0, //!< Storage of the detected payload value (has to be multiplicated by 2) storeCyc=0, //!< Storage of the cycle count storage=0, //!< Storage of ONE payload byte amount, // Counter to discover the amount of bits crcErr=0; //!< Need for displaying if the crc is true Boolean primStart = 0, // Boolean to mark a possible start sequence tss = 0, // Boolean to mark a transmission start sequence bss = 0; // Boolean to mark a byte start sequence protoTime actTime, // Timestamp of raw trace data record prevTime, // Timestamp to enable calculation if an edge is a only a spike or a real bit checkTime, // Timestamp to reduce the risk of wrong interpreting a spike byteTime=0, byteEnd; // Timestamp for the display function stageOneEntry *stageOneArray; // Pointer to array which will contain the output records stageOneArray = (stageOneEntry *) arrayOut; // type cast to the used output record type if (((flexRayParameters *) localdata)->repError) { stageOneArray[index].id = 3333; stageOneArray[index].timestamp = byteTime; index++; index++; goto interrupt; } ///////////////////////////////////////////////// While Start Sequence ///////////////////////////////////////////////// while (pos < arrayInSize) { ///////////////////////////////////////////////// //! Possiblity to stop the file ///////////////////////////////////////////////// if ((pos & 0xfff) == 0) //!< give GUI a chance to stop us if (PROTO_Cancel(context)) return PROTO_PROCESS_CANCEL; ///////////////////////////////////////////////// //! Searching the beginning of a new transmission ///////////////////////////////////////////////// while (tss == 0) { //! The search algorithm PROTO_ReadTrace(context, pos, &actTime, chan); actBit = BP; prevTime = actTime, prevBit = actBit; while (1) //! While loop is required to detect only true changes { pos++, i=1; if (pos >= arrayInSize) goto interrupt; PROTO_ReadTrace(context, pos, &actTime, chan); actBit = BP; if ((prevBit != actBit) && (BP != BM)) { PROTO_ReadTrace(context, (pos+1), &checkTime, chan); amount = (float)(checkTime - actTime)/flexClock + 0.4; //!< Calculates the amount of read bits if (amount >=1) break; } } amount = (float)(actTime - prevTime)/flexClock + 0.4; //!< Calculates the amount of read bits if (primStart == 1) { if ((amount == 2) && (prevBit == 1)) //!< Exactly 2 bit_0 were transfered tss=1, bss = 1, primStart = 0; else primStart = 0; } if ((amount >= 11) && (prevBit == 0)) //!< A minimum of 11 bit_0 were transfered (every Transmission is introduced by this primStart = 1, byteTime=actTime; } ///////////////////////////////////////////////// //! Searching for a new byte transmission start ///////////////////////////////////////////////// search: if (tss == 1) //! TSS has to be true { amBy=0, amBit=0, storage=0, bss=1; prevTime = actTime, prevBit = actBit; while (1) //! While loop is required to detect only true changes { pos++, i=1; if (pos >= arrayInSize) goto interrupt; PROTO_ReadTrace(context, pos, &actTime, chan); actBit = BP; if ((prevBit != actBit) && (BP != BM)) { PROTO_ReadTrace(context, (pos+1), &checkTime, chan); amount = (float)(checkTime - actTime)/flexClock + 0.4; //!< Calculates the amount of read bits if (amount >=1) break; } } amount = (float)(actTime - prevTime)/flexClock + 0.4; //!< Calculates the amount of read bits if ((amount == 1) && (prevBit == 0)) { byte++; prevTime = actTime, prevBit = actBit; while (1) //! While loop is required to detect only true changes { pos++, i=1; if (pos >= arrayInSize) goto interrupt; PROTO_ReadTrace(context, pos, &actTime, chan); actBit = BP; if ((prevBit != actBit) && (BP != BM)) { PROTO_ReadTrace(context, (pos+1), &checkTime, chan); amount = (float)(checkTime - actTime)/flexClock + 0.4; //!< Calculates the amount of read bits if (amount >=1) break; } } amount = (float)(actTime - prevTime)/flexClock + 0.4; //!< Calculates the amount of read bits while (amount>8) amount--; } //! Important: without this line the protcoll would have real problems at the end of the transmission! else if ((amount == 1) && (prevBit == 1)) goto search; else amount-=1, byte++; while (amount>8) //!Using this command, amount can't be bigger than 8 amount--; ///////////////////////////////////////////////// //! Interpreting the recieved bits ///////////////////////////////////////////////// while (bss==1) { //!Exit if the Message ends if (byte==(storePayLen+9)) break; ///////////////////////////////////////////////// //! First: the header ///////////////////////////////////////////////// //! First Byte decoding if ((pos >= 285860) && (byte <=1)) storeId=0; if (byte == 1) { while ((amBit<5) && (amount>0)) storeFive =(storeFive<<1)|(prevBit&0x1), amBit++, amount--, amBy=amBit; if (amBit==5) for (i=0; i < amount; i++) storeId =(storeId<<1)|(prevBit&0x1); } //! Second Byte decoding else if (byte==2) for (i=0; i < amount; i++) storeId =(storeId<<1)|(prevBit&0x1); if ((storeId == 0) && (byte >=3)) storeId = 0; //! Third Byte decoding else if (byte ==3) { while ((amBit<7) && (amount>0)) storePay =(storePay<<1)|(prevBit&0x1), amBit++, amount--, amBy=amBit; if (amBit==7) { storePayLen=2*storePay, storeHead =(storeHead<<1)|(prevBit&0x1); } } //! Fourth Byte decoding else if (byte==4) for (i=0; i < amount; i++) storeHead =(storeHead<<1)|(prevBit&0x1); //! Fifth Byte decoding else if (byte ==5) { while ((amBit<2) && (amount>0)) storeHead =(storeHead<<1)|(prevBit&0x1), amBit++, amount--, amBy=amBit; if (amBit==2) for (i=0; i < amount; i++) storeCyc =(storeCyc<<1)|(prevBit&0x1); } //! Detection of a new cycle else if ((byte==6)&&(storeCyc != oldCyc)) oldCyc = storeCyc, newCyc=1; ///////////////////////////////////////////////// //! Second: the payload ///////////////////////////////////////////////// if ((byte>=6)&&(input=storePayLen+6)&&(byte>5)) for (i=0; i < amount; i++) storeCrc = (storeCrc<<1)|(prevBit&0x1); ///////////////////////////////////////////////// //! Fourth: Storing the payload ///////////////////////////////////////////////// amBy +=amount; if ((amBy==8)&&(byte>=6)) stageOneArray[index].dataByte[input]=storage, input++; ///////////////////////////////////////////////// //! Fifth: Aborting the process ///////////////////////////////////////////////// if (amBy >9) bss=0, tss=0, err=1; else if (amBy==8) goto search; ///////////////////////////////////////////////// //! Sixth: Searching new bits ///////////////////////////////////////////////// prevTime = actTime, prevBit = actBit; while (1) //! While loop is required to detect only true changes { pos++, i=1; if (pos >= arrayInSize) goto interrupt; PROTO_ReadTrace(context, pos, &actTime, chan); actBit = BP; if ((prevBit != actBit) && (BP != BM)) { PROTO_ReadTrace(context, (pos+1), &checkTime, chan); amount = (float)(checkTime - actTime)/flexClock + 0.4; //!< Calculates the amount of read bits if (amount >=1) break; } } amount = (float)(actTime - prevTime)/flexClock + 0.4; //!< Calculates the amount of read bits if (amBy+amount>8) amount--; } /* bss==1 loop*/ ///////////////////////////////////////////////// //! Header CRC caluclation ///////////////////////////////////////////////// crc11 = 0xb85; init11=0x68, //!< Initialization vector 0x1A shifted <<2 crc11 <<=19; construct =0; construct = (storeFive & 0x03); //!< Only the last two bits are able to become bit_1 construct <<=11; construct += storeId; construct ^= init11; construct <<=7; construct += storePay; construct <<=11; construct +=storeHead; /*! The construct binary look: * 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 == init vector is used with the original using ^(XOR) * x x x x x|x x x x x x x x x x x|x x x x x x x|x x x x x x x x x x x * Five Bits Frame ID PayloadLength Header Crc * */ for (i=0; i<20;i++) { construct= construct & 0x40000000 ? (construct ^ crc11)<<1 : (construct << 1); amCrc++; if (construct==0) crcErr=1; } input =0; crc24 = 0x15d6dcb; crc24 <<= 25; init24 = channel ? 0xabcdef : 0xfedcba; //!< initialization vector is defined for the entered Channel! init24 <<=10; construct = storeFive; construct <<=11; construct += storeId; construct <<=7; construct += storePay; construct <<=11; construct +=storeHead; construct ^= init24; construct <<=6; construct +=storeCyc; amCrc=0; /*! The construct binary look: * 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 0 1 0 1 1 1 0 1 0 == init vector (Channel A) is used with the original using ^(XOR) * x x x x x|x x x x x x x x x x x|x x x x x x x|x x x x x x x x x x x|x x x x x x * Five Bits Frame ID PayloadLength Header Crc Cycle count * */ for (i=0; i<((storePayLen+8)*8);i++) { construct= construct & 0x2000000000000ull ? (construct ^ crc24)<<1 : (construct << 1); amCrc++; if (amCrc==(storePayLen+3)*8) construct +=storeCrc, amCrc++; if((input < storePayLen)&&(amCrc%8==0)) construct += stageOneArray[index].dataByte[input], input++; if (construct ==0) crcErr= crcErr | 0x2; } ///////////////////////////////////////////////// //! Storing the datasequences ///////////////////////////////////////////////// byteEnd = prevTime; //!< Calculation to mark the end of the transmission stageOneArray[index].timestamp = byteTime; stageOneArray[index].fiveBits = storeFive; stageOneArray[index].id = storeId; stageOneArray[index].payLen = storePayLen; stageOneArray[index].headCrc = storeHead; stageOneArray[index].crcErr = crcErr; stageOneArray[index].cyCount = storeCyc; stageOneArray[index].crc = storeCrc; stageOneArray[index].error = err; stageOneArray[index].cycle = newCyc; if (storeId == 0) storeId = 1; index++; if (index>=arrayOutSize) //! If there is no free space to store more return PROTO_PROCESS_OUTOFMEMORY; //! records, the processing is aborted //! Used to establish a proper chart visualisation and the beginning of idle-level stageOneArray[index].timestamp =byteEnd; //!< Beginning of the idle-mode stageOneArray[index].id =2048; //!< This Id can't be used by the protocoll, that's why it's used for the idle script index++; if (index>=arrayOutSize) //! If there is no free space to store more return PROTO_PROCESS_OUTOFMEMORY; //! records, the processing is aborted //! Reseting all used values, to store the next transmission storeFive=0, storeId=0, storePay=0, storeHead=0, storeCyc=0, storeCrc=0, storage=0, newCyc=0; tss=0, bss=0, byte=0, input=0, amCrc=0, crcErr=0, err=0; } /* tss==1 */ ///////////////////////////////////////////////// While End Sequence ///////////////////////////////////////////////// } // pos < arrayInSize interrupt: return index; //!< Important for the programm to use this command, in case of reaching the end of the traced material } // Process function ///////////////////////////////////////////////// //! Copy the needed datas for displayStageTwo ///////////////////////////////////////////////// static protoSizeT PROTOAPI processStageTwo(protoContext context, protoPtr arrayOut, protoSizeT arrayOutSize, protoPtr arrayIn, protoSizeT arrayInSize, protoPtr localdata) { protoSizeT i=0,j; int k=0; stageOneEntry *stageOneArray; //!< Pointer to array which will contain the input records stageTwoEntry *stageTwoArray; //!< Pointer to array which will contain the output records stageOneArray = (stageOneEntry *) arrayIn; stageTwoArray = (stageTwoEntry *) arrayOut; //! Copying the array data because the dll needs for every displayCallback function one input array while (i<(arrayInSize/2)) { stageTwoArray[i].timestamp = stageOneArray[k].timestamp; stageTwoArray[i].id = stageOneArray[k].id; stageTwoArray[i].payLen = stageOneArray[k].payLen; stageTwoArray[i].cyCount = stageOneArray[k].cyCount; stageTwoArray[i].error = stageOneArray[k].error; stageTwoArray[i].crcErr = stageOneArray[k].crcErr; stageTwoArray[i].cycle =stageOneArray[k].cycle; for (j=0; j<8; j++){ stageTwoArray[i].dataByte[j] = stageOneArray[k].dataByte[j]; } i++,k+=2; //!< Used to eliminate the "idle" timestamps which should not be displayed on level 2 if (i>=arrayOutSize){ //! If there is no free space to store more return PROTO_PROCESS_OUTOFMEMORY; //! records, the processing is aborted } } return i; //!< Important for displayStageTwo } ///////////////////////////////////////////////// //! Display data from processStageOne ///////////////////////////////////////////////// static void displayStageOne(protoContext context, protoPtr pdata, protoPtr localdata) { unsigned int i=0,r=0,k; stageOneEntry *entry; //!< Loading the array entry=(stageOneEntry *)pdata; //! Define for each Frame the corresponding String PROTO_Control(context, PROTO_ATTRIBUTE_LEVEL2); //! 2048 can't be used by the protocoll! - Used to mark up the Idle-Period if ((entry->id==2048)||(entry->id==3333)) goto idle; //! 0 can't be used by the protocoll! - Sign that that a protocoll error was detected else if (entry->id==0) { PROTO_Puts(context, " "); PROTO_Control(context, PROTO_ATTRIBUTE_ERROR); PROTO_Puts(context, " Completly Failed"); goto idle; } //! If there are no values... i=0; //! Loop to compare the datas from the textfile(info.flx) to the id! while ((entry->cyCount % ((flexRayParameters *) localdata)->rep[i]!=((flexRayParameters *) localdata)->off[i]) || (entry->id!=((flexRayParameters *) localdata)->id[i])) { i++; //! Important! Without using this phrase not entered id generates an error! if (i==((flexRayParameters *) localdata)->lineCount) break; } //! Displaying of the String and Maximum length of 25 chars! if (i<((flexRayParameters *) localdata)->lineCount) { for (k=0; k<25;k++) { if (((flexRayParameters *) localdata)->msg[i][k]&& ((flexRayParameters *) localdata)->msg[i][k]!=10) PROTO_Printf(context, "%1c", ((flexRayParameters *) localdata)->msg[i][k]); else PROTO_Puts(context, " "); } } else PROTO_Puts(context, " "); //! Presenting the payload, starting after the preview sequence PROTO_Control(context, PROTO_ATTRIBUTE_LEVEL1); PROTO_Puts(context, " "); for (i=8; ipayLen;i++) { if (r==8) { r=0; PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Puts(context, " "); } r++; PROTO_Puts(context, " "); PROTO_Printf(context, "%02x", entry->dataByte[i]); } //! Presenting additional informations PROTO_Control(context, PROTO_ATTRIBUTE_LEVEL2); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Puts(context, " "); PROTO_Printf(context, "fiveBits: 0x%02x", entry->fiveBits); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Puts(context, " "); //! Displays the result of the Header CRC check switch ((entry->crcErr)&0x1) { case 1: PROTO_Control(context, PROTO_ATTRIBUTE_LEVEL2); PROTO_Printf(context, "headCrc: 0x%03x", entry->headCrc); break; case 0: PROTO_Control(context, PROTO_ATTRIBUTE_ERROR); PROTO_Printf(context, "headCrc: 0x%03x", entry->headCrc); PROTO_Puts(context, " FAILED"); break; default: PROTO_Puts(context, "Header crc calculation error"); } PROTO_Control(context, PROTO_CONTROL_LINEFEED); //! Displays the result of the Trailer CRC check PROTO_Puts(context, " "); switch (entry->crcErr & 0x2) { case 0x2: PROTO_Control(context, PROTO_ATTRIBUTE_LEVEL2); PROTO_Printf(context, "crc: 0x%06x", entry->crc); break; case 0: PROTO_Control(context, PROTO_ATTRIBUTE_ERROR); PROTO_Printf(context, "crc: 0x%06x", entry->crc); PROTO_Puts(context, " FAILED"); break; default: PROTO_Puts(context, "Trailer crc calculation error"); } idle:; //!< Insert attributes to mark the end of transmission explicit } ///////////////////////////////////////////////// //! Display data from processStageTwo ///////////////////////////////////////////////// static void displayStageTwo(protoContext context, protoPtr pdata, protoPtr localdata) { int i,k,cut; stageTwoEntry *entry; int errLine = ((flexRayParameters *) localdata)->repError; entry=(stageTwoEntry *)pdata; /* Cast to correct type */ //! output if the t32.flx file has a invalid repitition (zero value) if (entry->id==3333) { PROTO_Control(context, PROTO_ATTRIBUTE_ERROR); PROTO_Puts(context, "ERROR was found in the info.flx file."); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Printf(context, "Invalid in line #%1d", errLine); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Printf(context, "Line %1d:", errLine); PROTO_Control(context, PROTO_ATTRIBUTE_LEVEL2); PROTO_Printf(context, " %.4d", ((flexRayParameters *) localdata)->id[errLine-1]); PROTO_Printf(context, " %.4d", ((flexRayParameters *) localdata)->off[errLine-1]); PROTO_Printf(context, " %.4d ", ((flexRayParameters *) localdata)->rep[errLine-1]); for (k=0; k<50;k++) PROTO_Printf(context, "%1c", ((flexRayParameters *) localdata)->msg[errLine-1][k]); } else { //! defines the length of the preview payload (max. 8) if (entry->payLen>8) cut=8; else cut=entry->payLen; //! Creates a line if a new cycle starts PROTO_Control(context, PROTO_ATTRIBUTE_LEVEL2); if (entry->cycle ==1) { PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Control(context, PROTO_CONTROL_LINETILLEND); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Control(context, PROTO_CONTROL_LINEFEED); } //! The most important informations which are shown on level 2 if ((entry->crcErr&0x3) !=0x3) PROTO_Control(context, PROTO_ATTRIBUTE_ERROR); PROTO_Printf(context, "ID: %04d", entry->id); PROTO_Puts(context, " "); PROTO_Printf(context, "LEN: %03d", entry->payLen); PROTO_Puts(context, " "); PROTO_Printf(context, "CYC #%02d", entry->cyCount); PROTO_Puts(context, " "); PROTO_Control(context, PROTO_ATTRIBUTE_LEVEL1); for (i=0; idataByte[i]); } //! Eyecatcher to mark an error if (entry->error ==1) { PROTO_Control(context, PROTO_ATTRIBUTE_ERROR); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Control(context, PROTO_CONTROL_LINETILLEND); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Control(context, PROTO_CONTROL_LINETILLEND); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Puts(context, "ERROR (Protocol structure is damaged)"); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Control(context, PROTO_CONTROL_LINETILLEND); PROTO_Control(context, PROTO_CONTROL_LINEFEED); PROTO_Control(context, PROTO_CONTROL_LINETILLEND); PROTO_Control(context, PROTO_CONTROL_LINEFEED); } } } ///////////////////////////////////////////////// //! Function to use the "Chart" command ///////////////////////////////////////////////// const char * PROTO_Chart(protoContext context, protoPtr pdata, protoPtr localdata) { unsigned int i=0; int idDiff, newId; stageOneEntry *entry =(stageOneEntry *)pdata; int id = entry->id; //! Actually the displayed strings has to be entered by the user. Fibex support not yet implemented static const char *chart[]={"Error","Idle", "BLUB", "WHUHUHU"}; //! 0 marks an error of the transmission if (id==0) return chart[0]; //! 2048 marks that the bus is in idle mode else if (id==2048) return chart[1]; i=0; //! Searchs for the suitable string while ((entry->cyCount % ((flexRayParameters *) localdata)->rep[i]!=((flexRayParameters *) localdata)->off[i]) || (id!=((flexRayParameters *) localdata)->id[i])) { i++; //! If the search isn't successful, "not known" will be pasted if (i==((flexRayParameters *) localdata)->lineCount) { ((flexRayParameters *) localdata)->id[i] = entry->id; ((flexRayParameters *) localdata)->rep[i]= 1; ((flexRayParameters *) localdata)->off[i]= 0; ((flexRayParameters *) localdata)->msg[i][0]='I'; ((flexRayParameters *) localdata)->msg[i][1]='D'; ((flexRayParameters *) localdata)->msg[i][2]='_'; idDiff=entry->id/1000; ((flexRayParameters *) localdata)->msg[i][3]=idDiff+48; newId = entry->id - (idDiff*1000); idDiff= newId/100; ((flexRayParameters *) localdata)->msg[i][4]=idDiff+48; newId = entry->id - (idDiff*100); idDiff= newId/10; ((flexRayParameters *) localdata)->msg[i][5]=idDiff+48; idDiff= newId%10; ((flexRayParameters *) localdata)->msg[i][6]=idDiff+48; ((flexRayParameters *) localdata)->lineCount++; } } return &((flexRayParameters *) localdata)->msg[i]; } ///////////////////////////////////////////////// //! PROTO_Init ///////////////////////////////////////////////// int PROTOAPI PROTO_Init(protoContext context, int command) { ///////////////////////////////////////////////// //! Definition Parameters ///////////////////////////////////////////////// int baudrate; int chan; int i,h,k=0,ramCount=0, pos, endOfValidData=1; ///////////////////////////////////////////////// // Fibex analyzer ///////////////////////////////////////////////// //! Analyzing file and storing important data into an array FILE *f; FILE *paste; unsigned char line[500]={0}; unsigned char pasteLine[300]={0}; unsigned char ram[5]; unsigned char flxGen[] = "-ID- -OFF -REP ---String--- \n"; unsigned char check[] = {" "}; unsigned char stringCheck[] = {" id[k]=(params ->id[k]*10)+(line[i]-48); line[i]=0; } //! Storing the offset for (i=5; i<9; i++) { params ->off[k]=(params ->off[k]*10)+(line[i]-48); line[i]=0; } //! Storing the repetition for (i=10; i<14; i++) { params ->rep[k]=(params ->rep[k]*10)+(line[i]-48); line[i]=0; } //! Error when repetition has an invalid value! if (params ->rep[k] ==0) params ->repError = k+1; //! Storing the string (max 80chars) for (i=15; i<95; i++) { //! This passage is need to enable ä, ö, ü, ß because the XML is UTF-8 if (line[i] == 195) { i++; switch(line[i]) { case 164: params ->msg[k][i-16]=97; params ->msg[k][i-15]=101; break; case 132: params ->msg[k][i-16]=65; params ->msg[k][i-15]=101; break; case 182: params ->msg[k][i-16]=111; params ->msg[k][i-15]=101; break; case 150: params ->msg[k][i-16]=79; params ->msg[k][i-15]=101; break; case 188: params ->msg[k][i-16]=117; params ->msg[k][i-15]=101; break; case 156: params ->msg[k][i-16]=85; params ->msg[k][i-15]=101; break; case 159: params ->msg[k][i-16]=115; params ->msg[k][i-15]=115; break; } } else if (line[i] == 10) //! destroy the /0 at the end of a row params ->msg[k][i-15]=0; else params ->msg[k][i-15]=line[i]; line[i]=0; } //! Incrementing the counting values k++; params->lineCount++; } fclose(f); //! Done } else if ((f=fopen("t32.xml","r"))!=NULL) { paste=fopen("t32.flx","w"); fputs(flxGen, paste); newLine: while (fgets(line,500,f)&&endOfValidData) { i=0; //! If the program finds you can abort because all Frame IDs were stored! while (line[i] == endCheck[i]) { i++; if (i == 14) endOfValidData=0; } if (line[0] == 9) { for (i=1; i<15; i++) if (line[i]!=check[i-1]) goto newLine; } else goto newLine; pos=15; while (line[pos]!= 46) pos++; //! Storing the ID, Off and Rep //! ID ramCount=0, pos++; while(line[pos] != 46) { params ->id[k] = (params ->id[k]*10)+(line[pos]-48); ram[ramCount] = line[pos]; ramCount++, pos++; } for(h=0; h<4-ramCount; h++) pasteLine[h] = 48; for(h=4-ramCount; h<4; h++) pasteLine[h] = ram[h+ramCount-4]; pasteLine[4]=32; ramCount=0, pos++; //! OFFSET while(line[pos] != 46) { params ->off[k] = (params ->off[k]*10)+(line[pos]-48); ram[ramCount] = line[pos]; ramCount++, pos++; } for(h=0; h<4-ramCount; h++) pasteLine[h+5] = 48; for(h=4-ramCount; h<4; h++) pasteLine[h+5] = ram[h+ramCount-4]; pasteLine[9]=32; ramCount=0, pos++; // REPETITION while(line[pos] != 95) { params ->rep[k] = (params ->rep[k]*10)+(line[pos]-48); ram[ramCount] = line[pos]; ramCount++, pos++; } for(h=0; h<4-ramCount; h++) pasteLine[h+10]=48; for(h=4-ramCount; h<4; h++) pasteLine[h+10]=ram[h+ramCount-4]; pasteLine[14]=32; //! Storing the String stringLine: fgets(line,500,f); //! Checking if it's the right section! if (line[0] == 9) { for (i=1; i<27; i++) if (line[i]!=stringCheck[i-1]) goto stringLine; } else goto stringLine; pos=27; while (line[pos]!=62) pos++; //! THE STRING pos++; for (i=pos; imsg[k][i-16]=97; params ->msg[k][i-15]=101; break; case 132: params ->msg[k][i-16]=65; params ->msg[k][i-15]=101; break; case 182: params ->msg[k][i-16]=111; params ->msg[k][i-15]=101; break; case 150: params ->msg[k][i-16]=79; params ->msg[k][i-15]=101; break; case 188: params ->msg[k][i-16]=117; params ->msg[k][i-15]=101; break; case 156: params ->msg[k][i-16]=85; params ->msg[k][i-15]=101; break; case 159: params ->msg[k][i-16]=115; params ->msg[k][i-15]=115; break; } pasteLine[i-pos+14] = params ->msg[k][i-16]; pasteLine[i-pos+15] = params ->msg[k][i-15]; } else if (line[i] == 10) //! destroying the /0 at the end of a row { params ->msg[k][i-pos] = 0; pasteLine[i-pos+15] = 10; } else { params ->msg[k][i-pos] = line[i]; pasteLine[i-pos+15] = line[i]; } } //! Pasting the char array into the *.flx file fputs(pasteLine, paste); //! Reseting the array and increment the counting values for(h=0; h<300; h++) pasteLine[h]=0; k++, params->lineCount++;; } //! Closing the files fclose(paste); fclose(f); } //! If there's no t32.xml or t32.flx we enter these default values to keep the engine working! else { params ->id[0] =0; params ->off[0]=1; params ->rep[0]=1; params->lineCount++; } ///////////////////////////////////////////////// // End Of Fibex analyzer ///////////////////////////////////////////////// //! End of Fibex-File-Interpretator PROTO_Parse(context, (protoPtr) 0, "", PROTO_PARSE_CHANNEL); /* Definition of the Protocol Channel */ PROTO_Parse(context, (protoPtr) 0, "", PROTO_PARSE_CHANNEL); /* Definition of the Protocol Channel */ PROTO_Parse(context, (protoPtr) &baudrate, "", PROTO_PARSE_FREQUENCY); params ->baudrate = baudrate; /* Definition of the Frequency */ PROTO_Parse(context, (protoPtr)(&chan), "A,B",PROTO_PARSE_SELECTION); params ->chanFlx = chan; ///////////////////////////////////////////////// //! Register callback functions ///////////////////////////////////////////////// PROTO_RegisterProcessCallback(context, processStageOne, (protoPtr) params, sizeof(stageOneEntry), 1); PROTO_RegisterProcessCallback(context, processStageTwo, (protoPtr) params, sizeof(stageTwoEntry), 2); PROTO_RegisterDisplayCallback(context, displayStageOne, (protoPtr) params, 1); PROTO_RegisterDisplayCallback(context, displayStageTwo, (protoPtr) params, 2); PROTO_RegisterChartCallback(context, PROTO_Chart, (protoPtr) params, 1); PROTO_SetDefaultLevel(context, 2); return PROTO_OK; }