示例#1
0
static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
{
	int rc = EOK;

	if (!IPC_GET_RETVAL(answer->data)) {
		/* The recipient authorized the change of state. */
		phone_t *recipient_phone;
		task_t *other_task_s;
		task_t *other_task_r;

		rc = phone_get(IPC_GET_ARG1(answer->data),
		    &recipient_phone);
		if (rc != EOK) {
			IPC_SET_RETVAL(answer->data, ENOENT);
			return ENOENT;
		}

		mutex_lock(&recipient_phone->lock);
		if (recipient_phone->state != IPC_PHONE_CONNECTED) {
			mutex_unlock(&recipient_phone->lock);
			IPC_SET_RETVAL(answer->data, EINVAL);
			return EINVAL;
		}

		other_task_r = recipient_phone->callee->task;
		other_task_s = (task_t *) IPC_GET_ARG5(*olddata);

		/*
		 * See if both the sender and the recipient meant the
		 * same third party task.
		 */
		if (other_task_r != other_task_s) {
			IPC_SET_RETVAL(answer->data, EINVAL);
			rc = EINVAL;
		} else {
			rc = event_task_notify_5(other_task_r,
			    EVENT_TASK_STATE_CHANGE, false,
			    IPC_GET_ARG1(*olddata),
			    IPC_GET_ARG2(*olddata),
			    IPC_GET_ARG3(*olddata),
			    LOWER32(olddata->task_id),
			    UPPER32(olddata->task_id));
			IPC_SET_RETVAL(answer->data, rc);
		}

		mutex_unlock(&recipient_phone->lock);
	}

	return rc;
}
示例#2
0
static int loc_category_get_ids_once(sysarg_t method, sysarg_t arg1,
    sysarg_t *id_buf, size_t buf_size, size_t *act_size)
{
	async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);

	ipc_call_t answer;
	aid_t req = async_send_1(exch, method, arg1, &answer);
	int rc = async_data_read_start(exch, id_buf, buf_size);
	
	loc_exchange_end(exch);
	
	if (rc != EOK) {
		async_forget(req);
		return rc;
	}
	
	sysarg_t retval;
	async_wait_for(req, &retval);
	
	if (retval != EOK) {
		return retval;
	}
	
	*act_size = IPC_GET_ARG1(answer);
	return EOK;
}
示例#3
0
/** Register new service.
 *
 * The @p interface is used when forwarding connection to the server.
 * If not 0, the first argument is the interface and the second argument
 * is the service ID.
 *
 * When the interface is zero (default), the first argument is directly
 * the handle (to ensure backward compatibility).
 *
 * @param      fqsn      Fully qualified service name
 * @param[out] sid       Service ID of new service
 * @param      interface Interface when forwarding
 *
 */
int loc_service_register_with_iface(const char *fqsn,
    service_id_t *sid, sysarg_t interface)
{
	async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER);
	
	ipc_call_t answer;
	aid_t req = async_send_2(exch, LOC_SERVICE_REGISTER, interface, 0,
	    &answer);
	sysarg_t retval = async_data_write_start(exch, fqsn, str_size(fqsn));
	
	loc_exchange_end(exch);
	
	if (retval != EOK) {
		async_forget(req);
		return retval;
	}
	
	async_wait_for(req, &retval);
	
	if (retval != EOK) {
		if (sid != NULL)
			*sid = -1;
		
		return retval;
	}
	
	if (sid != NULL)
		*sid = (service_id_t) IPC_GET_ARG1(answer);
	
	return retval;
}
示例#4
0
文件: adb.c 项目: jvesely/helenos
static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	/* Ignore parameters, the connection is already opened */
	while (true) {

		ipc_call_t call;
		ipc_callid_t callid = async_get_call(&call);

		int retval = EOK;
		
		if (!IPC_GET_IMETHOD(call)) {
			/* TODO: Handle hangup */
			return;
		}
		
		switch (IPC_GET_IMETHOD(call)) {
		case ADB_REG_NOTIF:
			adb_kbd_reg0_data(IPC_GET_ARG1(call));
			break;
		default:
			retval = ENOENT;
		}
		async_answer_0(callid, retval);
	}
}
示例#5
0
文件: apic.c 项目: jvesely/helenos
/** Handle one connection to APIC.
 *
 * @param iid   Hash of the request that opened the connection.
 * @param icall Call data of the request that opened the connection.
 * @param arg	Local argument.
 */
static void apic_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	ipc_callid_t callid;
	ipc_call_t call;
	
	/*
	 * Answer the first IPC_M_CONNECT_ME_TO call.
	 */
	async_answer_0(iid, EOK);
	
	while (true) {
		callid = async_get_call(&call);
		
		if (!IPC_GET_IMETHOD(call)) {
			/* The other side has hung up. */
			async_answer_0(callid, EOK);
			return;
		}
		
		switch (IPC_GET_IMETHOD(call)) {
		case IRC_ENABLE_INTERRUPT:
			async_answer_0(callid, apic_enable_irq(IPC_GET_ARG1(call)));
			break;
		case IRC_CLEAR_INTERRUPT:
			/* Noop */
			async_answer_0(callid, EOK);
			break;
		default:
			async_answer_0(callid, EINVAL);
			break;
		}
	}
}
示例#6
0
static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
{
	tcp_sockdata_t *sock;
	int sock_id;
	int rc;
	ipc_call_t answer;

	log_msg(LVL_DEBUG, "tcp_sock_socket()");

	rc = tcp_sock_create(client, &sock);
	if (rc != EOK) {
		async_answer_0(callid, rc);
		return;
	}

	sock->laddr.ipv4 = TCP_IPV4_ANY;
	sock->lconn = NULL;
	sock->backlog = 0;

	sock_id = SOCKET_GET_SOCKET_ID(call);
	rc = tcp_sock_finish_setup(sock, &sock_id);
	if (rc != EOK) {
		tcp_sock_uncreate(sock);
		async_answer_0(callid, rc);
		return;
	}

	SOCKET_SET_SOCKET_ID(answer, sock_id);

	SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
	SOCKET_SET_HEADER_SIZE(answer, sizeof(tcp_header_t));
	
	async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
	    IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
}
示例#7
0
static void kbdev_callback_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	kbdev_t *kbdev;
	int retval;
	int type, key;

	/* Kbdev device structure */
	kbdev = arg;

	while (true) {
		ipc_call_t call;
		ipc_callid_t callid;

		callid = async_get_call(&call);
		if (!IPC_GET_IMETHOD(call)) {
			kbdev_destroy(kbdev);
			return;
		}

		switch (IPC_GET_IMETHOD(call)) {
		case KBDEV_EVENT:
			/* Got event from keyboard device */
			retval = 0;
			type = IPC_GET_ARG1(call);
			key = IPC_GET_ARG2(call);
			kbd_push_event(kbdev->kbd_dev, type, key);
			break;
		default:
			retval = ENOTSUP;
			break;
		}

		async_answer_0(callid, retval);
	}
}
示例#8
0
文件: vbd.c 项目: jvesely/helenos
int vbd_part_create(vbd_t *vbd, service_id_t disk, vbd_part_spec_t *pspec,
    vbd_part_id_t *rpart)
{
	async_exch_t *exch;
	sysarg_t retval;
	ipc_call_t answer;

	exch = async_exchange_begin(vbd->sess);
	aid_t req = async_send_1(exch, VBD_PART_CREATE, disk, &answer);
	int rc = async_data_write_start(exch, pspec, sizeof(vbd_part_spec_t));
	async_exchange_end(exch);

	if (rc != EOK) {
		async_forget(req);
		return EIO;
	}

	async_wait_for(req, &retval);
	if (retval != EOK)
		return EIO;

	*rpart = (vbd_part_id_t)IPC_GET_ARG1(answer);
	return EOK;

}
示例#9
0
/** Add new Wake-On-LAN virtue.
 *
 * @param[in]  dev_sess
 * @param[in]  type     Type of the virtue
 * @param[in]  data     Data required for this virtue
 *                      (depends on type)
 * @param[in]  length   Length of the data
 * @param[out] id       Identifier of the new virtue
 *
 * @return EOK If the operation was successfully completed
 *
 */
int nic_wol_virtue_add(async_sess_t *dev_sess, nic_wv_type_t type,
    const void *data, size_t length, nic_wv_id_t *id)
{
	assert(id);
	
	bool send_data = ((data != NULL) && (length != 0));
	async_exch_t *exch = async_exchange_begin(dev_sess);
	
	ipc_call_t result;
	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
	    NIC_WOL_VIRTUE_ADD, (sysarg_t) type, send_data, &result);
	
	sysarg_t res;
	if (send_data) {
		int rc = async_data_write_start(exch, data, length);
		if (rc != EOK) {
			async_exchange_end(exch);
			async_wait_for(message_id, &res);
			return rc;
		}
	}
	
	async_exchange_end(exch);
	async_wait_for(message_id, &res);
	
	*id = IPC_GET_ARG1(result);
	return (int) res;
}
示例#10
0
文件: udp.c 项目: jvesely/helenos
/** Get information about the next received message from UDP service.
 *
 * @param udp  UDP client
 * @param rmsg Place to store message information
 *
 * @return EOK on success or negative error code
 */
static int udp_rmsg_info(udp_t *udp, udp_rmsg_t *rmsg)
{
	async_exch_t *exch;
	inet_ep_t ep;
	ipc_call_t answer;

	exch = async_exchange_begin(udp->sess);
	aid_t req = async_send_0(exch, UDP_RMSG_INFO, &answer);
	int rc = async_data_read_start(exch, &ep, sizeof(inet_ep_t));
	async_exchange_end(exch);

	if (rc != EOK) {
		async_forget(req);
		return rc;
	}

	sysarg_t retval;
	async_wait_for(req, &retval);
	if (retval != EOK)
		return retval;

	rmsg->udp = udp;
	rmsg->assoc_id = IPC_GET_ARG1(answer);
	rmsg->size = IPC_GET_ARG2(answer);
	rmsg->remote_ep = ep;
	return EOK;
}
示例#11
0
文件: vbd.c 项目: jvesely/helenos
/** Get list of IDs into a buffer of fixed size.
 *
 * @param vbd      Virtual Block Device
 * @param method   IPC method
 * @param arg1     First argument
 * @param id_buf   Buffer to store IDs
 * @param buf_size Buffer size
 * @param act_size Place to store actual size of complete data.
 *
 * @return EOK on success or negative error code.
 */
static int vbd_get_ids_once(vbd_t *vbd, sysarg_t method, sysarg_t arg1,
    sysarg_t *id_buf, size_t buf_size, size_t *act_size)
{
	async_exch_t *exch = async_exchange_begin(vbd->sess);

	ipc_call_t answer;
	aid_t req = async_send_1(exch, method, arg1, &answer);
	int rc = async_data_read_start(exch, id_buf, buf_size);

	async_exchange_end(exch);

	if (rc != EOK) {
		async_forget(req);
		return rc;
	}

	sysarg_t retval;
	async_wait_for(req, &retval);

	if (retval != EOK) {
		return retval;
	}

	*act_size = IPC_GET_ARG1(answer);
	return EOK;
}
示例#12
0
/** Handle data requests.
 *
 * @param fun  ddf_fun_t function.
 * @param id   callid
 * @param call IPC request.
 *
 */
void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call)
{
    const sysarg_t method = IPC_GET_IMETHOD(*call);
    const size_t size = IPC_GET_ARG1(*call);

    switch (method) {
    case IPC_CHAR_READ:
        if (size <= 4 * sizeof(sysarg_t)) {
            sysarg_t message[4] = {};

            i8042_read(fun, (char *) message, size);
            async_answer_4(id, size, message[0], message[1],
                           message[2], message[3]);
        } else
            async_answer_0(id, ELIMIT);
        break;

    case IPC_CHAR_WRITE:
        if (size <= 3 * sizeof(sysarg_t)) {
            const sysarg_t message[3] = {
                IPC_GET_ARG2(*call),
                IPC_GET_ARG3(*call),
                IPC_GET_ARG4(*call)
            };

            i8042_write(fun, (char *) message, size);
            async_answer_0(id, size);
        } else
            async_answer_0(id, ELIMIT);

    default:
        async_answer_0(id, EINVAL);
    }
}
示例#13
0
文件: xtkbd.c 项目: jvesely/helenos
/** Default handler for IPC methods not handled by DDF.
 *
 * @param fun     Device function handling the call.
 * @param icallid Call id.
 * @param icall   Call data.
 *
 */
static void default_connection_handler(ddf_fun_t *fun,
    ipc_callid_t icallid, ipc_call_t *icall)
{
	const sysarg_t method = IPC_GET_IMETHOD(*icall);
	xt_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun));

	switch (method) {
	case KBDEV_SET_IND: {
		/*
		 * XT keyboards do not support setting mods,
		 * assume AT keyboard with Scan Code Set 1.
		 */
		const unsigned mods = IPC_GET_ARG1(*icall);
		const uint8_t status = 0 |
		    ((mods & KM_CAPS_LOCK) ? LI_CAPS : 0) |
		    ((mods & KM_NUM_LOCK) ? LI_NUM : 0) |
		    ((mods & KM_SCROLL_LOCK) ? LI_SCROLL : 0);
		uint8_t cmds[] = { KBD_CMD_SET_LEDS, status };
		
		async_exch_t *exch = async_exchange_begin(kbd->parent_sess);
		const ssize_t size = chardev_write(exch, cmds, sizeof(cmds));
		async_exchange_end(exch);
		
		async_answer_0(icallid, size < 0 ? size : EOK);
		break;
	}
	/*
	 * This might be ugly but async_callback_receive_start makes no
	 * difference for incorrect call and malloc failure.
	 */
	case IPC_M_CONNECT_TO_ME: {
		async_sess_t *sess =
		    async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
		
		/* Probably ENOMEM error, try again. */
		if (sess == NULL) {
			ddf_msg(LVL_WARN,
			    "Failed creating callback session");
			async_answer_0(icallid, EAGAIN);
			break;
		}
		
		if (kbd->client_sess == NULL) {
			kbd->client_sess = sess;
			ddf_msg(LVL_DEBUG, "Set client session");
			async_answer_0(icallid, EOK);
		} else {
			ddf_msg(LVL_ERROR, "Client session already set");
			async_answer_0(icallid, ELIMIT);
		}
		
		break;
	}
	default:
		ddf_msg(LVL_ERROR, "Unknown method: %d.", (int)method);
		async_answer_0(icallid, EINVAL);
		break;
	}
}
示例#14
0
/** Character device connection handler */
static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	ipc_callid_t callid;
	ipc_call_t call;
	sysarg_t method;
	service_id_t dsid;
	int dev_addr, i;

	/* Get the device handle. */
	dsid = IPC_GET_ARG1(*icall);

	/* Determine which disk device is the client connecting to. */
	dev_addr = -1;
	for (i = 0; i < ADB_MAX_ADDR; i++) {
		if (adb_dev[i].service_id == dsid)
			dev_addr = i;
	}

	if (dev_addr < 0) {
		async_answer_0(iid, EINVAL);
		return;
	}

	/* Answer the IPC_M_CONNECT_ME_TO call. */
	async_answer_0(iid, EOK);

	while (true) {
		callid = async_get_call(&call);
		method = IPC_GET_IMETHOD(call);
		
		if (!method) {
			/* The other side has hung up. */
			async_answer_0(callid, EOK);
			return;
		}
		
		async_sess_t *sess =
		    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
		if (sess != NULL) {
			if (adb_dev[dev_addr].client_sess == NULL) {
				adb_dev[dev_addr].client_sess = sess;
				
				/*
				 * A hack so that we send the data to the session
				 * regardless of which address the device is on.
				 */
				for (i = 0; i < ADB_MAX_ADDR; ++i) {
					if (adb_dev[i].service_id == dsid)
						adb_dev[i].client_sess = sess;
				}
				
				async_answer_0(callid, EOK);
			} else
				async_answer_0(callid, ELIMIT);
		} else
			async_answer_0(callid, EINVAL);
	}
}
示例#15
0
static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t callid,
    ipc_call_t *call)
{
	int rc;
	iplink_srv_addr_t addr;

	addr.ipv4 = IPC_GET_ARG1(*call);

	rc = srv->ops->addr_remove(srv, &addr);
	async_answer_0(callid, rc);
}
示例#16
0
/** Callback when client connects to a telnet terminal. */
static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	/* Find the user. */
	telnet_user_t *user = telnet_user_get_for_client_connection(IPC_GET_ARG1(*icall));
	if (user == NULL) {
		async_answer_0(iid, ENOENT);
		return;
	}

	/* Handle messages. */
	con_conn(iid, icall, &user->srvs);
}
示例#17
0
/** Interrupt handler routine.
 *
 * Write new data to the corresponding buffer.
 *
 * @param dev  Device that caued the interrupt.
 * @param iid  Call id.
 * @param call pointerr to call data.
 *
 */
static void i8042_irq_handler(ddf_dev_t *dev, ipc_callid_t iid,
                              ipc_call_t *call)
{
    i8042_t *controller = dev_i8042(dev);

    const uint8_t status = IPC_GET_ARG1(*call);
    const uint8_t data = IPC_GET_ARG2(*call);

    buffer_t *buffer = (status & i8042_AUX_DATA) ?
                       &controller->aux_buffer : &controller->kbd_buffer;

    buffer_write(buffer, data);
}
示例#18
0
static void notification_received(ipc_callid_t callid, ipc_call_t *call)
{
	switch (IPC_GET_IMETHOD(*call)) {
	case VFS_TASK_STATE_CHANGE:
		if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
			vfs_pass_handle(
			    (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
			    IPC_GET_ARG5(*call)), call->in_task_id,
			    (int) IPC_GET_ARG2(*call));
		break;
	default:
		break;
	}
}
示例#19
0
/** Forward a received call to another destination - slow version.
 *
 * This function is the slow verision of the sys_ipc_forward_fast interface.
 * It can copy all five new arguments and the new interface and method from
 * the userspace. It naturally extends the functionality of the fast version.
 * For system methods, it additionally stores the new value of arg3 to ARG4.
 * For non-system methods, it additionally stores the new value of arg3, arg4
 * and arg5, respectively, to ARG3, ARG4 and ARG5, respectively.
 *
 * @param callid  Hash of the call to forward.
 * @param phoneid Phone handle to use for forwarding.
 * @param data    Userspace address of the new IPC data.
 * @param mode    Flags that specify mode of the forward operation.
 *
 * @return 0 on succes, otherwise an error code.
 *
 */
sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t phoneid,
    ipc_data_t *data, unsigned int mode)
{
	ipc_data_t newdata;
	int rc = copy_from_uspace(&newdata.args, &data->args,
	    sizeof(newdata.args));
	if (rc != 0)
		return (sysarg_t) rc;
	
	return sys_ipc_forward_common(callid, phoneid,
	    IPC_GET_IMETHOD(newdata), IPC_GET_ARG1(newdata),
	    IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata),
	    IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true); 
}
示例#20
0
static void ethip_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	ethip_nic_t *nic;
	service_id_t sid;

	sid = (service_id_t)IPC_GET_ARG1(*icall);
	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_client_conn(%u)", (unsigned)sid);
	nic = ethip_nic_find_by_iplink_sid(sid);
	if (nic == NULL) {
		log_msg(LOG_DEFAULT, LVL_WARN, "Uknown service ID.");
		return;
	}

	iplink_conn(iid, icall, &nic->iplink);
}
示例#21
0
static void connection_handler(ipc_callid_t iid, ipc_call_t *icall, void *arg)
{
	logger_interface_t iface = IPC_GET_ARG1(*icall);

	switch (iface) {
	case LOGGER_INTERFACE_CONTROL:
		logger_connection_handler_control(iid);
		break;
	case LOGGER_INTERFACE_WRITER:
		logger_connection_handler_writer(iid);
		break;
	default:
		async_answer_0(iid, EINVAL);
		break;
	}
}
示例#22
0
/** Close the file in the endpoint FS server. */
static int vfs_file_close_remote(vfs_file_t *file)
{
	assert(!file->refcnt);
	
	async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
	
	ipc_call_t answer;
	aid_t msg = async_send_2(exch, VFS_OUT_CLOSE, file->node->service_id,
	    file->node->index, &answer);
	
	vfs_exchange_release(exch);
	
	sysarg_t rc;
	async_wait_for(msg, &rc);
	
	return IPC_GET_ARG1(answer);
}
示例#23
0
static void inet_ev_recv(ipc_callid_t callid, ipc_call_t *call)
{
	int rc;
	inet_dgram_t dgram;

	dgram.src.ipv4 = IPC_GET_ARG1(*call);
	dgram.dest.ipv4 = IPC_GET_ARG2(*call);
	dgram.tos = IPC_GET_ARG3(*call);

	rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, &dgram.size);
	if (rc != EOK) {
		async_answer_0(callid, rc);
		return;
	}

	rc = inet_ev_ops->recv(&dgram);
	async_answer_0(callid, rc);
}
示例#24
0
static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t callid,
    ipc_call_t *call)
{
	iplink_srv_sdu_t sdu;
	int rc;

	sdu.lsrc.ipv4 = IPC_GET_ARG1(*call);
	sdu.ldest.ipv4 = IPC_GET_ARG2(*call);

	rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
	if (rc != EOK) {
		async_answer_0(callid, rc);
		return;
	}

	rc = srv->ops->send(srv, &sdu);
	free(sdu.data);
	async_answer_0(callid, rc);
}
示例#25
0
imagemap_handle_t fb_imagemap_create(async_sess_t *sess, imgmap_t *imgmap)
{
    async_exch_t *exch = async_exchange_begin(sess);

    ipc_call_t answer;
    aid_t req = async_send_0(exch, FB_IMAGEMAP_CREATE, &answer);
    int rc = async_share_out_start(exch, imgmap, AS_AREA_READ
                                   | AS_AREA_WRITE | AS_AREA_CACHEABLE);

    async_exchange_end(exch);

    sysarg_t ret;
    async_wait_for(req, &ret);

    if ((rc != EOK) || (ret != EOK))
        return 0;

    return (imagemap_handle_t) IPC_GET_ARG1(answer);
}
示例#26
0
文件: udp.c 项目: jvesely/helenos
/** Create new UDP association.
 *
 * Create a UDP association that allows sending and receiving messages.
 *
 * @a epp may specify remote address and port, in which case only messages
 * from that remote endpoint will be received. Also, that remote endpoint
 * is used as default when @c NULL is passed as destination to
 * udp_assoc_send_msg.
 *
 * @a epp may specify a local link or address. If it does not, the association
 * will listen on all local links/addresses. If @a epp does not specify
 * a local port number, a free dynamic port number will be allocated.
 *
 * The caller is informed about incoming data by invoking @a cb->recv_msg
 *
 * @param udp    UDP client
 * @param epp    Internet endpoint pair
 * @param cb     Callbacks
 * @param arg    Argument to callbacks
 * @param rassoc Place to store pointer to new association
 *
 * @return EOK on success or negative error code.
 */
int udp_assoc_create(udp_t *udp, inet_ep2_t *epp, udp_cb_t *cb, void *arg,
    udp_assoc_t **rassoc)
{
	async_exch_t *exch;
	udp_assoc_t *assoc;
	ipc_call_t answer;

	assoc = calloc(1, sizeof(udp_assoc_t));
	if (assoc == NULL)
		return ENOMEM;

	exch = async_exchange_begin(udp->sess);
	aid_t req = async_send_0(exch, UDP_ASSOC_CREATE, &answer);
	sysarg_t rc = async_data_write_start(exch, (void *)epp,
	    sizeof(inet_ep2_t));
	async_exchange_end(exch);

	if (rc != EOK) {
		sysarg_t rc_orig;
		async_wait_for(req, &rc_orig);
		if (rc_orig != EOK)
			rc = rc_orig;
		goto error;
	}

	async_wait_for(req, &rc);
	if (rc != EOK)
		goto error;

	assoc->udp = udp;
	assoc->id = IPC_GET_ARG1(answer);
	assoc->cb = cb;
	assoc->cb_arg = arg;

	list_append(&assoc->ludp, &udp->assoc);
	*rassoc = assoc;

	return EOK;
error:
	free(assoc);
	return (int) rc;
}
示例#27
0
static void fault_event(ipc_callid_t callid, ipc_call_t *call)
{
	const char *fname;
	char *s_taskid;
	int rc;

	task_id_t taskid;
	uintptr_t thread;

	taskid = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
	thread = IPC_GET_ARG3(*call);

	if (asprintf(&s_taskid, "%" PRIu64, taskid) < 0) {
		printf("Memory allocation failed.\n");
		return;
	}

	printf(NAME ": Task %" PRIu64 " fault in thread %p.\n", taskid,
	    (void *) thread);

	fname = "/app/taskdump";

#ifdef CONFIG_WRITE_CORE_FILES
	char *dump_fname;

	if (asprintf(&dump_fname, "/data/core%" PRIu64, taskid) < 0) {
		printf("Memory allocation failed.\n");
		return;
	}

	printf(NAME ": Executing %s -c %s -t %s\n", fname, dump_fname, s_taskid);
	rc = task_spawnl(NULL, fname, fname, "-c", dump_fname, "-t", s_taskid,
	    NULL);
#else
	printf(NAME ": Executing %s -t %s\n", fname, s_taskid);
	rc = task_spawnl(NULL, fname, fname, "-t", s_taskid, NULL);
#endif
	if (rc != EOK) {
		printf("%s: Error spawning %s (%s).\n", NAME, fname,
		    str_error(rc));
	}
}
示例#28
0
frontbuf_handle_t fb_frontbuf_create(async_sess_t *sess,
                                     screenbuffer_t *frontbuf)
{
    async_exch_t *exch = async_exchange_begin(sess);

    ipc_call_t answer;
    aid_t req = async_send_0(exch, FB_FRONTBUF_CREATE, &answer);
    int rc = async_share_out_start(exch, frontbuf, AS_AREA_READ
                                   | AS_AREA_WRITE | AS_AREA_CACHEABLE);

    async_exchange_end(exch);

    sysarg_t ret;
    async_wait_for(req, &ret);

    if ((rc != EOK) || (ret != EOK))
        return 0;

    return (frontbuf_handle_t) IPC_GET_ARG1(answer);
}
示例#29
0
/** Get category ID.
 *
 * Provided name of a category, return its ID.
 *
 * @param name		Category name
 * @param cat_id	Place to store ID
 * @param flags		IPC_FLAG_BLOCKING to wait for location service to start
 * @return		EOK on success or negative error code
 */
int loc_category_get_id(const char *name, category_id_t *cat_id,
    unsigned int flags)
{
	async_exch_t *exch;
	
	if (flags & IPC_FLAG_BLOCKING)
		exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
	else {
		exch = loc_exchange_begin(LOC_PORT_CONSUMER);
		if (exch == NULL)
			return errno;
	}
	
	ipc_call_t answer;
	aid_t req = async_send_0(exch, LOC_CATEGORY_GET_ID,
	    &answer);
	sysarg_t retval = async_data_write_start(exch, name, str_size(name));
	
	loc_exchange_end(exch);
	
	if (retval != EOK) {
		async_forget(req);
		return retval;
	}
	
	async_wait_for(req, &retval);
	
	if (retval != EOK) {
		if (cat_id != NULL)
			*cat_id = (category_id_t) -1;
		
		return retval;
	}
	
	if (cat_id != NULL)
		*cat_id = (category_id_t) IPC_GET_ARG1(answer);
	
	return retval;
}
示例#30
0
/**
 * Register a named application context to the audio server.
 * @param sess Valid audio session.
 * @param name Valid string identifier
 * @param record True if the application context wishes to receive data.
 * @return Valid ID on success, Error code on failure.
 */
hound_context_id_t hound_service_register_context(hound_sess_t *sess,
    const char *name, bool record)
{
	assert(sess);
	assert(name);
	ipc_call_t call;
	async_exch_t *exch = async_exchange_begin(sess);
	aid_t mid =
	    async_send_1(exch, IPC_M_HOUND_CONTEXT_REGISTER, record, &call);
	int ret = mid ? EOK : EPARTY;

	if (ret == EOK)
		ret = async_data_write_start(exch, name, str_size(name));
	else
		async_forget(mid);

	if (ret == EOK)
		async_wait_for(mid, (sysarg_t *)&ret);

	async_exchange_end(exch);
	return ret == EOK ? (hound_context_id_t)IPC_GET_ARG1(call) : ret;
}