📄 btctl-obex.c
字号:
/* Affix - Bluetooth Protocol Stack for Linux Copyright (C) 2001 Nokia Corporation Original Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com> 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.*//* $Id: btctl-obex.c,v 1.51 2003/04/15 10:47:06 kds Exp $ btctl - driver control program Fixes: Dmitry Kasatkin <dmitry.kasatkin@nokia.com> Imre Deak <ext-imre.deak@nokia.com>*/#include <affix/config.h>#include <stdint.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/stat.h>#include <arpa/inet.h>#include <netdb.h>#include <netinet/in.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#include <openobex/obex.h>#include <affix/bluetooth.h>#include <affix/btcore.h>#include <affix/obex.h>#include "btctl.h"union { struct sockaddr_affix bt; struct sockaddr_in in;} saddr;static obexclt_t *handle = NULL;static obex_target_t *target = NULL;static obex_target_t browse = {16, "\xF9\xEC\x7B\xC4\x95\x3C\x11\xD2\x98\x4E\x52\x54\x00\xDC\x9E\x09"};static int do_push = 0;int print_speed(char *format, char *name, struct timeval *tv_start){ struct timeval tv_end; long int sec, rsec; long int usec, rusec; long int size; double speed; size = get_filesize(name); gettimeofday(&tv_end, NULL); sec = tv_end.tv_sec - tv_start->tv_sec; usec = (1000000 * sec) + tv_end.tv_usec - tv_start->tv_usec; rsec = usec/1000000; rusec = (usec - (rsec * 1000000))/10000; speed = (double)(size)/((double)(rsec) + (double)(rusec)/100); printf(format, size, rsec, rusec, speed); return 0;}static void set_perm(char *perm, char *str){ int c; //printf("In set_perm\n"); for (;*str; str++) { c = tolower(*str); //printf("char: %c\n", c); switch (c) { case 'r': perm[1] = 'r'; break; case 'w': perm[2] = 'w'; break; case 'd': perm[3] = 'd'; case 'x': perm [4] = 'x'; break; } }}#define PERM_SIZE 6void print_folder(const char *buf){ char *next = (char*)buf, *elem, *attrs, *attr, *value; char *size = NULL, *name = NULL; int count = 0; char str[80], perm[PERM_SIZE]; //printf("buf: %s\n", buf); return; while ((elem = xml_element(&next, &attrs))) { if (strcmp(elem, "folder-listing") == 0) break; } while ((elem = xml_element(&next, &attrs))) { if (strcmp(elem, "/folder-listing") == 0) break; size = NULL, name = NULL; count = 0; //printf("element: %s\n", elem); //printf("attr left: %s\n", attrs); memset(perm, '-', PERM_SIZE); perm[PERM_SIZE-1] = '\0'; if (strcmp(elem, "folder") == 0) perm[0] = 'd'; else if (strcmp(elem, "file") == 0) ; else if (strcmp(elem, "parent-folder") == 0) { perm[0] = 'd'; name = ".."; } else { } // get attributes while ((attr = xml_attribute(&attrs, &value))) { //printf("attr: %s, value: %s\n", attr, value); if (strcmp(attr, "user-perm") == 0) set_perm(perm, value); else if ( name == NULL && strcmp(attr, "name") == 0 ) name = value; else if ( size == NULL && strcmp(attr, "size") == 0 ) size = value; } count += sprintf(str+count, "%s\t\t%s\t\t%s", perm, size?size:"0", name?name:"<no name>"); printf("%s\n", str); }}int obex_setaddress(void){ int err; if (do_push) target = NULL; else target = &browse; if (linkmode == PF_AFFIX) { struct sockaddr_affix *sa = &saddr.bt; int sch; if (!argv[argind]) return -1; sa->family = PF_AFFIX; sa->devnum = HCIDEV_ANY; err = get_bda(&sa->bda, argv[argind++]); if (err) { return -1; } if (sdpmode) { #if defined(CONFIG_AFFIX_SDP) slist_t *searchList = NULL; slist_t *attrList = NULL; slist_t *svcList = NULL; uint16_t count; sdpsvc_t *svcRec; uint32_t svc_id = 0; if (do_push) svc_id = SDP_UUID_OBEX_PUSH; else svc_id = SDP_UUID_OBEX_FTP; sa->port = 0; // SDP /* search for service ServiceID */ s_list_append_uuid16(&searchList, svc_id); /* set attributes to find */ s_list_append_uint(&attrList, SDP_ATTR_SERVICE_RECORD_HANDLE); s_list_append_uint(&attrList, SDP_ATTR_PROTO_DESC_LIST); err = __sdp_search_attr_req(sa, searchList, IndividualAttributes, attrList, 0xffff, &svcList, &count); s_list_free(&attrList); s_list_destroy(&searchList); if (err) { fprintf(stderr, "%s\n", sdp_error(err)); return -1; } if (count == 0) { printf("no services found\n"); return -1; } svcRec = s_list_dequeue(&svcList); // get first sdp_free_svclist(&svcList); sch = sdp_get_rfcomm_port(svcRec); sdp_free_svc(svcRec); if (sch > 0) DBPRT("Service found on channel %d\n", sch); else if (sch == 0) { DBPRT("Service is not available\n"); return -1; } else { DBPRT("Unable to get service channel: %d\n", sch); return -1; } sa->port = sch;#endif } else { if (!argv[argind]) return -1; sa->port = atoi(argv[argind++]); } } else if (linkmode == PF_INET) { if (argv[argind] == NULL) { return -1; err = inet_aton("127.0.0.1", &saddr.in.sin_addr); } else { err = inet_aton(argv[argind], &saddr.in.sin_addr); if (err == 0) { struct hostent *he; he = gethostbyname(argv[argind]); if (he == NULL) return -1; saddr.in.sin_addr.s_addr = *(uint32_t*)he->h_addr; } argind++; } saddr.in.sin_family = PF_INET; } else { } return 0;}int _cmd_open(struct btctl_command *cmd){ int err; err = obex_setaddress(); if (err) { printf("Address error\n"); return -1; } handle = obex_connect((struct sockaddr_affix*)&saddr, target, &err); if (handle == NULL) { fprintf(stderr, "Unable to connect: %s\n", obex_error(err)); return err; } printf("Connected.\n"); return 0;}int _cmd_close(struct btctl_command *cmd){ if (handle) { obex_disconnect(handle); handle = NULL; } return 0;}int _cmd_ls(struct btctl_command *cmd){ int err; char *buf; obex_file_t *file; if (!handle) { printf("Not connected.\n"); return -1; } file = obex_create_file(NULL); if (!file) return -1; err = obex_browse(handle, file->name, argv[argind]); if (err) { fprintf(stderr, "Browsing error: %s\n", obex_error(err)); } else { //printf("%s\n", buf); buf = obex_map_file(file); if (!buf) { fprintf(stderr, "%s\n", obex_error(-1)); obex_destroy_file(file, 1); return -1; } print_folder(buf); printf("Command complete.\n"); } obex_destroy_file(file, 1); return 0;}int _cmd_get(struct btctl_command *cmd){ int err; char *remote, *local; struct timeval tv_start; gettimeofday(&tv_start, NULL); if (!handle) { printf("Not connected.\n"); return -1; } if (argv[argind] == NULL) { printf("No file name.\n"); return -1; } remote = argv[argind++]; local = argv[argind++]; /* may be NULL */ printf("Transfer started...\n"); err = obex_get_file(handle, local, remote); if (err) { fprintf(stderr, "File transfer error: %s\n", obex_error(err)); } else { printf("Transfer complete.\n"); print_speed("%ld bytes received in %ld.%ld secs (%.2f B/s)\n", local, &tv_start); } return 0;}int _cmd_put(struct btctl_command *cmd){ int err; char *local, *remote; struct timeval tv_start; gettimeofday(&tv_start, NULL); if (!handle) { printf("Not connected.\n"); return -1; } if (argv[argind] == NULL) { printf("No file name.\n"); return -1; } local = argv[argind++]; remote = argv[argind++]; /* may be NULL */ printf("Transfer started...\n"); err = obex_put_file(handle, local, remote); if (err) { fprintf(stderr, "File transfer error: %s\n", obex_error(err)); } else { printf("Transfer complete.\n"); print_speed("%ld bytes sent in %ld.%ld secs (%.2f B/s)\n", local, &tv_start); } return 0;}int _cmd_push(struct btctl_command *cmd){ int err; char *local, *remote; struct timeval tv_start; gettimeofday(&tv_start, NULL); if (!handle) { printf("Not connected.\n"); return -1; } if (argv[argind] == NULL) { printf("No file name.\n"); return -1; } local = argv[argind++]; remote = argv[argind++]; printf("Transfer started...\n"); err = obex_put_file(handle, local, remote); if (err) { fprintf(stderr, "Object pushing error: %s\n", obex_error(err)); } else { printf("Transfer complete.\n"); print_speed("%ld bytes sent in %ld.%ld secs (%.2f B/s)\n", local, &tv_start); } return 0;}int _cmd_rm(struct btctl_command *cmd){ int err; char *name; if (!handle) { printf("Not connected.\n"); return -1; } if (argv[argind] == NULL) { printf("No file name.\n"); return -1; } name = argv[argind]; err = obex_remove(handle, name); if (err) { fprintf(stderr, "File removal error: %s\n", obex_error(err)); } else printf("Command complete.\n"); return 0;}int _cmd_cd(struct btctl_command *cmd){ int err; char *name; if (!handle) { printf("Not connected.\n"); return -1; } name = argv[argind]; err = obex_setpath(handle, name); if (err) { fprintf(stderr, "cd error: %s\n", obex_error(err)); } else printf("Command complete.\n"); return 0;}int _cmd_mkdir(struct btctl_command *cmd){ int err; char *name; if (!handle) { printf("Not connected.\n"); return 0; } name = argv[argind]; err = obex_mkdir(handle, name); if (err) { fprintf(stderr, "mkdir error: %s\n", obex_error(err)); } else printf("Command complete.\n"); return 0;}// primary commands//int cmd_open(struct btctl_command *cmd){ int err; if (!ftpmode) { printf("Command available only in FTP mode.\n"); return -1; } err = _cmd_open(cmd); return err;}int cmd_close(struct btctl_command *cmd){ int err; if (!ftpmode) { printf("Command available only in FTP mode.\n"); return -1; } err = _cmd_close(cmd); return err;} int cmd_ls(struct btctl_command *cmd){ int err; if (!ftpmode) { err = obex_setaddress(); if (err) { printf("Address error\n"); return 1; } handle = obex_connect((struct sockaddr_affix*)&saddr, target, &err); if (handle == NULL) { fprintf(stderr, "Connection failed: %s\n", obex_error(err)); return err; } } err = _cmd_ls(cmd); if (!ftpmode) { obex_disconnect(handle); } return err;}int cmd_put(struct btctl_command *cmd){ int err; if (!ftpmode) { err = obex_setaddress(); if (err) { printf("Address error\n"); return 1; } if (argv[argind] == NULL) { printf("No file name.\n"); return 1; } handle = obex_connect((struct sockaddr_affix*)&saddr, target, &err); if (handle == NULL) { fprintf(stderr, "Connection failed: %s\n", obex_error(err)); return err; } } err = _cmd_put(cmd); if (!ftpmode) { obex_disconnect(handle); } return err;}int cmd_get(struct btctl_command *cmd){ int err; if (!ftpmode) { err = obex_setaddress(); if (err) { printf("Address error\n"); return 1; } if (argv[argind] == NULL) { printf("No file name\n"); return 1; } handle = obex_connect((struct sockaddr_affix*)&saddr, target, &err); if (handle == NULL) { fprintf(stderr, "Connection failed: %s\n", obex_error(err)); return err; } } err = _cmd_get(cmd); if (!ftpmode) { obex_disconnect(handle); } return err;}int cmd_push(struct btctl_command *cmd){ int err; if (!ftpmode) { do_push = 1; err = obex_setaddress(); if (err) { printf("Address error\n"); return -1; } do_push = 0; if (argv[argind] == NULL) { printf("No file name\n"); return 1; } handle = obex_connect((struct sockaddr_affix*)&saddr, target, &err); if (handle == NULL) { fprintf(stderr, "Connection failed: %s\n", obex_error(err)); return err; } } err = _cmd_push(cmd); if (!ftpmode) { obex_disconnect(handle); } return err;}int cmd_rm(struct btctl_command *cmd){ int err; if (!ftpmode) { err = obex_setaddress(); if (err) { printf("Address error\n"); return 1; } if (argv[argind] == NULL) { printf("No file name\n"); return 1; } handle = obex_connect((struct sockaddr_affix*)&saddr, target, &err); if (handle == NULL) { fprintf(stderr, "Connection failed: %s\n", obex_error(err)); return err; } } err = _cmd_rm(cmd); if (!ftpmode) { obex_disconnect(handle); } return err;}int cmd_cd(struct btctl_command *cmd){ int err; if (!ftpmode) { printf("Command available only in FTP mode.\n"); return -1; } err = _cmd_cd(cmd); return err;}int cmd_mkdir(struct btctl_command *cmd){ int err; if (!ftpmode) { printf("Command available only in FTP mode.\n"); return -1; } err = _cmd_mkdir(cmd); return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -