- RFCOMM Channel

RFCOMM의 Channel은 1~30까지 사용할 수 있으나 이상하게 1~13번 채널을 사용하면 Server에 연결 되지 않았다.

테스트 환경은 Server의 경우 PC Ubuntu을 사용하였으며 Client는 Android ICS 4.0.4 번젼의 BlueZ v4.93을 사용

하였다. 현상을 보면 Client에서 Socket 생성까지는 무리 없이 동작하며 connect() 함수를 호출하였을 경우 에러를

리턴 하였다.


- bind 함수

bind() 함수 호출시 커널 2.6.7 버전 이상에서는 Channel값을 0으로 설정하면 자동으로 값을 설정한다고 하는데… 정확히 어떤말을 하는지 모르겠음.

=> kernel source를 보면 rfcomm_sock_getname() 함수를 보면 struct sockaddr을 반환해 주는 함수가 있음.(미검토)


ex) RFCOMM Server&Client

1) Server

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>

#define USE_DYNAMIC_BIND    0   

int dynamic_bind_rc(int sock, struct sockaddr_rc *sockaddr, uint8_t *port);

int main(int argc, char **argv)
{
    struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
    char buf[1024] = { 0 };
    int s, client, bytes_read;
    uint8_t ch;
    socklen_t opt = sizeof(rem_addr);

    if (argc != 2) {
        printf("Usage:\n");
        printf("\nrfcomm-server Channel\n");
        exit(1);
    }

    ch = (uint8_t)strtol(argv[1], NULL, 10);

#if(USE_DYNAMIC_BIND == 1)
    uint8_t port;
#endif

    // allocate socket
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

    // bind socket to port 1 of the first available
    // local bluetooth adapter
    loc_addr.rc_family = AF_BLUETOOTH;
    loc_addr.rc_bdaddr = *BDADDR_ANY;

#if(USE_DYNAMIC_BIND == 1)    
    dynamic_bind_rc(s, &loc_addr, &port);
    printf("Available Ch : %d\n", port);

    // put socket into listening mode
    listen(s, 1);
#else
    loc_addr.rc_channel = (uint8_t) ch;
    bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));

    // put socket into listening mode
    listen(s, 1);
#endif

    // accept one connection
    client = accept(s, (struct sockaddr *)&rem_addr, &opt);

    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, buf, sizeof(buf));
    if( bytes_read > 0 ) {
        printf("received [%s]\n", buf);
    }

    // close connection
    close(client);
    close(s);
    return 0;
}


int dynamic_bind_rc(int sock, struct sockaddr_rc *sockaddr, uint8_t *port)
{
    int err;
    for( *port = 1; *port <= 31; *port++ ) {
        sockaddr->rc_channel = *port;
        err = bind(sock, (struct sockaddr *)sockaddr, sizeof(sockaddr));
        if( ! err ) break;
    }
    if( *port == 31 ) {
        err = -1;
    }
    return err;
}


2) Client

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>

int main(int argc, char **argv)
{
    struct sockaddr_rc addr = { 0 };
    int s, status;
    char dest[18] = "00:15:83:6A:02:F2";
    uint8_t ch;

    if (argc != 2) {
        printf("Usage:\n");
        printf("\nrfcomm-client Channel\n");
        exit(1);
    }

    ch = (uint8_t)strtol(argv[1], NULL, 10);

    // allocate a socket
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

    // set the connection parameters (who to connect to)
    addr.rc_family = AF_BLUETOOTH;
    addr.rc_channel = (uint8_t) ch;
    str2ba( dest, &addr.rc_bdaddr );

    // connect to server
    status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
    printf("status %d \n", status);

    // send a message
    if( status == 0 ) {
        status = write(s, "hello!", 6);
    }

    if( status < 0 ) perror("uh oh");

    close(s);
    return 0;
}


춮처 : Bluetooth Essentials




Posted by 깍수
,