Bluetooth socket failures
-
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:00Code 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
-
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:00Code 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
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 thesocket
call, you should check the return value to see what it is. -
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 thesocket
call, you should check the return value to see what it is.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.
-
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 thesocket
call, you should check the return value to see what it is. -
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.
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 currenterrno
, but a successful library call does not reseterrno
to zero. If you're going to rely onperror()
, and by extensionerrno
, you need to make sure you set errrno to zero before any library call that might seterrno
. 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 foropen()
, or NULL forfopen()
, etc). You really should be testing the return value for failure before checkingperror()
-
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 currenterrno
, but a successful library call does not reseterrno
to zero. If you're going to rely onperror()
, and by extensionerrno
, you need to make sure you set errrno to zero before any library call that might seterrno
. 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 foropen()
, or NULL forfopen()
, etc). You really should be testing the return value for failure before checkingperror()
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);
#endifOutput
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 -
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 currenterrno
, but a successful library call does not reseterrno
to zero. If you're going to rely onperror()
, and by extensionerrno
, you need to make sure you set errrno to zero before any library call that might seterrno
. 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 foropen()
, or NULL forfopen()
, etc). You really should be testing the return value for failure before checkingperror()
-
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 currenterrno
, but a successful library call does not reseterrno
to zero. If you're going to rely onperror()
, and by extensionerrno
, you need to make sure you set errrno to zero before any library call that might seterrno
. 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 foropen()
, or NULL forfopen()
, etc). You really should be testing the return value for failure before checkingperror()
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;
}