Beispiel #1
0
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(&params->acceptedPresentationContext);
    if (presentationCtx == NULL) return NULL;

    (void) LST_Position(&params->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(&params->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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
    }
}
Beispiel #4
0
/* 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;
}
Beispiel #5
0
/* 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;
}
Beispiel #6
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;
}