main(int argc, char **argv) { DCM_OBJECT * object; CONDITION cond; char * fileInput; CTNBOOLEAN verbose = FALSE, exitFlag = FALSE, formatFlag = FALSE; unsigned long options = DCM_ORDERLITTLEENDIAN; long vmLimit = 0; LST_HEAD* fileNames = 0; UTL_FILEITEM* p = NULL; if (argc < 2) usageerror(); else { argv++; fileInput = *argv; } THR_Init(); DCM_Debug(verbose); cond = DCM_OpenFile(fileInput, options, &object); if (cond != DCM_NORMAL && ((options & DCM_PART10FILE) == 0)) { COND_DumpConditions(); (void) DCM_CloseObject(&object); (void) COND_PopCondition(TRUE); fprintf(stderr, "Could not open %s as expected. Trying Part 10 format.\n", p->path); cond = DCM_OpenFile(p->path, options | DCM_PART10FILE, &object); } if (cond == DCM_NORMAL) { printf("<?xml version=\"1.0\" ?>\n"); printf("<Structured_Report>\n"); iterateThroughElements(&object, 1); printf("</Structured_Report>\n"); } COND_DumpConditions(); (void) DCM_CloseObject(&object); (void) COND_PopCondition(TRUE); if (cond != DCM_NORMAL && exitFlag) { THR_Shutdown(); exit(1); } #ifdef MALLOC_DEBUG malloc_verify(0); malloc_shutdown(); #endif THR_Shutdown(); return 0; }
/* ** 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; }
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 void fileToHTML(const char* path) { DCM_OBJECT* obj; CONDITION cond; THR_Init(); cond = DCM_OpenFile(path, DCM_ORDERLITTLEENDIAN, &obj); if (cond != DCM_NORMAL) { (void) DCM_CloseObject(&obj); cond = DCM_OpenFile(path, DCM_PART10FILE, &obj); } if (cond != DCM_NORMAL) { exit(0); } #if 1 printf("Content-type: text/html\n\n"); printf("<HTML>\n"); printf("<HEAD>\n"); printf("<META HTTP-EQUIV=""Content-Type"" CONTENT=""text/html; charset=iso-2022-jp"">\n"); printf("<TITLE>dcm_to_html</TITLE>\n"); printf("</HEAD>"); printf("<BODY BGCOLOR=#ffffff FGCOLOR=#ff000000>\n"); printf("<B>%s</B>\n", path); printf("<TABLE BORDER>\n"); DCM_ScanParseObject(&obj, NULL, 0, /* Buffer/buffer size */ NULL, 0, /* Vector of elements to scan */ callback, NULL); printf("</TABLE>\n"); printf("</BODY>\n"); printf("</HTML>"); (void) DCM_CloseObject(&obj); THR_Shutdown(); #else html_header(); html_begin_body_options("File View", "bgcolor=#ffffff"); printf("%s<br>\n", path); html_end(); #endif }
static void activateCB_menu1_p1_b4( Widget wgt, XtPointer cd, XtPointer cb) { Widget UxWidget = wgt; XtPointer UxClientData = cd; XtPointer UxCallbackArg = cb; /* * activateCP_menu1_p1_b4 * * * Purpose: * This subroutine closes all the open structures and dicom * Object * before quitting the program * * * Parameter Dictinary: * none * Return Value: * none * * * Notes: * * * Algorithm: * Description of the algorithm (optional) and ant other * notes. * * */ if (ieIE != NULL) (void) IE_Free((void **) &ieIE); /** cond = IE_Free(ieIE); if(cond != IE_NORMAL) (void) COND_DumpConditions();**/ if (ieModule != NULL) (void) IE_Free((void **) &ieModule); /** cond = IE_Free(ieModule); if(cond != IE_NORMAL) (void) COND_DumpConditions();**/ if (ieAttr != NULL) (void) IE_Free((void **) &ieAttr); /** cond = IE_Free(ieAttr); if(cond != IE_NORMAL) (void) COND_DumpConditions();**/ if (ieObject != NULL) (void) IE_Free((void **) &ieObject); /** cond = IE_Free(ieObject); if(cond != IE_NORMAL) (void) COND_DumpConditions();**/ (void) DCM_CloseObject(&queryObject); exit(0); }
/* processGetResponse ** ** Purpose: ** This function processes the incoming response to the Get request. ** ** Parameter Dictionary: ** association Handle to the association ** presentationCtx Handle to the presentation context negotiated between ** the two communicating peers ** dirName path name of file where we wish to receive the data ** set. ** getRequest Pointer to the C-GET request structure ** localResponse Pointer to the C-GET response structure ** queryLevelString ** A string specifying the query at a specified level ** callback Pointer to user callback routine that is to be invoked ** after a response is received ** callbackCtx Any user context information that needs to be passed ** to the callback routine ** done A boolean flag indicating whether there are any more ** pending store requests ** cancelled A boolean flag indicating whether a Cancel request had ** been made ** getResponse Pointer to the GetResponse message received ** ** Return Values: ** SRV_NORMAL unless there is any error ** ** Notes: ** ** Algorithm: ** Description of the algorithm (optional) and any other notes. */ static CONDITION processGetResponse(DUL_ASSOCIATIONKEY ** association, DUL_PRESENTATIONCONTEXT * presentationCtx, char *dirName, MSG_C_GET_REQ * getRequest, MSG_C_GET_RESP * localResponse, char *queryLevelString, CONDITION(*callback) (), void *callbackCtx, CTNBOOLEAN * done, CTNBOOLEAN * cancelled, MSG_C_GET_RESP * getResponse, unsigned long *responseCount) { CONDITION cond; MSG_STATUS_DESCRIPTION statusDescription; DCM_OBJECT * commandObject; MSG_C_CANCEL_REQ cancelRequest = {MSG_K_C_CANCEL_REQ, 0, 0, DCM_CMDDATANULL}; cond = MSG_StatusLookup(localResponse->status, MSG_K_C_GET_RESP, &statusDescription); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest"); /* find the general category of the status received */ if (statusDescription.statusClass != MSG_K_CLASS_PENDING) *done = TRUE; /* No more pending requests */ if (localResponse->dataSetType != DCM_CMDDATANULL) { /* Some data set (identifier) has been sent back */ cond = SRV_ReceiveDataSet(association, presentationCtx, DUL_BLOCK, 0, dirName, &localResponse->identifier); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest"); } *responseCount++; if (!*cancelled) { /* no cancel request made */ cond = callback(getRequest, localResponse, *responseCount, presentationCtx->abstractSyntax, queryLevelString, callbackCtx); if (cond == SRV_OPERATIONCANCELLED) { *cancelled = TRUE; /* build a cancel request */ cancelRequest.messageIDRespondedTo = getRequest->messageID; cond = MSG_BuildCommand(&cancelRequest, &commandObject); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "CANCEL Request", "SRV_CGetRequest"); cond = SRV_SendCommand(association, presentationCtx, &commandObject); (void) DCM_CloseObject(&commandObject); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest"); }else if (cond != SRV_NORMAL){ *done = TRUE; /* callback did not return SRV_NORMAL. Hence we opt to quit the loop */ } } if (getResponse != NULL) { *getResponse = *localResponse; getResponse->identifier = NULL; } return SRV_NORMAL; }
static void localDirectory(llist entries) { LST_HEAD *patientList; DCM_OBJECT *dirFile; DDR_PATIENT *patientNode; CONDITION cond; cond = DCM_OpenFile("/tmp/dicomdir", DCM_ORDERLITTLEENDIAN | DCM_PART10FILE, &dirFile); patientList = LST_Create(); cond = DDR_GetPatientList(&dirFile, &patientList); html_header(); html_begin_body_options("DICOM Patient Search", "bgcolor=#ffffff"); printf("Please select one patient to see a list of studies<p>\n"); printf("<form method=GET action=""/cgi-bin/acc_agent.cgi"">\n"); patientNode = LST_Dequeue(&patientList); printf("<select name=patientID size=10>\n"); while(patientNode != NULL) { printf("<option value=""%s"">%s %s %s\n", patientNode->PatientID, patientNode->PatientID, patientNode->PatientName, patientNode->BirthDate); free(patientNode); patientNode = LST_Dequeue(&patientList); } printf("</select>\n"); printf("<br>\n"); printf("<input type=submit value=""LocalPatientSelect"" name=submitSearch>\n"); printf("<input type=submit value=""Retrieve All Studies from Archive"" name=submitSearch>\n"); printf("</form>\n"); html_end(); LST_Destroy(&patientList); DCM_CloseObject(&dirFile); }
static void localPatientSelect(llist entries) { LST_HEAD *studyList; DCM_OBJECT *dirFile; DDR_STUDY *studyNode; CONDITION cond; cond = DCM_OpenFile("/tmp/dicomdir", DCM_ORDERLITTLEENDIAN | DCM_PART10FILE, &dirFile); studyList = LST_Create(); cond = DDR_GetStudyList(&dirFile, cgi_val(entries, "patientID"), &studyList); html_header(); html_begin_body_options("DICOM Study Search", "bgcolor=#ffffff"); studyNode = LST_Dequeue(&studyList); printf("<tt>\n"); while(studyNode != NULL) { printf("%s %s %s %s <br>\n", studyNode->StudyDate, studyNode->AccessionNumber, studyNode->StudyID, studyNode->StudyDescription); free(studyNode); studyNode = LST_Dequeue(&studyList); } printf("</tt>\n"); html_end(); DCM_CloseObject(&dirFile); }
CONDITION SRV_CGetRequest(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, MSG_C_GET_REQ * getRequest, MSG_C_GET_RESP * getResponse, SRV_C_GET_REQ_CALLBACK * getCallback, void *getCallbackCtx, CONDITION(*storageCallback) (), void *storageCallbackCtx, char *dirName) { DCM_OBJECT * commandObject; /* Handle for a command object */ CONDITION cond; /* Return value from function calls */ DUL_PRESENTATIONCONTEXT * presentationCtx, /* Presentation context for GET service */ *storePresentationCtx; /* for the arriving store request */ DUL_PRESENTATIONCONTEXTID ctxID; void *message; MSG_TYPE messageType; CTNBOOLEAN done = FALSE; U32 l; unsigned long responseCount = 0; MSG_C_STORE_REQ * storeRequest; void *ctx; char queryLevelString[48] = ""; /* Initialization for AIX compiler */ DCM_ELEMENT queryLevelElement = {DCM_IDQUERYLEVEL, DCM_CS, "", 1, sizeof(queryLevelString), NULL}; unsigned short command; CTNBOOLEAN cancelled = FALSE; MSG_C_CANCEL_REQ cancelRequest = {MSG_K_C_CANCEL_REQ, 0, 0, DCM_CMDDATANULL}; queryLevelElement.d.string = queryLevelString; if ((getCallback == NULL) || (storageCallback == NULL)) return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_CGetRequest"); if (getRequest->type != MSG_K_C_GET_REQ) return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "GET Request", "SRV_CGetRequest"); if (getRequest->dataSetType == DCM_CMDDATANULL) return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "dataSetType", "GET Request", "SRV_CGetRequest"); ctx = NULL; cond = DCM_GetElementValue(&getRequest->identifier, &queryLevelElement, &l, &ctx); if (cond != DCM_NORMAL) return COND_PushCondition(SRV_OBJECTACCESSFAILED, SRV_Message(SRV_OBJECTACCESSFAILED), "Query Identifier", "SRV_CGetRequest"); queryLevelString[l] = '\0'; if (queryLevelString[l - 1] == ' ') queryLevelString[l - 1] = '\0'; presentationCtx = SRVPRV_PresentationContext(params, getRequest->classUID); if (presentationCtx == NULL) return COND_PushCondition(SRV_NOSERVICEINASSOCIATION, SRV_Message(SRV_NOSERVICEINASSOCIATION), getRequest->classUID, "SRV_CGetRequest"); cond = MSG_BuildCommand(getRequest, &commandObject); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "GET Request", "SRV_CGetRequest"); cond = SRV_SendCommand(association, presentationCtx, &commandObject); (void) DCM_CloseObject(&commandObject); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest"); cond = SRV_SendDataSet(association, presentationCtx, &getRequest->identifier, NULL, NULL, 0); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest"); while (!done) { /* do until there are no more pending requests */ cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID, &command, &messageType, &message); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest"); switch (messageType) { case MSG_K_C_GET_RESP: cond = processGetResponse(association, presentationCtx, dirName, getRequest, (MSG_C_GET_RESP *) message, queryLevelString, getCallback, getCallbackCtx, &done, &cancelled, getResponse, &responseCount); (void) MSG_Free(&message); if ((CTN_FATAL(cond)) || (CTN_ERROR(cond))) return cond; break; case MSG_K_C_STORE_REQ: storeRequest = (MSG_C_STORE_REQ *) message; storePresentationCtx = SRVPRV_PresentationContext(params, storeRequest->classUID); if (storePresentationCtx == NULL) return COND_PushCondition(SRV_PRESENTATIONCONTEXTERROR, SRV_Message(SRV_PRESENTATIONCONTEXTERROR), "SRV_CGetRequest"); cond = processStoreRequest(association, storePresentationCtx, storeRequest, storageCallback, storageCallbackCtx); if ((CTN_FATAL(cond)) || (CTN_ERROR(cond))) return cond; break; default: (void) MSG_Free(&message); return COND_PushCondition(SRV_UNEXPECTEDCOMMAND, SRV_Message(SRV_UNEXPECTEDCOMMAND), (int) command, "SRV_CGetRequest"); } } if (cancelled){ return SRV_OPERATIONCANCELLED; }else{ return SRV_NORMAL; } }
/* 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 */ }
/* SRV_NActionRequest ** ** Purpose: ** SRV_NActionRequest assists an application that wants to be an SCU of ** a number of SOP classes. This function constructs an N-ACTION-REQ ** message and sends it to the peer application which is acting as the ** SCP for a SOP class. This function waits for the response from the ** peer application and invokes the caller's callback function. ** ** The arguments to the callback function are: ** MSG_N_ACTION_REQ *actionRequest ** MSG_N_ACTION_RESP *actionResponse ** void *actionCtx ** ** The first two arguments are MSG structures that contain the N-ACTION ** Request and N-ACTION Response messages respectively. The final ** argument is the caller's context variable that is passed to ** SRV_NActionRequest. ** ** 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 to access an existing ** association. ** params The list of parameters for the association. This ** list includes the list of presentation contexts. ** SOPClass UID of the SOP class used when the association was ** negotiated. Since this can be a meta class, it may ** not be the same as the class UID in the N-ACTION ** request message. ** actionRequest Pointer to the structure with the N-ACTION request ** parameters. ** actionResponse Pointer to caller's pointer to an N-ACTION response. ** This function will allocate an MSG_N_ACTION_RESP ** message and return the pointer to the caller. ** 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_REQUESTFAILED ** SRV_UNEXPECTEDCOMMAND ** SRV_UNSUPPORTEDSERVICE ** ** Algorithm: ** Check if the callback function has been provided. ** Determine the presentation context ** Encode the N-ACTION request message as a command object and ** send it to an SCP ** Send data set, if one exists, to the SCP. ** Wait for a response message to arrive from the SCP ** Receive a data set, if one exists, from the SCP ** Return address of Response message structure to caller. ** ** Notes: ** The caller is responsible for explicitly setting the following ** fields in the N-ACTION request message: ** ** type ** messageID ** classUID ** dataSetType ** instanceUID ** actionTypeID ** ** The caller is also responsible for releasing the Response message ** structure after the SRV_NActionRequest function returns, ** using MSG_Free. */ CONDITION SRV_NActionRequest(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, char *SOPClass, MSG_N_ACTION_REQ * actionRequest, MSG_N_ACTION_RESP * actionResponse, SRV_N_ACTION_REQ_CALLBACK * actionCallback, void *actionCtx, char *dirName) { DCM_OBJECT * commandObject; /* Handle for a command object */ CONDITION cond; /* Return value from function calls */ DUL_PRESENTATIONCONTEXT * presentationCtx; /* Presentation context for this service */ DUL_PRESENTATIONCONTEXTID ctxID; void *message; MSG_TYPE messageType; MSG_N_ACTION_RESP * localResponse; unsigned short command; if (actionCallback == NULL) return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_NActionRequest"); presentationCtx = SRVPRV_PresentationContext(params, SOPClass); if (presentationCtx == NULL) return COND_PushCondition(SRV_UNSUPPORTEDSERVICE, SRV_Message(SRV_UNSUPPORTEDSERVICE), actionRequest->classUID, "SRV_NActionRequest"); if (actionRequest->type != MSG_K_N_ACTION_REQ) return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "N-ACTION Request", "SRV_NActionRequest"); cond = MSG_BuildCommand(actionRequest, &commandObject); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "N-ACTION Request", "SRV_NActionRequest"); cond = SRV_SendCommand(association, presentationCtx, &commandObject); (void) DCM_CloseObject(&commandObject); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_NActionRequest"); if (actionRequest->dataSetType != DCM_CMDDATANULL) { /* application specific action information exists */ cond = SRV_SendDataSet(association, presentationCtx, &actionRequest->actionInformation, NULL, NULL, 0); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_NActionRequest"); } cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID, &command, &messageType, &message); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_NActionRequest"); if (messageType != MSG_K_N_ACTION_RESP) { (void) MSG_Free(&message); return COND_PushCondition(SRV_UNEXPECTEDCOMMAND, SRV_Message(SRV_UNEXPECTEDCOMMAND), (int) command, "SRV_NActionRequest"); } localResponse = (MSG_N_ACTION_RESP *) message; if (localResponse->dataSetType == DCM_CMDDATANULL) { localResponse->actionReply = NULL; } else { /* application specific action reply needs to be received */ cond = SRV_ReceiveDataSet(association, presentationCtx, DUL_BLOCK, 0, dirName, &localResponse->actionReply); if (cond != SRV_NORMAL) { (void) MSG_Free(&message); return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_NActionRequest"); } } cond = actionCallback(actionRequest, localResponse, actionCtx); (void) MSG_Free(&message); if (localResponse->actionReply != NULL) { (void) DCM_CloseObject(&localResponse->actionReply); localResponse->actionReply = NULL; } if (actionResponse != NULL) *actionResponse = *localResponse; if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_NActionRequest"); return SRV_NORMAL; }
/* SRV_NSetRequest ** ** Purpose: ** SRV_NSetRequest assists an application that wants to be an SCU of ** a number of SOP classes. This function constructs an N-SET-REQ ** message and sends it to the peer application which is acting as the ** SCP for a SOP class. This function waits for the response from the ** peer application and invokes the caller's callback function. ** ** The arguments to the callback function are: ** MSG_N_SET_REQ *setRequest ** MSG_N_SET_RESP *setResponse ** void *setCtx ** ** The first two arguments are MSG structures that contain the N-SET ** Request and N-SET Response messages respectively. The final ** argument is the caller's context variable that is passed to ** SRV_NSetRequest. ** ** 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 to access an existing ** association. ** params The list of parameters for the association. This ** list includes the list of presentation contexts. ** SOPClass UID of the SOP class used when the association was ** negotiated. Since this can be a meta class, it may ** not be the same as the class UID in the N-SET ** request message. ** setRequest Pointer to the structure with the N-SET request ** parameters. ** setResponse Pointer to caller's pointer to an N-SET response. ** This function will allocate an MSG_N_SET_RESP ** message and return the pointer to the caller. ** setCallback Address of user callback function to be called ** with the N-SET response from SCP. ** setCtx 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_REQUESTFAILED ** SRV_UNEXPECTEDCOMMAND ** SRV_UNSUPPORTEDSERVICE ** ** Algorithm: ** Check if the callback function has been provided. ** Determine the presentation context ** Encode the N-SET request message as a command object and ** send it to an SCP ** Send data set, if one exists, to the SCP. ** Wait for a response message to arrive from the SCP ** Receive a data set, if one exists, from the SCP ** Return address of Response message structure to caller. ** ** Notes: ** The caller is responsible for explicitly setting the following ** fields in the N-SET request message: ** ** type ** messageID ** classUID ** dataSetType ** dataSet ** instanceUID ** ** The caller is also responsible for releasing the Response message ** structure after the SRV_NSetRequest function returns, ** using MSG_Free. */ CONDITION SRV_NSetRequest(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, char *SOPClass, MSG_N_SET_REQ * setRequest, MSG_N_SET_RESP * setResponse, SRV_N_SET_REQ_CALLBACK * setCallback, void *setCtx, char *dirName) { DCM_OBJECT * commandObject; /* Handle for a command object */ CONDITION cond; /* Return value from function calls */ DUL_PRESENTATIONCONTEXT * presentationCtx; /* Presentation context for this service */ DUL_PRESENTATIONCONTEXTID ctxID; void *message; MSG_TYPE messageType; MSG_N_SET_RESP * localResponse; unsigned short command; if (setCallback == NULL) return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_NSetRequest"); presentationCtx = SRVPRV_PresentationContext(params, SOPClass); if (presentationCtx == NULL) return COND_PushCondition(SRV_UNSUPPORTEDSERVICE, SRV_Message(SRV_UNSUPPORTEDSERVICE), setRequest->classUID, "SRV_NSetRequest"); if (setRequest->type != MSG_K_N_SET_REQ) return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "N-SET Request", "SRV_NSetRequest"); cond = MSG_BuildCommand(setRequest, &commandObject); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "N-SET Request", "SRV_NSetRequest"); cond = SRV_SendCommand(association, presentationCtx, &commandObject); (void) DCM_CloseObject(&commandObject); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_NSetRequest"); if (setRequest->dataSetType == DCM_CMDDATANULL) /* sending attribute list is mandatory */ return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "dataSetType", "N-SET Request", "SRV_NSetRequest"); cond = SRV_SendDataSet(association, presentationCtx, &setRequest->dataSet, NULL, NULL, 0); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_NSetRequest"); cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID, &command, &messageType, &message); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_NSetRequest"); if (messageType != MSG_K_N_SET_RESP) { (void) MSG_Free(&message); return COND_PushCondition(SRV_UNEXPECTEDCOMMAND, SRV_Message(SRV_UNEXPECTEDCOMMAND), (int) command, "SRV_NSetRequest"); } localResponse = (MSG_N_SET_RESP *) message; if (localResponse->dataSetType == DCM_CMDDATANULL) { localResponse->dataSet = NULL; } else { cond = SRV_ReceiveDataSet(association, presentationCtx, DUL_BLOCK, 0, dirName, &localResponse->dataSet); if (cond != SRV_NORMAL) { (void) MSG_Free(&message); return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_NSetRequest"); } } cond = setCallback(setRequest, localResponse, setCtx); (void) MSG_Free(&message); if (localResponse->dataSet != NULL) { (void) DCM_CloseObject(&localResponse->dataSet); localResponse->dataSet = NULL; } if (setResponse != NULL) *setResponse = *localResponse; if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_NSetRequest"); return SRV_NORMAL; }
CONDITION SRV_CStoreResponse(DUL_ASSOCIATIONKEY ** association, DUL_PRESENTATIONCONTEXT * ctx, MSG_C_STORE_REQ ** storeRequest, MSG_C_STORE_RESP * storeReply, char *fileName, SRV_C_STORE_RESP_CALLBACK * callback, void *callbackCtx, char *dirName) { int fd, done; unsigned long total, estimatedSize, nextCallback; unsigned short sendStatus = 0x0000; DUL_PDV pdv; CONDITION cond; DCM_OBJECT * object; DCM_FILE_META fileMeta; int storeAsPart10 = 0; char* paramValue; storeReply->messageIDRespondedTo = (*storeRequest)->messageID; storeReply->type = MSG_K_C_STORE_RESP; (void) strcpy(storeReply->classUID, (*storeRequest)->classUID); (void) strcpy(storeReply->instanceUID, (*storeRequest)->instanceUID); storeReply->conditionalFields = MSG_K_C_STORERESP_CLASSUID | MSG_K_C_STORERESP_INSTANCEUID; storeReply->dataSetType = DCM_CMDDATANULL; if (strlen(fileName) == 0 || fileName == NULL) { fd = -1; }else{ #ifdef _MSC_VER fd = _open(fileName, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, _S_IREAD | _S_IWRITE); #else fd = open(fileName, O_CREAT | O_WRONLY | O_TRUNC, 0666); #endif if (fd < 0) (void) COND_PushCondition(SRV_FILECREATEFAILED, SRV_Message(SRV_FILECREATEFAILED), fileName, "SRV_CStoreResponse"); } if (strcmp(ctx->acceptedTransferSyntax, DICOM_TRANSFERLITTLEENDIAN) != 0){ storeAsPart10 = 1; }else{ paramValue = UTL_GetConfigParameter("STORAGE/PART10FLAG"); if (paramValue != NULL) { if (strcmp(paramValue, "1") == 0) storeAsPart10 = 1; } } if ((storeAsPart10 == 1) && (fd > 0)){ int localStatus = 0; memset(&fileMeta, 0, sizeof(fileMeta)); setFileMeta(&fileMeta, *storeRequest, ctx->acceptedTransferSyntax); localStatus = writePart10MetaHeader(fd, &fileMeta); if (localStatus != 0) fd = -1; } if (fd < 0) { sendStatus = MSG_K_C_STORE_OUTOFRESOURCES; storeReply->conditionalFields |= MSG_K_C_STORERESP_ERRORCOMMENT; strcpy(storeReply->errorComment, "Storage Service unable to create local file"); fprintf(stderr,"Storage Service unable to create local file\n"); } done = 0; total = 0; estimatedSize = genericImageSize((*storeRequest)->classUID); nextCallback = estimatedSize / 10; while (!done) { cond = SRVPRV_ReadNextPDV(association, DUL_BLOCK, 0, &pdv); if (cond != SRV_NORMAL) { (void) MSG_Free((void **) storeRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse"); } if (pdv.pdvType != DUL_DATASETPDV) { (void) MSG_Free((void **) storeRequest); return COND_PushCondition(SRV_UNEXPECTEDPDVTYPE, SRV_Message(SRV_UNEXPECTEDPDVTYPE), (int) pdv.pdvType, "SRV_CStoreResponse"); } if (sendStatus == 0) if (write(fd, pdv.data, pdv.fragmentLength) != (int) pdv.fragmentLength) sendStatus = MSG_K_C_STORE_OUTOFRESOURCES; total += pdv.fragmentLength; if (pdv.lastPDV) done++; if (total > nextCallback){ cond = callback(*storeRequest, NULL, total, estimatedSize, NULL, callbackCtx, ctx); if (cond != SRV_NORMAL){ (void) MSG_Free((void **) storeRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse"); } nextCallback += estimatedSize / 10; } } if (fd >= 0) (void) close(fd); storeReply->status = sendStatus; if (sendStatus == 0x0000) { unsigned long options = DCM_ORDERLITTLEENDIAN; if (storeAsPart10 == 1) options = DCM_PART10FILE; cond = DCM_OpenFile(fileName, options, &object); if (cond != DCM_NORMAL) { (void) MSG_Free((void **) storeRequest); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse"); } cond = callback(*storeRequest, storeReply, total, estimatedSize, &object, callbackCtx, ctx); if (cond != SRV_NORMAL) { (void) DCM_CloseObject(&object); return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse"); } (void) DCM_CloseObject(&object); } (void) MSG_Free((void **) storeRequest); cond = MSG_BuildCommand(storeReply, &object); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "STORE Request", "SRV_CStoreResponse"); cond = SRV_SendCommand(association, ctx, &object); (void) DCM_CloseObject(&object); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse"); return SRV_NORMAL; }
void openfile(char *filename) { char buff[80], bname[80]; int nitems; int cnt = 0; XmString *strlist; CONDITION cond; /**memset(info, 0 ,sizeof(info)); copyWtext(info);**/ /* show selected patient filename in text widget */ sprintf(bname, "File Selected: %s", filename); XmTextSetString(text3, bname); /* clear the scrolledlist windows, befor opening a new file*/ XtVaGetValues(scrolledList1, XmNitemCount, &cnt, XmNitems, &strlist, NULL); if (cnt != 0) { XmListDeleteAllItems(scrolledList1); /*lint -e64*/ XtFree(strlist); /*lint +e64*/ } XtVaGetValues(scrolledList2, XmNitemCount, &cnt, XmNitems, &strlist, NULL); if (cnt != 0) { XmListDeleteAllItems(scrolledList2); /*lint -e64*/ XtFree(strlist); /*lint +e64*/ } XtVaGetValues(scrolledList3, XmNitemCount, &cnt, XmNitems, &strlist, NULL); if (cnt != 0) { XmListDeleteAllItems(scrolledList3); /*lint -e64*/ XtFree(strlist); /*lint +e64*/ } /* Clear text widgets */ if (strlen(XmTextGetString(text1)) != 0) XmTextSetString(text1, NULL); if (strlen(XmTextGetString(text2)) != 0) XmTextSetString(text2, NULL); if (strlen(XmTextGetString(scrolledText1)) != 0) XmTextSetString(scrolledText1, NULL); if (ieObject != NULL) { cond = IE_Free((void **) &ieObject); if (cond != IE_NORMAL) { (void) COND_ExtractConditions(errorstackP); copyWtext(info); (void) COND_PopCondition(clearStack); free(info); } } free(ieObject); if (ieIE != NULL) { cond = IE_Free((void **) &ieIE); if (cond != IE_NORMAL) { (void) COND_ExtractConditions(errorstackP); copyWtext(info); (void) COND_PopCondition(clearStack); free(info); } } free(ieIE); if (ieModule != NULL) { cond = IE_Free((void **) &ieModule); if (cond != IE_NORMAL) { (void) COND_ExtractConditions(errorstackP); copyWtext(info); (void) COND_PopCondition(clearStack); free(info); } } free(ieModule); if (ieAttr != NULL) { cond = IE_Free((void **) &ieAttr); if (cond != IE_NORMAL) { (void) COND_ExtractConditions(errorstackP); copyWtext(info); (void) COND_PopCondition(clearStack); free(info); } } free(ieAttr); if (queryObject != NULL) { cond = DCM_CloseObject(&queryObject); if (cond != DCM_NORMAL) { (void) COND_ExtractConditions(errorstackP); copyWtext(info); (void) COND_PopCondition(clearStack); free(info); } } free(queryObject); kount = kount + 1; printf(" %d, %s\n", kount, filename); cond = DCM_OpenFile(filename, options, &queryObject); if (cond != DCM_NORMAL) { (void) COND_ExtractConditions(errorstackP); copyWtext(info); (void) COND_PopCondition(clearStack); free(info); } else { cond = IE_ExamineObject(&queryObject, &ieObject); if (cond != IE_NORMAL) { (void) COND_ExtractConditions(errorstackP); copyWtext(info); (void) COND_PopCondition(clearStack); free(info); } ie_head = ieObject->ieList; MUT_LoadList(scrolledList1, ie_head, formatieList, buff); } free(filename); }
/* 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); }
/* processStoreRequest ** ** Purpose: ** Process the Store sub operation request. ** ** Parameter Dictionary: ** association Handle to the association ** presentationCtx The presentation context negotiated between the peers ** storeRequest Pointer to the received C-STORE request ** callback Pointer to user callback function to be invoked during ** store operation ** callbackCtx Any context information that needs to be passed to the ** callback function ** ** Return Values: ** SRV_NORMAL unless there is any error ** ** Notes: ** ** Algorithm: ** Description of the algorithm (optional) and any other notes. */ static CONDITION processStoreRequest(DUL_ASSOCIATIONKEY ** association, DUL_PRESENTATIONCONTEXT * presentationCtx, MSG_C_STORE_REQ * storeRequest, CONDITION(*callback) (), void *callbackCtx) { CONDITION cond; int fd; /* file descriptor */ CTNBOOLEAN first = TRUE, /* to tell the callback function if it was invoked the first time or not */ done = FALSE; unsigned long total, estimatedSize, nextCallback; unsigned short sendStatus = 0x0000; DUL_PDV pdv; DCM_OBJECT * object; char fileName[1024]; /* name of image file */ MSG_C_STORE_RESP storeResponse; storeResponse.messageIDRespondedTo = storeRequest->messageID; storeResponse.type = MSG_K_C_STORE_RESP; (void) strcpy(storeResponse.classUID, storeRequest->classUID); (void) strcpy(storeResponse.instanceUID, storeRequest->instanceUID); storeResponse.conditionalFields = MSG_K_C_STORERESP_CLASSUID | MSG_K_C_STORERESP_INSTANCEUID; storeResponse.dataSetType = DCM_CMDDATANULL; storeResponse.status = MSG_K_SUCCESS; /* we initialize it to success but the callback can change it */ /* invoke the call back for the first time and get the file name */ total = 0; estimatedSize = genericImageSize(storeRequest->classUID); cond = callback(storeRequest, &storeResponse, first, fileName, total, estimatedSize, NULL, callbackCtx); first = FALSE; if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "processStoreRequest"); #ifdef _MSC_VER fd = open(fileName, O_BINARY | O_CREAT | O_WRONLY | O_TRUNC, S_IREAD | S_IWRITE); #else fd = open(fileName, O_CREAT | O_WRONLY | O_TRUNC, 0666); #endif if (fd < 0) return COND_PushCondition(SRV_FILECREATEFAILED, SRV_Message(SRV_FILECREATEFAILED), fileName, "SRV_CGetRequest"); done = FALSE; nextCallback = estimatedSize / 10; while (!done) { cond = SRVPRV_ReadNextPDV(association, DUL_BLOCK, 0, &pdv); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetRequest"); if (pdv.pdvType != DUL_DATASETPDV) return COND_PushCondition(SRV_UNEXPECTEDPDVTYPE, SRV_Message(SRV_UNEXPECTEDPDVTYPE), (int) pdv.pdvType, "SRV_CGetRequest"); if (sendStatus == 0) { if (write(fd, pdv.data, pdv.fragmentLength) != (int) pdv.fragmentLength) sendStatus = 0xaf01; } total += pdv.fragmentLength; if (pdv.lastPDV) done = TRUE; if (total > nextCallback) { cond = callback(storeRequest, &storeResponse, first, NULL, total, estimatedSize, NULL, callbackCtx); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetRequest"); nextCallback += estimatedSize / 10; } } (void) close(fd); cond = DCM_OpenFile(fileName, DCM_ORDERLITTLEENDIAN, &object); if (cond != DCM_NORMAL) return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetRequest"); /* invoke the callback the last time with a valid object */ cond = callback(storeRequest, &storeResponse, first, NULL, total, estimatedSize, &object, callbackCtx); if (cond != SRV_NORMAL) { (void) DCM_CloseObject(&object); return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CGetRequest"); } (void) DCM_CloseObject(&object); /* Now build a C-Store response message and send it to the peer */ cond = MSG_BuildCommand(&storeResponse, &object); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "storeResponse", "processStoreRequest"); cond = SRV_SendCommand(association, presentationCtx, &object); (void) DCM_CloseObject(&object); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetRequest"); return SRV_NORMAL; }
int main(int argc, char **argv) { CONDITION cond; /* Return value from DUL and ACR routines */ DCM_OBJECT * object; /* Handle to the information object */ DCM_ELEMENT element; /* Handle to the DCM_ELEMENT */ IE_OBJECT * ieObject; /* Handle to the IE_OBJECT object */ IE_INFORMATIONENTITY * ieIE, *ie_node; /* Handle to IE_INFORMATIONENTITY */ LST_HEAD * ie_head, *mod_head, *attr_head; /* Handle to the LST_HEAD */ IE_MODULE * ieModule, *mod_node; /* Handle to IE_MODULE */ IE_ATTRIBUTE * attr_node; /* Handle to IE_ATTRIBUTE */ CTNBOOLEAN verbose = FALSE; /* For debugging purpose */ CTNBOOLEAN flag; /* Return value from findElement routine */ unsigned long options = DCM_ORDERLITTLEENDIAN; /* Byte order in data streams */ char *file; /* The image file name */ char UID[90]; /* The SOP Class UID of the image file */ U32 length; /* Length of the data field of DCM_ELEMENT */ int ie_loop, mod_loop, attr_loop, j, k, i;/* Iteration variables */ while (--argc > 0 && (*++argv)[0] == '-') { switch (*(argv[0] + 1)) { case 'v': verbose = TRUE; break; case 'b': options &= ~DCM_ORDERMASK; options |= DCM_ORDERBIGENDIAN; break; case 't': options &= ~DCM_FILEFORMATMASK; options |= DCM_PART10FILE; break; default: break; } } if (argc < 1) usageerror(); file = *argv; THR_Init(); DCM_Debug(verbose); /* Open a DICOM object file and put the contents into the memory represented by the information object. */ cond = DCM_OpenFile(file, options, &object); if (cond != DCM_NORMAL && ((options & DCM_PART10FILE) == 0)) { COND_DumpConditions(); (void) DCM_CloseObject(&object); (void) COND_PopCondition(TRUE); fprintf(stderr, "Could not open %s as expected. Trying Part 10 format.\n", file); cond = DCM_OpenFile(file, options | DCM_PART10FILE, &object); } if (cond != DCM_NORMAL) { COND_DumpConditions(); THR_Shutdown(); return 1; }else{ printf("file is successfully opened!\n"); /* Call IE_ExamineObject to examine this DCM object. */ cond = IE_ExamineObject(&object, &ieObject); if (cond == IE_ILLEGALDCMOBJECT || cond == IE_LISTFAILURE || cond == IE_MALLOCFAILURE){ COND_DumpConditions(); }else{ /* Print the IE_OBJECT object. */ strcpy(UID, ieObject->classUID); printObject(ieObject); /* Examine each IE on the list. */ ie_head = ieObject->ieList; ie_loop = LST_Count(&ie_head); for (i = 0; i < ie_loop; i++) { ie_node = LST_Pop(&ie_head); cond = IE_ExamineInformationEntity(&object, ie_node->ieType, &ieIE); /* Print each IE_IE. */ printIE(ieIE); /* Examine each module on the list. */ mod_head = ieIE->moduleList; mod_loop = LST_Count(&mod_head); for (k = 0; k < mod_loop; k++) { mod_node = LST_Pop(&mod_head); cond = IE_ExamineModule(&object, ieIE->ieType, mod_node->moduleType, &ieModule); printModule(ieModule); /* Print each IE_ATTRIBUTE. */ attr_head = ieModule->attributeList; attr_loop = LST_Count(&attr_head); for (j = 0; j < attr_loop; j++) { attr_node = LST_Pop(&attr_head); printIEAttribute(attr_node); free(attr_node); } free(mod_node); cond = IE_Free((void **) &ieModule); } free(ie_node); cond = IE_Free((void **) &ieIE); } cond = IE_Free((void **) &ieObject); /* Check to see the status of the Information Entities. */ cond = IE_ExamineObject(&object, &ieObject); printf("\n%s requirements:\n", ieObject->objectDescription); ie_head = ieObject->ieList; ie_loop = LST_Count(&ie_head); for (i = 0; i < ie_loop; i++) { ie_node = LST_Pop(&ie_head); if (ie_node->requirement == IE_K_REQUIRED) printIE(ie_node); free(ie_node); } cond = IE_Free((void **) &ieObject); /* Check to see the status of the Information Entity and status of the Modules within them. */ cond = IE_ExamineObject(&object, &ieObject); printf("\n%s requirements:\n", ieObject->objectDescription); ie_head = ieObject->ieList; ie_loop = LST_Count(&ie_head); for (i = 0; i < ie_loop; i++) { ie_node = LST_Pop(&ie_head); cond = IE_ExamineInformationEntity(&object, ie_node->ieType, &ieIE); if (ie_node->requirement == IE_K_REQUIRED) { printf("\n"); printIE(ieIE); mod_head = ieIE->moduleList; mod_loop = LST_Count(&mod_head); for (k = 0; k < mod_loop; k++) { mod_node = LST_Pop(&mod_head); if (mod_node->requirement == IE_K_REQUIRED) printModule(mod_node); free(mod_node); } } free(ie_node); cond = IE_Free((void **) &ieIE); } cond = IE_Free((void **) &ieObject); /* Check to see the missing attributes if there is any. */ cond = IE_ObjectRequirements(UID, &ieObject); printf("\n Missing required(type1 and type2) attributes: \n"); ie_head = ieObject->ieList; ie_loop = LST_Count(&ie_head); for (i = 0; i < ie_loop; i++) { ie_node = LST_Pop(&ie_head); cond = IE_IERequirements(UID, ie_node->ieType, &ieIE); mod_head = ieIE->moduleList; mod_loop = LST_Count(&mod_head); for (k = 0; k < mod_loop; k++) { mod_node = LST_Pop(&mod_head); cond = IE_ModuleRequirements(UID, ie_node->ieType, mod_node->moduleType, &ieModule); printf(" %s\n", ieModule->moduleDescription); attr_head = ieModule->attributeList; attr_loop = LST_Count(&attr_head); for (j = 0; j < attr_loop; j++) { attr_node = LST_Pop(&attr_head); flag = findElement(object, attr_node->element.tag, &element); cond = DCM_LookupElement(&element); if (cond != DCM_NORMAL) cond = COND_PopCondition(FALSE); if (!flag) { if (attr_node->requirement == IE_K_TYPE1){ printf(" %08x, %s\n", element.tag, element.description); }else if (attr_node->requirement == IE_K_TYPE2){ cond = DCM_GetElementSize(&object, attr_node->element.tag, &length); if (cond != DCM_NORMAL){ cond = COND_PopCondition(FALSE); printf(" %08x, %s\n", element.tag, element.description); } } } } /* finish one module */ free(mod_node); cond = IE_Free((void **) &ieModule); } free(ie_node); cond = IE_Free((void **) &ieIE); } cond = IE_Free((void **) &ieObject); } } /* Free the memory and remove the object handle. */ cond = DCM_CloseObject(&object); if (cond != DCM_NORMAL){ COND_DumpConditions(); }else{ printf("The object is closed successfully.\n"); } THR_Shutdown(); return 0; }
CONDITION SRV_CStoreRequest(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, MSG_C_STORE_REQ * storeRequest, MSG_C_STORE_RESP * storeResponse, SRV_C_STORE_REQ_CALLBACK * callback, void *callbackCtx, char *dirName) { DCM_OBJECT * commandObject, /* Handle for a command object */ *dataSetObject; /* Handle for a Data Set object */ CONDITION cond; /* Return value from function calls */ DUL_PRESENTATIONCONTEXT * presentationCtx; /* Presentation context for this service */ DUL_PRESENTATIONCONTEXTID ctxID; void *message; MSG_TYPE messageType; unsigned long objectSize; unsigned short command; STORAGE_CTX localCtx; MSG_C_STORE_RESP * response; localCtx.callback = callback; localCtx.storeRequest = storeRequest; localCtx.storeResponse = NULL; localCtx.userCtx = callbackCtx; if (callback == NULL) return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_CStoreRequest"); if (storeRequest->type != MSG_K_C_STORE_REQ) return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "STORE Request", "SRV_CStoreRequest"); if (storeRequest->dataSetType == DCM_CMDDATANULL) return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "dataSetType", "STORE Request", "SRV_CStoreRequest"); presentationCtx = SRVPRV_PresentationContext(params, storeRequest->classUID); if (presentationCtx == NULL) return COND_PushCondition(SRV_NOSERVICEINASSOCIATION, SRV_Message(SRV_NOSERVICEINASSOCIATION), storeRequest->classUID, "SRV_CStoreRequest"); cond = MSG_BuildCommand(storeRequest, &commandObject); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "STORE Request", "SRV_CStoreRequest"); dataSetObject = storeRequest->dataSet; if (dataSetObject == NULL) { cond = DCM_OpenFile(storeRequest->fileName, DCM_ORDERLITTLEENDIAN, &dataSetObject); if (cond != DCM_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest"); } cond = DCM_GetObjectSize(&dataSetObject, &objectSize); if (cond != DCM_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest"); cond = SRV_SendCommand(association, presentationCtx, &commandObject); (void) DCM_CloseObject(&commandObject); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest"); cond = callback(storeRequest, NULL, 0, objectSize, callbackCtx); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest"); cond = SRV_SendDataSet(association, presentationCtx, &dataSetObject, localCallback, &localCtx, objectSize); if (storeRequest->dataSet == NULL) (void) DCM_CloseObject(&dataSetObject); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest"); cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID, &command, &messageType, &message); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest"); if (messageType != MSG_K_C_STORE_RESP) { (void) MSG_Free(&message); return COND_PushCondition(SRV_UNEXPECTEDCOMMAND, SRV_Message(SRV_UNEXPECTEDCOMMAND), (int) command, "SRV_CStoreRequest"); } response = (MSG_C_STORE_RESP *) message; if (storeResponse != NULL) *storeResponse = *response; cond = callback(storeRequest, response, objectSize, objectSize, callbackCtx); (void) MSG_Free(&message); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CStoreRequest"); return SRV_NORMAL; }