1// Copyright 2017 The Fuchsia 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. 4 5#include <assert.h> 6#include <errno.h> 7#include <fcntl.h> 8#include <stdbool.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12#include <unistd.h> 13 14#include <zircon/device/input.h> 15#include <zircon/types.h> 16 17#define CLEAR_SCREEN printf("\033[2J") 18#define CURSOR_MOVE(r, c) printf("\033[%d;%dH", r, c) 19#define CLEAR_LINE printf("\033[2K") 20 21static void process_sensor_input(void* buf, size_t len) { 22 uint8_t* report = buf; 23 if (len < 1) { 24 printf("bad report size: %zd < %d\n", len, 1); 25 return; 26 } 27 28 29 uint8_t report_id = report[0]; 30 CURSOR_MOVE(report_id + 1, 0); 31 CLEAR_LINE; 32 33 // TODO(teisenbe): Once we can decode these reports, output them decoded. 34 printf("%3d:", report_id); 35 for (size_t i = 1; i < len; ++i) { 36 printf(" %02x", report[i]); 37 } 38 printf("\n"); 39 fflush(stdout); 40} 41 42int main(int argc, char* argv[]) { 43 if (argc != 2) { 44 printf("Usage: %s /dev/class/input/<id>\n", argv[0]); 45 return -1; 46 } 47 48 const char* devname = argv[1]; 49 int fd = open(devname, O_RDONLY); 50 if (fd < 0) { 51 printf("failed to open %s: %d\n", devname, errno); 52 return -1; 53 } 54 55 size_t rpt_desc_len = 0; 56 uint8_t* rpt_desc = NULL; 57 58 ssize_t ret = ioctl_input_get_report_desc_size(fd, &rpt_desc_len); 59 if (ret < 0) { 60 printf("failed to get report descriptor length for %s: %zd\n", devname, ret); 61 return -1; 62 } 63 64 rpt_desc = malloc(rpt_desc_len); 65 if (rpt_desc == NULL) { 66 printf("no memory!\n"); 67 return -1; 68 } 69 70 ret = ioctl_input_get_report_desc(fd, rpt_desc, rpt_desc_len); 71 if (ret < 0) { 72 printf("failed to get report descriptor for %s: %zd\n", devname, ret); 73 return -1; 74 } 75 76 assert(rpt_desc_len > 0); 77 assert(rpt_desc); 78 79 input_report_size_t max_rpt_sz = 0; 80 ret = ioctl_input_get_max_reportsize(fd, &max_rpt_sz); 81 if (ret < 0) { 82 printf("failed to get max report size: %zd\n", ret); 83 return -1; 84 } 85 void* buf = malloc(max_rpt_sz); 86 if (buf == NULL) { 87 printf("no memory!\n"); 88 return -1; 89 } 90 91 CLEAR_SCREEN; 92 fflush(stdout); 93 while (1) { 94 ssize_t r = read(fd, buf, max_rpt_sz); 95 if (r < 0) { 96 printf("sensor read error: %zd (errno=%d)\n", r, errno); 97 break; 98 } 99 100 process_sensor_input(buf, r); 101 } 102 103 free(buf); 104 free(rpt_desc); 105 close(fd); 106 return 0; 107} 108