Logo Search packages:      
Sourcecode: affix version File versions  Download package

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 6
void 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;
}



Generated by  Doxygen 1.6.0   Back to index