PACS connection

All other questions regarding DCMTK

Moderator: Moderator Team

Message
Author
Mitmal
Posts: 112
Joined: Mon, 2011-04-18, 19:36
Location: France

#61 Post by Mitmal »

my mistake, just with scp-> listen the service starts fine.
Now it only remains for me to find how to change the destination address of the images.
(And optionally, how to change the file names)
Respectueusement,
MitMal

Roadrunner
Posts: 56
Joined: Mon, 2010-06-14, 16:41

#62 Post by Roadrunner »

how to change the file names
with

Code: Select all

if (receiveDIMSEDataset(&presID, &dataObject,NULL,NULL).good())
{..
// receive and responding code here ....
if (dataObject->findAndGetOFString(DCM_SOPInstanceUID, dateiname,0, true).good())
                    qDebug() << "SOP IUID: "<< filename.c_str();
else {// some else code here otherwise you'll overwrite a file}
// save to file
dcmdataset->save(filename.c_str()); 
}
you get a dcmdataset and you can save it with
dcmdataset->save(filename.c_str()); where filename is a OFString

Mitmal
Posts: 112
Joined: Mon, 2011-04-18, 19:36
Location: France

#63 Post by Mitmal »

Fine, but I do not know where to put this code?
Respectueusement,
MitMal

Roadrunner
Posts: 56
Joined: Mon, 2010-06-14, 16:41

Your storescp here!

#64 Post by Roadrunner »

For all who don't know c++ and don't understand a bit of the dcmtk and
posts above and where unable to read the linked posts:

This is the code for receiving C-StoreRequests, saving files and sending the C-StoreResponse:

// DICOMEMPFANGEN.H

Code: Select all

#ifndef DICOMEMPFANGEN_H
#define DICOMEMPFANGEN_H


#include <dcmtk/dcmimage/diregist.h>      /* include to support color images */
#include "dcmtk/dcmjpeg/djdecode.h" /* for jpeg decoder */
#include "dcmtk/dcmdata/dcrledrg.h"
#include <dcmtk/ofstd/ofstring.h>
#include <dcmtk/ofstd/ofconsol.h>
#include <dcmtk/dcmdata/dcdeftag.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmimgle/dcmimage.h>
#include "dcmtk/dcmdata/dctk.h"
#include "dcmtk/dcmdata/dcistrmf.h"
#include "dcmtk/dcmnet/dimse.h"
#include "dcmtk/dcmnet/diutil.h"
#include "dcmtk/dcmnet/scp.h"

class DicomEmpfangen : public DcmSCP
{
public:
    DicomEmpfangen();



    /* ***********************************************************************
     *  Functions particularly interesting for overwriting in derived classes
     * ***********************************************************************
     */

    /** Handle incoming command set and react accordingly, e.g.\ sending response via
     *  DIMSE_sendXXXResponse(). The standard handler only knows how to handle an Echo request
     *  by calling handleEchoRequest(). This function is most likely to be implemented by a
     *  derived class implementing a specific SCP behaviour.
     *  @param TODO
     *  @return TODO
     */
    OFCondition handleIncomingCommand(T_DIMSE_Message *incomingMsg,
                                              const DcmPresentationContextInfo &presContextInfo);

private:
    OFString pname;
    OFString dateiname;
};

#endif // DICOMEMPFANGEN_H

// DICOMEMPFANGEN.CPP - CPP file:

Code: Select all

#include "dicomempfangen.h"
#include <QDebug>
#include <QTime>

DicomEmpfangen::DicomEmpfangen()
{
}


OFCondition DicomEmpfangen::handleIncomingCommand(T_DIMSE_Message *msg,
                                          const DcmPresentationContextInfo &info)
{
    OFCondition cond;
    switch(msg->CommandField)
    {
    case DIMSE_C_ECHO_RQ :{
        // Process C-ECHO request
        cond = handleECHORequest( msg->msg.CEchoRQ, info.presentationContextID );
        break;
    }// ende DIMSE_C_ECHO_RQ

    case DIMSE_C_STORE_RQ:{

        qDebug() << "data/files to save ... !!! :-)";

        T_DIMSE_C_StoreRSP response;
        T_DIMSE_C_StoreRQ request = msg->msg.CStoreRQ;
        DcmDataset *statusDetail = NULL;

        T_ASC_PresentationContextID presID = info.presentationContextID;
        DcmDataset *dataObject = new DcmDataset();

        if (receiveDIMSEDataset(&presID, &dataObject,NULL,NULL).good())
        {
            if (dataObject != NULL)
            {
                qDebug() << "Daten empfangen: " << QTime::currentTime();
                dateiname.clear();
                if (dataObject->findAndGetOFString(DCM_SOPInstanceUID, dateiname,0, true).good())
                    qDebug() << "SOP IUID: "<< dateiname.c_str();

                dataObject->saveFile(dateiname.c_str());

                bzero((char*)&response, sizeof(response));
                response.DimseStatus = STATUS_Success;  /* assume */
                response.MessageIDBeingRespondedTo = request.MessageID;
                response.DataSetType = DIMSE_DATASET_NULL;  /* always for C-STORE-RSP */
                strcpy(response.AffectedSOPClassUID, request.AffectedSOPClassUID);
                strcpy(response.AffectedSOPInstanceUID, request.AffectedSOPInstanceUID);
                response.opts = (O_STORE_AFFECTEDSOPCLASSUID | O_STORE_AFFECTEDSOPINSTANCEUID);
                if (request.opts & O_STORE_RQ_BLANK_PADDING) response.opts |= O_STORE_RSP_BLANK_PADDING;
                if (dcmPeerRequiresExactUIDCopy.get()) response.opts |= O_STORE_PEER_REQUIRES_EXACT_UID_COPY;

                OFCondition cond = sendSTOREResponse(presID, request, response, statusDetail);
                if( cond.bad() ) DCMNET_INFO("Cannot send C-Store Response: " );
                else DCMNET_INFO("C-STORE Response successfully sent");

            }
            else qDebug() << "no data received";
        }
        else qDebug() << "no dcmdataset.";
        break;
    }
    default:{
        // We cannot handle this kind of message. Note that the condition will be returned
        // and that the caller is responsible to end the association if desired.
        OFString tempStr;
        DCMNET_ERROR("Cannot handle this kind of DIMSE command (0x"
          << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4)
                     << OFstatic_cast(unsigned int, msg->CommandField) << ")");
        DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, *msg, DIMSE_INCOMING));
        cond = DIMSE_BADCOMMANDTYPE;
    }// Ende default
    }// Ende case
  return cond;
}
Then you need a main function
where you did the following:

Code: Select all

int main(int argc, char *argv[])
{

    //scp = new DcmSCP();
    DicomEmpfangen *scp; // put this in a headerfile if you use a class and not a main!
    scp = new DicomEmpfangen();
    scp->setPort(104);
    scp->setAETitle("CHANGEAETITLE"); 
    //scp->loadAssociationCfgFile("storescp.cfg");

    if (scp->loadAssociationCfgFile("storescp.cfg").good())
    {
        qDebug() << "SCP-Config-File gefunden :-)";
        qDebug() << "dime-timeout: " << scp->getDIMSETimeout();
        if (scp->setAndCheckAssociationProfile("Default").good())
        {
            qDebug() << "listen gestartet um: "<< QTime::currentTime();
            //scp->setDIMSETimeout(ULONG_MAX);
            if (scp->getDIMSEBlockingMode() == DIMSE_NONBLOCKING )
            {
                qDebug() << "scp is in non-blocking mode: ";
                scp->setConnnectionTimeout(ULONG_MAX);
                scp->setDIMSEBlockingMode(DIMSE_BLOCKING);
                if (scp->getDIMSEBlockingMode() == DIMSE_BLOCKING )
                    qDebug() << "2nd try: scp is in blocking mode: ";
                else qDebug() << "scp is still in non-blocking mode: ";
            }
            else {
                qDebug() << "scp is in blocking mode: ";
            }

            if (scp->listen().bad())
            {
                qDebug() << "error during listening!";
            }
            qDebug() << "listen stops at: " << QTime::currentTime();
        }
    }
    else
        qDebug() << "SCP-Config file not found :-(";
}

Now you have all for a storescp - please close this thread.
For the german comments - use google translator.

Be patient to this thread if you use the code above:
viewtopic.php?t=3234

btw: I am using the switch case not if () else because there are more
than two T_DIMSE_Command's and you want only handle echo and receive requests - other should be implemented later or give an error.

btw2: you should have the storescp.cfg from the dcmtk/etc/ directory and
i had to comment out line 96.
#PresentationContext28 = OphthalmicThicknessMapStorage\AnyTransferSyntax

Well i know there are memory leaks - so fix them or post a better code here.



Frank

Michael Onken
DCMTK Developer
Posts: 2048
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

#65 Post by Michael Onken »

Thanks Frank :)

Locked

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 1 guest