using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Text; using SafeMobileLib; namespace SDRgateway { public class LIPSDR { public string binarydata; public string PDU_type; public string reply; public string sourceaddress; public string destinationaddress; public string PIvalue; public string messageReference; public string TLlength_include_SDTS_TL_PDU_field; public string SDTS_TL_PDU_type; public string SDTS_TL_DATA_flags; public string SDTS_Encoding_scheme; public string User_data; public string protocolversion; public string headerlength; public string nextextensionPDUtype; public string callingpartytypeidentifire; public string callingpartyISSI; public string calledpartytypeidentifire; public string calledpartyISSI; public string protocolidentification; public string CMflags; public string broadcastchannelselection; public string repeaterrequest; public string regionselection; // public string headerlength; public string nextextensionPDUtypeNOext; public string TL_flags; public string TL_validityPeriod; public string TL_forwardaddress; public string TLdeliverystatus; public string CM_reply; public int sendlength; public int messageReferenceCounter; public static uint callOutNumber = 1; public void sdsDecoder(string data) { binarydata = ""; PDU_type = ""; reply = ""; sourceaddress = ""; destinationaddress = ""; PIvalue = ""; messageReference = ""; TLlength_include_SDTS_TL_PDU_field = ""; SDTS_TL_PDU_type = ""; SDTS_TL_DATA_flags = ""; SDTS_Encoding_scheme = ""; User_data = ""; CM_reply = ""; binarydata = data; PDU_type = data.Substring(4, 2); Int32 PDU_type_int = Convert.ToInt32(PDU_type); // value 3,2,1,0,17 //e.g. 000A 03 01010101 0004D2 00 00 //array begins with 0(zero)and offset +1.Because the 2 bytes length field is considered. switch (PDU_type_int) { case 3: { PDU_type = "SDTS-CM-REGISTER response"; string incoming_1 = data.Substring(22, 2); if ((incoming_1.CompareTo("00") == 0)) { reply = "Address Registered"; } else if ((incoming_1.CompareTo("01") == 0)) { reply = "Duplicate address"; } else if ((incoming_1.CompareTo("02") == 0)) { reply = "Invalid address"; } else if ((incoming_1.CompareTo("03") == 0)) { reply = "Registration not available"; } else if ((incoming_1.CompareTo("04") == 0)) { reply = "Invalid PassNumber"; } } break; case 0: { //e.g. 001F 00 0004D2 0010E1 C0 60 01 00 0090 00 00 00 000000 00 48656C6C6F20576F726C64 sourceaddress = Convert.ToString(Convert.ToInt32(data.Substring(6, 6), 16)); PDU_type = "SDTS-CM-DATA (Message from " + sourceaddress + ")"; destinationaddress = Convert.ToString(Convert.ToInt32(data.Substring(12, 6), 16)); PIvalue = Convert.ToString(Convert.ToInt32(data.Substring(18, 2), 16)); messageReference = Convert.ToString(Convert.ToInt32(data.Substring(22, 2), 16)); TLlength_include_SDTS_TL_PDU_field = Convert.ToString(Convert.ToInt32(data.Substring(26, 4), 16)); SDTS_TL_PDU_type = Convert.ToString(Convert.ToInt32(data.Substring(30, 2), 16)); if (SDTS_TL_PDU_type == "0") { SDTS_TL_DATA_flags = Convert.ToString(Convert.ToInt32(data.Substring(32, 2), 16)); if (SDTS_TL_DATA_flags == "0") { SDTS_TL_DATA_flags = "No Acknowledgement requested"; } else if (SDTS_TL_DATA_flags == "64") { SDTS_TL_DATA_flags = "Consumed requested"; } else if (SDTS_TL_DATA_flags == "128") { SDTS_TL_DATA_flags = "Received requested"; } else if (SDTS_TL_DATA_flags == "192") { SDTS_TL_DATA_flags = "Received and Consumed requested"; } int i_u = 0; for (i_u = 42; i_u <= data.Length - 2; i_u += 2) { User_data = User_data + Convert.ToString(Convert.ToChar(Convert.ToInt32(data.Substring(i_u, 2), 16))); } } else if (SDTS_TL_PDU_type == "1") { string temp = Convert.ToString(Convert.ToInt32(data.Substring(32, 2), 16)); if (temp == "0") { SDTS_TL_DATA_flags = "Received"; } else if (temp == "2") { SDTS_TL_DATA_flags = "Consumed"; } else if (temp == "81") { SDTS_TL_DATA_flags = "Coding Scheme not Supported"; } else if (temp == "82") { SDTS_TL_DATA_flags = "Destination Memory Full"; } } else if (SDTS_TL_PDU_type == "2") { SDTS_TL_DATA_flags = Convert.ToString(Convert.ToInt32(data.Substring(32, 2), 16)); User_data = data.Substring(32); } } break; case 1: { sourceaddress = Convert.ToString(Convert.ToInt32(data.Substring(6, 6), 16)); PDU_type = "SDTS-CM-REPORT response"; destinationaddress = Convert.ToString(Convert.ToInt32(data.Substring(12, 6), 16)); PIvalue = Convert.ToString(Convert.ToInt32(data.Substring(18, 2), 16)); messageReference = Convert.ToString(Convert.ToInt32(data.Substring(20, 2), 16)); //CM_reply = Convert.ToString(Convert.ToInt32(data.Substring(22, 2), 16)) CM_reply = Convert.ToString(data.Substring(22, 2)); if ((CM_reply.CompareTo("40") == 0)) { CM_reply = "Network overload"; } else if ((CM_reply.CompareTo("41") == 0)) { CM_reply = "Service disabled"; } else if ((CM_reply.CompareTo("42") == 0)) { CM_reply = "Service temporary not available on BS"; } else if ((CM_reply.CompareTo("44") == 0)) { CM_reply = "Destination is not Authorised for SDS"; } else if ((CM_reply.CompareTo("45") == 0)) { CM_reply = "Unknown destination address"; } else if ((CM_reply.CompareTo("47") == 0)) { CM_reply = "Group address with individual service"; } else if ((CM_reply.CompareTo("4a") == 0)) { CM_reply = "Not reachable"; } else if ((CM_reply.CompareTo("4b") == 0)) { CM_reply = "Not registered (MS has turned off)"; } else if ((CM_reply.CompareTo("4c") == 0)) { CM_reply = "Destination queue full"; } else if ((CM_reply.CompareTo("4d") == 0)) { CM_reply = "Message too long"; } else if ((CM_reply.CompareTo("4e") == 0)) { CM_reply = "Destination does not support SDS-TL"; } else if ((CM_reply.CompareTo("4f") == 0)) { CM_reply = "Destination Host not connected"; } else if ((CM_reply.CompareTo("50") == 0)) { CM_reply = "Protocol not supported"; } else if ((CM_reply.CompareTo("53") == 0)) { CM_reply = "Destination not accepting SDS message"; } else if ((CM_reply.CompareTo("56") == 0)) { CM_reply = "Destination address administratively prohibited"; } else if ((CM_reply.CompareTo("58") == 0)) { CM_reply = "Unknown external subscriber number"; } else if ((CM_reply.CompareTo("5a") == 0)) { CM_reply = "Destination not reachable, message delivery failed"; } else if ((CM_reply.CompareTo("8d") == 0)) { CM_reply = "Text Distribution Error, message discarded"; } else if ((CM_reply.CompareTo("8e") == 0)) { CM_reply = "Corrupt information element, message discarded"; } } break; case 2: { PDU_type = "02"; sourceaddress = Convert.ToString(Convert.ToInt32(data.Substring(6, 6), 16)); destinationaddress = Convert.ToString(Convert.ToInt32(data.Substring(12, 6), 16)); SDTS_TL_DATA_flags = Convert.ToString(Convert.ToInt32(data.Substring(32, 2), 16)); } break; case 17: { protocolversion = Convert.ToString(Convert.ToInt32(data.Substring(6, 2), 16)); headerlength = Convert.ToString(Convert.ToInt32(data.Substring(8, 4), 16)); nextextensionPDUtype = Convert.ToString(Convert.ToInt32(data.Substring(12, 2), 16)); callingpartytypeidentifire= Convert.ToString(Convert.ToInt32(data.Substring(24, 2), 16)); callingpartyISSI= Convert.ToString(Convert.ToInt32(data.Substring(26, 6), 16)); calledpartytypeidentifire= Convert.ToString(Convert.ToInt32(data.Substring(56, 2), 16)); calledpartyISSI= Convert.ToString(Convert.ToInt32(data.Substring(58, 6), 16)); protocolidentification= Convert.ToString(Convert.ToInt32(data.Substring(88, 2), 16)); CMflags = Convert.ToString(Convert.ToInt32(data.Substring(90, 2), 16)); messageReference= Convert.ToString(Convert.ToInt32(data.Substring(92, 2), 16)); broadcastchannelselection= Convert.ToString(Convert.ToInt32(data.Substring(96, 2), 16)); repeaterrequest= Convert.ToString(Convert.ToInt32(data.Substring(98, 2), 16)); regionselection= Convert.ToString(Convert.ToInt32(data.Substring(100, 4), 16)); headerlength= Convert.ToString(Convert.ToInt32(data.Substring(108, 4), 16)); nextextensionPDUtypeNOext= Convert.ToString(Convert.ToInt32(data.Substring(112, 2), 16)); SDTS_TL_PDU_type = Convert.ToString(Convert.ToInt32(data.Substring(118, 2), 16)); TL_flags= Convert.ToString(Convert.ToInt32(data.Substring(120, 2), 16)); TL_validityPeriod= Convert.ToString(Convert.ToInt32(data.Substring(122, 2), 16)); TL_forwardaddress= Convert.ToString(Convert.ToInt32(data.Substring(124, 6), 16)); TLdeliverystatus = Convert.ToString(Convert.ToInt32(data.Substring(142, 2), 16)); } break; } } public byte[] Sdts_Cm_Register_Encoder(int passnumber1, int passnumber2, int passnumber3, int passnumber4, int myISSI) { //e.g. 000902010101010004D200 byte[] sendarray = new byte[11]; sendarray[0] = Convert.ToByte("00", 16); //data length sendarray[1] = Convert.ToByte("09", 16); //data length sendarray[2] = Convert.ToByte("02", 16); //PDU 02 for sdts_cm_register request sendarray[3] = Convert.ToByte(Convert.ToString(passnumber1, 16), 16); sendarray[4] = Convert.ToByte(Convert.ToString(passnumber2, 16), 16); sendarray[5] = Convert.ToByte(Convert.ToString(passnumber3, 16), 16); sendarray[6] = Convert.ToByte(Convert.ToString(passnumber4, 16), 16); string issi = Convert.ToString(myISSI, 16); int issilength = 0; int i = 0; issilength = 6 - issi.Length; for (i = 1; i <= issilength; i++) { issi = "0" + issi; } sendarray[7] = Convert.ToByte(issi.ToString().Substring(0, 2), 16); sendarray[8] = Convert.ToByte(issi.ToString().Substring(2, 2), 16); sendarray[9] = Convert.ToByte(issi.ToString().Substring(4, 2), 16); sendarray[10] = Convert.ToByte("00", 16); //registration type return sendarray; } //encode for lip application only . unit public static byte[] Stds_Cm_Message_header_sdsEncoder_SF(uint Source_ISSI, uint Destination_ISSI, int PIvalue,int msgReferenceCounter, string message, bool isSF, bool needsConfirm) { byte[] functionReturnValue = null; int i_l = 0; int l = 21; byte[] sendarray = new byte[151]; try { // 11 is needed because SDTS-CM. .. message->Length divide by 2 because of it is a HExCode // adaptation layer consists of 4 bits xx xx. // thus + 2 bit // enter length sendarray[0] = Convert.ToByte("00", 16); // - adaptation layer sendarray[2] = Convert.ToByte("00", 16); // - pdu type // source issi string issi_s = Convert.ToString(Source_ISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } sendarray[3] = Convert.ToByte(issi_s.ToString().Substring(0, 2), 16); sendarray[4] = Convert.ToByte(issi_s.ToString().Substring(2, 2), 16); sendarray[5] = Convert.ToByte(issi_s.ToString().Substring(4, 2), 16); // destination issi is SF Server if SF option is active, or the target radio ISSI otherwise string issi_d = Convert.ToString(isSF ? Program.cfg.SDR_SFServer : (Int64)Destination_ISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } sendarray[6] = Convert.ToByte(issi_d.ToString().Substring(0, 2), 16); sendarray[7] = Convert.ToByte(issi_d.ToString().Substring(2, 2), 16); sendarray[8] = Convert.ToByte(issi_d.ToString().Substring(4, 2), 16); // Protocol Identifier Value sendarray[9] = Convert.ToByte(PIvalue); // SDTS-CM-DATA flags. 60(SDS type=111, SS=0, Not_defined=0000) sendarray[10] = Convert.ToByte(0x60);//96 ->60 in hexa //("60") // Reference Number int conv = 0; //msgReferenceCounter = msgReferenceCounter + 1; conv = Convert.ToInt32(msgReferenceCounter.ToString(), 16); sendarray[11] = Convert.ToByte(conv); // Not Defined sendarray[12] = Convert.ToByte("00", 16); // TL length (in bits including a 02 for LIP header. // TL-length is the total length in bits for tl pdu + user_data // put converted totallengthinbits into correct BYTE location sendarray[13] = (byte)((((message.Length + 6) * 8) & 0xff00) >> 8); sendarray[14] = (byte)(((message.Length + 6) * 8) & 0x00ff); // TL-PDU type 0x00 ->sdts-tl-data sendarray[15] = 0x00; // TL-flags if (isSF && needsConfirm) sendarray[16] = 0xE0; // SF and Confirmation else if (isSF && !needsConfirm) sendarray[16] = 0xA0; // only SF else if(!isSF && !needsConfirm) sendarray[16] = 0x80; // no SF and no Confirmation else if(!isSF && needsConfirm) sendarray[16] = 0xC0; // only Confirmation // TL-validity periode if(isSF) sendarray[17] = 0x1F; // max time else sendarray[17] = 0x00; // no storage // TL-forward address is 0x00 in case of no SF used, or the Destination ISSI (when SF is active) issi_d = Convert.ToString(isSF ? Destination_ISSI : 0x00, 16); issilength_d = 0; i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) issi_d = "0" + issi_d; sendarray[18] = Convert.ToByte(issi_d.ToString().Substring(0, 2), 16); sendarray[19] = Convert.ToByte(issi_d.ToString().Substring(2, 2), 16); sendarray[20] = Convert.ToByte(issi_d.ToString().Substring(4, 2), 16); //send user data int h = message.ToString().Length; byte[] temp = Encoding.UTF8.GetBytes(message); for (int i = 0; i < temp.Length; i++) { l = l + 1; try { sendarray[l] = temp[i]; } catch (Exception ex) { Console.WriteLine(ex.Message); } //Convert.ToByte(message.ToString.Substring(i_l, 2), 16) } sendarray[1] = Convert.ToByte(l - 2); Array.Resize(ref sendarray, l); functionReturnValue = sendarray; } catch (Exception ex) { Console.WriteLine("Invalid Hex Value Detected in the Send Button"); Array.Clear(sendarray, 0, l + 2); functionReturnValue = sendarray; } return functionReturnValue; } public static byte[] Stds_Cm_Message_header_sdsEncoder(Int64 Source_ISSI, Int64 Destination_ISSI, int PIvalue, int msgReferenceCounter, string message) { byte[] functionReturnValue = null; int i_l = 0; int l = 21; byte[] sendarray = new byte[151]; try { // 11 is needed because SDTS-CM. .. message->Length divide by 2 because of it is a HExCode // adaptation layer consists of 4 bits xx xx. // thus + 2 bit // enter length sendarray[0] = Convert.ToByte("00", 16); // - adaptation layer sendarray[2] = Convert.ToByte("00", 16); // - pdu type // source issi string issi_s = Convert.ToString(Source_ISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } sendarray[3] = Convert.ToByte(issi_s.ToString().Substring(0, 2), 16); sendarray[4] = Convert.ToByte(issi_s.ToString().Substring(2, 2), 16); sendarray[5] = Convert.ToByte(issi_s.ToString().Substring(4, 2), 16); // destination issi string issi_d = Convert.ToString(Destination_ISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } sendarray[6] = Convert.ToByte(issi_d.ToString().Substring(0, 2), 16); sendarray[7] = Convert.ToByte(issi_d.ToString().Substring(2, 2), 16); sendarray[8] = Convert.ToByte(issi_d.ToString().Substring(4, 2), 16); // Protocol Identifier Value sendarray[9] = Convert.ToByte(PIvalue); // SDTS-CM-DATA flags. 60(SDS type=111, SS=0, Not_defined=0000) sendarray[10] = Convert.ToByte(0x60);//96 ->60 in hexa //("60") // Reference Number int conv = 0; //msgReferenceCounter = msgReferenceCounter + 1; conv = Convert.ToInt32(msgReferenceCounter.ToString(), 16); sendarray[11] = Convert.ToByte(conv); // Not Defined sendarray[12] = Convert.ToByte("00", 16); // TL length (in bits including a 02 for LIP header. // TL-length is the total length in bits for tl pdu + user_data // put converted totallengthinbits into correct BYTE location sendarray[13] = (byte)((((message.Length + 6) * 8) & 0xff00) >> 8); sendarray[14] = (byte)(((message.Length + 6) * 8) & 0x00ff); // TL-PDU type 0x00 ->sdts-tl-data sendarray[15] = 0x00; // TL-flags sendarray[16] = 0x80; // Received confirmation // TL-validity periode sendarray[17] = 0x00; // 0x00 = no storage // TL-forward address 0x00 sendarray[18] = 0x00; sendarray[19] = 0x00; sendarray[20] = 0x00; //first char of the message 0x01 as for PI 130 sendarray[21] = 0x01; //send user data int h = message.ToString().Length; byte[] temp = Encoding.UTF8.GetBytes(message); for (int i = 0; i < temp.Length; i++) { l = l + 1; try { sendarray[l] = temp[i]; } catch (Exception ex) { Console.WriteLine(ex.Message); } //Convert.ToByte(message.ToString.Substring(i_l, 2), 16) } sendarray[1] = Convert.ToByte(l - 2); Array.Resize(ref sendarray, l); functionReturnValue = sendarray; } catch (Exception ex) { Console.WriteLine("Invalid Hex Value Detected in the Send Button"); Array.Clear(sendarray, 0, l + 2); functionReturnValue = sendarray; } return functionReturnValue; } //encode for lip application only . unit public static byte[] Stds_POLL_header_sdsEncoder(Int64 Source_ISSI, uint Destination_ISSI, int PIvalue, int msgReferenceCounter) { byte[] functionReturnValue = null; int i_l = 0; int l = 15; byte[] sendarray = new byte[151]; try { String message = "44104088800180114000C600A3800002A300"; // 11 is needed because SDTS-CM. .. message->Length divide by 2 because of it is a HExCode // adaptation layer consists of 4 bits xx xx. // thus + 2 bit // enter length sendarray[0] = Convert.ToByte("00", 16); // - adaptation layer sendarray[2] = Convert.ToByte("00", 16); // - pdu type // source issi string issi_s = Convert.ToString(Source_ISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } sendarray[3] = Convert.ToByte(issi_s.ToString().Substring(0, 2), 16); sendarray[4] = Convert.ToByte(issi_s.ToString().Substring(2, 2), 16); sendarray[5] = Convert.ToByte(issi_s.ToString().Substring(4, 2), 16); // destination issi string issi_d = Convert.ToString(Destination_ISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } sendarray[6] = Convert.ToByte(issi_d.ToString().Substring(0, 2), 16); sendarray[7] = Convert.ToByte(issi_d.ToString().Substring(2, 2), 16); sendarray[8] = Convert.ToByte(issi_d.ToString().Substring(4, 2), 16); // Protocol Identifier Value sendarray[9] = Convert.ToByte(PIvalue); // SDTS-CM-DATA flags. 60(SDS type=111, SS=0, Not_defined=0000) sendarray[10] = Convert.ToByte(0x60);//96 ->60 in hexa //("60") // Reference Number int conv = 0; //msgReferenceCounter = msgReferenceCounter + 1; conv = Convert.ToInt32(msgReferenceCounter.ToString(), 16); sendarray[11] = Convert.ToByte(conv); // Not Defined sendarray[12] = Convert.ToByte("00", 16); // TL length (in bits including a 02 for LIP header. // TL-length is the total length in bits for tl pdu + user_data int tl_length = (message.Length / 2) * 8 + 8; // put converted totallengthinbits into correct BYTE location //sendarray[13] = (byte)((((message.Length + 6) * 8) & 0xff00) >> 8); //sendarray[14] = (byte)(((message.Length + 6) * 8) & 0x00ff); sendarray[13] = 0x00; sendarray[14] = Convert.ToByte(tl_length); // TL-PDU type 0x00 ->sdts-tl-data sendarray[15] = 0x02; //send user data for (int i = 0; i < message.Length; i = i + 2) { l = l + 1; try { Int32 val = Convert.ToInt32(message.Substring(i, 2), 16); sendarray[l] = Convert.ToByte(val); } catch (Exception ex) { Console.WriteLine(ex.Message); } //Convert.ToByte(message.ToString.Substring(i_l, 2), 16) } sendarray[1] = Convert.ToByte(l - 1); Array.Resize(ref sendarray, l+1); functionReturnValue = sendarray; } catch (Exception ex) { Console.WriteLine("Invalid Hex Value Detected in the Send Button"); Array.Clear(sendarray, 0, l + 2); functionReturnValue = sendarray; } return functionReturnValue; } // encode a Immediate Location Request (Poll Request) public static byte[] Stds_Long_Immediate_Location_Request(uint sourceISSI, uint destinationISSI) { // see MR5.11_LIP_tehnical_guide page 18-22 List responseList = new List(); // source issi string issi_s = Convert.ToString(sourceISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } responseList.Add(Convert.ToByte(issi_s.ToString().Substring(0, 2), 16)); responseList.Add(Convert.ToByte(issi_s.ToString().Substring(2, 2), 16)); responseList.Add(Convert.ToByte(issi_s.ToString().Substring(4, 2), 16)); // destination issi string issi_d = Convert.ToString(destinationISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } responseList.Add(Convert.ToByte(issi_d.ToString().Substring(0, 2), 16)); responseList.Add(Convert.ToByte(issi_d.ToString().Substring(2, 2), 16)); responseList.Add(Convert.ToByte(issi_d.ToString().Substring(4, 2), 16)); // Protocol Identifier Value responseList.Add(0x0A); // Data from the Doc - page 21 responseList.Add(0x04); responseList.Add(0x50); responseList.Add(0x8A); responseList.Add(0x91); responseList.Add(0x8E); responseList.Add(0x3B); responseList.Add(0xB4); responseList.Add(0x0E); responseList.Add(0x78); // add LIP length responseList.Add(0x09); // convert the list of bytes to a byte array byte[] response = new byte[responseList.Count]; for (int i = 0; i < responseList.Count; i++) response[i] = responseList[i]; return response; } // encode a Immediate Location Request (Poll Request) public static byte[] Stds_Short_Immediate_Location_Request(uint sourceISSI, uint destinationISSI) { // see MR5.11_LIP_tehnical_guide page 18-22 List responseList = new List(); // source issi string issi_s = Convert.ToString(sourceISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } responseList.Add(Convert.ToByte(issi_s.ToString().Substring(0, 2), 16)); responseList.Add(Convert.ToByte(issi_s.ToString().Substring(2, 2), 16)); responseList.Add(Convert.ToByte(issi_s.ToString().Substring(4, 2), 16)); // destination issi string issi_d = Convert.ToString(destinationISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } responseList.Add(Convert.ToByte(issi_d.ToString().Substring(0, 2), 16)); responseList.Add(Convert.ToByte(issi_d.ToString().Substring(2, 2), 16)); responseList.Add(Convert.ToByte(issi_d.ToString().Substring(4, 2), 16)); // Protocol Identifier Value responseList.Add(0x0A); // Data from the Doc - page 21 responseList.Add(0x44); responseList.Add(0xCE); responseList.Add(0x3A); responseList.Add(0x34); responseList.Add(0x0E); responseList.Add(0x14); // add LIP length responseList.Add(0x06); // convert the list of bytes to a byte array byte[] response = new byte[responseList.Count]; for (int i = 0; i < responseList.Count; i++) response[i] = responseList[i]; return response; } //encode for lip application only . unit public static byte[] Stds_CallOutAlertPDU_sdsEncoder(uint callOutNumber, CallOutFunction callOutFunction, uint callOutSeverity, uint tgNumber, string calloutText, TGctrl tgCtrl) { // see page 118 from SDTS Programmers Guide L Rev5 List responseList = new List(); // UDH + Text encoding scheme //responseList.Add((byte)TextEncoding.ISO10646UT); responseList.Add((byte)TextEncoding.ISO8859Latin1); // Call Out Function [15-12] + CallOutNumber [11-4] + CallOutSeverity [3-0] //uint bytes23 = (uint)CallOutFunction.Alert * 4096 + callOutNumber * 16 + callOutSeverity; uint bytes23 = (uint)callOutFunction * 4096 + callOutNumber * 16 + callOutSeverity; responseList.Add(BitConverter.GetBytes(bytes23)[1]); responseList.Add(BitConverter.GetBytes(bytes23)[0]); // TGctrl [31-30] + TGnumber [29-6] + Reserved [6-0] if (tgCtrl == TGctrl.TGChangeOnAlert || tgCtrl == TGctrl.TGChangeUserInter) { uint bytes47 = (uint)tgCtrl * 40000000 + tgNumber * 40 + 0x00 * 10 + 0x0000; // 0x00 are used for Reserved responseList.Add(BitConverter.GetBytes(bytes47)[3]); responseList.Add(BitConverter.GetBytes(bytes47)[2]); responseList.Add(BitConverter.GetBytes(bytes47)[1]); responseList.Add(BitConverter.GetBytes(bytes47)[0]); } // add call out text foreach (byte by in System.Text.Encoding.UTF8.GetBytes(calloutText)) responseList.Add(by); // convert the list of bytes to a byte array byte[] response = new byte[responseList.Count]; for (int i = 0; i < responseList.Count; i++) response[i] = responseList[i]; return response; } public static byte[] Stds_CallOut_Message_header_sdsEncoder(Int64 Source_ISSI, Int64 Destination_ISSI, int PIvalue, int msgReferenceCounter, Byte [] bytemsg) { byte[] functionReturnValue = null; int i_l = 0; int l = 14; byte[] sendarray = new byte[151]; try { // 11 is needed because SDTS-CM. .. message->Length divide by 2 because of it is a HExCode // adaptation layer consists of 4 bits xx xx. // thus + 2 bit // enter length sendarray[0] = Convert.ToByte("00", 16); // - adaptation layer sendarray[2] = Convert.ToByte("00", 16); // - pdu type // source issi string issi_s = Convert.ToString(Source_ISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } sendarray[3] = Convert.ToByte(issi_s.ToString().Substring(0, 2), 16); sendarray[4] = Convert.ToByte(issi_s.ToString().Substring(2, 2), 16); sendarray[5] = Convert.ToByte(issi_s.ToString().Substring(4, 2), 16); // destination issi string issi_d = Convert.ToString(Destination_ISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } sendarray[6] = Convert.ToByte(issi_d.ToString().Substring(0, 2), 16); sendarray[7] = Convert.ToByte(issi_d.ToString().Substring(2, 2), 16); sendarray[8] = Convert.ToByte(issi_d.ToString().Substring(4, 2), 16); // Protocol Identifier Value sendarray[9] = Convert.ToByte(PIvalue); // SDTS-CM-DATA flags. 60(SDS type=111, SS=0, Not_defined=0000) sendarray[10] = Convert.ToByte(0x60);//96 ->60 in hexa //("60") // Reference Number int conv = 0; //msgReferenceCounter = msgReferenceCounter + 1; conv = Convert.ToInt32(msgReferenceCounter.ToString(), 16); sendarray[11] = Convert.ToByte(conv); // Not Defined sendarray[12] = Convert.ToByte("00", 16); // TL length (in bits including a 02 for LIP header. // TL-length is the total length in bits for tl pdu + user_data // put converted totallengthinbits into correct BYTE location //sendarray[13] = (byte)((((bytemsg.Length-1)*8) & 0xff00) >> 8); //sendarray[14] = (byte)(((bytemsg.Length-1)*8) & 0x00ff); sendarray[13] = (byte)((((5 - 1) * 8) & 0xff00) >> 8); sendarray[14] = (byte)(((5-1)*8) & 0x00ff); l = l + 1; sendarray[l] = 0x01; l = l + 1; sendarray[l] = 0x20; l = l + 1; sendarray[l] = 0x10; l = l + 1; sendarray[l] = 0x31; l = l + 1; sendarray[l] = 0x31; /* foreach (byte obj in bytemsg) { l = l + 1; try { sendarray[l] = obj; } catch (Exception ex) { Console.WriteLine(ex.Message); } } */ sendarray[1] = Convert.ToByte(l - 2); Array.Resize(ref sendarray, l); functionReturnValue = sendarray; } catch (Exception ex) { Console.WriteLine("Invalid Hex Value Detected in the Send Button"); Array.Clear(sendarray, 0, l + 2); functionReturnValue = sendarray; } return functionReturnValue; } //encode a Emergency ACK inside a SDTS-CM-DATA Request public static byte[] Stds_Emergency_ACK_sdsEncoder(uint sourceISSI, uint destinationISSI) { // see MR5.11_LIP_tehnical_guide page 18-22 List responseList = new List(); // PDU type responseList.Add(0x00); // source issi string issi_s = Convert.ToString(sourceISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } responseList.Add(Convert.ToByte(issi_s.ToString().Substring(0, 2), 16)); responseList.Add(Convert.ToByte(issi_s.ToString().Substring(2, 2), 16)); responseList.Add(Convert.ToByte(issi_s.ToString().Substring(4, 2), 16)); // destination issi string issi_d = Convert.ToString(destinationISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } responseList.Add(Convert.ToByte(issi_d.ToString().Substring(0, 2), 16)); responseList.Add(Convert.ToByte(issi_d.ToString().Substring(2, 2), 16)); responseList.Add(Convert.ToByte(issi_d.ToString().Substring(4, 2), 16)); // Protocol Identifier Value responseList.Add(0x10); // SDS type , SS and Reserved responseList.Add(0x60); // Message reference // area selection responseList.Add(0x00); // TL Length // convert the list of bytes to a byte array byte[] response = new byte[responseList.Count]; for (int i = 0; i < responseList.Count; i++) response[i] = responseList[i]; return response; } public static byte[] Sdts_Cm_Response_Encoder(int response,int messageReference, int Source_ISSI, int Destination_ISSI, int PIvalue) { byte[] sendarray = new byte[18]; //data length sendarray[0] = Convert.ToByte("00", 16); sendarray[1] = Convert.ToByte("0F", 16); sendarray[2] = Convert.ToByte("00", 16); // source issi string issi_s = Convert.ToString(Source_ISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } sendarray[3] = Convert.ToByte(issi_s.ToString().Substring(0, 2), 16); sendarray[4] = Convert.ToByte(issi_s.ToString().Substring(2, 2), 16); sendarray[5] = Convert.ToByte(issi_s.ToString().Substring(4, 2), 16); // destination issi string issi_d = Convert.ToString(Destination_ISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } sendarray[6] = Convert.ToByte(issi_d.ToString().Substring(0, 2), 16); sendarray[7] = Convert.ToByte(issi_d.ToString().Substring(2, 2), 16); sendarray[8] = Convert.ToByte(issi_d.ToString().Substring(4, 2), 16); // Protocol Identifier Value sendarray[9] = Convert.ToByte(PIvalue); // SDTS-CM-DATA flags. 60(SDS type=011, SS=0, Not_defined=0000) sendarray[10] = Convert.ToByte("60", 16); sendarray[11] = Convert.ToByte(messageReference); sendarray[12] = Convert.ToByte("00", 16); sendarray[13] = Convert.ToByte("00", 16); sendarray[14] = Convert.ToByte("10", 16); sendarray[15] = Convert.ToByte("01", 16); if ((response == 0)) { sendarray[16] = 0; } else if ((response == 64)) { sendarray[16] = Convert.ToByte("02", 16); } else if ((response == 128 | response == 152)) { sendarray[16] = Convert.ToByte("00", 16); } else if ((response == 192)) { sendarray[16] = Convert.ToByte("00", 16); sendarray[16] = Convert.ToByte("02", 16); } return sendarray; } //encode for lip application only . unit public byte[] add_mod_trigger_terminal_id(int Source_ISSI, int Destination_ISSI, int PIvalue, string message) { byte[] functionReturnValue = null; // header data 0020000004D20004D20A70010000980244104088800180114000C600A3800002A300 // lip data 44104088800180114000C600A3800002A300 int l = 15; int i_l = 0; byte[] sendarray = new byte[151]; try { // 11 is needed because SDTS-CM. .. message->Length divide by 2 because of it is a HExCode // adaptation layer consists of 4 bits xx xx. // thus + 2 bit int totallength = message.ToString().Length / 2 + 2; // enter length sendarray[0] = Convert.ToByte("00", 16); // - adaptation layer sendarray[2] = Convert.ToByte("00", 16); // - pdu type // source issi string issi_s = Convert.ToString(Source_ISSI, 16); int issilength_s = 0; int i_s = 0; issilength_s = 6 - issi_s.Length; for (i_s = 1; i_s <= issilength_s; i_s++) { issi_s = "0" + issi_s; } sendarray[3] = Convert.ToByte(issi_s.ToString().Substring(0, 2), 16); sendarray[4] = Convert.ToByte(issi_s.ToString().Substring(2, 2), 16); sendarray[5] = Convert.ToByte(issi_s.ToString().Substring(4, 2), 16); // destination issi string issi_d = Convert.ToString(Destination_ISSI, 16); int issilength_d = 0; int i_d = 0; issilength_d = 6 - issi_d.Length; for (i_d = 1; i_d <= issilength_d; i_d++) { issi_d = "0" + issi_d; } sendarray[6] = Convert.ToByte(issi_d.ToString().Substring(0, 2), 16); sendarray[7] = Convert.ToByte(issi_d.ToString().Substring(2, 2), 16); sendarray[8] = Convert.ToByte(issi_d.ToString().Substring(4, 2), 16); // Protocol Identifier Value sendarray[9] = Convert.ToByte(PIvalue); // SDTS-CM-DATA flags. 60(SDS type=111, SS=0, Not_defined=0000) sendarray[10] = Convert.ToByte("96"); //("60") // Reference Number int conv = 0; messageReferenceCounter = messageReferenceCounter + 1; conv = Convert.ToByte(messageReferenceCounter.ToString(), 16); sendarray[11] = Convert.ToByte(conv); // Not Defined sendarray[12] = Convert.ToByte("00", 16); // TL length (in bits including a 02 for LIP header. // TL-length is the total length in bits for tl pdu + user_data int tl_length = (message.ToString().Length / 2) * 8 + 8; // put converted totallengthinbits into correct BYTE location sendarray[13] = Convert.ToByte("00", 16); sendarray[14] = Convert.ToByte(tl_length); // for LIP 02. sendarray[15] = Convert.ToByte("02"); //send user data int h = message.ToString().Length; for (i_l = 0; i_l <= message.ToString().Length - 1; i_l += 2) { l = l + 1; try { sendarray[l] = Convert.ToByte(message.ToString().Substring(i_l, 2), 16); sendarray[l] = Convert.ToByte(sendarray[l]); } catch (Exception ex) { Utils.WriteLine("add_mod_trigger_terminal_id: " +ex.Message, ConsoleColor.Red); } } sendarray[1] = Convert.ToByte(l - 1); Array.Resize(ref sendarray, l + 1); functionReturnValue = sendarray; } catch (Exception ex) { Utils.WriteLine("Invalid Hex Value Detected in the Send Button", ConsoleColor.Red); Array.Clear(sendarray, 0, l + 2); functionReturnValue = sendarray; } return functionReturnValue; } public static string Byte2String(byte[] data, int startIndex, int len) { string sdata = ""; int i; if (startIndex > data.Length) return ""; for (i = startIndex; i < startIndex + len && i < data.Length; i++) { int ii; ii = (int)data[i]; sdata += "0x" + ii.ToString("X") + " "; } return sdata; } public static void printBytesArray(Byte[] receivedBytes) { //Console.Write("Data: "); for (int i = 0; i < receivedBytes.Length; i++) { Utils.WriteLine(String.Format("0x{0:X} ", receivedBytes[i])); } } public static string ConvertBytesToHex(Byte[] receivedBytes) { string response = ""; for (int i = 0; i < receivedBytes.Length; i++) { response = String.Format("{0} 0x{1:X}", response, receivedBytes[i]); } return response; } public MSG_TYPE GetMSGtype(string userData, int len) { MSG_TYPE type = MSG_TYPE.GPS; try { byte b1 =Convert.ToByte(userData.Substring(len - 4, 2),16); byte b2 = Convert.ToByte(userData.Substring(len - 2, 2),16); byte ls = (byte)(b1 % 16); /* Console.WriteLine("b1 : " + b1); Console.WriteLine("b2 : " + b2); Console.WriteLine("b1:0x{0:X} ls :0x{1:X} ", b1, ls); Console.WriteLine("b2:0x{0:X} ",b2);*/ if(ls != 0) type = MSG_TYPE.GPS; if (ls == 0) { switch (b2) { case 0x00: { type = MSG_TYPE.ARS_ON; break; } case 0x10: { type = MSG_TYPE.ARS_OFF; break; } case 0x20: { type = MSG_TYPE.Emergency; break; } default: type = MSG_TYPE.GPS; break; } } } catch (Exception ex) { Utils.WriteLine("GetMSGtype " + ex.ToString(), ConsoleColor.Red); } return type; } public enum TGctrl { TGControlNotUsed = 0x0, TGChangeOnAlert = 0x1, TGChangeUserInter = 0x2, Reserved = 0x3 }; public enum CallOutFunction { Alert = 0x1, Test = 0x2, Info = 0x3, Clear = 0x4, Availability=0x5, AvailabilityRequest = 0x6 }; public enum TextEncoding { ISO8859Latin1 = 0x1, ISO10646UTF = 0x1A }; public enum UDH { Yes = 0x01, No = 0x00 }; } }