DUL_PRESENTATIONCONTEXT * SRVPRV_PresentationContext(DUL_ASSOCIATESERVICEPARAMETERS * params, char *classUID) { DUL_PRESENTATIONCONTEXT * presentationCtx;/* Presentation context for this service */ #if 0 fprintf(stderr, "<%s>\n", classUID); #endif if (params->acceptedPresentationContext == NULL) return NULL; presentationCtx = LST_Head(¶ms->acceptedPresentationContext); if (presentationCtx == NULL) return NULL; (void) LST_Position(¶ms->acceptedPresentationContext, presentationCtx); while (presentationCtx != NULL){ #if 0 fprintf(stderr, "%d <%s> <%s>\n", presentationCtx->result, classUID, presentationCtx->abstractSyntax); #endif if ((strcmp(classUID, presentationCtx->abstractSyntax) == 0) && (presentationCtx->result == DUL_PRESENTATION_ACCEPT)) return presentationCtx; presentationCtx = LST_Next(¶ms->acceptedPresentationContext); } if (strcmp(classUID, DICOM_SOPCLASSDETACHEDINTERPRETMGMT) == 0){ return SRVPRV_PresentationContext(params, DICOM_SOPCLASSDETACHEDRESULTSMGMTMETA); }else if (strcmp(classUID, DICOM_SOPCLASSDETACHEDINTERPRETMGMT) == 0){ return SRVPRV_PresentationContext(params, DICOM_SOPCLASSDETACHEDRESULTSMGMTMETA); } return NULL; }
static CONDITION sendStoreRequest(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, MSG_C_STORE_REQ * storeRequest) { DUL_PRESENTATIONCONTEXT * storePresentationCtx; DCM_OBJECT * storeRequestObject; CONDITION cond; /* switch the presentation context to the store presentation context */ storePresentationCtx = SRVPRV_PresentationContext(params, storeRequest->classUID); if (!storePresentationCtx) return COND_PushCondition(SRV_PRESENTATIONCONTEXTERROR, SRV_Message(SRV_PRESENTATIONCONTEXTERROR), "sendStoreRequest"); /* build a StoreRequest command object */ cond = MSG_BuildCommand(storeRequest, &storeRequestObject); if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "MSG_BuildCommand", "sendStoreRequest"); /* Now send the store request on the same association */ cond = SRV_SendCommand(association, storePresentationCtx, &storeRequestObject); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED), "SRV_SendCommand", "sendStoreRequest"); /* Now send the data set */ cond = SRV_SendDataSet(association, storePresentationCtx, &storeRequest->dataSet, NULL, NULL, 0); if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED), "SRV_SendDataSet", "sendStoreRequest"); return SRV_NORMAL; }
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_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_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; }