3 # Patch managed by http://www.holgerschurig.de/patcher.html
6 --- obexpush/client/obex_main.c~add-obextool.patch
7 +++ obexpush/client/obex_main.c
14 - custfunc.userdata = gt->userdata;
16 custfunc.customdata = gt->userdata;
18 custfunc.connect = cobex_connect;
19 custfunc.disconnect = cobex_disconnect;
20 custfunc.write = cobex_write;
22 +++ obexpush/client/obextool.c
26 + * Bluetooth OBEX tool
28 + * Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
31 + * This program is free software; you can redistribute it and/or modify
32 + * it under the terms of the GNU General Public License as published by
33 + * the Free Software Foundation; either version 2 of the License, or
34 + * (at your option) any later version.
36 + * This program is distributed in the hope that it will be useful,
37 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 + * GNU General Public License for more details.
41 + * You should have received a copy of the GNU General Public License
42 + * along with this program; if not, write to the Free Software
43 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
55 +#include <sys/stat.h>
56 +#include <sys/time.h>
57 +#include <sys/param.h>
58 +#include <sys/socket.h>
60 +#include <bluetooth/bluetooth.h>
61 +#include <bluetooth/hci.h>
62 +#include <bluetooth/hci_lib.h>
63 +#include <bluetooth/rfcomm.h>
66 +#include <openobex/obex.h>
70 +volatile int finished = 0;
72 +struct btobex_context_t {
79 +gint btobex_connect(obex_t *handle, gpointer userdata)
81 + struct btobex_context_t *context = userdata;
82 + struct sockaddr_rc laddr, raddr;
85 + if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
86 + printf("Can't create socket. %s (%d)\n", strerror(errno), errno);
90 + laddr.rc_family = AF_BLUETOOTH;
91 + bacpy(&laddr.rc_bdaddr, BDADDR_ANY);
92 + laddr.rc_channel = 0;
93 + if (bind(s, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
94 + printf("Can't bind socket. %s (%d)\n", strerror(errno), errno);
99 + raddr.rc_family = AF_BLUETOOTH;
100 + bacpy(&raddr.rc_bdaddr, &context->bdaddr);
101 + raddr.rc_channel = context->channel;
102 + if (connect(s, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) {
103 + printf("Can't connect. %s (%d)\n", strerror(errno), errno);
114 +gint btobex_disconnect(obex_t *handle, gpointer userdata)
116 + struct btobex_context_t *context = userdata;
118 + close(context->fd);
124 +gint btobex_listen(obex_t *handle, gpointer userdata)
126 + printf("The listen command is not implemented\n");
132 +gint btobex_write(obex_t *handle, gpointer userdata, guint8 *buffer, gint length)
134 + struct btobex_context_t *context = userdata;
136 + return (write(context->fd, buffer, length));
140 +gint btobex_handleinput(obex_t *handle, gpointer userdata, gint timeout)
142 + struct btobex_context_t *context = userdata;
145 + unsigned char buf[1024];
148 + to.tv_sec = timeout;
152 + FD_SET(context->fd, &fdset);
156 + if ((sel = select(context->fd + 1, &fdset, NULL, NULL, &to)) > 0) {
157 + if ((len = read(context->fd, buf, sizeof(buf))) > 0)
158 + OBEX_CustomDataFeed(handle, buf, len);
165 +obex_ctrans_t btobex_ctrans = {
166 + customdata: &btobex_context,
167 + connect: btobex_connect,
168 + disconnect: btobex_disconnect,
169 + listen: btobex_listen,
170 + write: btobex_write,
171 + handleinput: btobex_handleinput,
175 +void btobex_event(obex_t *handle, obex_object_t *object, gint mode, gint event, gint obex_cmd, gint obex_rsp)
178 + case OBEX_EV_PROGRESS:
180 + case OBEX_EV_ABORT:
181 + printf("Request aborted\n");
184 + case OBEX_EV_REQDONE:
187 + case OBEX_EV_REQHINT:
188 + printf("Request hint\n");
191 + printf("Server request\n");
193 + case OBEX_EV_LINKERR:
194 + OBEX_TransportDisconnect(handle);
195 + printf("Link broken\n");
197 + case OBEX_EV_PARSEERR:
198 + printf("Parse error\n");
201 + printf("Unknown event 0x%02x\n", event);
208 +guint8 *btobex_readfile(const char *filename, int *filesize)
214 + stat(filename, &stats);
215 + fs = stats.st_size;
217 + if ((fd = open(filename, O_RDONLY, 0)) < 0)
220 + if (!(buf = g_malloc(fs))) {
225 + *filesize = read(fd, buf, fs);
233 +int btobex_push(bdaddr_t *bdaddr, uint8_t channel, char *filename, char *alias)
236 + obex_object_t *object;
237 + obex_headerdata_t hd;
239 + guint8 namebuf[MAXPATHLEN + 1];
246 + if (!(handle = OBEX_Init(OBEX_TRANS_CUST, btobex_event, 0))) {
247 + printf("Init of OBEX failed. %s (%d)", strerror(errno), errno);
251 + bacpy(&btobex_context.bdaddr, bdaddr);
252 + btobex_context.channel = channel;
254 + OBEX_SetUserData(handle, &btobex_context);
256 + if (OBEX_RegisterCTransport(handle, &btobex_ctrans) < 0) {
257 + printf("Custom transport callback registration failed.");
261 + if (OBEX_TransportConnect(handle, (void *)1, 0) != 1)
265 + object = OBEX_ObjectNew(handle, OBEX_CMD_CONNECT);
266 + err = OBEX_Request(handle, object);
269 + while (!finished) {
270 + if ((err = OBEX_HandleInput(handle, 1)) < 0) {
271 + printf("Error while handling input.\n");
277 + object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);
279 + namelen = OBEX_CharToUnicode(namebuf, alias, MAXPATHLEN);
281 + OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME, hd, namelen, 0);
283 + if (!(databuf = btobex_readfile(filename, &datalen))) {
284 + OBEX_TransportDisconnect(handle);
289 + OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hd, sizeof(guint32), 0);
292 + OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hd, datalen, 0);
294 + printf("Sending object ...\n");
296 + err = OBEX_Request(handle, object);
299 + while (!finished) {
300 + if ((err = OBEX_HandleInput(handle, 1)) < 0) {
301 + printf("Error while handling input.\n");
307 + object = OBEX_ObjectNew(handle, OBEX_CMD_DISCONNECT);
308 + err = OBEX_Request(handle, object);
311 + while (!finished) {
312 + if ((err = OBEX_HandleInput(handle, 1)) < 0) {
313 + printf("Error while handling input.\n");
319 + OBEX_TransportDisconnect(handle);
326 +static void usage(void);
329 +void cmd_push(bdaddr_t *local, int argc, char **argv)
341 + filename = argv[1];
342 + alias = basename(filename);
343 + str2ba(argv[2], &bdaddr);
344 + channel = (argc > 3) ? atoi(argv[3]) : 10;
346 + btobex_push(&bdaddr, channel, filename, alias);
352 + void (*func)(bdaddr_t *bdaddr, int argc, char **argv);
356 + { "push", cmd_push, "<file> <bdaddr> [channel]", "Push a file" },
357 + { NULL, NULL, 0, 0 }
361 +static void usage(void)
365 + printf("Bluetooth OBEX tool\n\n");
368 + "\tobextool [options] <command>\n"
371 + printf("Options:\n"
372 + "\t-i [hciX|bdaddr] Local HCI device or BD Address\n"
373 + "\t-h, --help Display help\n"
376 + printf("Commands:\n");
377 + for (i = 0; command[i].cmd; i++)
378 + printf("\t%-6s %-18s\t%s\n", command[i].cmd,
379 + command[i].opt ? command[i].opt : " ",
385 +static struct option main_options[] = {
386 + { "help", 0, 0, 'h' },
387 + { "device", 1, 0, 'i' },
392 +int main(int argc, char *argv[])
397 + bacpy(&bdaddr, BDADDR_ANY);
399 + while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
402 + if (strncmp(optarg, "hci", 3) == 0)
403 + hci_devba(atoi(optarg + 3), &bdaddr);
405 + str2ba(optarg, &bdaddr);
424 + for (i = 0; command[i].cmd; i++) {
425 + if (strncmp(command[i].cmd, argv[0], 3))
427 + command[i].func(&bdaddr, argc, argv);
435 --- obexpush/client/Makefile~add-obextool.patch
436 +++ obexpush/client/Makefile
440 ussp-push: obex_main.o obex_socket.o
441 - gcc obex_main.o obex_socket.o ${GLIBLIB} ${OBEXLIB} -o ussp-push
442 + $(CC) obex_main.o obex_socket.o ${GLIBLIB} ${OBEXLIB} -o ussp-push
444 obex_main.o: obex_main.c obex_socket.h
445 - gcc ${OBEXINC} ${GLIBINC} -c obex_main.c -o obex_main.o
446 + $(CC) ${OBEXINC} ${GLIBINC} -c obex_main.c -o obex_main.o
448 obex_socket.o: obex_socket.c obex_socket.h
449 - gcc ${OBEXINC} ${GLIBINC} -c obex_socket.c -o obex_socket.o
450 + $(CC) ${OBEXINC} ${GLIBINC} -c obex_socket.c -o obex_socket.o
454 +obextool: obextool.o
455 + $(CC) obextool.o ${GLIBLIB} ${OBEXLIB} -lbluetooth -o obextool
457 +obextool.o: obextool.c
458 + $(CC) ${OBEXINC} ${GLIBINC} -c obextool.c -o obextool.o
460 +all: ussp-push obextool