├── GSMCommunication ├── GsmCommunication │ ├── IMessageIndicationObject.cs │ ├── PhoneStorageType.cs │ ├── LoglineAddedEventHandler.cs │ ├── MessageReceivedEventHandler.cs │ ├── LogLevel.cs │ ├── ProgressEventHandler.cs │ ├── DeleteScope.cs │ ├── OperatorStatus.cs │ ├── OperatorFormat.cs │ ├── PhoneNumberService.cs │ ├── PhoneMessageStatus.cs │ ├── MessageStorageInfo.cs │ ├── OperatorSelectionMode.cs │ ├── SmsStatusReportIndicationStyle.cs │ ├── MessageEventArgs.cs │ ├── ProgressEventArgs.cs │ ├── IndicationBufferSetting.cs │ ├── MessageReceivedEventArgs.cs │ ├── Charset.cs │ ├── MessageErrorEventArgs.cs │ ├── MemoryStatusWithStorage.cs │ ├── MemoryStatus.cs │ ├── MoreMessagesMode.cs │ ├── AddressData.cs │ ├── DeleteFlag.cs │ ├── MemoryLocation.cs │ ├── PhonebookEntryWithStorage.cs │ ├── MessageIndicationMode.cs │ ├── LoglineAddedEventArgs.cs │ ├── CbmIndicationStyle.cs │ ├── IdentificationInfo.cs │ ├── SignalQualityInfo.cs │ ├── BatteryChargeInfo.cs │ ├── SmsDeliverIndicationStyle.cs │ ├── ShortMessageFromPhone.cs │ ├── MessageMemoryStatus.cs │ ├── ShortMessage.cs │ ├── DecodedShortMessage.cs │ ├── OperatorInfo.cs │ ├── PinStatus.cs │ ├── PhonebookEntry.cs │ ├── SubscriberInfo.cs │ ├── OperatorInfo2.cs │ ├── MessageIndicationSettings.cs │ ├── IProtocol.cs │ └── SerialPortFixer.cs └── Properties │ └── AssemblyInfo.cs ├── PDUConverter ├── GsmComm.PduConverter │ ├── ValidityPeriod.cs │ ├── ITimestamp.cs │ ├── OutgoingMessageType.cs │ ├── IncomingMessageType.cs │ ├── ValidityPeriodFormat.cs │ ├── MessageWaitingStore.cs │ ├── MessageWaitingDiscard.cs │ ├── ReservedCodingGroup.cs │ ├── MessageWaitingStoreUcs2.cs │ ├── StatusCategory.cs │ ├── SmartMessaging │ │ ├── IConcatenationInfo.cs │ │ ├── InformationElement.cs │ │ ├── ConcatInfoComparer.cs │ │ ├── PortAddressElement16.cs │ │ ├── UnknownInformationElement.cs │ │ ├── ConcatMessageElement8.cs │ │ └── ConcatMessageElement16.cs │ ├── MessageWaitingIndication.cs │ ├── IncomingMessageFlags.cs │ ├── OutgoingMessageFlags.cs │ ├── MessageCoding.cs │ ├── GeneralDataCoding.cs │ ├── KnownMessageStatus.cs │ ├── SmsStatusReportMessageFlags.cs │ ├── AddressType.cs │ ├── IncomingSmsPdu.cs │ ├── MessageStatus.cs │ ├── SmsDeliverMessageFlags.cs │ ├── OutgoingSmsPdu.cs │ ├── ParameterIndicator.cs │ ├── RelativeValidityPeriod.cs │ ├── Calc.cs │ ├── BcdWorker.cs │ ├── ProtocolID.cs │ └── SmsSubmitMessageFlags.cs └── Properties │ └── AssemblyInfo.cs ├── GSMCommServer ├── Server │ ├── MessageSendErrorEventHandler.cs │ ├── MessageSendEventHandler.cs │ ├── MessageSendErrorEventArgs.cs │ ├── AuthorizationModule.cs │ ├── MessageSendEventArgs.cs │ └── SmsSender.cs ├── Properties │ └── AssemblyInfo.cs └── GSMCommServer.csproj ├── .gitattributes ├── GSMCommShared ├── Properties │ └── AssemblyInfo.cs ├── Interfaces │ └── ISmsSender.cs ├── GSMCommShared.csproj ├── MessageServiceErrorException.cs ├── MobileEquipmentErrorException.cs ├── GsmCommunication │ ├── MessageServiceErrorException.cs │ ├── MobileEquipmentErrorException.cs │ └── CommException.cs └── CommException.cs ├── GSMComm.sln └── .gitignore /GSMCommunication/GsmCommunication/IMessageIndicationObject.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// The interface identifying an object as being used for indicating new incoming messages. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public interface IMessageIndicationObject 7 | { 8 | 9 | } 10 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/PhoneStorageType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Lists common storage types. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class PhoneStorageType 9 | { 10 | /// SIM storage 11 | public const string Sim = "SM"; 12 | 13 | /// Phone storage 14 | public const string Phone = "ME"; 15 | 16 | public PhoneStorageType() 17 | { 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/LoglineAddedEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// The method that handles the event. 5 | /// 6 | /// The origin of the event. 7 | /// The data for the event. 8 | namespace GsmComm.GsmCommunication 9 | { 10 | public delegate void LoglineAddedEventHandler(object sender, LoglineAddedEventArgs e); 11 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/ValidityPeriod.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Implements the base for a validity Period. 3 | /// 4 | /// 5 | /// Note to inheritors: Override the ToString method in derived classes to be able to 6 | /// display the validity immediately as a string. 7 | /// 8 | /// 9 | namespace GsmComm.PduConverter 10 | { 11 | public abstract class ValidityPeriod 12 | { 13 | protected ValidityPeriod() 14 | { 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MessageReceivedEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// The method that handles the event. 5 | /// 6 | /// The origin of the event. 7 | /// The arguments containing more information. 8 | namespace GsmComm.GsmCommunication 9 | { 10 | public delegate void MessageReceivedEventHandler(object sender, MessageReceivedEventArgs e); 11 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/ITimestamp.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Represents a common interface for messages to return their relevant 3 | /// timestamp. 4 | /// 5 | namespace GsmComm.PduConverter 6 | { 7 | public interface ITimestamp 8 | { 9 | /// 10 | /// Returns the relevant timestamp. 11 | /// 12 | /// A structure representing the relevant message timestamp. 13 | SmsTimestamp GetTimestamp(); 14 | } 15 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/OutgoingMessageType.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies the type of the outgoing message. 3 | /// 4 | namespace GsmComm.PduConverter 5 | { 6 | public enum OutgoingMessageType 7 | { 8 | /// Specifies that the message is an SMS-SUBMIT. 9 | SmsSubmit, 10 | /// Specifies that the message is an SMS-COMMAND. 11 | SmsCommand, 12 | /// Specifies that the message is an SMS-DELIVER-REPORT. 13 | SmsDeliverReport 14 | } 15 | } -------------------------------------------------------------------------------- /GSMCommServer/Server/MessageSendErrorEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// The method that handles the event. 5 | /// 6 | /// The origin of the event. 7 | /// The associated with the event. 8 | namespace GsmComm.Server 9 | { 10 | public delegate void MessageSendErrorEventHandler(object sender, MessageSendErrorEventArgs e); 11 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/IncomingMessageType.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies the type of the incoming message. 3 | /// 4 | namespace GsmComm.PduConverter 5 | { 6 | public enum IncomingMessageType 7 | { 8 | /// Specifies that the message is an SMS-DELIVER. 9 | SmsDeliver, 10 | /// Specifies that the message is an SMS-STATUS-REPORT. 11 | SmsStatusReport, 12 | /// Specifies that the message is an SMS-SUBMIT-REPORT. 13 | SmsSubmitReport 14 | } 15 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/LogLevel.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies the level of an entry written to the log. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum LogLevel 7 | { 8 | /// 9 | /// Error 10 | /// 11 | Error, 12 | /// 13 | /// Warning 14 | /// 15 | Warning, 16 | /// 17 | /// Information 18 | /// 19 | Info, 20 | /// 21 | /// Additional information 22 | /// 23 | Verbose 24 | } 25 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/ProgressEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// The method that handles the and the events. 5 | /// 6 | /// The origin of the event. 7 | /// The arguments containing more information. 8 | namespace GsmComm.GsmCommunication 9 | { 10 | public delegate void ProgressEventHandler(object sender, ProgressEventArgs e); 11 | } -------------------------------------------------------------------------------- /GSMCommServer/Server/MessageSendEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// The method that handles the and 5 | /// events. 6 | /// 7 | /// The origin of the event. 8 | /// The associated with the event. 9 | namespace GsmComm.Server 10 | { 11 | public delegate void MessageSendEventHandler(object sender, MessageSendEventArgs e); 12 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/DeleteScope.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Lists the possible scopes for deleting short messages. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum DeleteScope 7 | { 8 | /// Delete all read messages. 9 | Read = 1, 10 | /// Delete all read and sent messages. 11 | ReadAndSent = 2, 12 | /// Delete all read, sent and unsent messages 13 | ReadSentAndUnsent = 3, 14 | /// Delete all messages including unread messages. 15 | All = 4 16 | } 17 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/OperatorStatus.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Conatins the operator availability values. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum OperatorStatus 7 | { 8 | /// The operator status is unknown. 9 | Unknown, 10 | /// The operator is available for selection. 11 | Available, 12 | /// Denotes that this is the currently selected operator. 13 | Current, 14 | /// The phone must not connect to this operator. 15 | Forbidden 16 | } 17 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/OperatorFormat.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Contains the possible formats in which a network operator can be returned. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum OperatorFormat 7 | { 8 | /// Long format, alphanumeric 9 | LongFormatAlphanumeric, 10 | /// Short format, alphanumeric 11 | ShortFormatAlphanumeric, 12 | /// 13 | /// Numeric format, GSM Location Area Identification number (BCD encoded, 3 digits country code, 14 | /// 2 digits network code) 15 | /// 16 | Numeric 17 | } 18 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/PhoneNumberService.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Contains services related to a subscriber phone number. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum PhoneNumberService 7 | { 8 | /// Asynchronous modem 9 | AsynchronousModem, 10 | /// Synchronous modem 11 | SynchronousModem, 12 | /// PAD Access (asynchronous) 13 | PadAccess, 14 | /// Packet Access (synchronous) 15 | PacketAccess, 16 | /// Voice 17 | Voice, 18 | /// Fax 19 | Fax 20 | } 21 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/ValidityPeriodFormat.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies how the validity period is formatted. 3 | /// 4 | namespace GsmComm.PduConverter 5 | { 6 | public enum ValidityPeriodFormat 7 | { 8 | /// No validity is specified, the TP-VP block will not be specified. 9 | Unspecified, 10 | /// A relative validity is specified in the TP-VP block. 11 | Relative, 12 | /// An absolute validity is specified in the TP-VP block. 13 | Absolute, 14 | /// An enhanced validity is specified in the TP-VP block. 15 | Enhanced 16 | } 17 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/PhoneMessageStatus.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// The message status to request from the phone or the actual type. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum PhoneMessageStatus 7 | { 8 | /// The message was received, but not yet read. 9 | ReceivedUnread, 10 | /// The message was received and has been read. 11 | ReceivedRead, 12 | /// The message was stored, but had not been sent yet. 13 | StoredUnsent, 14 | /// The message was stored and sent. 15 | StoredSent, 16 | /// Specifies all status. 17 | All 18 | } 19 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MessageStorageInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Provides a structure that contains details about supported message storages. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public struct MessageStorageInfo 9 | { 10 | /// Specifies the storages that can be used for reading and deleting. 11 | public string[] ReadStorages; 12 | 13 | /// Speicifies the storages that can be used for writing and sending. 14 | public string[] WriteStorages; 15 | 16 | /// Specifies the storages that can be used as the preferred receive storage. 17 | public string[] ReceiveStorages; 18 | } 19 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/MessageWaitingStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Message Waiting Indication Group: Store Message 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class MessageWaitingStore : MessageWaitingIndication 9 | { 10 | /// 11 | /// Gets the alphabet being used. 12 | /// 13 | public override byte Alphabet 14 | { 15 | get 16 | { 17 | return 0; 18 | } 19 | } 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The DCS byte to decode. 25 | public MessageWaitingStore(byte dcs) : base(dcs) 26 | { 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/MessageWaitingDiscard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Message Waiting Indication Group: Discard Message 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class MessageWaitingDiscard : MessageWaitingIndication 9 | { 10 | /// 11 | /// Gets the alphabet being used. 12 | /// 13 | public override byte Alphabet 14 | { 15 | get 16 | { 17 | return 0; 18 | } 19 | } 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The DCS byte to decode. 25 | public MessageWaitingDiscard(byte dcs) : base(dcs) 26 | { 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/ReservedCodingGroup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Reserved coding 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class ReservedCodingGroup : DataCodingScheme 9 | { 10 | private byte dcs; 11 | 12 | /// 13 | /// Gets the alphabet being used. 14 | /// 15 | public override byte Alphabet 16 | { 17 | get 18 | { 19 | return 3; 20 | } 21 | } 22 | 23 | /// 24 | /// Initializes a new instance of the class. 25 | /// 26 | /// The DCS byte to decode. 27 | public ReservedCodingGroup(byte dcs) : base(dcs) 28 | { 29 | this.dcs = dcs; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/MessageWaitingStoreUcs2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Message Waiting Indication Group: Store Message (UCS2) 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class MessageWaitingStoreUcs2 : MessageWaitingIndication 9 | { 10 | /// 11 | /// Gets the alphabet being used. 12 | /// 13 | public override byte Alphabet 14 | { 15 | get 16 | { 17 | return 2; 18 | } 19 | } 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The DCS byte to decode. 25 | public MessageWaitingStoreUcs2(byte dcs) : base(dcs) 26 | { 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/StatusCategory.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Contains the possible categories of a message status. 3 | /// 4 | namespace GsmComm.PduConverter 5 | { 6 | public enum StatusCategory 7 | { 8 | /// Short message transaction completed. 9 | Success, 10 | /// Temporary error, SC still trying to transfer SM. 11 | TemporaryErrorWithRetry, 12 | /// Permanent error, SC is not making any more transfer attempts. 13 | PermanentError, 14 | /// Temporary error, SC is not making any more transfer attempts. 15 | TemporaryErrorNoRetry, 16 | /// Status code is out of the defined range. 17 | Reserved 18 | } 19 | } -------------------------------------------------------------------------------- /GSMCommServer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyCompany("Stefan Mayr")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCopyright("Copyright © 2004-2011 Stefan Mayr")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyFileVersion("1.21.0.0")] 10 | [assembly: AssemblyProduct("")] 11 | [assembly: AssemblyTitle("GSMComm Server")] 12 | [assembly: AssemblyTrademark("")] 13 | [assembly: AssemblyVersion("1.21.0.0")] 14 | [assembly: CompilationRelaxations(8)] 15 | [assembly: ComVisible(false)] 16 | [assembly: Guid("51344c27-1895-4355-9289-a25D0880918f")] 17 | [assembly: RuntimeCompatibility(WrapNonExceptionThrows=true)] 18 | -------------------------------------------------------------------------------- /PDUConverter/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyCompany("Stefan Mayr")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCopyright("Copyright © 2004-2011 Stefan Mayr")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyFileVersion("1.21.0.0")] 10 | [assembly: AssemblyProduct("")] 11 | [assembly: AssemblyTitle("SMS PDU Converter")] 12 | [assembly: AssemblyTrademark("")] 13 | [assembly: AssemblyVersion("1.21.0.0")] 14 | [assembly: CompilationRelaxations(8)] 15 | [assembly: ComVisible(false)] 16 | [assembly: Guid("36c38b1b-8e9a-4828-865e-eda5d402248d")] 17 | [assembly: RuntimeCompatibility(WrapNonExceptionThrows=true)] 18 | -------------------------------------------------------------------------------- /GSMCommunication/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyCompany("Stefan Mayr")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCopyright("Copyright © 2004-2011 Stefan Mayr")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyFileVersion("1.21.0.0")] 10 | [assembly: AssemblyProduct("")] 11 | [assembly: AssemblyTitle("GSM Communication")] 12 | [assembly: AssemblyTrademark("")] 13 | [assembly: AssemblyVersion("1.21.0.0")] 14 | [assembly: CompilationRelaxations(8)] 15 | [assembly: ComVisible(false)] 16 | [assembly: Guid("eec0C65f-a333-42d5-82b9-163a57814507")] 17 | [assembly: RuntimeCompatibility(WrapNonExceptionThrows=true)] 18 | -------------------------------------------------------------------------------- /GSMCommShared/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyCompany("Stefan Mayr")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCopyright("Copyright © 2004-2011 Stefan Mayr")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyFileVersion("1.21.0.0")] 10 | [assembly: AssemblyProduct("")] 11 | [assembly: AssemblyTitle("GSMComm Shared Implementations")] 12 | [assembly: AssemblyTrademark("")] 13 | [assembly: AssemblyVersion("1.21.0.0")] 14 | [assembly: CompilationRelaxations(8)] 15 | [assembly: ComVisible(false)] 16 | [assembly: Guid("c43ba0b1-3ffa-4b02-8fbd-2d5997e9b5c5")] 17 | [assembly: RuntimeCompatibility(WrapNonExceptionThrows=true)] 18 | -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmartMessaging/IConcatenationInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// A common interface for all information elements containing concatenation information. 5 | /// 6 | namespace GsmComm.PduConverter.SmartMessaging 7 | { 8 | public interface IConcatenationInfo 9 | { 10 | /// 11 | /// Gets the current message number. 12 | /// 13 | byte CurrentNumber 14 | { 15 | get; 16 | } 17 | 18 | /// 19 | /// Gets the message reference number. 20 | /// 21 | ushort ReferenceNumber 22 | { 23 | get; 24 | } 25 | 26 | /// 27 | /// Gets the total number of parts of the message. 28 | /// 29 | byte TotalMessages 30 | { 31 | get; 32 | } 33 | 34 | } 35 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/OperatorSelectionMode.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Contains the possible values for the operator selection mode. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum OperatorSelectionMode 7 | { 8 | /// 9 | /// The phone selects the operator automatically. 10 | /// 11 | Automatic = 0, 12 | /// 13 | /// A specific operator is selected. The phone does not attempt to select the operator automatically. 14 | /// 15 | Manual = 1, 16 | /// 17 | /// The phone is not registered to the network. 18 | /// 19 | Deregistered = 2, 20 | /// 21 | /// If manual selection fails, automatic mode is entered. 22 | /// 23 | ManualAutomatic = 4 24 | } 25 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/SmsStatusReportIndicationStyle.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies the possible indication settings for new status report messages. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum SmsStatusReportIndicationStyle 7 | { 8 | /// 9 | /// No SMS-STATUS-REPORTs are routed to the TE. 10 | /// 11 | Disabled, 12 | /// 13 | /// SMS-STATUS-REPORTs are routed to the TE using unsolicited result code. Depending on the currently 14 | /// selected message format, this is done in either PDU or text mode. 15 | /// 16 | RouteMessage, 17 | /// 18 | /// If SMS-STATUS-REPORT is stored into ME/TA, indication of the memory location is routed to the TE. 19 | /// 20 | RouteMemoryLocation 21 | } 22 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using GsmComm.PduConverter; 2 | using System; 3 | 4 | /// 5 | /// Provides data for the events that deal with message sending. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | public class MessageEventArgs : EventArgs 10 | { 11 | private OutgoingSmsPdu pdu; 12 | 13 | /// 14 | /// The message that was dealt with. 15 | /// 16 | public OutgoingSmsPdu Pdu 17 | { 18 | get 19 | { 20 | return this.pdu; 21 | } 22 | } 23 | 24 | /// 25 | /// Initializes a new instance of the . 26 | /// 27 | /// The message that was dealt with. 28 | public MessageEventArgs(OutgoingSmsPdu pdu) 29 | { 30 | this.pdu = pdu; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/ProgressEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Provides data for the and events. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class ProgressEventArgs : EventArgs 9 | { 10 | private int progress; 11 | 12 | /// 13 | /// Get the current progress value. 14 | /// 15 | public int Progress 16 | { 17 | get 18 | { 19 | return this.progress; 20 | } 21 | } 22 | 23 | /// 24 | /// Initializes a new instance of the event args. 25 | /// 26 | /// The current progress value. 27 | public ProgressEventArgs(int progress) 28 | { 29 | this.progress = progress; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/IndicationBufferSetting.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies what should happen to the TA's indication buffer. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum IndicationBufferSetting 7 | { 8 | /// 9 | /// The TA buffer of unsolicited result codes is flushed to the TE when an 10 | /// other than is entered. 11 | /// 12 | Flush, 13 | /// 14 | /// TA buffer of unsolicited result codes defined within this command is cleared when an 15 | /// other than is entered. 16 | /// 17 | Clear 18 | } 19 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MessageReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Provides data for the events. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public class MessageReceivedEventArgs 7 | { 8 | private IMessageIndicationObject indicationObject; 9 | 10 | /// 11 | /// The object that indicates a new received message. 12 | /// 13 | public IMessageIndicationObject IndicationObject 14 | { 15 | get 16 | { 17 | return this.indicationObject; 18 | } 19 | } 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The object that indicates a new received message. 25 | public MessageReceivedEventArgs(IMessageIndicationObject obj) 26 | { 27 | this.indicationObject = obj; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /GSMCommShared/Interfaces/ISmsSender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Defines the interface for an SMS Sender. 5 | /// 6 | namespace GsmComm.Interfaces 7 | { 8 | public interface ISmsSender 9 | { 10 | /// 11 | /// Sends an SMS message. 12 | /// 13 | /// The message to send. 14 | /// The destination (phone number) to which the message should be sent. 15 | void SendMessage(string message, string destination); 16 | 17 | /// 18 | /// Sends an SMS message. 19 | /// 20 | /// The message to send. 21 | /// The destination (phone number) to which the message should be sent. 22 | /// Specifies if the message should be sent as Unicode. 23 | void SendMessage(string message, string destination, bool unicode); 24 | } 25 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/Charset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Lists some common character sets. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class Charset 9 | { 10 | /// The UCS2 (Unicode) character set 11 | public const string Ucs2 = "UCS2"; 12 | 13 | /// The GSM character set 14 | public const string Gsm = "GSM"; 15 | 16 | /// The PCCP437 character set 17 | public const string Pccp437 = "PCCP437"; 18 | 19 | /// The PCDN character set 20 | public const string Pcdn = "PCDN"; 21 | 22 | /// The IRA character set 23 | public const string Ira = "IRA"; 24 | 25 | /// The ISO 8859-1 character set 26 | public const string Iso8859_1 = "8859-1"; 27 | 28 | /// The characters encoded as hex 29 | public const string Hex = "HEX"; 30 | 31 | public Charset() 32 | { 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MessageErrorEventArgs.cs: -------------------------------------------------------------------------------- 1 | using GsmComm.PduConverter; 2 | using System; 3 | 4 | /// 5 | /// Provides data for the error events that deal with message sending. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | public class MessageErrorEventArgs : MessageEventArgs 10 | { 11 | private Exception exception; 12 | 13 | /// 14 | /// Gets the exception that caused the error. 15 | /// 16 | public Exception Exception 17 | { 18 | get 19 | { 20 | return this.exception; 21 | } 22 | } 23 | 24 | /// 25 | /// Initializes a new instance of the . 26 | /// 27 | /// The message that failed sending. 28 | /// The exception that caused the error. 29 | public MessageErrorEventArgs(OutgoingSmsPdu pdu, Exception exception) : base(pdu) 30 | { 31 | this.exception = exception; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MemoryStatusWithStorage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains the memory status of a specific storage, including the storage type. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class MemoryStatusWithStorage : MemoryStatus 9 | { 10 | private string storage; 11 | 12 | /// 13 | /// Gets the storage that this memory status applies to. 14 | /// 15 | public string Storage 16 | { 17 | get 18 | { 19 | return this.storage; 20 | } 21 | } 22 | 23 | /// 24 | /// Initializes a new instance of the class. 25 | /// 26 | /// The storage that this memory status applies to 27 | /// The number of messages in the storage 28 | /// The total capacity of the storage 29 | public MemoryStatusWithStorage(string storage, int used, int total) : base(used, total) 30 | { 31 | this.storage = storage; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MemoryStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains the memory status of a specific storage. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class MemoryStatus 9 | { 10 | private int used; 11 | 12 | private int total; 13 | 14 | /// 15 | /// Gets the total capacity of the storage. 16 | /// 17 | public int Total 18 | { 19 | get 20 | { 21 | return this.total; 22 | } 23 | } 24 | 25 | /// 26 | /// Gets the number of messages in the storage. 27 | /// 28 | public int Used 29 | { 30 | get 31 | { 32 | return this.used; 33 | } 34 | } 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// The number of messages in the storage 40 | /// The total capacity of the storage 41 | public MemoryStatus(int used, int total) 42 | { 43 | this.used = used; 44 | this.total = total; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmartMessaging/InformationElement.cs: -------------------------------------------------------------------------------- 1 | using GsmComm.PduConverter; 2 | using System; 3 | 4 | /// 5 | /// Implements the base for an information element. 6 | /// 7 | namespace GsmComm.PduConverter.SmartMessaging 8 | { 9 | public abstract class InformationElement 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | protected InformationElement() 15 | { 16 | } 17 | 18 | /// 19 | /// In the derived classes, returns the byte array equivalent of this instance. 20 | /// 21 | /// The byte array. 22 | public abstract byte[] ToByteArray(); 23 | 24 | /// 25 | /// Returns the string equivalent of this instance, which is a hexadecimal representation of the element. 26 | /// 27 | /// The string. 28 | public override string ToString() 29 | { 30 | return Calc.IntToHex(this.ToByteArray()); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MoreMessagesMode.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Contains the possible modes for the AT+CMMS command to set the high-speed SMS sending behaviour. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum MoreMessagesMode 7 | { 8 | /// The function is disabled, the SMS link is not kept open. 9 | Disabled, 10 | /// 11 | /// Keep enabled until the time between the response of the latest message send command (+CMGS, +CMSS, etc.) 12 | /// and the next send command exceeds 1-5 seconds (the exact value is up to ME implementation), then ME shall 13 | /// close the link and TA switches the mode automatically back to disabled (0). 14 | /// 15 | Temporary, 16 | /// 17 | /// Enables (if the time between the response of the latest message send command and the next send command 18 | /// exceeds 1-5 seconds (the exact value is up to ME implementation), ME shall close the link but TA shall 19 | /// not switch automatically back to disabled (0)). 20 | /// 21 | Permanent 22 | } 23 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/AddressData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains network address data. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class AddressData 9 | { 10 | private string address; 11 | 12 | private int typeOfAddress; 13 | 14 | /// 15 | /// Gets the network address. 16 | /// 17 | public string Address 18 | { 19 | get 20 | { 21 | return this.address; 22 | } 23 | } 24 | 25 | /// 26 | /// Gets the type of the . 27 | /// 28 | public int TypeOfAddress 29 | { 30 | get 31 | { 32 | return this.typeOfAddress; 33 | } 34 | } 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// The network address 40 | /// The type of the given address 41 | public AddressData(string address, int typeOfAddress) 42 | { 43 | this.address = address; 44 | this.typeOfAddress = typeOfAddress; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/DeleteFlag.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Lists the possible delete flags for AT+CMGD. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum DeleteFlag 7 | { 8 | /// Delete the message specified in index. 9 | DeleteSpecified, 10 | /// 11 | /// Delete all read messages from preferred message storage, leaving unread messages and stored mobile 12 | /// originated messages (whether sent or not) untouched. 13 | /// 14 | DeleteRead, 15 | /// 16 | /// Delete all read messages from preferred message storage and sent mobile originated messages, 17 | /// leaving unread messages and unsent mobile originated messages untouched. 18 | /// 19 | DeleteReadAndSent, 20 | /// 21 | /// Delete all read messages from preferred message storage, sent and unsent mobile originated messages 22 | /// leaving unread messages untouched. 23 | /// 24 | DeleteReadSentAndUnsent, 25 | /// 26 | /// Delete all messages from preferred message storage including unread messages. 27 | /// 28 | DeleteAll 29 | } 30 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MemoryLocation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains the memory location of a saved message. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class MemoryLocation : IMessageIndicationObject 9 | { 10 | private string storage; 11 | 12 | private int index; 13 | 14 | /// 15 | /// Gets the message index within the specified . 16 | /// 17 | public int Index 18 | { 19 | get 20 | { 21 | return this.index; 22 | } 23 | } 24 | 25 | /// 26 | /// Gets the storage where the message is saved. 27 | /// 28 | public string Storage 29 | { 30 | get 31 | { 32 | return this.storage; 33 | } 34 | } 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// The storage where the message is saved. 40 | /// The message index within the specified storage. 41 | public MemoryLocation(string storage, int index) 42 | { 43 | this.storage = storage; 44 | this.index = index; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/PhonebookEntryWithStorage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Serialization; 3 | 4 | /// 5 | /// Represents a extended by the storage value. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | public class PhonebookEntryWithStorage : PhonebookEntry 11 | { 12 | private string storage; 13 | 14 | /// 15 | /// The storage the entry was read from. 16 | /// 17 | [XmlAttribute] 18 | public string Storage 19 | { 20 | get 21 | { 22 | return this.storage; 23 | } 24 | set 25 | { 26 | this.storage = value; 27 | } 28 | } 29 | 30 | /// 31 | /// Initializes a new instance of the class. 32 | /// 33 | public PhonebookEntryWithStorage() 34 | { 35 | } 36 | 37 | /// 38 | /// Initializes a new instance of the class using the specified values. 39 | /// 40 | /// The phonebook entry 41 | /// The storage the entry was read from. 42 | public PhonebookEntryWithStorage(PhonebookEntry entry, string storage) : base(entry) 43 | { 44 | this.storage = storage; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MessageIndicationMode.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies the possible modes for for new message indications. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum MessageIndicationMode 7 | { 8 | /// 9 | /// Buffer unsolicited result codes in the TA. If TA result code buffer is full, indications can be 10 | /// buffered in some other place or the oldest indications may be discarded and replaced with the new 11 | /// received indications. 12 | /// 13 | DoNotForward, 14 | /// 15 | /// Discard indication and reject new received message unsolicited result codes when TA-TE link is 16 | /// reserved (e.g. in on-line data mode). Otherwise forward them directly to the TE. 17 | /// 18 | SkipWhenReserved, 19 | /// 20 | /// Buffer unsolicited result codes in the TA when TA-TE link is reserved (e.g. in on-line data mode) and 21 | /// flush them to the TE after reservation. Otherwise forward them directly to the TE. 22 | /// 23 | BufferAndFlush, 24 | /// 25 | /// Forward unsolicited result codes directly to the TE. TA-TE link specific inband technique used to 26 | /// embed result codes and data when TA is in on-line data mode. 27 | /// 28 | ForwardAlways 29 | } 30 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/MessageWaitingIndication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Message waiting indication. This class is abstract. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public abstract class MessageWaitingIndication : DataCodingScheme 9 | { 10 | private bool indicationActive; 11 | 12 | private bool bit2; 13 | 14 | private byte indicationType; 15 | 16 | /// 17 | /// Gets if the indication should be set active. 18 | /// 19 | /// If true, the indication should be set active, if false, the indication should be set inactive. 20 | public bool IndicationActive 21 | { 22 | get 23 | { 24 | return this.indicationActive; 25 | } 26 | } 27 | 28 | /// 29 | /// Gets the indication type, how the indication should be shown. 30 | /// 31 | public byte IndicationType 32 | { 33 | get 34 | { 35 | return this.indicationType; 36 | } 37 | } 38 | 39 | /// 40 | /// Initializes a new instance of the class. 41 | /// 42 | /// The DCS byte to decode. 43 | public MessageWaitingIndication(byte dcs) : base(dcs) 44 | { 45 | this.indicationType = (byte)(dcs & 3); 46 | this.bit2 = (dcs & 4) > 0; 47 | this.indicationActive = (dcs & 8) > 0; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/LoglineAddedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Provides data for the event. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class LoglineAddedEventArgs 9 | { 10 | private LogLevel level; 11 | 12 | private string text; 13 | 14 | /// 15 | /// Gets the log level. 16 | /// 17 | public LogLevel Level 18 | { 19 | get 20 | { 21 | return this.level; 22 | } 23 | } 24 | 25 | /// 26 | /// Gets the log text. 27 | /// 28 | public string Text 29 | { 30 | get 31 | { 32 | return this.text; 33 | } 34 | } 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// The log level. 40 | /// The log text. 41 | public LoglineAddedEventArgs(LogLevel level, string text) 42 | { 43 | if (Enum.IsDefined(typeof(LogLevel), level)) 44 | { 45 | if (text != null) 46 | { 47 | this.level = level; 48 | this.text = text; 49 | return; 50 | } 51 | else 52 | { 53 | throw new ArgumentNullException("text"); 54 | } 55 | } 56 | else 57 | { 58 | throw new ArgumentException(string.Concat("Invalid log level \"", level, "\".")); 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/CbmIndicationStyle.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies the possible indication settings for new cell broadcast messages (CBMs). 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum CbmIndicationStyle 7 | { 8 | /// 9 | /// No CBM indications are routed to the TE. 10 | /// 11 | Disabled, 12 | /// 13 | /// If CBM is stored into ME/TA, indication of the memory location is routed to the TE. 14 | /// 15 | RouteMemoryLocation, 16 | /// 17 | /// New CBMs are routed directly to the TE. 18 | /// 19 | /// If ME supports data coding groups which define special routing also for messages other than 20 | /// class 3 (e.g. SIM specific messages), ME may choose not to route messages of such data coding schemes 21 | /// into TE (indication of a stored CBM may be given as with . 22 | RouteMessage, 23 | /// 24 | /// Class 3 CBMs are routed directly to TE using the same indications as with . 25 | /// If CBM storage is supported, messages of other classes result in indication as with 26 | /// . 27 | /// 28 | RouteSpecial 29 | } 30 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/IncomingMessageFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// The base class for the message flags of incoming messages. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public abstract class IncomingMessageFlags 9 | { 10 | /// 11 | /// Gets the message type. 12 | /// 13 | public abstract IncomingMessageType MessageType 14 | { 15 | get; 16 | } 17 | 18 | protected IncomingMessageFlags() 19 | { 20 | } 21 | 22 | /// 23 | /// In derived classes, converts the specified value into a new instance of the class. 24 | /// 25 | /// A value. 26 | protected abstract void FromByte(byte b); 27 | 28 | public static implicit operator Byte(IncomingMessageFlags flags) 29 | { 30 | return flags.ToByte(); 31 | } 32 | 33 | /// 34 | /// In derived classes, returns the byte equivalent of this instance. 35 | /// 36 | /// The byte value. 37 | public abstract byte ToByte(); 38 | 39 | /// 40 | /// Returns the string equivalent of this instance. 41 | /// 42 | /// The string. 43 | public override string ToString() 44 | { 45 | byte num = this.ToByte(); 46 | return num.ToString(); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/OutgoingMessageFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// The base class for the message flags of outgoing messages. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public abstract class OutgoingMessageFlags 9 | { 10 | /// 11 | /// Gets the message type. 12 | /// 13 | public abstract OutgoingMessageType MessageType 14 | { 15 | get; 16 | } 17 | 18 | protected OutgoingMessageFlags() 19 | { 20 | } 21 | 22 | /// 23 | /// In derived classes, converts the specified value into a new instance of the class. 24 | /// 25 | /// A value. 26 | protected abstract void FromByte(byte b); 27 | 28 | public static implicit operator Byte(OutgoingMessageFlags flags) 29 | { 30 | return flags.ToByte(); 31 | } 32 | 33 | /// 34 | /// In derived classes, returns the byte equivalent of this instance. 35 | /// 36 | /// The byte value. 37 | public abstract byte ToByte(); 38 | 39 | /// 40 | /// Returns the string equivalent of this instance. 41 | /// 42 | /// The string. 43 | public override string ToString() 44 | { 45 | byte num = this.ToByte(); 46 | return num.ToString(); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/IdentificationInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains information that identify a mobile phone. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public struct IdentificationInfo 9 | { 10 | private string manufacturer; 11 | 12 | private string model; 13 | 14 | private string revision; 15 | 16 | private string serialNumber; 17 | 18 | /// 19 | /// Gets or sets the manufacturer. 20 | /// 21 | public string Manufacturer 22 | { 23 | get 24 | { 25 | return this.manufacturer; 26 | } 27 | set 28 | { 29 | this.manufacturer = value; 30 | } 31 | } 32 | 33 | /// 34 | /// Gets or sets the model. 35 | /// 36 | public string Model 37 | { 38 | get 39 | { 40 | return this.model; 41 | } 42 | set 43 | { 44 | this.model = value; 45 | } 46 | } 47 | 48 | /// 49 | /// Gets or sets the revision. 50 | /// 51 | public string Revision 52 | { 53 | get 54 | { 55 | return this.revision; 56 | } 57 | set 58 | { 59 | this.revision = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Gets or sets the serial number. 65 | /// 66 | public string SerialNumber 67 | { 68 | get 69 | { 70 | return this.serialNumber; 71 | } 72 | set 73 | { 74 | this.serialNumber = value; 75 | } 76 | } 77 | 78 | } 79 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/MessageCoding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Data coding/Message class 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class MessageCoding : DataCodingScheme 9 | { 10 | private bool bit3; 11 | 12 | private byte dataCoding; 13 | 14 | private byte messageClass; 15 | 16 | /// 17 | /// Gets the alphabet being used. 18 | /// 19 | public override byte Alphabet 20 | { 21 | get 22 | { 23 | return this.dataCoding; 24 | } 25 | } 26 | 27 | /// 28 | /// Gets the data coding. 29 | /// 30 | public byte DataCoding 31 | { 32 | get 33 | { 34 | return this.dataCoding; 35 | } 36 | } 37 | 38 | /// 39 | /// Gets the message class. 40 | /// 41 | public byte MessageClass 42 | { 43 | get 44 | { 45 | return this.messageClass; 46 | } 47 | } 48 | 49 | /// 50 | /// Initializes a new instance of the class. 51 | /// 52 | /// The DCS byte to decode. 53 | public MessageCoding(byte dcs) : base(dcs) 54 | { 55 | object obj; 56 | this.bit3 = (dcs & 8) > 0; 57 | MessageCoding messageCoding = this; 58 | if ((dcs & 4) > 0) 59 | { 60 | obj = 1; 61 | } 62 | else 63 | { 64 | obj = null; 65 | } 66 | messageCoding.dataCoding = (byte)obj; 67 | this.messageClass = (byte)(dcs & 3); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/SignalQualityInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains the signal strength as calculcated by the ME. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class SignalQualityInfo 9 | { 10 | private int signalStrength; 11 | 12 | private int bitErrorRate; 13 | 14 | /// 15 | /// Gets the bit error rate. 16 | /// 17 | /// Usually 99 is used if the bit error rate is not known. 18 | public int BitErrorRate 19 | { 20 | get 21 | { 22 | return this.bitErrorRate; 23 | } 24 | } 25 | 26 | /// 27 | /// Gets the signal strength. 28 | /// 29 | /// Usual value is an RSSI value in the range of 0 (no signal) to 31 (best signal), 30 | /// 99 if not known. 31 | public int SignalStrength 32 | { 33 | get 34 | { 35 | return this.signalStrength; 36 | } 37 | } 38 | 39 | /// 40 | /// Initializes a new instance of the class. 41 | /// 42 | /// The signal strength, usual as an RSSI value in the range of 0 (no signal) 43 | /// to 31 (best signal), 99 if not known. 44 | /// The bit error rate, 99 if not known. 45 | public SignalQualityInfo(int signalStrength, int bitErrorRate) 46 | { 47 | this.signalStrength = signalStrength; 48 | this.bitErrorRate = bitErrorRate; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/BatteryChargeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains the ME battery charging status and charge level. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class BatteryChargeInfo 9 | { 10 | private int bcs; 11 | 12 | private int bcl; 13 | 14 | /// 15 | /// Gets the battery charge level. 16 | /// 17 | /// Usual values are in the range from 0 (empty) to 100 (full). 18 | public int BatteryChargeLevel 19 | { 20 | get 21 | { 22 | return this.bcl; 23 | } 24 | } 25 | 26 | /// 27 | /// Gets the battery charging status. 28 | /// 29 | /// Usual values are 0 for "not charging" and 1 for "charging". 30 | public int BatteryChargingStatus 31 | { 32 | get 33 | { 34 | return this.bcs; 35 | } 36 | } 37 | 38 | /// 39 | /// Initializes a new instance of the class. 40 | /// 41 | /// 42 | /// The battery charging status, usually 0 for "not charging" and 1 for "charging". 43 | /// 44 | /// 45 | /// The battery charge level, usually in the range of 0 (empty) to 100 (full). 46 | /// 47 | public BatteryChargeInfo(int batteryChargingStatus, int batteryChargeLevel) 48 | { 49 | this.bcs = batteryChargingStatus; 50 | this.bcl = batteryChargeLevel; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/SmsDeliverIndicationStyle.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Specifies the possible indication styles for new SMS-DELIVER messages. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum SmsDeliverIndicationStyle 7 | { 8 | /// 9 | /// No SMS-DELIVER indications are routed to the TE. 10 | /// 11 | Disabled, 12 | /// 13 | /// If SMS-DELIVER is stored into ME/TA, indication of the memory location is routed to the TE. 14 | /// 15 | RouteMemoryLocation, 16 | /// 17 | /// SMS-DELIVERs (except class 2 messages and messages in the message waiting indication 18 | /// group (store message)) are routed directly to the TE. Depending on the currently selected message 19 | /// format, this is done in either PDU or text mode. 20 | /// Class 2 messages and messages in the message waiting indication group (store message) result in 21 | /// the same indication as with . 22 | /// 23 | RouteMessage, 24 | /// 25 | /// Class 3 SMS-DELIVERs are routed directly to TE with the same format as with . 26 | /// Messages of other data coding schemes result in indication as with . 27 | /// 28 | RouteSpecial 29 | } 30 | } -------------------------------------------------------------------------------- /GSMCommServer/Server/MessageSendErrorEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Provides data for the error events that deal with message sending. 5 | /// 6 | namespace GsmComm.Server 7 | { 8 | public class MessageSendErrorEventArgs : MessageSendEventArgs 9 | { 10 | private Exception exception; 11 | 12 | /// 13 | /// Gets the exception that caused the error. 14 | /// 15 | public Exception Exception 16 | { 17 | get 18 | { 19 | return this.exception; 20 | } 21 | } 22 | 23 | /// 24 | /// Initializes a new instance of the . 25 | /// 26 | /// The message that failed sending. 27 | /// The destination the message was attempted to send to. 28 | /// The exception that caused the error. 29 | public MessageSendErrorEventArgs(string message, string destination, Exception exception) : base(message, destination) 30 | { 31 | this.exception = exception; 32 | } 33 | 34 | /// 35 | /// Initializes a new instance of the . 36 | /// 37 | /// The message that failed sending. 38 | /// The destination the message was attempted to send to. 39 | /// The exception that caused the error. 40 | /// The name of the user from which the action started. 41 | public MessageSendErrorEventArgs(string message, string destination, Exception exception, string userName) : base(message, destination, userName) 42 | { 43 | this.exception = exception; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/GeneralDataCoding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// General Data Coding indication 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class GeneralDataCoding : DataCodingScheme 9 | { 10 | private bool compressed; 11 | 12 | private bool classSpecified; 13 | 14 | private byte alphabet; 15 | 16 | private byte messageClass; 17 | 18 | /// 19 | /// Gets the alphabet being used. 20 | /// 21 | public override byte Alphabet 22 | { 23 | get 24 | { 25 | return this.alphabet; 26 | } 27 | } 28 | 29 | /// 30 | /// Determines if the property has a message class meaning. If not, 31 | /// the property contains a reserved value and has no message class meaning. 32 | /// 33 | public bool ClassSpecified 34 | { 35 | get 36 | { 37 | return this.classSpecified; 38 | } 39 | } 40 | 41 | /// 42 | /// Gets whether the text is compressed. 43 | /// 44 | public bool Compressed 45 | { 46 | get 47 | { 48 | return this.compressed; 49 | } 50 | } 51 | 52 | /// 53 | /// Gets the message class. 54 | /// 55 | public byte MessageClass 56 | { 57 | get 58 | { 59 | return this.messageClass; 60 | } 61 | } 62 | 63 | /// 64 | /// Initializes a new instance of the class. 65 | /// 66 | /// The DCS byte to decode. 67 | public GeneralDataCoding(byte dcs) : base(dcs) 68 | { 69 | this.compressed = (dcs & 32) > 0; 70 | this.classSpecified = (dcs & 16) > 0; 71 | this.alphabet = (byte)(dcs >> 2 & 3); 72 | this.messageClass = (byte)(dcs & 3); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/ShortMessageFromPhone.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Serialization; 3 | 4 | /// 5 | /// Represents a short message read from the phone in undecoded PDU format. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | public class ShortMessageFromPhone : ShortMessage 11 | { 12 | private int index; 13 | 14 | private int status; 15 | 16 | /// 17 | /// The index of the message. 18 | /// 19 | [XmlAttribute] 20 | public int Index 21 | { 22 | get 23 | { 24 | return this.index; 25 | } 26 | set 27 | { 28 | this.index = value; 29 | } 30 | } 31 | 32 | /// 33 | /// The message status (e.g. read, unread, etc.) 34 | /// 35 | [XmlAttribute] 36 | public int Status 37 | { 38 | get 39 | { 40 | return this.status; 41 | } 42 | set 43 | { 44 | this.status = value; 45 | } 46 | } 47 | 48 | /// 49 | /// Initializes a new instance of the class. 50 | /// 51 | public ShortMessageFromPhone() 52 | { 53 | this.index = 0; 54 | this.status = 0; 55 | } 56 | 57 | /// 58 | /// Initializes a new instance of the class. 59 | /// 60 | /// The index where the message is saved in the device in the currently active storage. 61 | /// The message status (e.g. read or unread) 62 | /// The alphabet in which the message is encoded. 63 | /// The length of the data. 64 | /// The actual message. 65 | /// The object contains all data returned by the phone. 66 | /// 67 | public ShortMessageFromPhone(int index, int status, string alpha, int length, string data) : base(alpha, length, data) 68 | { 69 | this.Index = index; 70 | this.Status = status; 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MessageMemoryStatus.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Contains status information of all message memories. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public class MessageMemoryStatus 7 | { 8 | private MemoryStatus readStorage; 9 | 10 | private MemoryStatus writeStorage; 11 | 12 | private MemoryStatus receiveStorage; 13 | 14 | /// 15 | /// Gets or sets the status of the current read storage. 16 | /// 17 | public MemoryStatus ReadStorage 18 | { 19 | get 20 | { 21 | return this.readStorage; 22 | } 23 | set 24 | { 25 | this.readStorage = value; 26 | } 27 | } 28 | 29 | /// 30 | /// Gets or sets the status of the current receive storage. 31 | /// 32 | public MemoryStatus ReceiveStorage 33 | { 34 | get 35 | { 36 | return this.receiveStorage; 37 | } 38 | set 39 | { 40 | this.receiveStorage = value; 41 | } 42 | } 43 | 44 | /// 45 | /// Gets or sets the status of the current write storage. 46 | /// 47 | public MemoryStatus WriteStorage 48 | { 49 | get 50 | { 51 | return this.writeStorage; 52 | } 53 | set 54 | { 55 | this.writeStorage = value; 56 | } 57 | } 58 | 59 | /// 60 | /// Initializes a new instance of the class. 61 | /// 62 | public MessageMemoryStatus() 63 | { 64 | } 65 | 66 | /// 67 | /// Initializes a new instance of the class with the specified parameters. 68 | /// 69 | /// Status of the current read storage 70 | /// Status of the current write storage 71 | /// Status of the current receive storage 72 | public MessageMemoryStatus(MemoryStatus readStorage, MemoryStatus writeStorage, MemoryStatus receiveStorage) 73 | { 74 | this.readStorage = readStorage; 75 | this.writeStorage = writeStorage; 76 | this.receiveStorage = receiveStorage; 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /GSMCommServer/Server/AuthorizationModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Runtime.Remoting.Channels; 4 | using System.Security.Principal; 5 | 6 | /// 7 | /// Implements the authorization module for the server. 8 | /// 9 | namespace GsmComm.Server 10 | { 11 | public class AuthorizationModule : IAuthorizeRemotingConnection 12 | { 13 | private bool allowAnonymous; 14 | 15 | /// 16 | /// Initializes a new instance of the module. 17 | /// 18 | /// Specifies if users authenticated anonymously can 19 | /// connect to the current channel. 20 | public AuthorizationModule(bool allowAnonymous) 21 | { 22 | this.allowAnonymous = allowAnonymous; 23 | } 24 | 25 | /// 26 | /// Gets a Boolean value that indicates whether the network address of the client is 27 | /// authorized to connect on the current channel. 28 | /// 29 | /// The that identifies the network address of the client. 30 | /// true if the network address of the client is authorized; otherwise, false. 31 | public bool IsConnectingEndPointAuthorized(EndPoint endPoint) 32 | { 33 | return true; 34 | } 35 | 36 | /// 37 | /// Gets a Boolean value that indicates whether the user identity of the client is 38 | /// authorized to connect on the current channel. 39 | /// 40 | /// The that represents the user identity of the client. 41 | /// true if the user identity of the client is authorized; otherwise, false. 42 | public bool IsConnectingIdentityAuthorized(IIdentity identity) 43 | { 44 | bool flag = true; 45 | WindowsIdentity windowsIdentity = identity as WindowsIdentity; 46 | if (windowsIdentity != null && windowsIdentity.IsAnonymous && !this.allowAnonymous) 47 | { 48 | flag = false; 49 | } 50 | return flag; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/ShortMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Serialization; 3 | 4 | /// 5 | /// Represents a short message in undecoded PDU format. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | [XmlInclude(typeof(ShortMessageFromPhone))] 11 | public class ShortMessage : IMessageIndicationObject 12 | { 13 | private string alpha; 14 | 15 | private int length; 16 | 17 | private string data; 18 | 19 | /// 20 | /// The alphabet in which the message is encoded. 21 | /// 22 | [XmlAttribute] 23 | public string Alpha 24 | { 25 | get 26 | { 27 | return this.alpha; 28 | } 29 | set 30 | { 31 | this.alpha = value; 32 | } 33 | } 34 | 35 | /// 36 | /// The actual message. 37 | /// 38 | [XmlElement] 39 | public string Data 40 | { 41 | get 42 | { 43 | return this.data; 44 | } 45 | set 46 | { 47 | this.data = value; 48 | } 49 | } 50 | 51 | /// 52 | /// The length of the message. In PDU format, this is the actual length without the SMSC header. 53 | /// 54 | [XmlAttribute] 55 | public int Length 56 | { 57 | get 58 | { 59 | return this.length; 60 | } 61 | set 62 | { 63 | this.length = value; 64 | } 65 | } 66 | 67 | /// 68 | /// Initializes a new instance of the class. 69 | /// 70 | public ShortMessage() 71 | { 72 | this.alpha = string.Empty; 73 | this.length = 0; 74 | this.data = string.Empty; 75 | } 76 | 77 | /// 78 | /// Initializes a new instance of the class. 79 | /// 80 | /// The alphabet in which the message is encoded. 81 | /// The length of the data. 82 | /// The message. 83 | public ShortMessage(string alpha, int length, string data) 84 | { 85 | this.Alpha = alpha; 86 | this.Length = length; 87 | this.Data = data; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/DecodedShortMessage.cs: -------------------------------------------------------------------------------- 1 | using GsmComm.PduConverter; 2 | using System; 3 | 4 | /// 5 | /// Represents a short message from the phone in its decoded state. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | public class DecodedShortMessage 10 | { 11 | private int index; 12 | 13 | private SmsPdu data; 14 | 15 | private PhoneMessageStatus status; 16 | 17 | private string storage; 18 | 19 | /// 20 | /// Gets the decoded message. 21 | /// 22 | public SmsPdu Data 23 | { 24 | get 25 | { 26 | return this.data; 27 | } 28 | } 29 | 30 | /// 31 | /// Gets the index where the message is saved in the device in the . 32 | /// 33 | public int Index 34 | { 35 | get 36 | { 37 | return this.index; 38 | } 39 | } 40 | 41 | /// 42 | /// Gets the parsed message status. 43 | /// 44 | public PhoneMessageStatus Status 45 | { 46 | get 47 | { 48 | return this.status; 49 | } 50 | } 51 | 52 | /// 53 | /// Gets the phone storage the message was read from. 54 | /// 55 | public string Storage 56 | { 57 | get 58 | { 59 | return this.storage; 60 | } 61 | } 62 | 63 | /// 64 | /// Initializes a new instance of the class. 65 | /// 66 | /// The index where the message is saved in the device in the . 67 | /// The decoded message. 68 | /// The parsed message status. 69 | /// The phone storage the message was read from. 70 | public DecodedShortMessage(int index, SmsPdu data, PhoneMessageStatus status, string storage) 71 | { 72 | this.index = index; 73 | this.data = data; 74 | this.status = status; 75 | this.storage = storage; 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /GSMCommServer/Server/MessageSendEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Provides data for the events that deal with message sending. 5 | /// 6 | namespace GsmComm.Server 7 | { 8 | public class MessageSendEventArgs : EventArgs 9 | { 10 | private string message; 11 | 12 | private string destination; 13 | 14 | private string userName; 15 | 16 | /// 17 | /// Gets the destination the message is being or was sent to. 18 | /// 19 | public string Destination 20 | { 21 | get 22 | { 23 | return this.destination; 24 | } 25 | } 26 | 27 | /// 28 | /// Gets the message that is being sent or was sent. 29 | /// 30 | public string Message 31 | { 32 | get 33 | { 34 | return this.message; 35 | } 36 | } 37 | 38 | /// 39 | /// Gets the user name from which the action started. 40 | /// 41 | public string UserName 42 | { 43 | get 44 | { 45 | return this.userName; 46 | } 47 | } 48 | 49 | /// 50 | /// Initializes a new instance of the . 51 | /// 52 | /// The message that is being sent or was sent. 53 | /// The destination the message is being or was sent to. 54 | public MessageSendEventArgs(string message, string destination) 55 | { 56 | this.message = message; 57 | this.destination = destination; 58 | this.userName = string.Empty; 59 | } 60 | 61 | /// 62 | /// Initializes a new instance of the . 63 | /// 64 | /// The message that is being sent or was sent. 65 | /// The destination the message is being or was sent to. 66 | /// The name of the user from which the action started. 67 | public MessageSendEventArgs(string message, string destination, string userName) 68 | { 69 | this.message = message; 70 | this.destination = destination; 71 | this.userName = userName; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /GSMComm.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PDUConverter", "PDUConverter\PDUConverter.csproj", "{5E657EFE-0A30-466D-B025-FF177E23A727}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GSMCommShared", "GSMCommShared\GSMCommShared.csproj", "{71EA4054-A98A-46BA-84FA-81652DB72B72}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GSMCommunication", "GSMCommunication\GSMCommunication.csproj", "{32B76F1E-B022-47C6-86EC-28639D348067}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GSMCommServer", "GSMCommServer\GSMCommServer.csproj", "{67CB92ED-436B-4005-A6D6-092503D6E496}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {5E657EFE-0A30-466D-B025-FF177E23A727}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {5E657EFE-0A30-466D-B025-FF177E23A727}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {5E657EFE-0A30-466D-B025-FF177E23A727}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {5E657EFE-0A30-466D-B025-FF177E23A727}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {71EA4054-A98A-46BA-84FA-81652DB72B72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {71EA4054-A98A-46BA-84FA-81652DB72B72}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {71EA4054-A98A-46BA-84FA-81652DB72B72}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {71EA4054-A98A-46BA-84FA-81652DB72B72}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {32B76F1E-B022-47C6-86EC-28639D348067}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {32B76F1E-B022-47C6-86EC-28639D348067}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {32B76F1E-B022-47C6-86EC-28639D348067}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {32B76F1E-B022-47C6-86EC-28639D348067}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {67CB92ED-436B-4005-A6D6-092503D6E496}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {67CB92ED-436B-4005-A6D6-092503D6E496}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {67CB92ED-436B-4005-A6D6-092503D6E496}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {67CB92ED-436B-4005-A6D6-092503D6E496}.Release|Any CPU.Build.0 = Release|Any CPU 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/KnownMessageStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// This enumarator represents the known status codes of a TP-ST octet. 5 | /// Reserved and SC specific values are not part of this list. 6 | /// 7 | namespace GsmComm.PduConverter 8 | { 9 | public enum KnownMessageStatus : byte 10 | { 11 | /// Short message received by the SME. 12 | OK_Received, 13 | /// Short message forwarded by the SC to the SME but the SC is unable to confirm delivery. 14 | OK_NotConfirmed, 15 | /// Short message replaced by the SC. 16 | OK_Replaced, 17 | /// Congestion. 18 | Temp_Congestion, 19 | /// SME busy. 20 | Temp_SmeBusy, 21 | /// No response from SME. 22 | Temp_NoResponseFromSme, 23 | /// Service Rejected. 24 | Temp_ServiceRejected, 25 | /// Quality of service not available. 26 | Temp_QosNotAvailable, 27 | /// Error in SME. 28 | Temp_ErrorInSme, 29 | /// Remote procedure error. 30 | Perm_RemoteProcedureError, 31 | /// Incompatible destination. 32 | Perm_IncompatibleDestination, 33 | /// Connection rejected by SME. 34 | Perm_ConnectionRejectedBySme, 35 | /// Not obtainable. 36 | Perm_NotObtainable, 37 | /// Quality of service not available. 38 | Perm_QosNotAvailable, 39 | /// No interworking available. 40 | Perm_NoInterworkingAvailable, 41 | /// SM Validity Period expired. 42 | Perm_SMValidityPeriodExpired, 43 | /// SM Deleted by originating SME. 44 | Perm_SMDeletedByOriginatingSme, 45 | /// SM Deleted by SC Administration. 46 | Perm_SMDeletedBySCAdministration, 47 | /// SM does not exist (The SM may have previously existed in the SC but the 48 | /// SC no longer has knowledge of it or the SM may never have previously existed in the SC). 49 | Perm_SMDoesNotExist, 50 | /// Congestion. 51 | Ntemp_Congestion, 52 | /// SME busy. 53 | Ntemp_SmeBusy, 54 | /// No response from SME. 55 | Ntemp_NoResponseFromSme, 56 | /// Service rejected. 57 | Ntemp_ServiceRejected, 58 | /// Quality of service not available. 59 | Ntemp_QosNotAvailable, 60 | /// Error in SME. 61 | Ntemp_ErrorInSme 62 | } 63 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/OperatorInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains information about a GSM network operator. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class OperatorInfo 9 | { 10 | private OperatorFormat format; 11 | 12 | private string theOperator; 13 | 14 | private string accessTechnology; 15 | 16 | /// 17 | /// Gets the access technology registered to. 18 | /// 19 | /// This is optional, as it is only useful for terminals capable to register to more than 20 | /// one access technology. 21 | public string AccessTechnology 22 | { 23 | get 24 | { 25 | return this.accessTechnology; 26 | } 27 | } 28 | 29 | /// 30 | /// Gets the format in which is specified in. 31 | /// 32 | public OperatorFormat Format 33 | { 34 | get 35 | { 36 | return this.format; 37 | } 38 | } 39 | 40 | /// 41 | /// Gets the operator in the format specified by . 42 | /// 43 | public string TheOperator 44 | { 45 | get 46 | { 47 | return this.theOperator; 48 | } 49 | } 50 | 51 | /// 52 | /// Initializes a new instance of the class. 53 | /// 54 | /// The format in which theOperator is specified in. See 55 | /// for a list of possible values. 56 | /// 57 | /// The operator in the format specified by format 58 | public OperatorInfo(OperatorFormat format, string theOperator) 59 | { 60 | this.format = format; 61 | this.theOperator = theOperator; 62 | this.accessTechnology = string.Empty; 63 | } 64 | 65 | /// 66 | /// Initializes a new instance of the class. 67 | /// 68 | /// The format in which theOperator is specified in. See 69 | /// for a list of possible values. 70 | /// 71 | /// The operator in the format specified by format 72 | /// The access technology registered to. 73 | public OperatorInfo(OperatorFormat format, string theOperator, string accessTechnology) 74 | { 75 | this.format = format; 76 | this.theOperator = theOperator; 77 | this.accessTechnology = accessTechnology; 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/PinStatus.cs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Lists the possible PIN states of the phone. 3 | /// 4 | namespace GsmComm.GsmCommunication 5 | { 6 | public enum PinStatus 7 | { 8 | /// Phone does not wait for any password 9 | Ready, 10 | /// Phone is waiting for SIM PIN to be given 11 | SimPin, 12 | /// Phone is waiting for SIM PUK to be given 13 | SimPuk, 14 | /// Phone is waiting for phone to SIM card password to be given 15 | PhoneToSimPin, 16 | /// Phone is waiting for phone-to-very first SIM card password to be given 17 | PhoneToFirstSimPin, 18 | /// Phone is waiting for phone-to-very first SIM card unblocking password to be given 19 | PhoneToFirstSimPuk, 20 | /// 21 | /// Phone is waiting for SIM PIN2 to be given (this status should be expected to be returned 22 | /// by phones only when the last executed command resulted in PIN2 authentication failure (i.e. device 23 | /// error 17); if PIN2 is not entered right after the failure, the phone should be expected not to block 24 | /// its operation) 25 | /// 26 | SimPin2, 27 | /// 28 | /// Phone is waiting for SIM PUK2 to be given (this status should be expected to be returned 29 | /// by phones only when the last executed command resulted in PUK2 authentication failure (i.e. device 30 | /// error 18); if PUK2 is not entered right after the failure, the phone should be expected not to block 31 | /// its operation) 32 | /// 33 | SimPuk2, 34 | /// Phone is waiting for network personalization password to be given 35 | PhoneToNetworkPin, 36 | /// Phone is waiting for network personalization unblocking password to be given 37 | PhoneToNetworkPuk, 38 | /// Phone is waiting for network subset personalization password to be given 39 | PhoneToNetworkSubsetPin, 40 | /// Phone is waiting for network subset personalization unblocking password to be given 41 | PhoneToNetworkSubsetPuk, 42 | /// Phone is waiting for service provider personalization password to be given 43 | PhoneToServiceProviderPin, 44 | /// Phone is waiting for service provider personalization unblocking password to be given 45 | PhoneToServiceProviderPuk, 46 | /// Phone is waiting for corporate personalization password to be given 47 | PhoneToCorporatePin, 48 | /// Phone is waiting for corporate personalization unblocking password to be given 49 | PhoneToCorporatePuk 50 | } 51 | } -------------------------------------------------------------------------------- /GSMCommShared/GSMCommShared.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {71ea4054-a98a-46ba-84fa-81652db72b72} 5 | 2 6 | Debug 7 | AnyCPU 8 | GSMCommShared 9 | Library 10 | GsmComm 11 | v4.0 12 | 13 | 14 | bin\Debug\ 15 | true 16 | DEBUG;TRACE 17 | false 18 | 4 19 | full 20 | prompt 21 | AnyCPU 22 | 23 | 24 | bin\Release\ 25 | false 26 | TRACE 27 | true 28 | 4 29 | pdbonly 30 | prompt 31 | AnyCPU 32 | 33 | 34 | 35 | 36 | false 37 | false 38 | 39 | 40 | false 41 | false 42 | 43 | 44 | false 45 | false 46 | 47 | 48 | false 49 | false 50 | 51 | 52 | false 53 | false 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmartMessaging/ConcatInfoComparer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | /// 5 | /// Implements a method to compare objects. 6 | /// 7 | /// This comparer is provided for performing sort order comparisons. It does not perform exact equality comparisons. 8 | namespace GsmComm.PduConverter.SmartMessaging 9 | { 10 | public class ConcatInfoComparer : IComparer 11 | { 12 | public ConcatInfoComparer() 13 | { 14 | } 15 | 16 | /// 17 | /// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other. 18 | /// 19 | /// The first object to compare. 20 | /// The second object to compare. 21 | /// 22 | /// 23 | /// 24 | /// Value 25 | /// Condition 26 | /// 27 | /// 28 | /// Less than zero 29 | /// x is less than y. 30 | /// 31 | /// 32 | /// Zero 33 | /// x equals y. 34 | /// 35 | /// 36 | /// Greater than zero 37 | /// x is greater than y. 38 | /// 39 | /// 40 | /// 41 | /// 42 | /// This method provides a sort order comparison for type . 43 | /// Comparing null with any reference type is allowed and does not generate an exception. A null reference 44 | /// is considered to be less than any reference that is not null. 45 | /// 46 | public int Compare(IConcatenationInfo x, IConcatenationInfo y) 47 | { 48 | int num; 49 | if (x != null || y != null) 50 | { 51 | if (x != null || y == null) 52 | { 53 | if (x == null || y != null) 54 | { 55 | if (x.ReferenceNumber != y.ReferenceNumber) 56 | { 57 | ushort referenceNumber = x.ReferenceNumber; 58 | num = referenceNumber.CompareTo(y.ReferenceNumber); 59 | } 60 | else 61 | { 62 | byte currentNumber = x.CurrentNumber; 63 | num = currentNumber.CompareTo(y.CurrentNumber); 64 | } 65 | } 66 | else 67 | { 68 | num = 1; 69 | } 70 | } 71 | else 72 | { 73 | num = -1; 74 | } 75 | } 76 | else 77 | { 78 | num = 0; 79 | } 80 | return num; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /GSMCommShared/MessageServiceErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | /// 5 | /// The exception that gets thrown when there is an error with the message service. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | public class MessageServiceErrorException : CommException 11 | { 12 | private int errorCode; 13 | 14 | /// 15 | /// Gets the error code reported by the network. 16 | /// 17 | public int ErrorCode 18 | { 19 | get 20 | { 21 | return this.errorCode; 22 | } 23 | } 24 | 25 | /// 26 | /// Initializes a new instance of the class with a specified error 27 | /// message, an error code and a communication trace. 28 | /// 29 | /// A message that describes the error. 30 | /// The error code reported by the network. 31 | /// The communication that occurred right before the error. 32 | /// This exception gets thrown when an action can not be executed due to a message service error. 33 | public MessageServiceErrorException(string message, int errorCode, string commTrace) : base(message, commTrace) 34 | { 35 | this.errorCode = errorCode; 36 | } 37 | 38 | /// 39 | /// Initializes a new instance of the class with a specified error 40 | /// message, an error code, a communication trace and a reference to the inner exception that is the cause of this exception. 41 | /// 42 | /// A message that describes the error. 43 | /// The error code reported by the network. 44 | /// The communication that occurred right before the error. 45 | /// The exception that is the cause of the current exception. 46 | /// This exception gets thrown when an action can not be executed due to a message service error. 47 | public MessageServiceErrorException(string message, int errorCode, string commTrace, Exception innerException) : base(message, commTrace, innerException) 48 | { 49 | this.errorCode = errorCode; 50 | } 51 | 52 | /// 53 | /// Initializes a new instance of the class with serialized data. 54 | /// 55 | /// The object that holds the serialized object data. 56 | /// The contextual information about the source or destination. 57 | protected MessageServiceErrorException(SerializationInfo info, StreamingContext context) : base(info, context) 58 | { 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /GSMCommShared/MobileEquipmentErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | /// 5 | /// The exception that gets thrown when the device detects an internal error. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | public class MobileEquipmentErrorException : CommException 11 | { 12 | private int errorCode; 13 | 14 | /// 15 | /// Gets the error code reported by the device. 16 | /// 17 | public int ErrorCode 18 | { 19 | get 20 | { 21 | return this.errorCode; 22 | } 23 | } 24 | 25 | /// 26 | /// Initializes a new instance of the class with a specified error 27 | /// message, an error code and a communication trace. 28 | /// 29 | /// A message that describes the error. 30 | /// The error code reported by the device. 31 | /// The communication that occurred right before the error. 32 | /// This exception gets thrown when an action can not be executed due to an internal device error. 33 | public MobileEquipmentErrorException(string message, int errorCode, string commTrace) : base(message, commTrace) 34 | { 35 | this.errorCode = errorCode; 36 | } 37 | 38 | /// 39 | /// Initializes a new instance of the class with a specified error 40 | /// message, an error code, a communication trace and a reference to the inner exception that is the cause of this exception. 41 | /// 42 | /// A message that describes the error. 43 | /// The error code reported by the device. 44 | /// The communication that occurred right before the error. 45 | /// The exception that is the cause of the current exception. 46 | /// This exception gets thrown when an action can not be executed due to an internal device error. 47 | public MobileEquipmentErrorException(string message, int errorCode, string commTrace, Exception innerException) : base(message, commTrace, innerException) 48 | { 49 | this.errorCode = errorCode; 50 | } 51 | 52 | /// 53 | /// Initializes a new instance of the class with serialized data. 54 | /// 55 | /// The object that holds the serialized object data. 56 | /// The contextual information about the source or destination. 57 | protected MobileEquipmentErrorException(SerializationInfo info, StreamingContext context) : base(info, context) 58 | { 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /GSMCommShared/GsmCommunication/MessageServiceErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | /// 5 | /// The exception that gets thrown when there is an error with the message service. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | public class MessageServiceErrorException : CommException 11 | { 12 | private int errorCode; 13 | 14 | /// 15 | /// Gets the error code reported by the network. 16 | /// 17 | public int ErrorCode 18 | { 19 | get 20 | { 21 | return this.errorCode; 22 | } 23 | } 24 | 25 | /// 26 | /// Initializes a new instance of the class with a specified error 27 | /// message, an error code and a communication trace. 28 | /// 29 | /// A message that describes the error. 30 | /// The error code reported by the network. 31 | /// The communication that occurred right before the error. 32 | /// This exception gets thrown when an action can not be executed due to a message service error. 33 | public MessageServiceErrorException(string message, int errorCode, string commTrace) : base(message, commTrace) 34 | { 35 | this.errorCode = errorCode; 36 | } 37 | 38 | /// 39 | /// Initializes a new instance of the class with a specified error 40 | /// message, an error code, a communication trace and a reference to the inner exception that is the cause of this exception. 41 | /// 42 | /// A message that describes the error. 43 | /// The error code reported by the network. 44 | /// The communication that occurred right before the error. 45 | /// The exception that is the cause of the current exception. 46 | /// This exception gets thrown when an action can not be executed due to a message service error. 47 | public MessageServiceErrorException(string message, int errorCode, string commTrace, Exception innerException) : base(message, commTrace, innerException) 48 | { 49 | this.errorCode = errorCode; 50 | } 51 | 52 | /// 53 | /// Initializes a new instance of the class with serialized data. 54 | /// 55 | /// The object that holds the serialized object data. 56 | /// The contextual information about the source or destination. 57 | protected MessageServiceErrorException(SerializationInfo info, StreamingContext context) : base(info, context) 58 | { 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /GSMCommShared/GsmCommunication/MobileEquipmentErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | /// 5 | /// The exception that gets thrown when the device detects an internal error. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | public class MobileEquipmentErrorException : CommException 11 | { 12 | private int errorCode; 13 | 14 | /// 15 | /// Gets the error code reported by the device. 16 | /// 17 | public int ErrorCode 18 | { 19 | get 20 | { 21 | return this.errorCode; 22 | } 23 | } 24 | 25 | /// 26 | /// Initializes a new instance of the class with a specified error 27 | /// message, an error code and a communication trace. 28 | /// 29 | /// A message that describes the error. 30 | /// The error code reported by the device. 31 | /// The communication that occurred right before the error. 32 | /// This exception gets thrown when an action can not be executed due to an internal device error. 33 | public MobileEquipmentErrorException(string message, int errorCode, string commTrace) : base(message, commTrace) 34 | { 35 | this.errorCode = errorCode; 36 | } 37 | 38 | /// 39 | /// Initializes a new instance of the class with a specified error 40 | /// message, an error code, a communication trace and a reference to the inner exception that is the cause of this exception. 41 | /// 42 | /// A message that describes the error. 43 | /// The error code reported by the device. 44 | /// The communication that occurred right before the error. 45 | /// The exception that is the cause of the current exception. 46 | /// This exception gets thrown when an action can not be executed due to an internal device error. 47 | public MobileEquipmentErrorException(string message, int errorCode, string commTrace, Exception innerException) : base(message, commTrace, innerException) 48 | { 49 | this.errorCode = errorCode; 50 | } 51 | 52 | /// 53 | /// Initializes a new instance of the class with serialized data. 54 | /// 55 | /// The object that holds the serialized object data. 56 | /// The contextual information about the source or destination. 57 | protected MobileEquipmentErrorException(SerializationInfo info, StreamingContext context) : base(info, context) 58 | { 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/PhonebookEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Serialization; 3 | 4 | /// 5 | /// Represents a phonebook entry. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | [XmlInclude(typeof(PhonebookEntryWithStorage))] 11 | public class PhonebookEntry 12 | { 13 | private int index; 14 | 15 | private string number; 16 | 17 | private int type; 18 | 19 | private string text; 20 | 21 | /// 22 | /// The index where the entry is saved in the phone. 23 | /// 24 | [XmlAttribute] 25 | public int Index 26 | { 27 | get 28 | { 29 | return this.index; 30 | } 31 | set 32 | { 33 | this.index = value; 34 | } 35 | } 36 | 37 | /// 38 | /// The phone number. 39 | /// 40 | [XmlAttribute] 41 | public string Number 42 | { 43 | get 44 | { 45 | return this.number; 46 | } 47 | set 48 | { 49 | this.number = value; 50 | } 51 | } 52 | 53 | /// 54 | /// The text (name) associated with the . 55 | /// 56 | [XmlAttribute] 57 | public string Text 58 | { 59 | get 60 | { 61 | return this.text; 62 | } 63 | set 64 | { 65 | this.text = value; 66 | } 67 | } 68 | 69 | /// 70 | /// The 's address type. 71 | /// 72 | [XmlAttribute] 73 | public int Type 74 | { 75 | get 76 | { 77 | return this.type; 78 | } 79 | set 80 | { 81 | this.type = value; 82 | } 83 | } 84 | 85 | /// 86 | /// Initializes a new instance of the class. 87 | /// 88 | public PhonebookEntry() 89 | { 90 | } 91 | 92 | /// 93 | /// Initializes a new instance of the class using the specified values. 94 | /// 95 | /// The index where the entry is saved in the phone. 96 | /// The phone number. 97 | /// The 's address type. 98 | /// The text (name) associated with the . 99 | public PhonebookEntry(int index, string number, int type, string text) 100 | { 101 | this.index = index; 102 | this.number = number; 103 | this.type = type; 104 | this.text = text; 105 | } 106 | 107 | /// 108 | /// Initializes a new instance of the class to copy an existing . 109 | /// 110 | /// The entry to copy. 111 | public PhonebookEntry(PhonebookEntry entry) 112 | { 113 | this.index = entry.Index; 114 | this.number = entry.Number; 115 | this.type = entry.type; 116 | this.text = entry.Text; 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /GSMCommShared/CommException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | /// 5 | /// General exception that gets thrown upon a communication error with the device. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | public class CommException : ApplicationException 11 | { 12 | private string commTrace; 13 | 14 | /// 15 | /// Gets the communication trace associated with the exception. 16 | /// 17 | public string CommTrace 18 | { 19 | get 20 | { 21 | return this.commTrace; 22 | } 23 | } 24 | 25 | /// 26 | /// Initializes a new instance of the class. 27 | /// 28 | /// A message that describes the error. 29 | public CommException(string message) : base(message) 30 | { 31 | } 32 | 33 | /// 34 | /// Initializes a new instance of the class with a specified error 35 | /// message and a communication trace. 36 | /// 37 | /// A message that describes the error. 38 | /// The communication that occurred right before the error. 39 | public CommException(string message, string commTrace) : base(message) 40 | { 41 | this.commTrace = commTrace; 42 | } 43 | 44 | /// 45 | /// Initializes a new instance of the class with a specified error 46 | /// message and a reference to the inner exception that is the cause of this exception. 47 | /// 48 | /// A message that describes the error. 49 | /// The exception that is the cause of the current exception. 50 | public CommException(string message, Exception innerException) : base(message, innerException) 51 | { 52 | } 53 | 54 | /// 55 | /// Initializes a new instance of the class with a specified error 56 | /// message, a communication trace and a reference to the inner exception that is the cause of this exception. 57 | /// 58 | /// A message that describes the error. 59 | /// The communication that occurred right before the error. 60 | /// The exception that is the cause of the current exception. 61 | public CommException(string message, string commTrace, Exception innerException) : base(message, innerException) 62 | { 63 | this.commTrace = commTrace; 64 | } 65 | 66 | /// 67 | /// Initializes a new instance of the class with serialized data. 68 | /// 69 | /// The object that holds the serialized object data. 70 | /// The contextual information about the source or destination. 71 | protected CommException(SerializationInfo info, StreamingContext context) : base(info, context) 72 | { 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /GSMCommShared/GsmCommunication/CommException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | /// 5 | /// General exception that gets thrown upon a communication error with the device. 6 | /// 7 | namespace GsmComm.GsmCommunication 8 | { 9 | [Serializable] 10 | public class CommException : ApplicationException 11 | { 12 | private string commTrace; 13 | 14 | /// 15 | /// Gets the communication trace associated with the exception. 16 | /// 17 | public string CommTrace 18 | { 19 | get 20 | { 21 | return this.commTrace; 22 | } 23 | } 24 | 25 | /// 26 | /// Initializes a new instance of the class. 27 | /// 28 | /// A message that describes the error. 29 | public CommException(string message) : base(message) 30 | { 31 | } 32 | 33 | /// 34 | /// Initializes a new instance of the class with a specified error 35 | /// message and a communication trace. 36 | /// 37 | /// A message that describes the error. 38 | /// The communication that occurred right before the error. 39 | public CommException(string message, string commTrace) : base(message) 40 | { 41 | this.commTrace = commTrace; 42 | } 43 | 44 | /// 45 | /// Initializes a new instance of the class with a specified error 46 | /// message and a reference to the inner exception that is the cause of this exception. 47 | /// 48 | /// A message that describes the error. 49 | /// The exception that is the cause of the current exception. 50 | public CommException(string message, Exception innerException) : base(message, innerException) 51 | { 52 | } 53 | 54 | /// 55 | /// Initializes a new instance of the class with a specified error 56 | /// message, a communication trace and a reference to the inner exception that is the cause of this exception. 57 | /// 58 | /// A message that describes the error. 59 | /// The communication that occurred right before the error. 60 | /// The exception that is the cause of the current exception. 61 | public CommException(string message, string commTrace, Exception innerException) : base(message, innerException) 62 | { 63 | this.commTrace = commTrace; 64 | } 65 | 66 | /// 67 | /// Initializes a new instance of the class with serialized data. 68 | /// 69 | /// The object that holds the serialized object data. 70 | /// The contextual information about the source or destination. 71 | protected CommException(SerializationInfo info, StreamingContext context) : base(info, context) 72 | { 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmartMessaging/PortAddressElement16.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Implements an Application Port Addressing Information Element (16 bit address). 5 | /// 6 | /// This element is used to indiate from which port a message 7 | /// originated and to which port it should be directed to. 8 | namespace GsmComm.PduConverter.SmartMessaging 9 | { 10 | public class PortAddressElement16 : InformationElement 11 | { 12 | /// 13 | /// The Information Element Identifier (IEI). 14 | /// 15 | public const byte Identifier = 5; 16 | 17 | private ushort destinationPort; 18 | 19 | private ushort originatorPort; 20 | 21 | /// 22 | /// Gets the destination port. 23 | /// 24 | public ushort DestinationPort 25 | { 26 | get 27 | { 28 | return this.destinationPort; 29 | } 30 | } 31 | 32 | /// 33 | /// Gets the originator port. 34 | /// 35 | public ushort OriginatorPort 36 | { 37 | get 38 | { 39 | return this.originatorPort; 40 | } 41 | } 42 | 43 | /// 44 | /// Initializes a new instance of the class. 45 | /// 46 | /// The destination port, e.g. 0x1582. 47 | /// The source port, e.g. 0x00. 48 | public PortAddressElement16(ushort destinationPort, ushort originatorPort) 49 | { 50 | this.destinationPort = destinationPort; 51 | this.originatorPort = originatorPort; 52 | } 53 | 54 | /// 55 | /// Initializes a new instance of the class. 56 | /// 57 | /// The information element as a byte array. 58 | public PortAddressElement16(byte[] element) 59 | { 60 | if (element != null) 61 | { 62 | if (element[0] == 5) 63 | { 64 | byte num = element[1]; 65 | if (num >= 4) 66 | { 67 | byte[] numArray = new byte[2]; 68 | numArray[0] = element[3]; 69 | numArray[1] = element[2]; 70 | this.destinationPort = BitConverter.ToUInt16(numArray, 0); 71 | byte[] numArray1 = new byte[2]; 72 | numArray1[0] = element[5]; 73 | numArray1[1] = element[4]; 74 | this.originatorPort = BitConverter.ToUInt16(numArray1, 0); 75 | return; 76 | } 77 | else 78 | { 79 | throw new FormatException("Information element data must be 4 bytes long."); 80 | } 81 | } 82 | else 83 | { 84 | throw new ArgumentException("Element is not an Application Port Addressing Information Element (16 bit address).", "element"); 85 | } 86 | } 87 | else 88 | { 89 | throw new ArgumentNullException("element"); 90 | } 91 | } 92 | 93 | /// 94 | /// Returns the byte array equivalent of this instance. 95 | /// 96 | /// The byte array. 97 | public override byte[] ToByteArray() 98 | { 99 | byte[] bytes = BitConverter.GetBytes(this.destinationPort); 100 | byte[] numArray = BitConverter.GetBytes(this.originatorPort); 101 | byte[] numArray1 = new byte[6]; 102 | numArray1[0] = 5; 103 | numArray1[1] = 4; 104 | numArray1[2] = bytes[1]; 105 | numArray1[3] = bytes[0]; 106 | numArray1[4] = numArray[1]; 107 | numArray1[5] = numArray[0]; 108 | return numArray1; 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmartMessaging/UnknownInformationElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Implements an unknown information element. 5 | /// 6 | namespace GsmComm.PduConverter.SmartMessaging 7 | { 8 | public class UnknownInformationElement : InformationElement 9 | { 10 | private byte identifier; 11 | 12 | private byte[] data; 13 | 14 | /// 15 | /// Gets the information element data. 16 | /// 17 | public byte[] Data 18 | { 19 | get 20 | { 21 | return this.data; 22 | } 23 | } 24 | 25 | /// 26 | /// Gets the information element identifier. 27 | /// 28 | public byte Identifier 29 | { 30 | get 31 | { 32 | return this.identifier; 33 | } 34 | } 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// The information element identifier. 40 | /// The information element data. 41 | /// data is null. 42 | /// data is larger than 255 bytes. 43 | public UnknownInformationElement(byte identifier, byte[] data) 44 | { 45 | if (data != null) 46 | { 47 | if ((int)data.Length <= 255) 48 | { 49 | this.identifier = identifier; 50 | this.data = data; 51 | return; 52 | } 53 | else 54 | { 55 | throw new ArgumentException("Data must be between 0 and 255 bytes long.", "data"); 56 | } 57 | } 58 | else 59 | { 60 | throw new ArgumentNullException("data"); 61 | } 62 | } 63 | 64 | /// 65 | /// Initializes a new instance of the class. 66 | /// 67 | /// The information element as a byte array. 68 | /// element is null. 69 | /// Information element is shorter than 2 bytes. 70 | /// Available number of data bytes is less than specified in data length. 71 | public UnknownInformationElement(byte[] element) 72 | { 73 | if (element != null) 74 | { 75 | if ((int)element.Length >= 2) 76 | { 77 | this.identifier = element[0]; 78 | byte num = element[1]; 79 | if ((int)element.Length >= num + 2) 80 | { 81 | this.data = new byte[num]; 82 | Array.Copy(element, 2, this.data, 0, num); 83 | return; 84 | } 85 | else 86 | { 87 | throw new FormatException("Available number of data bytes is less then specified in data length."); 88 | } 89 | } 90 | else 91 | { 92 | throw new ArgumentException("Information element must at least be 2 bytes long.", "element"); 93 | } 94 | } 95 | else 96 | { 97 | throw new ArgumentNullException("element"); 98 | } 99 | } 100 | 101 | /// 102 | /// Returns the byte array equivalent of this instance. 103 | /// 104 | /// The byte array. 105 | public override byte[] ToByteArray() 106 | { 107 | byte[] length = new byte[2 + (int)this.data.Length]; 108 | length[0] = this.identifier; 109 | length[1] = (byte)((int)this.data.Length); 110 | this.data.CopyTo(length, 2); 111 | return length; 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmsStatusReportMessageFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Represents the the first octet of an SMS-STATUS-REPORT PDU. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class SmsStatusReportMessageFlags : IncomingMessageFlags 9 | { 10 | private const byte TP_MTI_SMS_Status_Report = 2; 11 | 12 | private const byte TP_UDHI = 4; 13 | 14 | private const byte TP_MMS = 8; 15 | 16 | private const byte TP_SRQ = 16; 17 | 18 | private bool userDataHeaderPresent; 19 | 20 | private bool moreMessages; 21 | 22 | private bool qualifier; 23 | 24 | /// 25 | /// Parameter describing the message type. 26 | /// 27 | public override IncomingMessageType MessageType 28 | { 29 | get 30 | { 31 | return IncomingMessageType.SmsStatusReport; 32 | } 33 | } 34 | 35 | /// 36 | /// Parameter indicating whether or not there are more messages to send. 37 | /// 38 | public bool MoreMessages 39 | { 40 | get 41 | { 42 | return this.moreMessages; 43 | } 44 | set 45 | { 46 | this.moreMessages = value; 47 | } 48 | } 49 | 50 | /// 51 | /// Parameter indicating whether the previously submitted TPDU was an 52 | /// SMS-SUBMIT or an SMS-COMMAND. 53 | /// 54 | /// 55 | /// false = SMS-STATUS-REPORT is the result of a SMS-SUBMIT 56 | /// true = SMS-STATUS-REPORT is the result of a SMS-COMMAND 57 | /// 58 | public bool Qualifier 59 | { 60 | get 61 | { 62 | return this.qualifier; 63 | } 64 | set 65 | { 66 | this.qualifier = value; 67 | } 68 | } 69 | 70 | /// 71 | /// Parameter indicating that the TP-UD field contains a Header. 72 | /// 73 | public bool UserDataHeaderPresent 74 | { 75 | get 76 | { 77 | return this.userDataHeaderPresent; 78 | } 79 | set 80 | { 81 | this.userDataHeaderPresent = value; 82 | } 83 | } 84 | 85 | /// 86 | /// Initializes a new instance of the class. 87 | /// 88 | public SmsStatusReportMessageFlags() 89 | { 90 | this.userDataHeaderPresent = false; 91 | this.moreMessages = false; 92 | this.qualifier = false; 93 | } 94 | 95 | /// 96 | /// Initializes a new instance of the IncomingMessageFlags class with a 97 | /// predefined data byte. 98 | /// 99 | public SmsStatusReportMessageFlags(byte flags) 100 | { 101 | this.FromByte(flags); 102 | } 103 | 104 | /// 105 | /// Fills the object with values from the data byte. 106 | /// 107 | /// The byte value. 108 | protected override void FromByte(byte b) 109 | { 110 | IncomingMessageType incomingMessageType = IncomingMessageType.SmsStatusReport; 111 | if ((b & 2) > 0) 112 | { 113 | incomingMessageType = IncomingMessageType.SmsStatusReport; 114 | } 115 | if (incomingMessageType == IncomingMessageType.SmsStatusReport) 116 | { 117 | this.userDataHeaderPresent = (b & 4) > 0; 118 | this.moreMessages = (b & 8) == 0; 119 | this.qualifier = (b & 16) > 0; 120 | return; 121 | } 122 | else 123 | { 124 | throw new ArgumentException("Not an SMS-STATUS-REPORT message."); 125 | } 126 | } 127 | 128 | /// 129 | /// Returns the byte equivalent of this instance. 130 | /// 131 | /// The byte value. 132 | public override byte ToByte() 133 | { 134 | byte num = 0; 135 | num = (byte)(num | 2); 136 | if (this.userDataHeaderPresent) 137 | { 138 | num = (byte)(num | 4); 139 | } 140 | if (!this.moreMessages) 141 | { 142 | num = (byte)(num | 8); 143 | } 144 | if (this.qualifier) 145 | { 146 | num = (byte)(num | 16); 147 | } 148 | return num; 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /GSMCommServer/GSMCommServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {67CB92ED-436B-4005-A6D6-092503D6E496} 5 | 2 6 | Debug 7 | AnyCPU 8 | GSMCommServer 9 | Library 10 | GsmComm 11 | v4.0 12 | 13 | 14 | bin\Debug\ 15 | true 16 | DEBUG;TRACE 17 | false 18 | 4 19 | full 20 | prompt 21 | AnyCPU 22 | true 23 | 24 | 25 | bin\Release\ 26 | false 27 | TRACE 28 | true 29 | 4 30 | pdbonly 31 | prompt 32 | AnyCPU 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | false 41 | false 42 | 43 | 44 | false 45 | false 46 | 47 | 48 | false 49 | false 50 | 51 | 52 | false 53 | false 54 | 55 | 56 | false 57 | false 58 | 59 | 60 | false 61 | false 62 | 63 | 64 | false 65 | false 66 | 67 | 68 | false 69 | false 70 | 71 | 72 | 73 | 74 | {71ea4054-a98a-46ba-84fa-81652db72b72} 75 | GSMCommShared 76 | 77 | 78 | {32b76f1e-b022-47c6-86ec-28639d348067} 79 | GSMCommunication 80 | 81 | 82 | {5e657efe-0a30-466d-b025-ff177e23a727} 83 | PDUConverter 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/SubscriberInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains network subscriber info retrieved from the phone. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class SubscriberInfo 9 | { 10 | private string alpha; 11 | 12 | private string number; 13 | 14 | private int type; 15 | 16 | private int speed; 17 | 18 | private int service; 19 | 20 | private int itc; 21 | 22 | /// 23 | /// Gets an optional alphanumeric string associated with ; 24 | /// used character set is the one selected with . 25 | /// 26 | /// If the string is not defined, it is empty. 27 | public string Alpha 28 | { 29 | get 30 | { 31 | return this.alpha; 32 | } 33 | } 34 | 35 | /// 36 | /// Gets a value for the information transfer capability. 37 | /// 38 | /// Valid values are zero or greater, -1 means this info is not available. 39 | public int Itc 40 | { 41 | get 42 | { 43 | return this.itc; 44 | } 45 | } 46 | 47 | /// 48 | /// Gets the phone number of format specified by . 49 | /// 50 | public string Number 51 | { 52 | get 53 | { 54 | return this.number; 55 | } 56 | } 57 | 58 | /// 59 | /// Gets the service related to the phone number. 60 | /// 61 | /// Valid values are zero or greater, -1 means this info is not available. 62 | /// Some defined values can be found in the enumeration. 63 | /// 64 | public int Service 65 | { 66 | get 67 | { 68 | return this.service; 69 | } 70 | } 71 | 72 | /// 73 | /// Gets a value for the speed for data calls. 74 | /// 75 | /// Valid values are zero or greater, -1 means this info is not available. 76 | public int Speed 77 | { 78 | get 79 | { 80 | return this.speed; 81 | } 82 | } 83 | 84 | /// 85 | /// Gets the type of Address in integer format. 86 | /// 87 | public int Type 88 | { 89 | get 90 | { 91 | return this.type; 92 | } 93 | } 94 | 95 | /// 96 | /// Initializes a new instance of the class. 97 | /// 98 | /// Phone number of format specified by type. 99 | /// Type of address in integer format. 100 | public SubscriberInfo(string number, int type) 101 | { 102 | this.alpha = string.Empty; 103 | this.number = number; 104 | this.type = type; 105 | this.speed = -1; 106 | this.service = -1; 107 | this.itc = -1; 108 | } 109 | 110 | /// 111 | /// Initializes a new instance of the class. 112 | /// 113 | /// An optional alphanumeric string associated with number 114 | /// Phone number of format specified by type 115 | /// Type of address in integer format 116 | /// A value for the speed of data calls 117 | /// The service related to the phone number 118 | /// A value for the information transfer capability 119 | /// 120 | /// Valid values for speed, service and itc are zero or greater, 121 | /// set values to -1 where the information is not available. 122 | /// 123 | public SubscriberInfo(string alpha, string number, int type, int speed, int service, int itc) 124 | { 125 | this.alpha = alpha; 126 | this.number = number; 127 | this.type = type; 128 | this.speed = speed; 129 | this.service = service; 130 | this.itc = itc; 131 | } 132 | } 133 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/OperatorInfo2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Contains information about a GSM network operator. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public class OperatorInfo2 9 | { 10 | private OperatorStatus stat; 11 | 12 | private string longAlpha; 13 | 14 | private string shortAlpha; 15 | 16 | private string numeric; 17 | 18 | private string act; 19 | 20 | /// 21 | /// Gets the access technology the operator uses. 22 | /// 23 | /// This is optional, as it is only useful for terminals capable to register to more than 24 | /// one access technology. 25 | public string AccessTechnology 26 | { 27 | get 28 | { 29 | return this.act; 30 | } 31 | } 32 | 33 | /// 34 | /// Gets the operator name in long alphanumeric format. 35 | /// 36 | /// If the phone does not support this format, the string will be empty. 37 | public string LongAlphanumeric 38 | { 39 | get 40 | { 41 | return this.longAlpha; 42 | } 43 | } 44 | 45 | /// 46 | /// Gets the operator in numeric format. 47 | /// 48 | /// If the phone does not support this format, the string will be empty. 49 | public string Numeric 50 | { 51 | get 52 | { 53 | return this.numeric; 54 | } 55 | } 56 | 57 | /// 58 | /// Gets the operator name in short alphanumic format. 59 | /// 60 | /// If the phone does not support this format, the string will be empty. 61 | public string ShortAlphanumeric 62 | { 63 | get 64 | { 65 | return this.shortAlpha; 66 | } 67 | } 68 | 69 | /// 70 | /// Gets the availability of the operator. 71 | /// 72 | public OperatorStatus Status 73 | { 74 | get 75 | { 76 | return this.stat; 77 | } 78 | } 79 | 80 | /// 81 | /// Initializes a new instance of the class. 82 | /// 83 | /// The operator availability 84 | /// The operator name in long alphanumeric format 85 | /// The operator name in short alphanumeric format 86 | /// The operator in numeric format 87 | /// If the phone does not support one of the formats longAlphanumeric, 88 | /// shortAlphanumeric, numeric, the curresponding string is left empty. 89 | public OperatorInfo2(OperatorStatus status, string longAlphanumeric, string shortAlphanumeric, string numeric) 90 | { 91 | this.stat = status; 92 | this.longAlpha = longAlphanumeric; 93 | this.shortAlpha = shortAlphanumeric; 94 | this.numeric = numeric; 95 | this.act = string.Empty; 96 | } 97 | 98 | /// 99 | /// Initializes a new instance of the class. 100 | /// 101 | /// The operator availability 102 | /// The operator name in long alphanumeric format 103 | /// The operator name in short alphanumeric format 104 | /// The operator in numeric format 105 | /// The access technology the operator uses. 106 | /// 107 | /// If the phone does not support one of the formats longAlphanumeric, 108 | /// shortAlphanumeric, numeric, the curresponding string is left empty. 109 | /// The accessTechnology is optional, as it is only useful for terminals capable 110 | /// to register to more than one access technology. 111 | /// 112 | public OperatorInfo2(OperatorStatus status, string longAlphanumeric, string shortAlphanumeric, string numeric, string accessTechnology) 113 | { 114 | this.stat = status; 115 | this.longAlpha = longAlphanumeric; 116 | this.shortAlpha = shortAlphanumeric; 117 | this.numeric = numeric; 118 | this.act = accessTechnology; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/AddressType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Indicates the format of a phone number. 5 | /// 6 | /// 7 | /// The most common value of this octet is 91 hex (10010001 bin), which indicates international format. 8 | /// A phone number in international format looks like 46708251358 (where the country code is 46). 9 | /// In the national (or unknown) format the same phone number would look like 0708251358. The international 10 | /// format is the most generic, and it has to be accepted also when the message is destined to a recipient 11 | /// in the same country as the MSC or as the SGSN. 12 | /// 13 | namespace GsmComm.PduConverter 14 | { 15 | public class AddressType 16 | { 17 | /// 18 | /// Unknown type of number and numbering plan. 19 | /// 20 | public const byte Unknown = 0; 21 | 22 | /// 23 | /// Unknown type of number, telephone numbering plan. 24 | /// 25 | public const byte UnknownPhone = 129; 26 | 27 | /// 28 | /// International number, telephone numbering plan. 29 | /// 30 | public const byte InternationalPhone = 145; 31 | 32 | private bool bit7; 33 | 34 | private byte ton; 35 | 36 | private byte npi; 37 | 38 | /// 39 | /// The Numbering Plan Identification. 40 | /// 41 | /// 42 | /// The Numbering-plan-identification applies for Type-of-number = 000, 001 and 010. 43 | /// For Type-of-number = 101 bits 3,2,1,0 are reserved and shall be transmitted as 0000. 44 | /// Note that for addressing any of the entities SC, MSC, SGSN or MS, Numbering-plan-identification = 0001 45 | /// will always be used. However, for addressing the SME, any specified Numbering-plan-identification 46 | /// value may be used. 47 | /// 48 | public byte Npi 49 | { 50 | get 51 | { 52 | return this.npi; 53 | } 54 | set 55 | { 56 | this.npi = value; 57 | } 58 | } 59 | 60 | /// 61 | /// The Type of number. 62 | /// 63 | public byte Ton 64 | { 65 | get 66 | { 67 | return this.ton; 68 | } 69 | set 70 | { 71 | this.ton = value; 72 | } 73 | } 74 | 75 | /// 76 | /// Initializes a new instance of the class. 77 | /// 78 | public AddressType() 79 | { 80 | this.bit7 = true; 81 | this.ton = 0; 82 | this.npi = 0; 83 | } 84 | 85 | /// 86 | /// Initializes a new instance of the class using the given value. 87 | /// 88 | /// The Type-of-Address octet to initialize the object with. 89 | public AddressType(byte toa) 90 | { 91 | this.bit7 = (toa & 128) > 0; 92 | this.ton = (byte)(toa >> 4 & 7); 93 | this.npi = (byte)(toa & 15); 94 | } 95 | 96 | public static implicit operator AddressType(byte toa) 97 | { 98 | return new AddressType(toa); 99 | } 100 | 101 | public static implicit operator Byte(AddressType a) 102 | { 103 | return a.ToByte(); 104 | } 105 | 106 | /// 107 | /// Returns the byte equivalent of this instance. 108 | /// 109 | /// The byte value. 110 | public byte ToByte() 111 | { 112 | int num; 113 | if (this.bit7) 114 | { 115 | num = 128; 116 | } 117 | else 118 | { 119 | num = 0; 120 | } 121 | byte num1 = (byte)(num | this.ton << 4 | this.npi); 122 | return num1; 123 | } 124 | 125 | /// 126 | /// Indicates the Numbering Plan Identification (NPI) of the phone number. 127 | /// 128 | public enum NumberingPlan : byte 129 | { 130 | Unknown, 131 | Telephone, 132 | Data, 133 | Telex, 134 | National, 135 | Private, 136 | Ermes, 137 | Reserved 138 | } 139 | 140 | /// 141 | /// Indicates the type of the phone number (TON). 142 | /// 143 | public enum TypeOfNumber : byte 144 | { 145 | Unknown, 146 | International, 147 | National, 148 | NetworkSpecific, 149 | Subscriber, 150 | Alphanumeric, 151 | Abbreviated, 152 | Reserved 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/IncomingSmsPdu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Represents an incoming SMS PDU. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public abstract class IncomingSmsPdu : SmsPdu 9 | { 10 | private const byte TP_MTI_SMS_Deliver = 0; 11 | 12 | private const byte TP_MTI_SMS_Submit_Report = 1; 13 | 14 | private const byte TP_MTI_SMS_Status_Report = 2; 15 | 16 | /// 17 | /// The flags for this message. 18 | /// 19 | protected IncomingMessageFlags messageFlags; 20 | 21 | /// 22 | /// Gets the message type. 23 | /// 24 | public IncomingMessageType MessageType 25 | { 26 | get 27 | { 28 | return this.messageFlags.MessageType; 29 | } 30 | } 31 | 32 | protected IncomingSmsPdu() 33 | { 34 | } 35 | 36 | /// 37 | /// Decodes an incoming SMS PDU stream. 38 | /// 39 | /// The PDU string to decode. 40 | /// Specify true if the PDU data contains an SMSC header, otherwise false. 41 | /// The size of the PDU data in bytes, not counting the SMSC header. Set to -1 if unknown. 42 | /// An object representing the decoded message. 43 | public static IncomingSmsPdu Decode(string pdu, bool includesSmscData, int actualLength) 44 | { 45 | if (pdu != string.Empty) 46 | { 47 | int num = 0; 48 | if (includesSmscData) 49 | { 50 | int num1 = num; 51 | num = num1 + 1; 52 | byte num2 = BcdWorker.GetByte(pdu, num1); 53 | if (num2 > 0) 54 | { 55 | num = num + num2; 56 | } 57 | } 58 | int num3 = num; 59 | IncomingMessageType messageType = IncomingSmsPdu.GetMessageType(BcdWorker.GetByte(pdu, num3)); 60 | IncomingMessageType incomingMessageType = messageType; 61 | switch (incomingMessageType) 62 | { 63 | case IncomingMessageType.SmsDeliver: 64 | { 65 | return new SmsDeliverPdu(pdu, includesSmscData, actualLength); 66 | } 67 | case IncomingMessageType.SmsStatusReport: 68 | { 69 | return new SmsStatusReportPdu(pdu, includesSmscData, actualLength); 70 | } 71 | } 72 | throw new NotSupportedException(string.Concat("Message type ", messageType.ToString(), " recognized, but not supported by the SMS decoder.")); 73 | } 74 | else 75 | { 76 | throw new ArgumentException("pdu must not be an empty string."); 77 | } 78 | } 79 | 80 | /// 81 | /// Decodes an incoming SMS PDU stream. 82 | /// 83 | /// The PDU string to decode. 84 | /// Specify true if the PDU data contains an SMSC header, otherwise false. 85 | /// An object representing the decoded message. 86 | /// Use this overload only if you do not know the size of the PDU data. 87 | public static IncomingSmsPdu Decode(string pdu, bool includesSmscData) 88 | { 89 | return IncomingSmsPdu.Decode(pdu, includesSmscData, -1); 90 | } 91 | 92 | private static IncomingMessageType GetMessageType(byte flags) 93 | { 94 | IncomingMessageType incomingMessageType; 95 | int num; 96 | if ((flags & 2) > 0) 97 | { 98 | num = 1; 99 | } 100 | else 101 | { 102 | num = 0; 103 | } 104 | byte num1 = (byte)(num * 2 + (flags & 1)); 105 | byte num2 = num1; 106 | if (num2 == 0) 107 | { 108 | incomingMessageType = IncomingMessageType.SmsDeliver; 109 | } 110 | else if (num2 == 1) 111 | { 112 | incomingMessageType = IncomingMessageType.SmsSubmitReport; 113 | } 114 | else if (num2 == 2) 115 | { 116 | incomingMessageType = IncomingMessageType.SmsStatusReport; 117 | } 118 | else 119 | { 120 | string[] str = new string[5]; 121 | str[0] = "Unknown message type "; 122 | str[1] = num1.ToString(); 123 | str[2] = " (flags="; 124 | str[3] = flags.ToString(); 125 | str[4] = ")"; 126 | throw new ArgumentException(string.Concat(str), "flags"); 127 | } 128 | return incomingMessageType; 129 | } 130 | } 131 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/MessageStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// TP-ST / TP-Status. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public struct MessageStatus 9 | { 10 | private byte status; 11 | 12 | /// 13 | /// Gets the status category. 14 | /// 15 | /// 16 | /// If the valus does not fall into one of the predefined categories, 17 | /// is returned. 18 | /// 19 | public StatusCategory Category 20 | { 21 | get 22 | { 23 | if (this.status < 0 || this.status > 31) 24 | { 25 | if (this.status < 32 || this.status > 47) 26 | { 27 | if (this.status < 64 || this.status > 95) 28 | { 29 | if (this.status < 96 || this.status > 127) 30 | { 31 | return StatusCategory.Reserved; 32 | } 33 | else 34 | { 35 | return StatusCategory.TemporaryErrorNoRetry; 36 | } 37 | } 38 | else 39 | { 40 | return StatusCategory.PermanentError; 41 | } 42 | } 43 | else 44 | { 45 | return StatusCategory.TemporaryErrorWithRetry; 46 | } 47 | } 48 | else 49 | { 50 | return StatusCategory.Success; 51 | } 52 | } 53 | } 54 | 55 | /// 56 | /// Initializes a new instance of the . 57 | /// 58 | /// The status code. 59 | public MessageStatus(byte status) 60 | { 61 | this.status = status; 62 | } 63 | 64 | /// 65 | /// Initializes a new instance of the . 66 | /// 67 | /// One of the values. 68 | public MessageStatus(KnownMessageStatus status) 69 | { 70 | this.status = (byte)status; 71 | } 72 | 73 | /// 74 | /// Retrieves the known status of the current message status. 75 | /// 76 | /// Ae representing the message status. 77 | /// Check first with before calling this method. 78 | /// Message status is not a known message status. 79 | public KnownMessageStatus GetKnownStatus() 80 | { 81 | if (!this.IsKnownStatus()) 82 | { 83 | throw new ArgumentException(string.Concat(this.status.ToString(), " is not a known message status.")); 84 | } 85 | else 86 | { 87 | return (KnownMessageStatus)Enum.Parse(typeof(KnownMessageStatus), this.status.ToString()); 88 | } 89 | } 90 | 91 | /// 92 | /// Checks if the message status exists within the known status list. 93 | /// 94 | /// true if the status is a known status, otherwise false. 95 | public bool IsKnownStatus() 96 | { 97 | return Enum.IsDefined(typeof(KnownMessageStatus), this.status); 98 | } 99 | 100 | public static implicit operator Byte(MessageStatus s) 101 | { 102 | return s.ToByte(); 103 | } 104 | 105 | public static implicit operator MessageStatus(byte b) 106 | { 107 | return new MessageStatus(b); 108 | } 109 | 110 | public static implicit operator MessageStatus(KnownMessageStatus s) 111 | { 112 | return new MessageStatus(s); 113 | } 114 | 115 | /// 116 | /// Returns the byte representation of the status. 117 | /// 118 | /// A value representing the object's value. 119 | public byte ToByte() 120 | { 121 | return this.status; 122 | } 123 | 124 | /// 125 | /// Returns the string representation of the status. 126 | /// 127 | /// The string representation of the known status if it is a known status, 128 | /// the numerical status value otherwise. 129 | public override string ToString() 130 | { 131 | if (!this.IsKnownStatus()) 132 | { 133 | return this.status.ToString(); 134 | } 135 | else 136 | { 137 | return this.GetKnownStatus().ToString(); 138 | } 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmartMessaging/ConcatMessageElement8.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Implements a Concatenated Short Message Information Element (8-bit reference number) 5 | /// 6 | /// This element is used to indiate that a message is split into 7 | /// multiple parts. 8 | namespace GsmComm.PduConverter.SmartMessaging 9 | { 10 | public class ConcatMessageElement8 : InformationElement, IConcatenationInfo 11 | { 12 | /// 13 | /// The Information Element Identifier (IEI). 14 | /// 15 | public const byte Identifier = 0; 16 | 17 | private byte referenceNumber; 18 | 19 | private byte totalMessages; 20 | 21 | private byte currentNumber; 22 | 23 | /// 24 | /// Gets the current message number. 25 | /// 26 | public byte CurrentNumber 27 | { 28 | get 29 | { 30 | return this.currentNumber; 31 | } 32 | } 33 | 34 | /// 35 | /// Gets the current message number. 36 | /// 37 | byte GsmComm.PduConverter.SmartMessaging.IConcatenationInfo.CurrentNumber 38 | { 39 | get 40 | { 41 | return this.currentNumber; 42 | } 43 | } 44 | 45 | /// 46 | /// Gets the message reference number. 47 | /// 48 | ushort GsmComm.PduConverter.SmartMessaging.IConcatenationInfo.ReferenceNumber 49 | { 50 | get 51 | { 52 | return this.referenceNumber; 53 | } 54 | } 55 | 56 | /// 57 | /// Gets the total number of parts of the message. 58 | /// 59 | byte GsmComm.PduConverter.SmartMessaging.IConcatenationInfo.TotalMessages 60 | { 61 | get 62 | { 63 | return this.totalMessages; 64 | } 65 | } 66 | 67 | /// 68 | /// Gets the message reference number. 69 | /// 70 | public byte ReferenceNumber 71 | { 72 | get 73 | { 74 | return this.referenceNumber; 75 | } 76 | } 77 | 78 | /// 79 | /// Gets the total number of parts of the message. 80 | /// 81 | public byte TotalMessages 82 | { 83 | get 84 | { 85 | return this.totalMessages; 86 | } 87 | } 88 | 89 | /// 90 | /// Initializes a new instance of the class. 91 | /// 92 | /// The message's reference number, must 93 | /// be the same in all parts of the same message. 94 | /// The total number of parts of the message. 95 | /// The current message number. 96 | public ConcatMessageElement8(byte referenceNumber, byte totalMessages, byte currentNumber) 97 | { 98 | this.referenceNumber = referenceNumber; 99 | this.totalMessages = totalMessages; 100 | this.currentNumber = currentNumber; 101 | } 102 | 103 | /// 104 | /// Initializes a new instance of the class. 105 | /// 106 | /// The information element as a byte array. 107 | public ConcatMessageElement8(byte[] element) 108 | { 109 | if (element != null) 110 | { 111 | if (element[0] == 0) 112 | { 113 | byte num = element[1]; 114 | if (num >= 3) 115 | { 116 | this.referenceNumber = element[2]; 117 | this.totalMessages = element[3]; 118 | this.currentNumber = element[4]; 119 | return; 120 | } 121 | else 122 | { 123 | throw new FormatException("Information element data must be 3 bytes long."); 124 | } 125 | } 126 | else 127 | { 128 | throw new ArgumentException("Element is not a Concatenated Short Message Information Element (8-bit reference number).", "element"); 129 | } 130 | } 131 | else 132 | { 133 | throw new ArgumentNullException("element"); 134 | } 135 | } 136 | 137 | /// 138 | /// Returns the byte array equivalent of this instance. 139 | /// 140 | /// The byte array. 141 | public override byte[] ToByteArray() 142 | { 143 | byte[] numArray = new byte[5]; 144 | numArray[1] = 3; 145 | numArray[2] = this.referenceNumber; 146 | numArray[3] = this.totalMessages; 147 | numArray[4] = this.currentNumber; 148 | return numArray; 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmsDeliverMessageFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Represents the the first octet of an SMS-DELIVER PDU. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class SmsDeliverMessageFlags : IncomingMessageFlags 9 | { 10 | private const byte TP_MTI_SMS_Deliver = 0; 11 | 12 | private const byte TP_MMS = 4; 13 | 14 | private const byte TP_SRI = 32; 15 | 16 | private const byte TP_UDHI = 64; 17 | 18 | private const byte TP_RP = 128; 19 | 20 | private bool moreMessages; 21 | 22 | private bool statusReportRequested; 23 | 24 | private bool userDataHeaderPresent; 25 | 26 | private bool replyPathExists; 27 | 28 | /// 29 | /// Gets the type of the message. 30 | /// 31 | /// Always returns . 32 | public override IncomingMessageType MessageType 33 | { 34 | get 35 | { 36 | return IncomingMessageType.SmsDeliver; 37 | } 38 | } 39 | 40 | /// 41 | /// Gets or sets if there are more messages to send. 42 | /// 43 | public bool MoreMessages 44 | { 45 | get 46 | { 47 | return this.moreMessages; 48 | } 49 | set 50 | { 51 | this.moreMessages = value; 52 | } 53 | } 54 | 55 | /// 56 | /// Gets or sets if a reply path exists. 57 | /// 58 | public bool ReplyPathExists 59 | { 60 | get 61 | { 62 | return this.replyPathExists; 63 | } 64 | set 65 | { 66 | this.replyPathExists = value; 67 | } 68 | } 69 | 70 | /// 71 | /// Gets or sets if a status report was be requested. 72 | /// 73 | public bool StatusReportRequested 74 | { 75 | get 76 | { 77 | return this.statusReportRequested; 78 | } 79 | set 80 | { 81 | this.statusReportRequested = value; 82 | } 83 | } 84 | 85 | /// 86 | /// Gets or sets if a user data header is present. 87 | /// 88 | public bool UserDataHeaderPresent 89 | { 90 | get 91 | { 92 | return this.userDataHeaderPresent; 93 | } 94 | set 95 | { 96 | this.userDataHeaderPresent = value; 97 | } 98 | } 99 | 100 | /// 101 | /// Initializes a new instance of the class. 102 | /// 103 | public SmsDeliverMessageFlags() 104 | { 105 | this.moreMessages = false; 106 | this.statusReportRequested = false; 107 | this.userDataHeaderPresent = false; 108 | this.replyPathExists = false; 109 | } 110 | 111 | /// 112 | /// Initializes a new instance of the SmsDeliverMessageFlags class with a 113 | /// predefined data byte. 114 | /// 115 | /// The message flags as a byte value. 116 | public SmsDeliverMessageFlags(byte flags) 117 | { 118 | this.FromByte(flags); 119 | } 120 | 121 | /// 122 | /// Fills the object with values from the data byte. 123 | /// 124 | /// The byte value. 125 | protected override void FromByte(byte b) 126 | { 127 | IncomingMessageType incomingMessageType = IncomingMessageType.SmsDeliver; 128 | if (0 > 0) 129 | { 130 | incomingMessageType = IncomingMessageType.SmsDeliver; 131 | } 132 | if (incomingMessageType == IncomingMessageType.SmsDeliver) 133 | { 134 | this.moreMessages = (b & 4) == 0; 135 | this.StatusReportRequested = (b & 32) > 0; 136 | this.userDataHeaderPresent = (b & 64) > 0; 137 | this.replyPathExists = (b & 128) > 0; 138 | return; 139 | } 140 | else 141 | { 142 | throw new ArgumentException("Not an SMS-DELIVER message."); 143 | } 144 | } 145 | 146 | /// 147 | /// Returns the byte equivalent of this instance. 148 | /// 149 | /// The byte value. 150 | public override byte ToByte() 151 | { 152 | byte num = 0; 153 | num = (byte)num; 154 | if (!this.moreMessages) 155 | { 156 | num = (byte)(num | 4); 157 | } 158 | if (this.StatusReportRequested) 159 | { 160 | num = (byte)(num | 32); 161 | } 162 | if (this.userDataHeaderPresent) 163 | { 164 | num = (byte)(num | 64); 165 | } 166 | if (this.replyPathExists) 167 | { 168 | num = (byte)(num | 128); 169 | } 170 | return num; 171 | } 172 | } 173 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmartMessaging/ConcatMessageElement16.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Implements a Concatenated Short Message Information Element (16-bit reference number) 5 | /// 6 | /// This element is used to indiate that a message is split into 7 | /// multiple parts. 8 | namespace GsmComm.PduConverter.SmartMessaging 9 | { 10 | public class ConcatMessageElement16 : InformationElement, IConcatenationInfo 11 | { 12 | /// 13 | /// The Information Element Identifier (IEI). 14 | /// 15 | public const byte Identifier = 8; 16 | 17 | private ushort referenceNumber; 18 | 19 | private byte totalMessages; 20 | 21 | private byte currentNumber; 22 | 23 | /// 24 | /// Gets the current message number. 25 | /// 26 | public byte CurrentNumber 27 | { 28 | get 29 | { 30 | return this.currentNumber; 31 | } 32 | } 33 | 34 | /// 35 | /// Gets the current message number. 36 | /// 37 | byte GsmComm.PduConverter.SmartMessaging.IConcatenationInfo.CurrentNumber 38 | { 39 | get 40 | { 41 | return this.currentNumber; 42 | } 43 | } 44 | 45 | /// 46 | /// Gets the message reference number. 47 | /// 48 | ushort GsmComm.PduConverter.SmartMessaging.IConcatenationInfo.ReferenceNumber 49 | { 50 | get 51 | { 52 | return this.referenceNumber; 53 | } 54 | } 55 | 56 | /// 57 | /// Gets the total number of parts of the message. 58 | /// 59 | byte GsmComm.PduConverter.SmartMessaging.IConcatenationInfo.TotalMessages 60 | { 61 | get 62 | { 63 | return this.totalMessages; 64 | } 65 | } 66 | 67 | /// 68 | /// Gets the message reference number. 69 | /// 70 | public ushort ReferenceNumber 71 | { 72 | get 73 | { 74 | return this.referenceNumber; 75 | } 76 | } 77 | 78 | /// 79 | /// Gets the total number of parts of the message. 80 | /// 81 | public byte TotalMessages 82 | { 83 | get 84 | { 85 | return this.totalMessages; 86 | } 87 | } 88 | 89 | /// 90 | /// Initializes a new instance of the class. 91 | /// 92 | /// The message's reference number, must 93 | /// be the same in all parts of the same message. 94 | /// The total number of parts of the message. 95 | /// The current message number. 96 | public ConcatMessageElement16(ushort referenceNumber, byte totalMessages, byte currentNumber) 97 | { 98 | this.referenceNumber = referenceNumber; 99 | this.totalMessages = totalMessages; 100 | this.currentNumber = currentNumber; 101 | } 102 | 103 | /// 104 | /// Initializes a new instance of the class. 105 | /// 106 | /// The information element as a byte array. 107 | public ConcatMessageElement16(byte[] element) 108 | { 109 | if (element != null) 110 | { 111 | if (element[0] == 8) 112 | { 113 | byte num = element[1]; 114 | if (num >= 4) 115 | { 116 | byte[] numArray = new byte[2]; 117 | numArray[0] = element[3]; 118 | numArray[1] = element[2]; 119 | this.referenceNumber = BitConverter.ToUInt16(numArray, 0); 120 | this.totalMessages = element[4]; 121 | this.currentNumber = element[5]; 122 | return; 123 | } 124 | else 125 | { 126 | throw new FormatException("Information element data must be 4 bytes long."); 127 | } 128 | } 129 | else 130 | { 131 | throw new ArgumentException("Element is not a Concatenated Short Message Information Element (16-bit reference number).", "element"); 132 | } 133 | } 134 | else 135 | { 136 | throw new ArgumentNullException("element"); 137 | } 138 | } 139 | 140 | /// 141 | /// Returns the byte array equivalent of this instance. 142 | /// 143 | /// The byte array. 144 | public override byte[] ToByteArray() 145 | { 146 | byte[] bytes = BitConverter.GetBytes(this.referenceNumber); 147 | byte[] numArray = new byte[6]; 148 | numArray[0] = 8; 149 | numArray[1] = 4; 150 | numArray[2] = bytes[1]; 151 | numArray[3] = bytes[0]; 152 | numArray[4] = this.totalMessages; 153 | numArray[5] = this.currentNumber; 154 | return numArray; 155 | } 156 | } 157 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/OutgoingSmsPdu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Represents an outgoing SMS PDU. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public abstract class OutgoingSmsPdu : SmsPdu 9 | { 10 | private const byte TP_MTI_SMS_Deliver_Report = 0; 11 | 12 | private const byte TP_MTI_SMS_Submit = 1; 13 | 14 | private const byte TP_MTI_SMS_Command = 2; 15 | 16 | /// 17 | /// The flags for this message. 18 | /// 19 | protected OutgoingMessageFlags messageFlags; 20 | 21 | /// 22 | /// The message reference. 23 | /// 24 | protected byte messageReference; 25 | 26 | /// 27 | /// Gets or sets the message reference. 28 | /// 29 | /// Represents the TP-Message-Reference octet of the PDU. 30 | /// Normally there is no need to change this property because 31 | /// the reference is set by the sending device.. 32 | /// 33 | public byte MessageReference 34 | { 35 | get 36 | { 37 | return this.messageReference; 38 | } 39 | set 40 | { 41 | this.messageReference = value; 42 | } 43 | } 44 | 45 | /// 46 | /// Gets the message type. 47 | /// 48 | public OutgoingMessageType MessageType 49 | { 50 | get 51 | { 52 | return this.messageFlags.MessageType; 53 | } 54 | } 55 | 56 | /// 57 | /// Initializes a new instance. 58 | /// 59 | protected OutgoingSmsPdu() 60 | { 61 | this.messageReference = 0; 62 | } 63 | 64 | /// 65 | /// Decodes an outgoing SMS PDU stream. 66 | /// 67 | /// The PDU string to decode 68 | /// Specify true if the PDU data contains an SMSC header, otherwise false. 69 | /// The length of the PDU in bytes, not including the SMSC header. 70 | /// An object representing the decoded message. 71 | public static OutgoingSmsPdu Decode(string pdu, bool includesSmscData, int actualLength) 72 | { 73 | if (pdu != string.Empty) 74 | { 75 | int num = 0; 76 | if (includesSmscData) 77 | { 78 | int num1 = num; 79 | num = num1 + 1; 80 | byte num2 = BcdWorker.GetByte(pdu, num1); 81 | if (num2 > 0) 82 | { 83 | num = num + num2; 84 | } 85 | } 86 | int num3 = num; 87 | OutgoingMessageType messageType = OutgoingSmsPdu.GetMessageType(BcdWorker.GetByte(pdu, num3)); 88 | OutgoingMessageType outgoingMessageType = messageType; 89 | if (outgoingMessageType != OutgoingMessageType.SmsSubmit) 90 | { 91 | throw new NotSupportedException(string.Concat("Message type ", messageType.ToString(), " recognized, but not supported by the SMS decoder.")); 92 | } 93 | else 94 | { 95 | return new SmsSubmitPdu(pdu, includesSmscData, actualLength); 96 | } 97 | } 98 | else 99 | { 100 | throw new ArgumentException("pdu must not be an empty string."); 101 | } 102 | } 103 | 104 | /// 105 | /// Decodes an outgoing SMS PDU stream. 106 | /// 107 | /// The PDU string to decode. 108 | /// Specify true if the PDU data contains an SMSC header, otherwise false. 109 | /// An object representing the decoded message. 110 | /// Use this method when the actual length of the message is not known. 111 | public static OutgoingSmsPdu Decode(string pdu, bool includesSmscData) 112 | { 113 | return OutgoingSmsPdu.Decode(pdu, includesSmscData, -1); 114 | } 115 | 116 | private static OutgoingMessageType GetMessageType(byte flags) 117 | { 118 | OutgoingMessageType outgoingMessageType; 119 | int num; 120 | if ((flags & 2) > 0) 121 | { 122 | num = 1; 123 | } 124 | else 125 | { 126 | num = 0; 127 | } 128 | byte num1 = (byte)(num * 2 + (flags & 1)); 129 | byte num2 = num1; 130 | if (num2 == 0) 131 | { 132 | outgoingMessageType = OutgoingMessageType.SmsDeliverReport; 133 | } 134 | else if (num2 == 1) 135 | { 136 | outgoingMessageType = OutgoingMessageType.SmsSubmit; 137 | } 138 | else if (num2 == 2) 139 | { 140 | outgoingMessageType = OutgoingMessageType.SmsCommand; 141 | } 142 | else 143 | { 144 | string[] str = new string[5]; 145 | str[0] = "Unknown message type "; 146 | str[1] = num1.ToString(); 147 | str[2] = " (flags="; 148 | str[3] = flags.ToString(); 149 | str[4] = ")"; 150 | throw new ArgumentException(string.Concat(str), "flags"); 151 | } 152 | return outgoingMessageType; 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/MessageIndicationSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Specifies the settings for new message notifications. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public struct MessageIndicationSettings 9 | { 10 | private int mode; 11 | 12 | private int mt; 13 | 14 | private int bm; 15 | 16 | private int ds; 17 | 18 | private int bfr; 19 | 20 | /// 21 | /// Specifies how the indication buffer should be handled when indications are activated, i.e. 22 | /// when is set to any value except . 23 | /// 24 | /// 25 | /// You can use one of the values to set this property. 26 | /// 27 | public int BufferSetting 28 | { 29 | get 30 | { 31 | return this.bfr; 32 | } 33 | set 34 | { 35 | this.bfr = value; 36 | } 37 | } 38 | 39 | /// 40 | /// Specifies how new Cell Broadcast messages should be indicated. 41 | /// 42 | /// 43 | /// You can use one of the values to set this property. 44 | /// 45 | public int CellBroadcastStyle 46 | { 47 | get 48 | { 49 | return this.bm; 50 | } 51 | set 52 | { 53 | this.bm = value; 54 | } 55 | } 56 | 57 | /// 58 | /// Specifies how new SMS-DELIVER messages should be indicated. 59 | /// 60 | /// 61 | /// You can use one of the values to set this property. 62 | /// 63 | public int DeliverStyle 64 | { 65 | get 66 | { 67 | return this.mt; 68 | } 69 | set 70 | { 71 | this.mt = value; 72 | } 73 | } 74 | 75 | /// 76 | /// Specifies the general indication mode. 77 | /// 78 | /// 79 | /// You can use one of the values to set this property. 80 | /// 81 | public int Mode 82 | { 83 | get 84 | { 85 | return this.mode; 86 | } 87 | set 88 | { 89 | this.mode = value; 90 | } 91 | } 92 | 93 | /// 94 | /// Specifies how new SMS-STATUS-REPORT messages should be indicated. 95 | /// 96 | /// 97 | /// You can use one of the values to set this property. 98 | /// 99 | public int StatusReportStyle 100 | { 101 | get 102 | { 103 | return this.ds; 104 | } 105 | set 106 | { 107 | this.ds = value; 108 | } 109 | } 110 | 111 | /// 112 | /// Initializes a new instance of the structure. 113 | /// 114 | /// Specifies the general indication mode. 115 | /// Specifies how new SMS-DELIVER messages should be indicated. 116 | /// Specifies how new Cell Broadcast messages should be indicated. 117 | /// Specifies how new SMS-STATUS-REPORT messages should be indicated. 118 | /// Specifies how the indication buffer should be handled when indications are activated, i.e. 119 | /// when is set to any value except . 120 | public MessageIndicationSettings(int mode, int mt, int bm, int ds, int bfr) 121 | { 122 | this.mode = mode; 123 | this.mt = mt; 124 | this.bm = bm; 125 | this.ds = ds; 126 | this.bfr = bfr; 127 | } 128 | 129 | /// 130 | /// Initializes a new instance of the structure. 131 | /// 132 | /// Specifies the general indication mode. 133 | /// Specifies how new SMS-DELIVER messages should be indicated. 134 | /// Specifies how new Cell Broadcast messages should be indicated. 135 | /// Specifies how new SMS-STATUS-REPORT messages should be indicated. 136 | /// Specifies how the indication buffer should be handled when indications are activated, i.e. 137 | /// when is set to any value except . 138 | public MessageIndicationSettings(MessageIndicationMode mode, SmsDeliverIndicationStyle mt, CbmIndicationStyle bm, SmsStatusReportIndicationStyle ds, IndicationBufferSetting bfr) 139 | : this((int)mode, (int)mt, (int)bm, (int)ds, (int)bfr) 140 | { 141 | } 142 | } 143 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/ParameterIndicator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// TP-PI / TP-Parameter-Indicator. Represents particular optional parameter 5 | /// presence in the fields which follow. 6 | /// 7 | namespace GsmComm.PduConverter 8 | { 9 | public class ParameterIndicator 10 | { 11 | private const byte bit0 = 1; 12 | 13 | private const byte bit1 = 2; 14 | 15 | private const byte bit2 = 4; 16 | 17 | private const byte bit3 = 8; 18 | 19 | private const byte bit4 = 16; 20 | 21 | private const byte bit5 = 32; 22 | 23 | private const byte bit6 = 64; 24 | 25 | private const byte bit7 = 128; 26 | 27 | private bool tp_pid; 28 | 29 | private bool tp_dcs; 30 | 31 | private bool tp_udl; 32 | 33 | private bool reserved_bit3; 34 | 35 | private bool reserved_bit4; 36 | 37 | private bool reserved_bit5; 38 | 39 | private bool reserved_bit6; 40 | 41 | private bool extension; 42 | 43 | /// 44 | /// When set to true, will indicate that another TP-PI octet follows immediately afterwards. 45 | /// 46 | public bool Extension 47 | { 48 | get 49 | { 50 | return this.extension; 51 | } 52 | set 53 | { 54 | this.extension = value; 55 | } 56 | } 57 | 58 | /// 59 | /// Reserved. If set to true, the receiving entity should ignore 60 | /// this setting. 61 | /// 62 | public bool Reserved_Bit3 63 | { 64 | get 65 | { 66 | return this.reserved_bit3; 67 | } 68 | set 69 | { 70 | this.reserved_bit3 = value; 71 | } 72 | } 73 | 74 | /// 75 | /// Reserved. If set to true, the receiving entity should ignore 76 | /// this setting. 77 | /// 78 | public bool Reserved_Bit4 79 | { 80 | get 81 | { 82 | return this.reserved_bit4; 83 | } 84 | set 85 | { 86 | this.reserved_bit4 = value; 87 | } 88 | } 89 | 90 | /// 91 | /// Reserved. If set to true, the receiving entity should ignore 92 | /// this setting. 93 | /// 94 | public bool Reserved_Bit5 95 | { 96 | get 97 | { 98 | return this.reserved_bit5; 99 | } 100 | set 101 | { 102 | this.reserved_bit5 = value; 103 | } 104 | } 105 | 106 | /// 107 | /// Reserved. If set to true, the receiving entity should ignore 108 | /// this setting. 109 | /// 110 | public bool Reserved_Bit6 111 | { 112 | get 113 | { 114 | return this.reserved_bit6; 115 | } 116 | set 117 | { 118 | this.reserved_bit6 = value; 119 | } 120 | } 121 | 122 | /// 123 | /// When true, a TP-DCS field is present. 124 | /// 125 | public bool TP_DCS 126 | { 127 | get 128 | { 129 | return this.tp_dcs; 130 | } 131 | set 132 | { 133 | this.tp_dcs = value; 134 | } 135 | } 136 | 137 | /// 138 | /// When true, a TP-PID field is present. 139 | /// 140 | public bool TP_PID 141 | { 142 | get 143 | { 144 | return this.tp_pid; 145 | } 146 | set 147 | { 148 | this.tp_pid = value; 149 | } 150 | } 151 | 152 | /// 153 | /// When false, neither TP-UDL nor TP-UD field can be present. 154 | /// 155 | public bool TP_UDL 156 | { 157 | get 158 | { 159 | return this.tp_udl; 160 | } 161 | set 162 | { 163 | this.tp_udl = value; 164 | } 165 | } 166 | 167 | /// 168 | /// Initializes a new instance of the . 169 | /// 170 | /// The value to initialize the object with. 171 | public ParameterIndicator(byte value) 172 | { 173 | this.tp_pid = (value & 1) > 0; 174 | this.tp_dcs = (value & 2) > 0; 175 | this.tp_udl = (value & 4) > 0; 176 | this.reserved_bit3 = (value & 8) > 0; 177 | this.reserved_bit4 = (value & 16) > 0; 178 | this.reserved_bit5 = (value & 32) > 0; 179 | this.reserved_bit6 = (value & 64) > 0; 180 | this.extension = (value & 128) > 0; 181 | } 182 | 183 | public static implicit operator Byte(ParameterIndicator pi) 184 | { 185 | return pi.ToByte(); 186 | } 187 | 188 | public static implicit operator ParameterIndicator(byte b) 189 | { 190 | return new ParameterIndicator(b); 191 | } 192 | 193 | /// 194 | /// Returns the byte equivalent of this instance. 195 | /// 196 | /// The byte value. 197 | public byte ToByte() 198 | { 199 | byte num = 0; 200 | if (this.tp_pid) 201 | { 202 | num = (byte)(num | 1); 203 | } 204 | if (this.tp_dcs) 205 | { 206 | num = (byte)(num | 2); 207 | } 208 | if (this.tp_udl) 209 | { 210 | num = (byte)(num | 4); 211 | } 212 | if (this.reserved_bit3) 213 | { 214 | num = (byte)(num | 8); 215 | } 216 | if (this.reserved_bit4) 217 | { 218 | num = (byte)(num | 16); 219 | } 220 | if (this.reserved_bit5) 221 | { 222 | num = (byte)(num | 32); 223 | } 224 | if (this.reserved_bit6) 225 | { 226 | num = (byte)(num | 64); 227 | } 228 | if (this.extension) 229 | { 230 | num = (byte)(num | 128); 231 | } 232 | return num; 233 | } 234 | } 235 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/RelativeValidityPeriod.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | /// 5 | /// The relative validity period gives the length of the validity period 6 | /// counted from when the SMS-SUBMIT is received by the SC. 7 | /// 8 | namespace GsmComm.PduConverter 9 | { 10 | public class RelativeValidityPeriod : ValidityPeriod 11 | { 12 | private byte @value; 13 | 14 | /// 15 | /// Initializes a new instance of the . 16 | /// 17 | /// The byte value of the validity period. Use this 18 | /// if you have already calculated the validity yourself. 19 | public RelativeValidityPeriod(byte value) 20 | { 21 | this.@value = value; 22 | } 23 | 24 | /// 25 | /// Initializes a new instance of the . 26 | /// 27 | /// The validity period. 28 | /// 29 | /// There are some rules to note: 30 | /// 31 | /// 32 | /// The smallest validity period is 5 minutes, 63 weeks the largest. 33 | /// 34 | /// 35 | /// Periods between 5 minutes and 12 hours can be specified in 5 minute steps. 36 | /// 37 | /// 38 | /// Periods between 12h30min and 24 hours can be specified in 30 minute steps. 39 | /// 40 | /// 41 | /// Periods between two days and 30 days can be specified in 1 day steps. 42 | /// 43 | /// 44 | /// Periods between 5 weeks and 63 weeks can be specified in 1 week (=7 days) steps. 45 | /// 46 | /// 47 | /// 48 | /// Validity timespan is invalid. 49 | public RelativeValidityPeriod(TimeSpan period) 50 | { 51 | byte num = 0; 52 | while (num <= 255) 53 | { 54 | TimeSpan timeSpan = RelativeValidityPeriod.ToTimeSpan(num); 55 | if (timeSpan.CompareTo(period) != 0) 56 | { 57 | num = (byte)(num + 1); 58 | } 59 | else 60 | { 61 | this.@value = num; 62 | return; 63 | } 64 | } 65 | throw new ArgumentException("Invalid validity timespan."); 66 | } 67 | 68 | private void AppendIfNonzero(StringBuilder str, int val, string suffix) 69 | { 70 | if (val > 0) 71 | { 72 | if (str.Length != 0) 73 | { 74 | str.Append(" "); 75 | } 76 | str.Append(val.ToString()); 77 | str.Append(suffix); 78 | } 79 | } 80 | 81 | public static explicit operator RelativeValidityPeriod(TimeSpan ts) 82 | { 83 | return new RelativeValidityPeriod(ts); 84 | } 85 | 86 | public static implicit operator TimeSpan(RelativeValidityPeriod v) 87 | { 88 | return v.ToTimeSpan(); 89 | } 90 | 91 | public static implicit operator Byte(RelativeValidityPeriod v) 92 | { 93 | return v.ToByte(); 94 | } 95 | 96 | public static implicit operator RelativeValidityPeriod(byte b) 97 | { 98 | return new RelativeValidityPeriod(b); 99 | } 100 | 101 | /// 102 | /// Returns the byte equivalent of this instance. 103 | /// 104 | /// The byte value. 105 | public byte ToByte() 106 | { 107 | return this.@value; 108 | } 109 | 110 | /// 111 | /// Returns the string equivalent of this instance. 112 | /// 113 | public override string ToString() 114 | { 115 | TimeSpan timeSpan = this.ToTimeSpan(); 116 | if (timeSpan.TotalHours != 24) 117 | { 118 | StringBuilder stringBuilder = new StringBuilder(); 119 | this.AppendIfNonzero(stringBuilder, timeSpan.Days, "d"); 120 | this.AppendIfNonzero(stringBuilder, timeSpan.Hours, "h"); 121 | this.AppendIfNonzero(stringBuilder, timeSpan.Minutes, "m"); 122 | this.AppendIfNonzero(stringBuilder, timeSpan.Seconds, "s"); 123 | this.AppendIfNonzero(stringBuilder, timeSpan.Milliseconds, "ms"); 124 | return stringBuilder.ToString(); 125 | } 126 | else 127 | { 128 | return "24h"; 129 | } 130 | } 131 | 132 | /// 133 | /// Returns the TimeSpan equivalent of this instance. 134 | /// 135 | /// The TimeSpan value. 136 | public TimeSpan ToTimeSpan() 137 | { 138 | return RelativeValidityPeriod.ToTimeSpan(this.@value); 139 | } 140 | 141 | private static TimeSpan ToTimeSpan(byte value) 142 | { 143 | if (value < 0 || value > 143) 144 | { 145 | if (value < 144 || value > 167) 146 | { 147 | if (value < 168 || value > 196) 148 | { 149 | if (value < 197 || value > 255) 150 | { 151 | return TimeSpan.Zero; 152 | } 153 | else 154 | { 155 | return new TimeSpan((value - 192) * 7, 0, 0, 0); 156 | } 157 | } 158 | else 159 | { 160 | return new TimeSpan(value - 166, 0, 0, 0); 161 | } 162 | } 163 | else 164 | { 165 | return new TimeSpan(12, (value - 143) * 30, 0); 166 | } 167 | } 168 | else 169 | { 170 | return new TimeSpan(0, (value + 1) * 5, 0); 171 | } 172 | } 173 | } 174 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/Calc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Performs various numerical conversions and calculations. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class Calc 9 | { 10 | private static char[] hexDigits; 11 | 12 | static Calc() 13 | { 14 | char[] chrArray = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 15 | Calc.hexDigits = chrArray; 16 | } 17 | 18 | public Calc() 19 | { 20 | } 21 | 22 | /// 23 | /// Converts a bit string into a byte. 24 | /// 25 | /// The string to convert. 26 | /// The converted value. 27 | public static byte BinToInt(string s) 28 | { 29 | return Convert.ToByte(s, 2); 30 | } 31 | 32 | /// 33 | /// Converts a BCD encoded string (hexadecimal) into its byte representation. 34 | /// 35 | /// The string to convert. 36 | /// 37 | /// The length of the string should be even. This is not checked 38 | /// here to be able to process truncated strings. 39 | /// 40 | /// The converted value. 41 | /// 42 | /// A string containing "41" will become {0x41}, which equals 43 | /// the character 'A'. 44 | /// A string containing "414242" will become {0x41, 0x42, 0x43} 45 | /// which equals the string "ABC". 46 | /// 47 | public static byte[] HexToInt(string s) 48 | { 49 | byte[] num = new byte[s.Length / 2]; 50 | for (int i = 0; i < s.Length / 2; i++) 51 | { 52 | string str = s.Substring(i * 2, 2); 53 | num[i] = Convert.ToByte(str, 16); 54 | } 55 | return num; 56 | } 57 | 58 | /// 59 | /// Converts a byte into a bit string. 60 | /// 61 | /// The byte to convert. 62 | /// 63 | /// The final length the string should have. If the resulting string is 64 | /// shorter than this value, it is padded with leading zeroes. 65 | /// 66 | /// The converted value. 67 | public static string IntToBin(byte b, byte size) 68 | { 69 | return Convert.ToString(b, 2).PadLeft(size, '0'); 70 | } 71 | 72 | /// 73 | /// Converts a byte array into its hexadecimal representation (BCD encoding). 74 | /// 75 | /// The byte array to convert. 76 | /// The converted value. 77 | public static string IntToHex(byte[] bytes) 78 | { 79 | char[] chrArray = new char[(int)bytes.Length * 2]; 80 | for (int i = 0; i < (int)bytes.Length; i++) 81 | { 82 | int num = bytes[i]; 83 | chrArray[i * 2] = Calc.hexDigits[num >> 4]; 84 | chrArray[i * 2 + 1] = Calc.hexDigits[num & 15]; 85 | } 86 | return new string(chrArray); 87 | } 88 | 89 | /// 90 | /// Converts a byte array into its hexadecimal representation (BCD encoding). 91 | /// 92 | /// The byte array to convert. 93 | /// The starting index of the byte array to convert. 94 | /// The number of bytes to convert. 95 | /// The converted value. 96 | public static string IntToHex(byte[] bytes, int index, int count) 97 | { 98 | char[] chrArray = new char[count * 2]; 99 | for (int i = 0; i < count; i++) 100 | { 101 | int num = bytes[index + i]; 102 | chrArray[i * 2] = Calc.hexDigits[num >> 4]; 103 | chrArray[i * 2 + 1] = Calc.hexDigits[num & 15]; 104 | } 105 | return new string(chrArray); 106 | } 107 | 108 | /// 109 | /// Converts a byte into its BCD (hexadecimal) representation. 110 | /// 111 | /// The byte to convert. 112 | /// The converted value. 113 | public static string IntToHex(byte b) 114 | { 115 | return string.Concat(Calc.hexDigits[b >> 4].ToString(), Calc.hexDigits[b & 15].ToString()); 116 | } 117 | 118 | /// 119 | /// Determines if a string is a hexadecimal character. 120 | /// 121 | /// The character to check. 122 | /// true if the character is a hex char, false otherwise. 123 | public static bool IsHexDigit(char c) 124 | { 125 | char upper = char.ToUpper(c); 126 | char[] chrArray = Calc.hexDigits; 127 | int num = 0; 128 | while (num < (int)chrArray.Length) 129 | { 130 | char chr = chrArray[num]; 131 | if (upper != chr) 132 | { 133 | num++; 134 | } 135 | else 136 | { 137 | bool flag = true; 138 | return flag; 139 | } 140 | } 141 | return false; 142 | } 143 | 144 | /// 145 | /// Determines if a string consists only of hexadecimal characters. 146 | /// 147 | /// The string to check. 148 | /// true if the string is a hex string, false otherwise. 149 | public static bool IsHexString(string s) 150 | { 151 | if (s.Length != 0) 152 | { 153 | int num = 0; 154 | while (num < s.Length) 155 | { 156 | if (Calc.IsHexDigit(s[num])) 157 | { 158 | num++; 159 | } 160 | else 161 | { 162 | return false; 163 | } 164 | } 165 | return true; 166 | } 167 | else 168 | { 169 | return false; 170 | } 171 | } 172 | } 173 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/IProtocol.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Provides an interface for low-level access to the device. 5 | /// 6 | namespace GsmComm.GsmCommunication 7 | { 8 | public interface IProtocol 9 | { 10 | /// 11 | /// Executes the specified command and reads multiple times from the phone 12 | /// until a specific pattern is detected in the response. 13 | /// 14 | /// The command to execute. 15 | /// The regular expression pattern that the received data must match to stop 16 | /// reading. 17 | /// The response received. 18 | /// 19 | /// 20 | /// 21 | string ExecAndReceiveAnything(string command, string pattern); 22 | 23 | /// Executes the specified command and reads multiple times from the phone 24 | /// until one of the defined message termination patterns is detected in the response. 25 | /// The command to execute. 26 | /// The response received. 27 | /// 28 | /// 29 | /// 30 | string ExecAndReceiveMultiple(string command); 31 | 32 | /// Executes the specified command and reads a single response. 33 | /// The command to execute. 34 | /// The response received. 35 | /// 36 | /// This method returns whatever response comes in from the phone during a single read operation. 37 | /// The response received may not be complete. 38 | /// If you want to ensure that always complete responses are read, use instead. 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | string ExecCommand(string command); 45 | 46 | /// 47 | /// Executes the specified command and reads a single response. 48 | /// The command to execute. 49 | /// The message text for the exception if no data is received. 50 | /// The response received. 51 | /// 52 | /// This method returns whatever response comes in from the phone during a single read operation. 53 | /// The response received may not be complete. 54 | /// If you want to ensure that always complete responses are read, use instead. 55 | /// 56 | /// 57 | /// 58 | /// 59 | /// 60 | string ExecCommand(string command, string receiveErrorMessage); 61 | 62 | /// 63 | /// Receives raw string data. 64 | /// The data received. 65 | /// true if reception was successful, otherwise false. 66 | /// 67 | bool Receive(out string input); 68 | 69 | /// Reads multiple times from the phone until a specific pattern is detected in the response. 70 | /// The response received. 71 | /// The regular expression pattern that the received data must match to 72 | /// stop reading. Can be an empty string if the pattern should not be checked. 73 | /// 74 | /// 75 | /// 76 | string ReceiveAnything(string pattern); 77 | 78 | /// Reads multiple times from the phone until one of the defined 79 | /// message termination patterns is detected in the response. 80 | /// The response received. 81 | /// 82 | /// 83 | /// 84 | string ReceiveMultiple(); 85 | 86 | /// Sends raw string data. 87 | /// The data to send. 88 | /// 89 | void Send(string output); 90 | } 91 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/BcdWorker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// A class for working with BCD encoded data strings. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class BcdWorker 9 | { 10 | public BcdWorker() 11 | { 12 | } 13 | 14 | /// 15 | /// Counts the number of bytes in a BCD encoded string. 16 | /// 17 | /// The string containing the BCD data. 18 | /// The byte count. 19 | public static int CountBytes(string s) 20 | { 21 | return s.Length / 2; 22 | } 23 | 24 | /// 25 | /// Swaps the semi-octets of a BCD encoded string and checks the length. 26 | /// 27 | /// The string to decode. Must be of even length. 28 | /// The converted value. 29 | /// String length is not even. 30 | /// 21436587 becomes 12345678. 31 | public static string DecodeSemiOctets(string data) 32 | { 33 | if (data.Length % 2 == 0) 34 | { 35 | string empty = string.Empty; 36 | for (int i = 0; i < data.Length; i = i + 2) 37 | { 38 | empty = string.Concat(empty, data.Substring(i + 1, 1), data.Substring(i, 1)); 39 | } 40 | return empty; 41 | } 42 | else 43 | { 44 | throw new ArgumentException("String length must be even."); 45 | } 46 | } 47 | 48 | /// 49 | /// Swaps the semi-octets of a BCD encoded string. 50 | /// 51 | /// The string to convert. 52 | /// 53 | /// If the string is not of even length, it is padded with a 54 | /// hexadecimal "F" before converting. 55 | /// This method does not verify the actual contents of the string. 56 | /// 57 | /// The converted value. 58 | /// 59 | /// A string containing "12345678" will become "21436587". 60 | /// A string containing "1234567" will become "214365F7". 61 | /// 62 | public static string EncodeSemiOctets(string data) 63 | { 64 | if (data.Length % 2 != 0) 65 | { 66 | data = string.Concat(data, "F"); 67 | } 68 | string empty = string.Empty; 69 | for (int i = 0; i < data.Length; i = i + 2) 70 | { 71 | empty = string.Concat(empty, data.Substring(i + 1, 1), data.Substring(i, 1)); 72 | } 73 | return empty; 74 | } 75 | 76 | /// 77 | /// Swaps the semi-octets of a BCD encoded string. 78 | /// 79 | /// The string to convert. 80 | /// The width to pad the string to before converting. 81 | /// Padding character is hexadecimal "F". 82 | /// 83 | /// This method does not verify the actual contents of the string. 84 | /// 85 | /// The converted value. 86 | /// totalWidth is not even. 87 | public static string EncodeSemiOctets(string data, int totalWidth) 88 | { 89 | if (totalWidth % 2 == 0) 90 | { 91 | return BcdWorker.EncodeSemiOctets(data.PadRight(totalWidth, 'F')); 92 | } 93 | else 94 | { 95 | throw new ArgumentException("totalWidth must be even.", "totalWidth"); 96 | } 97 | } 98 | 99 | /// 100 | /// Gets a single byte out of a BCD encoded string. 101 | /// 102 | /// The string containing the BCD data. 103 | /// The position in the string to start. 104 | /// The byte at the specified position. 105 | /// No range checking is performed. 106 | public static byte GetByte(string s, int index) 107 | { 108 | string str = s.Substring(index * 2, 2); 109 | return Calc.HexToInt(str)[0]; 110 | } 111 | 112 | /// 113 | /// Gets multiple bytes out of a BCD encoded string. 114 | /// 115 | /// The string containing the BCD data. 116 | /// The position in the string to start. 117 | /// The number of bytes to read. 118 | /// The bytes within the specified range. 119 | /// No range checking is performed. 120 | public static byte[] GetBytes(string s, int index, int length) 121 | { 122 | string str = s.Substring(index * 2, length * 2); 123 | return Calc.HexToInt(str); 124 | } 125 | 126 | /// 127 | /// Gets multiple bytes as string out of a BCD encoded string. 128 | /// 129 | /// The string containing the BCD data. 130 | /// The position in the string to start. 131 | /// The number of bytes to read. 132 | /// The bytes within the specified range. 133 | /// No range checking is performed. 134 | public static string GetBytesString(string s, int index, int length) 135 | { 136 | return s.Substring(index * 2, length * 2); 137 | } 138 | 139 | /// 140 | /// Gets a single byte as string out of a BCD encoded string. 141 | /// 142 | /// The string containing the BCD data. 143 | /// The byte at the specified position. 144 | /// The byte at the specified position. 145 | /// No range checking is performed. 146 | public static string GetByteString(string s, int index) 147 | { 148 | return s.Substring(index * 2, 2); 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /GSMCommunication/GsmCommunication/SerialPortFixer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32.SafeHandles; 2 | using System; 3 | using System.IO; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace GsmComm.GsmCommunication 8 | { 9 | internal class SerialPortFixer : IDisposable 10 | { 11 | private const int DcbFlagAbortOnError = 14; 12 | 13 | private const int CommStateRetries = 10; 14 | 15 | private SafeFileHandle m_Handle; 16 | 17 | private SerialPortFixer(string portName) 18 | { 19 | if (portName == null || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase)) 20 | { 21 | throw new ArgumentException("Invalid Serial Port", "portName"); 22 | } 23 | else 24 | { 25 | SafeFileHandle safeFileHandle = SerialPortFixer.CreateFile(string.Concat("\\\\.\\", portName), -1073741824, 0, IntPtr.Zero, 3, 1073741824, IntPtr.Zero); 26 | if (safeFileHandle.IsInvalid) 27 | { 28 | SerialPortFixer.WinIoError(); 29 | } 30 | try 31 | { 32 | int fileType = SerialPortFixer.GetFileType(safeFileHandle); 33 | if (fileType == 2 || fileType == 0) 34 | { 35 | this.m_Handle = safeFileHandle; 36 | this.InitializeDcb(); 37 | } 38 | else 39 | { 40 | throw new ArgumentException("Invalid Serial Port", "portName"); 41 | } 42 | } 43 | catch 44 | { 45 | safeFileHandle.Close(); 46 | this.m_Handle = null; 47 | throw; 48 | } 49 | return; 50 | } 51 | } 52 | 53 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 54 | private static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref SerialPortFixer.Comstat lpStat); 55 | 56 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 57 | private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile); 58 | 59 | public void Dispose() 60 | { 61 | if (this.m_Handle != null) 62 | { 63 | this.m_Handle.Close(); 64 | this.m_Handle = null; 65 | } 66 | } 67 | 68 | public static void Execute(string portName) 69 | { 70 | using (SerialPortFixer serialPortFixer = new SerialPortFixer(portName)) 71 | { 72 | } 73 | } 74 | 75 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 76 | private static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr arguments); 77 | 78 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 79 | private static extern bool GetCommState(SafeFileHandle hFile, ref SerialPortFixer.Dcb lpDcb); 80 | 81 | private void GetCommStateNative(ref SerialPortFixer.Dcb lpDcb) 82 | { 83 | int num = 0; 84 | SerialPortFixer.Comstat comstat = new SerialPortFixer.Comstat(); 85 | int num1 = 0; 86 | while (num1 < 10) 87 | { 88 | if (!SerialPortFixer.ClearCommError(this.m_Handle, ref num, ref comstat)) 89 | { 90 | SerialPortFixer.WinIoError(); 91 | } 92 | if (!SerialPortFixer.GetCommState(this.m_Handle, ref lpDcb)) 93 | { 94 | if (num1 == 9) 95 | { 96 | SerialPortFixer.WinIoError(); 97 | } 98 | num1++; 99 | } 100 | else 101 | { 102 | return; 103 | } 104 | } 105 | } 106 | 107 | [DllImport("kernel32.dll", CharSet=CharSet.None)] 108 | private static extern int GetFileType(SafeFileHandle hFile); 109 | 110 | private static string GetMessage(int errorCode) 111 | { 112 | StringBuilder stringBuilder = new StringBuilder(512); 113 | if (SerialPortFixer.FormatMessage(12800, new HandleRef(null, IntPtr.Zero), errorCode, 0, stringBuilder, stringBuilder.Capacity, IntPtr.Zero) == 0) 114 | { 115 | return "Unknown Error"; 116 | } 117 | else 118 | { 119 | return stringBuilder.ToString(); 120 | } 121 | } 122 | 123 | private void InitializeDcb() 124 | { 125 | SerialPortFixer.Dcb flags = new SerialPortFixer.Dcb(); 126 | this.GetCommStateNative(ref flags); 127 | flags.Flags = (uint)(flags.Flags & -16385); 128 | this.SetCommStateNative(ref flags); 129 | } 130 | 131 | private static int MakeHrFromErrorCode(int errorCode) 132 | { 133 | return -2147024896 | errorCode; 134 | } 135 | 136 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)] 137 | private static extern bool SetCommState(SafeFileHandle hFile, ref SerialPortFixer.Dcb lpDcb); 138 | 139 | private void SetCommStateNative(ref SerialPortFixer.Dcb lpDcb) 140 | { 141 | int num = 0; 142 | SerialPortFixer.Comstat comstat = new SerialPortFixer.Comstat(); 143 | int num1 = 0; 144 | while (num1 < 10) 145 | { 146 | if (!SerialPortFixer.ClearCommError(this.m_Handle, ref num, ref comstat)) 147 | { 148 | SerialPortFixer.WinIoError(); 149 | } 150 | if (!SerialPortFixer.SetCommState(this.m_Handle, ref lpDcb)) 151 | { 152 | if (num1 == 9) 153 | { 154 | SerialPortFixer.WinIoError(); 155 | } 156 | num1++; 157 | } 158 | else 159 | { 160 | return; 161 | } 162 | } 163 | } 164 | 165 | private static void WinIoError() 166 | { 167 | int lastWin32Error = Marshal.GetLastWin32Error(); 168 | throw new IOException(SerialPortFixer.GetMessage(lastWin32Error), SerialPortFixer.MakeHrFromErrorCode(lastWin32Error)); 169 | } 170 | 171 | private struct Comstat 172 | { 173 | public readonly uint Flags; 174 | 175 | public readonly uint cbInQue; 176 | 177 | public readonly uint cbOutQue; 178 | } 179 | 180 | private struct Dcb 181 | { 182 | public readonly uint DCBlength; 183 | 184 | public readonly uint BaudRate; 185 | 186 | public uint Flags; 187 | 188 | public readonly ushort wReserved; 189 | 190 | public readonly ushort XonLim; 191 | 192 | public readonly ushort XoffLim; 193 | 194 | public readonly byte ByteSize; 195 | 196 | public readonly byte Parity; 197 | 198 | public readonly byte StopBits; 199 | 200 | public readonly byte XonChar; 201 | 202 | public readonly byte XoffChar; 203 | 204 | public readonly byte ErrorChar; 205 | 206 | public readonly byte EofChar; 207 | 208 | public readonly byte EvtChar; 209 | 210 | public readonly ushort wReserved1; 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/ProtocolID.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// This class and its contained classes contain all possible values for the 5 | /// Protocol Identifier. 6 | /// 7 | /// The members represent the TP-PID octet in the PDU. 8 | namespace GsmComm.PduConverter 9 | { 10 | public class ProtocolID 11 | { 12 | private const byte niwOffset = 0; 13 | 14 | private const byte iwOffset = 32; 15 | 16 | private const byte nuOffset = 64; 17 | 18 | private const byte resOffset = 128; 19 | 20 | private const byte scOffset = 192; 21 | 22 | private ProtocolID() 23 | { 24 | } 25 | 26 | /// 27 | /// Extracts the "Reserved" part of the PID. 28 | /// 29 | /// The PID containing the value. 30 | /// The value of the "Reserved" part. 31 | /// Value is not from the "Reserved" range. 32 | public static byte GetReservedValue(byte pid) 33 | { 34 | if (ProtocolID.IsReserved(pid)) 35 | { 36 | return (byte)(pid - 128); 37 | } 38 | else 39 | { 40 | throw new ArgumentException("Value is not from the \"Reserved\" range.", "pid"); 41 | } 42 | } 43 | 44 | /// 45 | /// Gets the "SC Specific Use" part of the ProtocolID. 46 | /// 47 | /// The PID byte to decode. 48 | /// The "SC Specific Use" value. 49 | /// Value in pid is not from the "SC specific" range. 50 | public static byte GetSCSpecificUseValue(byte pid) 51 | { 52 | if (ProtocolID.IsSCSpecificUse(pid)) 53 | { 54 | return (byte)(pid - 192); 55 | } 56 | else 57 | { 58 | throw new ArgumentException("Value is not from the \"SC specific\" range.", "pid"); 59 | } 60 | } 61 | 62 | /// 63 | /// Determines if the specified value is from the "Reserved" part. 64 | /// 65 | /// The value to check. 66 | /// true if the value is from the reserved part, false otherwise. 67 | public static bool IsReserved(byte pid) 68 | { 69 | if (pid < 128) 70 | { 71 | return false; 72 | } 73 | else 74 | { 75 | return pid - 128 <= 63; 76 | } 77 | } 78 | 79 | /// 80 | /// Determines if the specified PID is from the "SC Specific Use" part. 81 | /// 82 | /// The value to check. 83 | /// true if the value is for SC specific use, false otherwise. 84 | public static bool IsSCSpecificUse(byte pid) 85 | { 86 | if (pid < 192) 87 | { 88 | return false; 89 | } 90 | else 91 | { 92 | return pid - 192 <= 63; 93 | } 94 | } 95 | 96 | /// 97 | /// Allows the "Reserved" part of the ProtocolID to be used. 98 | /// 99 | /// The value for this part. 100 | /// Value is greater than 0x3F (63). 101 | /// The encoded protocol ID. 102 | public static byte Reserved(byte value) 103 | { 104 | if (value <= 63) 105 | { 106 | return (byte)(128 + value); 107 | } 108 | else 109 | { 110 | throw new ArgumentException("Value must not be greater than 0x3F (63)."); 111 | } 112 | } 113 | 114 | /// 115 | /// Allows the "SC Specific Use" part of the ProtocolID to be used. 116 | /// 117 | /// The value for this part. 118 | /// Value is greater than 0x3F (63). 119 | /// The encoded Protocol ID. 120 | public static byte SCSpecificUse(byte value) 121 | { 122 | if (value <= 63) 123 | { 124 | return (byte)(192 + value); 125 | } 126 | else 127 | { 128 | throw new ArgumentException("Value must not be greater than 0x3F (63)."); 129 | } 130 | } 131 | 132 | /// 133 | /// Telematic interworking. 134 | /// 135 | /// 136 | /// If an interworking protocol is specified in an SMS-SUBMIT PDU, 137 | /// it indicates that the SME is a telematic device of the specified type, 138 | /// and requests the SC to convert the SM into a form suited for that 139 | /// device type. If the destination network is ISDN, the SC must also 140 | /// select the proper service indicators for connecting to a device of 141 | /// that type. 142 | /// If an interworking protocol is specified in an SMS-DELIVER PDU, 143 | /// it indicates that the SME is a telematic device of the specified type. 144 | /// 145 | /// 146 | public enum Interworking : byte 147 | { 148 | Implicit, 149 | Telex, 150 | Group3Telefax, 151 | Group4Telefax, 152 | VoiceTelephone, 153 | Ermes, 154 | PagingSystem, 155 | VideoTex, 156 | Teletex, 157 | TeletexPSPDN, 158 | TeletexCSPDN, 159 | TeletexPSTN, 160 | TeletexISDN, 161 | Uci, 162 | Reserved0E, 163 | Reserved0F, 164 | MessageHandler, 165 | X400BasedHandler, 166 | InternetEMail, 167 | Reserved13, 168 | Reserved14, 169 | Reserved15, 170 | Reserved16, 171 | Reserved17, 172 | SCSpecific1, 173 | SCSpecific2, 174 | SCSpecific3, 175 | SCSpecific4, 176 | SCSpecific5, 177 | SCSpecific6, 178 | SCSpecific7, 179 | GsmMobileStation 180 | } 181 | 182 | /// 183 | /// For network use 184 | /// 185 | /// 186 | /// Details are written in the remarks section of the types. 187 | /// 188 | public enum NetworkUse : byte 189 | { 190 | ShortMessageType0, 191 | ReplaceShortMessageType1, 192 | ReplaceShortMessageType2, 193 | ReplaceShortMessageType3, 194 | ReplaceShortMessageType4, 195 | ReplaceShortMessageType5, 196 | ReplaceShortMessageType6, 197 | ReplaceShortMessageType7, 198 | ReturnCallMessage, 199 | MEDataDownload, 200 | MEDepersonalization, 201 | SIMDataDownload 202 | } 203 | 204 | /// 205 | /// For the straightforward case of simple MS-to-SC short message 206 | /// transfer. No interworking is performed. 207 | /// 208 | public enum NoInterworking : byte 209 | { 210 | SmeToSmeProtocol 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /GSMCommServer/Server/SmsSender.cs: -------------------------------------------------------------------------------- 1 | using GsmComm.GsmCommunication; 2 | using GsmComm.Interfaces; 3 | using GsmComm.PduConverter; 4 | using System; 5 | using System.Threading; 6 | 7 | /// 8 | /// Implements a remotable object to send SMS messages. 9 | /// 10 | namespace GsmComm.Server 11 | { 12 | public class SmsSender : MarshalByRefObject, ISmsSender 13 | { 14 | private GsmCommMain comm; 15 | 16 | private bool disposed; 17 | 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | /// The COM port to connect to. 22 | /// The baud rate to use. 23 | /// The communictaion timeout. 24 | public SmsSender(string portName, int baudRate, int timeout) 25 | { 26 | this.disposed = false; 27 | this.comm = new GsmCommMain(portName, baudRate, timeout); 28 | this.ConnectEvents(); 29 | try 30 | { 31 | this.comm.Open(); 32 | } 33 | catch (Exception exception) 34 | { 35 | this.DisconnectEvents(); 36 | this.comm = null; 37 | throw; 38 | } 39 | } 40 | 41 | private void comm_MessageSendComplete(object sender, MessageEventArgs e) 42 | { 43 | if (this.MessageSendComplete != null) 44 | { 45 | string userDataText = e.Pdu.UserDataText; 46 | string empty = string.Empty; 47 | if (e.Pdu is SmsSubmitPdu) 48 | { 49 | empty = (e.Pdu as SmsSubmitPdu).DestinationAddress; 50 | } 51 | MessageSendEventArgs messageSendEventArg = new MessageSendEventArgs(userDataText, empty, this.GetIdentityName()); 52 | this.MessageSendComplete(this, messageSendEventArg); 53 | } 54 | } 55 | 56 | private void comm_MessageSendFailed(object sender, MessageErrorEventArgs e) 57 | { 58 | if (this.MessageSendFailed != null) 59 | { 60 | string userDataText = e.Pdu.UserDataText; 61 | string empty = string.Empty; 62 | if (e.Pdu is SmsSubmitPdu) 63 | { 64 | empty = (e.Pdu as SmsSubmitPdu).DestinationAddress; 65 | } 66 | MessageSendErrorEventArgs messageSendErrorEventArg = new MessageSendErrorEventArgs(userDataText, empty, e.Exception, this.GetIdentityName()); 67 | this.MessageSendFailed(this, messageSendErrorEventArg); 68 | } 69 | } 70 | 71 | private void comm_MessageSendStarting(object sender, MessageEventArgs e) 72 | { 73 | if (this.MessageSendStarting != null) 74 | { 75 | string userDataText = e.Pdu.UserDataText; 76 | string empty = string.Empty; 77 | if (e.Pdu is SmsSubmitPdu) 78 | { 79 | empty = (e.Pdu as SmsSubmitPdu).DestinationAddress; 80 | } 81 | MessageSendEventArgs messageSendEventArg = new MessageSendEventArgs(userDataText, empty, this.GetIdentityName()); 82 | this.MessageSendStarting(this, messageSendEventArg); 83 | } 84 | } 85 | 86 | private void ConnectEvents() 87 | { 88 | this.comm.MessageSendStarting += new GsmCommMain.MessageEventHandler(this.comm_MessageSendStarting); 89 | this.comm.MessageSendComplete += new GsmCommMain.MessageEventHandler(this.comm_MessageSendComplete); 90 | this.comm.MessageSendFailed += new GsmCommMain.MessageErrorEventHandler(this.comm_MessageSendFailed); 91 | } 92 | 93 | private void DisconnectEvents() 94 | { 95 | this.comm.MessageSendStarting -= new GsmCommMain.MessageEventHandler(this.comm_MessageSendStarting); 96 | this.comm.MessageSendComplete -= new GsmCommMain.MessageEventHandler(this.comm_MessageSendComplete); 97 | this.comm.MessageSendFailed -= new GsmCommMain.MessageErrorEventHandler(this.comm_MessageSendFailed); 98 | } 99 | 100 | private string GetIdentityName() 101 | { 102 | return Thread.CurrentPrincipal.Identity.Name; 103 | } 104 | 105 | /// 106 | /// Determines how long the remoting object lives. 107 | /// 108 | /// Always null so that the object lives forever. 109 | public override object InitializeLifetimeService() 110 | { 111 | return null; 112 | } 113 | 114 | /// 115 | /// Sends an SMS message. 116 | /// 117 | /// The message to send. 118 | /// The destination (phone number) to which the message should be sent. 119 | public void SendMessage(string message, string destination) 120 | { 121 | lock (this) 122 | { 123 | if (!this.disposed) 124 | { 125 | SmsSubmitPdu smsSubmitPdu = new SmsSubmitPdu(message, destination); 126 | this.comm.SendMessage(smsSubmitPdu); 127 | } 128 | else 129 | { 130 | throw new ObjectDisposedException("SmsSender"); 131 | } 132 | } 133 | } 134 | 135 | /// 136 | /// Sends an SMS message. 137 | /// 138 | /// The message to send. 139 | /// The destination (phone number) to which the message should be sent. 140 | /// Specifies if the message should be sent as Unicode. 141 | public void SendMessage(string message, string destination, bool unicode) 142 | { 143 | SmsSubmitPdu smsSubmitPdu; 144 | lock (this) 145 | { 146 | if (!this.disposed) 147 | { 148 | if (!unicode) 149 | { 150 | smsSubmitPdu = new SmsSubmitPdu(message, destination); 151 | } 152 | else 153 | { 154 | smsSubmitPdu = new SmsSubmitPdu(message, destination, 8); 155 | } 156 | this.comm.SendMessage(smsSubmitPdu); 157 | } 158 | else 159 | { 160 | throw new ObjectDisposedException("SmsSender"); 161 | } 162 | } 163 | } 164 | 165 | /// 166 | /// Stops the SMS sender and releases its resources. 167 | /// 168 | public void Shutdown() 169 | { 170 | if (!this.disposed) 171 | { 172 | this.comm.Close(); 173 | this.DisconnectEvents(); 174 | this.disposed = true; 175 | } 176 | } 177 | 178 | /// 179 | /// The event that occurs after a successful message transfer. 180 | /// 181 | public event MessageSendEventHandler MessageSendComplete; 182 | 183 | /// 184 | /// The event that occurs after a failed message transfer. 185 | /// 186 | public event MessageSendErrorEventHandler MessageSendFailed; 187 | 188 | /// 189 | /// The event that occurs immediately before transferring a new message. 190 | /// 191 | public event MessageSendEventHandler MessageSendStarting; 192 | } 193 | } -------------------------------------------------------------------------------- /PDUConverter/GsmComm.PduConverter/SmsSubmitMessageFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /// 4 | /// Represents the the first octet of an SMS-SUBMIT-PDU. 5 | /// 6 | namespace GsmComm.PduConverter 7 | { 8 | public class SmsSubmitMessageFlags : OutgoingMessageFlags 9 | { 10 | private const byte TP_MTI_SMS_Submit = 1; 11 | 12 | private const byte TP_RD = 4; 13 | 14 | private const byte TP_VPF_Enhanced = 8; 15 | 16 | private const byte TP_VPF_Relative = 16; 17 | 18 | private const byte TP_VPF_Absolute = 24; 19 | 20 | private const byte TP_SRR = 32; 21 | 22 | private const byte TP_UDHI = 64; 23 | 24 | private const byte TP_RP = 128; 25 | 26 | private bool rejectDuplicates; 27 | 28 | private ValidityPeriodFormat validityPeriodFormat; 29 | 30 | private bool requestStatusReport; 31 | 32 | private bool userDataHeaderPresent; 33 | 34 | private bool replyPathExists; 35 | 36 | /// 37 | /// Gets the message type, always returns . 38 | /// 39 | public override OutgoingMessageType MessageType 40 | { 41 | get 42 | { 43 | return OutgoingMessageType.SmsSubmit; 44 | } 45 | } 46 | 47 | /// 48 | /// Gets or sets if the SC should reject duplicate messages. 49 | /// 50 | public bool RejectDuplicates 51 | { 52 | get 53 | { 54 | return this.rejectDuplicates; 55 | } 56 | set 57 | { 58 | this.rejectDuplicates = value; 59 | } 60 | } 61 | 62 | /// 63 | /// Gets or sets if a reply path exists. 64 | /// 65 | public bool ReplyPathExists 66 | { 67 | get 68 | { 69 | return this.replyPathExists; 70 | } 71 | set 72 | { 73 | this.replyPathExists = value; 74 | } 75 | } 76 | 77 | /// 78 | /// Gets or sets if s status report should be requested. 79 | /// 80 | public bool RequestStatusReport 81 | { 82 | get 83 | { 84 | return this.requestStatusReport; 85 | } 86 | set 87 | { 88 | this.requestStatusReport = value; 89 | } 90 | } 91 | 92 | /// 93 | /// Gets or sets if a user data header is present. 94 | /// 95 | public bool UserDataHeaderPresent 96 | { 97 | get 98 | { 99 | return this.userDataHeaderPresent; 100 | } 101 | set 102 | { 103 | this.userDataHeaderPresent = value; 104 | } 105 | } 106 | 107 | /// 108 | /// Gets or sets the validity period format. 109 | /// 110 | public ValidityPeriodFormat ValidityPeriodFormat 111 | { 112 | get 113 | { 114 | return this.validityPeriodFormat; 115 | } 116 | set 117 | { 118 | this.validityPeriodFormat = value; 119 | } 120 | } 121 | 122 | /// 123 | /// Initializes a new instance of the class. 124 | /// 125 | /// 126 | /// Default settings are: 127 | /// 128 | /// 129 | /// ReplyPathExists = false 130 | /// 131 | /// 132 | /// UserDataHeaderPresent = false 133 | /// 134 | /// 135 | /// RequestStatusReport = false 136 | /// 137 | /// 138 | /// ValidityPeriodFormat = ValidityPeriodFormat.Unspecified 139 | /// 140 | /// 141 | /// RejectDuplicates = false 142 | /// 143 | /// 144 | /// MessageType = OutgoingMessageType.SmsSubmit 145 | /// 146 | /// 147 | /// 148 | public SmsSubmitMessageFlags() 149 | { 150 | this.rejectDuplicates = false; 151 | this.validityPeriodFormat = ValidityPeriodFormat.Unspecified; 152 | this.requestStatusReport = false; 153 | this.userDataHeaderPresent = false; 154 | this.replyPathExists = false; 155 | } 156 | 157 | /// 158 | /// Initializes a new instance of the MessageFlags class with a 159 | /// predefined data byte. 160 | /// 161 | public SmsSubmitMessageFlags(byte flags) 162 | { 163 | this.FromByte(flags); 164 | } 165 | 166 | /// 167 | /// Fills the object with values from the data byte. 168 | /// 169 | /// The byte value. 170 | protected override void FromByte(byte b) 171 | { 172 | OutgoingMessageType outgoingMessageType = OutgoingMessageType.SmsSubmit; 173 | if ((b & 1) > 0) 174 | { 175 | outgoingMessageType = OutgoingMessageType.SmsSubmit; 176 | } 177 | if (outgoingMessageType == OutgoingMessageType.SmsSubmit) 178 | { 179 | this.rejectDuplicates = (b & 4) > 0; 180 | this.validityPeriodFormat = ValidityPeriodFormat.Unspecified; 181 | if ((b & 24) > 0) 182 | { 183 | this.validityPeriodFormat = ValidityPeriodFormat.Absolute; 184 | } 185 | if ((b & 16) > 0) 186 | { 187 | this.validityPeriodFormat = ValidityPeriodFormat.Relative; 188 | } 189 | if ((b & 8) > 0) 190 | { 191 | this.validityPeriodFormat = ValidityPeriodFormat.Enhanced; 192 | } 193 | this.requestStatusReport = (b & 32) > 0; 194 | this.userDataHeaderPresent = (b & 64) > 0; 195 | this.replyPathExists = (b & 128) > 0; 196 | return; 197 | } 198 | else 199 | { 200 | throw new ArgumentException("Not an SMS-SUBMIT message."); 201 | } 202 | } 203 | 204 | /// 205 | /// Returns the byte equivalent of this instance. 206 | /// 207 | /// The byte value. 208 | public override byte ToByte() 209 | { 210 | byte num = 0; 211 | num = (byte)(num | 1); 212 | if (this.rejectDuplicates) 213 | { 214 | num = (byte)(num | 4); 215 | } 216 | ValidityPeriodFormat validityPeriodFormat = this.validityPeriodFormat; 217 | switch (validityPeriodFormat) 218 | { 219 | case ValidityPeriodFormat.Relative: 220 | { 221 | num = (byte)(num | 16); 222 | break; 223 | } 224 | case ValidityPeriodFormat.Absolute: 225 | { 226 | num = (byte)(num | 24); 227 | break; 228 | } 229 | case ValidityPeriodFormat.Enhanced: 230 | { 231 | num = (byte)(num | 8); 232 | break; 233 | } 234 | } 235 | if (this.requestStatusReport) 236 | { 237 | num = (byte)(num | 32); 238 | } 239 | if (this.userDataHeaderPresent) 240 | { 241 | num = (byte)(num | 64); 242 | } 243 | if (this.replyPathExists) 244 | { 245 | num = (byte)(num | 128); 246 | } 247 | return num; 248 | } 249 | 250 | /// 251 | /// Returns the string equivalent of this instance. 252 | /// 253 | public override string ToString() 254 | { 255 | byte num = this.ToByte(); 256 | return num.ToString(); 257 | } 258 | } 259 | } --------------------------------------------------------------------------------