1761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
2761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Copyright 2017 The Android Open Source Project
3761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
4761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Licensed under the Apache License, Version 2.0 (the "License");
5761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// you may not use this file except in compliance with the License.
6761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// You may obtain a copy of the License at
7761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
8761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// http://www.apache.org/licenses/LICENSE-2.0
9761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
10761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Unless required by applicable law or agreed to in writing, software
11761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// distributed under the License is distributed on an "AS IS" BASIS,
12761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// See the License for the specific language governing permissions and
14761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// limitations under the License.
15761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
16761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
17761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include "hci_protocol.h"
18761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
19761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#define LOG_TAG "android.hardware.bluetooth-hci-hci_protocol"
20761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <android-base/logging.h>
21761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <assert.h>
22761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <fcntl.h>
23761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <utils/Log.h>
24761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
25761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace {
26761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
27761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonconst size_t preamble_size_for_type[] = {
28761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    0, HCI_COMMAND_PREAMBLE_SIZE, HCI_ACL_PREAMBLE_SIZE, HCI_SCO_PREAMBLE_SIZE,
29761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    HCI_EVENT_PREAMBLE_SIZE};
30761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonconst size_t packet_length_offset_for_type[] = {
31761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO,
32761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    HCI_LENGTH_OFFSET_EVT};
33761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
34761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonsize_t HciGetPacketLengthForType(HciPacketType type, const uint8_t* preamble) {
35761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  size_t offset = packet_length_offset_for_type[type];
36761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  if (type != HCI_PACKET_TYPE_ACL_DATA) return preamble[offset];
37761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  return (((preamble[offset + 1]) << 8) | preamble[offset]);
38761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}
39761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
40761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace
41761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
42761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace android {
43761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace hardware {
44761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace bluetooth {
45761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace hci {
46761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
47761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonsize_t HciProtocol::WriteSafely(int fd, const uint8_t* data, size_t length) {
48761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  size_t transmitted_length = 0;
49761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  while (length > 0) {
50761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    ssize_t ret =
51761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        TEMP_FAILURE_RETRY(write(fd, data + transmitted_length, length));
52761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
53761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    if (ret == -1) {
54761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      if (errno == EAGAIN) continue;
55761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
56761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      break;
57761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
58761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    } else if (ret == 0) {
59761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      // Nothing written :(
60761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      ALOGE("%s zero bytes written - something went wrong...", __func__);
61761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      break;
62761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    }
63761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
64761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    transmitted_length += ret;
65761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    length -= ret;
66761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  }
67761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
68761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  return transmitted_length;
69761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}
70761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
71761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace hci
72761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace bluetooth
73761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace hardware
74761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace android
75