Esempio n. 1
0
void rtcan_raw_remove_filter(struct rtcan_socket *sock)
{
    int i, j, begin, end;
    struct rtcan_recv *first, *next, *last;
    int ifindex = atomic_read(&sock->ifindex);
    struct rtcan_device *dev;

    if (!rtcan_sock_has_filter(sock)) /* nothing to do */
	return;

    if (ifindex) {
        /* Socket was bound to one interface only. */
        begin = ifindex;
        end   = ifindex;
    } else {
        /* Socket was bound to all interfaces */
        begin = 1;
        end = RTCAN_MAX_DEVICES;
    }

    for (i = begin; i <= end; i++) {

	if ((dev = rtcan_dev_get_by_index(i)) == NULL)
	    continue;

        /* Search for first list entry pointing to this socket */
        first = NULL;
        next = dev->recv_list;
        while (next->sock != sock) {
            first = next;
            next = first->next;
        }

        /* Now go to the end of the old filter list */
        last = next;
        for (j = 1; j < sock->flistlen; j++)
            last = last->next;

        /* Detach found first list entry from reception list */
        if (first)
            first->next = last->next;
        else
            dev->recv_list = last->next;
        /* Add partial list to the head of empty list */
        last->next = dev->empty_list;
        /* Adjust empty list pointer */
        dev->empty_list = next;

        /* Increase free entries counter by length of old filter list */
        dev->free_entries += sock->flistlen;

	rtcan_raw_print_filter(dev);
	rtcan_dev_dereference(dev);
    }
}
Esempio n. 2
0
int rtcan_raw_check_filter(struct rtcan_socket *sock, int ifindex,
			   struct rtcan_filter_list *flist)
{
    int old_ifindex = 0, old_flistlen_all = 0;
    int free_entries, i, begin, end;
    struct rtcan_device *dev;
    int flistlen;

    if (rtcan_flist_no_filter(flist))
	return 0;

    /* Check if filter list has been defined by user */
    flistlen = (flist) ? flist->flistlen : 1;

    /* Now we check if a reception list would overflow. This takes some
     * preparation, so let's go ... */

    /* Check current bind status */
    if (rtcan_sock_has_filter(sock)) {
        /* Socket is bound */
        i = atomic_read(&sock->ifindex);

        if (i == 0)
            /* Socket was bound to ALL interfaces */
            old_flistlen_all = sock->flistlen;
        else    /* Socket was bound to only one interface */
            old_ifindex = i;
    }

    if (ifindex) {
        /* We bind the socket to only one interface. */
        begin = ifindex;
        end   = ifindex;
    } else {
        /* Socket must be bound to all interfaces. */
        begin = 1;
        end = RTCAN_MAX_DEVICES;
    }

    /* Check if there is space for the new binding */
    for (i = begin; i <= end; i++) {
	if ((dev = rtcan_dev_get_by_index(i)) == NULL)
	    continue;
	free_entries = dev->free_entries + old_flistlen_all;
	rtcan_dev_dereference(dev);
	if (i == old_ifindex)
	    free_entries += sock->flistlen;
	/* Compare free list space to new filter list length */
	if (free_entries < flistlen)
	    return -ENOSPC;
    }

    return 0;
}
Esempio n. 3
0
void rtcan_dev_alloc_name(struct rtcan_device *dev, const char *mask)
{
    char buf[IFNAMSIZ];
    struct rtcan_device *tmp;
    int i;


    for (i = 0; i < RTCAN_MAX_DEVICES; i++) {
        snprintf(buf, IFNAMSIZ, mask, i);
        if ((tmp = rtcan_dev_get_by_name(buf)) == NULL) {
            strncpy(dev->name, buf, IFNAMSIZ);
            break;
        }
#ifdef RTCAN_USE_REFCOUNT
        else
            rtcan_dev_dereference(tmp);
#endif
    }
}
Esempio n. 4
0
int rtcan_raw_add_filter(struct rtcan_socket *sock, int ifindex)
{
    int i, j, begin, end;
    struct rtcan_recv *first, *last;
    struct rtcan_device *dev;
    /* Check if filter list has been defined by user */
    int flistlen;

    if (rtcan_flist_no_filter(sock->flist)) {
	return 0;
    }

    flistlen = (sock->flist) ? sock->flist->flistlen : 0;

    if (ifindex) {
        /* We bind the socket to only one interface. */
        begin = ifindex;
        end   = ifindex;
    } else {
        /* Socket must be bound to all interfaces. */
        begin = 1;
        end = RTCAN_MAX_DEVICES;
    }

    for (i = begin; i <= end; i++) {
	if ((dev = rtcan_dev_get_by_index(i)) == NULL)
	    continue;

        /* Take first entry of empty list */
        first = last = dev->empty_list;
        /* Check if filter list is empty */
        if (flistlen) {
            /* Filter list is not empty */
            /* Register first filter */
            rtcan_raw_mount_filter(&last->can_filter,
				   &sock->flist->flist[0]);
	    last->match_count = 0;
            last->sock = sock;
            for (j = 1; j < flistlen; j++) {
                /* Register remaining filters */
                last = last->next;
                rtcan_raw_mount_filter(&last->can_filter,
				       &sock->flist->flist[j]);
                last->sock = sock;
		last->match_count = 0;
            }
            /* Decrease free entries counter by length of filter list */
            dev->free_entries -= flistlen;

        } else {
            /* Filter list is empty. Socket must be bound to all CAN IDs. */
            /* Fill list entry members */
            last->can_filter.can_id = last->can_filter.can_mask = 0;
            last->sock = sock;
	    last->match_count = 0;
            /* Decrease free entries counter by 1
             * (one filter for all CAN frames) */
            dev->free_entries--;
        }

        /* Set new empty list header */
        dev->empty_list = last->next;
        /* Add new partial recv list to the head of reception list */
        last->next = dev->recv_list;
        /* Adjust rececption list pointer */
        dev->recv_list = first;

	rtcan_raw_print_filter(dev);
	rtcan_dev_dereference(dev);
    }

    return (flistlen) ? flistlen : 1;
}