Beispiel #1
0
OFCondition GIL::DICOM::DCMTK::Network::DropNetwork()
{

    OFCondition cond = ASC_dropNetwork(&m_pDCMTKNetwork);
    m_pDCMTKNetwork = NULL;

    return cond;
}
Beispiel #2
0
OFCondition Network::DropNetwork()
{
	OFCondition cond = ASC_dropNetwork(&net);
	net = NULL;

#ifdef _WIN32
    WSACleanup();
#endif

	return cond;
}
Beispiel #3
0
  void DicomServer::Stop()
  {
    if (continue_)
    {
      continue_ = false;

      if (pimpl_->thread_.joinable())
      {
        pimpl_->thread_.join();
      }

      pimpl_->workers_.reset(NULL);

      /* drop the network, i.e. free memory of T_ASC_Network* structure. This call */
      /* is the counterpart of ASC_initializeNetwork(...) which was called above. */
      OFCondition cond = ASC_dropNetwork(&pimpl_->network_);
      if (cond.bad())
      {
        LOG(ERROR) << "Error while dropping the network: " << cond.text();
      }
    }
  }
void PACSConnection::disconnect()
{
    OFCondition condition = ASC_releaseAssociation(m_dicomAssociation);
    if (condition.bad())
    {
        ERROR_LOG("No s'ha pogut desconnectar del PACS, descripcio error: " + QString(condition.text()));
    }

    condition = ASC_destroyAssociation(&m_dicomAssociation);
    if (condition.bad())
    {
        ERROR_LOG("Error al destruir la connexio amb el PACS, descripcio error: " + QString(condition.text()));
    }

    // Destrueix l'objecte i tanca el socket obert, fins que no es fa el drop de l'objecte no es tanca el socket
    condition = ASC_dropNetwork(&m_associationNetwork);
    if (condition.bad())
    {
        ERROR_LOG("Error al tancar el port de connexions entrants, descripcio error: " + QString(condition.text()));
    }

}
void QtDcmServersDicomSettingsWidget::sendEcho()
{
    if ( !treeWidget->currentItem() ) {
        return;
    }

    QtDcmPreferences* prefs = QtDcmPreferences::instance();
    
    const QString aet = prefs->aetitle();
    const QString serverAet = treeWidget->currentItem()->data ( 1, 1 ).toString();
    const QString hostname = prefs->hostname();
    const QString serverHostname = treeWidget->currentItem()->data ( 3, 1 ).toString();
    const QString serverPort = treeWidget->currentItem()->data ( 2, 1 ).toString();

    T_ASC_Network *net = 0; // network struct, contains DICOM upper layer FSM etc.

    OFCondition cond = ASC_initializeNetwork ( NET_REQUESTOR, 0, 30 /* timeout */, &net );
    if ( cond != EC_Normal ) {
        QMessageBox msgBox( QApplication::activeWindow() );
        msgBox.setIcon ( QMessageBox::Critical );
        msgBox.setText ( "Cannot initialize network" );
        msgBox.exec();
        
        ASC_dropNetwork ( &net );
        
        return;
    }

    QTcpSocket * socket = new QTcpSocket(this);
    socket->connectToHost(serverHostname, serverPort.toInt());
    if (!socket->waitForConnected(1000)) {
        QMessageBox msgBox( QApplication::activeWindow() );
        msgBox.setIcon ( QMessageBox::Information );
        msgBox.setText ( "Cannot connect to server " + serverHostname + " on port " + serverPort + " !" );
        msgBox.exec();
        
        ASC_dropNetwork ( &net );
        
        return;
    }
    
    socket->disconnectFromHost();
    delete socket;
    
    T_ASC_Parameters *params; // parameters of association request

    cond = ASC_createAssociationParameters ( &params, ASC_DEFAULTMAXPDU );

    // set calling and called AE titles
    cond = ASC_setAPTitles ( params, aet.toUtf8().data(), serverAet.toUtf8().data(), NULL );

    // the DICOM server accepts connections at server.nowhere.com port 104
    cond = ASC_setPresentationAddresses ( params, hostname.toUtf8().data(), QString ( serverHostname + ":" + serverPort ).toLatin1().data() );

    // list of transfer syntaxes, only a single entry here
    const char* ts[] = { UID_LittleEndianImplicitTransferSyntax };

    // add presentation context to association request
    cond = ASC_addPresentationContext ( params, 1, UID_VerificationSOPClass, ts, 1 );

    // request DICOM association
    T_ASC_Association *assoc = 0;

    if ( ASC_requestAssociation ( net, params, &assoc ).good() ) {
        if ( ASC_countAcceptedPresentationContexts ( params ) == 1 ) {
            // the remote SCP has accepted the Verification Service Class
            DIC_US id = assoc->nextMsgID++; // generate next message ID
            DIC_US status; // DIMSE status of C-ECHO-RSP will be stored here
            DcmDataset *sd = NULL; // status detail will be stored here
            // send C-ECHO-RQ and handle response
            DIMSE_echoUser ( assoc, id, DIMSE_BLOCKING, 0, &status, &sd );
            delete sd; // we don't care about status detail
            
            QMessageBox msgBox( QApplication::activeWindow() );
            msgBox.setIcon ( QMessageBox::Information );
            msgBox.setText ( "Echo request successful !" );
            msgBox.exec();
        }
        else {
            QMessageBox msgBox( QApplication::activeWindow() );
            msgBox.setIcon ( QMessageBox::Critical );
            msgBox.setText ( "Wrong presentation context, echo request failed" );
            msgBox.exec();
        }
    }
    else {
        QMessageBox msgBox( QApplication::activeWindow() );
        msgBox.setIcon ( QMessageBox::Critical );
        msgBox.setText ( "Wrong dicom association, echo request failed" );
        msgBox.exec();
    }

    ASC_releaseAssociation ( assoc ); // release association
    ASC_destroyAssociation ( &assoc ); // delete assoc structure
    ASC_dropNetwork ( &net ); // delete net structure
    
    net = 0;
    assoc = 0;
}
Beispiel #6
0
bool echoscu(const QString &peerTitle, const QString &ourTitle,
             const QString &hostname, int port,
             QString &msg)
{
    T_ASC_Network *net;
    T_ASC_Parameters *params;
    T_ASC_Association *assoc;
    OFString temp_str;
    bool ret = false;

#ifdef HAVE_WINSOCK_H
    WSAData winSockData;
    /* we need at least version 1.1 */
    WORD winSockVersionNeeded = MAKEWORD( 1, 1 );
    WSAStartup(winSockVersionNeeded, &winSockData);
#endif

    /* initialize network, i.e. create an instance of T_ASC_Network*. */
    OFCondition cond = ASC_initializeNetwork(NET_REQUESTOR, 0, 6, &net);
    if (cond.bad()) {
        DimseCondition::dump(temp_str, cond);
        msg = QString::fromLatin1(temp_str.c_str());
        goto cleanup;
    }

    /* initialize asscociation parameters, i.e. create an instance of T_ASC_Parameters*. */
    cond = ASC_createAssociationParameters(&params, ASC_DEFAULTMAXPDU);
    if (cond.bad()) {
        DimseCondition::dump(temp_str, cond);
        msg = QString::fromLatin1(temp_str.c_str());
        goto cleanup;
    }

    ASC_setAPTitles(params, ourTitle.toLocal8Bit().data(), peerTitle.toLocal8Bit().data(), NULL);

    /* Set the transport layer type (type of network connection) in the params */
    /* strucutre. The default is an insecure connection; where OpenSSL is  */
    /* available the user is able to request an encrypted,secure connection. */
    cond = ASC_setTransportLayerType(params, OFFalse);
    if (cond.bad()) {
        DimseCondition::dump(temp_str, cond);
        msg = QString::fromLatin1(temp_str.c_str());
        goto cleanup;
    }

    /* Figure out the presentation addresses and copy the */
    /* corresponding values into the association parameters.*/
    DIC_NODENAME localHost;
    DIC_NODENAME peerHost;
    gethostname(localHost, sizeof(localHost) - 1);
    sprintf(peerHost, "%s:%d", hostname.toLocal8Bit().data(), port);

    ASC_setPresentationAddresses(params, localHost, peerHost);

    /* Set the presentation contexts which will be negotiated */
    /* when the network connection will be established */
    int presentationContextID = 1; /* odd byte value 1, 3, 5, .. 255 */
    for (unsigned long ii=0; ii<1; ii++)
    {
        cond = ASC_addPresentationContext(params, presentationContextID, UID_VerificationSOPClass,
                 transferSyntaxes, 3);
        presentationContextID += 2;
        if (cond.bad())
        {
            DimseCondition::dump(temp_str, cond);
            msg = QString::fromLatin1(temp_str.c_str());
            goto cleanup;
        }
    }

    /* create association, i.e. try to establish a network connection to another */
    /* DICOM application. This call creates an instance of T_ASC_Association*. */
    cond = ASC_requestAssociation(net, params, &assoc);
    if (cond.bad()) {
        if (cond == DUL_ASSOCIATIONREJECTED)
        {
            T_ASC_RejectParameters rej;

            ASC_getRejectParameters(params, &rej);
            ASC_printRejectParameters(temp_str, &rej);
            msg = QString("Association Rejected: %1").arg(temp_str.c_str());
            goto cleanup;
        } else {
            DimseCondition::dump(temp_str, cond);
            msg = QString("Association Request Failed: %1").arg(temp_str.c_str());
            goto cleanup;
        }
    }

    /* count the presentation contexts which have been accepted by the SCP */
    /* If there are none, finish the execution */
    if (ASC_countAcceptedPresentationContexts(params) == 0) {
        msg = QString("No Acceptable Presentation Contexts");
        goto cleanup;
    }

    /* do the real work, i.e. send a number of C-ECHO-RQ messages to the DICOM application */
    /* this application is connected with and handle corresponding C-ECHO-RSP messages. */
    DIC_US msgId = assoc->nextMsgID++;
    DIC_US status;
    DcmDataset *statusDetail = NULL;

    /* send C-ECHO-RQ and handle response */
    cond = DIMSE_echoUser(assoc, msgId, DIMSE_BLOCKING, 0, &status, &statusDetail);

    /* check for status detail information, there should never be any */
    if (statusDetail != NULL) {
        delete statusDetail;
    }

    /* tear down association, i.e. terminate network connection to SCP */
    if (cond == EC_Normal)
    {
        cond = ASC_releaseAssociation(assoc);
        ret = true;
    }
    else if (cond == DUL_PEERABORTEDASSOCIATION)
    {

    }
    else
    {
        DimseCondition::dump(temp_str, cond);
        msg = QString::fromLatin1(temp_str.c_str());
        cond = ASC_abortAssociation(assoc);
    }

cleanup:
    /* destroy the association, i.e. free memory of T_ASC_Association* structure. This */
    /* call is the counterpart of ASC_requestAssociation(...) which was called above. */
    cond = ASC_destroyAssociation(&assoc);

    /* 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(&net);

#ifdef HAVE_WINSOCK_H
    WSACleanup();
#endif

    return ret;
}
Beispiel #7
0
  void DicomServer::ServerThread(DicomServer* server)
  {
    /* Disable "gethostbyaddr" (which results in memory leaks) and use raw IP addresses */
    dcmDisableGethostbyaddr.set(OFTrue);

    dcmDataDict.clear();
    DcmDataDictionary& d = dcmDataDict.wrlock();

#if DCMTK_USE_EMBEDDED_DICTIONARIES == 1
    LOG(WARNING) << "Loading the embedded dictionaries";
    /**
     * Do not load DICONDE dictionary, it breaks the other tags. The
     * command "strace storescu 2>&1 |grep dic" shows that DICONDE
     * dictionary is not loaded by storescu.
     **/
    //LoadEmbeddedDictionary(d, EmbeddedResources::DICTIONARY_DICONDE);

    LoadEmbeddedDictionary(d, EmbeddedResources::DICTIONARY_DICOM);
    LoadEmbeddedDictionary(d, EmbeddedResources::DICTIONARY_PRIVATE);

#elif defined(__linux)
    std::string path = "/usr/share/dcmtk";

    const char* env = std::getenv(DCM_DICT_ENVIRONMENT_VARIABLE);
    if (env != NULL)
    {
      path = std::string(env);
    }

    LoadExternalDictionary(d, path, "dicom.dic");
    LoadExternalDictionary(d, path, "private.dic");

#else
#error Support your platform here
#endif

    dcmDataDict.unlock();

    /* make sure data dictionary is loaded */
    if (!dcmDataDict.isDictionaryLoaded())
    {
      LOG(ERROR) << "No DICOM dictionary loaded, check environment variable: " << DCM_DICT_ENVIRONMENT_VARIABLE;
      throw OrthancException(ErrorCode_InternalError);
    }

    {
      // Test the dictionary with a simple DICOM tag
      DcmTag key(0x0010, 0x1030); // This is PatientWeight
      if (key.getEVR() != EVR_DS)
      {
        LOG(ERROR) << "The DICOM dictionary has not been correctly read";
        throw OrthancException(ErrorCode_InternalError);
      }
    }

    /* initialize network, i.e. create an instance of T_ASC_Network*. */
    T_ASC_Network *net;
    OFCondition cond = ASC_initializeNetwork
      (NET_ACCEPTOR, OFstatic_cast(int, server->port_), /*opt_acse_timeout*/ 30, &net);
    if (cond.bad())
    {
      LOG(ERROR) << "cannot create network: " << cond.text();
      throw OrthancException("Cannot create network");
    }

    LOG(INFO) << "DICOM server started";

    server->started_ = true;

    while (server->continue_)
    {
      /* receive an association and acknowledge or reject it. If the association was */
      /* acknowledged, offer corresponding services and invoke one or more if required. */
      std::auto_ptr<Internals::CommandDispatcher> dispatcher(Internals::AcceptAssociation(*server, net));

      if (dispatcher.get() != NULL)
      {
        if (server->isThreaded_)
        {
          server->bagOfDispatchers_.Add(dispatcher.release());
        }
        else
        {
          IRunnableBySteps::RunUntilDone(*dispatcher);
        }
      }
    }

    LOG(INFO) << "DICOM server stopping";

    /* 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(&net);
    if (cond.bad())
    {
      LOG(ERROR) << "Error while dropping the network: " << cond.text();
    }
  }