diff -ruN obex/apps/Makefile obex-s45/apps/Makefile --- obex/apps/Makefile Mon Nov 29 09:48:20 1999 +++ obex-s45/apps/Makefile Thu Jan 17 18:12:30 2002 @@ -28,12 +28,14 @@ LD = ld RM = rm -f -EXECS = irobex_palm3 irobex_test obex_tcp irxfer +EXECS = irobex_palm3 irobex_test irobex_S45 obex_tcp irxfer RM_CMD = $(RM) *.BAK *.bak *.o ,* *~ *.a core $(EXECS) -INCLUDES = -I$(ROOT)/usr/include -I/usr/lib/glib/include +INCLUDES = -I$(ROOT)/usr/local/include -I$(ROOT)/usr/include -I/usr/lib/glib/include -I/usr/include/glib-1.2 +#INCLUDES = -I$(ROOT)/usr/include -I/usr/lib/glib/include -I/usr/include/glib-1.2 LIBRARIES = -lobex -lglib -LIBPATH = -L$(ROOT)/usr/lib +LIBPATH = -L$(ROOT)/usr/local/lib -L$(ROOT)/usr/lib +#LIBPATH = -L$(ROOT)/usr/lib CFLAGS = $(RPM_OPT_FLAGS) -Wall $(INCLUDES) @@ -41,6 +43,8 @@ irobex_test: irobex_test.o cobex_R320.o $(CC) $(CFLAGS) -o irobex_test irobex_test.o cobex_R320.c $(LIBPATH) $(LIBRARIES) +irobex_S45: irobex_S45.o cobex_S45.o + $(CC) $(CFLAGS) -o irobex_S45 irobex_S45.o cobex_S45.c $(LIBPATH) $(LIBRARIES) irobex_palm3: irobex_palm3.o obex_put_common.o $(CC) $(CFLAGS) -o irobex_palm3 irobex_palm3.o obex_put_common.o $(LIBPATH) $(LIBRARIES) diff -ruN obex/apps/cobex_S45.c obex-s45/apps/cobex_S45.c --- obex/apps/cobex_S45.c Thu Jan 1 01:00:00 1970 +++ obex-s45/apps/cobex_S45.c Fri Jan 18 00:28:00 2002 @@ -0,0 +1,268 @@ +/********************************************************************* + * + * Filename: cobex_S45.c + * Version: 0.1 + * Description: Talk OBEX over a serial port (Siemens specific) + * Status: Experimental. + * Author: Christian W. Zuckschwerdt + * Created at: Don, 17 Jan 2002 18:27:25 +0100 + * Modified at: Don, 17 Jan 2002 23:46:52 +0100 + * Modified by: Christian W. Zuckschwerdt + * + * Based on code by Pontus Fuchs + * Original Copyright (c) 1998, 1999, Dag Brattli, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#define SERPORT "/dev/ttyS1" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "cobex_S45.h" + +int ttyfd; +char inputbuf[500]; +extern obex_t *handle; +struct termios oldtio, newtio; + + +/* Called when data arrives */ +void cobex_input_handler(int signal) +{ + int actual; + + g_print(__FUNCTION__ "()\n"); + + actual = read(ttyfd, &inputbuf, sizeof(inputbuf)); + g_print(__FUNCTION__ "() Read %d bytes\n", actual); + + OBEX_CustomDataFeed(handle, inputbuf, actual); +} + + +/* Send an AT-command an expect 1 line back as answer */ +int cobex_do_at_cmd(int fd, char *cmd, char *rspbuf, int rspbuflen) +{ + fd_set ttyset; + struct timeval tv; + + char *answer; + char *answer_end; + unsigned int answer_size; + + char tmpbuf[100] = {0,}; + int actual; + int total = 0; + int done = 0; + int cmdlen; + + cmdlen = strlen(cmd); + + rspbuf[0] = 0; +/* printf("Sending %d: %s\n", cmdlen, cmd); */ + + // Write command + if(write(fd, cmd, cmdlen) < cmdlen) { + perror("Error writing to port"); + return -1; + } + + while(!done) { + FD_ZERO(&ttyset); + FD_SET(fd, &ttyset); + tv.tv_sec = 2; + tv.tv_usec = 0; + if(select(fd+1, &ttyset, NULL, NULL, &tv)) { + actual = read(fd, &tmpbuf[total], sizeof(tmpbuf) - total); + if(actual < 0) + return actual; + total += actual; + +// printf("tmpbuf=%d: %s\n", total, tmpbuf); + + // Answer not found within 100 bytes. Cancel + if(total == sizeof(tmpbuf)) + return -1; + + if( (answer = index(tmpbuf, '\n')) ) { + // Remove first line (echo) + if( (answer_end = index(answer+1, '\n')) ) { + // Found end of answer + done = 1; + } + } + } + else { + // Anser didn't come in time. Cancel + return -1; + } + } + + +// printf("buf:%08lx answer:%08lx end:%08lx\n", tmpbuf, answer, answer_end); + + +// printf("Answer: %s\n", answer); + + // Remove heading and trailing \r + if((*answer_end == '\r') || (*answer_end == '\n')) + answer_end--; + if((*answer_end == '\r') || (*answer_end == '\n')) + answer_end--; + if((*answer == '\r') || (*answer == '\n')) + answer++; + if((*answer == '\r') || (*answer == '\n')) + answer++; +// printf("Answer: %s\n", answer); + + answer_size = (answer_end) - answer +1; + +// printf("Answer size=%d\n", answer_size); + if( (answer_size) >= rspbuflen ) + return -1; + + + strncpy(rspbuf, answer, answer_size); + rspbuf[answer_size] = 0; + return 0; +} + +/* Set the phone in OBEX-mode */ +gint cobex_init(char *ttyname) +{ + char rspbuf[200]; + + printf(__FUNCTION__ "()\n"); + + if( (ttyfd = open(ttyname, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) < 0 ) { + perror("Can' t open tty"); + return -1; + } + + tcgetattr(ttyfd, &oldtio); + bzero(&newtio, sizeof(newtio)); + newtio.c_cflag = B57600 | CS8 | CREAD; + newtio.c_iflag = IGNPAR; + newtio.c_oflag = 0; + tcflush(ttyfd, TCIFLUSH); + tcsetattr(ttyfd, TCSANOW, &newtio); + + if(cobex_do_at_cmd(ttyfd, "ATZ\r\n", rspbuf, sizeof(rspbuf)) < 0) { + printf("Comm-error\n"); + goto err; + } + if(strcasecmp("OK", rspbuf) != 0) { + printf("Error doing ATZ (%s)\n", rspbuf); + goto err; + } +/* + if(cobex_do_at_cmd(ttyfd, "AT^SIFS\r\n", rspbuf, sizeof(rspbuf)) < 0) { + printf("Comm-error\n"); + goto err; + } + if(strcasecmp("^SIFS: WIRE", rspbuf) != 0) { // expect "OK" also! + printf("Error doing AT^SIFS (%s)\n", rspbuf); + goto err; + } +*/ + if(cobex_do_at_cmd(ttyfd, "AT^SBFB=1\r\n", rspbuf, sizeof(rspbuf)) < 0) { + printf("Comm-error\n"); + goto err; + } + if(strcasecmp("OK", rspbuf) != 0) { + printf("Error doing AT^SBFB=1 (%s)\n", rspbuf); + goto err; + } + + return 1; +err: + cobex_cleanup(TRUE); + return -1; +} + +/* Set up input-handler */ +int cobex_start_io(void) +{ + int oflags; + int ret; + + signal(SIGIO, &cobex_input_handler); + fcntl(ttyfd, F_SETOWN, getpid()); + oflags = fcntl(0, F_GETFL); + ret = fcntl(ttyfd, F_SETFL, oflags | FASYNC); + if(ret < 0) + return ret; + return 0; +} + +void cobex_cleanup(int force) +{ + signal(SIGIO, SIG_IGN); + if(force) { + // Send a break to get out of OBEX-mode + if(ioctl(ttyfd, TCSBRKP, 0) < 0) { + printf("Unable to send break!\n"); + } + sleep(1); + } + close(ttyfd); + ttyfd = -1; +} + + +gint cobex_connect(obex_t *handle) +{ + printf(__FUNCTION__ "()\n"); + + if(cobex_init(SERPORT) < 0) + return -1; + if(cobex_start_io() < 0) + return -1; + return 1; +} + +gint cobex_disconnect(obex_t *handle) +{ + printf(__FUNCTION__ "()\n"); + cobex_cleanup(FALSE); + return 1; +} + +/* Called from OBEX-lib when data needs to be written */ +gint cobex_write(obex_t *handle, guint8 *buffer, gint length) +{ + int actual; + + printf(__FUNCTION__ "()\n"); + + actual = write(ttyfd, buffer, length); + g_print(__FUNCTION__ "() Wrote %d bytes (expected %d)\n", actual, length); + + return actual; +} diff -ruN obex/apps/cobex_S45.h obex-s45/apps/cobex_S45.h --- obex/apps/cobex_S45.h Thu Jan 1 01:00:00 1970 +++ obex-s45/apps/cobex_S45.h Thu Jan 17 23:49:27 2002 @@ -0,0 +1,38 @@ +/********************************************************************* + * + * Filename: cobex_S45.h + * Version: + * Description: + * Status: Experimental. + * Author: Christian W. Zuckschwerdt + * Created at: Don, 17 Jan 2002 18:27:25 +0100 + * Modified at: Don, 17 Jan 2002 23:46:52 +0100 + * Modified by: Christian W. Zuckschwerdt + * + * Based on code by Pontus Fuchs + * Original Copyright (c) 1998, 1999, Dag Brattli, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +int cobex_init(char *ttyname); +void cobex_cleanup(int force); +int cobex_start_io(void); + +gint cobex_write(obex_t *self, guint8 *buffer, gint length); +gint cobex_connect(obex_t *handle); +gint cobex_disconnect(obex_t *handle); diff -ruN obex/apps/irobex_S45.c obex-s45/apps/irobex_S45.c --- obex/apps/irobex_S45.c Thu Jan 1 01:00:00 1970 +++ obex-s45/apps/irobex_S45.c Thu Jan 17 23:47:41 2002 @@ -0,0 +1,657 @@ +/********************************************************************* + * + * Filename: irobex_S45.c + * Version: 0.1 + * Description: Test IrOBEX and OBEX over cable to S45s. + * Status: Experimental. + * Author: Christian W. Zuckschwerdt + * Created at: Don, 17 Jan 2002 18:27:25 +0100 + * Modified at: Don, 17 Jan 2002 23:46:52 +0100 + * Modified by: Christian W. Zuckschwerdt + * + * Based on code by Pontus Fuchs + * Original Copyright (c) 1998, 1999, Dag Brattli, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + + + +#include +#include +#include +#include +#include +#include + +#include + +#ifndef AF_IRDA +#define AF_IRDA 23 +#endif /* AF_IRDA */ + +#include "cobex_S45.h" + + +obex_t *handle; +gchar req_name[200]; + +/* + * Function safe_save_file (gchar *name, guint8 *buf, gint len) + * + * First remove path and add "/tmp/". Then save. + * + */ +gint safe_save_file(gchar *name, guint8 *buf, gint len) +{ + gchar *s; + gchar filename[255]; + gint fd; + gint actual; + + sprintf( filename, "/tmp/irobex-test-"); + s = rindex(name, '/'); + if (s == NULL) + s = name; + else + s++; + + strncat(filename, s, 250); + fd = open(filename, O_RDWR | O_CREAT, DEFFILEMODE); + if ( fd < 0) { + perror( filename); + return -1; + } + + actual = write(fd, buf, len); + close(fd); + + g_print( "irobex_test: wrote %s (%d bytes)\n", filename, actual); + + return actual; +} +void print_body(gchar *name, guint8 *buf, gint len) +{ + gchar *s; + // we need \0 termination + s = g_malloc(len + 1); + memcpy(s, buf, len); + s[len] = 0; + g_print( s ); +} + +/* + * Function client_done () + * + * + * + */ +void client_done(obex_object_t *object, gint obex_cmd, gint obex_rsp) +{ + obex_headerdata_t hv; + guint8 hi; + gint hlen; + GString *err; + + guint8 *body = NULL; + gint body_len; + + g_print(__FUNCTION__ "()\n"); + + if(obex_rsp != OBEX_RSP_SUCCESS) { + err = OBEX_GetResponseMessage(handle, obex_rsp); + g_print(__FUNCTION__ "() Operation failed %s (%02x)\n", err->str, obex_rsp); + g_string_free(err, TRUE); + } + + while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { + if(hi == OBEX_HEADER_BODY) { + g_print(__FUNCTION__ "() Found body\n"); + body = hv.bs; + body_len = hlen; + break; + } + else { + g_print(__FUNCTION__ "() Skipped header %02x\n", hi); + } + } + + switch(obex_cmd) { + case OBEX_CMD_CONNECT: + g_print("Connect done!\n"); + break; + case OBEX_CMD_DISCONNECT: + g_print("Disconnect done!\n"); + OBEX_TransportDisconnect(handle); + break; + } + + if(body) { + if(*req_name != 0) { + safe_save_file(req_name, body, body_len); + } else { + print_body("folder", body, body_len); + } + } +} + + + +/* Handle an incoming PUT*/ +void put_server(obex_object_t *object) +{ + obex_headerdata_t hv; + guint8 hi; + gint hlen; + + guint8 *body = NULL; + gint body_len; + gchar *name = NULL; + gchar *namebuf = NULL; + + g_print(__FUNCTION__ "()\n"); + + while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { + switch(hi) { + case OBEX_HEADER_BODY: + g_print(__FUNCTION__ "() Found body\n"); + body = hv.bs; + body_len = hlen; + break; + case OBEX_HEADER_NAME: + g_print(__FUNCTION__ "() Found name\n"); + if( (namebuf = g_malloc(hlen / 2))) { + OBEX_UnicodeToChar(namebuf, hv.bs, hlen); + name = namebuf; + } + break; + + default: + g_print(__FUNCTION__ "() Skipped header %02x\n", hi); + } + } + if(!body) { + g_print("Got a PUT without a body\n"); + return; + } + if(!name) { + name = "OBEX_PUT_Unknown_object"; + g_print("Got a PUT without a name. Setting name to %s\n", name); + + } + safe_save_file(name, body, body_len); + g_free(namebuf); +} + +/* Handle GET as a server*/ +void get_server(obex_object_t *object) +{ + guint8 *buf; + struct stat statbuf; + gint fd; + gint actual; + + obex_headerdata_t hv; + guint8 hi; + gint hlen; + + gchar *name = NULL; + gchar *namebuf = NULL; + + g_print(__FUNCTION__ "()\n"); + + while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { + switch(hi) { + case OBEX_HEADER_NAME: + g_print(__FUNCTION__ "() Found name\n"); + if( (namebuf = g_malloc(hlen / 2))) { + OBEX_UnicodeToChar(namebuf, hv.bs, hlen); + name = namebuf; + } + break; + + default: + g_print(__FUNCTION__ "() Skipped header %02x\n", hi); + } + } + + if(!name) { + g_print(__FUNCTION__ "() Got a GET without a name-header!\n"); + OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); + return; + } + g_print(__FUNCTION__ "() Got a request for %s\n", name); + + fd = open(name, O_RDONLY); + if( fd < 0) { + perror("Can't open file"); + OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); + return; + } + + if(fstat( fd, &statbuf) < 0) { + close(fd); + OBEX_ObjectSetRsp(object, OBEX_RSP_INTERNAL_SERVER_ERROR, OBEX_RSP_INTERNAL_SERVER_ERROR); + return; + } + + if(! (buf = g_malloc(statbuf.st_size)) ) { + close(fd); + OBEX_ObjectSetRsp(object, OBEX_RSP_INTERNAL_SERVER_ERROR, OBEX_RSP_INTERNAL_SERVER_ERROR); + return; + } + + actual = read(fd, buf, statbuf.st_size); + OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_BODY, (obex_headerdata_t) buf, actual, 0); + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_LENGTH, (obex_headerdata_t) (guint32) statbuf.st_size, sizeof(guint32), 0); + close(fd); + g_free(buf); + return; +} + +/* When server_indication sees a connect-attempt. Here we look for headers, and + If we find a HEADER_WHO with Linux in it we get happy */ + +void connect_server(obex_object_t *object) +{ + obex_headerdata_t hv; + guint8 hi; + gint hlen; + + guint8 *who; + gint who_len; + g_print(__FUNCTION__ "()\n"); + + while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { + if(hi == OBEX_HEADER_WHO) { + who = hv.bs; + who_len = hlen; + } + else { + g_print(__FUNCTION__ "() Skipped header %02x\n", hi); + } + } + if (who_len == 6) { + if(strncmp("Linux", who, 6) == 0) { + g_print("Weeeha. I'm talking to the coolest OS ever!\n"); + } + } + + OBEX_ObjectSetRsp(object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS); +} + +/* + * Function server_request () + * + * + * + */ +void server_request(obex_object_t *object, gint event, gint cmd) +{ + switch(cmd) { + case OBEX_CMD_CONNECT: + connect_server(object); + break; + case OBEX_CMD_DISCONNECT: + g_print("We got a disconnect-request\n"); + OBEX_ObjectSetRsp(object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS); + break; + case OBEX_CMD_GET: + /* A Get always fits one package */ + get_server(object); + break; + case OBEX_CMD_PUT: + /* If this is final package. Put is already done else we signal to go ahead! */ + if(event == OBEX_EV_REQ) { + OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); + put_server(object); + } + else /* OBEX_REQHINT */ + OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); + break; + default: + g_print(__FUNCTION__ "() Denied %02x request\n", cmd); + OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_IMPLEMENTED, OBEX_RSP_NOT_IMPLEMENTED); + break; + } + return; +} + + +/* + * Function obex_event () + * + * Called by the obex-layer when some event occurs. + * + */ +void obex_event(obex_object_t *object, gint mode, gint event, gint obex_cmd, gint obex_rsp) +{ + + switch (event) { + case OBEX_EV_PROGRESS: + g_print("Made some progress...\n"); + break; + case OBEX_EV_REQDONE: + if(mode == OBEX_CLIENT) + client_done(object, obex_cmd, obex_rsp); + else { + switch (obex_cmd) { + case OBEX_CMD_DISCONNECT: + g_print("Disconnect done!\n"); + OBEX_TransportDisconnect(handle); + break; + default: + g_print(__FUNCTION__ "() Command (%02x) has now finished\n", obex_cmd); + break; + } + } + break; + case OBEX_EV_REQ: + case OBEX_EV_REQHINT: + server_request(object, event, obex_cmd); + break; + case OBEX_EV_LINKERR: + g_print("Link broken!\n"); + OBEX_TransportDisconnect(handle); + break; + default: + g_print("Unknown event!\n"); + break; + } +} + + + + +/* Do a PUT of any file on local system */ +void put_client(void) +{ + obex_object_t *object; + + guint8 *buf; + gchar lname[200]; + gchar rname[200]; + gint rname_size; + + int fd; + int actual; + struct stat statbuf; + + printf("PUT file (local, remote)> "); + scanf("%s %s", lname, rname); + + fd = open(lname, O_RDONLY, 0); + if (fd == -1) { + perror("Unable to open file"); + return; + } + + /* Need to know the file length */ + fstat(fd, &statbuf); + + if(! (buf = g_malloc(statbuf.st_size)) ) { + close(fd); + return; + } + actual = read(fd, buf, statbuf.st_size); + + /* Build object */ + object = OBEX_ObjectNew(handle, OBEX_CMD_PUT); + + rname_size = OBEX_CharToUnicode(rname, rname, sizeof(rname)); + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_LENGTH, (obex_headerdata_t) (guint32) statbuf.st_size, + 4, 0); + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_NAME, (obex_headerdata_t) (guint8*) &rname, + rname_size, 0); + + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_BODY, (obex_headerdata_t) buf, actual, 0); + close(fd); + g_free(buf); + + OBEX_Request(handle, object); +} + +/* Do a GET of some file as a client. */ +void get_client() +{ + obex_object_t *object; + char rname[200]; + gint rname_size; + + guint8 oname[] = {0x37, 0x04, 0x00, 0x00, 0x00, 0x00}; + + printf("GET File> "); + scanf("%s", req_name); + + if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_GET))) { + g_print("Error\n"); + return; + } + + rname_size = OBEX_CharToUnicode(rname, req_name, sizeof(rname)); + + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_NAME, (obex_headerdata_t) (guint8*) rname, + rname_size, OBEX_FIT_ONE_PACKET); + + // add header 0x4c with 6 bytes data: <37><04><00><00><00><00> + OBEX_ObjectAddHeader(handle, object, 0x4c, (obex_headerdata_t) oname, + 6, OBEX_FIT_ONE_PACKET); + + OBEX_Request(handle, object); +} + +/* Do a GET of a specific type as a client. */ +/* Like getlist_client only more generic. */ +void gettype_client() +{ + obex_object_t *object; + gint req_name_size; + + printf("GET Type> "); + scanf("%s", req_name); + + if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_GET))) { + g_print("Error\n"); + return; + } + + req_name_size = strlen(req_name) + 1; // trailing 0x00 + + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_TYPE, (obex_headerdata_t) (guint8*) req_name, + req_name_size, OBEX_FIT_ONE_PACKET); + + OBEX_Request(handle, object); +} + +/* Do a GET of "x-obex/folder-listing" type as a client. */ +void getlist_client() +{ + obex_object_t *object; + char type_name[] = "x-obex/folder-listing"; + char rname[200]; + gint rname_size; + + printf("DIR Folder> "); /* be sure to use lower case only! */ + scanf("%s", req_name); + + if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_GET))) { + g_print("Error\n"); + return; + } + + rname_size = OBEX_CharToUnicode(rname, req_name, sizeof(rname)); + + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_TYPE, + (obex_headerdata_t) (guint8*) type_name, + sizeof(type_name), OBEX_FIT_ONE_PACKET); + if (*req_name != '/') + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_NAME, + (obex_headerdata_t) (guint8*) rname, + rname_size, OBEX_FIT_ONE_PACKET); + + *req_name = 0; + OBEX_Request(handle, object); +} + +/* Do a SETPATH a client. */ +void setpath_client() +{ + obex_object_t *object; + char rname[200]; + gint rname_size; + + printf("SETPATH Dir> "); + scanf("%s", req_name); + + if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_SETPATH))) { + g_print("Error\n"); + return; + } + + rname_size = OBEX_CharToUnicode(rname, req_name, sizeof(rname)); + + // add strange header 0x02 with data 0x00 beforehand? + OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_NAME, (obex_headerdata_t) (guint8*) rname, + rname_size, OBEX_FIT_ONE_PACKET); + + OBEX_Request(handle, object); +} + +/* Do a connect. Throw in some strange headers */ +/* +Connect +<80><00><1A> +WTF? Can't rebuild that one. My <11><00><04><00> seems to work though. + <10><00><40><06> +Target + <46><00><13><6b><01><31><41><06><11><9A><77><00><50><3F><47><1F> + */ +void connect_client() +{ + obex_object_t *object; + + guint8 target[] = {0x6b, 0x01, 0xCB, 0x31, 0x41, 0x06, 0x11, 0xD4, + 0x9A, 0x77, 0x00, 0x50, 0xDA, 0x3F, 0x47, 0x1F}; + + /* First connect transport */ + if(IrOBEX_TransportConnect(handle, "OBEX") < 0) { + g_print("Transport connect error!\n"); + return; + } + + if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_CONNECT))) { + g_print("Error\n"); + return; + } + + if(OBEX_ObjectAddHeader(handle, object, OBEX_HEADER_TARGET, + (obex_headerdata_t) target, sizeof(target), + OBEX_FIT_ONE_PACKET) < 0) { + g_print("Error adding header\n"); + OBEX_ObjectDelete(handle, object); + return; + } + OBEX_Request(handle, object); +} + +/* Do a Disconnect */ +void disconnect_client() +{ + obex_object_t *object; + + if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_DISCONNECT))) { + g_print("Error\n"); + return; + } + + OBEX_Request(handle, object); +} + + +int main (int argc, char *argv[]) +{ + char cmd[10]; + int end = 0; + int cobex = FALSE; + + obex_ctrans_t custfunc; + + if( (argc == 2) && (strcmp(argv[1], "cable") == 0 ) ) + cobex = TRUE; + + if(cobex) { + g_print("Do the cable-OBEX!\n"); + if(! (handle = OBEX_Init(OBEX_TRANS_CUST, obex_event, 0))) { + perror( "OBEX_Init failed"); + exit(0); + } + + custfunc.connect = cobex_connect; + custfunc.disconnect = cobex_disconnect; + custfunc.write = cobex_write; + custfunc.listen = NULL; + if(OBEX_RegisterCTransport(handle, &custfunc) < 0) { + g_print("Custom transport callback-registration failed\n"); + } + } + else { + if(! (handle = OBEX_Init(OBEX_TRANS_IRDA, obex_event, OBEX_FL_ASYNC))) { + perror( "OBEX_Init failed"); + exit(0); + } + } + + printf( "IrOBEX Test-Application.\n"); + + while (!end) { + printf("> "); + scanf("%s", cmd); + switch (cmd[0] | 0x20) { + case 'q': + end=1; + break; + case 'g': + get_client(); + break; + case 'p': + put_client(); + break; + case 'x': + setpath_client(); + break; + case 't': + gettype_client(); + break; + case 'l': + getlist_client(); + break; + case 'c': + connect_client(); + break; + case 'd': + disconnect_client(); + break; + case 's': + OBEX_ServerRegister(handle, "OBEX"); + break; + default: + printf("Unknown command %s\n", cmd); + } + } + return 0; +}