Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Linux Programming
  4. Bluetooth socket failures

Bluetooth socket failures

Scheduled Pinned Locked Moved Linux Programming
helpquestionannouncement
8 Posts 3 Posters 25 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    Vaclav_
    wrote on last edited by
    #1

    I am looking for somebody who can help me to resolve this bluetooth issue. ( I'll ignore any replies NOT discussing / leading to resolution , including insults and RTFM comments ) Included is "bare bones " bluetooth code , I have not included any necessary #includes / library , but if it will help I can add them later if necessary. I am still having an issue with "address already in use" , BUT my question for now is why I cannot close and successfully reallocate "socket" ? I understand that some functions DO NOT generate valid "errno" hence "invalid argument" is really somewhat bogus perror message, however SECOND call to socket should generate "Success" . Again please concentrate on that for now. Code output

    RPI_BT_SERVER _X86
    date version Feb 28 2020
    test time 10:17:50
    BRAEK @line 333
    STATUS allocate socket : Success
    STATUS close socket : Invalid argument
    STATUS reallocate socket : Invalid argument this is the issue
    STATUS bind : Address already in use
    STATUS listen : File descriptor in bad state
    STATUS accept : File descriptor in bad state
    accepted connection from 00:00:00:00:00:00

    Code snippet:

    struct sockaddr\_rc loc\_addr = { 0 }, rem\_addr = { 0 };
    char buf\[1024\] = { 0 };
    int socket\_fd, client\_fd, bytes\_read;
    socklen\_t opt = sizeof(rem\_addr);
    
    // allocate socket
    socket\_fd= socket(AF\_BLUETOOTH, SOCK\_STREAM, BTPROTO\_RFCOMM);
    perror("STATUS allocate socket ");
    
    // close socket
    close(socket\_fd);
    perror("STATUS close socket ");
    // re allocate socket
    socket\_fd = socket(AF\_BLUETOOTH, SOCK\_STREAM, BTPROTO\_RFCOMM);
    perror("STATUS reallocate socket ");
    
    // bind socket to port 1 of the first available
    // local bluetooth adapter
    loc\_addr.rc\_family = AF\_BLUETOOTH;
    
    struct hci\_dev\_info device\_info;
    hci\_devinfo(0, &device\_info);
    

    // exit(1);

    loc\_addr.rc\_bdaddr = device\_info.bdaddr; //   {"00:15:83:15:A2:CB"}; // "\*BDADDR\_ANY;
    loc\_addr.rc\_channel = (uint8\_t) 1;
    bind(socket\_fd, (struct sockaddr\*) &loc\_addr, sizeof(loc\_addr));
    perror("STATUS bind ");
    // put socket into listening mode
    listen(socket\_fd, 1);
    perror("STATUS listen ");
    // accept one connection
    client\_fd = accept(socket\_fd, (struct sockaddr\*) &rem\_addr, &opt);
    perror("STATUS accept ");
    ba2str(&rem\_addr.rc\_bdaddr, buf);
    fprintf(stderr, "accepted connection from %s\\n", buf);
    memset(buf, 0, sizeof(buf));
    
    // read data from the client
    bytes\_read = read(client\_fd, buf, sizeo
    
    L 1 Reply Last reply
    0
    • V Vaclav_

      I am looking for somebody who can help me to resolve this bluetooth issue. ( I'll ignore any replies NOT discussing / leading to resolution , including insults and RTFM comments ) Included is "bare bones " bluetooth code , I have not included any necessary #includes / library , but if it will help I can add them later if necessary. I am still having an issue with "address already in use" , BUT my question for now is why I cannot close and successfully reallocate "socket" ? I understand that some functions DO NOT generate valid "errno" hence "invalid argument" is really somewhat bogus perror message, however SECOND call to socket should generate "Success" . Again please concentrate on that for now. Code output

      RPI_BT_SERVER _X86
      date version Feb 28 2020
      test time 10:17:50
      BRAEK @line 333
      STATUS allocate socket : Success
      STATUS close socket : Invalid argument
      STATUS reallocate socket : Invalid argument this is the issue
      STATUS bind : Address already in use
      STATUS listen : File descriptor in bad state
      STATUS accept : File descriptor in bad state
      accepted connection from 00:00:00:00:00:00

      Code snippet:

      struct sockaddr\_rc loc\_addr = { 0 }, rem\_addr = { 0 };
      char buf\[1024\] = { 0 };
      int socket\_fd, client\_fd, bytes\_read;
      socklen\_t opt = sizeof(rem\_addr);
      
      // allocate socket
      socket\_fd= socket(AF\_BLUETOOTH, SOCK\_STREAM, BTPROTO\_RFCOMM);
      perror("STATUS allocate socket ");
      
      // close socket
      close(socket\_fd);
      perror("STATUS close socket ");
      // re allocate socket
      socket\_fd = socket(AF\_BLUETOOTH, SOCK\_STREAM, BTPROTO\_RFCOMM);
      perror("STATUS reallocate socket ");
      
      // bind socket to port 1 of the first available
      // local bluetooth adapter
      loc\_addr.rc\_family = AF\_BLUETOOTH;
      
      struct hci\_dev\_info device\_info;
      hci\_devinfo(0, &device\_info);
      

      // exit(1);

      loc\_addr.rc\_bdaddr = device\_info.bdaddr; //   {"00:15:83:15:A2:CB"}; // "\*BDADDR\_ANY;
      loc\_addr.rc\_channel = (uint8\_t) 1;
      bind(socket\_fd, (struct sockaddr\*) &loc\_addr, sizeof(loc\_addr));
      perror("STATUS bind ");
      // put socket into listening mode
      listen(socket\_fd, 1);
      perror("STATUS listen ");
      // accept one connection
      client\_fd = accept(socket\_fd, (struct sockaddr\*) &rem\_addr, &opt);
      perror("STATUS accept ");
      ba2str(&rem\_addr.rc\_bdaddr, buf);
      fprintf(stderr, "accepted connection from %s\\n", buf);
      memset(buf, 0, sizeof(buf));
      
      // read data from the client
      bytes\_read = read(client\_fd, buf, sizeo
      
      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      The invalid argument message on the close is saying the socket_fd is not a valid socket identifier. So none of the following calls are likely to succeed. Even though perror says success after the socket call, you should check the return value to see what it is.

      V 2 Replies Last reply
      0
      • L Lost User

        The invalid argument message on the close is saying the socket_fd is not a valid socket identifier. So none of the following calls are likely to succeed. Even though perror says success after the socket call, you should check the return value to see what it is.

        V Offline
        V Offline
        Vaclav_
        wrote on last edited by
        #3

        Richard, I have quit checking the actual file descriptor because perror gives a more information when it fails. But after your post I added such check back. I also replaced close with shutdown and still getting same results. Since I still do not trust cerr /perror running on X86 I am going to switch to ARM where the cout / cerr "synchronization " is NOT an issue. Interestingly , when I check the file descriptor on initial socket allocation , then the reallocated socket file descriptor is different. I am not sure if that matter, but OS "should" always allocate lowest level file descriptor and that tells me that the original file descriptor is somehow still active. One small note = I have to make sure perror actually reads the results of the socket call immediately after.

        K 1 Reply Last reply
        0
        • L Lost User

          The invalid argument message on the close is saying the socket_fd is not a valid socket identifier. So none of the following calls are likely to succeed. Even though perror says success after the socket call, you should check the return value to see what it is.

          V Offline
          V Offline
          Vaclav_
          wrote on last edited by
          #4

          I have moved the code to run on RPi ARM and have NO ISSUES! I shall go ahead and finish my experiment passing data using bluetooth on SAME hardware, Perhaps when I get it fully working it will be easier to find why it fails on X86. Thanks four your help.

          1 Reply Last reply
          0
          • V Vaclav_

            Richard, I have quit checking the actual file descriptor because perror gives a more information when it fails. But after your post I added such check back. I also replaced close with shutdown and still getting same results. Since I still do not trust cerr /perror running on X86 I am going to switch to ARM where the cout / cerr "synchronization " is NOT an issue. Interestingly , when I check the file descriptor on initial socket allocation , then the reallocated socket file descriptor is different. I am not sure if that matter, but OS "should" always allocate lowest level file descriptor and that tells me that the original file descriptor is somehow still active. One small note = I have to make sure perror actually reads the results of the socket call immediately after.

            K Offline
            K Offline
            k5054
            wrote on last edited by
            #5

            Vaclav_ wrote:

            I have quit checking the actual file descriptor because perror gives a more information when it fails.

            This could be a problem: perror() prints the associated error string with the current errno, but a successful library call does not reset errno to zero. If you're going to rely on perror(), and by extension errno, you need to make sure you set errrno to zero before any library call that might set errno. Otherwise, you could be getting invalid error information. Every library function I can think of will return a value that will indicate that it failed (e.g. -1 for open(), or NULL for fopen(), etc). You really should be testing the return value for failure before checking perror()

            V L 3 Replies Last reply
            0
            • K k5054

              Vaclav_ wrote:

              I have quit checking the actual file descriptor because perror gives a more information when it fails.

              This could be a problem: perror() prints the associated error string with the current errno, but a successful library call does not reset errno to zero. If you're going to rely on perror(), and by extension errno, you need to make sure you set errrno to zero before any library call that might set errno. Otherwise, you could be getting invalid error information. Every library function I can think of will return a value that will indicate that it failed (e.g. -1 for open(), or NULL for fopen(), etc). You really should be testing the return value for failure before checking perror()

              V Offline
              V Offline
              Vaclav_
              wrote on last edited by
              #6

              I have started doing both checks - return values and errno. If I understand perror it does something special when errno is zero. Perhaps I will try to keep track of errno. There are two "weird" behaviour I am unable to grasp. I am definitely getting different responses when running SAME code on X86 and ARM7. I am working on that to make sure. Even if errno is NOT changed between calls, getting "Invalid parameters" is puzzling when the parameters are SAME in both calls. Here is a proof you are on the right track ! Code

              // allocate socket
              socket\_fd = socket(AF\_BLUETOOTH, SOCK\_STREAM, BTPROTO\_RFCOMM);
              

              #ifdef TRACE
              cout << "Socket errno " << dec << errno << " @line " << __LINE__ << endl;
              perror("STATUS allocate socket ");

              this call sets the errno to 22 - AFTER perror is executed with errno being set to 0 success!

              cout << "socket_fd " << dec << socket_fd << endl;

              this call
              cout << "Socket errno " << dec << errno << " @line " << __LINE__ << endl;
              //exit(-1);
              #endif

              // reallocate socket
              

              here the errno is still set to 22 !

              socket\_fd = socket(AF\_BLUETOOTH, SOCK\_STREAM, BTPROTO\_RFCOMM);
              

              #ifdef TRACE
              cout << "Socket errno " << dec << errno << " @line " << __LINE__ << endl;
              perror("STATUS allocate socket ");
              cout << "socket_fd " << dec << socket_fd << endl;
              cout << "Socket errno " << dec << errno << " @line " << __LINE__ << endl;
              exit(-1);
              #endif

              Output

              SERVER_X86_228
              RPI_ARM
              date version Feb 29 2020
              test time 13:37:53
              STATUS allocate socket : Success
              BREAK @line 47
              Socket errno 0 @line 61
              socket_fd 3
              Socket errno 22 @line 64
              Socket errno 22 @line 72
              socket_fd 4
              Socket errno 22 @line 75
              STATUS allocate socket : Invalid argument

              1 Reply Last reply
              0
              • K k5054

                Vaclav_ wrote:

                I have quit checking the actual file descriptor because perror gives a more information when it fails.

                This could be a problem: perror() prints the associated error string with the current errno, but a successful library call does not reset errno to zero. If you're going to rely on perror(), and by extension errno, you need to make sure you set errrno to zero before any library call that might set errno. Otherwise, you could be getting invalid error information. Every library function I can think of will return a value that will indicate that it failed (e.g. -1 for open(), or NULL for fopen(), etc). You really should be testing the return value for failure before checking perror()

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                Good point, I totally forgot about that.

                1 Reply Last reply
                0
                • K k5054

                  Vaclav_ wrote:

                  I have quit checking the actual file descriptor because perror gives a more information when it fails.

                  This could be a problem: perror() prints the associated error string with the current errno, but a successful library call does not reset errno to zero. If you're going to rely on perror(), and by extension errno, you need to make sure you set errrno to zero before any library call that might set errno. Otherwise, you could be getting invalid error information. Every library function I can think of will return a value that will indicate that it failed (e.g. -1 for open(), or NULL for fopen(), etc). You really should be testing the return value for failure before checking perror()

                  V Offline
                  V Offline
                  Vaclav_
                  wrote on last edited by
                  #8

                  perror(3) - Linux manual page[^] Add a direct quote from man

                  When a system call fails, it usually returns -1 and sets the variable
                  errno to a value describing what went wrong. (These values can be
                  found in .) Many library functions do likewise. The
                  function perror() serves to translate this error code into human-
                  readable form. Note that errno is undefined after a successful
                  system call or library function call: this call may well change this
                  variable, even though it succeeds, for example because it internally
                  used some other library function that failed. Thus, if a failing
                  call is not immediately followed by a call to perror(), the value of
                  errno should be saved.

                  And I am not the only one using perror wrong. Take this gem I have commented out here just to show the original code. This "example" shows why some coders do not check the call result.

                  errcode = getaddrinfo("z\_desktop", NULL, &hints, &res);
                  //perror("STATE getaddrinfo");
                  if (errcode != 0) {           // call returns "-errors " 
                  	//cout <<"errno " << dec << errno << endl;
                  	perror("STATE getaddrinfo");     
                  

                  // perror prints "Success" ! getaddrinfo does not sets errno !
                  //cout << " errcode (?) " << dec << errcode << endl;
                  //cout << "hints.ai_addr " << dec << hints.ai_addr << endl;
                  //cout <<"hints.ai_family " << hints.ai_family << endl;
                  return -1;
                  }

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups