CONDITION IAP_SendInfoObject(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, const char *fileName, const char *fileXferSyntax, const char *moveAETitle, unsigned short moveMessageID, CONDITION(*sendCallback) (), void *callbackCtx) { static MSG_C_STORE_REQ request; CONDITION cond; DCM_OBJECT * object; static DCM_ELEMENT list[] = { {DCM_IDSOPCLASSUID, DCM_UI, "", 1, sizeof(request.classUID), (void *) &request.classUID[0]}, {DCM_IDSOPINSTANCEUID, DCM_UI, "", 1, sizeof(request.instanceUID), (void *) &request.instanceUID[0]}, }; U32 l; void *ctx; int index; if (fileName == NULL) return IAP_NORMAL; if (fileName[0] == '\0') return IAP_NORMAL; cond = DCM_OpenFile(fileName, DCM_PART10FILE, &object); if (cond != DCM_NORMAL) return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "IAP_SendInfoObject"); for (index = 0; index < (int) DIM_OF(list); index++) { ctx = NULL; cond = DCM_GetElementValue(&object, &list[index], &l, &ctx); if (cond != DCM_NORMAL) { (void) DCM_CloseObject(&object); return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "IAP_SendInfoObject"); } list[index].d.string[l] = '\0'; } (void) DCM_RemoveGroup(&object, DCM_GROUPFILEMETA); request.type = MSG_K_C_STORE_REQ; request.messageID = SRV_MessageIDOut(); request.priority = DCM_PRIORITYMEDIUM; request.dataSetType = DCM_CMDDATAIMAGE; request.dataSet = object; request.fileName = NULL; request.conditionalFields = 0; if (moveAETitle != NULL) { strcpy(request.moveAETitle, moveAETitle); request.moveMessageID = moveMessageID; request.conditionalFields |= MSG_K_C_STORE_MOVEMESSAGEID | MSG_K_C_STORE_MOVEAETITLE; }else{ request.moveAETitle[0] = '\0'; } cond = SRV_CStoreRequest(association, params, &request, NULL, sendCallback, callbackCtx, ""); (void) DCM_CloseObject(&object); if (cond != SRV_NORMAL) return COND_PushCondition(IAP_SENDFAILED, IAP_Message(IAP_SENDFAILED), "IAP_SendInfoObject"); return IAP_NORMAL; }
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; }