diff -r 000000000000 -r 8e480a14352b messagingfw/msgtest/targetautomation/Trgtest/trgtest.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/msgtest/targetautomation/Trgtest/trgtest.cpp Mon Jan 18 20:36:02 2010 +0200 @@ -0,0 +1,649 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32utils\trgtest\trgtesth.cpp +// +// + +#include +#include +#include + +const TUint8 SOH=0x01; +const TUint8 STX=0x02; +const TUint8 EOT=0x04; +const TUint8 ACK=0x06; +const TUint8 NAK=0x15; +const TUint8 CAN=0x18; +const TUint8 SUB=0x1A; +const TUint8 BIGC=0x43; +const TUint8 BIGG=0x47; + +#define READ_BUF_SIZE 32768 +#define WRITE_BUF_SIZE 32768 +#define MAX_LINE 32768 +#define PACKET_SIZE 1024 + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define OFFSET(p,off) ((void*)((char*)p+off)) + +#define RESET_COMM() PurgeComm(Comm, PURGE_RXCLEAR|PURGE_TXCLEAR) + + +FILE* LogFile; +HANDLE Comm; + +char ImgFileName[256]; +TInt ImgFileSize; +char LineBuf[MAX_LINE+1]; +void* ImgFileChunkBase; + +#define TT_ASSERT(x) __ASSERT_ALWAYS(x, __Panic(__LINE__)) + +void __Panic(TInt aLine) + { + fprintf(stderr, "Assertion failed at line %d\n", aLine); + exit(999); + } + +void WriteLog(const void* aBuf, TInt aLength) + { + fwrite(aBuf, 1, aLength, LogFile); + } + +void WriteLogS(const char* aString) + { + WriteLog( aString, strlen(aString) ); + } + +/* +void TraceLog(const char* aFmt, ...) + { + char buf[512]; + va_list list; + va_start(list, aFmt); + sprintf(buf, "TRGTEST: "); +// timestamp + vsprintf(buf, aFmt, list); + strcat(buf, "\n"); + WriteLogS(buf); + } +*/ + +/* +YModem packet structure: +Byte 0 = STX +Byte 1 = sequence number (first user data packet is 1) +Byte 2 = complement of sequence number +Bytes 3-1026 = data (1K per packet) +Bytes 1027, 1028 = 16-bit CRC (big-endian) + +A herald packet is sent first, with sequence number 0 +The data field consists of the null-terminated file name +followed by the null-terminated file size in ASCII decimal +digits. +*/ +struct SPacket + { + TUint8 iPTI; + TUint8 iSeq; + TUint8 iSeqBar; + TUint8 iData[PACKET_SIZE]; + TUint8 iCRC1; + TUint8 iCRC0; + }; + +static const TUint16 crcTab[256] = + { + 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,0x8108,0x9129,0xa14a, + 0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294, + 0x72f7,0x62d6,0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,0x2462, + 0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,0xa56a,0xb54b,0x8528,0x9509, + 0xe5ee,0xf5cf,0xc5ac,0xd58d,0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695, + 0x46b4,0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,0x48c4,0x58e5, + 0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948, + 0x9969,0xa90a,0xb92b,0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, + 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,0x6ca6,0x7c87,0x4ce4, + 0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b, + 0x8d68,0x9d49,0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,0xff9f, + 0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,0x9188,0x81a9,0xb1ca,0xa1eb, + 0xd10c,0xc12d,0xf14e,0xe16f,0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046, + 0x6067,0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,0x02b1,0x1290, + 0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e, + 0xe54f,0xd52c,0xc50d,0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, + 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,0x26d3,0x36f2,0x0691, + 0x16b0,0x6657,0x7676,0x4615,0x5634,0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9, + 0xb98a,0xa9ab,0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,0xcb7d, + 0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,0x4a75,0x5a54,0x6a37,0x7a16, + 0x0af1,0x1ad0,0x2ab3,0x3a92,0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8, + 0x8dc9,0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,0xef1f,0xff3e, + 0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,0x6e17,0x7e36,0x4e55,0x5e74,0x2e93, + 0x3eb2,0x0ed1,0x1ef0 + }; + +void UpdateCrc(const void* aPtr, TInt aLength, TUint16& aCrc) +// +// Perform a CCITT CRC checksum. +// + { + + register const TUint8* pB = (const TUint8*)aPtr; + register TUint16 crc=aCrc; + while (aLength--) + crc=TUint16((crc<<8)^crcTab[(crc>>8)^*pB++]); + aCrc=crc; + } + +void ClearCommError() + { + DWORD err; + COMSTAT s; + TT_ASSERT(ClearCommError(Comm,&err,&s)); + } + +void SetupCommPort(TInt aPort) + { + char buf[10]; + DCB dcb; + + sprintf(buf, "COM%d", aPort); + Comm = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (Comm == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "Can't open COM%d : Error %d\n", aPort, GetLastError()); + exit(999); + } + dcb.DCBlength = sizeof(dcb); + TT_ASSERT(GetCommState(Comm, &dcb)); + TT_ASSERT(SetCommMask(Comm, EV_ERR|EV_RXCHAR)); + TT_ASSERT(SetupComm(Comm, READ_BUF_SIZE, WRITE_BUF_SIZE)); + ClearCommError(); + + dcb.fAbortOnError = TRUE; + dcb.BaudRate=115200; + dcb.Parity=NOPARITY; + dcb.fParity = FALSE; + dcb.fErrorChar = FALSE; + dcb.ByteSize=8; + dcb.StopBits=ONESTOPBIT; + dcb.fInX = FALSE; + dcb.fOutX = FALSE; + dcb.XonChar = 0; + dcb.XoffChar = 0; + dcb.ErrorChar = 0; + dcb.fOutxDsrFlow = FALSE; + dcb.fOutxCtsFlow = FALSE; + dcb.fDsrSensitivity = FALSE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + TT_ASSERT(SetCommState(Comm, &dcb)); + EscapeCommFunction(Comm, SETDTR); + EscapeCommFunction(Comm, SETRTS); + } + +void SetupTimeout(TInt aInt, TInt aTot) + { + COMMTIMEOUTS ct; + GetCommTimeouts(Comm, &ct); + ct.ReadIntervalTimeout = aInt; //ms + ct.ReadTotalTimeoutMultiplier = 0; + ct.ReadTotalTimeoutConstant = aTot; // ms + ct.WriteTotalTimeoutConstant = 0; + ct.WriteTotalTimeoutMultiplier = 0; + SetCommTimeouts(Comm, &ct); + } + +TInt CommRead1(TInt aTimeout) + { + unsigned char c; + DWORD n=0; + BOOL ok; + + SetupTimeout(0,aTimeout); + ok = ReadFile(Comm, &c, 1, &n, NULL); + if (!ok) + ClearCommError(); + if (ok && n) + return c; + return KErrTimedOut; + } + +TInt CommRead(void* aBuf, TInt aMax, TInt aTimeout) + { + DWORD n=0; + BOOL ok; + + SetupTimeout(100, aTimeout); + ok = ReadFile(Comm, aBuf, aMax, &n, NULL); + if (!ok) + ClearCommError(); + if (n==0) + return KErrTimedOut; + return n; + } + +void CommWrite(const void* aBuf, TInt aLen) + { + DWORD n = 0; + BOOL ok = WriteFile(Comm, aBuf, aLen, &n, NULL); + if (!ok) + ClearCommError(); + } + +void CommWriteC(TUint aChar) + { + unsigned char c = (unsigned char)aChar; + CommWrite(&c, 1); + } + +void CommWriteS(const char* aString) + { + CommWrite( aString, strlen(aString) ); + } + +TInt PreparePacket(SPacket& pkt, TInt aSeq) + { + TInt r = KErrNone; + TUint16 crc = 0; + + pkt.iPTI = STX; + pkt.iSeq = (TUint8)(aSeq>=0 ? aSeq : 0); + pkt.iSeqBar = (TUint8)~pkt.iSeq; + if (aSeq>0) + { + TInt l; + TInt fpos = (aSeq-1)*PACKET_SIZE; // file position of packet + if ( fpos >= ImgFileSize ) + return KErrEof; + l = MIN(PACKET_SIZE, ImgFileSize-fpos); + memcpy(pkt.iData, OFFSET(ImgFileChunkBase,fpos), l); + if (l=p && *q!='\\') {} + sprintf( (char*)pkt.iData, "%s%c%d", q+1, 0, ImgFileSize); + } + } + UpdateCrc(pkt.iData, PACKET_SIZE, crc); + pkt.iCRC1 = (TUint8)(crc>>8); + pkt.iCRC0 = (TUint8)crc; + return r; + } + +TInt SendPacket(TInt& aSeq, TBool aStream) + { + TInt c; + SPacket pkt; + TInt retries = 10; + TInt tmout = (aSeq>=0) ? 2000 : 500; + TInt r = PreparePacket(pkt, aSeq); + +// if ( (aSeq & 7) == 0 ) +// printf("SendPacket %d\n", aSeq); + if ( (aSeq & 0x0F) == 0 ) + printf("."); + + if (r!=KErrNone) + return r; + for(;;) + { + RESET_COMM(); + CommWrite(&pkt, sizeof(pkt)); + if (aStream) + break; + c = CommRead1(tmout); + if (c==KErrTimedOut && aSeq<0) + return KErrNone; + if (c>=0) + { + if (c==ACK) + break; + } + if (--retries==0) + return KErrTimedOut; + } + if (aSeq==0) + { + c = CommRead1(100); + if (c==KErrTimedOut) + { + ++aSeq; + return KErrNone; + } + if (aStream && c!=BIGG) + return KErrTimedOut; + else if (!aStream && c!=BIGC) + return KErrTimedOut; + } + ++aSeq; + return r; + } + +TInt SendImageFile() + { + TInt r = 0; + TInt b1; + TUint8 b2[256]; + TBool stream; + TInt seq = 0; + + printf("Sending image file: %s\n",ImgFileName); +// TraceLog("Sending image file: %s",ImgFileName); + + RESET_COMM(); + r = CommRead(b2, 256, 20000); + if (r<0) + return r; +// TraceLog(b2); + if (b2[r-1]!=BIGG && b2[r-1]!=BIGC) + return KErrTimedOut; + stream = (b2[r-1]==BIGG); + seq = 0; + r = KErrNone; + while (r==KErrNone) + { + r = SendPacket(seq, stream); + if (r!=KErrNone && r!=KErrEof) + printf(" %d\n", seq, r); +// TraceLog(_L8("=0) + LineBuf[r]=0, WriteLog(LineBuf, r); + } while (r>=0); + } + +void IssueCommandAndGetResponse(const char* aCmd) + { + CommWriteS(aCmd); + GetResponse(); + } + +int token_length(const char* s) + { + const char* p = s; + for (; *p && !isspace(*p); ++p) {} + return p - s; + } + +const char* skip_space(const char* s) + { + for (; *s && isspace(*s); ++s) {} + return s; + } + +void GetMonitorInfo() + { + BOOL ok = FALSE; + int l; + int type; + RESET_COMM(); + IssueCommandAndGetResponse("replacement\xd"); + IssueCommandAndGetResponse("f\xd"); + const char* p = LineBuf; + const char* q = LineBuf + strlen(LineBuf); + while (pq || memcmp(p, "Fault Category: ", 16)) + { + p += token_length(p); + continue; + } + p = skip_space(p+16); + l = token_length(p); + if (l!=4 || memcmp(p, "KERN", 4)) + { + p += l; + continue; + } + p = skip_space(p+4); + if (p+14>q || memcmp(p, "Fault Reason: ", 14)) + { + p += token_length(p); + continue; + } + p = skip_space(p+14); + if (p+8<=q && memcmp(p, "00000050", 8)==0) + { + ok = TRUE; + break; + } + p+=8; + continue; + } + if (ok) + return; + + IssueCommandAndGetResponse("i\xd"); + for (type=0; type<14; ++type) + { + char b[8]; + sprintf(b, "c%x\xd", type); + IssueCommandAndGetResponse(b); + } + } + +TInt ReceiveTestLog() + { + const TInt KMaxNoActivityTimeout = 60 * 60 * 1000; // 1 hour + const TInt KSerialPollInterval = 10; + TInt bytes = 0; + TInt error = KErrNone; + TInt noActivityTimeMilliSeconds = 0; + + printf("\nLogging to file started.\n"); + + for (;;) + { + bytes = CommRead(LineBuf, 100, KSerialPollInterval); + if (bytes > 0) + { + if (bytes >= 23 && memcmp(LineBuf+bytes-23, "!TERMINATE_MSG_LOGGING!", 23)==0) + { + printf("SUCCESS: Terminated from remote.\n"); + error = KErrNone; + break; + } + LineBuf[bytes]=0; + WriteLog(LineBuf, bytes); +// printf(LineBuf); + noActivityTimeMilliSeconds=0; + } + else if (bytes == KErrTimedOut) + { + noActivityTimeMilliSeconds += KSerialPollInterval; + if (noActivityTimeMilliSeconds >= KMaxNoActivityTimeout) + { + error = KErrTimedOut; + printf("FAILED: Timed out.\n"); + break; + } + } + else + { + error = bytes; + printf("FAILED: Error detected (%d).\n",error); + break; + } + } + + CommRead(LineBuf, 100, 100); + return error; + } + +/* +void ReceiveTestLog() + { + TInt r=0; + TInt r2; + TInt tmc=0; + + for (;;) + { + r = CommRead(LineBuf, 100, 100); + if (r>0) + { + LineBuf[r]=0; + WriteLog(LineBuf, r); + printf(LineBuf); + } +// printf("r=%d\n",r); + if (r>=23 && memcmp(LineBuf+r-23, "!TERMINATE_MSG_LOGGING!", 23)==0) + break; + check = TRUE; + } + + for(;;) + { + TBool check = FALSE; + r = CommRead(LineBuf, MAX_LINE, 2000); + if (r==KErrTimedOut) + { + ++tmc; + if (tmc<500) + continue; + check = TRUE; + } + else if (r>=0) + tmc=0; + if (r>=10 && memcmp(LineBuf+r-10, "Password: ", 10)==0) + check = TRUE; + if (r>0) + WriteLog(LineBuf, r); + if (check || r==KErrTimedOut) + { + // Send CR to see if it elicits monitor prompt + CommWriteC(0x0d); + r2 = CommRead(LineBuf, 12, 1000); + if (r2>0) + WriteLog(LineBuf, r2); + if (r2==12 && memcmp(LineBuf, "\xd\xaPassword: ", 12)==0) + break; + } + if (r<0) + break; + } + + TT_ASSERT(r>0 || r==KErrTimedOut); + if (r>0) + { + // yes, extract info + GetMonitorInfo(); + CommWriteS("X\xd"); // this should make the target do a cold reboot + } + else + { + // locked up somehow + TraceLog("Target hung"); + } + } +*/ + +int main(int argc, char** argv) + { + TInt r; + TInt port; + const char* logfilename; + FILE* img; + int n; + + if (argc != 4) + { + fprintf(stderr, "trgtest \n"); + exit(999); + } + port = atoi(argv[1]); + strcpy(ImgFileName, argv[2]); + logfilename = argv[3]; + LogFile = fopen(logfilename, "wb"); + if (!LogFile) + { + fprintf(stderr, "Can't open %s for write\n", logfilename); + exit(999); + } + +// TraceLog("Port = %d\n", port); +// TraceLog("Image = %s\n", ImgFileName); +// TraceLog("Log = %s\n", logfilename); + + img = fopen(ImgFileName, "rb"); + if (!img) + { + fprintf(stderr, "Can't open %s for read\n", ImgFileName); + exit(999); + } + fseek(img,0,SEEK_END); + ImgFileSize=ftell(img); + fseek(img,0,SEEK_SET); +// TraceLog("ImgFileSize = %d\n", ImgFileSize); + ImgFileChunkBase = malloc(ImgFileSize); + TT_ASSERT(ImgFileChunkBase != NULL); + n = fread(ImgFileChunkBase, 1, ImgFileSize, img); + TT_ASSERT(n == ImgFileSize); + fclose(img); + + SetupCommPort(port); + + r = SendImageFile(); + free(ImgFileChunkBase); + if (r==KErrNone) + { +// TraceLog("Send image file OK"); + ReceiveTestLog(); + } +// else +// TraceLog("SendImageFile -> %d",r); + + WriteLogS("\n\n"); +// TraceLog("DONE"); + + EscapeCommFunction(Comm, CLRRTS); + EscapeCommFunction(Comm, CLRDTR); + CloseHandle(Comm); + fclose(LogFile); + return 0; + }