Beispiel #1
0
INT cd_multi(INT cmd, EQUIPMENT * pequipment)
{
   INT status;

   switch (cmd) {
   case CMD_INIT:
      status = multi_init(pequipment);
      break;

   case CMD_EXIT:
      status = multi_exit(pequipment);
      break;

   case CMD_START:
      status = multi_start(pequipment);
      break;

   case CMD_STOP:
      status = multi_stop(pequipment);
      break;

   case CMD_IDLE:
      status = multi_idle(pequipment);
      break;

   default:
      cm_msg(MERROR, "Multimeter class driver", "Received unknown command %d", cmd);
      status = FE_ERR_DRIVER;
      break;
   }

   return status;
}
Beispiel #2
0
int multi_fork( int n, struct multi_fork_status *p, time_t stoptime, int line )
{
	int i, result;

	for( i=0; i<n; i++ ) {
		p[i].state = MULTI_FORK_STATE_CRADLE;
	}

	cancel_hold();

	result = multi_start(n,p,stoptime,line);
	if(result==MULTI_FORK_SUCCESS) {
		result = multi_wait(n,p,stoptime,line,1);
		if(result!=MULTI_FORK_SUCCESS) {
			multi_kill(n,p,stoptime,line);
		}
	}

	cancel_release();

	return result;
}
Beispiel #3
0
void multi_test_visible_loop(struct multi_config *mc){
    uint8_t buf[MAX_BUFSIZE];
    int32_t retval;
    int32_t i;
    int32_t netlink_sock = 0;
    uint32_t ifi_idx = 0;
    struct iface *ni = NULL;

    /* Needed to create the netlink messages  */
    struct sockaddr_nl src_addr, dest_addr;
    struct iovec iov;
    struct msghdr msg;

    /* Select is used for easier timeouts  */
    fd_set copy, master;
    int32_t fdmax;
    struct timeval tv;

    memset(buf, 0, MAX_BUFSIZE);

    /* Initialise list */
    LIST_INIT(&iface_list);

    /* Define a private constant later! Needs to be set in netlink.h so that the
     * kernel will allow the socket to be created! */
    if((netlink_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_GENERIC)) < 0){
        perror("Could not create netlink socket: ");
        exit(EXIT_FAILURE);
    }

    /* These are both constant!  */
    memset(&src_addr, 0, sizeof(src_addr));
    memset(&dest_addr, 0, sizeof(dest_addr));
    memset(&msg, 0, sizeof(msg));

    src_addr.nl_family = AF_NETLINK;
    //If PID is set to zero, then the kernel assigns the unique value
    src_addr.nl_pid = 0; 
    //This is the source, it only multicasts, so it does not have to be 
    //member of any groups!
    src_addr.nl_groups = 0; 

    if(bind(netlink_sock, (struct sockaddr *) &src_addr, sizeof(src_addr)) < 0){
        perror("Could not bind netlink socket: ");
        exit(EXIT_FAILURE);
    }

    dest_addr.nl_family = AF_NETLINK;
    dest_addr.nl_pid = 0; 
    dest_addr.nl_groups = 1;

    MULTI_DEBUG_PRINT(stderr, "Multi manager is ready! Netlink socket %d\n", 
            netlink_sock);
    MULTI_DEBUG_PRINT(stderr, "M S\n");

    //Look at the Wikipedia site for iovec and man(7) netlink for examples on
    //how to properly parse netlink and have multiple iovec-entries
    msg.msg_name = (void *) &dest_addr; //This is the message's destination
    msg.msg_namelen = sizeof(dest_addr);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1; 

    //Initialise everything related to select
    FD_ZERO(&master);
    FD_ZERO(&copy);
    FD_SET(mc->socket_pipe[0], &master);
    fdmax = mc->socket_pipe[0];
    tv.tv_sec = 30;
    tv.tv_usec = 0;

    pthread_t multi_thread = multi_start(mc);

    while(1){
        copy = master;
        retval = select(fdmax + 1, &copy, NULL, NULL, &tv);

        //Repeat every UP message
        if(retval == 0){
            for(ni = iface_list.lh_first; ni != NULL; ni = ni->next.le_next){
                printf("Hei\n");
                iov.iov_base = (void *) ni->nlmsg;
                iov.iov_len = ni->nlmsg->nlmsg_len;
                sendmsg(netlink_sock, &msg, 0);
            }

            tv.tv_sec = 30;
            tv.tv_usec = 0;
            continue;
        }

        memset(buf, 0, MAX_BUFSIZE);

        //Sufficient to just memcpy this one and broadcast the netlink message
        retval = read(mc->socket_pipe[0], buf, MAX_BUFSIZE);

        if(retval == -1)
            perror("Failed to read from pipe");
        else {
            memcpy(&ifi_idx, (buf+1), sizeof(uint32_t));
           
            //This check needs to be performed irrespective of if link goes up
            //or down.
            LIST_FIND_CUSTOM(ni, &iface_list, next, &ifi_idx,
                        multi_mc_cmp_ifi);

            if(buf[0] == LINK_UP){
                //Sanity check. If the interface is already found, ignore the
                //announcement from MULTI.
                if(ni)
                    continue;

                //Create a new iface, buffer the up message and add to list
                ni = (struct iface*) malloc(sizeof(struct iface));
                ni->ifi_idx = ifi_idx;
                ni->nlmsg = (struct nlmsghdr *) malloc(NLMSG_SPACE(retval));
                memset(ni->nlmsg, 0, NLMSG_SPACE(retval));
                ni->nlmsg->nlmsg_pid = getpid();
                ni->nlmsg->nlmsg_flags = 0;
                ni->nlmsg->nlmsg_len = NLMSG_SPACE(retval);
                memcpy(NLMSG_DATA(ni->nlmsg), buf, retval);
                LIST_INSERT_HEAD(&iface_list, ni, next);

                //Adjust the base pointer of the message and broadcast message
                iov.iov_base = (void *) ni->nlmsg;
                iov.iov_len = ni->nlmsg->nlmsg_len;
                retval = sendmsg(netlink_sock, &msg, 0);
                MULTI_DEBUG_PRINT(stderr,"Broadcasted %d bytes about an UP "
                        "change in network state\n", retval);
            } else {
                if(ni){
                    //Forward message from MULTI
                    ni->nlmsg->nlmsg_len = NLMSG_SPACE(retval);
                    memcpy(NLMSG_DATA(ni->nlmsg), buf, retval);
                    iov.iov_base = (void *) ni->nlmsg;
                    iov.iov_len = ni->nlmsg->nlmsg_len;
                    retval = sendmsg(netlink_sock, &msg, 0);
                    MULTI_DEBUG_PRINT(stderr,"Broadcasted %d bytes about a "
                            "DOWN change in network state\n", retval);
                    
                    LIST_REMOVE(ni, next);
                    free(ni);
                }
            }
        }
    }
}