static int writePart10MetaHeader(int fd, DCM_FILE_META* fileMeta) { DCM_OBJECT* obj = 0; char buffer[2048]; CONDITION cond = DCM_CreateObject(&obj, 0); if (cond != DCM_NORMAL) { return -1; } cond = DCM_SetFileMeta(&obj, fileMeta); if (cond != DCM_NORMAL) { return -1; } cond = DCM_ExportStream(&obj, DCM_EXPLICITLITTLEENDIAN | DCM_PART10FILE, buffer, sizeof(buffer), callbackFunction, &fd); if (cond != DCM_NORMAL) { return -1; } return 0; }
CONDITION IAP_QueryToObject(Query * query, DCM_OBJECT ** object, char *SOPClass, int *elementCount) { CONDITION cond, returnCondition; int index; long flag; static char queryLevelString[48] = ""; /* Initialize for AIX compiler bug */ DCM_ELEMENT queryLevelElement = {DCM_IDQUERYLEVEL, DCM_CS, "", 1, sizeof(queryLevelString), (void *) &queryLevelString[0]}; static DCM_FLAGGED_ELEMENT localList[] = { {DCM_IDSOPINSTANCEUID, DCM_UI, "", 1, sizeof(q.Image.ImageUID), (void *) &q.Image.ImageUID[0], DB_K_QIMAGEUID, &q.Image.Query_Flag}, }; q = *query; *elementCount = 0; if (*object == NULL) { cond = DCM_CreateObject(object, 0); if (cond != DCM_NORMAL) return COND_PushCondition(IAP_OBJECTCREATEFAILED, IAP_Message(IAP_OBJECTCREATEFAILED), "IAP_QueryToObject"); } returnCondition = IAP_NORMAL; flag = q.QueryState & (DB_K_LEVELPAT | DB_K_LEVELSTUDY | DB_K_LEVELSERIES | DB_K_LEVELIMAGE); if (flag == 0){ returnCondition = COND_PushCondition(IAP_INCOMPLETEQUERY, "IAP_QueryToObject"); }else{ for (index = 0; index < DIM_OF(levelMap); index++) { if ((q.QueryState & levelMap[index].flag) != 0) { (void) strcpy(queryLevelString, levelMap[index].queryLevel); queryLevelElement.length = strlen(queryLevelElement.d.string); cond = DCM_ModifyElements(object, &queryLevelElement, 1, NULL, 0, NULL); if (cond != DCM_NORMAL) return cond; } } } flag = q.QueryState & (DB_K_CLASSPAT | DB_K_CLASSSTUDY | DB_K_CLASSPATSTUDY); if (flag == 0){ returnCondition = COND_PushCondition(IAP_INCOMPLETEQUERY, ""); }else{ for (index = 0; index < DIM_OF(classMap); index++) { if ((q.QueryState & classMap[index].flag) != 0) { (void) strcpy(SOPClass, classMap[index].SOPClass); cond = DCM_NORMAL; } } } cond = DCM_ModifyElements(object, NULL, 0, list, (int) DIM_OF(list), elementCount); if (cond != DCM_NORMAL) return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "IAP_QueryToObject"); cond = DCM_ModifyElements(object, NULL, 0, localList, (int) DIM_OF(localList), elementCount); if (cond != DCM_NORMAL) return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "IAP_QueryToObject"); return returnCondition; }
/* ** SRV_NEventReportResponse ** ** Purpose: ** SRV_NEventReportResponse assists an application that wants to be an SCU ** of a number of SOP classes. When an application receives an ** N-EVENT_REPORT request message, it calls this function with the ** N-EVENT_REPORT request and other parameters. SRV_NEventReportResponse ** checks the caller's parameters and calls the user's callback function. ** In the callback function, the caller fills in the parameters of the ** N-EVENT_REPORT response message and then returns to the SRV function. ** ** After the callback function returns, SRV_NEventReportResponse ** constructs a N-EVENT_REPORT Response message and sends it to the peer ** application which sent the request message. ** ** The arguments to the callback function are: ** MSG_N_EVENT_REPORT_REQ *eventRequest ** MSG_N_EVENT_REPORT_RESP *eventResponse ** void *eventCtx ** DUL_PRESENTATIONCONTEXT *pc ** ** The first two arguments are MSG structures that contain the ** N-EVENT_REPORT Request and N-EVENT_REPORT Response messages ** respectively. The third argument is the caller's context variable that ** is passed to SRV_NEventReportResponse. The presentation context is ** the one negotiated for this SOP class. ** ** The callback function should return SRV_NORMAL. Any other return ** value will cause the SRV facility to abort the Association. ** ** Parameter Dictionary: ** association The key which is used for transmitting the ** N-EVENT_REPORT response. ** presentationCtx Pointer to presentation context to be used when sending ** the N-EVENT_REPORT response. ** eventRequest Pointer to the structure with the N-EVENT_REPORT request ** parameters which was received by the application. ** eventResponse Pointer to structure in the caller's area which will be ** filled with the parameters of the N-EVENT_REPORT ** response command. After the parameters are filled in, ** the N-EVENT_REPORT response is sent to the peer ** application which sent the request. ** eventCallback Address of user callback function to be called ** with the N-EVENT_REPORT response from SCU. ** eventCtx Pointer to user context information which will be ** passed to the callback function. Caller uses this ** variable to contain any context required for the ** callback function. ** dirName Name of directory where files may be created. ** ** ** Return Values: ** ** SRV_CALLBACKABORTEDSERVICE ** SRV_ILLEGALPARAMETER ** SRV_NOCALLBACK ** SRV_NORMAL ** SRV_OBJECTBUILDFAILED ** SRV_RESPONSEFAILED ** ** Algorithm: ** Receive a data set, if any, from the peer application ** Invoke the callback function, if it exists. ** Build a command and send it to the requesting peer application. ** Send a data set, if any, to the peer application. ** ** Notes: ** The callback function is responsible for explicitly setting the ** following fields in the N-EVENT_REPORT request message: ** ** type ** messageIDRespondedTo ** classUID ** dataSetType ** instanceUID ** status ** */ CONDITION SRV_NEventReportResponse(DUL_ASSOCIATIONKEY ** association, DUL_PRESENTATIONCONTEXT * presentationCtx, MSG_N_EVENT_REPORT_REQ ** eventRequest, MSG_N_EVENT_REPORT_RESP * eventResponse, SRV_N_EVENTREPORT_RESP_CALLBACK * eventCallback, void *eventCtx, char *dirName) { CONDITION cond; DCM_OBJECT * responseObject; eventResponse->status = MSG_K_SUCCESS; if (eventCallback == NULL) { (void) MSG_Free((void **) eventRequest); return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_NEventReportResponse"); } if ((*eventRequest)->dataSetType != DCM_CMDDATANULL){ cond = SRV_ReceiveDataSet(association, presentationCtx, DUL_BLOCK, 0, dirName, &(*eventRequest)->dataSet); if (cond != SRV_NORMAL){ (void) MSG_Free((void **) eventRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_NEventReportResponse"); } } eventResponse->dataSetType = DCM_CMDDATANULL; cond = DCM_CreateObject(&eventResponse->dataSet, 0); if (cond != DCM_NORMAL) { (void) MSG_Free((void **) eventRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_NEventReportResponse"); } cond = eventCallback(*eventRequest, eventResponse, eventCtx, presentationCtx); (void) MSG_Free((void **) eventRequest); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_NEventReportRequest"); if (eventResponse->type != MSG_K_N_EVENT_REPORT_RESP) return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "N-EVENT_REPORT Response", "SRV_NEventReportResponse"); cond = MSG_BuildCommand(eventResponse, &responseObject); if (cond != MSG_NORMAL) { (void) DCM_CloseObject(&eventResponse->dataSet); return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "N-EVENT_REPORT Response", "SRV_NEventReportResponse"); } cond = SRV_SendCommand(association, presentationCtx, &responseObject); (void) DCM_CloseObject(&responseObject); if (cond != SRV_NORMAL) { (void) DCM_CloseObject(&eventResponse->dataSet); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_NEventReportResponse"); } if (eventResponse->dataSetType != DCM_CMDDATANULL){ /* application specific event reply exists */ cond = SRV_SendDataSet(association, presentationCtx, &eventResponse->dataSet, NULL, NULL, 0); if (cond != SRV_NORMAL){ (void) DCM_CloseObject(&eventResponse->dataSet); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_NEventReportResponse"); } } (void) DCM_CloseObject(&eventResponse->dataSet); return SRV_NORMAL; }
static void handleStudyQueries(DUL_ASSOCIATIONKEY** association, DUL_ASSOCIATESERVICEPARAMETERS* params, MSG_C_FIND_REQ* patientRequest, LST_HEAD* patientList, const char* queryLevel) { ITEM* item; CONDITION cond; MSG_C_FIND_RESP response; item = (ITEM*)LST_Head(&patientList); (void)LST_Position(&patientList, item); while (item != 0) { char* patientName; char* patientID; char* charSet; MSG_C_FIND_REQ studyRequest; DCM_OBJECT* q; patientName = getString(item->obj, DCM_PATNAME); patientID = getString(item->obj, DCM_PATID); charSet = getString(patientRequest->identifier, DCM_IDSPECIFICCHARACTER); printf("%s %s\n", patientID, patientName); studyRequest = *patientRequest; studyRequest.identifier = 0; DCM_CreateObject(&q, 0); addString(q, DCM_PATID, patientID); addString(q, DCM_IDSPECIFICCHARACTER, charSet); addString(q, DCM_IDQUERYLEVEL, "STUDY"); addString(q, DCM_RELSTUDYINSTANCEUID, ""); addString(q, DCM_IDSTUDYDATE, ""); addString(q, DCM_IDSTUDYTIME, ""); addString(q, DCM_IDACCESSIONNUMBER, ""); addString(q, DCM_IDSTUDYDESCRIPTION, ""); studyRequest.identifier = q; studyRequest.messageID = SRV_MessageIDOut(); item->lst = LST_Create(); cond = SRV_CFindRequest(association, params, &studyRequest, &response, queryCallback, item->lst, ""); if (!(CTN_SUCCESS(cond))) { (void) printf("Verification Request unsuccessful\n"); COND_DumpConditions(); } else { } item = LST_Next(&patientList); } }
DCM_OBJECT * createQueryObject(const char *fileName) { DCM_OBJECT *obj; CONDITION cond; DCM_ELEMENT e; char txt[1024] = ""; int group = 0; int element = 0; char textValue[1024]; if (fileName != NULL) { cond = DCM_OpenFile(fileName, DCM_ORDERLITTLEENDIAN, &obj); if (cond != DCM_NORMAL) { COND_DumpConditions(); exit(1); } return obj; } cond = DCM_CreateObject(&obj, 0); if (cond != DCM_NORMAL) { COND_DumpConditions(); exit(1); } while (fgets(txt, sizeof(txt), stdin) != NULL) { if (txt[0] == '#' || txt[0] == '\0') continue; if (txt[0] == '\n' || txt[0] == '\r') continue; if (sscanf(txt, "%x %x %[^\n]", &group, &element, textValue) != 3) continue; e.tag = DCM_MAKETAG(group, element); DCM_LookupElement(&e); if (strncmp(textValue, "#", 1) == 0) { e.length = 0; e.d.string = NULL; } else { e.length = strlen(textValue); e.d.string = textValue; } cond = DCM_AddElement(&obj, &e); if (cond != DCM_NORMAL) { COND_DumpConditions(); exit(1); } } return obj; }
CONDITION IAP_InstanceArraytoElement(char *SOPArray, size_t SOPSpacing, char *UIDArray, size_t UIDSpacing, int count, DCM_ELEMENT * e) { CONDITION cond; DCM_ELEMENT classElement = { DCM_IDREFERENCEDSOPCLASSUID, DCM_UI, "", 1, 0, NULL }, uidElement = { DCM_IDREFERENCEDSOPINSTUID, DCM_UI, "", 1, 0, NULL }; DCM_OBJECT * object; DCM_SEQUENCE_ITEM * item; e->d.sq = LST_Create(); if (e->d.sq == NULL) return 0; /* repair */ while (count-- > 0) { item = malloc(sizeof(*item)); if (item == NULL) return 0; /* repair */ cond = DCM_CreateObject(&item->object); if (cond != DCM_NORMAL) return 0; /* repair */ classElement.d.string = SOPArray; classElement.length = strlen(SOPArray); cond = DCM_AddElement(&item->object, &classElement); if (cond != DCM_NORMAL) return 0; /* repair */ uidElement.d.string = UIDArray; uidElement.length = strlen(UIDArray); cond = DCM_AddElement(&item->object, &uidElement); if (cond != DCM_NORMAL) return 0; /* repair */ cond = LST_Enqueue(&e->d.sq, item); if (cond != LST_NORMAL) return 0; /* repair */ SOPArray += SOPSpacing; UIDArray += UIDSpacing; } return HAP_NORMAL; }
CONDITION MSGPRV_BuildObject(DCM_OBJECT ** object, DCM_ELEMENT * required, int requiredCount, DCM_FLAGGED_ELEMENT * conditional, int conditionalCount) { int index; CONDITION cond; DCM_ELEMENT e; cond = DCM_CreateObject(object); if (cond != DCM_NORMAL) return COND_PushCondition(0, ""); /* repair */ cond = DCM_ModifyElements(object, required, requiredCount, conditional, conditionalCount, NULL); if (cond != DCM_NORMAL) return COND_PushCondition(0, ""); /* repair */ return MSG_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; }
/* SRV_NActionResponse ** ** Purpose: ** SRV_NActionResponse assists an application that wants to be an SCP ** of a number of SOP classes. When an application receives an N-ACTION ** request message, it calls this function with the N-ACTION request ** and other parameters. SRV_NActionResponse checks the caller's ** parameters and calls the user's callback function. In the callback ** function, the caller fills in the parameters of the N-ACTION response ** message and then returns to the SRV function. ** ** After the callback function returns, SRV_NActionResponse constructs a ** N-ACTION Response message and sends it to the peer application which ** sent the request message. ** ** The arguments to the callback function are: ** MSG_N_ACTION_REQ *actionRequest ** MSG_N_ACTION_RESP *actionResponse ** void *actionCtx ** DUL_PRESENTATIONCONTEXT *pc ** ** The first two arguments are MSG structures that contain the N-ACTION ** Request and N-ACTION Response messages respectively. The third ** argument is the caller's context variable that is passed to ** SRV_NActionResponse. The presentation context describes the SOP ** class that was negotiated for this message. ** ** The callback function should return SRV_NORMAL. Any other return ** value will cause the SRV facility to abort the Association. ** ** Parameter Dictionary: ** association The key which is used for transmitting the N-ACTION ** response. ** presentationCtx Pointer to presentation context to be used when sending ** the N-ACTION response. ** actionRequest Pointer to the structure with the N-ACTION request ** parameters which was received by the application. ** actionResponse Pointer to structure in the caller's area which will be ** filled with the parameters of the N-ACTION response ** command. After the parameters are filled in, the ** N-ACTION response is sent to the peer application ** which sent the request. ** actionCallback Address of user callback function to be called ** with the N-ACTION response from SCP. ** actionCtx Pointer to user context information which will be ** passed to the callback function. Caller uses this ** variable to contain any context required for the ** callback function. ** dirName Name of directory where files may be created. ** ** ** Return Values: ** ** SRV_CALLBACKABORTEDSERVICE ** SRV_ILLEGALPARAMETER ** SRV_NOCALLBACK ** SRV_NORMAL ** SRV_OBJECTBUILDFAILED ** SRV_RESPONSEFAILED ** ** Algorithm: ** Receive a data set, if any, from the peer application ** Invoke the callback function, if it exists. ** Build a command and send it to the requesting peer application. ** Send a data set, if any, to the peer application. ** ** Notes: ** The callback function is responsible for explicitly setting the ** following fields in the N-ACTION response message: ** ** type ** messageIDRespondedTo ** classUID ** dataSetType ** instanceUID ** status ** actionReply (if any) ** */ CONDITION SRV_NActionResponse(DUL_ASSOCIATIONKEY ** association, DUL_PRESENTATIONCONTEXT * presentationCtx, MSG_N_ACTION_REQ ** actionRequest, MSG_N_ACTION_RESP * actionResponse, SRV_N_ACTION_RESP_CALLBACK * actionCallback, void *actionCtx, char *dirName) { CONDITION rtnCond = SRV_NORMAL, cond; DCM_OBJECT * responseObject = NULL; actionResponse->status = MSG_K_SUCCESS; /* initialize */ actionResponse->dataSetType = DCM_CMDDATANULL; actionResponse->actionReply = NULL; if (actionCallback == NULL) { rtnCond = COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_NActionResponse"); actionResponse->status = MSG_K_RESOURCELIMITATION; goto SEND_RESPONSE; } /* check if there is any data coming over the network */ if ((*actionRequest)->dataSetType != DCM_CMDDATANULL) { cond = SRV_ReceiveDataSet(association, presentationCtx, DUL_BLOCK, 0, dirName, &(*actionRequest)->actionInformation); if (cond != SRV_NORMAL) { rtnCond = COND_PushCondition(SRV_RECEIVEDATASETFAILED, SRV_Message(SRV_RECEIVEDATASETFAILED), "SRV_NActionResponse"); actionResponse->status = MSG_K_PROCESSINGFAILURE; goto SEND_RESPONSE; } } /* SRV routine allocates space for the action reply */ cond = DCM_CreateObject(&actionResponse->actionReply, 0); if (cond != DCM_NORMAL) { rtnCond = COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "SRV_NActionResponse"); actionResponse->status = MSG_K_PROCESSINGFAILURE; goto SEND_RESPONSE; } cond = actionCallback(*actionRequest, actionResponse, actionCtx, presentationCtx); if (cond != SRV_NORMAL) { rtnCond = COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_NActionRequest"); goto SEND_RESPONSE; } if (actionResponse->type != MSG_K_N_ACTION_RESP) { rtnCond = COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "N-ACTION Response", "SRV_NActionResponse"); goto SEND_RESPONSE; } SEND_RESPONSE: /* At this point we free the request pointer */ (void) MSG_Free((void **) actionRequest); /* * If there are any errors in the following steps, it is necessary for * the SRV routine to free the data set object it had created earlier. * But we must verify that such a data set creation operation itself was * successful before we try to free the data set */ /* send the action reply (if any) only on success status */ if (actionResponse->status != MSG_K_SUCCESS) { actionResponse->dataSetType = DCM_CMDDATANULL; if (actionResponse->actionReply) (void) DCM_CloseObject(&actionResponse->actionReply); return rtnCond; } /* build a command object */ cond = MSG_BuildCommand(actionResponse, &responseObject); if (cond != MSG_NORMAL) { if (actionResponse->actionReply) (void) DCM_CloseObject(&actionResponse->actionReply); return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "N-ACTION Response", "SRV_NActionResponse"); } cond = SRV_SendCommand(association, presentationCtx, &responseObject); (void) DCM_CloseObject(&responseObject); if (cond != SRV_NORMAL) { if (actionResponse->actionReply) (void) DCM_CloseObject(&actionResponse->actionReply); return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED), "Command", "SRV_NActionResponse"); } /* * At this point, the response message status is "SUCCESS". This also * implies that the "data set" object exists but may be empty (not NULL) * Hence if there is any error, we need to close it first before we * return. */ if (actionResponse->dataSetType != DCM_CMDDATANULL) { cond = SRV_SendDataSet(association, presentationCtx, &actionResponse->actionReply, NULL, NULL, 0); if (cond != SRV_NORMAL) { (void) DCM_CloseObject(&actionResponse->actionReply); return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED), "Data Set", "SRV_NActionResponse"); } } (void) DCM_CloseObject(&actionResponse->actionReply); /* was allocated memory */ return SRV_NORMAL; /* everything is successful at this point */ }
CONDITION HAP_QueryToObject(Query * query, DCM_OBJECT ** object, char *SOPClass, int *elementCount) { CONDITION cond, returnCondition; int index; DCM_ELEMENT e; long flag; static char queryLevelString[48]; DCM_ELEMENT queryLevelElement = { DCM_IDQUERYLEVEL, DCM_CS, "", 1, sizeof(queryLevelString), (void *) queryLevelString }; q = *query; *elementCount = 0; if (*object == NULL) { cond = DCM_CreateObject(object); if (cond != DCM_NORMAL) return HAP_OBJECTCREATEFAILED; } returnCondition = HAP_NORMAL; flag = q.QueryState & (DB_K_LEVELPAT | DB_K_LEVELSTUDY | DB_K_LEVELSERIES | DB_K_LEVELIMAGE); if (flag == 0) returnCondition = COND_PushCondition(HAP_INCOMPLETEQUERY, ""); else { for (index = 0; index < DIM_OF(levelMap); index++) { if ((q.QueryState & levelMap[index].flag) != 0) { (void) strcpy(queryLevelString, levelMap[index].queryLevel); queryLevelElement.length = strlen(queryLevelElement.d.string); cond = DCM_ModifyElements(object, &queryLevelElement, 1, NULL, 0, NULL); if (cond != DCM_NORMAL) return cond; } } } flag = q.QueryState & (DB_K_CLASSPAT | DB_K_CLASSSTUDY | DB_K_CLASSPATSTUDY); if (flag == 0) returnCondition = COND_PushCondition(HAP_INCOMPLETEQUERY, ""); else { for (index = 0; index < DIM_OF(classMap); index++) { if ((q.QueryState & classMap[index].flag) != 0) { (void) strcpy(SOPClass, classMap[index].SOPClass); cond = DCM_NORMAL; } } } for (index = 0; index < (int) DIM_OF(list); index++) { flag = *list[index].flagAddress; if ((flag & list[index].flag) != 0) { e = list[index].e; e.length = strlen(e.d.string); cond = DCM_AddElement(object, &e); if (cond != DCM_NORMAL) return cond; (*elementCount)++; } } return returnCondition; }
static void handleSeriesQueries(DUL_ASSOCIATIONKEY** association, DUL_ASSOCIATESERVICEPARAMETERS* params, MSG_C_FIND_REQ* patientRequest, LST_HEAD* patientList, const char* queryLevel) { ITEM* item; ITEM* studyItem; CONDITION cond; MSG_C_FIND_RESP response; item = (ITEM*)LST_Head(&patientList); (void)LST_Position(&patientList, item); while (item != 0) { char* patientName; char* patientID; char* studyInstanceUID; char* charSet; patientName = getString(item->obj, DCM_PATNAME); patientID = getString(item->obj, DCM_PATID); charSet = getString(patientRequest->identifier, DCM_IDSPECIFICCHARACTER); printf("%s %s\n", patientID, patientName); studyItem = (ITEM*)LST_Head(&item->lst); (void)LST_Position(&item->lst, studyItem); while (studyItem != NULL) { DCM_OBJECT* q; MSG_C_FIND_REQ seriesRequest; seriesRequest = *patientRequest; seriesRequest.identifier = 0; DCM_CreateObject(&q, 0); studyInstanceUID = getString(studyItem->obj, DCM_RELSTUDYINSTANCEUID); addString(q, DCM_PATID, patientID); addString(q, DCM_IDSPECIFICCHARACTER, charSet); addString(q, DCM_IDQUERYLEVEL, "SERIES"); addString(q, DCM_RELSTUDYINSTANCEUID, studyInstanceUID); addString(q, DCM_IDMODALITY, ""); addString(q, DCM_RELSERIESNUMBER, ""); addString(q, DCM_ACQBODYPARTEXAMINED, ""); addString(q, DCM_ACQVIEWPOSITION, ""); seriesRequest.identifier = q; seriesRequest.messageID = SRV_MessageIDOut(); studyItem->lst = LST_Create(); cond = SRV_CFindRequest(association, params, &seriesRequest, &response, queryCallback, studyItem->lst, ""); if (!(CTN_SUCCESS(cond))) { (void) printf("C-Find Request unsuccessful\n"); COND_DumpConditions(); } else { } studyItem = LST_Next(&item->lst); } item = LST_Next(&patientList); } }