Пример #1
0
        internal bool SendPdu(ServiceClass service, string message, DicomObject pdu)
        {
            //Logging.Log("Association.SendPdu");

            try
            {
                if (State == State.Aborted)
                {
                    throw AbortException;
                }

                MemoryStream memory = new MemoryStream();
                pdu.Write(memory);

                NetworkStream output = new NetworkStream(socket, FileAccess.Write, false);

                byte[] bytes = memory.ToArray();
                Dump(">> " + message, bytes);

                if (service != null)
                {
                    service.LastMessage = null;
                }
                output.Write(bytes, 0, (int)memory.Length);

                State = (State != State.Closing) ? State.Waiting : State;
            }
            catch (Exception ex)
            {
                Logging.Log(LogLevel.Error, ex.Message);
                throw;
            }
            return(true);
        }
Пример #2
0
 protected ServiceClass(ServiceClass other)
 {
     this.association = null;
     this.uid         = other.uid;
     foreach (string syntax in other.syntaxes)
     {
         this.syntaxes.Add((string)syntax.Clone());
     }
     completeEvent = new System.Threading.AutoResetEvent(false);
     this.id       = 0xff;
     this.reason   = PCIReason.Undefined;
     this.role     = other.role;
 }
Пример #3
0
        internal bool SendPdu(ServiceClass service, MessageType type, string message, DataSet dicom)
        {
            bool result = true;

            if (State == State.Aborted)
            {
                throw AbortException;
            }
            if (service != null)
            {
                service.LastMessage = null;
            }

            dicom.Part10Header      = false;
            dicom.TransferSyntaxUID = MessageControl.IsCommand(type) ? Syntax.ImplicitVrLittleEndian : service.Syntaxes[0];

            MemoryStream memory = new MemoryStream();

            dicom.Write(memory);
            byte[] bytes = memory.ToArray();

            PresentationDataPdu   pdu = null;
            PresentationDataValue pdv = null;

            int index     = 0;
            int remaining = (int)memory.Length;
            int size      = this.packetSize - 128;

            State = (State != State.Closing) ? State.Waiting : State;
            while (remaining > this.packetSize && result)
            {
                pdu = new PresentationDataPdu(service.Syntaxes[0]);
                pdv = new PresentationDataValue(service.PresentationContextId, service.Syntaxes[0], type, bytes, index, size);
                pdu.Values.Add(pdv);

                result = Send(message, pdu);

                index     += size;
                remaining -= size;
            }

            if (result)
            {
                pdu = new PresentationDataPdu(service.Syntaxes[0]);
                pdv = new PresentationDataValue(service.PresentationContextId, service.Syntaxes[0], type + 2, bytes, index, remaining);
                pdu.Values.Add(pdv);
                result = Send(message, pdu);
            }

            return(result);
        }
Пример #4
0
        internal bool SendDataPdu(ServiceClass service, string message, DataSet dicom)
        {
            bool result = true;

            dicom.Part10Header      = false;
            dicom.TransferSyntaxUID = service.Syntaxes[0];

            MemoryStream memory = new MemoryStream();

            dicom.Write(memory);
            byte[] bytes = memory.ToArray();

            PresentationDataPdu   pdu = null;
            PresentationDataValue pdv = null;

            int index     = 0;
            int remaining = (int)memory.Length;
            int size      = this.packetSize - 128;

            while (remaining > this.packetSize && result)
            {
                pdu = new PresentationDataPdu(service.Syntaxes[0]);
                pdv = new PresentationDataValue(service.PresentationContextId, service.Syntaxes[0], MessageType.DataSet, bytes, index, size);
                pdu.Values.Add(pdv);

                result = SendPdu(service, message, pdu);

                index     += size;
                remaining -= size;
            }

            if (result)
            {
                pdu = new PresentationDataPdu(service.Syntaxes[0]);
                pdv = new PresentationDataValue(service.PresentationContextId, service.Syntaxes[0], MessageType.LastDataSet, bytes, index, remaining);
                pdu.Values.Add(pdv);
                result = SendPdu(service, message, pdu);
            }

            return(result);
        }
Пример #5
0
 public void AddService(ServiceClass service)
 {
     services.Add(service);
 }
Пример #6
0
        private void PduDataReceived(byte[] pdu)
        {
            //Logging.Log("PduDataReceived {0}", pdu);
            //Dump("<< P-DATA-TF", pdu);

            // TODO this must be able to handle multiple pdvs

            string       syntax  = Syntax.ImplicitVrLittleEndian;
            ServiceClass service = FindServiceClass(pdu[10]);

            if (service != null)
            {
                syntax = service.Syntaxes[0];
            }

            // TODO currently assuming that a Command comes in a single pdu
            // TODO all DataSet fragments are combined into a single Message

            if (MessageControl.IsDataSet((MessageType)pdu[11]))
            {
                //Logging.Log("dataset");
                if (MessageControl.IsNotLast((MessageType)pdu[11]))
                {
                    //Logging.Log("not last fragment");
                    if (file == null)
                    {
                        file = new FileStream(Guid.NewGuid().ToString() + ".tmp", FileMode.Create, FileAccess.ReadWrite);
                        //Dump("PduDataReceived1 ...", pdu);
                    }
                    else
                    {
                        //Logging.Log("Receiving {0} bytes", pdu.Length - 12);
                    }
                    file.Write(pdu, 12, pdu.Length - 12);
                    return;
                }
                else
                {
                    //Logging.Log("last fragment");
                    if (file != null)
                    {
                        Dump("PduDataReceived2 ...", pdu);

                        file.Write(pdu, 12, pdu.Length - 12);
                        file.Flush();

                        DataSet dicom = new DataSet();
                        dicom.TransferSyntaxUID = syntax;

                        file.Seek(0, SeekOrigin.Begin);
                        dicom.Read(file);

                        if (service != null)
                        {
                            try
                            {
                                service.LastMessage = new Message(dicom);
                                ((IPresentationDataSink)service).OnData(MessageType.LastDataSet, service.LastMessage);
                            }
                            catch (Exception ex)
                            {
                                Logging.Log(LogLevel.Error, "Exception in OnData for SOPClassUId={0}, {1}", service.SOPClassUId, ex.Message);
                            }
                        }

                        file.Close();
                        File.Delete(file.Name);
                        file = null;
                        return;
                    }
                }
            }

            // parse response
            MemoryStream        memory   = new MemoryStream(pdu, 0, pdu.Length);
            PresentationDataPdu response = new PresentationDataPdu(syntax);

            response.Read(memory);

            response.Dump();

            foreach (PresentationDataValue pdv in response.Values)
            {
                service = FindServiceClass(pdv.context);
                if (service != null && service is IPresentationDataSink)
                {
                    service.LastMessage = new Message(pdv.Dicom);
                    ((IPresentationDataSink)service).OnData(pdv.control, service.LastMessage);
                }
            }
        }
Пример #7
0
        private void AssociateRequestReceived(byte[] pdu)
        {
            Dump("<< A-ASSOCIATE-RQ", pdu);
//#if DEBUG
//            if (number != 0) Console.WriteLine("association {0,4} opened", number);
//#endif
            bool reject = true;
            // parse request
            MemoryStream        memory  = new MemoryStream(pdu, 0, pdu.Length);
            AssociateRequestPdu request = new AssociateRequestPdu();

            request.Read(memory);

            //request.Dump();
            CallingAeTitle = request.calling.TrimEnd();
            AssociateRequestPdu accept = new AssociateRequestPdu(ProtocolDataUnit.Type.A_ASSOCIATE_AC, request.called, request.calling);

            // record as much as we can about the caller
            IPEndPoint lep = socket.LocalEndPoint as IPEndPoint;

            if (lep != null)
            {
                scp = new ApplicationEntity(request.calling.TrimEnd(" ".ToCharArray()), lep.Address, lep.Port);
            }
            else
            {
                scp = new ApplicationEntity(request.calling.TrimEnd(" ".ToCharArray()), 0);
            }
            IPEndPoint rep = socket.RemoteEndPoint as IPEndPoint;

            if (rep != null)
            {
                scu = new ApplicationEntity(request.calling.TrimEnd(" ".ToCharArray()), rep.Address, rep.Port);
                CallingAeIpAddress = rep.Address;
            }
            else
            {
                scu = new ApplicationEntity(request.calling.TrimEnd(" ".ToCharArray()), 0);
            }

            foreach (Item item in request.fields)
            {
                switch ((ItemType)item.Type)
                {
                case ItemType.ApplicationItem:
                    ApplicationContextItem aci = item as ApplicationContextItem;
                    accept.fields.Add(aci);
                    break;

                case ItemType.PresentationContextItemRQ:
                    PresentationContextItem temp     = item as PresentationContextItem;
                    PresentationContextItem response = new PresentationContextItem((byte)ItemType.PresentationContextItemAC, temp.PresentationContextId);

                    SyntaxItem   abs      = ((SyntaxItem)temp.fields[0]);
                    ServiceClass service  = null;
                    SyntaxItem   transfer = null;
                    for (int n = 1; n < temp.fields.Count; n++)
                    {
                        transfer = temp.fields[n] as SyntaxItem;
                        service  = FindServiceClass(abs.Syntax, transfer.Syntax);
                        if (service != null)
                        {
                            break;
                        }
                    }
                    if (service == null)
                    {
                        response.PciReason = PCIReason.AbstractSyntaxNotSupported;
                        Logging.Log("SCU Reject PresentationContext={0} abstract={1}", temp.PresentationContextId, Reflection.GetName(typeof(SOPClass), abs.Syntax));
                    }
                    else
                    {
                        service.PresentationContextId = temp.PresentationContextId;
                        service.Syntaxes.Clear();
                        service.Syntaxes.Add(transfer.Syntax);

                        service.PciReason = response.PciReason = PCIReason.Accepted;
                        Logging.Log("SCU Accept PresentationContext={0} abstract={1} transfer={2}", service.PresentationContextId, Reflection.GetName(typeof(SOPClass), abs.Syntax), Reflection.GetName(typeof(Syntax), transfer.Syntax));
                        reject = false;
                    }

                    response.fields.Add(transfer);
                    accept.fields.Add(response);

                    break;

                case ItemType.UserInformationItem:
                    UserInfoItem uii   = item as UserInfoItem;
                    int          count = uii.fields.Count;
                    // note: this is editing the sent UserInfoItem in place rather
                    // than making a new object, make a new object
                    for (int n = count - 1; n >= 0; n--)
                    {
                        Item field = uii.fields[n];
                        switch ((ItemType)field.Type)
                        {
                        case ItemType.MaximumLengthSubItem:
                        {
                            MaximumLengthItem length = field as MaximumLengthItem;
                            packetSize = length.PacketSize;
                        }
                        break;

                        case ItemType.ImplementationClassUidSubItem:
                        {
                            SyntaxItem implementation = field as SyntaxItem;
                            implementation.Syntax = ImplementationClassUid;
                        }
                        break;

                        case ItemType.ImplementationVersionNameSubItem:
                        {
                            SyntaxItem implementation = field as SyntaxItem;
                            implementation.Syntax = version;
                        }
                        break;

                        case ItemType.AsynchronousOperationsWindowSubItem:
                        case ItemType.ScuScpRoleSubItem:
                        default:
                            uii.fields.RemoveAt(n);
                            break;
                        }
                    }
                    accept.fields.Add(uii);
                    break;

                default:
                    break;
                }
            }
            if (reject)
            {
                Abort(AbortSource.ServiceProvider, AbortReason.NoReasonGiven);
            }
            else
            {
                Send("A-ASSOCIATE-AC", accept);
            }
        }
Пример #8
0
        private void OnOpening(byte [] pdu)
        {
            // parse response
            MemoryStream memory = new MemoryStream(pdu, 0, pdu.Length);

            switch ((ProtocolDataUnit.Type)pdu[0])
            {
            case ProtocolDataUnit.Type.A_ASSOCIATE_AC:
            {
                Dump("<< A-ASSOCIATE-AC", pdu);

                AssociateRequestPdu response = new AssociateRequestPdu();
                response.Read(memory);
                //response.Dump();

                foreach (Item item in response.fields)
                {
                    Logging.Log(item.Dump());
                    switch ((ItemType)item.Type)
                    {
                    case ItemType.PresentationContextItemAC:
                        PresentationContextItem pci = item as PresentationContextItem;
                        SyntaxItem   transfer       = ((SyntaxItem)pci.fields[0]);
                        ServiceClass service        = FindServiceClass(pci.PresentationContextId);
                        if (service != null)
                        {
                            service.Syntaxes.Clear();
                            service.PciReason = pci.PciReason;
                            if (service.PciReason == PCIReason.Accepted)
                            {
                                service.Syntaxes.Add(transfer.Syntax);
                                Logging.Log("SCP Accept PresentationContext={0} class={1} syntax={2}", pci.PresentationContextId, Reflection.GetName(typeof(SOPClass), service.SOPClassUId), Reflection.GetName(typeof(Syntax), transfer.Syntax));
                            }
                            else
                            {
                                Logging.Log("SCP Reject PresentationContext={0} class={1} syntax={2}", pci.PresentationContextId, Reflection.GetName(typeof(SOPClass), service.SOPClassUId), Reflection.GetName(typeof(Syntax), transfer.Syntax));
                            }
                        }
                        else
                        {
                            Logging.Log(LogLevel.Error, "SCP unknown PresentationContext={0} reason={1} class={2} syntax={3}", pci.PresentationContextId, pci.PciReason, Reflection.GetName(typeof(SOPClass), service.SOPClassUId), Reflection.GetName(typeof(Syntax), transfer.Syntax));
                        }
                        break;

                    case ItemType.UserInformationItem:
                        UserInfoItem uii   = item as UserInfoItem;
                        int          count = uii.fields.Count;
                        for (int n = count - 1; n >= 0; n--)
                        {
                            Item field = uii.fields[n];
                            if ((ItemType)field.Type == ItemType.MaximumLengthSubItem)
                            {
                                MaximumLengthItem length = field as MaximumLengthItem;
                                packetSize = length.PacketSize;
                            }
                        }
                        break;
                    }
                }

                State = State.Open;
            }
            break;

            case ProtocolDataUnit.Type.A_ASSOCIATE_RJ:
            {
                AssociateRejectPdu response = new AssociateRejectPdu();
                response.Read(memory);
                State = State.Closed;

                Dump("<< A-ASSOCIATE-RJ", pdu);
            }
            break;

            default:
                State = State.Closed;
                Dump(String.Format("<< UNEXPECTED PDU(0x{0:x4})", pdu[0]), pdu);
                break;
            }

            if (completeEvent != null)
            {
                completeEvent.Set();
            }
        }
Пример #9
0
 /// <summary>
 /// Adds a Service to the Association.
 /// </summary>
 /// <param name="service"></param>
 public void AddService(ServiceClass service)
 {
     service.Association = this;
     services.Add(service);
 }