static CONDITION resultsSet(MSG_N_SET_REQ * request, MSG_N_SET_RESP * response, CALLBACK_CTX * ctx) { CONDITION cond; FIS_RESULTSRECORD results; long flag; #ifdef SMM results.Type = FIS_K_RESULTS; strcpy(results.ResUID, request->requestedInstanceUID); cond = FIS_GetOne(ctx->fis, FIS_K_RESULTS, FIS_K_RESULTS, request->requestedInstanceUID, flag, &results); if (cond != FIS_NORMAL) return 0; results.Flag &= flag; cond = FIS_BuildObject(&response->dataSet, FIS_K_RESULTS, &results, FIS_K_NO_EVENT); if (cond != FIS_NORMAL) return 0; response->dataSetType = DCM_CMDDATAOTHER; (void) DCM_DumpElements(&response->dataSet, 0); #endif return 1; }
static CONDITION interpretationSet(MSG_N_SET_REQ * request, MSG_N_SET_RESP * response, CALLBACK_CTX * ctx) { CONDITION cond; FIS_INTERPRETATIONRECORD interpretation; long flag; #ifdef SMM interpretation.Type = FIS_K_INTERPRETATION; strcpy(interpretation.IntUID, request->requestedInstanceUID); cond = FIS_GetOne(ctx->fis, FIS_K_INTERPRETATION, FIS_K_INTERPRETATION, request->requestedInstanceUID, flag, &interpretation); if (cond != FIS_NORMAL) return 0; interpretation.Flag &= flag; cond = FIS_BuildObject(&response->dataSet, FIS_K_INTERPRETATION, &interpretation, FIS_K_NO_EVENT); if (cond != FIS_NORMAL) return 0; response->dataSetType = DCM_CMDDATAOTHER; (void) DCM_DumpElements(&response->dataSet, 0); #endif return 1; }
static CONDITION studySet(MSG_N_SET_REQ * request, MSG_N_SET_RESP * response, CALLBACK_CTX * ctx) { CONDITION cond; FIS_STUDYRECORD study; long flag; if (request->dataSetType != DCM_CMDDATANULL) { (void) DCM_DumpElements(&request->dataSet, 0); } cond = FIS_ParseObject(&request->dataSet, FIS_K_STUDY, &study); if (cond != FIS_NORMAL) return 0; study.Flag &= STUDY_SET_FLAGS; if (study.Flag == 0) return 1; strcpy(study.StuInsUID, request->instanceUID); study.Flag |= FIS_K_STU_STUINSUID; cond = FIS_Update(ctx->fis, FIS_K_STUDY, &study); if (cond != FIS_NORMAL) { COND_DumpConditions(); } else { response->status = MSG_K_SUCCESS; } response->dataSetType = DCM_CMDDATANULL; strcpy(response->classUID, request->classUID); strcpy(response->instanceUID, request->instanceUID); response->conditionalFields = MSG_K_N_SETRESP_REQUESTEDCLASSUID | MSG_K_N_SETRESP_REQUESTEDINSTANCEUID; return 1; }
static CONDITION patientSet(MSG_N_SET_REQ * request, MSG_N_SET_RESP * response, CALLBACK_CTX * ctx) { CONDITION cond; FIS_PATIENTRECORD patient; #ifdef SMM patient.Type = FIS_K_PATIENT; strcpy(patient.PatUID, request->requestedInstanceUID); cond = FIS_GetOne(ctx->fis, FIS_K_PATIENT, FIS_K_PATIENT, request->requestedInstanceUID, 0, &patient); if (cond != FIS_NORMAL) return 0; /* SET FLAGS FOR HAP FACILITY BASED ON attributeList */ if (request->attributeCount == 0) patient.Flag = 0xffffffff; else convertTags(request->attributeCount, request->attributeList, patient_supported, &patient.Flag, (int) DIM_OF(patient_supported)); cond = FIS_BuildObject(&response->dataSet, FIS_K_PATIENT, &patient, FIS_K_NO_EVENT); if (cond != FIS_NORMAL) return 0; response->dataSetType = DCM_CMDDATAOTHER; (void) DCM_DumpElements(&response->dataSet, 0); #endif return 1; }
static CONDITION storageCallback(MSG_C_STORE_REQ * request, MSG_C_STORE_RESP * response, unsigned long received, unsigned long estimate, /* DCM_OBJECT ** object, STORAGE_PARAMS * params, */ DCM_OBJECT ** object, void *paramsPtr, DUL_PRESENTATIONCONTEXT * pc) { CONDITION cond = 0; IE_OBJECT * ieObject; /* The definition and assignment help satisfy prototypes for this callback ** function (defined by dicom_services.h) */ STORAGE_PARAMS *params; params = (STORAGE_PARAMS *) paramsPtr; if (!silent) printf("%8d bytes received of %8d estimated \n", received, estimate); if (!silent && (object != NULL)) (void) DCM_DumpElements(object, 0); if (object != NULL) { if (doVerification) { cond = IE_ExamineObject(object, &ieObject); (void) IE_Free((void **) &ieObject); if (cond != IE_NORMAL) { /* The image does not satisfy */ /* Part 3 requirements */ response->status = MSG_K_C_STORE_DATASETNOTMATCHSOPCLASSERROR; return SRV_NORMAL; } } cond = storeImage(params->handle, params->fileName, params->transferSyntax, request->classUID, params->owner, params->groupName, params->priv, object); } if (response != NULL) { if (cond == APP_NORMAL) response->status = MSG_K_SUCCESS; else response->status = MSG_K_C_STORE_OUTOFRESOURCES; } return SRV_NORMAL; }
CONDITION SRV_CGetResponse(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, DUL_PRESENTATIONCONTEXT * getPresentationCtx, MSG_C_GET_REQ ** getRequest, MSG_C_GET_RESP * getResponse, SRV_C_GET_RESP_CALLBACK * getCallback, void *getCtx, char *dirName) { int flag, responseCount = 0; U32 l; char queryLevelString[48] = ""; /* Initialization for AIX compiler */ CONDITION cond, rtnCond = SRV_NORMAL; DCM_OBJECT * responseObject; /* get response object */ void *ctx; DCM_ELEMENT queryLevelElement = {DCM_IDQUERYLEVEL, DCM_CS, "", 1, sizeof(queryLevelString), NULL}; static char *allowedQueryLevels[] = { DCM_QUERYLEVELPATIENT, DCM_QUERYLEVELSTUDY, DCM_QUERYLEVELSERIES, DCM_QUERYLEVELIMAGE}; MSG_STATUS_DESCRIPTION statusDescription; char pendingMsg[] = "\ In SRV_CGetResponse, the response message returned by your callback has \n\ a status of pending and data set that is not null.\n"; MSG_TYPE messageType; void *message; DUL_PRESENTATIONCONTEXTID ctxID; MSG_C_STORE_REQ storeRequest; char classUID[DICOM_UI_LENGTH + 1]; queryLevelElement.d.string = queryLevelString; if (getCallback == NULL) { (void) MSG_Free((void **) getRequest); return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_CGetResponse"); } if (getResponse->type != MSG_K_C_GET_RESP) { (void) MSG_Free((void **) getRequest); return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "GET Request", "SRV_CGetResponse"); } (void) strcpy(classUID, (*getRequest)->classUID); cond = DCM_CreateObject(&getResponse->identifier, 0); if (cond != DCM_NORMAL) return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse"); cond = SRV_ReceiveDataSet(association, getPresentationCtx, DUL_BLOCK, 0, dirName, &(*getRequest)->identifier); if (PRVSRV_debug && (cond == SRV_NORMAL)) (void) DCM_DumpElements(&(*getRequest)->identifier, 0); if (cond != SRV_NORMAL) { (void) MSG_Free((void **) getRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse"); } ctx = NULL; cond = DCM_GetElementValue(&(*getRequest)->identifier, &queryLevelElement, &l, &ctx); if (cond != DCM_NORMAL) { (void) MSG_Free((void **) getRequest); (void) COND_PushCondition(SRV_QUERYLEVELATTRIBUTEMISSING, SRV_Message(SRV_QUERYLEVELATTRIBUTEMISSING), "SRV_CGetResponse"); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse"); } queryLevelString[l] = '\0'; if (queryLevelString[l - 1] == ' ') queryLevelString[l - 1] = '\0'; for (flag = 0, l = 0; l < DIM_OF(allowedQueryLevels) && !flag; l++){ if (strcmp(queryLevelString, allowedQueryLevels[l]) == 0) flag = 1; } if (!flag) { (void) MSG_Free((void **) getRequest); (void) COND_PushCondition(SRV_ILLEGALQUERYLEVELATTRIBUTE, SRV_Message(SRV_ILLEGALQUERYLEVELATTRIBUTE), queryLevelString, "SRV_CGetResponse"); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse"); } getResponse->messageIDRespondedTo = (*getRequest)->messageID; getResponse->conditionalFields = 0; getResponse->remainingSubOperations = 0; getResponse->completedSubOperations = 0; getResponse->failedSubOperations = 0; getResponse->warningSubOperations = 0; /* * Fill up the Store request and let the callback routine do the matching * and fill the rest of the fields */ storeRequest.type = MSG_K_C_STORE_REQ; storeRequest.conditionalFields = 0; storeRequest.messageID = SRV_MessageIDOut(); storeRequest.priority = 0; storeRequest.moveMessageID = (*getRequest)->messageID; /* * We invoke the callback for the first time without any StoreResponse so * that the callback can deal with the query and fill the Store Request * message and the GET response message. We also pass responseCount as 0 * when we invoke the callback for the first time */ cond = getCallback(*getRequest, getResponse, &storeRequest, NULL, 0, getPresentationCtx->abstractSyntax, queryLevelString, getCtx); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CGetRespose"); if (storeRequest.dataSetType != DCM_CMDDATANULL) { /* Send a Store Request */ cond = sendStoreRequest(association, params, &storeRequest); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED),"sendStoreRequest", "SRV_CGetResponse"); }else{ /* * No images are to be transferred as the query may have been * unsuccessful in the call back routine. We expect the callback * routine to have supplied the appropriate values for the various * fields of the getResponse message. * * Send the CGetResponse Message and return from the routine */ cond = MSG_BuildCommand(getResponse, &responseObject); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "getResponse", "SRV_CGetResponse"); cond = SRV_SendCommand(association, getPresentationCtx, &responseObject); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED),"SRV_SendCommand", "SRV_CGetResponse"); if (getResponse->dataSetType != DCM_CMDDATANULL) { cond = SRV_SendDataSet(association, getPresentationCtx, &getResponse->identifier, NULL, NULL, 0); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED), "SRV_SendDataSet", "SRV_CGetResponse"); } return SRV_NORMAL; } flag = 0; while (!flag) { /* * Now wait for incoming Store Responses or a Cancel Request. If it * is a Store Response, invoke the callback routine, with the Store * Response. The callback will update the Get Response message * accordingly and also fill the Store Request message if any more * requests are to be made */ cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID, NULL, &messageType, (void **) &message); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_RECEIVEFAILED, SRV_Message(SRV_RECEIVEFAILED), "SRV_CGetResponse"); switch (messageType) { case MSG_K_C_CANCEL_REQ: rtnCond = SRV_OPERATIONCANCELLED; getResponse->status = MSG_K_CANCEL; (void) MSG_Free(&message); cond = getCallback(*getRequest, getResponse, NULL, NULL, responseCount, getPresentationCtx->abstractSyntax, queryLevelString, getCtx); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CGetRespose"); getResponse->messageIDRespondedTo = (*getRequest)->messageID; break; case MSG_K_C_STORE_RESP: responseCount++; getResponse->dataSetType = DCM_CMDDATANULL; getResponse->status = 0xffff; /* * Fill up the Store request and let the callback routine do the * matching and fill the rest of the fields */ storeRequest.type = MSG_K_C_STORE_REQ; storeRequest.conditionalFields = 0; storeRequest.messageID = SRV_MessageIDOut(); storeRequest.priority = 0; storeRequest.moveMessageID = (*getRequest)->messageID; cond = getCallback(*getRequest, getResponse, &storeRequest, (MSG_C_STORE_RESP *) message, responseCount, getPresentationCtx->abstractSyntax, queryLevelString, getCtx); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CGetRespose"); if (storeRequest.dataSetType != DCM_CMDDATANULL) { /* make the next store request */ cond = sendStoreRequest(association, params, &storeRequest); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED), "sendStoreRequest", "SRV_CGetResponse"); } break; default: break; } if (cond == SRV_NORMAL) { cond = MSG_StatusLookup(getResponse->status, MSG_K_C_GET_RESP, &statusDescription); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse"); if (statusDescription.statusClass != MSG_K_CLASS_PENDING) flag = 1; /* Consistency check */ if ((statusDescription.statusClass == MSG_K_CLASS_PENDING) && (getResponse->dataSetType != DCM_CMDDATANULL)) { if (PRVSRV_debug) fprintf(DEBUG_DEVICE, pendingMsg); rtnCond = COND_PushCondition(SRV_SUSPICIOUSRESPONSE, SRV_Message(SRV_SUSPICIOUSRESPONSE), "C-GET", "pending", "not null", "SRV_CGetResponse"); } }else{ flag = 1; } strcpy(getResponse->classUID, classUID); getResponse->conditionalFields |= MSG_K_C_GETRESP_CLASSUID; cond = MSG_BuildCommand(getResponse, &responseObject); if (cond != MSG_NORMAL) { (void) MSG_Free((void **) getRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse"); } cond = SRV_SendCommand(association, getPresentationCtx, &responseObject); if (cond != SRV_NORMAL) { (void) MSG_Free((void **) getRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse"); } if (getResponse->dataSetType != DCM_CMDDATANULL) { cond = SRV_SendDataSet(association, getPresentationCtx, &getResponse->identifier, NULL, NULL, 0); if (cond != SRV_NORMAL) { (void) MSG_Free((void **) getRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse"); } } } (void) MSG_Free((void **) getRequest); return rtnCond; }
static CONDITION studyComponentSet(MSG_N_SET_REQ * request, MSG_N_SET_RESP * response, CALLBACK_CTX * ctx) { CONDITION cond; FIS_STUDYCOMPONENTRECORD sc; long flag; FIS_SCSERIESRECORD *series; FIS_SCIMAGERECORD *image; response->status = MSG_K_SUCCESS; if (request->dataSetType != DCM_CMDDATANULL) { (void) DCM_DumpElements(&request->dataSet, 0); } else { response->status = MSG_K_MISSINGATTRIBUTE; goto ExitPoint; } cond = FIS_ParseObject(&request->dataSet, FIS_K_STUDYCOMPONENT, &sc); if (cond != FIS_NORMAL) { response->status = MSG_K_PROCESSINGFAILURE; goto ExitPoint; } sc.Flag &= STUDYCOMPONENT_SET_FLAGS; if (sc.Flag == 0) goto ExitPoint; strcpy(sc.StuComUID, request->instanceUID); sc.Flag |= FIS_K_STUDYCOMP_STUCOMUID; cond = FIS_Update(ctx->fis, FIS_K_STUDYCOMPONENT, &sc); if (cond != FIS_NORMAL) { response->status = MSG_K_PROCESSINGFAILURE; goto ExitPoint; } if (sc.Flag & FIS_K_STUDYCOMP_SERIESLIST) { /* Delete existing values in series/image tables and insert new values */ cond = FIS_Delete(ctx->fis, FIS_K_SCSERIES, FIS_K_STUDYCOMPONENT, request->instanceUID); if (cond != FIS_NORMAL) { response->status = MSG_K_PROCESSINGFAILURE; goto ExitPoint; } cond = FIS_Delete(ctx->fis, FIS_K_SCIMAGE, FIS_K_STUDYCOMPONENT, request->instanceUID); if (cond != FIS_NORMAL) { response->status = MSG_K_PROCESSINGFAILURE; goto ExitPoint; } while ((series = LST_Dequeue(&sc.SeriesList)) != NULL) { strcpy(series->StuComUID, sc.StuComUID); series->Flag |= FIS_K_SCSERIES_STUCOMUID; cond = FIS_Insert(ctx->fis, FIS_K_SCSERIES, series); if (cond != FIS_NORMAL) { response->status = MSG_K_PROCESSINGFAILURE; COND_DumpConditions(); goto ExitPoint; } while ((image = LST_Dequeue(&series->ImageList)) != NULL) { strcpy(image->SerInsUID, series->SerInsUID); strcpy(image->StuComUID, series->StuComUID); image->Flag |= FIS_K_SCIMAGE_SERINSUID | FIS_K_SCIMAGE_STUCOMUID; cond = FIS_Insert(ctx->fis, FIS_K_SCIMAGE, image); if (cond != FIS_NORMAL) { response->status = MSG_K_PROCESSINGFAILURE; COND_DumpConditions(); goto ExitPoint; } free(image); } (void) LST_Destroy(&series->ImageList); free(series); } (void) LST_Destroy(&sc.SeriesList); } response->dataSetType = DCM_CMDDATANULL; strcpy(response->classUID, request->classUID); strcpy(response->instanceUID, request->instanceUID); response->conditionalFields = MSG_K_N_SETRESP_REQUESTEDCLASSUID | MSG_K_N_SETRESP_REQUESTEDINSTANCEUID; ExitPoint: COND_DumpConditions(); return 1; }
/* makeDBEntry ** ** Purpose: ** Adds an image file to the database. ** The patient, study, series are created in the database if they don't ** already exist. If the image UID matches an existing one, the ** existing one is deleted before the new one is added. ** ** Parameter Dictionary: ** dbid DB database id ** imgfile Image file name ** prefmtImgfile Preformatted image file name ** ** Return Values: ** NONE ** ** Notes: ** ** Algorithm: ** Description of the algorithm (optional) and any other notes. */ void makeDBEntry(short dbid, char *imgfile, char *prefmtImgfile) { CONDITION cond; /* return condition status */ Query query; /* The Query structure */ DCM_OBJECT * object; /* Pointer to a DICOM object */ int parseCount; /* keeps track of the number of elements * parsed while converting from DCM object to * Query */ /* Initialize the query structure to all null characters */ (void) memset((void *) &query, '\0', sizeof(query)); /* Read the image file and convert it into an object representation */ cond = DCM_OpenFile(imgfile, (long) DCM_ORDERLITTLEENDIAN, &object); if (cond != DCM_NORMAL) myExit(DCMOPENFILEERROR); if (verbose) DCM_DumpElements(&object); /* Convert the object into the query structure */ cond = IAP_ObjectToQuery(&object, "", &query, &parseCount); if (verbose) { printf("Number of elements parsed = %d\n", parseCount); COND_DumpConditions(); printf("Query Structure created :- \n"); dump_query(&query); } if (ERROR(cond)) myExit(IAPOBJTOQUERYERROR); /* free the memory ocupied by the object */ cond = DCM_CloseObject(&object); if (cond != DCM_NORMAL) myExit(DCMCLOSEOBJERROR); /* * So far everything is fine. Now store the name of the preformatted * image file in the FileName field in the ImageLevel structure */ (void) sprintf(query.Image.FileName, "%.*s", sizeof(query.Image.FileName) - 2, prefmtImgfile); /* now create the PATIENT, STUDY and SERIES, if they don't already exist */ cond = DB_AddPatient(dbid, &query.Patient); if (cond != DB_NORMAL && cond != DB_DUPATIENT) myExit(DBADDPATERROR); cond = DB_AddStudy(dbid, query.Patient.PatID, &query.Study); if (cond != DB_NORMAL && cond != DB_DUPSTUDY) myExit(DBADDSTUDYERROR); cond = DB_AddSeries(dbid, query.Patient.PatID, query.Study.StudyUID, &query.Series); if (cond != DB_NORMAL && cond != DB_DUPSERIES) myExit(DBADDSERIESERROR); cond = DB_AddImage(dbid, query.Patient.PatID, query.Study.StudyUID, query.Series.SeriesUID, &query.Image); if (cond == DB_DUPIMAGE) { /* we just delete previous image and replace it by new one */ cond = DB_DelImage(dbid, query.Patient.PatID, query.Study.StudyUID, query.Series.SeriesUID, query.Image.ImageUID); if (cond != DB_NORMAL) myExit(DBDELIMGERROR); /* Now add this new image */ cond = DB_AddImage(dbid, query.Patient.PatID, query.Study.StudyUID, query.Series.SeriesUID, &query.Image); if (cond != DB_NORMAL) myExit(DBADDIMGERROR); } if (verbose) { dump_query(&query); DB_DumpDB(dbid); } /* As a last step, we close the data base */ cond = DB_Close(dbid); if (cond != DB_NORMAL) myExit(DBCLOSEERROR); }
static CONDITION cgetCallback(MSG_C_GET_REQ * request, MSG_C_GET_RESP * response, MSG_C_STORE_REQ * storeRequest, MSG_C_STORE_RESP * storeResponse, int responseCount, char *SOPClass, char *queryLevel, /* CGET_PARAMS * cgetParams) */ void *cgetParamsPtr) { CONDITION cond; static LST_HEAD *imageList = NULL; IDB_HANDLE **handle; static QUERY_MAP map[] = {{"PATIENT", IDB_PATIENT_LEVEL}, {"STUDY", IDB_STUDY_LEVEL}, {"SERIES", IDB_SERIES_LEVEL}, {"IMAGE", IDB_IMAGE_LEVEL}, }; int i, searchQueryEnd; CTNBOOLEAN done; long selectCount; IDB_Query queryStructure; QUERY_LIST_ITEM * queryItem; static LST_HEAD * queryList = NULL, *failedList = NULL; static DUL_NETWORKKEY * network; DUL_ASSOCIATESERVICEPARAMETERS * params; DCM_ELEMENT e = { DCM_IDFAILEDINSTANCEUIDLIST, DCM_UI, "", 1, 0, NULL }; IDB_InstanceListElement * instance; MSG_STATUS_DESCRIPTION statusDescription; /* to check the status returned by a * StoreResponse */ /* The following definition and cast operation allow us to satisfy prototypes ** for get callbacks as defined in dicom_services.h. */ CGET_PARAMS *cgetParams; cgetParams = (CGET_PARAMS *) cgetParamsPtr; network = *cgetParams->network; params = cgetParams->params; handle = cgetParams->handle; strcpy(response->classUID, request->classUID); response->conditionalFields = DCM_CMDDATANULL; response->dataSetType = DCM_CMDDATANULL; response->identifier = NULL; if (response->status == MSG_K_CANCEL) { if (!silent) printf("CGet cancelled\n"); if (queryList != NULL) { while ((queryItem = LST_Dequeue(&queryList)) != NULL) free(queryItem); } response->conditionalFields |= MSG_K_C_GET_COMPLETED | MSG_K_C_GET_FAILED | MSG_K_C_GET_WARNING; /* check if there is any failed UID list existing */ if (failedList != NULL) { response->dataSetType = DCM_CMDDATAIDENTIFIER; response->identifier = failedList; } response->conditionalFields |= MSG_K_C_GET_REMAINING; return SRV_NORMAL; } /* Check if there was a store response from the previous store request. ** If so, set various fields of the CGetResponse message. ** The first time this callback is invoked, store response will be ** NULL and response count will equal 0. */ if (storeResponse != NULL) { if (!silent) { printf("Store Response received\n"); MSG_DumpMessage(storeResponse, stdout); } cond = MSG_StatusLookup(storeResponse->status, MSG_K_C_STORE_RESP, &statusDescription); if (cond != MSG_NORMAL) { fprintf(stderr, "Invalid status code in store response: %s\n", storeResponse->status); return 0; /* repair */ } switch (statusDescription.statusClass) { case MSG_K_CLASS_SUCCESS: response->completedSubOperations++; break; case MSG_K_CLASS_WARNING: response->warningSubOperations++; break; case MSG_K_CLASS_REFUSED: case MSG_K_CLASS_FAILURE: response->failedSubOperations++; break; default: fprintf(stderr, "Invalid status code in store response: %s\n", storeResponse->status); break; } /* ** A status of pending does not contain a failed UID list. Also, a ** pending status must contain the number of remaining, completed, ** failed and warning sub operations */ response->dataSetType = DCM_CMDDATANULL; response->identifier = NULL; response->conditionalFields |= MSG_K_C_GET_REMAINING | MSG_K_C_GET_COMPLETED | MSG_K_C_GET_FAILED | MSG_K_C_GET_WARNING; /* we send a PENDING response */ response->status = MSG_K_C_GET_SUBOPERATIONSCONTINUING; } if (imageList == NULL) { imageList = LST_Create(); if (imageList == NULL) return 0; } if (!silent) { printf("CGet callback\n"); printf("SOP Class: %s\n", SOPClass); printf("Query Level: %s\n", queryLevel); printf("Response Count: %d\n", responseCount); } if (responseCount == 0) { if (!silent) (void) DCM_DumpElements(&request->identifier, 0); #ifdef CTN_MULTIBYTE cond = parseQueryMB(&request->identifier, &queryStructure); #else cond = parseQuery(&request->identifier, &queryStructure); #endif if (cond != APP_NORMAL) return 0; for (i = 0, done = FALSE; !done && i < (int) DIM_OF(map); i++) { if (strcmp(map[i].levelChar, queryLevel) == 0) { searchQueryEnd = map[i].levelInt; done = TRUE; } } switch (searchQueryEnd) { case IDB_PATIENT_LEVEL: queryStructure.study.StuInsUID[0] = '\0'; queryStructure.StudyQFlag = QF_STU_StuInsUID; queryStructure.StudyNullFlag = QF_STU_StuInsUID; queryStructure.series.SerInsUID[0] = '\0'; queryStructure.SeriesQFlag = QF_SER_SerInsUID; queryStructure.SeriesNullFlag = QF_SER_SerInsUID; queryStructure.image.SOPInsUID[0] = '\0'; queryStructure.ImageQFlag = QF_IMA_SOPInsUID; queryStructure.ImageNullFlag = QF_IMA_SOPInsUID; break; case IDB_STUDY_LEVEL: queryStructure.series.SerInsUID[0] = '\0'; queryStructure.SeriesQFlag = QF_SER_SerInsUID; queryStructure.SeriesNullFlag = QF_SER_SerInsUID; queryStructure.image.SOPInsUID[0] = '\0'; queryStructure.ImageQFlag = QF_IMA_SOPInsUID; queryStructure.ImageNullFlag = QF_IMA_SOPInsUID; break; case IDB_SERIES_LEVEL: queryStructure.image.SOPInsUID[0] = '\0'; queryStructure.ImageQFlag = QF_IMA_SOPInsUID; queryStructure.ImageNullFlag = QF_IMA_SOPInsUID; break; case IDB_IMAGE_LEVEL: break; } if (strcmp(SOPClass, DICOM_SOPPATIENTQUERY_GET) == 0) cond = IDB_Select(handle, PATIENT_ROOT, IDB_PATIENT_LEVEL, IDB_IMAGE_LEVEL, &queryStructure, &selectCount, selectCallback, imageList); else if (strcmp(SOPClass, DICOM_SOPPATIENTSTUDYQUERY_GET) == 0) cond = IDB_Select(handle, PATIENTSTUDY_ONLY, IDB_PATIENT_LEVEL, IDB_IMAGE_LEVEL, &queryStructure, &selectCount, selectCallback, imageList); else if (strcmp(SOPClass, DICOM_SOPSTUDYQUERY_GET) == 0) cond = IDB_Select(handle, STUDY_ROOT, IDB_PATIENT_LEVEL, IDB_IMAGE_LEVEL, &queryStructure, &selectCount, selectCallback, imageList); else cond = 0; if ((cond != IDB_NORMAL) && (cond != IDB_NOMATCHES)) { COND_DumpConditions(); return 0; } response->remainingSubOperations = LST_Count(&imageList); if (!silent) printf("Total store requests: %d\n", response->remainingSubOperations); failedList = LST_Create(); if (failedList == NULL) return 0; } if (imageList != NULL) queryItem = LST_Dequeue(&imageList); else queryItem = NULL; if (queryItem != NULL) { instance = LST_Head(&queryItem->query.image.InstanceList); if (instance != NULL) { storeRequest->dataSetType = DCM_CMDDATAOTHER; strcpy(storeRequest->classUID, queryItem->query.image.SOPClaUID); strcpy(storeRequest->instanceUID, queryItem->query.image.SOPInsUID); if (!silent) printf("Image file name: %s\n", instance->Path); if (strcmp(instance->Transfer, DICOM_TRANSFERLITTLEENDIAN) == 0) { cond = DCM_OpenFile(instance->Path, DCM_ORDERLITTLEENDIAN | DCM_NOGROUPLENGTH, &storeRequest->dataSet); } else { cond = DCM_OpenFile(instance->Path, DCM_PART10FILE | DCM_NOGROUPLENGTH, &storeRequest->dataSet); (void) DCM_RemoveGroup(&storeRequest->dataSet, DCM_GROUPFILEMETA); } if (cond != DCM_NORMAL) return 0; /* repair */ } else return 0; /* repair */ free(queryItem); /* repair - memory leak */ response->remainingSubOperations--; if (!silent) MSG_DumpMessage(response, stdout); } else { /* No more requests remain */ storeRequest->dataSetType = DCM_CMDDATANULL; if ((response->failedSubOperations == 0) && (response->warningSubOperations == 0)) { /* complete success */ response->status = MSG_K_SUCCESS; response->dataSetType = DCM_CMDDATANULL; response->identifier = NULL; response->conditionalFields |= MSG_K_C_GET_COMPLETED | MSG_K_C_GET_FAILED | MSG_K_C_GET_WARNING; } else if ((response->warningSubOperations == 0) && (response->completedSubOperations == 0)) { /* All sub operations failed */ response->status = MSG_K_C_GET_UNABLETOPROCESS; response->dataSetType = DCM_CMDDATAIDENTIFIER; response->identifier = failedList; response->conditionalFields |= MSG_K_C_GET_COMPLETED | MSG_K_C_GET_FAILED | MSG_K_C_GET_WARNING; } else { /* Some sub operations may have failed or had warnings */ response->status = MSG_K_C_GET_COMPLETEWITHFAILURES; response->dataSetType = DCM_CMDDATAIDENTIFIER; response->identifier = failedList; response->conditionalFields |= MSG_K_C_GET_COMPLETED | MSG_K_C_GET_FAILED | MSG_K_C_GET_WARNING; } } return SRV_NORMAL; }