蓝牙插座未收到数据包
过去 10 天我一直在研究蓝牙插座。我必须在客户端和服务器模式之间切换。我写了一段代码。我能够很好地发送数据包,但是当我在监听模式下工作时,我遇到了两个问题。 1.接受处于块模式,因此无法返回发送模式。 2.我使用 FNCTL() 将套接字设置为非阻塞,
但现在问题来了,即在两种模式之间完美切换,但它没有接收任何数据包。我的代码如下:-
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/l2cap.h>
#define MAXPROFILES 2
int SetTimer(struct timeval *tv, time_t sec)
{
gettimeofday(tv,NULL);
tv->tv_sec+=sec;
return 1;
}
void start_scan()
{
struct sockaddr_l2 addr1 = { 0 };
int s=0,h, status,f,contacted;
int search=1;
char *message = "hello!";
char dest[18] = "01:23:45:67:89:AB";
struct neighbor
{
char peer[19];
} p[h];
unsigned char buf[1024];
inquiry_info *devices = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags,cmp;
int x=0,i;
char addr[19] = { 0 };
char name[248] = { 0 };
dev_id = hci_get_route(NULL);
sock = hci_open_dev( dev_id );
if (dev_id < 0 || sock < 0)
{
perror("opening socket");
exit(1);
}
len = 3;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
devices = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
struct timeval tv;
SetTimer(&tv,15);
while(search == 1)
{ //fprintf(stderr,"\t%d \n", time);
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &devices, flags);
fprintf(stderr,"%s (%d) %d\n", "done scanning, found ", j, num_rsp);
if( num_rsp < 0 ) perror("hci_inquiry");
for (i = 0; i < num_rsp; i++)
{
ba2str(&(devices+i)->bdaddr, addr);
fprintf(stderr,"\t%s \n", addr);
cmp= strncmp(addr,"10:2E:AF:EB:33:BD",8);
if(cmp==0)
{
fprintf(stderr,"\t%s \t%d\n", addr,cmp);
for(f=0;f<=h;f++)
{
if(p[f].peer[18]==addr[19])
contacted=1;
}
if(contacted==1)
{
contacted=0;
continue;
}
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// set the connection parameters (who to connect to)
addr1.l2_family = AF_BLUETOOTH;
addr1.l2_psm = htobs(0x1001);
strncpy(dest, addr, 18);
str2ba( dest, &addr1.l2_bdaddr );
// connect to server
status = connect(s, (struct sockaddr *)&addr1, sizeof(addr1));
// send a message
if( status == 0 )
{
status = write(s, "hello", 10);
h++;
p[h].peer[18]=addr[19];
}
if( status < 0 )
{
perror("uh oh");
}
}
} // for
x++;
if(!(x%2))
flags = IREQ_CACHE_FLUSH;
else
flags = 0x00;
if (CheckTimer(&tv,5)==1)
{ //close(sock);
fprintf(stderr,"listen....\n");
start_listen(s);
}
}
}
int start_listen(int s)
{ struct sockaddr_l2 addr1 = { 0 },rem_addr = { 0 };;
fd_set fds;
int client, bytes_read,sock_flags;
char buf1[1024] = {0};
socklen_t opt = sizeof(rem_addr);
struct timeval tv;
addr1.l2_family = AF_BLUETOOTH;
addr1.l2_bdaddr = *BDADDR_ANY;
addr1.l2_psm = htobs(0x1001);
sock_flags=fcntl(s,F_GETFL,0);
fcntl(s,F_SETFL,sock_flags | O_NONBLOCK);
bind(s, (struct sockaddr *)&addr1, sizeof(addr1));
SetTimer(&tv,15);
// put socket into listening mode
while(!0)
{
listen(s, 1);
//fprintf(stderr,"I am listening....\n");
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
//fprintf(stderr,"I failed....\n");
FD_ZERO(&fds);
FD_SET(s,&fds);
ba2str( &rem_addr.l2_bdaddr, buf1 );
memset(buf1, 0, sizeof(buf1));
// read data from the client
bytes_read = read(client, buf1, sizeof(buf1));
if( bytes_read > 0 ){
printf("received [%s]\n", buf1);
fprintf(stderr, "accepted connection from %s\n", buf1);
}
close(client);
if (CheckTimer(&tv,5)==1)
{fprintf(stderr,"done listening...");
SetTimer(&tv,15);
return 1;
}
}//while of the listening mode
}
int CheckTimer(struct timeval *tv, time_t sec)
{
struct timeval ctv;
gettimeofday(&ctv,NULL);
if((ctv.tv_sec > tv->tv_sec))
{
gettimeofday(tv,NULL);
tv->tv_sec+=sec;
return 1;
}
else return 0;
}
int main(int argc, char **argv)
{start_scan();
}
I am working on a bluetooth socket for past 10 days. I have to switch between client and server mode. I have written a piece of code. I was able to send the packet fine but when i was working for listening mode I faced two problems.
1.The accept was in block mode so it was not able to go back to send mode.
2. I made the socket non block using FNCTL()
But now issue is coming that is is switching between two modes perfectly but it is not receiving any packet. My code is as follow:-
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/l2cap.h>
#define MAXPROFILES 2
int SetTimer(struct timeval *tv, time_t sec)
{
gettimeofday(tv,NULL);
tv->tv_sec+=sec;
return 1;
}
void start_scan()
{
struct sockaddr_l2 addr1 = { 0 };
int s=0,h, status,f,contacted;
int search=1;
char *message = "hello!";
char dest[18] = "01:23:45:67:89:AB";
struct neighbor
{
char peer[19];
} p[h];
unsigned char buf[1024];
inquiry_info *devices = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags,cmp;
int x=0,i;
char addr[19] = { 0 };
char name[248] = { 0 };
dev_id = hci_get_route(NULL);
sock = hci_open_dev( dev_id );
if (dev_id < 0 || sock < 0)
{
perror("opening socket");
exit(1);
}
len = 3;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
devices = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
struct timeval tv;
SetTimer(&tv,15);
while(search == 1)
{ //fprintf(stderr,"\t%d \n", time);
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &devices, flags);
fprintf(stderr,"%s (%d) %d\n", "done scanning, found ", j, num_rsp);
if( num_rsp < 0 ) perror("hci_inquiry");
for (i = 0; i < num_rsp; i++)
{
ba2str(&(devices+i)->bdaddr, addr);
fprintf(stderr,"\t%s \n", addr);
cmp= strncmp(addr,"10:2E:AF:EB:33:BD",8);
if(cmp==0)
{
fprintf(stderr,"\t%s \t%d\n", addr,cmp);
for(f=0;f<=h;f++)
{
if(p[f].peer[18]==addr[19])
contacted=1;
}
if(contacted==1)
{
contacted=0;
continue;
}
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// set the connection parameters (who to connect to)
addr1.l2_family = AF_BLUETOOTH;
addr1.l2_psm = htobs(0x1001);
strncpy(dest, addr, 18);
str2ba( dest, &addr1.l2_bdaddr );
// connect to server
status = connect(s, (struct sockaddr *)&addr1, sizeof(addr1));
// send a message
if( status == 0 )
{
status = write(s, "hello", 10);
h++;
p[h].peer[18]=addr[19];
}
if( status < 0 )
{
perror("uh oh");
}
}
} // for
x++;
if(!(x%2))
flags = IREQ_CACHE_FLUSH;
else
flags = 0x00;
if (CheckTimer(&tv,5)==1)
{ //close(sock);
fprintf(stderr,"listen....\n");
start_listen(s);
}
}
}
int start_listen(int s)
{ struct sockaddr_l2 addr1 = { 0 },rem_addr = { 0 };;
fd_set fds;
int client, bytes_read,sock_flags;
char buf1[1024] = {0};
socklen_t opt = sizeof(rem_addr);
struct timeval tv;
addr1.l2_family = AF_BLUETOOTH;
addr1.l2_bdaddr = *BDADDR_ANY;
addr1.l2_psm = htobs(0x1001);
sock_flags=fcntl(s,F_GETFL,0);
fcntl(s,F_SETFL,sock_flags | O_NONBLOCK);
bind(s, (struct sockaddr *)&addr1, sizeof(addr1));
SetTimer(&tv,15);
// put socket into listening mode
while(!0)
{
listen(s, 1);
//fprintf(stderr,"I am listening....\n");
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
//fprintf(stderr,"I failed....\n");
FD_ZERO(&fds);
FD_SET(s,&fds);
ba2str( &rem_addr.l2_bdaddr, buf1 );
memset(buf1, 0, sizeof(buf1));
// read data from the client
bytes_read = read(client, buf1, sizeof(buf1));
if( bytes_read > 0 ){
printf("received [%s]\n", buf1);
fprintf(stderr, "accepted connection from %s\n", buf1);
}
close(client);
if (CheckTimer(&tv,5)==1)
{fprintf(stderr,"done listening...");
SetTimer(&tv,15);
return 1;
}
}//while of the listening mode
}
int CheckTimer(struct timeval *tv, time_t sec)
{
struct timeval ctv;
gettimeofday(&ctv,NULL);
if((ctv.tv_sec > tv->tv_sec))
{
gettimeofday(tv,NULL);
tv->tv_sec+=sec;
return 1;
}
else return 0;
}
int main(int argc, char **argv)
{start_scan();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在绑定之前,我可以通过在侦听模式下再次输入以下命令来解决该问题。
但现在的问题是我的
close(client)
不起作用。我无法关闭客户端并收听新客户端。有谁知道为什么?I was able to solve the issue by entering the following command again in listen mode before binding.
But now the issue is my
close(client)
is not working. I am not able to close the client and listen to new client. Do anyone know why?根本不需要打开服务器套接字! (除非您的远程设备正在做一些非常奇怪的事情!!)套接字可用于发送和接收-- 无论是客户端套接字还是服务器套接字。
删除所有执行侦听+接受等操作的代码,然后写入和读取原始(客户端)套接字。(使用以下代码完成的代码:“
connect(s,
...”)如果您的远程设备确实需要使用一个新变量来保存套接字句柄,并且不要让服务器套接字句柄覆盖原始客户端句柄。
There is no need at all to open the server socket! (Unless your remote device is doing something very odd!!) A socket can be used for send and receive -- regardless of whether it is a client socket or a server socket.
Remove all the code to do the listen+accept etc, and write and read to the original (client) socket.(The one done with: "
connect(s,
...")If your remote device really needs the two different connections. The use a new variable to hold the socket handle and don't have the server socket handle overwrite the original client handle.