1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "device/bluetooth/bluetooth_socket_win.h"
9 #include "base/logging.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "device/bluetooth/bluetooth_init_win.h"
13 #include "device/bluetooth/bluetooth_service_record_win.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/winsock_init.h"
19 std::string
FormatErrorMessage(DWORD error_code
) {
20 TCHAR error_msg
[1024];
21 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
,
28 return base::SysWideToUTF8(error_msg
);
35 BluetoothSocketWin::BluetoothSocketWin(SOCKET fd
) : fd_(fd
) {
38 BluetoothSocketWin::~BluetoothSocketWin() {
43 scoped_refptr
<BluetoothSocket
> BluetoothSocketWin::CreateBluetoothSocket(
44 const BluetoothServiceRecord
& service_record
) {
45 BluetoothSocketWin
* bluetooth_socket
= NULL
;
46 if (service_record
.SupportsRfcomm()) {
47 net::EnsureWinsockInit();
48 SOCKET socket_fd
= socket(AF_BTH
, SOCK_STREAM
, BTHPROTO_RFCOMM
);
50 ZeroMemory(&sa
, sizeof(sa
));
51 sa
.addressFamily
= AF_BTH
;
52 sa
.port
= service_record
.rfcomm_channel();
53 const BluetoothServiceRecordWin
* service_record_win
=
54 static_cast<const BluetoothServiceRecordWin
*>(&service_record
);
55 sa
.btAddr
= service_record_win
->bth_addr();
57 int status
= connect(socket_fd
,
58 reinterpret_cast<SOCKADDR
*>(&sa
),
60 DWORD error_code
= WSAGetLastError();
61 if (status
== 0 || error_code
== WSAEINPROGRESS
) {
63 new BluetoothSocketWin(socket_fd
);
65 LOG(ERROR
) << "Failed to connect bluetooth socket "
66 << "(" << service_record
.address() << "): "
67 << "(" << error_code
<< ")" << FormatErrorMessage(error_code
);
68 closesocket(socket_fd
);
71 // TODO(youngki) add support for L2CAP sockets as well.
73 return scoped_refptr
<BluetoothSocketWin
>(bluetooth_socket
);
76 bool BluetoothSocketWin::Receive(net::GrowableIOBuffer
* buffer
) {
77 buffer
->SetCapacity(1024);
80 if (buffer
->RemainingCapacity() == 0)
81 buffer
->SetCapacity(buffer
->capacity() * 2);
82 bytes_read
= recv(fd_
, buffer
->data(), buffer
->RemainingCapacity(), 0);
84 buffer
->set_offset(buffer
->offset() + bytes_read
);
85 } while (bytes_read
> 0);
87 DWORD error_code
= WSAGetLastError();
88 if (bytes_read
< 0 && error_code
!= WSAEWOULDBLOCK
) {
89 error_message_
= FormatErrorMessage(error_code
);
95 bool BluetoothSocketWin::Send(net::DrainableIOBuffer
* buffer
) {
98 bytes_written
= send(fd_
, buffer
->data(), buffer
->BytesRemaining(), 0);
99 if (bytes_written
> 0)
100 buffer
->DidConsume(bytes_written
);
101 } while (buffer
->BytesRemaining() > 0 && bytes_written
> 0);
103 DWORD error_code
= WSAGetLastError();
104 if (bytes_written
< 0 && error_code
!= WSAEWOULDBLOCK
) {
105 error_message_
= FormatErrorMessage(error_code
);
111 std::string
BluetoothSocketWin::GetLastErrorMessage() const {
112 return error_message_
;
115 } // namespace device