android/Bluetooth
L2CAP을 이용한 Socket Programming Note
깍수
2014. 8. 21. 15:57
- MTU
아래와 같이 set/getsockeopt() 함수를 이용하면 MTU(Maximum Transmission Unit) 값을 변경할 수 있으며
해당 Local socket에서만 적용이 된다. Server or Client 각각 이를 설정해야 값을 지정할 수 있다.
기본 MTU 값은 672 Bytes이며 최소 48 Bytes에서 최대 65,535 Bytes까지 적용하 수 있다.
struct l2cap_options { uint16_t omtu; uint16_t imtu; uint16_t flush_to; uint8_t mode; };
int set_l2cap_mtu( int sock, uint16_t mtu ) {
struct l2cap_options opts;
int optlen = sizeof(opts), err;
err = getsockopt( s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen );
if( ! err ) {
opts.omtu = opts.imtu = mtu;
err = setsockopt( s, SOL_L2CAP, L2CAP_OPTIONS, &opts, optlen );
}
return err;
};
|
* 용어 정리
PSM : Protocol Service Multiplexer
L2CAP socket에서 사용가능한 Port는 4097~32,767(0x1001-0x7FFF)까지 홀수 번호이다.
ex) L2CAP Server&Client
1) Server
#include <stdio.h> #include <string.h>
#include <sys/socket.h> #include <bluetooth/bluetooth.h> #include <bluetooth/l2cap.h>
int main(int argc, char **argv) { struct sockaddr_l2 loc_addr = { 0 }, rem_addr = { 0 }; // struct l2cap_options opts;
char buf[1024] = { 0 }; int s, client, bytes_read, optlen; socklen_t opt = sizeof(rem_addr);
// allocate socket s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// bind socket to port 0x1001 of the first available // bluetooth adapter loc_addr.l2_family = AF_BLUETOOTH; loc_addr.l2_bdaddr = *BDADDR_ANY; loc_addr.l2_psm = htobs(0x1001);
bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
// optlen = sizeof(opts); // getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen); // printf("before omtu = %d, imtu = %d\n", opts.omtu, opts.imtu);
// put socket into listening mode listen(s, 1);
// accept one connection client = accept(s, (struct sockaddr *)&rem_addr, &opt);
// optlen = sizeof(opts); // getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen); // printf("after omtu = %d, imtu = %d\n", opts.omtu, opts.imtu);
ba2str( &rem_addr.l2_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); } |
2) Client
#include <string.h> #include <stdio.h> #include <stdlib.h> #include <string.h>
#include <sys/socket.h> #include <bluetooth/bluetooth.h> #include <bluetooth/l2cap.h>
int set_l2cap_mtu( int sock, uint16_t mtu );
int main(int argc, char **argv) { struct sockaddr_l2 addr = { 0 }; int s, status; char *message = "hello!"; char dest[18] = "01:23:45:67:89:AB";
struct l2cap_options opts; int optlen;
if(argc < 2) { fprintf(stderr, "usage: %s <bt_addr>\n", argv[0]); exit(2); }
strncpy(dest, argv[1], 18);
// allocate a socket s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
set_l2cap_mtu(s, 65535);
// set the connection parameters (who to connect to) addr.l2_family = AF_BLUETOOTH; addr.l2_psm = htobs(0x1001); str2ba( dest, &addr.l2_bdaddr );
// connect to server status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
optlen = sizeof(opts); getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen); printf("after omtu = %d, imtu = %d\n", opts.omtu, opts.imtu);
// send a message if( status == 0 ) { status = write(s, "hello!", 6); }
if( status < 0 ) perror("uh oh");
close(s); }
int set_l2cap_mtu( int sock, uint16_t mtu ) { struct l2cap_options opts; int optlen = sizeof(opts), err;
err = getsockopt( sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen ); if( ! err ) { printf(" current omtu = %d, imtu = %d\n", opts.omtu, opts.imtu); opts.omtu = opts.imtu = mtu; err = setsockopt( sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, optlen ); }
return err; } |
춮처 : Bluetooth Essentials