Openobex code sample that search for devices

Help
angel i
2008-07-29
2013-05-01
  • angel i
    angel i
    2008-07-29

    Hello,
    I am writing an application wich search for available bluetooth devices with range and try to send them a file (a wallpaper).
    I need to finish the app. pretty quick as my boss pushes me to do it in few days.
    I am trying to make it multithreading (spawning a thread for each discovered device, thread that connects to the device and sends it the file) but my C knowledge is not very advanced at this moment so I would like to know your oppinions in trying to make it better.

    Here's the sample code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <pthread.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/hci.h>
    #include <bluetooth/hci_lib.h>
    #include <obexftp/client.h> /*!!!*/

    #define NTHREADS 10    //max number of threads used in multithreading

    void *send_file(void *address); //prototype for the file sending function used in the new thread

    //searching for devices code is taken from some bluez examples
    int main(int argc, char **argv)
    {
        inquiry_info *ii = NULL;
        int max_rsp, num_rsp;
        int dev_id, sock, len, flags;
        int i,j;
        char addr[19] = { 0 };
        char name[248] = { 0 };
        pthread_t thread_id[NTHREADS];

        dev_id = hci_get_route(NULL);
        sock = hci_open_dev( dev_id );
        if (dev_id < 0 || sock < 0) {
            perror("opening socket");
            exit(1);
        }

        len  = 8;
        max_rsp = 255;
        flags = IREQ_CACHE_FLUSH;
        ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));

        num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
        if( num_rsp < 0 ) perror("hci_inquiry");

        printf ("%i devices discovered!\n",num_rsp);
        for (i = 0; i < num_rsp; i++) {
            ba2str(&(ii+i)->bdaddr, addr);
            memset(name, 0, sizeof(name));
            if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name),
                name, 0) < 0)
            strcpy(name, "[unknown]");

            //start multithreading
            /* Create independent threads each of which will execute function */
            printf ("Starting thread %i...\n",i);
            pthread_create( &thread_id[i], NULL, send_file, (void*) addr);
            pthread_join( thread_id[j], NULL);   //wait for the thread to finish its execution; not sure if this is good here

        }

        //free the resources
        free( ii );
        close( sock );
        return 0;
    }

    //file sending function, used in new threads
    void *send_file(void *ptr)
    {
            char *address = NULL;
            int channel = -1;
            char *filepath = "tux.jpg";
            char *filename;
            obexftp_client_t *cli = NULL; /*!!!*/
            int ret;

            printf("Thread number %ld\n", pthread_self());
            //pthread_exit(0);

            address = (char *)ptr;
            channel = obexftp_browse_bt_push(address); /*!!!*/

            /* Extract basename from file path */
            filename = strrchr(filepath, '/');
            if (!filename)
                    filename = filepath;
            else
                    filename++;

            printf("Sending file %s to %s\n", filename, address);

            /* Open connection */
            cli = obexftp_open(OBEX_TRANS_BLUETOOTH, NULL, NULL, NULL); /*!!!*/
            if (cli == NULL) {
                    fprintf(stderr, "Error opening obexftp client\n");
                    pthread_exit(NULL);
            }

            /* Connect to device */
            ret = obexftp_connect_push(cli, address, channel); /*!!!*/
            if (ret < 0) {
                    fprintf(stderr, "Error connecting to obexftp device\n");
                    obexftp_close(cli);
                    cli = NULL;
                    pthread_exit(NULL);
            }

            /* 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;

            pthread_exit(0);
    }

    =====================================================================================================

    compile with :

    gcc -Wall -L/usr/local/lib -lobexftp -lbluetooth -lpthread -o simplescan simplescan.c

    This seems to work fine with most devices, tho some of them are asked for a password in order to connect to the sender.
    Also, this does not look multithreading to me as the connections and sending the file to the receiver is done like in a procedural way, the "send_file" function does not execute as long as previous thread (another "send_file" function) is not over yet, but I ran this on a Linksys NSLU device wich has an ARM processwor of 266Mhz and only 32Mb of RAM so I think I can't get much "multithreading" with it.
    I am waiting for your comments in a way that I can improve this.
    Thanks a lot!

     
    • The forum isn't closely monitored. You can reach developers on the mailing list. Some quick hints (you can read more at ESRs How To Ask Questions The Smart Way: http://www.catb.org/~esr/faqs/smart-questions.html ) Your boss and timeframe isn't anybodys concern but yours. People would like to address you with your name, put it on your postings please.

      That said, your project looks very interesting. Are you planing to make this a free project, maybe a How To or Use Case example?

       
      • angel i
        angel i
        2008-07-29

        Thanks for the tips; would you mind providing me the developers mailing list? I tought this was it :P
        I will try to make this a "how to" even tho I don't know if I am the right person (having enough knowlendge) to give a good and correct example with this.
        Thanks for the help.

        Cristian

         
        • Sorry for the confusion, the "developer mailing list" is called "openobex-users" here. You can find the archives at the "Mailing Lists" tab above. The summary has additional information.

           
    • Rizwan Basha
      Rizwan Basha
      2008-11-24

      Hai

      #include <stdio.h>
      #include <stdlib.h>
      #include <unistd.h>
      #include <sys/socket.h>
      #include <pthread.h>
      #include <bluetooth/bluetooth.h>
      #include <bluetooth/hci.h>
      #include <bluetooth/hci_lib.h>
      #include <obexftp/client.h> /*!!!*/

      #define NTHREADS 10 //max number of threads used in multithreading

      void *send_file(void *address); //prototype for the file sending function used in the new thread

      //searching for devices code is taken from some bluez examples
      int main(int argc, char **argv)
      {
      inquiry_info *ii = NULL;
      int max_rsp, num_rsp;
      int dev_id, sock, len, flags;
      int i,j;
      char addr[19] = { 0 };
      char name[248] = { 0 };
      pthread_t thread_id[NTHREADS];

      dev_id = hci_get_route(NULL);
      sock = hci_open_dev( dev_id );
      if (dev_id < 0 || sock < 0) {
      perror("opening socket");
      exit(1);
      }

      len = 8;
      max_rsp = 255;
      flags = IREQ_CACHE_FLUSH;
      ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));

      num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
      if( num_rsp < 0 ) perror("hci_inquiry");

      printf ("%i devices discovered!\n",num_rsp);
      for (i = 0; i < num_rsp; i++) {
      ba2str(&(ii+i)->bdaddr, addr);
      memset(name, 0, sizeof(name));
      if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name),
      name, 0) < 0)
      strcpy(name, "[unknown]");

      //start multithreading
      /* Create independent threads each of which will execute function */
      printf ("Starting thread %i...\n",i);
      pthread_create( &thread_id[i], NULL, send_file, (void*) addr);
      pthread_join( thread_id[j], NULL); //wait for the thread to finish its execution; not sure if this is good here

      }

      //free the resources
      free( ii );
      close( sock );
      return 0;
      }

      //file sending function, used in new threads
      void *send_file(void *ptr)
      {
      char *address = NULL;
      int channel = -1;
      char *filepath = "tux.jpg";
      char *filename;
      obexftp_client_t *cli = NULL; /*!!!*/
      int ret;

      printf("Thread number %ld\n", pthread_self());
      //pthread_exit(0);

      address = (char *)ptr;
      channel = obexftp_browse_bt_push(address); /*!!!*/

      /* Extract basename from file path */
      filename = strrchr(filepath, '/');
      if (!filename)
      filename = filepath;
      else
      filename++;

      printf("Sending file %s to %s\n", filename, address);

      /* Open connection */
      cli = obexftp_open(OBEX_TRANS_BLUETOOTH, NULL, NULL, NULL); /*!!!*/
      if (cli == NULL) {
      fprintf(stderr, "Error opening obexftp client\n");
      pthread_exit(NULL);
      }

      /* Connect to device */
      ret = obexftp_connect_push(cli, address, channel); /*!!!*/
      if (ret < 0) {
      fprintf(stderr, "Error connecting to obexftp device\n");
      obexftp_close(cli);
      cli = NULL;
      pthread_exit(NULL);
      }

      /* 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;

      pthread_exit(0);
      }

      =====================================================================================================

      compile with :

      gcc -Wall -L/usr/local/lib -lobexftp -lbluetooth -lpthread -o simplescan simplescan.c

      Whenever I compile this
      Iam getting these errors yar.Please Help me

      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_TransportConnect'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_ObjectNew'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_InterfaceConnect'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_Cleanup'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_CharToUnicode'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_Init'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_ObjectSetNonHdrData'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_FindInterfaces'
      /usr/local/lib/libobexftp.so: undefined reference to `BtOBEX_TransportConnect'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_ObjectAddHeader'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_ObjectGetNextHeader'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_HandleInput'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_ObjectDelete'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_GetUserData'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_RegisterCTransport'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_SetUserData'
      /usr/local/lib/libobexftp.so: undefined reference to `IrOBEX_TransportConnect'
      /usr/local/lib/libobexftp.so: undefined reference to `cobex_ctrans'
      /usr/local/lib/libobexftp.so: undefined reference to `OBEX_Request'
      collect2: ld returned 1 exit status

      How to avoid this yar..plz help me ,.I hav openobex & obexftp installed previously.

       
      • Compile and link using pkg-config
        gcc -Wall $(pkg-config --cflags obexftp) $(pkg-config --libs obexftp) -lpthread -o simplescan simplescan.c 

        Also do not use threads. Your HCI is a global resource. Multiple threads won't be able to access it concurrently.

        Use non-blocking I/O and an event loop. You might get up to 4 transfers on a single HCI. I posted example earlier (here or on the list).

         
        • >Use non-blocking I/O and an event loop. You might get up to 4 transfers on a single HCI. I posted example earlier (here or on the list).

          Please  re-post  your Example Christian

          Thx.

           
    • Rizwan Basha
      Rizwan Basha
      2008-11-25

      Although I installed Obexftp previously.still same pkg config error reappears yar.  compiling as :

      gcc -Wall ftpserver.c  $(pkg-config --cflags obexftp) $(pkg-config --libs obexftp) -lpthread -o simplescan simplescan.c

      Package obexftp was not found in the pkg-config search path.
      Perhaps you should add the directory containing `obexftp.pc'
      to the PKG_CONFIG_PATH environment variable
      No package 'obexftp' found
      Package obexftp was not found in the pkg-config search path.
      Perhaps you should add the directory containing `obexftp.pc'
      to the PKG_CONFIG_PATH environment variable
      No package 'obexftp' found
      gcc: simplescan.c: No such file or directory
      ftpsrvr.c: In function ‘send_file’:
      ftpsrvr.c:77: warning: implicit declaration of function ‘obexftp_browse_bt_push’
      ftpsrvr.c:97: warning: implicit declaration of function ‘obexftp_connect_push’
      ftpsrvr.c:(.text+0x29c): undefined reference to `obexftp_browse_bt_push'
      ftpsrvr.c:(.text+0x305): undefined reference to `obexftp_open'
      ftpsrvr.c:(.text+0x358): undefined reference to `obexftp_connect_push'
      ftpsrvr.c:(.text+0x391): undefined reference to `obexftp_close'
      ftpsrvr.c:(.text+0x3bd): undefined reference to `obexftp_put_file'
      ftpsrvr.c:(.text+0x3f6): undefined reference to `obexftp_disconnect'
      ftpsrvr.c:(.text+0x42f): undefined reference to `obexftp_close'

      Perhaps there is no obexftp.pc in obexftp package to add to the path.How can i avoid these errors yar.Iam eager to see the file transfer .
      Furrther I added these to pkg config path to avoid

      export OBEXFTP=" -L/usr/lib -lobexftp"
      export OPENOBEX_CFLAGS="-I/usr/include/openobex/ -I/usr/include"
      But the errors are repeating the same yar.Plz help me to avoid these errors.

      Thanks for Previous reply..christian

       
      • Make sure obexftp is up to date, 0.22 is current. If you install to /usr/local add /usr/local/lib/pkgconfig to PKG_CONFIG_PATH.

        If you need manual path tweaks use CFLAGS and LDFLAGS or the automake options,  not your above mentioned ones.

        I'm curious, what does "yar" mean?

         
    • Rizwan Basha
      Rizwan Basha
      2008-11-26

      as u said i hav tried to install obexftp-0.22 .when i make I got these errors :

      obexftpd.c:81: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
      obexftpd.c: In function ‘start_server’:
      obexftpd.c:891: warning: implicit declaration of function ‘BtOBEX_ServerRegister’
      obexftpd.c:891: error: ‘bt_src’ undeclared (first use in this function)
      obexftpd.c:891: error: (Each undeclared identifier is reported only once
      obexftpd.c:891: error: for each function it appears in.)
      make[2]: *** [obexftpd.o] Error 1
      make[2]: Leaving directory `/root/Desktop/obexftp-0.22/apps'
      make[1]: *** [all-recursive] Error 1
      make[1]: Leaving directory `/root/Desktop/obexftp-0.22'
      make: *** [all] Error 2

      I ignored them and tried make install. same errors repeat again.Will there be any problem any with these errors.

      Thanks again. 'yar'  means friend in hindi. 

       
    • Rizwan Basha
      Rizwan Basha
      2008-11-26

      This time I got  another error after obexftp-0.22 installation
      on compiling:
      gcc -Wall ftpsrvr.c $(pkg-config --cflags obexftp) $(pkg-config --libs obexftp) -lpthread -o simplscan simplscan.c

      Package libusb was not found in the pkg-config search path.
      Perhaps you should add the directory containing `libusb.pc'
      to the PKG_CONFIG_PATH environment variable
      Package 'libusb', required by 'ObexFTP', not found
      Package libusb was not found in the pkg-config search path.
      Perhaps you should add the directory containing `libusb.pc'
      to the PKG_CONFIG_PATH environment variable
      Package 'libusb', required by 'ObexFTP', not found

      So I installed libusb01.12.but i could not find libusb.pc anywhere.How can i rectify this error to set the path.
      Plz help me...Is there any way to send files to nearby visible devices with a program?

       
      • You might be better off just using your distros packaged openobex, obexftp, libusb and all.

         
    • Rizwan Basha
      Rizwan Basha
      2008-11-27

      Iam using Fedora 8.I don't think so  there will be any problem with supporting of  packages  .Am i right

       
    • Rizwan Basha
      Rizwan Basha
      2008-11-27

      Thank u Christian..Finally I hav reduction in my errors .Iam happy that there are no Errors Regarding Packages & config paths
      I had found libucsb.pc path finally to support obexftp

      on compiling as:

                         gccl ftpsrvr.c $(pkg-config --cflags obexftp) $(pkg-config --libs obexftp) -lpthread -lbluetooth -o simplscan simplscan.c

      /tmp/ccpbUUaK.o: In function `main':
      simplscan.c:(.text+0x0): multiple definition of `main'
      /tmp/ccWBbMIv.o:ftpsrvr.c:(.text+0x0): first defined here
      /tmp/ccWBbMIv.o: In function `send_file':
      ftpsrvr.c:(.text+0x29c): undefined reference to `obexftp_browse_bt_push'
      ftpsrvr.c:(.text+0x358): undefined reference to `obexftp_connect_push'
      collect2: ld returned 1 exit status

      How can these Undefined reference errors can be avoided..

      thanx again

       
      • I don't know about "gccl"? You should compile with "-Wall" and "-g" to get better debug. In this case you need to include the headers defining those macros (those aren't functions). obexftp/client.h and obexftp/obexftp.h

         
    • Rizwan Basha
      Rizwan Basha
      2008-12-31

      Iam able to transfer File to Multiple number of devices ,but  procedures seems to be one after the other.Although I have tried MultiThreading  as:
      #include <stdio.h>
      #include <stdlib.h>
      #include <unistd.h>
      #include <sys/socket.h>
      #include <pthread.h>
      #include <bluetooth/bluetooth.h>
      #include <bluetooth/hci.h>
      #include <bluetooth/hci_lib.h>
      #include <obexftp/client.h> /*!!!*/

      #define NTHREADS 10 //max number of threads used in multithreading

      void *send_file(void *address); //prototype for the file sending function used in the new thread

      //searching for devices code is taken from some bluez examples
      int main(int argc, char **argv)
      {
      inquiry_info *ii = NULL;
      int max_rsp, num_rsp;
      int dev_id, sock, len, flags;
      int i,j;
      char addr[19] = { 0 };
      char name[248] = { 0 };
      pthread_t thread_id[NTHREADS];

      dev_id = hci_get_route(NULL);
      sock = hci_open_dev( dev_id );
      if (dev_id < 0 || sock < 0) {
      perror("opening socket");
      exit(1);
      }

      len = 8;
      max_rsp = 255;
      flags = IREQ_CACHE_FLUSH;
      ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));

      num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
      if( num_rsp < 0 ) perror("hci_inquiry");

      printf ("%i devices discovered!\n",num_rsp);
      for (i = 0; i < num_rsp; i++) {
      ba2str(&(ii+i)->bdaddr, addr);
      memset(name, 0, sizeof(name));
      if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name),
      name, 0) < 0)
      strcpy(name, "[unknown]");

      //start multithreading
      /* Create independent threads each of which will execute function */
      printf ("Starting thread %i...\n",i);
      pthread_create( &thread_id[i], NULL, send_file, (void*) addr);
      pthread_join( thread_id[j], NULL); //wait for the thread to finish its execution; not sure if this is good here

      }

      //free the resources
      free( ii );
      close( sock );
      return 0;
      }

      //file sending function, used in new threads
      void *send_file(void *ptr)
      {
      char *address = NULL;
      int channel = -1;
      char *filepath = "tux.jpg";
      char *filename;
      obexftp_client_t *cli = NULL; /*!!!*/
      int ret;

      printf("Thread number %ld\n", pthread_self());
      //pthread_exit(0);

      address = (char *)ptr;
      channel = obexftp_browse_bt_push(address); /*!!!*/

      /* Extract basename from file path */
      filename = strrchr(filepath, '/');
      if (!filename)
      filename = filepath;
      else
      filename++;

      printf("Sending file %s to %s\n", filename, address);

      /* Open connection */
      cli = obexftp_open(OBEX_TRANS_BLUETOOTH, NULL, NULL, NULL); /*!!!*/
      if (cli == NULL) {
      fprintf(stderr, "Error opening obexftp client\n");
      pthread_exit(NULL);
      }

      /* Connect to device */
      ret = obexftp_connect_push(cli, address, channel); /*!!!*/
      if (ret < 0) {
      fprintf(stderr, "Error connecting to obexftp device\n");
      obexftp_close(cli);
      cli = NULL;
      pthread_exit(NULL);
      }

      /* 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;

      pthread_exit(0);
      }

      I could not get it as Multithreading .Can u provide me information regarding how to transfer File to multiple devices at same time .(file transfer request should be shown to all devices at same time)

       
      • Read the thread about "multithreaded obex server".