SDL_Android/SmartDeviceLinkAndroidProxy - added the correct version of the proxy
[profile/ivi/smartdevicelink.git] / SDL_Android / SmartDeviceLinkProxyAndroid / src / com / smartdevicelink / trace / SmartDeviceLinkTrace.java
-//
-// Copyright (c) 2013 Ford Motor Company
-//
-package com.smartdevicelink.trace;
-
-import java.sql.Timestamp;
-
-import android.bluetooth.BluetoothDevice;
-import android.os.Build;
-import android.os.Debug;
-import android.os.Process;
-
-import com.smartdevicelink.protocol.ProtocolFrameHeader;
-import com.smartdevicelink.protocol.enums.FrameDataControlFrameType;
-import com.smartdevicelink.protocol.enums.FrameType;
-import com.smartdevicelink.protocol.enums.SessionType;
-import com.smartdevicelink.proxy.RPCMessage;
-import com.smartdevicelink.proxy.RPCRequest;
-import com.smartdevicelink.proxy.RPCResponse;
-import com.smartdevicelink.trace.enums.DetailLevel;
-import com.smartdevicelink.trace.enums.InterfaceActivityDirection;
-import com.smartdevicelink.trace.enums.Mod;
-import com.smartdevicelink.transport.SiphonServer;
-import com.smartdevicelink.util.BitConverter;
-import com.smartdevicelink.util.DebugTool;
-import com.smartdevicelink.util.NativeLogTool;
-
-/* This class handles the global TraceSettings as requested by the users either through the combination of the following
-   1. System defaults
-   2. Application XML config
-   3. Programmatic requests from application itself
-
-   It is manifested in the <SmartDeviceLink>...</SmartDeviceLink> tags
- */
-
-public class SyncTrace {
-       private static final String SmartDeviceLink_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66";
-       
-       static boolean canWriteLogs = false;
-               
-       public static final String SYSTEM_LOG_TAG = "SyncTrace";
-       
-       private static long baseTics  = java.lang.System.currentTimeMillis();
-       private final static String KeyStr = SmartDeviceLink_LIB_TRACE_KEY;
-       private static boolean acceptAPITraceAdjustments = true;
-
-       protected static ISTListener m_appTraceListener = null;
-
-       ///
-       ///  The PUBLIC interface to SyncTrace starts here
-       ///
-
-
-       public static void setAcceptAPITraceAdjustments(Boolean APITraceAdjustmentsAccepted) {
-               if (APITraceAdjustmentsAccepted != null) {
-                       acceptAPITraceAdjustments = APITraceAdjustmentsAccepted;
-               }
-       }
-       
-       public static boolean getAcceptAPITraceAdjustments() {
-               return acceptAPITraceAdjustments;
-       }
-       
-       public static void setAppTraceListener(ISTListener listener) {
-               m_appTraceListener = listener;
-       } // end-method
-
-       public static void setTracingEnable(Boolean enable) {
-               if (enable != null) {
-                       canWriteLogs = enable;
-               }
-       } // end-method
-
-       public static void setAppTraceLevel(DetailLevel dt) {
-               if ( dt != null && acceptAPITraceAdjustments)
-                       DiagLevel.setLevel(Mod.app, dt);
-       } // end-method
-
-       public static void setProxyTraceLevel(DetailLevel dt) {
-               if (dt != null && acceptAPITraceAdjustments)
-                       DiagLevel.setLevel(Mod.proxy, dt);
-       } // end-method
-
-       public static void setRpcTraceLevel(DetailLevel dt) {
-               if (dt != null && acceptAPITraceAdjustments)
-                       DiagLevel.setLevel(Mod.rpc, dt);
-       } // end-method
-
-       public static void setMarshallingTraceLevel(DetailLevel dt) {
-               if (dt != null && acceptAPITraceAdjustments)
-                       DiagLevel.setLevel(Mod.mar, dt);
-       } // end-method
-
-       public static void setProtocolTraceLevel(DetailLevel dt) {
-               if (dt != null && acceptAPITraceAdjustments)
-                       DiagLevel.setLevel(Mod.proto, dt);
-       } // end-method
-
-       public static void setTransportTraceLevel(DetailLevel dt) {
-               if (dt != null && acceptAPITraceAdjustments)
-                               DiagLevel.setLevel(Mod.tran, dt);
-       } // end-method
-
-       private static String encodeTraceMessage(long timestamp, Mod module, InterfaceActivityDirection msgDirection, String msgBodyXml) {
-               StringBuilder sb = new StringBuilder("<msg><dms>");
-               sb.append(timestamp);
-               sb.append("</dms><pid>");
-               sb.append(Process.myPid());
-               sb.append("</pid><tid>");
-               sb.append(Thread.currentThread().getId());
-               sb.append("</tid><mod>");
-               sb.append(module.toString());
-               sb.append("</mod>");
-               if (msgDirection != InterfaceActivityDirection.None) {
-                       sb.append("<dir>");
-                       sb.append(interfaceActivityDirectionToString(msgDirection));
-                       sb.append("</dir>");
-               } // end-if
-               sb.append(msgBodyXml);
-               sb.append("</msg>");
-
-               return sb.toString();
-       } // end-method
-
-       private static String interfaceActivityDirectionToString(InterfaceActivityDirection iaDirection) {
-               String str = "";
-               switch (iaDirection) {
-                       case Receive:
-                               str = "rx";
-                               break;
-                       case Transmit:
-                               str = "tx";
-                               break;
-               } // end-switch
-               return str;
-       } // end-method
-
-       static String B64EncodeForXML(String data) {
-               return Mime.base64Encode(data);
-       } // end-method
-       
-       public static void logProxyEvent(String eventText, String token) {
-               if (DiagLevel.getLevel(Mod.proxy) == DetailLevel.OFF || !token.equals(KeyStr)) {
-                       return;
-               } // end-if
-
-               String msg = SyncTrace.B64EncodeForXML(eventText);
-               String xml = SyncTrace.encodeTraceMessage(SyncTrace.getBaseTicsDelta(), Mod.proxy, InterfaceActivityDirection.None, "<d>" + msg + "</d>");
-               writeXmlTraceMessage(xml);
-       } // end-method
-
-       public static void logAppEvent(String eventText) {
-               if (DiagLevel.getLevel(Mod.app) == DetailLevel.OFF) {
-                       return;
-               } // end-if
-
-               long timestamp = SyncTrace.getBaseTicsDelta();
-               String msg = SyncTrace.B64EncodeForXML(eventText);
-               String xml = SyncTrace.encodeTraceMessage(timestamp, Mod.app, InterfaceActivityDirection.None, "<d>" + msg + "</d>");
-               writeXmlTraceMessage(xml);
-       } // end-method
-
-       public static void logRPCEvent(InterfaceActivityDirection msgDirection, RPCMessage rpcMsg, String token) {
-               DetailLevel dl = DiagLevel.getLevel(Mod.rpc);
-               if (dl == DetailLevel.OFF || !token.equals(KeyStr)) {
-                       return;
-               } // end-if
-
-               long timestamp = SyncTrace.getBaseTicsDelta();
-               String xml = SyncTrace.encodeTraceMessage(timestamp, Mod.rpc, msgDirection, rpc2Xml(dl, rpcMsg));
-               writeXmlTraceMessage(xml);
-       } // end-method
-
-       private static String rpc2Xml(DetailLevel dl, RPCMessage rpcMsg) {
-               StringBuilder rpcAsXml = new StringBuilder();
-               rpcAsXml.append("<op>");
-               rpcAsXml.append(rpcMsg.getFunctionName());
-               rpcAsXml.append("</op>");
-               boolean hasCorrelationID = false;
-               Integer correlationID = -1;
-               if (rpcMsg instanceof RPCRequest) {
-                       hasCorrelationID = true;
-                       correlationID = ((RPCRequest)rpcMsg).getCorrelationID();
-               } else if (rpcMsg instanceof RPCResponse) {
-                       hasCorrelationID = true;
-                       correlationID = ((RPCResponse)rpcMsg).getCorrelationID();
-               } // end-if
-               if (hasCorrelationID) {
-                       rpcAsXml.append("<cid>");
-                       rpcAsXml.append(correlationID);
-                       rpcAsXml.append("</cid>");
-               } // end-if
-               rpcAsXml.append("<type>");
-               rpcAsXml.append(rpcMsg.getMessageType());
-               rpcAsXml.append("</type>");
-
-               if (dl == DetailLevel.VERBOSE) {
-                       OpenRPCMessage orpcmsg = new OpenRPCMessage(rpcMsg);
-                       String rpcParamList = orpcmsg.msgDump();
-                       String msg = SyncTrace.B64EncodeForXML(rpcParamList);
-                       rpcAsXml.append("<d>");
-                       rpcAsXml.append(msg);
-                       rpcAsXml.append("</d>");
-               } // end-if
-               return rpcAsXml.toString();
-       } // end-method
-
-       public static void logMarshallingEvent(InterfaceActivityDirection msgDirection, byte[] marshalledMessage, String token) {
-               DetailLevel dl = DiagLevel.getLevel(Mod.mar);
-               if (dl == DetailLevel.OFF || !token.equals(KeyStr)) {
-                       return;
-               } // end-fif
-
-               long timestamp = SyncTrace.getBaseTicsDelta();
-               StringBuilder msg = new StringBuilder();
-               msg.append("<sz>");
-               msg.append(marshalledMessage.length);
-               msg.append("</sz>");
-               if (dl == DetailLevel.VERBOSE) {
-                       msg.append("<d>");
-                       msg.append(Mime.base64Encode(marshalledMessage));
-                       msg.append("</d>");
-               } // end-if
-               String xml = SyncTrace.encodeTraceMessage(timestamp, Mod.mar, msgDirection, msg.toString());
-               writeXmlTraceMessage(xml);
-       } // end-method
-
-       public static void logProtocolEvent(InterfaceActivityDirection frameDirection, ProtocolFrameHeader frameHeader, byte[] frameData, int frameDataOffset, int frameDataLength, String token) {
-               DetailLevel dl = DiagLevel.getLevel(Mod.proto);
-               if (dl == DetailLevel.OFF || !token.equals(KeyStr)) {
-                       return;
-               } // end-if
-
-               StringBuffer protoMsg = new StringBuffer();
-               protoMsg.append("<frame>");
-               protoMsg.append(SyncTrace.getProtocolFrameHeaderInfo(frameHeader, frameData));
-               if (dl == DetailLevel.VERBOSE) {
-                       if (frameData != null && frameDataLength > 0) {
-                               protoMsg.append("<d>");
-                               String bytesInfo = "";
-                               bytesInfo = Mime.base64Encode(frameData, frameDataOffset, frameDataLength);
-                               protoMsg.append(bytesInfo);
-                               protoMsg.append("</d>");
-                       } // end-if
-               } // end-if
-               protoMsg.append("</frame>");
-               String xml = SyncTrace.encodeTraceMessage(SyncTrace.getBaseTicsDelta(), Mod.proto, frameDirection, protoMsg.toString());
-               writeXmlTraceMessage(xml);
-       } // end-method
-
-       private static String getProtocolFrameType(FrameType f) {
-               if (f == FrameType.Control)
-                       return "Control";
-               else if (f == FrameType.Consecutive)
-                       return "Consecutive";
-               else if (f == FrameType.First)
-                       return "First";
-               else if (f == FrameType.Single)
-                       return "Single";
-
-               return "Unknown";
-       } // end-method
-
-       private static String getProtocolSessionType(SessionType serviceType) {
-               String s;
-               if (serviceType == SessionType.RPC )
-                       s = "rpc";
-               else if (serviceType == SessionType.Bulk_Data)
-                       s = "bulk";
-               else
-                       s = "Unknown";
-               return s;
-       } // end-method
-
-       private static String getProtocolFrameHeaderInfo(ProtocolFrameHeader hdr, byte[] buf) {
-               StringBuilder sb = new StringBuilder();
-               sb.append("<hdr>");
-               sb.append("<ver>");
-               sb.append(hdr.getVersion());
-               sb.append("</ver><cmp>");
-               sb.append(hdr.isCompressed());
-               sb.append("</cmp><ft>");
-               sb.append(getProtocolFrameType(hdr.getFrameType()));
-               sb.append("</ft><st>");
-               sb.append(getProtocolSessionType(hdr.getSessionType()));
-               sb.append("</st><sid>");
-               sb.append(hdr.getSessionID());
-               sb.append("</sid><sz>");
-               sb.append(hdr.getDataSize());
-               sb.append("</sz>");
-
-               int frameData = hdr.getFrameData();
-               if (hdr.getFrameType() == FrameType.Control) {
-                       sb.append("<ca>");
-                       if (frameData == FrameDataControlFrameType.StartSession.getValue()) 
-                               sb.append("StartSession");
-                       else if (frameData == FrameDataControlFrameType.StartSessionACK.getValue())
-                               sb.append("StartSessionACK");
-                       else if (frameData == FrameDataControlFrameType.StartSessionNACK.getValue())
-                               sb.append("StartSessionNACK");
-                       else if (frameData == FrameDataControlFrameType.EndSession.getValue())
-                               sb.append("EndSession");
-                       sb.append("</ca>");
-               } else if (hdr.getFrameType() == FrameType.Consecutive ) {
-                       sb.append("<fsn>");
-                       if (frameData == 0 )
-                               sb.append("lastFrame");
-                       else
-                               sb.append(String.format("%02X",frameData)); 
-                       sb.append("</fsn>");
-               } else if (hdr.getFrameType() == FrameType.First ) {
-                       int totalSize = BitConverter.intFromByteArray(buf, 0);                  
-                       int numFrames = BitConverter.intFromByteArray(buf, 4);
-                       sb.append("<total>" + totalSize + "</total><numframes>" + numFrames + "</numframes>");
-               } else if (hdr.getFrameType() == FrameType.Single ) {
-                       sb.append("<single/>");
-               }
-
-               sb.append("</hdr>");
-
-               return sb.toString();
-       } // end-method
-
-       public static String getBTDeviceInfo(BluetoothDevice btDevice) {
-               StringBuilder sb = new StringBuilder();
-               sb.append("<btp>");
-               String btdn = btDevice.getName();
-               sb.append("<btn>");
-               sb.append(SyncTrace.B64EncodeForXML(btdn));
-               sb.append("</btn>");
-               sb.append("<bta>" + btDevice.getAddress() + "</bta>");
-               sb.append("<bts>" + btDevice.getBondState() + "</bts>");
-               sb.append("</btp>");
-               return sb.toString();
-       } // end-method
-
-       public static void logTransportEvent(String preamble, String transportSpecificInfoXml, InterfaceActivityDirection msgDirection, byte buf[], int byteLength, String token) {
-               logTransportEvent(preamble, transportSpecificInfoXml, msgDirection, buf, 0, byteLength, token);
-       } // end-method
-
-       private static void checkB64(String x, byte[] buf, int offset, int byteLength) {
-               if ((x.length() % 4) != 0) {
-                       NativeLogTool.logWarning(SyncTrace.SYSTEM_LOG_TAG, "b64 string length (" + x.length() + ") isn't multiple of 4: buf.length=" + buf.length + ", offset=" + offset + ", len=" + byteLength);
-               } // end-if
-       } // end-method
-
-       public static void logTransportEvent(String preamble, String transportSpecificInfoXml, InterfaceActivityDirection msgDirection, byte buf[], int offset, int byteLength, String token) {
-               if (DiagLevel.getLevel(Mod.tran) == DetailLevel.OFF || !token.equals(KeyStr)) {
-                       return;
-               } // end-if
-
-               StringBuilder msg = new StringBuilder();
-               if (transportSpecificInfoXml != null && transportSpecificInfoXml.length() > 0) {
-                       msg.append(transportSpecificInfoXml);
-               } // end-if
-               if (preamble != null && preamble.length() > 0) {
-                       msg.append("<desc>");
-                       msg.append(preamble);
-                       msg.append("</desc>");
-               } // end-if
-               if (buf != null) {
-                       msg.append("<sz>");
-                       msg.append(byteLength);
-                       msg.append("</sz>");
-                       DetailLevel dl = DiagLevel.getLevel(Mod.tran);
-                       if (dl == DetailLevel.VERBOSE) {
-                               if (buf != null && byteLength > 0) {
-                                       msg.append("<d>");
-                                       String bytesInfo = Mime.base64Encode(buf, offset, byteLength);
-                                       checkB64(bytesInfo, buf, offset, byteLength);
-                                       msg.append(bytesInfo);
-                                       msg.append("</d>");
-                               } // end-if
-                       } // end-if
-               } // end-if
-               String xml = SyncTrace.encodeTraceMessage(SyncTrace.getBaseTicsDelta(), Mod.tran, msgDirection, msg.toString());
-               writeXmlTraceMessage(xml);
-       } // end-method
-
-       // Package-scoped
-       static long getBaseTicsDelta() {
-               return java.lang.System.currentTimeMillis() - getBaseTics();
-       }
-
-       // Package-scoped
-       static long getBaseTics() {
-               return baseTics;
-       } // end-method
-
-       public static Boolean writeMessageToSiphonServer(String info) {
-               return SiphonServer.sendFormattedTraceMessage(info);
-       }
-
-       private static void writeXmlTraceMessage(String msg) {
-               try {                   
-                       // Attempt to write formatted message to the Siphon
-                       if (false == writeMessageToSiphonServer(msg)) {
-                               // If writing to the Siphon fails, write to the native log
-                               NativeLogTool.logInfo(SyncTrace.SYSTEM_LOG_TAG, msg);
-                       }
-                       
-                       ISTListener localTraceListener = m_appTraceListener;
-
-                       if (localTraceListener != null) {
-                               try {
-                                       localTraceListener.logXmlMsg(msg, KeyStr);
-                               } catch (Exception ex) {
-                                       DebugTool.logError("Failure calling ISTListener: " + ex.toString(), ex);
-                               } // end-catch
-                       } // end-if
-               } catch (Exception ex) {
-                       NativeLogTool.logError(SyncTrace.SYSTEM_LOG_TAG, "Failure writing XML trace message: " + ex.toString());
-               }
-       } // end-method
-       
-       // Package-scoped
-       public static String getLogHeader(String dumpReason, int seqNo) {
-               final String Sep = "-";
-               StringBuilder write = new StringBuilder("<?xml version=\"1.0\"?>" + "<logs>");
-               write.append("<info>");
-               StringBuilder infoBlock = new StringBuilder();
-               String hostInfo = Build.BRAND + Sep + Build.MANUFACTURER + Sep + Build.MODEL + "(" + Build.HOST + ")";
-               infoBlock.append("<host>" + SyncTrace.B64EncodeForXML(hostInfo) + "</host>");
-               String osv = Build.VERSION.RELEASE + " (" + Build.VERSION.CODENAME + ")";
-               infoBlock.append("<osv>" + SyncTrace.B64EncodeForXML(osv) + "</osv>");
-               infoBlock.append(TraceDeviceInfo.getTelephonyHeader());
-
-               long heapSize = Debug.getNativeHeapFreeSize() / 1024;
-               long heapAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
-               infoBlock.append("<mem><hf>" + heapSize + "KB</hf><ha>" + heapAllocated + "KB</ha></mem>");
-               infoBlock.append("<np>" + Runtime.getRuntime().availableProcessors() + "</np>");
-               infoBlock.append("<pid>" + Process.myPid() + "</pid>");
-               infoBlock.append("<tid>" + Thread.currentThread().getId() + "</tid>");
-
-               Timestamp stamp = new Timestamp(SyncTrace.getBaseTics());
-               String GMTtime = stamp.toGMTString().substring(0, 19);
-               long fracSec = stamp.getNanos() / 1000000; // divide by a million
-               String fracSecStr = String.format("%03d", fracSec);
-               infoBlock.append("<utc>" + GMTtime + "." + fracSecStr + "</utc>");
-
-               infoBlock.append(TraceDeviceInfo.getLogHeaderBluetoothPairs());
-               infoBlock.append(getSmartDeviceLinkTraceRoot(dumpReason, seqNo));
-
-               write.append(infoBlock);
-
-               write.append("</info>" + "<msgs>");
-               return write.toString();
-       } // end-method
-       
-       private static String getSmartDeviceLinkTraceRoot(String dumpReason, int seqNo) {
-               StringBuilder write = new StringBuilder("<SmartDeviceLinktraceroot>" + "<sequencenum>" + seqNo
-                               + "</sequencenum>" + "<dumpreason>" + dumpReason
-                               + "</dumpreason><tracelevel>");
-
-               write.append("<tran>" + DiagLevel.getLevel(Mod.tran) + "</tran>");
-               write.append("<proto>" + DiagLevel.getLevel(Mod.proto) + "</proto>");
-               write.append("<mar>" + DiagLevel.getLevel(Mod.mar) + "</mar>");
-               write.append("<rpc>" + DiagLevel.getLevel(Mod.rpc) + "</rpc>");
-               write.append("<proxy>" + DiagLevel.getLevel(Mod.proxy) + "</proxy>");
-               write.append("<app>" + DiagLevel.getLevel(Mod.app) + "</app>");
-
-               write.append("</tracelevel>");
-               write.append("</SmartDeviceLinktraceroot>");
-               return write.toString();
-       } // end-method
-} // end-class
+package com.smartdevicelink.trace;\r
+\r
+import java.sql.Timestamp;\r
+\r
+import android.bluetooth.BluetoothDevice;\r
+import android.os.Build;\r
+import android.os.Debug;\r
+import android.os.Process;\r
+\r
+import com.smartdevicelink.protocol.ProtocolFrameHeader;\r
+import com.smartdevicelink.protocol.enums.FrameDataControlFrameType;\r
+import com.smartdevicelink.protocol.enums.FrameType;\r
+import com.smartdevicelink.protocol.enums.SessionType;\r
+import com.smartdevicelink.proxy.RPCMessage;\r
+import com.smartdevicelink.proxy.RPCRequest;\r
+import com.smartdevicelink.proxy.RPCResponse;\r
+import com.smartdevicelink.trace.enums.DetailLevel;\r
+import com.smartdevicelink.trace.enums.InterfaceActivityDirection;\r
+import com.smartdevicelink.trace.enums.Mod;\r
+import com.smartdevicelink.transport.SiphonServer;\r
+import com.smartdevicelink.util.BitConverter;\r
+import com.smartdevicelink.util.DebugTool;\r
+import com.smartdevicelink.util.NativeLogTool;\r
+\r
+/* This class handles the global TraceSettings as requested by the users either through the combination of the following\r
+   1. System defaults\r
+   2. Application XML config\r
+   3. Programmatic requests from application itself\r
+\r
+   It is manifested in the <applink>...</applink> tags\r
+ */\r
+\r
+public class SmartDeviceLinkTrace {\r
+       private static final String SMARTDEVICELINK_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66";\r
+       \r
+       static boolean canWriteLogs = false;\r
+               \r
+       public static final String SYSTEM_LOG_TAG = "SmartDeviceLinkTrace";\r
+       \r
+       private static long baseTics  = java.lang.System.currentTimeMillis();\r
+       private final static String KeyStr = SMARTDEVICELINK_LIB_TRACE_KEY;\r
+       private static boolean acceptAPITraceAdjustments = true;\r
+\r
+       protected static ISTListener m_appTraceListener = null;\r
+\r
+       ///\r
+       ///  The PUBLIC interface to SmartDeviceLinkTrace starts here\r
+       ///\r
+\r
+\r
+       public static void setAcceptAPITraceAdjustments(Boolean APITraceAdjustmentsAccepted) {\r
+               if (APITraceAdjustmentsAccepted != null) {\r
+                       acceptAPITraceAdjustments = APITraceAdjustmentsAccepted;\r
+               }\r
+       }\r
+       \r
+       public static boolean getAcceptAPITraceAdjustments() {\r
+               return acceptAPITraceAdjustments;\r
+       }\r
+       \r
+       public static void setAppTraceListener(ISTListener listener) {\r
+               m_appTraceListener = listener;\r
+       } // end-method\r
+\r
+       public static void setTracingEnable(Boolean enable) {\r
+               if (enable != null) {\r
+                       canWriteLogs = enable;\r
+               }\r
+       } // end-method\r
+\r
+       public static void setAppTraceLevel(DetailLevel dt) {\r
+               if ( dt != null && acceptAPITraceAdjustments)\r
+                       DiagLevel.setLevel(Mod.app, dt);\r
+       } // end-method\r
+\r
+       public static void setProxyTraceLevel(DetailLevel dt) {\r
+               if (dt != null && acceptAPITraceAdjustments)\r
+                       DiagLevel.setLevel(Mod.proxy, dt);\r
+       } // end-method\r
+\r
+       public static void setRpcTraceLevel(DetailLevel dt) {\r
+               if (dt != null && acceptAPITraceAdjustments)\r
+                       DiagLevel.setLevel(Mod.rpc, dt);\r
+       } // end-method\r
+\r
+       public static void setMarshallingTraceLevel(DetailLevel dt) {\r
+               if (dt != null && acceptAPITraceAdjustments)\r
+                       DiagLevel.setLevel(Mod.mar, dt);\r
+       } // end-method\r
+\r
+       public static void setProtocolTraceLevel(DetailLevel dt) {\r
+               if (dt != null && acceptAPITraceAdjustments)\r
+                       DiagLevel.setLevel(Mod.proto, dt);\r
+       } // end-method\r
+\r
+       public static void setTransportTraceLevel(DetailLevel dt) {\r
+               if (dt != null && acceptAPITraceAdjustments)\r
+                               DiagLevel.setLevel(Mod.tran, dt);\r
+       } // end-method\r
+\r
+       private static String encodeTraceMessage(long timestamp, Mod module, InterfaceActivityDirection msgDirection, String msgBodyXml) {\r
+               StringBuilder sb = new StringBuilder("<msg><dms>");\r
+               sb.append(timestamp);\r
+               sb.append("</dms><pid>");\r
+               sb.append(Process.myPid());\r
+               sb.append("</pid><tid>");\r
+               sb.append(Thread.currentThread().getId());\r
+               sb.append("</tid><mod>");\r
+               sb.append(module.toString());\r
+               sb.append("</mod>");\r
+               if (msgDirection != InterfaceActivityDirection.None) {\r
+                       sb.append("<dir>");\r
+                       sb.append(interfaceActivityDirectionToString(msgDirection));\r
+                       sb.append("</dir>");\r
+               } // end-if\r
+               sb.append(msgBodyXml);\r
+               sb.append("</msg>");\r
+\r
+               return sb.toString();\r
+       } // end-method\r
+\r
+       private static String interfaceActivityDirectionToString(InterfaceActivityDirection iaDirection) {\r
+               String str = "";\r
+               switch (iaDirection) {\r
+                       case Receive:\r
+                               str = "rx";\r
+                               break;\r
+                       case Transmit:\r
+                               str = "tx";\r
+                               break;\r
+               } // end-switch\r
+               return str;\r
+       } // end-method\r
+\r
+       static String B64EncodeForXML(String data) {\r
+               return Mime.base64Encode(data);\r
+               // Base64 only available in 2.2, when SmartDeviceLink base is 2.2 use: return Base64.encodeToString(data.getBytes(), Base64.DEFAULT);\r
+       } // end-method\r
+       \r
+       public static void logProxyEvent(String eventText, String token) {\r
+               if (DiagLevel.getLevel(Mod.proxy) == DetailLevel.OFF || !token.equals(KeyStr)) {\r
+                       return;\r
+               } // end-if\r
+\r
+               String msg = SmartDeviceLinkTrace.B64EncodeForXML(eventText);\r
+               String xml = SmartDeviceLinkTrace.encodeTraceMessage(SmartDeviceLinkTrace.getBaseTicsDelta(), Mod.proxy, InterfaceActivityDirection.None, "<d>" + msg + "</d>");\r
+               writeXmlTraceMessage(xml);\r
+       } // end-method\r
+\r
+       public static void logAppEvent(String eventText) {\r
+               if (DiagLevel.getLevel(Mod.app) == DetailLevel.OFF) {\r
+                       return;\r
+               } // end-if\r
+\r
+               long timestamp = SmartDeviceLinkTrace.getBaseTicsDelta();\r
+               String msg = SmartDeviceLinkTrace.B64EncodeForXML(eventText);\r
+               String xml = SmartDeviceLinkTrace.encodeTraceMessage(timestamp, Mod.app, InterfaceActivityDirection.None, "<d>" + msg + "</d>");\r
+               writeXmlTraceMessage(xml);\r
+       } // end-method\r
+\r
+       public static void logRPCEvent(InterfaceActivityDirection msgDirection, RPCMessage rpcMsg, String token) {\r
+               DetailLevel dl = DiagLevel.getLevel(Mod.rpc);\r
+               if (dl == DetailLevel.OFF || !token.equals(KeyStr)) {\r
+                       return;\r
+               } // end-if\r
+\r
+               long timestamp = SmartDeviceLinkTrace.getBaseTicsDelta();\r
+               String xml = SmartDeviceLinkTrace.encodeTraceMessage(timestamp, Mod.rpc, msgDirection, rpc2Xml(dl, rpcMsg));\r
+               writeXmlTraceMessage(xml);\r
+       } // end-method\r
+\r
+       private static String rpc2Xml(DetailLevel dl, RPCMessage rpcMsg) {\r
+               StringBuilder rpcAsXml = new StringBuilder();\r
+               rpcAsXml.append("<op>");\r
+               rpcAsXml.append(rpcMsg.getFunctionName());\r
+               rpcAsXml.append("</op>");\r
+               boolean hasCorrelationID = false;\r
+               Integer correlationID = -1;\r
+               if (rpcMsg instanceof RPCRequest) {\r
+                       hasCorrelationID = true;\r
+                       correlationID = ((RPCRequest)rpcMsg).getCorrelationID();\r
+               } else if (rpcMsg instanceof RPCResponse) {\r
+                       hasCorrelationID = true;\r
+                       correlationID = ((RPCResponse)rpcMsg).getCorrelationID();\r
+               } // end-if\r
+               if (hasCorrelationID) {\r
+                       rpcAsXml.append("<cid>");\r
+                       rpcAsXml.append(correlationID);\r
+                       rpcAsXml.append("</cid>");\r
+               } // end-if\r
+               rpcAsXml.append("<type>");\r
+               rpcAsXml.append(rpcMsg.getMessageType());\r
+               rpcAsXml.append("</type>");\r
+               //rpcAsXml.append(newline);\r
+\r
+               if (dl == DetailLevel.VERBOSE) {\r
+                       OpenRPCMessage orpcmsg = new OpenRPCMessage(rpcMsg);\r
+                       String rpcParamList = orpcmsg.msgDump();\r
+                       String msg = SmartDeviceLinkTrace.B64EncodeForXML(rpcParamList);\r
+                       rpcAsXml.append("<d>");\r
+                       rpcAsXml.append(msg);\r
+                       rpcAsXml.append("</d>");\r
+               } // end-if\r
+               return rpcAsXml.toString();\r
+       } // end-method\r
+\r
+       public static void logMarshallingEvent(InterfaceActivityDirection msgDirection, byte[] marshalledMessage, String token) {\r
+               DetailLevel dl = DiagLevel.getLevel(Mod.mar);\r
+               if (dl == DetailLevel.OFF || !token.equals(KeyStr)) {\r
+                       return;\r
+               } // end-fif\r
+\r
+               long timestamp = SmartDeviceLinkTrace.getBaseTicsDelta();\r
+               StringBuilder msg = new StringBuilder();\r
+               msg.append("<sz>");\r
+               msg.append(marshalledMessage.length);\r
+               msg.append("</sz>");\r
+               if (dl == DetailLevel.VERBOSE) {\r
+                       msg.append("<d>");\r
+                       msg.append(Mime.base64Encode(marshalledMessage));\r
+                       // Base64 only available in 2.2, when SmartDeviceLink base is 2.2 use: msg.append(Base64.encodeToString(marshalledMessage, Base64.DEFAULT));\r
+                       msg.append("</d>");\r
+               } // end-if\r
+               String xml = SmartDeviceLinkTrace.encodeTraceMessage(timestamp, Mod.mar, msgDirection, msg.toString());\r
+               writeXmlTraceMessage(xml);\r
+       } // end-method\r
+\r
+       public static void logProtocolEvent(InterfaceActivityDirection frameDirection, ProtocolFrameHeader frameHeader, byte[] frameData, int frameDataOffset, int frameDataLength, String token) {\r
+               DetailLevel dl = DiagLevel.getLevel(Mod.proto);\r
+               if (dl == DetailLevel.OFF || !token.equals(KeyStr)) {\r
+                       return;\r
+               } // end-if\r
+\r
+               StringBuffer protoMsg = new StringBuffer();\r
+               protoMsg.append("<frame>");\r
+               protoMsg.append(SmartDeviceLinkTrace.getProtocolFrameHeaderInfo(frameHeader, frameData));\r
+               if (dl == DetailLevel.VERBOSE) {\r
+                       if (frameData != null && frameDataLength > 0) {\r
+                               protoMsg.append("<d>");\r
+                               String bytesInfo = "";\r
+                               bytesInfo = Mime.base64Encode(frameData, frameDataOffset, frameDataLength);\r
+                               // Base64 only available in 2.2, when SmartDeviceLink base is 2.2 use: bytesInfo = Base64.encodeToString(frameData, frameDataOffset, frameDataLength, Base64.DEFAULT);\r
+                               protoMsg.append(bytesInfo);\r
+                               protoMsg.append("</d>");\r
+                       } // end-if\r
+               } // end-if\r
+               protoMsg.append("</frame>");\r
+               String xml = SmartDeviceLinkTrace.encodeTraceMessage(SmartDeviceLinkTrace.getBaseTicsDelta(), Mod.proto, frameDirection, protoMsg.toString());\r
+               writeXmlTraceMessage(xml);\r
+       } // end-method\r
+\r
+       private static String getProtocolFrameType(FrameType f) {\r
+               if (f == FrameType.Control)\r
+                       return "Control";\r
+               else if (f == FrameType.Consecutive)\r
+                       return "Consecutive";\r
+               else if (f == FrameType.First)\r
+                       return "First";\r
+               else if (f == FrameType.Single)\r
+                       return "Single";\r
+\r
+               return "Unknown";\r
+       } // end-method\r
+\r
+       private static String getProtocolSessionType(SessionType serviceType) {\r
+               String s;\r
+               if (serviceType == SessionType.RPC )\r
+                       s = "rpc";\r
+               else if (serviceType == SessionType.Bulk_Data)\r
+                       s = "bulk";\r
+               else\r
+                       s = "Unknown";\r
+               return s;\r
+       } // end-method\r
+\r
+       private static String getProtocolFrameHeaderInfo(ProtocolFrameHeader hdr, byte[] buf) {\r
+               StringBuilder sb = new StringBuilder();\r
+               sb.append("<hdr>");\r
+               sb.append("<ver>");\r
+               sb.append(hdr.getVersion());\r
+               sb.append("</ver><cmp>");\r
+               sb.append(hdr.isCompressed());\r
+               sb.append("</cmp><ft>");\r
+               sb.append(getProtocolFrameType(hdr.getFrameType()));\r
+               sb.append("</ft><st>");\r
+               sb.append(getProtocolSessionType(hdr.getSessionType()));\r
+               sb.append("</st><sid>");\r
+               sb.append(hdr.getSessionID());\r
+               sb.append("</sid><sz>");\r
+               sb.append(hdr.getDataSize());\r
+               sb.append("</sz>");\r
+\r
+               int frameData = hdr.getFrameData();\r
+               if (hdr.getFrameType() == FrameType.Control) {\r
+                       sb.append("<ca>");\r
+                       if (frameData == FrameDataControlFrameType.StartSession.getValue()) \r
+                               sb.append("StartSession");\r
+                       else if (frameData == FrameDataControlFrameType.StartSessionACK.getValue())\r
+                               sb.append("StartSessionACK");\r
+                       else if (frameData == FrameDataControlFrameType.StartSessionNACK.getValue())\r
+                               sb.append("StartSessionNACK");\r
+                       else if (frameData == FrameDataControlFrameType.EndSession.getValue())\r
+                               sb.append("EndSession");\r
+                       sb.append("</ca>");\r
+               } else if (hdr.getFrameType() == FrameType.Consecutive ) {\r
+                       sb.append("<fsn>");\r
+                       if (frameData == 0 )\r
+                               sb.append("lastFrame");\r
+                       else\r
+                               sb.append(String.format("%02X",frameData)); \r
+                       sb.append("</fsn>");\r
+               } else if (hdr.getFrameType() == FrameType.First ) {\r
+                       int totalSize = BitConverter.intFromByteArray(buf, 0);                  \r
+                       int numFrames = BitConverter.intFromByteArray(buf, 4);\r
+                       sb.append("<total>" + totalSize + "</total><numframes>" + numFrames + "</numframes>");\r
+               } else if (hdr.getFrameType() == FrameType.Single ) {\r
+                       sb.append("<single/>");\r
+               }\r
+\r
+               sb.append("</hdr>");\r
+\r
+               return sb.toString();\r
+       } // end-method\r
+\r
+       public static String getBTDeviceInfo(BluetoothDevice btDevice) {\r
+               StringBuilder sb = new StringBuilder();\r
+               sb.append("<btp>");\r
+               String btdn = btDevice.getName();\r
+               sb.append("<btn>");\r
+               sb.append(SmartDeviceLinkTrace.B64EncodeForXML(btdn));\r
+               sb.append("</btn>");\r
+               sb.append("<bta>" + btDevice.getAddress() + "</bta>");\r
+               sb.append("<bts>" + btDevice.getBondState() + "</bts>");\r
+               sb.append("</btp>");\r
+               return sb.toString();\r
+       } // end-method\r
+\r
+       public static void logTransportEvent(String preamble, String transportSpecificInfoXml, InterfaceActivityDirection msgDirection, byte buf[], int byteLength, String token) {\r
+               logTransportEvent(preamble, transportSpecificInfoXml, msgDirection, buf, 0, byteLength, token);\r
+       } // end-method\r
+\r
+       private static void checkB64(String x, byte[] buf, int offset, int byteLength) {\r
+               if ((x.length() % 4) != 0) {\r
+                       NativeLogTool.logWarning(SmartDeviceLinkTrace.SYSTEM_LOG_TAG, "b64 string length (" + x.length() + ") isn't multiple of 4: buf.length=" + buf.length + ", offset=" + offset + ", len=" + byteLength);\r
+               } // end-if\r
+       } // end-method\r
+\r
+       public static void logTransportEvent(String preamble, String transportSpecificInfoXml, InterfaceActivityDirection msgDirection, byte buf[], int offset, int byteLength, String token) {\r
+               if (DiagLevel.getLevel(Mod.tran) == DetailLevel.OFF || !token.equals(KeyStr)) {\r
+                       return;\r
+               } // end-if\r
+\r
+               StringBuilder msg = new StringBuilder();\r
+               if (transportSpecificInfoXml != null && transportSpecificInfoXml.length() > 0) {\r
+                       msg.append(transportSpecificInfoXml);\r
+               } // end-if\r
+               if (preamble != null && preamble.length() > 0) {\r
+                       msg.append("<desc>");\r
+                       msg.append(preamble);\r
+                       msg.append("</desc>");\r
+               } // end-if\r
+               if (buf != null) {\r
+                       msg.append("<sz>");\r
+                       msg.append(byteLength);\r
+                       msg.append("</sz>");\r
+                       DetailLevel dl = DiagLevel.getLevel(Mod.tran);\r
+                       if (dl == DetailLevel.VERBOSE) {\r
+                               if (buf != null && byteLength > 0) {\r
+                                       msg.append("<d>");\r
+                                       String bytesInfo = Mime.base64Encode(buf, offset, byteLength);\r
+                                       checkB64(bytesInfo, buf, offset, byteLength);\r
+                                       msg.append(bytesInfo);\r
+                                       msg.append("</d>");\r
+                               } // end-if\r
+                       } // end-if\r
+               } // end-if\r
+               String xml = SmartDeviceLinkTrace.encodeTraceMessage(SmartDeviceLinkTrace.getBaseTicsDelta(), Mod.tran, msgDirection, msg.toString());\r
+               writeXmlTraceMessage(xml);\r
+       } // end-method\r
+\r
+       // Package-scoped\r
+       static long getBaseTicsDelta() {\r
+               return java.lang.System.currentTimeMillis() - getBaseTics();\r
+       }\r
+\r
+       // Package-scoped\r
+       static long getBaseTics() {\r
+               return baseTics;\r
+       } // end-method\r
+\r
+       public static Boolean writeMessageToSiphonServer(String info) {\r
+               return SiphonServer.sendFormattedTraceMessage(info);\r
+       }\r
+\r
+       private static void writeXmlTraceMessage(String msg) {\r
+               try {                   \r
+                       // Attempt to write formatted message to the Siphon\r
+                       if (false == writeMessageToSiphonServer(msg)) {\r
+                               // If writing to the Siphon fails, write to the native log\r
+                               NativeLogTool.logInfo(SmartDeviceLinkTrace.SYSTEM_LOG_TAG, msg);\r
+                       }\r
+                       \r
+                       ISTListener localTraceListener = m_appTraceListener;\r
+\r
+                       if (localTraceListener != null) {\r
+                               try {\r
+                                       localTraceListener.logXmlMsg(msg, KeyStr);\r
+                               } catch (Exception ex) {\r
+                                       DebugTool.logError("Failure calling ISTListener: " + ex.toString(), ex);\r
+                               } // end-catch\r
+                       } // end-if\r
+               } catch (Exception ex) {\r
+                       NativeLogTool.logError(SmartDeviceLinkTrace.SYSTEM_LOG_TAG, "Failure writing XML trace message: " + ex.toString());\r
+               }\r
+       } // end-method\r
+       \r
+       // Package-scoped\r
+       public static String getLogHeader(String dumpReason, int seqNo) {\r
+               final String Sep = "-";\r
+               StringBuilder write = new StringBuilder("<?xml version=\"1.0\"?>" + "<logs>");\r
+               write.append("<info>");\r
+               StringBuilder infoBlock = new StringBuilder();\r
+               String hostInfo = Build.BRAND + Sep + Build.MANUFACTURER + Sep + Build.MODEL + "(" + Build.HOST + ")";\r
+               infoBlock.append("<host>" + SmartDeviceLinkTrace.B64EncodeForXML(hostInfo) + "</host>");\r
+               String osv = Build.VERSION.RELEASE + " (" + Build.VERSION.CODENAME + ")";\r
+               infoBlock.append("<osv>" + SmartDeviceLinkTrace.B64EncodeForXML(osv) + "</osv>");\r
+               infoBlock.append(TraceDeviceInfo.getTelephonyHeader());\r
+\r
+               long heapSize = Debug.getNativeHeapFreeSize() / 1024;\r
+               long heapAllocated = Debug.getNativeHeapAllocatedSize() / 1024;\r
+               infoBlock.append("<mem><hf>" + heapSize + "KB</hf><ha>" + heapAllocated + "KB</ha></mem>");\r
+               infoBlock.append("<np>" + Runtime.getRuntime().availableProcessors() + "</np>");\r
+               infoBlock.append("<pid>" + Process.myPid() + "</pid>");\r
+               infoBlock.append("<tid>" + Thread.currentThread().getId() + "</tid>");\r
+\r
+               // String dateStamp = (String)\r
+               // DateFormat.format("yy-MM-dd hh:mm:ss SSS", new Timestamp(baseTics));\r
+               Timestamp stamp = new Timestamp(SmartDeviceLinkTrace.getBaseTics());\r
+               String GMTtime = stamp.toGMTString().substring(0, 19);\r
+               long fracSec = stamp.getNanos() / 1000000; // divide by a million\r
+               String fracSecStr = String.format("%03d", fracSec);\r
+               infoBlock.append("<utc>" + GMTtime + "." + fracSecStr + "</utc>");\r
+\r
+               infoBlock.append(TraceDeviceInfo.getLogHeaderBluetoothPairs());\r
+               infoBlock.append(getApplinkTraceRoot(dumpReason, seqNo));\r
+\r
+               write.append(infoBlock);\r
+\r
+               write.append("</info>" + "<msgs>");\r
+               return write.toString();\r
+       } // end-method\r
+       \r
+       private static String getApplinkTraceRoot(String dumpReason, int seqNo) {\r
+               StringBuilder write = new StringBuilder("<applinktraceroot>" + "<sequencenum>" + seqNo\r
+                               + "</sequencenum>" + "<dumpreason>" + dumpReason\r
+                               + "</dumpreason><tracelevel>");\r
+\r
+               write.append("<tran>" + DiagLevel.getLevel(Mod.tran) + "</tran>");\r
+               write.append("<proto>" + DiagLevel.getLevel(Mod.proto) + "</proto>");\r
+               write.append("<mar>" + DiagLevel.getLevel(Mod.mar) + "</mar>");\r
+               write.append("<rpc>" + DiagLevel.getLevel(Mod.rpc) + "</rpc>");\r
+               write.append("<proxy>" + DiagLevel.getLevel(Mod.proxy) + "</proxy>");\r
+               write.append("<app>" + DiagLevel.getLevel(Mod.app) + "</app>");\r
+\r
+               write.append("</tracelevel>");\r
+               write.append("</applinktraceroot>");\r
+               return write.toString();\r
+       } // end-method\r
+} // end-class
\ No newline at end of file