diff -r 000000000000 -r d760517a8095 debuggercdi/com.nokia.carbide.trk.support/Native/GetTRKVersion/GetTRKVersion.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debuggercdi/com.nokia.carbide.trk.support/Native/GetTRKVersion/GetTRKVersion.cpp Tue Mar 24 22:20:21 2009 -0500 @@ -0,0 +1,374 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ +// GetTRKVersion.cpp : Defines the entry point for the DLL application. +// + +#include "stdafx.h" +#include "GetTRKVersion.h" +#include "com_nokia_carbide_trk_support_onDeviceSetup_ui_CheckExistingTRKPage.h" +#include "com_nokia_carbide_trk_support_service_TRKConnectedService.h" + + +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +static const DWORD kNoPingError = -1; +static const DWORD kNoVersionError = -2; + +const DWORD kBaudRates[] = { 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400 }; +enum { FlowHardware = 1, FlowSoftware = 2 }; + +static void SetDCB(DCB* ioDCB, int baudIndex, int dataBits, int parity, int stopBits, int flowControl) +{ + ioDCB->DCBlength = sizeof( DCB ); + + ioDCB->BaudRate = kBaudRates[baudIndex]; + + ioDCB->ByteSize = dataBits+4; + ioDCB->Parity = parity; + ioDCB->StopBits = stopBits; + + // setup hardware flow control + if (flowControl == FlowHardware) + ioDCB->fRtsControl = RTS_CONTROL_HANDSHAKE; + else + ioDCB->fRtsControl = RTS_CONTROL_DISABLE; + + ioDCB->fOutxCtsFlow = (flowControl == FlowHardware); + ioDCB->fDtrControl = DTR_CONTROL_ENABLE; + ioDCB->fDsrSensitivity = false; + + + // setup software flow control + + if (flowControl == FlowSoftware) + { + ioDCB->fInX = ioDCB->fOutX = 1; + ioDCB->XonChar = '\021'; // Ctrl-Q; + ioDCB->XoffChar = '\023'; // Ctrl-S; + ioDCB->XonLim = 100; + ioDCB->XoffLim = 100; + } + else + { + ioDCB->fInX = ioDCB->fOutX = 0; + } + + // other various settings + + ioDCB->fBinary = TRUE; + ioDCB->fParity = TRUE; + ioDCB->fNull = FALSE; + ioDCB->fAbortOnError = FALSE; + +} + +static DWORD OpenSerialPort(const char* inPortName, int baudIndex, int dataBits, int parity, int stopBits, int flowControl, HANDLE& serialPortHandle) +{ + serialPortHandle = CreateFile(inPortName, + GENERIC_READ|GENERIC_WRITE, + 0, // lock the port so no one else can get it + NULL, // no attributes + OPEN_EXISTING, + 0, + NULL ); + + + if (serialPortHandle == (HANDLE)-1) + { + return GetLastError(); + } + + if (!SetCommMask(serialPortHandle, EV_RXCHAR)) // WaitCommEvent notified by RX Events + { + CloseHandle(serialPortHandle); + return GetLastError(); + } + + if (!SetupComm(serialPortHandle, 4096, 4096)) // 4K Tx and Rx Buffers + { + CloseHandle(serialPortHandle); + return GetLastError(); + } + + // Get rid of any junk that might be sitting there. + PurgeComm(serialPortHandle, PURGE_TXABORT | PURGE_RXABORT | + PURGE_TXCLEAR | PURGE_RXCLEAR ); + + // Using these settings, the ReadFile command will return immediately + // rather than waiting for a timeout. + + COMMTIMEOUTS lclCommTimeOuts; + lclCommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; + lclCommTimeOuts.ReadTotalTimeoutMultiplier = 0; + lclCommTimeOuts.ReadTotalTimeoutConstant = 0; + lclCommTimeOuts.WriteTotalTimeoutMultiplier = 0; + lclCommTimeOuts.WriteTotalTimeoutConstant = 2001UL; + + if (!SetCommTimeouts(serialPortHandle, &lclCommTimeOuts)) + { + CloseHandle(serialPortHandle); + return GetLastError(); + } + + if (baudIndex >= 0) + { + DCB dcb; + + if (!GetCommState(serialPortHandle, &dcb)) + { + CloseHandle(serialPortHandle); + return GetLastError(); + } + + SetDCB(&dcb, baudIndex, dataBits, parity, stopBits, flowControl); + + if (!SetCommState(serialPortHandle, &dcb)) + { + CloseHandle(serialPortHandle); + return GetLastError(); + } + } + + return ERROR_SUCCESS; +} + +static void Disconnect(HANDLE serialPortHandle) +{ + // disable event notification + SetCommMask(serialPortHandle, 0); + + // drop DTR + EscapeCommFunction(serialPortHandle, CLRDTR); + + // purge any outstanding reads/writes and close device handle + PurgeComm(serialPortHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); + + CloseHandle(serialPortHandle); +} + +// inData: Pointer to data buffer to send +// inSize: Size of data to send +static DWORD SendData(HANDLE serialPortHandle, const void* inData, unsigned long inSize) +{ + DWORD lclNumBytes; + + if (WriteFile(serialPortHandle, inData, inSize, &lclNumBytes, NULL)) + return ERROR_SUCCESS; + + return GetLastError(); +} + +// inSize: Size of data to read in bytes +// outData: Pointer to data buffer to read data into +// outSize: Size actually read in bytes +static DWORD ReadData(HANDLE serialPortHandle, unsigned long inSize, void* outData, unsigned long &outSize) +{ + // Init our number of bytes read to zero + outSize = 0; + + COMSTAT lclComStat; + DWORD lclErrorFlags; + DWORD lclLength; + + // clear out any errors in the channel and get the length of the buffer + ClearCommError(serialPortHandle, &lclErrorFlags, &lclComStat); + lclLength = MIN(inSize, lclComStat.cbInQue ); + + if (lclLength > 0) + { + // Read lclLength number of bytes into outData. + if (!ReadFile(serialPortHandle, outData, lclLength, &outSize, NULL)) + return GetLastError(); + } + + return ERROR_SUCCESS; +} + + +static DWORD ReceiveData(HANDLE serialPortHandle, unsigned long timeout, unsigned long inSize, void* outData, unsigned long &outSize) +{ + const unsigned long kSleepMillis = 10; + + DWORD error = 0; + + int maxIters = timeout/kSleepMillis; + int i = 0; + for (; i < maxIters; i++) + { + error = ReadData(serialPortHandle, inSize, outData, outSize); + if (error != ERROR_SUCCESS) + return error; + + if (outSize > 0) + break; + else + Sleep(kSleepMillis); + } + if (i == maxIters) + return kNoPingError; + + return ERROR_SUCCESS; +} + + +__declspec(dllexport) +DWORD GetTRKVersion(const char* inPortName, int baudIndex, int dataBits, int parity, int stopBits, int flowControl, long version[3]) +{ + // open the serial port + HANDLE serialPortHandle = NULL; + DWORD error = OpenSerialPort(inPortName, baudIndex, dataBits, parity, stopBits, flowControl, serialPortHandle); + if (error != ERROR_SUCCESS) + return error; + + // send a ping command + unsigned char pingTxBuf[] = { 0x7e, 0x00, 0x00, 0xff, 0x7e }; + error = SendData(serialPortHandle, &pingTxBuf, 5); + if (error != ERROR_SUCCESS) { + Disconnect(serialPortHandle); + return error; + } + + // receive response + unsigned char pingRxBuf[16]; + unsigned long pingRxSize = 0; + error = ReceiveData(serialPortHandle, 2001, 16, pingRxBuf, pingRxSize); + if (error != ERROR_SUCCESS) { + Disconnect(serialPortHandle); + return error; + } + + // send get version command + unsigned char versTxBuf[] = { 0x7e, 0x08, 0x01, 0xf6, 0x7e }; + error = SendData(serialPortHandle, &versTxBuf, 5); + if (error != ERROR_SUCCESS) { + Disconnect(serialPortHandle); + return error; + } + + // receive response + unsigned char versRxBuf[16]; + unsigned long versRxSize = 0; + error = ReceiveData(serialPortHandle, 2001, 16, versRxBuf, versRxSize); + if (error != ERROR_SUCCESS) { + Disconnect(serialPortHandle); + if (error == kNoPingError) + return kNoVersionError; // ping ok, but no version + return error; + } + + if (versRxSize >= 9) + { + version[0] = versRxBuf[4]; + version[1] = versRxBuf[5]; + version[2] = versRxBuf[8]; + } + + Disconnect(serialPortHandle); + return ERROR_SUCCESS; +} + +static const char* GetErrorText(DWORD error) +{ + if (error == kNoPingError) + return "TRK did not respond"; + + else if (error == kNoVersionError) + return "TRK responded to PING, but not to GETVERSION command"; + + else if (error == ERROR_FILE_NOT_FOUND) + return "Could not open the serial port"; + + static char msg[256]; + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &msg, + sizeof(msg) - 1, + NULL); + + return msg; +} + + +/* + * Class: com_nokia_carbide_trk_support_onDeviceSetup_ui_CheckExistingTRKPage + * Method: getTRKVersion + * Signature: (Ljava/lang/String;[I)V + */ +JNIEXPORT void JNICALL Java_com_nokia_carbide_trk_support_onDeviceSetup_ui_CheckExistingTRKPage_getTRKVersion + (JNIEnv* env, jclass, jstring jPortName, jintArray jVersionInts) +{ + const char* portName = env->GetStringUTFChars(jPortName, NULL); + + jint versionInts[3]; + DWORD error = GetTRKVersion(portName, -1, 0, 0, 0, 0, versionInts); + env->SetIntArrayRegion(jVersionInts, 0, 3, versionInts); + + env->ReleaseStringUTFChars(jPortName, portName); + + if (error > ERROR_SUCCESS) + { + + jclass clazz = env->FindClass("Ljava/lang/Exception;"); + env->ThrowNew(clazz, GetErrorText(error)); + } + +} + +/* + * Class: com_nokia_carbide_trk_support_service_TRKConnectedService + * Method: getTRKVersionFromSerial + * Signature: (Ljava/lang/String;IIIII[I)V + */ +JNIEXPORT void JNICALL Java_com_nokia_carbide_trk_support_service_TRKConnectedService_getTRKVersionFromSerial + (JNIEnv* env, jclass, jstring jPortName, jint jBaud, jint jDataBits, jint jParity, jint jStopBits, jint jFlowControl, jintArray jVersionInts) +{ + const char* portName = env->GetStringUTFChars(jPortName, NULL); + + jint versionInts[3]; + DWORD error = GetTRKVersion(portName, jBaud, jDataBits, jParity, jStopBits, jFlowControl, versionInts); + env->SetIntArrayRegion(jVersionInts, 0, 3, versionInts); + + env->ReleaseStringUTFChars(jPortName, portName); + + if (error > ERROR_SUCCESS) + { + + jclass clazz = env->FindClass("Ljava/lang/Exception;"); + env->ThrowNew(clazz, GetErrorText(error)); + } +} + +