示例#1
0
        /// <summary>
        /// Gets PDU from stream, parses
        /// </summary>
        /// <param name="pdu">PDU to handle</param>
        private void PduHandler(string pdu)
        {
            string response = string.Empty;

            Events.LogChannelEvent(channel_name, "Receiving [" + Common.command_id.Values[Common.command_id.IndexOfKey(uint.Parse(pdu.Substring(8, 8), System.Globalization.NumberStyles.HexNumber))] + "]", debug ? pdu : "");

            switch (Common.command_id.Values[Common.command_id.IndexOfKey(uint.Parse(pdu.Substring(8, 8), System.Globalization.NumberStyles.HexNumber))])
            {
            case "generic_nack":
                // they do not understand my command
                // may be a bug in my pdu
                break;

            case "bind_transceiver_resp":
                var bind_transceiver = new BindTransceiverResp(pdu);
                commands_queue.Remove(bind_transceiver.sequence_number);
                if (bind_transceiver.command_status != 0)
                {
                    Events.LogChannelEvent(channel_name, "Error: " + Common.command_status[bind_transceiver.command_status].description);
                    if (!is_server)
                    {
                        // try to reconnect
                        Thread.Sleep(reconnectDelay);
                        Task.Run(() => { Gate.Clients[channel_name].Connect(); });
                    }
                }
                break;

            case "bind_transmitter_resp":
                var bind_transmitter = new BindTransmitterResp(pdu);
                commands_queue.Remove(bind_transmitter.sequence_number);
                if (bind_transmitter.command_status != 0)
                {
                    Events.LogChannelEvent(channel_name, "Error: " + Common.command_id[bind_transmitter.command_status]);

                    if (!is_server)
                    {
                        Thread.Sleep(reconnectDelay);
                        Task.Run(() => { Gate.Clients[channel_name].Connect(); });
                    }
                }

                break;

            case "bind_receiver_resp":
                var bind_receiver = new BindReceiverResp(pdu);
                commands_queue.Remove(bind_receiver.sequence_number);
                if (bind_receiver.command_status != 0)
                {
                    Events.LogChannelEvent(channel_name, "Error: " + Common.command_id[bind_receiver.command_status]);
                    Quit();

                    if (!is_server)
                    {
                        Thread.Sleep(reconnectDelay);
                        Task.Run(() => { Gate.Clients[channel_name].Connect(); });
                    }
                }

                break;

            case "submit_sm":
                var submit_sm_s      = new SubmitSm(pdu);
                var submit_sm_resp_s = new SubmitSmResp();

                submit_sm_resp_s.MessageID       = Guid.NewGuid().ToString("n");
                submit_sm_resp_s.sequence_number = submit_sm_s.sequence_number;
                response = submit_sm_resp_s.Encode();

                Events.LogChannelEvent(channel_name, "Message received from " + submit_sm_s.Sender + " to " + submit_sm_s.Recipient);
                Events.LogChannelEvent(channel_name, "Sending [submit_sm_resp]");
                SendPDU(response);

                if (submit_sm_s.isMultipart)
                {
                    int parts = 0;
                    lock (multipart_messages)
                    {
                        multipart_messages.Add(submit_sm_s.MultipartMessage);

                        foreach (Common.MultipartMessage mm in multipart_messages)
                        {
                            if (mm.reference == submit_sm_s.MultipartMessage.reference)
                            {
                                parts++;
                            }
                        }
                    }
                    if (parts == submit_sm_s.MultipartMessage.num_of_parts)
                    {
                        var for_remove    = new List <Common.MultipartMessage>();
                        var short_message = new StringBuilder();
                        var str           = new string[parts];
                        lock (multipart_messages)
                        {
                            foreach (Common.MultipartMessage mm in multipart_messages)
                            {
                                if (mm.reference == submit_sm_s.MultipartMessage.reference)
                                {
                                    for_remove.Add(mm);
                                    try
                                    {
                                        str[mm.part_num - 1] = mm.short_message;
                                    }
                                    catch (Exception e1)
                                    {
                                        Events.LogEvent(LogEvent.Level.Error, channel_name + " - " + e1 + "  " + pdu);
                                    }
                                }
                            }

                            foreach (Common.MultipartMessage k in for_remove)
                            {
                                multipart_messages.Remove(k);
                            }
                        }
                        // can be required
                        // short_message.Append("(" + submit_sm_s.MultipartMessage.reference.ToString() + ") ");
                        try
                        {
                            for (int k = 0; k < parts; k++)
                            {
                                short_message.Append(str[k]);
                            }
                            submit_sm_s.Body = short_message.ToString();
                        }
                        catch (Exception e1)
                        {
                            Events.LogEvent(LogEvent.Level.Error, channel_name + " - " + e1 + "  " + pdu);
                        }

                        Events.LogNewMessageEvent(channel_name, submit_sm_resp_s.MessageID, submit_sm_s.Sender, submit_sm_s.Recipient, submit_sm_s.Body, submit_sm_s.BodyFormat, submit_sm_s.RegisteredDelivery);
                    }
                }
                else
                {
                    Events.LogNewMessageEvent(channel_name, submit_sm_resp_s.MessageID, submit_sm_s.Sender, submit_sm_s.Recipient, submit_sm_s.Body, submit_sm_s.BodyFormat, submit_sm_s.RegisteredDelivery);
                }
                break;

            case "submit_sm_resp":
                try
                {
                    var submit_sm_resp = new SubmitSmResp(pdu);
                    if (submitted_messages.ContainsKey(submit_sm_resp.sequence_number))
                    {
                        var submitSmRespMessageId = "";
                        if (!string.IsNullOrEmpty(submit_sm_resp.MessageID))
                        {
                            submitSmRespMessageId = submit_sm_resp.MessageID;
                        }

                        if (submit_sm_resp.command_status == 0)
                        {
                            Events.LogMessageChangeStatusEvent(
                                submitted_messages[submit_sm_resp.sequence_number].message_id, Common.MessageStatus.sent, submitSmRespMessageId);
                        }
                        else
                        {
                            if (Common.command_status.ContainsKey(submit_sm_resp.command_status))
                            {
                                Events.LogMessageChangeStatusEvent(
                                    submitted_messages[submit_sm_resp.sequence_number].message_id,
                                    Common.MessageStatus.rejected, submitSmRespMessageId);
                            }
                            else
                            {
                                Events.LogMessageChangeStatusEvent(
                                    submitted_messages[submit_sm_resp.sequence_number].message_id,
                                    Common.MessageStatus.sent);
                            }
                        }
                        submitted_messages.Remove(submit_sm_resp.sequence_number);
                    }

                    if (submit_sm_resp.command_status != 0)
                    {
                        Events.LogChannelEvent(channel_name, "Error sending: " + submit_sm_resp.command_status);
                    }
                    else
                    {
                        Events.LogChannelEvent(channel_name, "Message reference: " + submit_sm_resp.MessageID);
                    }
                }
                catch (Exception e1)
                {
                    Events.LogEvent(LogEvent.Level.Error, channel_name + " - " + e1.ToString());
                }
                break;

            case "enquire_link":
                var enquire_link      = new EnquireLink(pdu);
                var enquire_link_resp = new EnquireLinkResp();

                enquire_link_resp.sequence_number = enquire_link.sequence_number;
                response = enquire_link_resp.Encode();
                SendPDU(response);
                Events.LogChannelEvent(channel_name, "Sending [enquire_link_resp]", debug ? response : "");
                break;

            case "enquire_link_resp":
                var enquire_link_resp_o = new EnquireLinkResp(pdu);
                commands_queue.Remove(enquire_link_resp_o.sequence_number);
                break;

            case "deliver_sm":
                DeliverSm deliver_sm;
                try
                {
                    deliver_sm        = new DeliverSm(pdu);
                    deliver_sm.Is8bit = use8bit;
                    deliver_sm.Decode();
                }
                catch (CommandLengthException)
                {
                    Events.LogEvent(LogEvent.Level.Error, channel_name + ". Command length error.");
                    break;
                }
                catch (Exception e1)
                {
                    Events.LogEvent(LogEvent.Level.Error, channel_name + ". Error: " + e1.Message);
                    break;
                }

                // Send Resp
                var deliver_sm_resp = new DeliverSmResp();
                deliver_sm_resp.MessageID       = Guid.NewGuid().ToString("n");
                deliver_sm_resp.sequence_number = deliver_sm.sequence_number;
                response = deliver_sm_resp.Encode();

                Events.LogChannelEvent(channel_name, "Sending [deliver_sm_resp]", debug ? response : "");
                SendPDU(response);

                // Multipart message
                if (deliver_sm.isMultipart)
                {
                    int parts = 0;
                    lock (multipart_messages)
                    {
                        multipart_messages.Add(deliver_sm.MultipartMessage);


                        foreach (Common.MultipartMessage mm in multipart_messages)
                        {
                            if (mm.reference == deliver_sm.MultipartMessage.reference)
                            {
                                parts++;
                            }
                        }
                    }
                    if (parts == deliver_sm.MultipartMessage.num_of_parts)
                    {
                        List <Common.MultipartMessage> for_remove = new List <Common.MultipartMessage>();
                        StringBuilder short_message = new StringBuilder();
                        string[]      str           = new string[parts];

                        lock (multipart_messages)
                        {
                            foreach (Common.MultipartMessage mm in multipart_messages)
                            {
                                if (mm.reference == deliver_sm.MultipartMessage.reference)
                                {
                                    for_remove.Add(mm);
                                    try
                                    {
                                        str[mm.part_num - 1] = mm.short_message;
                                    }
                                    catch (Exception e1)
                                    {
                                        Events.LogEvent(LogEvent.Level.Error, channel_name + " - " + e1.ToString() + "  " + pdu);
                                    }
                                }
                            }

                            foreach (Common.MultipartMessage k in for_remove)
                            {
                                multipart_messages.Remove(k);
                            }
                        }

                        try
                        {
                            for (int k = 0; k < parts; k++)
                            {
                                short_message.Append(str[k]);
                            }
                            deliver_sm.Body = short_message.ToString();
                        }
                        catch (Exception e1)
                        {
                            Events.LogEvent(LogEvent.Level.Error, channel_name + " - " + e1.ToString() + "  " + pdu);
                        }
                    }
                    else
                    {
                        // Multipart message is not built yet, wait for the rest
                        break;
                    }
                }

                // Delivery report
                if (deliver_sm.ESMClass == 4)
                {
                    Events.LogChannelEvent(channel_name, "Message ref: " + deliver_sm.Reference + " " + deliver_sm.DeliveryStatus, debug ? pdu : "");
                    if (deliver_sm.DeliveryStatus.ToUpper() == "DELIVR")
                    {
                        Events.LogMessageDeliverReportEvent(deliver_sm.Reference, Common.MessageStatus.delivered_ACK_received);
                    }
                    if (deliver_sm.DeliveryStatus.ToUpper() == "EXPIRE")
                    {
                        Events.LogMessageDeliverReportEvent(deliver_sm.Reference, Common.MessageStatus.ACK_expired);
                    }
                    if (deliver_sm.DeliveryStatus.ToUpper() == "UNKNOW")
                    {
                        Events.LogMessageDeliverReportEvent(deliver_sm.Reference, Common.MessageStatus.unknown_recipient);
                    }
                    if (deliver_sm.DeliveryStatus.ToUpper() == "ACCEPT")
                    {
                        Events.LogMessageDeliverReportEvent(deliver_sm.Reference, Common.MessageStatus.received_routed);
                    }
                    if (deliver_sm.DeliveryStatus.ToUpper() == "REJECT")
                    {
                        Events.LogMessageDeliverReportEvent(deliver_sm.Reference, Common.MessageStatus.rejected);
                    }
                    if (deliver_sm.DeliveryStatus.ToUpper() == "UNDELI")
                    {
                        Events.LogMessageDeliverReportEvent(deliver_sm.Reference, Common.MessageStatus.message_undeliverable);
                    }

                    break;
                }

                // Log message
                Events.LogChannelEvent(channel_name, "Message received from " + deliver_sm.Sender + " to " + deliver_sm.Recipient, debug ? pdu : "");
                Events.LogNewMessageEvent(channel_name, deliver_sm_resp.MessageID, deliver_sm.Sender, deliver_sm.Recipient, deliver_sm.Body, deliver_sm.BodyFormat, deliver_sm.RegisteredDelivery);

                break;

            case "deliver_sm_resp":
                try
                {
                    var deliver_sm_resp2 = new DeliverSmResp(pdu);
                    if (submitted_messages.ContainsKey(deliver_sm_resp2.sequence_number))
                    {
                        var deliverSmRespMessageId = "";
                        if (!string.IsNullOrEmpty(deliver_sm_resp2.MessageID))
                        {
                            deliverSmRespMessageId = deliver_sm_resp2.MessageID;
                        }

                        if (deliver_sm_resp2.command_status == 0)
                        {
                            if (registered_delivery != 1 && submitted_messages[deliver_sm_resp2.sequence_number].registered_delivery)
                            {
                                Events.LogMessageChangeStatusEvent(submitted_messages[deliver_sm_resp2.sequence_number].message_id, Common.MessageStatus.sent, deliverSmRespMessageId);
                            }
                        }
                        else
                        {
                            if (Common.command_status.ContainsKey(deliver_sm_resp2.command_status))
                            {
                                Events.LogMessageChangeStatusEvent(
                                    submitted_messages[deliver_sm_resp2.sequence_number].message_id,
                                    Common.MessageStatus.rejected, deliverSmRespMessageId);
                            }
                            else
                            {
                                Events.LogMessageChangeStatusEvent(
                                    submitted_messages[deliver_sm_resp2.sequence_number].message_id,
                                    Common.MessageStatus.sent, deliverSmRespMessageId);
                            }
                        }
                        submitted_messages.Remove(deliver_sm_resp2.sequence_number);
                    }

                    if (deliver_sm_resp2.command_status != 0)
                    {
                        Events.LogChannelEvent(channel_name, "Error sending: " + deliver_sm_resp2.command_status);
                    }
                    else
                    {
                        Events.LogChannelEvent(channel_name, "Message reference: " + deliver_sm_resp2.MessageID);
                    }
                }
                catch (Exception e1)
                {
                    Events.LogEvent(LogEvent.Level.Error, channel_name + " - " + e1);
                }
                break;

            case "data_sm":
                var data_sm_s      = new DataSm(pdu);
                var data_sm_resp_s = new DataSmResp();

                data_sm_resp_s.MessageID       = Guid.NewGuid().ToString("n");
                data_sm_resp_s.sequence_number = data_sm_s.sequence_number;
                response = data_sm_resp_s.Encode();

                Events.LogChannelEvent(channel_name, "Message received from " + data_sm_s.Sender + " to " + data_sm_s.Recipient, debug ? pdu : "");
                Events.LogChannelEvent(channel_name, "Sending [data_sm_resp]");
                SendPDU(response);

                Events.LogNewMessageEvent(channel_name, data_sm_resp_s.MessageID, data_sm_s.Sender, data_sm_s.Recipient, data_sm_s.Body, data_sm_s.BodyFormat, data_sm_s.RegisteredDelivery);

                break;

            case "data_sm_resp":
                try
                {
                    var data_sm_resp = new DataSmResp(pdu);
                    if (submitted_messages.ContainsKey(data_sm_resp.sequence_number))
                    {
                        var dataSmRespMessageId = "";
                        if (!string.IsNullOrEmpty(data_sm_resp.MessageID))
                        {
                            dataSmRespMessageId = data_sm_resp.MessageID;
                        }

                        if (data_sm_resp.command_status == 0)
                        {
                            if (registered_delivery != 1 && submitted_messages[data_sm_resp.sequence_number].registered_delivery)
                            {
                                Events.LogMessageChangeStatusEvent(submitted_messages[data_sm_resp.sequence_number].message_id, Common.MessageStatus.sent, dataSmRespMessageId);
                            }
                        }
                        else
                        {
                            if (Common.command_status.ContainsKey(data_sm_resp.command_status))
                            {
                                Events.LogMessageChangeStatusEvent(submitted_messages[data_sm_resp.sequence_number].message_id, Common.MessageStatus.rejected, dataSmRespMessageId);
                            }
                            else
                            {
                                Events.LogMessageChangeStatusEvent(submitted_messages[data_sm_resp.sequence_number].message_id, Common.MessageStatus.sent, dataSmRespMessageId);
                            }
                        }
                        submitted_messages.Remove(data_sm_resp.sequence_number);
                    }

                    if (data_sm_resp.command_status != 0)
                    {
                        Events.LogChannelEvent(channel_name, "Error sending: " + data_sm_resp.command_status);
                    }
                    else
                    {
                        Events.LogChannelEvent(channel_name, "Message reference: " + data_sm_resp.MessageID);
                    }
                }
                catch (Exception e1)
                {
                    Events.LogEvent(LogEvent.Level.Error, channel_name + ". error: " + e1);
                }
                break;

            case "unbind":
                var unbind      = new Unbind(pdu);
                var unbind_resp = new UnbindResp();
                unbind_resp.sequence_number = unbind.sequence_number;
                response = unbind_resp.Encode();
                SendPDU(response);

                Events.LogChannelEvent(channel_name, "Sending [unbind_resp]", debug ? response : "");

                enquire_link_timer.Stop();
                timeout_timer.Stop();

                tcp_stream.Close();
                tcp_client.Close();

                Gate.Clients.Remove(channel_name);
                Gate.Servers.Remove(channel_name);

                Events.LogChannelEvent(channel_name, "Disconnected");

                // should reconnect if it was a client
                if (!is_server)
                {
                    Thread.Sleep(10000);
                    Task.Run(() => { Gate.Clients[channel_name].Connect(); });
                }
                break;

            case "unbind_resp":
                ;
                break;

            default:
                Events.LogChannelEvent(channel_name, "Receiving unknown command", pdu);
                break;
            }
        }
示例#2
0
文件: Server.cs 项目: rl0pez/smsgate
        /// <summary>
        /// Handles incoming request
        /// </summary>
        private static void CreateConnection()
        {
            TcpClient tcp_client;

            try { tcp_client = tcp_server.AcceptTcpClient(); }
            catch { return; }

            try
            {
                if (tcp_client != null && tcp_client.Connected)
                {
                    NetworkStream ns;
                    ns = tcp_client.GetStream();
                    byte[] buffer     = new byte[Common.MAX_RECEIVE_LENGTH];
                    byte[] ByteLength = new byte[4];
                    byte[] BytePDU;
                    int    PDULength;
                    string pdu;
                    string systemId;
                    string response = "";
                    int    l        = 0;

                    string ip       = ((IPEndPoint)tcp_client.Client.RemoteEndPoint).Address.ToString();
                    int    authCode = 0;

                    ns.Read(buffer, 0, buffer.Length);
                    ByteLength[0] = buffer[0]; ByteLength[1] = buffer[1];
                    ByteLength[2] = buffer[2]; ByteLength[3] = buffer[3];
                    PDULength     = int.Parse(Common.ConvertByteArrayToHexString(ByteLength), System.Globalization.NumberStyles.HexNumber);

                    BytePDU = new byte[PDULength];
                    for (int k = 0; k < PDULength; k++)
                    {
                        try
                        {
                            BytePDU[k] = buffer[l++];
                        }
                        catch
                        {
                            ns.Close();
                            tcp_client.Close();
                            throw new CommandLengthException(String.Empty);
                        }
                    }
                    pdu = Common.ConvertByteArrayToHexString(BytePDU);

                    switch (Common.command_id.Values[Common.command_id.IndexOfKey(uint.Parse(pdu.Substring(8, 8), System.Globalization.NumberStyles.HexNumber))])
                    {
                    case "bind_receiver":
                        var bind_receiver      = new BindReceiver(pdu);
                        var bind_receiver_resp = new BindReceiverResp();

                        authCode = Authenticate(bind_receiver.SystemID, bind_receiver.Password, ip);
                        systemId = bind_receiver.SystemID;
                        bind_receiver_resp.SystemID        = Common.SMSC_ID;
                        bind_receiver_resp.command_status  = (uint)authCode;
                        bind_receiver_resp.sequence_number = bind_receiver.sequence_number;
                        response = bind_receiver_resp.Encode();

                        break;

                    case "bind_transmitter":
                        var bind_transmitter      = new BindTransmitter(pdu);
                        var bind_transmitter_resp = new BindTransmitterResp();

                        authCode = Authenticate(bind_transmitter.SystemID, bind_transmitter.Password, ip);
                        systemId = bind_transmitter.SystemID;
                        bind_transmitter_resp.SystemID        = Common.SMSC_ID;
                        bind_transmitter_resp.command_status  = (uint)authCode;
                        bind_transmitter_resp.sequence_number = bind_transmitter.sequence_number;
                        response = bind_transmitter_resp.Encode();

                        break;

                    case "bind_transceiver":
                        var bind_transceiver      = new BindTransceiver(pdu);
                        var bind_transceiver_resp = new BindTransceiverResp();

                        authCode = Authenticate(bind_transceiver.SystemID, bind_transceiver.Password, ip);
                        systemId = bind_transceiver.SystemID;
                        bind_transceiver_resp.SystemID        = Common.SMSC_ID;
                        bind_transceiver_resp.command_status  = (uint)authCode;
                        bind_transceiver_resp.sequence_number = bind_transceiver.sequence_number;
                        response = bind_transceiver_resp.Encode();

                        break;

                    default:
                        // Something unknown was received
                        ns.Close();
                        tcp_client.Close();
                        return;
                    }
                    byte[] msg;
                    msg = Common.ConvertHexStringToByteArray(response);

                    ns.Write(msg, 0, msg.Length);

                    if (authCode != 0)
                    {
                        // Events.LogEvent(LogEvent.Level.Error, "Received [" + Common.command_id.Values[Common.command_id.IndexOfKey(uint.Parse(pdu.Substring(8, 8), System.Globalization.NumberStyles.HexNumber))] + "]");
                        // Events.LogEvent(LogEvent.Level.Error, "Error connecting: " + Common.command_status[(uint)authCode].description);
                        ns.Close();
                        tcp_client.Close();
                        return;
                    }

                    Server esme = Gate.Servers.Values.FirstOrDefault(server => server.system_id == systemId);
                    esme.Events.LogChannelEvent(esme.channel_name, "Received [" + Common.command_id.Values[Common.command_id.IndexOfKey(uint.Parse(pdu.Substring(8, 8), System.Globalization.NumberStyles.HexNumber))] + "]");

                    esme.Events.LogChannelEvent(esme.channel_name, "Logged in successfully IP: " + ip);

                    esme.tcp_client = tcp_client;
                    esme.tcp_stream = tcp_client.GetStream();
                    esme.is_server  = true;
                    esme.connected  = true;
                    esme.enquire_link_timer.Start();
                    esme.timeout_timer.Start();
                    esme.Receive();
                }
            }
            catch (Exception)
            {
                return;
            }
        }