/*
* 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:
*
*/
/**
*
*/
package com.nokia.tcf.impl;
import com.nokia.tcf.Activator;
import com.nokia.tcf.api.*;
import org.eclipse.core.runtime.*;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
public class TCAPIConnection implements ITCAPIConnection {
static {
Activator plugin = Activator.getDefault();
IPath path = null;
String dePath = null;
if (plugin != null)
path = plugin.getDebuggerPath();
if (path != null)
dePath = path.toOSString();
if (dePath == null) {
System.loadLibrary("TCFClient");
} else {
try{
System.load(dePath + java.io.File.separator + "TCFClient.dll");
} catch (UnsatisfiedLinkError e) {
// if Carbide DLL is not found in DE,
// try to load one from the plugin itself
try {
System.loadLibrary("TCFClient");
} catch (UnsatisfiedLinkError e2) {
// no native TCF, e.g., not on Windows or in a misconfigured dev layout
e2.printStackTrace();
}
}
}
}
private TCErrorListenerList<ITCErrorListener> errorListenerList;
protected ITCCookie cookie; // this client's handle to native
protected ITCMessageIds messageIds; // this client's message ids
protected TCMessageInputStream inputStream; // this client's message input stream (not using message file)
protected ITCMessageOptions messageOptions; // this client's message options
protected TCFMonitorThread monitorThread; // the client's native monitor
public boolean stopTCFMonitorThread; // stream monitor start/stop flag
protected IStatus statusOK;
protected ITCConnection connection; // the client's connection
public ITCConnection getConnection() {
return this.connection;
}
public ITCMessageOptions getMessageOptions() {
return this.messageOptions;
}
/**
* Only constructor - fields are created using the public methods
*/
public TCAPIConnection() {
super();
this.errorListenerList = new TCErrorListenerList<ITCErrorListener>();
this.errorListenerList.clear();
this.connection = null;
IStatus status = new Status(Status.OK, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_NONE, "OK", null);
statusOK = status;
this.cookie = new TCCookie(-1, status, false, false);
this.inputStream = null;
this.messageIds = null;
this.messageOptions = null;
this.monitorThread = null;
this.stopTCFMonitorThread = false;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#addErrorListener(com.nokia.tcf.api.ITCErrorListener)
*/
public IStatus addErrorListener(ITCErrorListener inErrorListener) {
IStatus status = statusOK;
try {
errorListenerList.add(inErrorListener);
} catch (NullPointerException e) {
int err = (int)TCErrorConstants.TCAPI_ERR_ERRLISTENER_NULL;
status = new Status(Status.ERROR, Activator.PLUGIN_ID, err, TCErrorConstants.getErrorMessage(err), e);
}
// System.out.printf("addErrorListener status = %s\n", status.getMessage());
return status;
}
private IStatus checkConnected() {
IStatus status = statusOK;
if (this.connection == null || this.cookie.isConnected() == false) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MEDIA_NOT_OPEN,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MEDIA_NOT_OPEN), null);
}
return status;
}
protected IStatus checkDecodeFormat(String decodeFormat) {
IStatus status = statusOK;
return status;
}
protected IStatus checkConnectionType(ITCConnection inConnection) {
IStatus status = statusOK;
String type = inConnection.getConnectionType();
if (type.compareToIgnoreCase("virtualserial") == 0) {
ITCVirtualSerialConnection c = (ITCVirtualSerialConnection)inConnection;
String p = c.getComPort();
if (p == null) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MISSING_MEDIA_DATA,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MISSING_MEDIA_DATA), null);
}
} else if (type.compareToIgnoreCase("tcp") == 0) {
ITCRealTCPConnection c = (ITCRealTCPConnection)inConnection;
String ip = c.getIpAddress();
String p = c.getPort();
if (ip == null || p == null) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MISSING_MEDIA_DATA,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MISSING_MEDIA_DATA), null);
}
} else if (type.compareToIgnoreCase("serial") == 0) {
ITCRealSerialConnection c = (ITCRealSerialConnection)inConnection;
long err = checkRealSerialSettings(c);
if (err != TCErrorConstants.TCAPI_ERR_NONE) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)err, TCErrorConstants.getErrorMessage(err), null);
}
} else {
// Add other connection types here
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_UNKNOWN_MEDIA_TYPE,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_UNKNOWN_MEDIA_TYPE), null);
}
return status;
}
private IStatus checkConnection(ITCConnection inConnection) {
IStatus status = statusOK;
if (this.cookie.isConnected()) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_ALREADY_CONNECTED,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_ALREADY_CONNECTED), null);
}
if (inConnection == null) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MISSING_CONNECTION_SPEC,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MISSING_CONNECTION_SPEC), null);
}
if (status.isOK()) {
String decodeFormat = inConnection.getDecodeFormat();
status = checkDecodeFormat(decodeFormat);
}
if (status.isOK()) {
long retryI = inConnection.getRetryInterval();
long retryT = inConnection.getRetryTimeout();
if (retryI == 0 || retryT == 0 || retryI > retryT) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_INVALID_RETRY_PERIODS,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_INVALID_RETRY_PERIODS), null);
}
}
if (status.isOK()) {
status = checkConnectionType(inConnection);
}
return status;
}
private long checkRealSerialSettings(ITCRealSerialConnection c) {
String[] setting = new String[6];
setting[0] = c.getBaudRate();
setting[1] = c.getComPort();
setting[2] = c.getDataBits();
setting[3] = c.getFlowControl();
setting[4] = c.getParity();
setting[5] = c.getStopBits();
for (int i = 0; i < 6; i++) {
if (setting[i] == null) {
return TCErrorConstants.TCAPI_ERR_MISSING_MEDIA_DATA;
}
}
if ((setting[2] != ITCRealSerialConnection.DATABITS_4) && (setting[2] != ITCRealSerialConnection.DATABITS_5) && (setting[2] != ITCRealSerialConnection.DATABITS_6) &&
(setting[2] != ITCRealSerialConnection.DATABITS_7) && (setting[2] != ITCRealSerialConnection.DATABITS_8)) {
return TCErrorConstants.TCAPI_ERR_COMM_INVALID_DATABITS;
}
if ((setting[3] != ITCRealSerialConnection.FLOWCONTROL_HW) && (setting[3] != ITCRealSerialConnection.FLOWCONTROL_NONE) && (setting[3] != ITCRealSerialConnection.FLOWCONTROL_SW)) {
return TCErrorConstants.TCAPI_ERR_COMM_INVALID_FLOWCONTROL;
}
if ((setting[4] != ITCRealSerialConnection.PARITY_EVEN) && (setting[4] != ITCRealSerialConnection.PARITY_NONE) && (setting[4] != ITCRealSerialConnection.PARITY_ODD)) {
return TCErrorConstants.TCAPI_ERR_COMM_INVALID_PARITY;
}
if ((setting[5] != ITCRealSerialConnection.STOPBITS_1) && (setting[5] != ITCRealSerialConnection.STOPBITS_1_5) && (setting[5] != ITCRealSerialConnection.STOPBITS_2)) {
return TCErrorConstants.TCAPI_ERR_COMM_INVALID_STOPBITS;
}
return TCErrorConstants.TCAPI_ERR_NONE;
}
private IStatus checkMessage(ITCMessage inMessage) {
IStatus status = statusOK;
if (inMessage == null) {
// inMessage cannot be null
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MISSING_MESSAGE,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MISSING_MESSAGE), null);
} else if (inMessage.size() == 0) {
// bytes to send may be 0 if we're doing the header (header is the message)
if (this.messageOptions.getMessageEncodeFormat() == ITCMessageOptions.ENCODE_NO_FORMAT) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MISSING_MESSAGE,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MISSING_MESSAGE), null);
}
}
if (status.isOK()) {
// check options
if (inMessage.isUseMyMessageId()) {
if (this.messageOptions.getMessageEncodeFormat() == ITCMessageOptions.ENCODE_NO_FORMAT) {
// use my id, but don't encode = error
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MESSAGE_OPTIONS_CONFLICT,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MESSAGE_OPTIONS_CONFLICT), null);
} else {
// use my id, and encode = OK
}
} else {
if (this.messageOptions.getMessageEncodeFormat() == ITCMessageOptions.ENCODE_NO_FORMAT) {
// don't use my id, and don't encode = OK
} else {
// don't use my id, but encode = warning (we'll go ahead send this message raw)
status = new Status(Status.WARNING, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MESSAGE_OPTIONS_CONFLICT,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MESSAGE_OPTIONS_CONFLICT), null);
}
}
}
return status;
}
private IStatus checkMessageIds(ITCMessageIds inMessageIds) {
IStatus status = statusOK;
if (inMessageIds == null || inMessageIds.size() == 0) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_NO_MESSAGESIDS_REGISTERED,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_NO_MESSAGESIDS_REGISTERED), null);
}
if (status.isOK()) {
if (inMessageIds.size() > 256) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MESSAGEID_MAXIMUM,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MESSAGEID_MAXIMUM), null);
}
}
return status;
}
private IStatus checkMessageOptions(ITCMessageOptions inMessageOptions) {
IStatus status = statusOK;
if (inMessageOptions == null) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_MISSING_MESSAGE_OPTIONS,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_MISSING_MESSAGE_OPTIONS), null);
}
// if (status.isOK()) {
// long option = inMessageOptions.getMessageDestination();
// String file = inMessageOptions.getMessageFile().toOSString();
// if (option == ITCMessageOptions.DESTINATION_CLIENTFILE) {
// status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_FEATURE_NOT_IMPLEMENTED,
// TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_FEATURE_NOT_IMPLEMENTED), null);
// }
// }
if (status.isOK()) {
long option = inMessageOptions.getMessageEncodeFormat();
switch ((int)option) {
case (int)ITCMessageOptions.ENCODE_NO_FORMAT:
case (int)ITCMessageOptions.ENCODE_FORMAT:
case (int)ITCMessageOptions.ENCODE_TRK_FORMAT:
break;
default:
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_INVALID_ENCODE_FORMAT,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_INVALID_ENCODE_FORMAT), null);
}
}
if (status.isOK()) {
long option = inMessageOptions.getUnWrapFormat();
switch ((int)option) {
case (int)ITCMessageOptions.UNWRAP_DELETE_HEADERS:
case (int)ITCMessageOptions.UNWRAP_LEAVE_HEADERS:
break;
default:
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_INVALID_MESSAGE_UNWRAP_OPTION,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_INVALID_MESSAGE_UNWRAP_OPTION), null);
}
}
if (status.isOK()) {
long bufferSize = inMessageOptions.getInputStreamSize();
if (bufferSize <= 0) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_INVALID_STREAM_BUFFER_SIZE,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_INVALID_STREAM_BUFFER_SIZE), null);
}
}
return status;
}
protected IStatus checkConnectOptions(ITCConnection inConnection,
ITCMessageOptions inMessageOptions, ITCMessageIds inMessageIds) {
IStatus status = statusOK;
status = checkConnection(inConnection);
if (status.isOK()) {
status = checkMessageOptions(inMessageOptions);
}
if (status.isOK()) {
status = checkMessageIds(inMessageIds);
}
return status;
}
protected IStatus finishConnect(String type, String[] settings,
ITCConnection inConnection, ITCMessageOptions inMessageOptions, ITCMessageIds inMessageIds) {
IStatus status = statusOK;
// connect
long[] clientId = new long[1];
clientId[0] = -1;
long[] options = new long[3];
options[0] = inConnection.getRetryInterval(); // connection options
options[1] = inConnection.getRetryTimeout();
options[2] = 0;
long[] moptions = new long[2];
moptions[0] = inMessageOptions.getUnWrapFormat();
moptions[1] = inMessageOptions.getOSTVersion();
String filePath = null;
if (inMessageOptions.getMessageDestination() == ITCMessageOptions.DESTINATION_CLIENTFILE) {
filePath = inMessageOptions.getMessageFile().toOSString();
try {
ensureWritableFile(filePath);
} catch (IOException e) {
String msg = e.getMessage();
long err = TCErrorConstants.TCAPI_ERR_CREATE_FILE;
String tcErr = String.format("%s OSError: %s", TCErrorConstants.getErrorMessage(err), msg);
status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
(int)TCErrorConstants.TCAPI_ERR_CREATE_FILE, tcErr, e);
}
}
try {
long ret = nativeConnect(type, options, settings, moptions, filePath, clientId);
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
this.cookie.setClientId(clientId[0]);
this.cookie.setConnected(true);
this.connection = inConnection;
this.messageOptions = inMessageOptions;
} else if (ret == TCErrorConstants.TCAPI_ERR_COMM_SERVER_RESPONSE_TIMEOUT){
// TCFServer may have died, attempt to restart it
ret = nativeStartServer();
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
// now try connecting again
ret = nativeConnect(type, options, settings, moptions, filePath, clientId);
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
this.cookie.setClientId(clientId[0]);
this.cookie.setConnected(true);
this.connection = inConnection;
this.messageOptions = inMessageOptions;
} else {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
} else {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
} else {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
} catch (Exception e) {
// exception is thrown ONLY when err = TCAPI_ERR_WHILE_CONFIGURING_MEDIA from native
// and the message is the OS error generated
String msg = e.getMessage();
long ret = TCErrorConstants.TCAPI_ERR_WHILE_CONFIGURING_MEDIA;
String tcErr = String.format("%s OSError: %s", TCErrorConstants.getErrorMessage(ret), msg);
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, tcErr, null);
}
// send message ids to capture
if (status.isOK()) {
int number = (int)inMessageIds.size();
byte[] ids = new byte[number];
for (int i = 0; i < number; i++) {
ids[i] = inMessageIds.getMessageIds().get(i);
}
long ret = nativeSetMessageIds(this.cookie.getClientId(), ids);
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
this.messageIds = inMessageIds;
} else {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
}
// setup input stream
if (status.isOK() && inMessageOptions.getMessageDestination() == ITCMessageOptions.DESTINATION_INPUTSTREAM) {
inputStream = new TCMessageInputStream(this,
inMessageOptions.getInputStreamSize(),
cookie.getClientId());
try {
inputStream.open();
} catch (IOException e) {
// stream didn't open
status = new Status(Status.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
e.printStackTrace();
}
}
// create error monitor
if (status.isOK()) {
String monitorName = String.format("TCFMonitor%d", this.cookie.getClientId());
monitorThread = new TCFMonitorThread(this, monitorName);
stopTCFMonitorThread = false;
monitorThread.start();
}
// start capture
if (status.isOK()) {
long ret = nativeStart(this.cookie.getClientId());
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
this.cookie.setMessageProcessing(true);
} else {
// error in starting capture
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
}
if (!status.isOK()) {
// an error occurred along the way - unravel what we've done
if (this.cookie.isMessageProcessing()) {
long ret = nativeStop(this.cookie.getClientId());
// ignore error
this.cookie.setMessageProcessing(false);
}
if (this.monitorThread != null) {
this.stopTCFMonitorThread = true;
try {
this.monitorThread.join();
} catch (InterruptedException e) {
}
this.monitorThread = null;
}
if (this.inputStream != null && this.inputStream.isOpen()) {
try {
this.inputStream.close();
} catch (IOException e) {
}
this.inputStream = null;
}
if (this.cookie.isConnected()) {
long ret = nativeDisconnect(this.getClientId());
this.cookie.setConnected(false);
this.cookie.setClientId(-1);
}
}
return status;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#connect(com.nokia.tcf.api.ITCConnection, com.nokia.tcf.api.ITCMessageOptions, com.nokia.tcf.api.ITCMessageIds)
*/
public IStatus connect(ITCConnection inConnection,
ITCMessageOptions inMessageOptions, ITCMessageIds inMessageIds) {
IStatus status = checkConnectOptions(inConnection, inMessageOptions, inMessageIds);
String[] settings = null;
String type = null;
// do connect
if (status.isOK()) {
settings = null;
type = inConnection.getConnectionType();
if (type.compareToIgnoreCase("tcp") == 0) {
settings = new String[3];
ITCRealTCPConnection t = (ITCRealTCPConnection)inConnection;
settings[0] = t.getIpAddress();
settings[1] = t.getPort();
settings[2] = t.getDecodeFormat().toLowerCase();
} else if (type.compareToIgnoreCase("virtualserial") == 0) {
settings = new String[2];
ITCVirtualSerialConnection s = (ITCVirtualSerialConnection)inConnection;
settings[0] = s.getComPort();
settings[1] = s.getDecodeFormat().toLowerCase();
} else if (type.compareToIgnoreCase("serial") == 0) {
settings = new String[7];
ITCRealSerialConnection s = (ITCRealSerialConnection)inConnection;
settings[0] = s.getComPort();
settings[1] = s.getBaudRate();
settings[2] = s.getDataBits();
settings[3] = s.getParity();
settings[4] = s.getStopBits();
settings[5] = s.getFlowControl();
settings[6] = s.getDecodeFormat().toLowerCase();
} else if (type.compareToIgnoreCase("usb") == 0) {
settings = new String[1];
} else {
// Add other connections here
}
}
return finishConnect(type, settings, inConnection, inMessageOptions, inMessageIds);
}
protected void ensureWritableFile(String filePath) throws IOException {
// ensure file path points to a writable regular file
IPath path = new Path(filePath);
File file = path.toFile();
if (!file.exists()) {
file.createNewFile();
}
else { // file exists
if (file.isDirectory()) {
throw new IOException(MessageFormat.format("Path is a directory: {0}", filePath));
}
else if (!file.canWrite()) {
throw new IOException(MessageFormat.format("File exists and is not writable: {0}", filePath));
}
}
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#connect(com.nokia.tcf.api.ITCMessageOptions, com.nokia.tcf.api.ITCMessageIds)
*/
public IStatus connect(ITCMessageOptions inMessageOptions, ITCMessageIds inMessageIds) {
// not currently implemented or tested
long ret = TCErrorConstants.TCAPI_ERR_FEATURE_NOT_IMPLEMENTED;
IStatus status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
return status;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#disconnect()
*/
public IStatus disconnect() {
IStatus status = statusOK;
IStatus connectStatus = checkConnected();
// ignore error
if (connectStatus.isOK()) {
if (this.cookie.isMessageProcessing()) {
long ret = nativeStop(this.cookie.getClientId());
this.cookie.setMessageProcessing(false);
if (ret != TCErrorConstants.TCAPI_ERR_NONE) {
status = new Status(IStatus.ERROR,Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
}
if (this.monitorThread != null) {
this.stopTCFMonitorThread = true;
this.monitorThread.stop = true;
try {
this.monitorThread.join();
} catch (InterruptedException e) {
}
this.monitorThread = null;
}
if (this.inputStream != null && this.inputStream.isOpen()) {
try {
this.inputStream.close();
} catch (IOException e) {
}
this.inputStream = null;
}
if (this.cookie.isConnected()) {
long ret = nativeDisconnect(this.cookie.getClientId());
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
this.cookie.setConnected(false);
this.cookie.setClientId(-1);
} else {
// error from nativeDisconnect
status = new Status(Status.ERROR,Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
}
}
return status;
}
// private methods
/**
* This is called from TCFMonitorThread to send errors to registered listeners
*/
public void fireErrorListeners(long errorCode, String errorString) {
int s = this.errorListenerList.size();
// System.out.printf("fireErrorListeners s = %d\n", s);
for (int i = 0; i < s; i++) {
ITCErrorListener e = (ITCErrorListener)this.errorListenerList.get(i);
if (e != null) {
int errorStatus = Status.ERROR;
if (errorCode == TCErrorConstants.TCAPI_INFO_COMM_RECONNECTED)
errorStatus = Status.INFO;
IStatus status = new Status(errorStatus, Activator.PLUGIN_ID, (int)errorCode, errorString, null);
e.errorOccurred(status);
}
}
}
public long getClientId() {
return this.cookie.getClientId();
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#getConnections()
*/
public ITCConnection[] getConnections() {
IStatus status = statusOK;
ITCConnection[] connections = null;
long numberConnections = 0;
long[] number = new long[1];
long ret = nativeGetNumberConnections(number);
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
numberConnections = number[0];
} else {
// error processing from nativeGetNumberConnections
status = new Status(Status.ERROR,Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
if (numberConnections > 0)
{
connections = new ITCConnection[(int)numberConnections];
for (int inIndex = 0; inIndex < numberConnections; inIndex++)
{
String[] type = new String[1];
ret = nativeGetTypeOfConnection(inIndex, type);
if (type[0].compareToIgnoreCase("virtualserial") == 0) {
ITCVirtualSerialConnection outConnection = (ITCVirtualSerialConnection)TCFClassFactory.createITCVirtualSerialConnection(null);
String[] outType = new String[1];
long[] outOptions = new long[3];
String[] outSettings = new String[2];
ret = nativeGetConnectionSettings(inIndex, outType, outOptions, outSettings);
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
outConnection.setConnectionType(outType[0]);
outConnection.setRetryInterval(outOptions[0]);
outConnection.setRetryTimeout(outOptions[1]);
outConnection.setComPort(outSettings[0]);
outConnection.setDecodeFormat(outSettings[1]);
connections[inIndex] = outConnection;
} else {
// error processing from nativeGetConnectionSettings
status = new Status(Status.ERROR,Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
} else if (type[0].compareToIgnoreCase("serial") == 0) {
ITCRealSerialConnection outConnection = (ITCRealSerialConnection)TCFClassFactory.createITCRealSerialConnection(null);
String[] outType = new String[1];
long[] outOptions = new long[6];
String[] outSettings = new String[7];
ret = nativeGetConnectionSettings(inIndex, outType, outOptions, outSettings);
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
outConnection.setConnectionType(outType[0]);
outConnection.setRetryInterval(outOptions[0]);
outConnection.setRetryTimeout(outOptions[1]);
outConnection.setComPort(outSettings[0]);
outConnection.setBaudRate(outSettings[1]);
outConnection.setDataBits(outSettings[2]);
outConnection.setParity(outSettings[3]);
outConnection.setStopBits(outSettings[4]);
outConnection.setFlowControl(outSettings[5]);
outConnection.setDecodeFormat(outSettings[6]);
connections[inIndex] = outConnection;
} else {
// error processing from nativeGetConnectionSettings
status = new Status(Status.ERROR,Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
} else if (type[0].compareToIgnoreCase("tcp") == 0) {
ITCRealTCPConnection outConnection = (ITCRealTCPConnection)TCFClassFactory.createITCRealTCPConnection(null, null);
String[] outType = new String[1];
long[] outOptions = new long[3];
String[] outSettings = new String[3];
ret = nativeGetConnectionSettings(inIndex, outType, outOptions, outSettings);
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
outConnection.setConnectionType(outType[0]);
outConnection.setRetryInterval(outOptions[0]);
outConnection.setRetryTimeout(outOptions[1]);
outConnection.setIpAddress(outSettings[0]);
outConnection.setPort(outSettings[1]);
outConnection.setDecodeFormat(outSettings[2]);
connections[inIndex] = outConnection;
} else {
// error processing from nativeGetConnectionSettings
status = new Status(Status.ERROR,Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
} else if (type[0].compareToIgnoreCase("usb") == 0) {
// Finish this sometime when real USB is used on PC
} else {
// Add other connection types here
}
}
}
return connections;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#getInputStream()
*/
public ITCMessageInputStream getInputStream() {
return this.inputStream;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#getVersions()
*/
public ITCVersion[] getVersions() {
IStatus status = statusOK;
ITCVersion[] versions = null;
status = checkConnected();
if (status.isOK()) {
// we're connected call native
long numberVersions = nativeGetNumberVersionEntities(this.cookie.getClientId());
if (numberVersions > 0) {
versions = new TCVersion[(int)numberVersions];
String[] versStrings = new String[(int)numberVersions];
long numberGotten = nativeGetVersion(this.cookie.getClientId(), numberVersions, versStrings);
for (int i = 0; i < numberGotten; i++) {
versions[i] = new TCVersion(versStrings[i]);
}
}
}
return versions;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#removeErrorListener(com.nokia.tcf.api.ITCErrorListener)
*/
public IStatus removeErrorListener(ITCErrorListener inErrorListener) {
IStatus status = statusOK;
// System.out.printf("removeErrorListener\n");
this.errorListenerList.remove(inErrorListener);
return status;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#sendMessage(com.nokia.tcf.api.ITCMessage)
*/
public IStatus sendMessage(ITCMessage inMessage) {
IStatus status = statusOK;
status = checkConnected();
if (status.isOK()) {
// we are connected are we processing?
if (this.cookie.isMessageProcessing()) {
// we are running, check message
status = checkMessage(inMessage);
if (status.getSeverity() != Status.ERROR) {
// Status.OK or Status.WARNING (still attempt to send on warning)
// Encode if option is set
long[] formattingOptions = new long[5];
formattingOptions[0] = 0;
formattingOptions[1] = messageOptions.getMessageEncodeFormat(); // add protocol or not
formattingOptions[2] = messageOptions.getOSTVersion(); // OST version byte to use if OST
formattingOptions[3] = inMessage.getMyMessageId(); // message ID to use of adding protocol
formattingOptions[4] = (inMessage.isUseMyMessageId() == true) ? 1 : 0; // use my ID or not
String[] settings = new String[1];
settings[0] = connection.getDecodeFormat().toLowerCase();
try {
long ret = TCErrorConstants.TCAPI_ERR_NONE;
if (inMessage == null) { // OK if we're just sending a header
ret = nativeSendMessage(this.cookie.getClientId(), formattingOptions, settings, null);
} else {
ret = nativeSendMessage(this.cookie.getClientId(), formattingOptions, settings, inMessage.getMessage());
}
if (ret != TCErrorConstants.TCAPI_ERR_NONE) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
} catch (Exception e) {
// exception is thrown ONLY when err = TCAPI_ERR_COMM_ERROR from native
// message is OS Error
String msg = e.getMessage();
long ret = TCErrorConstants.TCAPI_ERR_COMM_ERROR;
String tcErr = String.format("%s OSError: %s", TCErrorConstants.getErrorMessage(ret), msg);
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, tcErr, null);
}
}
} else {
// we are stopped
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_ROUTING_STOPPED,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_ROUTING_STOPPED), null);
}
}
return status;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#setTCMessageIds(com.nokia.tcf.api.ITCMessageIds)
*/
public IStatus setTCMessageIds(ITCMessageIds inMessageIds) {
IStatus status = statusOK;
status = checkMessageIds(inMessageIds);
if (status.isOK()) {
// input is OK
status = checkConnected();
if (status.isOK()) {
// connected
if (this.cookie.isMessageProcessing()) {
// must be stopped to set new IDs
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)TCErrorConstants.TCAPI_ERR_ROUTING_IN_PROGRESS,
TCErrorConstants.getErrorMessage(TCErrorConstants.TCAPI_ERR_ROUTING_IN_PROGRESS), null);
}
}
}
if (status.isOK()) {
// everything OK, so we can save our IDs and register them
this.messageIds = inMessageIds;
int size = (int)inMessageIds.size();
byte[] messageids = new byte[size];
for (int i = 0; i < size; i++) {
messageids[0] = inMessageIds.getMessageIds().get(i);
}
long ret = nativeSetMessageIds(this.cookie.getClientId(), messageids);
if (ret != TCErrorConstants.TCAPI_ERR_NONE) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret,
TCErrorConstants.getErrorMessage(ret), null);
}
}
return status;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#start()
*/
public IStatus start() {
IStatus status = statusOK;
// check connected
status = checkConnected();
if (status.isOK()) {
if (this.cookie.isMessageProcessing() == false) {
// call native
long ret = nativeStart(this.cookie.getClientId());
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
this.cookie.setMessageProcessing(true);
} else {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
}
}
return status;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#stop()
*/
public IStatus stop() {
IStatus status = statusOK;
status = checkConnected();
if (status.isOK()) {
if (this.cookie.isMessageProcessing()) {
long ret = nativeStop(this.cookie.getClientId());
if (ret == TCErrorConstants.TCAPI_ERR_NONE) {
this.cookie.setMessageProcessing(false);
} else {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
}
}
return status;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#testConnection()
*/
public IStatus testConnection() {
IStatus status = statusOK;
status = checkConnected();
if (status.isOK()) {
long ret = nativeTestConnection(this.cookie.getClientId());
if (ret != TCErrorConstants.TCAPI_ERR_NONE) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)(ret), TCErrorConstants.getErrorMessage((int)ret), null);
}
}
return status;
}
protected IStatus doTestConnection(String type, String[] settings, ITCConnection inConnection) {
IStatus status = statusOK;
// test connection
long[] options = new long[3];
options[0] = inConnection.getRetryInterval(); // connection options
options[1] = inConnection.getRetryTimeout();
options[2] = 0;
long ret = nativeTestConnection(type, options, settings);
if (ret != TCErrorConstants.TCAPI_ERR_NONE) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
return status;
}
/* (non-Javadoc)
* @see com.nokia.tcf.api.ITCAPIConnection#testConnection(com.nokia.tcf.api.ITCConnection)
*/
public IStatus testConnection(ITCConnection inConnection) {
IStatus status = statusOK;
String[] settings = null;
String type = inConnection.getConnectionType();
if (type.compareToIgnoreCase("serial") == 0) {
settings = new String[7];
ITCRealSerialConnection s = (ITCRealSerialConnection)inConnection;
settings[0] = s.getComPort();
settings[1] = s.getBaudRate();
settings[2] = s.getDataBits();
settings[3] = s.getParity();
settings[4] = s.getStopBits();
settings[5] = s.getFlowControl();
settings[6] = s.getDecodeFormat().toLowerCase();
} else if (type.compareToIgnoreCase("tcp") == 0) {
settings = new String[3];
ITCRealTCPConnection s = (ITCRealTCPConnection)inConnection;
settings[0] = s.getIpAddress();
settings[1] = s.getPort();
settings[2] = s.getDecodeFormat().toLowerCase();
} else if (type.compareToIgnoreCase("usb") == 0) {
settings = new String[1];
// finish this sometime when real USB is used on PC
} else if (type.compareToIgnoreCase("virtualserial") == 0) {
settings = new String[2];
ITCVirtualSerialConnection s = (ITCVirtualSerialConnection)inConnection;
settings[0] = s.getComPort();
settings[1] = s.getDecodeFormat().toLowerCase();
} else {
// add new connections here
long err = TCErrorConstants.TCAPI_ERR_MEDIA_NOT_SUPPORTED;
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)err, TCErrorConstants.getErrorMessage((int)err), null);
}
if (status.isOK()) {
status = doTestConnection(type, settings, inConnection);
/* // test connection
long[] options = new long[3];
options[0] = inConnection.getRetryInterval(); // connection options
options[1] = inConnection.getRetryTimeout();
options[2] = inConnection.getDecodeFormat();
long ret = nativeTestConnection(type, options, settings);
if (ret != TCErrorConstants.TCAPI_ERR_NONE) {
status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
} */
}
return status;
}
public IStatus clearMessageFile() {
IStatus status = statusOK;
IStatus connStatus = checkConnected();
if (connStatus.isOK()) {
if (messageOptions.getMessageDestination() == ITCMessageOptions.DESTINATION_CLIENTFILE) {
if (messageOptions.getMessageFile() != null) {
long ret = nativeClearFile(cookie.getClientId());
if (ret != TCErrorConstants.TCAPI_ERR_NONE) {
status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null);
}
}
}
}
return status;
}
// natives
// connect/disconnect
protected native long nativeConnect(String inType, long[] inOptions, String[] inSettings, long[] inMessageOptions, String inFilePath, long[] outClientId);
protected native long nativeDisconnect(long inClientId);
// connections
protected native long nativeGetNumberConnections(long[] outNumber);
protected native long nativeGetTypeOfConnection(long inIndex, String[] outType);
protected native long nativeGetConnectionSettings(long inIndex, String[] outType, long[] outOptions, String[] outSettings);
// port handling errors
public native boolean nativePollError(long inClienId, int[] outErrorCode, boolean[] outHasOSErrorCode, long[] outOSErrorCode);
// versions
protected native long nativeGetNumberVersionEntities(long inClientId);
protected native long nativeGetVersion(long inClientId, long inNumToGet, String[] outVersion);
// input stream
public native long nativePollInputStream(long inClientId, long[] outNumberTotalMessages);
public native long nativePollInputStream2(long inClientId, long inNumberMessagesToPeek, long[] outNumberMessagesPeeked, long[] outNumberBytesPeeked);
public native long nativeGetInputStreamMessageBytes(long inClientId, long inNumberMessagesToPeek, long[] outNumberBytesPerMessage);
public native long nativeReadInputStream(long inClientId, long inNumberMessagesToRead, long[] outNumberMessagesRead, long[] outNumberBytesRead, long inNumberMaxBytes, byte[] outMessages);
public native long nativeOpenInputStream(long inClientId, String inBaseFilePath, long inInputStreamSize, boolean inOverFlowToFile);
public native long nativeCloseInputStream(long inClientId);
// message file
protected native long nativeClearFile(long inClientId);
// send message
protected native long nativeSendMessage(long inClientId, long[] inFormattingOptions, String[] inSettings, byte[] inMessage);
// register message IDs
protected native long nativeSetMessageIds(long inClientId, byte[] inMessageIds);
// start/stop processing
protected native long nativeStart(long inClientId);
protected native long nativeStop(long inClientId);
// test connections
protected native long nativeTestConnection(String inType, long[] inOptions, String[] inSettings);
protected native long nativeTestConnection(long inClientId);
// start/stop server - done from plugin activator start/stop methods
public native long nativeStartServer();
public native long nativeStopServer();
}