ir-ctl: make nec32 scancode encoding match kernel
Subsystems (3)
Sean Young
maintainerPATCH 1/1 ir-ctl: make nec32 scancode encoding match kernel
For the nec32 encoding, the kernel swaps in the "inverted" and normal address and command. This might not be the most logical scheme.
--- utils/common/ir-encode.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
utils/common/ir-encode.c +2 -7
@@ -64,15 +64,10 @@ static int nec_encode(enum rc_proto proto, unsigned scancode, unsigned *buf)add_byte (~scancode);break ;case RC_PROTO_NEC32 : -/* -* At the time of writing kernel software nec decoder -* reverses the bit order so it will not match. Hardware -* decoders do not have this issue. -*/ -add_byte (scancode >>24 );add_byte (scancode >>16 ); -add_byte (scancode >>8 ); +add_byte (scancode >>24 );add_byte (scancode); +add_byte (scancode >>8 );break ; }
Signature · 1 line
2.11.0
Sean Young
maintainerPATCH 1/2 media: rc: nec keymaps should specify the nec variant they use
The rc_proto field should list the exact variant used by the remote. This does not change the decoder used, but helps with using keymaps for transmit purposes.
--- drivers/media/rc/keymaps/rc-behold.c | 2 +- drivers/media/rc/keymaps/rc-delock-61959.c | 2 +- drivers/media/rc/keymaps/rc-imon-rsc.c | 2 +- drivers/media/rc/keymaps/rc-it913x-v1.c | 2 +- drivers/media/rc/keymaps/rc-it913x-v2.c | 2 +- drivers/media/rc/keymaps/rc-msi-digivox-iii.c | 2 +- drivers/media/rc/keymaps/rc-pixelview-002t.c | 2 +- drivers/media/rc/keymaps/rc-pixelview-mk12.c | 2 +- drivers/media/rc/keymaps/rc-reddo.c | 2 +- drivers/media/rc/keymaps/rc-terratec-slim.c | 2 +- drivers/media/rc/keymaps/rc-tivo.c | 2 +- drivers/media/rc/keymaps/rc-total-media-in-hand.c | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-)
drivers/media/rc/keymaps/rc-behold.c +1 -1
@@ -115,7 +115,7 @@ static struct rc_map_list behold_map = { .map = { .scan = behold, .size = ARRAY_SIZE(behold), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_BEHOLD, } };
drivers/media/rc/keymaps/rc-delock-61959.c +1 -1
@@ -60,7 +60,7 @@ static struct rc_map_list delock_61959_map = { .map = { .scan = delock_61959, .size = ARRAY_SIZE(delock_61959), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_DELOCK_61959, } };
drivers/media/rc/keymaps/rc-imon-rsc.c +1 -1
@@ -59,7 +59,7 @@ static struct rc_map_list imon_rsc_map = { .map = { .scan = imon_rsc, .size = ARRAY_SIZE(imon_rsc), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_IMON_RSC, } };
drivers/media/rc/keymaps/rc-it913x-v1.c +1 -1
@@ -73,7 +73,7 @@ static struct rc_map_list it913x_v1_map = { .map = { .scan = it913x_v1_rc, .size = ARRAY_SIZE(it913x_v1_rc), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_IT913X_V1, } };
drivers/media/rc/keymaps/rc-it913x-v2.c +1 -1
@@ -72,7 +72,7 @@ static struct rc_map_list it913x_v2_map = { .map = { .scan = it913x_v2_rc, .size = ARRAY_SIZE(it913x_v2_rc), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_IT913X_V2, } };
drivers/media/rc/keymaps/rc-msi-digivox-iii.c +1 -1
@@ -64,7 +64,7 @@ static struct rc_map_list msi_digivox_iii_map = { .map = { .scan = msi_digivox_iii, .size = ARRAY_SIZE(msi_digivox_iii), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_MSI_DIGIVOX_III, } };
drivers/media/rc/keymaps/rc-pixelview-002t.c +1 -1
@@ -51,7 +51,7 @@ static struct rc_map_list pixelview_map = { .map = { .scan = pixelview_002t, .size = ARRAY_SIZE(pixelview_002t), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_PIXELVIEW_002T, } };
drivers/media/rc/keymaps/rc-pixelview-mk12.c +1 -1
@@ -57,7 +57,7 @@ static struct rc_map_list pixelview_map = { .map = { .scan = pixelview_mk12, .size = ARRAY_SIZE(pixelview_mk12), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_PIXELVIEW_MK12, } };
drivers/media/rc/keymaps/rc-reddo.c +1 -1
@@ -64,7 +64,7 @@ static struct rc_map_list reddo_map = { .map = { .scan = reddo, .size = ARRAY_SIZE(reddo), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_REDDO, } };
drivers/media/rc/keymaps/rc-terratec-slim.c +1 -1
@@ -58,7 +58,7 @@ static struct rc_map_list terratec_slim_map = { .map = { .scan = terratec_slim, .size = ARRAY_SIZE(terratec_slim), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_TERRATEC_SLIM, } };
drivers/media/rc/keymaps/rc-tivo.c +1 -1
@@ -77,7 +77,7 @@ static struct rc_map_list tivo_map = { .map = { .scan = tivo, .size = ARRAY_SIZE(tivo), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NEC32, .name = RC_MAP_TIVO, } };
drivers/media/rc/keymaps/rc-total-media-in-hand.c +1 -1
@@ -64,7 +64,7 @@ static struct rc_map_list total_media_in_hand_map = { .map = { .scan = total_media_in_hand, .size = ARRAY_SIZE(total_media_in_hand), - .rc_proto = RC_PROTO_NEC, + .rc_proto = RC_PROTO_NECX, .name = RC_MAP_TOTAL_MEDIA_IN_HAND, } };
Signature · 1 line
2.17.1
Sean Young
maintainerPATCH 2/2 media: rc: self test for IR encoders and decoders
In reply to Sean Youngir-loopback can transmit IR on one rc device and check the correct scancode and protocol is decoded on a different rc device. This can be used to check IR transmission between two rc devices. Using rc-loopback, we use it to check the IR encoders and decoders themselves.
--- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/ir/.gitignore | 1 + tools/testing/selftests/ir/Makefile | 19 ++ tools/testing/selftests/ir/config | 12 ++ tools/testing/selftests/ir/ir-loopback.c | 209 ++++++++++++++++++++++ tools/testing/selftests/ir/ir-loopback.sh | 28 +++ 6 files changed, 270 insertions(+) create mode 100644 tools/testing/selftests/ir/.gitignore create mode 100644 tools/testing/selftests/ir/Makefile create mode 100644 tools/testing/selftests/ir/config create mode 100644 tools/testing/selftests/ir/ir-loopback.c create mode 100755 tools/testing/selftests/ir/ir-loopback.sh
tools/testing/selftests/Makefile +1 -0
@@ -15,6 +15,7 @@ TARGETS += futex TARGETS += gpio TARGETS += intel_pstate TARGETS += ipc +TARGETS += ir TARGETS += kcmp TARGETS += kvm TARGETS += lib
tools/testing/selftests/ir/.gitignore new file +1 -0
@@ -0,0 +1 @@ +ir-loopback
tools/testing/selftests/ir/Makefile new file +19 -0
@@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0 +uname_M := $(shell uname -m 2>/dev/null || echo not) +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/) +ifeq ($(ARCH),i386) + ARCH := x86 + CFLAGS := -DCONFIG_X86_32 -D__i386__ +endif +ifeq ($(ARCH),x86_64) + ARCH := x86 + CFLAGS := -DCONFIG_X86_64 -D__x86_64__ +endif + +CFLAGS += -I../../../../usr/include/ + +TEST_PROGS := ir-loopback.sh + +TEST_GEN_PROGS := ir-loopback + +include ../lib.mk
tools/testing/selftests/ir/config new file +12 -0
@@ -0,0 +1,12 @@ +CONFIG_RC_CORE=y +CONFIG_RC_LOOPBACK=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_IR_IMON_DECODER=m
tools/testing/selftests/ir/ir-loopback.c new file +209 -0
209 lines not on this page · raw message
tools/testing/selftests/ir/ir-loopback.sh new file +28 -0
@@ -0,0 +1,28 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +GREEN='\033[0;92m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +modprobe rc-loopback + +for i in /sys/class/rc/rc* +do + if grep -q DRV_NAME=rc-loopback $i/uevent + then + RCDEV=$(echo $i | sed sQ/sys/class/rc/QQ) + fi +done + +if [ -n $RCDEV ]; +then + TYPE=ir-loopback + ./ir-loopback $RCDEV $RCDEV + ret=$? + if [ $ret -ne 0 ]; then + echo -e ${RED}"FAIL: $TYPE"${NC} + else + echo -e ${GREEN}"PASS: $TYPE"${NC} + fi +fi
Signature · 1 line
2.17.1
shuah at kernel.org (Shuah Khan)
PATCH 2/2 media: rc: self test for IR encoders and decoders
Hi Sean,
Thanks for the patch. I just happened to see this when Mauro sent it to me. Doesn't look like linux-ksefltest and I weren't on the patch?
Quoted 6 lines · On 07/17/2018 03:33 PM, Sean Young (by way of Mauro Carvalho Chehab…
ir-loopback can transmit IR on one rc device and check the correct scancode and protocol is decoded on a different rc device. This can be used to check IR transmission between two rc devices. Using rc-loopback, we use it to check the IR encoders and decoders themselves.
Signed-off-by Sean Young <sean at mess.org>
Quoted 13 lines
--- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/ir/.gitignore | 1 + tools/testing/selftests/ir/Makefile | 19 ++ tools/testing/selftests/ir/config | 12 ++ tools/testing/selftests/ir/ir-loopback.c | 209 ++++++++++++++++++++++ tools/testing/selftests/ir/ir-loopback.sh | 28 +++ 6 files changed, 270 insertions(+) create mode 100644 tools/testing/selftests/ir/.gitignore create mode 100644 tools/testing/selftests/ir/Makefile create mode 100644 tools/testing/selftests/ir/config create mode 100644 tools/testing/selftests/ir/ir-loopback.c create mode 100755 tools/testing/selftests/ir/ir-loopback.sh
Why not add to the existing media directory? ../selftests/media_tests?
tools/testing/selftests/Makefile TARGETS += futex · line 18
Quoted 10 lines
tools/testing/selftests/Makefile +1
-0@@ -15,6 +15,7 @@ TARGETS += futex TARGETS += gpio TARGETS += intel_pstate TARGETS += ipc +TARGETS += ir
Does this test depend on any hardware being present in the system?
Quoted 23 lines
tools/testing/selftests/Makefile +0
-0TARGETS += kcmp TARGETS += kvm TARGETS += libtools/testing/selftests/ir/.gitignore new file +1
-0@@ -0,0 +1 @@ +ir-loopbacktools/testing/selftests/ir/Makefile new file +7
-0@@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0 +uname_M := $(shell uname -m 2>/dev/null || echo not) +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/) +ifeq ($(ARCH),i386) + ARCH := x86 + CFLAGS := -DCONFIG_X86_32 -D__i386__ +endif
tools/testing/selftests/ir/Makefile line 17
Quoted 10 lines
tools/testing/selftests/ir/Makefile new file +10
-0+ifeq ($(ARCH),x86_64) + ARCH := x86 + CFLAGS := -DCONFIG_X86_64 -D__x86_64__ +endif + +CFLAGS += -I../../../../usr/include/ + +TEST_PROGS := ir-loopback.sh + +TEST_GEN_PROGS := ir-loopback
Looks like ir-loopback get run from ir-loopback.sh. TEST_GEN_PROGS_EXTENDED is the right variable to use in this case.
TEST_GEN_PROGS_EXTENDED := ir-loopback
Quoted 84 lines
tools/testing/selftests/ir/Makefile new file +2
-0+ +include ../lib.mktools/testing/selftests/ir/config new file +12
-0@@ -0,0 +1,12 @@ +CONFIG_RC_CORE=y +CONFIG_RC_LOOPBACK=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_IR_IMON_DECODER=mtools/testing/selftests/ir/ir-loopback.c new file +58
-0@@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0 +// test ir decoder +// +// Copyright (C) 2018 Sean Young <sean at mess.org> + +// When sending LIRC_MODE_SCANCODE, the IR will be encoded. rc-loopback +// will send this IR to the receiver side, where we try to read the decoded +// IR. Decoding happens in a separate kernel thread, so we will need to +// wait until that is scheduled, hence we use poll to check for read +// readiness. + +#include <linux/lirc.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> +#include <poll.h> +#include <time.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <dirent.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define TEST_SCANCODES 10 +#define ARRAY_SIZE (arr) (sizeof(arr) / sizeof((arr)[0])) + +static const struct { +enum rc_proto proto; +const char *name; +unsigned int mask; +const char *decoder; +} protocols[] = { + {RC_PROTO_RC5 ,"rc-5" ,0x1f7f ,"rc-5" }, + {RC_PROTO_RC5X_20 ,"rc-5x-20" ,0x1f7f3f ,"rc-5" }, + {RC_PROTO_RC5_SZ ,"rc-5-sz" ,0x2fff ,"rc-5-sz" }, + {RC_PROTO_JVC ,"jvc" ,0xffff ,"jvc" }, + {RC_PROTO_SONY12 ,"sony-12" ,0x1f007f ,"sony" }, + {RC_PROTO_SONY15 ,"sony-15" ,0xff007f ,"sony" }, + {RC_PROTO_SONY20 ,"sony-20" ,0x1fff7f ,"sony" }, + {RC_PROTO_NEC ,"nec" ,0xffff ,"nec" }, + {RC_PROTO_NECX ,"nec-x" ,0xffffff ,"nec" }, + {RC_PROTO_NEC32 ,"nec-32" ,0xffffffff ,"nec" }, + {RC_PROTO_SANYO ,"sanyo" ,0x1fffff ,"sanyo" }, + {RC_PROTO_RC6_0 ,"rc-6-0" ,0xffff ,"rc-6" }, + {RC_PROTO_RC6_6A_20 ,"rc-6-6a-20" ,0xfffff ,"rc-6" }, + {RC_PROTO_RC6_6A_24 ,"rc-6-6a-24" ,0xffffff ,"rc-6" }, + {RC_PROTO_RC6_6A_32 ,"rc-6-6a-32" ,0xffffffff ,"rc-6" }, + {RC_PROTO_RC6_MCE ,"rc-6-mce" ,0x00007fff ,"rc-6" }, + {RC_PROTO_SHARP ,"sharp" ,0x1fff ,"sharp" }, +}; + +int lirc_open (const char *rc) +{ +struct dirent *dent; +char buf[100 ];
tools/testing/selftests/ir/ir-loopback.c line 68
Quoted 10 lines
tools/testing/selftests/ir/ir-loopback.c new file +10
-0+DIR *d; +int fd; + +snprintf (buf,sizeof (buf),"/sys/class/rc/%s" , rc); + + d =opendir (buf); +if (!d) { +printf ("cannot open %s: %m\n" , buf); +exit (1 ); + }
In this case, you will have to differentiate file not found case and use ksft_exit_skip() to skip the test.
tools/testing/selftests/ir/ir-loopback.c line 80
Quoted 12 lines
tools/testing/selftests/ir/ir-loopback.c new file +12
-0+ +while ((dent =readdir (d)) !=NULL ) { +if (!strncmp (dent->d_name,"lirc" ,4 )) { +snprintf (buf,sizeof (buf),"/dev/%s" , dent->d_name); +break ; + } + } + +if (!dent) { +printf ("cannot find lirc device for %s\n" , rc); +exit (1 ); + }
This might be a Skip condition as opposed to error. In general when test can't be run due unmet dependencies, please use Skip and not fail.
Quoted 16 lines
tools/testing/selftests/ir/ir-loopback.c new file +16
-0+ +closedir (d); + + fd =open (buf,O_RDWR |O_NONBLOCK ); +if (fd ==-1 ) { +printf ("cannot open: %s: %m\n" , buf); +exit (1 ); + } + +return fd; +} + +int main (int argc,char **argv) +{ +unsigned int mode; +char buf[100 ];
tools/testing/selftests/ir/ir-loopback.c line 106
Quoted 10 lines
tools/testing/selftests/ir/ir-loopback.c new file +10
-0+int rlircfd, wlircfd, protocolfd, i, n; +int errors =0 ; + +srand (time (NULL )); + +if (argc !=3 ) { +printf ("Usage: %s <write rcN> <read rcN>n" , argv[0 ]); +return 2 ; + } +
Please don't use random return codes. Return codes are interpreted by the common framework. Please check kselftest.h to see which one makes sense.
tools/testing/selftests/ir/ir-loopback.c line 113
Quoted 7 lines
tools/testing/selftests/ir/ir-loopback.c new file +7
-0+ rlircfd =lirc_open (argv[2 ]); + mode =LIRC_MODE_SCANCODE ; +if (ioctl (rlircfd,LIRC_SET_REC_MODE , &mode)) { +printf ("failed to set scancode rec mode %s: %m\n" , argv[2 ]); +return 1 ; + } +
Please don't use random return codes. Return codes are interpreted by the common framework. Please check kselftest.h to see which one makes sense.
tools/testing/selftests/ir/ir-loopback.c line 119
Quoted 6 lines
tools/testing/selftests/ir/ir-loopback.c new file +6
-0+ wlircfd =lirc_open (argv[1 ]); +if (ioctl (wlircfd,LIRC_SET_SEND_MODE , &mode)) { +printf ("failed to set scancode send mode %s: %m\n" , argv[1 ]); +return 1 ; + } +
Same as above.
tools/testing/selftests/ir/ir-loopback.c line 126
Quoted 7 lines
tools/testing/selftests/ir/ir-loopback.c new file +7
-0+snprintf (buf,sizeof (buf),"/sys/class/rc/%s/protocols" , argv[2 ]); + protocolfd =open (buf,O_WRONLY ); +if (protocolfd ==-1 ) { +printf ("failed to open %s: %m\n" , buf); +return 1 ; + } +
Same as above.
Quoted 89 lines
tools/testing/selftests/ir/ir-loopback.c new file +83
-0+printf ("Sending IR on %s and receiving IR on %s.\n" , argv[1 ], argv[2 ]); + +for (i=0 ; i<ARRAY_SIZE (protocols); i++) { +if (write (protocolfd, protocols[i].decoder, +strlen (protocols[i].decoder)) ==-1 ) { +printf ("failed to set write decoder\n" ); +return 1 ; + } + +printf ("Testing protocol %s for decoder %s (%d/%d)...\n" , + protocols[i].name, protocols[i].decoder, + i +1 , (int )ARRAY_SIZE (protocols)); + +for (n=0 ; n<TEST_SCANCODES ; n++) { +unsigned scancode =rand () & protocols[i].mask; +unsigned rc_proto = protocols[i].proto; + +if (rc_proto ==RC_PROTO_RC6_MCE ) + scancode |=0x800f0000 ; + +if (rc_proto ==RC_PROTO_NECX && + (((scancode >>16 ) ^ ~(scancode >>8 )) &0xff ) ==0 ) +continue ; + +if (rc_proto ==RC_PROTO_NEC32 && + (((scancode >>8 ) ^ ~scancode) &0xff ) ==0 ) +continue ; + +struct lirc_scancode lsc = { + .rc_proto = rc_proto, + .scancode = scancode + }; + +printf ("Testing scancode:%x\n" , scancode); + +while (write (wlircfd, &lsc,sizeof (lsc)) <0 ) { +if (errno ==EINTR ) +continue ; + +printf ("failed to send ir: %m\n" ); +return 1 ; + } + +struct pollfd pfd = { .fd = rlircfd, .events =POLLIN }; +struct lirc_scancode lsc2; + +poll (&pfd,1 ,1000 ); + +bool decoded = true; + +while (read (rlircfd, &lsc2,sizeof (lsc2)) <0 ) { +if (errno ==EINTR ) +continue ; + +printf ("no scancode decoded: %m\n" ); + errors++; + decoded = false; +break ; + } + +if (!decoded) +continue ; + +if (lsc.rc_proto != lsc2.rc_proto) { +printf ("decoded protocol is different: %d\n" , lsc2.rc_proto); + errors++; + } + +if (lsc.scancode != lsc2.scancode) { +printf ("decoded scancode is different: %llx\n" , lsc2.scancode); + errors++; + } + } + +printf ("OK\n" ); + } + +close (rlircfd); +close (wlircfd); +close (protocolfd); + +return errors >0 ; +}tools/testing/selftests/ir/ir-loopback.sh new file +0
-0
tools/testing/selftests/ir/ir-loopback.sh line 8
Quoted 8 lines
tools/testing/selftests/ir/ir-loopback.sh new file +8
-0@@ -0,0 +1,28 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +GREEN='\033[0;92m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +modprobe rc-loopback
Please check rc-loopback exists or not and handle modprobe failures. If module doesn't exit, the test should exit with skip code.
Quoted 11 lines
tools/testing/selftests/ir/ir-loopback.sh new file +10
-0+ +for i in /sys/class/rc/rc* +do + if grep -q DRV_NAME=rc-loopback $i/uevent + then + RCDEV=$(echo $i | sed sQ/sys/class/rc/QQ) + fi +done + +if [ -n $RCDEV ];
tools/testing/selftests/ir/ir-loopback.sh line 28
Quoted 10 lines
tools/testing/selftests/ir/ir-loopback.sh new file +10
-0+then + TYPE=ir-loopback + ./ir-loopback $RCDEV $RCDEV + ret=$? + if [ $ret -ne 0 ]; then + echo -e ${RED}"FAIL: $TYPE"${NC} + else + echo -e ${GREEN}"PASS: $TYPE"${NC} + fi +fi
Please check tools/testing/selftests/lib/*.sh for examples on how to handle loading test modules and error/skip conditions.
Please refer to the following or other tests that call ksft_* interfaces.
tools/testing/selftests/membarriertools/testing/selftests/breakpoints
thanks,
-- Shuah
sean at mess.org (Sean Young)
PATCH 2/2 media: rc: self test for IR encoders and decoders
Hi Shuah,
Quoted 4 lines · Shuah Khan
Hi Sean,
Thanks for the patch. I just happened to see this when Mauro sent it to me. Doesn't look like linux-ksefltest and I weren't on the patch?
This is true, and that is an oversight on my behalf.
Thank you for your review -- I agree with all your points and thanks for the helpful tips as well. I will fix for v2.
Thanks again,
Sean
Quoted 383 lines · Sean Young
Quoted 6 lines
ir-loopback can transmit IR on one rc device and check the correct scancode and protocol is decoded on a different rc device. This can be used to check IR transmission between two rc devices. Using rc-loopback, we use it to check the IR encoders and decoders themselves.
Signed-off-by Sean Young <sean at mess.org>Quoted 13 lines
--- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/ir/.gitignore | 1 + tools/testing/selftests/ir/Makefile | 19 ++ tools/testing/selftests/ir/config | 12 ++ tools/testing/selftests/ir/ir-loopback.c | 209 ++++++++++++++++++++++ tools/testing/selftests/ir/ir-loopback.sh | 28 +++ 6 files changed, 270 insertions(+) create mode 100644 tools/testing/selftests/ir/.gitignore create mode 100644 tools/testing/selftests/ir/Makefile create mode 100644 tools/testing/selftests/ir/config create mode 100644 tools/testing/selftests/ir/ir-loopback.c create mode 100755 tools/testing/selftests/ir/ir-loopback.shWhy not add to the existing media directory? ../selftests/media_tests?
tools/testing/selftests/Makefile TARGETS += futex · line 18
Quoted 10 lines
tools/testing/selftests/Makefile +1
-0@@ -15,6 +15,7 @@ TARGETS += futex TARGETS += gpio TARGETS += intel_pstate TARGETS += ipc +TARGETS += irDoes this test depend on any hardware being present in the system?
Quoted 23 lines
tools/testing/selftests/Makefile +0
-0TARGETS += kcmp TARGETS += kvm TARGETS += libtools/testing/selftests/ir/.gitignore new file +1
-0@@ -0,0 +1 @@ +ir-loopbacktools/testing/selftests/ir/Makefile new file +7
-0@@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0 +uname_M := $(shell uname -m 2>/dev/null || echo not) +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/) +ifeq ($(ARCH),i386) + ARCH := x86 + CFLAGS := -DCONFIG_X86_32 -D__i386__ +endiftools/testing/selftests/ir/Makefile line 17
Quoted 10 lines
tools/testing/selftests/ir/Makefile new file +10
-0+ifeq ($(ARCH),x86_64) + ARCH := x86 + CFLAGS := -DCONFIG_X86_64 -D__x86_64__ +endif + +CFLAGS += -I../../../../usr/include/ + +TEST_PROGS := ir-loopback.sh + +TEST_GEN_PROGS := ir-loopbackLooks like ir-loopback get run from
ir-loopback.sh.TEST_GEN_PROGS_EXTENDEDis the right variable to use in this case.
TEST_GEN_PROGS_EXTENDED:= ir-loopbackQuoted 84 lines
tools/testing/selftests/ir/Makefile new file +2
-0+ +include ../lib.mktools/testing/selftests/ir/config new file +12
-0@@ -0,0 +1,12 @@ +CONFIG_RC_CORE=y +CONFIG_RC_LOOPBACK=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_IR_IMON_DECODER=mtools/testing/selftests/ir/ir-loopback.c new file +58
-0@@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0 +// test ir decoder +// +// Copyright (C) 2018 Sean Young <sean at mess.org> + +// When sending LIRC_MODE_SCANCODE, the IR will be encoded. rc-loopback +// will send this IR to the receiver side, where we try to read the decoded +// IR. Decoding happens in a separate kernel thread, so we will need to +// wait until that is scheduled, hence we use poll to check for read +// readiness. + +#include <linux/lirc.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> +#include <poll.h> +#include <time.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <dirent.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define TEST_SCANCODES 10 +#define ARRAY_SIZE (arr) (sizeof(arr) / sizeof((arr)[0])) + +static const struct { +enum rc_proto proto; +const char *name; +unsigned int mask; +const char *decoder; +} protocols[] = { + {RC_PROTO_RC5 ,"rc-5" ,0x1f7f ,"rc-5" }, + {RC_PROTO_RC5X_20 ,"rc-5x-20" ,0x1f7f3f ,"rc-5" }, + {RC_PROTO_RC5_SZ ,"rc-5-sz" ,0x2fff ,"rc-5-sz" }, + {RC_PROTO_JVC ,"jvc" ,0xffff ,"jvc" }, + {RC_PROTO_SONY12 ,"sony-12" ,0x1f007f ,"sony" }, + {RC_PROTO_SONY15 ,"sony-15" ,0xff007f ,"sony" }, + {RC_PROTO_SONY20 ,"sony-20" ,0x1fff7f ,"sony" }, + {RC_PROTO_NEC ,"nec" ,0xffff ,"nec" }, + {RC_PROTO_NECX ,"nec-x" ,0xffffff ,"nec" }, + {RC_PROTO_NEC32 ,"nec-32" ,0xffffffff ,"nec" }, + {RC_PROTO_SANYO ,"sanyo" ,0x1fffff ,"sanyo" }, + {RC_PROTO_RC6_0 ,"rc-6-0" ,0xffff ,"rc-6" }, + {RC_PROTO_RC6_6A_20 ,"rc-6-6a-20" ,0xfffff ,"rc-6" }, + {RC_PROTO_RC6_6A_24 ,"rc-6-6a-24" ,0xffffff ,"rc-6" }, + {RC_PROTO_RC6_6A_32 ,"rc-6-6a-32" ,0xffffffff ,"rc-6" }, + {RC_PROTO_RC6_MCE ,"rc-6-mce" ,0x00007fff ,"rc-6" }, + {RC_PROTO_SHARP ,"sharp" ,0x1fff ,"sharp" }, +}; + +int lirc_open (const char *rc) +{ +struct dirent *dent; +char buf[100 ];tools/testing/selftests/ir/ir-loopback.c line 68
Quoted 10 lines
tools/testing/selftests/ir/ir-loopback.c new file +10
-0+DIR *d; +int fd; + +snprintf (buf,sizeof (buf),"/sys/class/rc/%s" , rc); + + d =opendir (buf); +if (!d) { +printf ("cannot open %s: %m\n" , buf); +exit (1 ); + }In this case, you will have to differentiate file not found case and use
ksft_exit_skip()to skip the test.tools/testing/selftests/ir/ir-loopback.c line 80
Quoted 12 lines
tools/testing/selftests/ir/ir-loopback.c new file +12
-0+ +while ((dent =readdir (d)) !=NULL ) { +if (!strncmp (dent->d_name,"lirc" ,4 )) { +snprintf (buf,sizeof (buf),"/dev/%s" , dent->d_name); +break ; + } + } + +if (!dent) { +printf ("cannot find lirc device for %s\n" , rc); +exit (1 ); + }This might be a Skip condition as opposed to error. In general when test can't be run due unmet dependencies, please use Skip and not fail.
Quoted 16 lines
tools/testing/selftests/ir/ir-loopback.c new file +16
-0+ +closedir (d); + + fd =open (buf,O_RDWR |O_NONBLOCK ); +if (fd ==-1 ) { +printf ("cannot open: %s: %m\n" , buf); +exit (1 ); + } + +return fd; +} + +int main (int argc,char **argv) +{ +unsigned int mode; +char buf[100 ];tools/testing/selftests/ir/ir-loopback.c line 106
Quoted 10 lines
tools/testing/selftests/ir/ir-loopback.c new file +10
-0+int rlircfd, wlircfd, protocolfd, i, n; +int errors =0 ; + +srand (time (NULL )); + +if (argc !=3 ) { +printf ("Usage: %s <write rcN> <read rcN>n" , argv[0 ]); +return 2 ; + } +Please don't use random return codes. Return codes are interpreted by the common framework. Please check
kselftest.hto see which one makes sense.tools/testing/selftests/ir/ir-loopback.c line 113
Quoted 7 lines
tools/testing/selftests/ir/ir-loopback.c new file +7
-0+ rlircfd =lirc_open (argv[2 ]); + mode =LIRC_MODE_SCANCODE ; +if (ioctl (rlircfd,LIRC_SET_REC_MODE , &mode)) { +printf ("failed to set scancode rec mode %s: %m\n" , argv[2 ]); +return 1 ; + } +Please don't use random return codes. Return codes are interpreted by the common framework. Please check
kselftest.hto see which one makes sense.tools/testing/selftests/ir/ir-loopback.c line 119
Quoted 6 lines
tools/testing/selftests/ir/ir-loopback.c new file +6
-0+ wlircfd =lirc_open (argv[1 ]); +if (ioctl (wlircfd,LIRC_SET_SEND_MODE , &mode)) { +printf ("failed to set scancode send mode %s: %m\n" , argv[1 ]); +return 1 ; + } +Same as above.
tools/testing/selftests/ir/ir-loopback.c line 126
Quoted 7 lines
tools/testing/selftests/ir/ir-loopback.c new file +7
-0+snprintf (buf,sizeof (buf),"/sys/class/rc/%s/protocols" , argv[2 ]); + protocolfd =open (buf,O_WRONLY ); +if (protocolfd ==-1 ) { +printf ("failed to open %s: %m\n" , buf); +return 1 ; + } +Same as above.
Quoted 89 lines
tools/testing/selftests/ir/ir-loopback.c new file +83
-0+printf ("Sending IR on %s and receiving IR on %s.\n" , argv[1 ], argv[2 ]); + +for (i=0 ; i<ARRAY_SIZE (protocols); i++) { +if (write (protocolfd, protocols[i].decoder, +strlen (protocols[i].decoder)) ==-1 ) { +printf ("failed to set write decoder\n" ); +return 1 ; + } + +printf ("Testing protocol %s for decoder %s (%d/%d)...\n" , + protocols[i].name, protocols[i].decoder, + i +1 , (int )ARRAY_SIZE (protocols)); + +for (n=0 ; n<TEST_SCANCODES ; n++) { +unsigned scancode =rand () & protocols[i].mask; +unsigned rc_proto = protocols[i].proto; + +if (rc_proto ==RC_PROTO_RC6_MCE ) + scancode |=0x800f0000 ; + +if (rc_proto ==RC_PROTO_NECX && + (((scancode >>16 ) ^ ~(scancode >>8 )) &0xff ) ==0 ) +continue ; + +if (rc_proto ==RC_PROTO_NEC32 && + (((scancode >>8 ) ^ ~scancode) &0xff ) ==0 ) +continue ; + +struct lirc_scancode lsc = { + .rc_proto = rc_proto, + .scancode = scancode + }; + +printf ("Testing scancode:%x\n" , scancode); + +while (write (wlircfd, &lsc,sizeof (lsc)) <0 ) { +if (errno ==EINTR ) +continue ; + +printf ("failed to send ir: %m\n" ); +return 1 ; + } + +struct pollfd pfd = { .fd = rlircfd, .events =POLLIN }; +struct lirc_scancode lsc2; + +poll (&pfd,1 ,1000 ); + +bool decoded = true; + +while (read (rlircfd, &lsc2,sizeof (lsc2)) <0 ) { +if (errno ==EINTR ) +continue ; + +printf ("no scancode decoded: %m\n" ); + errors++; + decoded = false; +break ; + } + +if (!decoded) +continue ; + +if (lsc.rc_proto != lsc2.rc_proto) { +printf ("decoded protocol is different: %d\n" , lsc2.rc_proto); + errors++; + } + +if (lsc.scancode != lsc2.scancode) { +printf ("decoded scancode is different: %llx\n" , lsc2.scancode); + errors++; + } + } + +printf ("OK\n" ); + } + +close (rlircfd); +close (wlircfd); +close (protocolfd); + +return errors >0 ; +}tools/testing/selftests/ir/ir-loopback.sh new file +0
-0tools/testing/selftests/ir/ir-loopback.sh line 8
Quoted 8 lines
tools/testing/selftests/ir/ir-loopback.sh new file +8
-0@@ -0,0 +1,28 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +GREEN='\033[0;92m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +modprobe rc-loopbackPlease check rc-loopback exists or not and handle modprobe failures. If module doesn't exit, the test should exit with skip code.
Quoted 11 lines
tools/testing/selftests/ir/ir-loopback.sh new file +10
-0+ +for i in /sys/class/rc/rc* +do + if grep -q DRV_NAME=rc-loopback $i/uevent + then + RCDEV=$(echo $i | sed sQ/sys/class/rc/QQ) + fi +done + +if [ -n $RCDEV ];tools/testing/selftests/ir/ir-loopback.sh line 28
Quoted 10 lines
tools/testing/selftests/ir/ir-loopback.sh new file +10
-0+then + TYPE=ir-loopback + ./ir-loopback $RCDEV $RCDEV + ret=$? + if [ $ret -ne 0 ]; then + echo -e ${RED}"FAIL: $TYPE"${NC} + else + echo -e ${GREEN}"PASS: $TYPE"${NC} + fi +fiPlease check
tools/testing/selftests/lib/*.shfor examples on how to handle loading test modules and error/skip conditions.Please refer to the following or other tests that call ksft_* interfaces.
tools/testing/selftests/membarriertools/testing/selftests/breakpointsthanks,
-- Shuah