using System; using Microsoft.SPOT; using System.IO.Ports; using System.Text; using System.Threading; using SWModules; using HWModules; namespace SensorModules { // This is a Singleton instantiation of FIFOQueue class based on // C# in Depth, Third Edition Jon Skeet // http://csharpindepth.com/Articles/General/Singleton.aspx // "a singleton is a class which only allows a single instance of itself to be created, and usually gives simple access to that instance" public sealed class IridiumModem1 : NAL_A3LAR { private IridiumModem1() : base("IridiumModem1", "COM3", 19200, Parity.None, 8, StopBits.One, 5000, 20, false, (byte)0) { MotherBoard mb = MotherBoard.Instance; } private static IridiumModem1 instance; public static IridiumModem1 Instance { get { instance = instance ?? (new IridiumModem1()); return instance; } } } public class NAL_A3LAR { public enum ReturnCodes : int { none = 0, CSQ, SBDWT, SBDIX, } public int returnCode; public NativeUART IOPort; private MotherBoard motherboard = MotherBoard.Instance; private string id; private BTConsole btConsole; public NAL_A3LAR(string id, string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, int readTimeout, int writeTimeout, bool useSTX, byte STX) { btConsole = BTConsole.Instance; id = "IModem"; IOPort = new NativeUART(id, QRecordType.IModem ,processMessage, portName, baudRate, parity, dataBits, stopBits, readTimeout, writeTimeout, useSTX, STX); } public NAL_A3LAR() { } public void init() { if (!IOPort.IsOpen) { IOPort.Open(); AttachDataHandler(); } IOPort.DiscardInBuffer(); IOPort.DiscardOutBuffer(); Thread.Sleep(3000); sendD0(); Thread.Sleep(1000); sendK0(); Thread.Sleep(1000); sendSBDD2(); Thread.Sleep(1000); sendGSN(); Thread.Sleep(1000); sendSBDC(); Thread.Sleep(1000); sendNoEcho(); Thread.Sleep(1000); sendCICCID(); } public void simpleInit() { if (!IOPort.IsOpen) { IOPort.Open(); AttachDataHandler(); } IOPort.DiscardInBuffer(); IOPort.DiscardOutBuffer(); } public void powerUp() { EngrLogger.writeToColumns("IModem Powering up"); motherboard.EnableChannelPower(MotherBoard.ChannelNames.IridiumChannel); init(); } public void powerDown() { EngrLogger.writeToColumns("IModem Powering down"); motherboard.DisableChannelPower(MotherBoard.ChannelNames.IridiumChannel); } private static readonly StringBuilder IModemHeader = new StringBuilder("IModem Message"); public void processMessage(QRecord qRecord) { if (qRecord.byteArray[0] == (byte)'$') { EngrLogger.Comment("Sending $ Line to BTConsole."); btConsole.processConsoleCommand(qRecord.byteArray); } EngrLogger.writeToColumns(EngrLiterals.ColumnNums.dateTime, qRecord.timeStamp, EngrLiterals.ColumnNums.state, qRecord.state, EngrLiterals.ColumnNums.comment, IModemHeader, EngrLiterals.ColumnNums.IModem, qRecord.byteArray); //Check for expected response if (waitingForResponse && !gotResponse) checkResponse(qRecord.byteArray); } private static readonly byte[] a3laAT = Encoding.UTF8.GetBytes("AT\r"); public int sendAT() { WriteArray(a3laAT); return (1); } //Reset the MOMSN (mobile origniated message sequence number private static readonly byte[] a3laSBDC = Encoding.UTF8.GetBytes("AT+SBDC\r"); public int sendSBDC() { //Debug.Print(DateTime.Now + " Sending SBDC"); WriteArray(a3laSBDC); return (1); } //Get the IMEI number private static readonly byte[] a3laGSN = Encoding.UTF8.GetBytes("AT+GSN\r"); public int sendGSN() { //Debug.Print(DateTime.Now + " Sending GSN"); WriteArray(a3laGSN); IOPort.WriteByte(13); return (1); } private static readonly byte[] a3laCSQ = Encoding.UTF8.GetBytes("AT+CSQ\r"); public int sendCSQ() { //Debug.Print(DateTime.Now + " Sending CSQ"); WriteArray(a3laCSQ); return (1); } private static readonly byte[] a3laD0 = Encoding.UTF8.GetBytes("AT&D0\r"); public void sendD0() { //Debug.Print(DateTime.Now + " Sending D0"); WriteArray(a3laD0); } private static readonly byte[] setFactoryDefault = Encoding.UTF8.GetBytes("AT&F0\r"); public void sendFactoryDefault() { //Debug.Print(DateTime.Now + " Sending D0"); WriteArray(setFactoryDefault); } private static readonly byte[] baEscapeSeq = Encoding.UTF8.GetBytes("+"); public void sendEscapeSequence() { //Debug.Print(DateTime.Now + " Sending Escape Sequence"); WriteArray(baEscapeSeq); Thread.Sleep(150); WriteArray(baEscapeSeq); Thread.Sleep(250); WriteArray(baEscapeSeq); } private static readonly byte[] noEcho = Encoding.UTF8.GetBytes("ATEn=0\r"); public void sendNoEcho() { //Debug.Print(DateTime.Now + " Sending No Echo"); WriteArray(noEcho); } private static readonly byte[] a3laK0 = Encoding.UTF8.GetBytes("AT&K0\r"); public void sendK0() { //Debug.Print(DateTime.Now + " Sending K0"); WriteArray(a3laK0); } private StringBuilder sbdwtMsg = new StringBuilder("EMPTY"); public StringBuilder SBDWTMsg { get { return sbdwtMsg; } set { sbdwtMsg = value; } } private static readonly StringBuilder sbTemp = new StringBuilder(2000); private static byte[] baCR = new byte[] { 13 }; public int loadSBDWTBuffer() { int msgLength = 0; if (sbdwtMsg.Length > 1910) { EngrLogger.Comment("[ERROR] SBDWT Buffer length exceeds 1910 characters"); msgLength = 1910; } else msgLength = sbdwtMsg.Length; IOPort.Write(UTF8Encoding.UTF8.GetBytes(sbdwtMsg.ToString()), 0, msgLength); IOPort.Write(baCR, 0, 1); sbTemp.Clear(); sbTemp.Append("IModem Loaded SBDWT Buffer with->"); sbTemp.Append(sbdwtMsg); sbTemp.Append("<-"); EngrLogger.writeToColumns(sbTemp); return (1); } private static readonly byte[] baSBDWT = Encoding.UTF8.GetBytes("AT+SBDWT\r"); public void sendSBDWTCommand() { //Debug.Print(DateTime.Now + " Sending SBDWT"); WriteArray(baSBDWT); sbTemp.Clear(); sbTemp.Append("Sent SBDWT Command"); EngrLogger.writeToColumns(sbTemp); } private void WriteArray(byte[] ba) { IOPort.Write(ba, 0, ba.Length); } private static readonly byte[] baSBDRT = Encoding.UTF8.GetBytes("AT+SBDRT\r"); public void sendSBDRT() { //Debug.Print(DateTime.Now + " Sending SBDRT"); WriteArray(baSBDRT); sbTemp.Clear(); sbTemp.Append("IModem Sent SBDRT Command"); EngrLogger.writeToColumns(sbTemp); } private static readonly byte[] baSBDD2 = Encoding.UTF8.GetBytes("AT+SBDD2\r"); public int sendSBDD2() { //Debug.Print(DateTime.Now + " Sending SBDD2"); WriteArray(baSBDD2); return (1); } private static readonly byte[] baSBDI = Encoding.UTF8.GetBytes("AT+SBDI\r"); public int sendSBDI() { //Debug.Print(DateTime.Now + " Sending SBDI"); WriteArray(baSBDI); return (1); } //private static readonly StringBuilder sbSBDIX = new StringBuilder("AT+SBDIX\r"); private static readonly byte[] baSBDIX = Encoding.UTF8.GetBytes("AT+SBDIX\r"); public void sendSBDIX() { //Debug.Print(DateTime.Now + " Sending SBDIX"); WriteArray(baSBDIX); sbTemp.Clear(); sbTemp.Append("IModem Sent SBDIX Command"); EngrLogger.writeToColumns(sbTemp); } // private static readonly StringBuilder sbCREG = new StringBuilder("AT+CREG?\r"); private static readonly byte[] baCREG = Encoding.UTF8.GetBytes("AT+CREG?\r"); public void sendCREG() { //Debug.Print(DateTime.Now + " Sending CREG?"); WriteArray(baCREG); } // private static readonly StringBuilder sbPAPUBX00 = new StringBuilder("AT+PA=A\r"); private static readonly byte[] baPAPUBX00 = Encoding.UTF8.GetBytes("AT+PA=A\r"); public void sendPAPUBX00() { //Debug.Print(DateTime.Now + " Sending PA=A"); WriteArray(baPAPUBX00); } private static readonly byte[] baCMEEVerbose = Encoding.UTF8.GetBytes("AT+CMEE=2\r"); private static readonly byte[] baCMEE = Encoding.UTF8.GetBytes("AT+CMEE\r"); public void sendCMEE() { WriteArray(baCMEEVerbose); Thread.Sleep(1000); WriteArray(baCMEE); } private static readonly byte[] baCICCID = Encoding.UTF8.GetBytes("AT+CICCID\r"); public void sendCICCID() { WriteArray(baCICCID); } private static readonly byte[] baCIER11 = Encoding.UTF8.GetBytes("AT+CIER=1,1\r"); public void sendCIER11() { WriteArray(baCIER11); } // private static readonly StringBuilder sbPAPUBX04 = new StringBuilder("AT+PA=C\r"); private static readonly byte[] baPAPUBX04 = Encoding.UTF8.GetBytes("AT+PA=C\r"); public void sendPAPUBX04() { //Debug.Print(DateTime.Now + " Sending PA=C"); WriteArray(baPAPUBX04); } private static readonly byte[] baATH0 = Encoding.UTF8.GetBytes("ATH0\r"); public void sendATH0() { WriteArray(baATH0); } private static readonly byte[] baCHUP = Encoding.UTF8.GetBytes("AT+CHUP\r"); public void sendCHUP() { WriteArray(baCHUP); } public void parseSQ(byte[] inBytes) { int colonIndex = -1; //if ((inBytes[0] == 43) && (inBytes[1] == 67) && (inBytes[2] == 83) && (inBytes[3] == 81)) // SignalQuality = (int)inBytes[5] - 48; colonIndex = Array.IndexOf(inBytes, (byte)':'); if (colonIndex >= 0) SignalQuality = (int)inBytes[colonIndex + 1] - 48; else SignalQuality = -1; } private static byte LF = 10; private static byte[] bytesRead = new byte[2048]; public static byte[] messageBytes = new byte[2048]; private static int bytesToRead; private static int messageIndex = 0; //private static StructQueue.qStruct qS = new StructQueue.qStruct(); //Singnal quality property moved from Program class to IModem class //in CPF_43 this var was set to -1 on state and substate entry, and exit, but was only every recorded //in EngrLog - never used to evaluate or determine action. private static int signalQuality = -1; public static int SignalQuality { get { return signalQuality; } set { signalQuality = value; } } private static readonly byte[] baATD = Encoding.UTF8.GetBytes("ATD"); private static readonly byte[] baATDRUDICS = Encoding.UTF8.GetBytes("atd00881600005391\r"); public int dialNumber(byte[] baNumber) { int retval = 0; //input check if (baNumber.Length <= 0) return -1; //WriteArray(baATDRUDICS); WriteArray(baNumber); //check if baNumber has /r if (baNumber[baNumber.Length - 1] != (byte)'\r') IOPort.WriteByte((byte)'\r'); return retval; } public int dialDefaultRudics() { WriteArray(baATDRUDICS); return 0; } public void ReleaseDataHandler() { //Debug.Print("Releasing Handler"); IOPort.ReleaseDefaultDataHandler(); } public void AttachDataHandler() { // return the serial port handler //Debug.Print("Attaching Handler"); IOPort.AttachDefaultDataHandler(); } private static byte[] fakeMTSBDMessage = UTF8Encoding.UTF8.GetBytes("$PARKTIME,5;$PARKPRESSURE,30;\r\n"); public static void fakeMTSBD() { //qS.timeStamp = DateTime.Now; //qS.state = SV.CurrentState; //sbTemp.Clear(); //sbTemp.Append(SafeEncoding.GetChars(fakeMTSBDMessage)); ////Debug.Print(DateTime.Now + " iModem Message = " + sbTemp.ToString()); //Array.Clear(qS.byteArray, 0, qS.byteArray.Length); //Array.Copy(fakeMTSBDMessage, qS.byteArray, fakeMTSBDMessage.Length); //qS.qRecordType = StructQueue.QRecordType.IModem; //Program.sQueue.Enqueue(qS); } public enum CallSpeed { AUTO = 0, BPS300 = 1, BPS1200 = 2, BPS2400 = 3, BPS4800 = 6, BPS9600 = 7, BPS300V110 = 65, BPS1200V110 = 66, BPS2400V110 = 68, BPS4800V110 = 70, BPS9600V110 = 71 } public void SelectBearerServiceType(CallSpeed speed) { int iSpeed = (int)speed; WriteArray(Encoding.UTF8.GetBytes("AT+CBST=" + iSpeed.ToString() + ",0,1\r")); } public enum commands : int { none = 0, d0, k0, sbdd2, creg, csq, sendSBDWT, loadSBDWTBuffer, sbdi, sbdix, papubx00, papubx04, nocarrier, connected, escapeSeq, ath0, chup, sbdrt } public bool waitingForResponse = false; public static bool gotResponse = false; private static readonly StringBuilder d0Response = new StringBuilder("AT&D0"); //TODO P2 maybe these should all be UTF8Encoding.GetBytes on string literals private static readonly StringBuilder k0Response = new StringBuilder("AT&K0"); private static readonly StringBuilder sbdd2Response = new StringBuilder("OK"); private static readonly StringBuilder cregResponse = new StringBuilder("+CREG:"); private static readonly StringBuilder csqResponse = new StringBuilder("+CSQ:"); private static readonly StringBuilder sendSBDWTResponse = new StringBuilder("READY"); private static readonly StringBuilder loadSBDWTResponse = new StringBuilder("OK"); private static readonly StringBuilder sbdiResponse = new StringBuilder("+SBDI:"); private static readonly StringBuilder sbdixResponse = new StringBuilder("+SBDIX:"); private static readonly StringBuilder sbdrtResponse = new StringBuilder("+SBDRT:"); //private static readonly StringBuilder sbdixResponse0 = new StringBuilder("+SBDIX: 0,"); //private static readonly StringBuilder sbdixResponse1 = new StringBuilder("+SBDIX: 1,"); //private static readonly StringBuilder sbdixResponse2 = new StringBuilder("+SBDIX: 2,"); //private static readonly StringBuilder sbdixResponse3 = new StringBuilder("+SBDIX: 3,"); //private static readonly StringBuilder sbdixResponse4 = new StringBuilder("+SBDIX: 4,"); //private static readonly StringBuilder[] sbdixResponses = new StringBuilder[] { sbdixResponse0, sbdixResponse1, sbdixResponse2, sbdixResponse3, sbdixResponse4, }; private static readonly StringBuilder papubx00Response = new StringBuilder("$PUBX,00"); private static readonly StringBuilder papubx04Response = new StringBuilder("$PUBX,04"); private static readonly StringBuilder noCarrierResponse = new StringBuilder("NO CARRIER"); private static readonly StringBuilder connectedResponse = new StringBuilder("CONNECT"); private static readonly StringBuilder okResponse = new StringBuilder("OK"); public int sbdixMTQueued = -1; public int sbdixMTStatus = -1; public int sbdixMOStatus = -1; //private static readonly StringBuilder expectedResponseSB = new StringBuilder(64); private byte[] expectedResponse = new byte[64]; private int expectedResponseLength = 0; private int numRetries = 0; private static readonly int maxNumRetries = 3; private DateTime wfrStartTime = new DateTime(); private readonly TimeSpan wfrTimeout = new TimeSpan(0, 0, 40); private static readonly string wfrFail = "IModem waitingForResponse expended all retries"; private commands currentCommand = commands.none; //TODO P2 find and use OO oriented version of this method public int waitForResponse(commands commandNum) { if (waitingForResponse) //Do this after the first call to this method { if (gotResponse) //success { waitingForResponse = false; numRetries = 0; currentCommand = commands.none; return (1); } else if ((DateTime.Now - wfrStartTime) > wfrTimeout) //if timeout has expired, try again up to the max number of retries { if (numRetries > maxNumRetries) { waitingForResponse = false; numRetries = 0; gotResponse = false; currentCommand = commands.none; EngrLogger.writeToColumns(wfrFail); return (-1); } else { waitingForResponse = false; return (-2); } } else return (0); } else //Do this the first time the method is called and after a timeout { currentCommand = commandNum; Array.Clear(expectedResponse, 0, expectedResponse.Length); switch (commandNum) { case commands.d0: Array.Copy(UTF8Encoding.UTF8.GetBytes(d0Response.ToString()), expectedResponse, d0Response.Length); expectedResponseLength = d0Response.Length; //Debug.Print(DateTime.Now.TimeOfDay.ToString() + " Sending ds command"); EngrLogger.writeToColumns("IModem Sending D0 cmd"); sendD0(); break; case commands.k0: Array.Copy(UTF8Encoding.UTF8.GetBytes(k0Response.ToString()), expectedResponse, k0Response.Length); expectedResponseLength = k0Response.Length; EngrLogger.writeToColumns("IModem Sending K0 cmd"); sendK0(); break; case commands.sbdd2: Array.Copy(UTF8Encoding.UTF8.GetBytes(sbdd2Response.ToString()), expectedResponse, sbdd2Response.Length); expectedResponseLength = sbdd2Response.Length; EngrLogger.writeToColumns("IModem Sending SBDD2 cmd"); sendSBDD2(); break; case commands.creg: Array.Copy(UTF8Encoding.UTF8.GetBytes(cregResponse.ToString()), expectedResponse, cregResponse.Length); expectedResponseLength = cregResponse.Length; EngrLogger.writeToColumns("IModem Sending CREG cmd"); sendCREG(); break; case commands.csq: Array.Copy(UTF8Encoding.UTF8.GetBytes(csqResponse.ToString()), expectedResponse, csqResponse.Length); expectedResponseLength = csqResponse.Length; EngrLogger.writeToColumns("IModem Sending CSQ cmd"); sendCSQ(); break; case commands.sendSBDWT: Array.Copy(UTF8Encoding.UTF8.GetBytes(sendSBDWTResponse.ToString()), expectedResponse, sendSBDWTResponse.Length); expectedResponseLength = sendSBDWTResponse.Length; EngrLogger.writeToColumns("IModem Sending SBDWT cmd"); sendSBDWTCommand(); break; case commands.loadSBDWTBuffer: Array.Copy(UTF8Encoding.UTF8.GetBytes(loadSBDWTResponse.ToString()), expectedResponse, loadSBDWTResponse.Length); expectedResponseLength = loadSBDWTResponse.Length; EngrLogger.writeToColumns("IModem Sending loadSBDWT cmd"); loadSBDWTBuffer(); break; case commands.sbdi: Array.Copy(UTF8Encoding.UTF8.GetBytes(sbdiResponse.ToString()), expectedResponse, sbdiResponse.Length); expectedResponseLength = sbdiResponse.Length; EngrLogger.writeToColumns("IModem Sending SBDI cmd"); sendSBDI(); break; case commands.sbdix: sbdixMTQueued = -1; sbdixMOStatus = -1; sbdixMTStatus = -1; EngrLogger.writeToColumns("IModem Sending SBDIX cmd"); sendSBDIX(); break; case commands.sbdrt: Array.Copy(UTF8Encoding.UTF8.GetBytes(sbdrtResponse.ToString()), expectedResponse, sbdrtResponse.Length); EngrLogger.writeToColumns("IModem Sending SBDRT cmd"); expectedResponseLength = sbdrtResponse.Length; sendSBDRT(); break; case commands.papubx00: Array.Copy(UTF8Encoding.UTF8.GetBytes(papubx00Response.ToString()), expectedResponse, papubx00Response.Length); expectedResponseLength = papubx00Response.Length; EngrLogger.writeToColumns("IModem Sending PAPUBX00 cmd"); sendPAPUBX00(); break; case commands.papubx04: Array.Copy(UTF8Encoding.UTF8.GetBytes(papubx04Response.ToString()), expectedResponse, papubx04Response.Length); expectedResponseLength = papubx04Response.Length; EngrLogger.writeToColumns("IModem Sending PAPUBX04 cmd"); sendPAPUBX04(); break; case commands.nocarrier: Array.Copy(Encoding.UTF8.GetBytes(noCarrierResponse.ToString()), expectedResponse, noCarrierResponse.Length); expectedResponseLength = noCarrierResponse.Length; break; case commands.ath0: Array.Copy(Encoding.UTF8.GetBytes(okResponse.ToString()), expectedResponse, okResponse.Length); expectedResponseLength = okResponse.Length; EngrLogger.writeToColumns("IModem Sending ATH0 cmd"); sendATH0(); break; case commands.chup: Array.Copy(Encoding.UTF8.GetBytes(okResponse.ToString()), expectedResponse, okResponse.Length); expectedResponseLength = okResponse.Length; EngrLogger.writeToColumns("IModem Sending CHUP cmd"); sendCHUP(); break; case commands.escapeSeq: Array.Copy(Encoding.UTF8.GetBytes(okResponse.ToString()), expectedResponse, okResponse.Length); expectedResponseLength = okResponse.Length; EngrLogger.writeToColumns("IModem Sending Escape sequence"); sendEscapeSequence(); break; } wfrStartTime = DateTime.Now; numRetries++; gotResponse = false; waitingForResponse = true; return (0); } } private static StringBuilder sbResponse = new StringBuilder(512); private static StringBuilder sbExpectedResponse = new StringBuilder(512); private static byte[] returnField = new byte[16]; private static byte[] returnField2 = new byte[16]; private const byte commaByte = (byte)','; private const byte colonByte = (byte)':'; /// /// MO status: MO session status provides an indication of the disposition of the mobile originated transaction. The field can take on the following values: /// Gateway-reported values: /// 0 MO message, if any, transferred successfully /// 1 MO message, if any, transferred successfully, but the MT message in the queue /// was too big to be transferred /// 2 MO message, if any, transferred successfully, but the requested Location Update /// was not accepted /// 3..4 Reserved, but indicate MO session success if used 5..8 Reserved, but indicate MO session failure if used /// 10 GSS reported that the call did not complete in the allowed time /// 11 MO message queue at the GSS is full /// 12 MO message has too many segments /// 13 GSS reported that the session did not complete /// 14 Invalid segment size /// 15 Access is denied /// A3LA-RG-reported values: /// 16 Modem has been locked and may not make SBD calls (see +CULK command) /// 17 Gateway not responding (local session timeout) /// 18 Connection lost (RF drop) /// 19 Link failure (A protocol error caused termination of the call) /// 20..31 Reserved, but indicate failure if used /// 32 No network service, unable to initiate call 33..34 Reserved, but indicate failure if used /// 35 A3LA-RG is busy, unable to initiate call 36.. Reserved, but indicate failure if used /// /// public bool MobileOriginationSuccess() { return (sbdixMOStatus >=0 && sbdixMOStatus <= 4); } public bool MobileSuccessAndMtEmpty() { return MobileOriginationSuccess() && sbdixMTStatus <= 0; } public enum SbdixMoStat:int { MOSuccess = 0, MTInQueue = 1 }; public enum SbdixMtStat : int { NoneAvailable = 0, SbdReceived, ErrorInRx = 2 } public void checkResponse(byte[] response) { int msgLength = response.Length; //check for expectedResponse anywhere in the IModem response message if (waitingForResponse) { if (msgLength > expectedResponseLength) { //start at the beginning of the qStructure byte array and test for the right character sequence //then start at the 2nd character in the qStrucutre byte array and so on if (currentCommand != commands.sbdix) { sbExpectedResponse.Clear(); sbExpectedResponse.Append("IModem Looking for IModem-->"); sbExpectedResponse.Append(SafeEncoding.GetChars(expectedResponse)); sbExpectedResponse.AppendLine("<--"); sbResponse.Clear(); sbResponse.Append("IModem Got-->"); sbResponse.Append(SafeEncoding.GetChars(response)); sbResponse.AppendLine("<--"); if (GHI.Utilities.Arrays.Contains(response, 0, expectedResponse, 0, expectedResponseLength) >= 0) { gotResponse = true; sbTemp.Clear(); sbTemp.Append("IModem correct response: "); sbTemp.Append(sbExpectedResponse); sbTemp.Append(sbResponse); EngrLogger.writeToColumns(sbTemp); if (currentCommand == commands.csq) parseSQ(response); } else { sbTemp.Clear(); sbTemp.Append("IModem invalid response: "); sbTemp.Append(sbExpectedResponse); sbTemp.Append(sbResponse); EngrLogger.writeToColumns(sbTemp); } } else { Array.Copy(UTF8Encoding.UTF8.GetBytes(sbdixResponse.ToString()), expectedResponse, sbdixResponse.Length); expectedResponseLength = sbdixResponse.Length; if (GHI.Utilities.Arrays.Contains(response, 0, expectedResponse, 0, expectedResponseLength) >= 0) { gotResponse = true; DecodeSbdixResponse(response); } else { sbTemp.Clear(); sbTemp.Append("IModem got invalid SBDIX response: "); sbTemp.Append(SafeEncoding.GetChars(response)); EngrLogger.writeToColumns(sbTemp); } } } } } private void DecodeSbdixResponse(byte[] response) { sbTemp.Clear(); Array.Clear(returnField, 0, returnField.Length); Array.Clear(returnField2, 0, returnField2.Length); Utils.getField(response, commaByte, 0, ref returnField); Utils.getField(returnField, colonByte, 1, ref returnField2); sbTemp.Append(SafeEncoding.GetChars(returnField2)); sbdixMOStatus = int.Parse(sbTemp.ToString()); sbTemp.Clear(); Array.Clear(returnField, 0, returnField.Length); Utils.getField(response, commaByte, 2, ref returnField); sbTemp.Append(SafeEncoding.GetChars(returnField)); sbdixMTStatus = int.Parse(sbTemp.ToString()); sbTemp.Clear(); Array.Clear(returnField, 0, returnField.Length); Utils.getField(response, commaByte, 5, ref returnField); sbTemp.Append(SafeEncoding.GetChars(returnField)); sbdixMTQueued = int.Parse(sbTemp.ToString()); sbTemp.Clear(); sbTemp.Append("IModem SBDIX Response: "); sbTemp.Append(SafeEncoding.GetChars(response)); sbTemp.Append(" sbdixMOStatus = "); sbTemp.Append(sbdixMOStatus.ToString()); sbTemp.Append(" sbdixMTStatus = "); sbTemp.Append(sbdixMTStatus.ToString()); sbTemp.Append(" sbdixMTQueued = "); sbTemp.Append(sbdixMTQueued.ToString()); EngrLogger.writeToColumns(sbTemp); } } }