DcmSCP, event handling, and etc ...

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
wrenashe
Posts: 20
Joined: Tue, 2013-10-08, 11:24

DcmSCP, event handling, and etc ...

#1 Post by wrenashe »

I am new to dcmtk tool and developing an app based on the dcmtk. The app is event processing framework deployed.

My idea is to new a socket event of scp listen socket, and in its event callback to do DIMSE command processing.

What I did is,

1. MyDcmSCP : DcmSCP

in MyDcmSCP,
2. a new member variable T_ASC_NETWORK *m_network added
3. overrided listen() : just return after ASC_initializeNetwork() is done, and have member variable m_network initialized instead of the local one like DcmSCP->listen()
4. a new member function getListenSock() is added to get socket on listening port.

Code: Select all

int  MyDcmSCP ::getListenSock() {
  if (m_network == NULL)
    return -1;
  else {
    PRIVATE_NETWORKKEY ** networkKey = (PRIVATE_NETWORKKEY **) &(m_network->network);
    return (*networkKey)->networkSpecific.TCP.listenSocket;
  }
}

4. a new member function waitForAssociationRequest() added and it will be called when listen socket event is triggered, in it DcmSCP->waitForAssociationRQ() is called and with the m_network initialized in #3.

Code: Select all

OFCondition MyDcmSCP::waitForAssociationRequest()
{

    if (m_network == NULL)
        return ASC_NULLKEY;

    OFCondition cond = EC_Normal;
    cond = waitForAssociationRQ(m_network);
    return cond;
}
5. handleIncomingCommand() is also overrided to handle the DIMSE commands.

And in the code, when MyDcmSCP->listen() is called, m_network is initialized, register a socket event which is obtained by getListenSock(). Then when a SCU request comes in , the event handler is fired to do the waitForAssociationRequest() . And now the problem is Association Abort thing always happens there. Was it the bad thing that m_network variable used like that? The reason to use it because I have no other way to pass the T_ASC_Netowrk to DcmSCP->waitForAssociationRQ().

Thanks for any guideline...

The SCP side,
[in:10/09/2013 15:31:06] Processing SOCKET (DICOM driver association listen/read) event 0x044A04A0
[in:10/09/2013 15:31:06] Calling cb 0x455a10
D: setting network send timeout to 60 seconds
D: setting network receive timeout to 60 seconds
T: DUL FSM Table: State: 1 Event: 4
T: DUL Event: Transport connection indication
T: DUL Action: AE 5 Transport Connect Response
T: Read PDU HEAD TCP: 01 00 00 00 00 cd
T: Read PDU HEAD TCP: type: 01, length: 205 (cd)
T: DUL FSM Table: State: 2 Event: 5
T: DUL Event: A-ASSOCIATE-RQ PDU (on transport)
T: DUL Action: AE 6 Examine Associate Request
D: PDU Type: Associate Request, PDU Length: 205 + 6 bytes PDU header
D: 01 00 00 00 00 cd 00 01 00 00 41 4e 59 2d 53 43
D: 50 20 20 20 20 20 20 20 20 20 45 43 48 4f 53 43
D: 55 20 20 20 20 20 20 20 20 20 00 00 00 00 00 00
D: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
D: 00 00 00 00 00 00 00 00 00 00 10 00 00 15 31 2e
D: 32 2e 38 34 30 2e 31 30 30 30 38 2e 33 2e 31 2e
D: 31 2e 31 20 00 00 2e 01 00 ff 00 30 00 00 11 31
D: 2e 32 2e 38 34 30 2e 31 30 30 30 38 2e 31 2e 31
D: 40 00 00 11 31 2e 32 2e 38 34 30 2e 31 30 30 30
D: 38 2e 31 2e 32 50 00 00 3a 51 00 00 04 00 00 40
D: 00 52 00 00 1b 31 2e 32 2e 32 37 36 2e 30 2e 37
D: 32 33 30 30 31 30 2e 33 2e 30 2e 33 2e 36 2e 30
D: 55 00 00 0f 4f 46 46 49 53 5f 44 43 4d 54 4b 5f
D: 33 36 30
D: Parsing an A-ASSOCIATE PDU
T: PDU type: 1 (A-ASSOCIATE RQ), PDU Length: 205
T: DICOM Protocol: 1
T: Called AP Title: ANY-SCP
T: Calling AP Title: ECHOSCU
T: Parsing remaining 137 bytes of A-ASSOCIATE PDU
T: Next item type: 10
T: Subitem parse: Type 10, Length 0021, Content: 1.2.840.10008.3.1.1.1
T: Successfully parsed Application Context
T: Parsing remaining 112 bytes of A-ASSOCIATE PDU
T: Next item type: 20
T: Parsing Presentation Context: (20), Length: 46
T: Presentation Context ID: 01
T: Parsing remaining 42 bytes of Presentation Context
T: Next item type: 30
T: Subitem parse: Type 30, Length 0017, Content: 1.2.840.10008.1.1
T: Successfully parsed Abstract Syntax
T: Parsing remaining 21 bytes of Presentation Context
T: Next item type: 40
T: Subitem parse: Type 40, Length 0017, Content: 1.2.840.10008.1.2
T: Successfully parsed Transfer Syntax
T: Successfully parsed Presentation Context
T: Parsing remaining 62 bytes of A-ASSOCIATE PDU
T: Next item type: 50
T: Parsing user info field (50), Length: 58
T: Parsing remaining 58 bytes of User Information
T: Next item type: 51
T: Maximum PDU Length: 16384
T: Successfully parsed Maximum PDU Length
T: Parsing remaining 50 bytes of User Information
T: Next item type: 52
T: Subitem parse: Type 52, Length 0027, Content: 1.2.276.0.7230010.3.0.3.6.0
T: Parsing remaining 19 bytes of User Information
T: Next item type: 55
T: Subitem parse: Type 55, Length 0015, Content: OFFIS_DCMTK_360
T: Successfully parsed User Information
I: Association Received localhost: ECHOSCU -> ANY-SCP
D: Incoming Association Request:
D: ====================== BEGIN A-ASSOCIATE-RQ =====================
D: Our Implementation Class UID: 1.2.276.0.7230010.3.0.3.6.1
D: Our Implementation Version Name: OFFIS_DCMTK_361
D: Their Implementation Class UID: 1.2.276.0.7230010.3.0.3.6.0
D: Their Implementation Version Name: OFFIS_DCMTK_360
D: Application Context Name: 1.2.840.10008.3.1.1.1
D: Calling Application Name: ECHOSCU
D: Called Application Name: ANY-SCP
D: Responding Application Name:
D: Our Max PDU Receive Size: 16384
D: Their Max PDU Receive Size: 16384
D: Presentation Contexts:
D: Context ID: 1 (Proposed)
D: Abstract Syntax: =VerificationSOPClass
D: Proposed SCP/SCU Role: Default
D: Proposed Transfer Syntax(es):
D: =LittleEndianImplicit
D: Requested Extended Negotiation: none
D: Accepted Extended Negotiation: none
D: Requested User Identity Negotiation: none
D: User Identity Negotiation Response: none
D: ======================= END A-ASSOCIATE-RQ ======================
T: DUL FSM Table: State: 3 Event: 6
T: DUL Event: A-ASSOCIATE resp prim (accept)
T: DUL Action: AE 7 Send Associate AC
D: Constructing Associate AC PDU
D: DcmSCP: Association Acknowledged
I: Association Acknowledged (Max Send PDV: 16372)
D: ====================== BEGIN A-ASSOCIATE-AC =====================
D: Our Implementation Class UID: 1.2.276.0.7230010.3.0.3.6.1
D: Our Implementation Version Name: OFFIS_DCMTK_361
D: Their Implementation Class UID: 1.2.276.0.7230010.3.0.3.6.0
D: Their Implementation Version Name: OFFIS_DCMTK_360
D: Application Context Name: 1.2.840.10008.3.1.1.1
D: Calling Application Name: ECHOSCU
D: Called Application Name: ANY-SCP
D: Responding Application Name: ANY-SCP
D: Our Max PDU Receive Size: 16384
D: Their Max PDU Receive Size: 16384
D: Presentation Contexts:
D: Context ID: 1 (Accepted)
D: Abstract Syntax: =VerificationSOPClass
D: Proposed SCP/SCU Role: Default
D: Accepted SCP/SCU Role: Default
D: Accepted Transfer Syntax: =LittleEndianImplicit
D: Requested Extended Negotiation: none
D: Accepted Extended Negotiation: none
D: Requested User Identity Negotiation: none
D: User Identity Negotiation Response: none
D: ======================= END A-ASSOCIATE-AC ======================
T: DIMSE receiveCommand
T: Read PDU HEAD TCP: 04 00 00 00 00 4a
T: Read PDU HEAD TCP: type: 04, length: 74 (4a)
T: DUL FSM Table: State: 6 Event: 9
T: DUL Event: P-DATA-TF PDU (on transport)
T: DUL Action: DT 2 Indicate P DATA PDU Received
D: DcmDataset::read() TransferSyntax="Little Endian Implicit"
T: DcmItem::readTagAndLength() TransferSyntax="Little Endian Implicit"
T: DcmItem::insert() Element (0000,0000) VR="UL" inserted at beginning
T: DcmItem::readSubItem() returns error = Normal
T: DcmItem::readTagAndLength() TransferSyntax="Little Endian Implicit"
T: DcmItem::insert() Element (0000,0002) VR="UI" inserted
T: DcmItem::readSubItem() returns error = Normal
T: DcmItem::readTagAndLength() TransferSyntax="Little Endian Implicit"
T: DcmItem::insert() Element (0000,0100) VR="US" inserted
T: DcmItem::readSubItem() returns error = Normal
T: DcmItem::readTagAndLength() TransferSyntax="Little Endian Implicit"
T: DcmItem::insert() Element (0000,0110) VR="US" inserted
T: DcmItem::readSubItem() returns error = Normal
T: DcmItem::readTagAndLength() TransferSyntax="Little Endian Implicit"
T: DcmItem::insert() Element (0000,0800) VR="US" inserted
T: DcmItem::readSubItem() returns error = Normal
T: DcmItem::readTagAndLength() TransferSyntax="Little Endian Implicit"
T: DcmItem::read() returns error = Normal
T: DcmDataset::read() returns error = Normal
T: DIMSE receiveCommand: 1 PDVs (68 bytes), PresID=1
T: DIMSE Command Received:
T:
T: # Dicom-Data-Set
T: # Used TransferSyntax: Little Endian Implicit
T: (0000,0002) UI =VerificationSOPClass # 18, 1 AffectedSOPClassUID
T: (0000,0100) US 48 # 2, 1 CommandField
T: (0000,0110) US 1 # 2, 1 MessageID
T: (0000,0800) US 257 # 2, 1 CommandDataSetType
T:
T: DcmItem::searchSubFromHere() Element (0000,0100) found
T: DcmItem::searchSubFromHere() Element (0000,0100) found
T: DcmItem::searchSubFromHere() Element (0000,0110) found
T: DcmItem::searchSubFromHere() Element (0000,0800) found
T: DcmItem::searchSubFromHere() Element (0000,0002) found
I: Received C-ECHO Request
D: ===================== INCOMING DIMSE MESSAGE ====================
D: Message Type : C-ECHO RQ
D: Presentation Context ID : 1
D: Message ID : 1
D: Data Set : none
D: ======================= END DIMSE MESSAGE =======================
I: Sending C-ECHO Response
T: DcmItem::insert() Element (0000,0000) VR="UL" inserted at beginning
T: DcmItem::insert() Element (0000,0100) VR="US" inserted
T: DcmItem::insert() Element (0000,0120) VR="US" inserted
T: DcmItem::insert() Element (0000,0800) VR="US" inserted
T: DcmItem::insert() Element (0000,0900) VR="US" inserted
T: DcmItem::insert() Element (0000,0002) VR="UI" inserted
T: DIMSE Command to be sent on Presentation Context ID: 1
T: DIMSE Command to send:
T:
T: # Dicom-Data-Set
T: # Used TransferSyntax: Little Endian Explicit
T: (0000,0000) UL 0 # 4, 1 CommandGroupLength
T: (0000,0002) UI =VerificationSOPClass # 18, 1 AffectedSOPClassUID
T: (0000,0100) US 32816 # 2, 1 CommandField
T: (0000,0120) US 1 # 2, 1 MessageIDBeingRespondedTo
T: (0000,0800) US 257 # 2, 1 CommandDataSetType
T: (0000,0900) US 0 # 2, 1 Status
T:
T: DIMSE sendDcmDataset: sending 78 bytes
T: DUL FSM Table: State: 6 Event: 8
T: DUL Event: P-DATA request primitive
T: DUL Action: DT 1 Send P DATA PDU
D: C-ECHO Response successfully sent
T: DIMSE receiveCommand
T: DUL FSM Table: State: 6 Event: 16
T: DUL Event: Transport connection closed
T: DUL Action: AA 4 Indicate AP Abort
I: Received Association Abort Request
D: DcmSCP: Association Terminated
D: +++++++++++++++++++++++++++++

The SCU side,

E:\dcmtk\dcmtk-3.6.0-win32-i386\bin>echoscu -v localhost 1112
I: Requesting Association
I: Association Accepted (Max Send PDV: 16372)
I: Sending Echo Request: MsgID 1
I: Received Echo Response (Status: Success)
I: Releasing Association
F: Association Release Failed: 0006:0317 Peer aborted Association (or never connected)

J. Riesmeier
DCMTK Developer
Posts: 2506
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: DcmSCP, event handling, and etc ...

#2 Post by J. Riesmeier »

I'm sorry but I don't get what you intend to do... Could you please describe in a few sentences what the background of your modifications is?

wrenashe
Posts: 20
Joined: Tue, 2013-10-08, 11:24

Re: DcmSCP, event handling, and etc ...

#3 Post by wrenashe »

J. Riesmeier wrote:I'm sorry but I don't get what you intend to do... Could you please describe in a few sentences what the background of your modifications is?
Thanks for such a prompt response.

I have an app to develop which is event processing system. I want to register a scp listen socket event to the system, and when scu request comes in , that event will be fired by the system, in event handler, I want to accept scu DIMSE command and do further DICOM processing.
By the way, I am working on windows with visual studio 2008 debug env, and dcmtk code is the snapshot of 20130920...
Header file,

Code: Select all

#include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
#include "dcmtk/dcmnet/diutil.h"
#include "dcmtk/dcmnet/scp.h"


class MyDcmSCP : public DcmSCP
{

public:
    MyDcmSCP();
    ~MyDcmSCP();

    //override listen() for event processing instead.
    OFCondition listen();
    OFCondition  waitForAssociationRequest();
    int  getNetworkSocket();
    
 protected:
    virtual OFCondition handleIncomingCommand(T_DIMSE_Message *incomingMsg,
                                              const DcmPresentationContextInfo &presContextInfo);
    virtual Uint16 checkAndProcessSTORERequest(const T_DIMSE_C_StoreRQ &reqMessage,
                                               DcmFileFormat &fileformat);

private:
    T_ASC_Network *m_network;
};

Class file,

Code: Select all

#include "MyDcmSCP.h"
#include "dcmtk/dcmnet/dulstruc.h"

MyDcmSCP::MyDcmSCP()   
    : DcmSCP(), m_stopAfterAssoc(OFFalse), m_network(NULL) {

     // make sure that the SCP at least supports C-ECHO with default transfer syntax
    OFList<OFString> transferSyntaxes;
    transferSyntaxes.push_back(UID_LittleEndianImplicitTransferSyntax);
    addPresentationContext(UID_VerificationSOPClass, transferSyntaxes);
};

MyDcmSCP::~MyDcmSCP() 
{ 
  if (m_network != NULL)
    ASC_dropNetwork( &m_network );

};

//override listen() for event processing instead.
OFCondition MyDcmSCP::listen()
{
    // make sure not to let dcmdata remove trailing blank padding or perform other
    // manipulations. We want to see the real data.
    dcmEnableAutomaticInputDataCorrection.set( OFFalse );

    OFCondition cond = EC_Normal;
    // Make sure data dictionary is loaded.
    if ( !dcmDataDict.isDictionaryLoaded() )
        DCMNET_WARN("No data dictionary loaded, check environment variable: " << DCM_DICT_ENVIRONMENT_VARIABLE);

    

    //m_cfg = getConfig();
    //setConfig((DcmSCPConfig *)m_cfg);

#ifndef DISABLE_PORT_PERMISSION_CHECK
#ifdef HAVE_GETEUID
    // If port is privileged we must be as well.
    if ( m_cfg->getPort() < 1024 && geteuid() != 0 )
    {
        DCMNET_ERROR("No privileges to open this network port (" << m_cfg->getPort() << ")");
        return NET_EC_InsufficientPortPrivileges;
    }
#endif
#endif

    // Initialize network, i.e. create an instance of T_ASC_Network*.    
    cond = ASC_initializeNetwork( NET_ACCEPTOR, getPort(), 10, &m_network );
    if ( cond.bad() )
        return cond;

#if defined(HAVE_SETUID) && defined(HAVE_GETUID)
    // Return to normal uid so that we can't do too much damage in case
    // things go very wrong. Only works if the program is setuid root,
    // and run by another user. Running as root user may be
    // potentially disastrous if this program screws up badly.
    setuid( getuid() );
#endif

    // If we get to this point, the entire initialization process has been completed
    // successfully. Now, we want to start handling all incoming requests. Since
    // this activity is supposed to represent a server process, we do not want to
    // terminate this activity (unless indicated by the stopAfterCurrentAssociation()
    // method). Hence, create an infinite while-loop.
    // while( cond.good() && !stopAfterCurrentAssociation() )
    // {
    //   // Wait for an association and handle the requests of
    //   // the calling applications correspondingly.
   // cond = waitForAssociationRQ(m_network);
    // }
    // // Drop the network, i.e. free memory of T_ASC_Network* structure. This call
    // // is the counterpart of ASC_initializeNetwork(...) which was called above.
    // cond = ASC_dropNetwork( &network );
    // network = NULL;

    // // return ok

    //reserve it, for waitForAssociationRQ(network);
    return cond;

}

OFCondition MyDcmSCP::waitForAssociationRequest()
{

    if (m_network == NULL)
        return ASC_NULLKEY;

    OFCondition cond = EC_Normal;
    cond = waitForAssociationRQ(m_network);
    return cond;

}


int  MyDcmSCP::getNetworkSocket() {

  if (m_network == NULL)
    return -1;
  else {
    PRIVATE_NETWORKKEY ** networkKey = (PRIVATE_NETWORKKEY **) &(m_network->network);
    return (*networkKey)->networkSpecific.TCP.listenSocket;
  }
}

OFCondition MyDcmSCP::loadAssociationConfiguration(const OFString &filename) {
    // first, try to load the configuration file
    OFCondition status = loadAssociationCfgFile(filename);
    // and then, try to select the desired profile
    //if (status.good())
    //    status = setAndCheckAssociationProfile(profile);
    return status;
}


OFCondition MyDcmSCP::handleIncomingCommand(T_DIMSE_Message *incomingMsg,
                                                 const DcmPresentationContextInfo &info)
{
    OFCondition status = EC_IllegalParameter;
    if (incomingMsg != NULL)
    {
        // check whether we've received a supported command
        if (incomingMsg->CommandField == DIMSE_C_ECHO_RQ)
        {
            // handle incoming C-ECHO request
            status = handleECHORequest(incomingMsg->msg.CEchoRQ, info.presentationContextID);
        }
        else if (incomingMsg->CommandField == DIMSE_C_STORE_RQ)
        {
           : 
        }
    }
    return status;
}
Event processing pesudo code,

Code: Select all

eventRegister()
{
   dcmApp = new MyDcmSCP();
   dcmApp->setPort(10014);
   :
   dcmApp->listen();
   
   registerSocketEvent(dcmApp->getNetworkSocket(), (void*)listenSocketeventCallback, (void*)dcmApp )

}

listenSocketeventCallback(void *ev) {
   dcmApp = (MyDcmSCP *) ev;
   dcmApp->waitForAssociationRequest();

}

wrenashe
Posts: 20
Joined: Tue, 2013-10-08, 11:24

Re: DcmSCP, event handling, and etc ...

#4 Post by wrenashe »

And when use storescu, it goes like this,

storescu side,

Code: Select all

:
D: Accepted Extended Negotiation:  none
D: Requested User Identity Negotiation: none
D: User Identity Negotiation Response:  none
D: ======================= END A-ASSOCIATE-AC ======================
I: Association Accepted (Max Send PDV: 16372)
I: Sending file: ..\..\image.dcm
D: DcmItem::checkTransferSyntax() TransferSyntax="Little Endian Explicit"
I: Transfer Syntax: JPEG2000 -> JPEG2000
I: Sending Store Request: MsgID 1, (MR)
D: ===================== OUTGOING DIMSE MESSAGE ====================
D: Message Type                  : C-STORE RQ
D: Message ID                    : 1
D: Affected SOP Class UID        : MRImageStorage
D: Affected SOP Instance UID     : 1.3.12.2.1107.5.2.5.11090.5.0.582367642721155
2
D: Data Set                      : present
D: Priority                      : low
D: ======================= END DIMSE MESSAGE =======================
E: Store Failed, file: ..\..\image.dcm:
E: 0006:020e DIMSE Failed to send message
E: 0006:031d TCP I/O Error (No error) occurred in routine: writeDataPDU
E: Store SCU Failed: 0006:020e DIMSE Failed to send message
E: 0006:031d TCP I/O Error (No error) occurred in routine: writeDataPDU
I: Aborting Association
E: Association Abort Failed: 0006:031d TCP I/O Error (No error) occurred in routine: sendAbortTCP
scp side,

Code: Select all

:
D: Requested Extended Negotiation: none
D: Accepted Extended Negotiation:  none
D: Requested User Identity Negotiation: none
D: User Identity Negotiation Response:  none
D: ======================= END A-ASSOCIATE-AC ======================
T: DIMSE receiveCommand
T: DUL  FSM Table: State: 6 Event: 16
T: DUL  Event:  Transport connection closed
T: DUL  Action: AA 4 Indicate AP Abort
I: Received Association Abort Request
D: DcmSCP: Association Terminated
D: +++++++++++++++++++++++++++++
Was that socket accept issue?

wrenashe
Posts: 20
Joined: Tue, 2013-10-08, 11:24

Re: DcmSCP, event handling, and etc ...

#5 Post by wrenashe »

The problem is DUL_NETWORKCLOSED occurred. The accpet socket looks not available at that time. It looks strange to me, that is in Visual studio 2008 debugging evironment(the same issue occurred in release version of my app). The screenshot is here http://yunpan.cn/QbB9NKpjjcc7T

call stack is,
> dcmtk.dll!defragmentTCP(DcmTransportConnection * connection=0x044a7de0, DUL_BLOCKOPTIONS block=DUL_BLOCK, __int64 timerStart=0, int timeout=0, void * p=0x044a369c, unsigned long l=6, unsigned long * rtnLen=0x043eed28) Line 3651 C++
dcmtk.dll!readPDUHeadTCP(PRIVATE_ASSOCIATIONKEY * * association=0x044a3180, unsigned char * buffer=0x044a369c, unsigned long maxLength=6, DUL_BLOCKOPTIONS block=DUL_BLOCK, int timeout=0, unsigned char * type=0x044a36a2, unsigned char * reserved=0x044a36a3, unsigned long * pduLength=0x044a36a4) Line 3431 + 0x3a bytes C++
dcmtk.dll!readPDUHead(PRIVATE_ASSOCIATIONKEY * * association=0x044a3180, unsigned char * buffer=0x044a369c, unsigned long maxLength=6, DUL_BLOCKOPTIONS block=DUL_BLOCK, int timeout=0, unsigned char * PDUType=0x044a36a2, unsigned char * PDUReserved=0x044a36a3, unsigned long * PDULength=0x044a36a4) Line 3297 + 0x43 bytes C++
dcmtk.dll!PRV_NextPDUType(PRIVATE_ASSOCIATIONKEY * * association=0x044a3180, DUL_BLOCKOPTIONS block=DUL_BLOCK, int timeout=0, unsigned char * pduType=0x043eefcf) Line 3181 + 0x46 bytes C++
dcmtk.dll!DUL_ReadPDVs(void * * callerAssociation=0x044a3180, DUL_PDVLIST * pdvList=0x00000000, DUL_BLOCKOPTIONS block=DUL_BLOCK, int timeout=0) Line 1145 + 0x19 bytes C++
dcmtk.dll!DIMSE_readNextPDV(T_ASC_Association * assoc=0x044a3180, T_DIMSE_BlockingMode blocking=DIMSE_BLOCKING, int timeout=0, DUL_PDV * pdv=0x043ef618) Line 266 + 0x17 bytes C++
dcmtk.dll!DIMSE_receiveCommand(T_ASC_Association * assoc=0x044a3180, T_DIMSE_BlockingMode blocking=DIMSE_BLOCKING, int timeout=0, unsigned char * presID=0x043ef7eb, T_DIMSE_Message * msg=0x043ef7f4, DcmDataset * * statusDetail=0x00000000, DcmDataset * * commandSet=0x00000000) Line 1182 + 0x1c bytes C++
dcmtk.dll!DcmSCP::handleAssociation() Line 589 + 0x3a bytes C++
dcmtk.dll!DcmSCP::processAssociationRQ() Line 544 + 0x12 bytes C++
dcmtk.dll!DcmSCP::waitForAssociationRQ(T_ASC_Network * network=0x044a21f0) Line 433 + 0x16 bytes C++
myapp.exe!MyDcmSCP::waitForAssociationRequest() Line 136 + 0x1b bytes C++
I really appreciate that if some comments were put here.

Tao

J. Riesmeier
DCMTK Developer
Posts: 2506
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: DcmSCP, event handling, and etc ...

#6 Post by J. Riesmeier »

In don't know what the registerSocketEvent() does but my first guess would be that your "event system" does something with the network socket that prevents the DCMTK network routines from working correctly. So, the only thing I can recommend is: do further debugging...

wrenashe
Posts: 20
Joined: Tue, 2013-10-08, 11:24

Re: DcmSCP, event handling, and etc ...

#7 Post by wrenashe »

J. Riesmeier wrote:In don't know what the registerSocketEvent() does but my first guess would be that your "event system" does something with the network socket that prevents the DCMTK network routines from working correctly. So, the only thing I can recommend is: do further debugging...
Hi,

Basically I think I got that issue fixed. The problem is the DIMSEtimeout for non-blocking accept socket is not set correctly in scp.cc, and that is not related to event processing model. If you did the testing on DcmSCP directly with non-blocking mode, you may also hit the similar situation(And DcmSCP works in blocking mode by default).

The fix is attached, it looks straightforward. Just have the DIMSE non-blocking timeout enabled in DIMSE_receiveCommand() call from DcmSCP::handleAssociation().

Code: Select all

diff C3 C:/d-cmnet_libsrc_scp.cc.2 C:/d-cmnet_libsrc_scp.cc
*** C:/d-cmnet_libsrc_scp.cc.2	Mon Oct 14 12:09:43 2013
--- C:/d-cmnet_libsrc_scp.cc	Mon Oct 14 12:08:23 2013
***************
*** 485,491 ****
    while( cond.good() )
    {
      // receive a DIMSE command over the network
!     cond = DIMSE_receiveCommand( m_assoc, m_cfg->getDIMSEBlockingMode(), m_cfg->getDIMSETimeout(), &presID, &message, NULL );
  
      // check if peer did release or abort, or if we have a valid message
      if( cond.good() )
--- 485,491 ----
    while( cond.good() )
    {
      // receive a DIMSE command over the network
!     cond = DIMSE_receiveCommand( m_assoc, m_cfg->getDIMSEBlockingMode(), 0, &presID, &message, NULL );
  
      // check if peer did release or abort, or if we have a valid message
      if( cond.good() )
Wish my post helps for better quality of dcmtk tool. It is brilliant already, keep going. :-)

J. Riesmeier
DCMTK Developer
Posts: 2506
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: DcmSCP, event handling, and etc ...

#8 Post by J. Riesmeier »

Thanks for your report. I've forwarded your posting to the author of the DcmSCP class, which is btw still labeled as "experimental". Now you know why :)

J. Riesmeier
DCMTK Developer
Posts: 2506
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: DcmSCP, event handling, and etc ...

#9 Post by J. Riesmeier »

This issue should be fixed with the following commit: http://git.dcmtk.org/web?p=dcmtk.git;a= ... 17eb0a02dc

Thanks again for your bug report!

wrenashe
Posts: 20
Joined: Tue, 2013-10-08, 11:24

Re: DcmSCP, event handling, and etc ...

#10 Post by wrenashe »

J. Riesmeier wrote:This issue should be fixed with the following commit: http://git.dcmtk.org/web?p=dcmtk.git;a= ... 17eb0a02dc

Thanks again for your bug report!
Proud of that for such a nice open source tool for DICOM world. :D

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest