diff --git a/Makefile b/Makefile index 81f1c12..09ed5c6 100755 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ TOP_DIR ?= $(UT_CORE_DIR) BIN_DIR ?= $(TOP_DIR)/build/bin LIB_DIR ?= $(TOP_DIR)/build/$(TARGET)/lib BUILD_DIR ?= $(TOP_DIR)/build/$(TARGET)/obj +HEADER_DIR ?= $(TOP_DIR)/build/include # Non-Moveable Directories FRAMEWORK_DIR = $(UT_CORE_DIR)/framework @@ -116,7 +117,7 @@ all: framework $(OBJS) # Build framework # Recursive make is needed as src files are not available during the first iteration -framework: checkvariantchange createdirs download_and_build +framework: check_variant_change createdirs download_and_build copy_headers @${ECHOE} ${GREEN}Framework downloaded and built${NC} @cp $(UT_CONTROL)/build/$(TARGET)/lib/libut_control.* $(LIB_DIR) @cp $(UT_CONTROL)/build/$(TARGET)/lib/libut_control.* $(BIN_DIR) @@ -125,6 +126,19 @@ framework: checkvariantchange createdirs download_and_build @if [ -d "$(TOP_DIR)/../include" ] && [ -d "$(BUILD_DIR)/src" ]; then \ ${UT_CORE_DIR}/compare-functions-in-headers-testsuite.sh $(TOP_DIR)/../include $(BIN_DIR)/${TARGET_EXEC} ${TARGET}; \ fi + @${ECHOE} ${GREEN}Building keyhandler${NC} + @make -C keyhandler/ + +# Copy header files to the build directory +copy_headers: + @${ECHOE} ${GREEN}Copying header files to [$(HEADER_DIR)]${NC} + @$(MKDIR_P) $(HEADER_DIR) + @for dir in $(INC_DIRS); do \ + if [ -d "$$dir" ]; then \ + find "$$dir" -type f -name "*.h" -exec cp {} $(HEADER_DIR) \; ; \ + fi \ + done + @${ECHOE} ${GREEN}Header files copied to ${HEADER_DIR}${NC} download_and_build: @${ECHOE} ${GREEN}Ensure ut-core frameworks are present${NC} @@ -159,7 +173,7 @@ $(BUILD_DIR)/%.o: %.cpp @$(COMPILER) $(CXXFLAGS) -c $< -o $@ # Rule to check if the VARIANT has changed -checkvariantchange: +check_variant_change: @if [ -f "$(VARIANT_FILE)" ]; then \ PREVIOUS_VARIANT=$$(cat $(VARIANT_FILE)); \ if [ "$$PREVIOUS_VARIANT" != "$(VARIANT)" ]; then \ @@ -186,6 +200,8 @@ clean: @$(RM) -rf $(VARIANT_FILE) @${ECHOE} ${GREEN}Performing Clean for $(TARGET) ${LIB_DIR} ${NC} @${RM} -rf ${LIB_DIR} + @${ECHOE} ${GREEN}Performing Clean for Keyhandler ${NC} + @make -C keyhandler/ clean @${ECHOE} ${GREEN}Clean Completed${NC} cleanall: clean diff --git a/keyhandler/Makefile b/keyhandler/Makefile index 4009dbe..bba221a 100644 --- a/keyhandler/Makefile +++ b/keyhandler/Makefile @@ -17,31 +17,48 @@ # * limitations under the License. # * ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) -BIN_DIR := $(ROOT_DIR)/build/bin + +# Set target based on TARGET variable +TARGET := $(if $(TARGET),$(TARGET),linux) +#export TARGET + +BUILD_DIR := $(ROOT_DIR)/../build +UT_CORE_DIR := ../$(ROOT_DIR) +BIN_DIR := $(BUILD_DIR)/bin #TOP_DIR := $(ROOT_DIR) ECHOE = /bin/echo -e TARGET_EXEC = ut_core_key_input # Variables +ifeq ($(TARGET),arm) +COMPILER := $(if $(filter CPP,$(VARIANT)),$(CXX),$(CC)) +#CC := arm-rdk-linux-gnueabi-gcc -mthumb -mfpu=vfp -mcpu=cortex-a9 -mfloat-abi=soft -mabi=aapcs-linux -mno-thumb-interwork -ffixed-r8 -fomit-frame-pointer +# CFLAGS will be overriden by Caller as required +INC_DIRS += $(UT_CORE_DIR)/sysroot/usr/include +else CC = gcc -ggdb -o0 -Wall -SRC = keyhandler.c ../src/ut_kvp_profile.c -INC_DIRS = ../include ../framework/CUnit-2.1-3/CUnit/Headers ../framework/ut-control/include +endif + +SRC = keyhandler.c +INC_DIRS = $(BUILD_DIR)/include # Final flags INC_FLAGS := $(addprefix -I,$(INC_DIRS)) -XCFLAGS += $(CFLAGS) $(INC_FLAGS) -DUT_CUNIT -XLDFLAGS += -L../framework/ut-control/build/linux/lib -lut_control -Wl,-rpath, -pthread -lpthread +XCFLAGS += $(CFLAGS) $(INC_FLAGS) +XLDFLAGS += -L$(BUILD_DIR)/$(TARGET)/lib -lut_control # Default target all: $(TARGET_EXEC) # Build target $(TARGET_EXEC): $(SRC) - @$(CC) $(SRC) $(XCFLAGS) $(XLDFLAGS) -o $(TARGET_EXEC) + @$(CC) $(SRC) $(XCFLAGS) $(XLDFLAGS) -o $(BIN_DIR)/$(TARGET_EXEC) + @cp *.yaml *.sh $(BIN_DIR) # Clean target clean: - @rm -f $(TARGET_EXEC) + @rm -f $(BIN_DIR)/$(TARGET_EXEC) + @rm -f $(BIN_DIR)/*.yaml $(BIN_DIR)/*.sh $(BIN_DIR)/*.so # Phony targets .PHONY: all clean diff --git a/keyhandler/keyhandler.c b/keyhandler/keyhandler.c index bf498c7..58862d7 100644 --- a/keyhandler/keyhandler.c +++ b/keyhandler/keyhandler.c @@ -23,18 +23,52 @@ #include #include // For open(), O_WRONLY, O_NONBLOCK #include +#include -#include #include +#include #include +static ut_kvp_instance_t *gKVP_Instance = NULL; +#define KEYHANDLER_PROFILE_YAML_FILE "input-event-codes-5.15.yaml" + +ut_kvp_status_t keyhandler_profile_open(char *fileName) +{ + ut_kvp_status_t result; + + if (gKVP_Instance == NULL) + { + gKVP_Instance = ut_kvp_createInstance(); + assert(gKVP_Instance != NULL); + } + + result = ut_kvp_open(gKVP_Instance, fileName); + assert( result == UT_KVP_STATUS_SUCCESS ); + + return result; +} + +void keyhandler_profile_close(void) +{ + if ( gKVP_Instance != NULL ) + { + ut_kvp_destroyInstance(gKVP_Instance); + gKVP_Instance = NULL; + } +} + +ut_kvp_instance_t *keyhandler_getInstance( void ) +{ + return gKVP_Instance; +} + void print_usage(const char *program_name) { - printf("\nUsage: %s -p -t -c -v \n", program_name); + printf("\nUsage: %s -p -t -c -v \n", program_name); printf("More Info : https://github.com/rdkcentral/ut-core/discussions/148\n"); } -void emit(int fd, int type, int code, int val) +void keyhandler_emit(int fd, int type, int code, int val) { struct input_event ie; @@ -45,16 +79,16 @@ void emit(int fd, int type, int code, int val) ie.time.tv_sec = 0; ie.time.tv_usec = 0; - write(fd, &ie, sizeof(ie)); + write(fd, &ie, sizeof(ie)); //FIXME : For every write error check is needed - ie.type = EV_SYN; + ie.type = EV_SYN; // for every KEY operation, need to report the event ie.code = SYN_REPORT; ie.value = 0; - write(fd, &ie, sizeof(ie)); + write(fd, &ie, sizeof(ie)); //FIXME : For every write error check is needed } -int get_code(ut_kvp_instance_t *pInstance, char *type, char *code) +int keyhandler_get_code(ut_kvp_instance_t *pInstance, char *type, char *code) { char key_code_str[256]; int key_code; @@ -62,12 +96,17 @@ int get_code(ut_kvp_instance_t *pInstance, char *type, char *code) snprintf(key_code_str, sizeof(key_code_str), "%s%s%s", type, "/", code); UT_LOG( "key_code_str=[%s]", key_code_str ); key_code = ut_kvp_getUInt32Field( pInstance, key_code_str ); + if (key_code == 0) + { + UT_LOG_ERROR("Keycode not found"); + return 0; + } UT_LOG( "key_code=[%d]", key_code ); return key_code; } -int get_type(ut_kvp_instance_t *pInstance, char *type) +int keyhandler_get_type(ut_kvp_instance_t *pInstance, char *type) { char event_type_str[256]; int event_type_code; @@ -75,12 +114,17 @@ int get_type(ut_kvp_instance_t *pInstance, char *type) snprintf(event_type_str, sizeof(event_type_str), "%s%s", "EVENT_TYPE/", type); UT_LOG("event_type_str=[%s]", event_type_str); event_type_code = ut_kvp_getUInt32Field(pInstance, event_type_str); + if (event_type_code == 0) + { + UT_LOG_ERROR("event type code not found"); + return 0; + } UT_LOG("event_type_code=[%d]", event_type_code); return event_type_code; } -void print_yaml(ut_kvp_instance_t *instance) +void keyhandler_print_yaml(ut_kvp_instance_t *instance) { char* kvpData; @@ -99,9 +143,10 @@ void print_yaml(ut_kvp_instance_t *instance) int main(int argc, char *argv[]) { int opt; - char *profile_file = NULL; - char *type = NULL; - char *code = NULL; + char *profileFile = NULL; + char *typeString = NULL; + char *codeString = NULL; + int type, code; int value; ut_kvp_status_t status; ut_kvp_instance_t *pInstance; @@ -109,8 +154,9 @@ int main(int argc, char *argv[]) // Parse command-line arguments /* - • -p - Path to the profile YAML file defining event types and key mappings. Required. + • -p + Path to the profile YAML file defining event types and key mappings. Optional. + Default : KEYHANDLER_PROFILE_YAML_FILE • -t Type of the event (e.g., EV_KEY). Required. • -c @@ -124,18 +170,19 @@ int main(int argc, char *argv[]) switch (opt) { case 'p': - profile_file = optarg; - status = ut_kvp_profile_open(optarg); + profileFile = optarg; + status = keyhandler_profile_open(optarg); if (status != UT_KVP_STATUS_SUCCESS) { - UT_LOG_ERROR("Failed to Load profile_file [%s]", optarg); + UT_LOG_ERROR("Failed to Load profileFile [%s]", optarg); } + UT_LOG_DEBUG("Profile File used: [%s]\n", profileFile); break; case 't': - type = optarg; + typeString = optarg; break; case 'c': - code = optarg; + codeString = optarg; break; case 'v': value = atoi(optarg); @@ -147,54 +194,72 @@ int main(int argc, char *argv[]) } // Validate required arguments - if (profile_file == NULL) + if (profileFile == NULL) { - UT_LOG_ERROR("Error: Missing required arguments."); - print_usage(argv[0]); - return 1; + profileFile = KEYHANDLER_PROFILE_YAML_FILE; + status = keyhandler_profile_open(KEYHANDLER_PROFILE_YAML_FILE); + if (status != UT_KVP_STATUS_SUCCESS) + { + UT_LOG_ERROR("Failed to Load profileFile [%s]", profileFile); + keyhandler_profile_close(); + return -1; + } + UT_LOG_DEBUG("Profile File used: [%s]\n", profileFile); } - pInstance = ut_kvp_profile_getInstance(); + pInstance = keyhandler_getInstance(); if(pInstance == NULL) { - UT_LOG_ERROR("perhaps platform profile was not passed using -p switch"); + UT_LOG_ERROR("KVP instance is NULL"); return -1; } - //print_yaml(pInstance); + //keyhandler_print_yaml(pInstance); + type = keyhandler_get_type(pInstance, typeString); + code = keyhandler_get_code(pInstance, typeString, codeString); - int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); + if (code == 0 || type == 0) + { + UT_LOG_ERROR("Code = [%d] and Type = [%d]\n", code, type); + keyhandler_profile_close(); + return -1; + } + int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); + //FIXME : error checks for ioctls and fds /* + * Note : Taken reference from : https://kernel.org/doc/html/latest/input/uinput.html#keyboard-events * The ioctls below will enable the device that is about to be - * created, to pass key events, in this case the space key. + * created, to pass key events. */ - //ioctl(fd, UI_SET_EVBIT, EV_KEY); - //ioctl(fd, UI_SET_KEYBIT, result_kvp); + //FIXME : error checks for ioctls and fds + ioctl(fd, UI_SET_EVBIT, type); + ioctl(fd, UI_SET_KEYBIT, code); memset(&usetup, 0, sizeof(usetup)); usetup.id.bustype = BUS_USB; - usetup.id.vendor = 0x1234; /* sample vendor */ - usetup.id.product = 0x5678; /* sample product */ - strcpy(usetup.name, "Example device"); + usetup.id.vendor = 0xbeef; /* from RDK Key Simulator */ + usetup.id.product = 0xfedc; /* from RDK Key Simulator */ + usetup.id.version = 1; /* from RDK Key Simulator */ + strcpy(usetup.name, "key-simulator"); /* from RDK Key Simulator */ ioctl(fd, UI_DEV_SETUP, &usetup); ioctl(fd, UI_DEV_CREATE); // Print the parsed arguments - //UT_LOG_DEBUG("Profile file: %s\n", profile_file); + //UT_LOG_DEBUG("Profile file: %s\n", profileFile); //UT_LOG_DEBUG("type: %s\n", type); //UT_LOG_DEBUG("code: %s\n", code); //UT_LOG_DEBUG("value: %d\n", value); /* Key press, report the event, send key release, and report again */ - emit(fd, get_type(pInstance, type), get_code(pInstance, type, code), value); + keyhandler_emit(fd, keyhandler_get_type(pInstance, typeString), keyhandler_get_code(pInstance, typeString, codeString), value); ioctl(fd, UI_DEV_DESTROY); close(fd); - ut_kvp_profile_close(); + keyhandler_profile_close(); return 0; -} +} \ No newline at end of file diff --git a/keyhandler/run.sh b/keyhandler/run.sh index a0c8369..586be69 100755 --- a/keyhandler/run.sh +++ b/keyhandler/run.sh @@ -32,4 +32,4 @@ if [ -d ../build/linux/lib ]; then cp ../build/linux/lib/libut_control.so . fi export LD_LIBRARY_PATH=/usr/lib:/lib:/home/root:. -./ut_core_key_input -p input-event-codes-5.15.yaml $@ +./ut_core_key_input $@