Add ScanDestinations support in DPWSCore

      In windowsvista/win7/win8, we can use WSDAPI.dll to find/subscribe/unsubscribe the deviceand receive the events which sent out by devices actively(link),but winXP didn't have this dll, so we needimplement the function by ourselves. a good message is DPWSCore isdoing this work, it is a open source project with BSD license. So you canmodify her source and use the source in your product code.

      Now the latest releaseversion of DPWSCore is 2.4.0.when you only want to only use the device's printevent, this version can meet your requirement.  but this version doesn'tsupport the ScanDestinations  in ScanAvailableEvent ,so if you want toscan print , you need to wait for release v3,this thread can explain this. we don't findthe v3 when this summer become a thing of past, so we need implement thisfunction by ourselves.

      If you want the DPWScore handlethe ScanDestinations, you need add the related structure into subscribe message,subscribeResponse message for internal use, also need add relatedstructure for external use for configure the real destination. 

      Step 1:open the eventsource.gsoap and addthe ScanDestinations related structure into _wse__Subscribe ,addthe DestinationResponses related structureinto _wse__SubscribeResponse. the WSDSCAN.sln will generate thesefunctions according this gsoap file.   

 //gsoap sca   schema namespace: http://schemas.microsoft.com/windows/2006/08/wdp/scan
 //gsoap sca   schema form:	unqualified
 typedef char* sca__ClientDisplayNameType;
 typedef char* sca__ClientContextType;
 struct sca__ScanDestinationType
 {
 	sca__ClientDisplayNameType sca__ClientDisplayName 1;
 	sca__ClientContextType sca__ClientContext 1;
 /// Extensible in the schema
 };
 
 struct sca__ScanDestinationsType
 {
 	struct sca__ScanDestinationType *sca__ScanDestination 1;
 };
 
 struct _wse__Subscribe
 {
 	endpoint_ref wse__EndTo	0;
 	struct wse__DeliveryType *wse__Delivery	1;
 	wse__ExpirationType wse__Expires 0;
 	struct wse__FilterType *wse__Filter	0;
 	struct sca__ScanDestinationsType *sca__ScanDestinations 0;
 /// Extensible in the schema
 };
 
 struct sca__DestinationResponseType
 {
 	sca__ClientContextType sca__ClientContext 1;
 	@xsd__anyURI sca__DestinationToken 1;
 /// Extensible in the schema	
 };
 
 struct sca__DestinationResponsesType
 {
 	struct sca__DestinationResponseType *sca__DestinationResponse 1;
 };
 
 struct _wse__SubscribeResponse
 {
 	endpoint_ref wse__SubscriptionManager	1;
 	wse__ExpirationType wse__Expires	1;
 	struct sca__DestinationResponsesType sca__DestinationResponses  0;
 /// Extensible in the schema
 };
 
Step 2: add wscn_scandestination_ref into dc_Types.hfor external use.

/**
 * WS-Eventing ScanDestination reference
 * Runtime structure that contains WS-Eventing ScanDestination reference data.
 * Used for the source, reply to and fault to WSA header fields.
 */
 struct sca_scandestination_ref {
 	char* client_display_name;	/**< client display name */
 	char* client_context;	/**< client context */
 };
 

      Step 3: add  ScanDestinations ralted urlinto dcDPWS_Dpws.c/dc_Constants.h.    

 #define SCA_PREFIX "sca"
 #define SCA_WILDCARD "http://schemas.xmlsoap.org/ws/*/eventing"
 #define SCA_URI "http://schemas.microsoft.com/windows/2006/08/wdp/scan"
 
 //add above macros into dpws11_default_namespaces,dpws10_protocols and dpws11_protocols in dcDPWS_Dpws.c.  dpws10_eventing_snd_namespaces and dpws11_eventing_snd_namespaces in dcDPWS_Event.c.
 

      Step 4: add ScanDestinationsType into dpws_event_subscribe_ex/dpws_event_subscribeas a parameter for external call in dc_Dpws.h and dcDPWS_Event.c. 

//dc_Dpws.h
DC_RT_FMAC1 struct wsa_endpoint_ref * dpws_event_subscribe(struct dpws* dpws, struct wsa_endpoint_ref* event_source, struct wsa_endpoint_ref* notify_to, struct wsa_endpoint_ref* end_to, char ** filter, char ** expiration, struct sca_scandestination_ref *sca_destination);

DC_RT_FMAC1 struct wsa_endpoint_ref * dpws_event_subscribe_ex(struct dpws* dpws, struct wsa_endpoint_ref* event_source, short href_notify_to, short href_end_to, char ** filter, char ** expiration, struct sca_scandestination_ref *sca_destination); 

//dcDPWS_Event.c.
struct wsa_endpoint_ref * dpws_event_subscribe_ex(
 struct dpws* dpws,
 struct wsa_endpoint_ref* event_source,
 	short href_notify_to,
 	short href_end_to,
 	char ** filter,
 	char ** expiration,
 struct sca_scandestination_ref *scan_destination
 	)
 {
 	struct wsa_endpoint_ref * sm;
 	http_transport_data_t * tdata;
 	char local_address[MAX_IP_ADDRESS_STRING_LEN];
 	struct wsa_endpoint_ref *notify_to = NULL, *end_to = NULL;
 	const transport_class_t * tclass;
 
 	DC_CHECK_PARAM_RETURN(dpws, NULL);
 	DC_CHECK_PARAM_NO_RC(dpws->err, event_source && href_notify_to >= 0 && expiration, NULL);
 
 	/* Connect to retrieve the local IP used for connecting the event source */
 	soap_set_endpoint(dpws_dpws2soap(dpws), event_source->address);
 	tclass = get_transport_class(event_source->address);
 	if (!tclass) {
 		dpws->err = WSA_ERR_DESTINATION_UNREACHABLE;
 		return NULL;
 	}
 	tdata = dc_http_open_output_channel(dpws, dpws->soap.host,	(unsigned short)dpws->soap.port, tclass);	// ports are positive integers
 	if (tdata == NULL)
 		return NULL;
 	if ((dpws->err = dc_http_get_local_address(dpws, tdata->base.socket, local_address, MAX_IP_ADDRESS_STRING_LEN)) != DPWS_OK)
 		goto error;
 
 	if (!(notify_to = (struct wsa_endpoint_ref *)DC_MSG_MALLOC(DC_MEM_API, dpws, sizeof(struct wsa_endpoint_ref))))
 	{
 		dpws->err = DPWS_ERR_EOM;
 		goto error;
 	}
 	if (!(notify_to = build_local_endpoint_ref(dpws, notify_to, local_address, href_notify_to)))
 	{
 		goto error;
 	}
 	if (href_end_to >= 0)
 	{
 		if (!(end_to = (struct wsa_endpoint_ref *)DC_MSG_MALLOC(DC_MEM_API, dpws, sizeof(struct wsa_endpoint_ref))))
 		{
 			dpws->err = DPWS_ERR_EOM;
 			goto error;
 		}
 		if (!(end_to = build_local_endpoint_ref(dpws, end_to, local_address, href_end_to)))
 		{
 			goto error;
 		}
 	}
 	sm = dpws_event_subscribe(dpws, event_source, notify_to, end_to, filter, expiration,scan_destination);
 	if ((dpws->err = dc_transport_close_channel(dpws)) != DPWS_OK)
 		return NULL;
 
 	return sm;
 
 error:
 	dc_transport_close_channel(dpws);
 	return NULL;
 }
 
 struct wsa_endpoint_ref* dpws_event_subscribe(
 struct dpws* dpws,
 struct wsa_endpoint_ref* event_source,
 struct wsa_endpoint_ref* notify_to,
 struct wsa_endpoint_ref* end_to,
 	char ** filter,
 	char ** expiration,
 struct sca_scandestination_ref *sca_destination
 	)
 {
 	struct _wse__Subscribe subscription;
 	struct wse__DeliveryType delivery;
 	struct wse__FilterType s_filter;
 	struct _wse__SubscribeResponse response;
 	DA_TYPED(str) actions = DA_INITIALIZER(char *, DC_MEM_API, 2);	// wrapper
 	struct wsa_endpoint_ref* ret = NULL;
 	int nbActions = 0;
 
 	DC_CHECK_PARAM_RETURN(dpws, NULL);
 	DC_CHECK_PARAM_NO_RC(dpws->err, event_source && notify_to && expiration, NULL);
 
 	soap_default__wse__Subscribe(dpws_dpws2soap(dpws), &subscription);
 	subscription.wse__EndTo = end_to;
 	subscription.wse__Delivery = &delivery;
 	delivery.Mode = WSE_MODE_PUSH;
 	delivery.wse__NotifyTo = notify_to;
 #ifdef DC_WITH_WSMAN
 	delivery.wsman__Heartbeats = dpws->wsman_headers.heartbeats;
 #else 
 	delivery.wsman__Heartbeats = NULL;
 #endif
 
 	subscription.wse__Expires = *expiration;
 	if (!filter || !*filter)
 		subscription.wse__Filter = NULL;
 	else {
 		subscription.wse__Filter = &s_filter;
 		s_filter.__item = (dyn_array_t *)&actions;
 		//s_filter.Dialect = event_source->dpws_version->wdp_wse_filtering_dialect;
 		s_filter.Dialect = DPWS10_WSE_FILTERING_DIALECT;
 		actions.tab = filter;	// NOTE: custom uri list marshalling use the null boundary and not the nb field
 		while (*filter++) nbActions++;
 		actions.nb = nbActions;
 	}
 	if(sca_destination == NULL)
 	{
 		subscription.sca__ScanDestinations = NULL;
 	}else {
 		subscription.sca__ScanDestinations = (struct sca__ScanDestinationsType *)malloc(sizeof(struct sca__ScanDestinationsType));
 		subscription.sca__ScanDestinations->sca__ScanDestination = sca_destination;
 	}	
 	
 	if (dpws_call___wse__SubscribeOp(dpws, event_source, NULL, &subscription, &response))
 		goto exit;
 	*expiration = response.wse__Expires;
 	ret = response.wse__SubscriptionManager;
 	ret->dpws_version = dpws->protocols;
 
 exit:
 	dpws_init_headers_and_version(dpws);
 	return ret;
 }


One thing important is we just need ScanDestinations insubscribe ScanAvailableEvent ,not all of scan events. 

Date Posted: October 12, 2012

Blog Posted: LCL_data at  http://blog.csdn.net/lcl_data/article/details/8063426


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值