~ubuntu-branches/ubuntu/trusty/ginkgocadx/trusty

« back to all changes in this revision

Viewing changes to src/cadxcore/main/controllers/pacscontroller.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2013-07-21 11:58:53 UTC
  • mfrom: (7.2.1 sid)
  • Revision ID: package-import@ubuntu.com-20130721115853-44e7n1xujqglu78e
Tags: 3.4.0.928.29+dfsg-1
* New upstream release [July 2013]
  + new B-D: "libjsoncpp-dev".
  + new patch "unbundle-libjsoncpp.patch" to avoid building bundled
    "libjsoncpp-dev".
  + new patch "fix-wx.patch" to avoid FTBFS due to missing
    "-lwx_gtk2u_html-2.8".
* Removed unnecessary versioned Build-Depends.
* Removed obsolete lintian override.
* Reference get-orig-source implementation for orig.tar clean-up and
  DFSG-repackaging.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
*
13
13
*/
14
14
#include <string>
 
15
#include <limits>
15
16
#include <openssl/md5.h>
16
17
 
17
18
#include "pacscontroller.h"
30
31
#include <dcmtk/dcmdata/dcdicdir.h>
31
32
#include <api/ientorno.h>
32
33
#include <api/dicom/imodelodicom.h>
 
34
#include <api/dicom/dcmdictionary.h>
33
35
#include <main/entorno.h>
34
36
#include <wx/filename.h>
35
37
#include <wx/dir.h>
36
38
#include <wx/file.h>
37
39
#include <wx/tokenzr.h>
 
40
#include <wx/wxhttpengine/httpbuilder.h>
38
41
#include <main/controllers/configurationcontroller.h>
39
42
#include <main/controllers/historycontroller.h>
40
43
#include <main/controllers/dicommanager.h>
 
44
/* curl stuff */
 
45
#include <curl/curl.h>
41
46
 
42
47
#ifdef verify
43
48
#define MACRO_QUE_ESTORBA verify
52
57
#define verify MACRO_QUE_ESTORBA
53
58
#endif
54
59
 
 
60
 
55
61
namespace GIL {
56
62
        namespace DICOM {
57
63
                wxCSConv GetConv(const std::string& Charset)
90
96
                        return wxConv;
91
97
                }
92
98
 
 
99
                //helper compare instances
 
100
                bool compare_instances (std::pair<long, std::string> first, std::pair<long, std::string> second) {
 
101
                        return first.first < second.first;
 
102
                }
 
103
 
93
104
                PACSController* PACSController::m_pInstance = NULL;
94
105
 
95
106
                PACSController::PACSController()
100
111
                PACSController::~PACSController()
101
112
                {
102
113
                        //std::cout << "PACSController destruyendose" << std::endl;
103
 
                        DicomServerList::FreeInstance();
104
114
                        //std::cout << "PACSController destruido" << std::endl;
105
115
                }
106
116
 
132
142
 
133
143
                }
134
144
 
135
 
                void PACSController::Store(const std::string& fileName, DcmDataset* dset)
136
 
                {
137
 
 
138
 
                        GTRACE("PACSController::Store() ");
139
 
                        // TODO: Try/catch
140
 
 
141
 
 
142
 
                        OFString OFPacienteUId;
143
 
                        OFString OFEstudioUId;
144
 
                        OFString OFSerieUId;
145
 
                        OFString OFImagenUId;
146
 
 
147
 
                        std::string PacienteUId;
148
 
                        std::string EstudioUId;
149
 
                        std::string SerieUId;
150
 
                        std::string ImagenUId;
151
 
 
152
 
                        if (dset->findAndGetOFString(DCM_PatientID, OFPacienteUId).good()) {
153
 
                                PacienteUId.assign(OFPacienteUId.c_str());
154
 
                        }
155
 
                        if (dset->findAndGetOFString(DCM_StudyInstanceUID, OFEstudioUId).good()) {
156
 
                                EstudioUId.assign(OFEstudioUId.c_str());
157
 
                        }
158
 
                        if (dset->findAndGetOFString(DCM_SeriesInstanceUID, OFSerieUId).good()) {
159
 
                                SerieUId.assign(OFSerieUId.c_str());
160
 
                        }
161
 
                        if (dset->findAndGetOFString(DCM_SOPInstanceUID, OFImagenUId).good()) {
162
 
                                ImagenUId.assign(OFImagenUId.c_str());
163
 
                        }
164
 
                        //std::cout << "PacienteUId = " << PacienteUId << std::endl;
165
 
                        //std::cout << "EstudioUId = " << EstudioUId << std::endl;
166
 
                        //std::cout << "SerieUId = " << SerieUId << std::endl;
167
 
                        //std::cout << "ImagenUId = " << ImagenUId << std::endl;
168
 
 
169
 
                        std::string rutaStd;
170
 
                        GetRutaImagenTemp(PacienteUId,EstudioUId,SerieUId,ImagenUId,rutaStd);
171
 
 
172
 
                        if (!wxRenameFile(FROMPATH(fileName), FROMPATH(rutaStd))) {
173
 
                                LOG_ERROR("PACSCONTROLLER-STORE", "Error writing file to temp dir");
174
 
                        }
175
 
                }
176
 
 
177
145
                IModeloDicom* PACSController::BuscarPaciente(
178
146
                        void* connectionKey,
179
147
                        const std::string& serverId,
185
153
                        )
186
154
                {
187
155
                        DicomServerList* listaServidores = DicomServerList::Instance();
188
 
                        DicomServer* server = listaServidores->GetServer(serverId);
 
156
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
189
157
 
190
158
                        wxCSConv conv = GetConv(server->GetDefaultCharset());
191
159
 
262
230
                        )
263
231
                {
264
232
                        DicomServerList* listaServidores = DicomServerList::Instance();
265
 
                        DicomServer* server = listaServidores->GetServer(serverId);
 
233
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
266
234
 
267
235
                        wxCSConv conv = GetConv(server->GetDefaultCharset());
268
236
 
386
354
 
387
355
                        std::string localAET = GNC::Entorno::Instance()->GetDicomLocalAET();
388
356
 
389
 
                        
 
357
 
390
358
                        if (server->useTLS) {
391
359
                                a.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
392
360
                        }
408
376
                        )
409
377
                {
410
378
                        DicomServerList* listaServidores = DicomServerList::Instance();
411
 
                        DicomServer* server = listaServidores->GetServer(serverId);
 
379
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
412
380
 
413
381
                        wxCSConv conv = GetConv(server->GetDefaultCharset());
414
382
 
501
469
                        )
502
470
                {
503
471
                        DicomServerList* listaServidores = DicomServerList::Instance();
504
 
                        DicomServer* server = listaServidores->GetServer(serverId);
 
472
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
505
473
 
506
474
                        wxCSConv conv = GetConv(server->GetDefaultCharset());
507
475
 
622
590
                                                                {
623
591
                                                                        if(FileRecord->findAndGetOFStringArray(DCM_ReferencedFileID,tmpString).good())
624
592
                                                                        {
625
 
                                                                                OFString uidImagen;
 
593
                                                                                OFString uidImagen,instanceNumber;
626
594
                                                                                FileRecord->findAndGetOFString(DCM_ReferencedSOPInstanceUIDInFile, uidImagen);
 
595
                                                                                FileRecord->findAndGetOFString(DCM_InstanceNumber, instanceNumber);
627
596
 
628
597
                                                                                wxString currentPath = FROMPATH(basePath);
629
598
 
709
678
                                                                                        }
710
679
                                                                                }//end recase
711
680
 
712
 
                                                                                pModelo->InsertarImagen(uidSerie.c_str(), uidImagen.c_str(), std::string(TOPATH(currentPath)));
 
681
                                                                                pModelo->InsertarImagen(uidSerie.c_str(), uidImagen.c_str(), instanceNumber.c_str(), std::string(TOPATH(currentPath)));
713
682
                                                                        }
714
683
                                                                }
715
684
                                                        }
809
778
                        return valido;
810
779
                }
811
780
 
812
 
                void PACSController::FillInQuery(const GIL::DICOM::DicomDataset& base, DcmDataset* query, DicomServer* server)
 
781
                void PACSController::FillInQuery(const GIL::DICOM::DicomDataset& base, DcmDataset* query, const GNC::GCS::Ptr<DicomServer>& server)
813
782
                {                       
814
783
                        wxCSConv conv = GetConv(server->GetDefaultCharset());
815
784
                        OFCondition cond;
833
802
 
834
803
                                for (TJerarquia::DatasetList::const_iterator it2 = base.secuencias.begin(); it2 != base.secuencias.end(); ++it2) {
835
804
                                        const TJerarquia& seq = (*it2);
836
 
                                        DcmElement* es = GIL::DICOM::DICOMManager::CrearElementoConValor(seq.tagName.c_str());                  
837
 
 
838
 
                                        for (TJerarquia::DatasetList::const_iterator it3 = seq.items.begin(); it3 != seq.items.end(); ++it3) {
839
 
                                                const TJerarquia& item = (*it3);
840
 
                                                DcmItem* di = new DcmItem();
841
 
 
842
 
                                                for (ListaTags::const_iterator it4 = item.tags.begin(); it4 != item.tags.end(); ++it4) {
843
 
                                                        DcmElement* ei = GIL::DICOM::DICOMManager::CrearElementoConValor((*it4).first.c_str());
844
 
                                                        if (ei != NULL) {
845
 
                                                                const std::string& val = (*it4).second;
846
 
                                                                if (val.size() > 0) {
847
 
                                                                        ei->putString( wxString( (*it4).second.c_str(), wxConvUTF8).mb_str(conv) );
848
 
                                                                }                                       
849
 
                                                                cond = di->insert(ei, true, false);
850
 
 
851
 
                                                                if (cond.bad()) {
852
 
                                                                        LOG_ERROR("PACSCONTROLLER", "No se pudo insertar el elemento: (" << ei->getTag().toString().c_str() << "): " << cond.text());
 
805
                                        DcmElement* es = GIL::DICOM::DICOMManager::CrearElementoConValor(seq.tagName.c_str());
 
806
                                        if (es != NULL) {
 
807
 
 
808
                                                for (TJerarquia::DatasetList::const_iterator it3 = seq.items.begin(); it3 != seq.items.end(); ++it3) {
 
809
                                                        const TJerarquia& item = (*it3);
 
810
                                                        DcmItem* di = new DcmItem();
 
811
 
 
812
                                                        for (ListaTags::const_iterator it4 = item.tags.begin(); it4 != item.tags.end(); ++it4) {
 
813
                                                                DcmElement* ei = GIL::DICOM::DICOMManager::CrearElementoConValor((*it4).first.c_str());
 
814
                                                                if (ei != NULL) {
 
815
                                                                        const std::string& val = (*it4).second;
 
816
                                                                        if (val.size() > 0) {
 
817
                                                                                ei->putString( wxString( (*it4).second.c_str(), wxConvUTF8).mb_str(conv) );
 
818
                                                                        }                                       
 
819
                                                                        cond = di->insert(ei, true, false);
 
820
 
 
821
                                                                        if (cond.bad()) {
 
822
                                                                                LOG_ERROR("PACSCONTROLLER", "No se pudo insertar el elemento: (" << ei->getTag().toString().c_str() << "): " << cond.text());
 
823
                                                                        }
853
824
                                                                }
 
825
 
854
826
                                                        }
855
827
 
856
 
                                                }
857
 
 
858
 
                                                query->insertSequenceItem(es->getTag(), di);
859
 
                                        }                                       
 
828
                                                        query->insertSequenceItem(es->getTag(), di);
 
829
                                                }                                       
 
830
                                        }
860
831
                                }
861
832
                        }
862
833
                }
864
835
                bool PACSController::Print(void* connectionKey, const std::string& serverId, const GIL::DICOM::DicomDataset& film, const GIL::DICOM::DicomDataset& layout, const GIL::DICOM::DicomDataset& job, const std::list<std::string> files, GNC::IProxyNotificadorProgreso* pNotificador)
865
836
                {
866
837
                        DicomServerList* listaServidores = DicomServerList::Instance();
867
 
                        DicomServer* server = listaServidores->GetServer(serverId);
868
 
                        if (server == NULL) {
 
838
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
 
839
                        if (!server.IsValid()) {
869
840
                                LOG_ERROR("C-MOVE/C-GET", "Invalid server");
870
841
                                return false;
871
842
                        }
890
861
                }
891
862
 
892
863
 
893
 
                bool PACSController::ObtenerEstudio(void* connectionKey, const std::string& serverId, const GIL::DICOM::DicomDataset& base, IModeloDicom* pModelo, GNC::IProxyNotificadorProgreso* pNotificador)
 
864
                bool PACSController::ObtenerEstudio(void* connectionKey, const std::string& serverId, const GIL::DICOM::DicomDataset& base, IModeloDicom* pModelo, GNC::IProxyNotificadorProgreso* pNotificador, bool link)
894
865
                {
895
866
                        DicomServerList* listaServidores = DicomServerList::Instance();
896
 
                        DicomServer* server = listaServidores->GetServer(serverId);
897
 
                        if (server == NULL) {
 
867
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
 
868
                        if (!server.IsValid()) {
898
869
                                LOG_ERROR("C-MOVE/C-GET", "Invalid server");
899
870
                                return false;
900
871
                        }
901
 
                        
 
872
 
902
873
                        wxCSConv conv = GetConv(server->GetDefaultCharset());
903
874
 
904
875
                        if (!server->GetReuseConnection()) {
946
917
 
947
918
                        std::string localAET = GNC::Entorno::Instance()->GetDicomLocalAET();
948
919
 
949
 
                        if (server->GetRetrieveSeries()) {
 
920
                        if (server->GetRetrieveSeries() || server->GetRetrieveMethod() == DicomServer::WADO) {
950
921
                                //buscar + descargar series...
951
922
                                //we have to know the series uids and obtain series by series
952
923
                                e = newDicomElement(DCM_QueryRetrieveLevel);
1021
992
                                        GIL::DICOM::DicomDataset baseAux = base;
1022
993
                                        baseAux.tags["0020|000e"] = (*itUIDS);
1023
994
                                        baseAux.tags["0008|0060"] = (*itModalities);
1024
 
                                        ObtenerSerie(connectionKey, serverId, baseAux, pModelo, pNotificador);
 
995
                                        ObtenerSerie(connectionKey, serverId, baseAux, pModelo, pNotificador, link);
1025
996
                                }
1026
997
 
1027
998
                                query.clear();  
1028
 
                        } else if (server->GetRetrieveWithMove()) {
 
999
                        } else if (server->GetRetrieveMethod() == DicomServer::MOVE) {
1029
1000
                                e = newDicomElement(DCM_QueryRetrieveLevel);
1030
1001
                                e->putString(wxString( "STUDY", wxConvUTF8).mb_str(conv));
1031
1002
                                query.insert(e, true);
1038
1009
 
1039
1010
                                a.SetRole(Association::RT_Requestor);
1040
1011
                                a.SetModelo(pModelo);
1041
 
                                a.SetCallbackHandler(this);
1042
1012
 
1043
1013
                                if (server->useTLS) {
1044
1014
                                        a.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
1112
1082
                                                                baseAux.tags["0020|000e"] = OFSSeriesInstanceUID.c_str();
1113
1083
                                                                baseAux.tags["0008|0060"] = OFSeriesModality.c_str();
1114
1084
 
1115
 
                                                                ObtenerSerie(connectionKey, serverId, baseAux, pModelo, pNotificador);
 
1085
                                                                ObtenerSerie(connectionKey, serverId, baseAux, pModelo, pNotificador, link);
1116
1086
                                                        }
1117
1087
                                                }
1118
1088
 
1127
1097
 
1128
1098
                }
1129
1099
 
1130
 
                bool PACSController::ObtenerSerie(void* connectionKey, const std::string& serverId, const GIL::DICOM::DicomDataset& base, IModeloDicom* pModelo, GNC::IProxyNotificadorProgreso* pNotificador)
 
1100
                bool PACSController::ObtenerSerie(void* connectionKey, const std::string& serverId, const GIL::DICOM::DicomDataset& base, IModeloDicom* pModelo, GNC::IProxyNotificadorProgreso* pNotificador, bool link)
1131
1101
                {
1132
1102
                        if (pModelo == NULL) {
1133
1103
                                return false;
1134
1104
                        }
1135
1105
                        DicomServerList* listaServidores = DicomServerList::Instance();
1136
 
                        DicomServer* server = listaServidores->GetServer(serverId);
 
1106
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
1137
1107
 
1138
 
                        if (server == NULL) {
 
1108
                        if (!server.IsValid()) {
1139
1109
                                LOG_ERROR("C-MOVE/C-GET", "Invalid server");
1140
1110
                                return false;
1141
1111
                        }
1152
1122
 
1153
1123
                        unsigned int numResults = 0;
1154
1124
 
1155
 
                        if (!server->GetRetrieveWithMove() && modality.empty()) { // We have to find series modality
 
1125
                        if (server->GetRetrieveMethod() == DicomServer::GET && modality.empty()) { // We have to find series modality
1156
1126
                                FillInQuery(base, &query, server);
1157
1127
 
1158
1128
                                e = newDicomElement(DCM_SpecificCharacterSet);
1225
1195
                                query.clear();
1226
1196
                        }// end query modality
1227
1197
 
1228
 
                        FillInQuery(base, &query, server);
1229
 
 
1230
 
                        e = newDicomElement(DCM_SpecificCharacterSet);
1231
 
                        e->putString(server->GetDefaultCharset().c_str());
1232
 
                        query.insert(e);                        
1233
 
 
1234
 
                        e = newDicomElement(DCM_QueryRetrieveLevel);
1235
 
                        e->putString(wxString( "SERIES", wxConvUTF8).mb_str(conv));
1236
 
                        query.insert(e, true);
1237
 
 
1238
 
                        e = newDicomElement(DCM_SeriesInstanceUID);
1239
 
                        if (query.insert(e).bad()) {
1240
 
                                delete e;
1241
 
                        }
1242
 
 
1243
 
                        e = newDicomElement(DCM_Modality);
1244
 
                        if (query.insert(e).bad()) {
1245
 
                                delete e;
1246
 
                        }
1247
 
 
1248
 
                        e = newDicomElement(DCM_SeriesNumber);
1249
 
                        if (query.insert(e).bad()) {
1250
 
                                delete e;
1251
 
                        }
 
1198
                        //association to make finds...
 
1199
                        NetClient<FindAssociation> f(connectionKey, "C-GET/FIND", pNotificador);
 
1200
                        f.SetMaxResults(-1);
1252
1201
 
1253
1202
                        std::string localAET = GNC::Entorno::Instance()->GetDicomLocalAET();
1254
1203
 
1255
 
                        if (server->GetRetrieveWithMove()) {
1256
 
 
1257
 
                                if (server) {
1258
 
                                        LOG_INFO("C-MOVE", "Obteniendo serie del PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-MOVE");
1259
 
                                }
1260
 
 
1261
 
                                if (server) {
1262
 
                                        LOG_INFO("C-MOVE", "Obteniendo estudio del PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-MOVE");
1263
 
                                }
1264
 
 
1265
 
                                NetClient<MoveAssociation> a(connectionKey, "C-MOVE", pNotificador);
1266
 
                                a.SetRole(Association::RT_Requestor);
1267
 
                                a.SetModelo(pModelo);
1268
 
 
1269
 
                                a.SetCallbackHandler(this);
1270
 
 
1271
 
                                if (server->useTLS) {
1272
 
                                        a.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
1273
 
                                }
1274
 
                                if (server->GetPACSUser() != "") {
1275
 
                                        a.SetUserPass(server->GetPACSUser(), server->GetPACSPass());
1276
 
                                }
1277
 
                                a.QueryServer(&query, server, pModelo, localAET, CT_MoveSerie);
1278
 
                        }
1279
 
                        else {
1280
 
                                if (server) {
1281
 
                                        LOG_INFO("C-GET", "Obteniendo serie del PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-GET");
1282
 
                                }
1283
 
 
1284
 
                                NetClient<GetAssociation> a(connectionKey, "C-GET", pNotificador);
1285
 
                                a.SetMaxResults(-1);
1286
 
                                a.SetWellKnownNumResults(numResults);
1287
 
                                a.SetStorageSOPClasses(GIL::DICOM::Conformance::GetModalities().GetSupportedSOPClassUIDs(modality));
1288
 
                                a.SetModelo(pModelo);
1289
 
 
1290
 
                                a.SetCallbackHandler(this);
1291
 
 
1292
 
                                if (server->useTLS) {
1293
 
                                        a.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
1294
 
                                }
1295
 
                                if (server->GetPACSUser() != "") {
1296
 
                                        a.SetUserPass(server->GetPACSUser(), server->GetPACSPass());
1297
 
                                }
1298
 
                                if (!a.QueryServer(&query, server, pModelo, localAET, CT_MoveSerie)) {
1299
 
                                        return false;
1300
 
                                }
1301
 
                        }
1302
 
                        query.clear();
 
1204
                        if (server->useTLS) {
 
1205
                                f.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
 
1206
                        }
 
1207
                        if (server->GetPACSUser() != "") {
 
1208
                                f.SetUserPass(server->GetPACSUser(), server->GetPACSPass());
 
1209
                        }
 
1210
 
 
1211
                        if (server->GetRetrieveMethod() == DicomServer::WADO) 
 
1212
                        {
 
1213
                                //we need to know StudyInstanceUID, SeriesInstanceUID and SopInstanceUID of all elements
 
1214
                                std::string seriesInstanceUID, studyInstanceUID;
 
1215
                                if (!base.getTag(GKDCM_SeriesInstanceUID, seriesInstanceUID)) {
 
1216
                                        LOG_ERROR("PACSController", "to obtain a series you must specify seriesInstanceUID");
 
1217
                                        return false;
 
1218
                                }
 
1219
                                if (!base.getTag(GKDCM_StudyInstanceUID, studyInstanceUID)) {
 
1220
                                        FillInQuery(base, &query, server);
 
1221
 
 
1222
                                        e = newDicomElement(DCM_SpecificCharacterSet);
 
1223
                                        e->putString(server->GetDefaultCharset().c_str());
 
1224
                                        query.insert(e);
 
1225
 
 
1226
                                        e = newDicomElement(DCM_QueryRetrieveLevel);
 
1227
                                        e->putString(wxString( "SERIES", wxConvUTF8).mb_str(conv));
 
1228
                                        query.insert(e, true);
 
1229
 
 
1230
                                        e = newDicomElement(DCM_StudyInstanceUID);
 
1231
                                        if (query.insert(e).bad()) {
 
1232
                                                delete e;
 
1233
                                        }
 
1234
 
 
1235
                                        e = newDicomElement(DCM_SeriesInstanceUID);
 
1236
                                        if (query.insert(e).bad()) {
 
1237
                                                delete e;
 
1238
                                        }
 
1239
 
 
1240
                                        if (!f.QueryServer(&query, server, pModelo, localAET, CT_None)) 
 
1241
                                        {
 
1242
                                                return false;
 
1243
                                        }
 
1244
 
 
1245
                                        if (f.Stopped()){
 
1246
                                                return false;
 
1247
                                        }
 
1248
                                        DcmStack* stack = f.GetResultStack();
 
1249
 
 
1250
                                        OFString tempOf;
 
1251
 
 
1252
                                        for (unsigned int i = 0; i < stack->card(); i++) {
 
1253
 
 
1254
                                                if (stack->elem(i)->ident() == EVR_dataset) {
 
1255
                                                        DcmDataset* dset = dynamic_cast<DcmDataset*>(stack->elem(i));
 
1256
                                                        if (dset) {
 
1257
 
 
1258
                                                                if ( dset->findAndGetOFString(DCM_StudyInstanceUID, tempOf).good() && tempOf.size() > 0 )
 
1259
                                                                {
 
1260
                                                                        studyInstanceUID = tempOf.c_str();
 
1261
                                                                        break;
 
1262
                                                                }
 
1263
                                                        }
 
1264
 
 
1265
                                                }
 
1266
                                        }
 
1267
                                        query.clear();
 
1268
                                }
 
1269
                                if (studyInstanceUID.empty()) {
 
1270
                                        LOG_ERROR("PACSController", "StudyInstanceUID not found");
 
1271
                                        return false;
 
1272
                                }
 
1273
 
 
1274
                                //now we have to get all sop instance uids...
 
1275
                                f.DeleteResultStack();
 
1276
                                e = newDicomElement(DCM_SpecificCharacterSet);
 
1277
                                e->putString(server->GetDefaultCharset().c_str());
 
1278
                                query.insert(e);
 
1279
 
 
1280
                                e = newDicomElement(DCM_QueryRetrieveLevel);
 
1281
                                e->putString(wxString( "IMAGE", wxConvUTF8).mb_str(conv));
 
1282
                                query.insert(e, true);
 
1283
 
 
1284
                                e = newDicomElement(DCM_SeriesInstanceUID);
 
1285
                                e->putString(wxString( seriesInstanceUID.c_str(), wxConvUTF8).mb_str(conv));
 
1286
                                if (query.insert(e).bad()) {
 
1287
                                        delete e;
 
1288
                                }
 
1289
 
 
1290
                                e = newDicomElement(DCM_SOPInstanceUID);
 
1291
                                if (query.insert(e).bad()) {
 
1292
                                        delete e;
 
1293
                                }
 
1294
 
 
1295
                                e = newDicomElement(DCM_InstanceNumber);
 
1296
                                if (query.insert(e).bad()) {
 
1297
                                        delete e;
 
1298
                                }
 
1299
 
 
1300
                                if (!f.QueryServer(&query, server, pModelo, localAET, CT_None)) 
 
1301
                                {
 
1302
                                        return false;
 
1303
                                }
 
1304
 
 
1305
                                if (f.Stopped()){
 
1306
                                        return false;
 
1307
                                }
 
1308
                                DcmStack* stack = f.GetResultStack();
 
1309
 
 
1310
                                OFString tempOf;
 
1311
                                std::list<std::pair<long, std::string> > instances;
 
1312
 
 
1313
                                for (unsigned int i = 0; i < stack->card(); i++) {
 
1314
                                        if (stack->elem(i)->ident() == EVR_dataset) {
 
1315
                                                DcmDataset* dset = dynamic_cast<DcmDataset*>(stack->elem(i));
 
1316
                                                if (dset) {
 
1317
                                                        if ( dset->findAndGetOFString(DCM_SOPInstanceUID, tempOf).good() && tempOf.size() > 0 )
 
1318
                                                        {
 
1319
                                                                const std::string sopInstanceUID = tempOf.c_str();
 
1320
                                                                long instanceNumber;
 
1321
                                                                std::pair<long, std::string> item;
 
1322
                                                                item.second = sopInstanceUID;
 
1323
                                                                if ( dset->findAndGetLongInt(DCM_InstanceNumber, instanceNumber).good() ) {
 
1324
                                                                        item.first = instanceNumber;
 
1325
                                                                } else {
 
1326
                                                                        item.first = LONG_MAX;
 
1327
                                                                }
 
1328
                                                                instances.push_back(item);
 
1329
                                                        }
 
1330
                                                }
 
1331
                                        }
 
1332
                                }
 
1333
                                query.clear();
 
1334
                                
 
1335
                                //sort by instance number...
 
1336
                                instances.sort(compare_instances);
 
1337
                                std::list<std::string> sopInstanceUIDs;
 
1338
                                std::list<long> instanceNumbers;
 
1339
                                for (std::list<std::pair<long, std::string> >::const_iterator it = instances.begin(); it != instances.end(); ++it) {
 
1340
                                        sopInstanceUIDs.push_back((*it).second);
 
1341
                                        instanceNumbers.push_back((*it).first);
 
1342
                                }
 
1343
 
 
1344
                                //now we have studyInstanceUID, seriesInstanceUID and sopInstancesUIDS.... download it!
 
1345
                                return DownloadWADOImages(serverId, studyInstanceUID, seriesInstanceUID, sopInstanceUIDs, instanceNumbers, pModelo, pNotificador, link);
 
1346
                        }//end wado
 
1347
                        else 
 
1348
                        {//get and move
 
1349
                                FillInQuery(base, &query, server);
 
1350
 
 
1351
                                e = newDicomElement(DCM_SpecificCharacterSet);
 
1352
                                e->putString(server->GetDefaultCharset().c_str());
 
1353
                                query.insert(e);                        
 
1354
 
 
1355
                                e = newDicomElement(DCM_QueryRetrieveLevel);
 
1356
                                e->putString(wxString( "SERIES", wxConvUTF8).mb_str(conv));
 
1357
                                query.insert(e, true);
 
1358
 
 
1359
                                e = newDicomElement(DCM_SeriesInstanceUID);
 
1360
                                if (query.insert(e).bad()) {
 
1361
                                        delete e;
 
1362
                                }
 
1363
 
 
1364
                                e = newDicomElement(DCM_Modality);
 
1365
                                if (query.insert(e).bad()) {
 
1366
                                        delete e;
 
1367
                                }
 
1368
 
 
1369
                                e = newDicomElement(DCM_SeriesNumber);
 
1370
                                if (query.insert(e).bad()) {
 
1371
                                        delete e;
 
1372
                                }
 
1373
 
 
1374
                                std::string localAET = GNC::Entorno::Instance()->GetDicomLocalAET();
 
1375
 
 
1376
                                if (server->GetRetrieveMethod() == DicomServer::MOVE) {
 
1377
 
 
1378
                                        if (server) {
 
1379
                                                LOG_INFO("C-MOVE", "Downloading serie from PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-MOVE");
 
1380
                                        }
 
1381
 
 
1382
                                        if (server) {
 
1383
                                                LOG_INFO("C-MOVE", "Downloading study from PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-MOVE");
 
1384
                                        }
 
1385
 
 
1386
                                        NetClient<MoveAssociation> a(connectionKey, "C-MOVE", pNotificador);
 
1387
                                        a.SetRole(Association::RT_Requestor);
 
1388
                                        a.SetModelo(pModelo);
 
1389
 
 
1390
 
 
1391
                                        if (server->useTLS) {
 
1392
                                                a.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
 
1393
                                        }
 
1394
                                        if (server->GetPACSUser() != "") {
 
1395
                                                a.SetUserPass(server->GetPACSUser(), server->GetPACSPass());
 
1396
                                        }
 
1397
                                        if (!a.QueryServer(&query, server, pModelo, localAET, CT_MoveSerie)) {
 
1398
                                                return false;
 
1399
                                        }
 
1400
                                }
 
1401
                                else {
 
1402
                                        if (server) {
 
1403
                                                LOG_INFO("C-GET", "Downloading serie from PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-GET");
 
1404
                                        }
 
1405
 
 
1406
                                        NetClient<GetAssociation> a(connectionKey, "C-GET", pNotificador);
 
1407
                                        a.SetMaxResults(-1);
 
1408
                                        a.SetWellKnownNumResults(numResults);
 
1409
                                        a.SetStorageSOPClasses(GIL::DICOM::Conformance::GetModalities().GetSupportedSOPClassUIDs(modality));
 
1410
                                        a.SetModelo(pModelo);
 
1411
                                        
 
1412
                                        if (server->useTLS) {
 
1413
                                                a.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
 
1414
                                        }
 
1415
                                        if (server->GetPACSUser() != "") {
 
1416
                                                a.SetUserPass(server->GetPACSUser(), server->GetPACSPass());
 
1417
                                        }
 
1418
                                        if (!a.QueryServer(&query, server, pModelo, localAET, CT_MoveSerie)) {
 
1419
                                                return false;
 
1420
                                        }
 
1421
                                }
 
1422
                                query.clear();
 
1423
                        }
1303
1424
                        return true;
1304
1425
 
1305
1426
                }
1310
1431
                                return false;
1311
1432
                        }
1312
1433
                        DicomServerList* listaServidores = DicomServerList::Instance();
1313
 
                        DicomServer* server = listaServidores->GetServer(serverId);
 
1434
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
1314
1435
 
1315
 
                        if (server == NULL) {
 
1436
                        if (!server.IsValid()) {
1316
1437
                                LOG_ERROR("C-MOVE/C-GET", "Invalid server");
1317
1438
                                return false;
1318
1439
                        }
1339
1460
 
1340
1461
                        std::string localAET = GNC::Entorno::Instance()->GetDicomLocalAET();
1341
1462
 
1342
 
                        if (server->GetRetrieveWithMove()) {
 
1463
                        if (server->GetRetrieveMethod() == DicomServer::MOVE) {
1343
1464
 
1344
1465
                                if (server) {
1345
 
                                        LOG_INFO("C-MOVE", "Obteniendo imagen del PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-MOVE");
 
1466
                                        LOG_INFO("C-MOVE", "Downloading imagen from PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-MOVE");
1346
1467
                                }
1347
1468
 
1348
1469
                                NetClient<MoveAssociation> a(connectionKey, "C-MOVE", pNotificador);
1349
1470
                                a.SetModelo(pModelo);
1350
 
 
1351
 
                                a.SetCallbackHandler(this);
1352
 
 
 
1471
                                
1353
1472
                                if (server->useTLS) {
1354
1473
                                        a.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
1355
1474
                                }
1356
1475
                                if (server->GetPACSUser() != "") {
1357
1476
                                        a.SetUserPass(server->GetPACSUser(), server->GetPACSPass());
1358
1477
                                }
1359
 
                                a.QueryServer(&query, server, pModelo, localAET, CT_MoveImagen);
 
1478
                                if (!a.QueryServer(&query, server, pModelo, localAET, CT_MoveImagen)) {
 
1479
                                        return false;
 
1480
                                }
1360
1481
 
1361
1482
                        }
1362
 
                        else {
 
1483
                        else if (server->GetRetrieveMethod() == DicomServer::GET) {
1363
1484
 
1364
1485
                                if (server) {
1365
 
                                        LOG_INFO("C-GET", "Obteniendo imagen del PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-GET");
 
1486
                                        LOG_INFO("C-GET", "Downloading image from PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser << ", Method=C-GET");
1366
1487
                                }
1367
1488
 
1368
1489
                                NetClient<GetAssociation> a(connectionKey, "C-GET", pNotificador);
1369
1490
                                a.SetModelo(pModelo);
1370
 
 
1371
 
                                a.SetCallbackHandler(this);
1372
 
 
 
1491
                                
1373
1492
                                if (server->useTLS) {
1374
1493
                                        a.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
1375
1494
                                }
1376
1495
                                if (server->GetPACSUser() != "") {
1377
1496
                                        a.SetUserPass(server->GetPACSUser(), server->GetPACSPass());
1378
1497
                                }
1379
 
                                a.QueryServer(&query, server, pModelo, localAET, CT_MoveImagen);
1380
 
                        }
1381
 
                        return true;
1382
 
                }
1383
 
 
1384
 
                /** Gets the current server ID list */
1385
 
                void PACSController::GetServerList(std::list<std::string>& /*list*/)
1386
 
                {
1387
 
                        //TODO
 
1498
                                if (!a.QueryServer(&query, server, pModelo, localAET, CT_MoveImagen))  {
 
1499
                                        return false;
 
1500
                                }
 
1501
                        } else if (server->GetRetrieveMethod() == DicomServer::WADO) {
 
1502
                                //we have to get seriesInstance and studyInstanceUID...
 
1503
                                std::string seriesInstanceUID, studyInstanceUID;
 
1504
                                if (!base.getTag(GKDCM_SeriesInstanceUID, seriesInstanceUID) || !base.getTag(GKDCM_StudyInstanceUID, studyInstanceUID)) {
 
1505
                                        FillInQuery(base, &query, server);
 
1506
 
 
1507
                                        e = newDicomElement(DCM_SpecificCharacterSet);
 
1508
                                        e->putString(server->GetDefaultCharset().c_str());
 
1509
                                        query.insert(e);
 
1510
 
 
1511
                                        e = newDicomElement(DCM_QueryRetrieveLevel);
 
1512
                                        e->putString(wxString( "IMAGE", wxConvUTF8).mb_str(conv));
 
1513
                                        query.insert(e, true);
 
1514
 
 
1515
                                        e = newDicomElement(DCM_StudyInstanceUID);
 
1516
                                        if (query.insert(e).bad()) {
 
1517
                                                delete e;
 
1518
                                        }
 
1519
                                        e = newDicomElement(DCM_SeriesInstanceUID);
 
1520
                                        if (query.insert(e).bad()) {
 
1521
                                                delete e;
 
1522
                                        }
 
1523
 
 
1524
                                        //association to make finds...
 
1525
                                        NetClient<FindAssociation> f(connectionKey, "WADO/FIND", pNotificador);
 
1526
                                        f.SetMaxResults(-1);
 
1527
 
 
1528
                                        std::string localAET = GNC::Entorno::Instance()->GetDicomLocalAET();
 
1529
 
 
1530
                                        if (server->useTLS) {
 
1531
                                                f.SetTLS(server->GetCertificate(), server->GetPrivateKey(), server->GetverifyCredentials());
 
1532
                                        }
 
1533
                                        if (server->GetPACSUser() != "") {
 
1534
                                                f.SetUserPass(server->GetPACSUser(), server->GetPACSPass());
 
1535
                                        }
 
1536
 
 
1537
 
 
1538
                                        if (!f.QueryServer(&query, server, pModelo, localAET, CT_None)) 
 
1539
                                        {
 
1540
                                                return false;
 
1541
                                        }
 
1542
 
 
1543
                                        if (f.Stopped()){
 
1544
                                                return false;
 
1545
                                        }
 
1546
                                        DcmStack* stack = f.GetResultStack();
 
1547
 
 
1548
                                        OFString tempOf;
 
1549
 
 
1550
                                        for (unsigned int i = 0; i < stack->card(); i++) {
 
1551
 
 
1552
                                                if (stack->elem(i)->ident() == EVR_dataset) {
 
1553
                                                        DcmDataset* dset = dynamic_cast<DcmDataset*>(stack->elem(i));
 
1554
                                                        if (dset) {
 
1555
 
 
1556
                                                                if ( dset->findAndGetOFString(DCM_StudyInstanceUID, tempOf).good() && tempOf.size() > 0 )
 
1557
                                                                {
 
1558
                                                                        studyInstanceUID = tempOf.c_str();
 
1559
                                                                }
 
1560
                                                                if ( dset->findAndGetOFString(DCM_SeriesInstanceUID, tempOf).good() && tempOf.size() > 0 )
 
1561
                                                                {
 
1562
                                                                        seriesInstanceUID = tempOf.c_str();
 
1563
                                                                }
 
1564
                                                        }
 
1565
                                                }
 
1566
                                        }
 
1567
                                        query.clear();
 
1568
                                }
 
1569
                                if (studyInstanceUID.empty() || seriesInstanceUID.empty()) {
 
1570
                                        LOG_ERROR("PACSController", "StudyInstanceUID or SeriesInstanceUID not found");
 
1571
                                        return false;
 
1572
                                }
 
1573
                                std::list<std::string> sopInstanceUIDs;
 
1574
                                sopInstanceUIDs.push_back(base.getTag(GKDCM_SOPInstanceUID));
 
1575
                                std::list<long> instanceNumbers;
 
1576
                                instanceNumbers.push_back(0);
 
1577
                                //now we have studyInstanceUID, seriesInstanceUID and sopInstancesUIDS.... download it!
 
1578
                                return DownloadWADOImages(serverId, studyInstanceUID, seriesInstanceUID, sopInstanceUIDs, instanceNumbers, pModelo, pNotificador, false);
 
1579
                        }
 
1580
                        return true;
 
1581
                }
 
1582
 
 
1583
                size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
 
1584
                        size_t written = fwrite(ptr, size, nmemb, stream);
 
1585
                        return written;
 
1586
                }
 
1587
 
 
1588
                //sopinstanceuids are sorted by instance number!
 
1589
                bool PACSController::DownloadWADOImages(const std::string& serverId, 
 
1590
                                const std::string& studyInstanceUID,
 
1591
                                const std::string& seriesInstanceUID,
 
1592
                                const std::list<std::string>& sopInstanceUID,
 
1593
                                const std::list<long>& instanceNumbers,
 
1594
                                IModeloDicom* pModelo,
 
1595
                                GNC::IProxyNotificadorProgreso* pNotificador,
 
1596
                                bool link)
 
1597
                {
 
1598
                        DicomServerList* listaServidores = DicomServerList::Instance();
 
1599
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
 
1600
 
 
1601
                        std::string pathOfSeries = GNC::Entorno::Instance()->CrearDirectorioTemporal();
 
1602
 
 
1603
                        int curr = 1;
 
1604
                        std::list<long>::const_iterator itInstanceNumber = instanceNumbers.begin();
 
1605
                        for (std::list<std::string>::const_iterator itSopInstances = sopInstanceUID.begin(); itSopInstances != sopInstanceUID.end(); ++itSopInstances, curr++, itInstanceNumber++)
 
1606
                        {
 
1607
                                std::ostringstream progress;
 
1608
                                progress << _Std("Downloading file") << " " << curr << "/" << sopInstanceUID.size();
 
1609
                                if (!pNotificador->NotificarProgreso((float)(curr-1)/sopInstanceUID.size(), progress.str())) {
 
1610
                                        return false;
 
1611
                                }
 
1612
                                std::ostringstream ostr;
 
1613
                                ostr << server->GetWADOURI();
 
1614
                                if (server->GetWADOURI().find("?") == std::string::npos) {
 
1615
                                        ostr << "?";
 
1616
                                }
 
1617
                                ostr << "requestType=WADO&contentType=application%2Fdicom&studyUID=" << studyInstanceUID;
 
1618
                                ostr << "&seriesUID=" << seriesInstanceUID;
 
1619
                                ostr << "&objectUID=" << (*itSopInstances);
 
1620
                                std::string url = ostr.str();
 
1621
 
 
1622
                                if (link && curr > 1) {
 
1623
                                        //link it
 
1624
                                        const IModeloSerie* pSeries;
 
1625
                                        pModelo->BuscarSerie(seriesInstanceUID, &pSeries);
 
1626
                                        std::ostringstream ostr;
 
1627
                                        ostr << (*itInstanceNumber);
 
1628
                                        pModelo->InsertarImagen(seriesInstanceUID,(*itSopInstances), ostr.str(),url);
 
1629
                                } else {
 
1630
                                        //download first file of the series...
 
1631
                                        std::ostringstream ofilePath;
 
1632
                                        ofilePath << pathOfSeries << (char)wxFileName::GetPathSeparator();
 
1633
                                        ofilePath << (*itSopInstances);
 
1634
                                        std::string filePath = ofilePath.str();
 
1635
                                        if (DownloadFileFromURL(url, filePath, pNotificador)) {
 
1636
                                                DICOMManager dm;
 
1637
                                                GIL::DICOM::DicomDataset base;
 
1638
                                                dm.CargarFichero(filePath, base);
 
1639
                                                const IModeloPaciente& paciente = pModelo->InsertarPaciente(base.getTag(GKDCM_PatientID), base.getTag(GKDCM_PatientName), base.getTag(GKDCM_PatientBirthDate), base.getTag(GKDCM_PatientSex));
 
1640
                                                pModelo->InsertarEstudio(paciente.GetUID(), base.getTag(GKDCM_StudyInstanceUID), base.getTag(GKDCM_AccessionNumber), base.getTag(GKDCM_StudyDescription), base.getTag(GKDCM_ModalitiesInStudy), base.getTag(GKDCM_StudyDate), base.getTag(GKDCM_StudyTime), base.getTag(GKDCM_ReferringPhysicianName));
 
1641
                                                pModelo->InsertarSerie(base.getTag(GKDCM_StudyInstanceUID), base.getTag(GKDCM_SeriesInstanceUID), base.getTag(GKDCM_SeriesType), base.getTag(GKDCM_SeriesDate), base.getTag(GKDCM_SeriesTime), base.getTag(GKDCM_SeriesDescription), base.getTag(GKDCM_SeriesNumber),base.getTag(GKDCM_ReferringPhysicianName));
 
1642
                                                pModelo->InsertarImagen(base.getTag(GKDCM_SeriesInstanceUID),base.getTag(GKDCM_SOPInstanceUID), base.getTag(GKDCM_InstanceNumber), filePath);
 
1643
                                        }
 
1644
                                }//end download first file of the series
 
1645
                        }
 
1646
                        return true;
 
1647
                }
 
1648
 
 
1649
                int progress_func_download_wado(void* ptr, double TotalToDownload, double NowDownloaded, double , double )
 
1650
                {
 
1651
                        GNC::IProxyNotificadorProgreso* pCmd = (GNC::IProxyNotificadorProgreso*)(ptr);
 
1652
                        if (pCmd != NULL && TotalToDownload != 0) {
 
1653
                                if (pCmd->NotificarProgreso((float)NowDownloaded/TotalToDownload, "")) {
 
1654
                                        return 0;
 
1655
                                } else {
 
1656
                                        return -1;
 
1657
                                }
 
1658
                        } else if (pCmd != NULL && NowDownloaded != 0) {
 
1659
                                wxString message = wxString::Format(wxT("Unknow file size downloaded %.2f Mb"), (float)NowDownloaded/(1024*1024));
 
1660
                                if (pCmd->NotificarProgreso((float)NowDownloaded/(10*1024*1024), std::string(message.ToUTF8()))) {
 
1661
                                        return 0;
 
1662
                                } else {
 
1663
                                        return -1;
 
1664
                                }
 
1665
                        } else {
 
1666
                                return 0;
 
1667
                        }
 
1668
                }
 
1669
 
 
1670
                bool PACSController::DownloadFileFromURL(const std::string& url, const std::string& filePath, GNC::IProxyNotificadorProgreso* pNotifier)
 
1671
                {
 
1672
                        LOG_DEBUG("PACSController", "Trying to download: " << url);
 
1673
                        CURL *http_handle;
 
1674
                        FILE *fp;
 
1675
 
 
1676
                        http_handle = curl_easy_init();
 
1677
                        if (http_handle) {
 
1678
                                fp = fopen(filePath.c_str(), "wb");
 
1679
                                curl_easy_setopt(http_handle, CURLOPT_URL, url.c_str());                                        
 
1680
                                //proxy settings
 
1681
                                wxProxySettings settings;
 
1682
                                settings.ProxySettingsLoadGeneral();
 
1683
                                if (settings.m_bUseProxy) {
 
1684
                                        curl_easy_setopt(http_handle, CURLOPT_PROXY, std::string(settings.m_strProxyHostname.ToUTF8()).c_str());
 
1685
                                        curl_easy_setopt(http_handle, CURLOPT_PROXYPORT, settings.m_nProxyPort);
 
1686
                                        if (settings.m_bRequiresAuth) {
 
1687
                                                curl_easy_setopt(http_handle, CURLOPT_PROXYUSERNAME,std::string(settings.m_strProxyUsername.ToUTF8()).c_str());
 
1688
                                                curl_easy_setopt(http_handle, CURLOPT_PROXYPASSWORD, std::string(settings.m_strProxyPassword.ToUTF8()).c_str());
 
1689
                                        }
 
1690
                                        curl_easy_setopt(http_handle, CURLOPT_NOPROXY, std::string(settings.m_strProxyExceptions.ToUTF8()).c_str());
 
1691
                                }
 
1692
                                //progress
 
1693
                                curl_easy_setopt(http_handle, CURLOPT_PROGRESSDATA , pNotifier);
 
1694
                                curl_easy_setopt(http_handle, CURLOPT_PROGRESSFUNCTION, progress_func_download_wado);
 
1695
                                curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0);
 
1696
                                //
 
1697
                                curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, write_data);
 
1698
                                curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, fp);
 
1699
                                CURLcode res = curl_easy_perform(http_handle);
 
1700
                                fclose(fp);
 
1701
                                long http_code = 0;
 
1702
                                curl_easy_getinfo (http_handle, CURLINFO_RESPONSE_CODE, &http_code);
 
1703
                                if (http_code == 200 && res != CURLE_ABORTED_BY_CALLBACK)
 
1704
                                {
 
1705
                                        //succeeed
 
1706
                                        curl_easy_cleanup(http_handle);
 
1707
                                        return true;
 
1708
                                } else {
 
1709
                                        curl_easy_cleanup(http_handle);
 
1710
                                        LOG_ERROR("PACSController", "Error downloading file " << url << " Curl code (" << res << ") " << curl_easy_strerror(res) << " http status: " << http_code );
 
1711
                                        std::ostringstream ostrMsg;
 
1712
                                        ostrMsg << _Std("Error downloading WADO file")  << " (HTTP Status: " << http_code << ") " << "URL :" << std::endl << url << std::endl << _Std("Check PACS configuration");
 
1713
                                        throw GIL::DICOM::PACSException( ostrMsg.str());
 
1714
                                }
 
1715
                        } else {
 
1716
                                LOG_ERROR("PACSController", "Error initializing curl");
 
1717
                                throw GIL::DICOM::PACSException( "Error initialiting curl" );
 
1718
                        }
1388
1719
                }
1389
1720
 
1390
1721
                /** Perform query */
1403
1734
                        resultsWrapper.clear();
1404
1735
 
1405
1736
                        DicomServerList* listaServidores = DicomServerList::Instance();
1406
 
                        DicomServer* server = listaServidores->GetServer(serverId);
 
1737
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
1407
1738
 
1408
1739
                        DcmDataset query;
1409
1740
                        DcmElement* e = NULL;
1456
1787
                        const std::string& serverId,
1457
1788
                        IModeloDicom* pModelo,
1458
1789
                        const GIL::DICOM::DicomDataset& base,
1459
 
                        GNC::IProxyNotificadorProgreso* pNotificador)
 
1790
                        GNC::IProxyNotificadorProgreso* pNotificador,
 
1791
                        bool link)
1460
1792
                {
1461
1793
                        std::string strTmp;
1462
1794
                        if(base.getTag("0008|0052", strTmp)) {
1468
1800
                                                throw GIL::DICOM::PACSException(_Std("You have to specify at least uid study or accession number"));
1469
1801
                                        }
1470
1802
 
1471
 
                                        ObtenerEstudio(connectionKey, serverId, base, pModelo, pNotificador);
 
1803
                                        ObtenerEstudio(connectionKey, serverId, base, pModelo, pNotificador, link);
1472
1804
                                } else if (strTmp == "SERIES") {
1473
1805
                                        std::string uidSeries;
1474
1806
                                        if (!base.getTag("0020|000e",uidSeries)) {
1475
1807
                                                throw GIL::DICOM::PACSException(_Std("You have to specify at least uid series"));
1476
1808
                                        }
1477
 
                                        ObtenerSerie(connectionKey, serverId, base, pModelo, pNotificador);
 
1809
                                        ObtenerSerie(connectionKey, serverId, base, pModelo, pNotificador, link);
1478
1810
                                } else if (strTmp == "IMAGE")  {
1479
1811
                                        std::string uidImage;
1480
1812
                                        if (!base.getTag("0008|0018",uidImage)) {
1491
1823
                        return true;
1492
1824
                }
1493
1825
 
 
1826
                void PACSController::TestWADOURL(const std::string& url) {
 
1827
                        CURL *http_handle = NULL;
 
1828
                        std::ostringstream errorMsg;
 
1829
                        bool success = true;
 
1830
 
 
1831
                        char curl_err[CURL_ERROR_SIZE];
 
1832
 
 
1833
                        http_handle = curl_easy_init();
 
1834
                        if (http_handle) {
 
1835
                                curl_easy_setopt(http_handle, CURLOPT_URL, url.c_str());                                        
 
1836
                                //proxy settings
 
1837
                                wxProxySettings settings;
 
1838
                                settings.ProxySettingsLoadGeneral();
 
1839
                                if (settings.m_bUseProxy) {
 
1840
                                        curl_easy_setopt(http_handle, CURLOPT_PROXY, std::string(settings.m_strProxyHostname.ToUTF8()).c_str());
 
1841
                                        curl_easy_setopt(http_handle, CURLOPT_PROXYPORT, settings.m_nProxyPort);
 
1842
                                        if (settings.m_bRequiresAuth) {
 
1843
                                                curl_easy_setopt(http_handle, CURLOPT_PROXYUSERNAME,std::string(settings.m_strProxyUsername.ToUTF8()).c_str());
 
1844
                                                curl_easy_setopt(http_handle, CURLOPT_PROXYPORT, std::string(settings.m_strProxyPassword.ToUTF8()).c_str());
 
1845
                                        }
 
1846
                                        curl_easy_setopt(http_handle, CURLOPT_NOPROXY, std::string(settings.m_strProxyExceptions.ToUTF8()).c_str());
 
1847
                                }
 
1848
 
 
1849
                                curl_easy_setopt(http_handle, CURLOPT_ERRORBUFFER, curl_err);
 
1850
                                long http_code = -1;
 
1851
 
 
1852
                                CURLcode res = curl_easy_perform(http_handle);
 
1853
                                
 
1854
                                if (res != CURLE_OK) {
 
1855
                                        errorMsg << _Std("Unable to perform HTTP request") << ": " << curl_err;
 
1856
                                        success = false;
 
1857
                                }
 
1858
                                if (success && (CURLE_OK != curl_easy_getinfo (http_handle, CURLINFO_RESPONSE_CODE, &http_code)) ) {
 
1859
                                        errorMsg << _Std("Invalid HTTP response")  << ": " << curl_err;
 
1860
                                        success = false;
 
1861
                                }
 
1862
                                if (success) {
 
1863
                                        if ( (http_code < 200 || http_code > 500) ) {
 
1864
                                                errorMsg << _Std("Invalid HTTP code") << ":" << http_code;
 
1865
                                                success = false;
 
1866
                                        }
 
1867
                                }
 
1868
                                curl_easy_cleanup(http_handle);
 
1869
 
 
1870
                        } else {
 
1871
                                errorMsg << _Std("Unable to init HTTP subsystem");
 
1872
                                success = false;
 
1873
                        }
 
1874
 
 
1875
                        if (!success) {
 
1876
                                throw GIL::DICOM::PACSException(errorMsg.str());
 
1877
                        }
 
1878
                }
 
1879
 
1494
1880
                GIL::DICOM::ICustomAssociation* PACSController::CreateCustomAssociation(void* connectionKey, const std::string& ambitolog, GNC::IProxyNotificadorProgreso* pNotificador)
1495
1881
                {
1496
1882
                        return new CustomAssociation(connectionKey, ambitolog, pNotificador);
1497
1883
                }
1498
 
                
 
1884
 
1499
1885
                void PACSController::DestroyCustomAssociation(GIL::DICOM::ICustomAssociation* assoc)
1500
1886
                {
1501
1887
                        if (assoc != NULL) {
1517
1903
                        this->m_pServiceInstance = new GIL::DICOM::Service(_Std("PACS-Service"));
1518
1904
                        this->m_pServiceInstance->SetRole(GIL::DICOM::Service::RT_Acceptor);
1519
1905
                        this->m_pServiceInstance->SetAcceptorPort(localPort);
1520
 
                        
 
1906
 
1521
1907
                        this->m_pServiceInstance->SetLocalAET(localAET);
1522
1908
                        this->m_pServiceInstance->Start();
1523
1909
 
1526
1912
                void PACSController::StopServer()
1527
1913
                {
1528
1914
                        if (this->m_pServiceInstance != NULL) {
1529
 
                                unsigned long tid = this->m_pServiceInstance->GetTid();
1530
 
                                GNC::GCS::ThreadController::Stop(tid);
 
1915
                                unsigned long tid;
 
1916
                                do {
 
1917
                                        tid = this->m_pServiceInstance->GetTid();
 
1918
                                        GNC::GCS::ThreadController::Stop(tid);
 
1919
                                } while (this->m_pServiceInstance->GetTid() != tid);
1531
1920
                                delete this->m_pServiceInstance;
1532
1921
                                this->m_pServiceInstance = NULL;
1533
1922
                        }
1551
1940
                        DicomServerList* listaServidores = DicomServerList::Instance();
1552
1941
                        std::string localAET = GNC::Entorno::Instance()->GetDicomLocalAET();
1553
1942
                        GIL::DICOM::DicomStoreAssociation asociacion;
1554
 
                        DicomServer* server = listaServidores->GetServer(serverId);
 
1943
                        GNC::GCS::Ptr<DicomServer> server = listaServidores->GetServer(serverId);
1555
1944
                        if (server) {
1556
1945
                                LOG_INFO("PACS-STORE", "Enviando al PACS " << serverId << ": " << server->AET << "@" << server->HostName << ":" << server->Port << " PDU=" << server->PDU << ", TLS=" << server->useTLS << ",  User = " << server->pacsUser);
1557
1946
                        }
1756
2145
                }
1757
2146
                //endregion
1758
2147
        };
1759
 
};
 
 
b'\\ No newline at end of file'
 
2148
};