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); }
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; }
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; }
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; }