private AssociateRequestPdu GetAssociationRequestPdu() { //Logging.Log("Association.GetAssociationRequestPdu"); AssociateRequestPdu pdu = new AssociateRequestPdu(ProtocolDataUnit.Type.A_ASSOCIATE_RQ, scp.Title, scu.Title); ApplicationContextItem ac = new ApplicationContextItem("1.2.840.10008.3.1.1.1"); pdu.fields.Add(ac); foreach (ServiceClass service in services) { service.PresentationContextId = index; index += 2; PresentationContextItem pci = new PresentationContextItem((byte)ItemType.PresentationContextItemRQ, service.PresentationContextId); pdu.fields.Add(pci); SyntaxItem abs = new SyntaxItem((byte)ItemType.AbstractSyntaxSubItem, service.SOPClassUId); pci.fields.Add(abs); foreach (string syntax in service.Syntaxes) { SyntaxItem trx = new SyntaxItem((byte)ItemType.TransferSyntaxSubItem, syntax); pci.fields.Add(trx); } } UserInfoItem user = new UserInfoItem(); pdu.fields.Add(user); MaximumLengthItem ml = new MaximumLengthItem(MaxPduSize); user.fields.Add(ml); SyntaxItem impl = new SyntaxItem((byte)ItemType.ImplementationClassUidSubItem, "1.2.840.113564.3.2"); user.fields.Add(impl); AsynchronousOperationsWindowItem operations = new AsynchronousOperationsWindowItem(); user.fields.Add(operations); foreach (ServiceClass service in services) { ScpScuRoleSelectionItem role = new ScpScuRoleSelectionItem(service.SOPClassUId, service.Role); user.fields.Add(role); } SyntaxItem implver = new SyntaxItem((byte)ItemType.ImplementationVersionNameSubItem, "not specified"); user.fields.Add(implver); return(pdu); }
public override long Read(Stream stream) { long bytes = 0; if (stream.CanRead) { EndianBinaryReader reader = new EndianBinaryReader(stream, Endian.Big); long start = stream.Position; type = (ProtocolDataUnit.Type)reader.ReadByte(); reserved1 = reader.ReadByte(); length = reader.ReadInt32(); version = reader.ReadInt16(); reserved2 = reader.ReadInt16(); byte[] temp = reader.ReadBytes(16); called = System.Text.Encoding.ASCII.GetString(temp); temp = reader.ReadBytes(16); calling = System.Text.Encoding.ASCII.GetString(temp); reserved3 = reader.ReadBytes(32); byte next = reader.PeekByte(); Item item = null; while (next == 0x10 || next == 0x20 || next == 0x21 || next == 0x50) { switch (next) { case 0x10: item = new ApplicationContextItem(); break; case 0x20: case 0x21: item = new PresentationContextItem(next); break; case 0x50: item = new UserInfoItem(); break; } fields.Add(item); item.Read(stream); if (stream.Position >= stream.Length) { break; } next = reader.PeekByte(); } if (fields.Count < 3) { throw new Exception("Ill-formed Protocol Data Unit."); } bytes = stream.Position - start; } return(bytes); }
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); } }
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(); } }