debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/service/TRKConnectedService.java
[Bug 9085] Add new TCP/IP connection type with port mappings and new service interface to optionally provide defaults.
/*
* Copyright (c) 2008 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:
*
*/
package com.nokia.carbide.trk.support.service;
import com.freescale.cdt.debug.cw.core.SerialConnectionSettings;
import com.nokia.carbide.remoteconnections.interfaces.*;
import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatus.EStatus;
import com.nokia.carbide.remoteconnections.interfaces.IRemoteAgentInstallerProvider.IRemoteAgentInstaller;
import com.nokia.carbide.trk.support.Messages;
import com.nokia.carbide.trk.support.connection.*;
import com.nokia.cpp.internal.api.utils.core.Check;
import com.nokia.cpp.internal.api.utils.core.Pair;
import com.nokia.tcf.api.*;
import org.eclipse.core.runtime.IProgressMonitor;
import org.osgi.framework.Version;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;
/**
*
*/
public class TRKConnectedService extends AbstractConnectedService {
static {
System.loadLibrary("GetTRKVersion"); //$NON-NLS-1$
}
public native static void getTRKVersionFromSerial(String portName,
int baud, int dataBits, int parity, int stopBits, int flowControl,
int[] version) throws Exception;
private static final String OK_STATUS =
Messages.getString("TRKConnectedService.OKStatus"); //$NON-NLS-1$
private static final String IS_LASTEST =
Messages.getString("TRKConnectedService.IsLatestStatus"); //$NON-NLS-1$
private static final String NEEDS_INSTALL =
Messages.getString("TRKConnectedService.NeedsInstallStatus1") + //$NON-NLS-1$
Messages.getString("TRKConnectedService.NeedsInstallStatus2"); //$NON-NLS-1$
private static final String ERROR =
Messages.getString("TRKConnectedService.ErrorStatus"); //$NON-NLS-1$
private static final String PORT_IN_USE =
Messages.getString("TRKConnectedService.PortInUseStatus"); //$NON-NLS-1$
private static final String TCPIP_IN_USE =
Messages.getString("TRKConnectedService.TCPIPInUseStatus"); //$NON-NLS-1$
private static final byte[] TRK_PING = {0x7e, 0x0, 0x0, (byte) 0xff, 0x7e};
private static final byte[] TRK_VERSION = {0x7e, 0x08, 0x01, (byte) 0xf6, 0x7e};
private Pair<String, Version> deviceOS;
private TRKService trkService;
public TRKConnectedService(IService service, AbstractSynchronizedConnection connection) {
super(service, connection);
Check.checkContract(service instanceof TRKService);
trkService = (TRKService) service;
currentStatus = new Status();
}
public IStatus getStatus() {
return currentStatus;
}
private String getSimplePortName(int portNum) {
return "COM" + portNum; //$NON-NLS-1$
}
private String getPortNameForSerial(int portNum) {
String portNamePrefix = portNum > 9 ? "\\\\.\\" : ""; //$NON-NLS-1$ //$NON-NLS-2$
return portNamePrefix + getSimplePortName(portNum);
}
private Version getTRKVersionFromDevice() throws ConnectionFailException {
if (connection.getConnectionType() instanceof SerialConnectionType) {
int[] versInts = {0,0,0};
String portNumStr = connection.getSettings().get(SerialConnectionSettings.PORT);
int portNum = Integer.parseInt(portNumStr);
int baud = getIndexValue(SerialConnectionSettings.BAUD);
int dataBits = getIndexValue(SerialConnectionSettings.DATA_BITS);
int parity = getIndexValue(SerialConnectionSettings.PARITY);
int stopBits = getIndexValue(SerialConnectionSettings.STOP_BITS);
int flowControl = getIndexValue(SerialConnectionSettings.FLOW_CONTROL);
try {
getTRKVersionFromSerial(getPortNameForSerial(portNum), baud, dataBits, parity, stopBits, flowControl, versInts);
}
catch (Exception e) {
throw new ConnectionFailException(e.getMessage());
}
return new Version(versInts[0], versInts[1], versInts[2]);
}
else if (connection.getConnectionType() instanceof USBConnectionType) {
String portNumStr = connection.getSettings().get(SerialConnectionSettings.PORT);
int portNum = Integer.parseInt(portNumStr);
return getTRKVersionFromOSTUSB(getSimplePortName(portNum));
}
return null;
}
private Version getTRKVersionFromOSTUSB(String port) throws ConnectionFailException {
ITCConnection conn = TCFClassFactory.createITCVirtualSerialConnection(port);
conn.setDecodeFormat("ost"); //$NON-NLS-1$
return getTRKVersionUsingTCF(conn, (byte)0x90, (byte)0x90);
}
private Version getTRKVersionUsingTCF(ITCConnection conn, byte trkResponseId, byte trkRequestId) throws ConnectionFailException {
// System.out.println("entering getTRKVersionUsingTCF");
Version version = null;
ITCMessageOptions options = TCFClassFactory.createITCMessageOptions();
options.setMessageEncodeFormat(ITCMessageOptions.ENCODE_FORMAT); // we send raw trk
options.setUnWrapFormat(ITCMessageOptions.UNWRAP_DELETE_HEADERS); // return raw trk
options.setInputStreamSize(64);
// message Ids to capture (we must capture TRK response messages = id=0x45)
ITCMessageIds ids = TCFClassFactory.createITCMessageIds();
ids.addMessageId(trkResponseId); // TRK response
ITCMessage tcMsgPing = TCFClassFactory.createITCMessage(TRK_PING);
tcMsgPing.setUseMyMessageId(true, trkRequestId);
ITCMessage tcMsgVersion = TCFClassFactory.createITCMessage(TRK_VERSION);
tcMsgVersion.setUseMyMessageId(true, trkRequestId);
// connect
ITCAPIConnection api = TCFClassFactory.createITCAPIConnection();
org.eclipse.core.runtime.IStatus connStatus = api.connect(conn, options, ids);
// get a reference to the input stream
ITCMessageInputStream stream = api.getInputStream();
// send trk ping
if (connStatus.isOK()) {
try {
org.eclipse.core.runtime.IStatus sendStatus = api.sendMessage(tcMsgPing);
if (sendStatus.isOK()) {
waitForSingleTCMessage(stream);
if (stream.peekMessages() > 0) {
/*ITCMessage message =*/ stream.readMessage(); // ping response
}
else
throw new ConnectionFailException(Messages.getString("TRKConnectedService.NoPingError")); //$NON-NLS-1$
// send trk version
sendStatus = api.sendMessage(tcMsgVersion);
waitForSingleTCMessage(stream);
if (stream.peekMessages() > 0) {
ITCMessage tcMessage = stream.readMessage(); // version response
byte[] message = tcMessage.getMessage();
// printMessage(message);
if (message != null && message.length == 11) {
version = new Version(message[4], message[5], message[8]);
}
else
throw new ConnectionFailException(Messages.getString("TRKConnectedService.BadVersionResponseError")); //$NON-NLS-1$
}
else
throw new ConnectionFailException(Messages.getString("TRKConnectedService.NoPingErrorNoVersionError")); //$NON-NLS-1$
}
else
throw new ConnectionFailException(sendStatus.getMessage());
}
catch (IOException e) {
throw new ConnectionFailException(e.getMessage());
}
finally {
api.disconnect();
// System.out.println("leaving getTRKVersionUsingTCF");
}
}
else
throw new ConnectionFailException(connStatus.getMessage());
return version;
}
// private void printMessage(byte[] message) {
// for (int i = 0; i < message.length; i++) {
// String hexString = Integer.toHexString(message[i]);
// if (hexString.length() == 1)
// hexString = "0" + hexString;
// else if (hexString.length() > 2)
// hexString = hexString.substring(hexString.length() - 2);
// System.out.print(hexString);
// if (i + 1 < message.length)
// System.out.print('-');
// }
// System.out.println();
//}
private void waitForSingleTCMessage(ITCMessageInputStream stream) throws IOException {
int timeout = TIMEOUT;
while (stream.peekMessages() == 0) {
try {
Thread.sleep(200);
timeout -= 200;
if (timeout <= 0)
break;
} catch (InterruptedException e) {
}
}
}
private int getIndexValue(String key) {
String val = connection.getSettings().get(key);
return SerialConnectionSettings.toIndex(key, val);
}
private Version getLatestVersionFromServer() {
if (deviceOS != null) {
List<IRemoteAgentInstaller> installers =
trkService.getInstallerProvider().getRemoteAgentInstallers(deviceOS.first, deviceOS.second);
if (installers != null && !installers.isEmpty()) {
// use the first one
return installers.get(0).getInstallerVersion();
}
}
return null;
}
private String getShortDescription(EStatus estatus) {
switch (estatus) {
case UP:
return Messages.getString("TRKConnectedService.RunningLabel"); //$NON-NLS-1$
case DOWN:
return Messages.getString("TRKConnectedService.DownLabel"); //$NON-NLS-1$
case IN_USE:
return Messages.getString("TRKConnectedService.InUseLabel"); //$NON-NLS-1$
}
return Messages.getString("TRKConnectedService.UnknownLabel"); //$NON-NLS-1$
}
protected TestResult runTestStatus(IProgressMonitor monitor) {
String message = null;
EStatus estatus = EStatus.DOWN;
monitor.beginTask(Messages.getString("TRKConnectedService.TaskLabel"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
synchronized (connection) {
boolean didTest = false;
try {
if (connection.isInUse()) {
estatus = EStatus.IN_USE;
IConnectionType connectionType = connection.getConnectionType();
if (connectionType instanceof SerialConnectionType ||
connectionType instanceof USBConnectionType)
message = MessageFormat.format(PORT_IN_USE,
connection.getSettings().get(SerialConnectionSettings.PORT));
else if (connectionType instanceof TCPIPConnectionType)
message = MessageFormat.format(TCPIP_IN_USE,
connection.getSettings().get(TCPIPConnectionFactory.IP_ADDRESS),
connection.getSettings().get(TCPIPConnectionFactory.IP_PORT));
}
else {
didTest = true;
connection.setServiceTestingAndInUse(true);
Version deviceVersion = getTRKVersionFromDevice();
if (deviceVersion != null) {
estatus = EStatus.UP;
Version serverVersion = getLatestVersionFromServer();
if (serverVersion == null) {
message = MessageFormat.format(OK_STATUS, deviceVersion);
}
else if (deviceVersion.compareTo(serverVersion) >= 0) {
message = MessageFormat.format(IS_LASTEST, deviceVersion);
}
else {
message = MessageFormat.format(NEEDS_INSTALL,
deviceVersion, serverVersion);
}
}
}
}
catch (Exception e) {
message = ERROR + e.getMessage();
estatus = EStatus.DOWN;
}
finally {
if (didTest)
connection.setServiceTestingAndInUse(false);
}
}
monitor.done();
return new TestResult(estatus, getShortDescription(estatus), message);
}
public void setDeviceOS(String familyName, Version version) {
deviceOS = new Pair<String, Version>(familyName, version);
}
}