From 2d43854e216bad1e6c0304de6bfe0dd285555fe1 Mon Sep 17 00:00:00 2001 From: strawmanbobi Date: Wed, 2 Nov 2016 22:29:13 +0800 Subject: [PATCH] update 2016-11-02 b1 1. created project 2. initialized ir encode and decode source files --- .gitignore | 2 + src/ir_decoder/.idea/.name | 1 + src/ir_decoder/.idea/codeStyleSettings.xml | 38 + src/ir_decoder/.idea/encodings.xml | 8 + src/ir_decoder/.idea/irda_decoder.iml | 42 + src/ir_decoder/.idea/misc.xml | 19 + src/ir_decoder/.idea/modules.xml | 8 + src/ir_decoder/.idea/workspace.xml | 781 ++++++++ src/ir_decoder/Android.mk | 23 + src/ir_decoder/CMakeLists.txt | 27 + src/ir_decoder/CleanSpec.mk | 49 + src/ir_decoder/MODULE_LICENSE_MIT | 0 src/ir_decoder/NOTICE | 19 + src/ir_decoder/bc_parse_parameter.c | 192 ++ src/ir_decoder/bc_parse_parameter.h | 53 + src/ir_decoder/include/ucon_decode_jni.h | 216 +++ src/ir_decoder/irda_apply.c | 667 +++++++ src/ir_decoder/irda_apply.h | 58 + src/ir_decoder/irda_defs.h | 94 + src/ir_decoder/irda_irframe.c | 190 ++ src/ir_decoder/irda_irframe.h | 29 + src/ir_decoder/irda_lib.c | 548 ++++++ src/ir_decoder/irda_lib.h | 264 +++ src/ir_decoder/irda_parse_ac_parameter.c | 1413 ++++++++++++++ src/ir_decoder/irda_parse_ac_parameter.h | 87 + src/ir_decoder/irda_parse_forbidden_info.c | 160 ++ src/ir_decoder/irda_parse_forbidden_info.h | 45 + src/ir_decoder/irda_parse_frame_parameter.c | 362 ++++ src/ir_decoder/irda_parse_frame_parameter.h | 60 + src/ir_decoder/irda_utils.c | 107 + src/ir_decoder/irda_utils.h | 39 + src/ir_decoder/ucon_decode.c | 1934 +++++++++++++++++++ src/ir_decoder/ucon_decode.h | 779 ++++++++ src/ir_decoder/ucon_decode_jni.c | 389 ++++ src/ir_encoder/.idea/misc.xml | 14 + src/ir_encoder/.idea/modules.xml | 8 + src/ir_encoder/.idea/vcs.xml | 6 + src/ir_encoder/.idea/workspace.xml | 760 ++++++++ src/ir_encoder/.idea/yk_encoder.iml | 11 + src/ir_encoder/merge.py | 33 + src/ir_encoder/s_ac_ii.py | 110 ++ src/ir_encoder/s_acleaner.py | 81 + src/ir_encoder/s_bc.py | 108 ++ src/ir_encoder/s_bstb.py | 81 + src/ir_encoder/s_crobot.py | 81 + src/ir_encoder/s_dvd.py | 80 + src/ir_encoder/s_fan.py | 81 + src/ir_encoder/s_iptv.py | 81 + src/ir_encoder/s_light.py | 81 + src/ir_encoder/s_nw.py | 81 + src/ir_encoder/s_pro.py | 128 ++ src/ir_encoder/s_pro_hex.py | 128 ++ src/ir_encoder/s_projector.py | 82 + src/ir_encoder/s_stb.py | 81 + src/ir_encoder/s_stereo.py | 81 + src/ir_encoder/s_stereo_2.py | 81 + src/ir_encoder/s_tv.py | 81 + 57 files changed, 11062 insertions(+) create mode 100644 .gitignore create mode 100644 src/ir_decoder/.idea/.name create mode 100644 src/ir_decoder/.idea/codeStyleSettings.xml create mode 100644 src/ir_decoder/.idea/encodings.xml create mode 100644 src/ir_decoder/.idea/irda_decoder.iml create mode 100644 src/ir_decoder/.idea/misc.xml create mode 100644 src/ir_decoder/.idea/modules.xml create mode 100644 src/ir_decoder/.idea/workspace.xml create mode 100644 src/ir_decoder/Android.mk create mode 100644 src/ir_decoder/CMakeLists.txt create mode 100644 src/ir_decoder/CleanSpec.mk create mode 100644 src/ir_decoder/MODULE_LICENSE_MIT create mode 100644 src/ir_decoder/NOTICE create mode 100644 src/ir_decoder/bc_parse_parameter.c create mode 100644 src/ir_decoder/bc_parse_parameter.h create mode 100644 src/ir_decoder/include/ucon_decode_jni.h create mode 100644 src/ir_decoder/irda_apply.c create mode 100644 src/ir_decoder/irda_apply.h create mode 100644 src/ir_decoder/irda_defs.h create mode 100644 src/ir_decoder/irda_irframe.c create mode 100644 src/ir_decoder/irda_irframe.h create mode 100644 src/ir_decoder/irda_lib.c create mode 100644 src/ir_decoder/irda_lib.h create mode 100644 src/ir_decoder/irda_parse_ac_parameter.c create mode 100644 src/ir_decoder/irda_parse_ac_parameter.h create mode 100644 src/ir_decoder/irda_parse_forbidden_info.c create mode 100644 src/ir_decoder/irda_parse_forbidden_info.h create mode 100644 src/ir_decoder/irda_parse_frame_parameter.c create mode 100644 src/ir_decoder/irda_parse_frame_parameter.h create mode 100644 src/ir_decoder/irda_utils.c create mode 100644 src/ir_decoder/irda_utils.h create mode 100644 src/ir_decoder/ucon_decode.c create mode 100644 src/ir_decoder/ucon_decode.h create mode 100644 src/ir_decoder/ucon_decode_jni.c create mode 100644 src/ir_encoder/.idea/misc.xml create mode 100644 src/ir_encoder/.idea/modules.xml create mode 100644 src/ir_encoder/.idea/vcs.xml create mode 100644 src/ir_encoder/.idea/workspace.xml create mode 100644 src/ir_encoder/.idea/yk_encoder.iml create mode 100644 src/ir_encoder/merge.py create mode 100644 src/ir_encoder/s_ac_ii.py create mode 100644 src/ir_encoder/s_acleaner.py create mode 100644 src/ir_encoder/s_bc.py create mode 100644 src/ir_encoder/s_bstb.py create mode 100644 src/ir_encoder/s_crobot.py create mode 100644 src/ir_encoder/s_dvd.py create mode 100644 src/ir_encoder/s_fan.py create mode 100644 src/ir_encoder/s_iptv.py create mode 100644 src/ir_encoder/s_light.py create mode 100644 src/ir_encoder/s_nw.py create mode 100644 src/ir_encoder/s_pro.py create mode 100644 src/ir_encoder/s_pro_hex.py create mode 100644 src/ir_encoder/s_projector.py create mode 100644 src/ir_encoder/s_stb.py create mode 100644 src/ir_encoder/s_stereo.py create mode 100644 src/ir_encoder/s_stereo_2.py create mode 100644 src/ir_encoder/s_tv.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bbfbbea --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.bin +*/output/ \ No newline at end of file diff --git a/src/ir_decoder/.idea/.name b/src/ir_decoder/.idea/.name new file mode 100644 index 0000000..3f09379 --- /dev/null +++ b/src/ir_decoder/.idea/.name @@ -0,0 +1 @@ +irda_decoder \ No newline at end of file diff --git a/src/ir_decoder/.idea/codeStyleSettings.xml b/src/ir_decoder/.idea/codeStyleSettings.xml new file mode 100644 index 0000000..23f6cae --- /dev/null +++ b/src/ir_decoder/.idea/codeStyleSettings.xml @@ -0,0 +1,38 @@ + + + + + + \ No newline at end of file diff --git a/src/ir_decoder/.idea/encodings.xml b/src/ir_decoder/.idea/encodings.xml new file mode 100644 index 0000000..e2f5581 --- /dev/null +++ b/src/ir_decoder/.idea/encodings.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/ir_decoder/.idea/irda_decoder.iml b/src/ir_decoder/.idea/irda_decoder.iml new file mode 100644 index 0000000..ff45b84 --- /dev/null +++ b/src/ir_decoder/.idea/irda_decoder.iml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ir_decoder/.idea/misc.xml b/src/ir_decoder/.idea/misc.xml new file mode 100644 index 0000000..87a6b24 --- /dev/null +++ b/src/ir_decoder/.idea/misc.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ir_decoder/.idea/modules.xml b/src/ir_decoder/.idea/modules.xml new file mode 100644 index 0000000..68c613d --- /dev/null +++ b/src/ir_decoder/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/ir_decoder/.idea/workspace.xml b/src/ir_decoder/.idea/workspace.xml new file mode 100644 index 0000000..6a82659 --- /dev/null +++ b/src/ir_decoder/.idea/workspace.xml @@ -0,0 +1,781 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + C/C++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1440737933115 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ir_decoder/Android.mk b/src/ir_decoder/Android.mk new file mode 100644 index 0000000..6249f05 --- /dev/null +++ b/src/ir_decoder/Android.mk @@ -0,0 +1,23 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_CFLAGS := -DBOARD_MT6580 +LOCAL_MODULE := libirdecode +LOCAL_SRC_FILES := ucon_decode_jni.c \ + ucon_decode.c \ + bc_parse_parameter.c \ + irda_lib.c \ + irda_apply.c \ + irda_irframe.c \ + irda_parse_ac_parameter.c \ + irda_parse_forbidden_info.c \ + irda_parse_frame_parameter.c \ + irda_utils.c \ + +LOCAL_MODULE_TAGS := optional +LOCAL_PRELINK_MODULE := false + +LOCAL_SHARED_LIBRARIES := liblog libcutils + +include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/src/ir_decoder/CMakeLists.txt b/src/ir_decoder/CMakeLists.txt new file mode 100644 index 0000000..4b9aec7 --- /dev/null +++ b/src/ir_decoder/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.2) +project(irda_decoder) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +add_definitions(-DBOARD_PC) +set(SOURCE_FILES + ucon_decode.c + ucon_decode.h + bc_parse_parameter.c + bc_parse_parameter.h + irda_lib.c + irda_lib.h + irda_apply.c + irda_apply.h + irda_defs.h + irda_irframe.c + irda_irframe.h + irda_parse_ac_parameter.c + irda_parse_ac_parameter.h + irda_parse_forbidden_info.c + irda_parse_forbidden_info.h + irda_parse_frame_parameter.c + irda_parse_frame_parameter.h + irda_utils.c + irda_utils.h) + +add_executable(irda_decoder ${SOURCE_FILES}) \ No newline at end of file diff --git a/src/ir_decoder/CleanSpec.mk b/src/ir_decoder/CleanSpec.mk new file mode 100644 index 0000000..b84e1b6 --- /dev/null +++ b/src/ir_decoder/CleanSpec.mk @@ -0,0 +1,49 @@ +# Copyright (C) 2007 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ + +# For example: +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) + +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ diff --git a/src/ir_decoder/MODULE_LICENSE_MIT b/src/ir_decoder/MODULE_LICENSE_MIT new file mode 100644 index 0000000..e69de29 diff --git a/src/ir_decoder/NOTICE b/src/ir_decoder/NOTICE new file mode 100644 index 0000000..b73fe7b --- /dev/null +++ b/src/ir_decoder/NOTICE @@ -0,0 +1,19 @@ +The LIBIRDECODE distribution is Copyright (c) 2015 Strawmanbobi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/ir_decoder/bc_parse_parameter.c b/src/ir_decoder/bc_parse_parameter.c new file mode 100644 index 0000000..6271a2d --- /dev/null +++ b/src/ir_decoder/bc_parse_parameter.c @@ -0,0 +1,192 @@ +/************************************************************************************************** +Filename: bc_parse_parameter.c +Revised: Date: 2016-02-25 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON BLE Central decode + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2016-02-25: created by strawmanbobi +**************************************************************************************************/ + +/* + *inclusion + */ +#include +#include +#include +#include "irda_defs.h" +#include "irda_utils.h" +#include "bc_parse_parameter.h" + +/* + * global vars + */ + +/* + * external vars + */ + +/* + * function declaration + */ +INT8 parse_ble_command(UINT8 *data, UINT16 *trav_offset, t_bc_command *bc_command); + +/* + * function definition + */ + +INT8 parse_ble_name(UINT8 *data, UINT8 length, char *name) +{ + if (NULL == data || NULL == name || 0 == length) + { + return IR_DECODE_FAILED; + } + irda_memcpy(name, data, length); + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_ble_need_conn_ack(UINT8 *data, UINT8 *nca) +{ + if (NULL == data || NULL == nca) + { + return IR_DECODE_FAILED; + } + + if (*data == '0') + { + *nca = 0; + } + else if (*data == '1') + { + *nca = 1; + } + else + { + *nca = 0; + } + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_ble_name_essential_length(UINT8 *data, UINT8 *nel) +{ + if (NULL == data || NULL == nel) + { + return IR_DECODE_FAILED; + } + + // must be 2 bytes + *nel = ((data[0] - '0') * 10) + (data[1] - '0'); + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_ble_name_length(UINT8 *data, UINT8 *nl) +{ + if (NULL == data || NULL == nl) + { + return IR_DECODE_FAILED; + } + + // must be 2 bytes + *nl = ((data[0] - '0') * 10) + (data[1] - '0'); + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_ble_command(UINT8 *data, UINT16 *trav_offset, t_bc_command *bc_command) +{ + UINT8 command_len = 0; + + if (NULL == data || NULL == bc_command || NULL == trav_offset) + { + return IR_DECODE_FAILED; + } + + command_len = data[*trav_offset]; + + if (0 == command_len || command_len > BLE_GAP_MTU) + { + // reset data structure of bc_command in case of invalid command_len is found + bc_command->length = 0; + bc_command->handle = 0x0000; + irda_memset(bc_command->command, 0x00, BLE_GAP_MTU); + return IR_DECODE_SUCCEEDED; + } + bc_command->length = command_len; + (*trav_offset)++; + + bc_command->handle = data[*trav_offset] * 0x0100; + (*trav_offset)++; + bc_command->handle += data[*trav_offset]; + (*trav_offset)++; + + // prepare commands + irda_memset(bc_command->command, 0x00, BLE_GAP_MTU); + irda_memcpy(bc_command->command, &data[*trav_offset], bc_command->length); + (*trav_offset) += bc_command->length; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_ble_commands(t_tag_head *tag, t_bc_commands *bc_commands) +{ + UINT16 hex_len = 0; +#if (defined BOARD_PC) || (defined BOARD_MT6580) + UINT16 i = 0; +#endif + UINT16 trav_offset = 0; + UINT8 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag || NULL == bc_commands) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + bc_commands->seg_count = hex_data[0]; + bc_commands->commands = (t_bc_command*)irda_malloc(bc_commands->seg_count * sizeof(t_bc_command)); + + for (seg_index = 0; seg_index < bc_commands->seg_count; seg_index++) + { + // trav_offset + 1 indicates the cursor pointing to internal data slice marked by trav_offset, considering + // the total length of a single byte + if (IR_DECODE_FAILED == parse_ble_command(&hex_data[trav_offset + 1], + &trav_offset, + &bc_commands->commands[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } +#if (defined BOARD_PC) || (defined BOARD_MT6580) + IR_PRINTF("command length = %d\n", bc_commands->commands[seg_index].length); + IR_PRINTF("command handle = 0x%02x\n", bc_commands->commands[seg_index].handle); + for(i = 0; i < bc_commands->commands[seg_index].length; i++) + { + IR_PRINTF("[%02X] ", bc_commands->commands[seg_index].command[i]); + } + IR_PRINTF("\n"); +#endif + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} \ No newline at end of file diff --git a/src/ir_decoder/bc_parse_parameter.h b/src/ir_decoder/bc_parse_parameter.h new file mode 100644 index 0000000..0476c05 --- /dev/null +++ b/src/ir_decoder/bc_parse_parameter.h @@ -0,0 +1,53 @@ +/************************************************************************************************** +Filename: bc_parse_parameter.h +Revised: Date: 2016-02-25 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON BLE Central decode + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2016-02-25: created by strawmanbobi +**************************************************************************************************/ + +/* + *inclusion + */ +#include "ucon_decode.h" + +#ifndef _BC_PARSE_PARAMETER_H_ +#define _BC_PARSE_PARAMETER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * public macros + */ + +/* + * public type definition + */ + +/* + * public function declaration + */ + +extern INT8 parse_ble_name(UINT8 *data, UINT8 length, char *name); + +extern INT8 parse_ble_need_conn_ack(UINT8 *data, UINT8 *nca); + +extern INT8 parse_ble_name_essential_length(UINT8 *data, UINT8 *nel); + +extern INT8 parse_ble_name_length(UINT8 *data, UINT8 *nl); + +extern INT8 parse_ble_commands(t_tag_head *tag, t_bc_commands *bc_commands); + +#ifdef __cplusplus +} +#endif + +#endif // _IRDA_PARSE_AC_PARAMETER_H_ \ No newline at end of file diff --git a/src/ir_decoder/include/ucon_decode_jni.h b/src/ir_decoder/include/ucon_decode_jni.h new file mode 100644 index 0000000..43f74db --- /dev/null +++ b/src/ir_decoder/include/ucon_decode_jni.h @@ -0,0 +1,216 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_yuekong_remote_service_DecodeService */ + +#ifndef _Included_com_yuekong_remote_service_DecodeService +#define _Included_com_yuekong_remote_service_DecodeService +#ifdef __cplusplus +extern "C" { +#endif +#undef com_yuekong_remote_service_DecodeService_BIND_ABOVE_CLIENT +#define com_yuekong_remote_service_DecodeService_BIND_ABOVE_CLIENT 8L +#undef com_yuekong_remote_service_DecodeService_BIND_ADJUST_WITH_ACTIVITY +#define com_yuekong_remote_service_DecodeService_BIND_ADJUST_WITH_ACTIVITY 128L +#undef com_yuekong_remote_service_DecodeService_BIND_ALLOW_OOM_MANAGEMENT +#define com_yuekong_remote_service_DecodeService_BIND_ALLOW_OOM_MANAGEMENT 16L +#undef com_yuekong_remote_service_DecodeService_BIND_AUTO_CREATE +#define com_yuekong_remote_service_DecodeService_BIND_AUTO_CREATE 1L +#undef com_yuekong_remote_service_DecodeService_BIND_DEBUG_UNBIND +#define com_yuekong_remote_service_DecodeService_BIND_DEBUG_UNBIND 2L +#undef com_yuekong_remote_service_DecodeService_BIND_IMPORTANT +#define com_yuekong_remote_service_DecodeService_BIND_IMPORTANT 64L +#undef com_yuekong_remote_service_DecodeService_BIND_NOT_FOREGROUND +#define com_yuekong_remote_service_DecodeService_BIND_NOT_FOREGROUND 4L +#undef com_yuekong_remote_service_DecodeService_BIND_WAIVE_PRIORITY +#define com_yuekong_remote_service_DecodeService_BIND_WAIVE_PRIORITY 32L +#undef com_yuekong_remote_service_DecodeService_CONTEXT_IGNORE_SECURITY +#define com_yuekong_remote_service_DecodeService_CONTEXT_IGNORE_SECURITY 2L +#undef com_yuekong_remote_service_DecodeService_CONTEXT_INCLUDE_CODE +#define com_yuekong_remote_service_DecodeService_CONTEXT_INCLUDE_CODE 1L +#undef com_yuekong_remote_service_DecodeService_CONTEXT_RESTRICTED +#define com_yuekong_remote_service_DecodeService_CONTEXT_RESTRICTED 4L +#undef com_yuekong_remote_service_DecodeService_MODE_APPEND +#define com_yuekong_remote_service_DecodeService_MODE_APPEND 32768L +#undef com_yuekong_remote_service_DecodeService_MODE_ENABLE_WRITE_AHEAD_LOGGING +#define com_yuekong_remote_service_DecodeService_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L +#undef com_yuekong_remote_service_DecodeService_MODE_MULTI_PROCESS +#define com_yuekong_remote_service_DecodeService_MODE_MULTI_PROCESS 4L +#undef com_yuekong_remote_service_DecodeService_MODE_PRIVATE +#define com_yuekong_remote_service_DecodeService_MODE_PRIVATE 0L +#undef com_yuekong_remote_service_DecodeService_MODE_WORLD_READABLE +#define com_yuekong_remote_service_DecodeService_MODE_WORLD_READABLE 1L +#undef com_yuekong_remote_service_DecodeService_MODE_WORLD_WRITEABLE +#define com_yuekong_remote_service_DecodeService_MODE_WORLD_WRITEABLE 2L +#undef com_yuekong_remote_service_DecodeService_START_CONTINUATION_MASK +#define com_yuekong_remote_service_DecodeService_START_CONTINUATION_MASK 15L +#undef com_yuekong_remote_service_DecodeService_START_FLAG_REDELIVERY +#define com_yuekong_remote_service_DecodeService_START_FLAG_REDELIVERY 1L +#undef com_yuekong_remote_service_DecodeService_START_FLAG_RETRY +#define com_yuekong_remote_service_DecodeService_START_FLAG_RETRY 2L +#undef com_yuekong_remote_service_DecodeService_START_NOT_STICKY +#define com_yuekong_remote_service_DecodeService_START_NOT_STICKY 2L +#undef com_yuekong_remote_service_DecodeService_START_REDELIVER_INTENT +#define com_yuekong_remote_service_DecodeService_START_REDELIVER_INTENT 3L +#undef com_yuekong_remote_service_DecodeService_START_STICKY +#define com_yuekong_remote_service_DecodeService_START_STICKY 1L +#undef com_yuekong_remote_service_DecodeService_START_STICKY_COMPATIBILITY +#define com_yuekong_remote_service_DecodeService_START_STICKY_COMPATIBILITY 0L +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaACLibOpen + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACLibOpen + (JNIEnv *, jobject, jstring); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaACControl + * Signature: (Lcom/yuekong/remote/bean/jnibean/JNIACStatus;II)[I + */ +JNIEXPORT jintArray JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACControl + (JNIEnv *, jobject, jobject, jint, jint); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaACLibClose + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACLibClose + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaACGetTemperatureRange + * Signature: (I)Lcom/yuekong/remote/bean/jnibean/JNITemperatureRange; + */ +JNIEXPORT jobject JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetTemperatureRange + (JNIEnv *, jobject, jint); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaACGetSupportedMode + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetSupportedMode + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaACGetSupportedWindSpeed + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetSupportedWindSpeed + (JNIEnv *, jobject, jint); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaACGetSupportedSwing + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetSupportedSwing + (JNIEnv *, jobject, jint); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaACGetSupportedWindDirection + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetSupportedWindDirection + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaTVLibOpen + * Signature: (Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaTVLibOpen + (JNIEnv *, jobject, jstring, jint); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaTVControl + * Signature: (I)[I + */ +JNIEXPORT jintArray JNICALL Java_com_yuekong_remote_service_DecodeService_irdaTVControl + (JNIEnv *, jobject, jint); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: irdaTVLibClose + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_yuekong_remote_service_DecodeService_irdaTVLibClose + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: bcLibOpen + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_bcLibOpen + (JNIEnv *, jobject, jstring); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: bcGetNeedConnAck + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetNeedConnAck + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: bcGetDeviceName + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetDeviceName + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: bcGetValidKeys + * Signature: ()[I + */ +JNIEXPORT jintArray JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetValidKeys + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: bcLibClose + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_yuekong_remote_service_DecodeService_bcLibClose + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: bcGetConnAck + * Signature: ()Lcom/yuekong/remote/bean/jnibean/JNIBCCommands; + */ +JNIEXPORT jobject JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetConnAck + (JNIEnv *, jobject); + +/* + * Class: com_yuekong_remote_service_DecodeService + * Method: bcGetCommand + * Signature: (I)Lcom/yuekong/remote/bean/jnibean/JNIBCCommands; + */ +JNIEXPORT jobject JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetCommand + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class com_yuekong_remote_service_DecodeService_LocalBinder */ + +#ifndef _Included_com_yuekong_remote_service_DecodeService_LocalBinder +#define _Included_com_yuekong_remote_service_DecodeService_LocalBinder +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/ir_decoder/irda_apply.c b/src/ir_decoder/irda_apply.c new file mode 100644 index 0000000..efc08ff --- /dev/null +++ b/src/ir_decoder/irda_apply.c @@ -0,0 +1,667 @@ +/************************************************************************************************** +Filename: irda_apply.c +Revised: Date: 2015-08-12 +Revision: Revision: 1.0 + +Description: This file provides methods for UCON applying functionalities + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-12: created by strawmanbobi +**************************************************************************************************/ +/* + *inclusion + */ + +#include "irda_utils.h" +#include "ucon_decode.h" +#include "irda_apply.h" +#if defined BOARD_CC254X +#include "npi.h" +#endif + +/* + * global vars + */ + +/* + * external vars + */ + +/* + * function declaration + */ + +/* + * function definition + */ + +INT8 apply_ac_parameter_type_1(UINT8 *dc_data, tag_comp *comp_data, UINT8 current_seg, UINT8 is_temp) +{ + if (0 != (comp_data->seg_len & 0x01)) + { + return IR_DECODE_FAILED; + } + + if (1 == is_temp) + { + dc_data[comp_data->segment[current_seg]] += comp_data->segment[current_seg + 1]; + } + else + { + dc_data[comp_data->segment[current_seg]] = comp_data->segment[current_seg + 1]; + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_ac_parameter_type_2(UINT8 *dc_data, tag_comp *comp_data, UINT8 current_seg, UINT8 is_temp) +{ + UINT8 start_bit = 0; + UINT8 end_bit = 0; + UINT8 cover_byte_pos_hi = 0; + UINT8 cover_byte_pos_lo = 0; + UINT8 value; + UINT8 move_bit = 0; + + if (0 != (comp_data->seg_len % 3)) + { + return IR_DECODE_FAILED; + } + + // TODO: to be validated + start_bit = comp_data->segment[current_seg]; + end_bit = comp_data->segment[current_seg + 1]; + cover_byte_pos_hi = start_bit >> 3; + cover_byte_pos_lo = (end_bit - 1) >> 3; + if (cover_byte_pos_hi == cover_byte_pos_lo) + { + // cover_byte_pos_hi or cover_bytes_pos_lo is target byte to be applied with AC parameter + // try get raw value of byte to be applied + UINT8 raw_value = comp_data->segment[current_seg + 2]; + UINT8 int_start_bit = start_bit - (cover_byte_pos_hi << 3); + UINT8 int_end_bit = end_bit - (cover_byte_pos_lo << 3); + UINT8 bit_range = end_bit - start_bit; + UINT8 mask = (0xFF << (8 - int_start_bit)) | (0xFF >> int_end_bit); + UINT8 origin = dc_data[cover_byte_pos_lo]; + + if (TRUE == is_temp) + { + move_bit = 8 - int_end_bit; + value = (origin & mask) | (((((origin & ~mask) >> move_bit) + raw_value) << move_bit) & ~mask); + } + else + { + value = (origin & mask) | ((raw_value << (8 - int_start_bit - bit_range)) & ~mask); + } + dc_data[cover_byte_pos_lo] = value; + } + else + { + UINT8 value = 0x00; + UINT8 origin_hi = 0x00; + UINT8 origin_lo = 0x00; + UINT8 mask_hi = 0x00; + UINT8 mask_lo = 0x00; + UINT8 raw_value = 0x00; + UINT8 int_start_bit = 0x00; + UINT8 int_end_bit = 0x00; + + if (cover_byte_pos_hi > cover_byte_pos_lo) + { + return IR_DECODE_FAILED; + } + // calculate the bit scope + UINT8 bit_range = end_bit - start_bit; + + raw_value = comp_data->segment[current_seg + 2]; + origin_hi = dc_data[cover_byte_pos_hi]; + origin_lo = dc_data[cover_byte_pos_lo]; + + int_start_bit = start_bit - (cover_byte_pos_hi << 3); + int_end_bit = end_bit - (cover_byte_pos_lo << 3); + + mask_hi = 0xFF << (8 - int_start_bit); + mask_lo = 0xFF >> int_end_bit; + + value = ((origin_hi & ~mask_hi) << int_end_bit) | ((origin_lo & ~mask_lo) >> (8 - int_end_bit)); + + if (TRUE == is_temp) + { + raw_value += value; + } + + dc_data[cover_byte_pos_hi] = (origin_hi & mask_hi) | + (((0xFF >> (8 - bit_range)) & raw_value) >> int_end_bit); + + dc_data[cover_byte_pos_lo] = (origin_lo & mask_lo) | + (((0xFF >> (8 - bit_range)) & raw_value) << (8 - int_end_bit)); + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_ac_power(struct ac_protocol *protocol, UINT8 power_status) +{ + UINT16 i = 0; + if (0 == protocol->power1.len) + { + return IR_DECODE_SUCCEEDED; + } + + if (0 == protocol->power1.comp_data[power_status].seg_len) + { + // force to apply power in any cases + return IR_DECODE_SUCCEEDED; + } + for (i = 0; i < protocol->power1.comp_data[power_status].seg_len; i += 2) + { + apply_ac_parameter_type_1(ir_hex_code, &(protocol->power1.comp_data[power_status]), i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_ac_mode(struct ac_protocol *protocol, UINT8 mode_status) +{ + UINT16 i = 0; + + if (0 == protocol->mode1.len) + { + goto try_applying_mode2; + } + + if (0 == protocol->mode1.comp_data[mode_status].seg_len) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < protocol->mode1.comp_data[mode_status].seg_len; i += 2) + { + apply_ac_parameter_type_1(ir_hex_code, &(protocol->mode1.comp_data[mode_status]), i, FALSE); + } + + // get return here since wind mode 1 is already applied + return IR_DECODE_SUCCEEDED; + + try_applying_mode2: + if (0 == protocol->mode2.len) + { + return IR_DECODE_SUCCEEDED; + } + + if (0 == protocol->mode2.comp_data[mode_status].seg_len) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < protocol->mode2.comp_data[mode_status].seg_len; i += 3) + { + apply_ac_parameter_type_2(ir_hex_code, + &(protocol->mode2.comp_data[mode_status]), + i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_ac_wind_speed(struct ac_protocol *protocol, UINT8 wind_speed) +{ + UINT16 i = 0; + + if (0 == protocol->speed1.len) + { + goto try_applying_wind_speed2; + } + + if (0 == protocol->speed1.comp_data[wind_speed].seg_len) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < protocol->speed1.comp_data[wind_speed].seg_len; i += 2) + { + apply_ac_parameter_type_1(ir_hex_code, &(protocol->speed1.comp_data[wind_speed]), i, FALSE); + } + + // get return here since wind speed 1 is already applied + return IR_DECODE_SUCCEEDED; + + try_applying_wind_speed2: + if (0 == protocol->speed2.len) + { + return IR_DECODE_SUCCEEDED; + } + + if (0 == protocol->speed2.comp_data[wind_speed].seg_len) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < protocol->speed2.comp_data[wind_speed].seg_len; i += 3) + { + apply_ac_parameter_type_2(ir_hex_code, + &(protocol->speed2.comp_data[wind_speed]), + i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_ac_temperature(struct ac_protocol *protocol, UINT8 temp_diff) +{ + UINT16 i = 0; + + if (0 == protocol->temp1.len) + { + goto try_applying_temp2; + } + + if (0 == protocol->temp1.comp_data[temp_diff].seg_len) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < protocol->temp1.comp_data[temp_diff].seg_len; i += 2) + { + if (TEMP_TYPE_DYNAMIC == protocol->temp1.type) + { + apply_ac_parameter_type_1(ir_hex_code, &(protocol->temp1.comp_data[temp_diff]), i, TRUE); + } + else if (TEMP_TYPE_STATIC == protocol->temp1.type) + { + apply_ac_parameter_type_1(ir_hex_code, &(protocol->temp1.comp_data[temp_diff]), i, FALSE); + } + } + + // get return here since temperature 1 is already applied + return IR_DECODE_SUCCEEDED; + + try_applying_temp2: + if (0 == protocol->temp2.len) + { + return IR_DECODE_SUCCEEDED; + } + + if (0 == protocol->temp2.comp_data[temp_diff].seg_len) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < protocol->temp2.comp_data[temp_diff].seg_len; i += 3) + { + if(0 != protocol->temp2.comp_data[temp_diff].seg_len) + { + if (TEMP_TYPE_DYNAMIC == protocol->temp2.type) + { + apply_ac_parameter_type_2(ir_hex_code, &(protocol->temp2.comp_data[temp_diff]), i, TRUE); + } + else if (TEMP_TYPE_STATIC == protocol->temp2.type) + { + apply_ac_parameter_type_2(ir_hex_code, &(protocol->temp2.comp_data[temp_diff]), i, FALSE); + } + } + } + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_ac_swing(struct ac_protocol *protocol, UINT8 swing_mode) +{ + UINT16 i = 0; + + if (0 == protocol->swing1.len) + { + goto try_applying_swing2; + } + + if (swing_mode >= protocol->swing1.count) + { + return IR_DECODE_FAILED; + } + + if (0 == protocol->swing1.comp_data[swing_mode].seg_len) + { + // swing does not have any empty data segment + return IR_DECODE_FAILED; + } + + for (i = 0; i < protocol->swing1.comp_data[swing_mode].seg_len; i += 2) + { + apply_ac_parameter_type_1(ir_hex_code, &(protocol->swing1.comp_data[swing_mode]), i, FALSE); + } + + // get return here since temperature 1 is already applied + return IR_DECODE_SUCCEEDED; + + try_applying_swing2: + if (0 == protocol->swing2.len) + { + return IR_DECODE_SUCCEEDED; + } + + if (swing_mode >= protocol->swing2.count) + { + return IR_DECODE_FAILED; + } + + if (0 == protocol->swing2.comp_data[swing_mode].seg_len) + { + // swing does not have any empty data segment + return IR_DECODE_FAILED; + } + + for (i = 0; i < protocol->swing2.comp_data[swing_mode].seg_len; i += 3) + { + apply_ac_parameter_type_2(ir_hex_code, + &(protocol->swing2.comp_data[swing_mode]), + i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_ac_function(struct ac_protocol *protocol, UINT8 function) +{ + UINT16 i = 0; + + // function index starts from 1 (AC_FUNCTION_POWER), do -1 operation at first + if (0 == protocol->function1.len) + { + goto try_applying_function2; + } + + if (0 == protocol->function1.comp_data[function - 1].seg_len) + { + // force to apply function in any case + return IR_DECODE_SUCCEEDED; + } + + for (i = 0; i < protocol->function1.comp_data[function - 1].seg_len; i += 2) + { + apply_ac_parameter_type_1(ir_hex_code, &(protocol->function1.comp_data[function - 1]), i, FALSE); + } + + // get return here since function 1 is already applied + return IR_DECODE_SUCCEEDED; + + try_applying_function2: + if (0 == protocol->function2.len) + { + return IR_DECODE_SUCCEEDED; + } + + if (0 == protocol->function2.comp_data[function - 1].seg_len) + { + return IR_DECODE_SUCCEEDED; + } + + for (i = 0; i < protocol->function2.comp_data[function - 1].seg_len; i += 3) + { + apply_ac_parameter_type_2(ir_hex_code, + &(protocol->function2.comp_data[function - 1]), + i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +/* modified by xiangjiang 2015-11-20 - begin - */ +INT8 apply_checksum_byte(UINT8 *ac_code, tag_checksum_data cs, BOOL inverse) +{ + UINT16 i = 0; + UINT8 checksum = 0x00; + + if (cs.len < 3) + { + return IR_DECODE_SUCCEEDED; + } + + for (i = cs.start_byte_pos; i < cs.end_byte_pos; i++) + { + checksum += ac_code[i]; + } + + checksum += cs.checksum_plus; + + if (TRUE == inverse) + { + checksum = ~checksum; + } + + // apply checksum + ac_code[cs.checksum_byte_pos] = checksum; + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + IR_PRINTF("checksum value = %02X\n", checksum); + IR_PRINTF("checksum byte pos = %d\n", cs.checksum_byte_pos); + IR_PRINTF("\n"); +#endif + + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_checksum_halfbyte(UINT8 *ac_code, tag_checksum_data cs, BOOL inverse) +{ + UINT16 i = 0; + UINT8 checksum = 0x00; + + if (cs.len < 3) + { + return IR_DECODE_SUCCEEDED; + } + + for (i = cs.start_byte_pos; i < cs.end_byte_pos; i++) + { + checksum += (ac_code[i] >> 4) + (ac_code[i] & 0x0F); + } + + checksum += cs.checksum_plus; + + if (TRUE == inverse) + { + checksum = ~checksum; + } + + // apply checksum + ac_code[cs.checksum_byte_pos] = checksum; + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + IR_PRINTF("checksum value = %02X\n", checksum & 0x0F); + IR_PRINTF("checksum byte pos = %d\n", cs.checksum_byte_pos); + IR_PRINTF("\n"); +#endif + + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_checksum_spec_byte(UINT8 *ac_code, tag_checksum_data cs, BOOL inverse) +{ + UINT16 i = 0; + UINT8 apply_byte_pos = 0; + UINT8 checksum = 0x00; + +#if 1 + if (cs.len < 4) + { + return IR_DECODE_SUCCEEDED; + } +#endif + + for (i = 0; i < cs.len - 3; i++) + { + UINT8 pos = cs.spec_pos[i]; + UINT8 byte_pos = pos >> 1; + + if (0 == (pos & 0x01)) + { + checksum += ac_code[byte_pos] >> 4; + } + else + { + checksum += ac_code[byte_pos] & 0x0F; + } + } + + checksum += cs.checksum_plus; + + if (TRUE == inverse) + { + checksum = ~checksum; + } + + // apply checksum, for specific-half-byte checksum, the byte pos actually indicates the half-byte pos + apply_byte_pos = cs.checksum_byte_pos >> 1; + if (0 == (cs.checksum_byte_pos & 0x01)) + { + // save low bits and add checksum as high bits + ac_code[apply_byte_pos] = (ac_code[apply_byte_pos] & 0x0F) | (checksum << 4); + } + else + { + // save high bits and add checksum as low bits + ac_code[apply_byte_pos] = (ac_code[apply_byte_pos] & 0xF0) | (checksum & 0x0F); + } + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + IR_PRINTF("checksum value = %02X\n", checksum & 0x0F); + IR_PRINTF("checksum byte pos = %d\n", apply_byte_pos); +#endif + + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_checksum_spec_byte_onebyte(UINT8 *ac_code, tag_checksum_data cs, BOOL inverse) +{ + UINT16 i = 0; + UINT8 apply_byte_pos = 0; + UINT8 checksum = 0x00; + +#if 1 + if (cs.len < 4) + { + return IR_DECODE_SUCCEEDED; + } +#endif + + for (i = 0; i < cs.len - 3; i++) + { + UINT8 pos = cs.spec_pos[i]; + UINT8 byte_pos = pos >> 1; + + if (0 == (pos & 0x01)) + { + checksum += ac_code[byte_pos] >> 4; + } + else + { + checksum += ac_code[byte_pos] & 0x0F; + } + } + + checksum += cs.checksum_plus; + + if (TRUE == inverse) + { + checksum = ~checksum; + } + + // apply checksum, for specific-half-byte checksum, the byte pos actually indicates the half-byte pos + apply_byte_pos = cs.checksum_byte_pos >> 1; + ac_code[apply_byte_pos] = checksum; + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + IR_PRINTF("checksum value = %02X\n", checksum); + IR_PRINTF("checksum byte pos = %d\n", apply_byte_pos); +#endif + + return IR_DECODE_SUCCEEDED; +} +/* modified by xiangjiang 2015-11-20 - end - */ + +INT8 apply_checksum(struct ac_protocol *protocol) +{ +/* modified by xiangjiang 2015-11-20 - begin - */ +#if 0 + if (0 == protocol->checksum.len) + { + return IR_DECODE_SUCCEEDED; + } + + switch (protocol->checksum.type) + { + case CHECKSUM_TYPE_BYTE: + apply_checksum_byte(ir_hex_code, protocol->checksum, FALSE); + break; + case CHECKSUM_TYPE_BYTE_INVERSE: + apply_checksum_byte(ir_hex_code, protocol->checksum, TRUE); + break; + case CHECKSUM_TYPE_HALF_BYTE: + apply_checksum_halfbyte(ir_hex_code, protocol->checksum, FALSE); + break; + case CHECKSUM_TYPE_HALF_BYTE_INVERSE: + apply_checksum_halfbyte(ir_hex_code, protocol->checksum, TRUE); + break; + case CHECKSUM_TYPE_SPEC_HALF_BYTE: + apply_checksum_spec_byte(ir_hex_code, protocol->checksum, FALSE); + break; + case CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE: + apply_checksum_spec_byte(ir_hex_code, protocol->checksum, TRUE); + break; + default: + break; + } +#else + UINT8 i = 0; + + if (0 == protocol->checksum.len) + { + return IR_DECODE_SUCCEEDED; + } + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + // have some debug + IR_PRINTF("\napply checksum :\n"); + IR_PRINTF("checksum num = %d\n", protocol->checksum.count); +#endif + + for(i = 0; i < protocol->checksum.count; i++) + { +#if (defined BOARD_PC) || (defined BOARD_MT6580) + // have some debug + IR_PRINTF("num : %d\n", i + 1); + IR_PRINTF("checksum type = %02X\n", protocol->checksum.checksum_data[i].type); +#endif + + switch (protocol->checksum.checksum_data[i].type) + { + case CHECKSUM_TYPE_BYTE: + apply_checksum_byte(ir_hex_code, protocol->checksum.checksum_data[i], FALSE); + break; + case CHECKSUM_TYPE_BYTE_INVERSE: + apply_checksum_byte(ir_hex_code, protocol->checksum.checksum_data[i], TRUE); + break; + case CHECKSUM_TYPE_HALF_BYTE: + apply_checksum_halfbyte(ir_hex_code, protocol->checksum.checksum_data[i], FALSE); + break; + case CHECKSUM_TYPE_HALF_BYTE_INVERSE: + apply_checksum_halfbyte(ir_hex_code, protocol->checksum.checksum_data[i], TRUE); + break; + case CHECKSUM_TYPE_SPEC_HALF_BYTE: + apply_checksum_spec_byte(ir_hex_code, protocol->checksum.checksum_data[i], FALSE); + break; + case CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE: + apply_checksum_spec_byte(ir_hex_code, protocol->checksum.checksum_data[i], TRUE); + break; + case CHECKSUM_TYPE_SPEC_HALF_BYTE_ONE_BYTE: + apply_checksum_spec_byte_onebyte(ir_hex_code, protocol->checksum.checksum_data[i], FALSE); + break; + case CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE_ONE_BYTE: + apply_checksum_spec_byte_onebyte(ir_hex_code, protocol->checksum.checksum_data[i], TRUE); + break; + default: + break; + } + } + +#endif +/* modified by xiangjiang 2015-11-20 - end - */ + + return IR_DECODE_SUCCEEDED; +} + diff --git a/src/ir_decoder/irda_apply.h b/src/ir_decoder/irda_apply.h new file mode 100644 index 0000000..07d5947 --- /dev/null +++ b/src/ir_decoder/irda_apply.h @@ -0,0 +1,58 @@ +/************************************************************************************************** +Filename: irda_apply.h +Revised: Date: 2015-08-12 +Revision: Revision: 1.0 + +Description: This file provides methods for UCON applying functionalities + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-12: created by strawmanbobi +**************************************************************************************************/ + +/* + *inclusion + */ +#include "ucon_decode.h" + +#ifndef _IRDA_APPLY_H_ +#define _IRDA_APPLY_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * public macros + */ +#define MIN_TAG_LENGTH_TYPE_1 4 +#define MIN_TAG_LENGTH_TYPE_2 6 + +/* + * public type definition + */ + +/* + * public function declaration + */ +extern INT8 apply_ac_power(struct ac_protocol *protocol, UINT8 power_status); + +extern INT8 apply_ac_mode(struct ac_protocol *protocol, UINT8 mode_status); + +extern INT8 apply_ac_temperature(struct ac_protocol *protocol, UINT8 temperature); + +extern INT8 apply_ac_wind_speed(struct ac_protocol *protocol, UINT8 wind_speed); + +extern INT8 apply_ac_swing(struct ac_protocol *protocol, UINT8 swing_status); + +extern INT8 apply_ac_function(struct ac_protocol *protocol, UINT8 function); + +extern INT8 apply_checksum(struct ac_protocol *protocol); + +#ifdef __cplusplus +} +#endif + +#endif //_IRDA_APPLY_H_ \ No newline at end of file diff --git a/src/ir_decoder/irda_defs.h b/src/ir_decoder/irda_defs.h new file mode 100644 index 0000000..c6d636d --- /dev/null +++ b/src/ir_decoder/irda_defs.h @@ -0,0 +1,94 @@ +/************************************************************************************************** +Filename: irda_defs.h +Revised: Date: 2015-08-26 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-01: created by strawmanbobi +**************************************************************************************************/ +#if defined BOARD_CC254X +#include "osal.h" +#endif + +#if defined BOARD_MC200 +#include "wmstdio.h" +#include "wm_os.h" +#endif + +#if defined BOARD_MT6580 +#include +#define LOG_TAG "ucon_decode" +#endif + +#ifndef PARSE_IR_DEFS_H +#define PARSE_IR_DEFS_H +#ifdef __cplusplus +extern "C" +{ +#endif + +#define TRUE 1 +#define FALSE 0 + +typedef unsigned char UINT8; +typedef signed char INT8; +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned char BOOL; + +#if defined BOARD_CC254X +#define irda_malloc(A) osal_mem_alloc(A) +#define irda_free(A) osal_mem_free(A) +#define irda_memcpy(A, B, C) osal_memcpy(A, B, C) +#define irda_memset(A, B, C) osal_memset(A, B, C) +#define irda_strlen(A) osal_strlen(A) +#define IR_PRINTF(A) + +#if !defined BOARD_CC254X +#define USER_DATA_SIZE UCON_USER_DATA_SIZE +#endif + +#elif defined BOARD_MC200 +#define irda_malloc(A) os_mem_alloc(A) +#define irda_free(A) os_mem_free(A) +#define irda_memcpy(A, B, C) memcpy(A, B, C) +#define irda_memset(A, B, C) memset(A, B, C) +#define irda_strlen(A) strlen(A) +#define IR_PRINTF(A) +// temporarily define USER_DATA_SIZE as 1200 for BOARD_MC200 +#define USER_DATA_SIZE 1200 +#elif defined BOARD_PC +#define irda_malloc(A) malloc(A) +#define irda_free(A) free(A) +#define irda_memcpy(A, B, C) memcpy(A, B, C) +#define irda_memset(A, B, C) memset(A, B, C) +#define irda_strlen(A) strlen(A) +#define IR_PRINTF printf +// temporarily define USER_DATA_SIZE as 2048 for BOARD_PC +#define USER_DATA_SIZE 2048 +#elif defined BOARD_MT6580 +#define irda_malloc(A) malloc(A) +#define irda_free(A) free(A) +#define irda_memcpy(A, B, C) memcpy(A, B, C) +#define irda_memset(A, B, C) memset(A, B, C) +#define irda_strlen(A) strlen(A) +#define IR_PRINTF(...) +#define USER_DATA_SIZE 2048 +#else +#define irda_malloc(A) malloc(A) +#define irda_free(A) free(A) +#define irda_memcpy(A, B, C) memcpy(A, B, C) +#define irda_memset(A, B, C) memset(A, B, C) +#define irda_strlen(A) strlen(A) +#define IR_PRINTF(A) +#endif + + +#ifdef __cplusplus +} +#endif +#endif //PARSE_IR_DEFS_H diff --git a/src/ir_decoder/irda_irframe.c b/src/ir_decoder/irda_irframe.c new file mode 100644 index 0000000..82eb849 --- /dev/null +++ b/src/ir_decoder/irda_irframe.c @@ -0,0 +1,190 @@ +/************************************************************************************************** +Filename: irda_irframe.c +Revised: Date: 2015-08-01 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-01: created by strawmanbobi +**************************************************************************************************/ +#include + +#include "irda_irframe.h" +#include "ucon_decode.h" + +extern protocol* context; + +//return bit number per byte,default value is 8 +UINT8 bits_per_byte(UINT8 index) +{ + UINT8 i = 0; + UINT8 size = 0; + + if (context->bitnum_cnt == 0) + return 8; //defaut value + + if (context->bitnum_cnt >= MAX_BITNUM) + size = MAX_BITNUM; + else + size = context->bitnum_cnt; + + for (i = 0; i < size; i++) + { + if (context->bitnum[i].pos == index) + return context->bitnum[i].bits; + if (context->bitnum[i].pos > index) + return 8; + } + return 8; +} + +UINT16 add_delaycode(UINT8 index) +{ + UINT8 i = 0, j = 0; + UINT8 size = 0; + UINT8 tail_delaycode = 0; + UINT16 tail_pos = 0; + +/* updated by xiangjiang - 2015-08-31 - begin */ +#if 0 + //Handle TAG307 + if ((context->lastbit == 0) && (index == (ir_hex_len - 1))) + { + context->time[context->code_cnt++] = context->one.low; //high + } + + if (context->dc_cnt == 0) + return 0; + else + size = context->dc_cnt; + + for (i = 0; i < size; i++) + { + + if (context->dc[i].pos == index) + { + for (j = 0; j < context->dc[i].time_cnt; j++) + { + context->time[context->code_cnt++] = context->dc[i].time[j]; + } + return context->dc[i].time_cnt; + } + } + return 0; +#else + + if(context->dc_cnt != 0) + { + size = context->dc_cnt; + + for (i = 0; i < size; i++) + { + if (context->dc[i].pos == index) + { + for (j = 0; j < context->dc[i].time_cnt; j++) + { + context->time[context->code_cnt++] = context->dc[i].time[j]; + } + } + else if(context->dc[i].pos == -1) + { + tail_delaycode = 1; + tail_pos = i; + } + } + } + + //Handle TAG307 + if ((context->lastbit == 0) && (index == (ir_hex_len - 1))) + { + context->time[context->code_cnt++] = context->one.low; //high + } + + if(context->dc_cnt != 0) + { + if((index == (ir_hex_len - 1)) && (tail_delaycode == 1)) + { + for (i = 0; i < context->dc[tail_pos].time_cnt; i++) + { + context->time[context->code_cnt++] = context->dc[tail_pos].time[i]; + } + } + } + + return context->dc[i].time_cnt; +#endif +/* updated by xiangjiang - 2015-08-31 - end */ +} + +UINT16 create_ir_frame() +{ + UINT16 i = 0, j = 0; + UINT8 bitnum = 0; + UINT8 *irdata = ir_hex_code; + UINT8 mask = 1; + UINT16 framelen = 0; + + context->code_cnt = 0; + + //bootcode + for (i = 0; i < context->bootcode.len; i++) + { + //IR_PRINTF("%d,",context->bootcode.data[i]); //tag[300] + context->time[context->code_cnt++] = context->bootcode.data[i]; + } + //code_cnt += context->bootcode.len; + + for (i = 0; i < ir_hex_len; i++) + { + bitnum = bits_per_byte(i);//use tag[1509] + //IR_PRINTF("bitnum:%d\n", bitnum); + for (j = 0; j < bitnum; j++) + { + if (context->endian == 0) //BIg Endian + mask = (1 << (bitnum - 1)) >> j; + else + mask = 1 << j; //Little Endian + + if (irdata[i] & mask) + { + //one[302] + //IR_PRINTF("%d,%d,", context->one.low, context->one.high); + context->time[context->code_cnt++] = context->one.low; + context->time[context->code_cnt++] = context->one.high; + } + else + { + //zero[301] + //IR_PRINTF("%d,%d,", context->zero.low, context->zero.high); + context->time[context->code_cnt++] = context->zero.low; + context->time[context->code_cnt++] = context->zero.high; + } + } + add_delaycode(i); + } + + framelen = context->code_cnt; + + for (i = 0; i < (context->repeat_times - 1); i++) + { + for (j = 0; j < framelen; j++) + { + context->time[context->code_cnt++] = context->time[j]; + } + } + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + for (i = 0; i < context->code_cnt; i++) + { + IR_PRINTF("%d,", context->time[i]); + } + IR_PRINTF("\n"); +#endif + + return context->code_cnt; +} + + diff --git a/src/ir_decoder/irda_irframe.h b/src/ir_decoder/irda_irframe.h new file mode 100644 index 0000000..ea06975 --- /dev/null +++ b/src/ir_decoder/irda_irframe.h @@ -0,0 +1,29 @@ +/************************************************************************************************** +Filename: irda_utils.c +Revised: Date: 2015-08-26 +Revision: Revision: 1.0 + +Description: This file provides generic utils for UCON IRDA algorithms + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-01: created by strawmanbobi +**************************************************************************************************/ +#include "irda_defs.h" + +#ifndef _IRDA_IRFRAME_H_ +#define _IRDA_IRFRAME_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern UINT16 create_ir_frame(); + +#ifdef __cplusplus +} +#endif + +#endif // _IRDA_IRFRAME_H_ \ No newline at end of file diff --git a/src/ir_decoder/irda_lib.c b/src/ir_decoder/irda_lib.c new file mode 100644 index 0000000..cd26bb3 --- /dev/null +++ b/src/ir_decoder/irda_lib.c @@ -0,0 +1,548 @@ +/************************************************************************************************** +Filename: irda_lib.c +Revised: Date: 2016-01-21 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode (command type) + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2016-01-21: created by strawmanbobi +* 2016-05-06: upadted by xiangjiang +**************************************************************************************************/ + +/************************************************************************************************** + * INCLUDES + **************************************************************************************************/ + +#include "stdio.h" +#include "irda_defs.h" +#include "irda_lib.h" +#include "string.h" + +#if defined BOARD_CC254X +#include "ucon_public.h" +#include "ucon_data.h" +#include "ucon_remote.h" +#include "OSAL.h" +#include "npi.h" +#endif + + +/************************************************************************************************** + * MACROS + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * CONSTANTS + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * LOCAL DATA TYPES + **************************************************************************************************/ +#if defined BOARD_MC200 +#pragma pack(1) +#endif +struct buffer +{ + UINT8 *data; + UINT16 len; + UINT16 offset; +} irda_file; +#if defined BOARD_MC200 +#pragma pack() +#endif + + + + +/************************************************************************************************** + * GLOBAL VARIABLES + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * EXTERNAL VARIABLES + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * LOCAL VARIABLES + **************************************************************************************************/ +static struct buffer *pbuffer = &irda_file; /* Store irda library data */ + +//static UINT8 *prot_name = NULL; //irda protocol name +static UINT8 *prot_cycles_num = NULL; //irda protocol cycles num +static irda_cycles_t *prot_cycles_data[IRDA_MAX]; +static UINT8 prot_items_cnt = 0; +static irda_data_t *prot_items_data = NULL; //irda protocol frame data +static irda_data_tv_t *remote_p; +static UINT8 *remote_pdata = NULL; + +static UINT16 time_index = 0; +static UINT8 irda_level = IRDA_LEVEL_LOW; +static UINT8 irda_toggle_bit = FALSE; +static UINT8 irda_decode_flag = IRDA_DECODE_1_BIT; +static UINT8 cycles_num_size = 0; + + + +/************************************************************************************************** + * LOCAL TABLES + **************************************************************************************************/ + + + + + + +/************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + **************************************************************************************************/ +static BOOL get_irda_protocol(UINT8 encode_type); +static BOOL get_irda_keymap(void); +static void print_irda_time(irda_data_t *data, UINT8 keyindex, UINT16 *irda_time); +static void process_decode_number(UINT8 keycode, irda_data_t *data, UINT8 valid_bits, UINT16 *irda_time); +static void convert_to_irda_time(UINT8 value, UINT16 *irda_time); +static void replace_with(irda_cycles_t *pcycles_num, UINT16 *irda_time); + + + +/************************************************************************************************** + * GLOBAL FUNCTIONS + **************************************************************************************************/ +void irda_lib_open(UINT8 *binary_file, UINT16 binary_length) +{ + // load binary to buffer + pbuffer->data = binary_file; + pbuffer->len = binary_length; + pbuffer->offset = 0; +} + +BOOL irda_lib_parse(UINT8 encode_type) +{ + if (FALSE == get_irda_protocol(encode_type)) + { + return FALSE; + } + + return get_irda_keymap(); +} + +UINT16 irda_lib_control(UINT8 key, UINT16 *user_data) +{ + UINT16 i = 0; + + time_index = 0; + irda_level = IRDA_LEVEL_LOW; + + for (i = 0; i < prot_items_cnt; i++) + { + print_irda_time(&prot_items_data[i], key, user_data); + } + + // next flip + if (2 == prot_cycles_num[IRDA_FLIP]) + { + irda_toggle_bit = (irda_toggle_bit == FALSE) ? TRUE : FALSE; + } + + return time_index; +} + +/************************************************************************************************** + * LOCAL FUNCTIONS + **************************************************************************************************/ +static BOOL get_irda_protocol(UINT8 encode_type) +{ + UINT8 i = 0; + UINT8 name_size = 20; + UINT8 *prot_cycles = NULL; + UINT8 cycles_sum = 0; + + if (pbuffer->data == NULL) + { + return FALSE; + } + + pbuffer->offset = 0; + + /* protocol name */ + // prot_name = pbuffer->data + pbuffer->offset; + pbuffer->offset += name_size; + + /* cycles number */ + prot_cycles_num = pbuffer->data + pbuffer->offset; + if (encode_type == 0) + { + cycles_num_size = 8; /* "BOOT", "STOP", "SEP", "ONE", "ZERO", "FLIP", "TWO", "THREE" */ + if (prot_cycles_num[IRDA_TWO] == 0 && prot_cycles_num[IRDA_THREE] == 0) + { + irda_decode_flag = IRDA_DECODE_1_BIT; + } + else + { + irda_decode_flag = IRDA_DECODE_2_BITS; + } + } + else if (encode_type == 1) + { + cycles_num_size = IRDA_MAX; + irda_decode_flag = IRDA_DECODE_4_BITS; + } + else + { + return FALSE; + } + pbuffer->offset += cycles_num_size; + + /* cycles data */ + prot_cycles = pbuffer->data + pbuffer->offset; + for (i = 0; i < cycles_num_size; i++) + { + if (0 != prot_cycles_num[i]) + { + prot_cycles_data[i] = (irda_cycles_t *) (&prot_cycles[sizeof(irda_cycles_t) * cycles_sum]); + } + else + { + prot_cycles_data[i] = NULL; + } + cycles_sum += prot_cycles_num[i]; + } + pbuffer->offset += sizeof(irda_cycles_t) * cycles_sum; + + /* items count */ + prot_items_cnt = pbuffer->data[pbuffer->offset]; + pbuffer->offset += sizeof(UINT8); + + /* items data */ + prot_items_data = (irda_data_t *) (pbuffer->data + pbuffer->offset); + pbuffer->offset += prot_items_cnt * sizeof(irda_data_t); + + /* added by xiangjiang 2015-08-08 - begin - */ + irda_toggle_bit = FALSE; + /* added by xiangjiang 2015-08-08 - end - */ + + return TRUE; +} + +static BOOL get_irda_keymap(void) +{ + remote_p = (irda_data_tv_t *) (pbuffer->data + pbuffer->offset); + pbuffer->offset += sizeof(irda_data_tv_t); + + if (strncmp(remote_p->magic, "ykir", 4) == 0) + { + remote_pdata = pbuffer->data + pbuffer->offset; + /* modified by xiangjiang 2015-06-03 - begin - */ + //pbuffer->offset += remote_p->per_keycode_bytes * 12; + //pbuffer->offset += remote_p->per_keycode_bytes * TV_KEY_MAX; + /* modified by xiangjiang 2015-06-03 - end - */ + return TRUE; + } + + return FALSE; +} + +static void print_irda_time(irda_data_t *data, UINT8 keyindex, UINT16 *irda_time) +{ + UINT8 i = 0; + UINT8 cycles_num = 0; + irda_cycles_t *pcycles = NULL; + UINT8 keycode = 0; + + if (NULL == data || NULL == irda_time) + { + return; + } + + pcycles = prot_cycles_data[data->index]; + keycode = remote_pdata[remote_p->per_keycode_bytes * keyindex + data->index - 1]; + + if (prot_cycles_num[IRDA_ONE] != 1 || prot_cycles_num[IRDA_ZERO] != 1) + { + return; + } + + if (time_index >= USER_DATA_SIZE) + { + return; + } + + if (data->bits == 1) + { + if (pcycles == NULL) + { + return; + } + + cycles_num = prot_cycles_num[data->index]; + if (cycles_num > 5) + { + return; + } + + for (i = cycles_num; i > 0; i--) + { + if (cycles_num == 2 && data->index == IRDA_FLIP) + { + if (irda_toggle_bit == TRUE) + { + pcycles += 1; + } + } + + if (pcycles->mask && pcycles->space) + { + if (pcycles->flag == IRDA_FLAG_NORMAL) + { + if (irda_level == IRDA_LEVEL_HIGH && time_index != 0) + { + time_index--; + irda_time[time_index++] += pcycles->mask; + } + else if (irda_level == IRDA_LEVEL_LOW) + { + irda_time[time_index++] = pcycles->mask; + } + irda_time[time_index++] = pcycles->space; + irda_level = IRDA_LEVEL_LOW; + } + else if (pcycles->flag == IRDA_FLAG_INVERSE) + { + if (irda_level == IRDA_LEVEL_LOW && time_index != 0) + { + time_index--; + irda_time[time_index++] += pcycles->space; + } + else if (irda_level == IRDA_LEVEL_HIGH) + { + irda_time[time_index++] = pcycles->space; + } + irda_time[time_index++] = pcycles->mask; + irda_level = IRDA_LEVEL_HIGH; + } + } + else if (0 == pcycles->mask && 0 != pcycles->space) + { + if (irda_level == IRDA_LEVEL_LOW && time_index != 0) + { + time_index--; + irda_time[time_index++] += pcycles->space; + } + else if (irda_level == IRDA_LEVEL_HIGH) + { + irda_time[time_index++] = pcycles->space; + } + irda_level = IRDA_LEVEL_LOW; + } + else if (0 == pcycles->space && 0 != pcycles->mask) + { + if (irda_level == IRDA_LEVEL_HIGH && time_index != 0) + { + time_index--; + irda_time[time_index++] += pcycles->mask; + } + else if (irda_level == IRDA_LEVEL_LOW) + { + irda_time[time_index++] = pcycles->mask; + } + irda_level = IRDA_LEVEL_HIGH; + } + else + { + // do nothing + } + + if (cycles_num == 2 && data->index == IRDA_FLIP) + { + break; + } + else + { + pcycles++; + } + } + } + else + { + // mode: inverse + if (data->mode == 1) + keycode = ~keycode; + + if (irda_decode_flag == IRDA_DECODE_1_BIT) + { +#if (defined BOARD_CC254X) && (PRINT_IRDA_DATA == TRUE) + NPI_PrintString("\r\n\r\n\r\n[TV-DECODE]: decode as 1 bit"); +#endif + process_decode_number(keycode, data, 1, irda_time); // '0','1' + } + else if (irda_decode_flag == IRDA_DECODE_2_BITS) + { +#if (defined BOARD_CC254X) && (PRINT_IRDA_DATA == TRUE) + NPI_PrintString("\r\n\r\n\r\n[TV-DECODE]: decode as 2 bits"); +#endif + process_decode_number(keycode, data, 2, irda_time); // '0','1','2','3' + } + else if (irda_decode_flag == IRDA_DECODE_4_BITS) + { +#if (defined BOARD_CC254X) && (PRINT_IRDA_DATA == TRUE) + NPI_PrintString("\r\n\r\n\r\n[TV-DECODE]: decode as 4 bits"); +#endif + process_decode_number(keycode, data, 4, irda_time); // '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', + } + } +} + +static void process_decode_number(UINT8 keycode, irda_data_t *data, UINT8 valid_bits, UINT16 *irda_time) +{ + UINT8 i = 0; + UINT8 value = 0; + UINT8 bit_num = data->bits / valid_bits; + UINT8 valid_value = 0; + + valid_value = (valid_bits == 1) ? 1 : (valid_bits * valid_bits - 1); + +#if (defined BOARD_CC254X) && (PRINT_IRDA_DATA == TRUE) + NPI_PrintValue("\r\n keycode : 0x", keycode, 16); + NPI_PrintValue("\r\n bits : ", data->bits, 10); + NPI_PrintValue("\r\n valid bits : 0x", valid_value, 16); +#endif + + if (data->lsb == IRDA_LSB) + { +#if (defined BOARD_CC254X) && (PRINT_IRDA_DATA == TRUE) + NPI_PrintString("\r\n endian : lsb"); +#endif + for (i = 0; i < bit_num; i++) + { + value = (keycode >> (valid_bits * i)) & valid_value; + convert_to_irda_time(value, irda_time); + } + } + else if (data->lsb == IRDA_MSB) + { +#if (defined BOARD_CC254X) && (PRINT_IRDA_DATA == TRUE) + NPI_PrintString("\r\n endian : msb"); +#endif + for (i = 0; i < bit_num; i++) + { + value = (keycode >> (data->bits - valid_bits * (i + 1))) & valid_value; + convert_to_irda_time(value, irda_time); + } + } +} + +static void convert_to_irda_time(UINT8 value, UINT16 *irda_time) +{ +#if (defined BOARD_CC254X) && (PRINT_IRDA_DATA == TRUE) + NPI_PrintValue("\r\n replace value : 0x", value, 16); +#endif + switch (value) + { + case 0: + replace_with(prot_cycles_data[IRDA_ZERO], irda_time); + break; + case 1: + replace_with(prot_cycles_data[IRDA_ONE], irda_time); + break; + case 2: + replace_with(prot_cycles_data[IRDA_TWO], irda_time); + break; + case 3: + replace_with(prot_cycles_data[IRDA_THREE], irda_time); + break; + case 4: + replace_with(prot_cycles_data[IRDA_FOUR], irda_time); + break; + case 5: + replace_with(prot_cycles_data[IRDA_FIVE], irda_time); + break; + case 6: + replace_with(prot_cycles_data[IRDA_SIX], irda_time); + break; + case 7: + replace_with(prot_cycles_data[IRDA_SEVEN], irda_time); + break; + case 8: + replace_with(prot_cycles_data[IRDA_EIGHT], irda_time); + break; + case 9: + replace_with(prot_cycles_data[IRDA_NINE], irda_time); + break; + case 0x0A: + replace_with(prot_cycles_data[IRDA_A], irda_time); + break; + case 0x0B: + replace_with(prot_cycles_data[IRDA_B], irda_time); + break; + case 0x0C: + replace_with(prot_cycles_data[IRDA_C], irda_time); + break; + case 0x0D: + replace_with(prot_cycles_data[IRDA_D], irda_time); + break; + case 0x0E: + replace_with(prot_cycles_data[IRDA_E], irda_time); + break; + case 0x0F: + replace_with(prot_cycles_data[IRDA_F], irda_time); + break; + default: + break; + } +} + +static void replace_with(irda_cycles_t *pcycles_num, UINT16 *irda_time) +{ + if (NULL == pcycles_num || NULL == irda_time) + { + return; + } + + if (pcycles_num->flag == IRDA_FLAG_NORMAL) + { + if (irda_level == IRDA_LEVEL_HIGH && time_index != 0) + { + time_index--; + irda_time[time_index++] += pcycles_num->mask; + } + else if (irda_level == IRDA_LEVEL_LOW) + { + irda_time[time_index++] = pcycles_num->mask; + } + irda_time[time_index++] = pcycles_num->space; + irda_level = IRDA_LEVEL_LOW; + } + else if (pcycles_num->flag == IRDA_FLAG_INVERSE) + { + if (irda_level == IRDA_LEVEL_LOW && time_index != 0) + { + time_index--; + irda_time[time_index++] += pcycles_num->space; + } + else if (irda_level == IRDA_LEVEL_HIGH) + { + irda_time[time_index++] = pcycles_num->space; + } + irda_time[time_index++] = pcycles_num->mask; + irda_level = IRDA_LEVEL_HIGH; + } +} + diff --git a/src/ir_decoder/irda_lib.h b/src/ir_decoder/irda_lib.h new file mode 100644 index 0000000..b7be7de --- /dev/null +++ b/src/ir_decoder/irda_lib.h @@ -0,0 +1,264 @@ +/************************************************************************************************** +Filename: irda_lib.h +Revised: Date: 2016-02-23 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode (command type) + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2016-01-21: created by strawmanbobi +* 2016-05-06: upadted by xiangjiang +**************************************************************************************************/ + +#ifndef _IRDA_H_ +#define _IRDA_H_ + +/************************************************************************************************** + * INCLUDES + **************************************************************************************************/ + +#include "irda_defs.h" + +#if defined BOARD_CC254X +#include "ucon_remote.h" +#endif + +/************************************************************************************************** + * MACROS + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * CONSTANTS + **************************************************************************************************/ +#define STB_CHANNEL_OFFSET 14 + +#define IRDA_FLAG_NORMAL 0 +#define IRDA_FLAG_INVERSE 1 + +#define IRDA_LEVEL_LOW 0 +#define IRDA_LEVEL_HIGH 1 + +#define IRDA_LSB 0 +#define IRDA_MSB 1 + +enum +{ + IRDA_DECODE_1_BIT = 0, + IRDA_DECODE_2_BITS, + IRDA_DECODE_4_BITS, +}; + +/************************************************************************************************** + * GLOBAL DATA TYPES + **************************************************************************************************/ + +//======================== IRDA protocol definition ============================= +typedef enum irda_flags +{ + IRDA_BOOT = 0, + IRDA_STOP, + IRDA_SEP, + IRDA_ONE, + IRDA_ZERO, + IRDA_FLIP, + IRDA_TWO, + IRDA_THREE = 7, + IRDA_FOUR, + IRDA_FIVE, + IRDA_SIX, + IRDA_SEVEN, + IRDA_EIGHT, + IRDA_NINE, + IRDA_A, + IRDA_B, + IRDA_C, + IRDA_D, + IRDA_E, + IRDA_F, + IRDA_MAX = 20, +} irda_flags_t; + +typedef struct irda_data +{ + UINT8 bits; + UINT8 lsb; + UINT8 mode; + UINT8 index; +} irda_data_t; + +#if (defined BOARD_PC) || (defined BOARD_MC200) || (defined BOARD_MT6580) +#pragma pack(1) +#endif +typedef struct irda_cycles +{ + UINT8 flag; + UINT16 mask; + UINT16 space; +} irda_cycles_t; +#if (defined BOARD_PC) || (defined BOARD_MC200) || (defined BOARD_MT6580) +#pragma pack() +#endif + +//================================== TV ================================== +typedef enum tv_key_value +{ + TV_POWER = 0, + TV_MUTE, + TV_UP, + TV_DOWN, + TV_LEFT, + TV_RIGHT, + TV_OK, + TV_VOL_UP, + TV_VOL_DOWN, + TV_BACK, + TV_INPUT, + TV_MENU, + TV_HOME, + TV_SET, + TV_0, + TV_1, + TV_2, + TV_3, + TV_4, + TV_5, + TV_6, + TV_7, + TV_8, + TV_9, + TV_KEY_MAX, +} tv_key_value_t; + +//================================== STB ================================== +typedef enum stb_key_value +{ + STB_POWER = 0, + STB_MUTE, + STB_UP, + STB_DOWN, + STB_LEFT, + STB_RIGHT, + STB_OK, + STB_VOL_UP, + STB_VOL_DOWN, + STB_BACK, + STB_INPUT, + STB_MENU, + STB_PAGE_UP, + STB_PAGE_DOWN, + STB_0, + STB_1, + STB_2, + STB_3, + STB_4, + STB_5, + STB_6, + STB_7, + STB_8, + STB_9, + STB_KEY_MAX, +} stb_key_value_t; + +//================================== NW ================================== +typedef enum nw_key_value +{ + NW_POWER = 0, + NW_UP, + NW_DOWN, + NW_LEFT, + NW_RIGHT, + NW_OK, + NW_VOL_UP, + NW_VOL_DOWN, + NW_BACK, + NW_MENU, + NW_HOME, + NW_0, + NW_1, + NW_2, + NW_3, + NW_4, + NW_5, + NW_6, + NW_7, + NW_8, + NW_9, + NW_KEY_MAX, +} nw_key_value_t; + +//================================== COMMON ================================== +typedef enum cm_key_value +{ + CM_POWER = 0, + CM_UP, + CM_DOWN, + CM_LEFT, + CM_RIGHT, + CM_OK, + CM_VOL_UP, + CM_VOL_DOWN, + CM_FUNC_1, + CM_FUNC_2, + CM_FUNC_3, + CM_BACK, + CM_HOME, + CM_MENU, + CM_MODE, + CM_KEY_MAX, +} cm_key_value_t; + +typedef struct irda_data_tv +{ + char magic[4]; + UINT8 per_keycode_bytes; +} irda_data_tv_t; + + +/************************************************************************************************** + * GLOBAL VARIABLES + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * EXTERNAL VARIABLES + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * GLOBAL TABLES + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * EXTERNAL FUNCTIONS + **************************************************************************************************/ + + + + + +/************************************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + **************************************************************************************************/ +extern void irda_lib_open(UINT8 *binary_file, UINT16 binary_length); +extern BOOL irda_lib_parse(UINT8 encode_type); +extern UINT16 irda_lib_control(UINT8 key, UINT16 *user_data); + + +#endif /* _IRDA_H_ */ + diff --git a/src/ir_decoder/irda_parse_ac_parameter.c b/src/ir_decoder/irda_parse_ac_parameter.c new file mode 100644 index 0000000..d83d9fc --- /dev/null +++ b/src/ir_decoder/irda_parse_ac_parameter.c @@ -0,0 +1,1413 @@ +/************************************************************************************************** +Filename: irda_parse_ac_parameter.c +Revised: Date: 2015-08-12 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode for AC functionality parameters + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-12: created by strawmanbobi +**************************************************************************************************/ +/* + *inclusion + */ +#include +#include +#include +#include "irda_utils.h" +#include "irda_parse_ac_parameter.h" +#include "ucon_decode.h" + +/* + * global vars + */ + +/* + * external vars + */ + +/* + * function declaration + */ + +/* + * function definition + */ +INT8 parse_comp_data_type_1(UINT8 *data, UINT16 *trav_offset, tag_comp *comp) +{ + UINT8 seg_len = data[*trav_offset]; + (*trav_offset)++; + + if (0 == seg_len) + { + // do alloc memory to this power segment and return SUCCESS + comp->seg_len = 0; + comp->segment = NULL; + return IR_DECODE_SUCCEEDED; + } + + comp->seg_len = seg_len; + comp->segment = (UINT8 *) irda_malloc(seg_len); + if (NULL == comp->segment) + { + return IR_DECODE_FAILED; + } + + irda_memcpy(comp->segment, &data[*trav_offset], seg_len); + *trav_offset += seg_len; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_comp_data_type_2(UINT8 *data, UINT16 *trav_offset, tag_comp *comp) +{ + UINT8 seg_len = data[*trav_offset]; + (*trav_offset)++; + + if (0 == seg_len) + { + // do alloc memory to this temp segment and return SUCCESS + comp->seg_len = 0; + comp->segment = NULL; + return IR_DECODE_SUCCEEDED; + } + + comp->seg_len = seg_len; + comp->segment = (UINT8 *) irda_malloc(seg_len); + if (NULL == comp->segment) + { + return IR_DECODE_FAILED; + } + + irda_memcpy(comp->segment, &data[*trav_offset], seg_len); + *trav_offset += seg_len; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_common_ac_parameter(t_tag_head *tag, tag_comp *comp_data, UINT8 with_end, UINT8 type) +{ + UINT16 hex_len = 0; +#if (defined BOARD_PC) || (defined BOARD_MT6580) + UINT16 i = 0; +#endif + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == comp_data) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to AC data structure + //*comp_len = hex_len; + + if (AC_PARAMETER_TYPE_1 == type) + { + for (seg_index = 0; seg_index < with_end; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_1(hex_data, &trav_offset, &comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } +#if (defined BOARD_PC) || (defined BOARD_MT6580) + // have some debug + IR_PRINTF("seg[%d].len = %d : \n", seg_index, comp_data[seg_index].seg_len); + for(i = 0; i < comp_data[seg_index].seg_len; i++) + { + IR_PRINTF("[%02X] ", comp_data[seg_index].segment[i]); + } + IR_PRINTF("\n"); +#endif + + if (trav_offset >= hex_len) + { + break; + } + } + } + else + { + for (seg_index = 0; seg_index < with_end; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_2(hex_data, &trav_offset, &comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } +#if (defined BOARD_PC) || (defined BOARD_MT6580) + // have some debug + IR_PRINTF("seg[%d].len = %d : \n", seg_index, comp_data[seg_index].seg_len); + for(i = 0; i < comp_data[seg_index].seg_len; i++) + { + IR_PRINTF("[%02X] ", comp_data[seg_index].segment[i]); + } + IR_PRINTF("\n"); +#endif + if (trav_offset >= hex_len) + { + break; + } + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_defaultcode_1002(struct tag_head *tag, ac_hex *default_code) +{ + UINT16 byteLen = 0; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + byteLen = tag->len >> 1; + string_to_hex(tag->pdata, default_code, byteLen); + + return IR_DECODE_SUCCEEDED; +} + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + +INT8 parse_power_1_1001(struct tag_head *tag, power_1 *power1) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == power1) + { + return IR_DECODE_FAILED; + } + // IR_PRINTF("\n============\n%s\n", __func__); + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to power1 data structure + power1->len = hex_len; + + for (seg_index = AC_POWER_ON; seg_index < AC_POWER_MAX; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_1(hex_data, &trav_offset, &power1->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + // have some debug + // IR_PRINTF("power_seg[%d].len = %d : \n", seg_index, power1->comp_data[seg_index].seg_len); + // IR_PRINTF("\n"); + + // prevent from buffer over flowing + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +#endif + +INT8 parse_temp_1_1003(struct tag_head *tag, temp_1 *temp1) +{ + UINT16 hex_len = 0; + UINT16 i = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data according to length + if (hex_data[0] == hex_len - 1) + { + // dynamic temperature tag + temp1->type = TEMP_TYPE_DYNAMIC; + temp1->len = hex_len; + UINT8 seg_len = hex_data[0]; + + for (seg_index = AC_TEMP_16; seg_index < AC_TEMP_MAX; seg_index++) + { + // 020210 indicates set the 02nd byte to [default] +10, +11, +12, +... + temp1->comp_data[seg_index].seg_len = seg_len; + temp1->comp_data[seg_index].segment = (UINT8 *) irda_malloc(seg_len); + if (NULL == temp1->comp_data[seg_index].segment) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + for (i = 1; i < seg_len; i += 2) + { + temp1->comp_data[seg_index].segment[i - 1] = hex_data[i]; + + // get the default value of temperature + temp1->comp_data[seg_index].segment[i] = hex_data[i + 1] * seg_index; + } + } + } + else + { + // static temperature tag + temp1->len = hex_len; + temp1->type = TEMP_TYPE_STATIC; + for (seg_index = AC_TEMP_16; seg_index < AC_TEMP_MAX; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_1(hex_data, &trav_offset, &temp1->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + // have some debug + IR_PRINTF("seg[%d].len = %d : \n", seg_index, temp1->comp_data[seg_index].seg_len); + for(i = 0; i < temp1->comp_data[seg_index].seg_len; i++) + { + IR_PRINTF("[%02X] ", temp1->comp_data[seg_index].segment[i]); + } + IR_PRINTF("\n"); +#endif + + if (trav_offset >= hex_len) + { + break; + } + } + } + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + +INT8 parse_mode_1_1004(struct tag_head *tag, mode_1 *mode1) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + // IR_PRINTF("\n============\n%s\n", __func__); + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to mode1 data structure + mode1->len = hex_len; + + for (seg_index = AC_MODE_COOL; seg_index < AC_MODE_MAX; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_1(hex_data, &trav_offset, &mode1->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + // have some debug + // IR_PRINTF("mode_seg[%d].len = %d : \n", seg_index, mode1->comp_data[seg_index].seg_len); + // IR_PRINTF("\n"); + + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_speed_1_1005(struct tag_head *tag, speed_1 *speed1) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + // IR_PRINTF("\n============\n%s\n", __func__); + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to speed1 data structure + speed1->len = hex_len; + + for (seg_index = AC_WS_AUTO; seg_index < AC_WS_MAX; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_1(hex_data, &trav_offset, &speed1->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + // have some debug + // IR_PRINTF("speed_seg[%d].len = %d : \n", seg_index, speed1->comp_data[seg_index].seg_len); + // IR_PRINTF("\n"); + + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_swing_1_1007(struct tag_head *tag, swing_1 *swing1, UINT16 swing_count) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + // IR_PRINTF("\n============\n%s\n", __func__); + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to swing1 data structure + swing1->count = swing_count; + swing1->len = hex_len; + swing1->comp_data = (tag_comp *) irda_malloc(sizeof(tag_comp) * swing_count); + if (NULL == swing1->comp_data) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + for (seg_index = 0; seg_index < swing_count; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_1(hex_data, &trav_offset, &swing1->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + // have some debug + // IR_PRINTF("swing_seg[%d].len = %d : \n", seg_index, swing1->comp_data[seg_index].seg_len); + // IR_PRINTF("\n"); + + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +#endif + +/* modified by xiangjiang 2015-11-20 - begin - */ +INT8 parse_checksum_byte_typed(UINT8 *csdata, tag_checksum_data *checksum, UINT16 len) +{ + checksum->start_byte_pos = csdata[2]; + checksum->end_byte_pos = csdata[3]; + checksum->checksum_byte_pos = csdata[4]; + + if (len > 5) + { + checksum->checksum_plus = csdata[5]; + } + else + { + checksum->checksum_plus = 0; + } + checksum->spec_pos = NULL; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_checksum_half_byte_typed(UINT8 *csdata, tag_checksum_data *checksum, UINT16 len) +{ + checksum->start_byte_pos = csdata[2]; + checksum->end_byte_pos = csdata[3]; + checksum->checksum_byte_pos = csdata[4]; + + if (len > 5) + { + checksum->checksum_plus = csdata[5]; + } + else + { + checksum->checksum_plus = 0; + } + checksum->spec_pos = NULL; + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_checksum_spec_half_byte_typed(UINT8 *csdata, tag_checksum_data *checksum, UINT16 len) +{ + /* + * note: + * for the type of specified half byte checksum algorithm, + * the checksum byte positions are in unit of HALF BYTE, rather than in unit of BYTE + * as well as the specified half byte positions (spec_pos). + * Thus the specified half byte checksum only affects 4 bits of a position + * of half byte specified by check_sum_byte_pos property. + */ + UINT16 spec_pos_size = len - 4; + + checksum->checksum_byte_pos = csdata[2]; + checksum->checksum_plus = csdata[3]; + checksum->start_byte_pos = 0; + checksum->end_byte_pos = 0; + checksum->spec_pos = (UINT8 *) irda_malloc(spec_pos_size); + if (NULL == checksum->spec_pos) + { + return IR_DECODE_FAILED; + } + irda_memcpy(checksum->spec_pos, &csdata[4], spec_pos_size); + + return IR_DECODE_SUCCEEDED; +} +/* modified by xiangjiang 2015-11-20 - end - */ + +/* added by xiangjiang 2015-11-20 - begin - */ +INT8 parse_checksum_1008_malloc(struct tag_head *tag, tchecksum *checksum) +{ + UINT8 i = 0; + UINT8 cnt = 0; + + for (i = 0; i < tag->len; i++) + { + if (tag->pdata[i] == '|') + { + cnt++; + } + } + + checksum->len = (tag->len - cnt) >> 1; + checksum->count = cnt + 1; + checksum->checksum_data = (tag_checksum_data*) irda_malloc(sizeof(tag_checksum_data) * checksum->count); + + if (NULL == checksum->checksum_data) + { + return IR_DECODE_FAILED; + } + irda_memset(checksum->checksum_data, 0x00, sizeof(tag_checksum_data) * checksum->count); + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_checksum_1008_data(UINT8 *buf, tag_checksum_data *checksum, UINT8 length) +{ + UINT8 *hex_data = NULL; + UINT16 hex_len = 0; + + if (NULL == buf) + { + return IR_DECODE_FAILED; + } + + if (NULL == checksum) + { + return IR_DECODE_FAILED; + } + + hex_len = length; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(buf, hex_data, hex_len); + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + UINT8 i = 0; + IR_PRINTF("hex len = %d\n", hex_len); + for(i = 0; i < hex_len; i++) + { + IR_PRINTF("[%02X] ", hex_data[i]); + } + IR_PRINTF("\n"); +#endif + + if (length != hex_data[0] + 1) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + checksum->len = hex_data[0]; + checksum->type = hex_data[1]; + switch (checksum->type) + { + case CHECKSUM_TYPE_BYTE: + case CHECKSUM_TYPE_BYTE_INVERSE: + if (IR_DECODE_FAILED == parse_checksum_byte_typed(hex_data, checksum, hex_len)) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + break; + case CHECKSUM_TYPE_HALF_BYTE: + case CHECKSUM_TYPE_HALF_BYTE_INVERSE: + if (IR_DECODE_FAILED == parse_checksum_half_byte_typed(hex_data, checksum, hex_len)) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + break; + case CHECKSUM_TYPE_SPEC_HALF_BYTE: + case CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE: + case CHECKSUM_TYPE_SPEC_HALF_BYTE_ONE_BYTE: + case CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE_ONE_BYTE: + if (IR_DECODE_FAILED == parse_checksum_spec_half_byte_typed(hex_data, checksum, hex_len)) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + break; + default: + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + break; + } + + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_SUCCEEDED; +} +/* added by xiangjiang 2015-11-20 - end - */ + +INT8 parse_checksum_1008(struct tag_head *tag, tchecksum *checksum) +{ +/* modified by xiangjiang 2015-11-20 - begin - */ +#if 0 + UINT8 *hex_data = NULL; + UINT16 hex_len = 0; + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + if (tag->len >> 1 != hex_data[0] + 1) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + checksum->len = hex_data[0]; + checksum->type = hex_data[1]; + switch (checksum->type) + { + case CHECKSUM_TYPE_BYTE: + case CHECKSUM_TYPE_BYTE_INVERSE: + parse_checksum_byte_typed(hex_data, checksum, hex_len); + break; + case CHECKSUM_TYPE_HALF_BYTE: + case CHECKSUM_TYPE_HALF_BYTE_INVERSE: + parse_checksum_half_byte_typed(hex_data, checksum, hex_len); + break; + case CHECKSUM_TYPE_SPEC_HALF_BYTE: + case CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE: + parse_checksum_spec_half_byte_typed(hex_data, checksum, hex_len); + break; + default: + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + irda_free(hex_data); + hex_data = NULL; + +#else + UINT8 i = 0; + UINT8 num = 0; + UINT16 preindex = 0; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == checksum) + { + return IR_DECODE_FAILED; + } + + if(IR_DECODE_FAILED == parse_checksum_1008_malloc(tag, checksum)) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < tag->len; i++) + { + if (tag->pdata[i] == '|') + { + if(IR_DECODE_FAILED == parse_checksum_1008_data(tag->pdata + preindex, + checksum->checksum_data + num, + (i - preindex) >> 1)) + { + return IR_DECODE_FAILED; + } + preindex = i + 1; + num++; + } + } + + if(IR_DECODE_FAILED == parse_checksum_1008_data(tag->pdata + preindex, + checksum->checksum_data + num, + (i - preindex) >> 1)) + { + return IR_DECODE_FAILED; + } + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + UINT8 j = 0; + for(i = 0; i < checksum->count; i++) + { + IR_PRINTF("checksum[%d].len = 1 + %d :\n", i, checksum->checksum_data[i].len); + for(j = 0; j <= checksum->checksum_data[i].len; j++) + { + IR_PRINTF("[%02X] ", *(((UINT8*)&checksum->checksum_data[i]) + j)); + if(j == 0) + { + IR_PRINTF(" "); + } + } + IR_PRINTF("\n"); + } +#endif + +#endif +/* modified by xiangjiang 2015-11-20 - end - */ + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_function_1(UINT8 *data, UINT16 *trav_offset, tag_comp *mode_seg) +{ + UINT8 seg_len = 0; + BOOL valid_function_id = TRUE; + + if (NULL == data) + { + return IR_DECODE_FAILED; + } + + if (NULL == trav_offset) + { + return IR_DECODE_FAILED; + } + + if (NULL == mode_seg) + { + return IR_DECODE_FAILED; + } + + seg_len = data[*trav_offset]; + (*trav_offset)++; + + // function id starts from 1 (POWER) + UINT8 function_id = data[*trav_offset] - 1; + + if (function_id > AC_FUNCTION_MAX - 1) + { + // ignore unsupported function ID + IR_PRINTF("\nunsupported function id : %d\n", function_id); + valid_function_id = FALSE; + } + + (*trav_offset)++; + + if (0 == seg_len) + { + // do alloc memory to this mode segment and return SUCCESS + if (TRUE == valid_function_id) + { + mode_seg[function_id].seg_len = 0; + + if (NULL != mode_seg[function_id].segment) + { + irda_free(mode_seg[function_id].segment); + mode_seg[function_id].segment = NULL; + } + } + + return IR_DECODE_SUCCEEDED; + } + + if (TRUE == valid_function_id) + { + mode_seg[function_id].seg_len = seg_len - 1; + mode_seg[function_id].segment = (UINT8 *) irda_malloc(seg_len - 1); + if (NULL == mode_seg[function_id].segment) + { + return IR_DECODE_FAILED; + } + irda_memcpy(mode_seg[function_id].segment, &data[*trav_offset], seg_len - 1); + } + *trav_offset += seg_len - 1; + + return function_id; +} + +INT8 parse_function_1_1010(struct tag_head *tag, function_1 *function1) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == function1) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to mode1 data structure + function1->len = hex_len; + + // seg_index in TAG 1010 and TAG 1016 only refers to functional count + for (seg_index = AC_FUNCTION_POWER; seg_index < AC_FUNCTION_MAX; seg_index++) + { + int fid = parse_function_1(hex_data, &trav_offset, &function1->comp_data[0]); + + /* + if (fid > AC_FUNCTION_MAX - 1) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + */ + + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_temp_2_1011(struct tag_head *tag, temp_2 *temp2) +{ + UINT16 hex_len = 0; + UINT16 i = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == temp2) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data according to length + if (hex_data[0] == hex_len - 1) + { + // dynamic temperature tag + temp2->type = TEMP_TYPE_DYNAMIC; + temp2->len = hex_len; + UINT8 seg_len = hex_data[0]; + + for (seg_index = AC_TEMP_16; seg_index < AC_TEMP_MAX; seg_index++) + { + // 020210 indicates set the 02nd byte to [default] +10, +11, +12, +... + temp2->comp_data[seg_index].seg_len = seg_len; + temp2->comp_data[seg_index].segment = (UINT8 *) irda_malloc(seg_len); + if (NULL == temp2->comp_data[seg_index].segment) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + for (i = 2; i < seg_len; i += 3) + { + temp2->comp_data[seg_index].segment[i - 2] = hex_data[i - 1]; + temp2->comp_data[seg_index].segment[i - 1] = hex_data[i]; + + // for this second type (TAG 1011) temperature update, apply the change in run time. + temp2->comp_data[seg_index].segment[i] = hex_data[i + 1] * seg_index; + } + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + // have some debug + IR_PRINTF("seg[%d].len = %d : \n", seg_index, temp2->comp_data[seg_index].seg_len); + for(i = 0; i < temp2->comp_data[seg_index].seg_len; i++) + { + IR_PRINTF("[%02X] ", temp2->comp_data[seg_index].segment[i]); + } + IR_PRINTF("\n"); +#endif + } + } + else + { + // static temperature tag + temp2->len = hex_len; + temp2->type = TEMP_TYPE_STATIC; + for (seg_index = AC_TEMP_16; seg_index < AC_TEMP_MAX; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_2(hex_data, &trav_offset, &temp2->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + if (trav_offset >= hex_len) + { + break; + } + } + } + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + +INT8 parse_mode_2_1012(struct tag_head *tag, mode_2 *mode2) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + // IR_PRINTF("\n============\n%s\n", __func__); + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == mode2) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to mode1 data structure + mode2->len = hex_len; + + for (seg_index = AC_MODE_COOL; seg_index < AC_MODE_MAX; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_2(hex_data, &trav_offset, &mode2->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + // have some debug + // IR_PRINTF("mode_seg[%d].len = %d : \n", seg_index, mode2->comp_data[seg_index].seg_len); + // IR_PRINTF("\n"); + + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_speed_2_1013(struct tag_head *tag, speed_2 *speed2) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + // IR_PRINTF("\n============\n%s\n", __func__); + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == speed2) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to speed1 data structure + speed2->len = hex_len; + + for (seg_index = AC_WS_AUTO; seg_index < AC_WS_MAX; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_2(hex_data, &trav_offset, &speed2->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + // have some debug + // IR_PRINTF("speed_seg[%d].len = %d : \n", seg_index, speed2->comp_data[seg_index].seg_len); + // IR_PRINTF("\n"); + + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_swing_2_1015(struct tag_head *tag, swing_2 *swing2, UINT16 swing_count) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + // IR_PRINTF("\n============\n%s\n", __func__); + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == swing2) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to swing2 data structure + swing2->count = swing_count; + swing2->len = hex_len; + swing2->comp_data = (tag_comp *) irda_malloc(sizeof(tag_comp) * swing_count); + if (NULL == swing2->comp_data) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + for (seg_index = 0; seg_index < swing_count; seg_index++) + { + if (IR_DECODE_FAILED == parse_comp_data_type_2(hex_data, &trav_offset, &swing2->comp_data[seg_index])) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + + // have some debug + // IR_PRINTF("swing_seg[%d].len = %d : \n", seg_index, swing2->comp_data[seg_index].seg_len); + // IR_PRINTF("\n"); + + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +#endif + +INT8 parse_function_2(UINT8 *data, UINT16 *trav_offset, tag_comp *mode_seg) +{ + UINT8 seg_len = 0; + BOOL valid_function_id = TRUE; + + if (NULL == data) + { + return IR_DECODE_FAILED; + } + + if (NULL == trav_offset) + { + return IR_DECODE_FAILED; + } + + if (NULL == mode_seg) + { + return IR_DECODE_FAILED; + } + + seg_len = data[*trav_offset]; + (*trav_offset)++; + + // function id starts from 1 (POWER) + UINT8 function_id = data[*trav_offset] - 1; + if (function_id > AC_FUNCTION_MAX - 1) + { + // ignore unsupported function ID + IR_PRINTF("\nunsupported function id : %d\n", function_id); + valid_function_id = FALSE; + } + + (*trav_offset)++; + + if (0 == seg_len) + { + if (TRUE == valid_function_id) + { + // do alloc memory to this mode segment and return SUCCESS + mode_seg[function_id].seg_len = 0; + + if (NULL != mode_seg[function_id].segment) + { + irda_free(mode_seg[function_id].segment); + mode_seg[function_id].segment = NULL; + } + } + + return IR_DECODE_SUCCEEDED; + } + + if (TRUE == valid_function_id) + { + mode_seg[function_id].seg_len = seg_len - 1; + mode_seg[function_id].segment = (UINT8 *) irda_malloc(seg_len - 1); + + if (NULL == mode_seg[function_id].segment) + { + return IR_DECODE_FAILED; + } + + irda_memcpy(mode_seg[function_id].segment, &data[*trav_offset], seg_len - 1); + } + *trav_offset += seg_len - 1; + + return function_id; +} + +INT8 parse_function_2_1016(struct tag_head *tag, function_2 *function2) +{ + UINT16 hex_len = 0; + UINT16 trav_offset = 0; + UINT16 seg_index = 0; + UINT8 *hex_data = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == function2) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to mode1 data structure + function2->len = hex_len; + + // seg_index in TAG 1010 and TAG 1016 only refers to functional count + for (seg_index = AC_FUNCTION_POWER; seg_index < AC_FUNCTION_MAX; seg_index++) + { + UINT8 fid = parse_function_2(hex_data, &trav_offset, &function2->comp_data[0]); + + /* + if (fid > AC_FUNCTION_MAX - 1) + { + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_FAILED; + } + */ + + if (trav_offset >= hex_len) + { + break; + } + } + + irda_free(hex_data); + hex_data = NULL; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_swing_info_1506(struct tag_head *tag, swing_info *si) +{ + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == si) + { + return IR_DECODE_FAILED; + } + /* + * 0 or 1 only - indicates swing info + */ + if (1 == tag->len) + { + if ('0' == tag->pdata[0]) + { + // to identify if there is only 1 status in TAG 1007 OR 1015 + si->type = SWING_TYPE_NOT_SPECIFIED; + si->mode_count = 0; + } + else if ('1' == tag->pdata[0]) + { + si->type = SWING_TYPE_SWING_ONLY; + si->mode_count = 1; + } + else + { + return IR_DECODE_FAILED; + } + return IR_DECODE_SUCCEEDED; + } + + /* + * length greater than 1 indicates both auto-swing and some swing angles are supported + */ + // count how many swing types are there + si->type = SWING_TYPE_NORMAL; + si->mode_count = (tag->len + 1) >> 1; + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_solo_code_1009(struct tag_head *tag, solo_code *sc) +{ + UINT16 hex_len = 0; + UINT8 *hex_data = NULL; + UINT8 i = 0; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + if (NULL == sc) + { + return IR_DECODE_FAILED; + } + + hex_len = tag->len >> 1; + + if(hex_len > AC_FUNCTION_MAX) + { + IR_PRINTF("solo function code exceeded!!\n"); + return IR_DECODE_FAILED; + } + + hex_data = (UINT8 *) irda_malloc(hex_len); + + if (NULL == hex_data) + { + return IR_DECODE_FAILED; + } + string_to_hex_common(tag->pdata, hex_data, hex_len); + + // parse hex data to mode1 data structure + sc->len = hex_len; + sc->solo_func_count = hex_len - 1; + + // per each function takes just 1 byte of length + sc->solo_func_count = hex_data[0]; + for (i = 1; i < hex_len; i++) + { + sc->solo_function_codes[i - 1] = hex_data[i]; + } + + irda_free(hex_data); + hex_data = NULL; + return IR_DECODE_SUCCEEDED; +} \ No newline at end of file diff --git a/src/ir_decoder/irda_parse_ac_parameter.h b/src/ir_decoder/irda_parse_ac_parameter.h new file mode 100644 index 0000000..89538d7 --- /dev/null +++ b/src/ir_decoder/irda_parse_ac_parameter.h @@ -0,0 +1,87 @@ +/************************************************************************************************** +Filename: irda_parse_ac_parameter.h +Revised: Date: 2015-08-12 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode for AC functionality parameters + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-12: created by strawmanbobi +**************************************************************************************************/ + +/* + *inclusion + */ +#include "ucon_decode.h" + +#ifndef _IRDA_PARSE_AC_PARAMETER_H_ +#define _IRDA_PARSE_AC_PARAMETER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * public macros + */ + +/* + * public type definition + */ + +/* + * public function declaration + */ + +extern INT8 parse_common_ac_parameter(t_tag_head *tag, tag_comp *comp_data, UINT8 with_end, UINT8 type); + +extern INT8 parse_defaultcode_1002(struct tag_head *tag, ac_hex *default_code); + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + +extern INT8 parse_power_1_1001(struct tag_head *tag, power_1 *power1); + +#endif + +extern INT8 parse_temp_1_1003(struct tag_head *tag, temp_1 *temp1); + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + +extern INT8 parse_mode_1_1004(struct tag_head *tag, mode_1 *mode1); + +extern INT8 parse_speed_1_1005(struct tag_head *tag, speed_1 *speed1); + +extern INT8 parse_swing_1_1007(struct tag_head *tag, swing_1 *swing1, UINT16 swing_count); + +#endif + +extern INT8 parse_checksum_1008(struct tag_head *tag, tchecksum *checksum); + +extern INT8 parse_function_1_1010(struct tag_head *tag, function_1 *function1); + +extern INT8 parse_temp_2_1011(struct tag_head *tag, temp_2 *temp2); + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + +extern INT8 parse_mode_2_1012(struct tag_head *tag, mode_2 *mode2); + +extern INT8 parse_speed_2_1013(struct tag_head *tag, speed_2 *speed2); + +extern INT8 parse_swing_2_1015(struct tag_head *tag, swing_2 *swing2, UINT16 swing_count); + +#endif + +extern INT8 parse_function_2_1016(struct tag_head *tag, function_2 *function2); + +extern INT8 parse_swing_info_1506(struct tag_head *tag, swing_info *si); + +extern INT8 parse_solo_code_1009(struct tag_head *tag, solo_code *sc); + +#ifdef __cplusplus +} +#endif + +#endif // _IRDA_PARSE_AC_PARAMETER_H_ \ No newline at end of file diff --git a/src/ir_decoder/irda_parse_forbidden_info.c b/src/ir_decoder/irda_parse_forbidden_info.c new file mode 100644 index 0000000..378ca0f --- /dev/null +++ b/src/ir_decoder/irda_parse_forbidden_info.c @@ -0,0 +1,160 @@ +/************************************************************************************************** +Filename: irda_parse_forbidden_info.c +Revised: Date: 2015-08-05 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode for TAG 150x + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-05: created by strawmanbobi +**************************************************************************************************/ + +/* + *inclusion + */ +#include "ucon_decode.h" +#include "irda_utils.h" +#include "irda_parse_forbidden_info.h" +#include +#include +#include + +/* + * global vars + */ + +/* + * external vars + */ +extern protocol* context; + +/* + * function declaration + */ + +/* + * function definition + */ +INT8 parse_nmode_150x_data_speed(char *pdata, ac_n_mode seq) +{ + char buf[16] = {0}; + char *p = pdata; + UINT16 pos = 0; + UINT16 cnt = 0, index = 0; + + while (index <= irda_strlen(pdata)) + { + while ((index != irda_strlen(pdata)) && (*(p++) != ',')) + { + index++; + } + irda_memcpy(buf, pdata + pos, index - pos); + pos = index + 1; + index = pos; + context->n_mode[seq].speed[cnt++] = atoi(buf); + context->n_mode[seq].speed_cnt = cnt; + irda_memset(buf, 0, 16); + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_nmode_150x_data_temp(char *pdata, ac_n_mode seq) +{ + + char buf[16] = {0}; + char *p = pdata; + UINT16 pos = 0; + UINT16 cnt = 0, index = 0; + + while (index <= irda_strlen(pdata)) + { + while ((index != irda_strlen(pdata)) && (*(p++) != ',')) + { + index++; + } + irda_memcpy(buf, pdata + pos, index - pos); + pos = index + 1; + index = pos; + context->n_mode[seq].temp[cnt++] = atoi(buf) - 16; + context->n_mode[seq].temp_cnt = cnt; + irda_memset(buf, 0, 16); + } + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_nmode_150x_pos(char *buf, ac_n_mode index) +{ + UINT16 i = 0; + char data[64] = {0}; + // char start[8] = {0}; + if (irda_strlen(buf) == 1) + { + if (buf[0] == 'S' || buf[0] == 's') + { + context->n_mode[index].allspeed = 1; + } + else if (buf[0] == 'T' || buf[0] == 't') + { + context->n_mode[index].alltemp = 1; + } + return IR_DECODE_SUCCEEDED; + } + + for (i = 0; i < irda_strlen(buf); i++) + { + if (buf[i] == '&') + { + irda_memcpy(data, buf + i + 1, irda_strlen(buf) - i - 1); + break; + } + } + if (buf[0] == 'S') + { + parse_nmode_150x_data_speed(data, index); + } + else + { + parse_nmode_150x_data_temp(data, index); + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_nmode_150x(struct tag_head *tag, ac_n_mode index) +{ + UINT16 i = 0; + UINT16 preindex = 0; + + char buf[64] = {0}; + + if (tag->pdata[0] == 'N' && tag->pdata[1] == 'A') + { + // ban this function directly + context->n_mode[index].enable = 0; + return IR_DECODE_SUCCEEDED; + } + else + { + context->n_mode[index].enable = 1; + } + + preindex = 0; + for (i = 0; i < tag->len; i++) + { + if (tag->pdata[i] == '|') + { + irda_memcpy(buf, tag->pdata + preindex, i - preindex); + preindex = i + 1; + parse_nmode_150x_pos(buf, index); + irda_memset(buf, 0, 64); + } + + } + irda_memcpy(buf, tag->pdata + preindex, i - preindex); + parse_nmode_150x_pos(buf, index); + irda_memset(buf, 0, 64); + return IR_DECODE_SUCCEEDED; +} diff --git a/src/ir_decoder/irda_parse_forbidden_info.h b/src/ir_decoder/irda_parse_forbidden_info.h new file mode 100644 index 0000000..0cd533a --- /dev/null +++ b/src/ir_decoder/irda_parse_forbidden_info.h @@ -0,0 +1,45 @@ +/************************************************************************************************** +Filename: irda_parse_forbidden_info.h +Revised: Date: 2015-08-05 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode for TAG 1002 + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-05: created by strawmanbobi +**************************************************************************************************/ + +/* + *inclusion + */ +#include "ucon_decode.h" + +#ifndef _IRDA_PARSE_PARSE_150X_H_ +#define _IRDA_PARSE_PARSE_150X_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * public macros + */ + +/* + * public type definition + */ + +/* + * public function declaration + */ +extern INT8 parse_nmode_150x(struct tag_head *tag, ac_n_mode index); + +#ifdef __cplusplus + } +#endif + +#endif // _IRDA_PARSE_PARSE_150X_H_ + diff --git a/src/ir_decoder/irda_parse_frame_parameter.c b/src/ir_decoder/irda_parse_frame_parameter.c new file mode 100644 index 0000000..cea396d --- /dev/null +++ b/src/ir_decoder/irda_parse_frame_parameter.c @@ -0,0 +1,362 @@ +/************************************************************************************************** +Filename: irda_parse_frame_parameter.c +Revised: Date: 2015-08-11 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode for AC frame parameters + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-11: created by strawmanbobi +**************************************************************************************************/ + +/* + *inclusion + */ +#include +#include +#include +#include "irda_utils.h" +#include "irda_parse_frame_parameter.h" +#include "ucon_decode.h" + +/* + * global vars + */ + +/* + * external vars + */ + +/* + * function declaration + */ + + +/* + * function definition + */ +INT8 parse_bootcode_300(struct tag_head *tag) +{ + UINT8 buf[16] = {0}; + UINT8 *p = NULL; + UINT16 pos = 0; + UINT16 cnt = 0, index = 0; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + p = tag->pdata; + + if (NULL == p) + { + return IR_DECODE_FAILED; + } + + while (index <= tag->len) + { + while ((index != (tag->len)) && (*(p++) != ',')) + { + index++; + } + irda_memcpy(buf, tag->pdata + pos, index - pos); + pos = index + 1; + index = pos; + context->bootcode.data[cnt++] = atoi((char *) buf); + irda_memset(buf, 0, 16); + } + context->bootcode.len = cnt; + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_zero_301(struct tag_head *tag) +{ + UINT8 low[16] = {0}; + UINT8 high[16] = {0}; + UINT16 index = 0; + UINT8 *p = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + p = tag->pdata; + + if (NULL == p) + { + return IR_DECODE_FAILED; + } + + while (*(p++) != ',') + { + index++; + } + + irda_memcpy(low, tag->pdata, index); + irda_memcpy(high, tag->pdata + index + 1, tag->len - index - 1); + + context->zero.low = atoi((char *) low); + context->zero.high = atoi((char *) high); + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_one_302(struct tag_head *tag) +{ + UINT8 low[16] = {0}; + UINT8 high[16] = {0}; + UINT16 index = 0; + UINT8 *p = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + p = tag->pdata; + + if (NULL == p) + { + return IR_DECODE_FAILED; + } + + while (*(p++) != ',') + { + index++; + } + irda_memcpy(low, tag->pdata, index); + irda_memcpy(high, tag->pdata + index + 1, tag->len - index - 1); + + context->one.low = atoi((char *) low); + context->one.high = atoi((char *) high); + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_delaycode_303_data(UINT8 *pdata) +{ + UINT8 buf[16] = {0}; + UINT8 *p = NULL; + UINT16 pos = 0; + UINT16 cnt = 0, index = 0; + + if (NULL == pdata) + { + return IR_DECODE_FAILED; + } + p = pdata; + + while (index <= irda_strlen((char *) pdata)) + { + while ((index != irda_strlen((char *) pdata)) && (*(p++) != ',')) + { + index++; + } + irda_memcpy(buf, pdata + pos, index - pos); + pos = index + 1; + index = pos; + context->dc[context->dc_cnt].time[cnt++] = atoi((char *) buf); + context->dc[context->dc_cnt].time_cnt = cnt; + irda_memset(buf, 0, 16); + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_delaycode_303_pos(UINT8 *buf) +{ + UINT16 i = 0; + UINT8 data[64] = {0}, start[8] = {0}; + + if (NULL == buf) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < irda_strlen((char *) buf); i++) + { + if (buf[i] == '&') + { + irda_memcpy(start, buf, i); + irda_memcpy(data, buf + i + 1, irda_strlen((char *) buf) - i - 1); + break; + } + } + parse_delaycode_303_data(data); + context->dc[context->dc_cnt].pos = atoi((char *) start); + + context->dc_cnt++; + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_delaycode_303(struct tag_head *tag) +{ + UINT8 buf[64] = {0}; + UINT16 i = 0; + UINT16 preindex = 0; + preindex = 0; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < tag->len; i++) + { + if (tag->pdata[i] == '|') + { + irda_memcpy(buf, tag->pdata + preindex, i - preindex); + preindex = i + 1; + parse_delaycode_303_pos(buf); + irda_memset(buf, 0, 64); + } + + } + irda_memcpy(buf, tag->pdata + preindex, i - preindex); + parse_delaycode_303_pos(buf); + irda_memset(buf, 0, 64); + + /* updated by xiangjiang - 2015-08-31 - begin */ +#if 0 + for (i = 0; i < context->dc_cnt; i++) + { + if (context->dc[i].pos == -1) + { + context->dc[i].pos = (context->default_code.len - 1); + } + } +#endif + /* updated by xiangjiang - 2015-08-31 - end */ + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_framelen_304(struct tag_head *tag, UINT16 len) +{ + UINT8 *temp = NULL; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + temp = (UINT8 *)irda_malloc(len + 1); + + if (NULL == temp) + { + return IR_DECODE_FAILED; + } + + irda_memset(temp, 0x00, len + 1); + + irda_memcpy(temp, tag->pdata, len); + temp[len] = '\0'; + + context->frame_length = atoi((char *) temp); + + irda_free(temp); + temp = NULL; + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_endian_306(struct tag_head *tag) +{ + UINT8 buf[8] = {0}; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + irda_memcpy(buf, tag->pdata, tag->len); + context->endian = atoi((char *) buf); + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_lastbit_307(struct tag_head *tag) +{ + UINT8 buf[8] = {0}; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + irda_memcpy(buf, tag->pdata, tag->len); + context->lastbit = atoi((char *) buf); + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_repeat_times_1508(struct tag_head *tag) +{ + char asc_code[8] = {0}; + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + irda_memcpy(asc_code, tag->pdata, tag->len); + + context->repeat_times = atoi((char *) asc_code); + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_delaycode_1509_pos(UINT8 *buf) +{ + UINT16 i = 0; + UINT8 data[64] = {0}, start[8] = {0}; + + if (NULL == buf) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < irda_strlen((char *) buf); i++) + { + if (buf[i] == '&') + { + irda_memcpy(start, buf, i); + irda_memcpy(data, buf + i + 1, irda_strlen((char *) buf) - i - 1); + break; + } + } + + context->bitnum[context->bitnum_cnt].pos = atoi((char *) start); + context->bitnum[context->bitnum_cnt].bits = atoi((char *) data); + context->bitnum_cnt++; + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_bitnum_1509(struct tag_head *tag) +{ + UINT16 i = 0; + UINT16 preindex = 0; + UINT8 buf[64] = {0}; + + if (NULL == tag) + { + return IR_DECODE_FAILED; + } + + preindex = 0; + for (i = 0; i < tag->len; i++) + { + if (tag->pdata[i] == '|') + { + irda_memcpy(buf, tag->pdata + preindex, i - preindex); + preindex = i + 1; + parse_delaycode_1509_pos(buf); + irda_memset(buf, 0, 64); + } + + } + irda_memcpy(buf, tag->pdata + preindex, i - preindex); + parse_delaycode_1509_pos(buf); + irda_memset(buf, 0, 64); + + for (i = 0; i < context->bitnum_cnt; i++) + { + if (context->bitnum[i].pos == -1) + context->bitnum[i].pos = (context->default_code.len - 1); //convert -1 to last data pos + } + return IR_DECODE_SUCCEEDED; +} diff --git a/src/ir_decoder/irda_parse_frame_parameter.h b/src/ir_decoder/irda_parse_frame_parameter.h new file mode 100644 index 0000000..031675c --- /dev/null +++ b/src/ir_decoder/irda_parse_frame_parameter.h @@ -0,0 +1,60 @@ +/************************************************************************************************** +Filename: irda_parse_frame_parameter.h +Revised: Date: 2015-08-11 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode for AC frame parameters + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-11: created by strawmanbobi +**************************************************************************************************/ + +/* + *inclusion + */ +#include "ucon_decode.h" + +#ifndef _IRDA_PARSE_FRAME_PARAMETER_H_ +#define _IRDA_PARSE_FRAME_PARAMETER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * public macros + */ + +/* + * public type definition + */ + +/* + * public function declaration + */ +extern INT8 parse_bootcode_300(struct tag_head *tag); + +extern INT8 parse_zero_301(struct tag_head *tag); + +extern INT8 parse_one_302(struct tag_head *tag); + +extern INT8 parse_delaycode_303(struct tag_head *tag); + +extern INT8 parse_framelen_304(struct tag_head *tag, UINT16 len); + +extern INT8 parse_endian_306(struct tag_head *tag); + +extern INT8 parse_lastbit_307(struct tag_head *tag); + +extern INT8 parse_repeat_times_1508(struct tag_head *tag); + +extern INT8 parse_bitnum_1509(struct tag_head *tag); + +#ifdef __cplusplus + } +#endif + +#endif // _IRDA_PARSE_FRAME_PARAMETER_H_ \ No newline at end of file diff --git a/src/ir_decoder/irda_utils.c b/src/ir_decoder/irda_utils.c new file mode 100644 index 0000000..77f4e3e --- /dev/null +++ b/src/ir_decoder/irda_utils.c @@ -0,0 +1,107 @@ +/************************************************************************************************** +Filename: irda_utils.c +Revised: Date: 2015-08-26 +Revision: Revision: 1.0 + +Description: This file provides generic utils for UCON IRDA algorithms + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-01: created by strawmanbobi +**************************************************************************************************/ +#include +#include +#include + +#include "irda_utils.h" +#include "ucon_decode.h" + +/* +*0123456789abcdef/0123456789ABCDEF +*/ +UINT8 char_to_hex(char chr) +{ + UINT8 value = 0; + if (chr >= '0' && chr <= '9') + value = chr - '0'; + if (chr >= 'a' && chr <= 'f') + value = chr - 'a' + 10; + if (chr >= 'A' && chr <= 'F') + value = chr - 'A' + 10; + return value; +} + +UINT8 chars_to_hex(UINT8 *p) +{ + return (char_to_hex(*p) << 4) + char_to_hex(*(p + 1)); +} + +void string_to_hex_common(UINT8 *p, UINT8 *hex_data, UINT16 len) +{ + // in condition of hex_code is already assigned + UINT16 i = 0; + + for (i = 0; i < len; i++) + { + hex_data[i] = chars_to_hex(p); + p = p + 2; + } +} + +void string_to_hex(UINT8 *p, ac_hex *pac_hex, UINT16 len) +{ + UINT8 i = 0; + + pac_hex->len = chars_to_hex(p); + p = p + 2; + for (i = 0; i < pac_hex->len; i++) + { + pac_hex->data[i] = chars_to_hex(p); + p = p + 2; + } +} + +char hex_half_byte_to_single_char(UINT8 length, UINT8 half_byte) +{ + if (1 != length || half_byte >= 16) + { + return '0'; + } + if (half_byte >= 10 && half_byte < 16) + { + return (half_byte - 10 + 0x41); + } + else + { + return half_byte + 0x30; + } +} + +void hex_byte_to_double_char(char* dest, UINT8 length, UINT8 src) +{ + UINT8 hi_num = 0; + UINT8 lo_num = 0; + if (NULL == dest || 2 != length) + { + return; + } + hi_num = (src >> 4) & 0x0F; + lo_num = src & 0x0F; + + dest[0] = hex_half_byte_to_single_char(1, hi_num); + dest[1] = hex_half_byte_to_single_char(1, lo_num); +} + +BOOL isin(UINT8 array[], UINT8 value, UINT8 len) +{ + UINT16 i = 0; + for(i = 0; i < len; i++) + { + if(array[i] == value) + { + return TRUE; + } + } + return FALSE; +} \ No newline at end of file diff --git a/src/ir_decoder/irda_utils.h b/src/ir_decoder/irda_utils.h new file mode 100644 index 0000000..21bd35b --- /dev/null +++ b/src/ir_decoder/irda_utils.h @@ -0,0 +1,39 @@ +/************************************************************************************************** +Filename: irda_utils.c +Revised: Date: 2015-08-26 +Revision: Revision: 1.0 + +Description: This file provides generic utils for UCON IRDA algorithms + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-01: created by strawmanbobi +**************************************************************************************************/ +#include "irda_defs.h" +#include "ucon_decode.h" + +#ifndef _IRDA_UTILS_H_ +#define _IRDA_UTILS_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +extern void string_to_hex(UINT8 *p, ac_hex *pac_hex, UINT16 len); + +extern void string_to_intArray(UINT8 *p, UINT8 *binary_code, UINT16 len); + +extern void string_to_hex_common(UINT8 *p, UINT8 *hex_data, UINT16 len); + +extern BOOL isin(UINT8 array[], UINT8 value, UINT8 len); + +extern void hex_byte_to_double_char(char* dest, UINT8 length, UINT8 src); + +#ifdef __cplusplus +} +#endif +#endif // _IRDA_UTILS_H_ \ No newline at end of file diff --git a/src/ir_decoder/ucon_decode.c b/src/ir_decoder/ucon_decode.c new file mode 100644 index 0000000..66a4b8e --- /dev/null +++ b/src/ir_decoder/ucon_decode.c @@ -0,0 +1,1934 @@ +/************************************************************************************************** +Filename: ucon_decode.c +Revised: Date: 2015-08-01 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode (status type) + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-01: created by strawmanbobi +**************************************************************************************************/ +#include +#include + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +#include +#include +#include +#endif + +#include + +#include "ucon_decode.h" +#include "irda_utils.h" +#include "irda_parse_frame_parameter.h" +#include "irda_parse_ac_parameter.h" +#include "irda_parse_forbidden_info.h" +#include "irda_irframe.h" +#include "irda_apply.h" +#include "irda_lib.h" +#include "bc_parse_parameter.h" + +#if defined BOARD_CC254X +#include "ucon_data.h" +#include "ucon_remote.h" +#include "ucon_public.h" +#include "ucon_irda.h" +#include "npi.h" +#endif + +#if defined BOARD_MC200 +#include "yk_irda.h" +#endif + +struct ir_bin_buffer binaryfile; +struct ir_bin_buffer *pirda_buffer = &binaryfile; +struct tag_head *tags; + +// IRDA hex code +UINT8* ir_hex_code = NULL; +UINT8 ir_hex_len = 0; + +// global output buffer +UINT8 tag_count = 0; +UINT16 tag_head_offset = 0; + +UINT16 global_mem_consume = 0; + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +UINT8 byteArray[PROTOCOL_SIZE] = {0}; +UINT16 user_data[USER_DATA_SIZE] = {0}; +UINT8 tv_bin[EXPECTED_MEM_SIZE] = {0}; +UINT16 tv_bin_length = 0; +remote_ac_status_t ac_status; +#endif + +// 2015-09-06 protocol version minor change: parse TAG 1009 instead of TAG 304 +const UINT16 tag_index[TAG_COUNT_FOR_PROTOCOL] = +{ + 300, 301, 302, 303, 305, 306, 307, 1001, 1002, + 1003, 1004, 1005, 1007, 1008, 1009, 1010, 1011, + 1012, 1013, 1015, 1016, 1501, 1502, 1503, 1504, 1505, + 1506, 1508, 1509 +}; + +const UINT16 bc_tag_index[TAG_COUNT_FOR_BC_PROTOCOL] = +{ + 100, 101, 102, 103, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 300 +}; + +// 2015-09-09 updated by strawmanbobi, change global data context to array pointer +protocol *context = (protocol *) byteArray; + +// BLE decode structure, share with a same byteArray to save memory +t_bc_protocol *context_bc = (t_bc_protocol *) byteArray; + +// ban function table +// fixed swing should not be counted in case of UCON +INT8 apply_power(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_mode(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_wind_speed(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_swing(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_temperature(remote_ac_status_t ac_status, UINT8 function_code); + +lp_apply_ac_parameter apply_table[AC_APPLY_MAX] = +{ + apply_power, + apply_mode, + apply_temperature, + apply_temperature, + apply_wind_speed, + apply_swing, + apply_swing +}; + +///////////////////////////////////////////////// Air Conditioner Begin ///////////////////////////////////////////////// + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +INT8 binary_open(const char *file) +{ + FILE *stream = fopen(file, "rb"); + if (stream == NULL) + { + IR_PRINTF("\nfile open failed : %d\n", errno); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_END); + pirda_buffer->len = ftell(stream); + + fseek(stream, 0, SEEK_SET); + fread(pirda_buffer->data, pirda_buffer->len, 1, stream); + fclose(stream); + + return IR_DECODE_SUCCEEDED; +} +#endif + +INT8 binary_parse_offset() +{ + int i = 0; + UINT16 *phead = (UINT16 *) &pirda_buffer->data[1]; + + tag_count = pirda_buffer->data[0]; + if(TAG_COUNT_FOR_PROTOCOL != tag_count) + { + return IR_DECODE_FAILED; + } + + tag_head_offset = (tag_count << 1) + 1; + + tags = (t_tag_head *) irda_malloc(tag_count * sizeof(t_tag_head)); + if (NULL == tags) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < tag_count; i++) + { + tags[i].tag = tag_index[i]; + tags[i].offset = *(phead + i); + if (tags[i].offset == TAG_INVALID) + { + tags[i].len = 0; + } + } + return IR_DECODE_SUCCEEDED; +} + +INT8 binary_parse_len() +{ + UINT16 i = 0, j = 0; + for (i = 0; i < (tag_count - 1); i++) + { + if (tags[i].offset == TAG_INVALID) + { + continue; + } + + for (j = (i + 1); j < tag_count; j++) + { + if (tags[j].offset != TAG_INVALID) + { + break; + } + } + if (j < tag_count) + { + tags[i].len = tags[j].offset - tags[i].offset; + } + else + { + tags[i].len = pirda_buffer->len - tags[i].offset - tag_head_offset; + return IR_DECODE_SUCCEEDED; + } + } + if (tags[tag_count - 1].offset != TAG_INVALID) + { + tags[tag_count - 1].len = pirda_buffer->len - tag_head_offset - tags[tag_count - 1].offset; + } + + return IR_DECODE_SUCCEEDED; +} + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +void binary_tags_info() +{ + UINT16 i = 0; + for (i = 0; i < tag_count; i++) + { + if (tags[i].len == 0) + { + continue; + } + IR_PRINTF("tag(%d).len = %d\n", tags[i].tag, tags[i].len); + } +} +#endif + +INT8 binary_parse_data() +{ + UINT16 i = 0; + for (i = 0; i < tag_count; i++) + { + tags[i].pdata = pirda_buffer->data + tags[i].offset + tag_head_offset; + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 free_ac_context() +{ + UINT16 i = 0; + + if (ir_hex_code != NULL) + { + irda_free(ir_hex_code); + ir_hex_code = NULL; + } + ir_hex_len = 0; + + if (context->default_code.data != NULL) + { + irda_free(context->default_code.data); + context->default_code.data = NULL; + context->default_code.len = 0; + } + + for (i = 0; i < AC_POWER_MAX; i++) + { + if (context->power1.comp_data[i].segment != NULL) + { + irda_free(context->power1.comp_data[i].segment); + context->power1.comp_data[i].segment = NULL; + context->power1.comp_data[i].seg_len = 0; + } + } + + for (i = 0; i < AC_TEMP_MAX; i++) + { + if (context->temp1.comp_data[i].segment != NULL) + { + irda_free(context->temp1.comp_data[i].segment); + context->temp1.comp_data[i].segment = NULL; + context->temp1.comp_data[i].seg_len = 0; + } + if (context->temp2.comp_data[i].segment != NULL) + { + irda_free(context->temp2.comp_data[i].segment); + context->temp2.comp_data[i].segment = NULL; + context->temp2.comp_data[i].seg_len = 0; + } + } + + for (i = 0; i < AC_MODE_MAX; i++) + { + if (context->mode1.comp_data[i].segment != NULL) + { + irda_free(context->mode1.comp_data[i].segment); + context->mode1.comp_data[i].segment = NULL; + context->mode1.comp_data[i].seg_len = 0; + } + if (context->mode2.comp_data[i].segment != NULL) + { + irda_free(context->mode2.comp_data[i].segment); + context->mode2.comp_data[i].segment = NULL; + context->mode2.comp_data[i].seg_len = 0; + } + } + for (i = 0; i < AC_WS_MAX; i++) + { + if (context->speed1.comp_data[i].segment != NULL) + { + irda_free(context->speed1.comp_data[i].segment); + context->speed1.comp_data[i].segment = NULL; + context->speed1.comp_data[i].seg_len = 0; + } + if (context->speed2.comp_data[i].segment != NULL) + { + irda_free(context->speed2.comp_data[i].segment); + context->speed2.comp_data[i].segment = NULL; + context->speed2.comp_data[i].seg_len = 0; + } + } + + for (i = 0; i < context->si.mode_count; i++) + { + if (context->swing1.comp_data != NULL && + context->swing1.comp_data[i].segment != NULL) + { + irda_free(context->swing1.comp_data[i].segment); + context->swing1.comp_data[i].segment = NULL; + context->swing1.comp_data[i].seg_len = 0; + } + if (context->swing2.comp_data != NULL && + context->swing2.comp_data[i].segment != NULL) + { + irda_free(context->swing2.comp_data[i].segment); + context->swing2.comp_data[i].segment = NULL; + context->swing2.comp_data[i].seg_len = 0; + } + } + + for (i = 0; i < AC_FUNCTION_MAX - 1; i++) + { + if (context->function1.comp_data[i].segment != NULL) + { + irda_free(context->function1.comp_data[i].segment); + context->function1.comp_data[i].segment = NULL; + context->function1.comp_data[i].seg_len = 0; + } + if (context->function2.comp_data[i].segment != NULL) + { + irda_free(context->function2.comp_data[i].segment); + context->function2.comp_data[i].segment = NULL; + context->function2.comp_data[i].seg_len = 0; + } + } + + // free composite data for swing1 and swing 2 + if(context->swing1.comp_data != NULL) + { + irda_free(context->swing1.comp_data); + context->swing1.comp_data = NULL; + } + if(context->swing2.comp_data != NULL) + { + irda_free(context->swing2.comp_data); + context->swing2.comp_data = NULL; + } + + /* modified by xiangjiang 2015-11-20 - begin - */ +#if 0 + if(context->checksum.spec_pos != NULL) + { + irda_free(context->checksum.spec_pos); + context->checksum.spec_pos = NULL; + } +#else + for(i = 0; i < context->checksum.count; i++) + { + if(context->checksum.checksum_data != NULL && + context->checksum.checksum_data[i].spec_pos != NULL) + { + irda_free(context->checksum.checksum_data[i].spec_pos); + context->checksum.checksum_data[i].len = 0; + context->checksum.checksum_data[i].spec_pos = NULL; + } + } + if(context->checksum.checksum_data != NULL) + { + irda_free(context->checksum.checksum_data); + context->checksum.checksum_data = NULL; + } +#endif + /* modified by xiangjiang 2015-11-20 - end - */ + + return IR_DECODE_SUCCEEDED; +} + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +INT8 irda_ac_lib_open(const char *file_name) +{ + IR_PRINTF("\nirda_ac_lib_open: %s\n", file_name); + return binary_open(file_name); +} +#else +INT8 irda_ac_lib_open(UINT8 *binary_file, UINT16 binary_length) +{ + // load bin to buffer + pirda_buffer->data = binary_file; + pirda_buffer->len = binary_length; + pirda_buffer->offset = 0; + return IR_DECODE_SUCCEEDED; +} +#endif + +INT8 irda_context_init() +{ + irda_memset(context, 0, sizeof(protocol)); + return IR_DECODE_SUCCEEDED; +} + +INT8 irda_ac_lib_parse() +{ + UINT16 i = 0; + // suggest not to call init function here for de-couple purpose +#if defined BOARD_CC254X + irda_context_init(); +#endif + if (IR_DECODE_FAILED == binary_parse_offset()) + { + return IR_DECODE_FAILED; + } + + if (IR_DECODE_FAILED == binary_parse_len()) + { + return IR_DECODE_FAILED; + } + + if (IR_DECODE_FAILED == binary_parse_data()) + { + return IR_DECODE_FAILED; + } + +#if (defined BOARD_PC) || (defined BOARD_MT6580) + binary_tags_info(); +#endif + context->endian = 0; + context->lastbit = 0; + context->repeat_times = 1; + + for (i = 0; i < N_MODE_MAX; i++) + { + context->n_mode[i].enable = TRUE; + context->n_mode[i].allspeed = FALSE; + context->n_mode[i].alltemp = FALSE; + irda_memset(context->n_mode[i].speed, 0x00, AC_WS_MAX); + context->n_mode[i].speed_cnt = 0; + irda_memset(context->n_mode[i].temp, 0x00, AC_TEMP_MAX); + context->n_mode[i].temp_cnt = 0; + } + + // parse tag 1506 in first priority + for (i = 0; i < tag_count; i++) + { + if (tags[i].tag == TAG_AC_SWING_INFO) + { + if (tags[i].len != 0) + { + parse_swing_info_1506(&tags[i], &(context->si)); + } + else + { + context->si.type = SWING_TYPE_NORMAL; + context->si.mode_count = 2; + } + context->si.dir_index = 0; + } + } + + for (i = 0; i < tag_count; i++) + { + if (tags[i].len == 0) + { + continue; + } + // then parse TAG 1007 or 1015 + if (context->si.type == SWING_TYPE_NORMAL) + { + UINT16 swing_space_size = 0; + if (tags[i].tag == TAG_AC_SWING_1) + { + IR_PRINTF("\nparse swing 1\n"); + context->swing1.count = context->si.mode_count; + context->swing1.len = tags[i].len >> 1; + swing_space_size = sizeof(tag_comp) * context->si.mode_count; + context->swing1.comp_data = (tag_comp*) irda_malloc(swing_space_size); + if (NULL == context->swing1.comp_data) + { + return IR_DECODE_FAILED; + } + + irda_memset(context->swing1.comp_data, 0x00, swing_space_size); + if (IR_DECODE_FAILED == parse_common_ac_parameter(&tags[i], + context->swing1.comp_data, + context->si.mode_count, + AC_PARAMETER_TYPE_1)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_SWING_2) + { + IR_PRINTF("\nparse swing 2\n"); + context->swing2.count = context->si.mode_count; + context->swing2.len = tags[i].len >> 1; + swing_space_size = sizeof(tag_comp) * context->si.mode_count; + context->swing2.comp_data = (tag_comp*) irda_malloc(swing_space_size); + if (NULL == context->swing2.comp_data) + { + return IR_DECODE_FAILED; + } + irda_memset(context->swing2.comp_data, 0x00, swing_space_size); + if (IR_DECODE_FAILED == parse_common_ac_parameter(&tags[i], + context->swing2.comp_data, + context->si.mode_count, + AC_PARAMETER_TYPE_2)) + { + return IR_DECODE_FAILED; + } + } + } + + if (tags[i].tag == TAG_AC_DEFAULT_CODE) // default code TAG + { + IR_PRINTF("\nparse default\n"); + context->default_code.data = (UINT8 *) irda_malloc((tags[i].len - 2) >> 1); + if (NULL == context->default_code.data) + { + return IR_DECODE_FAILED; + } + if (IR_DECODE_FAILED == parse_defaultcode_1002(&tags[i], &(context->default_code))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_POWER_1) // power tag + { + IR_PRINTF("\nparse power 1\n"); + context->power1.len = tags[i].len >> 1; + if (IR_DECODE_FAILED == parse_common_ac_parameter(&tags[i], + context->power1.comp_data, + AC_POWER_MAX, + AC_PARAMETER_TYPE_1)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_TEMP_1) // temperature tag type 1 + { + IR_PRINTF("\nparse temperature 1\n"); + if (IR_DECODE_FAILED == parse_temp_1_1003(&tags[i], &(context->temp1))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_MODE_1) // mode tag + { + IR_PRINTF("\nparse mode 1\n"); + context->mode1.len = tags[i].len >> 1; + if (IR_DECODE_FAILED == parse_common_ac_parameter(&tags[i], + context->mode1.comp_data, + AC_MODE_MAX, + AC_PARAMETER_TYPE_1)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_SPEED_1) // wind speed tag + { + IR_PRINTF("\nparse speed 1\n"); + context->speed1.len = tags[i].len >> 1; + if (IR_DECODE_FAILED == parse_common_ac_parameter(&tags[i], + context->speed1.comp_data, + AC_WS_MAX, + AC_PARAMETER_TYPE_1)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_CHECKSUM_TYPE) + { + IR_PRINTF("\nparse checksum\n"); + if (IR_DECODE_FAILED == parse_checksum_1008(&tags[i], &(context->checksum))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_MODE_2) + { + IR_PRINTF("\nparse mode 2\n"); + context->mode2.len = tags[i].len >> 1; + if (IR_DECODE_FAILED == parse_common_ac_parameter(&tags[i], context->mode2.comp_data, AC_MODE_MAX, AC_PARAMETER_TYPE_1)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_SPEED_2) + { + IR_PRINTF("\nparse speed 2\n"); + context->speed2.len = tags[i].len >> 1; + if (IR_DECODE_FAILED == parse_common_ac_parameter(&tags[i], context->speed2.comp_data, AC_WS_MAX, AC_PARAMETER_TYPE_1)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_TEMP_2) + { + IR_PRINTF("\nparse temperature 2\n"); + if (IR_DECODE_FAILED == parse_temp_2_1011(&tags[i], &(context->temp2))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_SOLO_FUNCTION) + { + IR_PRINTF("\nparse solo functions\n"); + if (IR_DECODE_FAILED == parse_solo_code_1009(&tags[i], &(context->sc))) + { + return IR_DECODE_FAILED; + } + context->solo_function_mark = 1; + } + else if (tags[i].tag == TAG_AC_FUNCTION_1) + { + if (IR_DECODE_FAILED == parse_function_1_1010(&tags[i], &(context->function1))) + { + IR_PRINTF("\nfunction code parse error\n"); + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_FUNCTION_2) + { + IR_PRINTF("\nparse function 2\n"); + if (IR_DECODE_FAILED == parse_function_2_1016(&tags[i], &(context->function2))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_FRAME_LENGTH) + { + if (IR_DECODE_FAILED == parse_framelen_304(&tags[i], tags[i].len)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_ZERO) + { + if (IR_DECODE_FAILED == parse_zero_301(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_ONE) + { + if (IR_DECODE_FAILED == parse_one_302(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BOOT_CODE) + { + if (IR_DECODE_FAILED == parse_bootcode_300(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_REPEAT_TIMES) + { + if (IR_DECODE_FAILED == parse_repeat_times_1508(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BITNUM) + { + if (IR_DECODE_FAILED == parse_bitnum_1509(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_ENDIAN) + { + if (IR_DECODE_FAILED == parse_endian_306(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BAN_FUNCTION_IN_COOL_MODE) + { + if (IR_DECODE_FAILED == parse_nmode_150x(&tags[i], N_COOL)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BAN_FUNCTION_IN_HEAT_MODE) + { + if (IR_DECODE_FAILED == parse_nmode_150x(&tags[i], N_HEAT)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BAN_FUNCTION_IN_AUTO_MODE) + { + if (IR_DECODE_FAILED == parse_nmode_150x(&tags[i], N_AUTO)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BAN_FUNCTION_IN_FAN_MODE) + { + if (IR_DECODE_FAILED == parse_nmode_150x(&tags[i], N_FAN)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BAN_FUNCTION_IN_DRY_MODE) + { + if (IR_DECODE_FAILED == parse_nmode_150x(&tags[i], N_DRY)) + { + return IR_DECODE_FAILED; + } + } + } + + for(i = 0 ; i < tag_count; i++) + { + if(tags[i].len == 0) + { + continue; + } + if (tags[i].tag == TAG_AC_DELAY_CODE) + { + if (IR_DECODE_FAILED == parse_delaycode_303(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + if (tags[i].tag == TAG_AC_LASTBIT) + { + if (IR_DECODE_FAILED == parse_lastbit_307(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + } + + if(NULL != tags) + { + irda_free(tags); + tags = NULL; + } + + ir_hex_code = (UINT8 *) irda_malloc(context->default_code.len); + if(NULL == ir_hex_code) + { + // warning: this AC bin contains no default code + return IR_DECODE_FAILED; + } + + ir_hex_len = context->default_code.len; + irda_memset(ir_hex_code, 0x00, ir_hex_len); + + // pre-calculate solo function status after parse phase + if (1 == context->solo_function_mark) + { + context->solo_function_mark = 0x00; + // bit order from right to left : power, mode, temp+, temp-, wind_speed, swing, fix + for (i = AC_FUNCTION_POWER; i < AC_FUNCTION_MAX; i++) + { + if (isin(context->sc.solo_function_codes, i, context->sc.solo_func_count)) + { + context->solo_function_mark |= (1 << (i - 1)); + } + } + } + + return IR_DECODE_SUCCEEDED; +} + +BOOL is_solo_function(UINT8 function_code) +{ + return (((context->solo_function_mark >> (function_code - 1)) & 0x01) == 0x01) ? TRUE : FALSE; +} + +UINT8 has_function(struct ac_protocol *protocol, UINT8 function) +{ + if (0 != protocol->function1.len) + { + if(0 != protocol->function1.comp_data[function - 1].seg_len) + { + return TRUE; + } + } + + if(0 != protocol->function2.len) + { + if(0 != protocol->function2.comp_data[function - 1].seg_len) + { + return TRUE; + } + } + + return FALSE; +} + +INT8 apply_power(remote_ac_status_t ac_status, UINT8 function_code) +{ + apply_ac_power(context, ac_status.acPower); + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_mode(remote_ac_status_t ac_status, UINT8 function_code) +{ + if (IR_DECODE_FAILED == apply_ac_mode(context, ac_status.acMode)) + { + // do not implement this mechanism since mode, temperature, wind + // speed would have unspecified function + //if(FALSE == has_function(context, AC_FUNCTION_MODE)) + { + return IR_DECODE_FAILED; + } + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_wind_speed(remote_ac_status_t ac_status, UINT8 function_code) +{ + if (FALSE == context->n_mode[ac_status.acMode].allspeed) + { + // if this level is not in black list + if(!isin(context->n_mode[ac_status.acMode].speed, + ac_status.acWindSpeed, + context->n_mode[ac_status.acMode].speed_cnt)) + { + if(IR_DECODE_FAILED == apply_ac_wind_speed(context, ac_status.acWindSpeed) && + function_code == AC_FUNCTION_WIND_SPEED) + { + // do not implement this mechanism since mode, temperature, wind + // speed would have unspecified function + //if(FALSE == has_function(context, AC_FUNCTION_WIND_SPEED)) + { + return IR_DECODE_FAILED; + } + } + } + else + { + // if this level is in black list, do not send IR wave if user want to apply this function + if(function_code == AC_FUNCTION_WIND_SPEED) + { + // do not implement this mechanism since mode, temperature, wind + // speed would have unspecified function + //if(FALSE == has_function(context, AC_FUNCTION_WIND_SPEED)) + { + return IR_DECODE_FAILED; + } + } + } + } + else + { + // if this level is in black list, do not send IR wave if user want to apply this function + if(function_code == AC_FUNCTION_WIND_SPEED) + { + // do not implement this mechanism since mode, temperature, wind + // speed would have unspecified function + //if(FALSE == has_function(context, AC_FUNCTION_WIND_SPEED)) + { + return IR_DECODE_FAILED; + } + } + } + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_swing(remote_ac_status_t ac_status, UINT8 function_code) +{ + if(function_code == AC_FUNCTION_WIND_FIX) + { + // adjust fixed wind direction according to current status + if(context->si.type == SWING_TYPE_NORMAL && context->si.mode_count > 1) + { + if (TRUE == context->change_wind_direction) + { + context->si.dir_index++; + } + + if(context->si.dir_index == context->si.mode_count) + { + // reset dir index + context->si.dir_index = 1; + } + context->swing_status = context->si.dir_index; + } + } + else if(function_code == AC_FUNCTION_WIND_SWING) + { + context->swing_status = 0; + } + else + { + // do nothing + } + + if(IR_DECODE_FAILED == apply_ac_swing(context, context->swing_status)) + { + if(function_code == AC_FUNCTION_WIND_SWING && FALSE == has_function(context, AC_FUNCTION_WIND_SWING)) + { + return IR_DECODE_FAILED; + } + else if(function_code == AC_FUNCTION_WIND_FIX && FALSE == has_function(context, AC_FUNCTION_WIND_FIX)) + { + return IR_DECODE_FAILED; + } + } + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_temperature(remote_ac_status_t ac_status, UINT8 function_code) +{ + if (FALSE == context->n_mode[ac_status.acMode].alltemp) + { + if(!isin(context->n_mode[ac_status.acMode].temp, + ac_status.acTemp, + context->n_mode[ac_status.acMode].temp_cnt)) + { + if(IR_DECODE_FAILED == apply_ac_temperature(context, ac_status.acTemp)) + { + if(function_code == AC_FUNCTION_TEMPERATURE_UP /*&& FALSE == has_function(context, AC_FUNCTION_TEMPERATURE_UP)*/) + { + return IR_DECODE_FAILED; + } + else if(function_code == AC_FUNCTION_TEMPERATURE_DOWN /*&& FALSE == has_function(context, AC_FUNCTION_TEMPERATURE_DOWN)*/) + { + return IR_DECODE_FAILED; + } + } + } + else + { + // if this level is in black list, do not send IR wave if user want to apply this function + if(function_code == AC_FUNCTION_TEMPERATURE_UP /*&& FALSE == has_function(context, AC_FUNCTION_TEMPERATURE_UP)*/) + { + return IR_DECODE_FAILED; + } + else if(function_code == AC_FUNCTION_TEMPERATURE_DOWN /*&& FALSE == has_function(context, AC_FUNCTION_TEMPERATURE_DOWN)*/) + { + return IR_DECODE_FAILED; + } + } + } + else + { + // if this level is in black list, do not send IR wave if user want to apply this function + if(function_code == AC_FUNCTION_TEMPERATURE_UP /*&& FALSE == has_function(context, AC_FUNCTION_TEMPERATURE_UP)*/) + { + return IR_DECODE_FAILED; + } + else if(function_code == AC_FUNCTION_TEMPERATURE_DOWN /*&& FALSE == has_function(context, AC_FUNCTION_TEMPERATURE_DOWN)*/) + { + return IR_DECODE_FAILED; + } + } + return IR_DECODE_SUCCEEDED; +} + +UINT16 irda_ac_lib_control(remote_ac_status_t ac_status, UINT16 *user_data, UINT8 function_code, + UINT8 change_wind_direction) +{ + UINT16 time_length = 0; +#if (defined BOARD_PC)|| (defined BOARD_MT6580) + UINT8 i = 0; +#endif + +#if 0 + // prepare ac status to parameter array + UINT8 parameter_array[AC_APPLY_MAX] = + { + ac_status.acPower, + ac_status.acMode, + ac_status.acWindSpeed, + ac_status.acWindDir, + ac_status.acTemp, + function_code + }; +#endif + + if (0 == context->default_code.len) + { + IR_PRINTF("\ndefault code is empty\n"); + return 0; + } + + // pre-set change wind direction flag here + context->change_wind_direction = change_wind_direction; + + context->time = user_data; + + // generate temp buffer for frame calculation + irda_memcpy(ir_hex_code, context->default_code.data, context->default_code.len); + +#if defined USE_APPLY_TABLE + if(ac_status.acPower != AC_POWER_OFF) + { + for (i = AC_APPLY_POWER; i < AC_APPLY_MAX; i++) + { + apply_table[i](context, parameter_array[i]); + } + } +#else + if(ac_status.acPower == AC_POWER_OFF) + { + // otherwise, power should always be applied + apply_power(ac_status, function_code); + } + else + { + // check the mode as the first priority, despite any other status + if(TRUE == context->n_mode[ac_status.acMode].enable) + { + if (is_solo_function(function_code)) + { + // this key press function needs to send solo code + apply_table[function_code - 1](ac_status, function_code); + } + else + { + if(!is_solo_function(AC_FUNCTION_POWER)) + { + apply_power(ac_status, function_code); + } + + if(!is_solo_function(AC_FUNCTION_MODE)) + { + if (IR_DECODE_FAILED == apply_mode(ac_status, function_code)) + { + return 0; + } + } + + if(!is_solo_function(AC_FUNCTION_WIND_SPEED)) + { + if (IR_DECODE_FAILED == apply_wind_speed(ac_status, function_code)) + { + return 0; + } + } + + if(!is_solo_function(AC_FUNCTION_WIND_SWING) && + !is_solo_function(AC_FUNCTION_WIND_FIX)) + { + if (IR_DECODE_FAILED == apply_swing(ac_status, function_code)) + { + return 0; + } + } + + if(!is_solo_function(AC_FUNCTION_TEMPERATURE_UP) && + !is_solo_function(AC_FUNCTION_TEMPERATURE_DOWN)) + { + if (IR_DECODE_FAILED == apply_temperature(ac_status, function_code)) + { + return 0; + } + } + } + } + else + { + return 0; + } + } +#endif + apply_ac_function(context, function_code); + // checksum should always be applied + apply_checksum(context); + + // have some debug +#if (defined BOARD_PC)|| (defined BOARD_MT6580) + IR_PRINTF("==============================\n"); + for(i = 0; i < ir_hex_len; i++) + { + IR_PRINTF("[%02X] ", ir_hex_code[i]); + } + IR_PRINTF("\n"); +#endif +#if (defined BOARD_CC254X) && (PRINT_IRDA_DATA == TRUE) + NPI_PrintString("hex:\r\n"); + + for (UINT16 i = 0; i < context->default_code.len; i++) + { + NPI_PrintValue("", ir_hex_code[i], 16); + } + NPI_PrintString("\r\n"); +#endif + + time_length = create_ir_frame(); + + return time_length; +} + +void irda_ac_lib_close() +{ + // free context + if (NULL != tags) + { + irda_free(tags); + tags = NULL; + } + free_ac_context(); + return; +} + +// utils +INT8 get_temperature_range(UINT8 ac_mode, INT8* temp_min, INT8* temp_max) +{ + UINT8 i = 0; + + if (ac_mode >= AC_MODE_MAX) + { + return IR_DECODE_FAILED; + } + if (NULL == temp_min || NULL == temp_max) + { + return IR_DECODE_FAILED; + } + + if (1 == context->n_mode[ac_mode].alltemp) + { + *temp_min = *temp_max = -1; + return IR_DECODE_SUCCEEDED; + } + + *temp_min = -1; + *temp_max = -1; + for (i = 0; i < AC_TEMP_MAX; i++) + { + if(isin(context->n_mode[ac_mode].temp, i, context->n_mode[ac_mode].temp_cnt) || + (context->temp1.len != 0 && 0 == context->temp1.comp_data[i].seg_len) || + (context->temp2.len != 0 && 0 == context->temp2.comp_data[i].seg_len)) + { + continue; + } + if (-1 == *temp_min) + { + *temp_min = i; + } + if (-1 == *temp_max || i > *temp_max) + { + *temp_max = i; + } + } + return IR_DECODE_SUCCEEDED; +} + +INT8 get_supported_mode(UINT8* supported_mode) +{ + UINT8 i = 0; + if (NULL == supported_mode) + { + return IR_DECODE_FAILED; + } + *supported_mode = 0x1F; + + for (i = 0; i < AC_MODE_MAX; i++) + { + if (0 == context->n_mode[i].enable || + (context->mode1.len != 0 && 0 == context->mode1.comp_data[i].seg_len) || + (context->mode2.len != 0 && 0 == context->mode2.comp_data[i].seg_len)) + { + *supported_mode &= ~(1 << i); + } + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 get_supported_wind_speed(UINT8 ac_mode, UINT8* supported_wind_speed) +{ + UINT8 i = 0; + if (ac_mode >= AC_MODE_MAX) + { + return IR_DECODE_FAILED; + } + + if (NULL == supported_wind_speed) + { + return IR_DECODE_FAILED; + } + + if (1 == context->n_mode[ac_mode].allspeed) + { + *supported_wind_speed = 0; + return IR_DECODE_SUCCEEDED; + } + + *supported_wind_speed = 0x0F; + + for (i = 0; i < AC_WS_MAX; i++) + { + if (isin(context->n_mode[ac_mode].speed, i, context->n_mode[ac_mode].speed_cnt) || + (context->speed1.len != 0 && 0 == context->speed1.comp_data[i].seg_len) || + (context->speed2.len != 0 && 0 == context->speed2.comp_data[i].seg_len)) + { + *supported_wind_speed &= ~(1 << i); + } + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 get_supported_swing(UINT8 ac_mode, UINT8* supported_swing) +{ + if (ac_mode >= AC_MODE_MAX) + { + return IR_DECODE_FAILED; + } + + if (NULL == supported_swing) + { + return IR_DECODE_FAILED; + } + + if (context->si.type == SWING_TYPE_NORMAL) + { + *supported_swing = 0x03; + } + else if (context->si.type == SWING_TYPE_SWING_ONLY) + { + *supported_swing = 0x02; + } + else if (context->si.type == SWING_TYPE_NOT_SPECIFIED) + { + *supported_swing = 0x00; + } + else + { + *supported_swing = 0x01; + } + return IR_DECODE_SUCCEEDED; +} + +INT8 get_supported_wind_direction(UINT8* supported_wind_direction) +{ + if (NULL != context) + { + *supported_wind_direction = context->si.mode_count - 1; + return IR_DECODE_SUCCEEDED; + } + else + { + return IR_DECODE_FAILED; + } +} + +///////////////////////////////////////////////// Air Conditioner End ///////////////////////////////////////////////// + +///////////////////////////////////////////////// TV Begin ///////////////////////////////////////////////// + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +INT8 binary_tv_open(const char *file) +{ + int print_index = 0; + FILE *stream = fopen(file, "rb"); + + IR_PRINTF("file name = %s\n", file); + + if (stream == NULL) + { + IR_PRINTF("\nfile open failed : %d\n", errno); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_END); + tv_bin_length = ftell(stream); + + IR_PRINTF("length of binary = %d\n", tv_bin_length); + + fseek(stream, 0, SEEK_SET); + fread(tv_bin, tv_bin_length, 1, stream); + fclose(stream); + + // have some debug + IR_PRINTF("=============================\n"); + // IR_PRINTF("length of binary = %d\n", tv_bin_length); + for(print_index = 0; print_index < tv_bin_length; print_index++) + { + IR_PRINTF("%02X ", tv_bin[print_index]); + } + IR_PRINTF("\n=============================\n"); + irda_lib_open(tv_bin, tv_bin_length); + return IR_DECODE_SUCCEEDED; +} +#endif + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +INT8 irda_tv_lib_open(const char *file_name) +{ + return binary_tv_open(file_name); +} +#else +INT8 irda_tv_lib_open(UINT8 *binary_file, UINT16 binary_length) +{ + irda_lib_open(binary_file, binary_length); + return IR_DECODE_SUCCEEDED; +} +#endif + +#if (defined BOARD_PC)|| (defined BOARD_MT6580) +INT8 irda_tv_lib_parse(UINT8 irda_hex_encode) +{ + if (FALSE == irda_lib_parse(irda_hex_encode)) + { + IR_PRINTF("parse irda binary failed\n"); + memset(tv_bin, 0x00, EXPECTED_MEM_SIZE); + tv_bin_length = 0; + return IR_DECODE_FAILED; + } + IR_PRINTF("parse irda binary successfully\n"); + return IR_DECODE_SUCCEEDED; +} + +UINT16 irda_tv_lib_control(UINT8 key, UINT16* l_user_data) +{ + UINT16 print_index = 0; + UINT16 irda_code_length = 0; + memset(user_data, 0x00, USER_DATA_SIZE); + irda_code_length = irda_lib_control(key, l_user_data); + + // have some debug + IR_PRINTF("=============================\n"); + IR_PRINTF("length of IRDA code = %d\n", irda_code_length); + for(print_index = 0; print_index < irda_code_length; print_index++) + { + IR_PRINTF("%d ", user_data[print_index]); + } + IR_PRINTF("\n=============================\n\n"); + + return irda_code_length; +} + +UINT16 irda_tv_lib_close() +{ + // no need to close tv binary +} +#endif + +///////////////////////////////////////////////// TV End ///////////////////////////////////////////////// + +///////////////////////////////////////////////// BLE Central Begin ///////////////////////////////////////////////// + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +INT8 binary_ble_open(const char *file) +{ + FILE *stream = fopen(file, "rb"); + if (stream == NULL) + { + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_END); + pirda_buffer->len = ftell(stream); + + fseek(stream, 0, SEEK_SET); + fread(pirda_buffer->data, pirda_buffer->len, 1, stream); + fclose(stream); + + return IR_DECODE_SUCCEEDED; +} +#endif + +INT8 binary_bc_parse_offset() +{ + int i = 0; + UINT16 *phead = (UINT16 *) &pirda_buffer->data[1]; + + tag_count = pirda_buffer->data[0]; + if(TAG_COUNT_FOR_BC_PROTOCOL != tag_count) + { + return IR_DECODE_FAILED; + } + + tag_head_offset = (tag_count << 1) + 1; + + tags = (t_tag_head *) irda_malloc(tag_count * sizeof(t_tag_head)); + if (NULL == tags) + { + return IR_DECODE_FAILED; + } + + for (i = 0; i < tag_count; i++) + { + tags[i].tag = bc_tag_index[i]; + tags[i].offset = *(phead + i); + if (tags[i].offset == TAG_INVALID) + { + tags[i].len = 0; + } + } + return IR_DECODE_SUCCEEDED; +} + +// might be merged with function binary_parse_len +INT8 binary_bc_parse_len() +{ + UINT16 i = 0, j = 0; + for (i = 0; i < (tag_count - 1); i++) + { + if (tags[i].offset == TAG_INVALID) + { + continue; + } + + for (j = (i + 1); j < tag_count; j++) + { + if (tags[j].offset != TAG_INVALID) + { + break; + } + } + if (j < tag_count) + { + tags[i].len = tags[j].offset - tags[i].offset; + } + else + { + tags[i].len = pirda_buffer->len - tags[i].offset - tag_head_offset; + return IR_DECODE_SUCCEEDED; + } + } + if (tags[tag_count - 1].offset != TAG_INVALID) + { + tags[tag_count - 1].len = pirda_buffer->len - tag_head_offset - tags[tag_count - 1].offset; + } + + return IR_DECODE_SUCCEEDED; +} + +// might be merged with function binary_parse_data +INT8 binary_bc_parse_data() +{ + UINT16 i = 0; + for (i = 0; i < tag_count; i++) + { + tags[i].pdata = pirda_buffer->data + tags[i].offset + tag_head_offset; + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 free_bc_context() +{ + UINT8 i = 0; + + if (NULL != context_bc->device_name) + { + irda_free(context_bc->device_name); + context_bc->device_name = NULL; + } + + if (NULL != context_bc->conn_ack.commands) + { + irda_free(context_bc->conn_ack.commands); + context_bc->conn_ack.commands = NULL; + } + context_bc->conn_ack.seg_count = 0; + + for (i = 0; i < KEY_COUNT; i++) + { + if (NULL != context_bc->generic_command[i].commands) + { + irda_free(context_bc->generic_command[i].commands); + context_bc->generic_command[i].commands = NULL; + } + context_bc->generic_command[i].seg_count = 0; + } + return IR_DECODE_SUCCEEDED; +} + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +INT8 bc_lib_open(const char *file_name) +{ + return binary_ble_open(file_name); +} +#else +INT8 bc_lib_open(UINT8 *binary_file, UINT16 binary_length) +{ + // load bin to buffer + pirda_buffer->data = binary_file; + pirda_buffer->len = binary_length; + pirda_buffer->offset = 0; + return IR_DECODE_SUCCEEDED; +} +#endif + +INT8 bc_context_init() +{ + irda_memset(context_bc, 0, sizeof(t_bc_protocol)); + return IR_DECODE_SUCCEEDED; +} + +INT8 bc_lib_parse() +{ + UINT16 i = 0; + // suggest not to call init function here for de-couple purpose +#if defined BOARD_CC254X + bc_context_init(); +#endif + if (IR_DECODE_FAILED == binary_bc_parse_offset()) + { + return IR_DECODE_FAILED; + } + + if (IR_DECODE_FAILED == binary_bc_parse_len()) + { + return IR_DECODE_FAILED; + } + + if (IR_DECODE_FAILED == binary_bc_parse_data()) + { + return IR_DECODE_FAILED; + } + +#if (defined BOARD_PC)|| (defined BOARD_MT6580) + binary_tags_info(); +#endif + + // parse tags + for (i = 0; i < tag_count; i++) + { + if (tags[i].len == 0) + { + continue; + } + if (tags[i].tag == TAG_BC_BLE_NAME) + { + context_bc->device_name = (char*)irda_malloc(tags[i].len + 1); + irda_memset(context_bc->device_name, 0x00, tags[i].len + 1); + if (IR_DECODE_FAILED == parse_ble_name(tags[i].pdata, tags[i].len, context_bc->device_name)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_BC_NEED_CONN_ACK) + { + if (IR_DECODE_FAILED == parse_ble_need_conn_ack(tags[i].pdata, &context_bc->need_connection_ack)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_BC_NAME_LENGTH) + { + if (IR_DECODE_FAILED == parse_ble_name_length(tags[i].pdata, &context_bc->name_length)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_BC_NAME_ESS_LENGTH) + { + if (IR_DECODE_FAILED == parse_ble_name_essential_length(tags[i].pdata, &context_bc->name_essential_length)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_BC_CONN_ACK_CMD) + { + if (IR_DECODE_FAILED == parse_ble_commands(&tags[i], + &context_bc->conn_ack)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag >= TAG_BC_KEY_0_CMD && tags[i].tag <= TAG_BC_KEY_14_CMD) + { + if (IR_DECODE_FAILED == parse_ble_commands(&tags[i], + &context_bc->generic_command[tags[i].tag - TAG_BC_KEY_0_CMD])) + { + return IR_DECODE_FAILED; + } + } + } + +#if (defined BOARD_PC)|| (defined BOARD_MT6580) + IR_PRINTF("\n=====================================\n"); + { + IR_PRINTF("\n"); + IR_PRINTF("device name = %s\n", context_bc->device_name); + IR_PRINTF("need ack per connected = %d\n", context_bc->need_connection_ack); + IR_PRINTF("length of name = %d\n", context_bc->name_length); + IR_PRINTF("essential length of name = %d\n", context_bc->name_essential_length); + IR_PRINTF("conn ack segment count = %d\n", context_bc->conn_ack.seg_count); + }; + IR_PRINTF("\n=====================================\n"); +#endif + + if(NULL != tags) + { + irda_free(tags); + tags = NULL; + } + + return IR_DECODE_SUCCEEDED; +} + +UINT16 bc_lib_control(int key_code, t_bc_commands* bc_commands) +{ +#if (defined BOARD_PC)|| (defined BOARD_MT6580) + UINT8 seg_index = 0; + UINT8 i = 0; + t_bc_commands key_command = context_bc->generic_command[key_code]; + + for (seg_index = 0; seg_index < key_command.seg_count; seg_index++) + { + IR_PRINTF("send %d bytes of command with handle 0x%04X\n", + key_command.commands[seg_index].length, + key_command.commands[seg_index].handle); + for(i = 0; i < key_command.commands[seg_index].length; i++) + { + IR_PRINTF("[%02X] ", key_command.commands[seg_index].command[i]); + } + } + + IR_PRINTF("\n"); + return 0; +#else + if (NULL == bc_commands) + { + return IR_DECODE_FAILED; + } + // CC254X would load some data from flash to complete this procedure + // TODO: + + return IR_DECODE_SUCCEEDED; +#endif +} + +void bc_lib_close() +{ + if (NULL != tags) + { + irda_free(tags); + tags = NULL; + } + // free context + free_bc_context(); + return; +} + +// utils +int get_valid_keys(int *valid_keys) +{ + int i = 0; + for (i = 0; i < KEY_COUNT; i++) + { + if (context_bc->generic_command[i].seg_count != 0) + { + valid_keys[i] = 1; + } + else + { + valid_keys[i] = 0; + } + } + return KEY_COUNT; +} +///////////////////////////////////////////////// BLE Central End ///////////////////////////////////////////////// + +///////////////////////////////////////////////// Decode Test Begin ///////////////////////////////////////////////// +#if (defined BOARD_PC) || (defined BOARD_MT6580) + +UINT8 decode_as_ac(char *file_name) +{ + // keyboard input + int in_char = 0; + int count = 0; + BOOL op_match = TRUE; + UINT8 function_code = AC_FUNCTION_MAX; + + // get status + UINT8 supported_mode = 0x00; + UINT8 min_temperature = 0; + UINT8 max_temperature = 0; + UINT8 supported_speed = 0x00; + UINT8 supported_swing = 0x00; + + BOOL need_control = TRUE; + + // init air conditioner status + ac_status.acDisplay = 0; + ac_status.acSleep = 0; + ac_status.acTimer = 0; + ac_status.acPower = AC_POWER_OFF; + ac_status.acMode = AC_MODE_COOL; + ac_status.acTemp = AC_TEMP_20; + ac_status.acWindDir = AC_SWING_ON; + ac_status.acWindSpeed = AC_WS_AUTO; + + if (IR_DECODE_FAILED == irda_ac_lib_open(file_name)) + { + irda_ac_lib_close(); + return IR_DECODE_FAILED; + } + + // no need to verify return value + irda_context_init(); + + if (IR_DECODE_FAILED == irda_ac_lib_parse()) + { + IR_PRINTF("\nac lib parse failed\n"); + irda_ac_lib_close(); + return IR_DECODE_FAILED; + } + do + { + in_char = getchar(); + op_match = TRUE; + need_control = TRUE; + switch(in_char) + { + case 'w': + case 'W': + // temperature plus + ac_status.acTemp = (ac_status.acTemp == AC_TEMP_30) ? AC_TEMP_30 : (ac_status.acTemp + 1); + function_code = AC_FUNCTION_TEMPERATURE_UP; + break; + case 's': + case 'S': + ac_status.acTemp = (ac_status.acTemp == AC_TEMP_16) ? AC_TEMP_16 : (ac_status.acTemp - 1); + function_code = AC_FUNCTION_TEMPERATURE_DOWN; + // temperature minus + break; + case 'a': + case 'A': + ++ac_status.acWindSpeed; + ac_status.acWindSpeed = ac_status.acWindSpeed % AC_WS_MAX; + function_code = AC_FUNCTION_WIND_SPEED; + // wind speed loop + break; + case 'd': + case 'D': + ac_status.acWindDir = (ac_status.acWindDir == 0) ? 1 : 0; + function_code = AC_FUNCTION_WIND_SWING; + // wind swing loop + break; + case 'q': + case 'Q': + ++ac_status.acMode; + ac_status.acMode = ac_status.acMode % AC_MODE_MAX; + function_code = AC_FUNCTION_MODE; + break; + case '1': + // turn on + ac_status.acPower = AC_POWER_ON; + function_code = AC_FUNCTION_POWER; + break; + case '2': + // turn off + ac_status.acPower = AC_POWER_OFF; + // FUNCTION MAX refers to power off + // function_code = AC_FUNCTION_POWER; + break; + case '3': + if (IR_DECODE_SUCCEEDED == get_supported_mode(&supported_mode)) + { + IR_PRINTF("\nsupported mode = %02X\n", supported_mode); + } + need_control = FALSE; + break; + + case '4': + if (IR_DECODE_SUCCEEDED == get_supported_swing(ac_status.acMode, &supported_swing)) + { + IR_PRINTF("\nsupported swing in %d = %02X\n", ac_status.acMode, supported_swing); + } + need_control = FALSE; + break; + case '5': + if (IR_DECODE_SUCCEEDED == get_supported_wind_speed(ac_status.acMode, &supported_speed)) + { + IR_PRINTF("\nsupported wind speed in %d = %02X\n", ac_status.acMode, supported_speed); + } + need_control = FALSE; + break; + + case '6': + if (IR_DECODE_SUCCEEDED == get_temperature_range(ac_status.acMode, &min_temperature, &max_temperature)) + { + IR_PRINTF("\nsupported temperature range in mode %d = %d, %d\n", ac_status.acMode, min_temperature, max_temperature); + } + need_control = FALSE; + break; + + default: + op_match = FALSE; + break; + } + + if(TRUE == op_match && TRUE == need_control) + { + IR_PRINTF("switch AC to power = %d, mode = %d, temp = %d, speed = %d, swing = %d\n", + ac_status.acPower, + ac_status.acMode, + ac_status.acTemp, + ac_status.acWindSpeed, + ac_status.acWindDir + ); + + irda_ac_lib_control(ac_status, user_data, function_code, TRUE); + } + } while('0' != in_char); + + irda_ac_lib_close(); + + return IR_DECODE_SUCCEEDED; +} + +UINT8 decode_as_tv(char *file_name, UINT8 irda_hex_encode) +{ + // keyboard input + int in_char = 0; + int key_code = -1; + int count = 0; + + if (IR_DECODE_FAILED == irda_tv_lib_open(file_name)) + { + return IR_DECODE_FAILED; + } + + if (IR_DECODE_FAILED == irda_tv_lib_parse(irda_hex_encode)) + { + return IR_DECODE_FAILED; + } + do + { + in_char = getchar(); + if (in_char >= '0' && in_char <= '9') + { + key_code = in_char - '0'; + irda_tv_lib_control(key_code, user_data); + } + else if (in_char >= 'a' && in_char <= 'f') + { + key_code = 10 + (in_char - 'a'); + irda_tv_lib_control(key_code, user_data); + } + else if (in_char == 'q') + { + irda_tv_lib_close(); + } + else + { + // do nothing + } + } while('Q' != in_char); + + return IR_DECODE_SUCCEEDED; +} + +UINT8 decode_as_ble_central(char *file_name) +{ + // keyboard input + int in_char = 0; + int count = 0; + int key_code = -1; + BOOL op_match = TRUE; + + if (IR_DECODE_FAILED == bc_lib_open(file_name)) + { + bc_lib_close(); + return IR_DECODE_FAILED; + } + + // no need to verify return value + bc_context_init(); + + if (IR_DECODE_FAILED == bc_lib_parse()) + { + bc_lib_close(); + return IR_DECODE_FAILED; + } + do + { + in_char = getchar(); + if (in_char >= '0' && in_char <= '9') + { + key_code = in_char - '0'; + bc_lib_control(key_code, NULL); + } + else if (in_char >= 'a' && in_char <= 'f') + { + key_code = 10 + (in_char - 'a'); + bc_lib_control(key_code, NULL); + } + else + { + // do nothing + } + } while('Q' != in_char); + + bc_lib_close(); + + return IR_DECODE_SUCCEEDED; +} + +#endif + +#if defined BOARD_PC + +int main(int argc, char *argv[]) +{ + char function = '0'; + UINT8 irda_hex_encode = 0; + + if (4 != argc) + { + IR_PRINTF("number of args error !\n"); + return -1; + } + + function = argv[1][0]; + irda_hex_encode = (UINT8)(argv[3][0] - '0'); + IR_PRINTF("decode functionality = %c\n", function); + + switch (function) + { + case '0': + IR_PRINTF("decode binary file as AC\n"); + decode_as_ac(argv[2]); + break; + + case '1': + IR_PRINTF("decode binary file as TV : %d\n", irda_hex_encode); + decode_as_tv(argv[2], irda_hex_encode); + break; + + case '2': + IR_PRINTF("decode binary file as BLE CENTRAL\n"); + decode_as_ble_central(argv[2]); + break; + + default: + IR_PRINTF("decode functionality error !\n"); + break; + } +} + +#endif + +///////////////////////////////////////////////// Decode Test End ///////////////////////////////////////////////// \ No newline at end of file diff --git a/src/ir_decoder/ucon_decode.h b/src/ir_decoder/ucon_decode.h new file mode 100644 index 0000000..53a7453 --- /dev/null +++ b/src/ir_decoder/ucon_decode.h @@ -0,0 +1,779 @@ +/************************************************************************************************** +Filename: ucon_decode.h +Revised: Date: 2015-08-01 +Revision: Revision: 1.0 + +Description: This file provides algorithms for UCON IR decode + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2015-08-01: created by strawmanbobi +**************************************************************************************************/ +#ifndef _IRDA_DECODE_H_ +#define _IRDA_DECODE_H_ + +#include +#include "irda_defs.h" + +#if defined BOARD_CC2541 +#include "osal.h" +#include "ucon_remote.h" +#endif +#if defined BOARD_MC200 +#include "wmstdio.h" +#include "wm_os.h" +#endif + +#define TAG_COUNT_FOR_PROTOCOL 29 +#define TAG_COUNT_FOR_BC_PROTOCOL 20 + +#if defined BOARD_CC254X + +#define KEY_COUNT 15 + +#elif (defined BOARD_PC) || (defined BOARD_MT6580) + +#define KEY_COUNT 15 + +#else + +#define KEY_COUNT 15 + +#endif + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +#define EXPECTED_MEM_SIZE 1024 +#endif + +#define TAG_INVALID 0xffff +#define MAX_DELAYCODE_NUM 16 +#define MAX_BITNUM 16 + +#define IR_DECODE_FAILED (-1) +#define IR_DECODE_SUCCEEDED (0) + +#define AC_PARAMETER_TYPE_1 0 +#define AC_PARAMETER_TYPE_2 1 + +#define BLE_GAP_MTU 20 +#define BLE_UUID_SIZE 16 +#define BLE_UUID_STRING_SIZE 32 +#define BLE_UUID_STRING_SIZE_MAX 36 + +typedef enum +{ + AC_POWER_ON = 0, + AC_POWER_OFF, + AC_POWER_MAX +} ac_power; + +typedef enum +{ + AC_TEMP_16 = 0, + AC_TEMP_17, + AC_TEMP_18, + AC_TEMP_19, + AC_TEMP_20, + AC_TEMP_21, + AC_TEMP_22, + AC_TEMP_23, + AC_TEMP_24, + AC_TEMP_25, + AC_TEMP_26, + AC_TEMP_27, + AC_TEMP_28, + AC_TEMP_29, + AC_TEMP_30, + AC_TEMP_MAX +} ac_temperature; + +typedef enum +{ + AC_MODE_COOL = 0, + AC_MODE_HEAT, + AC_MODE_AUTO, + AC_MODE_FAN, + AC_MODE_DRY, + AC_MODE_MAX +} ac_mode; + +typedef enum +{ + AC_FUNCTION_POWER = 1, + AC_FUNCTION_MODE, + AC_FUNCTION_TEMPERATURE_UP, + AC_FUNCTION_TEMPERATURE_DOWN, + AC_FUNCTION_WIND_SPEED, + AC_FUNCTION_WIND_SWING, + AC_FUNCTION_WIND_FIX, + AC_FUNCTION_MAX, +} ac_function; + +typedef enum +{ + AC_WS_AUTO = 0, + AC_WS_LOW, + AC_WS_MEDIUM, + AC_WS_HIGH, + AC_WS_MAX +} ac_wind_speed; + +typedef enum +{ + AC_SWING_ON = 0, + AC_SWING_OFF, + AC_SWING_MAX +} ac_swing; + +typedef enum +{ + SWING_TYPE_SWING_ONLY = 0, + SWING_TYPE_NORMAL, + SWING_TYPE_NOT_SPECIFIED, + SWING_TYPE_MAX +} swing_type; + +typedef enum +{ + TEMP_TYPE_DYNAMIC = 0, + TEMP_TYPE_STATIC, + TEMP_TYPE_MAX, +} temp_type; + +// enumeration for application polymorphism +typedef enum +{ + AC_APPLY_POWER = 0, + AC_APPLY_MODE, + AC_APPLY_TEMPERATURE_UP, + AC_APPLY_TEMPERATURE_DOWN, + AC_APPLY_WIND_SPEED, + AC_APPLY_WIND_SWING, + AC_APPLY_WIND_FIX, + AC_APPLY_MAX +} ac_apply; + +typedef struct _ac_hex +{ + UINT8 len; + UINT8 *data; +} ac_hex; + +typedef struct _ac_level +{ + UINT16 low; + UINT16 high; +} ac_level; + +typedef struct _ac_bootcode +{ + UINT16 len; + UINT16 data[16]; +} ac_bootcode; + +typedef struct _ac_delaycode +{ + INT16 pos; + UINT16 time[8]; + UINT16 time_cnt; +} ac_delaycode; + +/* + * the array of tag_100X application data + * seg_len : length for each segment + * byte_pos : the position of update byte + * byte_value : the value to be updated to position + */ +typedef struct _tag_comp_type_1 +{ + UINT8 seg_len; + UINT8 *segment; +} tag_comp; + +typedef struct _tag_1506_swing_info +{ + swing_type type; + UINT8 mode_count; + UINT8 dir_index; +} swing_info; + +typedef struct _tag_1001_power_1 +{ + UINT8 len; + tag_comp comp_data[AC_POWER_MAX]; +} power_1; + +typedef struct _tag_1003_temp_1 +{ + UINT8 len; + UINT8 type; + tag_comp comp_data[AC_TEMP_MAX]; +} temp_1; + +typedef struct tag_1004_mode_1 +{ + UINT8 len; + tag_comp comp_data[AC_MODE_MAX]; +} mode_1; + +typedef struct tag_1005_speed_1 +{ + UINT8 len; + tag_comp comp_data[AC_WS_MAX]; +} speed_1; + +typedef struct tag_1007_swing_1 +{ + UINT8 len; + UINT16 count; + tag_comp *comp_data; +} swing_1; + +typedef struct tag_1011_temp_2 +{ + UINT8 len; + UINT8 type; + tag_comp comp_data[AC_TEMP_MAX]; +} temp_2; + +typedef struct tag_1012_mode_2 +{ + UINT8 len; + tag_comp comp_data[AC_MODE_MAX]; +} mode_2; + +typedef struct tag_1013_speed_2 +{ + UINT8 len; + tag_comp comp_data[AC_WS_MAX]; +} speed_2; + +typedef struct tag_1015_swing_2 +{ + UINT8 len; + UINT16 count; + tag_comp *comp_data; +} swing_2; + +#if defined SUPPORT_HORIZONTAL_SWING +typedef struct tag_1006_horiswing_1 +{ + UINT16 len; + tag_comp comp_data[AC_HORI_SWING_MAX]; +} hori_swing_1; +#endif + +/* modified by xiangjiang 2015-11-20 - begin - */ +typedef struct _tag_checksum_data +{ + UINT8 len; + UINT8 type; + UINT8 start_byte_pos; + UINT8 end_byte_pos; + UINT8 checksum_byte_pos; + UINT8 checksum_plus; + UINT8 *spec_pos; +} tag_checksum_data; + +typedef struct tag_checksum +{ + UINT8 len; + UINT16 count; + tag_checksum_data *checksum_data; +} tchecksum; +/* modified by xiangjiang 2015-11-20 - end - */ + +typedef struct tag_function_1 +{ + UINT8 len; + tag_comp comp_data[AC_FUNCTION_MAX - 1]; +} function_1; + +typedef struct tag_function_2 +{ + UINT8 len; + tag_comp comp_data[AC_FUNCTION_MAX - 1]; +} function_2; + +typedef struct tag_solo_code +{ + UINT8 len; + UINT8 solo_func_count; + UINT8 solo_function_codes[AC_FUNCTION_MAX - 1]; +} solo_code; + +typedef struct _ac_bitnum +{ + INT16 pos; + UINT16 bits; +} ac_bitnum; + +typedef enum +{ + N_COOL = 0, + N_HEAT, + N_AUTO, + N_FAN, + N_DRY, + N_MODE_MAX, +} ac_n_mode; + +typedef enum +{ + CHECKSUM_TYPE_BYTE = 1, + CHECKSUM_TYPE_BYTE_INVERSE, + CHECKSUM_TYPE_HALF_BYTE, + CHECKSUM_TYPE_HALF_BYTE_INVERSE, + CHECKSUM_TYPE_SPEC_HALF_BYTE, + CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE, + CHECKSUM_TYPE_SPEC_HALF_BYTE_ONE_BYTE, + CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE_ONE_BYTE, + CHECKSUM_TYPE_MAX, +} checksum_type; + +typedef struct _ac_n_mode_info +{ + UINT8 enable; + UINT8 allspeed; + UINT8 alltemp; + UINT8 temp[AC_TEMP_MAX]; + UINT8 temp_cnt; + UINT8 speed[AC_WS_MAX]; + UINT8 speed_cnt; +} ac_n_mode_info; + +typedef struct ac_protocol +{ + UINT8 endian; + // ac_hex default_code; + ac_hex default_code; + ac_level zero; + ac_level one; + ac_bootcode bootcode; + ac_delaycode dc[MAX_DELAYCODE_NUM]; + power_1 power1; + temp_1 temp1; + mode_1 mode1; + speed_1 speed1; + swing_1 swing1; + tchecksum checksum; + + function_1 function1; + function_2 function2; + + temp_2 temp2; + mode_2 mode2; + speed_2 speed2; + swing_2 swing2; + + swing_info si; + solo_code sc; + + UINT8 swing_status; + + BOOL change_wind_direction; + + UINT16 dc_cnt; + ac_bitnum bitnum[MAX_BITNUM]; + UINT16 bitnum_cnt; + UINT16 repeat_times; + UINT16 frame_length; + ac_n_mode_info n_mode[N_MODE_MAX]; + UINT16 code_cnt; + UINT8 lastbit; + UINT16 *time; + UINT8 solo_function_mark; +} protocol; + +#if defined BOARD_MC200 +#pragma pack(1) +#endif +typedef struct bc_command +{ + UINT8 length; + UINT16 handle; + UINT8 command[BLE_GAP_MTU]; +} t_bc_command; +#if defined BOARD_MC200 +#pragma pack() +#endif + +typedef struct bc_commands +{ + UINT8 seg_count; + t_bc_command *commands; +} t_bc_commands; + +typedef struct bc_protocol +{ + // would save device_name within 20 bytes to flash + char *device_name; + // would save need_connection_ack of 1 byte to flash + UINT8 need_connection_ack; + // would save name essential length of 1 bytes to flash + UINT8 name_essential_length; + // would save name length of 2 byte to flash + UINT8 name_length; + + // would save generic_command of 4 x 20 bytes to flash with segment length tag + t_bc_commands conn_ack; + t_bc_commands generic_command[KEY_COUNT]; +} t_bc_protocol; + +typedef struct tag_head +{ + UINT16 tag; + UINT16 len; + unsigned short offset; + UINT8 *pdata; +} t_tag_head; + +#if (defined BOARD_PC) || (defined BOARD_MT6580) +struct ir_bin_buffer +{ + UINT8 data[EXPECTED_MEM_SIZE]; + UINT16 len; + UINT16 offset; +}; +#else +struct ir_bin_buffer +{ + UINT8 *data; + UINT16 len; + UINT16 offset; +}; +#endif + +typedef struct REMOTE_AC_STATUS +{ + UINT8 acPower; + UINT8 acTemp; + UINT8 acMode; + UINT8 acWindDir; + UINT8 acWindSpeed; + UINT8 acDisplay; + UINT8 acSleep; + UINT8 acTimer; +} remote_ac_status_t; + +// function polymorhism +typedef INT8 (*lp_apply_ac_parameter) (remote_ac_status_t ac_status, UINT8 function_code); + +#define TAG_AC_POWER_1 1001 +#define TAG_AC_DEFAULT_CODE 1002 +#define TAG_AC_TEMP_1 1003 +#define TAG_AC_MODE_1 1004 +#define TAG_AC_SPEED_1 1005 +#define TAG_AC_SWING_1 1007 + +#define TAG_AC_CHECKSUM_TYPE 1008 + +#define TAG_AC_TEMP_2 1011 +#define TAG_AC_MODE_2 1012 +#define TAG_AC_SPEED_2 1013 +#define TAG_AC_SWING_2 1015 + +#define TAG_AC_SOLO_FUNCTION 1009 + +#define TAG_AC_FUNCTION_1 1010 +#define TAG_AC_FUNCTION_2 1016 + +#define TAG_AC_SWING_INFO 1506 + +#define TAG_AC_BOOT_CODE 300 +#define TAG_AC_ZERO 301 +#define TAG_AC_ONE 302 +#define TAG_AC_DELAY_CODE 303 +#define TAG_AC_FRAME_LENGTH 304 +#define TAG_AC_REPEAT_TIMES 1508 +#define TAG_AC_BITNUM 1509 + +#define TAG_AC_ENDIAN 306 +#define TAG_AC_LASTBIT 307 + +#define TAG_AC_BAN_FUNCTION_IN_COOL_MODE 1501 +#define TAG_AC_BAN_FUNCTION_IN_HEAT_MODE 1502 +#define TAG_AC_BAN_FUNCTION_IN_AUTO_MODE 1503 +#define TAG_AC_BAN_FUNCTION_IN_FAN_MODE 1504 +#define TAG_AC_BAN_FUNCTION_IN_DRY_MODE 1505 + +//////////////// TAGS FOR BLE CENTRAL ////////////////// +#define TAG_BC_BLE_NAME 100 +#define TAG_BC_NEED_CONN_ACK 101 +#define TAG_BC_NAME_LENGTH 102 +#define TAG_BC_NAME_ESS_LENGTH 103 + +#define TAG_BC_CONN_ACK_CMD 300 + +#define TAG_BC_KEY_0_CMD 200 +#define TAG_BC_KEY_1_CMD 201 +#define TAG_BC_KEY_2_CMD 202 +#define TAG_BC_KEY_3_CMD 203 +#define TAG_BC_KEY_4_CMD 204 +#define TAG_BC_KEY_5_CMD 205 +#define TAG_BC_KEY_6_CMD 206 +#define TAG_BC_KEY_7_CMD 207 +#define TAG_BC_KEY_8_CMD 208 +#define TAG_BC_KEY_9_CMD 209 +#define TAG_BC_KEY_10_CMD 210 +#define TAG_BC_KEY_11_CMD 211 +#define TAG_BC_KEY_12_CMD 212 +#define TAG_BC_KEY_13_CMD 213 +#define TAG_BC_KEY_14_CMD 214 + +// definition about size +#if (defined BOARD_PC) || (defined BOARD_MT6580) +#define PROTOCOL_SIZE (sizeof(protocol)) +#define BC_PROTOCOL_SIZE (sizeof(t_bc_protocol)) +#elif defined BOARD_CC254X +#define PROTOCOL_SIZE 850 +#define BC_PROTOCOL_SIZE (sizeof(t_bc_protocol)) +#elif defined BOARD_MC200 +#define PROTOCOL_SIZE (sizeof(protocol)) //1168 +#define BC_PROTOCOL_SIZE (sizeof(t_bc_protocol)) +#else +#define PROTOCOL_SIZE 0 +#define BC_PROTOCOL_SIZE 0 +#endif + +/* exported variables */ +extern UINT8* ir_hex_code; +extern UINT8 ir_hex_len; +extern protocol* context; +extern t_bc_protocol* context_bc; +extern remote_ac_status_t ac_status; + +/* exported functions */ +///////////////////////////////////////////////// AC Begin ///////////////////////////////////////////////// +/* + * function irda_context_init + * + * parameters: + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 irda_context_init(); + +/* + * function irda_ac_lib_open + * + * parameters: file_name (in, for PC and MT6580) specified bin file path + * binary_file (in, for CC2541 and MC200) specified file content of bin + * binary_length (in, for CC2541 and MC200) length of binary file content + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +#if (defined BOARD_PC) || (defined BOARD_MT6580) +extern UINT16 user_data[]; +extern INT8 irda_ac_lib_open(const char *file_name); +#else +extern INT8 irda_ac_lib_open(UINT8 *binary_file, UINT16 binary_length); +#endif + +/* + * function irda_ac_lib_parse + * + * parameters: + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 irda_ac_lib_parse(); + +/* + * function irda_ac_lib_control + * + * parameters: ac_status (in) indicates the current status of air conditioner to be controlled + * user_data (out) wave code array to be transmitted + * function_code (in) indicates the AC function to be updated + * change_wind_direction (in) indicates if the wind direction need to be changed + * + * return: length of wave code array + */ +extern UINT16 irda_ac_lib_control(remote_ac_status_t ac_status, UINT16 *user_data, UINT8 function_code, + BOOL change_wind_direction); + +/* + * function irda_ac_lib_close + * + * parameters: + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern void irda_ac_lib_close(); +///////////////////////////////////////////////// AC End ///////////////////////////////////////////////// + +///////////////////////////////////////////////// TV Begin ///////////////////////////////////////////////// +#if (defined BOARD_PC) || (defined BOARD_MT6580) +/* + * function irda_tv_lib_open + * + * parameters: file_name (in, for PC and MT6580) specified bin file path + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 irda_tv_lib_open(const char *file_name); + +/* + * function irda_tv_lib_parse + * + * parameters: + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 irda_tv_lib_parse(UINT8 irda_hex_encode); + +/* + * function irda_tv_lib_control + * + * parameters: key_code (in) indicates the number of pressed key + * user_data (out) wave code array to be transmitted + * + * return: length of wave code array + */ +extern UINT16 irda_tv_lib_control(UINT8 key_code, UINT16 * l_user_data); +#endif +///////////////////////////////////////////////// TV End ///////////////////////////////////////////////// + +///////////////////////////////////////////////// BLE Central Begin ///////////////////////////////////////////////// +/* + * function bc_context_init + * + * parameters: + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 bc_context_init(); + +/* + * function bc_lib_open + * + * parameters: file_name (in, for PC and MT6580) specified bin file path + * binary_file (in, for CC2541 and MC200) specified file content of bin + * binary_length (in, for CC2541 and MC200) length of binary file content + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +#if (defined BOARD_PC) || (defined BOARD_MT6580) +extern INT8 bc_lib_open(const char *file_name); +#else +extern INT8 bc_lib_open(UINT8 *binary_file, UINT16 binary_length); +#endif + +/* + * function bc_lib_parse + * + * parameters: + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 bc_lib_parse(); + +/* + * function bc_lib_parse + * + * parameters: + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ + +/* + * function bc_lib_control + * + * parameters: key_code (in) indicates the number of pressed key + * bc_commands (out) command information + * + * return: length of commands + */ +extern UINT16 bc_lib_control(int key_code, t_bc_commands* bc_commands); + +/* + * function bc_lib_close + * + * parameters: + * + * return: + */ +extern void bc_lib_close(); +///////////////////////////////////////////////// BLE Central End ///////////////////////////////////////////////// + +///////////////////////////////////////////////// Utils Begin ///////////////////////////////////////////////// +/* + * function get_temperature_range + * + * parameters: ac_mode (in) specify in which AC mode the application need to get temperature info + * temp_min (out) the min temperature supported in a specified AC mode + * temp_max (out) the max temperature supported in a specified AC mode + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_temperature_range(UINT8 ac_mode, INT8* temp_min, INT8* temp_max); + +/* + * function get_supported_mode + * + * parameters: supported_mode (out) mode supported by the remote in lower 5 bits + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_mode(UINT8* supported_mode); + +/* + * function get_supported_wind_speed + * + * parameters: ac_mode (in) specify in which AC mode the application need to get wind speed info + * supported_wind_speed (out) wind speed supported by the remote in lower 4 bits + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_wind_speed(UINT8 ac_mode, UINT8* supported_wind_speed); + +/* + * function get_supported_swing + * + * parameters: ac_mode (in) specify in which AC mode the application need to get swing info + * supported_swing (out) swing supported by the remote in lower 2 bits + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_swing(UINT8 ac_mode, UINT8* supported_swing); + +/* + * function get_supported_wind_direction + * + * parameters: supported_wind_direction (out) swing supported by the remote in lower 2 bits + * + * return: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +INT8 get_supported_wind_direction(UINT8* supported_wind_direction); + +/* + * function get_bc_need_conn_ack + * + * parameters: + * + * return: boolean status indicating if bc connection need ACK + */ +extern UINT8 get_bc_need_conn_ack(); + +/* + * function get_bc_device_name + * + * parameters: + * + * return: name of BLE Peripheral device + */ +extern char* get_bc_device_name(); + +/* + * function get_valid_keys + * + * parameters: valid_keys (out) + * + * return: name of BLE Peripheral device + */ +extern int get_valid_keys(int *valid_keys); + +///////////////////////////////////////////////// Utils End ///////////////////////////////////////////////// + +#endif // _IRDA_DECODE_H_ diff --git a/src/ir_decoder/ucon_decode_jni.c b/src/ir_decoder/ucon_decode_jni.c new file mode 100644 index 0000000..5c14c37 --- /dev/null +++ b/src/ir_decoder/ucon_decode_jni.c @@ -0,0 +1,389 @@ +/************************************************************************************************** +Filename: ucon_decode_jni.c +Revised: Date: 2016-03-21 +Revision: Revision: 1.0 + +Description: This file links to java layer for Android application + +Copyright 2014-2016 UCON Tech all rights reserved + +Revision log: +* 2016-03-21: created by strawmanbobi +**************************************************************************************************/ +#include +#include +#include "include/ucon_decode_jni.h" +#include "irda_defs.h" +#include "ucon_decode.h" + +// function declaration +void FillBCCommandValuesToJni(JNIEnv* env, jobject j_bc_command, jclass bccommand_class, t_bc_command bc_command); + +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACLibOpen + (JNIEnv *env, jobject this_obj, jstring file_name) +{ + const char *n_file_name = (*env)->GetStringUTFChars(env, file_name, 0); + if (IR_DECODE_FAILED == irda_ac_lib_open(n_file_name)) + { + irda_ac_lib_close(); + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_FAILED; + } + + // no need to verify return value + irda_context_init(); + + if (IR_DECODE_FAILED == irda_ac_lib_parse()) + { + irda_ac_lib_close(); + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_FAILED; + } + + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_SUCCEEDED; +} + +JNIEXPORT jintArray JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACControl + (JNIEnv *env, jobject this_obj, jobject jni_ac_status, jint function_code, jint change_wind_direction) +{ + int i = 0; + int copy_array[USER_DATA_SIZE] = {0}; + + jclass n_ac_status = (*env)->GetObjectClass(env, jni_ac_status); + jfieldID ac_power_fid = (*env)->GetFieldID(env, n_ac_status, "acPower", "I"); + jint i_ac_power = (*env)->GetIntField(env, jni_ac_status, ac_power_fid); + + jfieldID ac_mode_fid = (*env)->GetFieldID(env, n_ac_status, "acMode", "I"); + jint i_ac_mode = (*env)->GetIntField(env, jni_ac_status, ac_mode_fid); + + jfieldID ac_temp_fid = (*env)->GetFieldID(env, n_ac_status, "acTemp", "I"); + jint i_ac_temp = (*env)->GetIntField(env, jni_ac_status, ac_temp_fid); + + jfieldID ac_wind_dir_fid = (*env)->GetFieldID(env, n_ac_status, "acWindDir", "I"); + jint i_ac_wind_dir = (*env)->GetIntField(env, jni_ac_status, ac_wind_dir_fid); + + jfieldID ac_wind_speed_fid = (*env)->GetFieldID(env, n_ac_status, "acWindSpeed", "I"); + jint i_ac_wind_speed = (*env)->GetIntField(env, jni_ac_status, ac_wind_speed_fid); + + IR_PRINTF("\nget ac status : %d, %d, %d, %d, %d, %d\n", + i_ac_power, + i_ac_mode, + i_ac_temp, + i_ac_wind_dir, + i_ac_wind_speed, + function_code); + + ac_status.acDisplay = 0; + ac_status.acSleep = 0; + ac_status.acTimer = 0; + ac_status.acPower = i_ac_power; + ac_status.acMode = i_ac_mode; + ac_status.acTemp = i_ac_temp; + ac_status.acWindDir = i_ac_wind_dir; + ac_status.acWindSpeed = i_ac_wind_speed; + + int wave_code_length = irda_ac_lib_control(ac_status, user_data, function_code, change_wind_direction); + + IR_PRINTF("\nsize of wave code = %d\n", wave_code_length); + + jintArray result = (*env)->NewIntArray(env, wave_code_length); + if (result == NULL) + { + return NULL; /* out of memory error thrown */ + } + for (i = 0; i < wave_code_length; i++) + { + copy_array[i] = (int)user_data[i]; + } + (*env)->SetIntArrayRegion(env, result, 0, wave_code_length, copy_array); + + // temporary solution, close ac lib here in order to release memory + // irda_ac_lib_close(); + + return result; +} + +JNIEXPORT void JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACLibClose + (JNIEnv *env, jobject this_obj) +{ + irda_ac_lib_close(); +} + +JNIEXPORT jobject JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetTemperatureRange + (JNIEnv *env, jobject this_obj, jint ac_mode) +{ + int tempMin = 0; + int tempMax = 0; + + jobject temperature_range = NULL; + jclass temperature_range_class = (*env)->FindClass(env, "com/yuekong/remote/bean/jnibean/JNITemperatureRange"); + jmethodID temperature_range_mid = (*env)->GetMethodID(env, temperature_range_class, "", "()V"); + jfieldID min_temp_fid = (*env)->GetFieldID(env, temperature_range_class, "tempMin", "I"); + jfieldID max_temp_fid = (*env)->GetFieldID(env, temperature_range_class, "tempMax", "I"); + + temperature_range = (*env)->NewObject(env, temperature_range_class, temperature_range_mid); + + get_temperature_range((UINT8)ac_mode, (UINT8*)&tempMin, (UINT8*)&tempMax); + + (*env)->SetIntField(env, temperature_range, min_temp_fid, tempMin); + (*env)->SetIntField(env, temperature_range, max_temp_fid, tempMax); + + return temperature_range; +} + +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetSupportedMode + (JNIEnv *env, jobject this_obj) +{ + int supported_mode = 0; + get_supported_mode((UINT8*)&supported_mode); + return supported_mode; +} + +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetSupportedWindSpeed + (JNIEnv *env, jobject this_obj, jint ac_mode) +{ + int supported_wind_speed = 0; + get_supported_wind_speed((UINT8)ac_mode, (UINT8*)&supported_wind_speed); + return supported_wind_speed; +} + +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetSupportedSwing + (JNIEnv *env, jobject this_obj, jint ac_mode) +{ + int supported_swing = 0; + get_supported_swing((UINT8)ac_mode, (UINT8*)&supported_swing); + return supported_swing; +} + +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaACGetSupportedWindDirection + (JNIEnv *env, jobject this_obj) +{ + int supported_wind_direction = 0; + get_supported_wind_direction((UINT8*)&supported_wind_direction); + return supported_wind_direction; +} + +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_irdaTVLibOpen + (JNIEnv *env, jobject this_obj, jstring file_name, jint j_irda_hex_encode) +{ + const char *n_file_name = (*env)->GetStringUTFChars(env, file_name, 0); + + if (IR_DECODE_FAILED == irda_tv_lib_open(n_file_name)) + { + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_FAILED; + } + + if (IR_DECODE_FAILED == irda_tv_lib_parse(j_irda_hex_encode)) + { + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_FAILED; + } + + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_SUCCEEDED; +} + +JNIEXPORT jintArray JNICALL Java_com_yuekong_remote_service_DecodeService_irdaTVControl + (JNIEnv *env, jobject this_obj, jint key_number) +{ + int i = 0; + int copy_array[USER_DATA_SIZE] = {0}; + int wave_code_length = irda_tv_lib_control(key_number, user_data); + + IR_PRINTF("\nsize of wave code = %d\n", wave_code_length); + + jintArray result = (*env)->NewIntArray(env, wave_code_length); + if (result == NULL) + { + return NULL; /* out of memory error thrown */ + } + for (i = 0; i < wave_code_length; i++) + { + copy_array[i] = (int)user_data[i]; + } + (*env)->SetIntArrayRegion(env, result, 0, wave_code_length, copy_array); + + return result; +} + +JNIEXPORT void JNICALL Java_com_yuekong_remote_service_DecodeService_irdaTVLibClose + (JNIEnv *env, jobject this_obj) +{ + // do nothing + return; +} + +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_bcLibOpen + (JNIEnv *env, jobject this_obj, jstring file_name) +{ + const char *n_file_name = (*env)->GetStringUTFChars(env, file_name, 0); + if (IR_DECODE_FAILED == bc_lib_open(n_file_name)) + { + bc_lib_close(); + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_FAILED; + } + + // no need to verify return value + bc_context_init(); + + if (IR_DECODE_FAILED == bc_lib_parse()) + { + bc_lib_close(); + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_FAILED; + } + + (*env)->ReleaseStringUTFChars(env, file_name, n_file_name); + return IR_DECODE_SUCCEEDED; +} + +JNIEXPORT jint JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetNeedConnAck + (JNIEnv *env, jobject this_obj) +{ + return context_bc->need_connection_ack; +} + +JNIEXPORT jstring JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetDeviceName + (JNIEnv *env, jobject this_obj) +{ + jstring ret_name; + const char* device_name = context_bc->device_name; + ret_name = (*env)->NewStringUTF(env, device_name); + return ret_name; +} + +JNIEXPORT jintArray JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetValidKeys + (JNIEnv *env, jobject this_obj) +{ + jintArray result; + int valid_keys[KEY_COUNT] = {0}; + int valid_keys_length = get_valid_keys(valid_keys); + + result = (*env)->NewIntArray(env, valid_keys_length); + if (result == NULL) + { + return NULL; + } + (*env)->SetIntArrayRegion(env, result, 0, valid_keys_length, valid_keys); + + return result; +} + +JNIEXPORT void JNICALL Java_com_yuekong_remote_service_DecodeService_bcLibClose + (JNIEnv *env, jobject this_obj) +{ + bc_lib_close(); +} + +JNIEXPORT jobject JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetConnAck + (JNIEnv *env, jobject this_obj) +{ + int segment_count = 0; + int i = 0; + jobject bc_commands = NULL; + + jclass bccommands_class = (*env)->FindClass(env, "com/yuekong/remote/bean/jnibean/JNIBCCommands"); + jclass bccommand_class = (*env)->FindClass(env, "com/yuekong/remote/bean/jnibean/JNIBCCommand"); + + jmethodID bccommands_mid = (*env)->GetMethodID(env, bccommands_class, "", "()V"); + jmethodID bccommand_mid = (*env)->GetMethodID(env, bccommand_class, "", "()V"); + + bc_commands = (*env)->NewObject(env, bccommands_class, bccommands_mid); + + // get connection ACK info + segment_count = context_bc->conn_ack.seg_count; + // set segment count for result data-structure + jfieldID segment_count_fid = (*env)->GetFieldID(env, bccommands_class, "segmentCount", "I"); + jfieldID commands_fid = (*env)->GetFieldID(env, + bccommands_class, + "commands", + "[com/yuekong/remote/bean/jnibean/JNIBCCommand"); + + (*env)->SetIntField(env, bc_commands, segment_count_fid, segment_count); + + // fill bc_command array for bc_commands + jobjectArray j_bc_command_array = (*env)->NewObjectArray(env, segment_count, bccommand_class, NULL); + + for (i = 0; i < segment_count; i++) + { + jobject bc_command = (*env)->NewObject(env, bccommand_class, bccommand_mid); + FillBCCommandValuesToJni(env, bc_command, bccommand_class, context_bc->conn_ack.commands[i]); + (*env)->SetObjectArrayElement(env, j_bc_command_array, + i, bc_command); + } + (*env)->SetObjectField(env, bc_commands, commands_fid, j_bc_command_array); + + return bc_commands; +} + +JNIEXPORT jobject JNICALL Java_com_yuekong_remote_service_DecodeService_bcGetCommand + (JNIEnv *env, jobject this_obj, jint key_number) +{ + int segment_count = 0; + int i = 0; + jobject bc_commands = NULL; + + jclass bccommands_class = (*env)->FindClass(env, "com/yuekong/remote/bean/jnibean/JNIBCCommands"); + jclass bccommand_class = (*env)->FindClass(env, "com/yuekong/remote/bean/jnibean/JNIBCCommand"); + + jmethodID bccommands_mid = (*env)->GetMethodID(env, bccommands_class, "", "()V"); + jmethodID bccommand_mid = (*env)->GetMethodID(env, bccommand_class, "", "()V"); + + bc_commands = (*env)->NewObject(env, bccommands_class, bccommands_mid); + + // get connection ACK info + segment_count = context_bc->conn_ack.seg_count; + // set segment count for result data-structure + jfieldID segment_count_fid = (*env)->GetFieldID(env, bccommands_class, "segmentCount", "I"); + jfieldID commands_fid = (*env)->GetFieldID(env, + bccommands_class, + "commands", + "[com/yuekong/remote/bean/jnibean/JNIBCCommand"); + + (*env)->SetIntField(env, bc_commands, segment_count_fid, segment_count); + + // fill bc_command array for bc_commands + jobjectArray j_bc_command_array = (*env)->NewObjectArray(env, segment_count, bccommand_class, NULL); + + for (i = 0; i < segment_count; i++) + { + jobject bc_command = (*env)->NewObject(env, bccommand_class, bccommand_mid); + FillBCCommandValuesToJni(env, bc_command, bccommand_class, context_bc->generic_command[key_number].commands[i]); + (*env)->SetObjectArrayElement(env, j_bc_command_array, + i, bc_command); + } + (*env)->SetObjectField(env, bc_commands, commands_fid, j_bc_command_array); + + return bc_commands; +} + +// utils +void FillBCCommandValuesToJni(JNIEnv* env, jobject j_bc_command, jclass bccommand_class, t_bc_command n_bc_command) +{ + int copy_array[BLE_GAP_MTU] = {0}; + jintArray ble_command_array = NULL; + int i = 0; + + jfieldID length_fid = (*env)->GetFieldID(env, bccommand_class, "length", "I"); + jfieldID handle_fid = (*env)->GetFieldID(env, bccommand_class, "handle", "I"); + jfieldID command_fid = (*env)->GetFieldID(env, bccommand_class, "command", "[I"); + + IR_PRINTF("Set int field [length] for bc_command : %d\n", n_bc_command.length); + (*env)->SetIntField(env, j_bc_command, length_fid, n_bc_command.length); + IR_PRINTF("Set int field [handle] for bc_command : 0x%02X\n", n_bc_command.handle); + (*env)->SetIntField(env, j_bc_command, handle_fid, n_bc_command.handle); + + ble_command_array = (*env)->NewIntArray(env, BLE_GAP_MTU); + + // prepare BLE command as int32 for java + for(i = 0; i < BLE_GAP_MTU; i++) + { + copy_array[i] = n_bc_command.command[i]; + IR_PRINTF("command %d origin_value = %02X, converted_value = %02X ", i, n_bc_command.command[i], copy_array[i]); + } + (*env)->SetIntArrayRegion(env, ble_command_array, 0, BLE_GAP_MTU, copy_array); + (*env)->SetObjectField(env, j_bc_command, command_fid, ble_command_array); +} \ No newline at end of file diff --git a/src/ir_encoder/.idea/misc.xml b/src/ir_encoder/.idea/misc.xml new file mode 100644 index 0000000..df245c4 --- /dev/null +++ b/src/ir_encoder/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ir_encoder/.idea/modules.xml b/src/ir_encoder/.idea/modules.xml new file mode 100644 index 0000000..ae66303 --- /dev/null +++ b/src/ir_encoder/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/ir_encoder/.idea/vcs.xml b/src/ir_encoder/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/src/ir_encoder/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/ir_encoder/.idea/workspace.xml b/src/ir_encoder/.idea/workspace.xml new file mode 100644 index 0000000..74907ac --- /dev/null +++ b/src/ir_encoder/.idea/workspace.xml @@ -0,0 +1,760 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1458870788618 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ir_encoder/.idea/yk_encoder.iml b/src/ir_encoder/.idea/yk_encoder.iml new file mode 100644 index 0000000..38eb8da --- /dev/null +++ b/src/ir_encoder/.idea/yk_encoder.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/ir_encoder/merge.py b/src/ir_encoder/merge.py new file mode 100644 index 0000000..14c0c2a --- /dev/null +++ b/src/ir_encoder/merge.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# coding=utf-8 + +import sys +import os + +for root, dirs, files in os.walk(sys.argv[1]): + for i in files: + fileType = i.split('.') + if cmp(fileType[1], 'bin') == 0: + print root + i + + print "========================list===========================" + + remotePath = sys.argv[2] + fileType2 = remotePath.split('.') + if cmp(fileType2[-1], 'bin') == 0: + prottype = fileType2[0].split('#') + print(prottype[0]) + print(fileType[0]) + if cmp(prottype[0].split('/')[-1], fileType[0]) == 0: + outname = remotePath.split('#') + binary = open(sys.argv[3] + "/ykir_"+outname[0].split('/')[-1]+"_"+outname[1], 'wb') + prot_file = open(root+i, "rb") + remote_file = open(remotePath, "rb") + binary.write(prot_file.read()) + binary.write(remote_file.read()) + binary.close() + prot_file.close() + remote_file.close() + print remotePath + print + print diff --git a/src/ir_encoder/s_ac_ii.py b/src/ir_encoder/s_ac_ii.py new file mode 100644 index 0000000..510e878 --- /dev/null +++ b/src/ir_encoder/s_ac_ii.py @@ -0,0 +1,110 @@ +# !/usr/bin/env python +# coding=utf-8 +# for protocol version V1.0 +# 29 tags are supported + +import sys,os +import xml.dom.minidom +import struct + + +alltags = [300, 301, 302, 303, 305, 306, 307, 1001, 1002, 1003, + 1004, 1005, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1015, + 1016, 1501, 1502, 1503, 1504, 1505, 1506, 1508, 1509] +tags_max_size = [0 for x in range(0, len(alltags))] + +# Definition of ac tag class +# (tag:value) + + +class ACTag: + def __init__(self, tag, value): + self.tag = tag + self.value = value + self.len = len(self.value) + + def __lt__(self, other): + return self.tag < other.tag + + def printf(self): + print "[%d] %s len:%d" % (self.tag, self.value, len(self.value)) + +# Definition of Remote_control class +# device id:(tag:value)...(tag:value) + + +class ACRemoteControl: + def __init__(self, device_id): + self.device_id = device_id + self.tags = [] + + def add(self, tag): + self.tags.append(tag) + + def sort(self): + self.tags.sort() + + def printf(self): + print "==========Device id:%d===========" % self.device_id + for j in range(len(self.tags)): + self.tags[j].printf() + + +def create_binary(ac_device): + find = 0 + offset = 0 + + f_content = open(sys.argv[2] + str(ac_device.device_id) + "_tmp.bin", "wb") + f_head = open(sys.argv[2] + "ykir_new_ac_" + str(ac_device.device_id) + ".bin", "wb") + f_head.write(struct.pack("B", 29)) + for i in range(len(alltags)): + find = 0 + for j in range(len(ac_device.tags)): + if (alltags[i] == ac_device.tags[j].tag): + f_content.write(ac_device.tags[j].value) + + f_head.write(struct.pack("H", offset)) + offset = offset + ac_device.tags[j].len +############################################################################### +# Find Max length +############################################################################### + if (tags_max_size[i] < ac_device.tags[j].len): + tags_max_size[i] = ac_device.tags[j].len; + find = 1 + break + + if find == 0: + f_head.write(struct.pack("H", 0xffff)) + #f.write(ac_device) + f_content.close() + f_tmp = open(sys.argv[2] + str(ac_device.device_id) + "_tmp.bin", "rb") + f_head.write(f_tmp.read()) + f_tmp.close() + f_head.close() + +dom = xml.dom.minidom.parse(sys.argv[1]) +device = dom.documentElement +#devices = root.getElementsByTagName('remote_controller') + +print "============================" +print "AC data:" +print "============================" +ac_device_arrary=[] +id = device.getElementsByTagName('id') +idnum = int(id[0].firstChild.data.encode('ascii'), 10) + +g_ac_device = ACRemoteControl(idnum) +print "------------AC Device ID: %d-------------" % idnum +exts = device.getElementsByTagName('exts') +for n in range(len(exts)): + ext = exts[n].getElementsByTagName('ext') + for j in range(len(ext)): + tag_index=ext[j].getElementsByTagName('tag') + tag_index_data = int(tag_index[0].firstChild.data.encode('ascii'), 10) + tag_value=ext[j].getElementsByTagName('value') + tag_value_data = tag_value[0].firstChild.data.encode('ascii') + g_ac_device.add(ACTag(tag_index_data, tag_value_data)) +g_ac_device.sort() +g_ac_device.printf() +create_binary(g_ac_device) +ac_device_arrary.append(g_ac_device) diff --git a/src/ir_encoder/s_acleaner.py b/src/ir_encoder/s_acleaner.py new file mode 100644 index 0000000..a868c43 --- /dev/null +++ b/src/ir_encoder/s_acleaner.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding=utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "UP", "DOWN", "LEFT", "RIGHT", "ION", "PLUS", "MINUS", "AUTO", "SPEED", "MODE", "TIMING", + "LIGHT", "FORCE", "SWITCH") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_bc.py b/src/ir_encoder/s_bc.py new file mode 100644 index 0000000..6eee469 --- /dev/null +++ b/src/ir_encoder/s_bc.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# coding = utf-8 +# for protocol version V1.0 +# 20 tags are supported + +import sys +import xml.dom.minidom +import struct + +allTags = [100, 101, 102, 103, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 300] +tags_max_size = [0 for x in range(0, len(allTags))] + +# Definition of BLE Central tag class +# (tag:value) + + +class BCTag: + def __init__(self, tag, value): + self.tag = tag + self.value = value + self.len = len(self.value) + + def __lt__(self, other): + return self.tag < other.tag + + def printf(self): + print "[%d] %s len:%d" % (self.tag, self.value, len(self.value)) + +# Definition of Remote_control class +# device id:(tag:value)...(tag:value) + + +class BCRemoteControl: + def __init__(self, device_id): + self.device_id = device_id + self.tags = [] + + def add(self, tag): + self.tags.append(tag) + + def sort(self): + self.tags.sort() + + def printf(self): + print "==========Device id:%d===========" % self.device_id + for j in range(len(self.tags)): + self.tags[j].printf() + + +def create_binary(bc_device): + find = 0 + offset = 0 + + f_content = open(sys.argv[2] + str(bc_device.device_id) + "_tmp.bin", "wb") + f_head = open(sys.argv[2] + "ykir_bc_" + str(bc_device.device_id) + ".bin", "wb") + f_head.write(struct.pack("B", 20)) + for i in range(len(allTags)): + find = 0 + for j in range(len(bc_device.tags)): + if allTags[i] == bc_device.tags[j].tag: + f_content.write(bc_device.tags[j].value) + + f_head.write(struct.pack("H", offset)) + offset = offset + bc_device.tags[j].len +############################################################################### +# Find Max length +############################################################################### + if tags_max_size[i] < bc_device.tags[j].len: + tags_max_size[i] = bc_device.tags[j].len + find = 1 + break + + if find == 0: + f_head.write(struct.pack("H", 0xffff)) + + f_content.close() + f_tmp = open(sys.argv[2] + str(bc_device.device_id) + "_tmp.bin", "rb") + f_head.write(f_tmp.read()) + f_tmp.close() + f_head.close() + +dom = xml.dom.minidom.parse(sys.argv[1]) +device = dom.documentElement +# devices = root.getElementsByTagName('remote_controller') + +print "============================" +print "BC data:" +print "============================" +bc_device_array=[] +id = device.getElementsByTagName('id') +idnum = int(id[0].firstChild.data.encode('ascii'), 10) + +g_bc_device = BCRemoteControl(idnum) +print "------------BC Device ID: %d-------------" % idnum +exts = device.getElementsByTagName('exts') +for n in range(len(exts)): + ext = exts[n].getElementsByTagName('ext') + for j in range(len(ext)): + tag_index=ext[j].getElementsByTagName('tag') + tag_index_data = int(tag_index[0].firstChild.data.encode('ascii'), 10) + tag_value=ext[j].getElementsByTagName('value') + tag_value_data = tag_value[0].firstChild.data.encode('ascii') + g_bc_device.add(BCTag(tag_index_data, tag_value_data)) +g_bc_device.sort() +g_bc_device.printf() +create_binary(g_bc_device) +bc_device_array.append(g_bc_device) diff --git a/src/ir_encoder/s_bstb.py b/src/ir_encoder/s_bstb.py new file mode 100644 index 0000000..9c7cf6b --- /dev/null +++ b/src/ir_encoder/s_bstb.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "UP", "DOWN", "LEFT", "RIGHT", "OK", "CHAN+", "CHAN-", "BACK", "MUTE", "PROGRAM", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_crobot.py b/src/ir_encoder/s_crobot.py new file mode 100644 index 0000000..9eb8e38 --- /dev/null +++ b/src/ir_encoder/s_crobot.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding=utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "UP", "DOWN", "LEFT", "RIGHT", "START", "PLUS", "MINUS", "AUTO", "SPOT", "SPEED", "TIMING", + "CHARGE", "PLAN", "SWITCH") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_dvd.py b/src/ir_encoder/s_dvd.py new file mode 100644 index 0000000..7cec023 --- /dev/null +++ b/src/ir_encoder/s_dvd.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# coding=utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "UP", "DOWN", "LEFT", "RIGHT", "OK", "VOL+", "VOL-", "PLAY", "PAUSE", "EJECT", "BACK", "FOR", "MENU", "SWITCH") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_fan.py b/src/ir_encoder/s_fan.py new file mode 100644 index 0000000..cc7ad3f --- /dev/null +++ b/src/ir_encoder/s_fan.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding=utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "UP", "DOWN", "LEFT", "RIGHT", "OK", "SPEED+", "SPEED-", "SWING", "SPEED", "MODE", "BACK", + "HOME", "MENU", "SWITCH") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath + "/" + protocol + "#" + filename[0] + ".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_iptv.py b/src/ir_encoder/s_iptv.py new file mode 100644 index 0000000..2de2008 --- /dev/null +++ b/src/ir_encoder/s_iptv.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "MUTE", "UP", "DOWN", "LEFT", "RIGHT", "OK", "VOL+", "VOL-", "BACK", "INPUT", "MENU", + "UP_PAGE", "DOWN_PAGE", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_light.py b/src/ir_encoder/s_light.py new file mode 100644 index 0000000..55223ca --- /dev/null +++ b/src/ir_encoder/s_light.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "COLOR_1", "COLOR_2", "COLOR_3", "COLOR_4", "COLOR_0", "BRIGHT", "DARK", "POWER_ON", "RAINBOW", + "POWER_OFF", "BACK", "HOME", "MENU", "SWITCH") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_nw.py b/src/ir_encoder/s_nw.py new file mode 100644 index 0000000..fb2441b --- /dev/null +++ b/src/ir_encoder/s_nw.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "UP", "DOWN", "LEFT", "RIGHT", "OK", "VOL+", "VOL-", "BACK", "MENU", "HOME", "0", "1", "2", + "3", "4", "5", "6", "7", "8", "9") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_pro.py b/src/ir_encoder/s_pro.py new file mode 100644 index 0000000..6f20009 --- /dev/null +++ b/src/ir_encoder/s_pro.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# coding=utf-8 + +import struct +import sys +import xml.dom.minidom + +flag_tab = ("boot", "stop", "separator", "one", "zero", "flip", "two", "three") + +class IRDAData: + def __init__(self, bits, lsb, mode, index): + self.bits = bits + self.lsb = lsb + self.mode = mode + self.index = index + + def printf(self): + print "%d %d %d %d" % (self.bits, self.lsb, self.mode, self.index) + + def packIRData(self): + return struct.pack("BBBB", self.bits, self.lsb, self.mode, self.index) + +class IRDAFlag: + def __init__(self, name, mask, space): + self.name = name + self.mask = mask + self.space = space + + def printf(self): + print "%s %d %d" % (self.name, self.mask, self.space) + + def packFlag(self): + return struct.pack("HH", self.mask, self.space) + + +def printProtocol(file): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + freqnode = root.getElementsByTagName('frequency') + freq = freqnode[0].firstChild.data + inverseflag = 0 + + protnode = root.getAttribute('name') + + print protnode + protname = protnode.split('_') + + binary = open(sys.argv[2], 'wb') + + bytes = struct.pack('20s', protnode.encode("ascii")) + binary.write(bytes) + + bit = root.getElementsByTagName('bit') + for n in range(len(flag_tab)): + for b in range(len(bit)): + name = bit[b].getAttribute('name') + cycles = bit[b].getAttribute('cycles') + if name and cycles: + if cmp(flag_tab[n], name) == 0: + bytes = struct.pack('B', int(cycles)) + binary.write(bytes) + break + if b == (len(bit) - 1): + bytes = struct.pack('B', 0) + binary.write(bytes) + for m in range(len(flag_tab)): + found = 0 + for i in range(len(bit)): + name = bit[i].getAttribute('name') + cycles = bit[i].getAttribute('cycles') + if name and cycles and cmp(flag_tab[m], name) == 0: + found = 1 + cycle = bit[i].getElementsByTagName('cycle') + for c in range(len(cycle)): + normal = cycle[c].getAttribute('flag') + mask = cycle[c].getAttribute('mask') + space = cycle[c].getAttribute('space') + if cmp(normal, "normal") == 0: + inverseflag = 0 + else: + inverseflag = 1 + print "{\"%s\", \"cycle:%s\", 0x%04x, 0x%04x, 0x%02x}" % ( + name, c, int(mask), int(space), int(cycles)) + bytes = struct.pack('B', inverseflag) + binary.write(bytes) + bytes = struct.pack('HH', int(mask), int(space)) + binary.write(bytes) + + frame = root.getElementsByTagName('frame') + + index = 0 + lsb = 0 + mode = 0 + flag = 0 + irda_frame = [] + flag_tab_dict = {"boot": 0, "stop": 1, "separator": 2, "one": 3, "zero": 4, "flip": 5, "two": 6, "three": 7} + for i in frame[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + index += 1 + if i.getAttribute('type'): + print "{%d, \"%s\", 0, 0, 0}" % (index, i.getAttribute('type')) + flag = IRDAData(1, 0, 0, flag_tab_dict[i.getAttribute('type').encode("ascii")]) + irda_frame.append(flag) + if i.getAttribute('bits'): + if cmp(i.getAttribute('ending'), "lsb") == 0: + lsb = 0 + else: + lsb = 1 + + if cmp(i.getAttribute('mode'), "normal") == 0: + mode = 0 + else: + mode = 1 + + print "{%d, \"%s\", %d, %d, %s}" % (index, i.getAttribute('bits'), \ + lsb, mode, i.firstChild.data) + flag = IRDAData(int(i.getAttribute('bits')), lsb, mode, int(i.firstChild.data)) + irda_frame.append(flag) + + binary.write(struct.pack("B", len(irda_frame))) + + for i in range(len(irda_frame)): + irda_frame[i].printf() + binary.write(irda_frame[i].packIRData()) + binary.close() + +printProtocol(sys.argv[1]) diff --git a/src/ir_encoder/s_pro_hex.py b/src/ir_encoder/s_pro_hex.py new file mode 100644 index 0000000..c380e7f --- /dev/null +++ b/src/ir_encoder/s_pro_hex.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# coding=utf-8 + +import struct +import sys +import xml.dom.minidom + +flag_tab = ("boot", "stop", "separator", "one", "zero", "flip", "two", "three", "four", "five", "six", "seven", "eight", "nine", "A", "B", "C", "D", "E", "F") + +class IRDAData: + def __init__(self, bits, lsb, mode, index): + self.bits = bits + self.lsb = lsb + self.mode = mode + self.index = index + + def printf(self): + print "%d %d %d %d" % (self.bits, self.lsb, self.mode, self.index) + + def packIRData(self): + return struct.pack("BBBB", self.bits, self.lsb, self.mode, self.index) + +class IRDAFlag: + def __init__(self, name, mask, space): + self.name = name + self.mask = mask + self.space = space + + def printf(self): + print "%s %d %d" % (self.name, self.mask, self.space) + + def packFlag(self): + return struct.pack("HH", self.mask, self.space) + + +def printProtocol(file): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + freqnode = root.getElementsByTagName('frequency') + freq = freqnode[0].firstChild.data + inverseflag = 0 + + protnode = root.getAttribute('name') + + print protnode + protname = protnode.split('_') + + binary = open(sys.argv[2], 'wb') + + bytes = struct.pack('20s', protnode.encode("ascii")) + binary.write(bytes) + + bit = root.getElementsByTagName('bit') + for n in range(len(flag_tab)): + for b in range(len(bit)): + name = bit[b].getAttribute('name') + cycles = bit[b].getAttribute('cycles') + if name and cycles: + if cmp(flag_tab[n], name) == 0: + bytes = struct.pack('B', int(cycles)) + binary.write(bytes) + break + if b == (len(bit) - 1): + bytes = struct.pack('B', 0) + binary.write(bytes) + for m in range(len(flag_tab)): + found = 0 + for i in range(len(bit)): + name = bit[i].getAttribute('name') + cycles = bit[i].getAttribute('cycles') + if name and cycles and cmp(flag_tab[m], name) == 0: + found = 1 + cycle = bit[i].getElementsByTagName('cycle') + for c in range(len(cycle)): + normal = cycle[c].getAttribute('flag') + mask = cycle[c].getAttribute('mask') + space = cycle[c].getAttribute('space') + if cmp(normal, "normal") == 0: + inverseflag = 0 + else: + inverseflag = 1 + print "{\"%s\", \"cycle:%s\", 0x%04x, 0x%04x, 0x%02x}" % ( + name, c, int(mask), int(space), int(cycles)) + bytes = struct.pack('B', inverseflag) + binary.write(bytes) + bytes = struct.pack('HH', int(mask), int(space)) + binary.write(bytes) + + frame = root.getElementsByTagName('frame') + + index = 0 + lsb = 0 + mode = 0 + flag = 0 + irda_frame = [] + flag_tab_dict = {"boot": 0, "stop": 1, "separator": 2, "one": 3, "zero": 4, "flip": 5, "two": 6, "three": 7, "four": 8, "five": 9, "six": 10, "seven": 11, "eight": 12, "nine": 13, "A": 14, "B": 15, "C": 16, "D": 17, "E": 18, "F": 19} + for i in frame[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + index += 1 + if i.getAttribute('type'): + print "{%d, \"%s\", 0, 0, 0}" % (index, i.getAttribute('type')) + flag = IRDAData(1, 0, 0, flag_tab_dict[i.getAttribute('type').encode("ascii")]) + irda_frame.append(flag) + if i.getAttribute('bits'): + if cmp(i.getAttribute('ending'), "lsb") == 0: + lsb = 0 + else: + lsb = 1 + + if cmp(i.getAttribute('mode'), "normal") == 0: + mode = 0 + else: + mode = 1 + + print "{%d, \"%s\", %d, %d, %s}" % (index, i.getAttribute('bits'), \ + lsb, mode, i.firstChild.data) + flag = IRDAData(int(i.getAttribute('bits')), lsb, mode, int(i.firstChild.data)) + irda_frame.append(flag) + + binary.write(struct.pack("B", len(irda_frame))) + + for i in range(len(irda_frame)): + irda_frame[i].printf() + binary.write(irda_frame[i].packIRData()) + binary.close() + +printProtocol(sys.argv[1]) diff --git a/src/ir_encoder/s_projector.py b/src/ir_encoder/s_projector.py new file mode 100644 index 0000000..2d145f7 --- /dev/null +++ b/src/ir_encoder/s_projector.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + + +keymap_dict = ("POWER", "UP", "DOWN", "LEFT", "RIGHT", "OK", "VOL+", "VOL-", "ZOOM+", "MENU1", "ZOOM-", "BACK", "HOME", + "MENU2", "SWITCH") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_stb.py b/src/ir_encoder/s_stb.py new file mode 100644 index 0000000..6f4fab0 --- /dev/null +++ b/src/ir_encoder/s_stb.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "MUTE", "UP", "DOWN", "LEFT", "RIGHT", "OK", "VOL+", "VOL-", "BACK", "INPUT", "MENU", + "UP_PAGE", "DOWN_PAGE", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_stereo.py b/src/ir_encoder/s_stereo.py new file mode 100644 index 0000000..9725f01 --- /dev/null +++ b/src/ir_encoder/s_stereo.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER1", "UP", "DOWN", "LEFT", "RIGHT", "OK", "VOL+", "VOL-", "MUTE", "MENU1", "POWER2", "BACK", "HOME", + "MENU2", "SWITCH") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_stereo_2.py b/src/ir_encoder/s_stereo_2.py new file mode 100644 index 0000000..3d133e6 --- /dev/null +++ b/src/ir_encoder/s_stereo_2.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "UP", "DOWN", "LEFT", "RIGHT", "OK", "VOL+", "VOL-", "MUTE", "INPUT1", "INPUT2", "BACK", "HOME", + "MENU", "SWITCH") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName) diff --git a/src/ir_encoder/s_tv.py b/src/ir_encoder/s_tv.py new file mode 100644 index 0000000..73fccbd --- /dev/null +++ b/src/ir_encoder/s_tv.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding = utf-8 + +import sys +import xml.dom.minidom +import struct + +keymap_dict = ("POWER", "MUTE", "UP", "DOWN", "LEFT", "RIGHT", "OK", "VOL+", "VOL-", "BACK", "INPUT", "MENU", "HOME", + "SET", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9") + + +class CKeyMap: + def __init__(self, name, value): + self.name = name + self.value = value + + def printf(self): + print self.name, self.value + + def packkey(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', self.value[i])) + + def packnull(self, file): + for i in range(len(self.value)): + file.write(struct.pack('B', 0)) + + def packlen(self, file): + file.write(struct.pack('B', len(self.value))) + print len(self.value) + + +def print_remote(file, realPath, realName): + print file + dom = xml.dom.minidom.parse(file) + root = dom.documentElement + protocol_node = root.getElementsByTagName('protocol') + protocol = protocol_node[0].firstChild.data + + filename = realName.split('.') + + binary = open(realPath+"/"+protocol+"#"+filename[0]+".bin", 'wb') + bytes = struct.pack('4s', 'ykir') + binary.write(bytes) + + print protocol + keymap = root.getElementsByTagName('key-map') + key = [] + empty_value = [] + for i in keymap[0].childNodes: + if i.nodeType == i.ELEMENT_NODE: + key_map_str = i.firstChild.data.encode('ascii').split(' ') + value = [] + empty_value = [] + for m in range(len(key_map_str)): + value.append(int(key_map_str[m], 16)) + empty_value.append(int('0', 16)) + name = i.getAttribute('name').encode('ascii') + data = CKeyMap(name, value) + key.append(data) + + key[0].packlen(binary) + for j in range(len(keymap_dict)): + empty_key = CKeyMap(keymap_dict[j], empty_value) + find = 0 + for n in range(len(key)): + if cmp(keymap_dict[j], key[n].name) == 0: + key[n].printf() + key[n].packkey(binary) + find = 1 + break + if find == 0: + print "Don't file this key %s" % (keymap_dict[j]) + empty_key.packkey(binary) + +fileName = sys.argv[1] +realName = sys.argv[2] +realPath = sys.argv[3] +fileType = fileName.split('.') +if cmp(fileType[1], "xml") == 0: + print_remote(fileName, realPath, realName)