@@ -102,7 +102,8 @@ static void zcan_received_cb(struct net_context *ctx, struct net_pkt *pkt,
102102			(struct  zcan_frame  * )net_pkt_data (pkt );
103103		struct  can_frame  frame ;
104104
105- 		if  (receivers [i ].iface  !=  net_pkt_iface (pkt )) {
105+ 		if  (!receivers [i ].ctx  || 
106+ 		    receivers [i ].iface  !=  net_pkt_iface (pkt )) {
106107			continue ;
107108		}
108109
@@ -343,8 +344,86 @@ static ssize_t can_sock_write_vmeth(void *obj, const void *buffer,
343344	return  zcan_sendto_ctx (obj , buffer , count , 0 , NULL , 0 );
344345}
345346
347+ static  bool  is_already_attached (struct  can_filter  * filter ,
348+ 				struct  net_if  * iface ,
349+ 				struct  net_context  * ctx )
350+ {
351+ 	int  i ;
352+ 
353+ 	for  (i  =  0 ; i  <  ARRAY_SIZE (receivers ); i ++ ) {
354+ 		if  (receivers [i ].ctx  !=  ctx  &&  receivers [i ].iface  ==  iface  && 
355+ 		    ((receivers [i ].can_id  &  receivers [i ].can_mask ) == 
356+ 		     (UNALIGNED_GET (& filter -> can_id ) & 
357+ 		      UNALIGNED_GET (& filter -> can_mask )))) {
358+ 			return  true;
359+ 		}
360+ 	}
361+ 
362+ 	return  false;
363+ }
364+ 
365+ static  int  close_socket (struct  net_context  * ctx )
366+ {
367+ 	const  struct  canbus_api  * api ;
368+ 	struct  net_if  * iface ;
369+ 	struct  device  * dev ;
370+ 
371+ 	iface  =  net_context_get_iface (ctx );
372+ 	dev  =  net_if_get_device (iface );
373+ 	api  =  dev -> driver_api ;
374+ 
375+ 	if  (!api  ||  !api -> close ) {
376+ 		return  - ENOTSUP ;
377+ 	}
378+ 
379+ 	api -> close (dev , net_context_get_filter_id (ctx ));
380+ 
381+ 	return  0 ;
382+ }
383+ 
384+ static  int  can_close_socket (struct  net_context  * ctx )
385+ {
386+ 	int  i , ret ;
387+ 
388+ 	for  (i  =  0 ; i  <  ARRAY_SIZE (receivers ); i ++ ) {
389+ 		if  (receivers [i ].ctx  ==  ctx ) {
390+ 			struct  can_filter  filter ;
391+ 
392+ 			receivers [i ].ctx  =  NULL ;
393+ 
394+ 			filter .can_id  =  receivers [i ].can_id ;
395+ 			filter .can_mask  =  receivers [i ].can_mask ;
396+ 
397+ 			if  (!is_already_attached (& filter ,
398+ 						net_context_get_iface (ctx ),
399+ 						ctx )) {
400+ 				/* We can detach now as there are no other 
401+ 				 * sockets that have same filter. 
402+ 				 */ 
403+ 				ret  =  close_socket (ctx );
404+ 				if  (ret  <  0 ) {
405+ 					return  ret ;
406+ 				}
407+ 			}
408+ 
409+ 			return  0 ;
410+ 		}
411+ 	}
412+ 
413+ 	return  0 ;
414+ }
415+ 
346416static  int  can_sock_ioctl_vmeth (void  * obj , unsigned int   request , va_list  args )
347417{
418+ 	if  (request  ==  ZFD_IOCTL_CLOSE ) {
419+ 		int  ret ;
420+ 
421+ 		ret  =  can_close_socket (obj );
422+ 		if  (ret  <  0 ) {
423+ 			NET_DBG ("Cannot detach net_context %p (%d)" , obj , ret );
424+ 		}
425+ 	}
426+ 
348427	return  sock_fd_op_vtable .fd_vtable .ioctl (obj , request , args );
349428}
350429
@@ -506,24 +585,6 @@ static void can_unregister_filters(struct net_if *iface,
506585	}
507586}
508587
509- static  bool  is_already_attached (struct  can_filter  * filter ,
510- 				struct  net_if  * iface ,
511- 				struct  net_context  * ctx )
512- {
513- 	int  i ;
514- 
515- 	for  (i  =  0 ; i  <  ARRAY_SIZE (receivers ); i ++ ) {
516- 		if  (receivers [i ].ctx  !=  ctx  &&  receivers [i ].iface  ==  iface  && 
517- 		    ((receivers [i ].can_id  &  receivers [i ].can_mask ) == 
518- 		     (UNALIGNED_GET (& filter -> can_id ) & 
519- 		      UNALIGNED_GET (& filter -> can_mask )))) {
520- 			return  true;
521- 		}
522- 	}
523- 
524- 	return  false;
525- }
526- 
527588static  int  can_sock_setsockopt_vmeth (void  * obj , int  level , int  optname ,
528589				     const  void  * optval , socklen_t  optlen )
529590{
0 commit comments