// new Function([arg1[, arg2[, ...]],] functionBody) js_val * func_new(js_val *instance, js_args *args, eval_state *state) { unsigned arglen = ARGLEN(args); unsigned i = 0; char *arg_lst = NULL; char *tmp; for (i = 0; arglen > 0 && i < (arglen - 1); i++) { if (!arg_lst) { arg_lst = TO_STR(ARG(args, i))->string.ptr; } else { tmp = arg_lst; arg_lst = fh_str_concat(arg_lst, ", "); free(tmp); tmp = arg_lst; arg_lst = fh_str_concat(arg_lst, TO_STR(ARG(args, i))->string.ptr); free(tmp); } } if (arglen <= 1) arg_lst = ""; char *body = arglen > 0 ? TO_STR(ARG(args, i))->string.ptr : ""; char *fmt = "(function(%s) { %s });"; int size = snprintf(NULL, 0, fmt, arg_lst, body) + 1; char *func_def = malloc(size); snprintf(func_def, size, fmt, arg_lst, body); return fh_eval_string(func_def, state->ctx); }
static int hdfsSingleNameNodeConnect(struct NativeMiniDfsCluster *cl, hdfsFS *fs, const char *username) { int ret; tPort port; hdfsFS hdfs; struct hdfsBuilder *bld; port = (tPort)nmdGetNameNodePort(cl); if (port < 0) { fprintf(stderr, "hdfsSingleNameNodeConnect: nmdGetNameNodePort " "returned error %d\n", port); return port; } bld = hdfsNewBuilder(); if (!bld) return -ENOMEM; hdfsBuilderSetForceNewInstance(bld); hdfsBuilderSetNameNode(bld, "localhost"); hdfsBuilderSetNameNodePort(bld, port); hdfsBuilderConfSetStr(bld, "dfs.block.size", TO_STR(TLH_DEFAULT_BLOCK_SIZE)); hdfsBuilderConfSetStr(bld, "dfs.blocksize", TO_STR(TLH_DEFAULT_BLOCK_SIZE)); if (username) { hdfsBuilderSetUserName(bld, username); } hdfs = hdfsBuilderConnect(bld); if (!hdfs) { ret = -errno; return ret; } *fs = hdfs; return 0; }
void free_input() { int i; if( input_strs_args ) { for( i = 0; i < size_input_prm; ++i ) { if( input_strs_args[i] ) { free( input_strs_args[i] ); } } free( input_strs_args ); } if( input_strs_file ) { for( i = 0; i < size_input_prm; ++i ) { if( input_strs_file[i] ) { free( input_strs_file[i] ); } } free( input_strs_file ); } for( i = 0; i < size_input_prm; ++i ) { if( input_prm[i]->ptr ) { if( strcmp( input_prm[i]->type, TO_STR(PTR_DOUBLE9) ) == 0 ) { free(*(PTR_DOUBLE9*)input_prm[i]->ptr); } else if( strcmp( input_prm[i]->type, TO_STR(PTR_INT) ) == 0 ) { free(*(PTR_INT*)input_prm[i]->ptr); } else if( strcmp( input_prm[i]->type, TO_STR(PTR_DOUBLE) ) == 0 ) { free(*(PTR_DOUBLE*)input_prm[i]->ptr); } else if( strcmp( input_prm[i]->type, TO_STR(PTR_STR) ) == 0 ) { free(*(PTR_STR*)input_prm[i]->ptr); } else if( strcmp( input_prm[i]->type, TO_STR(STR) ) == 0 && input_prm[i]->size == -1 ) { free(*(STR*)input_prm[i]->ptr); } } } free_rand(); }
// Error.prototype.toString() js_val * error_proto_to_string(js_val *instance, js_args *args, eval_state *state) { if (!IS_OBJ(instance)) fh_error(state, E_TYPE, "Error.prototype.toString called on a non-object"); js_val *name_prop = fh_get_proto(instance, "name"); js_val *msg_prop = fh_get_proto(instance, "message"); js_val *name = IS_UNDEF(name_prop) ? JSSTR("Error") : TO_STR(name_prop); js_val *msg = IS_UNDEF(msg_prop) ? JSSTR("") : TO_STR(msg_prop); if (strlen(name->string.ptr) == 0) return msg; if (strlen(msg->string.ptr) == 0) return name; return JSSTR(fh_str_concat(fh_str_concat(name->string.ptr, ": "), msg->string.ptr)); }
void FillVersion() { #define TO_STR(x) #x std::string ver_str; std::string md5_str; std::stringstream ss; ss << "svn version " << _SVN_VERSION_ << ", " << "compiled by " << TO_STR(_BUILDER_) << ", " << __DATE__ << __TIME__; ss >> ver_str; time_t now = time(); char str_tm[256]; memset(str_tm, 0, sizeof(str_tm)); ctime_r(&now, &str_tm); char exe_file[256]; sprintf(exe_file, "/proc/%d/exe", getpid()); uint8_t md5[16]; CalcFileMD5(exe_file, md5); const char *hex = "0123456789abcdef"; for (int i = 0; i < 16; ++i) { md5_str[i*2+0] = hex[ (md5[i]&0xF0)>>4 ]; md5_str[i*2+0] = hex[ (md5[i]&0x0F) ]; } #undef TO_STR }
ECode CameraInfo::ToString( /* [out] */ String* str) { VALIDATE_NOT_NULL(str) *str = TO_STR(mInfo); return NOERROR; }
static void usage(const char *progname) { fprintf(stderr, "SHA performance testing tool for OP-TEE (%s)\n\n", TO_STR(VERSION)); fprintf(stderr, "Usage:\n"); fprintf(stderr, " %s -h\n", progname); fprintf(stderr, " %s [-v] [-a algo] ", progname); fprintf(stderr, "[-s bufsize] [-r] [-n loops] [-l iloops] "); fprintf(stderr, "[-w warmup_time]\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -h Print this help and exit\n"); fprintf(stderr, " -l Inner loop iterations (TA hashes "); fprintf(stderr, "the buffer <x> times) [%u]\n", l); fprintf(stderr, " -a Algorithm (SHA1, SHA224, SHA256, SHA384, "); fprintf(stderr, "SHA512) [%s]\n", algo_str(algo)); fprintf(stderr, " -n Outer loop iterations [%u]\n", n); fprintf(stderr, " -r Get input data from /dev/urandom "); fprintf(stderr, "(otherwise use zero-filled buffer)\n"); fprintf(stderr, " -s Buffer size (process <x> bytes at a time) "); fprintf(stderr, "[%zu]\n", size); fprintf(stderr, " -u Use unaligned buffer (odd address)\n"); fprintf(stderr, " -v Be verbose (use twice for greater effect)\n"); fprintf(stderr, " -w Warm-up time in seconds: execute a busy "); fprintf(stderr, "loop before the test\n"); fprintf(stderr, " to mitigate the effects of cpufreq etc. "); fprintf(stderr, "[%u]\n", warmup); }
RESULT versaloon_get_target_voltage(uint16_t *voltage) { uint16_t inlen; #if PARAM_CHECK if (NULL == versaloon_buf) { LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf)); return ERRCODE_INVALID_BUFFER; } if (NULL == voltage) { LOG_BUG(ERRMSG_INVALID_PARAMETER, __func__); return ERRCODE_INVALID_PARAMETER; } #endif versaloon_buf[0] = VERSALOON_GET_TVCC; if ((ERROR_OK != versaloon_send_command(1, &inlen)) || (inlen != 2)) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon"); return ERRCODE_FAILURE_OPERATION; } else { *voltage = versaloon_buf[0] + (versaloon_buf[1] << 8); return ERROR_OK; } }
int read_record(FILE *fp, struct log_entry *entry) { char buffer[REFERER_MAXLEN]; int ret; int seconds; ret = fscanf(fp, "%d.%d | %d | " "%" TO_STR(IP_MAXLEN) "s | " "%" TO_STR(HEAD_ST_MAXLEN) "s | " "%d | " "%" TO_STR(METHOD_MAXLEN) "s | " "%" TO_STR(URI_MAXLEN) "s | " "%" TO_STR(USERNAME_MAXLEN) "s | " "%" TO_STR(HSTATUS_MAXLEN) "s | " "%" TO_STR(MIMETYPE_MAXLEN) "s | " "%d | ", &entry->time, &seconds, &entry->elaps, entry->ipaddr, entry->head_st, &entry->len, entry->method, entry->uri, entry->username, entry->h_status, entry->mime_type, &entry->port); if (get_user_agent(fp, buffer, USERAGENT_MAXLEN, entry->user_agent) == -1 || get_referer(fp, buffer, REFERER_MAXLEN, entry->referer) == -1) return -1; if (ret < 2) return 1; return 0; }
void parse_doubles( DOUBLE* tab ,INT count ) { INT i; STR str_temp; for( i = 0; i < count; ++i ) { str_temp = strtok( NULL, " \t" ); if( str_temp == NULL || !check_type( TO_STR(DOUBLE), str_temp ) ) UNERR("Wrong line in sub"); tab[ i ] = (DOUBLE)atof( str_temp ); } }
void parse_ints( INT* tab ,INT count ) { INT i; STR str_temp; for( i = 0; i < count; ++i ) { str_temp = strtok( NULL, " \t" ); if( str_temp == NULL || !check_type( TO_STR(INT), str_temp ) ) UNERR("Wrong line in sub"); tab[ i ] = atoi( str_temp ); } }
String DATA_ValueProvider::GetValue( /* in */ IComponentName* resolvedComponent, /* in */ IIntent* intent, /* in */ const String& resolvedType) { AutoPtr<IUri> data; intent->GetData((IUri**)&data); if (data != NULL) { return TO_STR(data); } return String(NULL); }
// [new] Error(message) js_val * error_new(js_val *instance, js_args *args, eval_state *state) { js_val *err = JSOBJ(); js_val *msg = ARG(args, 0); fh_set_class(err, "Error"); if (!IS_UNDEF(msg)) fh_set(err, "message", TO_STR(msg)); err->proto = fh_try_get_proto("Error"); return err; }
/** * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders * @dev: the struct rc_dev device descriptor * @ev: the struct ir_raw_event descriptor of the pulse/space * * This routine (which may be called from an interrupt context) stores a * pulse/space duration for the raw ir decoding state machines. Pulses are * signalled as positive values and spaces as negative values. A zero value * will reset the decoding state machines. */ int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) { if (!dev->raw) return -EINVAL; IR_dprintk(2, "sample: (%05dus %s)\n", TO_US(ev->duration), TO_STR(ev->pulse)); if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) return -ENOMEM; return 0; }
/** * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders * @input_dev: the struct input_dev device descriptor * @ev: the struct ir_raw_event descriptor of the pulse/space * * This routine (which may be called from an interrupt context) stores a * pulse/space duration for the raw ir decoding state machines. Pulses are * signalled as positive values and spaces as negative values. A zero value * will reset the decoding state machines. */ int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) { struct ir_input_dev *ir = input_get_drvdata(input_dev); if (!ir->raw) return -EINVAL; IR_dprintk(2, "sample: (05%dus %s)\n", TO_US(ev->duration), TO_STR(ev->pulse)); if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) return -ENOMEM; return 0; }
/** * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders * @dev: the struct rc_dev device descriptor * @ev: the struct ir_raw_event descriptor of the pulse/space * * This routine (which may be called from an interrupt context) stores a * pulse/space duration for the raw ir decoding state machines. Pulses are * signalled as positive values and spaces as negative values. A zero value * will reset the decoding state machines. */ int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) { if (!dev->raw) return -EINVAL; IR_dprintk(2, "sample: (%05dus %s)\n", TO_US(ev->duration), TO_STR(ev->pulse)); if (!kfifo_put(&dev->raw->kfifo, *ev)) { dev_err(&dev->dev, "IR event FIFO is full!\n"); return -ENOSPC; } return 0; }
int ask_for_players_num() { int num = -1; string str(""); while (1) { num = get_number("How many players are playing? "); if (num >= 2 && num <= 26) { break; } TO_STR(MAX_PLAYERS, str); str = "The player numer is from 2 to " + str + "! Try again!"; show_error(str); } return num; }
/** * Test that we can write a file with libhdfs and then read it back */ int main(void) { int port; struct NativeMiniDfsConf conf = { 1, /* doFormat */ 0, /* webhdfsEnabled */ 0, /* namenodeHttpPort */ 1, /* configureShortCircuit */ }; char testFileName[TEST_FILE_NAME_LENGTH]; hdfsFS fs; struct NativeMiniDfsCluster* cl; struct hdfsBuilder *bld; cl = nmdCreate(&conf); EXPECT_NONNULL(cl); EXPECT_ZERO(nmdWaitClusterUp(cl)); port = nmdGetNameNodePort(cl); if (port < 0) { fprintf(stderr, "TEST_ERROR: test_zerocopy: " "nmdGetNameNodePort returned error %d\n", port); return EXIT_FAILURE; } bld = hdfsNewBuilder(); EXPECT_NONNULL(bld); EXPECT_ZERO(nmdConfigureHdfsBuilder(cl, bld)); hdfsBuilderSetForceNewInstance(bld); hdfsBuilderConfSetStr(bld, "dfs.block.size", TO_STR(TEST_ZEROCOPY_FULL_BLOCK_SIZE)); /* ensure that we'll always get our mmaps */ hdfsBuilderConfSetStr(bld, "dfs.client.read.shortcircuit.skip.checksum", "true"); fs = hdfsBuilderConnect(bld); EXPECT_NONNULL(fs); EXPECT_ZERO(createZeroCopyTestFile(fs, testFileName, TEST_FILE_NAME_LENGTH)); EXPECT_ZERO(doTestZeroCopyReads(fs, testFileName)); EXPECT_ZERO(hdfsDisconnect(fs)); EXPECT_ZERO(nmdShutdown(cl)); nmdFree(cl); fprintf(stderr, "TEST_SUCCESS\n"); return EXIT_SUCCESS; }
std::shared_ptr<AST> AST::create(const Source &source, const String &sourceCode, CXTranslationUnit unit) { std::shared_ptr<AST> ast(new AST); ast->mState.reset(new sel::State {true}); sel::State &state = *ast->mState; registerClasses(state); ast->mSourceCode = sourceCode; state["sourceFile"] = source.sourceFile().ref(); state["sourceCode"] = sourceCode.ref(); state["write"] = [ast](const std::string &str) { // error() << "writing" << str; ast->mReturnValues.append(str); }; exposeArray(state["commandLine"], source.toCommandLine(Source::Default|Source::IncludeCompiler|Source::IncludeSourceFile)); if (unit) { UserData userData; userData.ast = ast.get(); visitor(clang_getTranslationUnitCursor(unit), clang_getNullCursor(), &userData); const Cursor root = userData.parents.front(); state["root"] = [root]() { return root; }; state["findByUsr"] = [ast](const std::string &usr) { return ast->mByUsr.value(usr); }; state["findByOffset"] = [ast](const std::string &str) { // int offset = atoi(str.c_str()); // if (offset) { // } else // sscanf // return mByUsr.value(usr); }; const String script = Path(TO_STR(RTAGS_SOURCE_DIR) "/rtags.lua").readAll(); state(script.constData()); } return ast; }
RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen) { int ret; #if PARAM_CHECK if (NULL == versaloon_buf) { LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf)); return ERRCODE_INVALID_BUFFER; } if ((0 == out_len) || (out_len > versaloon_interface.usb_setting.buf_size)) { LOG_BUG(ERRMSG_INVALID_PARAMETER, __func__); return ERRCODE_INVALID_PARAMETER; } #endif ret = usb_bulk_write(versaloon_usb_device_handle, versaloon_interface.usb_setting.ep_out, (char *)versaloon_buf, out_len, versaloon_usb_to); if (ret != out_len) { LOG_ERROR(ERRMSG_FAILURE_OPERATION_ERRSTRING, "send usb data", usb_strerror()); return ERRCODE_FAILURE_OPERATION; } if (inlen != NULL) { ret = usb_bulk_read(versaloon_usb_device_handle, versaloon_interface.usb_setting.ep_in, (char *)versaloon_buf, versaloon_interface.usb_setting.buf_size, versaloon_usb_to); if (ret > 0) { *inlen = (uint16_t)ret; return ERROR_OK; } else { LOG_ERROR(ERRMSG_FAILURE_OPERATION_ERRSTRING, "receive usb data", usb_strerror()); return ERROR_FAIL; } } else return ERROR_OK; }
RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen) { int ret; int transferred; #if PARAM_CHECK if (NULL == versaloon_buf) { LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf)); return ERRCODE_INVALID_BUFFER; } if ((0 == out_len) || (out_len > versaloon_interface.usb_setting.buf_size)) { LOG_BUG(ERRMSG_INVALID_PARAMETER, __func__); return ERRCODE_INVALID_PARAMETER; } #endif ret = libusb_bulk_transfer(versaloon_usb_device_handle, versaloon_interface.usb_setting.ep_out, versaloon_buf, out_len, &transferred, versaloon_usb_to); if (0 != ret || transferred != out_len) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "send usb data"); return ERRCODE_FAILURE_OPERATION; } if (inlen != NULL) { ret = libusb_bulk_transfer(versaloon_usb_device_handle, versaloon_interface.usb_setting.ep_in, versaloon_buf, versaloon_interface.usb_setting.buf_size, &transferred, versaloon_usb_to); if (0 == ret) { *inlen = (uint16_t)transferred; return ERROR_OK; } else { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "receive usb data"); return ERROR_FAIL; } } else return ERROR_OK; }
Map::Map(FILE *file, unsigned screen_position_x, unsigned screen_position_y, Game *game) : game(game), screen_position_x(screen_position_x), screen_position_y(screen_position_y) { tick_counter = 0; energizers_count = 0; while (true) { int ch = fgetc(file); if (ch == MAP_ENERGIZER) ++energizers_count; else if (ch == EOF) break; } energizers = new Cell*[energizers_count]; fseek(file, 0, SEEK_SET); if (fscanf(file, "%u %u", &width, &height) < 2) throw InvalidFileFormatError("no size definition in first line"); if (fgetc(file) != ';') throw InvalidFileFormatError("';' expected after size definition"); if (width == 0) throw NullMapSizeError("Width"); else if (height == 0) throw NullMapSizeError("Height"); init_positions.pacman = NULL; for( unsigned i = 0 ; i < GHOST_NUMBER ; ++i ) init_positions.ghosts[i] = NULL; unsigned size = width*height; cells = (Cell *)malloc(size * sizeof(cells[0])); if (cells == NULL) throw std::bad_alloc(); unsigned i = 0; unsigned ghost_index = 0; unsigned energizer_index = 0; points_num = 0; while (true) { int ch = fgetc(file); if (ch == EOF) throw InvalidFileFormatError("detected EOF but not all map cells defined"); else if (is_separator(ch)) continue; else { if (i >= size) throw InvalidFileFormatError("too many map cells defined"); ObjType ot; switch ( ch ) { case MAP_PACMAN: if (init_positions.pacman != NULL) throw InvalidFileFormatError("too many PacMans defined"); init_positions.pacman = &cells[i]; ot = EMPTY; break; case MAP_GHOST: if( ghost_index >= GHOST_NUMBER ) throw InvalidFileFormatError("too many ghosts defined (need " TO_STR(GHOST_NUMBER) ")"); init_positions.ghosts[ghost_index] = &cells[i]; ot = EMPTY; ++ghost_index; break; case MAP_POINT: ++points_num; ot = POINT; break; case MAP_EMPTY: ot = EMPTY; break; case MAP_ENERGIZER: ot = ENERGIZER; energizers[energizer_index++] = &cells[i]; break; case MAP_WALL: ot = WALL; break; default : char buffer[] = "invalid symbol in map cell definition (X)"; buffer[ strlen(buffer) - 2 ] = ch; throw InvalidFileFormatError(buffer); } new(&cells[i]) Cell (ot, &cells[ (i - width + size) % size ], &cells[ ( (i+1) % width == 0 ) ? (i + 1 - width ) : (i + 1) ], &cells[ (i + width) % size ], &cells[ ( i % width == 0 ) ? (i - 1 + width ) : (i - 1) ], screen_position_x + 2*(i % width), screen_position_y + (i / width), this ); ++i; if (i == size) break; } } if ( init_positions.pacman == NULL ) throw InvalidFileFormatError("one PacMan must be defined"); if ( ghost_index < GHOST_NUMBER ) throw InvalidFileFormatError("too few ghosts defined (need " TO_STR(GHOST_NUMBER) ")"); fclose(file); }
/** * ir_nec_decode() - Decode one NEC pulse or space * @input_dev: the struct input_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); struct nec_dec *data = &ir_dev->raw->nec; u32 scancode; u8 address, not_address, command, not_command; if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) return 0; if (IS_RESET(ev)) { data->state = STATE_INACTIVE; return 0; } IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2)) { data->is_nec_x = false; data->necx_repeat = false; } else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2)) data->is_nec_x = true; else break; data->count = 0; data->state = STATE_HEADER_SPACE; return 0; case STATE_HEADER_SPACE: if (ev.pulse) break; if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { ir_repeat(input_dev); IR_dprintk(1, "Repeat last key\n"); data->state = STATE_TRAILER_PULSE; return 0; } break; case STATE_BIT_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2)) break; data->state = STATE_BIT_SPACE; return 0; case STATE_BIT_SPACE: if (ev.pulse) break; if (data->necx_repeat && data->count == NECX_REPEAT_BITS && geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) { IR_dprintk(1, "Repeat last key\n"); ir_repeat(input_dev); data->state = STATE_INACTIVE; return 0; } else if (data->count > NECX_REPEAT_BITS) data->necx_repeat = false; data->bits <<= 1; if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) data->bits |= 1; else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2)) break; data->count++; if (data->count == NEC_NBITS) data->state = STATE_TRAILER_PULSE; else data->state = STATE_BIT_PULSE; return 0; case STATE_TRAILER_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2)) break; data->state = STATE_TRAILER_SPACE; return 0; case STATE_TRAILER_SPACE: if (ev.pulse) break; if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) break; address = bitrev8((data->bits >> 24) & 0xff); not_address = bitrev8((data->bits >> 16) & 0xff); command = bitrev8((data->bits >> 8) & 0xff); not_command = bitrev8((data->bits >> 0) & 0xff); if ((command ^ not_command) != 0xff) { IR_dprintk(1, "NEC checksum error: received 0x%08x\n", data->bits); break; } if ((address ^ not_address) != 0xff) { /* Extended NEC */ scancode = address << 16 | not_address << 8 | command; IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); } else { /* Normal NEC */ scancode = address << 8 | command; IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); } if (data->is_nec_x) data->necx_repeat = true; ir_keydown(input_dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_rc6_decode() - Decode one RC6 pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc6_dec *data = &dev->raw->rc6; u32 scancode; u8 toggle; enum rc_proto protocol; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) goto out; again: IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; /* Note: larger margin on first pulse since each RC6_UNIT is quite short and some hardware takes some time to adjust to the signal */ if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT)) break; data->state = STATE_PREFIX_SPACE; data->count = 0; return 0; case STATE_PREFIX_SPACE: if (ev.pulse) break; if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2)) break; data->state = STATE_HEADER_BIT_START; data->header = 0; return 0; case STATE_HEADER_BIT_START: if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) break; data->header <<= 1; if (ev.pulse) data->header |= 1; data->count++; data->state = STATE_HEADER_BIT_END; return 0; case STATE_HEADER_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == RC6_HEADER_NBITS) data->state = STATE_TOGGLE_START; else data->state = STATE_HEADER_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_TOGGLE_START: if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2)) break; data->toggle = ev.pulse; data->state = STATE_TOGGLE_END; return 0; case STATE_TOGGLE_END: if (!is_transition(&ev, &dev->raw->prev_ev) || !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) break; if (!(data->header & RC6_STARTBIT_MASK)) { IR_dprintk(1, "RC6 invalid start bit\n"); break; } data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_TOGGLE_END); data->count = 0; data->body = 0; switch (rc6_mode(data)) { case RC6_MODE_0: data->wanted_bits = RC6_0_NBITS; break; case RC6_MODE_6A: data->wanted_bits = RC6_6A_NBITS; break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } goto again; case STATE_BODY_BIT_START: if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) { /* Discard LSB's that won't fit in data->body */ if (data->count++ < CHAR_BIT * sizeof data->body) { data->body <<= 1; if (ev.pulse) data->body |= 1; } data->state = STATE_BODY_BIT_END; return 0; } else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse && geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) { data->state = STATE_FINISHED; goto again; } break; case STATE_BODY_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_FINISHED: if (ev.pulse) break; switch (rc6_mode(data)) { case RC6_MODE_0: scancode = data->body; toggle = data->toggle; protocol = RC_PROTO_RC6_0; IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", scancode, toggle); break; case RC6_MODE_6A: if (data->count > CHAR_BIT * sizeof data->body) { IR_dprintk(1, "RC6 too many (%u) data bits\n", data->count); goto out; } scancode = data->body; switch (data->count) { case 20: protocol = RC_PROTO_RC6_6A_20; toggle = 0; break; case 24: protocol = RC_PROTO_RC6_6A_24; toggle = 0; break; case 32: if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { protocol = RC_PROTO_RC6_MCE; toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); scancode &= ~RC6_6A_MCE_TOGGLE_MASK; } else { protocol = RC_PROTO_RC6_6A_32; toggle = 0; } break; default: IR_dprintk(1, "RC6(6A) unsupported length\n"); goto out; } IR_dprintk(1, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n", protocol, scancode, toggle); break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } rc_keydown(dev, protocol, scancode, toggle); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the * lircd userspace daemon for decoding. * @input_dev: the struct rc_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the lirc interfaces aren't wired up. */ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct lirc_codec *lirc = &dev->raw->lirc; int sample; if (!(dev->raw->enabled_protocols & RC_BIT_LIRC)) return 0; if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) return -EINVAL; /* Packet start */ if (ev.reset) return 0; /* Carrier reports */ if (ev.carrier_report) { sample = LIRC_FREQUENCY(ev.carrier); IR_dprintk(2, "carrier report (freq: %d)\n", sample); /* Packet end */ } else if (ev.timeout) { if (lirc->gap) return 0; lirc->gap_start = ktime_get(); lirc->gap = true; lirc->gap_duration = ev.duration; if (!lirc->send_timeout_reports) return 0; sample = LIRC_TIMEOUT(ev.duration / 1000); IR_dprintk(2, "timeout report (duration: %d)\n", sample); /* Normal sample */ } else { if (lirc->gap) { int gap_sample; lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), lirc->gap_start)); /* Convert to ms and cap by LIRC_VALUE_MASK */ do_div(lirc->gap_duration, 1000); lirc->gap_duration = min(lirc->gap_duration, (u64)LIRC_VALUE_MASK); gap_sample = LIRC_SPACE(lirc->gap_duration); lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &gap_sample); lirc->gap = false; } sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : LIRC_SPACE(ev.duration / 1000); IR_dprintk(2, "delivering %uus %s to lirc_dev\n", TO_US(ev.duration), TO_STR(ev.pulse)); } lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &sample); wake_up(&dev->raw->lirc.drv->rbuf->wait_poll); return 0; }
/** * ir_rc5_decode() - Decode one RC-5 pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc5_dec *data = &dev->raw->rc5; u8 toggle; u32 scancode; if (!(dev->raw->enabled_protocols & RC_TYPE_RC5)) return 0; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) goto out; again: IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; data->state = STATE_BIT_START; data->count = 1; /* We just need enough bits to get to STATE_CHECK_RC5X */ data->wanted_bits = RC5X_NBITS; decrease_duration(&ev, RC5_BIT_START); goto again; case STATE_BIT_START: if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) break; data->bits <<= 1; if (!ev.pulse) data->bits |= 1; data->count++; data->state = STATE_BIT_END; return 0; case STATE_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else if (data->count == CHECK_RC5X_NBITS) data->state = STATE_CHECK_RC5X; else data->state = STATE_BIT_START; decrease_duration(&ev, RC5_BIT_END); goto again; case STATE_CHECK_RC5X: if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) { /* RC5X */ data->wanted_bits = RC5X_NBITS; decrease_duration(&ev, RC5X_SPACE); } else { /* RC5 */ data->wanted_bits = RC5_NBITS; } data->state = STATE_BIT_START; goto again; case STATE_FINISHED: if (ev.pulse) break; if (data->wanted_bits == RC5X_NBITS) { /* RC5X */ u8 xdata, command, system; xdata = (data->bits & 0x0003F) >> 0; command = (data->bits & 0x00FC0) >> 6; system = (data->bits & 0x1F000) >> 12; toggle = (data->bits & 0x20000) ? 1 : 0; command += (data->bits & 0x01000) ? 0 : 0x40; scancode = system << 16 | command << 8 | xdata; IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n", scancode, toggle); } else {
/** * ir_sony_decode() - Decode one Sony pulse or space * @input_dev: the struct input_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); struct sony_dec *data = &ir_dev->raw->sony; u32 scancode; u8 device, subdevice, function; if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) return 0; if (IS_RESET(ev)) { data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) goto out; IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2)) break; data->count = 0; data->state = STATE_HEADER_SPACE; return 0; case STATE_HEADER_SPACE: if (ev.pulse) break; if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2)) break; data->state = STATE_BIT_PULSE; return 0; case STATE_BIT_PULSE: if (!ev.pulse) break; data->bits <<= 1; if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2)) data->bits |= 1; else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2)) break; data->count++; data->state = STATE_BIT_SPACE; return 0; case STATE_BIT_SPACE: if (ev.pulse) break; if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2)) break; decrease_duration(&ev, SONY_BIT_SPACE); if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; } data->state = STATE_FINISHED; /* Fall through */ case STATE_FINISHED: if (ev.pulse) break; if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2)) break; switch (data->count) { case 12: device = bitrev8((data->bits << 3) & 0xF8); subdevice = 0; function = bitrev8((data->bits >> 4) & 0xFE); break; case 15: device = bitrev8((data->bits >> 0) & 0xFF); subdevice = 0; function = bitrev8((data->bits >> 7) & 0xFD); break; case 20: device = bitrev8((data->bits >> 5) & 0xF8); subdevice = bitrev8((data->bits >> 0) & 0xFF); function = bitrev8((data->bits >> 12) & 0xFE); break; default: IR_dprintk(1, "Sony invalid bitcount %u\n", data->count); goto out; } scancode = device << 16 | subdevice << 8 | function; IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); ir_keydown(input_dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "Sony decode failed at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_rc6_decode() - Decode one RC6 pulse or space * @input_dev: the struct input_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); struct rc6_dec *data = &ir_dev->raw->rc6; u32 scancode; u8 toggle; if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) return 0; if (IS_RESET(ev)) { data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) goto out; again: IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; /* Note: larger margin on first pulse since each RC6_UNIT is quite short and some hardware takes some time to adjust to the signal */ if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT)) break; data->state = STATE_PREFIX_SPACE; data->count = 0; return 0; case STATE_PREFIX_SPACE: if (ev.pulse) break; if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2)) break; data->state = STATE_HEADER_BIT_START; return 0; case STATE_HEADER_BIT_START: if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) break; data->header <<= 1; if (ev.pulse) data->header |= 1; data->count++; data->state = STATE_HEADER_BIT_END; return 0; case STATE_HEADER_BIT_END: if (!is_transition(&ev, &ir_dev->raw->prev_ev)) break; if (data->count == RC6_HEADER_NBITS) data->state = STATE_TOGGLE_START; else data->state = STATE_HEADER_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_TOGGLE_START: if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2)) break; data->toggle = ev.pulse; data->state = STATE_TOGGLE_END; return 0; case STATE_TOGGLE_END: if (!is_transition(&ev, &ir_dev->raw->prev_ev) || !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) break; if (!(data->header & RC6_STARTBIT_MASK)) { IR_dprintk(1, "RC6 invalid start bit\n"); break; } data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_TOGGLE_END); data->count = 0; switch (rc6_mode(data)) { case RC6_MODE_0: data->wanted_bits = RC6_0_NBITS; break; case RC6_MODE_6A: /* This might look weird, but we basically check the value of the first body bit to determine the number of bits in mode 6A */ if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) || geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) data->wanted_bits = RC6_6A_LARGE_NBITS; else data->wanted_bits = RC6_6A_SMALL_NBITS; break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } goto again; case STATE_BODY_BIT_START: if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) break; data->body <<= 1; if (ev.pulse) data->body |= 1; data->count++; data->state = STATE_BODY_BIT_END; return 0; case STATE_BODY_BIT_END: if (!is_transition(&ev, &ir_dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) data->state = STATE_FINISHED; else data->state = STATE_BODY_BIT_START; decrease_duration(&ev, RC6_BIT_END); goto again; case STATE_FINISHED: if (ev.pulse) break; switch (rc6_mode(data)) { case RC6_MODE_0: scancode = data->body & 0xffff; toggle = data->toggle; IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", scancode, toggle); break; case RC6_MODE_6A: if (data->wanted_bits == RC6_6A_LARGE_NBITS) { toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0; scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK; } else { toggle = 0; scancode = data->body & 0xffffff; } IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n", scancode, toggle); break; default: IR_dprintk(1, "RC6 unknown mode\n"); goto out; } ir_keydown(input_dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } out: IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_sanyo_decode() - Decode one SANYO pulse or space * @dev: the struct rc_dev descriptor of the device * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct sanyo_dec *data = &dev->raw->sanyo; u32 scancode; u8 address, command, not_command; if (!(dev->raw->enabled_protocols & RC_BIT_SANYO)) return 0; if (!is_timing_event(ev)) { if (ev.reset) { IR_dprintk(1, "SANYO event reset received. reset to state 0\n"); data->state = STATE_INACTIVE; } return 0; } IR_dprintk(2, "SANYO decode started at state %d (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) { data->count = 0; data->state = STATE_HEADER_SPACE; return 0; } break; case STATE_HEADER_SPACE: if (ev.pulse) break; if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; } break; case STATE_BIT_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2)) break; data->state = STATE_BIT_SPACE; return 0; case STATE_BIT_SPACE: if (ev.pulse) break; if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) { if (!dev->keypressed) { IR_dprintk(1, "SANYO discarding last key repeat: event after key up\n"); } else { rc_repeat(dev); IR_dprintk(1, "SANYO repeat last key\n"); data->state = STATE_INACTIVE; } return 0; } data->bits <<= 1; if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2)) data->bits |= 1; else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2)) break; data->count++; if (data->count == SANYO_NBITS) data->state = STATE_TRAILER_PULSE; else data->state = STATE_BIT_PULSE; return 0; case STATE_TRAILER_PULSE: if (!ev.pulse) break; if (!eq_margin(ev.duration, SANYO_TRAILER_PULSE, SANYO_UNIT / 2)) break; data->state = STATE_TRAILER_SPACE; return 0; case STATE_TRAILER_SPACE: if (ev.pulse) break; if (!geq_margin(ev.duration, SANYO_TRAILER_SPACE, SANYO_UNIT / 2)) break; address = bitrev16((data->bits >> 29) & 0x1fff) >> 3; /* not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; */ command = bitrev8((data->bits >> 8) & 0xff); not_command = bitrev8((data->bits >> 0) & 0xff); if ((command ^ not_command) != 0xff) { IR_dprintk(1, "SANYO checksum error: received 0x%08Lx\n", data->bits); data->state = STATE_INACTIVE; return 0; } scancode = address << 8 | command; IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode); rc_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } IR_dprintk(1, "SANYO decode failed at count %d state %d (%uus %s)\n", data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }
/** * ir_rc5_decode() - Decode one RC-5 pulse or space * @dev: the struct rc_dev descriptor of the device * @ev: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct rc5_dec *data = &dev->raw->rc5; u8 toggle; u32 scancode; enum rc_type protocol; if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; return 0; } if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) goto out; again: IR_dprintk(2, "RC5(x/sz) decode started at state %i (%uus %s)\n", data->state, TO_US(ev.duration), TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) return 0; switch (data->state) { case STATE_INACTIVE: if (!ev.pulse) break; data->state = STATE_BIT_START; data->count = 1; decrease_duration(&ev, RC5_BIT_START); goto again; case STATE_BIT_START: if (!ev.pulse && geq_margin(ev.duration, RC5_TRAILER, RC5_UNIT / 2)) { data->state = STATE_FINISHED; goto again; } if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) break; data->bits <<= 1; if (!ev.pulse) data->bits |= 1; data->count++; data->state = STATE_BIT_END; return 0; case STATE_BIT_END: if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == CHECK_RC5X_NBITS) data->state = STATE_CHECK_RC5X; else data->state = STATE_BIT_START; decrease_duration(&ev, RC5_BIT_END); goto again; case STATE_CHECK_RC5X: if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) { data->is_rc5x = true; decrease_duration(&ev, RC5X_SPACE); } else data->is_rc5x = false; data->state = STATE_BIT_START; goto again; case STATE_FINISHED: if (ev.pulse) break; if (data->is_rc5x && data->count == RC5X_NBITS) { /* RC5X */ u8 xdata, command, system; if (!(dev->enabled_protocols & RC_BIT_RC5X)) { data->state = STATE_INACTIVE; return 0; } xdata = (data->bits & 0x0003F) >> 0; command = (data->bits & 0x00FC0) >> 6; system = (data->bits & 0x1F000) >> 12; toggle = (data->bits & 0x20000) ? 1 : 0; command += (data->bits & 0x01000) ? 0 : 0x40; scancode = system << 16 | command << 8 | xdata; protocol = RC_TYPE_RC5X; } else if (!data->is_rc5x && data->count == RC5_NBITS) {