Example #1
0
static pipeline_t va_pipe_pipeline(pipeline_t result_so_far,
                                   va_list args)
{
    pipe_processor_t proc = va_arg(args, pipe_processor_t);

    if(proc == NULL)
        return result_so_far;

    void*  aux       = va_arg(args, void*);
    size_t pipe_size = va_arg(args, size_t);

    if(pipe_size == 0)
    {
        pipe_consumer_free(result_so_far.out);
        result_so_far.out = NULL;
        return result_so_far;
    }

    pipe_t* pipe = pipe_new(pipe_size, 0);

    pipe_connect(result_so_far.out , proc, aux, pipe_producer_new(pipe));
    result_so_far.out = pipe_consumer_new(pipe);

    pipe_free(pipe);

    return va_pipe_pipeline(result_so_far, args);
}
Example #2
0
dt_env_t *
dt_create(uint16_t port, uint8_t num_workers)
{
	log_assert(port > 0);
	log_assert(num_workers > 0);

	dt_env_t *env = (dt_env_t *) malloc(sizeof(dt_env_t));
	if (!env) return NULL;

	// Flags. Initial valuse are set here, and each is set again, only once,
	// from another function, possibly in another thread; otherwise,
	// they're only ever read.
	env->so_connected = malloc(sizeof(uint8_t));
	env->dt_stopping = malloc(sizeof(uint8_t));

	*(env->so_connected) = 0;
	*(env->dt_stopping) = 0;

	env->so_pipe = pipe_new(sizeof(void *), 0);

	// These are used in the dt_worker therad. Unbound workers
	// create their own producers
	env->so_consumer = pipe_consumer_new(env->so_pipe);
	env->so_producer = pipe_producer_new(env->so_pipe);
	pthread_create(&env->dt_worker, NULL, __dt_worker, env);

	return env;
}
Example #3
0
pipeline_t pipe_parallel(size_t           instances,
                         size_t           in_size,
                         pipe_processor_t proc,
                         void*            aux,
                         size_t           out_size)
{
    pipe_t* in  = pipe_new(in_size,  0),
          * out = pipe_new(out_size, 0);

    while(instances--)
        pipe_connect(pipe_consumer_new(in),
                     proc, aux,
                     pipe_producer_new(out));

    pipeline_t ret = {
        .in  = pipe_producer_new(in),
        .out = pipe_consumer_new(out)
    };

    pipe_free(in);
    pipe_free(out);

    return ret;
}
Example #4
0
wtp_handle_t* wtp_alloc(const char* device, wtp_aslan_msg_cb msg_cb)
{
    if ((!device) || (!msg_cb))
	{
        errno = EINVAL;
		return NULL;
    }

    int ret = -1;

    wtp_handle_t *handle = calloc(1, sizeof(wtp_handle_t));
    if (!handle)
	{
        errno = ENOMEM;
		return NULL;
    }

	handle->wtp_state = WTP_STATE_NONE;
    handle->msg_cb = msg_cb;

    //for testing purposes only
    char hds_ip[] = "192.168.1.10";
    handle->hds_port = ASLAN_PROTOCOL_PORT;
    handle->hello_interval_seconds = 5;

    /* UDP socket */
    int s = -1;
    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
        free(handle);
		return NULL;
    }
    handle->udp_socket = s;

	if (pthread_mutex_init(&handle->hello_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

    if (pthread_mutex_init(&handle->udp_mutex, NULL) != 0)
    {
		free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->ack_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->sta_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->monitor_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

    handle->wtp_sta_hashmap = NULL;

    /* HDS parameters */
    handle->hds_inet_addr.sin_family = AF_INET;
    if (!inet_aton(hds_ip, (struct in_addr*) &(handle->hds_inet_addr.sin_addr.s_addr)))
	{
        errno = EINVAL;
		close_wtp(handle);
		return NULL;
    }
    handle->hds_ip = ntohl(handle->hds_inet_addr.sin_addr.s_addr);

    /* interface name */
    strncpy(handle->device, device, IFNAMSIZ - 1);

    /* interface IP */
    struct ifreq ifr;
    ifr.ifr_addr.sa_family = AF_INET;
    strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
    if (ioctl(handle->udp_socket, SIOCGIFADDR, &ifr) == -1)
	{
		close_wtp(handle);
		return NULL;
    }
    handle->local_ip = ntohl(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr);

    /* HDS sockaddr_in structure */
    handle->hds_inet_addr.sin_addr.s_addr = htonl(handle->hds_ip);
    handle->hds_inet_addr.sin_family  = AF_INET;
    handle->hds_inet_addr.sin_port = htons(handle->hds_port);

    /* UDP socket local port */
    struct sockaddr_in address;
    memset((char*) &address, 0, sizeof(address));
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = 0;
    address.sin_family = AF_INET;
    bind(handle->udp_socket, (struct sockaddr*) &address, sizeof(address));

    struct sockaddr_in sin = {0};
    socklen_t len = sizeof(sin);
    if (getsockname(handle->udp_socket, (struct sockaddr*)&sin, &len) == -1)
	{
		close_wtp(handle);
		return NULL;
    }
    handle->local_port = ntohs(sin.sin_port);
	wpa_printf(MSG_INFO, "INFO: UDP socket for ASLAN messages created, listening on port: %d\n", handle->local_port);

	/* create FIFO pipe producers and consumers */
	pipe_t* recv_pipe = pipe_new(sizeof(aslan_msg_t *), 100);
	handle->msg_recv_producer = pipe_producer_new(recv_pipe);
	handle->msg_recv_consumer = pipe_consumer_new(recv_pipe);
	pipe_free(recv_pipe);

	pipe_t* send_pipe = pipe_new(sizeof(aslan_msg_t *), 100);
	handle->msg_send_producer = pipe_producer_new(send_pipe);
	handle->msg_send_consumer = pipe_consumer_new(send_pipe);
	pipe_free(send_pipe);

    /* start receiving thread for ASLAN messages */
    if (pthread_create(&(handle->receive_thread), NULL, receive_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: receiving thread for ASLAN messages created\n");

	/* start processing thread for ASLAN messages */
    if (pthread_create(&(handle->process_thread), NULL, process_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: processing thread for ASLAN messages created\n");

	/* start sending thread for ASLAN messages */
    if (pthread_create(&(handle->send_thread), NULL, send_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: sending thread for ASLAN messages created\n");

    /* obtain HDS MAC address by a Hello message */
    if (wtp_send_hello_msg(handle) == -1)
	{
		close_wtp(handle);
		return NULL;
    }

    /* Check ARP cache */
    if (handle->local_ip != handle->hds_ip)
    {
        struct arpreq areq;
        memset(&areq, 0, sizeof(areq));
        struct sockaddr_in* sockaddr = NULL;
        sockaddr = (struct sockaddr_in*) &(areq.arp_pa);
        sockaddr->sin_family = AF_INET;
        sockaddr->sin_addr.s_addr = htonl(handle->hds_ip);
        sockaddr = (struct sockaddr_in*) &(areq.arp_ha);
        sockaddr->sin_family = ARPHRD_ETHER;
        strncpy(areq.arp_dev, device, IFNAMSIZ - 1);

        int i = 0;
        unsigned char mac_loopback[] = {0, 0, 0, 0, 0, 0};

        ioctl(s, SIOCGARP, (caddr_t) &areq);
        while ((i < 5) && (mac_cmp(areq.arp_ha.sa_data, mac_loopback)))
		{
            i++;
            sleep(1);
            ioctl(s, SIOCGARP, (caddr_t) &areq);
        }

        memcpy(handle->hds_mac, areq.arp_ha.sa_data, 6);

        if (mac_cmp(areq.arp_ha.sa_data, mac_loopback)) wpa_printf(MSG_WARNING, "WARNING: HDS MAC address obtaining failed\n");
        else wpa_printf(MSG_INFO, "INFO: HDS MAC address found: "MACSTR"\n", MAC2STR(handle->hds_mac));
    }
    else wpa_printf(MSG_INFO, "INFO: WTP started at loopback\n");

    return handle;
}