Exemple #1
0
static int vhc_virtdev_plug_generic(vhc_data_t *vhc,
    async_sess_t *sess, usbvirt_device_t *virtdev,
    uintptr_t *handle, bool connect, usb_address_t address)
{
	vhc_virtdev_t *dev = vhc_virtdev_create();
	if (dev == NULL) {
		return ENOMEM;
	}

	dev->dev_sess = sess;
	dev->dev_local = virtdev;
	dev->address = address;

	fibril_mutex_lock(&vhc->guard);
	list_append(&dev->link, &vhc->devices);
	fibril_mutex_unlock(&vhc->guard);

	fid_t fibril = fibril_create(vhc_transfer_queue_processor, dev);
	if (fibril == 0) {
		free(dev);
		return ENOMEM;
	}
	fibril_add_ready(fibril);

	if (handle != NULL) {
		*handle = (uintptr_t) dev;
	}

	if (connect) {
		// FIXME: check status
		(void) virthub_connect_device(&vhc->hub, dev);
	}

	return EOK;
}
/** Create new timer.
 *
 * @return		New timer on success, @c NULL if out of memory.
 */
fibril_timer_t *fibril_timer_create(void)
{
	fid_t fid;
	fibril_timer_t *timer;

	timer = calloc(1, sizeof(fibril_timer_t));
	if (timer == NULL)
		return NULL;

	fid = fibril_create(fibril_timer_func, (void *) timer);
	if (fid == 0) {
		free(timer);
		return NULL;
	}

	fibril_mutex_initialize(&timer->lock);
	fibril_condvar_initialize(&timer->cv);

	timer->fibril = fid;
	timer->state = fts_not_set;

	fibril_add_ready(fid);

	return timer;
}
Exemple #3
0
static int test2_dev_add(ddf_dev_t *dev)
{
	test2_t *test2;

	ddf_msg(LVL_DEBUG, "test2_dev_add(name=\"%s\", handle=%d)",
	    dev->name, (int) dev->handle);

	test2 = ddf_dev_data_alloc(dev, sizeof(test2_t));
	if (test2 == NULL) {
		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
		return ENOMEM;
	}

	test2->dev = dev;

	if (str_cmp(dev->name, "child") != 0) {
		fid_t postpone = fibril_create(plug_unplug, test2);
		if (postpone == 0) {
			ddf_msg(LVL_ERROR, "fibril_create() failed.");
			return ENOMEM;
		}
		fibril_add_ready(postpone);
	} else {
		(void) register_fun_verbose(dev, "child without available driver",
		    "ERROR", "non-existent.match.id", 10, &test2->fun_err);
	}

	return EOK;
}
Exemple #4
0
/** Start receive queue handler fibril. */
void tcp_rqueue_fibril_start(void)
{
	fid_t fid;

	log_msg(LVL_DEBUG, "tcp_rqueue_fibril_start()");

	fid = fibril_create(tcp_rqueue_fibril, NULL);
	if (fid == 0) {
		log_msg(LVL_ERROR, "Failed creating rqueue fibril.");
		return;
	}

	fibril_add_ready(fid);
}
Exemple #5
0
/** Initialize keyboard driver structure.
 *
 * @param kbd Keyboard driver structure to initialize.
 * @param dev DDF device structure.
 *
 * Connects to parent, creates keyboard function, starts polling fibril.
 *
 */
int at_kbd_init(at_kbd_t *kbd, ddf_dev_t *dev)
{
    assert(kbd);
    assert(dev);

    kbd->client_sess = NULL;
    kbd->parent_sess = ddf_dev_parent_sess_create(dev);

    if (!kbd->parent_sess) {
        ddf_msg(LVL_ERROR, "Failed creating parent session.");
        return EIO;
    }

    kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd");
    if (!kbd->kbd_fun) {
        ddf_msg(LVL_ERROR, "Failed creating function 'kbd'.");
        return ENOMEM;
    }

    ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops);

    int ret = ddf_fun_bind(kbd->kbd_fun);
    if (ret != EOK) {
        ddf_msg(LVL_ERROR, "Failed binding function 'kbd'.");
        ddf_fun_destroy(kbd->kbd_fun);
        return EEXIST;
    }

    ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard");
    if (ret != EOK) {
        ddf_msg(LVL_ERROR, "Failed adding function 'kbd' to category "
                "'keyboard'.");
        ddf_fun_unbind(kbd->kbd_fun);
        ddf_fun_destroy(kbd->kbd_fun);
        return ENOMEM;
    }

    kbd->polling_fibril = fibril_create(polling, kbd);
    if (!kbd->polling_fibril) {
        ddf_msg(LVL_ERROR, "Failed creating polling fibril.");
        ddf_fun_unbind(kbd->kbd_fun);
        ddf_fun_destroy(kbd->kbd_fun);
        return ENOMEM;
    }

    fibril_add_ready(kbd->polling_fibril);
    return EOK;
}
Exemple #6
0
/** Initialize UHCI hc driver structure
 *
 * @param[in] instance Memory place to initialize.
 * @param[in] regs Address of I/O control registers.
 * @param[in] reg_size Size of I/O control registers.
 * @param[in] interrupts True if hw interrupts should be used.
 * @return Error code.
 * @note Should be called only once on any structure.
 *
 * Initializes memory structures, starts up hw, and launches debugger and
 * interrupt fibrils.
 */
int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts)
{
	assert(reg_size >= sizeof(uhci_regs_t));
	int ret;

#define CHECK_RET_RETURN(ret, message...) \
	if (ret != EOK) { \
		usb_log_error(message); \
		return ret; \
	} else (void) 0

	instance->hw_interrupts = interrupts;
	instance->hw_failures = 0;

	/* allow access to hc control registers */
	uhci_regs_t *io;
	ret = pio_enable(regs, reg_size, (void **)&io);
	CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n",
	    io, str_error(ret));
	instance->registers = io;
	usb_log_debug(
	    "Device registers at %p (%zuB) accessible.\n", io, reg_size);

	ret = hc_init_mem_structures(instance);
	CHECK_RET_RETURN(ret,
	    "Failed to initialize UHCI memory structures: %s.\n",
	    str_error(ret));

#undef CHECK_RET_RETURN

	hcd_init(&instance->generic, USB_SPEED_FULL,
	    BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);

	instance->generic.private_data = instance;
	instance->generic.schedule = hc_schedule;
	instance->generic.ep_add_hook = NULL;

	hc_init_hw(instance);
	if (!interrupts) {
		instance->interrupt_emulator =
		    fibril_create(hc_interrupt_emulator, instance);
		fibril_add_ready(instance->interrupt_emulator);
	}
	(void)hc_debug_checker;

	return EOK;
}
Exemple #7
0
/** Fibril for each accepted socket.
 *
 * @param arg Corresponding @c telnet_user_t structure.
 */
static int network_user_fibril(void *arg)
{
	telnet_user_t *user = arg;

	int rc = loc_service_register(user->service_name, &user->service_id);
	if (rc != EOK) {
		telnet_user_error(user, "Unable to register %s with loc: %s.",
		    user->service_name, str_error(rc));
		return EOK;
	}

	telnet_user_log(user, "Service %s registerd with id %" PRIun ".",
	    user->service_name, user->service_id);
	
	fid_t spawn_fibril = fibril_create(spawn_task_fibril, user);
	assert(spawn_fibril);
	fibril_add_ready(spawn_fibril);
	
	/* Wait for all clients to exit. */
	fibril_mutex_lock(&user->guard);
	while (!user_can_be_destroyed_no_lock(user)) {
		if (user->task_finished) {
			closesocket(user->socket);
			user->socket_closed = true;
			user->srvs.aborted = true;
			continue;
		} else if (user->socket_closed) {
			if (user->task_id != 0) {
				task_kill(user->task_id);
			}
		}
		fibril_condvar_wait_timeout(&user->refcount_cv, &user->guard, 1000);
	}
	fibril_mutex_unlock(&user->guard);
	
	rc = loc_service_unregister(user->service_id);
	if (rc != EOK) {
		telnet_user_error(user,
		    "Unable to unregister %s from loc: %s (ignored).",
		    user->service_name, str_error(rc));
	}

	telnet_user_log(user, "Destroying...");
	telnet_user_destroy(user);

	return EOK;
}
/** Starts software periodic polling
 *
 *  Reset to new period if the original period was running
 *
 *  @param nic_data Nic data structure
 */
void nic_sw_period_start(nic_t *nic_data)
{
	/* Create the fibril if it is not crated */
	if (nic_data->sw_poll_info.fibril == 0) {
		nic_data->sw_poll_info.fibril = fibril_create(period_fibril_fun, 
		    nic_data);
		nic_data->sw_poll_info.running = 0;
		nic_data->sw_poll_info.run = 0;

		/* Start fibril */
		fibril_add_ready(nic_data->sw_poll_info.fibril);
	}

	/* Inform fibril about running with new period */
	nic_data->sw_poll_info.run = (nic_data->sw_poll_info.run + 1) % 100;
	nic_data->sw_poll_info.running = 1;
}
Exemple #9
0
void virtual_hub_device_init(ddf_fun_t *hc_dev)
{
	virthub_init(&virtual_hub_device);

	/*
	 * We need to register the root hub.
	 * This must be done in separate fibril because the device
	 * we are connecting to are ourselves and we cannot connect
	 * before leaving the add_device() function.
	 */
	fid_t root_hub_registration
	    = fibril_create(hub_register_in_devman_fibril, hc_dev);
	if (root_hub_registration == 0) {
		usb_log_fatal("Failed to create hub registration fibril.\n");
		return;
	}

	fibril_add_ready(root_hub_registration);
}
static void _fibril_condvar_wakeup_common(fibril_condvar_t *fcv, bool once)
{
	link_t *tmp;
	awaiter_t *wdp;

	futex_down(&async_futex);
	while (!list_empty(&fcv->waiters)) {
		tmp = list_first(&fcv->waiters);
		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
		list_remove(&wdp->wu_event.link);
		wdp->wu_event.inlist = false;
		if (!wdp->active) {
			wdp->active = true;
			fibril_add_ready(wdp->fid);
			optimize_execution_power();
			if (once)
				break;
		}
	}
	futex_up(&async_futex);
}
Exemple #11
0
/** Initialize keyboard driver structure.
 * @param kbd Keyboard driver structure to initialize.
 * @param dev DDF device structure.
 *
 * Connects to parent, creates mouse function, starts polling fibril.
 */
int xt_kbd_init(xt_kbd_t *kbd, ddf_dev_t *dev)
{
    assert(kbd);
    assert(dev);
    kbd->client_sess = NULL;
    kbd->parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE);
    if (!kbd->parent_sess)
        return ENOMEM;

    kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd");
    if (!kbd->kbd_fun) {
        return ENOMEM;
    }
    ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops);

    int ret = ddf_fun_bind(kbd->kbd_fun);
    if (ret != EOK) {
        ddf_fun_destroy(kbd->kbd_fun);
        return ENOMEM;
    }

    ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard");
    if (ret != EOK) {
        ddf_fun_unbind(kbd->kbd_fun);
        ddf_fun_destroy(kbd->kbd_fun);
        return ENOMEM;
    }

    kbd->polling_fibril = fibril_create(polling, kbd);
    if (!kbd->polling_fibril) {
        ddf_fun_unbind(kbd->kbd_fun);
        ddf_fun_destroy(kbd->kbd_fun);
        return ENOMEM;
    }
    fibril_add_ready(kbd->polling_fibril);
    return EOK;
}
static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm)
{
	if (fm->counter++ < 0) {
		link_t *tmp;
		awaiter_t *wdp;
		fibril_t *f;
	
		tmp = list_first(&fm->waiters);
		assert(tmp != NULL);
		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
		wdp->active = true;
		wdp->wu_event.inlist = false;

		f = (fibril_t *) wdp->fid;
		fm->oi.owned_by = f;
		f->waits_for = NULL;

		list_remove(&wdp->wu_event.link);
		fibril_add_ready(wdp->fid);
		optimize_execution_power();
	} else {
		fm->oi.owned_by = NULL;
	}
}
Exemple #13
0
/** Start automatic device polling over interrupt in pipe.
 *
 * @warning It is up to the callback to produce delays between individual
 * requests.
 *
 * @warning There is no guarantee when the request to the device
 * will be sent for the first time (it is possible that this
 * first request would be executed prior to return from this function).
 *
 * @param dev Device to be periodically polled.
 * @param pipe_index Index of the endpoint pipe used for polling.
 * @param callback Callback when data are available.
 * @param request_size How many bytes to ask for in each request.
 * @param terminated_callback Callback when polling is terminated.
 * @param arg Custom argument (passed as is to the callbacks).
 * @return Error code.
 * @retval EOK New fibril polling the device was already started.
 */
int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index,
    usb_polling_callback_t callback, size_t request_size,
    usb_polling_terminted_callback_t terminated_callback, void *arg)
{
	const usb_device_auto_polling_t auto_polling = {
		.debug = 1,
		.auto_clear_halt = true,
		.delay = 0,
		.max_failures = MAX_FAILED_ATTEMPTS,
		.on_data = callback,
		.on_polling_end = terminated_callback,
		.on_error = NULL,
		.arg = arg,
	};

	return usb_device_auto_polling(dev, pipe_index, &auto_polling,
	   request_size);
}

/** Start automatic device polling over interrupt in pipe.
 *
 * The polling settings is copied thus it is okay to destroy the structure
 * after this function returns.
 *
 * @warning There is no guarantee when the request to the device
 * will be sent for the first time (it is possible that this
 * first request would be executed prior to return from this function).
 *
 * @param dev Device to be periodically polled.
 * @param pipe_index Index of the endpoint pipe used for polling.
 * @param polling Polling settings.
 * @param request_size How many bytes to ask for in each request.
 * @param arg Custom argument (passed as is to the callbacks).
 * @return Error code.
 * @retval EOK New fibril polling the device was already started.
 */
int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
    const usb_device_auto_polling_t *polling,
    size_t request_size)
{
	if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
		return EBADMEM;
	}

	if (pipe_index >= dev->pipes_count || request_size == 0) {
		return EINVAL;
	}
	if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT)
	    || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) {
		return EINVAL;
	}

	polling_data_t *polling_data = malloc(sizeof(polling_data_t));
	if (polling_data == NULL) {
		return ENOMEM;
	}

	/* Fill-in the data. */
	polling_data->buffer = malloc(sizeof(request_size));
	if (polling_data->buffer == NULL) {
		free(polling_data);
		return ENOMEM;
	}
	polling_data->request_size = request_size;
	polling_data->dev = dev;
	polling_data->pipe_index = pipe_index;

	/* Copy provided settings. */
	polling_data->auto_polling = *polling;

	/* Negative value means use descriptor provided value. */
	if (polling->delay < 0) {
		polling_data->auto_polling.delay =
		    (int) dev->pipes[pipe_index].descriptor->poll_interval;
	}

	fid_t fibril = fibril_create(polling_fibril, polling_data);
	if (fibril == 0) {
		free(polling_data->buffer);
		free(polling_data);
		return ENOMEM;
	}
	fibril_add_ready(fibril);

	/* Fibril launched. That fibril will free the allocated data. */

	return EOK;
}
static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw)
{
	futex_down(&async_futex);
	if (frw->readers) {
		if (--frw->readers) {
			if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) {
				/*
				 * If this reader firbril was considered the
				 * owner of this rwlock, clear the ownership
				 * information even if there are still more
				 * readers.
				 *
				 * This is the limitation of the detection
				 * mechanism rooted in the fact that tracking
				 * all readers would require dynamically
				 * allocated memory for keeping linkage info.
				 */
				frw->oi.owned_by = NULL;
			}
			goto out;
		}
	} else {
		frw->writers--;
	}
	
	assert(!frw->readers && !frw->writers);
	
	frw->oi.owned_by = NULL;
	
	while (!list_empty(&frw->waiters)) {
		link_t *tmp = list_first(&frw->waiters);
		awaiter_t *wdp;
		fibril_t *f;
		
		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
		f = (fibril_t *) wdp->fid;
		
		f->waits_for = NULL;
		
		if (f->flags & FIBRIL_WRITER) {
			if (frw->readers)
				break;
			wdp->active = true;
			wdp->wu_event.inlist = false;
			list_remove(&wdp->wu_event.link);
			fibril_add_ready(wdp->fid);
			frw->writers++;
			frw->oi.owned_by = f;
			optimize_execution_power();
			break;
		} else {
			wdp->active = true;
			wdp->wu_event.inlist = false;
			list_remove(&wdp->wu_event.link);
			fibril_add_ready(wdp->fid);
			if (frw->readers++ == 0) {
				/* Consider the first reader the owner. */
				frw->oi.owned_by = f;
			}
			optimize_execution_power();
		}
	}
out:
	futex_up(&async_futex);
}
Exemple #15
0
int main(int argc, char *argv[])
{
	int port = 2223;
	
	async_set_client_connection(client_connection);
	int rc = loc_server_register(NAME);
	if (rc != EOK) {
		fprintf(stderr, "%s: Unable to register server\n", NAME);
		return rc;
	}
	
	struct sockaddr_in addr;
	
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	
	rc = inet_pton(AF_INET, "127.0.0.1", (void *)
	    &addr.sin_addr.s_addr);
	if (rc != EOK) {
		fprintf(stderr, "Error parsing network address: %s.\n",
		    str_error(rc));
		return 2;
	}

	int listen_sd = socket(PF_INET, SOCK_STREAM, 0);
	if (listen_sd < 0) {
		fprintf(stderr, "Error creating listening socket: %s.\n",
		    str_error(listen_sd));
		return 3;
	}

	rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
	if (rc != EOK) {
		fprintf(stderr, "Error binding socket: %s.\n",
		    str_error(rc));
		return 4;
	}

	rc = listen(listen_sd, BACKLOG_SIZE);
	if (rc != EOK) {
		fprintf(stderr, "listen() failed: %s.\n", str_error(rc));
		return 5;
	}

	printf("%s: HelenOS Remote console service\n", NAME);
	task_retval(0);

	while (true) {
		struct sockaddr_in raddr;
		socklen_t raddr_len = sizeof(raddr);
		int conn_sd = accept(listen_sd, (struct sockaddr *) &raddr,
		    &raddr_len);

		if (conn_sd < 0) {
			fprintf(stderr, "accept() failed: %s.\n",
			    str_error(rc));
			continue;
		}

		telnet_user_t *user = telnet_user_create(conn_sd);
		assert(user);

		con_srvs_init(&user->srvs);
		user->srvs.ops = &con_ops;
		user->srvs.sarg = user;
		user->srvs.abort_timeout = 1000;

		telnet_user_add(user);

		fid_t fid = fibril_create(network_user_fibril, user);
		assert(fid);
		fibril_add_ready(fid);
	}

	return 0;
}
Exemple #16
0
static void tcp_sock_accept(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
{
	ipc_call_t answer;
	int socket_id;
	int asock_id;
	socket_core_t *sock_core;
	tcp_sockdata_t *socket;
	tcp_sockdata_t *asocket;
	tcp_error_t trc;
	tcp_sock_t lsocket;
	tcp_sock_t fsocket;
	tcp_conn_t *conn;
	tcp_conn_t *rconn;
	tcp_sock_lconn_t *lconn;
	int rc;

	log_msg(LVL_DEBUG, "tcp_sock_accept()");

	socket_id = SOCKET_GET_SOCKET_ID(call);
	asock_id = SOCKET_GET_NEW_SOCKET_ID(call);

	sock_core = socket_cores_find(&client->sockets, socket_id);
	if (sock_core == NULL) {
		async_answer_0(callid, ENOTSOCK);
		return;
	}

	socket = (tcp_sockdata_t *)sock_core->specific_data;
	fibril_mutex_lock(&socket->lock);

	log_msg(LVL_DEBUG, " - verify socket->conn");
	if (socket->conn != NULL) {
		fibril_mutex_unlock(&socket->lock);
		async_answer_0(callid, EINVAL);
		return;
	}

	if (list_empty(&socket->ready)) {
		fibril_mutex_unlock(&socket->lock);
		async_answer_0(callid, ENOENT);
		return;
	}

	lconn = list_get_instance(list_first(&socket->ready),
	    tcp_sock_lconn_t, ready_list);
	list_remove(&lconn->ready_list);

	conn = lconn->conn;
	tcp_uc_set_cstate_cb(conn, NULL, NULL);

	/* Replenish listening connection */

	lsocket.addr.ipv4 = TCP_IPV4_ANY;
	lsocket.port = sock_core->port;
	fsocket.addr.ipv4 = TCP_IPV4_ANY;
	fsocket.port = TCP_PORT_ANY;

	trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, tcp_open_nonblock,
	    &rconn);
	if (rconn == NULL) {
		/* XXX Clean up */
		fibril_mutex_unlock(&socket->lock);
		async_answer_0(callid, ENOMEM);
		return;
	}

	tcp_uc_set_cstate_cb(rconn, tcp_sock_cstate_cb, lconn);

	assert(trc == TCP_EOK);
	rconn->name = (char *)"S";

	lconn->conn = rconn;

	/* Allocate socket for accepted connection */

	rc = tcp_sock_create(client, &asocket);
	if (rc != EOK) {
		fibril_mutex_unlock(&socket->lock);
		async_answer_0(callid, rc);
		return;
	}

	asocket->conn = conn;
	log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n");

	rc = tcp_sock_finish_setup(asocket, &asock_id);
	if (rc != EOK) {
		tcp_sock_uncreate(asocket);
		fibril_mutex_unlock(&socket->lock);
		async_answer_0(callid, rc);
		return;
	}

	fibril_add_ready(asocket->recv_fibril);

	log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n");

	SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
	SOCKET_SET_SOCKET_ID(answer, asock_id);
	SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in));
	
	async_answer_3(callid, asocket->sock_core->socket_id,
	    IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
	    IPC_GET_ARG3(answer));
	
	/* Push one fragment notification to client's queue */
	log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n");
	fibril_mutex_unlock(&socket->lock);
}
Exemple #17
0
static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
{
	int rc;
	struct sockaddr_in *addr;
	int socket_id;
	size_t addr_len;
	socket_core_t *sock_core;
	tcp_sockdata_t *socket;
	tcp_error_t trc;
	tcp_sock_t lsocket;
	tcp_sock_t fsocket;

	log_msg(LVL_DEBUG, "tcp_sock_connect()");

	rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len);
	if (rc != EOK || addr_len != sizeof(struct sockaddr_in)) {
		async_answer_0(callid, rc);
		return;
	}

	socket_id = SOCKET_GET_SOCKET_ID(call);

	sock_core = socket_cores_find(&client->sockets, socket_id);
	if (sock_core == NULL) {
		async_answer_0(callid, ENOTSOCK);
		return;
	}

	socket = (tcp_sockdata_t *)sock_core->specific_data;
	if (sock_core->port <= 0) {
		rc = socket_bind_free_port(&gsock, sock_core,
		    TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
		    last_used_port);
		if (rc != EOK) {
			async_answer_0(callid, rc);
			return;
		}

		last_used_port = sock_core->port;
	}

	fibril_mutex_lock(&socket->lock);

	if (socket->laddr.ipv4 == TCP_IPV4_ANY) {
		/* Determine local IP address */
		inet_addr_t loc_addr, rem_addr;

		rem_addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
		rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
		if (rc != EOK) {
			fibril_mutex_unlock(&socket->lock);
			async_answer_0(callid, rc);
			log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to "
			    "determine local address.");
			return;
		}

		socket->laddr.ipv4 = loc_addr.ipv4;
		log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4);
	}

	lsocket.addr.ipv4 = socket->laddr.ipv4;
	lsocket.port = sock_core->port;
	fsocket.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
	fsocket.port = uint16_t_be2host(addr->sin_port);

	trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn);

	if (socket->conn != NULL)
		socket->conn->name = (char *)"C";

	fibril_mutex_unlock(&socket->lock);

	switch (trc) {
	case TCP_EOK:
		rc = EOK;
		break;
	case TCP_ERESET:
		rc = ECONNREFUSED;
		break;
	default:
		assert(false);
	}

	if (rc == EOK)
		fibril_add_ready(socket->recv_fibril);

	async_answer_0(callid, rc);
}
Exemple #18
0
int main(int argc, char *argv[])
{
	int rc;
	int argi;

	rc = inetping_init(&ev_ops);
	if (rc != EOK) {
		printf(NAME ": Failed connecting to internet ping service "
		    "(%d).\n", rc);
		return 1;
	}

	argi = 1;
	if (argi < argc && str_cmp(argv[argi], "-r") == 0) {
		ping_repeat = true;
		++argi;
	} else {
		ping_repeat = false;
	}

	if (argc - argi != 1) {
		print_syntax();
		return 1;
	}

	/* Parse destination address */
	rc = addr_parse(argv[argi], &dest_addr);
	if (rc != EOK) {
		printf(NAME ": Invalid address format.\n");
		print_syntax();
		return 1;
	}

	/* Determine source address */
	rc = inetping_get_srcaddr(&dest_addr, &src_addr);
	if (rc != EOK) {
		printf(NAME ": Failed determining source address.\n");
		return 1;
	}

	fid_t fid;

	if (ping_repeat) {
		fid = fibril_create(transmit_fibril, NULL);
		if (fid == 0) {
			printf(NAME ": Failed creating transmit fibril.\n");
			return 1;
		}

		fibril_add_ready(fid);

		fid = fibril_create(input_fibril, NULL);
		if (fid == 0) {
			printf(NAME ": Failed creating input fibril.\n");
			return 1;
		}

		fibril_add_ready(fid);
	} else {
		ping_send(1);
	}

	fibril_mutex_lock(&done_lock);
	rc = EOK;
	while (!done && rc != ETIMEOUT) {
		rc = fibril_condvar_wait_timeout(&done_cv, &done_lock,
			ping_repeat ? 0 : PING_TIMEOUT);
	}
	fibril_mutex_unlock(&done_lock);

	if (rc == ETIMEOUT) {
		printf(NAME ": Echo request timed out.\n");
		return 1;
	}

	return 0;
}
Exemple #19
0
int main(int argc, char **argv)
{
	sysarg_t baud = 38400;
	service_id_t svc_id;
	char *serial_port_name = NULL;

	int arg = 1;
	int rc;

	isdv4_event_fn event_fn = emit_event;

	if (argc > arg && str_test_prefix(argv[arg], "--baud=")) {
		size_t arg_offset = str_lsize(argv[arg], 7);
		char* arg_str = argv[arg] + arg_offset;
		if (str_length(arg_str) == 0) {
			fprintf(stderr, "--baud requires an argument\n");
			syntax_print();
			return 1;
		}
		char *endptr;
		baud = strtol(arg_str, &endptr, 10);
		if (*endptr != '\0') {
			fprintf(stderr, "Invalid value for baud\n");
			syntax_print();
			return 1;
		}
		arg++;
	}

	if (argc > arg && str_cmp(argv[arg], "--print-events") == 0) {
		event_fn = print_and_emit_event;
		arg++;
	}

	if (argc > arg) {
		serial_port_name = argv[arg];
		rc = loc_service_get_id(serial_port_name, &svc_id, 0);
		if (rc != EOK) {
			fprintf(stderr, "Cannot find device service %s\n",
			    argv[arg]);
			return 1;
		}
		arg++;
	}
	else {
		category_id_t serial_cat_id;

		rc = loc_category_get_id("serial", &serial_cat_id, 0);
		if (rc != EOK) {
			fprintf(stderr, "Failed getting id of category "
			    "'serial'\n");
			return 1;
		}

		service_id_t *svc_ids;
		size_t svc_count;

		rc = loc_category_get_svcs(serial_cat_id, &svc_ids, &svc_count);		if (rc != EOK) {
			fprintf(stderr, "Failed getting list of services\n");
			return 1;
		}

		if (svc_count == 0) {
			fprintf(stderr, "No service in category 'serial'\n");
			free(svc_ids);
			return 1;
		}

		svc_id = svc_ids[0];

		rc = loc_service_get_name(svc_id, &serial_port_name);
		if (rc != EOK) {
			fprintf(stderr, "Failed getting name of serial service\n");
			return 1;
		}

		free(svc_ids);
	}

	if (argc > arg) {
		fprintf(stderr, "Too many arguments\n");
		syntax_print();
		return 1;
	}

	fibril_mutex_initialize(&client_mutex);

	printf(NAME ": Using serial port %s\n", serial_port_name);

	async_sess_t *sess = loc_service_connect(svc_id, INTERFACE_DDF,
	    IPC_FLAG_BLOCKING);
	if (!sess) {
		fprintf(stderr, "Failed connecting to service\n");
	}

	async_exch_t *exch = async_exchange_begin(sess);
	rc = async_req_4_0(exch, SERIAL_SET_COM_PROPS, baud,
	    SERIAL_NO_PARITY, 8, 1);
	async_exchange_end(exch);

	if (rc != EOK) {
		fprintf(stderr, "Failed setting serial properties\n");
		return 2;
	}

	rc = isdv4_init(&state, sess, event_fn);
	if (rc != EOK) {
		fprintf(stderr, "Failed initializing isdv4 state");
		return 2;
	}

	rc = isdv4_init_tablet(&state);
	if (rc != EOK) {
		fprintf(stderr, "Failed initializing tablet");
		return 2;
	}

	printf("Tablet information:\n");
	printf(" Stylus: %ux%u pressure: %u tilt: ", state.stylus_max_x,
	    state.stylus_max_y, state.stylus_max_pressure);
	if (state.stylus_tilt_supported) {
		printf("%ux%u\n", state.stylus_max_xtilt, state.stylus_max_ytilt);
	}
	else {
		printf("not supported\n");
	}
	printf(" Touch: %ux%u type: %s\n", state.touch_max_x, state.touch_max_y,
		touch_type(state.touch_type));
	
	fid_t fibril = fibril_create(read_fibril, NULL);
	/* From this on, state is to be used only by read_fibril */
	fibril_add_ready(fibril);

	async_set_fallback_port_handler(mouse_connection, NULL);
	rc = loc_server_register(NAME);
	if (rc != EOK) {
		printf("%s: Unable to register driver.\n", NAME);
		return rc;
	}

	service_id_t service_id;
	char *service_name;
	rc = asprintf(&service_name, "mouse/isdv4-%" PRIun, svc_id);
	if (rc < 0) {
		printf(NAME ": Unable to create service name\n");
		return rc;
	}

	rc = loc_service_register(service_name, &service_id);
	if (rc != EOK) {
		printf(NAME ": Unable to register service %s.\n", service_name);
		return rc;
	}

	category_id_t mouse_category;
	rc = loc_category_get_id("mouse", &mouse_category, IPC_FLAG_BLOCKING);
	if (rc != EOK) {
		printf(NAME ": Unable to get mouse category id.\n");
	}
	else {
		rc = loc_service_add_to_cat(service_id, mouse_category);
		if (rc != EOK) {
			printf(NAME ": Unable to add device to mouse category.\n");
		}
	}

	printf("%s: Accepting connections\n", NAME);
	task_retval(0);
	async_manager();

	/* Not reached */
	return 0;
}
Exemple #20
0
static void udp_sock_socket(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
{
	udp_sockdata_t *sock;
	socket_core_t *sock_core;
	int sock_id;
	int rc;
	ipc_call_t answer;

	log_msg(LVL_DEBUG, "udp_sock_socket()");
	sock = calloc(sizeof(udp_sockdata_t), 1);
	if (sock == NULL) {
		async_answer_0(callid, ENOMEM);
		return;
	}

	fibril_mutex_initialize(&sock->lock);
	sock->client = client;

	sock->recv_buffer_used = 0;
	sock->recv_error = UDP_EOK;
	fibril_mutex_initialize(&sock->recv_buffer_lock);
	fibril_condvar_initialize(&sock->recv_buffer_cv);

	rc = udp_uc_create(&sock->assoc);
	if (rc != EOK) {
		free(sock);
		async_answer_0(callid, rc);
		return;
	}

	sock->recv_fibril = fibril_create(udp_sock_recv_fibril, sock);
	if (sock->recv_fibril == 0) {
		udp_uc_destroy(sock->assoc);
		free(sock);
		async_answer_0(callid, ENOMEM);
		return;
	}

	sock_id = SOCKET_GET_SOCKET_ID(call);
	rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
	if (rc != EOK) {
		fibril_destroy(sock->recv_fibril);
		udp_uc_destroy(sock->assoc);
		free(sock);
		async_answer_0(callid, rc);
		return;
	}

	fibril_add_ready(sock->recv_fibril);

	sock_core = socket_cores_find(&client->sockets, sock_id);
	assert(sock_core != NULL);
	sock->sock_core = sock_core;
	
	SOCKET_SET_SOCKET_ID(answer, sock_id);

	SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE);
	SOCKET_SET_HEADER_SIZE(answer, sizeof(udp_header_t));
	async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
	    IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
}