source: mainline/uspace/app/mkbd/main.c@ 338d54a7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 338d54a7 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 7.2 KB
RevLine 
[4880210]1/*
2 * Copyright (c) 2011 Lubos Slovak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup mkbd
30 * @{
31 */
32/**
33 * @file
34 * Sample application using the data from multimedia keys on keyboard
35 */
36
37#include <inttypes.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <errno.h>
41#include <str_error.h>
[3e6a98c5]42#include <stdbool.h>
[4880210]43#include <getopt.h>
44#include <devman.h>
[15f3c3f]45#include <loc.h>
[a44424f]46#include <usbhid_iface.h>
[b2995c3]47#include <usb/dev/pipes.h>
[4e78236]48#include <async.h>
[1a38701]49#include <usb/dev.h>
[d7c72db]50#include <usb/hid/usages/core.h>
51#include <usb/hid/hidparser.h>
52#include <usb/hid/hiddescriptor.h>
53#include <usb/hid/usages/consumer.h>
[2e833cf7]54#include <io/console.h>
55#include <io/keycode.h>
[d7c72db]56#include <assert.h>
[4880210]57
58#define NAME "mkbd"
59
[79ae36dd]60static async_sess_t *dev_sess = NULL;
[4880210]61
[b7fd2a0]62static errno_t initialize_report_parser(async_sess_t *dev_sess,
[79ae36dd]63 usb_hid_report_t **report)
[d7c72db]64{
[79ae36dd]65 *report = (usb_hid_report_t *) malloc(sizeof(usb_hid_report_t));
66 if (*report == NULL)
[d7c72db]67 return ENOMEM;
[a35b458]68
[b7fd2a0]69 errno_t rc = usb_hid_report_init(*report);
[d7c72db]70 if (rc != EOK) {
[a8c4e871]71 usb_hid_report_deinit(*report);
[fa8d346]72 *report = NULL;
[d7c72db]73 return rc;
74 }
[a35b458]75
[79ae36dd]76 /* Get the report descriptor length from the device */
[d7c72db]77 size_t report_desc_size;
[79ae36dd]78 rc = usbhid_dev_get_report_descriptor_length(dev_sess,
79 &report_desc_size);
[d7c72db]80 if (rc != EOK) {
[a8c4e871]81 usb_hid_report_deinit(*report);
[fa8d346]82 *report = NULL;
[d7c72db]83 return rc;
84 }
[a35b458]85
[d7c72db]86 if (report_desc_size == 0) {
[a8c4e871]87 usb_hid_report_deinit(*report);
[fa8d346]88 *report = NULL;
[79ae36dd]89 // TODO: other error code?
90 return EINVAL;
[d7c72db]91 }
[a35b458]92
[79ae36dd]93 uint8_t *desc = (uint8_t *) malloc(report_desc_size);
[d7c72db]94 if (desc == NULL) {
[a8c4e871]95 usb_hid_report_deinit(*report);
[fa8d346]96 *report = NULL;
[d7c72db]97 return ENOMEM;
98 }
[a35b458]99
[79ae36dd]100 /* Get the report descriptor from the device */
[d7c72db]101 size_t actual_size;
[79ae36dd]102 rc = usbhid_dev_get_report_descriptor(dev_sess, desc, report_desc_size,
[d7c72db]103 &actual_size);
104 if (rc != EOK) {
[a8c4e871]105 usb_hid_report_deinit(*report);
[fa8d346]106 *report = NULL;
[d7c72db]107 free(desc);
108 return rc;
109 }
[a35b458]110
[d7c72db]111 if (actual_size != report_desc_size) {
[a8c4e871]112 usb_hid_report_deinit(*report);
[fa8d346]113 *report = NULL;
[d7c72db]114 free(desc);
[79ae36dd]115 // TODO: other error code?
116 return EINVAL;
[d7c72db]117 }
[a35b458]118
[79ae36dd]119 /* Initialize the report parser */
[a35b458]120
[fa8d346]121 rc = usb_hid_parse_report_descriptor(*report, desc, report_desc_size);
[d7c72db]122 free(desc);
[a35b458]123
[e540424a]124 return rc;
[d7c72db]125}
[4880210]126
[d7c72db]127static void print_key(uint8_t *buffer, size_t size, usb_hid_report_t *report)
128{
129 assert(buffer != NULL);
130 assert(report != NULL);
[a35b458]131
[d7c72db]132 uint8_t report_id;
[b7fd2a0]133 errno_t rc = usb_hid_parse_report(report, buffer, size, &report_id);
[79ae36dd]134 if (rc != EOK)
[da56be2]135 return;
[a35b458]136
[d7c72db]137 usb_hid_report_path_t *path = usb_hid_report_path();
138 if (path == NULL) {
139 return;
140 }
[a35b458]141
[d7c72db]142 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
[a35b458]143
[d7c72db]144 usb_hid_report_path_set_report_id(path, report_id);
[4880210]145
[d7c72db]146 usb_hid_report_field_t *field = usb_hid_report_get_sibling(
[79ae36dd]147 report, NULL, path, USB_HID_PATH_COMPARE_END
148 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
[d7c72db]149 USB_HID_REPORT_TYPE_INPUT);
[a35b458]150
[d7c72db]151 while (field != NULL) {
152 if (field->value != 0) {
[1b20da0]153 const char *key_str =
[d7c72db]154 usbhid_multimedia_usage_to_str(field->usage);
155 printf("Pressed key: %s\n", key_str);
156 }
[a35b458]157
[d7c72db]158 field = usb_hid_report_get_sibling(
159 report, field, path, USB_HID_PATH_COMPARE_END
[1b20da0]160 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
[d7c72db]161 USB_HID_REPORT_TYPE_INPUT);
162 }
[a35b458]163
[d7c72db]164 usb_hid_report_path_free(path);
165}
[4880210]166
[b7fd2a0]167static errno_t wait_for_quit_fibril(void *arg)
[2e833cf7]168{
169 console_ctrl_t *con = console_init(stdin, stdout);
170
171 printf("Press <ESC> to quit the application.\n");
172
173 while (1) {
[07b7c48]174 cons_event_t ev;
175 bool ok = console_get_event(con, &ev);
[2e833cf7]176 if (!ok) {
177 printf("Connection with console broken: %s.\n",
178 str_error(errno));
179 break;
180 }
181
[07b7c48]182 if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS &&
183 ev.ev.key.key == KC_ESCAPE) {
[2e833cf7]184 break;
185 }
186 }
187
188 console_done(con);
189
190 exit(0);
191
192 return EOK;
193}
194
[d7c72db]195#define MAX_PATH_LENGTH 1024
[4880210]196
197static void print_usage(char *app_name)
198{
199#define _INDENT " "
[79ae36dd]200 printf(NAME ": Print out what multimedia keys were pressed.\n\n");
201 printf("Usage: %s device\n", app_name);
202 printf(_INDENT "The device is a devman path to the device.\n");
[4880210]203#undef _OPTION
204#undef _INDENT
205}
206
207int main(int argc, char *argv[])
208{
[266fcd8]209 int act_event = -1;
[a35b458]210
[4880210]211 if (argc <= 1) {
212 print_usage(argv[0]);
213 return -1;
214 }
[a35b458]215
[5c2c459]216 char *devpath = argv[1];
[a35b458]217
[e765ccb]218 devman_handle_t dev_handle = 0;
[a35b458]219
[b7fd2a0]220 errno_t rc = usb_resolve_device_handle(devpath, &dev_handle);
[4880210]221 if (rc != EOK) {
[f9a627a]222 printf("Device not found or not of USB kind: %s.\n",
[e765ccb]223 str_error(rc));
224 return rc;
[4880210]225 }
[a35b458]226
[f9b2cb4c]227 async_sess_t *sess = devman_device_connect(dev_handle, 0);
[79ae36dd]228 if (!sess) {
[e765ccb]229 printf(NAME ": failed to connect to the device (handle %"
[79ae36dd]230 PRIun "): %s.\n", dev_handle, str_error(errno));
231 return errno;
[4880210]232 }
[a35b458]233
[79ae36dd]234 dev_sess = sess;
[a35b458]235
[e765ccb]236 char path[MAX_PATH_LENGTH];
[7beb220]237 rc = devman_fun_get_path(dev_handle, path, MAX_PATH_LENGTH);
[e765ccb]238 if (rc != EOK) {
[c1694b6b]239 printf(NAME ": failed to get path (handle %"
240 PRIun "): %s.\n", dev_handle, str_error(errno));
[e765ccb]241 return ENOMEM;
242 }
[a35b458]243
[e765ccb]244 printf("Device path: %s\n", path);
[a35b458]245
246
[d7c72db]247 usb_hid_report_t *report = NULL;
[79ae36dd]248 rc = initialize_report_parser(dev_sess, &report);
[d7c72db]249 if (rc != EOK) {
250 printf("Failed to initialize report parser: %s\n",
251 str_error(rc));
252 return rc;
253 }
[a35b458]254
[d7c72db]255 assert(report != NULL);
[a35b458]256
[e765ccb]257 size_t size;
[79ae36dd]258 rc = usbhid_dev_get_event_length(dev_sess, &size);
[e765ccb]259 if (rc != EOK) {
[d7c72db]260 printf("Failed to get event length: %s.\n", str_error(rc));
[e765ccb]261 return rc;
262 }
[a35b458]263
[d7c72db]264 uint8_t *event = (uint8_t *)malloc(size);
[e765ccb]265 if (event == NULL) {
[c1694b6b]266 printf("Out of memory.\n");
[79ae36dd]267 // TODO: hangup phone?
[e765ccb]268 return ENOMEM;
269 }
[a35b458]270
[2e833cf7]271 fid_t quit_fibril = fibril_create(wait_for_quit_fibril, NULL);
272 if (quit_fibril == 0) {
273 printf("Failed to start extra fibril.\n");
274 return -1;
275 }
276 fibril_add_ready(quit_fibril);
277
[e765ccb]278 size_t actual_size;
[266fcd8]279 int event_nr;
[a35b458]280
[79ae36dd]281 while (true) {
[d7c72db]282 /** @todo Try blocking call. */
[1b20da0]283 rc = usbhid_dev_get_event(dev_sess, event, size, &actual_size,
[266fcd8]284 &event_nr, 0);
[e765ccb]285 if (rc != EOK) {
[79ae36dd]286 // TODO: hangup phone?
[e765ccb]287 printf("Error in getting event from the HID driver:"
288 "%s.\n", str_error(rc));
289 break;
290 }
[a35b458]291
[266fcd8]292 if (event_nr > act_event) {
293 print_key(event, size, report);
294 act_event = event_nr;
295 }
[a35b458]296
[61f49a0]297 async_usleep(10000);
[e765ccb]298 }
[a35b458]299
[4880210]300 return 0;
301}
302
303/** @}
304 */
Note: See TracBrowser for help on using the repository browser.