obexftp-0.24-Source/ 40777 0 0 0 12115602310 7352 5obexftp-0.24-Source/apps/ 40777 0 0 0 12115602310 10315 5obexftp-0.24-Source/apps/CMakeLists.txt100777 0 0 1315 12115454406 13170 0 add_definitions( -DVERSION="${VERSION}" ) # always set this add_definitions ( -DHAVE_USB ) add_executable ( obexftp_app obexftp.c ) target_link_libraries ( obexftp_app obexftp ) set_target_properties ( obexftp_app PROPERTIES OUTPUT_NAME obexftp ) add_executable ( obexftpd_app obexftpd.c ) target_link_libraries ( obexftpd_app obexftp ) set_target_properties ( obexftpd_app PROPERTIES OUTPUT_NAME obexftpd ) add_executable ( discovery_app discovery.c ) target_link_libraries ( discovery_app obexftp ) set_target_properties ( discovery_app PROPERTIES OUTPUT_NAME obexftp-discovery ) install ( TARGETS obexftp_app obexftpd_app RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT applications ) obexftp-0.24-Source/apps/discovery.c100777 0 0 22370 12115454406 12627 0/** \file apps/discovery.c Discover mobile and detect its class (Siemens, Ericsson). ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #define speed_t DWORD typedef HANDLE fd_t; #else #include #include typedef int fd_t; #endif #include struct mobile_param { const char *gmi; /* Manufacturer Identification to match */ const char *proto; /* Serial Protocol to use */ }; static struct mobile_param mobile_param[] = { {"siemens", "plain"}, {"ericsson", "bfb"}, {0, 0} }; struct mobile_info { char *gmi; /* AT+GMI : SIEMENS */ char *gmm; /* AT+GMM : Gipsy Soft Protocolstack */ char *gmr; /* AT+GMR : V2.550 */ char *cgmi; /* AT+CGMI : SIEMENS */ char *cgmm; /* AT+CGMM : S45 */ char *cgmr; /* AT+CGMR : 21 */ const char *ttyname; speed_t speed; }; /* S45: (auto baud) SIEMENS, Gipsy Soft Protocolstack, V2.550 SIEMENS, S45, 21 */ /* S25: (fixed at 19200) SIEMENS, Gipsy Soft Protocolstack, V2.400 SIEMENS, S25, 42 */ /* T68: Ericsson, T68, R2E006 prgCXC125326_TAE ERICSSON, 1130202-BVT68, R2E006 CXC125319 */ /* if auto-baud is enabled this will yoield the highest speed first */ #ifdef _WIN32 speed_t speeds[] = {CBR_115200, CBR_57600, CBR_38400, CBR_19200, CBR_9600, 0}; #else speed_t speeds[] = {B115200, B57600, B38400, B19200, B9600, B0}; #endif /* Send an AT-command an expect 1 line back as answer */ static int do_at_cmd(fd_t fd, const char *cmd, char *rspbuf, int rspbuflen) { #ifdef _WIN32 DWORD actual; #else fd_set ttyset; struct timeval tv; int actual; #endif char *answer; char *answer_end = NULL; int answer_size; char tmpbuf[200] = {0,}; int total = 0; int done = 0; int cmdlen; return_val_if_fail (fd > 0, -1); return_val_if_fail (cmd != NULL, -1); cmdlen = strlen(cmd); rspbuf[0] = 0; DEBUG(3, "%s() Sending %d: %s\n", __func__, cmdlen, cmd); /* Write command */ #ifdef _WIN32 if(!WriteFile(fd, cmd, cmdlen, &actual, NULL) || (actual != cmdlen)) { #else if(write(fd, cmd, cmdlen) != cmdlen) { #endif DEBUG(1, "Error writing to port\n"); return -1; } while(!done) { #ifdef _WIN32 if (!ReadFile(fd, &tmpbuf[total], sizeof(tmpbuf) - total, &actual, NULL)) { DEBUG(2, "%s() Read error: %ld\n", __func__, actual); } #else FD_ZERO(&ttyset); FD_SET(fd, &ttyset); tv.tv_sec = 2; tv.tv_usec = 0; if(select(fd+1, &ttyset, NULL, NULL, &tv)) { sleep(1); actual = read(fd, &tmpbuf[total], sizeof(tmpbuf) - total); #endif if(actual < 0) return actual; total += actual; DEBUG(3, "%s() tmpbuf=%d: %s\n", __func__, total, tmpbuf); /* Answer not found within 100 bytes. Cancel */ if(total == sizeof(tmpbuf)) return -1; if( (answer = strchr(tmpbuf, '\n')) ) { /* Remove first line (echo) */ if( (answer_end = strchr(answer+1, '\n')) ) { /* Found end of answer */ done = 1; } } #ifndef _WIN32 } else { /* Anser didn't come in time. Cancel */ return -1; } #endif } /* DEBUG(3, "%s() buf:%08lx answer:%08lx end:%08lx\n", __func__, tmpbuf, answer, answer_end); */ DEBUG(3, "%s() Answer: %s\n", __func__, 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++; DEBUG(3, "%s() Answer: %s\n", __func__, answer); answer_size = (answer_end) - answer +1; DEBUG(2, "%s() Answer size=%d\n", __func__, answer_size); if( (answer_size) >= rspbuflen ) return -1; strncpy(rspbuf, answer, answer_size); rspbuf[answer_size] = 0; return 0; } /* Init the phone and set it in BFB-mode */ /* Returns fd or -1 on failure */ static struct mobile_info *probe_tty(const char *ttyname) { int speed; char rspbuf[200]; struct mobile_info *info; char *p; #ifdef _WIN32 HANDLE ttyfd; DCB dcb; COMMTIMEOUTS ctTimeOuts; return_val_if_fail (ttyname != NULL, INVALID_HANDLE_VALUE); DEBUG(3, "%s() CreateFile\n", __func__); ttyfd = CreateFile (ttyname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (ttyfd == INVALID_HANDLE_VALUE) { fprintf(stderr, "Error: CreateFile()\n"); return NULL; } if(!GetCommState(ttyfd, &dcb)) fprintf(stderr, "Error: GetCommState()\n"); dcb.fBinary = TRUE; dcb.BaudRate = CBR_57600; dcb.fParity = FALSE; dcb.Parity = 0; dcb.ByteSize = 8; dcb.StopBits = 1; dcb.fInX = FALSE; dcb.fOutX = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fOutxCtsFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fRtsControl = RTS_CONTROL_ENABLE; if(!SetCommState(ttyfd, &dcb)) fprintf(stderr, "Error: SetCommState()\n"); ctTimeOuts.ReadIntervalTimeout = 250; ctTimeOuts.ReadTotalTimeoutMultiplier = 1; /* no good with big buffer */ ctTimeOuts.ReadTotalTimeoutConstant = 500; ctTimeOuts.WriteTotalTimeoutMultiplier = 1; ctTimeOuts.WriteTotalTimeoutConstant = 5000; if(!SetCommTimeouts(ttyfd, &ctTimeOuts)) fprintf(stderr, "Error: SetCommTimeouts()\n"); Sleep(500); /* flush all pending input */ if(!PurgeComm(ttyfd, PURGE_RXABORT | PURGE_RXCLEAR)) fprintf(stderr, "Error: PurgeComm()\n"); #else /* _WIN32 */ int ttyfd; struct termios oldtio, newtio; return_val_if_fail (ttyname != NULL, NULL); DEBUG(3, "%s() \n", __func__); info = calloc(1, sizeof(struct mobile_info)); info->ttyname = ttyname; if( (ttyfd = open(ttyname, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) < 0 ) { fprintf(stderr, "Error: Can't open tty\n"); free(info); return NULL; } /* probe mobile */ tcgetattr(ttyfd, &oldtio); for (speed = 0; speeds[speed] != B0; speed++) { memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = speeds[speed] | CS8 | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; tcflush(ttyfd, TCIFLUSH); tcsetattr(ttyfd, TCSANOW, &newtio); /* is this ok? do we need to send both cr and lf? */ if(do_at_cmd(ttyfd, "AT\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error doing AT\n"); } else if(strcasecmp("OK", rspbuf) == 0) { DEBUG(2, "OKAY doing AT (%s)\n", rspbuf); break; } } if(speeds[speed] == B0) { close(ttyfd); free(info); DEBUG(1, "Nothing found\n"); return NULL; } info->speed = speeds[speed]; /* detect mobile */ if(do_at_cmd(ttyfd, "AT+GMI\r", rspbuf, sizeof(rspbuf)) < 0) { close(ttyfd); free(info); DEBUG(1, "Comm-error doing AT+GMI\n"); return NULL; } if ((p=strchr(rspbuf, '\r')) != NULL) *p = 0; if ((p=strchr(rspbuf, '\n')) != NULL) *p = 0; info->gmi = strdup(rspbuf); if(do_at_cmd(ttyfd, "AT+GMM\r", rspbuf, sizeof(rspbuf)) < 0) { close(ttyfd); free(info); DEBUG(1, "Comm-error doing AT+GMM\n"); return NULL; } if ((p=strchr(rspbuf, '\r')) != NULL) *p = 0; if ((p=strchr(rspbuf, '\n')) != NULL) *p = 0; info->gmm = strdup(rspbuf); if(do_at_cmd(ttyfd, "AT+GMR\r", rspbuf, sizeof(rspbuf)) < 0) { close(ttyfd); free(info); DEBUG(1, "Comm-error doing AT+GMR\n"); return NULL; } if ((p=strchr(rspbuf, '\r')) != NULL) *p = 0; if ((p=strchr(rspbuf, '\n')) != NULL) *p = 0; info->gmr= strdup(rspbuf); if(do_at_cmd(ttyfd, "AT+CGMI\r", rspbuf, sizeof(rspbuf)) < 0) { close(ttyfd); free(info); DEBUG(1, "Comm-error doing AT+CGMI\n"); return NULL; } if ((p=strchr(rspbuf, '\r')) != NULL) *p = 0; if ((p=strchr(rspbuf, '\n')) != NULL) *p = 0; info->cgmi = strdup(rspbuf); if(do_at_cmd(ttyfd, "AT+CGMM\r", rspbuf, sizeof(rspbuf)) < 0) { close(ttyfd); free(info); DEBUG(1, "Comm-error doing AT+CGMM\n"); return NULL; } if ((p=strchr(rspbuf, '\r')) != NULL) *p = 0; if ((p=strchr(rspbuf, '\n')) != NULL) *p = 0; info->cgmm = strdup(rspbuf); if(do_at_cmd(ttyfd, "AT+CGMR\r", rspbuf, sizeof(rspbuf)) < 0) { close(ttyfd); free(info); DEBUG(1, "Comm-error doing AT+CGMR\n"); return NULL; } if ((p=strchr(rspbuf, '\r')) != NULL) *p = 0; if ((p=strchr(rspbuf, '\n')) != NULL) *p = 0; info->cgmr= strdup(rspbuf); close(ttyfd); #endif return info; } int main(int argc, char *argv[]) { struct mobile_info *info; if (mobile_param != NULL) { }; if (argc > 1) info = probe_tty(argv[1]); else #ifdef _WIN32 info = probe_tty("COM1"); #else info = probe_tty("/dev/ttyS0"); #endif if (info != NULL) { printf("%s (%d):\n%s, %s, %s\n%s, %s, %s\n", info->ttyname, info->speed, info->gmi, info->gmm, info->gmr, info->cgmi, info->cgmm, info->cgmr); return (EXIT_SUCCESS); } return (EXIT_FAILURE); } obexftp-0.24-Source/apps/obexftp.c100777 0 0 54012 12115454406 12265 0/** \file apps/obexftp.c Command line client to transfer from/to Mobile Equipment via OBEX. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #define strcasestr strstr #define ETIMEDOUT WSAETIMEDOUT #define ECONNREFUSED WSAECONNREFUSED #define EHOSTDOWN WSAEHOSTDOWN #define EINPROGRESS WSAEINPROGRESS #endif /* _WIN32 */ #include #ifdef HAVE_SYS_TIMES_H #include #endif // perhaps this scheme would be better? // IRDA irda://[nick?] // CABLE tty://path // BLUETOOTH bt://[device[:channel]] // USB usb://[enum] // INET host://host[:port] #define OBEXFTP_CABLE "OBEXFTP_CABLE" #define OBEXFTP_BLUETOOTH "OBEXFTP_BLUETOOTH" #define OBEXFTP_USB "OBEXFTP_USB" #define OBEXFTP_INET "OBEXFTP_INET" #define OBEXFTP_CHANNEL "OBEXFTP_CHANNEL" /* current command, set by main, read from info_cb */ int c; static void info_cb(int event, const char *msg, int len, void *UNUSED(data)) { char progress[] = "\\|/-"; static unsigned int i = 0; switch (event) { case OBEXFTP_EV_ERRMSG: fprintf(stderr, "Error: %s\n", msg); break; case OBEXFTP_EV_ERR: // OBEX_EV_REQDONE: obex_rsp=43 (SE user reject) fprintf(stderr, "failed: %s\n", msg); break; case OBEXFTP_EV_OK: fprintf(stderr, "done\n"); break; case OBEXFTP_EV_CONNECTING: fprintf(stderr, "Connecting..."); break; case OBEXFTP_EV_DISCONNECTING: fprintf(stderr, "Disconnecting..."); break; case OBEXFTP_EV_SENDING: fprintf(stderr, "Sending \"%s\"... ", msg); break; case OBEXFTP_EV_RECEIVING: fprintf(stderr, "Receiving \"%s\"... ", msg); break; case OBEXFTP_EV_LISTENING: fprintf(stderr, "Waiting for incoming connection\n"); break; case OBEXFTP_EV_CONNECTIND: fprintf(stderr, "Incoming connection\n"); break; case OBEXFTP_EV_DISCONNECTIND: fprintf(stderr, "Disconnecting\n"); break; case OBEXFTP_EV_INFO: printf("Got info %u: \n", *(uint32_t*)msg); break; case OBEXFTP_EV_BODY: if (c == 'l' || c == 'X' || c == 'P') { if (msg == NULL) fprintf(stderr, "No body.\n"); else if (len == 0) fprintf(stderr, "Empty body.\n"); else write(STDOUT_FILENO, msg, len); } break; case OBEXFTP_EV_PROGRESS: fprintf(stderr, "%c%c", 0x08, progress[i++]); fflush(stdout); if (i >= strlen(progress)) i = 0; break; } } /* create global uuid buffers */ static const uint8_t *fbs_uuid = UUID_FBS; static const uint8_t *irmc_uuid = UUID_IRMC; static const uint8_t *s45_uuid = UUID_S45; static const uint8_t *pcsoftware_uuid = UUID_PCSOFTWARE; /* parse UUID string to real bytes */ static int parse_uuid(char *name, const uint8_t **uuid, int *uuid_len) { if (name == NULL || *name == '\0' || !strncasecmp(name, "none", 4) || !strncasecmp(name, "null", 4) || !strncasecmp(name, "push", 4) || !strncasecmp(name, "goep", 4)) { fprintf(stderr, "Suppressing FBS.\n"); if (uuid) *uuid = NULL; if (uuid_len) *uuid_len = 0; return 0; } if (!strncasecmp(name, "fbs", 3) || !strncasecmp(name, "ftp", 3)) { fprintf(stderr, "Using FBS uuid.\n"); if (uuid) *uuid = fbs_uuid; if (uuid_len) *uuid_len = sizeof(UUID_FBS); return sizeof(UUID_FBS); } if (!strncasecmp(name, "sync", 4) || !strncasecmp(name, "irmc", 4)) { fprintf(stderr, "Using SYNCH uuid.\n"); if (uuid) *uuid = irmc_uuid; if (uuid_len) *uuid_len = sizeof(UUID_IRMC); return sizeof(UUID_IRMC); } if (!strncasecmp(name, "s45", 3) || !strncasecmp(name, "sie", 3)) { fprintf(stderr, "Using S45 uuid.\n"); if (uuid) *uuid = s45_uuid; if (uuid_len) *uuid_len = sizeof(UUID_S45); return sizeof(UUID_S45); } if (!strncasecmp(name, "pcsoftware", 10) || !strncasecmp(name, "sharp", 5)) { fprintf(stderr, "Using PCSOFTWARE uuid.\n"); if (uuid) *uuid = pcsoftware_uuid; if (uuid_len) *uuid_len = sizeof(UUID_PCSOFTWARE); return sizeof(UUID_PCSOFTWARE); } return -1; } #ifdef HAVE_USB static void discover_usb() { char **devices; char **dev; int interfaces_number; devices = obexftp_discover(OBEX_TRANS_USB); interfaces_number = 0; for(dev = devices; *dev; dev++) interfaces_number++; printf("Found %d USB OBEX interfaces\n\n", interfaces_number); for(dev = devices; *dev; dev++) { fprintf(stderr, "%s\n", *dev); } printf("\nUse '-u interface_number' to connect\n"); } #endif static int find_bt(char *addr, char **res_bdaddr, int *res_channel) { char **devices; char **dev; *res_bdaddr = addr; if (!addr || strlen(addr) < (6*2+5) || addr[2]!=':') { fprintf(stderr, "Scanning for %s ...\n", addr); devices = obexftp_discover(OBEX_TRANS_BLUETOOTH); for(dev = devices; dev && *dev; dev++) { if (!addr || strcasestr(*dev, addr)) { fprintf(stderr, "Found: %s\n", *dev); *res_bdaddr = *dev; break; } fprintf(stderr, "Seen: %s\n", *dev); } } if (!*res_bdaddr) return -1; /* No (matching) BT device found */ // (*res_bdaddr)[17] = '\0'; if (*res_channel < 0) { fprintf(stderr, "Browsing %s ...\n", *res_bdaddr); *res_channel = obexftp_browse_bt_ftp(*res_bdaddr); } if (*res_channel < 0) return -1; /* No valid BT channel found */ return 0; } /*@only@*/ /*@null@*/ static obexftp_client_t *cli = NULL; static const char *src_dev = NULL; #ifdef HAVE_BLUETOOTH static int transport = OBEX_TRANS_BLUETOOTH; #else static int transport = OBEX_TRANS_IRDA; #endif /* HAVE_BLUETOOTH */ /*@only@*/ /*@null@*/ static char *device = NULL; static int channel = -1; static const uint8_t *use_uuid = UUID_FBS; static int use_uuid_len = sizeof(UUID_FBS); static int use_conn=1; static int use_path=1; static int timeout = 20; /* default accept/reject timeout of 20 seconds */ /* connect with given uuid. re-connect every time */ static int cli_connect_uuid(const uint8_t *uuid, int uuid_len) { int ret, retry; #ifdef HAVE_SYS_TIMES_H clock_t clock; struct tms tms; #endif if (cli == NULL) { /* Open */ cli = obexftp_open (transport, NULL, info_cb, NULL); if(cli == NULL) { fprintf(stderr, "Error opening obexftp-client\n"); exit(1); //return -1; } if (!use_conn) { cli->quirks &= ~OBEXFTP_CONN_HEADER; } if (!use_path) { cli->quirks &= ~OBEXFTP_SPLIT_SETPATH; } cli->accept_timeout=timeout; } /* complete bt address if necessary */ if (transport == OBEX_TRANS_BLUETOOTH) { find_bt(device, &device, &channel); // we should free() the find_bt result at some point } for (retry = 0; retry < 3; retry++) { /* Connect */ #ifdef HAVE_SYS_TIMES_H clock = times(&tms); #endif ret = obexftp_connect_src(cli, src_dev, device, channel, uuid, uuid_len); #ifdef HAVE_SYS_TIMES_H clock = (times(&tms) - clock) * 1000 / sysconf(_SC_CLK_TCK); fprintf(stderr, "Tried to connect for %ldms\n", (long)clock); #endif if (ret >= 0) return ret; switch (errno) { case ETIMEDOUT: perror("The device may have moved out of range"); break; /* retry */ case ECONNREFUSED: perror("The user may have rejected the transfer"); return -errno; case EHOSTDOWN: perror("The device may be out of range or turned off"); break; /* retry */ case EINPROGRESS: perror("Interupted/bad reception or the device moved out of range"); break; /* retry */ default: fprintf(stderr, "unknown error on connect\n"); break; } fprintf(stderr, "Still trying to connect\n"); } obexftp_close(cli); cli = NULL; return ret; } /* connect, possibly without fbs uuid. won't re-connect */ static int cli_connect() { if (cli != NULL) { return 0; } if (cli_connect_uuid(use_uuid, use_uuid_len) < 0) exit(1); return 0; } static void cli_disconnect() { if (cli != NULL) { /* Disconnect */ (void) obexftp_disconnect (cli); /* Close */ obexftp_close (cli); cli = NULL; } } static void probe_device_uuid(const uint8_t *uuid, int uuid_len) { int rsp[10]; if (cli_connect_uuid(uuid, uuid_len) < 0) { printf("couldn't connect.\n"); return; } printf("getting null object without type\n"); (void) obexftp_get_type(cli, NULL, NULL, NULL); rsp[0] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting empty object without type\n"); (void) obexftp_get_type(cli, NULL, NULL, ""); rsp[1] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting null object with x-obex/folder-listing type\n"); (void) obexftp_get_type(cli, XOBEX_LISTING, NULL, NULL); rsp[2] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting empty object with x-obex/folder-listing type\n"); (void) obexftp_get_type(cli, XOBEX_LISTING, NULL, ""); rsp[3] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting null object with x-obex/capability type\n"); (void) obexftp_get_type(cli, XOBEX_CAPABILITY, NULL, NULL); rsp[4] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting empty object with x-obex/capability type\n"); (void) obexftp_get_type(cli, XOBEX_CAPABILITY, NULL, ""); rsp[5] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting null object with x-obex/object-profile type\n"); (void) obexftp_get_type(cli, XOBEX_PROFILE, NULL, NULL); rsp[6] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting empty object with x-obex/object-profile type\n"); (void) obexftp_get_type(cli, XOBEX_PROFILE, NULL, ""); rsp[7] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting telecom/devinfo.txt object\n"); cli->quirks = 0; (void) obexftp_get_type(cli, NULL, NULL, "telecom/devinfo.txt"); rsp[8] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("getting telecom/devinfo.txt object with setpath\n"); cli->quirks = (OBEXFTP_LEADING_SLASH | OBEXFTP_TRAILING_SLASH | OBEXFTP_SPLIT_SETPATH); (void) obexftp_get_type(cli, NULL, NULL, "telecom/devinfo.txt"); rsp[9] = cli->obex_rsp; printf("response code %02x\n", cli->obex_rsp); printf("=== response codes === %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5], rsp[6], rsp[7], rsp[8], rsp[9]); //cli_disconnect(); if (cli != NULL) { (void) obexftp_disconnect (cli); } } /* try the whole probing with different uuids */ static void probe_device() { printf("\n=== Probing with FBS uuid.\n"); probe_device_uuid(UUID_FBS, sizeof(UUID_FBS)); printf("\n=== Probing with S45 uuid.\n"); probe_device_uuid(UUID_S45, sizeof(UUID_S45)); printf("\n=== Probing without uuid.\n"); probe_device_uuid(NULL, 0); printf("\nEnd of probe.\n"); exit (0); } int main(int argc, char *argv[]) { int verbose = 0; int most_recent_cmd = 0; char *output_file = NULL; char *move_src = NULL; int ret = 0; /* preset mode of operation depending on our name */ if (strstr(argv[0], "ls") != NULL) most_recent_cmd = 'l'; if (strstr(argv[0], "get") != NULL) most_recent_cmd = 'g'; if (strstr(argv[0], "put") != NULL) most_recent_cmd = 'p'; if (strstr(argv[0], "rm") != NULL) most_recent_cmd = 'k'; /* preset the port from environment */ if (getenv(OBEXFTP_CHANNEL) != NULL) { channel = atoi(getenv(OBEXFTP_CHANNEL)); } if (channel >= 0) { transport = OBEX_TRANS_USB; fprintf(stderr, "Presetting to USB: %d\n", channel); } if (getenv(OBEXFTP_CABLE) != NULL) { device = getenv(OBEXFTP_CABLE); transport = OBEX_TRANS_CUSTOM; fprintf(stderr, "Presetting to TTY: %s\n", device); } if (getenv(OBEXFTP_BLUETOOTH) != NULL) { device = getenv(OBEXFTP_BLUETOOTH); transport = OBEX_TRANS_BLUETOOTH; fprintf(stderr, "Presetting to BT: %s (%d)\n", device, channel); } if (getenv(OBEXFTP_INET) != NULL) { device = getenv(OBEXFTP_INET); transport = OBEX_TRANS_INET; fprintf(stderr, "Presetting to INET: %s\n", device); } while (1) { int option_index = 0; static struct option long_options[] = { {"irda", no_argument, NULL, 'i'}, #ifdef HAVE_BLUETOOTH {"bluetooth", optional_argument, NULL, 'b'}, {"channel", required_argument, NULL, 'B'}, {"hci", required_argument, NULL, 'd'}, #endif #ifdef HAVE_USB {"usb", optional_argument, NULL, 'u'}, #endif {"tty", required_argument, NULL, 't'}, {"network", required_argument, NULL, 'n'}, {"uuid", optional_argument, NULL, 'U'}, {"noconn", no_argument, NULL, 'H'}, {"nopath", no_argument, NULL, 'S'}, {"timeout", required_argument, NULL, 'T'}, {"list", optional_argument, NULL, 'l'}, {"chdir", required_argument, NULL, 'c'}, {"mkdir", required_argument, NULL, 'C'}, {"output", required_argument, NULL, 'o'}, {"get", required_argument, NULL, 'g'}, {"getdelete", required_argument, NULL, 'G'}, {"put", required_argument, NULL, 'p'}, {"delete", required_argument, NULL, 'k'}, {"capability", no_argument, NULL, 'X'}, {"probe", no_argument, NULL, 'Y'}, {"info", no_argument, NULL, 'x'}, {"move", required_argument, NULL, 'm'}, {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, {"usage", no_argument, NULL, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "-ib::B:d:u::t:n:U::HST:L::l::c:C:f:o:g:G:p:k:XYxm:VvhN:FP", long_options, &option_index); if (c == -1) break; if (c == 1) c = most_recent_cmd; switch (c) { case 'i': transport = OBEX_TRANS_IRDA; device = NULL; channel = 0; break; #ifdef HAVE_BLUETOOTH case 'b': transport = OBEX_TRANS_BLUETOOTH; /* handle severed optional option argument */ if (!optarg && argc > optind && argv[optind][0] != '-') { optarg = argv[optind]; optind++; } device = optarg; break; case 'B': channel = atoi(optarg); break; case 'd': src_dev = optarg; break; #endif /* HAVE_BLUETOOTH */ #ifdef HAVE_USB case 'u': #ifndef _WIN32 if (geteuid() != 0) fprintf(stderr, "If USB doesn't work setup permissions in udev or run as superuser.\n"); #endif transport = OBEX_TRANS_USB; device = NULL; /* handle severed optional option argument */ if (!optarg && argc > optind && argv[optind][0] != '-') { optarg = argv[optind]; optind++; channel = atoi(optarg); } else { discover_usb(); } break; #endif /* HAVE_USB */ case 't': transport = OBEX_TRANS_CUSTOM; device = optarg; channel = 0; if (strstr(optarg, "ir") != NULL) fprintf(stderr, "Do you really want to use IrDA via ttys?\n"); break; case 'N': fprintf(stderr,"Option -%c is deprecated, use -%c instead\n",'N','n'); case 'n': transport = OBEX_TRANS_INET; device = optarg; channel = 0; { char *p; if ((p=strchr(optarg, ':'))) { *p = '\0'; channel = atoi(++p); } } { int n; if (sscanf(optarg, "%d.%d.%d.%d", &n, &n, &n, &n) != 4) fprintf(stderr, "Please use dotted quad notation.\n"); } break; case 'F': fprintf(stderr,"Option -%c is deprecated, use -%c instead\n",'F','U'); optarg = "none"; case 'U': /* handle severed optional option argument */ if (!optarg && argc > optind && argv[optind][0] != '-') { optarg = argv[optind]; optind++; } if (parse_uuid(optarg, &use_uuid, &use_uuid_len) < 0) fprintf(stderr, "Unknown UUID %s\n", optarg); break; case 'H': use_conn=0; break; case 'S': use_path=0; break; case 'T': timeout = atoi(optarg); if (timeout < 0) { fprintf(stderr, "timeout can't be less than 0. Using default.\n"); timeout = 20; } break; case 'L': /* handle severed optional option argument */ if (!optarg && argc > optind && argv[optind][0] != '-') { optarg = argv[optind]; optind++; } if (cli_connect() >= 0) { /* List folder */ stat_entry_t *ent; void *dir = obexftp_opendir(cli, optarg); while ((ent = obexftp_readdir(dir)) != NULL) { stat_entry_t *st; st = obexftp_stat(cli, ent->name); if (!st) continue; printf("%d %s%s\n", st->size, ent->name, ent->mode&S_IFDIR?"/":""); } obexftp_closedir(dir); } most_recent_cmd = c; break; case 'l': /* handle severed optional option argument */ if (!optarg && argc > optind && argv[optind][0] != '-') { optarg = argv[optind]; optind++; } if (cli_connect() >= 0) { /* List folder */ ret = obexftp_list(cli, NULL, optarg); } most_recent_cmd = c; break; case 'c': if (cli_connect() >= 0) { /* Change dir */ ret = obexftp_setpath(cli, optarg, 0); } most_recent_cmd = c; break; case 'C': if (cli_connect() >= 0) { /* Change or Make dir */ ret = obexftp_setpath(cli, optarg, 1); } most_recent_cmd = c; break; case 'o': output_file = optarg; break; case 'g': case 'G': if (cli_connect() >= 0) { char *p; /* basename or output_file */ if ((p = strrchr(optarg, '/')) != NULL) p++; else p = optarg; if (output_file) p = output_file; /* Get file */ ret = obexftp_get(cli, p, optarg); if (ret > 0 && c == 'G') ret = obexftp_del(cli, optarg); output_file = NULL; } most_recent_cmd = c; break; case 'p': if (cli_connect() >= 0) { char *p; /* basename or output_file */ if ((p = strrchr(optarg, '/')) != NULL) p++; else p = optarg; if (output_file) p = output_file; /* Send file */ ret = obexftp_put_file(cli, optarg, p); output_file = NULL; } most_recent_cmd = c; break; case 'k': if (cli_connect() >= 0) { /* Delete file */ ret = obexftp_del(cli, optarg); } most_recent_cmd = c; break; case 'X': if (cli_connect() >= 0) { /* Get capabilities */ ret = obexftp_get_capability(cli, optarg, 0); } most_recent_cmd = 'h'; // not really break; case 'P': fprintf(stderr,"Option -%c is deprecated, use -%c instead\n",'P','Y'); case 'Y': if (cli == NULL) probe_device(); fprintf(stderr, "No other transfer options allowed with --probe\n"); break; case 'x': if (cli_connect() >= 0) { /* for S65 */ (void) obexftp_disconnect (cli); (void) obexftp_connect_uuid (cli, device, channel, UUID_S45, sizeof(UUID_S45)); /* Retrieve Infos */ (void) obexftp_info(cli, 0x01); (void) obexftp_info(cli, 0x02); } most_recent_cmd = 'h'; // not really break; case 'm': most_recent_cmd = c; if (move_src == NULL) { move_src = optarg; break; } if (cli_connect() >= 0) { /* Rename a file */ ret = obexftp_rename(cli, move_src, optarg); } move_src = NULL; break; case 'v': verbose++; break; case 'V': printf("ObexFTP %s\n", VERSION); most_recent_cmd = 'h'; // not really break; case 'h': printf("ObexFTP %s\n", VERSION); printf("Usage: %s [ -i | -b [-B ] | -U | -t | -N ]\n" "[-c ...] [-C ] [-l []]\n" "[-g ...] [-p ...] [-k ...] [-x] [-m ...]\n" "Transfer files from/to Mobile Equipment.\n" "Copyright (c) 2002-2004 Christian W. Zuckschwerdt\n" "\n" " -i, --irda connect using IrDA transport (default)\n" #ifdef HAVE_BLUETOOTH " -b, --bluetooth [] use or search a bluetooth device\n" " [ -B, --channel ] use this bluetooth channel when connecting\n" " [ -d, --hci ] use source device with this address or number\n" #endif #ifdef HAVE_USB " -u, --usb [] connect to a usb interface or list interfaces\n" #endif " -t, --tty connect to this tty using a custom transport\n" " -n, --network connect to this host\n\n" " -U, --uuid use given uuid (none, FBS, IRMC, S45, SHARP)\n" " -H, --noconn suppress connection ids (no conn header)\n" " -S, --nopath dont use setpaths (use path as filename)\n" " -T, --timeout timeout transfer if no accept/reject received\n\n" " -c, --chdir chdir\n" " -C, --mkdir mkdir and chdir\n" " -l, --list [] list current/given folder\n" " -o, --output specify the target file name\n" " get and put always specify the remote name.\n" " -g, --get fetch files\n" " -G, --getdelete fetch and delete (move) files \n" " -p, --put send files\n" " -k, --delete delete files\n\n" " -X, --capability retrieve capability object\n" " -Y, --probe probe and report device characteristics\n" " -x, --info retrieve infos (Siemens)\n" " -m, --move move files (Siemens)\n\n" " -v, --verbose verbose messages\n" " -V, --version print version info\n" " -h, --help, --usage this help text\n" "\n", argv[0]); most_recent_cmd = 'h'; // not really break; default: printf("Try `%s --help' for more information.\n", argv[0]); } if (ret < 0) printf("The operation failed with return code %d\n", -ret); } if (most_recent_cmd == 0) fprintf(stderr, "Nothing to do. Use --help for help.\n"); if (optind < argc) { fprintf(stderr, "non-option ARGV-elements: "); while (optind < argc) fprintf(stderr, "%s ", argv[optind++]); fprintf(stderr, "\n"); } cli_disconnect (); exit (-ret); } obexftp-0.24-Source/apps/obexftpd.c100777 0 0 60723 12115454406 12437 0/** \file apps/obexftpd.c OBEX file server. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2003-2006 Christian W. Zuckschwerdt Alan Zhang Hendrik Sattler Frode Isaksen ObexFTP is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with ObexFTP. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #define S_IRGRP 0 #define S_IROTH 0 #define S_IWGRP 0 #define S_IWOTH 0 #define S_IXGRP 0 #define S_IXOTH 0 #define sleep(n) Sleep((n) * 1000) #define mkdir(dir,mode) _mkdir(dir) #define lstat stat #else #include #include #include #include #endif #include /* just until there is a server layer in obexftp */ #include #include #include #include #include /* define this to "", "\r\n" or "\n" */ #define EOLCHARS "\n" /* Application defined headers */ #define HDR_CREATOR 0xcf /* so we don't require OpenOBEX 1.3 */ #define WORK_PATH_MAX 128 #define CUR_DIR "./" static char *device = NULL; static int channel = 10; /* OBEX_PUSH_HANDLE */ static char init_work_path[WORK_PATH_MAX]; volatile int finished = 0; volatile int success = 0; volatile int obexftpd_reset = 0; uint32_t connection_id = 0; int verbose = 0; // this whole thing needs a review: static int parsehostport(const char *name, char **host, int *port) { struct hostent *e; char *p, *s; uint8_t n[4]; p = strdup(name); *port = 650; if ((s=strchr(p, ':'))) { *s = '\0'; *port = atoi(++s); } *host = "0.0.0.0"; if (sscanf(p, "%hhu.%hhu.%hhu.%hhu", &n[0], &n[1], &n[2], &n[3]) == 4) { *host = strdup(p); } else { e = gethostbyname(p); if (e) { *host = e->h_addr_list[0]; // inet_ntoa needed! } } free(p); return 0; } //BEGIN of compositor the folder listing XML document struct rawdata_stream { char *data; unsigned int block_size; unsigned int size; unsigned int max_size; }; static struct rawdata_stream* INIT_RAWDATA_STREAM(unsigned int size) { struct rawdata_stream *stream = malloc(sizeof(*stream)); if (NULL == stream) { return NULL; } stream->data = malloc(size); if (NULL == stream->data) { free(stream); return NULL; } memset(stream->data,0,size); stream->size = 0; stream->block_size = size; stream->max_size = size; return stream; } static int ADD_RAWDATA_STREAM_DATA(struct rawdata_stream *stream, const char *data) { char *databuf; unsigned int size; if (data == NULL) return 0; size = strlen(data); if (size == 0) return 0; if ((size + stream->size) >= stream->max_size) { while((size + stream->size) >= stream->max_size) { stream->max_size += stream->block_size; } databuf = realloc(stream->data, stream->max_size); if (NULL == databuf) { fprintf(stderr, "realloc() failed\n"); return -1; } stream->data = databuf; } strcat(stream->data, data); stream->size += size; return size; } static void FREE_RAWDATA_STREAM(struct rawdata_stream *stream) { free(stream->data); free(stream); } #define FL_XML_VERSION(stream) \ ADD_RAWDATA_STREAM_DATA(stream, "" EOLCHARS); #define FL_XML_TYPE(stream) \ ADD_RAWDATA_STREAM_DATA(stream, "" EOLCHARS); #define FL_XML_BODY_BEGIN(stream) \ ADD_RAWDATA_STREAM_DATA(stream, "" EOLCHARS); #define FL_XML_BODY_END(stream) \ ADD_RAWDATA_STREAM_DATA(stream, "" EOLCHARS); #define FL_XML_BODY_ITEM_BEGIN(stream) \ ADD_RAWDATA_STREAM_DATA(stream, "<"); #define FL_XML_BODY_ITEM_END(stream) \ ADD_RAWDATA_STREAM_DATA(stream, "/>" EOLCHARS); inline static void FL_XML_BODY_FOLDERNAME(struct rawdata_stream *stream, char *name) { ADD_RAWDATA_STREAM_DATA(stream, "folder name=\""); ADD_RAWDATA_STREAM_DATA(stream, name); ADD_RAWDATA_STREAM_DATA(stream, "\" "); } inline static void FL_XML_BODY_FILENAME(struct rawdata_stream *stream, char *name) { ADD_RAWDATA_STREAM_DATA(stream, "file name=\""); ADD_RAWDATA_STREAM_DATA(stream, name); ADD_RAWDATA_STREAM_DATA(stream, "\" "); } inline static void FL_XML_BODY_SIZE(struct rawdata_stream *stream, unsigned int size) { const char format[] = "size=\"%d\" "; char str_size[sizeof(format)+14]; snprintf(str_size,sizeof(str_size), format, size); ADD_RAWDATA_STREAM_DATA(stream, str_size); } inline static void FL_XML_BODY_PERM(struct rawdata_stream *stream, mode_t file, mode_t dir) { const char format[] = "user-perm=\"%s%s%s\" "; char str_perm[sizeof(format)]; snprintf(str_perm,sizeof(str_perm),format, (file & (S_IRUSR|S_IRGRP|S_IROTH)? "R": ""), (file & (S_IWUSR|S_IWGRP|S_IWOTH)? "W": ""), (dir & (S_IWUSR|S_IWGRP|S_IWOTH)? "D": "")); ADD_RAWDATA_STREAM_DATA(stream,str_perm); } inline static void FL_XML_BODY_TIME(struct rawdata_stream *stream, const char* type, time_t time) { struct tm* tm = gmtime(&time); char str_tm[sizeof("=\"yyyymmddThhmmssZ\" ")]; if (tm == NULL || stream == NULL || strftime(str_tm,sizeof(str_tm),"=\"%Y%m%dT%H%M%SZ\" ",tm) == 0) return; ADD_RAWDATA_STREAM_DATA(stream, type); ADD_RAWDATA_STREAM_DATA(stream, str_tm); } #define FL_XML_BODY_MTIME(stream,time) \ FL_XML_BODY_TIME(stream,"modified",time) #define FL_XML_BODY_CTIME(stream,time) \ FL_XML_BODY_TIME(stream,"created",time) #define FL_XML_BODY_ATIME(stream,time) \ FL_XML_BODY_TIME(stream,"accessed",time) //END of compositor the folder listing XML document inline static int is_type_fl(const char *type) { return (type && strcmp(type, XOBEX_LISTING) == 0); } static void connect_server(obex_t *handle, obex_object_t *object) { obex_headerdata_t hv; uint8_t hi; uint32_t hlen; uint8_t *target = NULL; int target_len = 0; //printf("%s()\n", __FUNCTION__); while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch(hi) { case OBEX_HDR_TARGET: if (0 < hlen) { if( (target = malloc(hlen))) { target_len = hlen; memcpy(target,hv.bs,target_len); } } break; default: printf("%s() Skipped header %02x\n", __FUNCTION__, hi); break; } } OBEX_ObjectSetRsp(object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS); hv.bq4 = connection_id; if(OBEX_ObjectAddHeader(handle, object, OBEX_HDR_CONNECTION, hv, sizeof(hv.bq4), OBEX_FL_FIT_ONE_PACKET) < 0 ) { fprintf(stderr, "Error adding header CONNECTION\n"); OBEX_ObjectDelete(handle, object); return; } if (target && target_len) { hv.bs = target; if(OBEX_ObjectAddHeader(handle,object,OBEX_HDR_WHO, hv,target_len,OBEX_FL_FIT_ONE_PACKET) < 0 ) { fprintf(stderr, "Error adding header WHO\n"); OBEX_ObjectDelete(handle, object); return; } free(target); } } static void set_server_path(obex_t *handle, obex_object_t *object) { char *name = NULL; char fullname[WORK_PATH_MAX]; // "Backup Level" and "Don't Create" flag in first byte uint8_t setpath_nohdr_dummy = 0; uint8_t *setpath_nohdr_data; obex_headerdata_t hv; uint8_t hi; uint32_t hlen; OBEX_ObjectGetNonHdrData(object, &setpath_nohdr_data); if (NULL == setpath_nohdr_data) { setpath_nohdr_data = &setpath_nohdr_dummy; printf("nohdr data not found\n"); } printf("nohdr data: %x\n", *setpath_nohdr_data); while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch(hi) { case OBEX_HDR_NAME: printf("%s() Found name\n", __FUNCTION__); if (0 < hlen) { if( (name = malloc(hlen / 2))) { UnicodeToChar((uint8_t*)name, hv.bs, hlen); printf("name:%s\n", name); } } else { if (verbose) printf("set path to root\n"); chdir(init_work_path); } break; default: printf("%s() Skipped header %02x\n", __FUNCTION__, hi); } } if (name) { if (strstr(name, "/../")) { OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_FORBIDDEN); } else { strcpy(fullname, CUR_DIR); strncat(fullname, name, sizeof(fullname)-1); if ((*setpath_nohdr_data & 2) == 0) { if (verbose) printf("mkdir %s\n", name); if (mkdir(fullname, 0755) < 0) { perror("requested mkdir failed"); } } if (verbose) printf("Set path to %s\n",fullname); if (chdir(fullname) < 0) { perror("requested chdir failed\n"); OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_FORBIDDEN); } } free(name); name = NULL; } } // // Get the filesize in a "portable" way // static int get_filesize(const char *filename) { struct stat stats; stat(filename, &stats); if (S_ISDIR(stats.st_mode)) { fprintf(stderr,"GET of directories not implemented !!!!\n"); return -1; } return (int) stats.st_size; } // // Read a file and alloc a buffer for it // static uint8_t* easy_readfile(const char *filename, int *file_size) { int actual; int fd; uint8_t *buf; *file_size = get_filesize(filename); printf("name=%s, size=%d\n", filename, *file_size); fd = open(filename, O_RDONLY, 0); if (fd == -1) { return NULL; } buf = malloc(*file_size); if(buf == NULL) { return NULL; } actual = read(fd, buf, *file_size); close(fd); *file_size = actual; return buf; } static void get_server(obex_t *handle, obex_object_t *object) { uint8_t *buf = NULL; obex_headerdata_t hv; uint8_t hi; uint32_t hlen; int file_size; char *name = NULL; char *type = NULL; printf("%s()\n", __FUNCTION__); while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch(hi) { case OBEX_HDR_NAME: printf("%s() Found name\n", __FUNCTION__); if( (name = malloc(hlen / 2))) { UnicodeToChar((uint8_t*)name, hv.bs, hlen); printf("name:%s\n", name); } break; case OBEX_HDR_TYPE: if( (type = malloc(hlen + 1))) { strcpy(type, (char *)hv.bs); } printf("%s() type:%s\n", __FUNCTION__, type); break; case 0xbe: // user-defined inverse push printf("%s() Found inverse push req\n", __FUNCTION__); printf("data:%02x\n", hv.bq1); break; case OBEX_HDR_APPARAM: printf("%s() Found apparam\n", __FUNCTION__); printf("name:%d (%02x %02x ...)\n", hlen, *hv.bs, *(hv.bs+1)); break; default: printf("%s() Skipped header %02x\n", __FUNCTION__, hi); } } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); if (is_type_fl(type)) { struct dirent *dirp; DIR *dp; struct stat statdir; struct stat statbuf; char *filename; struct rawdata_stream *xmldata; xmldata = INIT_RAWDATA_STREAM(512); if (NULL == xmldata) goto out; FL_XML_VERSION(xmldata); FL_XML_TYPE(xmldata); FL_XML_BODY_BEGIN(xmldata); stat(CUR_DIR, &statdir); dp = opendir(CUR_DIR); while(NULL != dp && NULL != (dirp = readdir(dp))) { if (0 == strcmp(dirp->d_name, ".") || 0 == strcmp(dirp->d_name, "..")) continue; FL_XML_BODY_ITEM_BEGIN(xmldata); //Adding 1 bytes due to containing '\0' filename = malloc(strlen(CUR_DIR) + strlen(dirp->d_name) + 1); strcpy(filename, CUR_DIR); strcat(filename, dirp->d_name); lstat(filename, &statbuf); if (0 == S_ISDIR(statbuf.st_mode)) //it is a file FL_XML_BODY_FILENAME(xmldata, dirp->d_name); else //it is a directory FL_XML_BODY_FOLDERNAME(xmldata, dirp->d_name); FL_XML_BODY_SIZE(xmldata, statbuf.st_size); FL_XML_BODY_PERM(xmldata, statbuf.st_mode, statdir.st_mode); FL_XML_BODY_MTIME(xmldata, statbuf.st_mtime); FL_XML_BODY_CTIME(xmldata, statbuf.st_ctime); FL_XML_BODY_ATIME(xmldata, statbuf.st_atime); FL_XML_BODY_ITEM_END(xmldata); //printf("---filename:%s\n", filename); //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); free(filename); filename = NULL; //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); FL_XML_BODY_END(xmldata); closedir(dp); printf("xml doc:%s\n", xmldata->data); //composite the obex obejct OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); hv.bq4 = xmldata->size; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hv, sizeof(uint32_t), 0); hv.bs = (uint8_t *)xmldata->data; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, xmldata->size, 0); //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); FREE_RAWDATA_STREAM(xmldata); //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); } else if (name) { printf("%s() Got a request for %s\n", __FUNCTION__, name); buf = easy_readfile(name, &file_size); if(buf == NULL) { printf("Can't find file %s\n", name); OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); return; } OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); hv.bq4 = file_size; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hv, sizeof(uint32_t), 0); hv.bs = buf; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, file_size, 0); } else { printf("%s() Got a GET without a name-header!\n", __FUNCTION__); OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); return; } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); if (NULL != buf) { free(buf); } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); out: if (NULL != name) { free(name); } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); if (NULL != type) { free(type); } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); return; } /* * Function safe_save_file () * * First remove path and add "/tmp/". Then save. * */ static int safe_save_file(char *name, const uint8_t *buf, int len) { char *s = NULL; char filename[255] = {0,}; int fd; int actual; printf("Filename = %s\n", name); s = strrchr(name, '/'); if (s == NULL) s = name; else s++; strncat(filename, s, 250); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if ( fd < 0) { perror( filename); return -1; } actual = write(fd, buf, len); close(fd); printf( "Wrote %s (%d bytes)\n", filename, actual); return actual; } /* * Function put_done() * * Parse what we got from a PUT * */ static void put_done(obex_t *handle, obex_object_t *object, int final) { obex_headerdata_t hv; uint8_t hi; uint32_t hlen; const uint8_t *body = NULL; int body_len = 0; static char *name = NULL; char fullname[WORK_PATH_MAX]; struct stat statbuf; //char *namebuf = NULL; fprintf(stderr, "put_done>>>\n"); while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch(hi) { case OBEX_HDR_BODY: body = hv.bs; body_len = hlen; fprintf(stderr, "hv.bs=%p, hlen=%d\n", hv.bs, hlen); break; case OBEX_HDR_NAME: if (NULL != name) { free(name); } if( (name = malloc(hlen / 2))) { UnicodeToChar((uint8_t *)name, hv.bs, hlen); fprintf(stderr, "put file name: %s\n", name); } break; case OBEX_HDR_LENGTH: printf("HEADER_LENGTH = %d\n", hv.bq4); break; case HDR_CREATOR: printf("CREATORID = %#x\n", hv.bq4); break; default: printf("%s () Skipped header %02x\n", __FUNCTION__ , hi); } } if(!body) { printf("Got a PUT without a body\n"); OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); } if(!name) { name = strdup("OBEX_PUT_Unknown_object"); printf("Got a PUT without a name. Setting name to %s\n", name); } if (body) { safe_save_file(name, body, body_len); } if(final && !body) { strcpy(fullname, CUR_DIR); strcat(fullname, name); if (!stat(fullname, &statbuf)) { perror("stat failed"); } if (S_ISDIR(statbuf.st_mode)) { printf("Removing dir %s\n", name); rmdir(fullname); } else { printf("Deleting file %s\n", name); unlink(fullname); } } if (final) { free(name); name = NULL; fprintf(stderr, "<<= strlen(progress)) i = 0; switch(obex_cmd) { case OBEX_CMD_PUT: fprintf(stderr, "obex_ev_progress: obex_cmd_put\n"); put_done(handle, obj, 0); break; default: break; } break; case OBEX_EV_ABORT: /* Request was aborted */ printf("%s() OBEX_EV_ABORT: mode=%02x, obex_cmd=%02x, obex_rsp=%02x\n", __func__, mode, obex_cmd, obex_rsp); break; case OBEX_EV_STREAMEMPTY: //(void) cli_fillstream(cli, object); break; case OBEX_EV_UNEXPECTED: /* Unexpected data, not fatal */ break; default: printf("%s() Unhandled event %d\n", __func__, event); break; } } static void start_server(int transport) { int use_sdp = 0; obex_t *handle = NULL; struct sockaddr_in saddr; if (NULL == getcwd(init_work_path, WORK_PATH_MAX) && ERANGE == errno) { fprintf(stderr, "Wah, work path is too long, exceed %d.\n", WORK_PATH_MAX); exit(0); } if (transport==OBEX_TRANS_BLUETOOTH && (0 > obexftp_sdp_register_push(channel) || 0 > obexftp_sdp_register_ftp(channel))) { //OBEX_Cleanup(handle); fprintf(stderr, "register to SDP Server failed.\n"); } else { use_sdp = 1; } reset: handle = OBEX_Init(transport, obex_event, 0); if (NULL == handle) { perror("failed to init obex."); exit(-1); } switch (transport) { case OBEX_TRANS_INET: saddr.sin_family = AF_INET; saddr.sin_port = htons(channel); #ifdef _WIN32 saddr.sin_addr.s_addr = inet_addr(device); #else (void) inet_aton(device, &saddr.sin_addr); #endif if (0 > TcpOBEX_ServerRegister(handle, (struct sockaddr *)&saddr, sizeof(saddr))) { perror("failed to register inet server"); exit(-1); } break; #ifdef HAVE_BLUETOOTH case OBEX_TRANS_BLUETOOTH: if (0 > BtOBEX_ServerRegister(handle, /*bdaddr_t *bt_src*/NULL, channel)) { perror("failed to register bluetooth server"); exit(-1); } break; #endif case OBEX_TRANS_IRDA: if (0 > IrOBEX_ServerRegister(handle, "")) { perror("failed to register IrDA server"); exit(-1); } break; case OBEX_TRANS_CUSTOM: /* A simple Ericsson protocol session perhaps? */ default: fprintf(stderr, "Transport type unknown\n"); exit(-1); } printf("Waiting for connection...\n"); while (!finished) { //printf("Handling connection...\n"); OBEX_HandleInput(handle, -1); } OBEX_Cleanup(handle); sleep(1); /* throttle */ if (obexftpd_reset) { fprintf(stderr, "obexftpd reset\n"); obexftpd_reset = 0; finished = 0; success = 0; goto reset; } if (use_sdp) { fprintf(stderr, "sdp unregister\n"); if (0 > obexftp_sdp_unregister_push() || 0 > obexftp_sdp_unregister_ftp()) { fprintf(stderr, "unregister from SDP Server failed.\n"); } } } int main(int argc, char *argv[]) { int c; while (1) { int option_index = 0; static struct option long_options[] = { {"irda", no_argument, NULL, 'i'}, {"bluetooth", optional_argument, NULL, 'b'}, {"tty", required_argument, NULL, 't'}, {"network", required_argument, NULL, 'n'}, {"chdir", required_argument, NULL, 'c'}, {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, {"usage", no_argument, NULL, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "-ib::t:n:c:vVh", long_options, &option_index); if (c == -1) break; switch (c) { case 'i': start_server(OBEX_TRANS_IRDA); break; case 'b': if (optarg) { channel = atoi(optarg); } start_server(OBEX_TRANS_BLUETOOTH); fprintf(stderr, "server end\n"); break; case 'n': parsehostport(optarg, &device, &channel); //channel = atoi(optarg); start_server(OBEX_TRANS_INET); fprintf(stderr, "server end\n"); break; case 't': printf("accepting on tty not implemented yet."); /* start_server(OBEX_TRANS_CUSTOM); optarg */ break; case 'c': chdir(optarg); break; case 'v': verbose++; break; case 'V': printf("ObexFTPd %s\n", VERSION); break; case 'h': printf("ObexFTPd %s\n", VERSION); printf("Usage: %s [-c ] [-v] [-i | -b | -t | -n ]\n" "Recieve files from/to Mobile Equipment.\n" "Copyright (c) 2003-2006 Christian W. Zuckschwerdt, Alan Zhang,\n" " Hendrik Sattler, Frode Isaksen\n" "\n" " -i, --irda accept IrDA connections\n" " -b, --bluetooth [] accept bluetooth connections\n" " -t, --tty accept connections from this tty\n" " -n, --network accept network connections\n" "\n" " -c, --chdir set a default basedir\n" " -v, --verbose verbose messages\n" "\n" " -V, --version print version info\n" " -h, --help, --usage this help text\n", argv[0]); exit(0); default: printf("Try `%s --help' for more information.\n", argv[0]); } } if (optind < argc) { fprintf(stderr, "non-option ARGV-elements: "); while (optind < argc) fprintf(stderr, "%s ", argv[optind++]); fprintf(stderr, "\n"); exit (-1); } exit (0); } obexftp-0.24-Source/AUTHORS100777 0 0 124 12115454406 10512 0Christian W. Zuckschwerdt Hendrik Sattler obexftp-0.24-Source/bfb/ 40777 0 0 0 12115602310 10103 5obexftp-0.24-Source/bfb/bfb.c100777 0 0 31533 12115454406 11140 0/** \file bfb/bfb.c BFB transport encapsulation (used for Siemens mobile equipment). ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include /* htons */ #ifdef _WIN32 #include #include /* for endianess */ #else #include #endif #include "crc.h" #include "bfb.h" #include /* Provide convenience macros for handling structure * fields through their offsets. */ #define STRUCT_OFFSET(struct_type, member) \ ((uint64_t) ((char*) &((struct_type*) 0)->member)) #define STRUCT_MEMBER_P(struct_p, struct_offset) \ ((void *) ((char*) (struct_p) + (uint64_t) (struct_offset))) #define STRUCT_MEMBER(member_type, struct_p, struct_offset) \ (*(member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset))) /* mobile need little-endianess always */ /* Solaris: _LITTLE_ENDIAN / _BIG_ENDIAN */ /* Linux: */ #if (BYTE_ORDER == LITTLE_ENDIAN) || defined (_LITTLE_ENDIAN) #define htoms(A) (A) #define htoml(A) (A) #define mtohs(A) (A) #define mtohl(A) (A) #elif (BYTE_ORDER == BIG_ENDIAN) || defined (_BIG_ENDIAN) #define htoms(A) ((((uint16_t)(A) & 0xff00) >> 8) | \ (((uint16_t)(A) & 0x00ff) << 8)) #define htoml(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \ (((uint32_t)(A) & 0x00ff0000) >> 8) | \ (((uint32_t)(A) & 0x0000ff00) << 8) | \ (((uint32_t)(A) & 0x000000ff) << 24)) #define mtohs htoms #define mtohl htoml #else #error "BYTE_ORDER needs to be either BIG_ENDIAN or LITTLE_ENDIAN." #endif /** Returns the whole buffer folded with xor. */ uint8_t bfb_checksum(uint8_t *data, int len) { int i; uint8_t chk = 0; for (i=0; i < len; i++) chk ^= data[i]; return chk; } /** Stuff data frame into serial cable encapsulation. buffer needs to be of at leaset len+7 size Type 0x01: "prepare" command. Type 0x02: first transmission in a row. Type 0x03: continued transmission. seq needs to be incremented afterwards. */ int bfb_stuff_data(uint8_t *buffer, uint8_t type, uint8_t *data, uint16_t len, uint8_t seq) { int i; union { uint16_t value; uint8_t bytes[2]; } fcs; /* special case: "attention" packet */ if (type == 1) { buffer[0] = 0x01; buffer[1] = ~buffer[0]; return 2; } /* error */ if (type != 2 && type != 3) { buffer[0] = 0x00; /* just terminate the buffer */ return 0; } buffer[0] = type; buffer[1] = ~buffer[0]; buffer[2] = seq; fcs.value = htons(len); buffer[3] = fcs.bytes[0]; buffer[4] = fcs.bytes[1]; /* copy data */ memcpy(&buffer[5], data, len); /* gen CRC */ fcs.value = INIT_FCS; for (i=2; i < len+5; i++) { fcs.value = irda_fcs(fcs.value, buffer[i]); } fcs.value = ~fcs.value; /* append CRC to packet */ /* fcs.value = htons(fcs.value); */ buffer[len+5] = fcs.bytes[0]; buffer[len+6] = fcs.bytes[1]; return len+7; } /** Send a cmd, subcmd packet, add chk (no parameters). */ int bfb_write_subcmd(fd_t fd, uint8_t type, uint8_t subtype) { uint8_t buffer[2]; buffer[0] = subtype; buffer[1] = bfb_checksum(buffer, 1); return bfb_write_packets(fd, type, buffer, 2); } /** Send a cmd, subcmd packet. */ int bfb_write_subcmd0(fd_t fd, uint8_t type, uint8_t subtype) { return bfb_write_packets(fd, type, &subtype, 1); } /** Send a cmd, subcmd, data packet. */ int bfb_write_subcmd8(fd_t fd, uint8_t type, uint8_t subtype, uint8_t p1) { uint8_t buffer[2]; buffer[0] = subtype; buffer[1] = p1; return bfb_write_packets(fd, type, buffer, 2); } /** Send a cmd, subcmd packet, add chk (one word parameter). */ int bfb_write_subcmd1(fd_t fd, uint8_t type, uint8_t subtype, uint16_t p1) { uint8_t buffer[4]; buffer[0] = subtype; p1 = htoms(p1); /* mobile need little-endianess always */ buffer[1] = STRUCT_MEMBER(uint8_t, &p1, 0); buffer[2] = STRUCT_MEMBER(uint8_t, &p1, 1); buffer[3] = bfb_checksum(buffer, 3); DEBUG(3, "buf: %x %x %x %x\n", buffer[0], buffer[1], buffer[2], buffer[3]); return bfb_write_packets(fd, type, buffer, 4); } /** Send a cmd, subcmd packet, add chk (two word parameter). */ int bfb_write_subcmd2(fd_t fd, uint8_t type, uint8_t subtype, uint16_t p1, uint16_t p2) { uint8_t buffer[6]; buffer[0] = subtype; p1 = htoms(p1); /* mobile need little-endianess always */ buffer[1] = STRUCT_MEMBER(uint8_t, &p1, 0); buffer[2] = STRUCT_MEMBER(uint8_t, &p1, 1); p2 = htoms(p2); /* mobile need little-endianess always */ buffer[3] = STRUCT_MEMBER(uint8_t, &p2, 0); buffer[4] = STRUCT_MEMBER(uint8_t, &p2, 1); buffer[5] = bfb_checksum(buffer, 5); DEBUG(3, "buf: %x %x %x %x %x %x\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); return bfb_write_packets(fd, type, buffer, 6); } /** Send a cmd, subcmd packet, add chk (three word parameter). */ int bfb_write_subcmd3(fd_t fd, uint8_t type, uint8_t subtype, uint16_t p1, uint16_t p2, uint16_t p3) { uint8_t buffer[8]; buffer[0] = subtype; p1 = htoms(p1); /* mobile need little-endianess always */ buffer[1] = STRUCT_MEMBER(uint8_t, &p1, 0); buffer[2] = STRUCT_MEMBER(uint8_t, &p1, 1); p2 = htoms(p2); /* mobile need little-endianess always */ buffer[3] = STRUCT_MEMBER(uint8_t, &p2, 0); buffer[4] = STRUCT_MEMBER(uint8_t, &p2, 1); p3 = htoms(p3); /* mobile need little-endianess always */ buffer[5] = STRUCT_MEMBER(uint8_t, &p3, 0); buffer[6] = STRUCT_MEMBER(uint8_t, &p3, 1); buffer[7] = bfb_checksum(buffer, 7); DEBUG(3, "buf: %x %x %x %x %x %x %x %x\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); return bfb_write_packets(fd, type, buffer, 8); } /** Send a cmd, subcmd packet, add long, word parameter. */ int bfb_write_subcmd_lw(fd_t fd, uint8_t type, uint8_t subtype, uint32_t p1, uint16_t p2) { uint8_t buffer[8]; buffer[0] = subtype; p1 = htoml(p1); /* mobile need little-endianess always */ buffer[1] = STRUCT_MEMBER(uint8_t, &p1, 0); buffer[2] = STRUCT_MEMBER(uint8_t, &p1, 1); buffer[3] = STRUCT_MEMBER(uint8_t, &p1, 2); buffer[4] = STRUCT_MEMBER(uint8_t, &p1, 3); p2 = htoms(p2); /* mobile need little-endianess always */ buffer[5] = STRUCT_MEMBER(uint8_t, &p2, 0); buffer[6] = STRUCT_MEMBER(uint8_t, &p2, 1); buffer[7] = bfb_checksum(buffer, 7); DEBUG(3, "buf: %02x %02x %02x %02x %02x %02x %02x\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6]); return bfb_write_packets(fd, type, buffer, 7); /* no chk? */ } /** Send actual packets. Patch from Jorge Ventura to handle EAGAIN from write. */ int bfb_write_packets(fd_t fd, uint8_t type, uint8_t *buffer, int length) { bfb_frame_t *frame; int i; int l; struct timeval timeout; fd_set fds; int rc; #ifdef _WIN32 DWORD actual; #else int actual; #endif #ifdef _WIN32 return_val_if_fail (fd != INVALID_HANDLE_VALUE, FALSE); #else return_val_if_fail (fd > 0, FALSE); #endif /* select setup */ FD_ZERO(&fds); FD_SET(fd, &fds); /* alloc frame buffer */ frame = malloc((length > MAX_PACKET_DATA ? MAX_PACKET_DATA : length) + sizeof (bfb_frame_t)); if (frame == NULL) return -1; for(i=0; i MAX_PACKET_DATA) l = MAX_PACKET_DATA; frame->type = type; frame->len = l; frame->chk = frame->type ^ frame->len; memcpy(frame->payload, &buffer[i], l); /* Set time limit. */ timeout.tv_sec = 1; timeout.tv_usec = 0; /* actual = bfb_io_write(fd, frame, l + sizeof (bfb_frame_t)); */ rc = select(fd+1, NULL, &fds, NULL, &timeout); if ( rc > 0) { #ifdef _WIN32 if(!WriteFile(fd, frame, l + sizeof (bfb_frame_t), &actual, NULL)) { DEBUG(2, "%s() Write error: %ld\n", __func__, actual); } #else actual = write(fd, frame, l + sizeof (bfb_frame_t)); #endif DEBUG(3, "%s() Wrote %d bytes (expected %lu)\n", __func__, actual, (unsigned long)(l + sizeof (bfb_frame_t))); if (actual < 0 || actual < l + (int) sizeof (bfb_frame_t)) { DEBUG(1, "%s() Write failed\n", __func__); free(frame); return -1; } } else { /* ! rc > 0*/ DEBUG(1, "%s() Select failed\n", __func__); free(frame); return -1; } } free(frame); return i / MAX_PACKET_DATA; } /** Stuff data into packet buffers and send all packets. */ int bfb_send_data(fd_t fd, uint8_t type, uint8_t *data, uint16_t length, uint8_t seq) { uint8_t *buffer; int actual; buffer = malloc(length + 7); if (buffer == NULL) return -1; actual = bfb_stuff_data(buffer, type, data, length, seq); DEBUG(3, "%s() Stuffed %d bytes\n", __func__, actual); actual = bfb_write_packets(fd, BFB_FRAME_DATA, buffer, actual); DEBUG(3, "%s() Wrote %d packets\n", __func__, actual); free(buffer); return actual; } /** Retrieve actual packets. */ /*@null@*/ bfb_frame_t *bfb_read_packets(uint8_t *buffer, int *length) { bfb_frame_t *frame; int l; DEBUG(3, "%s() \n", __func__); if (*length < 0) { DEBUG(1, "%s() Wrong length?\n", __func__); return NULL; } if (*length == 0) { DEBUG(1, "%s() No packet?\n", __func__); return NULL; } if (*length < (int) sizeof(bfb_frame_t)) { DEBUG(1, "%s() Short packet?\n", __func__); return NULL; } /* temp frame */ frame = (bfb_frame_t *)buffer; if ((frame->type ^ frame->len) != frame->chk) { DEBUG(1, "%s() Header error?\n", __func__); DEBUGBUFFER(buffer, *length); return NULL; } if (*length < frame->len + (int) sizeof(bfb_frame_t)) { DEBUG(2, "%s() Need more data?\n", __func__); return NULL; } /* copy frame from buffer */ l = sizeof(bfb_frame_t) + frame->len; frame = malloc(l); if (frame == NULL) return NULL; memcpy(frame, buffer, l); /* remove frame from buffer */ *length -= l; memmove(buffer, &buffer[l], *length); DEBUG(3, "%s() Packet 0x%02x (%d bytes)\n", __func__, frame->type, frame->len); return frame; } /** Append BFB frame to a data buffer. */ int bfb_assemble_data(bfb_data_t **data, int *size, int *len, bfb_frame_t *frame) { bfb_data_t *tmp; int l; DEBUG(3, "%s() \n", __func__); if (frame->type != BFB_FRAME_DATA) { DEBUG(1, "%s() Wrong frame type (0x%02x)?\n", __func__, frame->type); return -1; } /* temp data */ tmp = (bfb_data_t *)frame->payload; if ((*len == 0) && (tmp->cmd == BFB_DATA_ACK)) { DEBUG(3, "%s() Skipping ack\n", __func__); return 0; } /* copy frame from buffer */ DEBUG(3, "%s() data: %d + frame: %d\n", __func__, *len, frame->len); l = *len + frame->len; if (l > *size) { DEBUG(1, "%s() data buffer to small, realloc'ing\n", __func__); *data = realloc(*data, l); *size = l; } /* memcpy(ret, *data, *len); */ memcpy(&((uint8_t *)*data)[*len], frame->payload, frame->len); /* free(*data); */ *len = l; return 1; } /** Check if data buffer is complete and valid. */ int bfb_check_data(bfb_data_t *data, int len) { int i; union { uint16_t value; uint8_t bytes[2]; } l; uint8_t inv_chk; DEBUG(3, "%s() \n", __func__); if (data == NULL) return -1; if (len < (int) sizeof(bfb_data_t)) return 0; DEBUG(3, "%s() cmd: 0x%02x, chk: 0x%02x, seq: %d\n", __func__, data->cmd, data->chk, data->seq); inv_chk = ~data->chk; if (data->cmd != inv_chk) { DEBUG(1, "%s() Broken data?\n", __func__); DEBUGBUFFER(data, len); } if ((data->cmd != BFB_DATA_FIRST) && (data->cmd != BFB_DATA_NEXT)) { DEBUG(1, "%s() Wrong data type (0x%02x)?\n", __func__, data->cmd); return -1; } l.bytes[0] = data->len0; l.bytes[1] = data->len1; l.value = htons(l.value); DEBUG(3, "%s() fragment size %d, payload %lu of indicated %d\n", __func__, len, (unsigned long)(len - sizeof(bfb_data_t)), l.value); if (len-(int)sizeof(bfb_data_t) < (int)(l.value) + /*crc*/ 2) return 0; /* check CRC */ l.value = INIT_FCS; for (i=2; i < len-2; i++) { l.value = irda_fcs(l.value, ((uint8_t *)data)[i]); } l.value = ~l.value; if ((((uint8_t *)data)[len-2] != l.bytes[0]) || (((uint8_t *)data)[len-1] != l.bytes[1])) { DEBUG(1, "%s() CRC-ERROR %02x %02x vs %02x %02x\n", __func__, ((uint8_t *)data)[len-2], ((uint8_t *)data)[len-1], l.bytes[0], l.bytes[1]); } DEBUG(2, "%s() data ready!\n", __func__); return 1; } obexftp-0.24-Source/bfb/bfb.h100777 0 0 6776 12115454406 11140 0/** \file bfb/bfb.h BFB transport encapsulation (used for Siemens mobile equipment). ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef BFB_H #define BFB_H #include #ifdef __cplusplus extern "C" { #endif #ifdef _WIN32 #include typedef HANDLE fd_t; #else typedef int fd_t; #endif #pragma pack(1) typedef struct { uint8_t type; uint8_t len; uint8_t chk; uint8_t payload[0]; /* ... up to 32 */ /* uint8_t xor; ? */ } bfb_frame_t; #pragma pack() #pragma pack(1) typedef struct { uint8_t cmd; uint8_t chk; uint8_t seq; uint8_t len0; uint8_t len1; uint8_t data[0]; /* ... up to 518 ? */ /* uint16_t crc; */ } bfb_data_t; #pragma pack() #define BFB_FRAME_CONNECT 0x02 /* ^B */ #define BFB_FRAME_INTERFACE 0x01 /* ^A */ #define BFB_FRAME_KEY 0x05 /* ^E */ #define BFB_FRAME_AT 0x06 /* ^F */ #define BFB_FRAME_EEPROM 0x14 /* ^N */ #define BFB_FRAME_DATA 0x16 /* ^P */ #define BFB_CONNECT_HELLO 0x14 /* ^N */ #define BFB_CONNECT_HELLO_ACK 0xaa #define BFB_KEY_PRESS 0x06 /* ^F */ #define MAX_PACKET_DATA 32 #define BFB_DATA_ACK 0x01 /* aka ok */ #define BFB_DATA_FIRST 0x02 /* first transmission in a row */ #define BFB_DATA_NEXT 0x03 /* continued transmission */ uint8_t bfb_checksum(uint8_t *data, int len); int bfb_write_subcmd(fd_t fd, uint8_t type, uint8_t subtype); int bfb_write_subcmd0(fd_t fd, uint8_t type, uint8_t subtype); int bfb_write_subcmd8(fd_t fd, uint8_t type, uint8_t subtype, uint8_t p1); int bfb_write_subcmd1(fd_t fd, uint8_t type, uint8_t subtype, uint16_t p1); int bfb_write_subcmd2(fd_t fd, uint8_t type, uint8_t subtype, uint16_t p1, uint16_t p2); int bfb_write_subcmd3(fd_t fd, uint8_t type, uint8_t subtype, uint16_t p1, uint16_t p2, uint16_t p3); int bfb_write_subcmd_lw(fd_t fd, uint8_t type, uint8_t subtype, uint32_t p1, uint16_t p2); int bfb_stuff_data(/*@out@*/ uint8_t *buffer, uint8_t type, uint8_t *data, uint16_t len, uint8_t seq); int bfb_write_packets(fd_t fd, uint8_t type, uint8_t *buffer, int length); #define bfb_write_at(fd, data) \ bfb_write_packets(fd, BFB_FRAME_AT, (uint8_t *)data, strlen(data)) #define bfb_write_key(fd, data) \ bfb_write_subcmd8(fd, BFB_FRAME_KEY, BFB_KEY_PRESS, data) int bfb_send_data(fd_t fd, uint8_t type, uint8_t *data, uint16_t length, uint8_t seq); #define bfb_send_ack(fd) \ bfb_send_data(fd, BFB_DATA_ACK, NULL, 0, 0) #define bfb_send_first(fd, data, length) \ bfb_send_data(fd, BFB_DATA_FIRST, data, length, 0) #define bfb_send_next(fd, data, length, seq) \ bfb_send_data(fd, BFB_DATA_NEXT, data, length, seq) /*@null@*/ bfb_frame_t * bfb_read_packets(uint8_t *buffer, int *length); int bfb_assemble_data(/*@null@*/ /*@out@*/ bfb_data_t **data, int *size, int *len, bfb_frame_t *frame); int bfb_check_data(bfb_data_t *data, int len); #ifdef __cplusplus } #endif #endif /* BFB_H */ obexftp-0.24-Source/bfb/bfb_io.c100777 0 0 35330 12115454406 11626 0/** \file bfb/bfb_io.c BFB transport encapsulation (for Siemens mobile equipment). ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include #include #include #ifdef _WIN32 #include #define sleep(n) Sleep(n*1000) #else #include #include #endif #include "bfb.h" #include "bfb_io.h" #include /* Write out an IO buffer */ int bfb_io_write(fd_t fd, const void *buffer, int length) { #ifdef _WIN32 DWORD bytes; DEBUG(3, "%s() WriteFile\n", __func__); if (fd == INVALID_HANDLE_VALUE) { DEBUG(1, "%s() Error INVALID_HANDLE_VALUE\n", __func__); return -1; } if(!WriteFile(fd, buffer, length, &bytes, NULL)) DEBUG(1, "%s() Write error: %ld\n", __func__, bytes); return bytes; #else int bytes; if (fd <= 0) { DEBUG(1, "%s() Error file handle invalid\n", __func__); return -1; } bytes = write(fd, buffer, length); if (bytes < length) DEBUG(1, "%s() Error short write (%d / %d)\n", __func__, bytes, length); if (bytes < 0) DEBUG(1, "%s() Error writing to port\n", __func__); return bytes; #endif } /* Read an answer to an IO buffer of max length bytes */ int bfb_io_read(fd_t fd, void *buffer, int length, int timeout) { #ifdef _WIN32 DWORD bytes; DEBUG(3, "%s() ReadFile\n", __func__); return_val_if_fail (fd != INVALID_HANDLE_VALUE, -1); if (!ReadFile(fd, buffer, length, &bytes, NULL)) { DEBUG(2, "%s() Read error: %ld\n", __func__, bytes); } return bytes; #else struct timeval time; fd_set fdset; int actual; return_val_if_fail (fd > 0, -1); time.tv_sec = timeout; time.tv_usec = 0; FD_ZERO(&fdset); FD_SET(fd, &fdset); if(select(fd+1, &fdset, NULL, NULL, &time)) { actual = read(fd, buffer, length); if (actual < 0) { DEBUG(2, "%s() Read error: %d\n", __func__, actual); } return actual; } else { DEBUG(1, "%s() No data (timeout: %d)\n", __func__, timeout); return 0; } #endif } /** Read (repeatedly) from fd until a timeout or an error is encountered. */ static int bfb_io_read_all(int fd, char *buffer, int length, int timeout) { int actual; int pos = 0; for (;;) { actual = bfb_io_read(fd, &buffer[pos], length - pos, timeout); if (actual < 0) return actual; if (actual == 0) return pos; pos += actual; } } /* Send an BFB init command an check for a valid answer frame */ int bfb_io_init(fd_t fd) { int actual; int tries=3; bfb_frame_t *frame = NULL; uint8_t rspbuf[200]; int rsplen; uint8_t init_magic = BFB_CONNECT_HELLO; uint8_t init_magic2 = BFB_CONNECT_HELLO_ACK; /* uint8_t speed115200[] = {0xc0,'1','1','5','2','0','0',0x13,0xd2,0x2b}; uint8_t sifs[] = {'a','t','^','s','i','f','s',0x13}; */ #ifdef _WIN32 return_val_if_fail (fd != INVALID_HANDLE_VALUE, FALSE); #else return_val_if_fail (fd > 0, FALSE); #endif while (!frame && tries-- > 0) { actual = bfb_write_packets (fd, BFB_FRAME_CONNECT, &init_magic, sizeof(init_magic)); DEBUG(2, "%s() Wrote %d packets\n", __func__, actual); if (actual < 1) { DEBUG(1, "BFB port error\n"); return FALSE; } rsplen = 0; while (!frame && actual > 0) { actual = bfb_io_read(fd, &rspbuf[rsplen], sizeof(rspbuf)-rsplen, 2); DEBUG(2, "%s() Read %d bytes\n", __func__, actual); if (actual < 0) { DEBUG(1, "BFB read error\n"); return FALSE; } if (actual == 0) { DEBUG(1, "BFB read timeout\n"); } rsplen += actual; frame = bfb_read_packets(rspbuf, &rsplen); DEBUG(2, "%s() Unstuffed, %d bytes remaining\n", __func__, rsplen); } } if (frame == NULL) { DEBUG(1, "BFB init error\n"); return FALSE; } DEBUG(2, "BFB init ok.\n"); if ((frame->len == 2) && (frame->payload[0] == init_magic) && (frame->payload[1] == init_magic2)) { free(frame); return TRUE; } DEBUG(1, "Error doing BFB init (%d, %x %x)\n", frame->len, frame->payload[0], frame->payload[1]); free(frame); return FALSE; } /** Send an AT-command and expect an answer of one or more lines. \note Start your command with "AT" and terminate it with "\r" (CR). \note The expected lines are the the echo, one optional information response and a final result code of "OK" or "ERROR". */ int do_at_cmd(fd_t fd, const char *cmd, char *rspbuf, int rspbuflen) { #ifdef _WIN32 DWORD actual; #else int actual; #endif char *answer = NULL; int answer_size; char tmpbuf[100] = {0,}; unsigned int total = 0; int cmdlen; return_val_if_fail (cmd != NULL, -1); cmdlen = strlen(cmd); rspbuf[0] = 0; DEBUG(3, "%s() Sending %d: %s\n", __func__, cmdlen, cmd); /* Write command */ if (bfb_io_write(fd, cmd, cmdlen) < cmdlen) return -1; actual = 1; while (actual > 0) { actual = bfb_io_read(fd, &tmpbuf[total], sizeof(tmpbuf) - total, 2); if (actual < 0) /* error checking */ return actual; total += actual; tmpbuf[total] = '\0'; /* terminate the string, always */ DEBUG(3, "%s() tmpbuf=%d: %s\n", __func__, total, tmpbuf); /* Answer not found within 100 bytes. Cancel */ if (total >= sizeof(tmpbuf)) return -1; /* Remove first line (echo), then search final result code */ for (answer = tmpbuf; answer && *answer ; ) { while ((*answer != '\r') && (*answer != '\n') && (*answer != '\0')) answer++; while ((*answer == '\r') || (*answer == '\n')) answer++; if (!strncmp(answer, "OK\r", 3) || !strncmp(answer, "ERROR\r", 6) || !strncmp(answer, "OK\n", 3) || !strncmp(answer, "ERROR\n", 6)) { actual = 0; /* we are done */ } } } /* try hard to discard remaing CR/LF */ if (total > 0 && tmpbuf[total-1] != '\n') actual = bfb_io_read(fd, &tmpbuf[total], sizeof(tmpbuf) - total, 2); /* Remove echo and trailing CRs */ answer = strchr(tmpbuf, '\r'); if (!answer) /* no echo found */ return -1; while (*answer == '\r' || *answer == '\n') answer++; answer_size = 0; while (answer[answer_size] != '\0' && answer[answer_size] != '\r' && answer[answer_size] != '\n') answer_size++; DEBUG(3, "%s() Answer (size=%d): %s\n", __func__, answer_size, answer); if( (answer_size) >= rspbuflen ) return -1; strncpy(rspbuf, answer, answer_size); rspbuf[answer_size] = '\0'; return 0; } /* close the connection */ void bfb_io_close(fd_t fd, int force) { DEBUG(3, "%s()\n", __func__); #ifdef _WIN32 return_if_fail (fd != INVALID_HANDLE_VALUE); #else return_if_fail (fd > 0); #endif /* we don't know if it's a BFB type link, don't send */ /* bfb_write_at(fd, "at^sbfb=0\r"); */ if(force) { /* Send a break to get out of OBEX-mode */ #ifdef _WIN32 if(SetCommBreak(fd) != TRUE) { #elif defined(TCSBRKP) if(ioctl(fd, TCSBRKP, 0) < 0) { #elif defined(TCSBRK) if(ioctl(fd, TCSBRK, 0) < 0) { #else if(tcsendbreak(fd, 0) < 0) { #endif DEBUG(1, "Unable to send break!\n"); } sleep(1); } #ifdef _WIN32 CloseHandle(fd); #else close(fd); #endif } /* Init the phone and set it in BFB-mode */ /* Returns fd or -1 on failure */ fd_t bfb_io_open(const char *ttyname, enum trans_type *typeinfo) { char rspbuf[200]; int actual; #ifdef _WIN32 HANDLE ttyfd; DCB dcb; COMMTIMEOUTS ctTimeOuts; return_val_if_fail (ttyname != NULL, INVALID_HANDLE_VALUE); DEBUG(3, "%s() CreateFile\n", __func__); ttyfd = CreateFile (ttyname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (ttyfd == INVALID_HANDLE_VALUE) { DEBUG(1, "Error: CreateFile()\n"); return INVALID_HANDLE_VALUE; } if(!GetCommState(ttyfd, &dcb)) { DEBUG(1, "Error: GetCommState()\n"); } dcb.fBinary = TRUE; dcb.BaudRate = CBR_57600; dcb.fParity = FALSE; dcb.Parity = NOPARITY; dcb.ByteSize = 8; dcb.StopBits = ONESTOPBIT; dcb.fInX = FALSE; dcb.fOutX = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fOutxCtsFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fRtsControl = RTS_CONTROL_ENABLE; if(!SetCommState(ttyfd, &dcb)) DEBUG(1, "SetCommState failed\n"); ctTimeOuts.ReadIntervalTimeout = 250; ctTimeOuts.ReadTotalTimeoutMultiplier = 1; /* no good with big buffer */ ctTimeOuts.ReadTotalTimeoutConstant = 500; ctTimeOuts.WriteTotalTimeoutMultiplier = 1; ctTimeOuts.WriteTotalTimeoutConstant = 5000; if(!SetCommTimeouts(ttyfd, &ctTimeOuts)) { DEBUG(1, "Error: SetCommTimeouts()\n"); } Sleep(500); /* flush all pending input */ if(!PurgeComm(ttyfd, PURGE_RXABORT | PURGE_RXCLEAR)) { DEBUG(1, "Error: PurgeComm\n"); } #else int ttyfd; struct termios oldtio, newtio; return_val_if_fail (ttyname != NULL, -1); DEBUG(2, "%s() \n", __func__); if( (ttyfd = open(ttyname, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) < 0 ) { DEBUG(1, "Can' t open tty\n"); return -1; } (void) tcgetattr(ttyfd, &oldtio); memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = B57600 | CS8 | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; (void) tcflush(ttyfd, TCIFLUSH); (void) tcsetattr(ttyfd, TCSANOW, &newtio); #endif /* Can't just try that now, as it will break some phones. */ //if (bfb_io_init (ttyfd)) { // DEBUG(1, "Already in BFB mode.\n"); // goto bfbmode; //} /* check if we are in transparent OBEX or AT mode: */ /* send an ABORT (0xFF) with cleverly embedded AT command. */ /* look for valid OBEX frame (OK=0xA0, BADREQ=0xC0, or alike) */ DEBUG(1, "Checking for transparent OBEX mode\n"); actual = bfb_io_write(ttyfd, "\377\000\010\313ATZ\r", 8); if (actual == 8) { DEBUG(3, "Write ok, reading back\n"); actual = bfb_io_read_all(ttyfd, rspbuf, sizeof(rspbuf), 2); if (actual >= 3 && rspbuf[actual-1] == actual) { DEBUG(3, "Received %02X OBEX frame\n", (uint8_t)rspbuf[0]); DEBUG(1, "Transparent OBEX\n"); *typeinfo = TT_GENERIC; return ttyfd; } else if (actual >= 3 && !strncmp(rspbuf, "ATZ", 3)) { DEBUG(1, "AT mode\n"); } } if(do_at_cmd(ttyfd, "ATZ\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error or already in BFB mode\n"); #ifdef _WIN32 goto bfbmode; #else newtio.c_cflag = B19200 | CS8 | CREAD; (void) tcflush(ttyfd, TCIFLUSH); (void) tcsetattr(ttyfd, TCSANOW, &newtio); if(do_at_cmd(ttyfd, "ATZ\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error or already in BFB mode\n"); goto bfbmode; } #endif } if(strcasecmp("OK", rspbuf) != 0) { DEBUG(1, "Error doing ATZ (%s)\n", rspbuf); goto err; } if(do_at_cmd(ttyfd, "AT+GMI\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } DEBUG(1, "AT+GMI: %s\n", rspbuf); if(strncasecmp("ERICSSON", rspbuf, 8) == 0 || strncasecmp("SONY ERICSSON", rspbuf, 13) == 0) { DEBUG(1, "Ericsson detected\n"); goto ericsson; } if(strncasecmp("MOTOROLA", rspbuf, 8) == 0 || /* is this needed? */ strstr(rspbuf, "Motorola")) { DEBUG(1, "Motorola detected\n"); goto motorola; } if(strncasecmp("SIEMENS", rspbuf, 7) != 0) { DEBUG(1, "No Siemens detected. Trying generic.\n"); goto generic; } if(do_at_cmd(ttyfd, "AT^SIFS\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if(strcasecmp("^SIFS: WIRE", rspbuf) != 0 /* DCA-500, DCA-510 */ && strcasecmp("^SIFS: BLUE", rspbuf) != 0 && strcasecmp("^SIFS: IRDA", rspbuf) != 0 && strcasecmp("^SIFS: USB", rspbuf) != 0) { /* DCA-540 */ DEBUG(1, "Unknown connection doing AT^SIFS (%s), continuing anyway ...\n", rspbuf); } /* prefer connection without BFB */ if(do_at_cmd(ttyfd, "AT^SBFB=?\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if(!strncasecmp("^SBFB: (0-3", rspbuf, 11) != 0) { DEBUG(1, "New plain Siemens protocol. (%s)\n", rspbuf); goto newsiemens; } DEBUG(1, "Old BFB Siemens protocol. (%s)\n", rspbuf); if(do_at_cmd(ttyfd, "AT^SBFB=1\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if(strcasecmp("OK", rspbuf) != 0) { DEBUG(1, "Error doing AT^SBFB=1 (%s)\n", rspbuf); goto err; } sleep(1); /* synch a bit */ bfbmode: #ifndef _WIN32 newtio.c_cflag = B57600 | CS8 | CREAD; (void) tcflush(ttyfd, TCIFLUSH); (void) tcsetattr(ttyfd, TCSANOW, &newtio); #endif if (! bfb_io_init (ttyfd)) { /* well there may be some garbage -- just try again */ if (! bfb_io_init (ttyfd)) { DEBUG(1, "Couldn't init BFB mode.\n"); goto err; } } *typeinfo = TT_BFB; return ttyfd; ericsson: if(do_at_cmd(ttyfd, "AT*EOBEX\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if(strcasecmp("CONNECT", rspbuf) != 0) { DEBUG(1, "Error doing AT*EOBEX (%s)\n", rspbuf); goto err; } *typeinfo = TT_ERICSSON; return ttyfd; motorola: if(do_at_cmd(ttyfd, "AT+MODE=22\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if(strcasecmp("CONNECT", rspbuf) != 0 || /* is this needed? */ strcasecmp("OK", rspbuf) != 0) { DEBUG(1, "Error doing AT+MODE=22 (%s)\n", rspbuf); goto err; } *typeinfo = TT_MOTOROLA; return ttyfd; newsiemens: /* ^SBFB=3 only works when switching from RCCP(0) to OBEX(3) * but the phone may be in GIPSY(2) mode. * No need to implement BFC(1) mode if we only want to run OBEX. */ if(do_at_cmd(ttyfd, "AT^SQWE?\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if (strcasecmp("^SQWE:0",rspbuf) != 0) { if(do_at_cmd(ttyfd, "AT^SQWE=0\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if(strcasecmp("OK", rspbuf) != 0) { DEBUG(1, "Error doing AT^SQWE=0 (%s)\n", rspbuf); goto err; } sleep(1); } if(do_at_cmd(ttyfd, "AT^SQWE=3\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if(strcasecmp("OK", rspbuf) != 0) { DEBUG(1, "Error doing AT^SQWE=3 (%s)\n", rspbuf); goto err; } sleep(1); /* synch a bit */ *typeinfo = TT_SIEMENS; return ttyfd; generic: if(do_at_cmd(ttyfd, "AT+CPROT=0\r", rspbuf, sizeof(rspbuf)) < 0) { DEBUG(1, "Comm-error\n"); goto err; } if(strcasecmp("CONNECT", rspbuf) != 0) { DEBUG(1, "Error doing AT+CPROT=0 (%s)\n", rspbuf); goto err; } *typeinfo = TT_GENERIC; return ttyfd; err: bfb_io_close(ttyfd, TRUE); #ifdef _WIN32 return INVALID_HANDLE_VALUE; #else return -1; #endif } obexftp-0.24-Source/bfb/bfb_io.h100777 0 0 3503 12115454406 11610 0/** \file bfb/bfb_io.h BFB protocol IO layer. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef BFB_IO_H #define BFB_IO_H #include enum trans_type { TT_BFB, /* use a bfb transport */ TT_ERICSSON, /* just custom init and teardown */ TT_SIEMENS, /* new siemens, like ericsson above */ TT_MOTOROLA, /* experimental motorola support */ TT_GENERIC /* should work on most phones */ }; #ifdef __cplusplus extern "C" { #endif /* Write out a BFB buffer */ int bfb_io_write(fd_t fd, const void *buffer, int length); /* Read in a BFB answer */ int bfb_io_read(fd_t fd, void *buffer, int length, int timeout); /* Send an BFB init command an check for a valid answer frame */ int bfb_io_init(fd_t fd); /* Send an AT-command an expect 1 line back as answer */ int do_at_cmd(fd_t fd, const char *cmd, char *rspbuf, int rspbuflen); /* close the connection */ void bfb_io_close(fd_t fd, int force); /* Init the phone and set it in BFB-mode */ /* Returns fd or -1 on failure */ fd_t bfb_io_open(const char *ttyname, enum trans_type *typeinfo); #ifdef __cplusplus } #endif #endif /* BFB_IO_H */ obexftp-0.24-Source/bfb/CMakeLists.txt100777 0 0 1274 12115454406 12762 0 set ( bfb_SOURCES bfb.c bfb_io.c crc.c ) set ( bfb_PUBLIC_HEADERS bfb.h bfb_io.h ) set ( bfb_HEADERS crc.h ${bfb_PUBLIC_HEADERS} ) add_library ( bfb ${bfb_SOURCES} ${bfb_HEADERS} ) set_property ( TARGET bfb PROPERTY VERSION 0.0.5 ) set_property ( TARGET bfb PROPERTY SOVERSION 0 ) set_property ( TARGET bfb PROPERTY PUBLIC_HEADER ${bfb_PUBLIC_HEADERS} ) install ( TARGETS bfb RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT library LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/bfb COMPONENT devel ) obexftp-0.24-Source/bfb/crc.c100777 0 0 6136 12115454406 11137 0/********************************************************************* * * Filename: crc.c * Version: 0.1 * Description: CRC calculation routines * Status: Experimental. * Author: Dag Brattli * Created at: Mon Aug 4 20:40:53 1997 * Modified at: Sun May 2 20:28:08 1999 * Modified by: Dag Brattli * Sources: ppp.c by Michael Callahan * Al Longyear * ********************************************************************/ #include "crc.h" /* * This mysterious table is just the CRC of each possible byte. It can be * computed using the standard bit-at-a-time methods. The polynomial can * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12. * Add the implicit x^16, and you have the standard CRC-CCITT. */ uint16_t const irda_crc16_table[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; unsigned short crc_calc(uint16_t fcs, uint8_t const *buf, int len) { while (len--) fcs = irda_fcs(fcs, *buf++); return fcs; } obexftp-0.24-Source/bfb/crc.h100777 0 0 1716 12115454406 11143 0/********************************************************************* * * Filename: crc.h * Version: * Description: CRC routines * Status: Experimental. * Author: Dag Brattli * Created at: Mon Aug 4 20:40:53 1997 * Modified at: Sun May 2 20:25:23 1999 * Modified by: Dag Brattli * ********************************************************************/ #ifndef IRDA_CRC_H #define IRDA_CRC_H #include #define INIT_FCS 0xffff /* Initial FCS value */ #define GOOD_FCS 0xf0b8 /* Good final FCS value */ extern uint16_t const irda_crc16_table[]; /* Recompute the FCS with one more character appended. */ static inline uint16_t irda_fcs(uint16_t fcs, uint8_t c) { return (((fcs) >> 8) ^ irda_crc16_table[((fcs) ^ (c)) & 0xff]); } /* Recompute the FCS with len bytes appended. */ unsigned short crc_calc( uint16_t fcs, uint8_t const *buf, int len); #endif obexftp-0.24-Source/ChangeLog100777 0 0 26756 12115454406 11277 0ObexFTP 0.24 (released 2013-03-05) ---------------------------------- * Maintainer changed from Christian to Hendrik * change build system to using CMake * integrate obexfs-0.12 * fix build for OpenOBEX-1.7 ObexFTP 0.23 (released 2009-02-17) ---------------------------------- * allow win32 to use hci src names * adding a simpler connect wrapper * show OBEX_HandleInput errors * catch errors and let the user know * print timeout stats if available * sdp unregister more verbose * upgrading btkit * fix for win32 without bt * replacing deprecated automake vars * sizeof() fixes * removing bdaddr_t reference from obexftpd.c * adding bootstrap helper * concurrency bug in extconf.rb generated Makefile (fix by Alin Năstac) * switching from POD to asciidoc * clearing gnu-style implicit rules ObexFTP 0.22 (released 2008-06-15) ---------------------------------- * added proper unicode support * added support for transparent OBEX-over-AT mode * rewritten at-command function * added specific error messages * refactored to flexible bt_kit layer * fixed cache root duplicates * fixed off-by-one and unfreed mem in cache layer * added pkg-config file * added example code * switched to doxygen * added python binding callbacks * portable packed structs * enabled linux hci dev names for source selection * Python binding uses distutils now, tested by Adam Williamson * removed exit from bt discovery * Better autodetection for possible language bindings * reworked win32 support * Motorola SLVR L2 cobex fix by Andrey Rahmatullin * now using AC_HELP_STRING for compat with autoconf <=2.57 * added hci selection support, drafted by Manuel Naranjo * switched obexftp cli to new discovery api * prefer PCSUITE over FTP, req. by Martin Storsjö for Series 60 2nd Ed. * fixed compile error with >=swig-1.3.28 * renamed sdp browse function * fixed month/day swapping in atotime, spotted by Dr. Johannes Zellner * added BFC compatibility for newer Siemens phones * added PCSOFTWARE uuid support for SHARP phones * added motorola support * end bfb mode properly * added CPROT=0 support from 3GPP 27.007 * fixed ericsson init * fixed invalid conn_id in disconnect rep. by Alan J. McFarlane * better create flag handling in setpath * Changed LDADD to LIBADD sug. by Sergey Vlasov * obexftpd clean up by Hendrik Sattler * 64-bit fixes by Hendrik Sattler * Removed all (dangerous) obex_headerdata_t casts * Reorganized all swig-dependant Makefiles * Applied cobex write patch from Simon Ruggier * Applied from Frode Isaksen ObexFTP 0.21 (released 2006-06-27) ---------------------------------- 2006-05-26 Christian W. Zuckschwerdt * Fixes to obexftpd suggested by Hendrik Sattler 2006-05-24 Christian W. Zuckschwerdt * Added ruby binding * Added preliminary discovery function ObexFTP 0.20 (released 2006-05-16) ---------------------------------- 2006-05-16 Christian W. Zuckschwerdt * Change __S_IFDIR to S_IFDIR with fallback sug. by Alex Kanavin * Added old CLI switches and documentation sug. by Hendrik Sattler 2006-04-26 Christian W. Zuckschwerdt * Fixed the -g CLI switch (bug reported by many people) 2006-03-08 Christian W. Zuckschwerdt * Added obexfsd written by Alan Zhang * Fixed iconv (found by Stanislav Nikolov) 2006-03-07 Christian W. Zuckschwerdt * device/channel code cleanup ObexFTP 0.19 (released 2006-02-08) ---------------------------------- 2006-02-08 Christian W. Zuckschwerdt * Updated for OpenOBEX 1.1 (pkg-config) 2006-01-26 Christian W. Zuckschwerdt * Added --output switch by Daniel Burr/Andrzej Szombierski. 2006-01-21 Christian W. Zuckschwerdt * Simplified the swig/perl/Makefile.am. ObexFTP 0.18 (released 2006-01-18) ---------------------------------- 2006-01-11 Christian W. Zuckschwerdt * Fixed a pointer typo and a free() typo. 2005-12-12 Christian W. Zuckschwerdt * Added perl, python and tcl binding with swig. 2005-09-15 Christian W. Zuckschwerdt * Quick iconv hack. Needs to be done in openobex. 2005-09-14 Christian W. Zuckschwerdt * Rewrote folder-listing parser to enhance compatibility 2005-09-12 Christian W. Zuckschwerdt * Connection headers by Philip Kovacs 2005-08-06 Christian W. Zuckschwerdt * Nokia hack (suppressing FBS) * Capabilty retrieving by Marco Canini 2005-06-27 Christian W. Zuckschwerdt * USB support, mainly by Daniel Burr 2005-06-19 Christian W. Zuckschwerdt * Added implicit setpath support in every function. 2005-06-11 Christian W. Zuckschwerdt * Fixed quoting problem. Lets hope this wont break libtool. 2005-06-10 Christian W. Zuckschwerdt * Added simple caching * Removed recursive put. Apps should implement it themselves. 2005-06-09 Christian W. Zuckschwerdt * New configure flag to enable building docs (disabled by default now) 2005-03-23 Christian W. Zuckschwerdt * Security fix suggested by Kevin Finisterre 2005-03-21 Christian W. Zuckschwerdt * GCC 2.96 compat fixes by Paul Boddie 2005-01-15 Christian W. Zuckschwerdt * Documentation updated by Hendrik Sattler 2005-01-10 Christian W. Zuckschwerdt * Typo fix to setpath by Olivier Berger * Removed some BT ifdefs by Hendrik Sattler * Use VERSION macro suggested by Andrej Kacian ObexFTP 0.17 (released 2004-12-17) ---------------------------------- 2004-12-17 Christian W. Zuckschwerdt * Added sdp lib checks, reported by George Styles and Johan Debal 2004-12-12 Christian W. Zuckschwerdt * Fixed do_at_cmd, reported by Donald Burns 2004-11-21 Christian W. Zuckschwerdt * Bluetooth device and channel auto-discovery ObexFTP 0.16 (released 2004-11-23) ---------------------------------- 2004-11-20 Christian W. Zuckschwerdt * FreeBSD patch by Bruce Simpson 2004-11-19 Christian W. Zuckschwerdt * Bug fixes (for Sony-Ericsson) by David Haslam ObexFTP 0.15 (released 2004-11-13) ---------------------------------- 2004-11-12 Christian W. Zuckschwerdt * Don't send S45 UUID first (broke other phones too, sorry S45 users) 2004-11-10 Christian W. Zuckschwerdt * Fixed linebreaks in contributed backup script. ObexFTP 0.14 (released 2004-09-26) ---------------------------------- 2004-09-26 Christian W. Zuckschwerdt * Moved vmo converter into a seperate package 2004-09-05 Christian W. Zuckschwerdt * Serial-USB converter fix, Gerhard Reithofer 2004-08-10 Christian W. Zuckschwerdt * Uploads discard path info now. 2004-07-25 Christian W. Zuckschwerdt * Added support for Sony-Ericsson phones, debian Bug#261328 2004-06-11 Christian W. Zuckschwerdt * Version option added 2004-03-05 Christian W. Zuckschwerdt * NetBSD portability patch by Soren S. Jorvang 2004-02-04 Christian W. Zuckschwerdt * Skip transports not linked, François Fleuret 2004-01-30 Christian W. Zuckschwerdt * IrCOMM 1-line show stopper fixed by Stefan Behnel 2003-12-28 Christian W. Zuckschwerdt * setpath patch for T610 by Adam Goode 2003-10-22 Christian W. Zuckschwerdt * bfb_write_packets patch by Jorge Ventura * connection setup fixes (cobex) 2003-10-01 Christian W. Zuckschwerdt * Bluetooth support 2003-09-24 Christian W. Zuckschwerdt * Ericsson phones are now working with the unified cobex. * removed the automatic directory parsing, please just the -c switch. * Shuffled the option names for obexftp to counter missunderstandings. 2003-07-18 Christian W. Zuckschwerdt * fixed a Makefile bug reported by Carwyn Edwards ObexFTP 0.13 (released 2003-04-11) ---------------------------------- 2003-04-11 Christian W. Zuckschwerdt * all but data output goes to stderr now (suggested by Heiko) * The environment variable OBEXFTP_PORT is used as a default. ObexFTP 0.12 (released 2003-02-17) ---------------------------------- 2003-02-17 Christian W. Zuckschwerdt * Added vmo converters (suggested by Dmitry Zakharov) 2003-02-11 Christian W. Zuckschwerdt * Added UUID fallback for C55 (suggested by Hristo Todorov) ObexFTP 0.11 (released 2003-01-26) ---------------------------------- 2003-01-26 Christian W. Zuckschwerdt * Unified BFB and PE; 2003-01-19 Christian W. Zuckschwerdt * C++ compatible header files (suggested Carsten Pfeiffer) ObexFTP 0.10 (released 2003-01-10) ---------------------------------- 2003-01-09 Christian W. Zuckschwerdt * Big file transmission problem solved 2002-11-22 Christian W. Zuckschwerdt * Jan Metz supplied me with his RH8 box and some SL45i connected to it. Finally S45(i) is working. 2002-11-19 Christian W. Zuckschwerdt * this is the last release to support OpenOBEX 0.9.8 2002-11-14 Christian W. Zuckschwerdt * Removed glib dependancy * win32 target is working (tested with mingw) 2002-10-17 Christian W. Zuckschwerdt * Removed Siemens references in favor of OBEX enabled devices * Enhancements for upcoming OpenOBEX 1.0.0 2002-04-29 Christian W. Zuckschwerdt * Erricsson T39m support, req. by Ole Streicher 2002-03-04 Christian W. Zuckschwerdt * Try harder to connect. IRDA needs patience. * Wrote a man page. Should really be a docbook refentry. ObexFTP 0.9 (released 2002-02-18) --------------------------------- ObexFTP 0.8 (released 2002-02-14) --------------------------------- ObexFTP 0.7 (released 2002-02-13) --------------------------------- ObexFTP 0.6 (released 2002-02-12) --------------------------------- ObexFTP 0.5 (released 2002-02-11) --------------------------------- 2002-02-11 Christian W. Zuckschwerdt * cobex now capable of asynch operation ObexFTP 0.4 (released 2002-02-09) --------------------------------- 2002-02-09 Christian W. Zuckschwerdt * Rewrote main using getopt. ObexFTP 0.3 (released 2002-02-08) --------------------------------- 2002-02-08 Christian W. Zuckschwerdt * Fixed BFB protocol (Code 0x01 is ACK not PREPARE...). 2002-02-07 Christian W. Zuckschwerdt * Implemented BFB protocol. ObexFTP 0.2 (released 2002-01-19) --------------------------------- 2002-01-19 Christian W. Zuckschwerdt * Implemented delete and rename. ObexFTP 0.1 (released 2002-01-18) --------------------------------- 2002-01-18 Christian W. Zuckschwerdt * Initial beta. * It's work in progress so expect errors and report/fix then! obexftp-0.24-Source/CMakeLists.txt100777 0 0 4241 12115454406 12226 0 cmake_minimum_required(VERSION 2.8.5) project ( obexftp C ) # # The project version # set ( VERSION_MAJOR 0 ) set ( VERSION_MINOR 24 ) set ( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}" ) # # The path for our own CMake modules # set ( CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules ) # # Define the default build type # set ( CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "" FORCE ) if ( NOT CMAKE_BUILD_TYPE ) set ( CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE ) endif ( NOT CMAKE_BUILD_TYPE ) include ( MaintainerMode ) include ( GNUInstallDirs ) # # define how to build libraries # option ( BUILD_SHARED_LIBS "Build shared libraries" ON ) include_directories ( ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/includes ) # # many parts of this project need the OpenObex includes # find_package ( OpenObex ${OpenObex_FORCE_VERSION} QUIET NO_MODULE) if ( NOT OpenObex_FOUND ) find_package ( OpenObex REQUIRED ) endif ( NOT OpenObex_FOUND ) include_directories ( ${OpenObex_INCLUDE_DIRS} ) # # some code is only included if bluetooth is available # find_package ( Bluetooth ) if ( Bluetooth_FOUND ) include_directories ( ${Bluetooth_INCLUDE_DIRS} ) add_definitions ( -DHAVE_BLUETOOTH -DHAVE_SDP ) endif ( Bluetooth_FOUND ) add_subdirectory ( bfb ) add_subdirectory ( multicobex ) add_subdirectory ( obexftp ) add_subdirectory ( apps ) add_subdirectory ( fuse ) add_subdirectory ( swig ) add_subdirectory ( doc ) #examples set ( prefix "${CMAKE_INSTALL_PREFIX}" ) set ( exec_prefix "\${prefix}" ) set ( libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}" ) set ( includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}" ) set ( REQUIRES "bluetooth openobex" ) configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/obexftp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/obexftp.pc @ONLY ) if ( NOT CMAKE_INSTALL_PKGCONFIGDIR ) set ( CMAKE_INSTALL_PKGCONFIGDIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig CACHE PATH "Where to install .pc files to" FORCE ) endif ( NOT CMAKE_INSTALL_PKGCONFIGDIR ) mark_as_advanced ( CMAKE_INSTALL_PKGCONFIGDIR ) install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/obexftp.pc DESTINATION ${CMAKE_INSTALL_PKGCONFIGDIR} COMPONENT devel ) obexftp-0.24-Source/CMakeModules/ 40777 0 0 0 12115602310 11663 5obexftp-0.24-Source/CMakeModules/FindBluetooth.cmake100777 0 0 7270 12115454406 15554 0# - Find system default bluetooth implementation # # On Linux it will use PkgConfig if present and supported, # else and on all other architectures, it looks for it on its own. # The following standard variables get defined: # Bluetooth_FOUND: true if Bluetooth was found # Bluetooth_INCLUDE_DIRS: the directory that contains the include file # Bluetooth_LIBRARIES: full path to the libraries include ( CheckCSourceCompiles ) include ( CheckLibraryExists ) include ( CheckIncludeFile ) if ( CMAKE_SYSTEM_NAME STREQUAL "Linux" ) find_package ( PkgConfig ) if ( PKG_CONFIG_FOUND ) pkg_check_modules ( PKGCONFIG_BLUEZ bluez ) endif ( PKG_CONFIG_FOUND ) find_path ( Bluetooth_INCLUDE_DIRS NAMES bluetooth/bluetooth.h PATH_SUFFIXES include ) mark_as_advanced ( Bluetooth_INCLUDE_DIRS ) if ( PKGCONFIG_BLUEZ_FOUND ) foreach ( i ${PKGCONFIG_BLUEZ_LIBRARIES} ) find_library ( ${i}_LIBRARY NAMES ${i} PATHS ${PKGCONFIG_BLUEZ_LIBRARY_DIRS} ) mark_as_advanced ( ${i}_LIBRARY ) if ( ${i}_LIBRARY ) list ( APPEND Bluetooth_LIBRARIES ${${i}_LIBRARY} ) endif ( ${i}_LIBRARY ) endforeach ( i ) add_definitions ( -DHAVE_SDPLIB ) else ( PKGCONFIG_BLUEZ_FOUND ) find_library ( bluetooth_LIBRARY NAMES bluetooth PATH_SUFFIXES lib ) mark_as_advanced ( bluetooth_LIBRARY ) if ( bluetooth_LIBRARY ) set ( Bluetooth_LIBRARIES ${bluetooth_LIBRARY} ) endif ( bluetooth_LIBRARY ) endif ( PKGCONFIG_BLUEZ_FOUND ) if ( Bluetooth_INCLUDE_DIRS AND Bluetooth_LIBRARIES ) set ( Bluetooth_FOUND true ) endif ( Bluetooth_INCLUDE_DIRS AND Bluetooth_LIBRARIES ) elseif ( CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" ) find_path ( Bluetooth_INCLUDE_DIRS NAMES bluetooth.h PATH_SUFFIXES include ) mark_as_advanced ( Bluetooth_INCLUDE_DIRS ) find_library ( Bluetooth_LIBRARIES NAMES bluetooth PATH_SUFFIXES lib ) mark_as_advanced ( Bluetooth_LIBRARIES ) if ( Bluetooth_INCLUDE_DIRS ) set ( CMAKE_REQUIRED_INCLUDES ${Bluetooth_INCLUDE_DIRS} ) CHECK_C_SOURCE_COMPILES ( "#include int main () { struct sockaddr_rfcomm f; return 0; }" Bluetooth_FOUND ) endif ( Bluetooth_INCLUDE_DIRS ) elseif ( CMAKE_SYSTEM_NAME STREQUAL "NetBSD" ) find_path ( Bluetooth_INCLUDE_DIRS NAMES bluetooth.h PATH_SUFFIXES include ) mark_as_advanced ( Bluetooth_INCLUDE_DIRS ) find_library ( Bluetooth_LIBRARIES NAMES bluetooth PATH_SUFFIXES lib ) mark_as_advanced ( Bluetooth_LIBRARIES ) if ( Bluetooth_INCLUDE_DIRS ) set ( CMAKE_REQUIRED_INCLUDES ${Bluetooth_INCLUDE_DIRS} ) CHECK_C_SOURCE_COMPILES ( "#include int main () { struct sockaddr_bt f; return 0; }" Bluetooth_FOUND ) endif ( Bluetooth_INCLUDE_DIRS ) elseif ( WIN32 ) CHECK_C_SOURCE_COMPILES ( "#include #include int main () { SOCKADDR_BTH f; return 0; }" Bluetooth_FOUND ) endif ( CMAKE_SYSTEM_NAME STREQUAL "Linux" ) if ( Bluetooth_FOUND ) set ( Bluetooth_FOUND true ) else ( Bluetooth_FOUND ) set ( Bluetooth_FOUND false ) endif ( Bluetooth_FOUND ) if ( NOT Bluetooth_FOUND ) if ( NOT Bluetooth_FIND_QUIETLY ) message ( STATUS "Bluetooth not found." ) endif ( NOT Bluetooth_FIND_QUIETLY ) if ( Bluetooth_FIND_REQUIRED ) message ( FATAL_ERROR "Bluetooth not found but required." ) endif ( Bluetooth_FIND_REQUIRED ) endif ( NOT Bluetooth_FOUND ) obexftp-0.24-Source/CMakeModules/FindFuse.cmake100777 0 0 4102 12115454406 14500 0# - Find Fuse (file system in userspace) # # It will use PkgConfig if present and supported, else search # it on its own. # # The following standard variables get defined: # Fuse_FOUND: true if fuse was found # Fuse_VERSION_STRING: the version of fuse, if any # Fuse_INCLUDE_DIRS: the directory that contains the include file # Fuse_LIBRARIES: full path to the libraries # Fuse_DEFINITIONS additional compiler flags find_package ( PkgConfig ) if ( PKG_CONFIG_FOUND ) if ( Fuse_FIND_VERSION ) pkg_check_modules ( PKGCONFIG_FUSE fuse=${Fuse_FIND_VERSION} ) else ( Fuse_FIND_VERSION ) pkg_check_modules ( PKGCONFIG_FUSE fuse ) endif ( Fuse_FIND_VERSION ) endif ( PKG_CONFIG_FOUND ) if ( PKGCONFIG_FUSE_FOUND ) set ( Fuse_FOUND ${PKGCONFIG_FUSE_FOUND} ) set ( Fuse_VERSION_STRING ${PKGCONFIG_FUSE_VERSION} ) set ( Fuse_DEFINITIONS ${PKGCONFIG_FUSE_CFLAGS_OTHER} ) set ( Fuse_INCLUDE_DIRS ${PKGCONFIG_FUSE_INCLUDE_DIRS} ) foreach ( i ${PKGCONFIG_FUSE_LIBRARIES} ) find_library ( ${i}_LIBRARY NAMES ${i} PATHS ${PKGCONFIG_FUSE_LIBRARY_DIRS} ) if ( ${i}_LIBRARY ) list ( APPEND Fuse_LIBRARIES ${${i}_LIBRARY} ) endif ( ${i}_LIBRARY ) mark_as_advanced ( ${i}_LIBRARY ) endforeach ( i ) else ( PKGCONFIG_FUSE_FOUND ) find_path ( Fuse_INCLUDE_DIRS NAMES fuse/fuse.h PATH_SUFFIXES include ) mark_as_advanced ( Fuse_INCLUDE_DIRS ) find_library ( fuse_LIBRARY NAMES fuse ) mark_as_advanced ( fuse_LIBRARY ) if ( fuse_LIBRARY ) set ( Fuse_LIBRARIES ${fuse_LIBRARY} ) endif ( fuse_LIBRARY ) set ( Fuse_DEFINITIONS -D_FILE_OFFSET_BITS=64 ) if ( Fuse_INCLUDE_DIRS AND Fuse_LIBRARIES ) set ( Fuse_FOUND true ) endif ( Fuse_INCLUDE_DIRS AND Fuse_LIBRARIES ) endif ( PKGCONFIG_FUSE_FOUND ) if ( NOT Fuse_FOUND ) if ( NOT Fuse_FIND_QUIETLY ) message ( STATUS "Fuse not found." ) endif ( NOT Fuse_FIND_QUIETLY ) if ( Fuse_FIND_REQUIRED ) message ( FATAL_ERROR "" ) endif ( Fuse_FIND_REQUIRED ) endif ( NOT Fuse_FOUND ) obexftp-0.24-Source/CMakeModules/FindIconv.cmake100777 0 0 3011 12115454406 14652 0 find_path ( ICONV_INCLUDE_DIR iconv.h ) mark_as_advanced ( ICONV_INCLUDE_DIR ) set ( ICONV_INCLUDE_DIRS ${ICONV_INCLUDE_DIR} ) if ( ICONV_INCLUDE_DIRS ) include ( CheckFunctionExists ) unset ( CMAKE_REQUIRED_FLAGS ) unset ( CMAKE_REQUIRED_DEFINITIONS ) set ( CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIRS} ) unset ( CMAKE_REQUIRED_LIBRARIES ) check_function_exists ( iconv_open ICONV_FOUND ) if ( NOT ICONV_FOUND ) find_library ( iconv_LIBRARY iconv ) if ( iconv_LIBRARY ) set ( CMAKE_REQUIRED_LIBRARIES ${iconv_LIBRARY} ) check_function_exists ( iconv_open ICONV_FOUND ) if ( ICONV_FOUND ) set ( ICONV_LIBRARIES ${iconv_LIBRARY} ) endif ( ICONV_FOUND ) endif ( iconv_LIBRARY ) endif ( NOT ICONV_FOUND ) endif ( ICONV_INCLUDE_DIRS ) if ( ICONV_FOUND ) set ( ICONV_CONST_TEST_SOURCE " #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, const char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif int main(void) { return 0; } ") unset ( CMAKE_REQUIRED_FLAGS ) unset ( CMAKE_REQUIRED_DEFINITIONS ) set ( CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIRS} ) unset ( CMAKE_REQUIRED_LIBRARIES ) check_c_source_compiles ( "${ICONV_CONST_TEST_SOURCE}" ICONV_USES_CONST ) endif ( ICONV_FOUND ) if ( NOT ICONV_FOUND ) if ( Iconv_REQUIRED ) message ( FATAL_ERROR "Iconv not found" ) endif ( Iconv_REQUIRED ) endif ( NOT ICONV_FOUND ) obexftp-0.24-Source/CMakeModules/MaintainerMode.cmake100777 0 0 2746 12115454406 15705 0option ( USE_MAINTAINER_MODE "Enable some stuff only relevant to developers" OFF ) if ( USE_MAINTAINER_MODE ) if ( CMAKE_COMPILER_IS_GNUCC ) set ( MAINTAINER_MODE_WARN_FLAGS all extra no-unused-parameter no-missing-field-initializers declaration-after-statement missing-declarations redundant-decls cast-align error ) set ( MAINTAINER_MODE_FLAGS # pedantic # std=c99 ) foreach ( flag ${MAINTAINER_MODE_WARN_FLAGS} ) list ( APPEND MAINTAINER_MODE_FLAGS "W${flag}" ) endforeach ( flag ) foreach ( flag ${MAINTAINER_MODE_FLAGS} ) set ( cflag "-${flag}" ) set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${cflag}" ) foreach ( type DEBUG RELEASE MINSIZEREL RELWITHDEBINFO ) set ( CMAKE_C_FLAGS_${type} "${CMAKE_C_FLAGS_${type}} ${cflag}" ) endforeach ( type ) endforeach ( flag ) elseif ( MSVC ) set ( MAINTAINER_MODE_FLAGS W3 WX ) foreach ( flag ${MAINTAINER_MODE_FLAGS} ) set ( cflag "/${flag}" ) set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${cflag}" ) foreach ( type DEBUG RELEASE MINSIZEREL RELWITHDEBINFO ) set ( CMAKE_C_FLAGS_${type} "${CMAKE_C_FLAGS_${type}} ${cflag}" ) endforeach ( type ) endforeach ( flag ) endif ( CMAKE_COMPILER_IS_GNUCC ) # foreach ( type DEBUG RELEASE MINSIZEREL RELWITHDEBINFO ) # message ( "CMAKE_C_FLAGS_${type} set to \"${CMAKE_C_FLAGS_${type}}\"" ) # endforeach ( type ) endif ( USE_MAINTAINER_MODE ) obexftp-0.24-Source/doc/ 40777 0 0 0 12115602310 10117 5obexftp-0.24-Source/doc/CMakeLists.txt100777 0 0 3034 12115454406 12772 0 find_program ( ASCIIDOC_EXECUTABLE asciidoc ) find_program ( XMLTO_EXECUTABLE xmlto ) set ( PROGRAMS obexftp obexftpd ) foreach ( program ${PROGRAMS} ) set ( ASCIIDOC_INPUT ${CMAKE_CURRENT_SOURCE_DIR}/${program}.1.txt ) set ( ASCIIDOC_XML_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${program}.1.xml ) set ( ASCIIDOC_HTML_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${program}.1.html ) add_custom_command ( OUTPUT ${ASCIIDOC_XML_OUTPUT} COMMAND ${ASCIIDOC_EXECUTABLE} ARGS --doctype=manpage --backend=docbook -o ${ASCIIDOC_XML_OUTPUT} ${ASCIIDOC_INPUT} DEPENDS ${ASCIIDOC_INPUT} VERBATIM ) add_custom_command ( OUTPUT ${ASCIIDOC_HTML_OUTPUT} COMMAND ${ASCIIDOC_EXECUTABLE} ARGS --doctype=manpage --backend=xhtml11 -o ${ASCIIDOC_HTML_OUTPUT} ${ASCIIDOC_INPUT} DEPENDS ${ASCIIDOC_INPUT} VERBATIM ) list ( APPEND html_help_files ${ASCIIDOC_HTML_OUTPUT} ) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${program}.1 COMMAND ${XMLTO_EXECUTABLE} ARGS -o ${CMAKE_CURRENT_BINARY_DIR} man ${ASCIIDOC_XML_OUTPUT} DEPENDS ${ASCIIDOC_XML_OUTPUT} VERBATIM ) list ( APPEND manpage_files ${CMAKE_CURRENT_BINARY_DIR}/${program}.1 ) endforeach ( program ) add_custom_target ( doc DEPENDS ${manpage_files} ) install ( FILES ${manpage_files} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT documentation OPTIONAL ) add_custom_target ( htmldoc DEPENDS ${html_help_files} ) install ( FILES ${html_help_files} DESTINATION ${CMAKE_INSTALL_DOCDIR}/html COMPONENT documentation OPTIONAL ) obexftp-0.24-Source/doc/obexftp.1.txt100777 0 0 10451 12115454406 12622 0= OBEXFTP(1) == NAME obexftp - Mobile Equipment file transfer tool == SYNOPSIS *obexftp* [_OPTION_] [_COMMANDS_] == DESCRIPTION *obexftp* is used to access files on mobile equipment, i.e. cell phones. With *obexftpd* you can transfer files between any computers using *IrDA*, *Bluetooth* and *TCP/IP*. This tool lets you access the *ObexFTP* library by the means of a command line interface. You might consider using the other means available. E.g. the *ObexFS* filesystem for Linux. == OPTIONS The ordering of options is important. Every command will use the most recent device set. Every file without command switch will apply to the command given most recent. See *EXAMPLES* === Transport Options *-i*, *--irda*:: Connect using the IrDA protocol. This is the default. *-b* _device_, *--bluetooth* _device_:: Connect to this bluetooth device. If the device is not given the first device found will be used. *-B* _number_, *--channel* _number_:: Use this bluetooth channel when connecting. The channel will be discoverd automatically if this option is not used. *-d* _no/address_, *--hci* _no/address_:: Use the bluetooth device referenced by number or address as source device for the connection. *-u* _intf no_, *--usb* _intf no_:: Connect to this usb interface or list all available usb interfaces. *-t* _device_, *--tty* _device_:: Connect to this tty device. *-n* _host_, *--network* _host_:: Connect to this network host. === Compatibility Options *-U* _uuid_, *--uuid* _uuid_:: Select the UUID to connect with. Recognized values are currently "none" needed by some Nokia mobile devices, "FBS" (default) for the normal file browsing service, "IRMC" for IRMC synchronisation and "S45" when connecting to a Siemens Mobile phone via cable or "SHARP" for PCSOFTWARE UUID with Sharp devices. *-H*, *--noconn*:: Suppress connection IDs (i.e. send no connection header to the mobile). *-S*, *--nopath*:: Don't use "setpath" commands (i.e. send the whole path as filename to the mobile). Can be used together with *--noconn* and *--uuid none* to send an OBEX-PUSH. === Setting The File Path *-c* _folder_, *--chdir* _folder_:: Set the mobiles current working directory. *-C* _folder_, *--mkdir* _folder_:: Set the mobiles current working directory. The folder will be created if it doesn't exist. *-l* _folder_, *--list* _folder_:: List a folder. === Sending And Retrieving Files *-o* _path_, *--output* _path_:: Specify the target file name, overriding the implicit local name from *--get* or the implicit remote name from *--put* *-g* _source_, *--get* _source_:: Retrieve files from mobile. *-G* _source_, *--getdelete* _source_:: Retrieve files from mobile and delete them on the mobile *-p* _source_, *--put* _source_:: Send files to the mobile. *-k* _source_, *--delete* _source_:: Delete files from the mobile. === Experimental Extras *-X*, *--capability*:: Retrieve the capability object from the mobile (if available). *-Y*, *--probe*:: Probe and report device characteristics *-x*, *--info*:: Retrieve misc infos from mobile. I.e. memory size and free memory. Siemens specific for now. *-m* _src_ _dest_, *--move* _src_ _dest_:: Move (rename) files on the mobile. Siemens specific for now. === Version Information And Help *-v*, *--verbose*:: Be verbose and give some additional infos. *-V*, *--version*:: Print version string and exit. *-h*, *--help*, *--usage*:: Print short usage instructions. == EXAMPLES To get the directory listing from the first irda device:: *obexftp -i -l* or just *obexftp -l* as IrDA is the default. To get the file bar from directory foo from the first bluetooth device:: *obexftp -b -c foo -g bar* To send the file bar to directory foo with device on first serial port:: *obexftp -t /dev/ttyS0 -c foo -p bar* It is possible to use RfComm (serial port over bluetooth):: *obexftp -t /dev/rfcomm0 -c foo -p bar* And also IrComm (serial port over IrDA):: *obexftp -t /dev/ircomm0 -c foo -p bar* To send the file bar using plain OBEX PUSH:: *obexftp --bluetooth --nopath --noconn --uuid none --put bar* == SEE ALSO obexftpd(1), openobex(3), obexftp(3), multicobex(3), libbfb(3). == BUGS Bugs ? Features ! == NOTES The software has been tested and reported working on at least Siemens, Ericsson, and Nokia phones. == AUTHOR Christian W. Zuckschwerdt obexftp-0.24-Source/doc/obexftpd.1.txt100777 0 0 3002 12115454406 12740 0= OBEXFTPD(1) == NAME obexftpd - Mobile Equipment file transfer server == SYNOPSIS *obexftpd* [_OPTIONS_] [_TRANSPORT_] == DESCRIPTION With *obexftpd* you can set up an obex server on any computers using *IrDA*, *Bluetooth* or *TCP/IP*. Use e.g. *obexftp* or the *ObexFS* to access the files on this server. == OPTIONS The ordering of options is important. The first transport option will start the server. Use basedir and verbose options prior to any transport. See *EXAMPLES* === Transport Options *-i*, *--irda*:: Acceopt connections using the IrDA protocol. *-b*, *--bluetooth*:: Accept connections via bluetooth. *-t* _device_, *--tty* _device_:: Accept connections from this tty device. NOT WORKING! *-n* _host_, *--network* _host_:: Accept connections from the network to this port. === Setting The File Path *-c* _folder_, *--chdir* _folder_:: Set the base directory for the server. === Version Information And Help *-v*, *--verbose*:: Be verbose and give some additional infos. *-V*, *--version*:: Print version string and exit. *-h*, *--help*, *--usage*:: Print short usage instructions. == EXAMPLES Start listening for bluetooth connections and use a safe basedir::: *obexftpd -c /tmp/inbox -b* == SEE ALSO obexftp(1), openobex(3), obexftp(3), multicobex(3), libbfb(3). == BUGS Bugs ? Features ! == NOTES The software has been tested and reported working on at least Siemens, Ericsson, and Nokia phones. == AUTHOR Christian W. Zuckschwerdt Alan Zhang obexftp-0.24-Source/Doxyfile100777 0 0 23673 12115454406 11226 0# Doxyfile 1.4.7 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = ObexFTP PROJECT_NUMBER = 0.24 OUTPUT_DIRECTORY = doc/api CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO BUILTIN_STL_SUPPORT = NO DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = NO EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = NO FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = bfb/bfb.c bfb/bfb.h \ multicobex/multi_cobex.c multicobex/multi_cobex.h \ obexftp/cache.c obexftp/client.c obexftp/client.h \ obexftp/obexftp.h obexftp/uuid.h \ Doxyfile.coverpage FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.C \ *.CC \ *.C++ \ *.II \ *.I++ \ *.H \ *.HH \ *.H++ \ *.CS \ *.PHP \ *.PHP3 \ *.M \ *.MM \ *.PY RECURSIVE = NO EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = *_private.h EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = NO INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES USE_HTAGS = NO VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = YES MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO obexftp-0.24-Source/Doxyfile.coverpage100777 0 0 7556 12115454406 13162 0/** \mainpage \section intro_sec Introduction ObexFTP implements the Object Exchange (OBEX) file transfer feature for clients and servers. The standard is defined in more detail in section K12.5 (Profiles: OBEX FTP) in Bluetooth V1.1 Profile Specifications. ObexFTP works out-of-the-box with all transports supported by OpenOBEX. Currently there is IrDA, Bluetooth, USB and network (TCP) transport support. ObexFTP also comes with ready to use custom transport support for many mobile phones serial cables. It's well tested with Siemens and Sony/Ericsson mobile phones. But then most Motorola and Sharp (generic) as well as Samsung phones will work too, please contact the author if not. This ObexFTP distribution contains libraries as well as some applications. Applications to access e.g. Flex. Memory and Multimedia- /Secure Digital Card memory on mobile equipment: - obexftp - all in one client application (heavy on options) - Symlinks to obexftp for default operations: - obexls - list the mobiles contents - obexget - copy files(s) to mobile - obexput - copy files(s) from mobile - obexrm - remove files on the mobile - obexftpd - obex ftp server application (experimental) Applications to hack Siemens mobile equipment using datalink cable - bfb_keysim - simulate key presses on the mobile - bfb_eeprom - list and examine the user eeprom on the mobile Library parts to be used in other applications - obexftp - high level abstraction of OBEX FTP (SYNC, PUSH also) protocol - multicobex - cable OBEX support for many phones (i.e. Siemens BFB and BFC Sony/Ericsson, Motorola and generic (Sharp) modes) - bfb - Siemens mobile datalink cable protocol layer \section install_sec Short Installation Instructions To compile and install: \verbatim # ./configure # make # make install (as superuser) \endverbatim If you plan to use a Siemens x45 or x55 series (e.g. S45 or C55, not S65) use \verbatim CFLAGS="$CFLAGS -DCOMPAT_S45" ./configure \endverbatim instead Consider using pedantic error checking: \verbatim CFLAGS="$CFLAGS -Werror" ./configure \endverbatim If compiling doesn't work, try to disable some of the language bindings on configure. \verbatim --disable-perl --disable-python --disable-ruby --disable-tcl \endverbatim \section development_sec Further Development If this tool lacks support for your phone or just won't work quite right please let me know. Development will focus on your needs. This package lacks advanced examples using the bindings. There are some 3rd party GUIs and other projects like a obex file system though. Please see the OpenOBEX / ObexFTP web site for details. Developers are free to use the bindings as well as obexftp, multicobex and bfb libraries. Please join the mailing list and keep in touch - You'll recieve pre-releases and support. That way your application can benefit from the newest library features and further development can focus on your needs. \section debugging_sec Debugging remove all ObexFTP installations from your system. Build using \verbatim CFLAGS="-DOBEXFTP_DEBUG=5" ./configure make clean ; make \endverbatim Start debugging using \verbatim ./apps/obexftp [...] \endverbatim You might want to try picking up compiler warnings too (and mail them to me) \verbatim CFLAGS="$CFLAGS -g -Wall -Wmissing-declarations -Wmissing-prototypes \ -Werror" ./configure make clean ; make \endverbatim Please mail me all warnings and errors, if any. The bindings use language-native installers which are missing the uninstall targets. Our distcheck will boldly ignore those files. \section contact_sec Author and Contact Author: Christian W. Zuckschwerdt - http://dev.zuckschwerdt.org/openobex/ - http://openobex.sourceforge.net/ - http://sourceforge.net/tracker/?group_id=8960 - http://sourceforge.net/forum/?group_id=8960 */ obexftp-0.24-Source/Doxyfile.developer100777 0 0 23461 12115454406 13205 0# Doxyfile 1.4.7 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = ObexFTP PROJECT_NUMBER = 0.22 OUTPUT_DIRECTORY = doc/handbook CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO BUILTIN_STL_SUPPORT = NO DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = NO FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = bfb multicobex obexftp includes Doxyfile.coverpage FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.C \ *.CC \ *.C++ \ *.II \ *.I++ \ *.H \ *.HH \ *.H++ \ *.CS \ *.PHP \ *.PHP3 \ *.M \ *.MM \ *.PY RECURSIVE = NO EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = *_private.h EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = NO INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES USE_HTAGS = NO VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO obexftp-0.24-Source/examples/ 40777 0 0 0 12115602310 11170 5obexftp-0.24-Source/examples/c_example.c100777 0 0 3250 12115454406 13404 0/* Minimal ObexFTP C client example Copyright (c) 2007 Christian W. Zuckschwerdt Compile with: gcc -Wall $(pkg-config --libs obexftp) -o c_example c_example.c */ #include #include #include /*!!!*/ int main(int argc, char *argv[]) { char *device; int channel; char *filename = NULL; obexftp_client_t *cli = NULL; /*!!!*/ int ret; /* Get device, channel and optional filename */ if (argc < 3) { fprintf(stderr, "Usage: %s []\n", argv[0]); exit(1); } device = argv[1]; channel = atoi(argv[2]); if (argc > 3) { filename = argv[3]; } /* Open connection */ cli = obexftp_open(OBEX_TRANS_BLUETOOTH, NULL, NULL, NULL); /*!!!*/ if (cli == NULL) { fprintf(stderr, "Error opening obexftp client\n"); exit(1); } /* Connect to device */ ret = obexftp_connect(cli, device, channel); /*!!!*/ if (ret < 0) { fprintf(stderr, "Error connecting to obexftp device\n"); obexftp_close(cli); cli = NULL; exit(1); } if (filename == NULL) { /* List folder */ ret = obexftp_list(cli, NULL, "/"); /*!!!*/ if (ret < 0) { fprintf(stderr, "Error getting a folder listing\n"); } else { printf("%s\n", cli->buf_data); /*!!!*/ } } else { /* Get file */ ret = obexftp_get(cli, NULL, filename); /*!!!*/ if (ret < 0) { fprintf(stderr, "Error getting a file\n"); } else { /* do something with cli->buf_data and cli->buf_size */ } } /* Disconnect */ ret = obexftp_disconnect(cli); /*!!!*/ if (ret < 0) { fprintf(stderr, "Error disconnecting the client\n"); } /* Close */ obexftp_close(cli); /*!!!*/ cli = NULL; exit(0); } obexftp-0.24-Source/examples/c_example_obex_push.c100777 0 0 3132 12115454406 15457 0/* OBEX PUSH ObexFTP C client example Copyright (c) 2007 Christian W. Zuckschwerdt Compile with: gcc -Wall $(pkg-config --libs obexftp) -o c_example_obex_push c_example_obex_push.c */ #include #include #include #include /*!!!*/ int main(int argc, char *argv[]) { char *device = NULL; int channel = -1; char *filepath, *filename; obexftp_client_t *cli = NULL; /*!!!*/ int ret; /* Get the filename, device and optional channel */ if (argc < 3) { fprintf(stderr, "Usage: %s []\n", argv[0]); exit(1); } filepath = argv[1]; device = argv[2]; if (argc > 3) channel = atoi(argv[3]); else channel = obexftp_browse_bt_push(device); /*!!!*/ /* Extract basename from file path */ filename = strrchr(filepath, '/'); if (!filename) filename = filepath; else filename++; /* Open connection */ cli = obexftp_open(OBEX_TRANS_BLUETOOTH, NULL, NULL, NULL); /*!!!*/ if (cli == NULL) { fprintf(stderr, "Error opening obexftp client\n"); exit(1); } /* Connect to device */ ret = obexftp_connect_push(cli, device, channel); /*!!!*/ if (ret < 0) { fprintf(stderr, "Error connecting to obexftp device\n"); obexftp_close(cli); cli = NULL; exit(1); } /* Push file */ ret = obexftp_put_file(cli, filepath, filename); /*!!!*/ if (ret < 0) { fprintf(stderr, "Error putting file\n"); } /* Disconnect */ ret = obexftp_disconnect(cli); /*!!!*/ if (ret < 0) { fprintf(stderr, "Error disconnecting the client\n"); } /* Close */ obexftp_close(cli); /*!!!*/ cli = NULL; exit(0); } obexftp-0.24-Source/examples/obexftpbackup100777 0 0 4415 12115454406 14067 0#!/bin/bash --norc #btchan="-B 15" retries=10 [ "X$1" == "X-version" ] && { echo "$0 version 2.0" exit 0 } overwrite=0 [ "X$1" == "X-o" ] && { overwrite=1 shift } [ $# -gt 1 ] && { echo "usage: $0 [-o] [dir]" echo "usage: $0 [-version]" exit 1 } topdir=$1 [ -z "$1" ] && topdir=~/Documents/Obexftp-backups [ ! -d $topdir ] && { echo "${0}: ${topdir}: No such directory" exit 1 } echo "Scanning for new phones" for btaddr in `hcitool scan | grep : | cut -f2` do sleep 1 subdir=`hcitool scan | grep --fixed-strings $btaddr | cut -f3` echo "Found phone $subdir" mkdir "$topdir/$subdir" 2>/dev/null echo $btaddr > "$topdir/$subdir/.Bluetooth-addr" done sleep 1 obexftpdir() { echo "Parsing \$1=\"$1\" \$2=\"$2\" \$3=\"$3\" \$4=\"$4\" \$5=\"$5\" \$6=\"$6\" \$7=\"$7\" \$8=\"$8\"" sleep 1 obexftp -b $btaddr $btchan ${1:+-c "$1"} ${2:+-c "$2"} ${3:+-c "$3"} ${4:+-c "$4"} ${5:+-c "$5"} ${6:+-c "$6"} ${7:+-c "$7"} ${8:+-c "$8"} -l 2>/dev/null | tr '<' '\012' | grep "file name" | cut -d\" -f2 | sed -e "s/\&apos\;/'/" | while read fil do sleep 1 echo "Checking file $fil" [ ! -z "`echo $fil | grep '\.dm$'`" ] && { echo "Cannot copy DRM protected files" touch "$fil" } [ $overwrite == "1" ] || [ ! -f "$fil" ] && { echo "reading $fil" retry=0 success=0 while [ $success -eq 0 -a $retry -lt $retries ] do success=`obexftp -b $btaddr $btchan ${1:+-c "$1"} ${2:+-c "$2"} ${3:+-c "$3"} ${4:+-c "$4"} ${5:+-c "$5"} ${6:+-c "$6"} ${7:+-c "$7"} ${8:+-c "$8"} -g "$fil" 2>&1 | grep -c '^Receiving.*'"$fil"'.*done$'` sleep 1 [ $success -eq 0 ] && echo "Retrying ..." retry=`expr $retry + 1` done echo "read $fil success $success" } done sleep 1 obexftp -b $btaddr $btchan ${1:+-c "$1"} ${2:+-c "$2"} ${3:+-c "$3"} ${4:+-c "$4"} ${5:+-c "$5"} ${6:+-c "$6"} ${7:+-c "$7"} -l 2>/dev/null | tr '<' '\012' | grep "folder name" | cut -d\" -f2 | while read sub do echo "Subdir is \"$sub\"" mkdir "$sub" 2>/dev/null cd "$sub" obexftpdir ${1:+"$1"} ${2:+"$2"} ${3:+"$3"} ${4:+"$4"} ${5:+"$5"} ${6:+"$6"} ${7:+"$7"} "$sub" cd .. done } cd $topdir ls | while read dir do echo Getting files for phone `basename "$dir"` btaddr=`cat "$dir/.Bluetooth-addr"` mkdir "$dir" 2>/dev/null cd "$dir" obexftpdir cd .. done exit 0 obexftp-0.24-Source/examples/perl_example.pl100777 0 0 1445 12115454406 14321 0#!/usr/bin/perl -w use strict; use OBEXFTP; my $obex = new OBEXFTP::client($OBEXFTP::BLUETOOTH); my $devs = $obex->discover(); die "No devices found" unless @$devs > 0; print "Found " . scalar @$devs . " devices\n"; my $dev = $devs->[0]; # or $$devs[0] my $channel = OBEXFTP::browsebt($dev, 0); # default is ftp print "Using device $dev on channel $channel\n"; sleep 2; my $ret = $obex->connect($dev, $channel); print "$ret\n"; $ret = $obex->list("/"); print "$ret\n"; sleep 2; $ret = $obex->list("/images"); print "$ret\n"; sleep 2; $ret = $obex->get("/images/some.jpg"); open OUT, ">downloaded.jpg" or die "Can't write test.out: $@"; binmode(OUT); print OUT $ret; close OUT; $ret = $obex->get("/data/README.txt"); print "$ret\n"; $ret = $obex->disconnect(); print "$ret\n"; $obex->DESTROY(); obexftp-0.24-Source/examples/picture-mover100777 0 0 576 12115454406 14017 0#!/bin/sh # append your mobiles address to '-b' for slight speedup # optionally choose a channel with '-B' # change the '-c path' into something useful for your device # use '-G' instead of '-g' to move the pictures (copy & delete) pics=$(obexftp -b -c MMCard -c Pictures -l |grep 'file.*jpg' |cut -d '"' -f 2) echo Getting $pics sleep 3 obexftp -b -c MMCard -c Pictures -g $pics obexftp-0.24-Source/examples/python_example.py100777 0 0 652 12115454406 14674 0#!/usr/bin/python import obexftp obex = obexftp.client(obexftp.BLUETOOTH) devs = obex.discover(); print devs; dev = devs[0] print "Using %s" % dev channel = obexftp.browsebt(dev,0) print "Channel %d" % channel print obex.connect(dev, channel) print obex.list("/") print obex.list("/images") data = obex.get("/images/some.jpg") file = open('downloaded.jpg', 'wb') file.write(data) print obex.disconnect() obex.delete obexftp-0.24-Source/examples/README_obexftpbackup100777 0 0 2465 12115454406 15107 0------------- obexftpbackup 2.0 ------------- A while ago I wrote an obexftpbackup script which worked fine on the basic SE T610 file structure. Since upgrading to obexftp 0.18 I've had to modify the error checking, but more significantly I've had to completely re-write it to handle the directory structure of the SE K750i. In its current form it will handle up to 8 levels of subdirectories and will accept file and directory names with spaces in them. There's also a sed line to handle filenames with apostrophes in them. To use it simply create a directory called ~/Documents/Obexftp-backups, switch your phone's bluetooth to visible for the first run, then run obexftpbackup. On subsequent runs the phone can be hidden. I've only found one bug so far, and that appears to be in obexftp itself when trying read the directory contents for the Pictures directory. I suspect this could be due to having over 100 jpegs in that folder. Enjoy! Ken. ------------- obexftpbackup 1.0 ------------- The sleeps appear to be necessary to give my Sony Ericsson T610 a chance. If you wish to retain all your previous downloads from the phone then don't use the -o option, and take care to rename your pictures from the default name otherwise Picture(1).jpg etc will omitted from your backup. Ken Booth obexftp-0.24-Source/examples/ruby_example.rb100777 0 0 665 12115454406 14313 0#!/usr/bin/env ruby require 'obexftp' intfs = Obexftp.discover(Obexftp::USB) intfs.each { |i| puts i } # - or - obex = Obexftp::Client.new(Obexftp::BLUETOOTH) intfs = obex.discover intfs.each { |i| puts i } # - then - dev = intfs.first channel = Obexftp.browsebt(dev, 0) # default is ftp obex = Obexftp::Client.new(Obexftp::BLUETOOTH) # or reuse the above puts obex.connect(dev, channel) puts obex.list('/') puts obex.disconnect obexftp-0.24-Source/examples/ruby_list_devices.rb100777 0 0 765 12115454406 15336 0#!/usr/bin/env ruby require 'obexftp' puts "Scanning USB..." intfs = Obexftp.discover(Obexftp::USB) intfs.each do |dev| puts "usb/#{dev}" end puts "Scanning BT..." intfs = Obexftp.discover(Obexftp::BLUETOOTH) intfs.each do |dev| channel = Obexftp.browsebt(dev, Obexftp::PUSH) puts "bt/[#{dev}]:#{channel} (push)" channel = Obexftp.browsebt(dev, Obexftp::FTP) puts "bt/[#{dev}]:#{channel} (ftp)" channel = Obexftp.browsebt(dev, Obexftp::SYNC) puts "bt/[#{dev}]:#{channel} (sync)" end obexftp-0.24-Source/examples/ruby_obexftp.rb100777 0 0 13037 12115454406 14364 0#!/usr/bin/env ruby # == Synopsis # # Transfer files from/to Mobile Equipment. # # == Usage # # ruby_obexftp.rb # transport: [ -i | -b [-B ] | -U | -t | -N ] # operations: [-c ...] [-C ] [-l []] # [-g ...] [-p ...] [-k ...] # # -i, --irda connect using IrDA transport (default) # -b, --bluetooth [] use or search a bluetooth device # [ -B, --channel ] use this bluetooth channel when connecting # -u, --usb [] connect to a usb interface or list interfaces # -t, --tty connect to this tty using a custom transport # -n, --network connect to this host # # -F, --ftp use FTP (default) # -P, --push use OPUSH # -S, --sync use IRMC # -c, --chdir chdir # -C, --mkdir mkdir and chdir # -l, --list [] list current/given folder # -o, --output specify the target file name # get and put always specify the remote name. # -g, --get fetch files # -G, --getdelete fetch and delete (move) files # -p, --put send files # -k, --delete delete files # # -X, --capability retrieve capability object # -v, --verbose verbose messages # -V, --version print version info # -h, --help, --usage this help text # # fmtstring:: # A +strftime+ format string controlling the # display of the date and time. If omitted, # use "%Y% M% d %H:%m" # # == Author # Christian W. Zuckschwerdt # # == Copyright # Copyright (c) 2006 Christian W. Zuckschwerdt # Licensed under the same terms as Ruby. require 'optparse' require 'rdoc/usage' require 'obexftp' @cli = nil @transport = Obexftp::BLUETOOTH @service = Obexftp::FTP @device = nil @channel = -1 # connect with given uuid. re-connect every time def cli_connect if @cli.nil? # Open @cli = Obexftp::Client.new(@transport) raise "Error opening obexftp-client" if @cli.nil? end @cli.callback Proc.new { |num, msg| puts "Callback no.#{num} '#{msg}'" if msg.length < 30 } # for (retry = 0; retry < 3; retry++) # Connect @cli.connect(@device, @channel) and return @cli # fprintf(stderr, "Still trying to connect\n") # end @cli.close @cli = nil end def cli_disconnect return if @cli.nil? @cli.disconnect # @cli.close @cli = nil end # preset mode of operation depending on our name # preset from environment OptionParser.new do |opts| verbose = false target_path = nil output_file = nil opts.on('-i', '--irda') do @transport = Obexftp::IRDA @device = nil @channel = 0 end opts.on('-b', '--bluetooth [ADDR]') do |arg| @transport = Obexftp::BLUETOOTH @device = arg if arg.nil? intfs = Obexftp.discover(@transport) intfs.each { |i| puts i } @device = intfs.first end @channel = Obexftp.browsebt(@device, @service) puts "Got channel #{@channel}" end opts.on('-B', '--channel N', Integer) do |arg| @channel = arg end opts.on('-u', '--usb [N]', Integer) do |arg| # "If USB doesn't work setup permissions in udev or run as superuser." @transport = Obexftp::USB @device = nil @channel = arg intfs = Obexftp.discover(@transport) end opts.on('-t', '--tty DEVICE') do |arg| @transport, @device, @channel = Obexftp::CABLE, arg, -1 # if (strstr(arg, "ir") != NULL) # fprintf(stderr, "Do you really want to use IrDA via ttys?\n"); end opts.on('-n', '--network HOST') do |arg| @transport = Obexftp::NETWORK @device = arg # dotted quad, hopefully @channel = 0 end opts.on('-F', '--ftp') do cli_disconnect @service = Obexftp::FTP end opts.on('-P', '--push') do cli_disconnect @service = Obexftp::PUSH end opts.on('-S', '--sync') do cli_disconnect @service = Obexftp::SYNC end opts.on('-l', '--list [PATH]') do |arg| puts cli_connect.list(arg) end opts.on('-c', '--chdir [PATH]') do |arg| cli_connect.chpath(arg) end opts.on('-C', '--mkdir PATH') do |arg| cli_connect.mkpath(arg) end opts.on('-o', '--output PATH') do |arg| output_file = arg end opts.on('-g', '--get PATH') do |arg| output_file ||= File.basename(arg) result = cli_connect.get(arg) raise "No such file" if result.nil? open(output_file, 'w') do |file| file.print(result) end output_file = nil end opts.on('-G', '--getdelete PATH') do |arg| output_file ||= File.basename(arg) cli = cli_connect result = cli.get(arg) raise "No such file" if result.nil? open(output_file, 'w') do |file| file.print(result) cli.del(arg) end output_file = nil end opts.on('-p', '--put PATH') do |arg| output_file ||= File.basename(arg) cli_connect.put_file(arg, output_file) output_file = nil end opts.on('-k', '--delete PATH') do |arg| cli_connect.delete(arg) end opts.on('-X', '--capabilities [PATH]') do |arg| cli_connect.get_capability(arg) end opts.on('-v', '--[no-]verbose', 'Run verbosely') do |arg| verbose = arg end opts.on('-V', '--version') do puts "ObexFTP #{VERSION}" end opts.on('-h', '--help') do RDoc::usage end opts.parse!(ARGV) # rescue RDoc::usage('usage') end cli_disconnect obexftp-0.24-Source/examples/ruby_obex_push.rb100777 0 0 3163 12115454406 14670 0#!/usr/bin/env ruby =begin ruby_obex_push.rb - Ruby/GTK2 example of ObexFTP push client. Copyright (c) 2007 Christian W. Zuckschwerdt Original Ruby/GTK2 examples Copyright Ruby-GNOME2 Project Team This program is licenced under the same licence as Ruby-GNOME2. =end require 'gtk2' require 'obexftp' dialog = Gtk::FileChooserDialog.new("Send file via bluetooth", nil, Gtk::FileChooser::ACTION_OPEN, "gnome-vfs", [Gtk::Stock::COPY, Gtk::Dialog::RESPONSE_ACCEPT], [Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_CANCEL] ) label = Gtk::Label.new("Select target device:") combo = Gtk::ComboBox.new hbox = Gtk::HBox.new hbox.add(label).add(combo).show_all dialog.extra_widget = hbox dialog.signal_connect("response") do |widget, response| case response when Gtk::Dialog::RESPONSE_ACCEPT filename = dialog.filename dev = combo.active_text channel = Obexftp.browsebt(dev, Obexftp::PUSH) obex = Obexftp::Client.new(Obexftp::BLUETOOTH) puts obex.connectpush(dev, channel) puts obex.put_file(filename) puts obex.disconnect else dialog.destroy Gtk.main_quit end end # Should use gtk.timeout_add and/or Thread.new for the scanning... puts "Scanning USB..." intfs = Obexftp.discover(Obexftp::USB) # intfs.each { |i| combo.append_text(i) } # enable this with >=ObexFTP-0.23 puts "Scanning BT..." intfs = Obexftp.discover(Obexftp::BLUETOOTH) intfs.each { |i| combo.append_text(i) } combo.active = 0 dialog.show_all Gtk.main obexftp-0.24-Source/examples/tcl_example.tcl100777 0 0 330 12115454406 14260 0#!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@" load obexftp.so puts [discover $BLUETOOTH] client c $BLUETOOTH puts [c connect "00:11:22:33:44:55" 6] puts [c list "/"] c disconnect c -delete obexftp-0.24-Source/fuse/ 40777 0 0 0 12115602310 10314 5obexftp-0.24-Source/fuse/CMakeLists.txt100777 0 0 615 12115454406 13151 0 find_package ( Fuse ) if ( Fuse_FOUND ) include_directories ( ${Fuse_INCLUDE_DIRS} ) add_definitions ( ${Fuse_DEFINITIONS} ) add_executable ( obexfs obexfs.c ) target_link_libraries ( obexfs obexftp ${Fuse_LIBRARIES} ) add_executable ( obexautofs obexautofs.c ) target_link_libraries ( obexautofs obexftp ${Fuse_LIBRARIES} ) endif ( Fuse_FOUND ) obexftp-0.24-Source/fuse/obexautofs.c100777 0 0 46636 12115454406 13011 0/* * obexautofs.c: FUSE Filesystem to access OBEX with automount * This is just a wrapper. ObexFTP API does the real work. * * Copyright (c) 2003-2006 Christian W. Zuckschwerdt * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program 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 General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* strndup */ #define _GNU_SOURCE /* at least fuse v 2.2 is needed */ #define FUSE_USE_VERSION 22 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define UNUSED(x) x __attribute__((unused)) #define DEBUGOUPUT #ifdef DEBUGOUPUT #define DEBUG(...) fprintf(stderr, __VA_ARGS__) #else #define DEBUG(...) do { } while (0) #endif typedef struct connection connection_t; struct connection { char *alias; int transport; char *addr; int channel; obexftp_client_t *cli; int nodal; int recent; connection_t *next; }; #define SCAN_INTERVAL 2 static time_t last_scan = 0; static connection_t *connections; static char *tty = NULL; // "/dev/ttyS0"; static char *source = NULL; // "00:11:22:33:44:55"; "hci0"; static int search_irda = 1; static int search_bt = 1; static int search_usb = 1; static int nonblock = 0; static int discover_irda(void) { return -1; } static int discover_usb(void) { char **devices, **dev; char name[25], *p; connection_t *conn; DEBUG("Scanning USB...\n"); devices = obexftp_discover(OBEX_TRANS_USB); for(dev = devices; *dev; dev++) { strcpy(name, "usb"); strncpy(&name[3], *dev, sizeof(name)-4); p = strchr(name, ' '); if (p) *p = '\0'; DEBUG("Found %s (%d), %s\n", name, atoi(*dev), *dev); for (conn = connections; conn; conn = conn->next) { if (!strcmp(conn->addr, name)) { conn->recent++; break; } } if (!conn) { DEBUG("Adding %s\n", name); conn = calloc(1, sizeof(connection_t)); if (!conn) return -1; conn->alias = NULL; conn->transport = OBEX_TRANS_USB; conn->addr = strdup(name); conn->channel = atoi(*dev); //conn->cli = cli_open(OBEX_TRANS_USB, NULL, conn->channel); conn->recent++; conn->next = connections; connections = conn; } } return 0; } static int discover_tty(char *UNUSED(port)) { return -1; } static int discover_bt(void) { char *hci = NULL; char **devs, **dev, *name; connection_t *conn; DEBUG("Scanning ...\n"); devs = obexftp_discover_bt_src(hci); if(!devs) { perror("Inquiry failed."); return -1; } for(dev = devs; dev && *dev; dev++) { for (conn = connections; conn; conn = conn->next) { if (!strcmp(conn->addr, *dev)) { conn->recent++; break; } } if (!conn) { name = obexftp_bt_name_src(*dev, hci); DEBUG("Adding\t%s\t%s\n", *dev, name); conn = calloc(1, sizeof(connection_t)); if (!conn) return -1; conn->alias = name; conn->transport = OBEX_TRANS_BLUETOOTH; conn->addr = *dev; conn->channel = obexftp_browse_bt_ftp(conn->addr); //conn->cli = cli_open(OBEX_TRANS_BLUETOOTH, conn->addr, conn->channel); conn->recent++; conn->next = connections; connections = conn; } else free(*dev); } free(devs); return 0; } static void cli_close(obexftp_client_t *cli); static int discover_devices(void) { connection_t *conn, *prev; for (conn = connections; conn; conn = conn->next) conn->recent = 0; if (search_irda) discover_irda(); if (search_bt) discover_bt(); if (search_usb) discover_usb(); if (tty) discover_tty(tty); /* remove from head */ while (connections && connections->recent == 0) { DEBUG("Deleting %s\n", connections->addr); conn = connections; connections = conn->next; cli_close(conn->cli); if (conn->alias) free(conn->alias); free(conn->addr); free(conn); } /* remove from body */ for (prev = connections; prev; prev = prev->next) if(prev->next && prev->next->recent == 0) { DEBUG("Deleting2 %s\n", prev->next->addr); conn = prev->next; prev->next = conn->next; cli_close(conn->cli); if (conn->alias) free(conn->alias); free(conn->addr); free(conn); } return 0; } typedef struct data_buffer data_buffer_t; struct data_buffer { size_t size; char *data; int write_mode; /* is this a write buffer? */ }; static char *mknod_dummy = NULL; /* bad coder, no biscuits! */ /* connection handling operations */ static obexftp_client_t *cli_open(int transport, char *addr, int channel) { obexftp_client_t *cli; int retry; /* Open */ cli = obexftp_open (transport, NULL, NULL, NULL); if(cli == NULL) { /* Error opening obexftp-client */ return NULL; } for (retry = 0; retry < 3; retry++) { /* Connect */ if (obexftp_connect_src (cli, source, addr, channel, UUID_FBS, sizeof(UUID_FBS)) >= 0) return cli; /* Still trying to connect */ sleep(1); } return NULL; } static void cli_close(obexftp_client_t *cli) { if (!cli) return; /* Disconnect */ (void) obexftp_disconnect (cli); /* Close */ obexftp_close (cli); } static int ofs_connect(connection_t *conn) { if (!conn || !conn->cli) return -ENOENT; if (nonblock) { if (++conn->nodal > 1) { conn->nodal--; return -EBUSY; } } else { while (++conn->nodal > 1) { conn->nodal--; sleep(1); } } DEBUG("%s() >>>blocking<<<\n", __func__); return 0; } static void ofs_disconnect(connection_t *conn) { if (!conn || !conn->cli) return; /* -ENOENT */ conn->nodal--; DEBUG("%s() <<>>\n", __func__); } static connection_t *ofs_find_connection(const char *path, char **filepath) { int namelen; connection_t *conn; if (!path || path[0] != '/') { DEBUG("Invalid base path \"%s\"\n", path); return NULL; } path++; *filepath = strchr(path, '/'); if (*filepath) namelen = *filepath - path; else namelen = strlen(path); for (conn = connections; conn; conn = conn->next) { if (!strncmp(conn->addr, path, namelen) || (conn->alias && !strncmp(conn->alias, path, namelen))) { if (!conn->cli) conn->cli = cli_open(conn->transport, conn->addr, conn->channel); return conn; } } return NULL; } /* file and directory operations */ static int ofs_getattr(const char *path, struct stat *stbuf) { connection_t *conn; char *filepath; stat_entry_t *st; int res; if(!path || *path == '\0' || !strcmp(path, "/")) { /* root */ stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 1; /* should be NSUB+2 for dirs */ stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); stbuf->st_size = 0; stbuf->st_blocks = 0; stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL); return 0; } DEBUG("%s() '%s'\n", __func__, path); if (mknod_dummy && !strcmp(path, mknod_dummy)) { /* fresh mknod dummy */ stbuf->st_mode = S_IFREG | 0755; stbuf->st_nlink = 1; /* should be NSUB+2 for dirs */ stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); stbuf->st_size = 0; stbuf->st_blocks = 0; stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL); free(mknod_dummy); mknod_dummy = NULL; return 0; } conn = ofs_find_connection(path, &filepath); if (!conn) return -ENOENT; if(!filepath) { /* the device entry itself */ if (!strcmp(path + 1, conn->addr)) stbuf->st_mode = S_IFDIR | 0755; else stbuf->st_mode = S_IFLNK | 0777; stbuf->st_nlink = 1; /* should be NSUB+2 for dirs */ stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); stbuf->st_size = 0; stbuf->st_blocks = 0; stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL); return 0; } res = ofs_connect(conn); if(res < 0) return res; /* errno */ st = obexftp_stat(conn->cli, filepath); ofs_disconnect(conn); if (!st) return -ENOENT; stbuf->st_mode = st->mode; stbuf->st_nlink = 1; /* should be NSUB+2 for dirs */ stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); stbuf->st_size = st->size; stbuf->st_blksize = 512; /* they expect us to do so... */ stbuf->st_blocks = (st->size + stbuf->st_blksize) / stbuf->st_blksize; stbuf->st_mtime = st->mtime; stbuf->st_atime = st->mtime; stbuf->st_ctime = st->mtime; return 0; } static int ofs_readlink (const char *path, char *link, size_t UNUSED(size)) { connection_t *conn; for (conn = connections; conn; conn = conn->next) { if(conn->alias && !strcmp(conn->alias, path + 1)) { strcpy(link, conn->addr); return 0; } } return -ENOENT; } static int ofs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler) { connection_t *conn; char *filepath; DIR *dir; stat_entry_t *ent; int res; if(!path || *path == '\0' || !strcmp(path, "/")) { /* list devices */ if (last_scan + SCAN_INTERVAL < time(NULL)) { discover_devices(); last_scan = time(NULL); } DEBUG("listing devices...\n"); res = filler(h, ".", DT_DIR, 0); res = filler(h, "..", DT_DIR, 0); for (conn = connections; conn; conn = conn->next) { if (conn->alias) res = filler(h, conn->alias, DT_LNK, 0); res = filler(h, conn->addr, DT_DIR, 0); if(res != 0) break; } return 0; } conn = ofs_find_connection(path, &filepath); if (!conn) return -1; /* FIXME */ res = ofs_connect(conn); if(res < 0) return res; /* errno */ dir = obexftp_opendir(conn->cli, filepath); if (!dir) { ofs_disconnect(conn); return -ENOENT; } res = filler(h, ".", DT_DIR, 0); res = filler(h, "..", DT_DIR, 0); while ((ent = obexftp_readdir(dir)) != NULL) { DEBUG("GETDIR:%s\n", ent->name); res = filler(h, ent->name, S_ISDIR(ent->mode) ? DT_DIR : DT_REG, 0); if(res != 0) break; } obexftp_closedir(dir); ofs_disconnect(conn); return 0; } /* needed for creating files and writing to them */ static int ofs_mknod(const char *path, mode_t UNUSED(mode), dev_t UNUSED(dev)) { /* check for access */ /* create dummy for subsequent stat */ if (mknod_dummy) { free(mknod_dummy); fprintf(stderr, "warning: overlapping mknod calls.\n"); } mknod_dummy = strdup(path); return 0; } static int ofs_mkdir(const char *path, mode_t UNUSED(mode)) { connection_t *conn; char *filepath; int res; if(!path || *path != '/') return 0; conn = ofs_find_connection(path, &filepath); if (!conn) return -1; /* FIXME */ res = ofs_connect(conn); if(res < 0) return res; /* errno */ (void) obexftp_setpath(conn->cli, filepath, 1); ofs_disconnect(conn); return 0; } static int ofs_unlink(const char *path) { connection_t *conn; char *filepath; int res; if(!path || *path != '/') return 0; conn = ofs_find_connection(path, &filepath); if (!conn) return -1; /* FIXME */ res = ofs_connect(conn); if(res < 0) return res; /* errno */ (void) obexftp_del(conn->cli, filepath); ofs_disconnect(conn); return 0; } static int ofs_rename(const char *from, const char *to) { connection_t *conn; char *filepath; int res; if(!from || *from != '/') return 0; if(!to || *to != '/') return 0; conn = ofs_find_connection(from, &filepath); if (!conn) return -1; /* FIXME */ res = ofs_connect(conn); if(res < 0) return res; /* errno */ (void) obexftp_rename(conn->cli, from, to); ofs_disconnect(conn); return 0; } /* needed for overwriting files */ static int ofs_truncate(const char *UNUSED(path), off_t UNUSED(offset)) { DEBUG("%s() called. This is a dummy!\n", __func__); return 0; } /* well RWX for everyone I guess! */ static int ofs_open(const char *UNUSED(path), struct fuse_file_info *fi) { data_buffer_t *wb; wb = calloc(1, sizeof(data_buffer_t)); if (!wb) return -1; fi->fh = (unsigned long)wb; return 0; } static int ofs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *UNUSED(fi)) { connection_t *conn; char *filepath; data_buffer_t *wb; int res = 0; size_t actual; if(!path || *path != '/') return 0; wb = (data_buffer_t *)fi->fh; if (!wb->data) { conn = ofs_find_connection(path, &filepath); if (!conn) return -1; /* FIXME */ res = ofs_connect(conn); if(res < 0) return res; /* errno */ (void) obexftp_get(conn->cli, NULL, filepath); wb->size = conn->cli->buf_size; wb->data = conn->cli->buf_data; /* would be better to memcpy this */ //conn->cli->buf_data = NULL; /* now the data is ours -- without copying */ ofs_disconnect(conn); } actual = wb->size - offset; if (actual > size) actual = size; DEBUG("reading %s at %" PRId64 " for %zu (peek: %02x\n", path, offset, actual, wb->data[offset]); memcpy(buf, wb->data + offset, actual); return actual; } static int ofs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { data_buffer_t *wb; size_t newsize; DEBUG("Writing %s at %" PRId64 " for %zu\n", path, offset, size); wb = (data_buffer_t *)fi->fh; if (!wb) return -1; if (offset + size > wb->size) newsize = offset + size; else newsize = wb->size; /* don't change the buffer size */ if (!wb->data) wb->data = malloc(newsize); else if (newsize != wb->size) wb->data = realloc(wb->data, newsize); if (!wb->data) return -1; wb->size = newsize; wb->write_mode = 1; DEBUG("memcpy to %p (%p) from %p cnt %zu\n", wb->data + offset, wb->data, buf, size); (void) memcpy(&wb->data[offset], buf, size); return size; } /* careful, this can be a read release or a write release */ static int ofs_release(const char *path, struct fuse_file_info *fi) { connection_t *conn; char *filepath; data_buffer_t *wb; int res; wb = (data_buffer_t *)fi->fh; DEBUG("Releasing: %s (%p)\n", path, wb); if (wb && wb->data && wb->write_mode) { DEBUG("Now writing %s for %zu (%02x)\n", path, wb->size, wb->data[0]); conn = ofs_find_connection(path, &filepath); if (!conn) return -1; /* FIXME */ res = ofs_connect(conn); if(res < 0) return res; /* errno */ (void) obexftp_put_data(conn->cli, (uint8_t*)wb->data, wb->size, filepath); ofs_disconnect(conn); free(wb->data); free(wb); } return 0; } #ifdef SIEMENS /* just sum all clients */ static int ofs_statfs(const char *UNUSED(label), struct statfs *st) { connection_t *conn; int size = 0, free = 0; for (conn = connections; conn; conn = conn->next) if (conn->cli && ofs_connect(conn) >= 0) { /* for S45 */ (void) obexftp_disconnect (conn->cli); (void) obexftp_connect_uuid (conn->cli, conn->addr, conn->channel, UUID_S45, sizeof(UUID_S45)); /* Retrieve Infos */ (void) obexftp_info(conn->cli, 0x01); size += conn->cli->apparam_info; (void) obexftp_info(conn->cli, 0x02); free += conn->cli->apparam_info; DEBUG("%s() GOT FS STAT: %d / %d\n", __func__, free, size); (void) obexftp_disconnect (conn->cli); (void) obexftp_connect (conn->cli, conn->addr, conn->channel); ofs_disconnect(conn); } memset(st, 0, sizeof(struct statfs)); st->f_bsize = 1; /* optimal transfer block size */ st->f_blocks = size; /* total data blocks in file system */ st->f_bfree = free; /* free blocks in fs */ st->f_bavail = free; /* free blocks avail to non-superuser */ /* st->f_files; / * total file nodes in file system */ /* st->f_ffree; / * free file nodes in fs */ /* st->f_namelen; / * maximum length of filenames */ return 0; } #endif static void *ofs_init(void) { /* Open connection */ //res = cli_open(); //if(res < 0) // return res; /* errno */ //discover_bt(&alias, &bdaddr, &channel); //cli_open(); return NULL; } static void ofs_destroy(void *UNUSED(private_data)) { connection_t *conn; DEBUG("terminating...\n"); /* Close connection */ for (conn = connections; conn; conn = conn->next) { cli_close(conn->cli); if (conn->alias) free(conn->alias); free(conn->addr); free(conn); } return; } /* main */ static struct fuse_operations ofs_oper = { getattr: ofs_getattr, readlink: ofs_readlink, opendir: NULL, readdir: NULL, releasedir: NULL, getdir: ofs_getdir, mknod: ofs_mknod, mkdir: ofs_mkdir, symlink: NULL, unlink: ofs_unlink, rmdir: ofs_unlink, rename: ofs_rename, link: NULL, chmod: NULL, chown: NULL, truncate: ofs_truncate, utime: NULL, open: ofs_open, read: ofs_read, write: ofs_write, #ifdef SIEMENS statfs: ofs_statfs, #endif release: ofs_release, flush: NULL, fsync: NULL, init: ofs_init, destroy: ofs_destroy }; int main(int argc, char *argv[]) { while (1) { int option_index = 0; int c; static struct option long_options[] = { {"noirda", no_argument, NULL, 'I'}, {"nobluetooth", no_argument, NULL, 'B'}, {"nousb", no_argument, NULL, 'U'}, {"tty", required_argument, NULL, 't'}, {"hci", required_argument, NULL, 'd'}, {"nonblock", no_argument, NULL, 'N'}, {"help", no_argument, NULL, 'h'}, {"usage", no_argument, NULL, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "+IBUt:d:Nh", long_options, &option_index); if (c == -1) break; switch (c) { case 'I': search_irda = 0; break; case 'B': search_bt = 0; break; case 'U': search_usb = 0; break; case 't': if (tty != NULL) free (tty); tty = NULL; if (strcasecmp(optarg, "irda")) tty = optarg; break; case 'd': source = optarg; break; case 'N': nonblock = 1; break; case 'h': /* printf("ObexFS %s\n", VERSION); */ printf("Usage: %s [-I] [-B] [-U] [-t ] [-d ] [-N] [-- ]\n" "Transfer files from/to Mobile Equipment.\n" "Copyright (c) 2002-2005 Christian W. Zuckschwerdt\n" "\n" " -I, --noirda dont search for IrDA devices\n" " -B, --nobluetooth dont search for bluetooth devices\n" " -U, --nousb dont search for usb devices\n" " -t, --tty search for devices at this tty\n\n" " -d, --hci use only this source device address or number\n" " -N, --nonblock nonblocking mode\n\n" " -h, --help, --usage this help text\n\n" "Options to fusermount need to be preceeded by two dashes (--).\n" "\n", argv[0]); exit(0); break; default: printf("Try `%s --help' for more information.\n", argv[0]); exit(0); } } if (!search_irda && !search_bt && !search_usb && !tty) { fprintf(stderr, "No device selected. Use --help for help.\n"); exit(0); } argv[optind-1] = argv[0]; fprintf(stderr, "IrDA searching not available.\n"); fprintf(stderr, "USB searching not available.\n"); fprintf(stderr, "TTY searching not available.\n"); /* loop */ fuse_main(argc-optind+1, &argv[optind-1], &ofs_oper); return 0; } obexftp-0.24-Source/fuse/obexfs.c100777 0 0 33013 12115454406 12101 0/* * obexfs.c: FUSE Filesystem to access OBEX * This is just a wrapper. ObexFTP API does the real work. * * Copyright (c) 2003-2006 Christian W. Zuckschwerdt * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program 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 General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* strndup */ #define _GNU_SOURCE /* at least fuse v 2.2 is needed */ #define FUSE_USE_VERSION 22 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define UNUSED(x) x __attribute__((unused)) #define DEBUGOUPUT #ifdef DEBUGOUPUT #define DEBUG(...) fprintf(stderr, __VA_ARGS__) #else #define DEBUG(...) do { } while (0) #endif typedef struct data_buffer data_buffer_t; struct data_buffer { size_t size; char *data; int write_mode; /* is this a write buffer? */ }; static obexftp_client_t *cli = NULL; static int transport = 0; static char *source = NULL; // "00:11:22:33:44:55"; "hci0"; static char *device = NULL; // "00:11:22:33:44:55"; "/dev/ttyS0"; static int channel = -1; static int nonblock = 0; static char *mknod_dummy = NULL; /* bad coder, no cookies! */ static int nodal = 0; static int cli_open() { int retry; if (cli != NULL) return 0; /* Open */ cli = obexftp_open (transport, NULL, NULL, NULL); if(cli == NULL) { /* Error opening obexftp-client */ return -1; } if (channel < 0) { channel = obexftp_browse_bt_ftp(device); } for (retry = 0; retry < 3; retry++) { /* Connect */ if (obexftp_connect_src (cli, source, device, channel, UUID_FBS, sizeof(UUID_FBS)) >= 0) return 0; /* Still trying to connect */ sleep(1); } cli = NULL; return -1; } static void cli_close() { if (cli != NULL) { /* Disconnect */ (void) obexftp_disconnect (cli); /* Close */ obexftp_close (cli); } cli = NULL; } static int ofs_connect() { if (!cli) return -1; if (nonblock) { if (++nodal > 1) { nodal--; return -EBUSY; } } else { while (++nodal > 1) { nodal--; sleep(1); } } DEBUG("%s() >>>blocking<<<\n", __func__); return 0; } static void ofs_disconnect() { nodal--; DEBUG("%s() <<>>\n", __func__); } static int ofs_getattr(const char *path, struct stat *stbuf) { stat_entry_t *st; int res; if(!path || *path == '\0' || !strcmp(path, "/")) { stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 1; /* should be NSUB+2 for dirs */ stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); stbuf->st_size = 0; stbuf->st_blocks = 0; stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL); return 0; } DEBUG("%s() '%s'\n", __func__, path); if (mknod_dummy && !strcmp(path, mknod_dummy)) { stbuf->st_mode = S_IFREG | 0755; stbuf->st_nlink = 1; /* should be NSUB+2 for dirs */ stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); stbuf->st_size = 0; stbuf->st_blocks = 0; stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL); free(mknod_dummy); mknod_dummy = NULL; return 0; } res = ofs_connect(); if(res < 0) return res; /* errno */ st = obexftp_stat(cli, path); ofs_disconnect(); if (!st) return -ENOENT; stbuf->st_mode = st->mode; stbuf->st_nlink = 1; /* should be NSUB+2 for dirs */ stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); stbuf->st_size = st->size; stbuf->st_blksize = 512; /* they expect us to do so... */ stbuf->st_blocks = (st->size + stbuf->st_blksize) / stbuf->st_blksize; stbuf->st_mtime = st->mtime; stbuf->st_atime = st->mtime; stbuf->st_ctime = st->mtime; return 0; } static int ofs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler) { DIR *dir; stat_entry_t *ent; int res; res = ofs_connect(); if(res < 0) return res; /* errno */ dir = obexftp_opendir(cli, path); if (!dir) { ofs_disconnect(); return -ENOENT; } res = filler(h, ".", DT_DIR, 0); res = filler(h, "..", DT_DIR, 0); while ((ent = obexftp_readdir(dir)) != NULL) { DEBUG("GETDIR:%s\n", ent->name); res = filler(h, ent->name, S_ISDIR(ent->mode) ? DT_DIR : DT_REG, 0); if(res != 0) break; } obexftp_closedir(dir); ofs_disconnect(); return 0; } /* needed for creating files and writing to them */ static int ofs_mknod(const char *path, mode_t UNUSED(mode), dev_t UNUSED(dev)) { /* check for access */ /* create dummy for subsequent stat */ if (mknod_dummy) { free(mknod_dummy); fprintf(stderr, "warning: overlapping mknod calls.\n"); } mknod_dummy = strdup(path); return 0; } static int ofs_mkdir(const char *path, mode_t UNUSED(mode)) { int res; if(!path || *path != '/') return 0; res = ofs_connect(); if(res < 0) return res; /* errno */ (void) obexftp_setpath(cli, path, 1); ofs_disconnect(); return 0; } static int ofs_unlink(const char *path) { int res; if(!path || *path != '/') return 0; res = ofs_connect(); if(res < 0) return res; /* errno */ (void) obexftp_del(cli, path); ofs_disconnect(); return 0; } static int ofs_rename(const char *from, const char *to) { int res; if(!from || *from != '/') return 0; if(!to || *to != '/') return 0; res = ofs_connect(); if(res < 0) return res; /* errno */ (void) obexftp_rename(cli, from, to); ofs_disconnect(); return 0; } /* needed for overwriting files */ static int ofs_truncate(const char *UNUSED(path), off_t UNUSED(offset)) { DEBUG("%s() called. This is a dummy!\n", __func__); return 0; } /* well RWX for everyone I guess! */ static int ofs_open(const char *UNUSED(path), struct fuse_file_info *fi) { data_buffer_t *wb; wb = calloc(1, sizeof(data_buffer_t)); if (!wb) return -1; fi->fh = (unsigned long)wb; return 0; } static int ofs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *UNUSED(fi)) { data_buffer_t *wb; int res = 0; size_t actual; if(!path || *path != '/') return 0; wb = (data_buffer_t *)fi->fh; if (!wb->data) { res = ofs_connect(); if(res < 0) return res; /* errno */ (void) obexftp_get(cli, NULL, path); wb->size = cli->buf_size; wb->data = cli->buf_data; /* would be better to memcpy this */ //cli->buf_data = NULL; /* now the data is ours -- without copying */ ofs_disconnect(); } actual = wb->size - offset; if (actual > size) actual = size; DEBUG("reading %s at %" PRId64 " for %zu (peek: %02x\n", path, offset, actual, wb->data[offset]); memcpy(buf, wb->data + offset, actual); return actual; } static int ofs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { data_buffer_t *wb; size_t newsize; DEBUG("Writing %s at %" PRId64 " for %zu\n", path, offset, size); wb = (data_buffer_t *)fi->fh; if (!wb) return -1; if (offset + size > wb->size) newsize = offset + size; else newsize = wb->size; /* don't change the buffer size */ if (!wb->data) wb->data = malloc(newsize); else if (newsize != wb->size) wb->data = realloc(wb->data, newsize); if (!wb->data) return -1; wb->size = newsize; wb->write_mode = 1; DEBUG("memcpy to %p (%p) from %p cnt %zu\n", wb->data + offset, wb->data, buf, size); (void) memcpy(&wb->data[offset], buf, size); return size; } /* careful, this can be a read release or a write release */ static int ofs_release(const char *path, struct fuse_file_info *fi) { data_buffer_t *wb; int res; wb = (data_buffer_t *)fi->fh; DEBUG("Releasing: %s (%p)\n", path, wb); if (wb && wb->data && wb->write_mode) { DEBUG("Now writing %s for %zu (%02x)\n", path, wb->size, wb->data[0]); res = ofs_connect(); if(res < 0) return res; /* errno */ (void) obexftp_put_data(cli, (uint8_t *)wb->data, wb->size, path); ofs_disconnect(); free(wb->data); free(wb); } return 0; } #ifdef SIEMENS static int ofs_statfs(const char *UNUSED(label), struct statfs *st) { int res; int size, free; memset(st, 0, sizeof(struct statfs)); res = ofs_connect(); if(res < 0) return res; /* errno */ /* for S45 */ (void) obexftp_disconnect (cli); (void) obexftp_connect_uuid (cli, device, channel, UUID_S45, sizeof(UUID_S45)); /* Retrieve Infos */ (void) obexftp_info(cli, 0x01); size = cli->apparam_info; (void) obexftp_info(cli, 0x02); free = cli->apparam_info; DEBUG("%s() GOT FS STAT: %d / %d\n", __func__, free, size); (void) obexftp_disconnect (cli); (void) obexftp_connect (cli, device, channel); ofs_disconnect(); st->f_bsize = 1; /* optimal transfer block size */ st->f_blocks = size; /* total data blocks in file system */ st->f_bfree = free; /* free blocks in fs */ st->f_bavail = free; /* free blocks avail to non-superuser */ /* st->f_files; / * total file nodes in file system */ /* st->f_ffree; / * free file nodes in fs */ /* st->f_namelen; / * maximum length of filenames */ return 0; } #endif static void *ofs_init(void) { //cli_open(); return NULL; } static void ofs_destroy(void *UNUSED(private_data)) { fprintf(stderr, "terminating...\n"); cli_close(); return; } static struct fuse_operations ofs_oper = { getattr: ofs_getattr, readlink: NULL, opendir: NULL, readdir: NULL, releasedir: NULL, getdir: ofs_getdir, mknod: ofs_mknod, mkdir: ofs_mkdir, symlink: NULL, unlink: ofs_unlink, rmdir: ofs_unlink, rename: ofs_rename, link: NULL, chmod: NULL, chown: NULL, truncate: ofs_truncate, utime: NULL, open: ofs_open, read: ofs_read, write: ofs_write, #ifdef SIEMENS statfs: ofs_statfs, #endif release: ofs_release, flush: NULL, fsync: NULL, init: ofs_init, destroy: ofs_destroy }; int main(int argc, char *argv[]) { int res; while (1) { int option_index = 0; int c; static struct option long_options[] = { {"irda", no_argument, NULL, 'i'}, {"bluetooth", required_argument, NULL, 'b'}, {"channel", required_argument, NULL, 'B'}, {"hci", required_argument, NULL, 'd'}, {"usb", required_argument, NULL, 'u'}, {"tty", required_argument, NULL, 't'}, {"network", required_argument, NULL, 'n'}, {"nonblock", no_argument, NULL, 'N'}, {"help", no_argument, NULL, 'h'}, {"usage", no_argument, NULL, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "+ib:B:d:u:t:n:Nh", long_options, &option_index); if (c == -1) break; switch (c) { case 'i': transport = OBEX_TRANS_IRDA; device = NULL; channel = 0; break; case 'b': transport = OBEX_TRANS_BLUETOOTH; device = optarg; channel = -1; break; case 'B': channel = atoi(optarg); break; case 'd': source = optarg; break; case 'u': if (geteuid() != 0) fprintf(stderr, "If USB doesn't work setup permissions in udev or run as superuser.\n"); transport = OBEX_TRANS_USB; device = NULL; channel = atoi(optarg); break; case 't': transport = OBEX_TRANS_CUSTOM; device = optarg; channel = 0; break; case 'n': transport = OBEX_TRANS_INET; device = optarg; channel = 650; { int n; if (sscanf(optarg, "%d.%d.%d.%d", &n, &n, &n, &n) != 4) fprintf(stderr, "Please use dotted quad notation.\n"); } break; case 'N': nonblock = 1; break; case 'h': /* printf("ObexFS %s\n", VERSION); */ printf("Usage: %s [-i | -b [-B ] [-d ] | -u | -t | -n ] [-- ]\n" "Transfer files from/to Mobile Equipment.\n" "Copyright (c) 2002-2005 Christian W. Zuckschwerdt\n" "\n" " -i, --irda connect using IrDA transport\n" " -b, --bluetooth connect to this bluetooth device\n" " -B, --channel use this bluetooth channel when connecting\n" " -d, --hci use source device with this address or number\n" " -u, --usb connect to this usb interface number\n" " -t, --tty connect to this tty using a custom transport\n" " -n, --network connect to this network host\n\n" " -N, --nonblock nonblocking mode\n\n" " -h, --help, --usage this help text\n\n" "Options to fusermount need to be preceeded by two dashes (--).\n" "\n", argv[0]); exit(0); break; default: printf("Try `%s --help' for more information.\n", argv[0]); exit(0); } } if (transport == 0) { fprintf(stderr, "No device selected. Use --help for help.\n"); exit(0); } argv[optind-1] = argv[0]; /* Open connection */ res = cli_open(); if(res < 0) return res; /* errno */ /* loop */ fuse_main(argc-optind+1, &argv[optind-1], &ofs_oper); /* Close connection */ cli_close(); return 0; } obexftp-0.24-Source/includes/ 40777 0 0 0 12115602310 11160 5obexftp-0.24-Source/includes/common.h100777 0 0 3155 12115454406 12740 0/** \file includes/common.h ObexFTP common macros and debugging. ObexFTP library - language bindings for OBEX file transfer. */ #ifndef _OBEXFTP_COMMON_H #define _OBEXFTP_COMMON_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef UNUSED #elif defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) #elif defined(__LCLINT__) # define UNUSED(x) /*@unused@*/ x #else # define UNUSED(x) x #endif #ifndef FALSE #define FALSE (0) #endif #ifndef TRUE #define TRUE (!FALSE) #endif /* these are not asserts! dont define to nothing */ #define return_if_fail(expr) do { if (!(expr)) return; } while(0); #define return_val_if_fail(expr,val) do { if (!(expr)) return val; } while(0); #ifdef _WIN32 #define snprintf _snprintf #endif /* _WIN32 */ /* use 0 for production, 1 for verification, >2 for debug */ #ifndef OBEXFTP_DEBUG #define OBEXFTP_DEBUG 0 #endif #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define DEBUG(n, ...) if (OBEXFTP_DEBUG >= (n)) fprintf(stderr, __VA_ARGS__) #elif defined (__GNUC__) #define DEBUG(n, format...) if (OBEXFTP_DEBUG >= (n)) fprintf (stderr, format) #else /* !__GNUC__ */ static void DEBUG (int n, const char *format, ...) { va_list args; if (OBEXFTP_DEBUG >= (n)) { va_start (args, format); fprintf (stderr, format, args); va_end (args); } } #endif /* !__GNUC__ */ #if OBEXFTP_DEBUG > 4 #define DEBUGBUFFER(b,l) do { \ int i; \ for (i=0; i < (l); i++) \ fprintf (stderr, "%02x ", ((uint8_t *)(b))[i]); \ fprintf (stderr, "\n"); \ } while (0) #else #define DEBUGBUFFER(b,l) do { } while (0) #endif #endif /* _OBEXFTP_COMMON_H */ obexftp-0.24-Source/multicobex/ 40777 0 0 0 12115602310 11525 5obexftp-0.24-Source/multicobex/CMakeLists.txt100777 0 0 1475 12115454406 14407 0 set ( multicobex_SOURCES multi_cobex.c ) set ( multicobex_PUBLIC_HEADERS multi_cobex.h ) set ( multicobex_HEADERS multi_cobex.h ${multicobex_PUBLIC_HEADERS} ) add_library ( multicobex ${multicobex_SOURCES} ${multicobex_HEADERS} ) set_property ( TARGET multicobex PROPERTY VERSION 1.0.1 ) set_property ( TARGET multicobex PROPERTY SOVERSION 1 ) set_property ( TARGET multicobex PROPERTY PUBLIC_HEADER ${multicobex_PUBLIC_HEADERS} ) target_link_libraries ( multicobex bfb ) install ( TARGETS multicobex RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT library LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/multicobex COMPONENT devel ) obexftp-0.24-Source/multicobex/multi_cobex.c100777 0 0 20065 12115454406 14341 0/** \file multicobex/multi_cobex.c Detect, initiate and run OBEX over custom serial port protocols (Siemens, Ericsson, New-Siemens, Motorola, Generic). ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #define sleep(t) Sleep((t) * 1000) #define usleep(t) Sleep((t) < 500 ? 1 : ((t) + 500) / 1000); #else #include #include #endif #include #include "multi_cobex.h" #include "multi_cobex_private.h" #include #include #include static void cobex_cleanup(cobex_t *c, int force) { return_if_fail (c != NULL); #ifdef _WIN32 return_if_fail (c->fd != INVALID_HANDLE_VALUE); #else return_if_fail (c->fd > 0); #endif if (c->type == CT_BFB) { /* needed to leave transparent OBEX(3) mode * and enter RCCP(0) mode. * DCA-540 needs cable replug, probably problem * with the linux driver (linux-2.6.17.13) */ bfb_write_at(c->fd, "AT^SBFB=0\r"); sleep(1); bfb_io_write(c->fd, "+++", 3); sleep(1); bfb_io_write(c->fd,"\r", 1); } bfb_io_close(c->fd, force); #ifdef _WIN32 c->fd = INVALID_HANDLE_VALUE; #else c->fd = -1; #endif } /** Called from OBEX-lib to set up a connection. */ int cobex_connect(obex_t *self, void *data) { cobex_t *c; enum trans_type typeinfo; return_val_if_fail (self != NULL, -1); return_val_if_fail (data != NULL, -1); c = (cobex_t *) data; DEBUG(3, "%s() \n", __func__); c->fd = bfb_io_open(c->tty, &typeinfo); DEBUG(3, "%s() bfb_io_open returned %d, %d\n", __func__, c->fd, typeinfo); switch (typeinfo) { case TT_BFB: c->type = CT_BFB; break; case TT_ERICSSON: c->type = CT_ERICSSON; break; case TT_SIEMENS: c->type = CT_SIEMENS; break; case TT_MOTOROLA: c->type = CT_MOTOROLA; break; case TT_GENERIC: c->type = CT_GENERIC; break; default: c->type = 0; /* invalid */ return -1; } #ifdef _WIN32 if(c->fd == INVALID_HANDLE_VALUE) #else if(c->fd == -1) #endif return -1; return 1; } /** Called from OBEX-lib to tear down a connection. */ int cobex_disconnect(obex_t *self, void *data) { cobex_t *c; return_val_if_fail (self != NULL, -1); return_val_if_fail (data != NULL, -1); c = (cobex_t *) data; DEBUG(3, "%s() \n", __func__); cobex_cleanup(c, FALSE); return 1; } /** Called from OBEX-lib when data needs to be written. */ int cobex_write(obex_t *self, void *data, uint8_t *buffer, int length) { int written; cobex_t *c; return_val_if_fail (self != NULL, -1); return_val_if_fail (data != NULL, -1); c = (cobex_t *) data; DEBUG(3, "%s() \n", __func__); DEBUG(3, "%s() Data %d bytes\n", __func__, length); if (c->type != CT_BFB) { int retries=0, chunk, fails=0; written = 0; for (retries = 0; written < length; retries++) { chunk = write(c->fd, buffer+written, length-written); if (chunk <= 0) { if ( ++fails >= 10 ) { // to avoid infinite looping if something is really wrong DEBUG(1, "%s() Error writing to port (written %d bytes out of %d, in %d retries)\n", __func__, written, length, retries); return written; } usleep(1); // This mysteriously avoids a resource not available error on write() } else { written += chunk; fails = 0; // Reset error counter on successful write op } } if (retries > 0) DEBUG(2, "%s() Wrote %d bytes in %d retries\n", __func__, written, retries); return written; } if (c->seq == 0){ written = bfb_send_first(c->fd, buffer, length); DEBUG(2, "%s() Wrote %d first packets (%d bytes)\n", __func__, written, length); } else { written = bfb_send_next(c->fd, buffer, length, c->seq); DEBUG(2, "%s() Wrote %d packets (%d bytes)\n", __func__, written, length); } c->seq++; return written; } /** Called when input data is needed. */ int cobex_handleinput(obex_t *self, void *data, int timeout) { #ifdef _WIN32 DWORD actual; #else struct timeval time; fd_set fdset; int actual; #endif bfb_frame_t *frame; cobex_t *c; return_val_if_fail (self != NULL, -1); return_val_if_fail (data != NULL, -1); c = (cobex_t *) data; #ifdef _WIN32 if (!ReadFile(c->fd, &(c->recv[c->recv_len]), sizeof(c->recv) - c->recv_len, &actual, NULL)) DEBUG(2, "%s() Read error: %ld\n", __func__, actual); DEBUG(2, "%s() Read %ld bytes (%d bytes already buffered)\n", __func__, actual, c->recv_len); /* FIXME ... */ #else time.tv_sec = timeout; time.tv_usec = 0; /* Add the fd's to the set. */ FD_ZERO(&fdset); FD_SET(c->fd, &fdset); /* Wait for input */ actual = select(c->fd + 1, &fdset, NULL, NULL, &time); DEBUG(2, "%s() There is something (%d)\n", __func__, actual); /* Check if this is a timeout (0) or error (-1) */ if(actual <= 0) return actual; actual = read(c->fd, &(c->recv[c->recv_len]), sizeof(c->recv) - c->recv_len); DEBUG(2, "%s() Read %d bytes (%d bytes already buffered)\n", __func__, actual, c->recv_len); #endif if (c->type != CT_BFB) { if (actual > 0) { OBEX_CustomDataFeed(self, c->recv, actual); return 1; } return actual; } if ((c->data_buf == NULL) || (c->data_size == 0)) { c->data_size = 1024; c->data_buf = malloc(c->data_size); } if (actual > 0) { c->recv_len += actual; DEBUGBUFFER(c->recv, c->recv_len); while ((frame = bfb_read_packets(c->recv, &(c->recv_len)))) { DEBUG(2, "%s() Parsed %x (%d bytes remaining)\n", __func__, frame->type, c->recv_len); (void) bfb_assemble_data(&c->data_buf, &c->data_size, &c->data_len, frame); if (bfb_check_data(c->data_buf, c->data_len) == 1) { actual = bfb_send_ack(c->fd); #ifdef _WIN32 DEBUG(2, "%s() Wrote ack packet (%ld)\n", __func__, actual); #else DEBUG(2, "%s() Wrote ack packet (%d)\n", __func__, actual); #endif OBEX_CustomDataFeed(self, c->data_buf->data, c->data_len-7); /* free(c->data); c->data = NULL; */ c->data_len = 0; if (c->recv_len > 0) { DEBUG(2, "%s() Data remaining after feed, this can't be good.\n", __func__); DEBUGBUFFER(c->recv, c->recv_len); } return 1; } } } return actual; } /* Well, maybe this should be somewhere in the header */ /* static obex_ctrans_t _cobex_ctrans = { connect: cobex_connect, disconnect: cobex_disconnect, write: cobex_write, listen: NULL, handleinput: cobex_handleinput, }; */ /** Create a new multi cobex instance for a given TTY. \param tty the TTY to use. Defaults to the first serial TTY if NULL. */ obex_ctrans_t *cobex_ctrans (const char *tty) { obex_ctrans_t *ctrans; cobex_t *cobex; cobex = calloc (1, sizeof(cobex_t)); if(tty == NULL) tty = SERPORT; cobex->tty = strdup (tty); ctrans = calloc (1, sizeof(obex_ctrans_t)); ctrans->connect = cobex_connect; ctrans->disconnect = cobex_disconnect; ctrans->write = cobex_write; ctrans->listen = NULL; ctrans->handleinput = cobex_handleinput; ctrans->customdata = cobex; return ctrans; } /** Free all data related to a multi cobex instance. */ void cobex_free (obex_ctrans_t *ctrans) { cobex_t *cobex; return_if_fail (ctrans != NULL); cobex = (cobex_t *)ctrans->customdata; return_if_fail (cobex != NULL); free (cobex->tty); /* maybe there is a bfb_data_t left? */ /* free(cobex->data); */ free (cobex); free (ctrans); return; } obexftp-0.24-Source/multicobex/multi_cobex.h100777 0 0 2637 12115454406 14333 0/** \file multicobex/multi_cobex.h Detect, initiate and run OBEX over custom serial port protocols (Siemens, Ericsson, New-Siemens, Motorola, Generic). ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef MULTICOBEX_H #define MULTICOBEX_H #include #ifdef __cplusplus extern "C" { #endif /* session handling */ obex_ctrans_t * cobex_ctrans (const char *tty); void cobex_free (obex_ctrans_t * ctrans); /* callbacks */ int cobex_connect (obex_t *self, void *data); int cobex_disconnect (obex_t *self, void *data); int cobex_write (obex_t *self, void *data, uint8_t *buffer, int length); int cobex_handleinput (obex_t *self, void *data, int timeout); #ifdef __cplusplus } #endif #endif /* MULTICOBEX_H */ obexftp-0.24-Source/multicobex/multi_cobex_private.h100777 0 0 3451 12115454406 16060 0/** \file multicobex/multi_cobex_private.h Detect, initiate and run OBEX over custom serial port protocols (Siemens, Ericsson, New-Siemens, Motorola, Generic). ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2005 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef MULTICOBEX_PRIVATE_H #define MULTICOBEX_PRIVATE_H #include #define SERPORT "/dev/ttyS0" #define RECVSIZE 500 /* Recieve up to this much from socket */ enum cobex_type { CT_BFB, /* use a bfb transport */ CT_ERICSSON, /* just custom init and teardown */ CT_SIEMENS, /* new siemens, like ericsson above */ CT_MOTOROLA, /* experimental motorola support */ CT_GENERIC /* should work on most phones */ }; typedef struct { enum cobex_type type; /* Type of connected mobile */ char *tty; #ifdef _WIN32 HANDLE fd; /* Socket descriptor */ #else int fd; /* Socket descriptor */ #endif uint8_t recv[RECVSIZE]; /* Buffer socket input */ int recv_len; uint8_t seq; bfb_data_t *data_buf; /* assembled obex frames */ int data_size; /* max buffer size */ int data_len; /* filled buffer length */ } cobex_t; #endif /* MULTICOBEX_PRIVATE_H */ obexftp-0.24-Source/NEWS100777 0 0 1347 12115454406 10171 0ObexFTP recent NEWS =================== * proper unicode support * support for transparent OBEX-over-AT mode * working win32 support (again) * full Series 60 support * Newer Siemens phones (BFC support) * Sharp support (PCSOFTWARE uuid) * added motorola support * 3GPP 27.007 cable support (CPROT=0) * 64-bit clean * obexftpd daemon application * Motorola support, tested with models v710/e815 * be sure to give ObexFS a spin! * object caching and directory parsing (for things like ObexFS) * Nokia support via IrDA and Bluetooth * Siemens S65 support * Everything but data goes to stderr for more simple redirection. * VMO converter (gsm and wav) split into seperate package. * Ericsson and Siemens cable support unified (still testing). obexftp-0.24-Source/obexftp/ 40777 0 0 0 12115602310 11021 5obexftp-0.24-Source/obexftp/bt_kit.c100777 0 0 62641 12115454406 12605 0/** \file obexftp/bt_kit.c Bluetooth, SDP, HCI kit for Linux, FreeBSD, NetBSD and Win32. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #ifdef _WIN32 #include #include #define WSA_VER_MAJOR 2 #define WSA_VER_MINOR 2 #else #include #include #include #endif /* _WIN32 */ #include "bt_kit.h" #include #ifdef HAVE_BLUETOOTH /** Nokia OBEX PC Suite Services. binary representation of 00005005-0000-1000-8000-0002ee000001 \note prefer this over FTP on Series 60 devices */ #define __SVC_UUID_PCSUITE_bytes \ { 0x00, 0x00, 0x50, 0x05, \ 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, \ 0x00, 0x02, 0xee, 0x00, 0x00, 0x01 } #define SVC_UUID_PCSUITE ((const uint8_t []) __SVC_UUID_PCSUITE_bytes) //Nokia SyncML Server UUID 128: 00005601-0000-1000-8000-0002ee000001 /* well known services 0x1000 to 0x12FF */ #define __SVC_UUID_BASE_bytes \ { 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, \ 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB } #define SVC_UUID_BASE ((const uint8_t []) __SVC_UUID_BASE_bytes) /* 0x0001: server; 0x0002: client; 0x0003: DM server; 0x0004: DM client */ #define __SVC_UUID_SYNCML_bytes \ { 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, \ 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 } #define SVC_UUID_SYNCML ((const uint8_t []) __SVC_UUID_SYNCML_bytes) /** Allocate and setup the network stack. \note Needed for win32 winsock compatibility. */ int btkit_init(void) { #ifdef _WIN32 WORD wVersionRequired = MAKEWORD(WSA_VER_MAJOR,WSA_VER_MINOR); WSADATA lpWSAData; if (WSAStartup(wVersionRequired, &lpWSAData) != 0) { DEBUG(2, "%s: WSAStartup failed (%d)\n", __func__, WSAGetLastError()); return -1; } if (LOBYTE(lpWSAData.wVersion) != WSA_VER_MAJOR || HIBYTE(lpWSAData.wVersion) != WSA_VER_MINOR) { DEBUG(2, "%s: WSA version mismatch\n", __func__); WSACleanup(); return -1; } #endif /* _WIN32 */ return 0; } /** Tear-down and free the network stack. \note Needed for win32 winsock compatibility. */ int btkit_exit(void) { #ifdef _WIN32 if (WSACleanup() != 0) { DEBUG(2, "%s: WSACleanup failed (%d)\n", __func__, WSAGetLastError()); return -1; } #endif /* _WIN32 */ return 0; } #ifdef _WIN32 //void baswap(bdaddr_t *dst, const bdaddr_t *src) //bdaddr_t *strtoba(const char *str) //char *batostr(const bdaddr_t *ba) /** Implementation of ba2str for winsock2. */ int ba2str(const bdaddr_t *btaddr, char *straddr) { /* WSAAddressToString() is not useful, it adds parentheses */ unsigned char *b = btaddr; return sprintf(straddr, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", b[7], b[6], b[5], b[4], b[3], b[2]); } /** Implementation of str2ba for winsock2. */ int str2ba(const char *straddr, bdaddr_t *btaddr) { int i; unsigned int aaddr[6]; bdaddr_t tmpaddr = 0; if (sscanf(straddr, "%02x:%02x:%02x:%02x:%02x:%02x", &aaddr[0], &aaddr[1], &aaddr[2], &aaddr[3], &aaddr[4], &aaddr[5]) != 6) return 1; *btaddr = 0; for (i = 0; i < 6; i++) { tmpaddr = (bdaddr_t) (aaddr[i] & 0xff); *btaddr = ((*btaddr) << 8) + tmpaddr; } return 0; } char **btkit_discover(const char *src) { unsigned int ret; WSAQUERYSET querySet; char addressAsString[18]; char **res, **p; memset(&querySet, 0, sizeof(querySet)); querySet.dwSize = sizeof(querySet); querySet.dwNameSpace = NS_BTH; HANDLE hLookup; DWORD flags = LUP_CONTAINERS | LUP_FLUSHCACHE | LUP_RETURN_ADDR | LUP_RES_SERVICE; ret = WSALookupServiceBegin(&querySet, flags, &hLookup); if (ret != 0) { DEBUG(2, "%s: WSALookupServiceBegin failed (%d)\n", __func__, WSAGetLastError()); } p = res = calloc(15 + 1, sizeof(char *)); for (;;) { BYTE buffer[1000]; DWORD bufferLength = sizeof(buffer); WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer; ret = WSALookupServiceNext(hLookup, flags, &bufferLength, pResults); if (GetLastError() == WSA_E_NO_MORE) { break; } if (ret != 0) { DEBUG(2, "%s: WSALookupServiceNext failed (%d)\n", __func__, WSAGetLastError()); } ba2str(pResults->lpcsaBuffer->RemoteAddr.lpSockaddr, addressAsString); DEBUG(3, "%s: Found\t%s\n", __func__, addressAsString); *p++ = strdup(addressAsString); } ret = WSALookupServiceEnd(hLookup); if (ret != 0) { DEBUG(2, "%s: WSALookupServiceEnd failed (%d)\n", __func__, WSAGetLastError()); } return res; } char *btkit_getname(const char *src, const char *addr) { unsigned int ret; WSAQUERYSET querySet; char addressAsString[18]; char *res = NULL; memset(&querySet, 0, sizeof(querySet)); querySet.dwSize = sizeof(querySet); querySet.dwNameSpace = NS_BTH; HANDLE hLookup; DWORD flags = LUP_CONTAINERS | LUP_FLUSHCACHE | LUP_RETURN_ADDR | LUP_RES_SERVICE; ret = WSALookupServiceBegin(&querySet, flags, &hLookup); if (ret != 0) { DEBUG(2, "%s: WSALookupServiceBegin failed (%d)\n", __func__, WSAGetLastError()); } for (;;) { BYTE buffer[1000]; DWORD bufferLength = sizeof(buffer); WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer; ret = WSALookupServiceNext(hLookup, flags | LUP_RETURN_NAME, &bufferLength, pResults); if (GetLastError() == WSA_E_NO_MORE) { break; } if (ret != 0) { DEBUG(2, "%s: WSALookupServiceNext failed (%d)\n", __func__, WSAGetLastError()); } ba2str(pResults->lpcsaBuffer->RemoteAddr.lpSockaddr, addressAsString); if (!strcmp(addressAsString, addr)) { DEBUG(3, "%s: Found\t%s\n", __func__, pResults->lpszServiceInstanceName); res = pResults->lpszServiceInstanceName; break; } DEBUG(3, "%s: Skipping\t%s\n", __func__, pResults->lpszServiceInstanceName); } ret = WSALookupServiceEnd(hLookup); if (ret != 0) { DEBUG(2, "%s: WSALookupServiceEnd failed (%d)\n", __func__, WSAGetLastError()); } return res; } int btkit_browse(const char *src, const char *addr, int svclass) { unsigned int ret; int port = 0; WSAQUERYSET querySet; char addressAsString[20]; // "(XX:XX:XX:XX:XX:XX)" snprintf(addressAsString, 20, "(%s)", addr); if (!addr || strlen(addr) != 17) { DEBUG(1, "%s: bad address\n", __func__); return -1; } if ((svclass<0x0001 || svclass>0x0004) && (svclass<0x1000 || svclass>0x12FF)) { DEBUG(1, "%s: bad service class\n", __func__); return -1; } GUID baseServiceClassId = { 0x00000000, 0x0000, 0x1000, { 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB } }; // Bluetooth_Base_UUID baseServiceClassId.Data1 = svclass; GUID syncmlClassId = { 0x00000000, 0x0000, 0x1000, { 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 } }; // common UUID for SyncML Client/Server syncmlClassId.Data1 = svclass; memset(&querySet, 0, sizeof(querySet)); querySet.dwSize = sizeof(querySet); querySet.dwNameSpace = NS_BTH; if (svclass>=0x0001 && svclass<=0x0004) querySet.lpServiceClassId = &syncmlClassId; else querySet.lpServiceClassId = &baseServiceClassId; querySet.lpszContext = addressAsString; HANDLE hLookup; DWORD flags = LUP_NOCONTAINERS | LUP_FLUSHCACHE | LUP_RETURN_ADDR | LUP_RES_SERVICE | LUP_RETURN_NAME; ret = WSALookupServiceBegin(&querySet, flags, &hLookup); if (ret != 0) { DEBUG(2, "%s: WSALookupServiceBegin failed (%d)\n", __func__, WSAGetLastError()); return -1; } for (;;) { BYTE buffer[4000]; DWORD bufferLength = sizeof(buffer); WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer; ret = WSALookupServiceNext(hLookup, flags, &bufferLength, pResults); if (GetLastError() == WSA_E_NO_MORE) { break; } if (ret != 0) { DEBUG(2, "%s: WSALookupServiceNext failed (%d)\n", __func__, WSAGetLastError()); break; } port = ((SOCKADDR_BTH*)pResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->port; DEBUG(3, "%s: Found\t%s\t%li\n", __func__, pResults->lpszServiceInstanceName, port); } ret = WSALookupServiceEnd(hLookup); if (ret != 0) { DEBUG(2, "%s: WSALookupServiceEnd failed (%d)\n", __func__, WSAGetLastError()); return -1; } return port; } int btkit_register_obex(int UNUSED(svclass), int UNUSED(channel)) { DEBUG(1, "Implement this stub."); return -1; } int btkit_unregister_service(int UNUSED(svclass)) { DEBUG(1, "Implement this stub."); return -1; } #else /* _WIN32 */ #ifdef HAVE_SDP #if defined(__NetBSD__) || defined(__FreeBSD__) char **btkit_discover(const char *src) { struct bt_devinquiry *di; char **res; int num_rsp = 10; int length = 8; int i; DEBUG(2, "%s: Scanning ...\n", __func__); num_rsp = bt_devinquiry(src, length, num_rsp, &di); if(num_rsp < 0) { DEBUG(1, "%s: Inquiry failed\n", __func__); return NULL; } res = calloc(num_rsp + 1, sizeof(char *)); for(i = 0; i < num_rsp; i++) { res[i] = bt_malloc(18); /* size of text bdaddr */ bt_ntoa(&di->bdaddr, res[i]); DEBUG(2, "%s: Found\t%s\n", __func__, res[i]); } free(di); return res; } static int btkit_getname_cb(int UNUSED(s), const struct bt_devinfo *di, void *arg) { if ((di->enabled)) { strncpy(arg, di->devname, HCI_DEVNAME_SIZE); return 1; } return 0; } char *btkit_getname(const char *src, const char *addr) { hci_remote_name_req_cp cp; hci_remote_name_req_compl_ep ep; struct bt_devreq req; int s; return_val_if_fail(addr != NULL, NULL); if (!src) { if (bt_devenum(btkit_getname_cb, ep.name) == -1) { DEBUG(1, "%s: device enumeration failed\n", __func__); return NULL; } src = (const char *)ep.name; } s = bt_devopen(src, 0); if (s == -1) { DEBUG(1, "%s: HCI device open failed\n", __func__); return NULL; } memset(&cp, 0, sizeof(cp)); bt_aton(addr, &cp.bdaddr); memset(&req, 0, sizeof(req)); req.opcode = HCI_CMD_REMOTE_NAME_REQ; req.cparam = &cp; req.clen = sizeof(cp); req.event = HCI_EVENT_REMOTE_NAME_REQ_COMPL; req.rparam = &ep; req.rlen = sizeof(ep); if (bt_devreq(s, &req, 100) == -1) { DEBUG(1, "%s: remote name request failed\n", __func__); strcpy(ep.name, "No Name"); } close(s); return strndup(ep.name, sizeof(ep.name)); } static int btkit_browse_sdp(sdp_session_t ss, uuid_t *uuid) { uint8_t buf[19]; /* enough for uuid128 (ssp) and uint16 (ail) */ sdp_data_t seq, ssp, ail, rsp, rec, value, pdl; uintmax_t channel; uint16_t attr; seq.next = buf; seq.end = buf + sizeof(buf); /* build ServiceSearchPattern */ ssp.next = seq.next; sdp_put_uuid(&seq, uuid); ssp.end = seq.next; /* build AttributeIDList */ ail.next = seq.next; sdp_put_uint16(&seq, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST); ail.end = seq.next; if (!sdp_service_search_attribute(ss, &ssp, &ail, &rsp)) { DEBUG(1, "%s: SDP service search failed\n", __func__); return -1; } /* * we expect the response to contain a list of records * containing ProtocolDescriptorList. Return the first * one with a valid RFCOMM channel. */ while (sdp_get_seq(&rsp, &rec)) { if (!sdp_get_attr(&rec, &attr, &value) || attr != SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST) continue; /* drop any alt header */ sdp_get_alt(&value, &value); /* for each protocol stack */ while (sdp_get_seq(&value, &pdl)) { /* and for each protocol */ while (sdp_get_seq(&pdl, &seq)) { /* check for RFCOMM */ if (sdp_match_uuid16(&seq, SDP_UUID_PROTOCOL_RFCOMM) && sdp_get_uint(&seq, &channel) && channel >= RFCOMM_CHANNEL_MIN && channel <= RFCOMM_CHANNEL_MAX) return channel; } } } DEBUG(1, "%s: no channel found\n", __func__); return -1; } int btkit_browse(const char *src, const char *addr, int svclass) { bdaddr_t laddr, raddr; sdp_session_t ss; uuid_t uuid; int channel; return_val_if_fail(addr != NULL, -1); bt_aton(addr, &raddr); if (src) { if (!bt_devaddr(src, &laddr)) { DEBUG(1, "%s: invalid source address\n", __func__); return -1; } } else { bdaddr_copy(&laddr, BDADDR_ANY); } ss = sdp_open(&laddr, &raddr); if (ss == NULL) { DEBUG(1, "%s: Failed to connect to SDP server\n", __func__); return -1; } if (svclass >= 0x0001 && svclass <= 0x0004) { uuid_dec_be(SVC_UUID_SYNCML, &uuid); uuid.time_low = svclass; } else if (svclass >= 0x1000 && svclass <= 0x12FF) { uuid_dec_be(SVC_UUID_BASE, &uuid); uuid.time_low = svclass; } else { svclass = SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER; } DEBUG(1, "%s: svclass 0x%04x\n", __func__, svclass); channel = -1; /* Try PCSUITE first */ if (svclass == SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER) { DEBUG(1, "%s: trying PCSUITE first\n", __func__); uuid_dec_be(SVC_UUID_PCSUITE, &uuid); channel = btkit_browse_sdp(ss, &uuid); uuid_dec_be(SVC_UUID_BASE, &uuid); uuid.time_low = svclass; } if (channel == -1) channel = btkit_browse_sdp(ss, &uuid); sdp_close(ss); return channel; } static sdp_session_t ss; static uint32_t opush_handle; static uint32_t ftrn_handle; static uint32_t irmc_handle; int btkit_register_obex(int svclass, int channel) { uint8_t buffer[256]; sdp_data_t rec; uint32_t *hp; DEBUG(1, "%s: svclass 0x%04x channel %d\n", __func__, svclass, channel); /* Build SDP record */ rec.next = buffer; rec.end = buffer + sizeof(buffer); sdp_put_uint16(&rec, SDP_ATTR_SERVICE_RECORD_HANDLE); sdp_put_uint32(&rec, 0x00000000); sdp_put_uint16(&rec, SDP_ATTR_SERVICE_CLASS_ID_LIST); sdp_put_seq(&rec, 3); sdp_put_uuid16(&rec, (uint16_t)svclass); sdp_put_uint16(&rec, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST); sdp_put_seq(&rec, 17); sdp_put_seq(&rec, 3); sdp_put_uuid16(&rec, SDP_UUID_PROTOCOL_L2CAP); sdp_put_seq(&rec, 5); sdp_put_uuid16(&rec, SDP_UUID_PROTOCOL_RFCOMM); sdp_put_uint8(&rec, (uint8_t)channel); sdp_put_seq(&rec, 3); sdp_put_uuid16(&rec, SDP_UUID_PROTOCOL_OBEX); sdp_put_uint16(&rec, SDP_ATTR_BROWSE_GROUP_LIST); sdp_put_seq(&rec, 3); sdp_put_uuid16(&rec, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP); sdp_put_uint16(&rec, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST); sdp_put_seq(&rec, 9); sdp_put_uint16(&rec, 0x656e); /* "en" */ sdp_put_uint16(&rec, 106); /* UTF-8 */ sdp_put_uint16(&rec, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID); sdp_put_uint16(&rec, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST); sdp_put_seq(&rec, 8); sdp_put_seq(&rec, 6); sdp_put_uuid16(&rec, (uint16_t)svclass); sdp_put_uint16(&rec, 0x0100); /* v1.0 */ sdp_put_uint16(&rec, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET); switch (svclass) { case SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH: sdp_put_str(&rec, "OBEX Object Push", -1); sdp_put_uint16(&rec, SDP_ATTR_SUPPORTED_FORMATS_LIST); sdp_put_seq(&rec, 2); sdp_put_uint8(&rec, 0xff); /* Any */ hp = &opush_handle; break; case SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER: sdp_put_str(&rec, "OBEX File Transfer", -1); hp = &ftrn_handle; break; case SDP_SERVICE_CLASS_IR_MC_SYNC: sdp_put_str(&rec, "IrMC Sync", -1); hp = &irmc_handle; break; default: DEBUG(1, "%s: unknown svclass\n", __func__); return -1; break; } rec.end = rec.next; rec.next = buffer; /* Register service with SDP server */ if (ss == NULL) { ss = sdp_open_local(NULL); if (ss == NULL) { DEBUG(1, "%s: failed to open SDP session\n", __func__); return -1; } DEBUG(2, "%s: opened SDP session\n", __func__); } if (!sdp_record_insert(ss, NULL, hp, &rec)) { DEBUG(1, "%s: failed to insert SDP record\n", __func__); sdp_data_print(&rec, 2); return -1; } return 0; } int btkit_unregister_service(int svclass) { uint32_t *hp; if (ss == NULL) { DEBUG(1, "%s: no session open\n", __func__); return -1; } switch (svclass) { case SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH: hp = &opush_handle; break; case SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER: hp = &ftrn_handle; break; case SDP_SERVICE_CLASS_IR_MC_SYNC: hp = &irmc_handle; break; default: DEBUG(1, "%s: unknown svclass\n", __func__); return -1; break; } if (!sdp_record_remove(ss, *hp)) { DEBUG(1, "%s: failed to remove SDP record\n", __func__); return -1; } *hp = 0; if (opush_handle == 0 && ftrn_handle == 0 && irmc_handle == 0) { DEBUG(2, "%s: closed SDP session\n", __func__); sdp_close(ss); ss = NULL; } return 0; } #else /* defined(__NetBSD__) || defined(__FreeBSD__) */ /** Discover all bluetooth devices in range. \param src optional source interface address (HCI or MAC) \return an array of device addresses */ char **btkit_discover(const char *src) { char **res; inquiry_info *info = NULL; bdaddr_t bdswap; int dev_id; int num_rsp = 10; int flags = 0; int length = 8; int dd, i; /* Get local bluetooth address */ if (src && strlen(src) == 17) dev_id = hci_devid(src); else if (src) dev_id = atoi(src); else dev_id = hci_get_route(NULL); DEBUG(2, "%s: Scanning ...\n", __func__); flags = IREQ_CACHE_FLUSH; /* only show devices currently in range */ num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if(num_rsp < 0) { DEBUG(1, "%s: Inquiry failed", __func__); return NULL; } dd = hci_open_dev(dev_id); if (dd < 0) { DEBUG(1, "%s: HCI device open failed", __func__); free(info); return NULL; } res = calloc(num_rsp + 1, sizeof(char *)); for(i = 0; i < num_rsp; i++) { baswap(&bdswap, &(info+i)->bdaddr); res[i] = batostr(&bdswap); DEBUG(2, "%s: Found\t%s\n", __func__, res[i]); } hci_close_dev(dd); free(info); return res; } /** Get the name of a bluetooth device. \param src optional source interface address (HCI or MAC) \param addr the bluetooth address of the device to query \return the bluetooth name of the device */ char *btkit_getname(const char *src, const char *addr) { bdaddr_t bdaddr; int dev_id, dd; char name[248]; return_val_if_fail(addr != NULL, NULL); str2ba(addr, &bdaddr); /* Get local bluetooth address */ if (src && strlen(src) == 17) dev_id = hci_devid(src); else if (src) dev_id = atoi(src); else { dev_id = hci_get_route(&bdaddr); if (dev_id < 0) dev_id = hci_get_route(NULL); } dd = hci_open_dev(dev_id); if (dd < 0) { DEBUG(1, "%s: HCI device open failed", __func__); return NULL; } if(hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 100000) < 0) { strcpy(name, "No Name"); } hci_close_dev(dd); return strdup(name); } static int browse_sdp_uuid(sdp_session_t *sess, uuid_t *uuid) { sdp_list_t *attrid, *search, *seq, *loop; uint32_t range = SDP_ATTR_PROTO_DESC_LIST; /* 0x0000ffff for SDP_ATTR_REQ_RANGE */ int channel = -1; attrid = sdp_list_append(0, &range); search = sdp_list_append(0, uuid); /* Get a linked list of services */ if(sdp_service_search_attr_req(sess, search, SDP_ATTR_REQ_INDIVIDUAL, attrid, &seq) < 0) { DEBUG(1, "%s: SDP service search failed", __func__); sdp_close(sess); return -1; } sdp_list_free(attrid, 0); sdp_list_free(search, 0); /* Loop through the list of services */ for(loop = seq; loop; loop = loop->next) { sdp_record_t *rec = (sdp_record_t *) loop->data; sdp_list_t *access = NULL; /* get the RFCOMM channel */ sdp_get_access_protos(rec, &access); if(access) { channel = sdp_get_proto_port(access, RFCOMM_UUID); } } sdp_list_free(seq, 0); return channel; } /** Browse a bluetooth device for a given service class. \param src optional source interface address (HCI or MAC) \param addr the bluetooth address of the device to query \return the channel on which the service runs */ int btkit_browse(const char *src, const char *addr, int svclass) { int res = -1; int dev_id; sdp_session_t *sess; uuid_t root_uuid; bdaddr_t bdaddr; bdaddr_t adapter; if (!addr || strlen(addr) != 17) return -1; str2ba(addr, &bdaddr); /* Get local bluetooth address */ if (src && strlen(src) == 17) dev_id = hci_devid(src); else if (src) dev_id = atoi(src); else { dev_id = hci_get_route(&bdaddr); if (dev_id < 0) dev_id = hci_get_route(NULL); } if (dev_id >= 0) hci_devba(dev_id, &adapter); else bacpy(&adapter, BDADDR_ANY); /* Connect to remote SDP server */ sess = sdp_connect(&adapter, &bdaddr, SDP_RETRY_IF_BUSY); if(!sess) { DEBUG(1, "%s: Failed to connect to SDP server", __func__); return -1; } // baswap(&bdswap, &bdaddr); // *res_bdaddr = batostr(&bdswap); // fprintf(stderr, "Browsing %s ...\n", *res_bdaddr); /* special case: SyncML */ if (svclass >= 0x0001 && svclass <= 0x0004) { unsigned short data1 = svclass; sdp_uuid128_create(&root_uuid, &SVC_UUID_SYNCML); memcpy(&root_uuid.value.uuid128.data[2], &data1, 2); res = browse_sdp_uuid(sess, &root_uuid); sdp_close(sess); return res; } /* determine the service class we're looking for */ if (svclass < 0x1000 || svclass > 0x12FF) { svclass = OBEX_FILETRANS_SVCLASS_ID; } /* prefer PCSUITE over FTP */ if (svclass == OBEX_FILETRANS_SVCLASS_ID) { sdp_uuid128_create(&root_uuid, &SVC_UUID_PCSUITE); res = browse_sdp_uuid(sess, &root_uuid); if (res > 0) { sdp_close(sess); return res; } } /* browse for the service class */ sdp_uuid16_create(&root_uuid, svclass); res = browse_sdp_uuid(sess, &root_uuid); sdp_close(sess); return res; } /** Search for OBEX FTP service. \return 1 if service is found and 0 otherwise */ static sdp_record_t *sdp_search_service(sdp_session_t *sess, uint16_t service) { sdp_list_t *attrid, *srch, *rsp = NULL; uint32_t range = 0x0000ffff; uuid_t svclass; int ret; attrid = sdp_list_append(0, &range); sdp_uuid16_create(&svclass, service); srch = sdp_list_append(NULL, &svclass); ret = sdp_service_search_attr_req(sess, srch, SDP_ATTR_REQ_RANGE, attrid, &rsp); sdp_list_free(attrid, 0); sdp_list_free(srch, 0); if (ret < 0) { DEBUG(1, "Failed to search the local SDP server."); return NULL; } if (sdp_list_len(rsp) == 0) { DEBUG(1, "No records found on the local SDP server."); return NULL; } return (sdp_record_t *) rsp->data; } /** Delete a service record from the local SDP server. */ int btkit_unregister_service(int svclass) { sdp_session_t *session; sdp_record_t *record; session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); if (!session) { DEBUG(1, "Failed to connect to the local SDP server."); return -1; } record = sdp_search_service(session, svclass); if (record && sdp_record_unregister(session, record)) DEBUG(1, "Service record unregistration failed."); sdp_close(session); return 0; } /** Add a service record to the local SDP server. */ int btkit_register_obex(int service, int channel) { sdp_session_t *session; sdp_record_t *record; sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, l2cap, rfcomm, obex, obexftp; sdp_profile_desc_t profile; sdp_list_t *proto[3]; sdp_data_t *v; uint8_t channel_id = 1; /* should look for a free one */ int status; if (channel > 0) channel_id = channel; session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); if (!session) { DEBUG(1, "Failed to connect to the local SDP server."); return -1; } record = sdp_record_alloc(); if (!record) { DEBUG(1, "Failed to allocate service record."); sdp_close(session); return -1; } /* Register to Public Browse Group */ sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(record, root); sdp_list_free(root, NULL); /* Protocol Descriptor List: L2CAP */ sdp_uuid16_create(&l2cap, L2CAP_UUID); proto[0] = sdp_list_append(NULL, &l2cap); apseq = sdp_list_append(NULL, proto[0]); /* Protocol Descriptor List: RFCOMM */ sdp_uuid16_create(&rfcomm, RFCOMM_UUID); proto[1] = sdp_list_append(NULL, &rfcomm); v = sdp_data_alloc(SDP_UINT8, &channel_id); proto[1] = sdp_list_append(proto[1], v); apseq = sdp_list_append(apseq, proto[1]); /* Protocol Descriptor List: OBEX */ sdp_uuid16_create(&obex, OBEX_UUID); proto[2] = sdp_list_append(NULL, &obex); apseq = sdp_list_append(apseq, proto[2]); aproto = sdp_list_append(NULL, apseq); sdp_set_access_protos(record, aproto); sdp_list_free(proto[0], NULL); sdp_list_free(proto[1], NULL); sdp_list_free(proto[2], NULL); sdp_list_free(apseq, NULL); sdp_list_free(aproto, NULL); sdp_data_free(v); /* Service Class ID List: */ sdp_uuid16_create(&obexftp, service); svclass = sdp_list_append(NULL, &obexftp); sdp_set_service_classes(record, svclass); /* Profile Descriptor List: */ /* profile id matches service id here */ sdp_uuid16_create(&profile.uuid, service); profile.version = 0x0100; pfseq = sdp_list_append(NULL, &profile); sdp_set_profile_descs(record, pfseq); sdp_set_info_attr(record, "OBEX File Transfer", NULL, NULL); status = sdp_device_record_register(session, BDADDR_ANY, record, SDP_RECORD_PERSIST); if (status < 0) { DEBUG(1, "SDP registration failed."); sdp_record_free(record); record = NULL; sdp_close(session); return -1; } sdp_close(session); return 0; } #endif /* BlueZ/Linux */ #else #warning "no bluetooth sdp support for this platform" char **btkit_discover(const char *UNUSED(src)) { return NULL; } char *btkit_getname(const char *UNUSED(src), const char *UNUSED(addr)) { return NULL; } int btkit_browse(const char *UNUSED(src), const char *UNUSED(addr), int UNUSED(svclass)) { return -1; } int btkit_register_obex(int UNUSED(svclass), int UNUSED(channel)) { DEBUG(1, "SDP not supported."); return -1; } int btkit_unregister_service(int UNUSED(svclass)) { return -1; } #endif /* HAVE_SDP */ #endif /* _WIN32 */ #else #warning "bluetooth not available" #endif /* HAVE_BLUETOOTH */ obexftp-0.24-Source/obexftp/bt_kit.h100777 0 0 10010 12115454406 12571 0/** \file obexftp/bt_kit.h Bluetooth, SDP, HCI kit for Linux, FreeBSD, NetBSD and Win32. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef BT_KIT_H #define BT_KIT_H #ifdef HAVE_CONFIG_H #include #endif #ifndef BTKITSYM #define BTKITSYM __attribute__ ((visibility ("hidden"))) #endif #ifdef __cplusplus extern "C" { #endif #ifdef HAVE_BLUETOOTH /* Service Class UUIDs for bt browse. */ /* Only Service Class UUID-16s are accepted (0x1000-0x12FF). Esp. not Protocol UUIDs. */ /* Also SYNCML UUID-16s (0x0001-0x0004) are translated to correct UUID-128s. */ #define BTKIT_SPP_SERVICE (0x1101) /* aka SerialPortServiceClassID_UUID16 */ #define BTKIT_SYNC_SERVICE (0x1104) /* aka IrMCSyncServiceClassID_UUID16 */ #define BTKIT_PUSH_SERVICE (0x1105) /* aka OBEXObjectPushServiceClassID_UUID16 */ #define BTKIT_FTP_SERVICE (0x1106) /* aka OBEXFileTransferServiceClassID_UUID16 */ #define BTKIT_SYNCML_SERVER (0x0001) /* aka SyncMLServer_UUID */ #define BTKIT_SYNCML_CLIENT (0x0002) /* aka SyncMLClient_UUID */ #define BTKIT_SYNCML_DM_SERVER (0x0003) /* aka SyncMLDMServer_UUID */ #define BTKIT_SYNCML_DM_CLIENT (0x0004) /* aka SyncMLDMClient_UUID */ //#ifndef _WIN32 //#include //#include //#include //#endif /* _WIN32 */ /* Windows with headers files from the Platform SDK */ #ifdef _WIN32 #include #include //#include //#include #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT #define ETIMEDOUT WSAETIMEDOUT #define ECONNREFUSED WSAECONNREFUSED #define EHOSTDOWN WSAEHOSTDOWN #define EINPROGRESS WSAEINPROGRESS #define bdaddr_t BTH_ADDR #define sockaddr_rc _SOCKADDR_BTH #define rc_family addressFamily #define rc_bdaddr btAddr #define rc_channel port #define PF_BLUETOOTH PF_BTH #define AF_BLUETOOTH PF_BLUETOOTH #define BTPROTO_RFCOMM BTHPROTO_RFCOMM #define BDADDR_ANY (&(BTH_ADDR){BTH_ADDR_NULL}) #define bacpy(dst,src) memcpy((dst),(src),sizeof(BTH_ADDR)) #define bacmp(a,b) memcmp((a),(b),sizeof(BTH_ADDR)) BTKITSYM int ba2str(const bdaddr_t *btaddr, char *straddr); BTKITSYM int str2ba(const char *straddr, BTH_ADDR *btaddr); /* Various BSD systems */ #elif defined(__NetBSD__) || defined(__FreeBSD__) #define COMPAT_BLUEZ #include #ifdef HAVE_SDP #include #include #endif #ifndef BDADDR_ANY #define BDADDR_ANY NG_HCI_BDADDR_ANY #endif #ifndef RFCOMM_CHANNEL_MIN #define RFCOMM_CHANNEL_MIN 1 #endif #ifndef RFCOMM_CHANNEL_MAX #define RFCOMM_CHANNEL_MAX 30 #endif /* BlueZ, Linux 2.4.6 and up (incl. 2.6) */ #else #include #include #include #include #include #include #endif /* _WIN32 */ /* library setup/teardown functions (needed for win32) */ BTKITSYM int btkit_init(void); BTKITSYM int btkit_exit(void); /* additional functions */ BTKITSYM char **btkit_discover(const char *src); /* HCI no. or address */ BTKITSYM char *btkit_getname(const char *src, const char *addr); BTKITSYM int btkit_browse(const char *src, const char *addr, int svclass); BTKITSYM int btkit_register_obex(int svclass, int channel); BTKITSYM int btkit_unregister_service(int svclass); //KITSYM int btkit_open_rfcomm(char *src, char *dest, int channel); #endif /* HAVE_BLUETOOTH */ #ifdef __cplusplus } #endif #endif /* BT_KIT_H */ obexftp-0.24-Source/obexftp/bt_kit_test.c100777 0 0 4211 12115454406 13611 0/** \file obexftp/bt_kit_test.c Bluetooth, SDP, HCI kit for Linux, FreeBSD, NetBSD and Win32. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ /* gcc -Wall -I. -I../includes -DOBEXFTP_DEBUG=3 -DHAVE_BLUETOOTH -o bt_kit_test bt_kit.c bt_kit_test.c */ /* on win32 add: -lws2_32 */ #include #include #include int main(int argc, char *argv[]) { int ret, i; char **list, *device; char *hci = NULL; int svclass = BTKIT_FTP_SERVICE; if (argc > 1) { hci = argv[1]; } if (argc > 2) { svclass = atoi(argv[2]); } fprintf(stderr, "Initializing stack\n"); fflush(stderr); ret = btkit_init(); /* !!! */ if (ret != 0) { fprintf(stderr, "btkit_init failed (%d)\n", ret); fflush(stderr); } fprintf(stderr, "Discovering devices\n"); fflush(stderr); list = btkit_discover(hci); /* !!! */ if (list == NULL) { fprintf(stderr, "btkit_discover failed\n"); fflush(stderr); } else { for (i=0 ; list[i]; i++) { fprintf(stderr, "device %d: \"%s\"\n", i, list[i]); fflush(stderr); device = btkit_getname(hci, list[i]); /* !!! */ fprintf(stderr, "bt name %d: \"%s\"\n", i, device); fflush(stderr); ret = btkit_browse(hci, list[i], svclass); /* !!! */ fprintf(stderr, "service channel: %i\n", ret); fflush(stderr); } free(list); } fprintf(stderr, "Disposing stack\n"); fflush(stderr); ret = btkit_exit(); /* !!! */ if (ret != 0) { fprintf(stderr, "btkit_exit failed (%d)\n", ret); fflush(stderr); } return 0; } obexftp-0.24-Source/obexftp/cache.c100777 0 0 27321 12115454406 12370 0/** \file obexftp/cache.c ObexFTP client API caching layer. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include /* __S_IFDIR, __S_IFREG */ #ifndef S_IFDIR #define S_IFDIR __S_IFDIR #endif #ifndef S_IFREG #define S_IFREG __S_IFREG #endif #include #include "obexftp.h" #include "client.h" #include "object.h" #include "unicode.h" #include "cache.h" #include /** Normalize the path argument, add/remove leading/trailing slash turns relative paths into (most likely wrong) absolute ones wont expand "../" or "./". */ static /*@only@*/ char *normalize_dir_path(int quirks, const char *name) { char *copy, *p; if (!name) name = ""; p = copy = malloc(strlen(name) + 2); /* at most add two slashes */ if (OBEXFTP_USE_LEADING_SLASH(quirks)) *p++ = '/'; while (*name == '/') name++; while (*name) { if (*name == '/') { *p++ = *name++; while (*name == '/') name++; } else { *p++ = *name++; } } if (p > copy && *(p-1) == '/') p--; if (OBEXFTP_USE_TRAILING_SLASH(quirks)) *p++ = '/'; *p = '\0'; return copy; } /** Purge all cache object at/below a given path. Methods that need to invalidate cache lines: - setpath (when create is on) - put - put_file - del - rename */ void cache_purge(cache_object_t **root, const char *path) { cache_object_t *cache, *tmp; char *name; char *pathonly; #define FREE_NODE(node) do { \ if (node->name) \ free(node->name); \ if (node->content) \ free(node->content); \ if (node->stats) \ free(node->stats); \ free(node); \ } while(0) if (!path || *path == '\0' || *path != '/') { /* purge all */ while (*root) { cache = *root; *root = cache->next; FREE_NODE(cache); } return; } pathonly = strdup(path); name = strrchr(pathonly, '/'); *name++ = '\0'; /* removing far too much, the siblings could stay cached... */ while (*root && !strncmp((*root)->name, pathonly, strlen(pathonly))) { cache = *root; *root = cache->next; FREE_NODE(cache); } for (cache = *root; cache->next; cache = cache->next) { if (!strncmp(cache->next->name, pathonly, strlen(pathonly))) { tmp = cache->next; cache->next = cache->next->next; FREE_NODE(tmp); } } free(pathonly); } /** Retrieve an object from the cache. */ int get_cache_object(const obexftp_client_t *cli, const char *name, char **object, int *size) { cache_object_t *cache; return_val_if_fail(cli != NULL, -1); /* search the cache */ for (cache = cli->cache; cache && strcmp(cache->name, name); cache = cache->next); if (cache) { DEBUG(2, "%s() Listing %s from cache\n", __func__, cache->name); if (object) *object = cache->content; if (size) *size = cache->size; return 0; } return -1; } /** Store an object in the cache. */ int put_cache_object(obexftp_client_t *cli, /*@only@*/ char *name, /*@only@*/ char *object, int size) { cache_object_t *cache; return_val_if_fail(cli != NULL, -1); /* prepend to cache */ cache = cli->cache; cli->cache = calloc(1, sizeof(cache_object_t)); cli->cache->next = cache; cli->cache->timestamp = time(NULL); cli->cache->size = size; cli->cache->name = name; cli->cache->content = object; return 0; } /** List a directory from cache, optionally loading it first. */ static char *obexftp_cache_list(obexftp_client_t *cli, const char *name) { char *path, *listing; return_val_if_fail(cli != NULL, NULL); cli->infocb(OBEXFTP_EV_RECEIVING, name, 0, cli->infocb_data); path = normalize_dir_path(cli->quirks, name); DEBUG(2, "%s() Listing %s (%s)\n", __func__, name, path); /* search the cache */ if (!get_cache_object(cli, path, &listing, NULL)) { DEBUG(2, "%s() Listing %s from cache\n", __func__, path); if (path) free(path); return listing; } if (path && !strcmp(path, "/telecom/")) { listing = strdup(""); put_cache_object(cli, path, listing, strlen(listing)); } if (obexftp_list(cli, NULL, path) < 0) return NULL; listing = strdup(cli->buf_data); put_cache_object(cli, path, listing, strlen(listing)); return listing; } /* simple xml parser */ /** Parse fixed format date string to time_t. */ static time_t atotime (const char *date) { struct tm tm; time_t retval = 0; if (6 == sscanf(date, "%4d%2d%2dT%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)) { tm.tm_year -= 1900; tm.tm_mon--; tm.tm_isdst = 0; retval = mktime(&tm); } return retval; } static mode_t get_perm(char *perm) { mode_t retval = 0; if(strcasestr(perm, "R")!=NULL) retval |= S_IRUSR | S_IRGRP; if(strcasestr(perm, "W")!=NULL) retval |= S_IWUSR | S_IRGRP; return retval; } /** Parse an XML file to array of stat_entry_t's. Very limited - not multi-byte character save. It's actually "const char *xml" but can't be declared as such. \return a new allocated array of stat_entry_t's. */ static stat_entry_t *parse_directory(char *xml) { const char *line; const char *p, *h; char tagname[201]; char name[201]; // bad coder char perm[201]; char mod[201]; // - no biscuits! char acc[201]; char cre[201]; char size[201]; // int would be ok too. stat_entry_t *dir_start, *dir; int ret, n, i; uint8_t *xml_conv; if (!xml) return NULL; n = strlen(xml) + 1; xml_conv = malloc(n); if (xml_conv) { ret = Utf8ToChar(xml_conv, (uint8_t *)xml, n); if (ret > 0) { xml = (char *)xml_conv; } else { DEBUG(1, "UTF-8 conversion error\n"); } } DEBUG(4, "Converted cache xml: '%s'\n", xml); /* prepare a cache to hold this dir */ p = xml; for (i = 0; p && *p; p = strchr(++p, '>')) i++; DEBUG(2, "max %d cache lines\n", i); dir_start = dir = calloc(i, sizeof(stat_entry_t)); for (line = xml; *line != '\0'; ) { p = line; line = strchr(line, '>'); if (!line) break; line++; while (*p != '<') p++; tagname[0] = '\0'; sscanf (p, "<%200[^> \t\n\r] ", tagname); name[0] = '\0'; h = strstr(p, "name="); if (h) sscanf (h, "name=\"%200[^\"]\"", name); perm[0] = '\0'; h = strstr(p, "user-perm="); if (h) sscanf(h, "user-perm=\"%200[^\"]\"", perm); else strcpy(perm, "RW"); //default permissions cre[0] = '\0'; h = strstr(p, "created="); if (h) sscanf (h, "created=\"%200[^\"]\"", cre); mod[0] = '\0'; h = strstr(p, "modified="); if (h) sscanf (h, "modified=\"%200[^\"]\"", mod); acc[0] = '\0'; h = strstr(p, "accessed="); if (h) sscanf(h, "accessed=\"%200[^\"]\"", acc); size[0] = '\0'; h = strstr(p, "size="); if (h) sscanf (h, "size=\"%200[^\"]\"", size); if (!strcmp("folder", tagname)) { dir->mode = S_IFDIR | get_perm(perm); if (get_perm(perm) & (S_IRUSR | S_IRGRP)) dir->mode |= S_IXUSR | S_IXGRP; strcpy(dir->name, name); DEBUG(2, "FOLDER: times for '%s'(ctime, mtime, atime): " "'%s', '%s', '%s'\n", name, cre, mod, acc); dir->ctime = atotime(cre); dir->mtime = atotime(mod); dir->atime = atotime(acc); dir->size = 0; dir++; } if (!strcmp("file", tagname)) { dir->mode = S_IFREG | get_perm(perm); strcpy(dir->name, name); DEBUG(2, "FILE: times for '%s'(ctime, mtime, atime): " "'%s', '%s', '%s'\n", name, cre, mod, acc); dir->ctime = atotime(cre); dir->mtime = atotime(mod); dir->atime = atotime(acc); i = 0; sscanf(size, "%i", &i); dir->size = i; /* int to off_t */ dir++; } // handle hidden folder! } dir->name[0] = '\0'; if (xml_conv) free (xml_conv); return dir_start; } /* directory handling */ typedef struct { stat_entry_t *cur; /* stat_entry_t *head; -- so we can free this? */ } dir_stream_t; /** Prepare a directory for reading. */ void *obexftp_opendir(obexftp_client_t *cli, const char *name) { cache_object_t *cache; dir_stream_t *stream; char *abs; /* fetch dir if needed */ (void) obexftp_cache_list(cli, name); /* search the cache */ abs = normalize_dir_path(cli->quirks, name); for (cache = cli->cache; cache && strcmp(cache->name, abs); cache = cache->next); free(abs); if (!cache) return NULL; DEBUG(2, "%s() dir prepared (%s)\n", __func__, cache->name); /* read dir */ if (!cache->stats) cache->stats = parse_directory(cache->content); DEBUG(2, "%s() got stats\n", __func__); stream = malloc(sizeof(dir_stream_t)); stream->cur = cache->stats; return (void *)stream; } /** Close a directory after reading. The stat entry is a cache object so we do nothing. */ int obexftp_closedir(void *dir) { if (!dir) return -1; free (dir); return 0; } /** Read the next entry from an open directory. */ stat_entry_t *obexftp_readdir(void *dir) { dir_stream_t *stream; stream = (dir_stream_t *)dir; if (!stream || !(stream->cur)) return NULL; if (!(*stream->cur->name)) return NULL; return stream->cur++; } /** Stat a directory entry. */ stat_entry_t *obexftp_stat(obexftp_client_t *cli, const char *name) { cache_object_t *cache; stat_entry_t *entry; char *path, *abs, *p; const char *basename; return_val_if_fail(name != NULL, NULL); path = strdup(name); p = strrchr(path, '/'); if (p) { *p++ = '\0'; basename = p; } else { *path = '\0'; basename = name; } DEBUG(2, "%s() stating '%s' / '%s'\n", __func__, path, basename); /* fetch dir if needed */ (void) obexftp_cache_list(cli, path); /* search the cache for the path */ abs = normalize_dir_path(cli->quirks, path); for (cache = cli->cache; cache && strcmp(cache->name, abs); cache = cache->next); free(abs); if (!cache) { free(path); return NULL; } DEBUG(2, "%s() found '%s'\n", __func__, cache->name); /* read dir */ if (!cache->stats) cache->stats = parse_directory(cache->content); DEBUG(2, "%s() got dir '%s'\n", __func__, path); /* then lookup the basename */ for (entry = cache->stats; entry && *entry->name && strcmp(entry->name, basename); entry++); free(path); if (!entry || !(*entry->name)) return NULL; DEBUG(2, "%s() got stats\n", __func__); return entry; /* dev_t st_dev; / * device * / ino_t st_ino; / * inode * / mode_t st_mode; / * protection * / nlink_t st_nlink; / * number of hard links * / uid_t st_uid; / * user ID of owner * / gid_t st_gid; / * group ID of owner * / dev_t st_rdev; / * device type (if inode device) * / off_t st_size; / * total size, in bytes * / blksize_t st_blksize; / * blocksize for filesystem I/O * / blkcnt_t st_blocks; / * number of blocks allocated * / time_t st_atime; / * time of last access * / time_t st_mtime; / * time of last modification * / time_t st_ctime; / * time of last status change * / */ } obexftp-0.24-Source/obexftp/cache.h100777 0 0 2366 12115454406 12357 0/** \file obexftp/cache.h ObexFTP client API caching layer. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef OBEXFTP_CACHE_H #define OBEXFTP_CACHE_H #ifdef __cplusplus extern "C" { #endif void cache_purge(cache_object_t **root, const char *path); void xfer_purge(obexftp_client_t *cli); int put_cache_object(obexftp_client_t *cli, /*@only@*/ char *name, /*@only@*/ char *object, int size); int get_cache_object(const obexftp_client_t *cli, const char *name, char **object, int *size); #ifdef __cplusplus } #endif #endif /* OBEXFTP_CACHE_H */ obexftp-0.24-Source/obexftp/client.c100777 0 0 102327 12115454406 12623 0/** \file obexftp/client.c ObexFTP client API implementation. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #define O_BINARY (_O_BINARY) #define CREATE_MODE_FILE (S_IRUSR|S_IWUSR) #else #include #include #include #define O_BINARY (0) #define CREATE_MODE_FILE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) #endif /* _WIN32 */ #ifdef HAVE_BLUETOOTH #include "bt_kit.h" #else #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT #endif /* HAVE_BLUETOOTH */ #include #include #include "obexftp.h" #include "client.h" #include "object.h" #include "obexftp_io.h" #include "uuid.h" #include "cache.h" #include #pragma pack(1) typedef struct { /* fixed to 6 bytes for now */ uint8_t code; uint8_t info_len; uint8_t info[4]; } apparam_t; #pragma pack() /** Empty callback used as default. */ static void dummy_info_cb(int UNUSED(event), const char *UNUSED(msg), int UNUSED(len), void *UNUSED(data)) { /* do nothing */ } /** Normalize the path argument. \note wont turn relative paths into (most likely wrong) absolute ones. wont expand "../" or "./". */ /* static char *normalize_file_path(const char *name) { char *p, *copy; return_val_if_fail(name != NULL, NULL); p = copy = malloc(strlen(name) + 1); / * cant be longer, can it? * / / * if (OBEXFTP_USE_LEADING_SLASH(quirks)) *p++ = '/'; while (*name == '/') name++; * / while (*name) { if (*name == '/') { *p++ = *name++; while (*name == '/') name++; } else { *p++ = *name++; } } *p = '\0'; return copy; } */ /** Normalize the path argument and split into pathname and basename. \note Wont turn relative paths into (most likely wrong) absolute ones. Wont expand "../" or "./". Will keep "telecom" prefix. \warning Do not use this function if there is no slash in the argument! */ static void split_file_path(const char *name, /*@only@*/ char **basepath, /*@only@*/ char **basename) { char *p; const char *tail; return_if_fail(name != NULL); for (tail = name; *tail == '/'; tail++); if (!strncmp(tail, "telecom/", 8)) { *basename = strdup(tail); /* keep whole path */ *basepath = strdup(""); /* cd top */ return; } tail = strrchr(name, '/'); if (tail) tail++; else tail = name; if (basename) *basename = strdup(tail); if (!basepath) return; p = *basepath = malloc(strlen(name) + 1); /* cant be longer, can it? */ /* if (OBEXFTP_USE_LEADING_SLASH(quirks)) *p++ = '/'; while (*name == '/') name++; */ while (*name && name < tail) { if (*name == '/') { *p++ = *name++; while (*name == '/') name++; } else { *p++ = *name++; } } /* if (p > *basepath && *(p-1) == '/') p--; if (OBEXFTP_USE_TRAILING_SLASH(quirks)) *p++ = '/'; */ *p = '\0'; } /** Add more data from memory to stream. */ static int cli_fillstream_from_memory(obexftp_client_t *cli, obex_object_t *object) { obex_headerdata_t hv; int actual = cli->out_size - cli->out_pos; if (actual > STREAM_CHUNK) actual = STREAM_CHUNK; DEBUG(3, "%s() Read %d bytes\n", __func__, actual); if(actual > 0) { /* Read was ok! */ hv.bs = (const uint8_t *) &cli->out_data[cli->out_pos]; (void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY, hv, actual, OBEX_FL_STREAM_DATA); cli->out_pos += actual; } else if(actual == 0) { /* EOF */ cli->out_data = NULL; /* dont free, isnt ours */ hv.bs = (const uint8_t *) &cli->out_data[cli->out_pos]; (void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_DATAEND); } else { /* Error */ cli->out_data = NULL; /* dont free, isnt ours */ hv.bs = (const uint8_t *) NULL; (void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_DATA); } return actual; } /** Add more data from file to stream. */ static int cli_fillstream_from_file(obexftp_client_t *cli, obex_object_t *object) { obex_headerdata_t hv; int actual; DEBUG(3, "%s()\n", __func__); actual = read(cli->fd, cli->stream_chunk, STREAM_CHUNK); DEBUG(3, "%s() Read %d bytes\n", __func__, actual); if(actual > 0) { /* Read was ok! */ hv.bs = (const uint8_t *) cli->stream_chunk; (void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY, hv, actual, OBEX_FL_STREAM_DATA); } else if(actual == 0) { /* EOF */ (void) close(cli->fd); cli->fd = -1; hv.bs = (const uint8_t *) cli->stream_chunk; (void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_DATAEND); } else { /* Error */ (void) close(cli->fd); cli->fd = -1; hv.bs = (const uint8_t *) NULL; (void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_DATA); } return actual; } /** Save body from object or return application parameters. */ static void client_done(obex_t *handle, obex_object_t *object, int UNUSED(obex_cmd), int UNUSED(obex_rsp)) { obex_headerdata_t hv; uint8_t hi; uint32_t hlen; const apparam_t *app = NULL; char *p; const uint8_t *body_data = NULL; uint32_t body_len = -1; /*@temp@*/ obexftp_client_t *cli; cli = OBEX_GetUserData(handle); DEBUG(3, "%s()\n", __func__); if (cli->fd > 0) (void) close(cli->fd); if (cli->buf_data) { DEBUG(1, "%s: Warning: buffer still active?\n", __func__); free(cli->buf_data); cli->buf_data = NULL; } while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { if(hi == OBEX_HDR_BODY) { DEBUG(3, "%s() Found body (length: %d)\n", __func__, hlen); if (cli->target_fn == NULL) { if (cli->buf_data) { DEBUG(1, "%s: Warning: purging non-empty buffer.\n", __func__); /* ok to free since we must have malloc' it right here */ free(cli->buf_data); } p = malloc(hlen + 1); if (p) { memcpy(p, hv.bs, hlen); p[hlen] = '\0'; cli->buf_size = hlen; cli->buf_data = p; } } body_len = hlen; body_data = hv.bs; cli->infocb(OBEXFTP_EV_BODY, (char *)hv.bs, hlen, cli->infocb_data); DEBUG(3, "%s() Done body\n", __func__); /* break; */ } else if(hi == OBEX_HDR_CONNECTION) { DEBUG(3, "%s() Found connection number: %d\n", __func__, hv.bq4); cli->connection_id = hv.bq4; } else if(hi == OBEX_HDR_WHO) { DEBUG(3, "%s() Sender identified\n", __func__); } else if(hi == OBEX_HDR_NAME) { DEBUG(3, "%s() Sender name\n", __func__); DEBUGBUFFER(hv.bs, hlen); } else if(hi == OBEX_HDR_APPARAM) { DEBUG(3, "%s() Found application parameters\n", __func__); if(hlen == sizeof(apparam_t)) { app = (const apparam_t *)hv.bs; /* order is network byte order (big-endian) */ cli->apparam_info = (app->info[0] << (3*8)) + (app->info[1] << (2*8)) + (app->info[2] << (1*8)) + (app->info[3] << (0*8)); cli->infocb(OBEXFTP_EV_INFO, (char*)&cli->apparam_info, 0, cli->infocb_data); } else DEBUG(3, "%s() Application parameters don't fit %d vs. %lu.\n", __func__, hlen, (unsigned long)sizeof(apparam_t)); break; } else { DEBUG(3, "%s() Skipped header %02x\n", __func__, hi); } } if(body_data) { if (body_len > 0) { if (cli->target_fn != NULL) { /* simple body writer */ int fd; //fd = open_safe("", cli-> target_fn); fd = open(cli-> target_fn, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, CREATE_MODE_FILE); if(fd > 0) { (void) write(fd, body_data, body_len); (void) close(fd); } else { DEBUG(3, "%s() Error writing body\n", __func__); } free (cli->target_fn); cli->target_fn = NULL; } else { DEBUG(3, "%s() Body not written\n", __func__); } } else { DEBUG(3, "%s() Skipping empty body\n", __func__); } } if(app) { DEBUG(3, "%s() Appcode %d, data (%d) %d\n", __func__, app->code, app->info_len, cli->apparam_info); } } /** Handle incoming event from OpenOBEX. */ static void cli_obex_event(obex_t *handle, obex_object_t *object, int UNUSED(mode), int event, int obex_cmd, int obex_rsp) { /*@temp@*/ obexftp_client_t *cli; cli = OBEX_GetUserData(handle); switch (event) { case OBEX_EV_PROGRESS: cli->infocb(OBEXFTP_EV_PROGRESS, "", 0, cli->infocb_data); break; case OBEX_EV_REQDONE: cli->finished = TRUE; if(obex_rsp == OBEX_RSP_SUCCESS) cli->success = TRUE; else { cli->success = FALSE; DEBUG(2, "%s() OBEX_EV_REQDONE: obex_rsp=%d%02d\n", __func__, obex_rsp >> 8, obex_rsp & 0xF); } cli->obex_rsp = obex_rsp; client_done(handle, object, obex_cmd, obex_rsp); break; case OBEX_EV_LINKERR: cli->finished = TRUE; cli->success = FALSE; DEBUG(2, "%s() OBEX_EV_LINKERR\n", __func__); break; case OBEX_EV_STREAMEMPTY: if (cli->out_data) (void) cli_fillstream_from_memory(cli, object); else (void) cli_fillstream_from_file(cli, object); break; default: DEBUG(1, "%s() Unknown event %d\n", __func__, event); break; } } /** Wait for the OBEX client to finish. */ static int obexftp_sync(obexftp_client_t *cli) { int ret; DEBUG(3, "%s()\n", __func__); /* cli->finished = FALSE; */ while(cli->finished == FALSE) { ret = OBEX_HandleInput(cli->obexhandle, cli->accept_timeout); DEBUG(3, "%s() OBEX_HandleInput = %d\n", __func__, ret); if (ret <= 0) { DEBUG(2, "%s() OBEX_HandleInput error: %d\n", __func__, errno); return -1; } } DEBUG(3, "%s() Done success=%d\n", __func__, cli->success); if(cli->success) return 1; else return - cli->obex_rsp; } /** Do an OBEX request synchronous. */ static int cli_sync_request(obexftp_client_t *cli, obex_object_t *object) { DEBUG(3, "%s()\n", __func__); if (cli->finished == FALSE) return -EBUSY; cli->finished = FALSE; (void) OBEX_Request(cli->obexhandle, object); return obexftp_sync (cli); } /** Create an obexftp client. \param transport the transport type that will be used \param ctrans optional custom transport (don't use) \param infocb optional info callback \param infocb_data optional info callback data \return a new allocated ObexFTP client instance, NULL on error */ obexftp_client_t *obexftp_open(int transport, /*const*/ obex_ctrans_t *ctrans, obexftp_info_cb_t infocb, void *infocb_data) { obexftp_client_t *cli; DEBUG(3, "%s()\n", __func__); cli = calloc (1, sizeof(obexftp_client_t)); if(cli == NULL) return NULL; cli->finished = TRUE; cli->accept_timeout = 20; /* 20 seconds accept/reject timeout, default value */ if (infocb) cli->infocb = infocb; else cli->infocb = dummy_info_cb; cli->infocb_data = infocb_data; cli->quirks = DEFAULT_OBEXFTP_QUIRKS; cli->cache_timeout = DEFAULT_CACHE_TIMEOUT; cli->cache_maxsize = DEFAULT_CACHE_MAXSIZE; cli->fd = -1; cli->obexhandle = OBEX_Init(transport, cli_obex_event, 0); if(cli->obexhandle == NULL) { free(cli); return NULL; } cli->transport = transport; if ( ctrans ) { DEBUG(2, "Custom OBEX transport requested!\n"); /* OBEX_RegisterCTransport is const to ctrans ... */ if(OBEX_RegisterCTransport(cli->obexhandle, ctrans) < 0) { DEBUG(1, "Custom transport callback-registration failed\n"); } cli->ctrans = ctrans; } OBEX_SetUserData(cli->obexhandle, cli); /* Buffer for body */ cli->stream_chunk = malloc(STREAM_CHUNK); if(cli->stream_chunk == NULL) { free(cli); return NULL; } return cli; } /** Close an obexftp client and free the resources. \param cli the obexftp_client_t to be shut done and free'd. It's save to pass NULL here. Closes the given obexftp client and frees the resources. It's recommended to set the client reference to NULL afterwards. */ void obexftp_close(obexftp_client_t *cli) { DEBUG(3, "%s()\n", __func__); return_if_fail(cli != NULL); OBEX_Cleanup(cli->obexhandle); if (cli->buf_data) { DEBUG(1, "%s: Warning: purging left-over buffer.\n", __func__); free(cli->buf_data); } cache_purge(&cli->cache, NULL); free(cli->stream_chunk); free(cli); } /** Do simple connect as client. \param cli an obexftp_client_t created by obexftp_open(). \param device the device address to connect to (transport specific) \param port the port/channel for the device address \param uuid UUID string for CONNECT (no default) \param uuid_len length of the UUID string (excluding terminating zero) \return the result of the CONNECT request, -1 on error \note Wrapper function for obexftp_connect_src() \warning Always use a UUID (except for OBEX PUSH) */ int obexftp_connect_uuid(obexftp_client_t *cli, const char *device, int port, const uint8_t uuid[], uint32_t uuid_len) { return obexftp_connect_src(cli, NULL, device, port, uuid, uuid_len); } int obexftp_connect_service(obexftp_client_t *cli, const char *src, const char *device, int port, int service) { const uint8_t *uuid = NULL; uint32_t uuid_len = 0; if (service == OBEX_FTP_SERVICE) { uuid = UUID_FBS; uuid_len = sizeof(UUID_FBS); } if (service == OBEX_SYNC_SERVICE) { uuid = UUID_IRMC; uuid_len = sizeof(UUID_IRMC); } // otherwiese default to OBEX_PUSH_SERVICE return obexftp_connect_src(cli, src, device, port, uuid, uuid_len); } /** Connect this ObexFTP client using a given source address by sending an OBEX CONNECT request. \param cli an obexftp_client_t created by obexftp_open(). \param src optional local source interface address (transport specific) \param device the device address to connect to (transport specific) \param port the port/channel for the device address \param uuid UUID string for CONNECT (no default) \param uuid_len length of the UUID string (excluding terminating zero) \return the result of the CONNECT request, -1 on error \note Always use a UUID (except for OBEX PUSH) */ int obexftp_connect_src(obexftp_client_t *cli, const char *src, const char *device, int port, const uint8_t uuid[], uint32_t uuid_len) { struct sockaddr_in peer; #ifdef HAVE_BLUETOOTH char *devicedup, *devicep; bdaddr_t bdaddr, src_addr; #endif #ifdef HAVE_USB int obex_intf_cnt; #endif obex_object_t *object; obex_headerdata_t hv; int ret = -1; /* no connection yet */ DEBUG(3, "%s()\n", __func__); return_val_if_fail(cli != NULL, -EINVAL); cli->infocb(OBEXFTP_EV_CONNECTING, "", 0, cli->infocb_data); switch (cli->transport) { case OBEX_TRANS_IRDA: ret = IrOBEX_TransportConnect(cli->obexhandle, "OBEX"); DEBUG(3, "%s() IR %d\n", __func__, ret); break; case OBEX_TRANS_INET: if (!device) { ret = -EINVAL; break; } #ifdef _WIN32 peer.sin_addr.s_addr = inet_addr(device); ret = (peer.sin_addr.s_addr == INADDR_NONE) ? 0 : 1; #else ret = inet_aton(device, &peer.sin_addr); #endif if (ret) { peer.sin_family = AF_INET; peer.sin_port = htons(port); /* overridden with OBEX_PORT 650 anyhow */ ret = TcpOBEX_TransportConnect(cli->obexhandle, (struct sockaddr *) &peer, sizeof(struct sockaddr_in)); DEBUG(3, "%s() TCP %d\n", __func__, ret); } else ret = -EINVAL; /* is there a better errno? */ break; case OBEX_TRANS_CUSTOM: /* don't change the custom transport once it is in place */ if (cli->ctrans == NULL) { cli->ctrans = cobex_ctrans (device); if(OBEX_RegisterCTransport(cli->obexhandle, cli->ctrans) < 0) { DEBUG(1, "Custom transport callback-registration failed\n"); } } ret = OBEX_TransportConnect(cli->obexhandle, NULL, 0); DEBUG(3, "%s() TC %d\n", __func__, ret); break; #ifdef HAVE_BLUETOOTH case OBEX_TRANS_BLUETOOTH: if (!src) { bacpy(&src_addr, BDADDR_ANY); } #if defined(_WIN32) /* nothing */ #elif defined(__NetBSD__) || defined(__FreeBSD__) else if (bt_devaddr(src, &src_addr)) { } #else else if (!strncmp(src, "hci", 3)) { hci_devba(atoi(src + 3), &src_addr); } else if (atoi(src) != 0) { hci_devba(atoi(src), &src_addr); } #endif else { str2ba(src, &src_addr); } if (!device) { ret = -EINVAL; break; } if (port < 1) { port = obexftp_browse_bt(device, OBEX_FTP_SERVICE); } /* transform some chars to colons */ devicedup = devicep = strdup(device); for (; *devicep; devicep++) { if (*devicep == '-') *devicep = ':'; if (*devicep == '_') *devicep = ':'; if (*devicep == '/') *devicep = ':'; } (void) str2ba(devicedup, &bdaddr); free(devicedup); ret = BtOBEX_TransportConnect(cli->obexhandle, &src_addr, &bdaddr, (uint8_t)port); DEBUG(3, "%s() BT %d\n", __func__, ret); break; #endif /* HAVE_BLUETOOTH */ #ifdef HAVE_USB case OBEX_TRANS_USB: obex_intf_cnt = OBEX_EnumerateInterfaces(cli->obexhandle); DEBUG(3, "%s() \n", __func__); if (obex_intf_cnt <= 0) { DEBUG(1, "%s() there are no valid USB interfaces\n", __func__); ret = -EINVAL; /* is there a better errno? */ } else if (port >= obex_intf_cnt) { DEBUG(1, "%s() %d is an invalid USB interface number\n", __func__, port); ret = -EINVAL; /* is there a better errno? */ } else { obex_interface_t *obex_intf; obex_intf = OBEX_GetInterfaceByIndex(cli->obexhandle, port); ret = OBEX_InterfaceConnect(cli->obexhandle, obex_intf); } DEBUG(3, "%s() USB %d\n", __func__, ret); break; #endif /* HAVE_USB */ default: ret = -ESOCKTNOSUPPORT; break; } if (ret < 0) { /* could be -EBUSY or -ESOCKTNOSUPPORT */ cli->infocb(OBEXFTP_EV_ERR, "connect", 0, cli->infocb_data); return ret; } #ifdef COMPAT_S45 // try S45 UUID first. object = OBEX_ObjectNew(cli->obexhandle, OBEX_CMD_CONNECT); hv.bs = UUID_S45; if(OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_TARGET, hv, sizeof(UUID_S45), OBEX_FL_FIT_ONE_PACKET) < 0) { DEBUG(1, "Error adding header\n"); OBEX_ObjectDelete(cli->obexhandle, object); return -1; } cli->connection_id = 0xffffffff; ret = cli_sync_request(cli, object); if(ret < 0) { cli->infocb(OBEXFTP_EV_ERR, "S45 UUID", 0, cli->infocb_data); #endif object = OBEX_ObjectNew(cli->obexhandle, OBEX_CMD_CONNECT); if (uuid) { hv.bs = uuid; if(OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_TARGET, hv, uuid_len, OBEX_FL_FIT_ONE_PACKET) < 0) { DEBUG(1, "Error adding header\n"); OBEX_ObjectDelete(cli->obexhandle, object); return -1; } } cli->connection_id = 0xffffffff; ret = cli_sync_request(cli, object); if (!OBEXFTP_USE_CONN_HEADER(cli->quirks)) cli->connection_id = 0xffffffff; #ifdef COMPAT_S45 } #endif if(ret < 0) cli->infocb(OBEXFTP_EV_ERR, "send UUID", 0, cli->infocb_data); else cli->infocb(OBEXFTP_EV_OK, "", 0, cli->infocb_data); return ret; } /** Disconnect this ObexFTP client by sending an OBEX DISCONNECT request. \param cli an obexftp_client_t created by obexftp_open(). \return the result of the DISCONNECT request */ int obexftp_disconnect(obexftp_client_t *cli) { obex_object_t *object; obex_headerdata_t hv; int ret; DEBUG(3, "%s()\n", __func__); return_val_if_fail(cli != NULL, -EINVAL); cli->infocb(OBEXFTP_EV_DISCONNECTING, "", 0, cli->infocb_data); object = OBEX_ObjectNew(cli->obexhandle, OBEX_CMD_DISCONNECT); if(cli->connection_id != 0xffffffff) { hv.bq4 = cli->connection_id; (void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_CONNECTION, hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET); } ret = cli_sync_request(cli, object); if(ret < 0) cli->infocb(OBEXFTP_EV_ERR, "disconnect", 0, cli->infocb_data); else cli->infocb(OBEXFTP_EV_OK, "", 0, cli->infocb_data); /* don't -- obexftp_close will handle this with OBEX_Cleanup */ /* OBEX_TransportDisconnect(cli->obexhandle); */ return ret; } /** Send a custom Siemens OBEX app info opcode. \param cli an obexftp_client_t created by obexftp_open(). \param opcode the info opcode, 0x01 to inquire installed memory, 0x02 to get free memory \return the result of the app info request */ int obexftp_info(obexftp_client_t *cli, uint8_t opcode) { obex_object_t *object = NULL; int ret; return_val_if_fail(cli != NULL, -EINVAL); cli->infocb(OBEXFTP_EV_RECEIVING, "info", 0, cli->infocb_data); DEBUG(2, "%s() Retrieving info %d\n", __func__, opcode); object = obexftp_build_info (cli->obexhandle, cli->connection_id, opcode); if(object == NULL) return -1; ret = cli_sync_request(cli, object); if(ret < 0) { cli->infocb(OBEXFTP_EV_ERR, "info", 0, cli->infocb_data); } else cli->infocb(OBEXFTP_EV_OK, "info", 0, cli->infocb_data); return ret; } /** Send an OBEX GET with optional TYPE. Directories will be changed into first if split path quirk is set. \param cli an obexftp_client_t created by obexftp_open(). \param type OBEX TYPE of the request \param localname optional file to write \param remotename OBEX NAME to request \return the result of GET request \note \a localname and \a remotename may be null. */ int obexftp_get_type(obexftp_client_t *cli, const char *type, const char *localname, const char *remotename) { obex_object_t *object = NULL; int ret; return_val_if_fail(cli != NULL, -EINVAL); return_val_if_fail(remotename != NULL || type != NULL, -EINVAL); if (cli->buf_data) { DEBUG(1, "%s: Warning: buffer still active?\n", __func__); free(cli->buf_data); cli->buf_data = NULL; } cli->infocb(OBEXFTP_EV_RECEIVING, remotename, 0, cli->infocb_data); if (localname && *localname) cli->target_fn = strdup(localname); else cli->target_fn = NULL; if (OBEXFTP_USE_SPLIT_SETPATH(cli->quirks) && remotename && strchr(remotename, '/')) { char *basepath, *basename; split_file_path(remotename, &basepath, &basename); ret = obexftp_setpath(cli, basepath, 0); if(ret < 0) { cli->infocb(OBEXFTP_EV_ERR, basepath, 0, cli->infocb_data); return ret; } DEBUG(2, "%s() Getting %s -> %s (%s)\n", __func__, basename, localname, type); object = obexftp_build_get (cli->obexhandle, cli->connection_id, basename, type); free(basepath); free(basename); } else { DEBUG(2, "%s() Getting %s -> %s (%s)\n", __func__, remotename, localname, type); object = obexftp_build_get (cli->obexhandle, cli->connection_id, remotename, type); } if(object == NULL) return -1; ret = cli_sync_request(cli, object); if(ret < 0) cli->infocb(OBEXFTP_EV_ERR, remotename, 0, cli->infocb_data); else cli->infocb(OBEXFTP_EV_OK, remotename, 0, cli->infocb_data); return ret; } /** Send an custom Siemens OBEX rename request. \param cli an obexftp_client_t created by obexftp_open(). \param sourcename remote filename to be renamed \param targetname remote target filename \return the result of Siemens rename request */ int obexftp_rename(obexftp_client_t *cli, const char *sourcename, const char *targetname) { obex_object_t *object = NULL; int ret; return_val_if_fail(cli != NULL, -EINVAL); cli->infocb(OBEXFTP_EV_SENDING, sourcename, 0, cli->infocb_data); DEBUG(2, "%s() Moving %s -> %s\n", __func__, sourcename, targetname); object = obexftp_build_rename (cli->obexhandle, cli->connection_id, sourcename, targetname); if(object == NULL) return -1; cache_purge(&cli->cache, NULL); ret = cli_sync_request(cli, object); if(ret < 0) cli->infocb(OBEXFTP_EV_ERR, sourcename, 0, cli->infocb_data); else cli->infocb(OBEXFTP_EV_OK, sourcename, 0, cli->infocb_data); return ret; } /** Send an OBEX PUT with empty file name (delete). \param cli an obexftp_client_t created by obexftp_open(). \param name the remote filename/foldername to be removed. \return the result of the empty OBEX PUT request */ int obexftp_del(obexftp_client_t *cli, const char *name) { obex_object_t *object; int ret; return_val_if_fail(cli != NULL, -EINVAL); cli->infocb(OBEXFTP_EV_SENDING, name, 0, cli->infocb_data); /* split path and go there first */ if (OBEXFTP_USE_SPLIT_SETPATH(cli->quirks) && name && strchr(name, '/')) { char *basepath, *basename; split_file_path(name, &basepath, &basename); ret = obexftp_setpath(cli, basepath, 0); if(ret < 0) { cli->infocb(OBEXFTP_EV_ERR, basepath, 0, cli->infocb_data); return ret; } DEBUG(2, "%s() Deleting %s\n", __func__, basename); object = obexftp_build_del (cli->obexhandle, cli->connection_id, basename); free(basepath); free(basename); } else { DEBUG(2, "%s() Deleting %s\n", __func__, name); object = obexftp_build_del (cli->obexhandle, cli->connection_id, name); } if(object == NULL) return -1; cache_purge(&cli->cache, NULL); ret = cli_sync_request(cli, object); if(ret < 0) cli->infocb(OBEXFTP_EV_ERR, name, 0, cli->infocb_data); else cli->infocb(OBEXFTP_EV_OK, name, 0, cli->infocb_data); return ret; } /** Send OBEX SETPATH request (multiple requests if split path flag is set). \param cli an obexftp_client_t created by obexftp_open(). \param name path to change into \param create flag whether to create missing folders or fail \return the result of the OBEX SETPATH request(s). \note handles NULL, "", "/" and everything else correctly. */ int obexftp_setpath(obexftp_client_t *cli, const char *name, int create) { obex_object_t *object; int ret = 0; char *copy, *tail, *p; return_val_if_fail(cli != NULL, -EINVAL); DEBUG(2, "%s() Changing to %s\n", __func__, name); if (OBEXFTP_USE_SPLIT_SETPATH(cli->quirks) && name && *name && strchr(name, '/')) { tail = copy = strdup(name); for (p = strchr(tail, '/'); tail; ) { if (p) { *p = '\0'; p++; } cli->infocb(OBEXFTP_EV_SENDING, tail, 0, cli->infocb_data); DEBUG(2, "%s() Setpath \"%s\" (create:%d)\n", __func__, tail, create); /* try without the create flag */ object = obexftp_build_setpath (cli->obexhandle, cli->connection_id, tail, 0); ret = cli_sync_request(cli, object); if ((ret < 0) && create) { /* try again with create flag set maybe? */ object = obexftp_build_setpath (cli->obexhandle, cli->connection_id, tail, 1); ret = cli_sync_request(cli, object); } if (ret < 0) break; tail = p; if (p) p = strchr(p, '/'); /* prevent a trailing slash from messing all up with a cd top */ if (tail && *tail == '\0') break; } free (copy); } else { cli->infocb(OBEXFTP_EV_SENDING, name, 0, cli->infocb_data); DEBUG(2, "%s() Setpath \"%s\"\n", __func__, name); object = obexftp_build_setpath (cli->obexhandle, cli->connection_id, name, create); ret = cli_sync_request(cli, object); } if (create) cache_purge(&cli->cache, NULL); /* no way to know where we started */ if(ret < 0) cli->infocb(OBEXFTP_EV_ERR, name, 0, cli->infocb_data); else cli->infocb(OBEXFTP_EV_OK, name, 0, cli->infocb_data); return ret; } /** Send an OBEX PUT, optionally with (some) SETPATHs for a local file. \param cli an obexftp_client_t created by obexftp_open(). \param filename local file to send \param remotename remote name to write \return the result of the OBEX PUT (and SETPATH) request(s). \note Puts to filename's basename if remotename is NULL or ends with a slash. */ int obexftp_put_file(obexftp_client_t *cli, const char *filename, const char *remotename) { obex_object_t *object; int ret; return_val_if_fail(cli != NULL, -EINVAL); return_val_if_fail(filename != NULL, -EINVAL); if (cli->out_data) { DEBUG(1, "%s: Warning: buffer still active?\n", __func__); free(cli->buf_data); cli->buf_data = NULL; } cli->infocb(OBEXFTP_EV_SENDING, filename, 0, cli->infocb_data); // TODO: if remotename ends with a slash: add basename if (!remotename) { remotename = strrchr(filename, '/'); if (remotename) remotename++; else remotename = filename; } if (OBEXFTP_USE_SPLIT_SETPATH(cli->quirks) && remotename && strchr(remotename, '/')) { char *basepath, *basename; split_file_path(remotename, &basepath, &basename); ret = obexftp_setpath(cli, basepath, 0); if(ret < 0) { cli->infocb(OBEXFTP_EV_ERR, basepath, 0, cli->infocb_data); return ret; } DEBUG(2, "%s() Sending %s -> %s\n", __func__, filename, basename); object = build_object_from_file (cli->obexhandle, cli->connection_id, filename, basename); free(basepath); free(basename); } else { DEBUG(2, "%s() Sending %s -> %s\n", __func__, filename, remotename); object = build_object_from_file (cli->obexhandle, cli->connection_id, filename, remotename); } cli->fd = open(filename, O_RDONLY | O_BINARY, 0); if(cli->fd < 0) ret = -1; else { cli->out_data = NULL; /* dont free, isnt ours */ cache_purge(&cli->cache, NULL); ret = cli_sync_request(cli, object); } /* close(cli->fd); */ if(ret < 0) cli->infocb(OBEXFTP_EV_ERR, filename, 0, cli->infocb_data); else cli->infocb(OBEXFTP_EV_OK, filename, 0, cli->infocb_data); return ret; } /** Send memory data by OBEX PUT, optionally with (some) SETPATHs. \param cli an obexftp_client_t created by obexftp_open(). \param data data to send \param size length of the data \param remotename remote name to write \return the result of the OBEX PUT (and SETPATH) request(s). \note A remotename must be given always. */ int obexftp_put_data(obexftp_client_t *cli, const uint8_t *data, int size, const char *remotename) { obex_object_t *object; int ret; return_val_if_fail(cli != NULL, -EINVAL); return_val_if_fail(remotename != NULL, -EINVAL); if (cli->out_data) { DEBUG(1, "%s: Warning: buffer still active?\n", __func__); free(cli->buf_data); cli->buf_data = NULL; } cli->infocb(OBEXFTP_EV_SENDING, remotename, 0, cli->infocb_data); if (OBEXFTP_USE_SPLIT_SETPATH(cli->quirks) && remotename && strchr(remotename, '/')) { char *basepath, *basename; split_file_path(remotename, &basepath, &basename); ret = obexftp_setpath(cli, basepath, 0); if(ret < 0) { cli->infocb(OBEXFTP_EV_ERR, basepath, 0, cli->infocb_data); return ret; } DEBUG(2, "%s() Sending memdata -> %s\n", __func__, basename); object = obexftp_build_put (cli->obexhandle, cli->connection_id, basename, size); free(basepath); free(basename); } else { DEBUG(2, "%s() Sending memdata -> %s\n", __func__, remotename); object = obexftp_build_put (cli->obexhandle, cli->connection_id, remotename, size); } cli->out_data = data; /* memcpy would be safer */ cli->out_size = size; cli->out_pos = 0; cli->fd = -1; cache_purge(&cli->cache, NULL); ret = cli_sync_request(cli, object); if(ret < 0) cli->infocb(OBEXFTP_EV_ERR, remotename, 0, cli->infocb_data); else cli->infocb(OBEXFTP_EV_OK, remotename, 0, cli->infocb_data); return ret; } /** Simple device discovery wrappers. USB and BT only. */ static char **discover_usb() { char **res = NULL; #ifdef HAVE_USB obex_t *handle; int i, interfaces_number; if(! (handle = OBEX_Init(OBEX_TRANS_USB, cli_obex_event, 0))) { DEBUG(1, "%s() OBEX_Init failed\n", __func__); return NULL; } interfaces_number = OBEX_EnumerateInterfaces(handle); res = calloc(interfaces_number + 1, sizeof(char *)); for (i=0; i < interfaces_number; i++) { obex_interface_t *obex_intf; res[i] = malloc(201); obex_intf = OBEX_GetInterfaceByIndex(handle, i); snprintf(res[i], 200, "%d (Manufacturer: %s Product: %s Serial: %s Interface description: %s)", i, obex_intf->usb.manufacturer, obex_intf->usb.product, obex_intf->usb.serial, obex_intf->usb.control_interface); } /* OBEX_FreeInterfaces(handle); OpenOBEX 1.2 will crash */ OBEX_Cleanup(handle); #endif /* HAVE_USB */ return res; } char **obexftp_discover_bt_src(const char *src) { #ifdef HAVE_BLUETOOTH return btkit_discover(src); #else return NULL; #endif /* HAVE_BLUETOOTH */ } char *obexftp_bt_name_src(const char *addr, const char *src) { #ifdef HAVE_BLUETOOTH return btkit_getname(src, addr); #else return NULL; #endif /* HAVE_BLUETOOTH */ } int obexftp_browse_bt_src(const char *src, const char *addr, int svclass) { #ifdef HAVE_BLUETOOTH return btkit_browse(src, addr, svclass); #else return 0; #endif /* HAVE_BLUETOOTH */ } int obexftp_sdp_register(int svclass, int channel) { #ifdef HAVE_BLUETOOTH return btkit_register_obex(svclass, channel); #else return 0; #endif /* HAVE_BLUETOOTH */ } int obexftp_sdp_unregister(int svclass) { #ifdef HAVE_BLUETOOTH return btkit_unregister_service(svclass); #else return 0; #endif /* HAVE_BLUETOOTH */ } /** Device discovery wrapper for a named transport. \param transport a transport from the OBEX_TRANS_x enum. \return the discovery results as array of strings. \note USB and BT only for now. */ char **obexftp_discover(int transport) { switch (transport) { case OBEX_TRANS_BLUETOOTH: return obexftp_discover_bt(); case OBEX_TRANS_USB: return discover_usb(); default: DEBUG(1, "%s() Discovery not implemented: %d\n", __func__, transport); return NULL; } } obexftp-0.24-Source/obexftp/client.h100777 0 0 14522 12115454406 12607 0/** \file obexftp/client.h ObexFTP client API. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef OBEXFTP_CLIENT_H #define OBEXFTP_CLIENT_H #include #include #include #include #ifndef OBEX_TRANS_USB #define OBEX_TRANS_USB 6 #endif #include "obexftp.h" #include "object.h" #include "uuid.h" #ifdef __cplusplus extern "C" { #endif /* quirks */ #define OBEXFTP_LEADING_SLASH 0x01 /* used in get (and alike) */ #define OBEXFTP_TRAILING_SLASH 0x02 /* used in list */ #define OBEXFTP_SPLIT_SETPATH 0x04 /* some phones dont have a cwd */ #define OBEXFTP_CONN_HEADER 0x08 /* do we even need this? */ #define OBEXFTP_USE_LEADING_SLASH(x) ((x & OBEXFTP_LEADING_SLASH) != 0) #define OBEXFTP_USE_TRAILING_SLASH(x) ((x & OBEXFTP_TRAILING_SLASH) != 0) #define OBEXFTP_USE_SPLIT_SETPATH(x) ((x & OBEXFTP_SPLIT_SETPATH) != 0) #define OBEXFTP_USE_CONN_HEADER(x) ((x & OBEXFTP_CONN_HEADER) != 0) /* dont disable leading slashes unless you disable split setpath */ #define DEFAULT_OBEXFTP_QUIRKS \ (OBEXFTP_LEADING_SLASH | OBEXFTP_TRAILING_SLASH | OBEXFTP_SPLIT_SETPATH | OBEXFTP_CONN_HEADER) #define DEFAULT_CACHE_TIMEOUT 180 /* 3 minutes */ #define DEFAULT_CACHE_MAXSIZE 10240 /* 10k */ /* types */ typedef struct { char name[256]; mode_t mode; int size; time_t mtime; time_t atime; time_t ctime; } stat_entry_t; typedef struct cache_object cache_object_t; struct cache_object { cache_object_t *next; int refcnt; time_t timestamp; int size; /* or uint32_t */ char *name; char *content; /* or uint8_t */ stat_entry_t *stats; /* only if its a parsed directory */ }; typedef struct { /* state */ obex_t *obexhandle; uint32_t connection_id; /* set to 0xffffffff if unused */ obex_ctrans_t *ctrans; /* only valid with OBEX_TRANS_CUSTOM */ int transport; /* the transport for obexhandle */ int finished; int success; int obex_rsp; int mutex; /* should be using pthreads for this */ int quirks; /* client */ obexftp_info_cb_t infocb; void *infocb_data; /* transfer (put) */ int fd; /* used in put body */ uint8_t *stream_chunk; uint32_t out_size; uint32_t out_pos; const uint8_t *out_data; /* transfer (get) */ char *target_fn; /* used in get body */ uint32_t buf_size; /* not size but len... */ char *buf_data; uint32_t apparam_info; /* persistence */ cache_object_t *cache; int cache_timeout; int cache_maxsize; int accept_timeout; /* accept/reject timeout in seconds */ } obexftp_client_t; /* session */ /*@null@*/ obexftp_client_t *obexftp_open(int transport, /*@null@*/ /*const*/ obex_ctrans_t *ctrans, /*@null@*/ obexftp_info_cb_t infocb, /*@null@*/ void *infocb_data); void obexftp_close(/*@only@*/ /*@out@*/ /*@null@*/ obexftp_client_t *cli); int obexftp_connect_uuid(obexftp_client_t *cli, /*@null@*/ const char *device, /* for INET, BLUETOOTH */ int port, /* INET(?), BLUETOOTH, USB*/ /*@null@*/ const uint8_t uuid[], uint32_t uuid_len); int obexftp_connect_src(obexftp_client_t *cli, /*@null@*/ const char *src, /* HCI no. or address */ /*@null@*/ const char *device, /* for INET, BLUETOOTH */ int port, /* INET(?), BLUETOOTH, USB*/ /*@null@*/ const uint8_t uuid[], uint32_t uuid_len); int obexftp_connect_service(obexftp_client_t *cli, /*@null@*/ const char *src, /* HCI no. or address */ /*@null@*/ const char *device, /* for INET, BLUETOOTH */ int port, /* INET(?), BLUETOOTH, USB*/ int service); //int obexftp_connect_service(obexftp_client_t *cli, // /*@null@*/ const char *service, // /*@null@*/ const char *device, /* for INET, BLUETOOTH */ // int port, /* INET(?), BLUETOOTH, USB*/ ); #define obexftp_connect(cli, device, port) \ obexftp_connect_uuid(cli, device, port, UUID_FBS, sizeof(UUID_FBS)) #define obexftp_connect_ftp(cli, device, port) \ obexftp_connect_uuid(cli, device, port, UUID_FBS, sizeof(UUID_FBS)) #define obexftp_connect_push(cli, device, port) \ obexftp_connect_uuid(cli, device, port, NULL, 0) #define obexftp_connect_sync(cli, device, port) \ obexftp_connect_uuid(cli, device, port, UUID_IRMC, sizeof(UUID_IRMC)) int obexftp_disconnect(obexftp_client_t *cli); /* transfer */ int obexftp_setpath(obexftp_client_t *cli, /*@null@*/ const char *name, int create); #define obexftp_chpath(cli, name) \ obexftp_setpath(cli, name, 0) #define obexftp_mkpath(cli, name) \ obexftp_setpath(cli, name, 1) #define obexftp_cdup(cli) \ obexftp_setpath(cli, NULL, 0) #define obexftp_cdtop(cli) \ obexftp_setpath(cli, "", 0) int obexftp_get_type(obexftp_client_t *cli, const char *type, /*@null@*/ const char *localname, /*@null@*/ const char *remotename); #define obexftp_get(cli, localname, remotename) \ obexftp_get_type(cli, NULL, localname, remotename) #define obexftp_list(cli, localname, remotename) \ obexftp_get_type(cli, XOBEX_LISTING, localname, remotename) #define obexftp_get_capability(cli, localname, remotename) \ obexftp_get_type(cli, XOBEX_CAPABILITY, localname, remotename) int obexftp_put_file(obexftp_client_t *cli, const char *filename, const char *remotename); int obexftp_put_data(obexftp_client_t *cli, const uint8_t *data, int size, const char *remotename); int obexftp_del(obexftp_client_t *cli, const char *name); /* Siemens only */ int obexftp_info(obexftp_client_t *cli, uint8_t opcode); int obexftp_rename(obexftp_client_t *cli, const char *sourcename, const char *targetname); /* compatible directory handling */ void *obexftp_opendir(obexftp_client_t *cli, const char *name); int obexftp_closedir(void *dir); stat_entry_t *obexftp_readdir(void *dir); stat_entry_t *obexftp_stat(obexftp_client_t *cli, const char *name); #ifdef __cplusplus } #endif #endif /* OBEXFTP_CLIENT_H */ obexftp-0.24-Source/obexftp/CMakeLists.txt100777 0 0 2440 12115454406 13674 0 set ( obexftp_SOURCES object.c client.c obexftp_io.c cache.c unicode.c bt_kit.c ) set ( obexftp_PUBLIC_HEADERS obexftp.h client.h uuid.h object.h ) set ( obexftp_HEADERS object.h obexftp_io.h cache.h unicode.h bt_kit.h ${obexftp_PUBLIC_HEADERS} ) find_package ( Iconv REQUIRED ) add_definitions ( -DHAVE_ICONV ) if ( ICONV_USES_CONST ) add_definitions ( -DICONV_CONST=const ) endif ( ICONV_USES_CONST ) find_file ( HAVE_LANGINFO_H NAMES langinfo.h ) if ( HAVE_LANGINFO_H ) add_definitions ( -DHAVE_LANGINFO_H ) endif ( HAVE_LANGINFO_H ) # always set this add_definitions ( -DHAVE_USB ) add_library ( obexftp ${obexftp_SOURCES} ${obexftp_HEADERS} ) set_property ( TARGET obexftp PROPERTY VERSION 0.3.0 ) set_property ( TARGET obexftp PROPERTY SOVERSION 0 ) set_property ( TARGET obexftp PROPERTY PUBLIC_HEADER ${obexftp_PUBLIC_HEADERS} ) target_link_libraries ( obexftp multicobex ${Bluetooth_LIBRARIES} ${OpenObex_LIBRARIES} ) install ( TARGETS obexftp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT library LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/obexftp COMPONENT devel ) obexftp-0.24-Source/obexftp/obexftp.h100777 0 0 6067 12115454406 12765 0/** \file obexftp/obexftp.h Data structures and general functions for OBEX clients and servers. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef OBEXFTP_H #define OBEXFTP_H #ifdef __cplusplus extern "C" { #endif /** ObexFTP message callback prototype. */ typedef void (*obexftp_info_cb_t) (int event, const char *buf, int len, void *data); /** ObexFTP message callback events */ enum { OBEXFTP_EV_ERRMSG, /* not used / internal error */ OBEXFTP_EV_OK, OBEXFTP_EV_ERR, OBEXFTP_EV_CONNECTING, OBEXFTP_EV_DISCONNECTING, OBEXFTP_EV_SENDING, OBEXFTP_EV_LISTENING, OBEXFTP_EV_CONNECTIND, OBEXFTP_EV_DISCONNECTIND, OBEXFTP_EV_RECEIVING, OBEXFTP_EV_BODY, OBEXFTP_EV_INFO, OBEXFTP_EV_PROGRESS, /* approx. every 1KByte */ }; /** Number of bytes passed at one time to OBEX. */ #define STREAM_CHUNK 4096 /* bt svclass */ #define OBEX_SYNC_SERVICE 0x1104 #define OBEX_PUSH_SERVICE 0x1105 #define OBEX_FTP_SERVICE 0x1106 /* server and client helpers for bt */ char **obexftp_discover(int transport); char **obexftp_discover_bt_src(const char *src); /* HCI no. or address */ #define obexftp_discover_bt() \ obexftp_discover_bt_src(NULL) char *obexftp_bt_name_src(const char *addr, const char *src); #define obexftp_bt_name(addr) \ obexftp_bt_name_src(addr, NULL) int obexftp_browse_bt_src(const char *src, const char *addr, int svclass); #define obexftp_browse_bt(device, service) \ obexftp_browse_bt_src(NULL, device, service) #define obexftp_browse_bt_ftp(device) \ obexftp_browse_bt_src(NULL, device, OBEX_FTP_SERVICE) #define obexftp_browse_bt_push(device) \ obexftp_browse_bt_src(NULL, device, OBEX_PUSH_SERVICE) #define obexftp_browse_bt_sync(device) \ obexftp_browse_bt_src(NULL, device, OBEX_SYNC_SERVICE) int obexftp_sdp_register(int svclass, int channel); #define obexftp_sdp_register_ftp(channel) \ obexftp_sdp_register(OBEX_FTP_SERVICE, channel) #define obexftp_sdp_register_push(channel) \ obexftp_sdp_register(OBEX_PUSH_SERVICE, channel) #define obexftp_sdp_register_sync(channel) \ obexftp_sdp_register(OBEX_SYNC_SERVICE, channel) int obexftp_sdp_unregister(int svclass); #define obexftp_sdp_unregister_ftp() \ obexftp_sdp_unregister(OBEX_FTP_SERVICE) #define obexftp_sdp_unregister_push() \ obexftp_sdp_unregister(OBEX_PUSH_SERVICE) #define obexftp_sdp_unregister_sync() \ obexftp_sdp_unregister(OBEX_SYNC_SERVICE) #ifdef __cplusplus } #endif #endif /* OBEXFTP */ obexftp-0.24-Source/obexftp/obexftp_io.c100777 0 0 14261 12115454406 13462 0/** \file obexftp/obexftp_io.c ObexFTP IO abstraction implementation. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "obexftp_io.h" #include "unicode.h" #include #ifdef _WIN32 #define S_IRGRP 0 #define S_IROTH 0 #define S_IXGRP 0 #define S_IXOTH 0 #endif #define DEFFILEMOD (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) /* 0644 */ #define DEFXFILEMOD (DEFFILEMOD | S_IXGRP | S_IXUSR | S_IXOTH) /* 0755 */ /* Get some file-info. (size and lastmod) */ /* lastmod needs to have at least 21 bytes */ static int get_fileinfo(const char *name, char *lastmod) { struct stat stats; struct tm *tm; if ((0 == stat(name, &stats)) && ((tm = gmtime(&stats.st_mtime)) != NULL)) { (void) snprintf(lastmod, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); return (int) stats.st_size; } return -1; } /* Create an object from a file. Attach some info-headers to it */ obex_object_t *build_object_from_file(obex_t *obex, uint32_t conn, const char *localname, const char *remotename) { obex_object_t *object; obex_headerdata_t hv; uint8_t *ucname; int ucname_len, size; char lastmod[] = "11997700--0011--0011TT0000::0000::0000ZZ."; /* Get filesize and modification-time */ size = get_fileinfo(localname, lastmod); object = OBEX_ObjectNew(obex, OBEX_CMD_PUT); if(object == NULL) return NULL; if(conn != 0xffffffff) { hv.bq4 = conn; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_CONNECTION, hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET); } ucname_len = strlen(remotename)*2 + 2; ucname = malloc(ucname_len); if(ucname == NULL) { (void) OBEX_ObjectDelete(obex, object); return NULL; } ucname_len = CharToUnicode(ucname, (uint8_t*)remotename, ucname_len); hv.bs = ucname; (void ) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_NAME, hv, ucname_len, 0); free(ucname); hv.bq4 = (const uint32_t) size; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_LENGTH, hv, sizeof(uint32_t), 0); #if 0 /* Win2k excpects this header to be in unicode. I suspect this in incorrect so this will have to wait until that's investigated */ hv.bs = (const uint8_t *) lastmod; OBEX_ObjectAddHeader(obex, object, OBEX_HDR_TIME, hv, strlen(lastmod)+1, 0); #endif hv.bs = (const uint8_t *) NULL; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_START); DEBUG(3, "%s() Lastmod = %s\n", __func__, lastmod); return object; } /* Check for dangerous filenames. */ static int nameok(const char *name) { DEBUG(3, "%s() \n", __func__); return_val_if_fail (name != NULL, FALSE); /* No abs paths */ if(name[0] == '/') return FALSE; if(strlen(name) >= 3) { /* "../../vmlinuz" */ if(name[0] == '.' && name[1] == '.' && name[2] == '/') return FALSE; /* "dir/../../../vmlinuz" */ if(strstr(name, "/../") != NULL) return FALSE; } return TRUE; } /* Concatenate two pathnames. */ /* The first path may be NULL. */ /* The second path is always treated relative. */ static int pathncat(/*@unique@*/ char *dest, const char *path, const char *name, size_t n) { size_t len; if(name == NULL) return -EINVAL; while(*name == '/') name++; if((path == NULL) || (*path == '\0')) { strncpy(dest, name, n); dest[n - 1] = '\0'; } else { strncpy(dest, path, n); dest[n - 1] = '\0'; len = strlen(dest); if (len >= n - 1) return -ENOMEM; if (dest[len - 1] != '/') { dest[len] = '/'; dest[len + 1] = '\0'; } strncat(dest, name, n - strlen(dest) - 1); } return 0; } /* Open a file, but do some sanity-checking first. */ int open_safe(const char *path, const char *name) { char *diskname; size_t maxlen; int fd; DEBUG(3, "%s() \n", __func__); /* Check for dangerous filenames */ if(nameok(name) == FALSE) return -1; /* TODO! Rename file if already exist. */ maxlen = strlen(name) + 1; if (path) maxlen += strlen(path); diskname = malloc(maxlen); if(!diskname) return -1; (void) pathncat(diskname, path, name, maxlen); DEBUG(3, "%s() Creating file %s\n", __func__, diskname); fd = open(diskname, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMOD); free(diskname); return fd; } /* Go to a directory. Create if not exists and create is true. */ int checkdir(const char *path, const char *dir, int create, int allowabs) { char *newpath; size_t maxlen; struct stat statbuf; int ret = -1; if(!allowabs) { if(nameok(dir) == FALSE) return -1; } if(!dir) return 1; maxlen = strlen(dir) + 1; if (path) maxlen += strlen(path); newpath = malloc(maxlen); if(!newpath) return -1; (void) pathncat(newpath, path, dir, maxlen); DEBUG(3, "%s() path = %s dir = %s, create = %d, allowabs = %d\n", __func__, path, dir, create, allowabs); if(stat(newpath, &statbuf) == 0) { /* If this directory aleady exist we are done */ if(S_ISDIR(statbuf.st_mode)) { DEBUG(3, "%s() Using existing dir\n", __func__); free(newpath); return 1; } else { /* A non-directory with this name already exist. */ DEBUG(3, "%s() A non-dir called %s already exist\n", __func__, newpath); free(newpath); return -1; } } if(create) { DEBUG(3, "%s() Will try to create %s\n", __func__, newpath); #ifdef _WIN32 ret = mkdir(newpath); #else ret = mkdir(newpath, DEFXFILEMOD); #endif } else { ret = -1; } free(newpath); return ret; } obexftp-0.24-Source/obexftp/obexftp_io.h100777 0 0 2156 12115454406 13447 0/** \file obexftp/obexftp_io.h ObexFTP IO abstraction. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef OBEXFTP_IO_H #define OBEXFTP_IO_H /*@null@*/ obex_object_t *build_object_from_file(obex_t *handle, uint32_t conn, const char *localname, const char *remotename); int open_safe(const char *path, const char *name); int checkdir(const char *path, const char *dir, int create, int allowabs); #endif /* OBEXFTP_IO_H */ obexftp-0.24-Source/obexftp/object.c100777 0 0 22421 12115454406 12567 0/** \file obexftp/object.c Collection of functions to build common OBEX request objects. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #include #include #include #include "unicode.h" #include "object.h" /** Build an INFO request object (Siemens only). \param obex reference to an OpenOBEX instance. \param conn optional connection id number \param opcode select if you want to read mem installed (0x01) or free mem (0x02) \return a new obex object if successful, NULL otherwise */ obex_object_t *obexftp_build_info (obex_t *obex, uint32_t conn, uint8_t opcode) { obex_object_t *object; obex_headerdata_t hv; uint8_t cmdstr[] = {APPARAM_INFO_CODE, 0x01, 0x00}; object = OBEX_ObjectNew(obex, OBEX_CMD_GET); if(object == NULL) return NULL; if(conn != 0xffffffff) { hv.bq4 = conn; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_CONNECTION, hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET); } cmdstr[2] = opcode; hv.bs = (const uint8_t *) cmdstr; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_APPARAM, hv, sizeof(cmdstr), OBEX_FL_FIT_ONE_PACKET); return object; } /** Build a GET request object. \param obex reference to an OpenOBEX instance. \param conn optional connection id number \param name name of the requested file \param type type of the requested file \return a new obex object if successful, NULL otherwise \note \a name and \a type musn't both be NULL */ obex_object_t *obexftp_build_get (obex_t *obex, uint32_t conn, const char *name, const char *type) { obex_object_t *object; obex_headerdata_t hv; uint8_t *ucname; int ucname_len; object = OBEX_ObjectNew(obex, OBEX_CMD_GET); if(object == NULL) return NULL; if(conn != 0xffffffff) { hv.bq4 = conn; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_CONNECTION, hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET); } if(type != NULL) { // type header is a null terminated ascii string hv.bs = (const uint8_t *) type; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_TYPE, hv, strlen(type)+1, OBEX_FL_FIT_ONE_PACKET); } if (name != NULL) { ucname_len = strlen(name)*2 + 2; ucname = malloc(ucname_len); if(ucname == NULL) { (void) OBEX_ObjectDelete(obex, object); return NULL; } ucname_len = CharToUnicode(ucname, (uint8_t*)name, ucname_len); hv.bs = (const uint8_t *) ucname; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_NAME, hv, ucname_len, OBEX_FL_FIT_ONE_PACKET); free(ucname); } return object; } /** Build a RENAME request object (Siemens only). \param obex reference to an OpenOBEX instance. \param conn optional connection id number \param from original name of the requested file \param to new name of the requested file \return a new obex object if successful, NULL otherwise \note neither filename may be NULL */ obex_object_t *obexftp_build_rename (obex_t *obex, uint32_t conn, const char *from, const char *to) { obex_object_t *object; obex_headerdata_t hv; uint8_t *appstr; uint8_t *appstr_p; int appstr_len; int ucname_len; char opname[] = {'m','o','v','e'}; if((from == NULL) || (to == NULL)) return NULL; object = OBEX_ObjectNew(obex, OBEX_CMD_PUT); if(object == NULL) return NULL; if(conn != 0xffffffff) { hv.bq4 = conn; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_CONNECTION, hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET); } appstr_len = 1 + 1 + sizeof(opname) + strlen(from)*2 + 2 + strlen(to)*2 + 2 + 2; appstr = malloc(appstr_len); if(appstr == NULL) { (void) OBEX_ObjectDelete(obex, object); return NULL; } appstr_p = appstr; *appstr_p++ = 0x34; *appstr_p++ = sizeof(opname); memcpy(appstr_p, opname, sizeof(opname)); appstr_p += sizeof(opname); *appstr_p++ = 0x35; ucname_len = CharToUnicode(appstr_p + 1, (uint8_t*)from, strlen(from)*2 + 2); *appstr_p = ucname_len - 2; /* no trailing 0 */ appstr_p += ucname_len - 1; *appstr_p++ = 0x36; ucname_len = CharToUnicode(appstr_p + 1, (uint8_t*)to, strlen(to)*2 + 2); *appstr_p = ucname_len - 2; /* no trailing 0 */ hv.bs = (const uint8_t *) appstr; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_APPARAM, hv, appstr_len - 2, 0); free(appstr); return object; } /** Build a DELETE request object. \param obex reference to an OpenOBEX instance. \param conn optional connection id number \param name name of the file to be deleted \return a new obex object if successful, NULL otherwise \note \a name may not be NULL */ obex_object_t *obexftp_build_del (obex_t *obex, uint32_t conn, const char *name) { obex_object_t *object; obex_headerdata_t hv; uint8_t *ucname; int ucname_len; if(name == NULL) return NULL; object = OBEX_ObjectNew(obex, OBEX_CMD_PUT); if(object == NULL) return NULL; if(conn != 0xffffffff) { hv.bq4 = conn; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_CONNECTION, hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET); } ucname_len = strlen(name)*2 + 2; ucname = malloc(ucname_len); if(ucname == NULL) { (void) OBEX_ObjectDelete(obex, object); return NULL; } ucname_len = CharToUnicode(ucname, (uint8_t*)name, ucname_len); hv.bs = (const uint8_t *) ucname; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_NAME, hv, ucname_len, OBEX_FL_FIT_ONE_PACKET); free(ucname); return object; } /** Build a SETPATH request object. \param obex reference to an OpenOBEX instance. \param conn optional connection id number \param name name of the file to be deleted \param create create the folder if neccessary \return a new obex object if successful, NULL otherwise \note if \a name is NULL ascend one directory if \a name is empty change to top/default directory */ obex_object_t *obexftp_build_setpath (obex_t *obex, uint32_t conn, const char *name, int create) { obex_object_t *object; obex_headerdata_t hv; // "Backup Level" and "Don't Create" flag in first byte // second byte is reserved and needs to be 0 uint8_t setpath_nohdr_data[2] = {0, 0}; uint8_t *ucname; int ucname_len; object = OBEX_ObjectNew(obex, OBEX_CMD_SETPATH); if(object == NULL) return NULL; if(conn != 0xffffffff) { hv.bq4 = conn; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_CONNECTION, hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET); } if (create == 0) { // set the 'Don't Create' bit setpath_nohdr_data[0] |= 2; } if (name) { ucname_len = strlen(name)*2 + 2; ucname = malloc(ucname_len); if (ucname == NULL) { (void) OBEX_ObjectDelete(obex, object); return NULL; } ucname_len = CharToUnicode(ucname, (uint8_t*)name, ucname_len); /* apparently the empty name header is meant to be really empty... */ if (ucname_len == 2) ucname_len = 0; hv.bs = (const uint8_t *) ucname; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_NAME, hv, ucname_len, 0); free(ucname); } else { setpath_nohdr_data[0] = 1; /* or |= perhaps? */ } (void) OBEX_ObjectSetNonHdrData(object, setpath_nohdr_data, 2); return object; } /** Build a PUT request object. \param obex reference to an OpenOBEX instance. \param conn optional connection id number \param name name of the target file \param size size hint for the target file \return a new obex object if successful, NULL otherwise \note use build_object_from_file() instead */ obex_object_t *obexftp_build_put (obex_t *obex, uint32_t conn, const char *name, const int size) { obex_object_t *object; obex_headerdata_t hv; uint8_t *ucname; int ucname_len; object = OBEX_ObjectNew(obex, OBEX_CMD_PUT); if(object == NULL) return NULL; if(conn != 0xffffffff) { hv.bq4 = conn; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_CONNECTION, hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET); } ucname_len = strlen(name)*2 + 2; ucname = malloc(ucname_len); if(ucname == NULL) { (void) OBEX_ObjectDelete(obex, object); return NULL; } ucname_len = CharToUnicode(ucname, (uint8_t*)name, ucname_len); hv.bs = (const uint8_t *) ucname; (void ) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_NAME, hv, ucname_len, 0); free(ucname); hv.bq4 = (uint32_t) size; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_LENGTH, hv, sizeof(uint32_t), 0); hv.bs = (const uint8_t *) NULL; (void) OBEX_ObjectAddHeader(obex, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_START); return object; } obexftp-0.24-Source/obexftp/object.h100777 0 0 4265 12115454406 12562 0/** \file obexftp/object.h Collection of functions to build common OBEX request objects. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef OBEXFTP_OBJECT_H #define OBEXFTP_OBJECT_H #include #include #ifdef __cplusplus extern "C" { #endif /** Telecom/IrMC Synchronization Service: Name Prefix. */ #define IRMC_NAME_PREFIX "telecom/" /** Telecom/IrMC Synchronization Service: Object Profile file-type. */ #define XOBEX_PROFILE "x-obex/object-profile" /** Telecom/IrMC Synchronization Service: Capability file-type. */ #define XOBEX_CAPABILITY "x-obex/capability" /** Folder Browsing Service: Folder Listing file-type. */ #define XOBEX_LISTING "x-obex/folder-listing" /** Siemens specific: app. param. for memory info. * parameter 0x01: mem installed, 0x02: free mem */ #define APPARAM_INFO_CODE '2' /*@null@*/ obex_object_t *obexftp_build_info (obex_t *obex, uint32_t conn, uint8_t opcode); /*@null@*/ obex_object_t *obexftp_build_get (obex_t *obex, uint32_t conn, const char *name, const char *type); /*@null@*/ obex_object_t *obexftp_build_rename (obex_t *obex, uint32_t conn, const char *from, const char *to); /*@null@*/ obex_object_t *obexftp_build_del (obex_t *obex, uint32_t conn, const char *name); /*@null@*/ obex_object_t *obexftp_build_setpath (obex_t *obex, uint32_t conn, const char *name, int create); /*@null@*/ obex_object_t *obexftp_build_put (obex_t *obex, uint32_t conn, const char *name, int size); #ifdef __cplusplus } #endif #endif /* OBEXFTP_OBJECT_H */ obexftp-0.24-Source/obexftp/unicode.c100777 0 0 16372 12115454406 12757 0/** \file obexftp/unicode.c Unicode charset and encoding conversions. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #ifdef _WIN32 /* no need for iconv */ #include /* pulls in Winnls.h */ #else #ifdef HAVE_ICONV #include #include #ifndef ICONV_CONST #define ICONV_CONST #endif #ifdef HAVE_LANGINFO_H #include #define locale_charset nl_langinfo(CODESET) #else #define locale_charset "" #endif /* HAVE_LANGINFO_H */ #endif /* HAVE_ICONV */ #endif /* _WIN32 */ #include "unicode.h" #include /** Convert a string to UTF-16BE, tries to guess charset and encoding. As a lib we can't be sure what the input charset and encoding is. Try to read the input as UTF-8, this will also work for plain ASCII (7bit). On errors fall back to the environment locale, which again could be UTF-8. As last resort try to copy verbatim, i.e. as ISO-8859-1. \note This is a quick hack until OpenOBEX is iconv-ready. */ int CharToUnicode(uint8_t *uc, const uint8_t *c, int size) { #ifdef _WIN32 /* no need for iconv */ int ret, i; char tmp; return_val_if_fail(uc != NULL, -1); return_val_if_fail(c != NULL, -1); /* ANSI to UTF-16LE */ ret = MultiByteToWideChar(CP_ACP, 0, c, -1, (LPWSTR)uc, size); /* turn the eggs the right way around now */ for (i=0; i < ret; i++) { tmp = uc[2*i]; uc[2*i] = uc[2*i+1]; uc[2*i+1] = tmp; } return ret * 2; /* 0 on error */ #else /* _WIN32 */ #ifdef HAVE_ICONV iconv_t utf16; size_t ni, no, nrc; /* avoid type-punned dereferecing (breaks strict aliasing) */ ICONV_CONST char *cc = (ICONV_CONST char *)c; char *ucc = (char *)uc; return_val_if_fail(uc != NULL, -1); return_val_if_fail(c != NULL, -1); /* try UTF-8 to UTF-16BE */ ni = strlen(cc) + 1; no = size; utf16 = iconv_open("UTF-16BE", "UTF-8"); nrc = iconv(utf16, &cc, &ni, &ucc, &no); (void)iconv_close(utf16); if (nrc == (size_t)(-1)) { DEBUG(3, "Iconv from UTF-8 conversion error: '%s'\n", cc); } else { return size-no; } /* try current locale charset to UTF-16BE */ setlocale(LC_CTYPE, ""); DEBUG(2, "Iconv from locale \"%s\"\n", locale_charset); cc = (ICONV_CONST char *)c; ucc = (char *)uc; ni = strlen(cc) + 1; no = size; utf16 = iconv_open("UTF-16BE", locale_charset); nrc = iconv(utf16, &cc, &ni, &ucc, &no); (void)iconv_close(utf16); if (nrc == (size_t)(-1)) { DEBUG(3, "Iconv from locale conversion error: '%s'\n", cc); } else { return size-no; } /* fallback to ISO-8859-1 to UTF-16BE (every byte is valid here) */ cc = (ICONV_CONST char *)c; ucc = (char *)uc; ni = strlen(cc) + 1; no = size; utf16 = iconv_open("UTF-16BE", "ISO-8859-1"); nrc = iconv(utf16, &cc, &ni, &ucc, &no); (void)iconv_close(utf16); if (nrc == (size_t)(-1)) { DEBUG(2, "Iconv internal conversion error: '%s'\n", cc); return -1; } return size-no; #else /* HAVE_ICONV */ int len, n; if (uc == NULL || c == NULL) return -1; len = n = strlen((char *) c); if (n*2+2 > size) return -1; uc[n*2+1] = 0; uc[n*2] = 0; while (n--) { uc[n*2+1] = c[n]; uc[n*2] = 0; } return (len * 2) + 2; #endif /* HAVE_ICONV */ #endif /* _WIN32 */ } /** Convert a string from UTF-16BE to locale charset. Plain ASCII (7bit) and basic ISO-8859-1 will always work. This conversion supports UTF-8 and single byte locales. \note This is a quick hack until OpenOBEX is iconv-ready. */ int UnicodeToChar(uint8_t *c, const uint8_t *uc, int size) { #ifdef _WIN32 /* no need for iconv */ int ret, n, i; uint8_t *le; return_val_if_fail(uc != NULL, -1); return_val_if_fail(c != NULL, -1); /* turn the eggs around, pointy side up */ for (n=0; uc[2*n] != 0 || uc[2*n+1] != 0; n++); le = malloc(2*n+2); for (i=0; i <= n; i++) { le[2*i] = uc[2*i+1]; le[2*i+1] = uc[2*i]; } /* UTF-16LE to ANSI */ ret = WideCharToMultiByte(CP_ACP, 0, le, -1, c, size, NULL, NULL); free(le); return ret; /* 0 on error */ #else /* _WIN32 */ #ifdef HAVE_ICONV iconv_t utf16; size_t ni, no, nrc; /* avoid type-punned dereferecing (breaks strict aliasing) */ char *cc = (char *)c; ICONV_CONST char *ucc = (ICONV_CONST char *)uc; return_val_if_fail(uc != NULL, -1); return_val_if_fail(c != NULL, -1); /* UTF-16BE to current locale charset */ setlocale(LC_CTYPE, ""); DEBUG(3, "Iconv to locale \"%s\"\n", locale_charset); for (ni=0; ucc[2*ni] != 0 || ucc[2*ni+1] != 0; ni++); ni = 2*ni+2; no = size; utf16 = iconv_open(locale_charset, "UTF-16BE"); nrc = iconv(utf16, &ucc, &ni, &cc, &no); (void)iconv_close(utf16); if (nrc == (size_t)(-1)) { DEBUG(2, "Iconv from locale conversion error: '%s'\n", cc); } return size-no; #else /* HAVE_ICONV */ int n; if (uc == NULL || c == NULL) return -1; /* Make sure buffer is big enough! */ for (n = 0; uc[n*2+1] != 0; n++); if (n >= size) return -1; for (n = 0; uc[n*2+1] != 0; n++) c[n] = uc[n*2+1]; c[n] = 0; return 0; #endif /* HAVE_ICONV */ #endif /* _WIN32 */ } /** Convert a (xml) string from UTF-8 to locale charset. Plain ASCII (7bit) and basic ISO-8859-1 will always work. This conversion supports UTF-8 and single byte locales. \note This is a quick hack until OpenOBEX is iconv-ready. */ int Utf8ToChar(uint8_t *c, const uint8_t *uc, int size) { #ifdef _WIN32 /* no need for iconv */ int ret, n, i; uint8_t *le; return_val_if_fail(uc != NULL, -1); return_val_if_fail(c != NULL, -1); n = strlen(uc)*2+2; le = malloc(n); /* UTF-8 to UTF-16LE */ ret = MultiByteToWideChar(CP_UTF8, 0, uc, -1, (LPWSTR)le, n); /* UTF-16LE to ANSI */ ret = WideCharToMultiByte(CP_ACP, 0, le, -1, c, size, NULL, NULL); free(le); return ret; /* 0 on error */ #else /* _WIN32 */ #ifdef HAVE_ICONV iconv_t utf8; size_t ni, no, nrc; /* avoid type-punned dereferecing (breaks strict aliasing) */ char *cc = (char *)c; ICONV_CONST char *ucc = (ICONV_CONST char *)uc; return_val_if_fail(uc != NULL, -1); return_val_if_fail(c != NULL, -1); setlocale(LC_CTYPE, ""); DEBUG(2, "Iconv to \"%s\"\n", locale_charset); ni = strlen(ucc); no = size; utf8 = iconv_open(locale_charset, "UTF-8"); nrc = iconv(utf8, &ucc, &ni, &cc, &no); (void)iconv_close(utf8); if (nrc != (size_t)(-1)) { DEBUG(2, "Iconv from locale conversion error: '%s'\n", cc); } return size-no; #else /* HAVE_ICONV */ int n, i; n = strlen(uc); strncpy(c, uc, size); c[size] = '\0'; return n; #endif /* HAVE_ICONV */ #endif /* _WIN32 */ } obexftp-0.24-Source/obexftp/unicode.h100777 0 0 2233 12115454406 12733 0/** \file obexftp/unicode.h Unicode charset and encoding conversions. ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2007 Christian W. Zuckschwerdt ObexFTP 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 program 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 ObexFTP. If not, see . */ #ifndef OBEXFTP_UNICODE_H #define OBEXFTP_UNICODE_H #include #ifdef __cplusplus extern "C" { #endif int CharToUnicode(uint8_t *uc, const uint8_t *c, int size); int UnicodeToChar(uint8_t *c, const uint8_t *uc, int size); int Utf8ToChar(uint8_t *c, const uint8_t *uc, int size); #ifdef __cplusplus } #endif #endif /* OBEXFTP_UNICODE_H */ obexftp-0.24-Source/obexftp/uuid.h100777 0 0 2533 12115454406 12256 0/** \file obexftp/uuid.h Definitions of well-known Universal Unique Identifiers (UUIDs). ObexFTP library - language bindings for OBEX file transfer. Copyright (c) 2002-2007 Christian W. Zuckschwerdt */ #ifndef OBEXFTP_UUID_H #define OBEXFTP_UUID_H /** Folder Browsing service UUID. binary representation of F9EC7BC4-953C-11D2-984E-525400DC9E09 */ #define __UUID_FBS_bytes \ { 0xF9, 0xEC, 0x7B, 0xC4, \ 0x95, 0x3C, 0x11, 0xD2, 0x98, 0x4E, \ 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 } #define UUID_FBS ((const uint8_t []) __UUID_FBS_bytes) /** UUID for Siemens S45 and maybe others too. binary representation of 6B01CB31-4106-11D4-9A77-0050DA3F471F */ #define __UUID_S45_bytes \ { 0x6B, 0x01, 0xCB, 0x31, \ 0x41, 0x06, 0x11, 0xD4, 0x9A, 0x77, \ 0x00, 0x50, 0xDA, 0x3F, 0x47, 0x1F } #define UUID_S45 ((const uint8_t []) __UUID_S45_bytes) /** UUID for Telecom/IrMC Synchronization Service (see IrOBEX spec). The character string "IRMC-SYNC". */ #define __UUID_IRMC_bytes \ { 'I', 'R', 'M', 'C', '-', 'S', 'Y', 'N', 'C' } #define UUID_IRMC ((const uint8_t []) __UUID_IRMC_bytes) /** UUID for Sharp mobiles. The character string "PCSOFTWARE". */ #define __UUID_PCSOFTWARE_bytes \ { 'P', 'C', 'S', 'O', 'F', 'T', 'W', 'A', 'R', 'E' } #define UUID_PCSOFTWARE ((const uint8_t []) __UUID_PCSOFTWARE_bytes) #endif /* OBEXFTP_UUID_H */ obexftp-0.24-Source/obexftp.pc.in100777 0 0 371 12115454406 12046 0prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: ObexFTP Description: OBEX file transfer library Version: @VERSION@ Requires: @REQUIRES@ Libs: -L${libdir} -lobexftp -lmulticobex -lbfb Cflags: -I${includedir} obexftp-0.24-Source/README100777 0 0 6177 12115454406 10360 0ObexFTP Readme ============== Introduction ------------ ObexFTP implements the Object Exchange (OBEX) file transfer feature for clients and servers. The standard is defined in more detail in section K12.5 (Profiles: OBEX FTP) in Bluetooth V1.1 Profile Specifications. ObexFTP works out-of-the-box with all transports supported by OpenOBEX. Currently there is IrDA, Bluetooth, USB and network (TCP) transport support. ObexFTP also comes with ready to use custom transport support for many mobile phones serial cables. It's well tested with Siemens and Sony/Ericsson mobile phones. But then most Motorola and Sharp (generic) as well as Samsung phones will work too, please contact the author if not. This ObexFTP distribution contains libraries as well as some applications. Applications to access e.g. Flex. Memory and Multimedia- /Secure Digital Card memory on mobile equipment: - obexftp - all in one client application (heavy on options) - Symlinks to obexftp for default operations: - obexls - list the mobiles contents - obexget - copy files(s) to mobile - obexput - copy files(s) from mobile - obexrm - remove files on the mobile - obexftpd - obex ftp server application (experimental) Applications to hack Siemens mobile equipment using datalink cable - bfb_keysim - simulate key presses on the mobile - bfb_eeprom - list and examine the user eeprom on the mobile Library parts to be used in other applications - obexftp - high level abstraction of OBEX FTP (SYNC, PUSH also) protocol - multicobex - cable OBEX support for many phones (i.e. Siemens BFB and BFC Sony/Ericsson, Motorola and generic (Sharp) modes) - bfb - Siemens mobile datalink cable protocol layer Short Installation Instructions ------------------------------- To compile and install: # mkdir build # cd build # cmake .. # make # make install (as superuser) If you plan to use a Siemens x45 or x55 series (e.g. S45 or C55, not S65) use # export CFLAGS="$CFLAGS -DCOMPAT_S45" before calling cmake. Consider using pedantic error checking: # export CFLAGS="$CFLAGS -Werror" If compiling doesn't work, try to disable some of the language bindings: # cmake -DENABLE_PERL=NO -DENABLE_PYTHON=NO -DENABLE_RUBY=NO -DENABLE_TCL=NO Further Development ------------------- If this tool lacks support for your phone or just won't work quite right please let me know. Development will focus on your needs. This package lacks advanced examples using the bindings. There are some 3rd party GUIs and other projects like a obex file system though. Please see the OpenOBEX / ObexFTP web site for details. Developers are free to use the bindings as well as obexftp, multicobex and bfb libraries. Please join the mailing list and keep in touch - You'll recieve pre-releases and support. That way your application can benefit from the newest library features and further development can focus on your needs. Debugging --------- remove all ObexFTP installations from your system. Rebuild using: # export CFLAGS="$CFLAGS -DOBEXFTP_DEBUG=5" Start debugging using ./apps/obexftp [...] Author and Contact ------------------ See file AUTHORS. obexftp-0.24-Source/swig/ 40777 0 0 0 12115602310 10323 5obexftp-0.24-Source/swig/charmap.i100777 0 0 6054 12115454406 12230 0/* * swig/charmap.i: ObexFTP client library SWIG interface * * Copyright (c) 2006 Christian W. Zuckschwerdt * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program 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 General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* handle strings that maybe NULL */ #if defined SWIGPERL /* perl5.swg uses PL_sv_undef. */ #elif defined SWIGPYTHON /* python.swg uses "". Change to Py_None maybe? */ #elif defined SWIGRUBY %typemap(in) char * "$1 = ($input != Qnil) ? StringValuePtr($input) : NULL;"; %typemap(freearg) char * ""; /* Fix for >=swig-1.3.28 */ %typemap(out) char * "$result = $1 ? rb_str_new2($1) : Qnil;"; #elif defined SWIGTCL /* tcl8.swg is naive about this. Does it work? */ #else #warning "no char * in-typemap for this language" #endif /* handle non-sz strings */ %typemap(out) char * { #if defined SWIGPERL $result = newSVpvn(arg1->buf_data, arg1->buf_size); argvi++; #elif defined SWIGPYTHON $result = PyString_FromStringAndSize(arg1->buf_data, arg1->buf_size); #elif defined SWIGRUBY $result = arg1->buf_data ? rb_str_new(arg1->buf_data, arg1->buf_size) : Qnil; #elif defined SWIGTCL Tcl_SetObjResult(interp,Tcl_NewStringObj((char *)arg1->buf_data,arg1->buf_size)); #else #warning "no char * out-typemap for this language" #endif }; /* handle arrays of strings */ %typemap(out) char ** { #if defined SWIGPERL char **p; AV *myav = newAV(); for (p = $1; p && *p; p++) av_push(myav, newSVpv(*p, 0)); $result = newRV_noinc((SV*)myav); sv_2mortal($result); argvi++; #elif defined SWIGPYTHON char **p; $result = PyList_New(0); for (p = $1; p && *p; p++) PyList_Append($result, PyString_FromString(*p)); #elif defined SWIGRUBY char **p; $result = rb_ary_new(); for (p = $1; p && *p; p++) rb_ary_push($result, rb_str_new2(*p)); #elif defined SWIGTCL char **p; /* $result = Tcl_NewListObj(0, NULL); // not needed? */ for (p = $1; p && *p; p++) Tcl_ListObjAppendElement(interp, $result, Tcl_NewStringObj(*p, strlen(*p))); #else #warning "no char ** out-typemap for this language" #endif } %typemap(in) (char *data, size_t size) { /* Danger Wil Robinson */ #if defined SWIGPERL $1 = SvPV($input,$2); #elif defined SWIGPYTHON $1 = PyString_AsString($input); $2 = PyString_Size($input); #elif defined SWIGRUBY $1 = RSTRING_PTR($input); $2 = (int) RSTRING_LEN($input); #elif defined SWIGTCL $1 = Tcl_GetStringFromObj($input,(int*)&$2); #else #warning "no char *, size_t in-typemap for this language" #endif }; obexftp-0.24-Source/swig/client.i100777 0 0 11166 12115454406 12113 0/* * obexftp/client.i: ObexFTP client library SWIG interface * * Copyright (c) 2005 Christian W. Zuckschwerdt * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program 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 General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* perl croaks if this is lowercase. override for every other binding. */ %module OBEXFTP %{ #include #include %} %include "charmap.i" %constant int IRDA = OBEX_TRANS_IRDA; %constant int INET = OBEX_TRANS_INET; %constant int CABLE = OBEX_TRANS_CUSTOM; %constant int BLUETOOTH = OBEX_TRANS_BLUETOOTH; %constant int USB = OBEX_TRANS_USB; %constant int SYNC = OBEX_SYNC_SERVICE; %constant int PUSH = OBEX_PUSH_SERVICE; %constant int FTP = OBEX_FTP_SERVICE; %rename(discover) obexftp_discover; char **obexftp_discover(int transport); %rename(browsebt) obexftp_browse_bt; int obexftp_browse_bt(char *addr, int service); #if defined SWIGPERL #elif defined SWIGPYTHON %typemap(in) (obexftp_info_cb_t infocb, void *user_data) { if (!PyCallable_Check($input)) { /* should raise an exception here */ $1 = NULL; $2 = NULL; } else { Py_XINCREF($input); $1 = proxy_info_cb; $2 = $input; } }; %{ static void proxy_info_cb (int evt, const char *buf, int len, void *data) { PyObject *proc = (PyObject *)data; /* PyObject *msg = PyString_FromStringAndSize(buf, len); */ PyObject_CallFunction(proc, "is", evt, buf); } %} #elif defined SWIGRUBY %typemap(in) (obexftp_info_cb_t infocb, void *user_data) { $1 = proxy_info_cb; SWIG_ConvertPtr($input, &$2, NULL, 0); }; %{ static void proxy_info_cb (int event, const char *buf, int len, void *data) { VALUE proc = SWIG_NewPointerObj(data, NULL, 0); VALUE msg = buf ? rb_str_new(buf, len) : Qnil; rb_funcall(proc, rb_intern("call"), 2, INT2NUM(event), msg); } %} #elif defined SWIGTCL #else #warning "no callbacks for this language" #endif /* Which binding wants this capitalized too? */ %rename(client) obexftp_client_t; #ifdef SWIGRUBY %rename(Client) obexftp_client_t; #endif typedef struct { } obexftp_client_t; %extend obexftp_client_t { obexftp_client_t(int transport) { return obexftp_open(transport, NULL, NULL, NULL); } ~obexftp_client_t() { obexftp_close(self); } void callback(obexftp_info_cb_t infocb, void *user_data) { self->infocb = infocb; self->infocb_data = user_data; } char **discover() { return obexftp_discover(self->transport); } int connect(char *device, int port, char *src=NULL) { return obexftp_connect_src(self, src, device, port, UUID_FBS, sizeof(UUID_FBS)); } int connectpush(char *device, int port, char *src=NULL) { self->quirks &= ~OBEXFTP_SPLIT_SETPATH; return obexftp_connect_src(self, src, device, port, NULL, 0); } int connectsync(char *device, int port, char *src=NULL) { self->quirks &= ~OBEXFTP_SPLIT_SETPATH; return obexftp_connect_src(self, src, device, port, UUID_IRMC, sizeof(UUID_IRMC)); } int disconnect() { return obexftp_disconnect(self); } int chpath(char *name) { return obexftp_setpath(self, name, 0); } int mkpath(char *name) { return obexftp_setpath(self, name, 1); } int cdup() { return obexftp_setpath(self, NULL, 0); } int cdtop() { return obexftp_setpath(self, "", 0); } char *get(char *path) { (void) obexftp_get_type(self, NULL, NULL, path); return (char *)self->buf_data; } char *list(char *path=NULL) { (void) obexftp_get_type(self, XOBEX_LISTING, NULL, path); return (char *)self->buf_data; } char *get_capability(char *path=NULL) { (void) obexftp_get_type(self, XOBEX_CAPABILITY, NULL, path); return (char *)self->buf_data; } int get_file(char *path, char *localname) { return obexftp_get_type(self, NULL, localname, path); } int put_file(char *filename, char *remotename=NULL) { return obexftp_put_file(self, filename, remotename); } int put_data(char *data, size_t size, char *remotename=NULL) { return obexftp_put_data(self, data, size, remotename); } int delete(char *name) { return obexftp_del(self, name); } } obexftp-0.24-Source/swig/CMakeLists.txt100777 0 0 1430 12115454406 13174 0 find_package ( SWIG ) if ( SWIG_FOUND ) include ( ${SWIG_USE_FILE} ) include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) set ( obexftp_SWIG_SOURCES client.i ) option ( ENABLE_PERL "Build the obexftp PERL module (using swig)" ON ) if ( ENABLE_PERL) add_subdirectory ( perl ) endif ( ENABLE_PERL ) option ( ENABLE_PYTHON "Build the obexftp Python module (using swig)" ON ) if ( ENABLE_PYTHON) add_subdirectory ( python ) endif ( ENABLE_PYTHON ) option ( ENABLE_RUBY "Build the obexftp Ruby module (using swig)" ON ) if ( ENABLE_RUBY) add_subdirectory ( ruby ) endif ( ENABLE_RUBY ) option ( ENABLE_TCL "Build the obexftp Tcl module (using swig)" OFF ) if ( ENABLE_TCL) add_subdirectory ( tcl ) endif ( ENABLE_TCL ) endif ( SWIG_FOUND ) obexftp-0.24-Source/swig/perl/ 40777 0 0 0 12115602310 11265 5obexftp-0.24-Source/swig/perl/CMakeLists.txt100777 0 0 3437 12115454406 14147 0 find_package ( PerlLibs REQUIRED ) #foreach ( lib SITESEARCH SITELIB VENDORARCH VENDORLIB ARCHLIB PRIVLIB ) # message ( "PERL_${lib}: ${PERL_${lib}}" ) #endforeach ( lib ) add_definitions ( ${PERL_EXTRA_C_FLAGS} ) include_directories ( ${PERL_ARCHLIB}/CORE ) foreach ( src ${obexftp_SWIG_SOURCES} ) list ( APPEND obexftp-perl_SWIG_SOURCES ../${src} ) endforeach ( src ) set ( CMAKE_SWIG_FLAGS -module OBEXFTP ) set ( SWIG_PYTHON_EXTRA_FILE_EXTENSION "pm" ) set_source_files_properties ( ${obexftp-python_SWIG_SOURCES} PROPERTIES SWIG_MODULE_NAME OBEXFTP ) swig_add_module ( obexftp-perl perl ${obexftp-perl_SWIG_SOURCES} ) set_target_properties ( ${SWIG_MODULE_obexftp-perl_REAL_NAME} PROPERTIES OUTPUT_NAME OBEXFTP PREFIX "" ) swig_link_libraries ( obexftp-perl obexftp ) # # Get the install directory for ruby modules and strip the ruby install prefix # so that we can use our own prefix. # execute_process ( COMMAND ${PERL_EXECUTABLE} -V:installprefix OUTPUT_VARIABLE PERL_PREFIX ) string ( REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_PREFIX ${PERL_PREFIX} ) file ( TO_CMAKE_PATH "${PERL_PREFIX}" PERL_PREFIX ) execute_process ( COMMAND ${PERL_EXECUTABLE} -V:installvendorarch OUTPUT_VARIABLE PERL_FULL_VENDOR_ARCH_DIR ) string ( REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_FULL_VENDOR_ARCH_DIR ${PERL_FULL_VENDOR_ARCH_DIR} ) file ( TO_CMAKE_PATH "${PERL_FULL_VENDOR_ARCH_DIR}" PERL_FULL_VENDOR_ARCH_DIR ) string ( REGEX REPLACE "^${PERL_PREFIX}/" "" PERL_VENDOR_ARCH_DIR "${PERL_FULL_VENDOR_ARCH_DIR}" ) install ( TARGETS ${SWIG_MODULE_obexftp-perl_REAL_NAME} LIBRARY DESTINATION ${PERL_VENDOR_ARCH_DIR}/auto/OBEXFTP COMPONENT library ) install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/OBEXFTP.pm DESTINATION ${PERL_VENDOR_ARCH_DIR} COMPONENT library ) obexftp-0.24-Source/swig/perl/Makefile.PL.in100777 0 0 1524 12115454406 13761 0#!/usr/bin/perl -w use ExtUtils::MakeMaker ; WriteMakefile( 'ABSTRACT' => q[Perl interface to OBEX filesytem] , 'AUTHOR' => q[Christian W. Zuckschwerdt ] , # 'VERSION' => q[@VERSION@], # Avoid compilation problem for Fedora Core 1 'DEFINE' => q[-DSKIP_SEARCH_H @DEFS@], 'INC' => q[-I@top_srcdir@ @CPPFLAGS@], # Default value for LDDLFLAGS is $Config{lddlflags}="-shared -L/usr/local/lib" # but we want rpath to be @libdir@ or @exec_prefix@/lib 'LDDLFLAGS' => q[-shared -Wl,-rpath=@prefix@/lib], 'LIBS' => q[-L@top_builddir@/obexftp/.libs -lobexftp -L@top_builddir@/multicobex/.libs -lmulticobex -L@top_builddir@/bfb/.libs -lbfb @OPENOBEX_LIBS@], 'OBJECT' => 'perl_wrap.o', # $(OBJ_EXT) 'NAME' => 'OBEXFTP', 'FIRST_MAKEFILE' => 'Makefile.perl', ) ; obexftp-0.24-Source/swig/python/ 40777 0 0 0 12115602310 11644 5obexftp-0.24-Source/swig/python/CMakeLists.txt100777 0 0 3471 12115454406 14524 0 find_package ( PythonLibs REQUIRED ) find_package ( PythonInterp REQUIRED ) if ( PYTHON_VERSION_STRING AND PYTHONLIBS_VERSION_STRING ) if ( NOT PYTHON_VERSION_STRING VERSION_EQUAL PYTHONLIBS_VERSION_STRING ) message ( FATAL_ERROR "Version mismatch between python interpreter and libraries" ) endif ( NOT PYTHON_VERSION_STRING VERSION_EQUAL PYTHONLIBS_VERSION_STRING ) endif ( PYTHON_VERSION_STRING AND PYTHONLIBS_VERSION_STRING ) include_directories ( ${PYTHON_INCLUDE_DIRS} ) foreach ( src ${obexftp_SWIG_SOURCES} ) list ( APPEND obexftp-python_SWIG_SOURCES ../${src} ) endforeach ( src ) set ( CMAKE_SWIG_FLAGS -module obexftp ) set_source_files_properties ( ${obexftp-python_SWIG_SOURCES} PROPERTIES SWIG_MODULE_NAME obexftp ) swig_add_module ( obexftp-python python ${obexftp-python_SWIG_SOURCES} ) set_target_properties ( ${SWIG_MODULE_obexftp-python_REAL_NAME} PROPERTIES OUTPUT_NAME _obexftp ) swig_link_libraries ( obexftp-python obexftp ) # # Get the install directory for ruby modules and strip the ruby install prefix # so that we can use our own prefix. # execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "import site, sys; sys.stdout.write(site.PREFIXES[-1])" OUTPUT_VARIABLE PYTHON_PREFIX ) file ( TO_CMAKE_PATH "${PYTHON_PREFIX}" PYTHON_PREFIX ) execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "import site, sys; sys.stdout.write(site.getsitepackages()[-1])" OUTPUT_VARIABLE PYTHON_SITE_DIR ) file ( TO_CMAKE_PATH "${PYTHON_SITE_DIR}" PYTHON_SITE_DIR ) string ( REGEX REPLACE "^${PYTHON_PREFIX}/" "" PYTHON_SITE_DIR "${PYTHON_SITE_DIR}" ) install ( TARGETS ${SWIG_MODULE_obexftp-python_REAL_NAME} LIBRARY DESTINATION ${PYTHON_SITE_DIR} COMPONENT library ) install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/obexftp.py DESTINATION ${PYTHON_SITE_DIR} COMPONENT library ) obexftp-0.24-Source/swig/python/setup.py.in100777 0 0 1626 12115454406 14103 0from distutils.core import setup, Extension import string setup(name = 'obexftp', version = '@VERSION@', author = 'Christian Zuckschwerdt', author_email = 'zany@triq.net', url = 'http://www.openobex.org/', description = 'ObexFTP python bindings', download_url = 'http://triq.net/obexftp/', package_dir = {'obexftp': '@srcdir@'}, packages = [ 'obexftp' ], ext_package = 'obexftp', ext_modules = [Extension('_obexftp', ['python_wrap.c'], include_dirs=['@top_srcdir@'], extra_link_args = string.split('-L@top_builddir@/obexftp/.libs -lobexftp -L@top_builddir@/multicobex/.libs -lmulticobex -L@top_builddir@/bfb/.libs -lbfb @OPENOBEX_LIBS@'), # static: extra_link_args = string.split('@top_builddir@/obexftp/.libs/libobexftp.a @top_builddir@/multicobex/.libs/libmulticobex.a @top_builddir@/bfb/.libs/libbfb.a @OPENOBEX_LIBS@'), )], ) obexftp-0.24-Source/swig/ruby/ 40777 0 0 0 12115602310 11304 5obexftp-0.24-Source/swig/ruby/CMakeLists.txt100777 0 0 2546 12115454406 14166 0 find_package ( Ruby REQUIRED ) include_directories ( ${RUBY_INCLUDE_DIRS} ) foreach ( src ${obexftp_SWIG_SOURCES} ) list ( APPEND obexftp-ruby_SWIG_SOURCES ../${src} ) endforeach ( src ) set ( CMAKE_SWIG_FLAGS -module obexftp ) set_source_files_properties ( ${obexftp-ruby_SWIG_SOURCES} PROPERTIES SWIG_MODULE_NAME obexftp ) swig_add_module ( obexftp-ruby ruby ${obexftp-ruby_SWIG_SOURCES} ) set_target_properties ( ${SWIG_MODULE_obexftp-ruby_REAL_NAME} PROPERTIES OUTPUT_NAME obexftp PREFIX "" ) swig_link_libraries ( obexftp-ruby obexftp ) # # Get the install directory for ruby modules and strip the ruby install prefix # so that we can use our own prefix. # execute_process ( COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['prefix']" OUTPUT_VARIABLE RUBY_PREFIX ) file ( TO_CMAKE_PATH "${RUBY_PREFIX}" RUBY_PREFIX ) execute_process ( COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['vendorarchdir']" OUTPUT_VARIABLE RUBY_FULL_VENDOR_ARCH_DIR ) file ( TO_CMAKE_PATH "${RUBY_FULL_VENDOR_ARCH_DIR}" RUBY_FULL_VENDOR_ARCH_DIR ) string ( REGEX REPLACE "^${RUBY_PREFIX}/" "" RUBY_VENDOR_ARCH_DIR "${RUBY_FULL_VENDOR_ARCH_DIR}" ) install ( TARGETS ${SWIG_MODULE_obexftp-ruby_REAL_NAME} LIBRARY DESTINATION ${RUBY_VENDOR_ARCH_DIR} COMPONENT library ) obexftp-0.24-Source/swig/ruby/extconf.rb100777 0 0 2020 12115454406 13404 0#!/usr/bin/env ruby require 'mkmf' # hack 1: ruby black magic to write a Makefile.new instead of a Makefile alias open_orig open def open(path, mode=nil, perm=nil) path = 'Makefile.new' if path == 'Makefile' if block_given? open_orig(path, mode, perm) { |io| yield(io) } else open_orig(path, mode, perm) end end if ENV['PREFIX'] prefix = CONFIG['prefix'] %w[ prefix sitedir datadir infodir mandir oldincludedir ].each do |key| CONFIG[key] = CONFIG[key].sub(/#{prefix}/, ENV['PREFIX']) end end dir_config('obexftp') if have_library('openobex', 'OBEX_Init') and find_library('bfb', 'bfb_io_open', '../../bfb/.libs') and find_library('multicobex', 'cobex_ctrans', '../../multicobex/.libs') and find_library('obexftp', 'obexftp_open', '../../obexftp/.libs') create_makefile('obexftp') # hack 2: strip all rpath references open('Makefile.ruby', 'w') do |out| IO.foreach('Makefile.new') do |line| out.puts line.gsub(/-Wl,-R'[^']*'/, '') end end else puts 'obex libs not found' end obexftp-0.24-Source/swig/tcl/ 40777 0 0 0 12115602310 11105 5obexftp-0.24-Source/swig/tcl/CMakeLists.txt100777 0 0 1356 12115454406 13765 0 find_package ( TCL ) if ( TCL_FOUND ) include_directories ( ${TCL_INCLUDE_PATH} ) foreach ( src ${obexftp_SWIG_SOURCES} ) list ( APPEND obexftp-tcl_SWIG_SOURCES ../${src} ) endforeach ( src ) set ( CMAKE_SWIG_FLAGS -module obexftp ) set_source_files_properties ( ${obexftp-tcl_SWIG_SOURCES} PROPERTIES SWIG_MODULE_NAME obexftp ) swig_add_module ( obexftp-tcl tcl ${obexftp-tcl_SWIG_SOURCES} ) set_target_properties ( ${SWIG_MODULE_obexftp-tcl_REAL_NAME} PROPERTIES OUTPUT_NAME obexftp PREFIX "" ) swig_link_libraries ( obexftp-tcl obexftp ) install ( TARGETS ${SWIG_MODULE_obexftp-tcl_REAL_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ) endif ( TCL_FOUND ) obexftp-0.24-Source/THANKS100777 0 0 2451 12115454406 10402 0stef - helped in initial S45 (BFB) research Erich Schubert - provided a debian package Eduard Bloch - Debian maintainer since 2003. Jan Metz - supplied RH8 box and SL45i, ObexFTP info page Carsten Pfeiffer - coded a kio slave Jorge Ventura - write/select patch François Fleuret - suggested transport checks Adam Goode and Ken Booth - setpath Soren S. Jorvang - NetBSD portability fixes Bruce Simpson - FreeBSD portability fixes David Haslam - Sony-Ericsson fixes Philip Kovacs - connection id support Alan Zhang - daemon application Frode Isaksen - obexftpd improvements Simon Ruggier - cobex write patch Sergey Vlasov sugg. LDADD to LIBADD Alan J. McFarlane - rep. invalid conn_id in disconnect Dr. Johannes Zellner - spotted month/day swapping in atotime Martin Storsjö - PCSUITE over FTP sugg. for Series 60 2nd Ed. Manuel Naranjo - hci selection draft Andrey Rahmatullin - Motorola SLVR L2 cobex fix Adam Williamson - Python distutils testing obexftp-0.24-Source/TODO100777 0 0 542 12115454406 10136 0ObexFTP to do list ================== * verify memory alloc's with bindings * cancel (async?) support for bindings * obexftp.is_connected() perhaps? * get perl and ruby to uninstall for distcheck (only python and tcl distcheck clean) * put to specified file (-p file.vcf -f telecom/pb.vcf) * Discover port and protocol to use (i.e. Bt, IrDA, TTY)