Home | History | Annotate | Download | only in dumpstate
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "dumpstate"
     18 
     19 #include "DumpstateDevice.h"
     20 
     21 #include "DumpstateUtil.h"
     22 
     23 #include <errno.h>
     24 #include <log/log.h>
     25 #include <fcntl.h>
     26 #include <stdlib.h>
     27 #include <stdio.h>
     28 #include <string.h>
     29 
     30 static const char base64[] =
     31     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     32 static const char pad64 = '=';
     33 
     34 using android::os::dumpstate::CommandOptions;
     35 using android::os::dumpstate::DumpFileToFd;
     36 using android::os::dumpstate::RunCommandToFd;
     37 
     38 namespace android {
     39 namespace hardware {
     40 namespace dumpstate {
     41 namespace V1_0 {
     42 namespace implementation {
     43 
     44 static void base64_output3(int out_fd, const unsigned char *src, int len)
     45 {
     46     dprintf(out_fd, "%c", base64[src[0] >> 2]);
     47     dprintf(out_fd, "%c", base64[((src[0] & 0x03) << 4) | (src[1] >> 4)]);
     48     if (len == 1) {
     49         dprintf(out_fd, "==");
     50         return;
     51     }
     52     dprintf(out_fd, "%c", base64[((src[1] & 0x0F) << 2) | (src[2] >> 6)]);
     53     if (len == 2) {
     54         dprintf(out_fd, "=");
     55         return;
     56     }
     57     dprintf(out_fd, "%c", base64[src[2] & 0x3F]);
     58 }
     59 
     60 static void fugu_dump_base64(int out_fd, const char *path)
     61 {
     62 
     63     dprintf(out_fd, "------ (%s) ------\n", path);
     64     int fd = open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
     65     if (fd < 0) {
     66         dprintf(out_fd, "*** %s: %s\n\n", path, strerror(errno));
     67         return;
     68     }
     69 
     70     /* buffer size multiple of 3 for ease of use */
     71     unsigned char buffer[1200];
     72     int left = 0;
     73     int count = 0;
     74     for (;;) {
     75         int ret = read(fd, &buffer[left], sizeof(buffer) - left);
     76         if (ret <= 0) {
     77             break;
     78         }
     79         left += ret;
     80         int ofs = 0;
     81         while (left > 2) {
     82             base64_output3(out_fd, &buffer[ofs], 3);
     83             left -= 3;
     84             ofs += 3;
     85             count += 4;
     86             if (count > 72) {
     87                 dprintf(out_fd, "\n");
     88                 count = 0;
     89             }
     90         }
     91         if (left) {
     92             memmove(buffer, &buffer[ofs], left);
     93         }
     94     }
     95     close(fd);
     96 
     97     if (!left) {
     98         dprintf(out_fd, "\n------ end ------\n");
     99         return;
    100     }
    101 
    102     /* finish padding */
    103     count = left;
    104     while (count < 3) {
    105         buffer[count++] = 0;
    106     }
    107     base64_output3(out_fd, buffer, left);
    108 
    109     dprintf(out_fd, "\n------ end ------\n");
    110 }
    111 
    112 // Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow.
    113 Return<void> DumpstateDevice::dumpstateBoard(const hidl_handle& handle) {
    114     if (handle->numFds < 1) {
    115         ALOGE("no FDs\n");
    116         return Void();
    117     }
    118 
    119     int fd = handle->data[0];
    120     if (fd < 0) {
    121         ALOGE("invalid FD: %d\n", handle->data[0]);
    122         return Void();
    123     }
    124 
    125     DumpFileToFd(fd, "INTERRUPTS", "/proc/interrupts");
    126     DumpFileToFd(fd, "last ipanic_console", "/data/dontpanic/ipanic_console");
    127     DumpFileToFd(fd, "last ipanic_threads", "/data/dontpanic/ipanic_threads");
    128 
    129     fugu_dump_base64(fd, "/dev/snd_atvr_mSBC");
    130     fugu_dump_base64(fd, "/dev/snd_atvr_pcm");
    131 
    132     return Void();
    133 }
    134 
    135 }  // namespace implementation
    136 }  // namespace V1_0
    137 }  // namespace dumpstate
    138 }  // namespace hardware
    139 }  // namespace android
    140