/** Send message via UDP association. * * @param assoc Association * @param dest Destination endpoint or @c NULL to use association's remote ep. * @param data Message data * @param bytes Message size in bytes * * @return EOK on success or negative error code */ int udp_assoc_send_msg(udp_assoc_t *assoc, inet_ep_t *dest, void *data, size_t bytes) { async_exch_t *exch; exch = async_exchange_begin(assoc->udp->sess); aid_t req = async_send_1(exch, UDP_ASSOC_SEND_MSG, assoc->id, NULL); sysarg_t rc = async_data_write_start(exch, (void *)dest, sizeof(inet_ep_t)); if (rc != EOK) { async_exchange_end(exch); async_forget(req); return rc; } rc = async_data_write_start(exch, data, bytes); if (rc != EOK) { async_forget(req); return rc; } async_exchange_end(exch); if (rc != EOK) { async_forget(req); return rc; } async_wait_for(req, &rc); return rc; }
/** Connect to specified network. * * @param[in] dev_sess Device session. * @param[in] ssid_start Network SSID prefix. * @param[in] password Network password (pass empty string if not needed). * * @return EOK If the operation was successfully completed, * negative error code otherwise. * */ int ieee80211_connect(async_sess_t *dev_sess, char *ssid_start, char *password) { assert(ssid_start); sysarg_t rc_orig; async_exch_t *exch = async_exchange_begin(dev_sess); aid_t aid = async_send_1(exch, DEV_IFACE_ID(IEEE80211_DEV_IFACE), IEEE80211_CONNECT, NULL); sysarg_t rc = async_data_write_start(exch, ssid_start, str_size(ssid_start) + 1); if (rc != EOK) { async_exchange_end(exch); async_wait_for(aid, &rc_orig); if (rc_orig == EOK) return (int) rc; return (int) rc_orig; } // FIXME: Typecasting string literal if (password == NULL) password = (char *) ""; rc = async_data_write_start(exch, password, str_size(password) + 1); if (rc != EOK) { async_exchange_end(exch); async_wait_for(aid, &rc_orig); if (rc_orig == EOK) return (int) rc; return (int) rc_orig; } async_exchange_end(exch); async_wait_for(aid, &rc); if (rc != EOK) return rc; /* Send DHCP discover. */ nic_address_t wifi_mac; rc = nic_get_address(dev_sess, &wifi_mac); if (rc != EOK) return rc; sysarg_t link_id = get_link_id(wifi_mac.address); if (link_id == ((sysarg_t) -1)) return EINVAL; rc = dhcp_discover(link_id); return (int) rc; }
/** Copy string to clipboard. * * Sets the clipboard contents to @a str. Passing an empty string or NULL * makes the clipboard empty. * * @param str String to put to clipboard or NULL. * * @return Zero on success or negative error code. * */ int clipboard_put_str(const char *str) { size_t size = str_size(str); if (size == 0) { async_exch_t *exch = clip_exchange_begin(); sysarg_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE); clip_exchange_end(exch); return (int) rc; } else { async_exch_t *exch = clip_exchange_begin(); aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL); sysarg_t rc = async_data_write_start(exch, (void *) str, size); clip_exchange_end(exch); if (rc != EOK) { sysarg_t rc_orig; async_wait_for(req, &rc_orig); if (rc_orig == EOK) return (int) rc; else return (int) rc_orig; } async_wait_for(req, &rc); return (int) rc; } }
/** Set pathname of the program to load. * * Sets the name of the program file to load. The name can be relative * to the current working directory (it will be absolutized before * sending to the loader). * * @param ldr Loader connection structure. * @param path Pathname of the program file. * * @return Zero on success or negative error code. * */ int loader_set_pathname(loader_t *ldr, const char *path) { size_t pa_len; char *pa = absolutize(path, &pa_len); if (!pa) return ENOMEM; /* Send program pathname */ async_exch_t *exch = async_exchange_begin(ldr->sess); ipc_call_t answer; aid_t req = async_send_0(exch, LOADER_SET_PATHNAME, &answer); sysarg_t rc = async_data_write_start(exch, (void *) pa, pa_len); async_exchange_end(exch); free(pa); if (rc != EOK) { async_forget(req); return (int) rc; } async_wait_for(req, &rc); return (int) rc; }
/** Set current working directory for the loaded task. * * Sets the current working directory for the loaded task. * * @param ldr Loader connection structure. * * @return Zero on success or negative error code. * */ int loader_set_cwd(loader_t *ldr) { char *cwd = (char *) malloc(MAX_PATH_LEN + 1); if (!cwd) return ENOMEM; if (!getcwd(cwd, MAX_PATH_LEN + 1)) str_cpy(cwd, MAX_PATH_LEN + 1, "/"); size_t len = str_length(cwd); async_exch_t *exch = async_exchange_begin(ldr->sess); ipc_call_t answer; aid_t req = async_send_0(exch, LOADER_SET_CWD, &answer); sysarg_t rc = async_data_write_start(exch, cwd, len); async_exchange_end(exch); free(cwd); if (rc != EOK) { async_forget(req); return (int) rc; } async_wait_for(req, &rc); return (int) rc; }
/** Send formatted message to the logger service. * * @param session Initialized IPC session with the logger. * @param log Log to use. * @param level Verbosity level of the message. * @param message The actual message. * @return Error code of the conversion or EOK on success. */ static int logger_message(async_sess_t *session, log_t log, log_level_t level, char *message) { async_exch_t *exchange = async_exchange_begin(session); if (exchange == NULL) { return ENOMEM; } if (log == LOG_DEFAULT) log = default_log_id; // FIXME: remove when all USB drivers use libc logging explicitly str_rtrim(message, '\n'); aid_t reg_msg = async_send_2(exchange, LOGGER_WRITER_MESSAGE, log, level, NULL); int rc = async_data_write_start(exchange, message, str_size(message)); sysarg_t reg_msg_rc; async_wait_for(reg_msg, ®_msg_rc); async_exchange_end(exchange); /* * Getting ENAK means no-one wants our message. That is not an * error at all. */ if (rc == ENAK) rc = EOK; if (rc != EOK) { return rc; } return reg_msg_rc; }
/** Set which multicast frames are received. * * @param[in] dev_sess * @param[in] mode Current operation mode * @param[in] address_list The list of addresses. Can be NULL. * @param[in] address_count Number of addresses in the list. * * @return EOK If the operation was successfully completed * */ int nic_multicast_set_mode(async_sess_t *dev_sess, nic_multicast_mode_t mode, const nic_address_t *address_list, size_t address_count) { if (address_list == NULL) address_count = 0; async_exch_t *exch = async_exchange_begin(dev_sess); aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_MULTICAST_SET_MODE, (sysarg_t) mode, address_count, NULL); int rc; if (address_count) rc = async_data_write_start(exch, address_list, address_count * sizeof(nic_address_t)); else rc = EOK; async_exchange_end(exch); sysarg_t res; async_wait_for(message_id, &res); if (rc != EOK) return rc; return (int) res; }
/** Set which source MACs are blocked * * @param[in] dev_sess * @param[in] address_list The list of addresses. Can be NULL. * @param[in] address_count Number of addresses in the list. * * @return EOK If the operation was successfully completed * */ int nic_blocked_sources_set(async_sess_t *dev_sess, const nic_address_t *address_list, size_t address_count) { if (address_list == NULL) address_count = 0; async_exch_t *exch = async_exchange_begin(dev_sess); aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_BLOCKED_SOURCES_SET, address_count, NULL); int rc; if (address_count) rc = async_data_write_start(exch, address_list, address_count * sizeof(nic_address_t)); else rc = EOK; async_exchange_end(exch); sysarg_t res; async_wait_for(message_id, &res); if (rc != EOK) return rc; return (int) res; }
/** 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; }
/** 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; }
int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu) { if (srv->client_sess == NULL) return EIO; async_exch_t *exch = async_exchange_begin(srv->client_sess); ipc_call_t answer; aid_t req = async_send_2(exch, IPLINK_EV_RECV, sdu->lsrc.ipv4, sdu->ldest.ipv4, &answer); int rc = async_data_write_start(exch, sdu->data, sdu->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; return EOK; }
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; }
/** * Destroy an existing connection between a source and a sink. * @param sess Valid audio session. * @param source Source name, valid string. * @param sink Sink name, valid string. * @return Error code. */ int hound_service_disconnect_source_sink(hound_sess_t *sess, const char *source, const char *sink) { assert(sess); async_exch_t *exch = async_exchange_begin(sess); if (!exch) return ENOMEM; ipc_call_t call; aid_t id = async_send_0(exch, IPC_M_HOUND_DISCONNECT, &call); int ret = id ? EOK : EPARTY; if (ret == EOK) ret = async_data_write_start(exch, source, str_size(source)); if (ret == EOK) ret = async_data_write_start(exch, sink, str_size(sink)); async_wait_for(id, (sysarg_t*)&ret); async_exchange_end(exch); return ENOTSUP; }
/** Set command-line arguments for the program. * * Sets the vector of command-line arguments to be passed to the loaded * program. By convention, the very first argument is typically the same as * the command used to execute the program. * * @param ldr Loader connection structure. * @param argv NULL-terminated array of pointers to arguments. * * @return Zero on success or negative error code. * */ int loader_set_args(loader_t *ldr, const char *const argv[]) { /* * Serialize the arguments into a single array. First * compute size of the buffer needed. */ const char *const *ap = argv; size_t buffer_size = 0; while (*ap != NULL) { buffer_size += str_size(*ap) + 1; ap++; } char *arg_buf = malloc(buffer_size); if (arg_buf == NULL) return ENOMEM; /* Now fill the buffer with null-terminated argument strings */ ap = argv; char *dp = arg_buf; while (*ap != NULL) { str_cpy(dp, buffer_size - (dp - arg_buf), *ap); dp += str_size(*ap) + 1; ap++; } /* Send serialized arguments to the loader */ async_exch_t *exch = async_exchange_begin(ldr->sess); ipc_call_t answer; aid_t req = async_send_0(exch, LOADER_SET_ARGS, &answer); sysarg_t rc = async_data_write_start(exch, (void *) arg_buf, buffer_size); async_exchange_end(exch); free(arg_buf); if (rc != EOK) { async_forget(req); return (int) rc; } async_wait_for(req, &rc); return (int) rc; }
/** Set the address of the device (e.g. MAC on Ethernet) * * @param[in] dev_sess * @param[in] address Pointer to the address * * @return EOK If the operation was successfully completed * */ int nic_set_address(async_sess_t *dev_sess, const nic_address_t *address) { assert(address); async_exch_t *exch = async_exchange_begin(dev_sess); aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_SET_ADDRESS, NULL); int rc = async_data_write_start(exch, address, sizeof(nic_address_t)); async_exchange_end(exch); sysarg_t res; async_wait_for(aid, &res); if (rc != EOK) return rc; return (int) res; }
/** Send frame from NIC * * @param[in] dev_sess * @param[in] data Frame data * @param[in] size Frame size in bytes * * @return EOK If the operation was successfully completed * */ int nic_send_frame(async_sess_t *dev_sess, void *data, size_t size) { async_exch_t *exch = async_exchange_begin(dev_sess); ipc_call_t answer; aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_SEND_MESSAGE, &answer); sysarg_t retval = async_data_write_start(exch, data, size); async_exchange_end(exch); if (retval != EOK) { async_forget(req); return retval; } async_wait_for(req, &retval); return retval; }
/** 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; }
/** Register new driver with loc. */ int loc_server_register(const char *name) { async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER); ipc_call_t answer; aid_t req = async_send_2(exch, LOC_SERVER_REGISTER, 0, 0, &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; } exch = loc_exchange_begin(LOC_PORT_SUPPLIER); async_connect_to_me(exch, 0, 0, 0, NULL, NULL); loc_exchange_end(exch); async_wait_for(req, &retval); return retval; }
/** * 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; }
int loc_namespace_get_id(const char *name, service_id_t *handle, 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_2(exch, LOC_NAMESPACE_GET_ID, flags, 0, &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 (handle != NULL) *handle = (service_id_t) -1; return retval; } if (handle != NULL) *handle = (service_id_t) IPC_GET_ARG1(answer); return retval; }
/** 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; }
int inet_send(inet_dgram_t *dgram, uint8_t ttl, inet_df_t df) { async_exch_t *exch = async_exchange_begin(inet_sess); ipc_call_t answer; aid_t req = async_send_5(exch, INET_SEND, dgram->src.ipv4, dgram->dest.ipv4, dgram->tos, ttl, df, &answer); int rc = async_data_write_start(exch, dgram->data, dgram->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; return EOK; }
int bd_write_blocks(bd_t *bd, aoff64_t ba, size_t cnt, const void *data, size_t size) { async_exch_t *exch = async_exchange_begin(bd->sess); ipc_call_t answer; aid_t req = async_send_3(exch, BD_WRITE_BLOCKS, LOWER32(ba), UPPER32(ba), cnt, &answer); int rc = async_data_write_start(exch, data, 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; return EOK; }
/** Set the mask used for VLAN filtering. * * If NULL, VLAN filtering is disabled. * * @param[in] dev_sess * @param[in] mask Pointer to mask structure or NULL to disable. * * @return EOK If the operation was successfully completed * */ int nic_vlan_set_mask(async_sess_t *dev_sess, const nic_vlan_mask_t *mask) { async_exch_t *exch = async_exchange_begin(dev_sess); aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_VLAN_SET_MASK, mask != NULL, NULL); int rc; if (mask != NULL) rc = async_data_write_start(exch, mask, sizeof(nic_vlan_mask_t)); else rc = EOK; async_exchange_end(exch); sysarg_t res; async_wait_for(message_id, &res); if (rc != EOK) return rc; return (int) res; }
/** Set the current time * * @param sess Session of the device * @param t The current time that will be written to the device * * @return EOK on success or a negative error code */ int clock_dev_time_set(async_sess_t *sess, struct tm *t) { aid_t req; int ret; async_exch_t *exch = async_exchange_begin(sess); req = async_send_1(exch, DEV_IFACE_ID(CLOCK_DEV_IFACE), CLOCK_DEV_TIME_SET, NULL); ret = async_data_write_start(exch, t, sizeof(*t)); async_exchange_end(exch); sysarg_t rc; if (ret != EOK) { async_forget(req); return ret; } async_wait_for(req, &rc); return (int)rc; }
/** Create a new (sub-) log. * * This function always returns a valid log_t. In case of errors, * @c parent is returned and errors are silently ignored. * * @param name Log name under which message will be reported (appended to parents name). * @param parent Parent log. * @return Opaque identifier of the newly created log. */ log_t log_create(const char *name, log_t parent) { async_exch_t *exchange = async_exchange_begin(logger_session); if (exchange == NULL) return parent; if (parent == LOG_DEFAULT) parent = default_log_id; ipc_call_t answer; aid_t reg_msg = async_send_1(exchange, LOGGER_WRITER_CREATE_LOG, parent, &answer); int rc = async_data_write_start(exchange, name, str_size(name)); sysarg_t reg_msg_rc; async_wait_for(reg_msg, ®_msg_rc); async_exchange_end(exchange); if ((rc != EOK) || (reg_msg_rc != EOK)) return parent; return IPC_GET_ARG1(answer); }
/** Read to or write from device. * * Helper function to read to or write from a device * using its character interface. * * @param sess Session to the device. * @param buf Buffer for the data read from or written to the device. * @param size Maximum size of data (in bytes) to be read or written. * @param read Read from the device if true, write to it otherwise. * * @return Non-negative number of bytes actually read from or * written to the device on success, negative error number * otherwise. * */ static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read) { ipc_call_t answer; aid_t req; int ret; async_exch_t *exch = async_exchange_begin(sess); if (read) { req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_DEV_READ, &answer); ret = async_data_read_start(exch, buf, size); } else { req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_DEV_WRITE, &answer); ret = async_data_write_start(exch, buf, size); } async_exchange_end(exch); sysarg_t rc; if (ret != EOK) { async_wait_for(req, &rc); if (rc == EOK) return (ssize_t) ret; return (ssize_t) rc; } async_wait_for(req, &rc); ret = (int) rc; if (ret != EOK) return (ssize_t) ret; return (ssize_t) IPC_GET_ARG1(answer); }
/** Set the interrupt/poll mode of the NIC. * * @param[in] dev_sess * @param[in] mode New poll mode * @param[in] period Period used in periodic polling. Can be NULL. * * @return EOK If the operation was successfully completed * */ int nic_poll_set_mode(async_sess_t *dev_sess, nic_poll_mode_t mode, const struct timeval *period) { async_exch_t *exch = async_exchange_begin(dev_sess); aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_POLL_SET_MODE, (sysarg_t) mode, period != NULL, NULL); int rc; if (period) rc = async_data_write_start(exch, period, sizeof(struct timeval)); else rc = EOK; async_exchange_end(exch); sysarg_t res; async_wait_for(message_id, &res); if (rc != EOK) return rc; return (int) res; }
/** * Retrieve a list of server side actors. * @param[in] sess Valid audio session. * @param[out] ids list of string identifiers. * @param[out] count Number of elements int the @p ids list. * @param[in] flags list requirements. * @param[in] connection name of target actor. Used only if the list should * contain connected actors. * @retval Error code. */ int hound_service_get_list(hound_sess_t *sess, const char ***ids, size_t *count, int flags, const char *connection) { assert(sess); assert(ids); assert(count); if (connection && !(flags & HOUND_CONNECTED)) return EINVAL; async_exch_t *exch = async_exchange_begin(sess); if (!exch) return ENOMEM; ipc_call_t res_call; aid_t mid = async_send_3(exch, IPC_M_HOUND_GET_LIST, flags, *count, (bool)connection, &res_call); int ret = EOK; if (mid && connection) ret = async_data_write_start(exch, connection, str_size(connection)); if (ret == EOK) async_wait_for(mid, (sysarg_t*)&ret); if (ret != EOK) { async_exchange_end(exch); return ret; } unsigned name_count = IPC_GET_ARG1(res_call); /* Start receiving names */ const char **names = NULL; if (name_count) { size_t *sizes = calloc(name_count, sizeof(size_t)); names = calloc(name_count, sizeof(char *)); if (!names || !sizes) ret = ENOMEM; if (ret == EOK) ret = async_data_read_start(exch, sizes, name_count * sizeof(size_t)); for (unsigned i = 0; i < name_count && ret == EOK; ++i) { char *name = malloc(sizes[i] + 1); if (name) { memset(name, 0, sizes[i] + 1); ret = async_data_read_start(exch, name, sizes[i]); names[i] = name; } else { ret = ENOMEM; } } free(sizes); } async_exchange_end(exch); if (ret != EOK) { for (unsigned i = 0; i < name_count; ++i) free(names[i]); free(names); } else { *ids = names; *count = name_count; } return ret; }
/** * Write audio data to a stream. * @param exch IPC exchange in STREAM MODE. * @param data Audio data buffer. * @size size of the buffer * @return Error code. */ int hound_service_stream_write(async_exch_t *exch, const void *data, size_t size) { return async_data_write_start(exch, data, size); }