staging: usbip: userspace: usbip_network.c: coding style cleanup
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / usbip / userspace / src / usbip_network.c
bloba3833ff1561eaf1841e9c79ec804657b33b669c2
1 /*
2 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
3 * 2005-2007 Takahiro Hirofuchi
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/socket.h>
21 #include <string.h>
23 #include <arpa/inet.h>
24 #include <netdb.h>
25 #include <netinet/tcp.h>
26 #include <unistd.h>
28 #include "usbip_common.h"
29 #include "usbip_network.h"
31 void pack_uint32_t(int pack, uint32_t *num)
33 uint32_t i;
35 if (pack)
36 i = htonl(*num);
37 else
38 i = ntohl(*num);
40 *num = i;
43 void pack_uint16_t(int pack, uint16_t *num)
45 uint16_t i;
47 if (pack)
48 i = htons(*num);
49 else
50 i = ntohs(*num);
52 *num = i;
55 void pack_usb_device(int pack, struct usbip_usb_device *udev)
57 pack_uint32_t(pack, &udev->busnum);
58 pack_uint32_t(pack, &udev->devnum);
59 pack_uint32_t(pack, &udev->speed );
61 pack_uint16_t(pack, &udev->idVendor );
62 pack_uint16_t(pack, &udev->idProduct);
63 pack_uint16_t(pack, &udev->bcdDevice);
66 void pack_usb_interface(int pack __attribute__((unused)),
67 struct usbip_usb_interface *udev __attribute__((unused)))
69 /* uint8_t members need nothing */
72 static ssize_t usbip_xmit(int sockfd, void *buff, size_t bufflen, int sending)
74 ssize_t nbytes;
75 ssize_t total = 0;
77 if (!bufflen)
78 return 0;
80 do {
81 if (sending)
82 nbytes = send(sockfd, buff, bufflen, 0);
83 else
84 nbytes = recv(sockfd, buff, bufflen, MSG_WAITALL);
86 if (nbytes <= 0)
87 return -1;
89 buff = (void *)((intptr_t) buff + nbytes);
90 bufflen -= nbytes;
91 total += nbytes;
93 } while (bufflen > 0);
95 return total;
98 ssize_t usbip_recv(int sockfd, void *buff, size_t bufflen)
100 return usbip_xmit(sockfd, buff, bufflen, 0);
103 ssize_t usbip_send(int sockfd, void *buff, size_t bufflen)
105 return usbip_xmit(sockfd, buff, bufflen, 1);
108 int usbip_send_op_common(int sockfd, uint32_t code, uint32_t status)
110 struct op_common op_common;
111 int rc;
113 memset(&op_common, 0, sizeof(op_common));
115 op_common.version = USBIP_VERSION;
116 op_common.code = code;
117 op_common.status = status;
119 PACK_OP_COMMON(1, &op_common);
121 rc = usbip_send(sockfd, &op_common, sizeof(op_common));
122 if (rc < 0) {
123 dbg("usbip_send failed: %d", rc);
124 return -1;
127 return 0;
130 int usbip_recv_op_common(int sockfd, uint16_t *code)
132 struct op_common op_common;
133 int rc;
135 memset(&op_common, 0, sizeof(op_common));
137 rc = usbip_recv(sockfd, &op_common, sizeof(op_common));
138 if (rc < 0) {
139 dbg("usbip_recv failed: %d", rc);
140 goto err;
143 PACK_OP_COMMON(0, &op_common);
145 if (op_common.version != USBIP_VERSION) {
146 dbg("version mismatch: %d %d", op_common.version,
147 USBIP_VERSION);
148 goto err;
151 switch (*code) {
152 case OP_UNSPEC:
153 break;
154 default:
155 if (op_common.code != *code) {
156 dbg("unexpected pdu %#0x for %#0x", op_common.code,
157 *code);
158 goto err;
162 if (op_common.status != ST_OK) {
163 dbg("request failed at peer: %d", op_common.status);
164 goto err;
167 *code = op_common.code;
169 return 0;
170 err:
171 return -1;
174 int usbip_set_reuseaddr(int sockfd)
176 const int val = 1;
177 int ret;
179 ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
180 if (ret < 0)
181 dbg("setsockopt: SO_REUSEADDR");
183 return ret;
186 int usbip_set_nodelay(int sockfd)
188 const int val = 1;
189 int ret;
191 ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
192 if (ret < 0)
193 dbg("setsockopt: TCP_NODELAY");
195 return ret;
198 int usbip_set_keepalive(int sockfd)
200 const int val = 1;
201 int ret;
203 ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
204 if (ret < 0)
205 dbg("setsockopt: SO_KEEPALIVE");
207 return ret;
211 * IPv6 Ready
213 int usbip_net_tcp_connect(char *hostname, char *service)
215 struct addrinfo hints, *res, *rp;
216 int sockfd;
217 int ret;
219 memset(&hints, 0, sizeof(hints));
220 hints.ai_family = AF_UNSPEC;
221 hints.ai_socktype = SOCK_STREAM;
223 /* get all possible addresses */
224 ret = getaddrinfo(hostname, service, &hints, &res);
225 if (ret < 0) {
226 dbg("getaddrinfo: %s service %s: %s", hostname, service,
227 gai_strerror(ret));
228 return ret;
231 /* try the addresses */
232 for (rp = res; rp; rp = rp->ai_next) {
233 sockfd = socket(rp->ai_family, rp->ai_socktype,
234 rp->ai_protocol);
235 if (sockfd < 0)
236 continue;
238 /* should set TCP_NODELAY for usbip */
239 usbip_set_nodelay(sockfd);
240 /* TODO: write code for heartbeat */
241 usbip_set_keepalive(sockfd);
243 if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) == 0)
244 break;
246 close(sockfd);
249 if (!rp)
250 return EAI_SYSTEM;
252 freeaddrinfo(res);
254 return sockfd;