11572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum/* 21572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * Copyright (C) 2017 The Android Open Source Project 31572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * 41572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * Licensed under the Apache License, Version 2.0 (the "License"); 51572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * you may not use this file except in compliance with the License. 61572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * You may obtain a copy of the License at 71572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * 81572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * http://www.apache.org/licenses/LICENSE-2.0 91572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * 101572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * Unless required by applicable law or agreed to in writing, software 111572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * distributed under the License is distributed on an "AS IS" BASIS, 121572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * See the License for the specific language governing permissions and 141572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum * limitations under the License. 151572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum */ 161572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 171572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#define LOG_TAG "lowpan-hdlc-adapter" 181572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 191572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include "hdlc_lite.h" 201572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 211572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <unistd.h> 221572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 23c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum#include <mutex> 24c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum#include <condition_variable> 25c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum 261572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <hidl/HidlTransportSupport.h> 271572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <hidl/ServiceManagement.h> 281572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <hidl/Status.h> 291572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <hardware/hardware.h> 301572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <utils/Thread.h> 311572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <utils/Errors.h> 321572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <utils/StrongPointer.h> 331572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <log/log.h> 341572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <android/hardware/lowpan/1.0/ILowpanDevice.h> 351572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#include <android/hidl/manager/1.0/IServiceManager.h> 361572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 371572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum#define LOWPAN_HDLC_ADAPTER_MAX_FRAME_SIZE 2048 381572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 391572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing ::android::hardware::Return; 401572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing ::android::hardware::Void; 411572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing ::android::hardware::configureRpcThreadpool; 421572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing ::android::hardware::hidl_death_recipient; 431572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing ::android::hardware::hidl_string; 441572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing ::android::hardware::hidl_vec; 451572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing ::android::hardware::joinRpcThreadpool; 461572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing ::android::sp; 471572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing namespace ::android::hardware::lowpan::V1_0; 481572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumusing namespace ::android; 491572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 501572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumstruct LowpanDeathRecipient : hidl_death_recipient { 511572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum LowpanDeathRecipient() = default; 521572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum virtual void serviceDied(uint64_t /*cookie*/, const wp<::android::hidl::base::V1_0::IBase>& /*who*/) { 531572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("LowpanDevice died"); 541572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum exit(EXIT_FAILURE); 551572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 561572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum}; 571572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 581572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumstruct LowpanDeviceCallback : public ILowpanDeviceCallback { 591572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum int mFd; 60c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum std::mutex mMutex; 61c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum std::condition_variable mConditionVariable; 62c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum int mOpenError; 631572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum static const uint32_t kMaxFrameSize = LOWPAN_HDLC_ADAPTER_MAX_FRAME_SIZE; 641572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumpublic: 65c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum LowpanDeviceCallback(int fd): mFd(fd), mOpenError(-1) {} 661572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum virtual ~LowpanDeviceCallback() = default; 671572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 68c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum int waitForOpenStatus() { 69c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum std::unique_lock<std::mutex> lock(mMutex); 70c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum if (mOpenError == -1) { 71c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mConditionVariable.wait(lock); 72c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum } 73c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum return mOpenError; 74c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum } 75c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum 761572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum Return<void> onReceiveFrame(const hidl_vec<uint8_t>& data) override { 771572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (data.size() > kMaxFrameSize) { 781572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("TOOBIG: Frame received from device is too big"); 791572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum return Return<void>(); 801572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 811572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 821572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum int bufferIndex = 0; 831572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum uint16_t fcs = kHdlcCrcResetValue; 841572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum uint8_t buffer[kMaxFrameSize*2 + 5]; // every character escaped, escaped crc, and frame marker 851572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum uint8_t c; 861572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 871572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum for (size_t i = 0; i < data.size(); i++) 881572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum { 891572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum c = data[i]; 901572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum fcs = hdlc_crc16(fcs, c); 911572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum bufferIndex += hdlc_write_byte(buffer + bufferIndex, c); 921572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 931572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 941572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum fcs = hdlc_crc16_finalize(fcs); 951572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 961572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum bufferIndex += hdlc_write_byte(buffer + bufferIndex, uint8_t(fcs & 0xFF)); 971572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum bufferIndex += hdlc_write_byte(buffer + bufferIndex, uint8_t((fcs >> 8) & 0xFF)); 981572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 991572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum buffer[bufferIndex++] = HDLC_BYTE_FLAG; 1001572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 101c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum std::unique_lock<std::mutex> lock(mMutex); 102c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum 1031572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (write(mFd, buffer, bufferIndex) != bufferIndex) { 1041572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("IOFAIL: write: %s (%d)", strerror(errno), errno); 1051572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum exit(EXIT_FAILURE); 1061572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 1071572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1081572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum return Return<void>(); 1091572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 1101572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1111572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum Return<void> onEvent(LowpanEvent event, LowpanStatus status) override { 112c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum std::unique_lock<std::mutex> lock(mMutex); 113c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum 1141572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum switch (event) { 1151572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum case LowpanEvent::OPENED: 116c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum if (mOpenError == -1) { 117c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mOpenError = 0; 118c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mConditionVariable.notify_all(); 119c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum } 1201572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGI("Device opened"); 1211572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 1221572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1231572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum case LowpanEvent::CLOSED: 1241572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGI("Device closed"); 125c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum exit(EXIT_SUCCESS); 1261572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 1271572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1281572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum case LowpanEvent::RESET: 1291572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGI("Device reset"); 1301572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 1311572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1321572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum case LowpanEvent::ERROR: 133c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum if (mOpenError == -1) { 134c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mOpenError = int(status); 135c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mConditionVariable.notify_all(); 136c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum } 1371572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum switch (status) { 1381572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum case LowpanStatus::IOFAIL: 1391572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("IOFAIL: Input/Output error from device. Terminating."); 1401572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum exit(EXIT_FAILURE); 1411572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 1421572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum case LowpanStatus::GARBAGE: 1431572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGW("GARBAGE: Bad frame from device."); 1441572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 1451572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum case LowpanStatus::TOOBIG: 1461572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGW("TOOBIG: Device sending frames that are too large."); 1471572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 1481572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum default: 1491572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGW("Unknown error %d", status); 1501572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 1511572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 1521572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 1531572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 1541572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum return Return<void>(); 1551572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 1561572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum}; 1571572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1581572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumclass ReadThread : public Thread { 1591572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum int kReadThreadBufferSize; 1601572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1611572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum sp<ILowpanDevice> mService; 1621572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum int mFd; 1631572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum uint8_t mBuffer[LOWPAN_HDLC_ADAPTER_MAX_FRAME_SIZE]; 1641572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum int mBufferIndex; 1651572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum bool mUnescapeNextByte; 1661572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum uint16_t mFcs; 167c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum sp<LowpanDeviceCallback> mCallback; 1681572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1691572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumpublic: 170c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum ReadThread(sp<ILowpanDevice> service, int fd, sp<LowpanDeviceCallback> callback): 171c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum Thread(false /*canCallJava*/), 172c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum kReadThreadBufferSize(service->getMaxFrameSize()), 173c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mService(service), 174c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mFd(fd), 175c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mBufferIndex(0), 176c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mUnescapeNextByte(false), 177c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mFcs(kHdlcCrcResetValue), 178c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum mCallback(callback) { 1791572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (kReadThreadBufferSize < 16) { 1801572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("Device returned bad max frame size: %d bytes", kReadThreadBufferSize); 1811572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum exit(EXIT_FAILURE); 1821572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 1831572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if ((size_t)kReadThreadBufferSize > sizeof(mBuffer)) { 1841572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum kReadThreadBufferSize = (int)sizeof(mBuffer); 1851572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 1861572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 1871572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1881572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum virtual ~ReadThread() {} 1891572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1901572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumprivate: 1911572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 1921572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum bool threadLoop() override { 1931572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum uint8_t buffer[LOWPAN_HDLC_ADAPTER_MAX_FRAME_SIZE]; 1941572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 195c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum if (int error = mCallback->waitForOpenStatus()) { 196c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum ALOGE("Call to `open()` failed: %d", error); 197c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum exit(EXIT_FAILURE); 198c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum } 199c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum 2001572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum while (!exitPending()) { 2011572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ssize_t bytesRead = read(mFd, buffer, sizeof(buffer)); 2021572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (exitPending()) { 2031572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 2041572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2051572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2061572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (bytesRead < 0) { 2071572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("IOFAIL: read: %s (%d)", strerror(errno), errno); 2081572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum exit(EXIT_FAILURE); 2091572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum break; 2101572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2111572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum feedBytes(buffer, bytesRead); 2121572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2131572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2141572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum return false; 2151572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2161572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2171572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum void feedBytes(const uint8_t* dataPtr, ssize_t dataLen) { 2181572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum while(dataLen--) { 2191572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum feedByte(*dataPtr++); 2201572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2211572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2221572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2231572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum void sendFrame(uint8_t* p_data, uint16_t data_len) { 2241572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum hidl_vec<uint8_t> data; 2251572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum data.setToExternal(p_data, data_len); 2261572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mService->sendFrame(data); 2271572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2281572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2291572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum void feedByte(uint8_t byte) { 2301572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (mBufferIndex >= kReadThreadBufferSize) { 2311572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("TOOBIG: HDLC frame too big (Max: %d)", kReadThreadBufferSize); 2321572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mUnescapeNextByte = false; 2331572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mBufferIndex = 0; 2341572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mFcs = kHdlcCrcResetValue; 2351572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2361572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } else if (byte == HDLC_BYTE_FLAG) { 2371572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (mBufferIndex <= 2) { 2381572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum // Ignore really small frames. 2391572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum // Don't remove this or we will underflow our 2401572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum // index for onReceiveFrame(), below! 2411572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2421572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } else if (mUnescapeNextByte || (mFcs != kHdlcCrcCheckValue)) { 2431572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("GARBAGE: HDLC frame with bad CRC (LEN:%d, mFcs:0x%04X)", mBufferIndex, mFcs); 2441572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2451572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } else { 2461572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum // -2 for CRC 2471572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum sendFrame(mBuffer, uint16_t(mBufferIndex - 2)); 2481572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2491572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2501572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mUnescapeNextByte = false; 2511572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mBufferIndex = 0; 2521572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mFcs = kHdlcCrcResetValue; 2531572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2541572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } else if (byte == HDLC_BYTE_ESC) { 2551572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mUnescapeNextByte = true; 2561572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2571572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } else if (hdlc_byte_needs_escape(byte)) { 2581572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum // Skip all other control codes. 2591572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2601572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } else { 2611572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (mUnescapeNextByte) { 2621572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum byte = byte ^ HDLC_ESCAPE_XFORM; 2631572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mUnescapeNextByte = false; 2641572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2651572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2661572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mFcs = hdlc_crc16(mFcs, byte); 2671572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum mBuffer[mBufferIndex++] = byte; 2681572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2691572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2701572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum}; 2711572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2721572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaumint main(int argc, char* argv []) { 2731572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum using ::android::hardware::defaultServiceManager; 2741572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport; 2751572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2761572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum const char* serviceName = "default"; 2771572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2781572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (argc >= 2) { 2791572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum serviceName = argv[1]; 2801572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2811572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2821572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum sp<ILowpanDevice> service = ILowpanDevice::getService(serviceName, false /* getStub */); 2831572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2841572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (service == nullptr) { 2851572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("Unable to find LowpanDevice named \"%s\"", serviceName); 2861572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum exit(EXIT_FAILURE); 2871572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 2881572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2891572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum service->linkToDeath(new LowpanDeathRecipient(), 0 /*cookie*/); 2901572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2911572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum configureRpcThreadpool(1, true /* callerWillJoin */); 2921572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 293c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum sp<LowpanDeviceCallback> callback = new LowpanDeviceCallback(STDOUT_FILENO); 2941572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 2951572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum { 2961572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum auto status = service->open(callback); 2971572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (status.isOk()) { 2981572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum if (status == LowpanStatus::OK) { 2991572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGD("%s: open() ok.", serviceName); 3001572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } else { 3011572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("%s: open() failed: (%d).", serviceName, LowpanStatus(status)); 3021572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum exit(EXIT_FAILURE); 3031572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 3041572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } else { 3051572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGE("%s: open() failed: transport error", serviceName); 3061572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum exit(EXIT_FAILURE); 3071572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 3081572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum } 3091572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 310c47e2c6a99ddad9497bc3b390c47e363f38e11a4Robert Quattlebaum sp<Thread> readThread = new ReadThread(service, STDIN_FILENO, callback); 3111572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 3121572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum readThread->run("ReadThread"); 3131572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 3141572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum joinRpcThreadpool(); 3151572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 3161572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum ALOGI("Shutting down"); 3171572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum 3181572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum return EXIT_SUCCESS; 3191572e354fd9654ae8cb19caa7b8f88877586f362Robert Quattlebaum} 320