разъем Bluetooth не получает пакет - PullRequest
2 голосов
/ 15 августа 2011

Я работаю над разъемом Bluetooth в течение последних 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();
}

Ответы [ 2 ]

0 голосов
/ 09 декабря 2012

Нет необходимости открывать сокет сервера! ( Если ваше удаленное устройство что-то не делает очень нечетно !!) Разъем можно использовать для отправки и приема - независимо от будь то сокет клиента или сокет сервера.

Удалите весь код для прослушивания + принятия и т. Д., А также запишите и прочитайте в исходный (клиентский) сокет (тот, что сделан с: "connect(s, ...")

Если ваше удаленное устройство действительно нуждается в двух разных соединениях. Используйте новую переменную для хранения дескриптора сокета и не позволяйте дескриптору сокета сервера перезаписывать оригинальный дескриптор клиента.

0 голосов
/ 16 августа 2011

Я смог решить эту проблему, введя следующую команду еще раз в режиме прослушивания перед привязкой.

s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);

Но теперь проблема в том, что мой close(client) не работает. Я не могу закрыть клиента и прослушать нового клиента. Кто-нибудь знает почему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...