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