From c4e9a48bfd362290822cc845b077801801d0197a Mon Sep 17 00:00:00 2001 From: Mikkel Kamstrup Erlandsen Date: Wed, 19 Mar 2014 13:28:25 +0100 Subject: client: add a bunch of comments and function docs --- src/client.c | 35 +++++++++++++++++++++++++++++++++++ src/device.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) 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; -- cgit v1.1-32-gdbae