/// <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; } }
/// <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; } }