summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client.c35
-rw-r--r--src/device.c56
2 files changed, 90 insertions, 1 deletions
diff --git a/src/client.c b/src/client.c
index 1e15a1e..c6a7ce8 100644
--- a/src/client.c
+++ b/src/client.c
@@ -71,6 +71,14 @@ struct mux_client {
static struct collection client_list;
pthread_mutex_t client_list_mutex;
+/**
+ * Receive raw data from the client socket.
+ *
+ * @param client Client to read from.
+ * @param buffer Buffer to store incoming data.
+ * @param len Max number of bytes to read.
+ * @return Same as recv() system call. Number of bytes read; when < 0 errno will be set.
+ */
int client_read(struct mux_client *client, void *buffer, uint32_t len)
{
usbmuxd_log(LL_SPEW, "client_read fd %d buf %p len %d", client->fd, buffer, len);
@@ -81,6 +89,14 @@ int client_read(struct mux_client *client, void *buffer, uint32_t len)
return recv(client->fd, buffer, len, 0);
}
+/**
+ * Send raw data to the client socket.
+ *
+ * @param client Client to send to.
+ * @param buffer The data to send.
+ * @param len Number of bytes to write.
+ * @return Same as system call send(). Number of bytes written; when < 0 errno will be set.
+ */
int client_write(struct mux_client *client, void *buffer, uint32_t len)
{
usbmuxd_log(LL_SPEW, "client_write fd %d buf %p len %d", client->fd, buffer, len);
@@ -91,6 +107,16 @@ int client_write(struct mux_client *client, void *buffer, uint32_t len)
return send(client->fd, buffer, len, 0);
}
+/**
+ * Set event mask to use for ppoll()ing the client socket.
+ * Typically POLLOUT and/or POLLIN. Note that this overrides
+ * the current mask, that is, it is not ORing the argument
+ * into the current mask.
+ *
+ * @param client The client to set the event mask on.
+ * @param events The event mask to sert.
+ * @return 0 on success, -1 on error.
+ */
int client_set_events(struct mux_client *client, short events)
{
if((client->state != CLIENT_CONNECTED) && (client->state != CLIENT_CONNECTING2)) {
@@ -103,6 +129,15 @@ int client_set_events(struct mux_client *client, short events)
return 0;
}
+/**
+ * Wait for an inbound connection on the usbmuxd socket
+ * and create a new mux_client instance for it, and store
+ * the client in the client list.
+ *
+ * @param listenfd the socket fd to accept() on.
+ * @return The connection fd for the client, or < 0 for error
+ * in which case errno will be set.
+ */
int client_accept(int listenfd)
{
struct sockaddr_un addr;
diff --git a/src/device.c b/src/device.c
index ce0f28f..15f829b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -329,6 +329,13 @@ int device_start_connect(int device_id, uint16_t dport, struct mux_client *clien
return 0;
}
+/**
+ * Examine the state of a connection's buffers and
+ * update all connection flags and masks accordingly.
+ * Does not do I/O.
+ *
+ * @param conn The connection to update.
+ */
static void update_connection(struct mux_connection *conn)
{
uint32_t sent = conn->tx_seq - conn->rx_ack;
@@ -362,8 +369,18 @@ static void update_connection(struct mux_connection *conn)
client_set_events(conn->client, conn->events);
}
+/**
+ * Flush input and output buffers for a client connection.
+ *
+ * @param device_id Numeric id for the device.
+ * @param client The client to flush buffers for.
+ * @param events event mask for the client. POLLOUT means that
+ * the client is ready to receive data, POLLIN that it has
+ * data to be read (and send along to the device).
+ */
void device_client_process(int device_id, struct mux_client *client, short events)
{
+ // Find the connection for the given device_id
struct mux_connection *conn = NULL;
pthread_mutex_lock(&device_list_mutex);
FOREACH(struct mux_device *dev, &device_list) {
@@ -388,6 +405,8 @@ void device_client_process(int device_id, struct mux_client *client, short event
int res;
int size;
if(events & POLLOUT) {
+ // Client is ready to receive data, send what we have
+ // in the client's connection buffer
size = client_write(conn->client, conn->ib_buf, conn->ib_size);
if(size <= 0) {
usbmuxd_log(LL_DEBUG, "error writing to client (%d)", size);
@@ -403,6 +422,8 @@ void device_client_process(int device_id, struct mux_client *client, short event
}
}
if(events & POLLIN) {
+ // There is inbound trafic on the client socket,
+ // convert it to tcp and send to the device
size = client_read(conn->client, conn->ob_buf, conn->sendable);
if(size <= 0) {
if (size < 0) {
@@ -422,6 +443,23 @@ void device_client_process(int device_id, struct mux_client *client, short event
update_connection(conn);
}
+/**
+ * Copy a payload to a connection's in-buffer and
+ * set the POLLOUT event mask on the connection so
+ * the next main_loop iteration will dispatch the
+ * buffer if the connection socket is writable.
+ *
+ * Connection buffers are flushed in the
+ * device_client_process() function.
+ *
+ * @param conn The connection to add incoming data to.
+ * @param payload Payload to prepare for writing.
+ * The payload will be copied immediately so you are
+ * free to alter or free the payload buffer when this
+ * function returns.
+ * @param payload_length number of bytes to copy from from
+ * the payload.
+ */
static void connection_device_input(struct mux_connection *conn, unsigned char *payload, uint32_t payload_length)
{
if((conn->ib_size + payload_length) > conn->ib_capacity) {
@@ -483,6 +521,14 @@ static void device_version_input(struct mux_device *dev, struct version_header *
preflight_worker_device_add(&info);
}
+/**
+ * Handle an incoming TCP packet from the device.
+ *
+ * @param dev The device handle TCP input on.
+ * @param th Pointer to the TCP header struct.
+ * @param payload Payload data.
+ * @param payload_length Number of bytes in payload.
+ */
static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned char *payload, uint32_t payload_length)
{
uint16_t sport = ntohs(th->th_dport);
@@ -561,6 +607,14 @@ static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned
}
}
+/**
+ * Take input data from the device that has been read into a buffer
+ * and dispatch it to the right protocol backend (eg. TCP).
+ *
+ * @param usbdev
+ * @param buffer
+ * @param length
+ */
void device_data_input(struct usb_device *usbdev, unsigned char *buffer, uint32_t length)
{
struct mux_device *dev = NULL;
@@ -595,7 +649,7 @@ void device_data_input(struct usb_device *usbdev, unsigned char *buffer, uint32_
dev->pktlen = 0;
return;
}
- memcpy(dev->pktbuf + dev->pktlen, buffer, length);
+ memcpy(dev->pktbuf + dev->pktlen, buffer, length);
struct mux_header *mhdr = (struct mux_header *)dev->pktbuf;
if((length < USB_MRU) || (ntohl(mhdr->length) == (length + dev->pktlen))) {
buffer = dev->pktbuf;