From f68bf51234f9bbeb0d18c3ca6d97778dce689c64 Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch Date: Mon, 25 Nov 2024 03:45:57 +0100 Subject: elksmart-comm: adjust code style --- elksmart-comm.c | 537 ++++++++++++++++++++++++++------------------------------ 1 file changed, 251 insertions(+), 286 deletions(-) diff --git a/elksmart-comm.c b/elksmart-comm.c index 98e100f..4d5d830 100644 --- a/elksmart-comm.c +++ b/elksmart-comm.c @@ -28,32 +28,30 @@ /// Search for a device with given vendor and product ID. /// This is quite similar to libusb_open_device_with_vid_pid(). static libusb_device_handle * -find_device (int vendor, int product, int *error) +find_device(int vendor, int product, int *error) { libusb_device **list = NULL; libusb_device_handle *handle = NULL; int result = 0; - ssize_t len = libusb_get_device_list (NULL, &list); - if (len < 0) - { + ssize_t len = libusb_get_device_list(NULL, &list); + if (len < 0) { result = len; goto out; } - for (ssize_t i = 0; i < len; i++) - { + for (ssize_t i = 0; i < len; i++) { libusb_device *device = list[i]; struct libusb_device_descriptor desc = {}; - if ((result = libusb_get_device_descriptor (device, &desc))) - print_debug ("%s", libusb_strerror (result)); + if ((result = libusb_get_device_descriptor(device, &desc))) + print_debug("%s", libusb_strerror(result)); else if (desc.idVendor != vendor || desc.idProduct != product) continue; - else if (!(result = libusb_open (device, &handle))) + else if (!(result = libusb_open(device, &handle))) break; } - libusb_free_device_list (list, true); + libusb_free_device_list(list, true); out: if (error != NULL && result != 0) *error = result; @@ -61,61 +59,60 @@ out: } static void -wait_ms (long ms) +wait_ms(long ms) { - struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; - nanosleep (&ts, NULL); + struct timespec ts = {ms / 1000, (ms % 1000) * 1000 * 1000}; + nanosleep(&ts, NULL); } static void -dump_hex (const unsigned char *buf, size_t len) +dump_hex(const unsigned char *buf, size_t len) { for (size_t i = 0; i < len; i++) - printf ("%02x", buf[i]); - printf ("\n"); + printf("%02x", buf[i]); + printf("\n"); } static bool -read_hex (const char *string, struct str *out) +read_hex(const char *string, struct str *out) { static const char *alphabet = "0123456789abcdef"; - str_reset (out); - while (true) - { - while (*string && strchr (" \t\n\r\v\f", *string)) + str_reset(out); + while (true) { + while (*string && strchr(" \t\n\r\v\f", *string)) string++; if (!*string) return true; const char *hi, *lo; - if (!(hi = strchr (alphabet, tolower_ascii (*string++))) || !*string - || !(lo = strchr (alphabet, tolower_ascii (*string++)))) + if (!(hi = strchr(alphabet, tolower_ascii(*string++))) || !*string || + !(lo = strchr(alphabet, tolower_ascii(*string++)))) return false; - str_pack_u8 (out, (hi - alphabet) << 4 | (lo - alphabet)); + str_pack_u8(out, (hi - alphabet) << 4 | (lo - alphabet)); } } // --- Coding ------------------------------------------------------------------ // Values are in microseconds. -struct pulse { unsigned on, off; }; +struct pulse { + unsigned on, off; +}; static bool -pulse_equal (struct pulse a, struct pulse b) +pulse_equal(struct pulse a, struct pulse b) { return a.on == b.on && a.off == b.off; } static size_t -decode_learned_direct (const uint8_t *b, size_t b_len, struct pulse *pulses) +decode_learned_direct(const uint8_t *b, size_t b_len, struct pulse *pulses) { size_t pulses_len = 0; - for (size_t i = 0; i < b_len; ) - { + for (size_t i = 0; i < b_len;) { struct pulse *pulse = &pulses[pulses_len++]; - while (b[i] == 0xff) - { + while (b[i] == 0xff) { pulse->on += 4080; if (++i == b_len) return 0; @@ -126,8 +123,7 @@ decode_learned_direct (const uint8_t *b, size_t b_len, struct pulse *pulses) if (i == b_len) break; - while (b[i] == 0xff) - { + while (b[i] == 0xff) { pulse->off += 4080; if (++i == b_len) return 0; @@ -138,80 +134,75 @@ decode_learned_direct (const uint8_t *b, size_t b_len, struct pulse *pulses) } static struct pulse * -decode_learned (const struct str *code, size_t *len, struct error **e) +decode_learned(const struct str *code, size_t *len, struct error **e) { // This conveniently has an upper bound. - struct pulse *pulses = xcalloc (code->len, sizeof *pulses); - if (!(*len = decode_learned_direct - ((const uint8_t *) code->str, code->len, pulses))) - { - error_set (e, "code ends unexpectedly"); - free (pulses); + struct pulse *pulses = xcalloc(code->len, sizeof *pulses); + if (!(*len = decode_learned_direct( + (const uint8_t *) code->str, code->len, pulses))) { + error_set(e, "code ends unexpectedly"); + free(pulses); return NULL; } return pulses; } static struct pulse * -encode_nec_byte (struct pulse *p, uint8_t byte) +encode_nec_byte(struct pulse *p, uint8_t byte) { for (int i = 7; i >= 0; i--) *p++ = (struct pulse) - { .on = 550, .off = ((byte >> i) & 1) ? 1650 : 550 }; + {.on = 550, .off = ((byte >> i) & 1) ? 1650 : 550}; return p; } static struct pulse * -encode_nec (const struct str *code, size_t *len, struct error **e) +encode_nec(const struct str *code, size_t *len, struct error **e) { - if (code->len % 2) - { - error_set (e, "NEC transmission format requires pairs"); + if (code->len % 2) { + error_set(e, "NEC transmission format requires pairs"); return NULL; } // The timings seem to be rather tolerant. *len = code->len / 2 * (1 /* leader */ + 32 + 1 /* stop */); - struct pulse *pulses = xcalloc (*len, sizeof *pulses), *p = pulses; - for (size_t i = 0; i < code->len; i += 2) - { - *p++ = (struct pulse) { .on = 8500, .off = 4250 }; - p = encode_nec_byte (p, code->str[i + 0]); - p = encode_nec_byte (p, ~code->str[i + 0]); - p = encode_nec_byte (p, code->str[i + 1]); - p = encode_nec_byte (p, ~code->str[i + 1]); - *p++ = (struct pulse) { .on = 550, .off = 25000 }; + struct pulse *pulses = xcalloc(*len, sizeof *pulses), *p = pulses; + for (size_t i = 0; i < code->len; i += 2) { + *p++ = (struct pulse) {.on = 8500, .off = 4250}; + p = encode_nec_byte(p, code->str[i + 0]); + p = encode_nec_byte(p, ~code->str[i + 0]); + p = encode_nec_byte(p, code->str[i + 1]); + p = encode_nec_byte(p, ~code->str[i + 1]); + *p++ = (struct pulse) {.on = 550, .off = 25000}; } return pulses; } static void -compress_value (unsigned value, struct str *encoded) +compress_value(unsigned value, struct str *encoded) { - if (value <= 2032) - { + if (value <= 2032) { // We fix a minor problem in the original Ocrustar algorithm. uint8_t v = value / 16. + .5; - str_pack_u8 (encoded, MAX (2, v)); - } - else - do - { + str_pack_u8(encoded, MAX(2, v)); + } else { + do { uint8_t v = value & 0x7f; if ((value >>= 7)) v |= 0x80; - str_pack_u8 (encoded, v); + str_pack_u8(encoded, v); } while (value); + } } static void compress_pulses (const struct pulse *pulses, size_t len, struct str *encoded) { unsigned counts[len]; - memset (counts, 0, sizeof counts); + memset(counts, 0, sizeof counts); for (size_t i = 0; i < len; i++) for (size_t k = 0; k < len; k++) - if (pulse_equal (pulses[i], pulses[k])) + if (pulse_equal(pulses[i], pulses[k])) counts[i]++; struct pulse p1 = {}, p2 = {}; @@ -220,8 +211,8 @@ compress_pulses (const struct pulse *pulses, size_t len, struct str *encoded) if (counts[i] > counts[top1]) p1 = pulses[top1 = i]; for (size_t i = 0; i < len; i++) - if (counts[i] < counts[top1] - && counts[i] > counts[top2]) + if (counts[i] < counts[top1] && + counts[i] > counts[top2]) p2 = pulses[top2 = i]; else if (counts[top2] == counts[top1]) p2 = pulses[top2 = i]; @@ -230,32 +221,29 @@ compress_pulses (const struct pulse *pulses, size_t len, struct str *encoded) // this will work even in the degenerated case of len <= 2. // XXX: The receiver might not like multibyte values here, // Ocrustar also oddly replaces 0xff with 0xfe for these fields. - compress_value (p2.on, encoded); - compress_value (p2.off, encoded); - compress_value (p1.on, encoded); - compress_value (p1.off, encoded); - str_pack_u8 (encoded, -1); - str_pack_u8 (encoded, -1); - str_pack_u8 (encoded, -1); - - for (size_t i = 0; i < len; i++) - { - if (pulse_equal (pulses[i], p1)) - str_pack_u8 (encoded, 0); - else if (pulse_equal (pulses[i], p2)) - str_pack_u8 (encoded, 1); - else - { - compress_value (pulses[i].on, encoded); - compress_value (pulses[i].off, encoded); + compress_value(p2.on, encoded); + compress_value(p2.off, encoded); + compress_value(p1.on, encoded); + compress_value(p1.off, encoded); + str_pack_u8(encoded, -1); + str_pack_u8(encoded, -1); + str_pack_u8(encoded, -1); + + for (size_t i = 0; i < len; i++) { + if (pulse_equal(pulses[i], p1)) { + str_pack_u8(encoded, 0); + } else if (pulse_equal(pulses[i], p2)) { + str_pack_u8(encoded, 1); + } else { + compress_value(pulses[i].on, encoded); + compress_value(pulses[i].off, encoded); } } } // --- Device interaction ------------------------------------------------------ -enum -{ +enum { USB_VENDOR_SMTCTL = 0x045c, // 0x134 (EKX5S ~ 5s, 5th generation remote) @@ -269,43 +257,39 @@ enum }; static uint8_t - c_transmit[] = { -1, -1, -1, -1 }, - c_learn[] = { -2, -2, -2, -2 }, - c_stop[] = { -3, -3, -3, -3 }, - c_identify[] = { -4, -4, -4, -4 }; + c_transmit[] = {-1, -1, -1, -1}, + c_learn[] = {-2, -2, -2, -2}, + c_stop[] = {-3, -3, -3, -3}, + c_identify[] = {-4, -4, -4, -4}; -static struct -{ +static struct { unsigned char endpoint_out; ///< Outgoing endpoint unsigned char endpoint_in; ///< Incoming endpoint -} -g; +} g; static bool -init_device_from_desc (struct libusb_config_descriptor *desc, struct error **e) +init_device_from_desc(struct libusb_config_descriptor *desc, struct error **e) { // We're not being particuarly strict in here. if (desc->bNumInterfaces != 1) - return error_set (e, "unexpected USB interface count"); + return error_set(e, "unexpected USB interface count"); if (desc->interface->num_altsetting != 1) - return error_set (e, "unexpected alternate setting count"); + return error_set(e, "unexpected alternate setting count"); const struct libusb_interface_descriptor *asd = desc->interface->altsetting; if (asd->bInterfaceClass != LIBUSB_CLASS_COMM) - return error_set (e, "unexpected USB interface class"); + return error_set(e, "unexpected USB interface class"); if (asd->bNumEndpoints != 2) - return error_set (e, "unexpected endpoint count"); + return error_set(e, "unexpected endpoint count"); bool have_out = false, have_in = false; - for (uint8_t i = 0; i < asd->bNumEndpoints; i++) - { + for (uint8_t i = 0; i < asd->bNumEndpoints; i++) { const struct libusb_endpoint_descriptor *epd = asd->endpoint + i; - if ((epd->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) - != LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK) - return error_set (e, "unexpected endpoint transfer type"); + if ((epd->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != + LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK) + return error_set(e, "unexpected endpoint transfer type"); - switch ((epd->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)) - { + switch ((epd->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)) { break; case LIBUSB_ENDPOINT_OUT: have_out = true; g.endpoint_out = epd->bEndpointAddress; @@ -315,39 +299,38 @@ init_device_from_desc (struct libusb_config_descriptor *desc, struct error **e) } } if (!have_out || !have_in) - return error_set (e, "USB interface is not bidirectional"); + return error_set(e, "USB interface is not bidirectional"); return true; } static bool -init_device (libusb_device_handle *device, struct error **e) +init_device(libusb_device_handle *device, struct error **e) { struct libusb_config_descriptor *desc = NULL; int result = - libusb_get_active_config_descriptor (libusb_get_device (device), &desc); + libusb_get_active_config_descriptor(libusb_get_device(device), &desc); if (result) - return error_set (e, "%s", libusb_strerror (result)); + return error_set(e, "%s", libusb_strerror(result)); bool ok = true; - if ((result = libusb_kernel_driver_active (device, USB_INTERFACE)) == 1) - ok = error_set (e, "device is claimed by a kernel driver"); + if ((result = libusb_kernel_driver_active(device, USB_INTERFACE)) == 1) + ok = error_set(e, "device is claimed by a kernel driver"); else if (result) - ok = error_set (e, "%s", libusb_strerror (result)); + ok = error_set(e, "%s", libusb_strerror(result)); else - ok = init_device_from_desc (desc, e); + ok = init_device_from_desc(desc, e); - libusb_free_config_descriptor (desc); + libusb_free_config_descriptor(desc); return ok; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static uint8_t -mangle (uint8_t value) +mangle(uint8_t value) { uint8_t reversed = 0; - for (int i = 0; i < 8; i++) - { + for (int i = 0; i < 8; i++) { reversed = (reversed << 1) | (value & 1); value >>= 1; } @@ -355,202 +338,191 @@ mangle (uint8_t value) } static uint8_t -checksum (const uint8_t *b, size_t len) +checksum(const uint8_t *b, size_t len) { uint32_t sum = 0; for (size_t i = 0; i < len; i++) sum += b[i]; - return mangle ((sum & 0xF0) | ((sum >> 8) & 0x0F)); + return mangle((sum & 0xF0) | ((sum >> 8) & 0x0F)); } static bool -send_transmit (libusb_device_handle *device, unsigned long frequency, +send_transmit(libusb_device_handle *device, unsigned long frequency, const struct pulse *pulses, size_t pulses_len, struct error **e) { if (g_debug_mode) - for (size_t i = 0; i < pulses_len; ) - { - printf ("%u,%u", pulses[i].on, pulses[i].off); - putchar (++i == pulses_len ? '\n' : ','); + for (size_t i = 0; i < pulses_len;) { + printf("%u,%u", pulses[i].on, pulses[i].off); + putchar(++i == pulses_len ? '\n' : ','); } - struct str compressed = str_make (); - compress_pulses (pulses, pulses_len, &compressed); + struct str compressed = str_make(); + compress_pulses(pulses, pulses_len, &compressed); - struct str message = str_make (); - str_append_data (&message, c_transmit, sizeof c_transmit); + struct str message = str_make(); + str_append_data(&message, c_transmit, sizeof c_transmit); frequency += 0x7ffff; - str_pack_u8 (&message, mangle (frequency >> 8)); - str_pack_u8 (&message, mangle (frequency >> 16)); - str_pack_u8 (&message, mangle (frequency)); - str_pack_u8 (&message, mangle (compressed.len >> 8)); - str_pack_u8 (&message, mangle (compressed.len)); - str_append_str (&message, &compressed); - str_free (&compressed); + str_pack_u8(&message, mangle(frequency >> 8)); + str_pack_u8(&message, mangle(frequency >> 16)); + str_pack_u8(&message, mangle(frequency)); + str_pack_u8(&message, mangle(compressed.len >> 8)); + str_pack_u8(&message, mangle(compressed.len)); + str_append_str(&message, &compressed); + str_free(&compressed); size_t i = 0; uint8_t buffer[64]; bool ok = true; - while (i != message.len) - { - size_t chunk = MIN (62, message.len - i); - memcpy (buffer, message.str + i, chunk); + while (i != message.len) { + size_t chunk = MIN(62, message.len - i); + memcpy(buffer, message.str + i, chunk); i += chunk; - if (chunk == 62) - { - buffer[chunk] = checksum (buffer, chunk); + if (chunk == 62) { + buffer[chunk] = checksum(buffer, chunk); chunk++; } int result = 0, len = 0; - if ((result = libusb_bulk_transfer (device, g.endpoint_out, - buffer, chunk, &len, 100))) - { - ok = error_set (e, "send: %s", libusb_strerror (result)); + if ((result = libusb_bulk_transfer( + device, g.endpoint_out, buffer, chunk, &len, 100))) { + ok = error_set(e, "send: %s", libusb_strerror(result)); break; } - wait_ms (2); + wait_ms(2); } - str_free (&message); + str_free(&message); return ok; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static bool -pulse_is_likely_leader (const struct pulse *p) +pulse_is_likely_leader(const struct pulse *p) { return p->on >= 2048 && p->off >= 2048; } static void -try_to_depulse (const struct str *code) +try_to_depulse(const struct str *code) { size_t len = 0; - struct pulse *pulses = decode_learned (code, &len, NULL); + struct pulse *pulses = decode_learned(code, &len, NULL); if (!pulses) return; struct pulse *p = pulses, *end = p + len; - while (p != end && pulse_is_likely_leader (p)) - { + while (p != end && pulse_is_likely_leader(p)) { p++; - printf ("Attempted pulse decode:\n"); + printf("Attempted pulse decode:\n"); uint8_t bits = 0, nibble = 0; - for (; p != end && !pulse_is_likely_leader (p); p++) - { + for (; p != end && !pulse_is_likely_leader(p); p++) { nibble = nibble << 1 | (p->off > 2 * p->on); - if (++bits == 4) - { - putchar ("0123456789abcdef"[nibble]); + if (++bits == 4) { + putchar("0123456789abcdef"[nibble]); bits = nibble = 0; } } - putchar ('\n'); + putchar('\n'); } - free (pulses); + free(pulses); } static bool -recv_learn (libusb_device_handle *device, struct str *data, struct error **e) +recv_learn(libusb_device_handle *device, struct str *data, struct error **e) { uint8_t buffer[64] = {}; int result = 0, len = 0; - while ((result = libusb_bulk_transfer (device, g.endpoint_in, - buffer, sizeof buffer, &len, 100))) - { + while ((result = libusb_bulk_transfer( + device, g.endpoint_in, buffer, sizeof buffer, &len, 100))) { if (result != LIBUSB_ERROR_TIMEOUT) - return error_set (e, "learn/recv: %s", libusb_strerror (result)); - print_debug ("learn/recv: %s", libusb_strerror (result)); + return error_set(e, "learn/recv: %s", libusb_strerror(result)); + print_debug("learn/recv: %s", libusb_strerror(result)); } - if (len < 6 || memcmp (buffer, c_learn, sizeof c_learn)) - return error_set (e, "learn/recv: %s", "unexpected response"); + if (len < 6 || memcmp(buffer, c_learn, sizeof c_learn)) + return error_set(e, "learn/recv: %s", "unexpected response"); // This field might only make sense for a later device, // because it doesn't always correspond with how much data we receive. // Nonetheless, it does match exactly often enough. size_t size = buffer[4] << 8 | buffer[5]; - print_debug ("learn: code size: %zu", size); - - str_append_data (data, buffer + 6, len - 6); - dump_hex ((const unsigned char *) data->str, data->len); - while (data->len < size) - { - if (!(result = libusb_bulk_transfer (device, g.endpoint_in, - buffer, sizeof buffer, &len, 100))) - { - dump_hex (buffer, len); - - str_append_data (data, buffer, len); - print_debug ("learn: received %d (have %zu of %zu)", - len, data->len, size); + print_debug("learn: code size: %zu", size); + + str_append_data(data, buffer + 6, len - 6); + dump_hex((const unsigned char *) data->str, data->len); + while (data->len < size) { + if (!(result = libusb_bulk_transfer( + device, g.endpoint_in, buffer, sizeof buffer, &len, 100))) { + dump_hex(buffer, len); + + str_append_data(data, buffer, len); + print_debug( + "learn: received %d (have %zu of %zu)", len, data->len, size); continue; } if (result != LIBUSB_ERROR_TIMEOUT) - return error_set (e, "learn/recv: %s", libusb_strerror (result)); + return error_set(e, "learn/recv: %s", libusb_strerror(result)); // The device seems to queue up its output with pauses. - print_debug ("learn/recv: %s", libusb_strerror (result)); + print_debug("learn/recv: %s", libusb_strerror(result)); } // As far as I know, this doesn't do anything, // and the device doesn't accept it while scanning infrared codes either. - if ((result = libusb_bulk_transfer (device, g.endpoint_out, - c_stop, sizeof c_stop, &len, 100))) - return error_set (e, "learn/send: %s", libusb_strerror (result)); + if ((result = libusb_bulk_transfer( + device, g.endpoint_out, c_stop, sizeof c_stop, &len, 100))) + return error_set(e, "learn/send: %s", libusb_strerror(result)); return true; } static bool -send_learn (libusb_device_handle *device, struct error **e) +send_learn(libusb_device_handle *device, struct error **e) { int result = 0, len = 0; - if ((result = libusb_bulk_transfer (device, g.endpoint_out, - c_learn, sizeof c_learn, &len, 100))) - return error_set (e, "learn/send: %s", libusb_strerror (result)); + if ((result = libusb_bulk_transfer( + device, g.endpoint_out, c_learn, sizeof c_learn, &len, 100))) + return error_set(e, "learn/send: %s", libusb_strerror(result)); - printf ("Reading remote control codes.\n"); - printf ("Press a remote control button from less than a centimeter.\n"); - printf ("The dongle may be unusable until it returns some data.\n"); + printf("Reading remote control codes.\n"); + printf("Press a remote control button from less than a centimeter.\n"); + printf("The dongle may be unusable until it returns some data.\n"); // ... Resetting the device using libusb_reset_device() doesn't help then. - printf ("If the code fails to replay, retry the capture.\n"); - - struct str data = str_make (); - bool ok = recv_learn (device, &data, e); - if (ok) - { - printf ("Full command:\n"); - dump_hex ((const unsigned char *) data.str, data.len); - try_to_depulse (&data); + printf("If the code fails to replay, retry the capture.\n"); + + struct str data = str_make(); + bool ok = recv_learn(device, &data, e); + if (ok) { + printf("Full command:\n"); + dump_hex((const unsigned char *) data.str, data.len); + try_to_depulse(&data); } - str_free (&data); + str_free(&data); return ok; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static bool -send_identify (libusb_device_handle *device, struct error **e) +send_identify(libusb_device_handle *device, struct error **e) { uint8_t buffer[64] = {}; int result = 0, len = 0; - while (!(result = libusb_bulk_transfer (device, g.endpoint_in, - buffer, sizeof buffer, &len, 10))) + while (!(result = libusb_bulk_transfer( + device, g.endpoint_in, buffer, sizeof buffer, &len, 10))) /* Flush buffers. */; - if ((result = libusb_bulk_transfer (device, g.endpoint_out, - c_identify, sizeof c_identify, &len, 100))) - return error_set (e, "identify/send: %s", libusb_strerror (result)); - if ((result = libusb_bulk_transfer (device, g.endpoint_in, - buffer, sizeof buffer, &len, 100))) - return error_set (e, "identify/recv: %s", libusb_strerror (result)); + if ((result = libusb_bulk_transfer( + device, g.endpoint_out, c_identify, sizeof c_identify, &len, 100))) + return error_set(e, "identify/send: %s", libusb_strerror(result)); + if ((result = libusb_bulk_transfer( + device, g.endpoint_in, buffer, sizeof buffer, &len, 100))) + return error_set(e, "identify/recv: %s", libusb_strerror(result)); // XXX: Sometimes, the device doesn't send any identification values. - if (len != 6 || memcmp (buffer, c_identify, sizeof c_identify) - || buffer[4] != 0x70 || buffer[5] != 0x01) - return error_set (e, "device busy or not supported"); + if (len != 6 || memcmp(buffer, c_identify, sizeof c_identify) || + buffer[4] != 0x70 || buffer[5] != 0x01) + return error_set(e, "device busy or not supported"); #if 0 // The EKX4S does not respond to this request. @@ -561,143 +533,136 @@ send_identify (libusb_device_handle *device, struct error **e) if ((result = libusb_bulk_transfer (device, g.endpoint_in, buffer, sizeof buffer, &len, 100))) return error_set (e, "serial/recv: %s", libusb_strerror (result)); - if (len < (int) sizeof c_serial - || memcmp (buffer, c_serial, sizeof c_serial)) + if (len < (int) sizeof c_serial || + memcmp (buffer, c_serial, sizeof c_serial)) return error_set (e, "serial retrieval failed"); #endif return true; } static bool -run (libusb_device_handle *device, unsigned long frequency, bool nec, +run(libusb_device_handle *device, unsigned long frequency, bool nec, char **codes, size_t codes_len, struct error **e) { - if (!send_identify (device, e)) + if (!send_identify(device, e)) return false; if (!codes_len) - return send_learn (device, e); + return send_learn(device, e); - struct str code = str_make (); + struct str code = str_make(); bool ok = true; - for (size_t i = 0; i < codes_len; i++) - { - if (!read_hex (codes[i], &code)) - { - ok = error_set (e, "invalid hex string"); + for (size_t i = 0; i < codes_len; i++) { + if (!read_hex(codes[i], &code)) { + ok = error_set(e, "invalid hex string"); break; } size_t pulses_len = 0; struct pulse *pulses = nec - ? encode_nec (&code, &pulses_len, e) - : decode_learned (&code, &pulses_len, e); + ? encode_nec(&code, &pulses_len, e) + : decode_learned(&code, &pulses_len, e); - ok = pulses && send_transmit (device, frequency, pulses, pulses_len, e); - free (pulses); + ok = pulses && send_transmit(device, frequency, pulses, pulses_len, e); + free(pulses); if (!ok) break; - wait_ms (100); + wait_ms(100); } - str_free (&code); + str_free(&code); return ok; } // --- Main -------------------------------------------------------------------- int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { unsigned long frequency = 38000; bool nec = false; - static const struct opt opts[] = - { - { 'd', "debug", NULL, 0, "run in debug mode" }, - { 'f', "frequency", "HZ", 0, "frequency (38000 Hz by default)" }, - { 'n', "nec", NULL, 0, "use the NEC transmission format" }, - { 'h', "help", NULL, 0, "display this help and exit" }, - { 'V', "version", NULL, 0, "output version information and exit" }, - { 0, NULL, NULL, 0, NULL } - }; - - struct opt_handler oh = opt_handler_make (argc, argv, opts, "[COMMAND...]", + static const struct opt opts[] = { + {'d', "debug", NULL, 0, "run in debug mode"}, + {'f', "frequency", "HZ", 0, "frequency (38000 Hz by default)"}, + {'n', "nec", NULL, 0, "use the NEC transmission format"}, + {'h', "help", NULL, 0, "display this help and exit"}, + {'V', "version", NULL, 0, "output version information and exit"}, + {0, NULL, NULL, 0, NULL}}; + + struct opt_handler oh = opt_handler_make(argc, argv, opts, "[COMMAND...]", "Transmit or receive infrared commands."); int c; - while ((c = opt_handler_get (&oh)) != -1) - switch (c) - { + while ((c = opt_handler_get(&oh)) != -1) + switch (c) { case 'd': g_debug_mode = true; break; case 'f': - if (!xstrtoul (&frequency, optarg, 10) || !frequency) - exit_fatal ("invalid frequency"); + if (!xstrtoul(&frequency, optarg, 10) || !frequency) + exit_fatal("invalid frequency"); break; case 'n': nec = true; break; case 'h': - opt_handler_usage (&oh, stdout); - exit (EXIT_SUCCESS); + opt_handler_usage(&oh, stdout); + exit(EXIT_SUCCESS); case 'V': - printf (PROGRAM_NAME " " PROGRAM_VERSION "\n"); - exit (EXIT_SUCCESS); + printf(PROGRAM_NAME " " PROGRAM_VERSION "\n"); + exit(EXIT_SUCCESS); default: - print_error ("wrong options"); - opt_handler_usage (&oh, stderr); - exit (EXIT_FAILURE); + print_error("wrong options"); + opt_handler_usage(&oh, stderr); + exit(EXIT_FAILURE); } argc -= optind; argv += optind; - opt_handler_free (&oh); + opt_handler_free(&oh); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #if LIBUSB_API_VERSION >= 0x0100010A - const struct libusb_init_option option = - { + const struct libusb_init_option option = { .option = LIBUSB_OPTION_LOG_LEVEL, .value.ival = LIBUSB_LOG_LEVEL_DEBUG, }; - int result = libusb_init_context (NULL, &option, g_debug_mode); + int result = libusb_init_context(NULL, &option, g_debug_mode); #else - int result = libusb_init (NULL); + int result = libusb_init(NULL); #endif if (result) - exit_fatal ("libusb: %s", libusb_strerror (result)); + exit_fatal("libusb: %s", libusb_strerror(result)); libusb_device_handle *device = NULL; if (!device && !result) - device = find_device (USB_VENDOR_SMTCTL, - USB_PRODUCT_SMTCTL_SMART_EKX4S, &result); + device = find_device( + USB_VENDOR_SMTCTL, USB_PRODUCT_SMTCTL_SMART_EKX4S, &result); if (!device && !result) - device = find_device (USB_VENDOR_SMTCTL, - USB_PRODUCT_SMTCTL_SMART_EKX5S_T, &result); + device = find_device( + USB_VENDOR_SMTCTL, USB_PRODUCT_SMTCTL_SMART_EKX5S_T, &result); if (result) - exit_fatal ("couldn't open device: %s", libusb_strerror (result)); + exit_fatal("couldn't open device: %s", libusb_strerror(result)); else if (!device) - exit_fatal ("no suitable device found"); + exit_fatal("no suitable device found"); struct error *e = NULL; - if (!init_device (device, &e)) - exit_fatal ("%s", e->message); - if ((result = libusb_claim_interface (device, USB_INTERFACE)) == 1) - exit_fatal ("couldn't claim interface: %s", libusb_strerror (result)); - - if (!run (device, frequency, nec, argv, argc, &e)) - { - print_error ("%s", e->message); - error_free (e); + if (!init_device(device, &e)) + exit_fatal("%s", e->message); + if ((result = libusb_claim_interface(device, USB_INTERFACE)) == 1) + exit_fatal("couldn't claim interface: %s", libusb_strerror(result)); + + if (!run(device, frequency, nec, argv, argc, &e)) { + print_error("%s", e->message); + error_free(e); } - if ((result = libusb_release_interface (device, USB_INTERFACE)) == 1) - exit_fatal ("couldn't release interface: %s", libusb_strerror (result)); + if ((result = libusb_release_interface(device, USB_INTERFACE)) == 1) + exit_fatal("couldn't release interface: %s", libusb_strerror(result)); - libusb_close (device); - libusb_exit (NULL); + libusb_close(device); + libusb_exit(NULL); return 0; } -- cgit v1.2.3-70-g09d2