network

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 25, 2026 License: MIT Imports: 16 Imported by: 0

README

network — DICOM Networking for Go

The network package implements the DICOM Upper Layer Protocol (DICOM PS3.7/PS3.8), providing both client (SCU) and server (SCP) capabilities. It is the Go equivalent of Python's pynetdicom, redesigned with native Go concurrency (goroutines, channels, context.Context).

Features

  • All 11 DIMSE services: C-ECHO, C-STORE, C-FIND, C-MOVE, C-GET, N-EVENT-REPORT, N-GET, N-SET, N-ACTION, N-CREATE, N-DELETE
  • SCU (client): Connect to PACS, modalities, and other DICOM nodes
  • SCP (server): Accept associations with goroutine-per-connection concurrency
  • 80+ Storage SOP Classes: CT, MR, US, PET, NM, RT, XR, CR, DX, MG, VL, SR, waveforms, encapsulated documents
  • 15 Transfer Syntaxes: All standard uncompressed and compressed (JPEG, JPEG-LS, JPEG 2000, RLE)
  • TLS encryption: For HIPAA-compliant communication
  • Extended negotiation: Async operations, SCP/SCU role selection, user identity (username/password, Kerberos, SAML, JWT)
  • Handler system: Composable handlers — embed BaseHandler and override only what you need
  • File-format agnostic: Works with any DICOM source (.dcm, .ima, DICOMDIR, raw/extensionless)
  • 80 tests with race detection, including full end-to-end integration tests

Quick Start

C-ECHO (Verification / Ping)
ctx := context.Background()

scu := network.NewSCU(network.SCUConfig{
    CallingAE: "MY_APP",
    CalledAE:  "PACS",
    Address:   "pacs.hospital.com:11112",
})

err := scu.Associate(ctx, network.DefaultVerificationContexts())
if err != nil {
    log.Fatal(err)
}
defer scu.Release(ctx)

err = scu.Echo(ctx)  // Success = server is reachable
C-STORE (Send DICOM Data)
// dataset can come from any source: .dcm, .ima, DICOMDIR, in-memory
err := scu.Associate(ctx, nil) // nil = propose all default contexts
if err != nil {
    log.Fatal(err)
}
defer scu.Release(ctx)

err = scu.Store(ctx, dataset)
C-FIND (Query)
// Build query
query := dataset.NewDataset()
query.Add(dataelem.NewDataElement(tag.New(0x0008, 0x0052), dataelem.CS, []byte("STUDY")))
query.Add(dataelem.NewDataElement(tag.New(0x0010, 0x0010), dataelem.PN, []byte("Smith*")))
query.Add(dataelem.NewDataElement(tag.New(0x0010, 0x0020), dataelem.LO, []byte{})) // request Patient ID

// Results stream on a Go channel
results, err := scu.Find(ctx, query)
if err != nil {
    log.Fatal(err)
}

for result := range results {
    if result.Err != nil {
        log.Printf("error: %v", result.Err)
        break
    }
    fmt.Println(result.DataSet) // each matching study
}
C-MOVE (Retrieve)
err = scu.Move(ctx, queryDataset, "DEST_AE")
SCP Server (Receive Files)
scp := network.NewSCP(network.SCPConfig{
    AETitle: "MY_SCP",
    Port:    11112,
})

scp.SetHandler(&network.StorageHandler{
    OnStore: func(ctx context.Context, sopClass, sopInstance string, ds *dataset.Dataset) uint16 {
        // Save to disk, database, forward to another PACS, etc.
        log.Printf("Received %s", sopInstance)
        return network.StatusSuccess
    },
})

// Blocks. Each incoming association runs in its own goroutine.
// Cancel ctx for graceful shutdown.
log.Fatal(scp.ListenAndServe(ctx))
TLS Encrypted Communication
// SCU with TLS
transport, err := network.DialTLS(ctx, "pacs:2762", 30*time.Second, &network.TLSConfig{
    CertFile:   "client.crt",
    KeyFile:    "client.key",
    ServerName: "pacs.hospital.com",
})

// SCP with TLS
ln, err := network.ListenTLS("0.0.0.0:2762", &network.TLSConfig{
    CertFile: "server.crt",
    KeyFile:  "server.key",
})

Handler Patterns

The Handler interface defines methods for all DIMSE services. Embed BaseHandler and override only what you need:

Echo-Only Server
scp.SetHandler(&network.EchoHandler{})
Storage Server with Callback
scp.SetHandler(&network.StorageHandler{
    OnStore: func(ctx context.Context, sopClass, sopInstance string, ds *dataset.Dataset) uint16 {
        // Works with ALL DICOM modalities: CT, MR, US, XR, PET, RT, SR, etc.
        // Works with ALL file types: .dcm, .ima, DICOMDIR, raw DICOM
        return network.StatusSuccess
    },
})
Query/Retrieve Server
scp.SetHandler(&network.QueryRetrieveHandler{
    OnFind: func(ctx context.Context, sopClass string, query *dataset.Dataset) ([]*dataset.Dataset, error) {
        // Search your database, return matching results
        return results, nil
    },
    OnMove: func(ctx context.Context, sopClass, dest string, query *dataset.Dataset) error {
        // Send matching instances to the destination AE
        return nil
    },
})
Modality Worklist Server
scp.SetHandler(&network.WorklistHandler{
    OnWorklist: func(ctx context.Context, query *dataset.Dataset) ([]*dataset.Dataset, error) {
        // Return scheduled procedures for the requesting modality
        return procedures, nil
    },
})
Composite Handler (Mix & Match)
h := network.NewCompositeHandler()
h.SetStoreHandler(myStoreHandler)
h.SetFindHandler(myFindHandler)
scp.SetHandler(h)
Custom Handler (Full Control)
type MyHandler struct {
    network.BaseHandler // provides defaults for unimplemented methods
}

func (h *MyHandler) HandleCStore(ctx context.Context, req *network.CStoreRequest) (*network.CStoreResponse, error) {
    log.Printf("Received %s from %s", req.AffectedSOPInstance, req.AffectedSOPClass)
    // Custom processing...
    return &network.CStoreResponse{
        MessageIDRespondedTo: req.MessageID,
        AffectedSOPClass:     req.AffectedSOPClass,
        AffectedSOPInstance:  req.AffectedSOPInstance,
        Status:               network.StatusSuccess,
    }, nil
}

func (h *MyHandler) HandleNCreate(ctx context.Context, req *network.NCreateRequest) (*network.NCreateResponse, error) {
    // Handle MPPS N-CREATE, Print N-CREATE, etc.
    return &network.NCreateResponse{
        MessageIDRespondedTo: req.MessageID,
        AffectedSOPClass:     req.AffectedSOPClass,
        AffectedSOPInstance:  req.AffectedSOPInstance,
        Status:               network.StatusSuccess,
    }, nil
}

CLI Tools

The library includes CLI tools equivalent to pynetdicom's command-line utilities:

# Build
go build -o dicom .

# Verification (ping)
./dicom echoscu pacs.hospital.com:11112

# Send DICOM files (any format: .dcm, .ima, etc.)
./dicom storescu -aec PACS pacs:11112 study/*.dcm

# Receive DICOM files
./dicom storescp -port 11112 -output ./received/

# Query for studies
./dicom findscu -patient-name "Smith*" -level STUDY pacs:11112

# Retrieve studies
./dicom movescu -dest MY_SCP -study 1.2.3.4 pacs:11112

Architecture

network/
├── doc.go                  # Package documentation
├── config.go               # NetworkConfig, SCUConfig, SCPConfig
├── errors.go               # PDUError, AssociationError, TimeoutError, CommunicationError, DIMSEError
├── pdu.go                  # PDU types and encoding/decoding (A-ASSOCIATE, P-DATA, A-RELEASE, A-ABORT)
├── transport.go            # TCP connection management with context-aware timeouts
├── tls.go                  # TLS encryption (DialTLS, ListenTLS)
├── presentation.go         # Transfer syntax UIDs, presentation context negotiation
├── sopclass.go             # 80+ Storage SOP Classes, Q/R, Worklist, MPPS, Print
├── extended.go             # Extended negotiation (async ops, role selection, user identity)
├── association.go          # Association state machine (DICOM Part 8)
├── dimse.go                # C-DIMSE message types (C-ECHO, C-STORE, C-FIND, C-MOVE, C-GET)
├── ndimse.go               # N-DIMSE message types (N-EVENT-REPORT, N-GET, N-SET, N-ACTION, N-CREATE, N-DELETE)
├── handlers.go             # Handler interfaces + BaseHandler, EchoHandler, StorageHandler, etc.
├── scu.go                  # Service Class User (client)
├── scp.go                  # Service Class Provider (server)
├── *_test.go               # 80 tests including integration tests
└── README.md               # This file

Supported SOP Classes

Storage (80+)

CT, Enhanced CT, MR, Enhanced MR, MR Spectroscopy, US, Enhanced US, CR, DX, Digital Mammography, Intra-oral XR, Secondary Capture (all multi-frame variants), Nuclear Medicine, PET, Enhanced PET, RT Image/Dose/Structure/Plan/Beams/Ion, XA, Enhanced XA, XRF, Enhanced XRF, 3D Angiographic, Breast Tomosynthesis, VL Endoscopic/Microscopic/Photographic, Video, Ophthalmic Photography/Tomography, Whole Slide Microscopy, ECG (12-lead, General, Ambulatory), Hemodynamic, Cardiac EP, Arterial Pulse, Respiratory, Audio, EMG, EEG, Body Position, Basic/Enhanced/Comprehensive SR, Procedure Log, CAD SR (Mammography, Chest, Colon), Key Object Selection, Radiation Dose SR, Presentation States (Grayscale, Color, Pseudo-Color, Blending), Segmentation, Surface Segmentation, Parametric Map, Raw Data, Spatial Registration/Fiducials, Encapsulated PDF/CDA/STL/OBJ/MTL

Query/Retrieve

Patient Root Q/R (Find, Move, Get), Study Root Q/R (Find, Move, Get)

Worklist & Procedure Step

Modality Worklist (MWL) Find, Modality Performed Procedure Step (N-CREATE, N-SET), Unified Procedure Step (Push, Watch, Pull, Event, Query)

Print Management

Basic Film Session, Basic Film Box, Basic Grayscale/Color Image Box, Print Job, Grayscale/Color Print Management, Printer, Printer Configuration Retrieval

Other

Storage Commitment (Push Model), Instance Availability Notification, Substance Administration Logging, Hanging Protocol/Color Palette/Implant Template Storage

Comparison with pynetdicom

Feature pynetdicom go-dicom/network
Language Python Go
Concurrency threading goroutines (lightweight, scalable)
Result streaming callbacks Go channels
Cancellation N/A context.Context (timeouts, graceful shutdown)
Association handling thread pool goroutine-per-association
C-DIMSE 5 services 5 services
N-DIMSE 6 services 6 services
TLS ssl.SSLContext crypto/tls
CLI tools 7 5 (echoscu, storescu, storescp, findscu, movescu)
Event system evt_handlers Handler interface with BaseHandler embedding
Testing pytest go test -race (80 tests, 0 race conditions)

Testing

# Unit + integration tests
go test -v ./network/...

# With race detection
go test -race ./network/...

# Integration tests only (real TCP SCP+SCU)
go test -v -run TestIntegration ./network/...

# Specific test
go test -v -run TestIntegrationCStoreRoundTrip ./network/...

Status Codes

The package defines standard DICOM status codes:

Constant Value Meaning
StatusSuccess 0x0000 Operation completed successfully
StatusPending 0xFF00 More results to follow
StatusPendingWarning 0xFF01 More results, with warnings
StatusCancel 0xFE00 Operation cancelled
StatusWarning 0x0001 Coercion warning
StatusOutOfResources 0xA700 Out of resources
StatusUnableToProcess 0xC000 Unable to process
StatusMoveDestUnknown 0xA801 Move destination unknown
StatusClassNotSupported 0x0122 SOP Class not supported

References

Documentation

Overview

Package network provides DICOM networking capabilities implementing the DICOM Upper Layer Protocol (DICOM Part 8). It enables communication with PACS, modalities, and other DICOM-compliant systems over TCP.

The package provides both client (SCU - Service Class User) and server (SCP - Service Class Provider) implementations supporting the following DIMSE services:

  • C-ECHO: Verification (ping) to test connectivity
  • C-STORE: Send/receive DICOM objects
  • C-FIND: Query for DICOM objects
  • C-MOVE: Retrieve DICOM objects via sub-operations
  • C-GET: Retrieve DICOM objects on the same association

SCU (Client) Usage:

scu, err := network.NewSCU(network.SCUConfig{
    CallingAE: "MY_APP",
    CalledAE:  "PACS",
    Address:   "pacs.hospital.com:11112",
})
if err != nil {
    log.Fatal(err)
}
defer scu.Release(ctx)

// Verification
err = scu.Echo(ctx)

// Store a dataset
err = scu.Store(ctx, dataset)

// Query
results, err := scu.Find(ctx, queryDataset)
for result := range results {
    fmt.Println(result)
}

SCP (Server) Usage:

scp, err := network.NewSCP(network.SCPConfig{
    AETitle: "MY_SCP",
    Port:    11112,
})
scp.SetHandler(&MyHandler{})
err = scp.ListenAndServe(ctx)

Index

Constants

View Source
const (
	// DefaultMaxPDUSize is the default maximum PDU size (16 KB).
	DefaultMaxPDUSize = 16384

	// DefaultPort is the default DICOM port.
	DefaultPort = 11112

	// DefaultAETitle is the default Application Entity title.
	DefaultAETitle = "GODICOM"

	// DefaultARTIMTimeout is the ARTIM timer timeout (Association Request/Reject/Release Timer).
	DefaultARTIMTimeout = 30 * time.Second

	// DefaultDIMSETimeout is the default timeout for DIMSE operations.
	DefaultDIMSETimeout = 60 * time.Second

	// DefaultNetworkTimeout is the default TCP connection timeout.
	DefaultNetworkTimeout = 30 * time.Second

	// MaxMaxPDUSize is the absolute maximum PDU size allowed.
	MaxMaxPDUSize = 0 // 0 means no limit (per DICOM standard, negotiated)

	// MinPDUSize is the minimum PDU size required by the standard.
	MinPDUSize = 4096

	// ProtocolVersion is the DICOM Upper Layer protocol version.
	ProtocolVersion uint16 = 1
)
View Source
const (
	CommandCStoreRQ  uint16 = 0x0001
	CommandCStoreRSP uint16 = 0x8001
	CommandCGetRQ    uint16 = 0x0010
	CommandCGetRSP   uint16 = 0x8010
	CommandCFindRQ   uint16 = 0x0020
	CommandCFindRSP  uint16 = 0x8020
	CommandCMoveRQ   uint16 = 0x0021
	CommandCMoveRSP  uint16 = 0x8021
	CommandCEchoRQ   uint16 = 0x0030
	CommandCEchoRSP  uint16 = 0x8030
	CommandCCancelRQ uint16 = 0x0FFF
)

DIMSE command field values (DICOM Part 7, Annex E).

View Source
const (
	StatusSuccess              uint16 = 0x0000
	StatusCancel               uint16 = 0xFE00
	StatusPending              uint16 = 0xFF00
	StatusPendingWarning       uint16 = 0xFF01
	StatusWarning              uint16 = 0x0001 // Coercion of Data Elements warning
	StatusOutOfResources       uint16 = 0xA700
	StatusUnableToProcess      uint16 = 0xC000
	StatusDataSetNotMatch      uint16 = 0xA900
	StatusMoveDestUnknown      uint16 = 0xA801
	StatusClassNotSupported    uint16 = 0x0122
	StatusDuplicateSOPInstance uint16 = 0x0111
)

DICOM status values.

View Source
const (
	CommandDataSetTypeNull    uint16 = 0x0101 // No dataset present
	CommandDataSetTypePresent uint16 = 0x0000 // Dataset present (any value != 0x0101 would work per spec, but 0 is unused)
)

DICOM command dataset type values.

View Source
const (
	PriorityMedium uint16 = 0x0000
	PriorityHigh   uint16 = 0x0001
	PriorityLow    uint16 = 0x0002
)

DICOM priority values.

View Source
const (
	ItemTypeAsyncOperationsWindow  byte = 0x53
	ItemTypeSCPSCURoleSelection    byte = 0x54
	ItemTypeSOPClassExtended       byte = 0x56
	ItemTypeSOPClassCommonExtended byte = 0x57
	ItemTypeUserIdentity           byte = 0x58
	ItemTypeUserIdentityAC         byte = 0x59
)

Extended negotiation sub-item types within User Information.

View Source
const (
	CommandNEventReportRQ  uint16 = 0x0100
	CommandNEventReportRSP uint16 = 0x8100
	CommandNGetRQ          uint16 = 0x0110
	CommandNGetRSP         uint16 = 0x8110
	CommandNSetRQ          uint16 = 0x0120
	CommandNSetRSP         uint16 = 0x8120
	CommandNActionRQ       uint16 = 0x0130
	CommandNActionRSP      uint16 = 0x8130
	CommandNCreateRQ       uint16 = 0x0140
	CommandNCreateRSP      uint16 = 0x8140
	CommandNDeleteRQ       uint16 = 0x0150
	CommandNDeleteRSP      uint16 = 0x8150
)

N-DIMSE command field values (DICOM Part 7, Annex E).

View Source
const (
	PDUTypeAssociateRQ byte = 0x01
	PDUTypeAssociateAC byte = 0x02
	PDUTypeAssociateRJ byte = 0x03
	PDUTypeDataTF      byte = 0x04
	PDUTypeReleaseRQ   byte = 0x05
	PDUTypeReleaseRP   byte = 0x06
	PDUTypeAbort       byte = 0x07
)

PDU type constants (DICOM Part 8, Section 9.3).

View Source
const (
	ItemTypeApplicationContext    byte = 0x10
	ItemTypePresentationContextRQ byte = 0x20
	ItemTypePresentationContextAC byte = 0x21
	ItemTypeAbstractSyntax        byte = 0x30
	ItemTypeTransferSyntax        byte = 0x40
	ItemTypeUserInformation       byte = 0x50
	ItemTypeMaxPDULength          byte = 0x51
	ItemTypeImplementationClass   byte = 0x52
	ItemTypeImplementationVersion byte = 0x55
)

Item type constants for sub-items within PDUs.

View Source
const (
	RJResultRejectedPermanent byte = 1
	RJResultRejectedTransient byte = 2
)

A-ASSOCIATE-RJ result values.

View Source
const (
	RJSourceServiceUser                 byte = 1
	RJSourceServiceProviderACSE         byte = 2
	RJSourceServiceProviderPresentation byte = 3
)

A-ASSOCIATE-RJ source values.

View Source
const (
	AbortSourceServiceUser     byte = 0
	AbortSourceServiceProvider byte = 2
)

A-ABORT source values.

View Source
const (
	PCResultAcceptance                 byte = 0
	PCResultUserRejection              byte = 1
	PCResultNoReason                   byte = 2
	PCResultAbstractSyntaxNotSupported byte = 3
	PCResultTransferSyntaxNotSupported byte = 4
)

Presentation context result values.

View Source
const (
	VerificationSOPClassUID = "1.2.840.10008.1.1"

	// Storage SOP Classes
	CTImageStorageUID               = "1.2.840.10008.5.1.4.1.1.2"
	EnhancedCTImageStorageUID       = "1.2.840.10008.5.1.4.1.1.2.1"
	MRImageStorageUID               = "1.2.840.10008.5.1.4.1.1.4"
	EnhancedMRImageStorageUID       = "1.2.840.10008.5.1.4.1.1.4.1"
	USImageStorageUID               = "1.2.840.10008.5.1.4.1.1.6.1"
	SecondaryCaptureImageStorageUID = "1.2.840.10008.5.1.4.1.1.7"
	XRayAngiographicImageStorageUID = "1.2.840.10008.5.1.4.1.1.12.1"
	DigitalXRayImageStorageUID      = "1.2.840.10008.5.1.4.1.1.1.1"
	CRImageStorageUID               = "1.2.840.10008.5.1.4.1.1.1"

	// Query/Retrieve SOP Classes
	PatientRootQueryRetrieveFind = "1.2.840.10008.5.1.4.1.2.1.1"
	PatientRootQueryRetrieveMove = "1.2.840.10008.5.1.4.1.2.1.2"
	PatientRootQueryRetrieveGet  = "1.2.840.10008.5.1.4.1.2.1.3"
	StudyRootQueryRetrieveFind   = "1.2.840.10008.5.1.4.1.2.2.1"
	StudyRootQueryRetrieveMove   = "1.2.840.10008.5.1.4.1.2.2.2"
	StudyRootQueryRetrieveGet    = "1.2.840.10008.5.1.4.1.2.2.3"
)

Common DICOM SOP Class UIDs used in networking.

View Source
const (
	// Uncompressed
	ImplicitVRLittleEndianUID         = "1.2.840.10008.1.2"
	ExplicitVRLittleEndianUID         = "1.2.840.10008.1.2.1"
	DeflatedExplicitVRLittleEndianUID = "1.2.840.10008.1.2.1.99"
	ExplicitVRBigEndianUID            = "1.2.840.10008.1.2.2"

	// JPEG
	JPEGBaselineUID    = "1.2.840.10008.1.2.4.50"
	JPEGExtendedUID    = "1.2.840.10008.1.2.4.51"
	JPEGLosslessSV1UID = "1.2.840.10008.1.2.4.57"
	JPEGLosslessUID    = "1.2.840.10008.1.2.4.70"

	// JPEG-LS
	JPEGLSLosslessUID     = "1.2.840.10008.1.2.4.80"
	JPEGLSNearLosslessUID = "1.2.840.10008.1.2.4.81"

	// JPEG 2000
	JPEG2000LosslessUID                    = "1.2.840.10008.1.2.4.90"
	JPEG2000UID                            = "1.2.840.10008.1.2.4.91"
	JPEG2000Part2MultiComponentLosslessUID = "1.2.840.10008.1.2.4.92"
	JPEG2000Part2MultiComponentUID         = "1.2.840.10008.1.2.4.93"

	// JPIP
	JPIPReferencedUID        = "1.2.840.10008.1.2.4.94"
	JPIPReferencedDeflateUID = "1.2.840.10008.1.2.4.95"

	// MPEG2
	MPEG2MainProfileUID             = "1.2.840.10008.1.2.4.100"
	MPEG2MainProfileFragmentUID     = "1.2.840.10008.1.2.4.100.1"
	MPEG2MainProfileHighUID         = "1.2.840.10008.1.2.4.101"
	MPEG2MainProfileHighFragmentUID = "1.2.840.10008.1.2.4.101.1"

	// MPEG-4 AVC/H.264
	MPEG4AVCH264HighProfileUID           = "1.2.840.10008.1.2.4.102"
	MPEG4AVCH264HighProfileFragmentUID   = "1.2.840.10008.1.2.4.102.1"
	MPEG4AVCH264BDCompatibleUID          = "1.2.840.10008.1.2.4.103"
	MPEG4AVCH264BDCompatibleFragmentUID  = "1.2.840.10008.1.2.4.103.1"
	MPEG4AVCH264HighProfile2DUID         = "1.2.840.10008.1.2.4.104"
	MPEG4AVCH264HighProfile2DFragmentUID = "1.2.840.10008.1.2.4.104.1"
	MPEG4AVCH264HighProfile3DUID         = "1.2.840.10008.1.2.4.105"
	MPEG4AVCH264HighProfile3DFragmentUID = "1.2.840.10008.1.2.4.105.1"
	MPEG4AVCH264StereoHighProfileUID     = "1.2.840.10008.1.2.4.106"
	MPEG4AVCH264StereoHighFragmentUID    = "1.2.840.10008.1.2.4.106.1"

	// HEVC/H.265
	HEVCH265MainProfileUID   = "1.2.840.10008.1.2.4.107"
	HEVCH265Main10ProfileUID = "1.2.840.10008.1.2.4.108"

	// JPEG XL
	JPEGXLLosslessUID          = "1.2.840.10008.1.2.4.110"
	JPEGXLJPEGRecompressionUID = "1.2.840.10008.1.2.4.111"
	JPEGXLUID                  = "1.2.840.10008.1.2.4.112"

	// High-Throughput JPEG 2000
	HTJ2KLosslessUID              = "1.2.840.10008.1.2.4.201"
	HTJ2KLosslessRPCLUID          = "1.2.840.10008.1.2.4.202"
	HTJ2KUID                      = "1.2.840.10008.1.2.4.203"
	JPIPHTJ2KReferencedUID        = "1.2.840.10008.1.2.4.204"
	JPIPHTJ2KReferencedDeflateUID = "1.2.840.10008.1.2.4.205"

	// RLE
	RLELosslessUID = "1.2.840.10008.1.2.5"

	// SMPTE ST 2110
	SMPTEST2110UncompressedProgressiveUID = "1.2.840.10008.1.2.7.1"
	SMPTEST2110UncompressedInterlacedUID  = "1.2.840.10008.1.2.7.2"
	SMPTEST2110PCMDigitalAudioUID         = "1.2.840.10008.1.2.7.3"
)

DICOM Transfer Syntax UIDs — complete set matching pynetdicom.

View Source
const (
	ComputedRadiographyImageStorageUID         = "1.2.840.10008.5.1.4.1.1.1"
	DigitalXRayImageStorageForPresentationUID  = "1.2.840.10008.5.1.4.1.1.1.1"
	DigitalXRayImageStorageForProcessingUID    = "1.2.840.10008.5.1.4.1.1.1.1.1"
	DigitalMammographyImageStoragePresentUID   = "1.2.840.10008.5.1.4.1.1.1.2"
	DigitalMammographyImageStorageProcessUID   = "1.2.840.10008.5.1.4.1.1.1.2.1"
	DigitalIntraOralXRayImageStoragePresentUID = "1.2.840.10008.5.1.4.1.1.1.3"
	DigitalIntraOralXRayImageStorageProcessUID = "1.2.840.10008.5.1.4.1.1.1.3.1"
)

Computed Radiography and Digital X-Ray

View Source
const (
	CTImageStorageSOP                 = "1.2.840.10008.5.1.4.1.1.2"
	EnhancedCTImageStorageSOP         = "1.2.840.10008.5.1.4.1.1.2.1"
	LegacyConvertedEnhancedCTImageUID = "1.2.840.10008.5.1.4.1.1.2.2"
	MRImageStorageSOP                 = "1.2.840.10008.5.1.4.1.1.4"
	EnhancedMRImageStorageSOP         = "1.2.840.10008.5.1.4.1.1.4.1"
	MRSpectroscopyStorageUID          = "1.2.840.10008.5.1.4.1.1.4.2"
	EnhancedMRColorImageStorageUID    = "1.2.840.10008.5.1.4.1.1.4.3"
	LegacyConvertedEnhancedMRImageUID = "1.2.840.10008.5.1.4.1.1.4.4"
)

CT and MR

View Source
const (
	UltrasoundMultiFrameImageStorageRetiredUID = "1.2.840.10008.5.1.4.1.1.3"
	UltrasoundMultiFrameImageStorageUID        = "1.2.840.10008.5.1.4.1.1.3.1"
	UltrasoundImageStorageRetiredUID           = "1.2.840.10008.5.1.4.1.1.6"
	UltrasoundImageStorageSOP                  = "1.2.840.10008.5.1.4.1.1.6.1"
	EnhancedUSVolumeStorageUID                 = "1.2.840.10008.5.1.4.1.1.6.2"
	PhotoacousticImageStorageUID               = "1.2.840.10008.5.1.4.1.1.6.3"
)

Ultrasound

View Source
const (
	SecondaryCaptureImageStorageSOP            = "1.2.840.10008.5.1.4.1.1.7"
	MultiFrameSingleBitSecondaryCaptureUID     = "1.2.840.10008.5.1.4.1.1.7.1"
	MultiFrameGrayscaleByteSecondaryCaptureUID = "1.2.840.10008.5.1.4.1.1.7.2"
	MultiFrameGrayscaleWordSecondaryCaptureUID = "1.2.840.10008.5.1.4.1.1.7.3"
	MultiFrameTrueColorSecondaryCaptureUID     = "1.2.840.10008.5.1.4.1.1.7.4"
)

Secondary Capture

View Source
const (
	NuclearMedicineImageStorageRetiredUID = "1.2.840.10008.5.1.4.1.1.5"
	NuclearMedicineImageStorageUID        = "1.2.840.10008.5.1.4.1.1.20"
	PositronEmissionTomographyImageUID    = "1.2.840.10008.5.1.4.1.1.128"
	EnhancedPETImageStorageUID            = "1.2.840.10008.5.1.4.1.1.130"
	LegacyConvertedEnhancedPETImageUID    = "1.2.840.10008.5.1.4.1.1.128.1"
)

Nuclear Medicine and PET

View Source
const (
	RTImageStorageUID             = "1.2.840.10008.5.1.4.1.1.481.1"
	RTDoseStorageUID              = "1.2.840.10008.5.1.4.1.1.481.2"
	RTStructureSetStorageUID      = "1.2.840.10008.5.1.4.1.1.481.3"
	RTBeamsTreatmentRecordUID     = "1.2.840.10008.5.1.4.1.1.481.4"
	RTPlanStorageUID              = "1.2.840.10008.5.1.4.1.1.481.5"
	RTBrachyTreatmentRecordUID    = "1.2.840.10008.5.1.4.1.1.481.6"
	RTTreatmentSummaryRecordUID   = "1.2.840.10008.5.1.4.1.1.481.7"
	RTIonPlanStorageUID           = "1.2.840.10008.5.1.4.1.1.481.8"
	RTIonBeamsTreatmentRecordUID  = "1.2.840.10008.5.1.4.1.1.481.9"
	RTBeamsDeliveryInstructionUID = "1.2.840.10008.5.1.4.34.7"
)

Radiation Therapy

View Source
const (
	XRayAngiographicImageStorageSOP       = "1.2.840.10008.5.1.4.1.1.12.1"
	EnhancedXAImageStorageUID             = "1.2.840.10008.5.1.4.1.1.12.1.1"
	XRayRadiofluoroscopicImageStorageUID  = "1.2.840.10008.5.1.4.1.1.12.2"
	EnhancedXRFImageStorageUID            = "1.2.840.10008.5.1.4.1.1.12.2.1"
	XRay3DAngiographicImageStorageUID     = "1.2.840.10008.5.1.4.1.1.13.1.1"
	XRay3DCraniofacialImageStorageUID     = "1.2.840.10008.5.1.4.1.1.13.1.2"
	BreastTomosynthesisImageStorageUID    = "1.2.840.10008.5.1.4.1.1.13.1.3"
	BreastProjectionXRayImageStoragePUID  = "1.2.840.10008.5.1.4.1.1.13.1.4"
	BreastProjectionXRayImageStoragePrUID = "1.2.840.10008.5.1.4.1.1.13.1.5"
)

X-Ray Angiographic and Fluoroscopy

View Source
const (
	VLEndoscopicImageStorageUID              = "1.2.840.10008.5.1.4.1.1.77.1.1"
	VideoEndoscopicImageStorageUID           = "1.2.840.10008.5.1.4.1.1.77.1.1.1"
	VLMicroscopicImageStorageUID             = "1.2.840.10008.5.1.4.1.1.77.1.2"
	VideoMicroscopicImageStorageUID          = "1.2.840.10008.5.1.4.1.1.77.1.2.1"
	VLSlideCoordinatesMicroscopicUID         = "1.2.840.10008.5.1.4.1.1.77.1.3"
	VLPhotographicImageStorageUID            = "1.2.840.10008.5.1.4.1.1.77.1.4"
	VideoPhotographicImageStorageUID         = "1.2.840.10008.5.1.4.1.1.77.1.4.1"
	OphthalmicPhotography8BitUID             = "1.2.840.10008.5.1.4.1.1.77.1.5.1"
	OphthalmicPhotography16BitUID            = "1.2.840.10008.5.1.4.1.1.77.1.5.2"
	StereometricRelationshipStorageUID       = "1.2.840.10008.5.1.4.1.1.77.1.5.3"
	OphthalmicTomographyImageUID             = "1.2.840.10008.5.1.4.1.1.77.1.5.4"
	WideFieldOphthalmicStereoProjectionUID   = "1.2.840.10008.5.1.4.1.1.77.1.5.5"
	WideFieldOphthalmic3DCoordinatesUID      = "1.2.840.10008.5.1.4.1.1.77.1.5.6"
	OphthalmicOCTEnFaceImageUID              = "1.2.840.10008.5.1.4.1.1.77.1.5.7"
	OphthalmicOCTBscanVolumeAnalysisUID      = "1.2.840.10008.5.1.4.1.1.77.1.5.8"
	VLWholeSlideMicroscopyImageUID           = "1.2.840.10008.5.1.4.1.1.77.1.6"
	DermoscopicPhotographyImageStorageUID    = "1.2.840.10008.5.1.4.1.1.77.1.7"
	ConfocalMicroscopyImageStorageUID        = "1.2.840.10008.5.1.4.1.1.77.1.8"
	ConfocalMicroscopyTiledPyramidalImageUID = "1.2.840.10008.5.1.4.1.1.77.1.9"
)

Visible Light / Ophthalmology / Pathology / Microscopy

View Source
const (
	LensometryMeasurementsStorageUID        = "1.2.840.10008.5.1.4.1.1.78.1"
	AutorefractionMeasurementsStorageUID    = "1.2.840.10008.5.1.4.1.1.78.2"
	KeratometryMeasurementsStorageUID       = "1.2.840.10008.5.1.4.1.1.78.3"
	SubjectiveRefractionMeasurementsUID     = "1.2.840.10008.5.1.4.1.1.78.4"
	VisualAcuityMeasurementsStorageUID      = "1.2.840.10008.5.1.4.1.1.78.5"
	SpectaclePrescriptionReportStorageUID   = "1.2.840.10008.5.1.4.1.1.78.6"
	OphthalmicAxialMeasurementsStorageUID   = "1.2.840.10008.5.1.4.1.1.78.7"
	IntraocularLensCalculationsStorageUID   = "1.2.840.10008.5.1.4.1.1.78.8"
	MacularGridThicknessVolumeReportUID     = "1.2.840.10008.5.1.4.1.1.79.1"
	OphthalmicVisualFieldStaticPerimetryUID = "1.2.840.10008.5.1.4.1.1.80.1"
	OphthalmicThicknessMapStorageUID        = "1.2.840.10008.5.1.4.1.1.81.1"
	CornealTopographyMapStorageUID          = "1.2.840.10008.5.1.4.1.1.82.1"
)

Ophthalmic Measurements

View Source
const (
	IntravascularOCTImageStoragePresentUID = "1.2.840.10008.5.1.4.1.1.14.1"
	IntravascularOCTImageStorageProcessUID = "1.2.840.10008.5.1.4.1.1.14.2"
)

Intravascular OCT

View Source
const (
	RTPhysicianIntentStorageUID              = "1.2.840.10008.5.1.4.1.1.481.10"
	RTSegmentAnnotationStorageUID            = "1.2.840.10008.5.1.4.1.1.481.11"
	RTRadiationSetStorageUID                 = "1.2.840.10008.5.1.4.1.1.481.12"
	CArmPhotonElectronRadiationStorageUID    = "1.2.840.10008.5.1.4.1.1.481.13"
	TomotherapeuticRadiationStorageUID       = "1.2.840.10008.5.1.4.1.1.481.14"
	RoboticArmRadiationStorageUID            = "1.2.840.10008.5.1.4.1.1.481.15"
	RTRadiationRecordSetStorageUID           = "1.2.840.10008.5.1.4.1.1.481.16"
	RTRadiationSalvageRecordStorageUID       = "1.2.840.10008.5.1.4.1.1.481.17"
	TomotherapeuticRadiationRecordStorageUID = "1.2.840.10008.5.1.4.1.1.481.18"
	CArmPhotonElectronRadiationRecordUID     = "1.2.840.10008.5.1.4.1.1.481.19"
	RoboticArmRadiationRecordStorageUID      = "1.2.840.10008.5.1.4.1.1.481.20"
	RTRadiationSetDeliveryInstructionUID     = "1.2.840.10008.5.1.4.1.1.481.21"
	RTTreatmentPreparationStorageUID         = "1.2.840.10008.5.1.4.1.1.481.22"
	EnhancedRTImageStorageUID                = "1.2.840.10008.5.1.4.1.1.481.23"
	EnhancedContinuousRTImageStorageUID      = "1.2.840.10008.5.1.4.1.1.481.24"
	RTBrachyApplicationSetupDeliveryInstUID  = "1.2.840.10008.5.1.4.34.10"
)

Additional RT Storage

View Source
const (
	ExtensibleSRStorageUID                    = "1.2.840.10008.5.1.4.1.1.88.35"
	PlannedImagingAgentAdministrationSRUID    = "1.2.840.10008.5.1.4.1.1.88.74"
	PerformedImagingAgentAdministrationSRUID  = "1.2.840.10008.5.1.4.1.1.88.75"
	EnhancedXRayRadiationDoseSRStorageUID     = "1.2.840.10008.5.1.4.1.1.88.76"
	WaveformAnnotationSRStorageUID            = "1.2.840.10008.5.1.4.1.1.88.77"
	ContentAssessmentResultsStorageUID        = "1.2.840.10008.5.1.4.1.1.90.1"
	MicroscopyBulkSimpleAnnotationsStorageUID = "1.2.840.10008.5.1.4.1.1.91.1"
)

Additional SR / Annotations / Content

View Source
const (
	GrayscalePlanarMPRVolumetricPresentUID       = "1.2.840.10008.5.1.4.1.1.11.6"
	CompositingPlanarMPRVolumetricPresentUID     = "1.2.840.10008.5.1.4.1.1.11.7"
	AdvancedBlendingPresentationStateUID         = "1.2.840.10008.5.1.4.1.1.11.8"
	VolumeRenderingVolumetricPresentUID          = "1.2.840.10008.5.1.4.1.1.11.9"
	SegmentedVolumeRenderingVolumetricPresentUID = "1.2.840.10008.5.1.4.1.1.11.10"
	MultipleVolumeRenderingVolumetricPresentUID  = "1.2.840.10008.5.1.4.1.1.11.11"
	VariableModalityLUTSoftcopyPresentUID        = "1.2.840.10008.5.1.4.1.1.11.12"
	WaveformPresentationStateStorageUID          = "1.2.840.10008.5.1.4.1.1.9.100.1"
	WaveformAcquisitionPresentationStateUID      = "1.2.840.10008.5.1.4.1.1.9.100.2"
)

Additional Presentation State

View Source
const (
	General32bitECGWaveformStorageUID = "1.2.840.10008.5.1.4.1.1.9.1.4"
	BasicVoiceAudioWaveformStorageUID = "1.2.840.10008.5.1.4.1.1.9.4.1"
)

Additional Waveform

View Source
const (
	BasicStructuredDisplayStorageUID       = "1.2.840.10008.5.1.4.1.1.131"
	CTPerformedProcedureProtocolStorageUID = "1.2.840.10008.5.1.4.1.1.200.2"
	XAPerformedProcedureProtocolStorageUID = "1.2.840.10008.5.1.4.1.1.200.8"
	CTDefinedProcedureProtocolStorageUID   = "1.2.840.10008.5.1.4.1.1.200.1"
	ProtocolApprovalStorageUID             = "1.2.840.10008.5.1.4.1.1.200.3"
	XADefinedProcedureProtocolStorageUID   = "1.2.840.10008.5.1.4.1.1.200.7"
	InventoryStorageUID                    = "1.2.840.10008.5.1.4.1.1.201.1"
	TractographyResultsStorageUID          = "1.2.840.10008.5.1.4.1.1.66.6"
	LabelMapSegmentationStorageUID         = "1.2.840.10008.5.1.4.1.1.66.7"
	MediaStorageDirectoryStorageUID        = "1.2.840.10008.1.3.10"
)

Additional Miscellaneous Storage

View Source
const (
	TwelveLeadECGWaveformStorageUID     = "1.2.840.10008.5.1.4.1.1.9.1.1"
	GeneralECGWaveformStorageUID        = "1.2.840.10008.5.1.4.1.1.9.1.2"
	AmbulatoryECGWaveformStorageUID     = "1.2.840.10008.5.1.4.1.1.9.1.3"
	HemodynamicWaveformStorageUID       = "1.2.840.10008.5.1.4.1.1.9.2.1"
	BasicCardiacElectrophysiologyUID    = "1.2.840.10008.5.1.4.1.1.9.3.1"
	ArterialPulseWaveformStorageUID     = "1.2.840.10008.5.1.4.1.1.9.5.1"
	RespiratoryWaveformStorageUID       = "1.2.840.10008.5.1.4.1.1.9.6.1"
	GeneralAudioWaveformStorageUID      = "1.2.840.10008.5.1.4.1.1.9.4.2"
	MultichannelRespiratoryWaveformUID  = "1.2.840.10008.5.1.4.1.1.9.6.2"
	RoutineScalpElectroencephalogramUID = "1.2.840.10008.5.1.4.1.1.9.7.1"
	ElectromyogramWaveformStorageUID    = "1.2.840.10008.5.1.4.1.1.9.7.2"
	ElectrooculogramWaveformStorageUID  = "1.2.840.10008.5.1.4.1.1.9.7.3"
	SleepElectroencephalogramUID        = "1.2.840.10008.5.1.4.1.1.9.7.4"
	BodyPositionWaveformStorageUID      = "1.2.840.10008.5.1.4.1.1.9.8.1"
)

Waveform Storage

View Source
const (
	BasicTextSRStorageUID                 = "1.2.840.10008.5.1.4.1.1.88.11"
	EnhancedSRStorageUID                  = "1.2.840.10008.5.1.4.1.1.88.22"
	ComprehensiveSRStorageUID             = "1.2.840.10008.5.1.4.1.1.88.33"
	Comprehensive3DSRStorageUID           = "1.2.840.10008.5.1.4.1.1.88.34"
	ProcedureLogStorageUID                = "1.2.840.10008.5.1.4.1.1.88.40"
	MammographyCADSRStorageUID            = "1.2.840.10008.5.1.4.1.1.88.50"
	KeyObjectSelectionDocumentUID         = "1.2.840.10008.5.1.4.1.1.88.59"
	ChestCADSRStorageUID                  = "1.2.840.10008.5.1.4.1.1.88.65"
	XRayRadiationDoseSRStorageUID         = "1.2.840.10008.5.1.4.1.1.88.67"
	RadiopharmaceuticalRadiationDoseSRUID = "1.2.840.10008.5.1.4.1.1.88.68"
	ColonCADSRStorageUID                  = "1.2.840.10008.5.1.4.1.1.88.69"
	ImplantationPlanSRStorageUID          = "1.2.840.10008.5.1.4.1.1.88.70"
	AcquisitionContextSRStorageUID        = "1.2.840.10008.5.1.4.1.1.88.71"
	SimplifiedAdultEchoSRStorageUID       = "1.2.840.10008.5.1.4.1.1.88.72"
	PatientRadiationDoseSRStorageUID      = "1.2.840.10008.5.1.4.1.1.88.73"
)

Structured Reporting

View Source
const (
	GrayscaleSoftcopyPresentationStateUID = "1.2.840.10008.5.1.4.1.1.11.1"
	ColorSoftcopyPresentationStateUID     = "1.2.840.10008.5.1.4.1.1.11.2"
	PseudoColorSoftcopyPresentationUID    = "1.2.840.10008.5.1.4.1.1.11.3"
	BlendingSoftcopyPresentationStateUID  = "1.2.840.10008.5.1.4.1.1.11.4"
	XAXRFGrayscaleSoftcopyPresentUID      = "1.2.840.10008.5.1.4.1.1.11.5"
)

Presentation State

View Source
const (
	SegmentationStorageUID        = "1.2.840.10008.5.1.4.1.1.66.4"
	SurfaceSegmentationStorageUID = "1.2.840.10008.5.1.4.1.1.66.5"
	SurfaceScanMeshStorageUID     = "1.2.840.10008.5.1.4.1.1.68.1"
	SurfaceScanPointCloudUID      = "1.2.840.10008.5.1.4.1.1.68.2"
)

Segmentation and Surface

View Source
const (
	ParametricMapStorageUID       = "1.2.840.10008.5.1.4.1.1.30"
	RealWorldValueMappingUID      = "1.2.840.10008.5.1.4.1.1.67"
	RawDataStorageUID             = "1.2.840.10008.5.1.4.1.1.66"
	SpatialRegistrationStorageUID = "1.2.840.10008.5.1.4.1.1.66.1"
	SpatialFiducialsStorageUID    = "1.2.840.10008.5.1.4.1.1.66.2"
	DeformableSpatialRegUID       = "1.2.840.10008.5.1.4.1.1.66.3"
)

Parametric Map and Real World Value

View Source
const (
	EncapsulatedPDFStorageUID = "1.2.840.10008.5.1.4.1.1.104.1"
	EncapsulatedCDAStorageUID = "1.2.840.10008.5.1.4.1.1.104.2"
	EncapsulatedSTLStorageUID = "1.2.840.10008.5.1.4.1.1.104.3"
	EncapsulatedOBJStorageUID = "1.2.840.10008.5.1.4.1.1.104.4"
	EncapsulatedMTLStorageUID = "1.2.840.10008.5.1.4.1.1.104.5"
)

Encapsulated Document Storage

View Source
const (
	ModalityWorklistInformationModelFindUID = "1.2.840.10008.5.1.4.31"
	ModalityPerformedProcedureStepUID       = "1.2.840.10008.3.1.2.3.3"
	ModalityPerformedProcedureStepRetrUID   = "1.2.840.10008.3.1.2.3.4"
	ModalityPerformedProcedureStepNotifUID  = "1.2.840.10008.3.1.2.3.5"
)

--- Worklist and Procedure Step ---

View Source
const (
	BasicFilmSessionSOPClassUID       = "1.2.840.10008.5.1.1.1"
	BasicFilmBoxSOPClassUID           = "1.2.840.10008.5.1.1.2"
	BasicGrayscaleImageBoxSOPClassUID = "1.2.840.10008.5.1.1.4"
	BasicColorImageBoxSOPClassUID     = "1.2.840.10008.5.1.1.4.1"
	PrintJobSOPClassUID               = "1.2.840.10008.5.1.1.14"
	BasicGrayscalePrintManagementUID  = "1.2.840.10008.5.1.1.9"
	BasicColorPrintManagementUID      = "1.2.840.10008.5.1.1.18"
	PrinterSOPClassUID                = "1.2.840.10008.5.1.1.16"
	PrinterConfigurationRetrievalUID  = "1.2.840.10008.5.1.1.16.376"
)

--- Print Management ---

View Source
const (
	UnifiedProcedureStepPushUID  = "1.2.840.10008.5.1.4.34.6.1"
	UnifiedProcedureStepWatchUID = "1.2.840.10008.5.1.4.34.6.2"
	UnifiedProcedureStepPullUID  = "1.2.840.10008.5.1.4.34.6.3"
	UnifiedProcedureStepEventUID = "1.2.840.10008.5.1.4.34.6.4"
	UnifiedProcedureStepQueryUID = "1.2.840.10008.5.1.4.34.6.5"
)

--- Unified Procedure Step ---

View Source
const (
	SubstanceAdministrationLoggingUID = "1.2.840.10008.1.42"
	ProductCharacteristicsQueryUID    = "1.2.840.10008.5.1.4.41"
	SubstanceApprovalQueryUID         = "1.2.840.10008.5.1.4.42"
)

--- Substance Administration ---

View Source
const (
	HangingProtocolStorageUID  = "1.2.840.10008.5.1.4.38.1"
	ColorPaletteStorageUID     = "1.2.840.10008.5.1.4.39.1"
	GenericImplantTemplateUID  = "1.2.840.10008.5.1.4.43.1"
	ImplantAssemblyTemplateUID = "1.2.840.10008.5.1.4.44.1"
	ImplantTemplateGroupUID    = "1.2.840.10008.5.1.4.45.1"
)

--- Non-Patient Object Storage ---

View Source
const (
	StatusRefusedOutOfResources       uint16 = 0x0112
	StatusRefusedSOPClassNotSupported uint16 = 0x0122
	StatusRefusedNotAuthorized        uint16 = 0x0124
	StatusInvalidArgumentValue        uint16 = 0x0115
	StatusInvalidObjectInstance       uint16 = 0x0117
	StatusMissingAttribute            uint16 = 0x0120
	StatusMistypedArgument            uint16 = 0x0212
	StatusNoSuchArgument              uint16 = 0x0114
	StatusNoSuchSOPClass              uint16 = 0x0118
	StatusProcessingFailure           uint16 = 0x0110
	StatusResourceLimitation          uint16 = 0x0213
	StatusUnrecognizedOperation       uint16 = 0x0211
	StatusDuplicateInvocation         uint16 = 0x0210
)

--- General Status Codes (all services) ---

View Source
const (
	StatusStorageCoercionOfDataElements  uint16 = 0xB000
	StatusStorageDataSetNotMatchSOPClass uint16 = 0xB007
	StatusStorageElementsDiscarded       uint16 = 0xB006
)

--- Storage Service Status Codes ---

View Source
const (
	StatusQROptionalKeysNotSupported  uint16 = 0x0001
	StatusQRSubOpsOneOrMoreFailures   uint16 = 0xB000
	StatusQRRefusedOutOfResourcesFind uint16 = 0xA700
	StatusQRRefusedOutOfResourcesMove uint16 = 0xA701
	StatusQRIdentifierNotMatch        uint16 = 0xA900
	StatusQRMoveDestinationUnknown    uint16 = 0xA801
	StatusQRCancelMatchingTerminated  uint16 = 0xFE00
	StatusQRPendingMatches            uint16 = 0xFF00
	StatusQRPendingMatchesWarning     uint16 = 0xFF01
)

--- Query/Retrieve Service Status Codes ---

View Source
const (
	StatusPrintFilmSessionEmpty        uint16 = 0xB600
	StatusPrintFilmSessionPrintingDone uint16 = 0xB601
	StatusPrintFilmSessionSomePrinted  uint16 = 0xB602
	StatusPrintFilmBoxEmpty            uint16 = 0xB603
	StatusPrintImageDemagnified        uint16 = 0xB604
	StatusPrintMinMaxDensityOutOfRange uint16 = 0xB605
	StatusPrintImageCropped            uint16 = 0xB609
	StatusPrintImageDecimated          uint16 = 0xB60A
)

--- Print Management Service Status Codes ---

View Source
const (
	StatusWorklistRefusedOutOfResources uint16 = 0xA700
	StatusWorklistIdentifierNotMatch    uint16 = 0xA900
	StatusWorklistCancelMatchTerminated uint16 = 0xFE00
	StatusWorklistPendingMatches        uint16 = 0xFF00
	StatusWorklistPendingMatchesWarning uint16 = 0xFF01
)

--- Modality Worklist Status Codes ---

View Source
const (
	StatusUPSUnknownActionType   uint16 = 0xC300
	StatusUPSRefusedNotUpdatable uint16 = 0xC301
	StatusUPSCannotDelete        uint16 = 0xC302
	StatusUPSAlreadyCompleted    uint16 = 0xC303
	StatusUPSNoSuchProcedureStep uint16 = 0xC307
	StatusUPSAlreadyInProgress   uint16 = 0xC310
)

--- Unified Procedure Step Status Codes ---

View Source
const (
	StatusStorageCommitmentRefused            uint16 = 0x0110
	StatusStorageCommitmentNoSuchObject       uint16 = 0x0112
	StatusStorageCommitmentResourceLimitation uint16 = 0xA700
)

--- Storage Commitment Status Codes ---

View Source
const DefaultApplicationContextUID = "1.2.840.10008.3.1.1.1"

DefaultApplicationContextUID is the DICOM Application Context Name.

View Source
const DefaultImplementationClassUID = "1.2.826.0.1.3680043.10.511"

DefaultImplementationClassUID is a placeholder implementation class UID.

View Source
const DefaultImplementationVersionName = "GO-DICOM-1.2.0"

DefaultImplementationVersionName identifies this implementation to peers in the A-ASSOCIATE User Information item. Limited to 16 characters by PS3.7 D.3.3.2.

View Source
const (
	InstanceAvailabilityNotificationUID = "1.2.840.10008.5.1.4.33"
)

--- Instance Availability ---

View Source
const MaxPDULengthLimit uint32 = 128 << 20

MaxPDULengthLimit is the hard ceiling on the declared length of a single received PDU. The PDU length field is a peer-controlled 32-bit value, so without a limit a remote peer could declare ~4 GiB and force an allocation of that size before a single byte of payload is read. 128 MiB is far above any legitimate DICOM PDU (negotiated maximums are typically 16-128 KB) while keeping a malicious declaration cheap to reject.

View Source
const (
	StorageCommitmentPushModelUID = "1.2.840.10008.1.20.1"
)

--- Storage Commitment ---

Variables

View Source
var DefaultLogger = NewLogger(LogLevelSilent, os.Stderr)

DefaultLogger is the package-level logger (silent by default).

Functions

func AllQueryRetrieveSOPClassUIDs

func AllQueryRetrieveSOPClassUIDs() []string

AllQueryRetrieveSOPClassUIDs returns all Query/Retrieve SOP Class UIDs.

func AllStorageSOPClassUIDs

func AllStorageSOPClassUIDs() []string

AllStorageSOPClassUIDs returns all supported Storage SOP Class UIDs. This is the equivalent of pynetdicom's StoragePresentationContexts.

func AllTransferSyntaxUIDs

func AllTransferSyntaxUIDs() []string

AllTransferSyntaxUIDs returns all supported Transfer Syntax UIDs (45 total). Matches pynetdicom's ALL_TRANSFER_SYNTAXES.

func AllWorklistSOPClassUIDs

func AllWorklistSOPClassUIDs() []string

AllWorklistSOPClassUIDs returns Worklist-related SOP Class UIDs.

func BuildAcceptedContextMap

func BuildAcceptedContextMap(
	requested []PresentationContextItem,
	results []PresentationContextResultItem,
) map[byte]*PresentationContext

BuildAcceptedContextMap creates a map from presentation context ID to accepted context from the A-ASSOCIATE-AC response.

func BuildCCancelRQ

func BuildCCancelRQ(messageIDBeingRespondedTo uint16) *dataset.Dataset

BuildCCancelRQ builds a C-CANCEL-RQ command dataset to cancel an in-progress operation.

func BuildCEchoRQ

func BuildCEchoRQ(messageID uint16) *dataset.Dataset

BuildCEchoRQ builds a C-ECHO-RQ command dataset.

func BuildCEchoRSP

func BuildCEchoRSP(messageID uint16, status uint16) *dataset.Dataset

BuildCEchoRSP builds a C-ECHO-RSP command dataset.

func BuildCFindRQ

func BuildCFindRQ(messageID uint16, sopClassUID string, priority uint16) *dataset.Dataset

BuildCFindRQ builds a C-FIND-RQ command dataset.

func BuildCFindRSP

func BuildCFindRSP(messageID uint16, sopClassUID string, status uint16, hasDataSet bool) *dataset.Dataset

BuildCFindRSP builds a C-FIND-RSP command dataset.

func BuildCGetRQ

func BuildCGetRQ(messageID uint16, sopClassUID string, priority uint16) *dataset.Dataset

BuildCGetRQ builds a C-GET-RQ command dataset.

func BuildCGetRSP

func BuildCGetRSP(messageID uint16, sopClassUID string, status uint16,
	remaining, completed, failed, warning uint16) *dataset.Dataset

BuildCGetRSP builds a C-GET-RSP command dataset.

func BuildCMoveRQ

func BuildCMoveRQ(messageID uint16, sopClassUID, moveDestination string, priority uint16) *dataset.Dataset

BuildCMoveRQ builds a C-MOVE-RQ command dataset.

func BuildCMoveRSP

func BuildCMoveRSP(messageID uint16, sopClassUID string, status uint16,
	remaining, completed, failed, warning uint16) *dataset.Dataset

BuildCMoveRSP builds a C-MOVE-RSP command dataset.

func BuildCStoreRQ

func BuildCStoreRQ(messageID uint16, sopClassUID, sopInstanceUID string, priority uint16) *dataset.Dataset

BuildCStoreRQ builds a C-STORE-RQ command dataset.

func BuildCStoreRSP

func BuildCStoreRSP(messageID uint16, sopClassUID, sopInstanceUID string, status uint16) *dataset.Dataset

BuildCStoreRSP builds a C-STORE-RSP command dataset.

func BuildNActionRQ

func BuildNActionRQ(messageID uint16, sopClassUID, sopInstanceUID string, actionTypeID uint16, hasDataSet bool) *dataset.Dataset

BuildNActionRQ builds an N-ACTION-RQ command dataset.

func BuildNActionRSP

func BuildNActionRSP(messageID uint16, sopClassUID, sopInstanceUID string, actionTypeID, status uint16) *dataset.Dataset

BuildNActionRSP builds an N-ACTION-RSP command dataset.

func BuildNCreateRQ

func BuildNCreateRQ(messageID uint16, sopClassUID, sopInstanceUID string, hasDataSet bool) *dataset.Dataset

BuildNCreateRQ builds an N-CREATE-RQ command dataset.

func BuildNCreateRSP

func BuildNCreateRSP(messageID uint16, sopClassUID, sopInstanceUID string, status uint16) *dataset.Dataset

BuildNCreateRSP builds an N-CREATE-RSP command dataset.

func BuildNDeleteRQ

func BuildNDeleteRQ(messageID uint16, sopClassUID, sopInstanceUID string) *dataset.Dataset

BuildNDeleteRQ builds an N-DELETE-RQ command dataset.

func BuildNDeleteRSP

func BuildNDeleteRSP(messageID uint16, sopClassUID, sopInstanceUID string, status uint16) *dataset.Dataset

BuildNDeleteRSP builds an N-DELETE-RSP command dataset.

func BuildNEventReportRQ

func BuildNEventReportRQ(messageID uint16, sopClassUID, sopInstanceUID string, eventTypeID uint16, hasDataSet bool) *dataset.Dataset

BuildNEventReportRQ builds an N-EVENT-REPORT-RQ command dataset.

func BuildNEventReportRSP

func BuildNEventReportRSP(messageID uint16, sopClassUID, sopInstanceUID string, eventTypeID, status uint16) *dataset.Dataset

BuildNEventReportRSP builds an N-EVENT-REPORT-RSP command dataset.

func BuildNGetRQ

func BuildNGetRQ(messageID uint16, sopClassUID, sopInstanceUID string) *dataset.Dataset

BuildNGetRQ builds an N-GET-RQ command dataset.

func BuildNGetRSP

func BuildNGetRSP(messageID uint16, sopClassUID, sopInstanceUID string, status uint16, hasDataSet bool) *dataset.Dataset

BuildNGetRSP builds an N-GET-RSP command dataset.

func BuildNSetRQ

func BuildNSetRQ(messageID uint16, sopClassUID, sopInstanceUID string) *dataset.Dataset

BuildNSetRQ builds an N-SET-RQ command dataset.

func BuildNSetRSP

func BuildNSetRSP(messageID uint16, sopClassUID, sopInstanceUID string, status uint16) *dataset.Dataset

BuildNSetRSP builds an N-SET-RSP command dataset.

func ContextWithAssociationInfo added in v1.1.1

func ContextWithAssociationInfo(ctx context.Context, info *AssociationInfo) context.Context

ContextWithAssociationInfo returns a new context with the given AssociationInfo attached.

func DebugLogger

func DebugLogger()

DebugLogger enables debug-level logging to stderr. This is the equivalent of pynetdicom's debug_logger().

func DecodeCommandDataset

func DecodeCommandDataset(data []byte) (*dataset.Dataset, error)

DecodeCommandDataset decodes a DICOM command dataset from Implicit VR Little Endian bytes.

func DecodeDataset added in v1.2.0

func DecodeDataset(data []byte, transferSyntax string) (*dataset.Dataset, error)

DecodeDataset parses a data set encoded with the given transfer syntax.

func DefaultTransferSyntaxes

func DefaultTransferSyntaxes() []string

DefaultTransferSyntaxes returns the default set of transfer syntaxes to propose.

func EncodeCommandDataset

func EncodeCommandDataset(ds *dataset.Dataset) ([]byte, error)

EncodeCommandDataset creates a DICOM command dataset as Implicit VR Little Endian bytes.

func EncodeDataset added in v1.2.0

func EncodeDataset(ds *dataset.Dataset, transferSyntax string) ([]byte, error)

EncodeDataset serializes a data set using the given transfer syntax.

The transfer syntax must be the one negotiated for the presentation context the data will be sent on; encoding with a different syntax than the peer agreed to produces a data set the peer cannot parse.

func EncodePDU

func EncodePDU(pdu PDU) ([]byte, error)

EncodePDU encodes a PDU to bytes. This is a convenience function that calls the PDU's Encode method.

func EventTypeString

func EventTypeString(et EventType) string

EventTypeString returns a human-readable name for an event type.

func FindPresentationContextID

func FindPresentationContextID(accepted map[byte]*PresentationContext, abstractSyntax string) (byte, bool)

FindPresentationContextID returns the presentation context ID for a given abstract syntax from the accepted contexts map. Returns 0, false if not found.

func FormatStatus

func FormatStatus(status uint16) string

FormatStatus returns a human-readable string for a DIMSE status code.

func GetAffectedSOPClassUID

func GetAffectedSOPClassUID(ds *dataset.Dataset) (string, error)

GetAffectedSOPClassUID extracts the Affected SOP Class UID from a command dataset.

func GetAffectedSOPInstanceUID

func GetAffectedSOPInstanceUID(ds *dataset.Dataset) (string, error)

GetAffectedSOPInstanceUID extracts the Affected SOP Instance UID from a command dataset.

func GetDataSetType

func GetDataSetType(ds *dataset.Dataset) (uint16, error)

GetDataSetType extracts the CommandDataSetType from a command dataset.

func HasDataSet

func HasDataSet(ds *dataset.Dataset) bool

HasDataSet returns whether the command indicates a data set follows.

func IsCancel

func IsCancel(status uint16) bool

IsCancel returns true if the status indicates cancellation.

func IsFailure

func IsFailure(status uint16) bool

IsFailure returns true if the status indicates failure.

func IsPending

func IsPending(status uint16) bool

IsPending returns true if the status indicates more results to follow.

func IsQueryRetrieveSOPClass

func IsQueryRetrieveSOPClass(uid string) bool

IsQueryRetrieveSOPClass returns true if the given UID is a Query/Retrieve SOP Class.

func IsStorageSOPClass

func IsStorageSOPClass(uid string) bool

IsStorageSOPClass returns true if the given UID is a Storage SOP Class.

func IsSuccess

func IsSuccess(status uint16) bool

IsSuccess returns true if the status indicates success.

func IsWarning

func IsWarning(status uint16) bool

IsWarning returns true if the status indicates a warning.

func LoggingEventHandlers

func LoggingEventHandlers(logger *Logger) map[EventType]EventHandler

LoggingEventHandlers returns event handlers that log association lifecycle events. Attach these to an SCP's EventManager for operational visibility.

func PDUTypeString

func PDUTypeString(pduType byte) string

PDUTypeString returns a human-readable string for a PDU type.

func ParseCommandDataset

func ParseCommandDataset(ds *dataset.Dataset) (commandField uint16, messageID uint16, status uint16, err error)

ParseCommandDataset extracts common DIMSE fields from a command dataset.

func SetDefaultLogLevel

func SetDefaultLogLevel(level LogLevel)

SetDefaultLogLevel sets the log level on the package-level logger.

func UncompressedTransferSyntaxUIDs

func UncompressedTransferSyntaxUIDs() []string

UncompressedTransferSyntaxUIDs returns only uncompressed transfer syntaxes.

Types

type AbortPDU

type AbortPDU struct {
	Source byte
	Reason byte
}

AbortPDU represents an A-ABORT PDU.

func (*AbortPDU) Encode

func (p *AbortPDU) Encode() ([]byte, error)

func (*AbortPDU) Type

func (p *AbortPDU) Type() byte

type AssociateAC

type AssociateAC struct {
	ProtocolVersion       uint16
	CalledAE              string
	CallingAE             string
	ApplicationContextUID string
	PresentationContexts  []PresentationContextResultItem
	UserInformation       UserInformationItem
}

AssociateAC represents an A-ASSOCIATE-AC PDU.

func (*AssociateAC) Encode

func (p *AssociateAC) Encode() ([]byte, error)

func (*AssociateAC) Type

func (p *AssociateAC) Type() byte

type AssociateRJ

type AssociateRJ struct {
	Result byte
	Source byte
	Reason byte
}

AssociateRJ represents an A-ASSOCIATE-RJ PDU.

func (*AssociateRJ) Encode

func (p *AssociateRJ) Encode() ([]byte, error)

func (*AssociateRJ) Type

func (p *AssociateRJ) Type() byte

type AssociateRQ

type AssociateRQ struct {
	ProtocolVersion       uint16
	CalledAE              string
	CallingAE             string
	ApplicationContextUID string
	PresentationContexts  []PresentationContextItem
	UserInformation       UserInformationItem
}

AssociateRQ represents an A-ASSOCIATE-RQ PDU.

func (*AssociateRQ) Encode

func (p *AssociateRQ) Encode() ([]byte, error)

func (*AssociateRQ) Type

func (p *AssociateRQ) Type() byte

type Association

type Association struct {
	// contains filtered or unexported fields
}

Association represents a DICOM association between two AEs.

func NewAssociation

func NewAssociation(transport *Transport) *Association

NewAssociation creates a new association in the Idle state.

func (*Association) Abort

func (a *Association) Abort(ctx context.Context, source, reason byte) error

Abort sends an A-ABORT PDU.

func (*Association) AcceptAssociation

func (a *Association) AcceptAssociation(ctx context.Context, rq *AssociateRQ,
	supportedAbstractSyntaxes map[string]bool, supportedTransferSyntaxes map[string]bool,
	maxPDUSize uint32) error

AcceptAssociation handles an incoming A-ASSOCIATE-RQ (SCP side).

func (*Association) AcceptedContexts

func (a *Association) AcceptedContexts() map[byte]*PresentationContext

AcceptedContexts returns the map of accepted presentation contexts.

func (*Association) CalledAE

func (a *Association) CalledAE() string

CalledAE returns the called AE title.

func (*Association) CallingAE

func (a *Association) CallingAE() string

CallingAE returns the calling AE title.

func (*Association) MaxPDUSize

func (a *Association) MaxPDUSize() uint32

MaxPDUSize returns the negotiated maximum PDU size.

func (*Association) PeerUserInformation added in v1.2.0

func (a *Association) PeerUserInformation() UserInformationItem

PeerUserInformation returns the User Information the peer sent during association negotiation, including any extended negotiation sub-items (async operations window, role selection, user identity response).

func (*Association) ReceivePData

func (a *Association) ReceivePData(ctx context.Context) (byte, []byte, bool, error)

ReceivePData reads and reassembles P-DATA-TF PDUs until a complete message is received. Returns the context ID, the assembled data, whether it's a command, and any error.

func (*Association) RejectAssociation

func (a *Association) RejectAssociation(ctx context.Context, result, source, reason byte) error

RejectAssociation sends an A-ASSOCIATE-RJ PDU (SCP side).

func (*Association) Release

func (a *Association) Release(ctx context.Context) error

Release performs an orderly release of the association.

func (*Association) RequestAssociation

func (a *Association) RequestAssociation(ctx context.Context, callingAE, calledAE string,
	contexts []PresentationContextItem, maxPDUSize uint32) error

RequestAssociation sends an A-ASSOCIATE-RQ and processes the response (SCU side).

func (*Association) RequestAssociationWithNegotiation added in v1.2.0

func (a *Association) RequestAssociationWithNegotiation(ctx context.Context, callingAE, calledAE string,
	contexts []PresentationContextItem, maxPDUSize uint32, ext *ExtendedNegotiation) error

RequestAssociationWithNegotiation sends an A-ASSOCIATE-RQ carrying optional extended negotiation items (async operations window, SCP/SCU role selection, user identity) and processes the response.

Role selection is required to act as an SCP for a SOP Class on an association this AE initiated — notably for C-GET, where the peer sends C-STORE sub-operations back over the same association.

func (*Association) RoleSelectionFor added in v1.2.0

func (a *Association) RoleSelectionFor(sopClassUID string) (SCPSCURoleSelection, bool)

RoleSelectionFor returns the negotiated SCP/SCU role selection for a SOP Class, and whether the peer supplied one.

func (*Association) SendPData

func (a *Association) SendPData(ctx context.Context, contextID byte, data []byte, isCommand bool) error

SendPData sends data as P-DATA-TF PDUs, fragmenting if necessary.

func (*Association) State

func (a *Association) State() AssociationState

State returns the current association state.

func (*Association) TransferSyntaxFor added in v1.2.0

func (a *Association) TransferSyntaxFor(contextID byte) string

TransferSyntaxFor returns the transfer syntax negotiated for a presentation context ID. It returns the empty string when the context was not accepted, which callers treat as DICOM's implicit VR little endian default.

type AssociationError

type AssociationError struct {
	Message string
	Code    string
	Detail  string
	Result  byte // A-ASSOCIATE-RJ result field
	Source  byte // A-ASSOCIATE-RJ source field
	Reason  byte // A-ASSOCIATE-RJ reason field
}

AssociationError represents errors during association negotiation.

func NewAssociationError

func NewAssociationError(code, message string) *AssociationError

NewAssociationError creates a new association error.

func NewAssociationRejection

func NewAssociationRejection(result, source, reason byte) *AssociationError

NewAssociationRejection creates an error from A-ASSOCIATE-RJ PDU fields.

func (*AssociationError) Details

func (e *AssociationError) Details() string

func (*AssociationError) Error

func (e *AssociationError) Error() string

func (*AssociationError) ErrorCode

func (e *AssociationError) ErrorCode() string

type AssociationInfo added in v1.1.1

type AssociationInfo struct {
	// CallingAE is the AE title of the remote peer (the SCU).
	CallingAE string

	// CalledAE is the AE title that was called (the SCP).
	CalledAE string

	// RemoteAddr is the network address of the remote peer.
	RemoteAddr net.Addr

	// LocalAddr is the local network address of this side of the connection.
	LocalAddr net.Addr

	// MaxPDUSize is the negotiated maximum PDU size for the association.
	MaxPDUSize uint32

	// AcceptedContexts contains the negotiated presentation contexts,
	// keyed by presentation context ID.
	AcceptedContexts map[byte]*PresentationContext

	// PeerImplementationClassUID is the implementation class UID reported
	// by the remote peer in the A-ASSOCIATE-RQ.
	PeerImplementationClassUID string

	// PeerImplementationVersion is the implementation version name reported
	// by the remote peer in the A-ASSOCIATE-RQ.
	PeerImplementationVersion string
}

AssociationInfo holds association-level information that is made available to Handler methods via the context. This allows handlers to access details about the current association (e.g., who is connecting) without changing the Handler interface.

func AssociationInfoFromContext added in v1.1.1

func AssociationInfoFromContext(ctx context.Context) *AssociationInfo

AssociationInfoFromContext extracts the AssociationInfo from the context. Returns nil if no association info is present.

type AssociationState

type AssociationState int

AssociationState represents the state of a DICOM association.

const (
	StateIdle                  AssociationState = iota // No association
	StateAwaitingAssocResponse                         // A-ASSOCIATE-RQ sent, waiting for response
	StateAssociated                                    // Association established
	StateAwaitingRelease                               // A-RELEASE-RQ sent, waiting for response
	StateAwaitingReleaseRP                             // Received A-RELEASE-RQ, processing
)

func (AssociationState) String

func (s AssociationState) String() string

String returns a human-readable name for the association state.

type AsynchronousOperationsWindow

type AsynchronousOperationsWindow struct {
	MaxOperationsInvoked   uint16
	MaxOperationsPerformed uint16
}

AsynchronousOperationsWindow negotiates the number of asynchronous operations.

func DecodeAsyncOperationsWindow

func DecodeAsyncOperationsWindow(data []byte) (*AsynchronousOperationsWindow, error)

DecodeAsyncOperationsWindow decodes an async operations window sub-item.

func (*AsynchronousOperationsWindow) Encode

func (a *AsynchronousOperationsWindow) Encode() []byte

Encode serializes the async operations window sub-item.

type BaseHandler

type BaseHandler struct{}

BaseHandler provides default implementations for all Handler methods. Embed this in your handler to only override the methods you need.

func (*BaseHandler) HandleCEcho

func (h *BaseHandler) HandleCEcho(_ context.Context, req *CEchoRequest) (*CEchoResponse, error)

HandleCEcho returns success by default.

func (*BaseHandler) HandleCFind

func (h *BaseHandler) HandleCFind(_ context.Context, _ *CFindRequest) ([]*CFindResponse, error)

HandleCFind returns an empty result set by default.

func (*BaseHandler) HandleCGet

func (h *BaseHandler) HandleCGet(_ context.Context, _ *CGetRequest) (*CGetResponse, error)

HandleCGet returns an error by default.

func (*BaseHandler) HandleCMove

func (h *BaseHandler) HandleCMove(_ context.Context, _ *CMoveRequest) (*CMoveResponse, error)

HandleCMove returns an error by default.

func (*BaseHandler) HandleCStore

func (h *BaseHandler) HandleCStore(_ context.Context, req *CStoreRequest) (*CStoreResponse, error)

HandleCStore returns success by default.

func (*BaseHandler) HandleNAction

func (h *BaseHandler) HandleNAction(_ context.Context, _ *NActionRequest) (*NActionResponse, error)

HandleNAction returns an error by default.

func (*BaseHandler) HandleNCreate

func (h *BaseHandler) HandleNCreate(_ context.Context, _ *NCreateRequest) (*NCreateResponse, error)

HandleNCreate returns an error by default.

func (*BaseHandler) HandleNDelete

func (h *BaseHandler) HandleNDelete(_ context.Context, _ *NDeleteRequest) (*NDeleteResponse, error)

HandleNDelete returns an error by default.

func (*BaseHandler) HandleNEventReport

func (h *BaseHandler) HandleNEventReport(_ context.Context, _ *NEventReportRequest) (*NEventReportResponse, error)

HandleNEventReport returns an error by default.

func (*BaseHandler) HandleNGet

func (h *BaseHandler) HandleNGet(_ context.Context, _ *NGetRequest) (*NGetResponse, error)

HandleNGet returns an error by default.

func (*BaseHandler) HandleNSet

func (h *BaseHandler) HandleNSet(_ context.Context, _ *NSetRequest) (*NSetResponse, error)

HandleNSet returns an error by default.

type CEchoRequest

type CEchoRequest struct {
	MessageID        uint16
	AffectedSOPClass string
}

CEchoRequest represents a C-ECHO-RQ message.

type CEchoResponse

type CEchoResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	Status               uint16
}

CEchoResponse represents a C-ECHO-RSP message.

type CFindRequest

type CFindRequest struct {
	MessageID        uint16
	AffectedSOPClass string
	Priority         uint16
	DataSet          *dataset.Dataset
}

CFindRequest represents a C-FIND-RQ message.

type CFindResponse

type CFindResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	Status               uint16
	DataSet              *dataset.Dataset
}

CFindResponse represents a C-FIND-RSP message.

type CFindResult

type CFindResult struct {
	DataSet *dataset.Dataset
	Err     error
}

CFindResult wraps a find result or error.

type CGetRequest

type CGetRequest struct {
	MessageID        uint16
	AffectedSOPClass string
	Priority         uint16
	DataSet          *dataset.Dataset
}

CGetRequest represents a C-GET-RQ message.

type CGetResponse

type CGetResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	Status               uint16
	NumberOfRemaining    uint16
	NumberOfCompleted    uint16
	NumberOfFailed       uint16
	NumberOfWarning      uint16
	DataSet              *dataset.Dataset
}

CGetResponse represents a C-GET-RSP message.

type CMoveRequest

type CMoveRequest struct {
	MessageID        uint16
	AffectedSOPClass string
	Priority         uint16
	MoveDestination  string
	DataSet          *dataset.Dataset
}

CMoveRequest represents a C-MOVE-RQ message.

type CMoveResponse

type CMoveResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	Status               uint16
	NumberOfRemaining    uint16
	NumberOfCompleted    uint16
	NumberOfFailed       uint16
	NumberOfWarning      uint16
	DataSet              *dataset.Dataset
}

CMoveResponse represents a C-MOVE-RSP message.

type CStoreRequest

type CStoreRequest struct {
	MessageID           uint16
	AffectedSOPClass    string
	AffectedSOPInstance string
	Priority            uint16
	MoveOriginatorAE    string
	MoveOriginatorMsgID uint16
	DataSet             *dataset.Dataset
}

CStoreRequest represents a C-STORE-RQ message.

type CStoreResponse

type CStoreResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	AffectedSOPInstance  string
	Status               uint16
}

CStoreResponse represents a C-STORE-RSP message.

type CommunicationError

type CommunicationError struct {
	Message string
	Code    string
	Detail  string
	Cause   error
}

CommunicationError represents a transport-level communication error.

func NewCommunicationError

func NewCommunicationError(code, message string, cause error) *CommunicationError

NewCommunicationError creates a new communication error.

func (*CommunicationError) Details

func (e *CommunicationError) Details() string

func (*CommunicationError) Error

func (e *CommunicationError) Error() string

func (*CommunicationError) ErrorCode

func (e *CommunicationError) ErrorCode() string

func (*CommunicationError) Unwrap

func (e *CommunicationError) Unwrap() error

type CompositeHandler

type CompositeHandler struct {
	BaseHandler
	// contains filtered or unexported fields
}

CompositeHandler allows registering separate handlers for different service types.

func NewCompositeHandler

func NewCompositeHandler() *CompositeHandler

NewCompositeHandler creates a new CompositeHandler.

func (*CompositeHandler) HandleCEcho

func (h *CompositeHandler) HandleCEcho(ctx context.Context, req *CEchoRequest) (*CEchoResponse, error)

HandleCEcho delegates to the echo handler.

func (*CompositeHandler) HandleCFind

func (h *CompositeHandler) HandleCFind(ctx context.Context, req *CFindRequest) ([]*CFindResponse, error)

HandleCFind delegates to the find handler.

func (*CompositeHandler) HandleCGet

func (h *CompositeHandler) HandleCGet(ctx context.Context, req *CGetRequest) (*CGetResponse, error)

HandleCGet delegates to the get handler.

func (*CompositeHandler) HandleCMove

func (h *CompositeHandler) HandleCMove(ctx context.Context, req *CMoveRequest) (*CMoveResponse, error)

HandleCMove delegates to the move handler.

func (*CompositeHandler) HandleCStore

func (h *CompositeHandler) HandleCStore(ctx context.Context, req *CStoreRequest) (*CStoreResponse, error)

HandleCStore delegates to the store handler.

func (*CompositeHandler) SetEchoHandler

func (h *CompositeHandler) SetEchoHandler(handler Handler)

SetEchoHandler sets the handler for C-ECHO requests.

func (*CompositeHandler) SetFindHandler

func (h *CompositeHandler) SetFindHandler(handler Handler)

SetFindHandler sets the handler for C-FIND requests.

func (*CompositeHandler) SetGetHandler

func (h *CompositeHandler) SetGetHandler(handler Handler)

SetGetHandler sets the handler for C-GET requests.

func (*CompositeHandler) SetMoveHandler

func (h *CompositeHandler) SetMoveHandler(handler Handler)

SetMoveHandler sets the handler for C-MOVE requests.

func (*CompositeHandler) SetStoreHandler

func (h *CompositeHandler) SetStoreHandler(handler Handler)

SetStoreHandler sets the handler for C-STORE requests.

type DIMSEError

type DIMSEError struct {
	Message string
	Code    string
	Detail  string
	Status  uint16
}

DIMSEError represents an error in DIMSE message processing.

func NewDIMSEError

func NewDIMSEError(code, message string, status uint16) *DIMSEError

NewDIMSEError creates a new DIMSE error.

func (*DIMSEError) Details

func (e *DIMSEError) Details() string

func (*DIMSEError) Error

func (e *DIMSEError) Error() string

func (*DIMSEError) ErrorCode

func (e *DIMSEError) ErrorCode() string

type EchoHandler

type EchoHandler struct {
	BaseHandler
}

EchoHandler is a simple handler that only supports C-ECHO (verification).

type Event

type Event struct {
	Type      EventType
	Timestamp time.Time

	// Association context (may be nil for connection-level events)
	CallingAE  string
	CalledAE   string
	RemoteAddr string

	// PDU/DIMSE context (set for PDU/DIMSE events)
	PDUType     byte
	CommandType uint16

	// Additional context
	Description string
	Error       error
}

Event carries information about a network event.

type EventHandler

type EventHandler func(event *Event)

EventHandler is a function that handles network events.

type EventManager

type EventManager struct {
	// contains filtered or unexported fields
}

EventManager manages event handlers. Thread-safe.

func NewEventManager

func NewEventManager() *EventManager

NewEventManager creates a new EventManager.

func (*EventManager) Emit

func (em *EventManager) Emit(event *Event)

Emit fires an event, calling all registered handlers.

func (*EventManager) HasHandlers

func (em *EventManager) HasHandlers(eventType EventType) bool

HasHandlers returns true if any handlers are registered for the event type.

func (*EventManager) Off

func (em *EventManager) Off(eventType EventType)

Off removes all handlers for an event type.

func (*EventManager) On

func (em *EventManager) On(eventType EventType, handler EventHandler)

On registers a handler for an event type. Multiple handlers per event are supported.

type EventType

type EventType int

EventType identifies a network event.

const (
	// Connection lifecycle
	EVTConnOpen  EventType = iota + 1 // Connection opened
	EVTConnClose                      // Connection closed

	// Association lifecycle
	EVTAssocRequested   // Association requested (SCU sent A-ASSOCIATE-RQ)
	EVTAssocAccepted    // Association accepted (SCP sent A-ASSOCIATE-AC)
	EVTAssocRejected    // Association rejected (SCP sent A-ASSOCIATE-RJ)
	EVTAssocEstablished // Association established (both sides)
	EVTAssocReleased    // Association released normally
	EVTAssocAborted     // Association aborted abnormally

	// ACSE (Association Control Service Element) primitives
	EVTACSERecv // ACSE primitive received from DUL
	EVTACSESent // ACSE primitive sent to DUL

	// PDU (Protocol Data Unit) level
	EVTPDURecv // PDU received and decoded
	EVTPDUSent // PDU encoded and sent

	// Raw data level
	EVTDataRecv // Raw PDU data received from remote
	EVTDataSent // Raw PDU data sent to remote

	// DIMSE (DICOM Message Service Element) level
	EVTDIMSERecv // Complete DIMSE message received and decoded
	EVTDIMSESent // DIMSE message encoded and sent to DUL

	// State machine
	EVTFSMTransition // DUL state machine about to transition

	// C-DIMSE service events (intervention)
	EVTCEcho  // C-ECHO request received
	EVTCStore // C-STORE request received
	EVTCFind  // C-FIND request received
	EVTCMove  // C-MOVE request received
	EVTCGet   // C-GET request received

	// N-DIMSE service events (intervention)
	EVTNEventReport // N-EVENT-REPORT request received
	EVTNGet         // N-GET request received
	EVTNSet         // N-SET request received
	EVTNAction      // N-ACTION request received
	EVTNCreate      // N-CREATE request received
	EVTNDelete      // N-DELETE request received

	// Negotiation events (intervention)
	EVTAsyncOps    // Asynchronous operations negotiation requested
	EVTSOPExtended // SOP class extended negotiation requested
	EVTSOPCommon   // SOP class common extended negotiation requested
	EVTUserID      // User identity negotiation requested
)

Notification events — informational, multiple handlers allowed. These match pynetdicom's EVT_* constants for full compatibility.

type ExtendedNegotiation

type ExtendedNegotiation struct {
	AsyncOperations *AsynchronousOperationsWindow
	RoleSelections  []SCPSCURoleSelection
	UserIdentity    *UserIdentityNegotiation
}

ExtendedNegotiation holds all extended negotiation items.

type Handler

type Handler interface {
	// C-DIMSE services
	HandleCEcho(ctx context.Context, req *CEchoRequest) (*CEchoResponse, error)
	HandleCStore(ctx context.Context, req *CStoreRequest) (*CStoreResponse, error)
	HandleCFind(ctx context.Context, req *CFindRequest) ([]*CFindResponse, error)
	HandleCMove(ctx context.Context, req *CMoveRequest) (*CMoveResponse, error)
	HandleCGet(ctx context.Context, req *CGetRequest) (*CGetResponse, error)

	// N-DIMSE services
	HandleNEventReport(ctx context.Context, req *NEventReportRequest) (*NEventReportResponse, error)
	HandleNGet(ctx context.Context, req *NGetRequest) (*NGetResponse, error)
	HandleNSet(ctx context.Context, req *NSetRequest) (*NSetResponse, error)
	HandleNAction(ctx context.Context, req *NActionRequest) (*NActionResponse, error)
	HandleNCreate(ctx context.Context, req *NCreateRequest) (*NCreateResponse, error)
	HandleNDelete(ctx context.Context, req *NDeleteRequest) (*NDeleteResponse, error)
}

Handler defines the interface for handling DIMSE requests on the SCP side. Implement only the methods you need; use BaseHandler for defaults.

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

Listener wraps a TCP listener for accepting DICOM associations.

func Listen

func Listen(address string) (*Listener, error)

Listen creates a new TCP listener on the specified address.

func ListenTLS

func ListenTLS(address string, tlsCfg *TLSConfig) (*Listener, error)

ListenTLS creates a TLS-encrypted TCP listener.

func (*Listener) Accept

func (l *Listener) Accept(ctx context.Context) (*Transport, error)

Accept waits for and returns the next incoming connection as a Transport.

func (*Listener) Addr

func (l *Listener) Addr() net.Addr

Addr returns the listener's address.

func (*Listener) Close

func (l *Listener) Close() error

Close closes the listener.

type LogLevel

type LogLevel int

LogLevel controls the verbosity of network logging.

const (
	LogLevelSilent LogLevel = iota // No logging
	LogLevelError                  // Errors only
	LogLevelWarn                   // Errors + warnings
	LogLevelInfo                   // Errors + warnings + info
	LogLevelDebug                  // Everything including PDU/DIMSE details
)

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger provides structured logging for DICOM network operations.

func NewLogger

func NewLogger(level LogLevel, output io.Writer) *Logger

NewLogger creates a new Logger. If output is nil, os.Stderr is used.

func (*Logger) Debug

func (l *Logger) Debug(format string, args ...interface{})

Debug logs a debug message.

func (*Logger) Error

func (l *Logger) Error(format string, args ...interface{})

Error logs an error message.

func (*Logger) Info

func (l *Logger) Info(format string, args ...interface{})

Info logs an informational message.

func (*Logger) SetLevel

func (l *Logger) SetLevel(level LogLevel)

SetLevel changes the log level.

func (*Logger) SetOutput

func (l *Logger) SetOutput(w io.Writer)

SetOutput changes the log output destination.

func (*Logger) Warn

func (l *Logger) Warn(format string, args ...interface{})

Warn logs a warning message.

type NActionRequest

type NActionRequest struct {
	MessageID            uint16
	RequestedSOPClass    string
	RequestedSOPInstance string
	ActionTypeID         uint16
	DataSet              *dataset.Dataset
}

NActionRequest represents an N-ACTION-RQ message.

type NActionResponse

type NActionResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	AffectedSOPInstance  string
	ActionTypeID         uint16
	Status               uint16
	DataSet              *dataset.Dataset
}

NActionResponse represents an N-ACTION-RSP message.

type NCreateRequest

type NCreateRequest struct {
	MessageID           uint16
	AffectedSOPClass    string
	AffectedSOPInstance string
	DataSet             *dataset.Dataset
}

NCreateRequest represents an N-CREATE-RQ message.

type NCreateResponse

type NCreateResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	AffectedSOPInstance  string
	Status               uint16
	DataSet              *dataset.Dataset
}

NCreateResponse represents an N-CREATE-RSP message.

type NDeleteRequest

type NDeleteRequest struct {
	MessageID            uint16
	RequestedSOPClass    string
	RequestedSOPInstance string
}

NDeleteRequest represents an N-DELETE-RQ message.

type NDeleteResponse

type NDeleteResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	AffectedSOPInstance  string
	Status               uint16
}

NDeleteResponse represents an N-DELETE-RSP message.

type NEventReportRequest

type NEventReportRequest struct {
	MessageID           uint16
	AffectedSOPClass    string
	AffectedSOPInstance string
	EventTypeID         uint16
	DataSet             *dataset.Dataset
}

NEventReportRequest represents an N-EVENT-REPORT-RQ message.

type NEventReportResponse

type NEventReportResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	AffectedSOPInstance  string
	EventTypeID          uint16
	Status               uint16
	DataSet              *dataset.Dataset
}

NEventReportResponse represents an N-EVENT-REPORT-RSP message.

type NGetRequest

type NGetRequest struct {
	MessageID            uint16
	RequestedSOPClass    string
	RequestedSOPInstance string
	AttributeList        []tag.Tag
}

NGetRequest represents an N-GET-RQ message.

type NGetResponse

type NGetResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	AffectedSOPInstance  string
	Status               uint16
	DataSet              *dataset.Dataset
}

NGetResponse represents an N-GET-RSP message.

type NSetRequest

type NSetRequest struct {
	MessageID            uint16
	RequestedSOPClass    string
	RequestedSOPInstance string
	DataSet              *dataset.Dataset
}

NSetRequest represents an N-SET-RQ message.

type NSetResponse

type NSetResponse struct {
	MessageIDRespondedTo uint16
	AffectedSOPClass     string
	AffectedSOPInstance  string
	Status               uint16
	DataSet              *dataset.Dataset
}

NSetResponse represents an N-SET-RSP message.

type NetworkConfig

type NetworkConfig struct {
	// MaxPDUSize is the maximum PDU size to propose during association negotiation.
	MaxPDUSize uint32

	// ARTIMTimeout is the timeout for the ARTIM timer.
	ARTIMTimeout time.Duration

	// DIMSETimeout is the timeout for DIMSE operations.
	DIMSETimeout time.Duration

	// NetworkTimeout is the timeout for establishing TCP connections.
	NetworkTimeout time.Duration
}

NetworkConfig holds configuration for DICOM network operations.

func DefaultNetworkConfig

func DefaultNetworkConfig() NetworkConfig

DefaultNetworkConfig returns a NetworkConfig with sensible defaults.

type NetworkError

type NetworkError interface {
	error
	ErrorCode() string
	Details() string
}

NetworkError is the base interface for all network-specific errors.

type PDU

type PDU interface {
	Type() byte
	Encode() ([]byte, error)
}

PDU is the interface for all Protocol Data Units.

func DecodePDU

func DecodePDU(r io.Reader) (PDU, error)

DecodePDU reads and decodes a PDU from a reader.

type PDUError

type PDUError struct {
	Message string
	Code    string
	Detail  string
}

PDUError represents errors in PDU encoding/decoding.

func NewPDUError

func NewPDUError(code, message string) *PDUError

NewPDUError creates a new PDU error.

func NewPDUErrorf

func NewPDUErrorf(code, format string, args ...interface{}) *PDUError

NewPDUErrorf creates a new PDU error with formatted message.

func (*PDUError) Details

func (e *PDUError) Details() string

func (*PDUError) Error

func (e *PDUError) Error() string

func (*PDUError) ErrorCode

func (e *PDUError) ErrorCode() string

type PDVItem

type PDVItem struct {
	PresentationContextID byte
	IsCommand             bool
	IsLast                bool
	Data                  []byte
}

PDVItem represents a Presentation Data Value item within a P-DATA-TF PDU.

type PDataTF

type PDataTF struct {
	PDVItems []PDVItem
}

PDataTF represents a P-DATA-TF PDU containing one or more PDV items.

func (*PDataTF) Encode

func (p *PDataTF) Encode() ([]byte, error)

func (*PDataTF) Type

func (p *PDataTF) Type() byte

type PresentationContext

type PresentationContext struct {
	ID             byte
	AbstractSyntax string
	TransferSyntax string
	Result         byte
}

PresentationContext represents a negotiated presentation context pairing an abstract syntax (SOP Class) with a transfer syntax.

func (*PresentationContext) IsAccepted

func (pc *PresentationContext) IsAccepted() bool

IsAccepted returns true if this presentation context was accepted.

type PresentationContextItem

type PresentationContextItem struct {
	ID               byte
	AbstractSyntax   string
	TransferSyntaxes []string
}

PresentationContextItem represents a presentation context in an A-ASSOCIATE-RQ.

func AllStoragePresentationContexts

func AllStoragePresentationContexts() []PresentationContextItem

AllStoragePresentationContexts returns presentation contexts for all storage SOP classes.

func BasicWorklistPresentationContexts

func BasicWorklistPresentationContexts() []PresentationContextItem

BasicWorklistPresentationContexts returns presentation contexts for Modality Worklist.

func DefaultQueryRetrieveContexts

func DefaultQueryRetrieveContexts() []PresentationContextItem

DefaultQueryRetrieveContexts returns presentation contexts for query/retrieve operations.

func DefaultStorageContexts

func DefaultStorageContexts() []PresentationContextItem

DefaultStorageContexts returns presentation contexts for common storage SOP classes.

func DefaultVerificationContexts

func DefaultVerificationContexts() []PresentationContextItem

DefaultVerificationContexts returns presentation contexts for C-ECHO.

func InstanceAvailabilityPresentationContexts

func InstanceAvailabilityPresentationContexts() []PresentationContextItem

InstanceAvailabilityPresentationContexts returns contexts for Instance Availability.

func ModalityPerformedProcedurePresentationContexts

func ModalityPerformedProcedurePresentationContexts() []PresentationContextItem

ModalityPerformedProcedurePresentationContexts returns contexts for MPPS.

func NonPatientObjectPresentationContexts

func NonPatientObjectPresentationContexts() []PresentationContextItem

NonPatientObjectPresentationContexts returns contexts for Non-Patient Object Storage.

func PrintManagementPresentationContexts

func PrintManagementPresentationContexts() []PresentationContextItem

PrintManagementPresentationContexts returns contexts for Print Management.

func QueryRetrievePresentationContexts

func QueryRetrievePresentationContexts() []PresentationContextItem

QueryRetrievePresentationContexts returns presentation contexts for Q/R services.

func StorageCommitmentPresentationContexts

func StorageCommitmentPresentationContexts() []PresentationContextItem

StorageCommitmentPresentationContexts returns contexts for Storage Commitment.

func SubstanceAdministrationPresentationContexts

func SubstanceAdministrationPresentationContexts() []PresentationContextItem

SubstanceAdministrationPresentationContexts returns contexts for Substance Administration.

func UnifiedProcedureStepPresentationContexts

func UnifiedProcedureStepPresentationContexts() []PresentationContextItem

UnifiedProcedureStepPresentationContexts returns contexts for UPS.

func VerificationPresentationContexts

func VerificationPresentationContexts() []PresentationContextItem

VerificationPresentationContexts returns presentation contexts for C-ECHO.

type PresentationContextResultItem

type PresentationContextResultItem struct {
	ID             byte
	Result         byte
	TransferSyntax string
}

PresentationContextResultItem represents a presentation context result in an A-ASSOCIATE-AC.

func NegotiatePresentationContexts

func NegotiatePresentationContexts(
	requested []PresentationContextItem,
	supportedAbstractSyntaxes map[string]bool,
	supportedTransferSyntaxes map[string]bool,
) []PresentationContextResultItem

NegotiatePresentationContexts selects transfer syntaxes for requested presentation contexts based on what the SCP supports. Returns the result items for the A-ASSOCIATE-AC PDU.

type QueryRetrieveHandler

type QueryRetrieveHandler struct {
	BaseHandler
	OnFind func(ctx context.Context, sopClassUID string, query *dataset.Dataset) ([]*dataset.Dataset, error)
	OnMove func(ctx context.Context, sopClassUID, moveDestination string, query *dataset.Dataset) error
	OnGet  func(ctx context.Context, sopClassUID string, query *dataset.Dataset) ([]*dataset.Dataset, error)
}

QueryRetrieveHandler handles C-FIND, C-MOVE, and C-GET requests with callbacks.

func (*QueryRetrieveHandler) HandleCFind

func (h *QueryRetrieveHandler) HandleCFind(ctx context.Context, req *CFindRequest) ([]*CFindResponse, error)

HandleCFind delegates to the OnFind callback if set.

func (*QueryRetrieveHandler) HandleCGet added in v1.2.0

func (h *QueryRetrieveHandler) HandleCGet(ctx context.Context, req *CGetRequest) (*CGetResponse, error)

HandleCGet delegates to the OnGet callback if set.

The returned datasets are the instances matching the query. Sending them back as C-STORE sub-operations is not yet implemented, so the response reports the match count and a warning status rather than claiming success.

func (*QueryRetrieveHandler) HandleCMove

func (h *QueryRetrieveHandler) HandleCMove(ctx context.Context, req *CMoveRequest) (*CMoveResponse, error)

HandleCMove delegates to the OnMove callback if set.

type ReleaseRP

type ReleaseRP struct{}

ReleaseRP represents an A-RELEASE-RP PDU.

func (*ReleaseRP) Encode

func (p *ReleaseRP) Encode() ([]byte, error)

func (*ReleaseRP) Type

func (p *ReleaseRP) Type() byte

type ReleaseRQ

type ReleaseRQ struct{}

ReleaseRQ represents an A-RELEASE-RQ PDU.

func (*ReleaseRQ) Encode

func (p *ReleaseRQ) Encode() ([]byte, error)

func (*ReleaseRQ) Type

func (p *ReleaseRQ) Type() byte

type SCP

type SCP struct {
	// contains filtered or unexported fields
}

SCP (Service Class Provider) is a DICOM network server.

func NewSCP

func NewSCP(config SCPConfig) *SCP

NewSCP creates a new SCP with the given configuration.

func (*SCP) Addr

func (s *SCP) Addr() string

Addr returns the listener address, or empty string if not listening.

func (*SCP) Close

func (s *SCP) Close() error

Close stops the SCP server gracefully.

func (*SCP) ListenAndServe

func (s *SCP) ListenAndServe(ctx context.Context) error

ListenAndServe starts the SCP server, listening for incoming associations. It blocks until the context is canceled.

func (*SCP) SetHandler

func (s *SCP) SetHandler(handler Handler)

SetHandler sets the handler for incoming DIMSE requests.

func (*SCP) SetSupportedAbstractSyntaxes

func (s *SCP) SetSupportedAbstractSyntaxes(syntaxes []string)

SetSupportedAbstractSyntaxes sets the abstract syntaxes this SCP supports.

func (*SCP) SetSupportedTransferSyntaxes

func (s *SCP) SetSupportedTransferSyntaxes(syntaxes []string)

SetSupportedTransferSyntaxes sets the transfer syntaxes this SCP supports.

type SCPConfig

type SCPConfig struct {
	// AETitle is the AE title of this SCP.
	AETitle string

	// Port is the TCP port to listen on.
	Port int

	// BindAddress is the address to bind to. Empty string means all interfaces.
	BindAddress string

	// Network holds low-level network settings.
	Network NetworkConfig

	// MaxAssociations is the maximum number of concurrent associations. 0 means unlimited.
	MaxAssociations int
}

SCPConfig holds configuration for a Service Class Provider (server).

type SCPConfigTLS

type SCPConfigTLS struct {
	SCPConfig
	TLS *TLSConfig
}

SCPConfigTLS extends SCPConfig with TLS settings.

type SCPSCURoleSelection

type SCPSCURoleSelection struct {
	SOPClassUID string
	SCURole     bool
	SCPRole     bool
}

SCPSCURoleSelection negotiates SCP/SCU roles for a SOP Class.

func DecodeSCPSCURoleSelection

func DecodeSCPSCURoleSelection(data []byte) (*SCPSCURoleSelection, error)

DecodeSCPSCURoleSelection decodes a SCP/SCU role selection sub-item.

func (*SCPSCURoleSelection) Encode

func (r *SCPSCURoleSelection) Encode() []byte

Encode serializes the SCP/SCU role selection sub-item.

type SCU

type SCU struct {
	// contains filtered or unexported fields
}

SCU (Service Class User) is a DICOM network client.

func NewSCU

func NewSCU(config SCUConfig) *SCU

NewSCU creates a new SCU with the given configuration.

func (*SCU) Abort

func (s *SCU) Abort(ctx context.Context) error

Abort sends an A-ABORT and closes the connection.

func (*SCU) Associate

func (s *SCU) Associate(ctx context.Context, contexts []PresentationContextItem) error

Associate establishes an association with the SCP, proposing the given presentation contexts. If contexts is nil, default verification + storage + query/retrieve contexts are proposed.

func (*SCU) Association added in v1.2.0

func (s *SCU) Association() *Association

Association returns the SCU's current association, or nil when not associated. Use it to inspect what was negotiated — accepted presentation contexts, the agreed transfer syntax per context, and any extended negotiation the peer returned.

func (*SCU) Cancel

func (s *SCU) Cancel(ctx context.Context, messageID uint16) error

Cancel sends a C-CANCEL-RQ to cancel an in-progress C-FIND, C-MOVE, or C-GET.

func (*SCU) Echo

func (s *SCU) Echo(ctx context.Context) error

Echo performs a C-ECHO verification.

func (*SCU) Find

func (s *SCU) Find(ctx context.Context, queryDS *dataset.Dataset) (<-chan *CFindResult, error)

Find performs a C-FIND query and returns results on a channel.

func (*SCU) Get

func (s *SCU) Get(ctx context.Context, queryDS *dataset.Dataset) error

Get performs a C-GET request (retrieve objects on the same association).

func (*SCU) IsAssociated

func (s *SCU) IsAssociated() bool

IsAssociated returns whether the SCU has an active association.

func (*SCU) Move

func (s *SCU) Move(ctx context.Context, queryDS *dataset.Dataset, moveDestination string) error

Move performs a C-MOVE request.

func (*SCU) NAction

func (s *SCU) NAction(ctx context.Context, sopClassUID, sopInstanceUID string, actionTypeID uint16, ds *dataset.Dataset) (*NActionResponse, error)

NAction sends an N-ACTION-RQ.

func (*SCU) NCreate

func (s *SCU) NCreate(ctx context.Context, sopClassUID, sopInstanceUID string, ds *dataset.Dataset) (*NCreateResponse, error)

NCreate sends an N-CREATE-RQ.

func (*SCU) NDelete

func (s *SCU) NDelete(ctx context.Context, sopClassUID, sopInstanceUID string) (*NDeleteResponse, error)

NDelete sends an N-DELETE-RQ.

func (*SCU) NEventReport

func (s *SCU) NEventReport(ctx context.Context, sopClassUID, sopInstanceUID string, eventTypeID uint16, ds *dataset.Dataset) (*NEventReportResponse, error)

NEventReport sends an N-EVENT-REPORT-RQ.

func (*SCU) NGet

func (s *SCU) NGet(ctx context.Context, sopClassUID, sopInstanceUID string) (*NGetResponse, error)

NGet sends an N-GET-RQ.

func (*SCU) NSet

func (s *SCU) NSet(ctx context.Context, sopClassUID, sopInstanceUID string, ds *dataset.Dataset) (*NSetResponse, error)

NSet sends an N-SET-RQ.

func (*SCU) Release

func (s *SCU) Release(ctx context.Context) error

Release performs an orderly release of the association.

func (*SCU) Store

func (s *SCU) Store(ctx context.Context, ds *dataset.Dataset) error

Store sends a DICOM dataset to the SCP using C-STORE.

type SCUConfig

type SCUConfig struct {
	// CallingAE is the AE title of this SCU (the client).
	CallingAE string

	// CalledAE is the AE title of the target SCP (the server).
	CalledAE string

	// Address is the target address in "host:port" format.
	Address string

	// Network holds low-level network settings.
	Network NetworkConfig

	// ExtendedNegotiation carries optional A-ASSOCIATE-RQ extended negotiation
	// items: asynchronous operations window, SCP/SCU role selection, and user
	// identity (username/password, Kerberos, SAML, JWT). Nil proposes none.
	ExtendedNegotiation *ExtendedNegotiation
}

SCUConfig holds configuration for a Service Class User (client).

type SCUConfigTLS

type SCUConfigTLS struct {
	SCUConfig
	TLS *TLSConfig
}

SCUConfigTLS extends SCUConfig with TLS settings.

type SOPClassExtendedNegotiation

type SOPClassExtendedNegotiation struct {
	SOPClassUID string
	ServiceData []byte
}

SOPClassExtendedNegotiation carries service-specific negotiation data.

func DecodeSOPClassExtendedNegotiation added in v1.2.0

func DecodeSOPClassExtendedNegotiation(data []byte) (*SOPClassExtendedNegotiation, error)

DecodeSOPClassExtendedNegotiation decodes a SOP Class Extended Negotiation sub-item: a 2-byte UID length, the SOP Class UID, then service-class-specific application information filling the remainder.

func (*SOPClassExtendedNegotiation) Encode

func (s *SOPClassExtendedNegotiation) Encode() []byte

Encode serializes the SOP Class Extended Negotiation sub-item.

type Server

type Server struct {

	// Events provides hooks into server lifecycle events.
	Events *EventManager

	// Logger for this server instance.
	Logger *Logger
	// contains filtered or unexported fields
}

Server represents a non-blocking DICOM SCP server. Unlike SCP.ListenAndServe (which blocks), Server can be started and stopped programmatically, allowing multiple servers to run simultaneously in the same process.

Example — run 3 servers simultaneously:

echoServer := network.StartServer(ctx, network.SCPConfig{AETitle: "ECHO", Port: 11112}, &network.EchoHandler{})
storeServer := network.StartServer(ctx, network.SCPConfig{AETitle: "STORE", Port: 11113}, storeHandler)
wlServer := network.StartServer(ctx, network.SCPConfig{AETitle: "WORKLIST", Port: 11114}, worklistHandler)

// All three are running concurrently
fmt.Println(echoServer.Addr())    // "0.0.0.0:11112"
fmt.Println(storeServer.Addr())   // "0.0.0.0:11113"
fmt.Println(wlServer.Addr())      // "0.0.0.0:11114"

// Stop one
echoServer.Stop()

// Wait for all to finish
storeServer.Wait()
wlServer.Wait()

func StartServer

func StartServer(ctx context.Context, config SCPConfig, handler Handler) (*Server, error)

StartServer creates and starts a non-blocking DICOM SCP server. Returns immediately. The server runs in a background goroutine.

func StartServerTLS

func StartServerTLS(ctx context.Context, config SCPConfig, handler Handler, tlsCfg *TLSConfig) (*Server, error)

StartServerTLS creates and starts a TLS-encrypted DICOM SCP server.

func (*Server) Addr

func (s *Server) Addr() string

Addr returns the server's listening address.

func (*Server) SetHandler

func (s *Server) SetHandler(handler Handler)

SetHandler changes the server's DIMSE handler.

func (*Server) SetSupportedAbstractSyntaxes

func (s *Server) SetSupportedAbstractSyntaxes(syntaxes []string)

SetSupportedAbstractSyntaxes configures which SOP Classes this server accepts.

func (*Server) SetSupportedTransferSyntaxes

func (s *Server) SetSupportedTransferSyntaxes(syntaxes []string)

SetSupportedTransferSyntaxes configures which Transfer Syntaxes this server accepts.

func (*Server) Stop

func (s *Server) Stop()

Stop gracefully stops the server.

func (*Server) Wait

func (s *Server) Wait()

Wait blocks until the server has stopped.

type ServerGroup

type ServerGroup struct {
	// contains filtered or unexported fields
}

ServerGroup manages multiple DICOM servers running simultaneously.

Example:

group := network.NewServerGroup()
group.Add(ctx, network.SCPConfig{AETitle: "ECHO", Port: 11112}, &network.EchoHandler{})
group.Add(ctx, network.SCPConfig{AETitle: "STORE", Port: 11113}, storeHandler)
group.Add(ctx, network.SCPConfig{AETitle: "QR", Port: 11114}, qrHandler)
// ... all 3 running ...
group.StopAll()

func NewServerGroup

func NewServerGroup() *ServerGroup

NewServerGroup creates a new ServerGroup.

func (*ServerGroup) Add

func (g *ServerGroup) Add(ctx context.Context, config SCPConfig, handler Handler) (*Server, error)

Add creates and starts a new server, adding it to the group.

func (*ServerGroup) AddTLS

func (g *ServerGroup) AddTLS(ctx context.Context, config SCPConfig, handler Handler, tlsCfg *TLSConfig) (*Server, error)

AddTLS creates and starts a new TLS server, adding it to the group.

func (*ServerGroup) Count

func (g *ServerGroup) Count() int

Count returns the number of servers in the group.

func (*ServerGroup) Servers

func (g *ServerGroup) Servers() []*Server

Servers returns all servers in the group.

func (*ServerGroup) StopAll

func (g *ServerGroup) StopAll()

StopAll stops all servers in the group.

func (*ServerGroup) WaitAll

func (g *ServerGroup) WaitAll()

WaitAll blocks until all servers have stopped.

type StatusCategory

type StatusCategory int

StatusCategory represents the category of a DICOM status code.

const (
	StatusCategorySuccess StatusCategory = iota
	StatusCategoryPending
	StatusCategoryCancel
	StatusCategoryWarning
	StatusCategoryFailure
	StatusCategoryUnknown
)

func CategorizeStatus

func CategorizeStatus(status uint16) StatusCategory

CategorizeStatus returns the category of a DICOM status code.

func (StatusCategory) String

func (sc StatusCategory) String() string

String returns the name of the status category.

type StorageHandler

type StorageHandler struct {
	BaseHandler
	OnStore func(ctx context.Context, sopClassUID, sopInstanceUID string, ds *dataset.Dataset) uint16
}

StorageHandler is a handler that accepts C-STORE requests and calls a callback.

func (*StorageHandler) HandleCStore

func (h *StorageHandler) HandleCStore(ctx context.Context, req *CStoreRequest) (*CStoreResponse, error)

HandleCStore delegates to the OnStore callback if set.

type TLSConfig

type TLSConfig struct {
	// CertFile is the path to the TLS certificate file (PEM format).
	CertFile string

	// KeyFile is the path to the TLS private key file (PEM format).
	KeyFile string

	// CAFile is the path to the CA certificate file for client verification.
	CAFile string

	// InsecureSkipVerify disables certificate verification (for testing only).
	InsecureSkipVerify bool

	// ServerName is the expected server hostname for certificate verification.
	ServerName string

	// MinVersion is the minimum TLS version (default: TLS 1.2).
	MinVersion uint16

	// Config allows providing a custom *tls.Config directly.
	// If set, CertFile/KeyFile/CAFile are ignored.
	Config *tls.Config
}

TLSConfig holds TLS configuration for encrypted DICOM communication. DICOM Part 15 recommends TLS for HIPAA compliance and PHI protection.

type TimeoutError

type TimeoutError struct {
	Message   string
	Code      string
	Detail    string
	Operation string
}

TimeoutError represents a network operation timeout.

func NewTimeoutError

func NewTimeoutError(operation, message string) *TimeoutError

NewTimeoutError creates a new timeout error.

func (*TimeoutError) Details

func (e *TimeoutError) Details() string

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

func (*TimeoutError) ErrorCode

func (e *TimeoutError) ErrorCode() string

type Transport

type Transport struct {
	// contains filtered or unexported fields
}

Transport wraps a TCP connection with DICOM-specific read/write operations.

func Dial

func Dial(ctx context.Context, address string, timeout time.Duration) (*Transport, error)

Dial establishes a TCP connection to the given address.

func DialTLS

func DialTLS(ctx context.Context, address string, timeout time.Duration, tlsCfg *TLSConfig) (*Transport, error)

DialTLS establishes a TLS-encrypted TCP connection.

func NewTransport

func NewTransport(conn net.Conn, maxPDUSize uint32) *Transport

NewTransport creates a new Transport wrapping an existing connection.

func (*Transport) Close

func (t *Transport) Close() error

Close closes the underlying TCP connection.

func (*Transport) IsClosed

func (t *Transport) IsClosed() bool

IsClosed returns whether the transport has been closed.

func (*Transport) LocalAddr

func (t *Transport) LocalAddr() net.Addr

LocalAddr returns the local network address.

func (*Transport) MaxPDUSize

func (t *Transport) MaxPDUSize() uint32

MaxPDUSize returns the current maximum PDU size.

func (*Transport) ReadPDU

func (t *Transport) ReadPDU(ctx context.Context) (PDU, error)

ReadPDU reads and decodes a PDU from the connection.

func (*Transport) RemoteAddr

func (t *Transport) RemoteAddr() net.Addr

RemoteAddr returns the remote network address.

func (*Transport) SetMaxPDUSize

func (t *Transport) SetMaxPDUSize(size uint32)

SetMaxPDUSize updates the maximum PDU size (typically after negotiation).

func (*Transport) WritePDU

func (t *Transport) WritePDU(ctx context.Context, pdu PDU) error

WritePDU encodes and sends a PDU over the connection.

type UserIdentityNegotiation

type UserIdentityNegotiation struct {
	Type                      UserIdentityType
	PositiveResponseRequested bool
	PrimaryField              []byte // Username, Kerberos ticket, SAML assertion, or JWT
	SecondaryField            []byte // Password (only for UserIdentityUsernamePassword)
}

UserIdentityNegotiation provides user identity in association requests.

func DecodeUserIdentityNegotiation

func DecodeUserIdentityNegotiation(data []byte) (*UserIdentityNegotiation, error)

DecodeUserIdentityNegotiation decodes a user identity negotiation sub-item.

func (*UserIdentityNegotiation) Encode

func (u *UserIdentityNegotiation) Encode() []byte

Encode serializes the user identity negotiation sub-item.

type UserIdentityResponse

type UserIdentityResponse struct {
	ServerResponse []byte
}

UserIdentityResponse represents the server response to user identity negotiation.

func (*UserIdentityResponse) Encode

func (u *UserIdentityResponse) Encode() []byte

Encode serializes the user identity response sub-item.

type UserIdentityType

type UserIdentityType byte

UserIdentityType defines the type of user identity negotiation.

const (
	UserIdentityUsername         UserIdentityType = 1
	UserIdentityUsernamePassword UserIdentityType = 2
	UserIdentityKerberos         UserIdentityType = 3
	UserIdentitySAML             UserIdentityType = 4
	UserIdentityJWT              UserIdentityType = 5
)

type UserInformationItem

type UserInformationItem struct {
	MaxPDULength           uint32
	ImplementationClassUID string
	ImplementationVersion  string

	// AsyncOperations carries the Asynchronous Operations Window sub-item
	// (PS3.7 D.3.3.3) when the peer negotiates one. Nil when absent.
	AsyncOperations *AsynchronousOperationsWindow

	// RoleSelections carries SCP/SCU Role Selection sub-items (PS3.7 D.3.3.4),
	// which let an SCU also act as an SCP for a SOP Class — required by C-GET.
	RoleSelections []SCPSCURoleSelection

	// UserIdentity carries the User Identity Negotiation sub-item
	// (PS3.7 D.3.3.7) used for username/password, Kerberos, SAML, or JWT auth.
	UserIdentity *UserIdentityNegotiation

	// UserIdentityResponse carries the server's identity response in an
	// A-ASSOCIATE-AC. Nil when absent.
	UserIdentityResponse *UserIdentityResponse

	// SOPClassExtended carries SOP Class Extended Negotiation sub-items
	// (PS3.7 D.3.3.5) holding service-class-specific data.
	SOPClassExtended []SOPClassExtendedNegotiation
}

UserInformationItem holds user information sub-items.

type WorklistHandler

type WorklistHandler struct {
	BaseHandler
	OnWorklist func(ctx context.Context, query *dataset.Dataset) ([]*dataset.Dataset, error)
}

WorklistHandler handles Modality Worklist (MWL) queries.

func (*WorklistHandler) HandleCFind

func (h *WorklistHandler) HandleCFind(ctx context.Context, req *CFindRequest) ([]*CFindResponse, error)

HandleCFind delegates worklist queries to the OnWorklist callback.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL