From 7b3adb5b048012c26f5dfb9c9b3737dcf5b4d9ec Mon Sep 17 00:00:00 2001 From: strawmanbobi Date: Sat, 3 Feb 2024 14:06:46 +0800 Subject: [PATCH] updated unix format ending --- .../ui/fragment/ControlFragment.java | 67 +- android-example/build.gradle | 2 +- .../ir_decoder/jni/src/ir_decode_jni.c | 2 +- .../ir_decoder/jni/src/ir_decode_jni.h | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- android-example/gradlew | 320 +- .../main/java/net/irext/webapi/WebAPIs.java | 756 ++-- .../ir_decoder/src/include/ir_ac_apply.h | 92 +- .../ir_decoder/src/include/ir_ac_control.h | 886 ++--- .../Source/ir_decoder/src/include/ir_decode.h | 740 ++-- .../Source/ir_decoder/src/include/ir_defs.h | 154 +- .../ir_decoder/src/include/ir_tv_control.h | 436 +-- .../Source/ir_decoder/src/include/ir_utils.h | 78 +- .../Source/ir_decoder/src/ir_ac_apply.c | 1578 ++++---- .../Source/ir_decoder/src/ir_ac_build_frame.c | 290 +- .../Source/ir_decoder/src/ir_ac_control.c | 1120 +++--- .../src/ir_ac_parse_forbidden_info.c | 296 +- .../Source/ir_decoder/src/ir_decode.c | 1544 ++++---- .../Source/ir_decoder/src/ir_tv_control.c | 904 ++--- .../ir_decoder/src/include/ir_decode.h | 740 ++-- .../Application/ir_decoder/src/ir_decode.c | 1544 ++++---- .../Source/Application/simpleBLEPeripheral.c | 3184 ++++++++--------- .../Source/Application/simpleBLEPeripheral.h | 224 +- .../common/cc26xx/Boundary/BoundaryConfig.xml | 2 +- .../decodesdk/output/META-INF/MANIFEST.MF | 6 +- .../decodesdk/src/META-INF/MANIFEST.MF | 6 +- jni-example/jni-example.iml | 20 +- .../IRextWin32Example/IRextWin32Example.sln | 62 +- .../IRextWin32Example.vcxproj | 354 +- .../IRextWin32Example.vcxproj.filters | 172 +- win32-example/IRextWin32Example/ReadMe.txt | 2 +- 31 files changed, 7782 insertions(+), 7803 deletions(-) diff --git a/android-example/app/src/main/java/net/irext/ircontrol/ui/fragment/ControlFragment.java b/android-example/app/src/main/java/net/irext/ircontrol/ui/fragment/ControlFragment.java index 5c351cb..0137d17 100644 --- a/android-example/app/src/main/java/net/irext/ircontrol/ui/fragment/ControlFragment.java +++ b/android-example/app/src/main/java/net/irext/ircontrol/ui/fragment/ControlFragment.java @@ -210,50 +210,29 @@ public class ControlFragment extends Fragment implements View.OnClickListener { public void onClick(View v) { vibrate(mParent); int []decoded = null; - switch(v.getId()) { - case R.id.iv_power: - decoded = irControl(KEY_POWER); - break; - - case R.id.iv_up: - decoded = irControl(KEY_UP); - break; - - case R.id.iv_down: - decoded = irControl(KEY_DOWN); - break; - - case R.id.iv_left: - decoded = irControl(KEY_LEFT); - break; - - case R.id.iv_right: - decoded = irControl(KEY_RIGHT); - break; - - case R.id.iv_ok: - decoded = irControl(KEY_OK); - break; - - case R.id.iv_plus: - decoded = irControl(KEY_PLUS); - break; - - case R.id.iv_minus: - decoded = irControl(KEY_MINUS); - break; - - case R.id.iv_back: - decoded = irControl(KEY_BACK); - break; - - case R.id.iv_home: - decoded = irControl(KEY_HOME); - break; - - case R.id.iv_menu: - decoded = irControl(KEY_MENU); - break; + int id = v.getId(); + if (id == R.id.iv_power) { + decoded = irControl(KEY_POWER); + } else if (id == R.id.iv_up) { + decoded = irControl(KEY_UP); + } else if (id == R.id.iv_down) { + decoded = irControl(KEY_DOWN); + } else if (id == R.id.iv_left) { + decoded = irControl(KEY_LEFT); + } else if (id == R.id.iv_right) { + decoded = irControl(KEY_RIGHT); + } else if (id == R.id.iv_ok) { + decoded = irControl(KEY_OK); + } else if (id == R.id.iv_plus) { + decoded = irControl(KEY_PLUS); + } else if (id == R.id.iv_minus) { + decoded = irControl(KEY_MINUS); + } else if (id == R.id.iv_back) { + decoded = irControl(KEY_BACK); + } else if (id == R.id.iv_home) { + decoded = irControl(KEY_HOME); + } else if (id == R.id.iv_menu) { + decoded = irControl(KEY_MENU); } // send decoded integer array to IR emitter ConsumerIrManager irEmitter = diff --git a/android-example/build.gradle b/android-example/build.gradle index 2e2d29d..96475e0 100644 --- a/android-example/build.gradle +++ b/android-example/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.2.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/android-example/decodesdk/ir_decoder/jni/src/ir_decode_jni.c b/android-example/decodesdk/ir_decoder/jni/src/ir_decode_jni.c index 98e476c..001bb84 100644 --- a/android-example/decodesdk/ir_decoder/jni/src/ir_decode_jni.c +++ b/android-example/decodesdk/ir_decoder/jni/src/ir_decode_jni.c @@ -1,4 +1,4 @@ -/************************************************************************************************** +/************************************************************************************************** Filename: ir_decode_jni.c Revised: Date: 2016-03-21 Revision: Revision: 1.0 diff --git a/android-example/decodesdk/ir_decoder/jni/src/ir_decode_jni.h b/android-example/decodesdk/ir_decoder/jni/src/ir_decode_jni.h index ad47f7e..0ed7280 100644 --- a/android-example/decodesdk/ir_decoder/jni/src/ir_decode_jni.h +++ b/android-example/decodesdk/ir_decoder/jni/src/ir_decode_jni.h @@ -1,4 +1,4 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ +/* DO NOT EDIT THIS FILE - it is machine generated */ #if defined BOARD_ANDROID #include #elif (defined BOARD_PC) && (defined BOARD_PC_JNI) diff --git a/android-example/gradle/wrapper/gradle-wrapper.properties b/android-example/gradle/wrapper/gradle-wrapper.properties index 8049c68..59bc51a 100644 --- a/android-example/gradle/wrapper/gradle-wrapper.properties +++ b/android-example/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/android-example/gradlew b/android-example/gradlew index e834973..9d82f78 100755 --- a/android-example/gradlew +++ b/android-example/gradlew @@ -1,160 +1,160 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android-example/web-api/src/main/java/net/irext/webapi/WebAPIs.java b/android-example/web-api/src/main/java/net/irext/webapi/WebAPIs.java index 12b2a01..121b1fc 100644 --- a/android-example/web-api/src/main/java/net/irext/webapi/WebAPIs.java +++ b/android-example/web-api/src/main/java/net/irext/webapi/WebAPIs.java @@ -1,378 +1,378 @@ -package net.irext.webapi; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.util.Log; - -import com.google.gson.Gson; -import net.irext.webapi.model.*; -import net.irext.webapi.utils.Constants; -import net.irext.webapi.request.*; -import net.irext.webapi.response.*; -import net.irext.webapi.utils.PackageUtils; -import net.irext.webapi.WebAPICallbacks.*; - -import okhttp3.*; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Filename: WebAPIs.java - * Revised: Date: 2017-03-30 - * Revision: Revision: 1.0 - *

- * Description: HTTP Request initializer - *

- * Revision log: - * 2017-03-30: created by strawmanbobi - */ -public class WebAPIs { - - @SuppressWarnings("all") - private static final String TAG = WebAPIs.class.getSimpleName(); - - private static WebAPIs mInstance = null; - - private static final String DEFAULT_ADDRESS = "http://srv.irext.net"; - private static final String DEFAULT_APP = "/irext-server"; - private static String URL_PREFIX = DEFAULT_ADDRESS + DEFAULT_APP; - - // download bin from OSS - private static final String IR_BIN_FILE_PREFIX = "irda_"; - private static final String IR_BIN_FILE_SUFFIX = ".bin"; - private static final String IR_BIN_DOWNLOAD_PREFIX = "http://irext-debug.oss-cn-hangzhou.aliyuncs.com/"; - - private static final String SERVICE_SIGN_IN = "/app/app_login"; - private static final String SERVICE_LIST_CATEGORIES = "/indexing/list_categories"; - private static final String SERVICE_LIST_BRANDS = "/indexing/list_brands"; - private static final String SERVICE_LIST_PROVINCES = "/indexing/list_provinces"; - private static final String SERVICE_LIST_CITIES = "/indexing/list_cities"; - private static final String SERVICE_LIST_OPERATORS = "/indexing/list_operators"; - private static final String SERVICE_LIST_INDEXES = "/indexing/list_indexes"; - private static final String SERVICE_DOWNLOAD_BIN = "/operation/download_bin"; - private static final String SERVICE_ONLINE_DECODE = "/operation/decode"; - - private int id; - private String token; - - private OkHttpClient mHttpClient; - - private WebAPIs(String address, String appName) { - if (null != address && null != appName) { - URL_PREFIX = address + appName; - } - mHttpClient = new OkHttpClient(); - } - - private static void initializeInstance(String address, String appName) { - mInstance = new WebAPIs(address, appName); - } - - @SuppressWarnings("unused") - public static WebAPIs getInstance(String address, String appName) { - if (null == mInstance) { - initializeInstance(address, appName); - } - return mInstance; - } - - private InputStream getFileByteStreamByURL(String url) throws IOException { - Request request = new Request.Builder() - .url(url) - .get() - .build(); - - Response response = new OkHttpClient().newCall(request).execute(); - return response.body().byteStream(); - } - - private String postToServer(String url, String json) throws IOException { - MediaType JSON - = MediaType.parse("application/json; charset=utf-8"); - - RequestBody body = RequestBody.create(JSON, json); - Log.d(TAG, "post URL = " + url); - Request request = new Request.Builder() - .url(url) - .post(body) - .build(); - Response response = mHttpClient.newCall(request).execute(); - return response.body().string(); - } - - private InputStream postToServerForOctets(String url, String json) throws IOException { - MediaType JSON - = MediaType.parse("application/json; charset=utf-8"); - RequestBody body = RequestBody.create(JSON, json); - - Request request = new Request.Builder() - .url(url) - .post(body) - .build(); - - Response response = mHttpClient.newCall(request).execute(); - return response.body().byteStream(); - } - - @SuppressWarnings("unused") - public void signIn(Context context, SignInCallback signInCallback) { - try { - String signInURL = URL_PREFIX + SERVICE_SIGN_IN; - AppSignInRequest appSignInRequest = new AppSignInRequest(); - - ApplicationInfo appInfo = context.getPackageManager() - .getApplicationInfo(context.getPackageName(), - PackageManager.GET_META_DATA); - String appKey = appInfo.metaData.getString("irext_app_key"); - String appSecret = appInfo.metaData.getString("irext_app_secret"); - - appSignInRequest.setAppKey(appKey); - appSignInRequest.setAppSecret(appSecret); - appSignInRequest.setAppType(0); - - String packageName = context.getApplicationContext().getPackageName(); - appSignInRequest.setAndroidPackageName(packageName); - - String signature = PackageUtils.getCertificateSHA1Fingerprint(context); - - appSignInRequest.setAndroidSignature(signature); - String bodyJson = appSignInRequest.toJson(); - - Log.d(TAG, "Android APP example sign-in request data : " + bodyJson); - String response = postToServer(signInURL, bodyJson); - - Log.d(TAG, "Android APP example sign-in response data : " + response); - LoginResponse loginResponse = new Gson().fromJson(response, LoginResponse.class); - if (loginResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { - UserApp userApp = loginResponse.getEntity(); - if (0 != userApp.getId() && null != userApp.getToken()) { - id = userApp.getId(); - token = userApp.getToken(); - signInCallback.onSignInSuccess(userApp); - } else { - signInCallback.onSignInFailed(); - } - } - } catch (Exception e) { - e.printStackTrace(); - signInCallback.onSignInError(); - } - } - - @SuppressWarnings("unused") - public void listCategories(int from, int count, ListCategoriesCallback listCategoriesCallback) { - String listCategoriesURL = URL_PREFIX + SERVICE_LIST_CATEGORIES; - ListCategoriesRequest listCategoriesRequest = new ListCategoriesRequest(); - listCategoriesRequest.setId(id); - listCategoriesRequest.setToken(token); - listCategoriesRequest.setFrom(from); - listCategoriesRequest.setCount(count); - String bodyJson = listCategoriesRequest.toJson(); - - try { - String response = postToServer(listCategoriesURL, bodyJson); - CategoriesResponse categoriesResponse = new Gson().fromJson(response, CategoriesResponse.class); - - if(categoriesResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { - listCategoriesCallback.onListCategoriesSuccess(categoriesResponse.getEntity()); - } else { - listCategoriesCallback.onListCategoriesFailed(); - } - } catch (Exception e) { - e.printStackTrace(); - listCategoriesCallback.onListCategoriesError(); - } - } - - @SuppressWarnings("unused") - public void listBrands(int categoryId, int from, int count, - ListBrandsCallback listBrandsCallback) { - String listBrandsURL = URL_PREFIX + SERVICE_LIST_BRANDS; - ListBrandsRequest listBrandsRequest = new ListBrandsRequest(); - listBrandsRequest.setId(id); - listBrandsRequest.setToken(token); - listBrandsRequest.setCategoryId(categoryId); - listBrandsRequest.setFrom(from); - listBrandsRequest.setCount(count); - String bodyJson = listBrandsRequest.toJson(); - - try { - String response = postToServer(listBrandsURL, bodyJson); - BrandsResponse brandsResponse = new Gson().fromJson(response, BrandsResponse.class); - - if (brandsResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { - listBrandsCallback.onListBrandsSuccess(brandsResponse.getEntity()); - } else { - listBrandsCallback.onListBrandsFailed(); - } - } catch (Exception e) { - e.printStackTrace(); - listBrandsCallback.onListBrandsError(); - } - } - - @SuppressWarnings("unused") - public void listProvinces(ListProvincesCallback listProvincesCallback) { - String listProvincesURL = URL_PREFIX + SERVICE_LIST_PROVINCES; - ListCitiesRequest listCitiesRequest = new ListCitiesRequest(); - listCitiesRequest.setId(id); - listCitiesRequest.setToken(token); - String bodyJson = listCitiesRequest.toJson(); - - try { - String response = postToServer(listProvincesURL, bodyJson); - CitiesResponse citiesResponse = new Gson().fromJson(response, CitiesResponse.class); - - if (citiesResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { - listProvincesCallback.onListProvincesSuccess(citiesResponse.getEntity()); - } else { - listProvincesCallback.onListProvincesFailed(); - } - } catch (Exception e) { - e.printStackTrace(); - listProvincesCallback.onListProvincesError(); - } - } - - @SuppressWarnings("unused") - public void listCities(String prefix, ListCitiesCallback listCitiesCallback) { - String listCitiesURL = URL_PREFIX + SERVICE_LIST_CITIES; - ListCitiesRequest listCitiesRequest = new ListCitiesRequest(); - listCitiesRequest.setId(id); - listCitiesRequest.setToken(token); - listCitiesRequest.setProvincePrefix(prefix); - String bodyJson = listCitiesRequest.toJson(); - - try { - String response = postToServer(listCitiesURL, bodyJson); - CitiesResponse citiesResponse = new Gson().fromJson(response, CitiesResponse.class); - - if (citiesResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { - listCitiesCallback.onListCitiesSuccess(citiesResponse.getEntity()); - } else { - listCitiesCallback.onListCitiesFailed(); - } - } catch (Exception e) { - e.printStackTrace(); - listCitiesCallback.onListCitiesError(); - } - } - - @SuppressWarnings("unused") - public void listOperators(String cityCode, - ListOperatersCallback listOperatersCallback) { - String listOperatorsURL = URL_PREFIX + SERVICE_LIST_OPERATORS; - ListOperatorsRequest listOperatorsRequest = new ListOperatorsRequest(); - listOperatorsRequest.setId(id); - listOperatorsRequest.setToken(token); - listOperatorsRequest.setCityCode(cityCode); - listOperatorsRequest.setFrom(0); - listOperatorsRequest.setCount(20); - String bodyJson = listOperatorsRequest.toJson(); - - try { - String response = postToServer(listOperatorsURL, bodyJson); - OperatorsResponse operatorsResponse = new Gson().fromJson(response, OperatorsResponse.class); - - if (operatorsResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { - listOperatersCallback.onListOperatorsSuccess(operatorsResponse.getEntity()); - } else { - listOperatersCallback.onListOperatorsFailed(); - } - } catch (Exception e) { - e.printStackTrace(); - listOperatersCallback.onListOperatorsError(); - } - } - - @SuppressWarnings("unused") - public void listRemoteIndexes(int categoryId, - int brandId, - String cityCode, - String operatorId, - ListIndexesCallback onListIndexCallback) { - String listIndexesURL = URL_PREFIX + SERVICE_LIST_INDEXES; - ListIndexesRequest listIndexesRequest = new ListIndexesRequest(); - listIndexesRequest.setId(id); - listIndexesRequest.setToken(token); - listIndexesRequest.setCategoryId(categoryId); - listIndexesRequest.setBrandId(brandId); - listIndexesRequest.setCityCode(cityCode); - listIndexesRequest.setOperatorId(operatorId); - listIndexesRequest.setFrom(0); - listIndexesRequest.setCount(20); - String bodyJson = listIndexesRequest.toJson(); - - try { - String response = postToServer(listIndexesURL, bodyJson); - - IndexesResponse indexesResponse = new Gson().fromJson(response, IndexesResponse.class); - - if (indexesResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { - onListIndexCallback.onListIndexesSuccess(indexesResponse.getEntity()); - } else { - onListIndexCallback.onListIndexesFailed(); - } - } catch (Exception e) { - e.printStackTrace(); - onListIndexCallback.onListIndexesError(); - } - } - - @SuppressWarnings("unused") - public void downloadBin(String remoteMap, int indexId, - DownloadBinCallback downloadBinCallback) { - String fileName = IR_BIN_FILE_PREFIX + remoteMap + IR_BIN_FILE_SUFFIX; - String downloadURL = IR_BIN_DOWNLOAD_PREFIX + fileName; - DownloadBinaryRequest downloadBinaryRequest = new DownloadBinaryRequest(); - downloadBinaryRequest.setId(id); - downloadBinaryRequest.setToken(token); - downloadBinaryRequest.setIndexId(indexId); - - String bodyJson = downloadBinaryRequest.toJson(); - - if (null != bodyJson) { - try { - InputStream binStream = getFileByteStreamByURL(downloadURL); - - if (null != binStream) { - downloadBinCallback.onDownloadBinSuccess(binStream); - } else { - downloadBinCallback.onDownloadBinFailed(); - } - } catch (IOException e) { - e.printStackTrace(); - downloadBinCallback.onDownloadBinError(); - } - } - } - - @SuppressWarnings("unused") - @Deprecated - public int[] decodeIR(int indexId) { - String decodeURL = URL_PREFIX + SERVICE_ONLINE_DECODE; - DecodeRequest decodeRequest = new DecodeRequest(); - decodeRequest.setId(id); - decodeRequest.setToken(token); - decodeRequest.setIndexId(indexId); - - String bodyJson = decodeRequest.toJson(); - - if (null != bodyJson) { - try { - String response = postToServer(decodeURL, bodyJson); - - DecodeResponse decodeResponse = new Gson().fromJson(response, DecodeResponse.class); - - if (decodeResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { - return decodeResponse.getEntity(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - return null; - } -} +package net.irext.webapi; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.util.Log; + +import com.google.gson.Gson; +import net.irext.webapi.model.*; +import net.irext.webapi.utils.Constants; +import net.irext.webapi.request.*; +import net.irext.webapi.response.*; +import net.irext.webapi.utils.PackageUtils; +import net.irext.webapi.WebAPICallbacks.*; + +import okhttp3.*; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Filename: WebAPIs.java + * Revised: Date: 2017-03-30 + * Revision: Revision: 1.0 + *

+ * Description: HTTP Request initializer + *

+ * Revision log: + * 2017-03-30: created by strawmanbobi + */ +public class WebAPIs { + + @SuppressWarnings("all") + private static final String TAG = WebAPIs.class.getSimpleName(); + + private static WebAPIs mInstance = null; + + private static final String DEFAULT_ADDRESS = "http://srv.irext.net"; + private static final String DEFAULT_APP = "/irext-server"; + private static String URL_PREFIX = DEFAULT_ADDRESS + DEFAULT_APP; + + // download bin from OSS + private static final String IR_BIN_FILE_PREFIX = "irda_"; + private static final String IR_BIN_FILE_SUFFIX = ".bin"; + private static final String IR_BIN_DOWNLOAD_PREFIX = "http://irext-debug.oss-cn-hangzhou.aliyuncs.com/"; + + private static final String SERVICE_SIGN_IN = "/app/app_login"; + private static final String SERVICE_LIST_CATEGORIES = "/indexing/list_categories"; + private static final String SERVICE_LIST_BRANDS = "/indexing/list_brands"; + private static final String SERVICE_LIST_PROVINCES = "/indexing/list_provinces"; + private static final String SERVICE_LIST_CITIES = "/indexing/list_cities"; + private static final String SERVICE_LIST_OPERATORS = "/indexing/list_operators"; + private static final String SERVICE_LIST_INDEXES = "/indexing/list_indexes"; + private static final String SERVICE_DOWNLOAD_BIN = "/operation/download_bin"; + private static final String SERVICE_ONLINE_DECODE = "/operation/decode"; + + private int id; + private String token; + + private OkHttpClient mHttpClient; + + private WebAPIs(String address, String appName) { + if (null != address && null != appName) { + URL_PREFIX = address + appName; + } + mHttpClient = new OkHttpClient(); + } + + private static void initializeInstance(String address, String appName) { + mInstance = new WebAPIs(address, appName); + } + + @SuppressWarnings("unused") + public static WebAPIs getInstance(String address, String appName) { + if (null == mInstance) { + initializeInstance(address, appName); + } + return mInstance; + } + + private InputStream getFileByteStreamByURL(String url) throws IOException { + Request request = new Request.Builder() + .url(url) + .get() + .build(); + + Response response = new OkHttpClient().newCall(request).execute(); + return response.body().byteStream(); + } + + private String postToServer(String url, String json) throws IOException { + MediaType JSON + = MediaType.parse("application/json; charset=utf-8"); + + RequestBody body = RequestBody.create(JSON, json); + Log.d(TAG, "post URL = " + url); + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + Response response = mHttpClient.newCall(request).execute(); + return response.body().string(); + } + + private InputStream postToServerForOctets(String url, String json) throws IOException { + MediaType JSON + = MediaType.parse("application/json; charset=utf-8"); + RequestBody body = RequestBody.create(JSON, json); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + Response response = mHttpClient.newCall(request).execute(); + return response.body().byteStream(); + } + + @SuppressWarnings("unused") + public void signIn(Context context, SignInCallback signInCallback) { + try { + String signInURL = URL_PREFIX + SERVICE_SIGN_IN; + AppSignInRequest appSignInRequest = new AppSignInRequest(); + + ApplicationInfo appInfo = context.getPackageManager() + .getApplicationInfo(context.getPackageName(), + PackageManager.GET_META_DATA); + String appKey = appInfo.metaData.getString("irext_app_key"); + String appSecret = appInfo.metaData.getString("irext_app_secret"); + + appSignInRequest.setAppKey(appKey); + appSignInRequest.setAppSecret(appSecret); + appSignInRequest.setAppType(0); + + String packageName = context.getApplicationContext().getPackageName(); + appSignInRequest.setAndroidPackageName(packageName); + + String signature = PackageUtils.getCertificateSHA1Fingerprint(context); + + appSignInRequest.setAndroidSignature(signature); + String bodyJson = appSignInRequest.toJson(); + + Log.d(TAG, "Android APP example sign-in request data : " + bodyJson); + String response = postToServer(signInURL, bodyJson); + + Log.d(TAG, "Android APP example sign-in response data : " + response); + LoginResponse loginResponse = new Gson().fromJson(response, LoginResponse.class); + if (loginResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { + UserApp userApp = loginResponse.getEntity(); + if (0 != userApp.getId() && null != userApp.getToken()) { + id = userApp.getId(); + token = userApp.getToken(); + signInCallback.onSignInSuccess(userApp); + } else { + signInCallback.onSignInFailed(); + } + } + } catch (Exception e) { + e.printStackTrace(); + signInCallback.onSignInError(); + } + } + + @SuppressWarnings("unused") + public void listCategories(int from, int count, ListCategoriesCallback listCategoriesCallback) { + String listCategoriesURL = URL_PREFIX + SERVICE_LIST_CATEGORIES; + ListCategoriesRequest listCategoriesRequest = new ListCategoriesRequest(); + listCategoriesRequest.setId(id); + listCategoriesRequest.setToken(token); + listCategoriesRequest.setFrom(from); + listCategoriesRequest.setCount(count); + String bodyJson = listCategoriesRequest.toJson(); + + try { + String response = postToServer(listCategoriesURL, bodyJson); + CategoriesResponse categoriesResponse = new Gson().fromJson(response, CategoriesResponse.class); + + if(categoriesResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { + listCategoriesCallback.onListCategoriesSuccess(categoriesResponse.getEntity()); + } else { + listCategoriesCallback.onListCategoriesFailed(); + } + } catch (Exception e) { + e.printStackTrace(); + listCategoriesCallback.onListCategoriesError(); + } + } + + @SuppressWarnings("unused") + public void listBrands(int categoryId, int from, int count, + ListBrandsCallback listBrandsCallback) { + String listBrandsURL = URL_PREFIX + SERVICE_LIST_BRANDS; + ListBrandsRequest listBrandsRequest = new ListBrandsRequest(); + listBrandsRequest.setId(id); + listBrandsRequest.setToken(token); + listBrandsRequest.setCategoryId(categoryId); + listBrandsRequest.setFrom(from); + listBrandsRequest.setCount(count); + String bodyJson = listBrandsRequest.toJson(); + + try { + String response = postToServer(listBrandsURL, bodyJson); + BrandsResponse brandsResponse = new Gson().fromJson(response, BrandsResponse.class); + + if (brandsResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { + listBrandsCallback.onListBrandsSuccess(brandsResponse.getEntity()); + } else { + listBrandsCallback.onListBrandsFailed(); + } + } catch (Exception e) { + e.printStackTrace(); + listBrandsCallback.onListBrandsError(); + } + } + + @SuppressWarnings("unused") + public void listProvinces(ListProvincesCallback listProvincesCallback) { + String listProvincesURL = URL_PREFIX + SERVICE_LIST_PROVINCES; + ListCitiesRequest listCitiesRequest = new ListCitiesRequest(); + listCitiesRequest.setId(id); + listCitiesRequest.setToken(token); + String bodyJson = listCitiesRequest.toJson(); + + try { + String response = postToServer(listProvincesURL, bodyJson); + CitiesResponse citiesResponse = new Gson().fromJson(response, CitiesResponse.class); + + if (citiesResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { + listProvincesCallback.onListProvincesSuccess(citiesResponse.getEntity()); + } else { + listProvincesCallback.onListProvincesFailed(); + } + } catch (Exception e) { + e.printStackTrace(); + listProvincesCallback.onListProvincesError(); + } + } + + @SuppressWarnings("unused") + public void listCities(String prefix, ListCitiesCallback listCitiesCallback) { + String listCitiesURL = URL_PREFIX + SERVICE_LIST_CITIES; + ListCitiesRequest listCitiesRequest = new ListCitiesRequest(); + listCitiesRequest.setId(id); + listCitiesRequest.setToken(token); + listCitiesRequest.setProvincePrefix(prefix); + String bodyJson = listCitiesRequest.toJson(); + + try { + String response = postToServer(listCitiesURL, bodyJson); + CitiesResponse citiesResponse = new Gson().fromJson(response, CitiesResponse.class); + + if (citiesResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { + listCitiesCallback.onListCitiesSuccess(citiesResponse.getEntity()); + } else { + listCitiesCallback.onListCitiesFailed(); + } + } catch (Exception e) { + e.printStackTrace(); + listCitiesCallback.onListCitiesError(); + } + } + + @SuppressWarnings("unused") + public void listOperators(String cityCode, + ListOperatersCallback listOperatersCallback) { + String listOperatorsURL = URL_PREFIX + SERVICE_LIST_OPERATORS; + ListOperatorsRequest listOperatorsRequest = new ListOperatorsRequest(); + listOperatorsRequest.setId(id); + listOperatorsRequest.setToken(token); + listOperatorsRequest.setCityCode(cityCode); + listOperatorsRequest.setFrom(0); + listOperatorsRequest.setCount(20); + String bodyJson = listOperatorsRequest.toJson(); + + try { + String response = postToServer(listOperatorsURL, bodyJson); + OperatorsResponse operatorsResponse = new Gson().fromJson(response, OperatorsResponse.class); + + if (operatorsResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { + listOperatersCallback.onListOperatorsSuccess(operatorsResponse.getEntity()); + } else { + listOperatersCallback.onListOperatorsFailed(); + } + } catch (Exception e) { + e.printStackTrace(); + listOperatersCallback.onListOperatorsError(); + } + } + + @SuppressWarnings("unused") + public void listRemoteIndexes(int categoryId, + int brandId, + String cityCode, + String operatorId, + ListIndexesCallback onListIndexCallback) { + String listIndexesURL = URL_PREFIX + SERVICE_LIST_INDEXES; + ListIndexesRequest listIndexesRequest = new ListIndexesRequest(); + listIndexesRequest.setId(id); + listIndexesRequest.setToken(token); + listIndexesRequest.setCategoryId(categoryId); + listIndexesRequest.setBrandId(brandId); + listIndexesRequest.setCityCode(cityCode); + listIndexesRequest.setOperatorId(operatorId); + listIndexesRequest.setFrom(0); + listIndexesRequest.setCount(20); + String bodyJson = listIndexesRequest.toJson(); + + try { + String response = postToServer(listIndexesURL, bodyJson); + + IndexesResponse indexesResponse = new Gson().fromJson(response, IndexesResponse.class); + + if (indexesResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { + onListIndexCallback.onListIndexesSuccess(indexesResponse.getEntity()); + } else { + onListIndexCallback.onListIndexesFailed(); + } + } catch (Exception e) { + e.printStackTrace(); + onListIndexCallback.onListIndexesError(); + } + } + + @SuppressWarnings("unused") + public void downloadBin(String remoteMap, int indexId, + DownloadBinCallback downloadBinCallback) { + String fileName = IR_BIN_FILE_PREFIX + remoteMap + IR_BIN_FILE_SUFFIX; + String downloadURL = IR_BIN_DOWNLOAD_PREFIX + fileName; + DownloadBinaryRequest downloadBinaryRequest = new DownloadBinaryRequest(); + downloadBinaryRequest.setId(id); + downloadBinaryRequest.setToken(token); + downloadBinaryRequest.setIndexId(indexId); + + String bodyJson = downloadBinaryRequest.toJson(); + + if (null != bodyJson) { + try { + InputStream binStream = getFileByteStreamByURL(downloadURL); + + if (null != binStream) { + downloadBinCallback.onDownloadBinSuccess(binStream); + } else { + downloadBinCallback.onDownloadBinFailed(); + } + } catch (IOException e) { + e.printStackTrace(); + downloadBinCallback.onDownloadBinError(); + } + } + } + + @SuppressWarnings("unused") + @Deprecated + public int[] decodeIR(int indexId) { + String decodeURL = URL_PREFIX + SERVICE_ONLINE_DECODE; + DecodeRequest decodeRequest = new DecodeRequest(); + decodeRequest.setId(id); + decodeRequest.setToken(token); + decodeRequest.setIndexId(indexId); + + String bodyJson = decodeRequest.toJson(); + + if (null != bodyJson) { + try { + String response = postToServer(decodeURL, bodyJson); + + DecodeResponse decodeResponse = new Gson().fromJson(response, DecodeResponse.class); + + if (decodeResponse.getStatus().getCode() == Constants.ERROR_CODE_SUCCESS) { + return decodeResponse.getEntity(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } +} diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_ac_apply.h b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_ac_apply.h index 725d2e2..af68831 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_ac_apply.h +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_ac_apply.h @@ -1,47 +1,47 @@ -/************************************************************************************** -Filename: ir_ac_apply.h -Revised: Date: 2016-10-12 -Revision: Revision: 1.0 - -Description: This file provides methods for AC IR applying functionalities - -Revision log: -* 2016-10-12: created by strawmanbobi -**************************************************************************************/ - -#ifndef _IR_APPLY_H_ -#define _IR_APPLY_H_ - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "OCUnusedMacroInspection" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "ir_decode.h" - -#define MIN_TAG_LENGTH_TYPE_1 4 -#define MIN_TAG_LENGTH_TYPE_2 6 - -INT8 apply_power(t_remote_ac_status ac_status, UINT8 function_code); - -INT8 apply_mode(t_remote_ac_status ac_status, UINT8 function_code); - -INT8 apply_wind_speed(t_remote_ac_status ac_status, UINT8 function_code); - -INT8 apply_swing(t_remote_ac_status ac_status, UINT8 function_code); - -INT8 apply_temperature(t_remote_ac_status ac_status, UINT8 function_code); - -INT8 apply_function(struct ac_protocol *protocol, UINT8 function); - -INT8 apply_checksum(struct ac_protocol *protocol); - -#ifdef __cplusplus -} -#endif - +/************************************************************************************** +Filename: ir_ac_apply.h +Revised: Date: 2016-10-12 +Revision: Revision: 1.0 + +Description: This file provides methods for AC IR applying functionalities + +Revision log: +* 2016-10-12: created by strawmanbobi +**************************************************************************************/ + +#ifndef _IR_APPLY_H_ +#define _IR_APPLY_H_ + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "OCUnusedMacroInspection" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "ir_decode.h" + +#define MIN_TAG_LENGTH_TYPE_1 4 +#define MIN_TAG_LENGTH_TYPE_2 6 + +INT8 apply_power(t_remote_ac_status ac_status, UINT8 function_code); + +INT8 apply_mode(t_remote_ac_status ac_status, UINT8 function_code); + +INT8 apply_wind_speed(t_remote_ac_status ac_status, UINT8 function_code); + +INT8 apply_swing(t_remote_ac_status ac_status, UINT8 function_code); + +INT8 apply_temperature(t_remote_ac_status ac_status, UINT8 function_code); + +INT8 apply_function(struct ac_protocol *protocol, UINT8 function); + +INT8 apply_checksum(struct ac_protocol *protocol); + +#ifdef __cplusplus +} +#endif + #endif // _IR_APPLY_H_ \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_ac_control.h b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_ac_control.h index a7ed296..60d8722 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_ac_control.h +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_ac_control.h @@ -1,443 +1,443 @@ -/************************************************************************************** -Filename: ir_ac_control.h -Revised: Date: 2016-12-31 -Revision: Revision: 1.0 - -Description: This file provides methods for AC IR control - -Revision log: -* 2016-10-12: created by strawmanbobi -**************************************************************************************/ -#ifndef _IR_DECODER_IR_AC_CONTROL_H -#define _IR_DECODER_IR_AC_CONTROL_H - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "ir_defs.h" - - -#define TAG_COUNT_FOR_PROTOCOL 29 - -#define TAG_INVALID 0xffff - -#define MAX_DELAYCODE_NUM 16 -#define MAX_BITNUM 16 - -#define AC_PARAMETER_TYPE_1 0 -#define AC_PARAMETER_TYPE_2 1 - -typedef enum -{ - AC_POWER_ON = 0, - AC_POWER_OFF, - AC_POWER_MAX -} t_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 -} t_ac_temperature; - -typedef enum -{ - AC_MODE_COOL = 0, - AC_MODE_HEAT, - AC_MODE_AUTO, - AC_MODE_FAN, - AC_MODE_DRY, - AC_MODE_MAX -} t_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, -} t_ac_function; - -typedef enum -{ - AC_WS_AUTO = 0, - AC_WS_LOW, - AC_WS_MEDIUM, - AC_WS_HIGH, - AC_WS_MAX -} t_ac_wind_speed; - -typedef enum -{ - AC_SWING_ON = 0, - AC_SWING_OFF, - AC_SWING_MAX -} t_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, -} t_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 -} t_ac_apply; - -typedef struct _ac_hex -{ - UINT8 len; - UINT8 *data; -} t_ac_hex; - -typedef struct _ac_level -{ - UINT16 low; - UINT16 high; -} t_ac_level; - -typedef struct _ac_bootcode -{ - UINT16 len; - UINT16 data[16]; -} t_ac_bootcode; - -typedef struct _ac_delaycode -{ - INT16 pos; - UINT16 time[8]; - UINT16 time_cnt; -} t_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; -} t_tag_comp; - -typedef struct _tag_swing_info -{ - swing_type type; - UINT8 mode_count; - UINT8 dir_index; -} t_swing_info; - -typedef struct _tag_power_1 -{ - UINT8 len; - t_tag_comp comp_data[AC_POWER_MAX]; -} t_power_1; - -typedef struct _tag_temp_1 -{ - UINT8 len; - UINT8 type; - t_tag_comp comp_data[AC_TEMP_MAX]; -} t_temp_1; - -typedef struct tag_mode_1 -{ - UINT8 len; - t_tag_comp comp_data[AC_MODE_MAX]; -} t_mode_1; - -typedef struct tag_speed_1 -{ - UINT8 len; - t_tag_comp comp_data[AC_WS_MAX]; -} t_speed_1; - -typedef struct tag_swing_1 -{ - UINT8 len; - UINT16 count; - t_tag_comp *comp_data; -} t_swing_1; - -typedef struct tag_temp_2 -{ - UINT8 len; - UINT8 type; - t_tag_comp comp_data[AC_TEMP_MAX]; -} t_temp_2; - -typedef struct tag_mode_2 -{ - UINT8 len; - t_tag_comp comp_data[AC_MODE_MAX]; -} t_mode_2; - -typedef struct tag_speed_2 -{ - UINT8 len; - t_tag_comp comp_data[AC_WS_MAX]; -} t_speed_2; - -typedef struct tag_swing_2 -{ - UINT8 len; - UINT16 count; - t_tag_comp *comp_data; -} t_swing_2; - -#if defined SUPPORT_HORIZONTAL_SWING -typedef struct tag_horiswing_1 -{ - UINT16 len; - t_tag_comp comp_data[AC_HORI_SWING_MAX]; -} hori_swing_1; -#endif - -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; -} t_tag_checksum_data; - -typedef struct tag_checksum -{ - UINT8 len; - UINT16 count; - t_tag_checksum_data *checksum_data; -} t_checksum; - -typedef struct tag_function_1 -{ - UINT8 len; - t_tag_comp comp_data[AC_FUNCTION_MAX - 1]; -} t_function_1; - -typedef struct tag_function_2 -{ - UINT8 len; - t_tag_comp comp_data[AC_FUNCTION_MAX - 1]; -} t_function_2; - -typedef struct tag_solo_code -{ - UINT8 len; - UINT8 solo_func_count; - UINT8 solo_function_codes[AC_FUNCTION_MAX - 1]; -} t_solo_code; - -typedef struct _ac_bitnum -{ - INT16 pos; - UINT16 bits; -} t_ac_bit_num; - -typedef enum -{ - N_COOL = 0, - N_HEAT, - N_AUTO, - N_FAN, - N_DRY, - N_MODE_MAX, -} t_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, -} t_checksum_type; - -typedef struct _ac_n_mode_info -{ - UINT8 enable; - UINT8 all_speed; - UINT8 all_temp; - UINT8 temp[AC_TEMP_MAX]; - UINT8 temp_cnt; - UINT8 speed[AC_WS_MAX]; - UINT8 speed_cnt; -} t_ac_n_mode_info; - -typedef struct ac_protocol -{ - UINT8 endian; - // t_ac_hex default_code; - t_ac_hex default_code; - t_ac_level zero; - t_ac_level one; - t_ac_bootcode boot_code; - t_ac_delaycode dc[MAX_DELAYCODE_NUM]; - t_power_1 power1; - t_temp_1 temp1; - t_mode_1 mode1; - t_speed_1 speed1; - t_swing_1 swing1; - t_checksum checksum; - - t_function_1 function1; - t_function_2 function2; - - t_temp_2 temp2; - t_mode_2 mode2; - t_speed_2 speed2; - t_swing_2 swing2; - - t_swing_info si; - t_solo_code sc; - - UINT8 swing_status; - - BOOL change_wind_direction; - - UINT16 dc_cnt; - t_ac_bit_num bit_num[MAX_BITNUM]; - UINT16 bit_num_cnt; - UINT16 repeat_times; - t_ac_n_mode_info n_mode[N_MODE_MAX]; - UINT16 code_cnt; - UINT8 last_bit; - UINT16 *time; - UINT8 solo_function_mark; - - UINT16 frame_length; -} t_ac_protocol; - -typedef struct tag_head -{ - UINT16 tag; - UINT16 len; - UINT16 offset; - UINT8 *p_data; -} t_tag_head; - -struct ir_bin_buffer -{ - UINT8 *data; - UINT16 len; - UINT16 offset; -}; - -typedef struct REMOTE_AC_STATUS -{ - t_ac_power ac_power; - t_ac_temperature ac_temp; - t_ac_mode ac_mode; - t_ac_swing ac_wind_dir; - t_ac_wind_speed ac_wind_speed; - UINT8 ac_display; - UINT8 ac_sleep; - UINT8 ac_timer; -} t_remote_ac_status; - -// function polymorphism -typedef INT8 (*lp_apply_ac_parameter)(t_remote_ac_status ac_status, UINT8 function_code); - -#define TAG_AC_BOOT_CODE 1 -#define TAG_AC_ZERO 2 -#define TAG_AC_ONE 3 -#define TAG_AC_DELAY_CODE 4 -#define TAG_AC_FRAME_LENGTH 5 -#define TAG_AC_ENDIAN 6 -#define TAG_AC_LAST_BIT 7 - -#define TAG_AC_POWER_1 21 -#define TAG_AC_DEFAULT_CODE 22 -#define TAG_AC_TEMP_1 23 -#define TAG_AC_MODE_1 24 -#define TAG_AC_SPEED_1 25 -#define TAG_AC_SWING_1 26 -#define TAG_AC_CHECKSUM_TYPE 27 -#define TAG_AC_SOLO_FUNCTION 28 -#define TAG_AC_FUNCTION_1 29 -#define TAG_AC_TEMP_2 30 -#define TAG_AC_MODE_2 31 -#define TAG_AC_SPEED_2 32 -#define TAG_AC_SWING_2 33 -#define TAG_AC_FUNCTION_2 34 - -#define TAG_AC_BAN_FUNCTION_IN_COOL_MODE 41 -#define TAG_AC_BAN_FUNCTION_IN_HEAT_MODE 42 -#define TAG_AC_BAN_FUNCTION_IN_AUTO_MODE 43 -#define TAG_AC_BAN_FUNCTION_IN_FAN_MODE 44 -#define TAG_AC_BAN_FUNCTION_IN_DRY_MODE 45 -#define TAG_AC_SWING_INFO 46 -#define TAG_AC_REPEAT_TIMES 47 -#define TAG_AC_BIT_NUM 48 - - -// definition about size - -#define PROTOCOL_SIZE (sizeof(t_ac_protocol)) - -/* exported variables */ -extern UINT8 *ir_hex_code; -extern UINT8 ir_hex_len; -extern t_ac_protocol *context; - - -extern INT8 ir_ac_lib_parse(); - -extern INT8 free_ac_context(); - -extern BOOL is_solo_function(UINT8 function_code); - -#ifdef __cplusplus -} -#endif - -#endif // _IR_DECODER_IR_AC_CONTROL_H +/************************************************************************************** +Filename: ir_ac_control.h +Revised: Date: 2016-12-31 +Revision: Revision: 1.0 + +Description: This file provides methods for AC IR control + +Revision log: +* 2016-10-12: created by strawmanbobi +**************************************************************************************/ +#ifndef _IR_DECODER_IR_AC_CONTROL_H +#define _IR_DECODER_IR_AC_CONTROL_H + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "ir_defs.h" + + +#define TAG_COUNT_FOR_PROTOCOL 29 + +#define TAG_INVALID 0xffff + +#define MAX_DELAYCODE_NUM 16 +#define MAX_BITNUM 16 + +#define AC_PARAMETER_TYPE_1 0 +#define AC_PARAMETER_TYPE_2 1 + +typedef enum +{ + AC_POWER_ON = 0, + AC_POWER_OFF, + AC_POWER_MAX +} t_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 +} t_ac_temperature; + +typedef enum +{ + AC_MODE_COOL = 0, + AC_MODE_HEAT, + AC_MODE_AUTO, + AC_MODE_FAN, + AC_MODE_DRY, + AC_MODE_MAX +} t_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, +} t_ac_function; + +typedef enum +{ + AC_WS_AUTO = 0, + AC_WS_LOW, + AC_WS_MEDIUM, + AC_WS_HIGH, + AC_WS_MAX +} t_ac_wind_speed; + +typedef enum +{ + AC_SWING_ON = 0, + AC_SWING_OFF, + AC_SWING_MAX +} t_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, +} t_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 +} t_ac_apply; + +typedef struct _ac_hex +{ + UINT8 len; + UINT8 *data; +} t_ac_hex; + +typedef struct _ac_level +{ + UINT16 low; + UINT16 high; +} t_ac_level; + +typedef struct _ac_bootcode +{ + UINT16 len; + UINT16 data[16]; +} t_ac_bootcode; + +typedef struct _ac_delaycode +{ + INT16 pos; + UINT16 time[8]; + UINT16 time_cnt; +} t_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; +} t_tag_comp; + +typedef struct _tag_swing_info +{ + swing_type type; + UINT8 mode_count; + UINT8 dir_index; +} t_swing_info; + +typedef struct _tag_power_1 +{ + UINT8 len; + t_tag_comp comp_data[AC_POWER_MAX]; +} t_power_1; + +typedef struct _tag_temp_1 +{ + UINT8 len; + UINT8 type; + t_tag_comp comp_data[AC_TEMP_MAX]; +} t_temp_1; + +typedef struct tag_mode_1 +{ + UINT8 len; + t_tag_comp comp_data[AC_MODE_MAX]; +} t_mode_1; + +typedef struct tag_speed_1 +{ + UINT8 len; + t_tag_comp comp_data[AC_WS_MAX]; +} t_speed_1; + +typedef struct tag_swing_1 +{ + UINT8 len; + UINT16 count; + t_tag_comp *comp_data; +} t_swing_1; + +typedef struct tag_temp_2 +{ + UINT8 len; + UINT8 type; + t_tag_comp comp_data[AC_TEMP_MAX]; +} t_temp_2; + +typedef struct tag_mode_2 +{ + UINT8 len; + t_tag_comp comp_data[AC_MODE_MAX]; +} t_mode_2; + +typedef struct tag_speed_2 +{ + UINT8 len; + t_tag_comp comp_data[AC_WS_MAX]; +} t_speed_2; + +typedef struct tag_swing_2 +{ + UINT8 len; + UINT16 count; + t_tag_comp *comp_data; +} t_swing_2; + +#if defined SUPPORT_HORIZONTAL_SWING +typedef struct tag_horiswing_1 +{ + UINT16 len; + t_tag_comp comp_data[AC_HORI_SWING_MAX]; +} hori_swing_1; +#endif + +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; +} t_tag_checksum_data; + +typedef struct tag_checksum +{ + UINT8 len; + UINT16 count; + t_tag_checksum_data *checksum_data; +} t_checksum; + +typedef struct tag_function_1 +{ + UINT8 len; + t_tag_comp comp_data[AC_FUNCTION_MAX - 1]; +} t_function_1; + +typedef struct tag_function_2 +{ + UINT8 len; + t_tag_comp comp_data[AC_FUNCTION_MAX - 1]; +} t_function_2; + +typedef struct tag_solo_code +{ + UINT8 len; + UINT8 solo_func_count; + UINT8 solo_function_codes[AC_FUNCTION_MAX - 1]; +} t_solo_code; + +typedef struct _ac_bitnum +{ + INT16 pos; + UINT16 bits; +} t_ac_bit_num; + +typedef enum +{ + N_COOL = 0, + N_HEAT, + N_AUTO, + N_FAN, + N_DRY, + N_MODE_MAX, +} t_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, +} t_checksum_type; + +typedef struct _ac_n_mode_info +{ + UINT8 enable; + UINT8 all_speed; + UINT8 all_temp; + UINT8 temp[AC_TEMP_MAX]; + UINT8 temp_cnt; + UINT8 speed[AC_WS_MAX]; + UINT8 speed_cnt; +} t_ac_n_mode_info; + +typedef struct ac_protocol +{ + UINT8 endian; + // t_ac_hex default_code; + t_ac_hex default_code; + t_ac_level zero; + t_ac_level one; + t_ac_bootcode boot_code; + t_ac_delaycode dc[MAX_DELAYCODE_NUM]; + t_power_1 power1; + t_temp_1 temp1; + t_mode_1 mode1; + t_speed_1 speed1; + t_swing_1 swing1; + t_checksum checksum; + + t_function_1 function1; + t_function_2 function2; + + t_temp_2 temp2; + t_mode_2 mode2; + t_speed_2 speed2; + t_swing_2 swing2; + + t_swing_info si; + t_solo_code sc; + + UINT8 swing_status; + + BOOL change_wind_direction; + + UINT16 dc_cnt; + t_ac_bit_num bit_num[MAX_BITNUM]; + UINT16 bit_num_cnt; + UINT16 repeat_times; + t_ac_n_mode_info n_mode[N_MODE_MAX]; + UINT16 code_cnt; + UINT8 last_bit; + UINT16 *time; + UINT8 solo_function_mark; + + UINT16 frame_length; +} t_ac_protocol; + +typedef struct tag_head +{ + UINT16 tag; + UINT16 len; + UINT16 offset; + UINT8 *p_data; +} t_tag_head; + +struct ir_bin_buffer +{ + UINT8 *data; + UINT16 len; + UINT16 offset; +}; + +typedef struct REMOTE_AC_STATUS +{ + t_ac_power ac_power; + t_ac_temperature ac_temp; + t_ac_mode ac_mode; + t_ac_swing ac_wind_dir; + t_ac_wind_speed ac_wind_speed; + UINT8 ac_display; + UINT8 ac_sleep; + UINT8 ac_timer; +} t_remote_ac_status; + +// function polymorphism +typedef INT8 (*lp_apply_ac_parameter)(t_remote_ac_status ac_status, UINT8 function_code); + +#define TAG_AC_BOOT_CODE 1 +#define TAG_AC_ZERO 2 +#define TAG_AC_ONE 3 +#define TAG_AC_DELAY_CODE 4 +#define TAG_AC_FRAME_LENGTH 5 +#define TAG_AC_ENDIAN 6 +#define TAG_AC_LAST_BIT 7 + +#define TAG_AC_POWER_1 21 +#define TAG_AC_DEFAULT_CODE 22 +#define TAG_AC_TEMP_1 23 +#define TAG_AC_MODE_1 24 +#define TAG_AC_SPEED_1 25 +#define TAG_AC_SWING_1 26 +#define TAG_AC_CHECKSUM_TYPE 27 +#define TAG_AC_SOLO_FUNCTION 28 +#define TAG_AC_FUNCTION_1 29 +#define TAG_AC_TEMP_2 30 +#define TAG_AC_MODE_2 31 +#define TAG_AC_SPEED_2 32 +#define TAG_AC_SWING_2 33 +#define TAG_AC_FUNCTION_2 34 + +#define TAG_AC_BAN_FUNCTION_IN_COOL_MODE 41 +#define TAG_AC_BAN_FUNCTION_IN_HEAT_MODE 42 +#define TAG_AC_BAN_FUNCTION_IN_AUTO_MODE 43 +#define TAG_AC_BAN_FUNCTION_IN_FAN_MODE 44 +#define TAG_AC_BAN_FUNCTION_IN_DRY_MODE 45 +#define TAG_AC_SWING_INFO 46 +#define TAG_AC_REPEAT_TIMES 47 +#define TAG_AC_BIT_NUM 48 + + +// definition about size + +#define PROTOCOL_SIZE (sizeof(t_ac_protocol)) + +/* exported variables */ +extern UINT8 *ir_hex_code; +extern UINT8 ir_hex_len; +extern t_ac_protocol *context; + + +extern INT8 ir_ac_lib_parse(); + +extern INT8 free_ac_context(); + +extern BOOL is_solo_function(UINT8 function_code); + +#ifdef __cplusplus +} +#endif + +#endif // _IR_DECODER_IR_AC_CONTROL_H diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_decode.h b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_decode.h index 54aa5c3..1e82dc6 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_decode.h +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_decode.h @@ -1,371 +1,371 @@ -/************************************************************************************** -Filename: ir_decode.h -Revised: Date: 2016-10-01 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - -#ifndef _IR_DECODE_H_ -#define _IR_DECODE_H_ - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" -#pragma ide diagnostic ignored "OCUnusedMacroInspection" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include "ir_defs.h" -#include "ir_ac_control.h" -#include "ir_tv_control.h" - -#define IR_DECODE_FAILED (-1) -#define IR_DECODE_SUCCEEDED (0) - -#define IR_TYPE_STATUS 0 -#define IR_TYPE_COMMANDS 1 - -// remote control key definition -#define KEY_TV_POWER 0 -#define KEY_TV_MUTE 1 -#define KEY_TV_UP 2 -#define KEY_TV_DOWN 3 -#define KEY_TV_LEFT 4 -#define KEY_TV_RIGHT 5 -#define KEY_TV_OK 6 -#define KEY_TV_VOL_PLUS 7 -#define KEY_TV_VOL_MINUS 8 -#define KEY_TV_BACK 9 -#define KEY_TV_INPUT 10 -#define KEY_TV_MENU 11 -#define KEY_TV_HOME 12 -#define KEY_TV_SETTINGS 13 - -#define KEY_AC_POWER 0 -#define KEY_AC_MODE_SWITCH 1 -#define KEY_AC_TEMP_PLUS 2 -#define KEY_AC_TEMP_MINUS 3 -#define KEY_AC_WIND_SPEED 9 -#define KEY_AC_WIND_SWING 10 -#define KEY_AC_WIND_FIX 11 - -#define KEY_STB_POWER 0 -#define KEY_STB_MUTE 1 -#define KEY_STB_UP 2 -#define KEY_STB_DOWN 3 -#define KEY_STB_LEFT 4 -#define KEY_STB_RIGHT 5 -#define KEY_STB_OK 6 -#define KEY_STB_VOL_PLUS 7 -#define KEY_STB_VOL_MINUS 8 -#define KEY_STB_BACK 9 -#define KEY_STB_INPUT 10 -#define KEY_STB_MENU 11 -#define KEY_STB_PAGE_UP 12 -#define KEY_STB_PAGE_DOWN 13 - -#define KEY_NETBOX_POWER 0 -#define KEY_NETBOX_UP 1 -#define KEY_NETBOX_DOWN 2 -#define KEY_NETBOX_LEFT 3 -#define KEY_NETBOX_RIGHT 4 -#define KEY_NETBOX_OK 5 -#define KEY_NETBOX_VOL_PLUS 6 -#define KEY_NETBOX_VOL_MINUS 7 -#define KEY_NETBOX_BACK 8 -#define KEY_NETBOX_MENU 9 -#define KEY_NETBOX_HOME 10 - -#define KEY_IPTV_POWER 0 -#define KEY_IPTV_MUTE 1 -#define KEY_IPTV_UP 2 -#define KEY_IPTV_DOWN 3 -#define KEY_IPTV_LEFT 4 -#define KEY_IPTV_RIGHT 5 -#define KEY_IPTV_OK 6 -#define KEY_IPTV_VOL_PLUS 7 -#define KEY_IPTV_VOL_MINUS 8 -#define KEY_IPTV_BACK 9 -#define KEY_IPTV_INPUT 10 -#define KEY_IPTV_MENU 11 -#define KEY_IPTV_PAGE_UP 12 -#define KEY_IPTV_PAGE_DOWN 13 - -#define KEY_DVD_POWER 0 -#define KEY_DVD_UP 1 -#define KEY_DVD_DOWN 2 -#define KEY_DVD_LEFT 3 -#define KEY_DVD_RIGHT 4 -#define KEY_DVD_OK 5 -#define KEY_DVD_VOL_PLUS 6 -#define KEY_DVD_VOL_MINUS 7 -#define KEY_DVD_PLAY 8 -#define KEY_DVD_PAUSE 9 -#define KEY_DVD_EJECT 10 -#define KEY_DVD_REWIND 11 -#define KEY_DVD_FASTFORWARD 12 -#define KEY_DVD_MENU 13 - -#define KEY_FAN_POWER 0 -#define KEY_FAN_WIND_PLUS 6 -#define KEY_FAN_WIND_MUNIS 7 -#define KEY_FAN_SWING 8 -#define KEY_FAN_WIND_SPEED 9 -#define KEY_FAN_WIND_TYPE 10 - -#define KEY_PROJECTOR_POWER 0 -#define KEY_PROJECTOR_UP 1 -#define KEY_PROJECTOR_DOWN 2 -#define KEY_PROJECTOR_LEFT 3 -#define KEY_PROJECTOR_RIGHT 4 -#define KEY_PROJECTOR_OK 5 -#define KEY_PROJECTOR_VOL_PLUS 6 -#define KEY_PROJECTOR_VOL_MINUS 7 -#define KEY_PROJECTOR_ZOOM_OUT 8 -#define KEY_PROJECTOR_MENU 9 -#define KEY_PROJECTOR_ZOOM_IN 10 -#define KEY_PROJECTOR_BACK 11 - -#define KEY_STEREO_POWER 0 -#define KEY_STEREO_UP 1 -#define KEY_STEREO_DOWN 2 -#define KEY_STEREO_LEFT 3 -#define KEY_STEREO_RIGHT 4 -#define KEY_STEREO_OK 5 -#define KEY_STEREO_VOL_PLUS 6 -#define KEY_STEREO_VOL_MINUS 7 -#define KEY_STEREO_MUTE 8 -#define KEY_STEREO_MENU 9 - -#define KEY_BULB_POWER 0 -#define KEY_BULB_COLOR_1 1 -#define KEY_BULB_COLOR_2 2 -#define KEY_BULB_COLOR_3 3 -#define KEY_BULB_COLOR_4 4 -#define KEY_BULB_COLOR_0 5 -#define KEY_BULB_BRIGHT_PLUS 6 -#define KEY_BULB_BRIGHT_MINUS 7 -#define KEY_BULB_BRIGHT_POWER_ON 8 -#define KEY_BULB_BRIGHT_RAINBOW 9 -#define KEY_BULB_BRIGHT_POWER_OFF 10 - -#define KEY_CLEANROBOT_POWER 0 -#define KEY_CLEANROBOT_FOWWARD 1 -#define KEY_CLEANROBOT_BACKWARD 2 -#define KEY_CLEANROBOT_LEFT 3 -#define KEY_CLEANROBOT_RIGHT 4 -#define KEY_CLEANROBOT_START 5 -#define KEY_CLEANROBOT_STOP 6 -#define KEY_CLEANROBOT_AUTO 8 -#define KEY_CLEANROBOT_SPOT 9 -#define KEY_CLEANROBOT_SPEED 10 -#define KEY_CLEANROBOT_TIMER 11 -#define KEY_CLEANROBOT_CHARGE 12 -#define KEY_CLEANROBOT_PRESERVE 13 - -#define KEY_AIRCLEANER_POWER 0 -#define KEY_AIRCLEANER_ION 5 -#define KEY_AIRCLEANER_AUTO 8 -#define KEY_AIRCLEANER_WIND_SPEED 9 -#define KEY_AIRCLEANER_MODE_SWITCH 10 -#define KEY_AIRCLEANER_TIMER 11 -#define KEY_AIRCLEANER_LIGHT 12 -#define KEY_AIRCLEANER_FORCE 13 - -#define KEY_DYSON_POWER 0 -#define KEY_DYSON_WIND_SPEED_PLUS 1 -#define KEY_DYSON_WIND_SPEED_MINUS 2 -#define KEY_DYSON_TIMER_MINUS 3 -#define KEY_DYSON_TIMER_PLUS 4 -#define KEY_DYSON_AUTO 5 -#define KEY_DYSON_TEMP_PLUS 6 -#define KEY_DYSON_TEMP_MINUS 7 -#define KEY_DYSON_SWING 8 -#define KEY_DYSON_DIFFUSION 9 -#define KEY_DYSON_FAV 10 -#define KEY_DYSON_TIMER 11 -#define KEY_DYSON_SLEEP 12 -#define KEY_DYSON_COOL 13 - -#define STANDARD_KEY_COUNT 14 -#define CHANNEL_KEY_COUNT 10 - -typedef enum -{ - REMOTE_CATEGORY_NONE = 0, - REMOTE_CATEGORY_AC = 1, - REMOTE_CATEGORY_TV = 2, - REMOTE_CATEGORY_STB = 3, - REMOTE_CATEGORY_NETBOX = 4, - REMOTE_CATEGORY_IPTV = 5, - REMOTE_CATEGORY_DVD = 6, - REMOTE_CATEGORY_FAN = 7, - REMOTE_CATEGORY_PROJECTOR = 8, - REMOTE_CATEGORY_STEREO = 9, - REMOTE_CATEGORY_LIGHT = 10, - REMOTE_CATEGORY_BSTB = 11, - REMOTE_CATEGORY_CLEANING_ROBOT = 12, - REMOTE_CATEGORY_AREMOTE_CLEANER = 13, - REMOTE_CATEGORY_DYSON = 14, - REMOTE_CATEGORY_NEXT, - REMOTE_CATEGORY_MAX = 64, -} t_remote_category; - -typedef enum -{ - SUB_CATEGORY_BINARY = 0, // deprecated - SUB_CATEGORY_QUATERNARY = 1, - SUB_CATEGORY_HEXADECIMAL = 2, - SUB_CATEGORY_NEXT = 3, - SUB_CATEGORY_MAX = 4, -} t_remote_sub_category; - -/** - * function get_lib_version - * - * description: get version of library - * - * parameters: N/A - * - * returns: the string contains library version - * - */ -extern const char* get_lib_version(); - -/** - * function ir_file_open - * - * description: open IR binary code from file - * - * parameters: category (in) - category ID get from indexing API - * sub_category (in) - subcategory ID get from indexing API - * file_name (in) - file name of IR binary - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - * - */ -extern INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name); - -/** - * function ir_binary_open - * - * description: open IR binary code from buffer - * - * parameters: category (in) - category ID get from indexing API - * sub_category (in) - subcategory ID get from indexing API - * binary (in) - pointer to binary buffer - * bin_length (in) - binary buffer size - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binary, UINT16 bin_length); - -/** - * function ir_decode - * - * description: decode IR binary into INT16 array which indicates the IR levels - * - * parameters: key_code (in) - the code of pressed key - * user_data (out) - output decoded data in INT16 array format - * ac_status(in) - pointer to AC status (optional) - * change_wind_direction (in) - if control changes wind direction for AC (for AC only) - * - * returns: length of decoded data (0 indicates decode failure) - */ -extern UINT16 ir_decode(UINT8 key_code, UINT16* user_data, t_remote_ac_status* ac_status, BOOL change_wind_direction); - -/** - * function ir_close - * - * description: close IR binary code - * - * parameters: N/A - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 ir_close(); - -/** - * function get_temperature_range - * - * description: get the supported temperature range [min, max] for the opened AC IR binary - * - * 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 - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_temperature_range(UINT8 ac_mode, INT8 *temp_min, INT8 *temp_max); - -/** - * function get_supported_mode - * - * description: get supported mode for the opened AC IR binary - * - * parameters: supported_mode (out) mode supported by the remote in lower 5 bits - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_supported_mode(UINT8 *supported_mode); - -/** - * function get_supported_wind_speed - * - * description: get supported wind speed levels for the opened AC IR binary in certain mode - * - * 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 - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_supported_wind_speed(UINT8 ac_mode, UINT8 *supported_wind_speed); - -/** - * function get_supported_swing - * - * description: get supported swing functions for the opened AC IR binary in certain mode - * - * 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 - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_supported_swing(UINT8 ac_mode, UINT8 *supported_swing); - -/** - * function get_supported_wind_direction - * - * description: get supported wind directions for the opened AC IR binary in certain mode - * - * parameters: supported_wind_direction (out) swing supported by the remote in lower 2 bits - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_supported_wind_direction(UINT8 *supported_wind_direction); - - -// private extern function -#if (defined BOARD_PC || defined BOARD_PC_DLL) -extern void ir_lib_free_inner_buffer(); -#endif - -// this function is preferred being called by JNI only -UINT16 ir_decode_combo(const UINT8 category, const UINT8 sub_category, - UINT8* binary, UINT16 bin_length, - UINT8 key_code, UINT16* user_data, - t_remote_ac_status* ac_status, BOOL change_wind_direction); - -#ifdef __cplusplus -} -#endif - +/************************************************************************************** +Filename: ir_decode.h +Revised: Date: 2016-10-01 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + +#ifndef _IR_DECODE_H_ +#define _IR_DECODE_H_ + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#pragma ide diagnostic ignored "OCUnusedMacroInspection" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "ir_defs.h" +#include "ir_ac_control.h" +#include "ir_tv_control.h" + +#define IR_DECODE_FAILED (-1) +#define IR_DECODE_SUCCEEDED (0) + +#define IR_TYPE_STATUS 0 +#define IR_TYPE_COMMANDS 1 + +// remote control key definition +#define KEY_TV_POWER 0 +#define KEY_TV_MUTE 1 +#define KEY_TV_UP 2 +#define KEY_TV_DOWN 3 +#define KEY_TV_LEFT 4 +#define KEY_TV_RIGHT 5 +#define KEY_TV_OK 6 +#define KEY_TV_VOL_PLUS 7 +#define KEY_TV_VOL_MINUS 8 +#define KEY_TV_BACK 9 +#define KEY_TV_INPUT 10 +#define KEY_TV_MENU 11 +#define KEY_TV_HOME 12 +#define KEY_TV_SETTINGS 13 + +#define KEY_AC_POWER 0 +#define KEY_AC_MODE_SWITCH 1 +#define KEY_AC_TEMP_PLUS 2 +#define KEY_AC_TEMP_MINUS 3 +#define KEY_AC_WIND_SPEED 9 +#define KEY_AC_WIND_SWING 10 +#define KEY_AC_WIND_FIX 11 + +#define KEY_STB_POWER 0 +#define KEY_STB_MUTE 1 +#define KEY_STB_UP 2 +#define KEY_STB_DOWN 3 +#define KEY_STB_LEFT 4 +#define KEY_STB_RIGHT 5 +#define KEY_STB_OK 6 +#define KEY_STB_VOL_PLUS 7 +#define KEY_STB_VOL_MINUS 8 +#define KEY_STB_BACK 9 +#define KEY_STB_INPUT 10 +#define KEY_STB_MENU 11 +#define KEY_STB_PAGE_UP 12 +#define KEY_STB_PAGE_DOWN 13 + +#define KEY_NETBOX_POWER 0 +#define KEY_NETBOX_UP 1 +#define KEY_NETBOX_DOWN 2 +#define KEY_NETBOX_LEFT 3 +#define KEY_NETBOX_RIGHT 4 +#define KEY_NETBOX_OK 5 +#define KEY_NETBOX_VOL_PLUS 6 +#define KEY_NETBOX_VOL_MINUS 7 +#define KEY_NETBOX_BACK 8 +#define KEY_NETBOX_MENU 9 +#define KEY_NETBOX_HOME 10 + +#define KEY_IPTV_POWER 0 +#define KEY_IPTV_MUTE 1 +#define KEY_IPTV_UP 2 +#define KEY_IPTV_DOWN 3 +#define KEY_IPTV_LEFT 4 +#define KEY_IPTV_RIGHT 5 +#define KEY_IPTV_OK 6 +#define KEY_IPTV_VOL_PLUS 7 +#define KEY_IPTV_VOL_MINUS 8 +#define KEY_IPTV_BACK 9 +#define KEY_IPTV_INPUT 10 +#define KEY_IPTV_MENU 11 +#define KEY_IPTV_PAGE_UP 12 +#define KEY_IPTV_PAGE_DOWN 13 + +#define KEY_DVD_POWER 0 +#define KEY_DVD_UP 1 +#define KEY_DVD_DOWN 2 +#define KEY_DVD_LEFT 3 +#define KEY_DVD_RIGHT 4 +#define KEY_DVD_OK 5 +#define KEY_DVD_VOL_PLUS 6 +#define KEY_DVD_VOL_MINUS 7 +#define KEY_DVD_PLAY 8 +#define KEY_DVD_PAUSE 9 +#define KEY_DVD_EJECT 10 +#define KEY_DVD_REWIND 11 +#define KEY_DVD_FASTFORWARD 12 +#define KEY_DVD_MENU 13 + +#define KEY_FAN_POWER 0 +#define KEY_FAN_WIND_PLUS 6 +#define KEY_FAN_WIND_MUNIS 7 +#define KEY_FAN_SWING 8 +#define KEY_FAN_WIND_SPEED 9 +#define KEY_FAN_WIND_TYPE 10 + +#define KEY_PROJECTOR_POWER 0 +#define KEY_PROJECTOR_UP 1 +#define KEY_PROJECTOR_DOWN 2 +#define KEY_PROJECTOR_LEFT 3 +#define KEY_PROJECTOR_RIGHT 4 +#define KEY_PROJECTOR_OK 5 +#define KEY_PROJECTOR_VOL_PLUS 6 +#define KEY_PROJECTOR_VOL_MINUS 7 +#define KEY_PROJECTOR_ZOOM_OUT 8 +#define KEY_PROJECTOR_MENU 9 +#define KEY_PROJECTOR_ZOOM_IN 10 +#define KEY_PROJECTOR_BACK 11 + +#define KEY_STEREO_POWER 0 +#define KEY_STEREO_UP 1 +#define KEY_STEREO_DOWN 2 +#define KEY_STEREO_LEFT 3 +#define KEY_STEREO_RIGHT 4 +#define KEY_STEREO_OK 5 +#define KEY_STEREO_VOL_PLUS 6 +#define KEY_STEREO_VOL_MINUS 7 +#define KEY_STEREO_MUTE 8 +#define KEY_STEREO_MENU 9 + +#define KEY_BULB_POWER 0 +#define KEY_BULB_COLOR_1 1 +#define KEY_BULB_COLOR_2 2 +#define KEY_BULB_COLOR_3 3 +#define KEY_BULB_COLOR_4 4 +#define KEY_BULB_COLOR_0 5 +#define KEY_BULB_BRIGHT_PLUS 6 +#define KEY_BULB_BRIGHT_MINUS 7 +#define KEY_BULB_BRIGHT_POWER_ON 8 +#define KEY_BULB_BRIGHT_RAINBOW 9 +#define KEY_BULB_BRIGHT_POWER_OFF 10 + +#define KEY_CLEANROBOT_POWER 0 +#define KEY_CLEANROBOT_FOWWARD 1 +#define KEY_CLEANROBOT_BACKWARD 2 +#define KEY_CLEANROBOT_LEFT 3 +#define KEY_CLEANROBOT_RIGHT 4 +#define KEY_CLEANROBOT_START 5 +#define KEY_CLEANROBOT_STOP 6 +#define KEY_CLEANROBOT_AUTO 8 +#define KEY_CLEANROBOT_SPOT 9 +#define KEY_CLEANROBOT_SPEED 10 +#define KEY_CLEANROBOT_TIMER 11 +#define KEY_CLEANROBOT_CHARGE 12 +#define KEY_CLEANROBOT_PRESERVE 13 + +#define KEY_AIRCLEANER_POWER 0 +#define KEY_AIRCLEANER_ION 5 +#define KEY_AIRCLEANER_AUTO 8 +#define KEY_AIRCLEANER_WIND_SPEED 9 +#define KEY_AIRCLEANER_MODE_SWITCH 10 +#define KEY_AIRCLEANER_TIMER 11 +#define KEY_AIRCLEANER_LIGHT 12 +#define KEY_AIRCLEANER_FORCE 13 + +#define KEY_DYSON_POWER 0 +#define KEY_DYSON_WIND_SPEED_PLUS 1 +#define KEY_DYSON_WIND_SPEED_MINUS 2 +#define KEY_DYSON_TIMER_MINUS 3 +#define KEY_DYSON_TIMER_PLUS 4 +#define KEY_DYSON_AUTO 5 +#define KEY_DYSON_TEMP_PLUS 6 +#define KEY_DYSON_TEMP_MINUS 7 +#define KEY_DYSON_SWING 8 +#define KEY_DYSON_DIFFUSION 9 +#define KEY_DYSON_FAV 10 +#define KEY_DYSON_TIMER 11 +#define KEY_DYSON_SLEEP 12 +#define KEY_DYSON_COOL 13 + +#define STANDARD_KEY_COUNT 14 +#define CHANNEL_KEY_COUNT 10 + +typedef enum +{ + REMOTE_CATEGORY_NONE = 0, + REMOTE_CATEGORY_AC = 1, + REMOTE_CATEGORY_TV = 2, + REMOTE_CATEGORY_STB = 3, + REMOTE_CATEGORY_NETBOX = 4, + REMOTE_CATEGORY_IPTV = 5, + REMOTE_CATEGORY_DVD = 6, + REMOTE_CATEGORY_FAN = 7, + REMOTE_CATEGORY_PROJECTOR = 8, + REMOTE_CATEGORY_STEREO = 9, + REMOTE_CATEGORY_LIGHT = 10, + REMOTE_CATEGORY_BSTB = 11, + REMOTE_CATEGORY_CLEANING_ROBOT = 12, + REMOTE_CATEGORY_AREMOTE_CLEANER = 13, + REMOTE_CATEGORY_DYSON = 14, + REMOTE_CATEGORY_NEXT, + REMOTE_CATEGORY_MAX = 64, +} t_remote_category; + +typedef enum +{ + SUB_CATEGORY_BINARY = 0, // deprecated + SUB_CATEGORY_QUATERNARY = 1, + SUB_CATEGORY_HEXADECIMAL = 2, + SUB_CATEGORY_NEXT = 3, + SUB_CATEGORY_MAX = 4, +} t_remote_sub_category; + +/** + * function get_lib_version + * + * description: get version of library + * + * parameters: N/A + * + * returns: the string contains library version + * + */ +extern const char* get_lib_version(); + +/** + * function ir_file_open + * + * description: open IR binary code from file + * + * parameters: category (in) - category ID get from indexing API + * sub_category (in) - subcategory ID get from indexing API + * file_name (in) - file name of IR binary + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + * + */ +extern INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name); + +/** + * function ir_binary_open + * + * description: open IR binary code from buffer + * + * parameters: category (in) - category ID get from indexing API + * sub_category (in) - subcategory ID get from indexing API + * binary (in) - pointer to binary buffer + * bin_length (in) - binary buffer size + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binary, UINT16 bin_length); + +/** + * function ir_decode + * + * description: decode IR binary into INT16 array which indicates the IR levels + * + * parameters: key_code (in) - the code of pressed key + * user_data (out) - output decoded data in INT16 array format + * ac_status(in) - pointer to AC status (optional) + * change_wind_direction (in) - if control changes wind direction for AC (for AC only) + * + * returns: length of decoded data (0 indicates decode failure) + */ +extern UINT16 ir_decode(UINT8 key_code, UINT16* user_data, t_remote_ac_status* ac_status, BOOL change_wind_direction); + +/** + * function ir_close + * + * description: close IR binary code + * + * parameters: N/A + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 ir_close(); + +/** + * function get_temperature_range + * + * description: get the supported temperature range [min, max] for the opened AC IR binary + * + * 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 + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_temperature_range(UINT8 ac_mode, INT8 *temp_min, INT8 *temp_max); + +/** + * function get_supported_mode + * + * description: get supported mode for the opened AC IR binary + * + * parameters: supported_mode (out) mode supported by the remote in lower 5 bits + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_mode(UINT8 *supported_mode); + +/** + * function get_supported_wind_speed + * + * description: get supported wind speed levels for the opened AC IR binary in certain mode + * + * 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 + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_wind_speed(UINT8 ac_mode, UINT8 *supported_wind_speed); + +/** + * function get_supported_swing + * + * description: get supported swing functions for the opened AC IR binary in certain mode + * + * 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 + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_swing(UINT8 ac_mode, UINT8 *supported_swing); + +/** + * function get_supported_wind_direction + * + * description: get supported wind directions for the opened AC IR binary in certain mode + * + * parameters: supported_wind_direction (out) swing supported by the remote in lower 2 bits + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_wind_direction(UINT8 *supported_wind_direction); + + +// private extern function +#if (defined BOARD_PC || defined BOARD_PC_DLL) +extern void ir_lib_free_inner_buffer(); +#endif + +// this function is preferred being called by JNI only +UINT16 ir_decode_combo(const UINT8 category, const UINT8 sub_category, + UINT8* binary, UINT16 bin_length, + UINT8 key_code, UINT16* user_data, + t_remote_ac_status* ac_status, BOOL change_wind_direction); + +#ifdef __cplusplus +} +#endif + #endif // _IR_DECODE_H_ \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_defs.h b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_defs.h index 0217651..be31f58 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_defs.h +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_defs.h @@ -1,78 +1,78 @@ -/************************************************************************************** -Filename: ir_defs.h -Revised: Date: 2016-10-26 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - -#ifndef _IR_DEFS_H -#define _IR_DEFS_H - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" -#pragma ide diagnostic ignored "OCUnusedMacroInspection" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#if defined BOARD_ANDROID -#include -#define LOG_TAG "ir_decode" -#endif - -#if defined BOARD_CC26XX -#include "OSAL.h" -#endif - -#define TRUE 1 -#define FALSE 0 - -#define FORMAT_HEX 16 -#define FORMAT_DECIMAL 10 - -// #define USE_DYNAMIC_TAG 1 - -#if defined USE_DYNAMIC_TAG -#include -#endif - -typedef unsigned char UINT8; -typedef signed char INT8; -typedef unsigned short UINT16; -typedef signed short INT16; -typedef signed int INT; -typedef unsigned int UINT; -typedef int BOOL; - -void noprint(const char *fmt, ...); - -#if defined BOARD_CC26XX -#define ir_malloc(A) ICall_malloc(A) -#define ir_free(A) ICall_free(A) -#else -#define ir_malloc(A) malloc(A) -#define ir_free(A) free(A) -#endif - -#define ir_memcpy(A, B, C) memcpy(A, B, C) -#define ir_memset(A, B, C) memset(A, B, C) -#define ir_strlen(A) strlen(A) -#if ((defined BOARD_PC) || (defined BOARD_PC_JNI)) && (defined DEBUG) -#define ir_printf printf -#else -#define ir_printf noprint -#endif -#define USER_DATA_SIZE 1636 -// #define USER_DATA_SIZE 4096 - -#ifdef __cplusplus -} -#endif +/************************************************************************************** +Filename: ir_defs.h +Revised: Date: 2016-10-26 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + +#ifndef _IR_DEFS_H +#define _IR_DEFS_H + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#pragma ide diagnostic ignored "OCUnusedMacroInspection" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined BOARD_ANDROID +#include +#define LOG_TAG "ir_decode" +#endif + +#if defined BOARD_CC26XX +#include "OSAL.h" +#endif + +#define TRUE 1 +#define FALSE 0 + +#define FORMAT_HEX 16 +#define FORMAT_DECIMAL 10 + +// #define USE_DYNAMIC_TAG 1 + +#if defined USE_DYNAMIC_TAG +#include +#endif + +typedef unsigned char UINT8; +typedef signed char INT8; +typedef unsigned short UINT16; +typedef signed short INT16; +typedef signed int INT; +typedef unsigned int UINT; +typedef int BOOL; + +void noprint(const char *fmt, ...); + +#if defined BOARD_CC26XX +#define ir_malloc(A) ICall_malloc(A) +#define ir_free(A) ICall_free(A) +#else +#define ir_malloc(A) malloc(A) +#define ir_free(A) free(A) +#endif + +#define ir_memcpy(A, B, C) memcpy(A, B, C) +#define ir_memset(A, B, C) memset(A, B, C) +#define ir_strlen(A) strlen(A) +#if ((defined BOARD_PC) || (defined BOARD_PC_JNI)) && (defined DEBUG) +#define ir_printf printf +#else +#define ir_printf noprint +#endif +#define USER_DATA_SIZE 1636 +// #define USER_DATA_SIZE 4096 + +#ifdef __cplusplus +} +#endif #endif //_IR_DEFS_H \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_tv_control.h b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_tv_control.h index 6ccfe6b..94f04ae 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_tv_control.h +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_tv_control.h @@ -1,219 +1,219 @@ -/************************************************************************************** -Filename: ir_tv_control.h -Revised: Date: 2016-02-23 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode (compressed command type) - -Revision log: -* 2016-10-21: created by strawmanbobi -**************************************************************************************/ - -#ifndef _IR_TV_CONTROL_H_ -#define _IR_TV_CONTROL_H_ - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "OCUnusedMacroInspection" -#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "ir_defs.h" - -#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 type definitions - */ -typedef enum ir_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, -} t_ir_flags; - -typedef struct ir_data -{ - UINT8 bits; - UINT8 lsb; - UINT8 mode; - UINT8 index; -} t_ir_data; - -#if !defined BOARD_51 && !defined BOARD_STM8 -#pragma pack(1) -#endif -typedef struct ir_cycles -{ - UINT8 flag; - UINT16 mask; - UINT16 space; -} t_ir_cycles; - -#if !defined BOARD_51 && !defined BOARD_STM8 -#pragma pack() -#endif - -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, -} t_tv_key_value; - - -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, -} t_stb_key_value; - -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, -} t_nw_key_value; - -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, -} t_cm_key_value; - -typedef struct ir_data_tv -{ - char magic[4]; - UINT8 per_keycode_bytes; -} t_ir_data_tv; - - -extern INT8 tv_binary_open(UINT8 *binary, UINT16 binary_length); - -extern BOOL tv_binary_parse(UINT8 encode_type); - -extern UINT16 tv_binary_decode(UINT8 key, UINT16 *user_data); - -extern UINT8 tv_lib_close(); - -#ifdef __cplusplus -} -#endif - +/************************************************************************************** +Filename: ir_tv_control.h +Revised: Date: 2016-02-23 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode (compressed command type) + +Revision log: +* 2016-10-21: created by strawmanbobi +**************************************************************************************/ + +#ifndef _IR_TV_CONTROL_H_ +#define _IR_TV_CONTROL_H_ + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "OCUnusedMacroInspection" +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "ir_defs.h" + +#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 type definitions + */ +typedef enum ir_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, +} t_ir_flags; + +typedef struct ir_data +{ + UINT8 bits; + UINT8 lsb; + UINT8 mode; + UINT8 index; +} t_ir_data; + +#if !defined BOARD_51 && !defined BOARD_STM8 +#pragma pack(1) +#endif +typedef struct ir_cycles +{ + UINT8 flag; + UINT16 mask; + UINT16 space; +} t_ir_cycles; + +#if !defined BOARD_51 && !defined BOARD_STM8 +#pragma pack() +#endif + +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, +} t_tv_key_value; + + +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, +} t_stb_key_value; + +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, +} t_nw_key_value; + +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, +} t_cm_key_value; + +typedef struct ir_data_tv +{ + char magic[4]; + UINT8 per_keycode_bytes; +} t_ir_data_tv; + + +extern INT8 tv_binary_open(UINT8 *binary, UINT16 binary_length); + +extern BOOL tv_binary_parse(UINT8 encode_type); + +extern UINT16 tv_binary_decode(UINT8 key, UINT16 *user_data); + +extern UINT8 tv_lib_close(); + +#ifdef __cplusplus +} +#endif + #endif // _IR_TV_CONTROL_H_ \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_utils.h b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_utils.h index 587d243..842ac16 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_utils.h +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/include/ir_utils.h @@ -1,40 +1,40 @@ -/************************************************************************************** -Filename: ir_utils.c -Revised: Date: 2016-10-26 -Revision: Revision: 1.0 - -Description: This file provides generic utils for IRDA algorithms - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - -#ifndef _IR_UTILS_H_ -#define _IR_UTILS_H_ - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "ir_defs.h" -#include "ir_decode.h" - -#include - -extern void string_to_hex(UINT8 *p, t_ac_hex *pac_hex); - -extern void string_to_hex_common(UINT8 *p, UINT8 *hex_data, UINT16 len); - -extern BOOL is_in(const UINT8 *array, UINT8 value, UINT8 len); - -extern void hex_byte_to_double_char(char *dest, UINT8 length, UINT8 src); - -#ifdef __cplusplus -} -#endif +/************************************************************************************** +Filename: ir_utils.c +Revised: Date: 2016-10-26 +Revision: Revision: 1.0 + +Description: This file provides generic utils for IRDA algorithms + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + +#ifndef _IR_UTILS_H_ +#define _IR_UTILS_H_ + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "ir_defs.h" +#include "ir_decode.h" + +#include + +extern void string_to_hex(UINT8 *p, t_ac_hex *pac_hex); + +extern void string_to_hex_common(UINT8 *p, UINT8 *hex_data, UINT16 len); + +extern BOOL is_in(const UINT8 *array, UINT8 value, UINT8 len); + +extern void hex_byte_to_double_char(char *dest, UINT8 length, UINT8 src); + +#ifdef __cplusplus +} +#endif #endif // _IR_UTILS_H_ \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_apply.c b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_apply.c index 13848f9..1dc8881 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_apply.c +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_apply.c @@ -1,790 +1,790 @@ -/************************************************************************************** -Filename: ir_ac_apply.c -Revised: Date: 2016-10-12 -Revision: Revision: 1.0 - -Description: This file provides methods for AC IR applying functionalities - -Revision log: -* 2016-10-12: created by strawmanbobi -**************************************************************************************/ -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "bugprone-branch-clone" -#pragma ide diagnostic ignored "hicpp-signed-bitwise" -#endif - -#include "include/ir_utils.h" -#include "include/ir_ac_apply.h" - -static INT8 apply_ac_power(struct ac_protocol *protocol, UINT8 power_status); - -static INT8 apply_ac_mode(struct ac_protocol *protocol, UINT8 mode_status); - -static INT8 apply_ac_temperature(struct ac_protocol *protocol, UINT8 temp_diff); - -static INT8 apply_ac_wind_speed(struct ac_protocol *protocol, UINT8 wind_speed); - -static INT8 apply_ac_swing(struct ac_protocol *protocol, UINT8 swing_mode); - -static UINT8 has_function(struct ac_protocol *protocol, UINT8 function); - - -INT8 apply_ac_parameter_type_1(UINT8 *dc_data, t_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, t_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; - } - - 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 = (UINT8) (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 = (UINT8) ((0xFF << (8 - int_start_bit)) | (0xFF >> int_end_bit)); - UINT8 origin = dc_data[cover_byte_pos_lo]; - - if (TRUE == is_temp) - { - move_bit = (UINT8) (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 origin_hi = 0; - UINT8 origin_lo = 0; - UINT8 mask_hi = 0; - UINT8 mask_lo = 0; - UINT8 raw_value = 0; - UINT8 int_start_bit = 0; - UINT8 int_end_bit = 0; - - 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 = (UINT8) 0xFF << (8 - int_start_bit); - mask_lo = (UINT8) 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] = (UINT8) ((origin_hi & mask_hi) | - (((0xFF >> (8 - bit_range)) & raw_value) >> int_end_bit)); - - dc_data[cover_byte_pos_lo] = (UINT8) ((origin_lo & mask_lo) | - (((0xFF >> (8 - bit_range)) & raw_value) << (8 - int_end_bit))); - } - - return IR_DECODE_SUCCEEDED; -} - -static 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]), (UINT8) i, FALSE); - } - return IR_DECODE_SUCCEEDED; -} - -static 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]), (UINT8) 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]), - (UINT8) i, FALSE); - } - return IR_DECODE_SUCCEEDED; -} - -static 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]), (UINT8) 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]), - (UINT8) i, FALSE); - } - return IR_DECODE_SUCCEEDED; -} - -static 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]), (UINT8) i, TRUE); - } - else if (TEMP_TYPE_STATIC == protocol->temp1.type) - { - apply_ac_parameter_type_1(ir_hex_code, &(protocol->temp1.comp_data[temp_diff]), (UINT8) 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]), (UINT8) i, TRUE); - } - else if (TEMP_TYPE_STATIC == protocol->temp2.type) - { - apply_ac_parameter_type_2(ir_hex_code, &(protocol->temp2.comp_data[temp_diff]), (UINT8) i, FALSE); - } - } - } - return IR_DECODE_SUCCEEDED; -} - -static 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]), (UINT8) 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]), - (UINT8) i, FALSE); - } - return IR_DECODE_SUCCEEDED; -} - -static INT8 apply_checksum_byte(UINT8 *ac_code, t_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; - - return IR_DECODE_SUCCEEDED; -} - -static INT8 apply_checksum_halfbyte(UINT8 *ac_code, t_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; - - return IR_DECODE_SUCCEEDED; -} - -static INT8 apply_checksum_spec_byte(UINT8 *ac_code, t_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] = (UINT8) ((ac_code[apply_byte_pos] & 0x0F) | (checksum << 4)); - } - else - { - // save high bits and add checksum as low bits - ac_code[apply_byte_pos] = (UINT8) ((ac_code[apply_byte_pos] & 0xF0) | (checksum & 0x0F)); - } - - return IR_DECODE_SUCCEEDED; -} - -static INT8 apply_checksum_spec_byte_onebyte(UINT8 *ac_code, t_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; - - return IR_DECODE_SUCCEEDED; -} - -static UINT8 has_function(struct ac_protocol *protocol, UINT8 function) -{ - if (function < AC_FUNCTION_POWER || function > AC_FUNCTION_WIND_FIX) - { - return FALSE; - } - - 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_function(struct ac_protocol *protocol, UINT8 function) -{ - UINT16 i = 0; - - if (function < AC_FUNCTION_POWER || function > AC_FUNCTION_WIND_FIX) - { - return IR_DECODE_FAILED; - } - - // 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]), (UINT8) 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]), - (UINT8) i, FALSE); - } - return IR_DECODE_SUCCEEDED; -} - -INT8 apply_checksum(struct ac_protocol *protocol) -{ - UINT16 i = 0; - - if (0 == protocol->checksum.len) - { - return IR_DECODE_SUCCEEDED; - } - - for (i = 0; i < protocol->checksum.count; i++) - { - 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; - } - } - - return IR_DECODE_SUCCEEDED; -} - -INT8 apply_power(t_remote_ac_status ac_status, UINT8 function_code) -{ - (void) function_code; - apply_ac_power(context, ac_status.ac_power); - return IR_DECODE_SUCCEEDED; -} - -INT8 apply_mode(t_remote_ac_status ac_status, UINT8 function_code) -{ - (void) function_code; - if (IR_DECODE_FAILED == apply_ac_mode(context, ac_status.ac_mode)) - { - // 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(t_remote_ac_status ac_status, UINT8 function_code) -{ - if (FALSE == context->n_mode[ac_status.ac_mode].all_speed) - { - // if this level is not in black list - if (!is_in(context->n_mode[ac_status.ac_mode].speed, - ac_status.ac_wind_speed, - context->n_mode[ac_status.ac_mode].speed_cnt)) - { - if (IR_DECODE_FAILED == apply_ac_wind_speed(context, ac_status.ac_wind_speed) && - 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(t_remote_ac_status ac_status, UINT8 function_code) -{ - (void) ac_status; - 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(t_remote_ac_status ac_status, UINT8 function_code) -{ - if (FALSE == context->n_mode[ac_status.ac_mode].all_temp) - { - if (!is_in(context->n_mode[ac_status.ac_mode].temp, - ac_status.ac_temp, - context->n_mode[ac_status.ac_mode].temp_cnt)) - { - if (IR_DECODE_FAILED == apply_ac_temperature(context, ac_status.ac_temp)) - { - 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; +/************************************************************************************** +Filename: ir_ac_apply.c +Revised: Date: 2016-10-12 +Revision: Revision: 1.0 + +Description: This file provides methods for AC IR applying functionalities + +Revision log: +* 2016-10-12: created by strawmanbobi +**************************************************************************************/ +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "bugprone-branch-clone" +#pragma ide diagnostic ignored "hicpp-signed-bitwise" +#endif + +#include "include/ir_utils.h" +#include "include/ir_ac_apply.h" + +static INT8 apply_ac_power(struct ac_protocol *protocol, UINT8 power_status); + +static INT8 apply_ac_mode(struct ac_protocol *protocol, UINT8 mode_status); + +static INT8 apply_ac_temperature(struct ac_protocol *protocol, UINT8 temp_diff); + +static INT8 apply_ac_wind_speed(struct ac_protocol *protocol, UINT8 wind_speed); + +static INT8 apply_ac_swing(struct ac_protocol *protocol, UINT8 swing_mode); + +static UINT8 has_function(struct ac_protocol *protocol, UINT8 function); + + +INT8 apply_ac_parameter_type_1(UINT8 *dc_data, t_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, t_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; + } + + 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 = (UINT8) (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 = (UINT8) ((0xFF << (8 - int_start_bit)) | (0xFF >> int_end_bit)); + UINT8 origin = dc_data[cover_byte_pos_lo]; + + if (TRUE == is_temp) + { + move_bit = (UINT8) (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 origin_hi = 0; + UINT8 origin_lo = 0; + UINT8 mask_hi = 0; + UINT8 mask_lo = 0; + UINT8 raw_value = 0; + UINT8 int_start_bit = 0; + UINT8 int_end_bit = 0; + + 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 = (UINT8) 0xFF << (8 - int_start_bit); + mask_lo = (UINT8) 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] = (UINT8) ((origin_hi & mask_hi) | + (((0xFF >> (8 - bit_range)) & raw_value) >> int_end_bit)); + + dc_data[cover_byte_pos_lo] = (UINT8) ((origin_lo & mask_lo) | + (((0xFF >> (8 - bit_range)) & raw_value) << (8 - int_end_bit))); + } + + return IR_DECODE_SUCCEEDED; +} + +static 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]), (UINT8) i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +static 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]), (UINT8) 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]), + (UINT8) i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +static 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]), (UINT8) 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]), + (UINT8) i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +static 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]), (UINT8) i, TRUE); + } + else if (TEMP_TYPE_STATIC == protocol->temp1.type) + { + apply_ac_parameter_type_1(ir_hex_code, &(protocol->temp1.comp_data[temp_diff]), (UINT8) 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]), (UINT8) i, TRUE); + } + else if (TEMP_TYPE_STATIC == protocol->temp2.type) + { + apply_ac_parameter_type_2(ir_hex_code, &(protocol->temp2.comp_data[temp_diff]), (UINT8) i, FALSE); + } + } + } + return IR_DECODE_SUCCEEDED; +} + +static 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]), (UINT8) 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]), + (UINT8) i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +static INT8 apply_checksum_byte(UINT8 *ac_code, t_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; + + return IR_DECODE_SUCCEEDED; +} + +static INT8 apply_checksum_halfbyte(UINT8 *ac_code, t_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; + + return IR_DECODE_SUCCEEDED; +} + +static INT8 apply_checksum_spec_byte(UINT8 *ac_code, t_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] = (UINT8) ((ac_code[apply_byte_pos] & 0x0F) | (checksum << 4)); + } + else + { + // save high bits and add checksum as low bits + ac_code[apply_byte_pos] = (UINT8) ((ac_code[apply_byte_pos] & 0xF0) | (checksum & 0x0F)); + } + + return IR_DECODE_SUCCEEDED; +} + +static INT8 apply_checksum_spec_byte_onebyte(UINT8 *ac_code, t_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; + + return IR_DECODE_SUCCEEDED; +} + +static UINT8 has_function(struct ac_protocol *protocol, UINT8 function) +{ + if (function < AC_FUNCTION_POWER || function > AC_FUNCTION_WIND_FIX) + { + return FALSE; + } + + 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_function(struct ac_protocol *protocol, UINT8 function) +{ + UINT16 i = 0; + + if (function < AC_FUNCTION_POWER || function > AC_FUNCTION_WIND_FIX) + { + return IR_DECODE_FAILED; + } + + // 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]), (UINT8) 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]), + (UINT8) i, FALSE); + } + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_checksum(struct ac_protocol *protocol) +{ + UINT16 i = 0; + + if (0 == protocol->checksum.len) + { + return IR_DECODE_SUCCEEDED; + } + + for (i = 0; i < protocol->checksum.count; i++) + { + 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; + } + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_power(t_remote_ac_status ac_status, UINT8 function_code) +{ + (void) function_code; + apply_ac_power(context, ac_status.ac_power); + return IR_DECODE_SUCCEEDED; +} + +INT8 apply_mode(t_remote_ac_status ac_status, UINT8 function_code) +{ + (void) function_code; + if (IR_DECODE_FAILED == apply_ac_mode(context, ac_status.ac_mode)) + { + // 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(t_remote_ac_status ac_status, UINT8 function_code) +{ + if (FALSE == context->n_mode[ac_status.ac_mode].all_speed) + { + // if this level is not in black list + if (!is_in(context->n_mode[ac_status.ac_mode].speed, + ac_status.ac_wind_speed, + context->n_mode[ac_status.ac_mode].speed_cnt)) + { + if (IR_DECODE_FAILED == apply_ac_wind_speed(context, ac_status.ac_wind_speed) && + 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(t_remote_ac_status ac_status, UINT8 function_code) +{ + (void) ac_status; + 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(t_remote_ac_status ac_status, UINT8 function_code) +{ + if (FALSE == context->n_mode[ac_status.ac_mode].all_temp) + { + if (!is_in(context->n_mode[ac_status.ac_mode].temp, + ac_status.ac_temp, + context->n_mode[ac_status.ac_mode].temp_cnt)) + { + if (IR_DECODE_FAILED == apply_ac_temperature(context, ac_status.ac_temp)) + { + 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; } \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_build_frame.c b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_build_frame.c index 6bba2ba..366e08c 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_build_frame.c +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_build_frame.c @@ -1,146 +1,146 @@ -/************************************************************************************** -Filename: ir_ac_build_frame.c -Revised: Date: 2016-10-01 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR frame build - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "hicpp-signed-bitwise" -#pragma ide diagnostic ignored "readability-redundant-declaration" -#endif - -#include "include/ir_ac_build_frame.h" -#include "include/ir_decode.h" - -extern t_ac_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->bit_num_cnt == 0) - return 8; //defaut value - - if (context->bit_num_cnt >= MAX_BITNUM) - size = MAX_BITNUM; - else - size = (UINT8) context->bit_num_cnt; - - for (i = 0; i < size; i++) - { - if (context->bit_num[i].pos == index) - return (UINT8) context->bit_num[i].bits; - if (context->bit_num[i].pos > index) - return 8; - } - return 8; -} - -UINT16 add_delaycode(UINT8 index) -{ - UINT16 i = 0; - UINT16 j = 0; - UINT8 size = 0; - UINT8 tail_delay_code = 0; - UINT16 tail_pos = 0; - - if (context->dc_cnt != 0) - { - size = (UINT8) 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_delay_code = 1; - tail_pos = i; - } - } - } - - if ((context->last_bit == 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_delay_code == 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; -} - -UINT16 create_ir_frame() -{ - UINT16 i = 0, j = 0; - UINT8 bit_num = 0; - UINT8 *ir_data = ir_hex_code; - UINT8 mask = 0; - UINT16 frame_length = 0; - - context->code_cnt = 0; - - // boot code - for (i = 0; i < context->boot_code.len; i++) - { - context->time[context->code_cnt++] = context->boot_code.data[i]; - } - - for (i = 0; i < ir_hex_len; i++) - { - bit_num = bits_per_byte((UINT8) i); - for (j = 0; j < bit_num; j++) - { - if (context->endian == 0) - mask = (UINT8) ((1 << (bit_num - 1)) >> j); - else - mask = (UINT8) (1 << j); - - if (ir_data[i] & mask) - { - context->time[context->code_cnt++] = context->one.low; - context->time[context->code_cnt++] = context->one.high; - } - else - { - context->time[context->code_cnt++] = context->zero.low; - context->time[context->code_cnt++] = context->zero.high; - } - } - add_delaycode((UINT8) i); - } - - frame_length = context->code_cnt; - - for (i = 0; i < (context->repeat_times - 1); i++) - { - for (j = 0; j < frame_length; j++) - { - context->time[context->code_cnt++] = context->time[j]; - } - } - - return context->code_cnt; +/************************************************************************************** +Filename: ir_ac_build_frame.c +Revised: Date: 2016-10-01 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR frame build + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "hicpp-signed-bitwise" +#pragma ide diagnostic ignored "readability-redundant-declaration" +#endif + +#include "include/ir_ac_build_frame.h" +#include "include/ir_decode.h" + +extern t_ac_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->bit_num_cnt == 0) + return 8; //defaut value + + if (context->bit_num_cnt >= MAX_BITNUM) + size = MAX_BITNUM; + else + size = (UINT8) context->bit_num_cnt; + + for (i = 0; i < size; i++) + { + if (context->bit_num[i].pos == index) + return (UINT8) context->bit_num[i].bits; + if (context->bit_num[i].pos > index) + return 8; + } + return 8; +} + +UINT16 add_delaycode(UINT8 index) +{ + UINT16 i = 0; + UINT16 j = 0; + UINT8 size = 0; + UINT8 tail_delay_code = 0; + UINT16 tail_pos = 0; + + if (context->dc_cnt != 0) + { + size = (UINT8) 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_delay_code = 1; + tail_pos = i; + } + } + } + + if ((context->last_bit == 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_delay_code == 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; +} + +UINT16 create_ir_frame() +{ + UINT16 i = 0, j = 0; + UINT8 bit_num = 0; + UINT8 *ir_data = ir_hex_code; + UINT8 mask = 0; + UINT16 frame_length = 0; + + context->code_cnt = 0; + + // boot code + for (i = 0; i < context->boot_code.len; i++) + { + context->time[context->code_cnt++] = context->boot_code.data[i]; + } + + for (i = 0; i < ir_hex_len; i++) + { + bit_num = bits_per_byte((UINT8) i); + for (j = 0; j < bit_num; j++) + { + if (context->endian == 0) + mask = (UINT8) ((1 << (bit_num - 1)) >> j); + else + mask = (UINT8) (1 << j); + + if (ir_data[i] & mask) + { + context->time[context->code_cnt++] = context->one.low; + context->time[context->code_cnt++] = context->one.high; + } + else + { + context->time[context->code_cnt++] = context->zero.low; + context->time[context->code_cnt++] = context->zero.high; + } + } + add_delaycode((UINT8) i); + } + + frame_length = context->code_cnt; + + for (i = 0; i < (context->repeat_times - 1); i++) + { + for (j = 0; j < frame_length; j++) + { + context->time[context->code_cnt++] = context->time[j]; + } + } + + return context->code_cnt; } \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_control.c b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_control.c index 2526857..9dbdef8 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_control.c +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_control.c @@ -1,560 +1,560 @@ -/************************************************************************************** -Filename: ir_ac_control.c -Revised: Date: 2017-01-02 -Revision: Revision: 1.0 - -Description: This file provides methods for AC IR control - -Revision log: -* 2016-10-12: created by strawmanbobi -**************************************************************************************/ - -#include -#include -#include - -#include "include/ir_ac_control.h" -#include "include/ir_ac_binary_parse.h" -#include "include/ir_decode.h" -#include "include/ir_ac_parse_parameter.h" -#include "include/ir_ac_parse_forbidden_info.h" -#include "include/ir_ac_parse_frame_info.h" -#include "include/ir_utils.h" - - -#if defined USE_DYNAMIC_TAG -extern struct tag_head *tags; -#else -extern struct tag_head tags[]; -#endif - -extern UINT8 tag_count; - -static INT8 ir_context_init(); - - -static INT8 ir_context_init() -{ - ir_memset(context, 0, sizeof(t_ac_protocol)); - return IR_DECODE_SUCCEEDED; -} - - -INT8 ir_ac_lib_parse() -{ - UINT i = 0; - // suggest not to call init function here for de-couple purpose - ir_context_init(); - - 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; - } - - binary_tags_info(); - - context->endian = 0; - context->last_bit = 0; - context->repeat_times = 1; - - for (i = 0; i < N_MODE_MAX; i++) - { - context->n_mode[i].enable = TRUE; - context->n_mode[i].all_speed = FALSE; - context->n_mode[i].all_temp = FALSE; - ir_memset(context->n_mode[i].speed, 0x00, AC_WS_MAX); - context->n_mode[i].speed_cnt = 0; - ir_memset(context->n_mode[i].temp, 0x00, AC_TEMP_MAX); - context->n_mode[i].temp_cnt = 0; - } - - // parse TAG 46 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(&tags[i], &(context->si)); - } - else - { - context->si.type = SWING_TYPE_NORMAL; - context->si.mode_count = 2; - } - context->si.dir_index = 0; - break; - } - } - - for (i = 0; i < tag_count; i++) - { - if (tags[i].len == 0) - { - continue; - } - // then parse TAG 26 or 33 - if (context->si.type == SWING_TYPE_NORMAL) - { - UINT16 swing_space_size = 0; - if (tags[i].tag == TAG_AC_SWING_1) - { - context->swing1.count = context->si.mode_count; - context->swing1.len = (UINT8) tags[i].len >> (UINT8) 1; - swing_space_size = sizeof(t_tag_comp) * context->si.mode_count; - context->swing1.comp_data = (t_tag_comp *) ir_malloc(swing_space_size); - if (NULL == context->swing1.comp_data) - { - return IR_DECODE_FAILED; - } - - ir_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) - { - context->swing2.count = context->si.mode_count; - context->swing2.len = (UINT8) tags[i].len >> (UINT8) 1; - swing_space_size = sizeof(t_tag_comp) * context->si.mode_count; - context->swing2.comp_data = (t_tag_comp *) ir_malloc(swing_space_size); - if (NULL == context->swing2.comp_data) - { - return IR_DECODE_FAILED; - } - ir_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 - { - context->default_code.data = (UINT8 *) ir_malloc(((size_t) tags[i].len - 2) >> (UINT8) 1); - if (NULL == context->default_code.data) - { - return IR_DECODE_FAILED; - } - if (IR_DECODE_FAILED == parse_default_code(&tags[i], &(context->default_code))) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_POWER_1) // power tag - { - context->power1.len = (UINT8) tags[i].len >> (UINT8) 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 - { - if (IR_DECODE_FAILED == parse_temp_1(&tags[i], &(context->temp1))) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_MODE_1) // mode tag - { - context->mode1.len = (UINT8) tags[i].len >> (UINT8) 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 - { - context->speed1.len = (UINT8) tags[i].len >> (UINT8) 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) - { - if (IR_DECODE_FAILED == parse_checksum(&tags[i], &(context->checksum))) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_MODE_2) - { - context->mode2.len = (UINT8) tags[i].len >> (UINT8) 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) - { - context->speed2.len = (UINT8) tags[i].len >> (UINT8) 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) - { - if (IR_DECODE_FAILED == parse_temp_2(&tags[i], &(context->temp2))) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_SOLO_FUNCTION) - { - if (IR_DECODE_FAILED == parse_solo_code(&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_tag29(&tags[i], &(context->function1))) - { - ir_printf("\nfunction code parse error\n"); - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_FUNCTION_2) - { - if (IR_DECODE_FAILED == parse_function_2_tag34(&tags[i], &(context->function2))) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_FRAME_LENGTH) - { - if (IR_DECODE_FAILED == parse_frame_len(&tags[i], tags[i].len)) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_ZERO) - { - if (IR_DECODE_FAILED == parse_zero(&tags[i])) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_ONE) - { - if (IR_DECODE_FAILED == parse_one(&tags[i])) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_BOOT_CODE) - { - if (IR_DECODE_FAILED == parse_boot_code(&tags[i])) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_REPEAT_TIMES) - { - if (IR_DECODE_FAILED == parse_repeat_times(&tags[i])) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_BIT_NUM) - { - if (IR_DECODE_FAILED == parse_bit_num(&tags[i])) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_ENDIAN) - { - if (IR_DECODE_FAILED == parse_endian(&tags[i])) - { - return IR_DECODE_FAILED; - } - } - else if (tags[i].tag == TAG_AC_BAN_FUNCTION_IN_COOL_MODE) - { - if (IR_DECODE_FAILED == parse_nmode(&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(&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(&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(&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(&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_delay_code(&tags[i])) - { - return IR_DECODE_FAILED; - } - } - if (tags[i].tag == TAG_AC_LAST_BIT) - { - if (IR_DECODE_FAILED == parse_lastbit(&tags[i])) - { - return IR_DECODE_FAILED; - } - } - } - -#if defined USE_DYNAMIC_TAG - if (NULL != tags) - { - ir_free(tags); - tags = NULL; - } -#endif - - ir_hex_code = (UINT8 *) ir_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; - ir_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 (is_in(context->sc.solo_function_codes, i, context->sc.solo_func_count)) - { - context->solo_function_mark |= (UINT8) ((UINT8) 1 << (i - 1)); - } - } - } - - // it is strongly recommended that we free p_ir_buffer - // or make global buffer shared in extreme memory case - /* in case of running with test - begin */ -#if (defined BOARD_PC || defined BOARD_PC_DLL) - ir_lib_free_inner_buffer(); - ir_printf("AC parse done\n"); -#endif - /* in case of running with test - end */ - - return IR_DECODE_SUCCEEDED; -} - - -INT8 free_ac_context() -{ - UINT16 i = 0; - - if (ir_hex_code != NULL) - { - ir_free(ir_hex_code); - ir_hex_code = NULL; - } - ir_hex_len = 0; - - if (context->default_code.data != NULL) - { - ir_free(context->default_code.data); - context->default_code.data = NULL; - context->default_code.len = 0; - } - - for (i = 0; i < (UINT16) AC_POWER_MAX; i++) - { - if (context->power1.comp_data[i].segment != NULL) - { - ir_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 < (UINT16) AC_TEMP_MAX; i++) - { - if (context->temp1.comp_data[i].segment != NULL) - { - ir_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) - { - ir_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 < (UINT16) AC_MODE_MAX; i++) - { - if (context->mode1.comp_data[i].segment != NULL) - { - ir_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) - { - ir_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 < (UINT16) AC_WS_MAX; i++) - { - if (context->speed1.comp_data[i].segment != NULL) - { - ir_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) - { - ir_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) - { - ir_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) - { - ir_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 < (UINT16) AC_FUNCTION_MAX - 1; i++) - { - if (context->function1.comp_data[i].segment != NULL) - { - ir_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) - { - ir_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) - { - ir_free(context->swing1.comp_data); - context->swing1.comp_data = NULL; - } - if (context->swing2.comp_data != NULL) - { - ir_free(context->swing2.comp_data); - context->swing2.comp_data = NULL; - } - - for (i = 0; i < context->checksum.count; i++) - { - if (context->checksum.checksum_data != NULL && - context->checksum.checksum_data[i].spec_pos != NULL) - { - ir_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) - { - ir_free(context->checksum.checksum_data); - context->checksum.checksum_data = NULL; - } - - return IR_DECODE_SUCCEEDED; -} - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "hicpp-signed-bitwise" -#endif - -BOOL is_solo_function(UINT8 function_code) -{ - return (((context->solo_function_mark >> (function_code - 1)) & 0x01) == 0x01) ? TRUE : FALSE; -} +/************************************************************************************** +Filename: ir_ac_control.c +Revised: Date: 2017-01-02 +Revision: Revision: 1.0 + +Description: This file provides methods for AC IR control + +Revision log: +* 2016-10-12: created by strawmanbobi +**************************************************************************************/ + +#include +#include +#include + +#include "include/ir_ac_control.h" +#include "include/ir_ac_binary_parse.h" +#include "include/ir_decode.h" +#include "include/ir_ac_parse_parameter.h" +#include "include/ir_ac_parse_forbidden_info.h" +#include "include/ir_ac_parse_frame_info.h" +#include "include/ir_utils.h" + + +#if defined USE_DYNAMIC_TAG +extern struct tag_head *tags; +#else +extern struct tag_head tags[]; +#endif + +extern UINT8 tag_count; + +static INT8 ir_context_init(); + + +static INT8 ir_context_init() +{ + ir_memset(context, 0, sizeof(t_ac_protocol)); + return IR_DECODE_SUCCEEDED; +} + + +INT8 ir_ac_lib_parse() +{ + UINT i = 0; + // suggest not to call init function here for de-couple purpose + ir_context_init(); + + 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; + } + + binary_tags_info(); + + context->endian = 0; + context->last_bit = 0; + context->repeat_times = 1; + + for (i = 0; i < N_MODE_MAX; i++) + { + context->n_mode[i].enable = TRUE; + context->n_mode[i].all_speed = FALSE; + context->n_mode[i].all_temp = FALSE; + ir_memset(context->n_mode[i].speed, 0x00, AC_WS_MAX); + context->n_mode[i].speed_cnt = 0; + ir_memset(context->n_mode[i].temp, 0x00, AC_TEMP_MAX); + context->n_mode[i].temp_cnt = 0; + } + + // parse TAG 46 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(&tags[i], &(context->si)); + } + else + { + context->si.type = SWING_TYPE_NORMAL; + context->si.mode_count = 2; + } + context->si.dir_index = 0; + break; + } + } + + for (i = 0; i < tag_count; i++) + { + if (tags[i].len == 0) + { + continue; + } + // then parse TAG 26 or 33 + if (context->si.type == SWING_TYPE_NORMAL) + { + UINT16 swing_space_size = 0; + if (tags[i].tag == TAG_AC_SWING_1) + { + context->swing1.count = context->si.mode_count; + context->swing1.len = (UINT8) tags[i].len >> (UINT8) 1; + swing_space_size = sizeof(t_tag_comp) * context->si.mode_count; + context->swing1.comp_data = (t_tag_comp *) ir_malloc(swing_space_size); + if (NULL == context->swing1.comp_data) + { + return IR_DECODE_FAILED; + } + + ir_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) + { + context->swing2.count = context->si.mode_count; + context->swing2.len = (UINT8) tags[i].len >> (UINT8) 1; + swing_space_size = sizeof(t_tag_comp) * context->si.mode_count; + context->swing2.comp_data = (t_tag_comp *) ir_malloc(swing_space_size); + if (NULL == context->swing2.comp_data) + { + return IR_DECODE_FAILED; + } + ir_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 + { + context->default_code.data = (UINT8 *) ir_malloc(((size_t) tags[i].len - 2) >> (UINT8) 1); + if (NULL == context->default_code.data) + { + return IR_DECODE_FAILED; + } + if (IR_DECODE_FAILED == parse_default_code(&tags[i], &(context->default_code))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_POWER_1) // power tag + { + context->power1.len = (UINT8) tags[i].len >> (UINT8) 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 + { + if (IR_DECODE_FAILED == parse_temp_1(&tags[i], &(context->temp1))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_MODE_1) // mode tag + { + context->mode1.len = (UINT8) tags[i].len >> (UINT8) 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 + { + context->speed1.len = (UINT8) tags[i].len >> (UINT8) 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) + { + if (IR_DECODE_FAILED == parse_checksum(&tags[i], &(context->checksum))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_MODE_2) + { + context->mode2.len = (UINT8) tags[i].len >> (UINT8) 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) + { + context->speed2.len = (UINT8) tags[i].len >> (UINT8) 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) + { + if (IR_DECODE_FAILED == parse_temp_2(&tags[i], &(context->temp2))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_SOLO_FUNCTION) + { + if (IR_DECODE_FAILED == parse_solo_code(&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_tag29(&tags[i], &(context->function1))) + { + ir_printf("\nfunction code parse error\n"); + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_FUNCTION_2) + { + if (IR_DECODE_FAILED == parse_function_2_tag34(&tags[i], &(context->function2))) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_FRAME_LENGTH) + { + if (IR_DECODE_FAILED == parse_frame_len(&tags[i], tags[i].len)) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_ZERO) + { + if (IR_DECODE_FAILED == parse_zero(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_ONE) + { + if (IR_DECODE_FAILED == parse_one(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BOOT_CODE) + { + if (IR_DECODE_FAILED == parse_boot_code(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_REPEAT_TIMES) + { + if (IR_DECODE_FAILED == parse_repeat_times(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BIT_NUM) + { + if (IR_DECODE_FAILED == parse_bit_num(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_ENDIAN) + { + if (IR_DECODE_FAILED == parse_endian(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + else if (tags[i].tag == TAG_AC_BAN_FUNCTION_IN_COOL_MODE) + { + if (IR_DECODE_FAILED == parse_nmode(&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(&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(&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(&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(&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_delay_code(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + if (tags[i].tag == TAG_AC_LAST_BIT) + { + if (IR_DECODE_FAILED == parse_lastbit(&tags[i])) + { + return IR_DECODE_FAILED; + } + } + } + +#if defined USE_DYNAMIC_TAG + if (NULL != tags) + { + ir_free(tags); + tags = NULL; + } +#endif + + ir_hex_code = (UINT8 *) ir_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; + ir_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 (is_in(context->sc.solo_function_codes, i, context->sc.solo_func_count)) + { + context->solo_function_mark |= (UINT8) ((UINT8) 1 << (i - 1)); + } + } + } + + // it is strongly recommended that we free p_ir_buffer + // or make global buffer shared in extreme memory case + /* in case of running with test - begin */ +#if (defined BOARD_PC || defined BOARD_PC_DLL) + ir_lib_free_inner_buffer(); + ir_printf("AC parse done\n"); +#endif + /* in case of running with test - end */ + + return IR_DECODE_SUCCEEDED; +} + + +INT8 free_ac_context() +{ + UINT16 i = 0; + + if (ir_hex_code != NULL) + { + ir_free(ir_hex_code); + ir_hex_code = NULL; + } + ir_hex_len = 0; + + if (context->default_code.data != NULL) + { + ir_free(context->default_code.data); + context->default_code.data = NULL; + context->default_code.len = 0; + } + + for (i = 0; i < (UINT16) AC_POWER_MAX; i++) + { + if (context->power1.comp_data[i].segment != NULL) + { + ir_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 < (UINT16) AC_TEMP_MAX; i++) + { + if (context->temp1.comp_data[i].segment != NULL) + { + ir_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) + { + ir_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 < (UINT16) AC_MODE_MAX; i++) + { + if (context->mode1.comp_data[i].segment != NULL) + { + ir_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) + { + ir_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 < (UINT16) AC_WS_MAX; i++) + { + if (context->speed1.comp_data[i].segment != NULL) + { + ir_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) + { + ir_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) + { + ir_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) + { + ir_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 < (UINT16) AC_FUNCTION_MAX - 1; i++) + { + if (context->function1.comp_data[i].segment != NULL) + { + ir_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) + { + ir_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) + { + ir_free(context->swing1.comp_data); + context->swing1.comp_data = NULL; + } + if (context->swing2.comp_data != NULL) + { + ir_free(context->swing2.comp_data); + context->swing2.comp_data = NULL; + } + + for (i = 0; i < context->checksum.count; i++) + { + if (context->checksum.checksum_data != NULL && + context->checksum.checksum_data[i].spec_pos != NULL) + { + ir_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) + { + ir_free(context->checksum.checksum_data); + context->checksum.checksum_data = NULL; + } + + return IR_DECODE_SUCCEEDED; +} + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "hicpp-signed-bitwise" +#endif + +BOOL is_solo_function(UINT8 function_code) +{ + return (((context->solo_function_mark >> (function_code - 1)) & 0x01) == 0x01) ? TRUE : FALSE; +} diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_parse_forbidden_info.c b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_parse_forbidden_info.c index 4624411..5121932 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_parse_forbidden_info.c +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_ac_parse_forbidden_info.c @@ -1,149 +1,149 @@ -/************************************************************************************** -Filename: ir_parse_forbidden_info.c -Revised: Date: 2016-10-05 -Revision: Revision: 1.0 - -Description: This file provides algorithms for forbidden area of AC code - -Revision log: -* 2016-10-05: created by strawmanbobi -**************************************************************************************/ - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "readability-redundant-declaration" -#endif - -#include -#include -#include - -#include "include/ir_decode.h" -#include "include/ir_ac_parse_forbidden_info.h" - - -extern t_ac_protocol *context; - - -INT8 parse_nmode_data_speed(char *pdata, t_ac_n_mode seq) -{ - char buf[16] = { 0 }; - char *p = pdata; - char *ptr = NULL; - UINT16 pos = 0; - UINT16 cnt = 0, index = 0; - - while (index <= ir_strlen(pdata)) - { - while ((index != ir_strlen(pdata)) && (*(p++) != ',')) - { - index++; - } - ir_memcpy(buf, pdata + pos, index - pos); - pos = (UINT16) (index + 1); - index = pos; - context->n_mode[seq].speed[cnt++] = (UINT8) strtol(buf, &ptr, 10); - context->n_mode[seq].speed_cnt = (UINT8) cnt; - ir_memset(buf, 0, 16); - } - - return IR_DECODE_SUCCEEDED; -} - -INT8 parse_nmode_data_temp(char *pdata, t_ac_n_mode seq) -{ - - char buf[16] = { 0 }; - char *p = pdata; - char *ptr = NULL; - UINT16 pos = 0; - UINT16 cnt = 0, index = 0; - - while (index <= ir_strlen(pdata)) - { - while ((index != ir_strlen(pdata)) && (*(p++) != ',')) - { - index++; - } - ir_memcpy(buf, pdata + pos, index - pos); - pos = (UINT16) (index + 1); - index = pos; - context->n_mode[seq].temp[cnt++] = (UINT8) (strtol(buf, &ptr, 10) - 16); - context->n_mode[seq].temp_cnt = (UINT8) cnt; - ir_memset(buf, 0, 16); - } - return IR_DECODE_SUCCEEDED; -} - -INT8 parse_nmode_pos(char *buf, t_ac_n_mode index) -{ - UINT16 i = 0; - char data[64] = { 0 }; - // char start[8] = { 0 }; - if (ir_strlen(buf) == 1) - { - if (buf[0] == 'S' || buf[0] == 's') - { - context->n_mode[index].all_speed = 1; - } - else if (buf[0] == 'T' || buf[0] == 't') - { - context->n_mode[index].all_temp = 1; - } - return IR_DECODE_SUCCEEDED; - } - - for (i = 0; i < (UINT16) ir_strlen(buf); i++) - { - if (buf[i] == '&') - { - ir_memcpy(data, buf + i + 1, ir_strlen(buf) - i - 1); - break; - } - } - if (buf[0] == 'S') - { - parse_nmode_data_speed(data, index); - } - else - { - parse_nmode_data_temp(data, index); - } - - return IR_DECODE_SUCCEEDED; -} - -INT8 parse_nmode(struct tag_head *tag, t_ac_n_mode index) -{ - UINT16 i = 0; - UINT16 preindex = 0; - - char buf[64] = { 0 }; - - if (tag->p_data[0] == 'N' && tag->p_data[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->p_data[i] == '|') - { - ir_memcpy(buf, tag->p_data + preindex, i - preindex); - preindex = (UINT16) (i + 1); - parse_nmode_pos(buf, index); - ir_memset(buf, 0, 64); - } - - } - ir_memcpy(buf, tag->p_data + preindex, i - preindex); - parse_nmode_pos(buf, index); - ir_memset(buf, 0, 64); - return IR_DECODE_SUCCEEDED; +/************************************************************************************** +Filename: ir_parse_forbidden_info.c +Revised: Date: 2016-10-05 +Revision: Revision: 1.0 + +Description: This file provides algorithms for forbidden area of AC code + +Revision log: +* 2016-10-05: created by strawmanbobi +**************************************************************************************/ + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "readability-redundant-declaration" +#endif + +#include +#include +#include + +#include "include/ir_decode.h" +#include "include/ir_ac_parse_forbidden_info.h" + + +extern t_ac_protocol *context; + + +INT8 parse_nmode_data_speed(char *pdata, t_ac_n_mode seq) +{ + char buf[16] = { 0 }; + char *p = pdata; + char *ptr = NULL; + UINT16 pos = 0; + UINT16 cnt = 0, index = 0; + + while (index <= ir_strlen(pdata)) + { + while ((index != ir_strlen(pdata)) && (*(p++) != ',')) + { + index++; + } + ir_memcpy(buf, pdata + pos, index - pos); + pos = (UINT16) (index + 1); + index = pos; + context->n_mode[seq].speed[cnt++] = (UINT8) strtol(buf, &ptr, 10); + context->n_mode[seq].speed_cnt = (UINT8) cnt; + ir_memset(buf, 0, 16); + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_nmode_data_temp(char *pdata, t_ac_n_mode seq) +{ + + char buf[16] = { 0 }; + char *p = pdata; + char *ptr = NULL; + UINT16 pos = 0; + UINT16 cnt = 0, index = 0; + + while (index <= ir_strlen(pdata)) + { + while ((index != ir_strlen(pdata)) && (*(p++) != ',')) + { + index++; + } + ir_memcpy(buf, pdata + pos, index - pos); + pos = (UINT16) (index + 1); + index = pos; + context->n_mode[seq].temp[cnt++] = (UINT8) (strtol(buf, &ptr, 10) - 16); + context->n_mode[seq].temp_cnt = (UINT8) cnt; + ir_memset(buf, 0, 16); + } + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_nmode_pos(char *buf, t_ac_n_mode index) +{ + UINT16 i = 0; + char data[64] = { 0 }; + // char start[8] = { 0 }; + if (ir_strlen(buf) == 1) + { + if (buf[0] == 'S' || buf[0] == 's') + { + context->n_mode[index].all_speed = 1; + } + else if (buf[0] == 'T' || buf[0] == 't') + { + context->n_mode[index].all_temp = 1; + } + return IR_DECODE_SUCCEEDED; + } + + for (i = 0; i < (UINT16) ir_strlen(buf); i++) + { + if (buf[i] == '&') + { + ir_memcpy(data, buf + i + 1, ir_strlen(buf) - i - 1); + break; + } + } + if (buf[0] == 'S') + { + parse_nmode_data_speed(data, index); + } + else + { + parse_nmode_data_temp(data, index); + } + + return IR_DECODE_SUCCEEDED; +} + +INT8 parse_nmode(struct tag_head *tag, t_ac_n_mode index) +{ + UINT16 i = 0; + UINT16 preindex = 0; + + char buf[64] = { 0 }; + + if (tag->p_data[0] == 'N' && tag->p_data[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->p_data[i] == '|') + { + ir_memcpy(buf, tag->p_data + preindex, i - preindex); + preindex = (UINT16) (i + 1); + parse_nmode_pos(buf, index); + ir_memset(buf, 0, 64); + } + + } + ir_memcpy(buf, tag->p_data + preindex, i - preindex); + parse_nmode_pos(buf, index); + ir_memset(buf, 0, 64); + return IR_DECODE_SUCCEEDED; } \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_decode.c b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_decode.c index 86e9359..1994d5f 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_decode.c +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_decode.c @@ -1,773 +1,773 @@ -/************************************************************************************** -Filename: ir_decode.c -Revised: Date: 2016-10-01 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode (status type) - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - -#include -#include - -#include - -#include "include/ir_decode.h" -#include "include/ir_utils.h" -#include "include/ir_ac_build_frame.h" -#include "include/ir_ac_apply.h" - -struct ir_bin_buffer binary_file; -struct ir_bin_buffer *p_ir_buffer = &binary_file; - -static const char* version = "0.2.5"; - -#if defined USE_DYNAMIC_TAG -struct tag_head *tags; -#else -struct tag_head tags[TAG_COUNT_FOR_PROTOCOL]; -#endif - -static UINT8 byte_array[PROTOCOL_SIZE] = { 0 }; -#if !defined NO_FS -static size_t binary_length = 0; -static UINT8 *binary_content = NULL; -#endif - -static t_remote_category remote_category = REMOTE_CATEGORY_NONE; -static UINT8 ir_binary_type = IR_TYPE_STATUS; -static UINT8 ir_hexadecimal = SUB_CATEGORY_QUATERNARY; - -static int KEY_CODE_MAX[] = -{ - 0, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, - STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, -}; - -UINT8 *ir_hex_code = NULL; -UINT8 ir_hex_len = 0; -t_ac_protocol *context = (t_ac_protocol *) byte_array; - -static lp_apply_ac_parameter apply_table[AC_APPLY_MAX] = -{ - apply_power, - apply_mode, - apply_temperature, - apply_temperature, - apply_wind_speed, - apply_swing, - apply_swing -}; - -// static functions declarations -#if !defined NO_FS -static INT8 ir_ac_file_open(const char *file_name); -#endif - -static INT8 ir_ac_binary_open(UINT8 *binary, UINT16 bin_length); -static UINT16 ir_ac_control(t_remote_ac_status ac_status, UINT16* user_data, UINT8 key_code, - BOOL change_wind_direction); -static INT8 ir_ac_binary_close(); - -#if !defined NO_FS -static INT8 ir_tv_file_open(const char *file_name); -#endif - -static INT8 ir_tv_binary_open(UINT8 *binary, UINT16 bin_length); -static INT8 ir_tv_binary_parse(UINT8 ir_hex_encode); -static UINT16 ir_tv_control(UINT8 key, UINT16 *l_user_data); -static INT8 ir_tv_binary_close(); - - -void noprint(const char *fmt, ...) -{ - (void) fmt; -} - -// pubic function definitions -const char* get_lib_version() -{ - return version; -} - -#if (!defined BOARD_51 && !defined BOARD_CC26XX) -INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name) -{ - INT8 ret = 0; - if (category < REMOTE_CATEGORY_AC || - category >= REMOTE_CATEGORY_NEXT) - { - ir_printf("wrong remote category : %d\n", category); - return IR_DECODE_FAILED; - } - remote_category = category; - - if (sub_category < SUB_CATEGORY_QUATERNARY || - sub_category >= SUB_CATEGORY_NEXT) - { - ir_printf("wrong remote sub category : %d\n", sub_category); - return IR_DECODE_FAILED; - } - - if (category == REMOTE_CATEGORY_AC) - { - ir_binary_type = IR_TYPE_STATUS; - ret = ir_ac_file_open(file_name); - if (IR_DECODE_SUCCEEDED == ret) - { - return ir_ac_lib_parse(); - } - else - { - return ret; - } - } - else - { - ir_binary_type = IR_TYPE_COMMANDS; - if (SUB_CATEGORY_QUATERNARY == sub_category) - { - ir_hexadecimal = 0; - } - else if (SUB_CATEGORY_HEXADECIMAL == sub_category) - { - ir_hexadecimal = 1; - } - else - { - return IR_DECODE_FAILED; - } - - ret = ir_tv_file_open(file_name); - if (IR_DECODE_SUCCEEDED == ret) - { - return ir_tv_binary_parse(ir_hexadecimal); - } - else - { - return ret; - } - } -} -#else -INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name) -{ - return IR_DECODE_SUCCEEDED; -} -#endif - -INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binary, UINT16 bin_length) -{ - INT8 ret = 0; - - if (category < REMOTE_CATEGORY_AC || - category >= REMOTE_CATEGORY_NEXT) - { - ir_printf("wrong remote category\n"); - return IR_DECODE_FAILED; - } - remote_category = (t_remote_category) category; - - if (sub_category < SUB_CATEGORY_QUATERNARY || - sub_category >= SUB_CATEGORY_NEXT) - { - ir_printf("wrong remote sub category : %d\n", sub_category); - return IR_DECODE_FAILED; - } - - if (category == REMOTE_CATEGORY_AC) - { - ir_binary_type = IR_TYPE_STATUS; - ret = ir_ac_binary_open(binary, bin_length); - if (IR_DECODE_SUCCEEDED == ret) - { - return ir_ac_lib_parse(); - } - else - { - return ret; - } - } - else - { - ir_binary_type = IR_TYPE_COMMANDS; - if (SUB_CATEGORY_QUATERNARY == sub_category) - { - ir_hexadecimal = 0; - } - else if (SUB_CATEGORY_HEXADECIMAL == sub_category) - { - ir_hexadecimal = 1; - } - else - { - return IR_DECODE_FAILED; - } - - ret = ir_tv_binary_open(binary, bin_length); - if (IR_DECODE_SUCCEEDED == ret) - { - return ir_tv_binary_parse(ir_hexadecimal); - } - else - { - return ret; - } - } -} - -/** the main entry of decode algorithm **/ -UINT16 ir_decode(UINT8 key_code, UINT16* user_data, - t_remote_ac_status* ac_status, BOOL change_wind_direction) -{ - ir_printf("remote_category = %d, KEY_CODE_MAX = %d\n", remote_category, KEY_CODE_MAX[remote_category]); - - if (key_code < 0 || key_code >= KEY_CODE_MAX[remote_category]) - { - ir_printf("key_code exceeded!\n"); - return 0; - } - - if (IR_TYPE_COMMANDS == ir_binary_type) - { - return ir_tv_control(key_code, user_data); - } - else - { - if (NULL == ac_status) - { - return 0; - } - ir_printf("ac status is not null in decode core : power = %d, mode = %d, " - "temp = %d, wind_dir = %d, wind_speed = %d, " - "key_code = %d, change_wind_direction = %d\n", - ac_status->ac_power, ac_status->ac_mode, - ac_status->ac_temp, ac_status->ac_wind_dir, - ac_status->ac_wind_speed, - key_code, change_wind_direction); - return ir_ac_control(*ac_status, user_data, key_code, change_wind_direction); - } -} - - -INT8 ir_close() -{ - if (IR_TYPE_COMMANDS == ir_binary_type) - { - ir_printf("tv binary close\n"); - return ir_tv_binary_close(); - } - else - { - ir_printf("ac binary close\n"); - return ir_ac_binary_close(); - } -} - - -// static function definitions - -//////// AC Begin //////// -#if !defined NO_FS -static INT8 ir_ac_file_open(const char *file_name) -{ - size_t ret = 0; -#if !defined WIN32 - FILE *stream = fopen(file_name, "rb"); -#else - FILE *stream; - fopen_s(&stream, file_name, "rb"); -#endif - if (NULL == stream) - { - ir_printf("\nfile open failed\n"); - return IR_DECODE_FAILED; - } - - fseek(stream, 0, SEEK_END); - binary_length = (size_t) ftell(stream); - binary_content = (UINT8 *) ir_malloc(binary_length); - - if (NULL == binary_content) - { - ir_printf("\nfailed to alloc memory for binary\n"); - fclose(stream); - return IR_DECODE_FAILED; - } - - fseek(stream, 0, SEEK_SET); - ret = fread(binary_content, binary_length, 1, stream); - - if (ret <= 0) - { - fclose(stream); - ir_free(binary_content); - binary_length = 0; - return IR_DECODE_FAILED; - } - - fclose(stream); - - if (IR_DECODE_FAILED == ir_ac_binary_open(binary_content, (UINT16) binary_length)) - { - ir_free(binary_content); - binary_length = 0; - return IR_DECODE_FAILED; - } - return IR_DECODE_SUCCEEDED; -} -#endif - -static INT8 ir_ac_binary_open(UINT8 *binary, UINT16 bin_length) -{ - // it is recommended that the parameter binary pointing to - // a global memory block in embedded platform environment - p_ir_buffer->data = binary; - p_ir_buffer->len = bin_length; - p_ir_buffer->offset = 0; - return IR_DECODE_SUCCEEDED; -} - -static UINT16 ir_ac_control(t_remote_ac_status ac_status, UINT16* user_data, UINT8 key_code, - BOOL change_wind_direction) -{ - UINT16 time_length = 0; - UINT8 function_code = 0; - - switch(key_code) - { - case 0: - function_code = AC_FUNCTION_POWER; - break; - case 1: - function_code = AC_FUNCTION_MODE; - break; - case 2: - case 7: - function_code = AC_FUNCTION_TEMPERATURE_UP; - break; - case 3: - case 8: - function_code = AC_FUNCTION_TEMPERATURE_DOWN; - break; - case 9: - function_code = AC_FUNCTION_WIND_SPEED; - break; - case 10: - function_code = AC_FUNCTION_WIND_SWING; - break; - case 11: - function_code = AC_FUNCTION_WIND_FIX; - break; - default: - ir_printf("unsupported key_code\n"); - return 0; - } - - 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 - ir_memcpy(ir_hex_code, context->default_code.data, context->default_code.len); - -#if defined USE_APPLY_TABLE - if(ac_status.ac_power != AC_POWER_OFF) - { - for (i = AC_APPLY_POWER; i < AC_APPLY_MAX; i++) - { - apply_table[i](context, parameter_array[i]); - } - } -#else - if (ac_status.ac_power == 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.ac_mode].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_function(context, function_code); - // checksum should always be applied - apply_checksum(context); - - time_length = create_ir_frame(); - - return time_length; -} - -static INT8 ir_ac_binary_close() -{ -#if defined USE_DYNAMIC_TAG - // free context - if (NULL != tags) - { - ir_free(tags); - tags = NULL; - } -#endif - - free_ac_context(); - - return IR_DECODE_SUCCEEDED; -} - -// 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].all_temp) - { - *temp_min = *temp_max = -1; - return IR_DECODE_SUCCEEDED; - } - - *temp_min = -1; - *temp_max = -1; - for (i = 0; i < (UINT8) AC_TEMP_MAX; i++) - { - if (is_in(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 < (UINT8) 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 &= (UINT8)(~(UINT8)((UINT8)1 << (UINT8)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].all_speed) - { - *supported_wind_speed = 0; - return IR_DECODE_SUCCEEDED; - } - - *supported_wind_speed = 0x0F; - - for (i = 0; i < (UINT8) AC_WS_MAX; i++) - { - if (is_in(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 &= (UINT8)(~(UINT8)((UINT8)1 << (UINT8)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 = (UINT8) (context->si.mode_count - 1); - if (*supported_wind_direction < 0) - { - *supported_wind_direction = 0; - } - return IR_DECODE_SUCCEEDED; - } - else - { - return IR_DECODE_FAILED; - } -} - -//////// AC End //////// - -//////// TV Begin //////// -#if !defined NO_FS -static INT8 ir_tv_file_open(const char *file_name) -{ - size_t ret = 0; - -#if !defined WIN32 - FILE *stream = fopen(file_name, "rb"); -#else - FILE *stream; - fopen_s(&stream, file_name, "rb"); -#endif - - if (stream == NULL) - { - ir_printf("\nfile open failed\n"); - return IR_DECODE_FAILED; - } - - fseek(stream, 0, SEEK_END); - binary_length = (size_t) ftell(stream); - - binary_content = (UINT8 *) ir_malloc(binary_length); - if (NULL == binary_content) - { - ir_printf("\nfailed to alloc memory for binary\n"); - fclose(stream); - return IR_DECODE_FAILED; - } - - fseek(stream, 0, SEEK_SET); - ret = fread(binary_content, binary_length, 1, stream); - if (ret <= 0) - { - fclose(stream); - ir_free(binary_content); - binary_length = 0; - return IR_DECODE_FAILED; - } - - fclose(stream); - - if (IR_DECODE_FAILED == ir_tv_binary_open(binary_content, (UINT16) binary_length)) - { - ir_free(binary_content); - binary_length = 0; - return IR_DECODE_FAILED; - } - return IR_DECODE_SUCCEEDED; -} -#endif - -static INT8 ir_tv_binary_open(UINT8 *binary, UINT16 bin_length) -{ - return tv_binary_open(binary, bin_length); -} - -static INT8 ir_tv_binary_parse(UINT8 ir_hex_encode) -{ - if (FALSE == tv_binary_parse(ir_hex_encode)) - { - ir_printf("parse irda binary failed\n"); - return IR_DECODE_FAILED; - } - return IR_DECODE_SUCCEEDED; -} - -static UINT16 ir_tv_control(UINT8 key, UINT16 *l_user_data) -{ -#if defined BOARD_PC - UINT16 print_index = 0; -#endif - UINT16 ir_code_length = 0; - memset(l_user_data, 0x00, USER_DATA_SIZE); - ir_code_length = tv_binary_decode(key, l_user_data); - - return ir_code_length; -} - -static INT8 ir_tv_binary_close() -{ -#if (defined BOARD_PC || defined BOARD_PC_DLL) - ir_lib_free_inner_buffer(); -#endif - return IR_DECODE_SUCCEEDED; -} -//////// TV End //////// - -// combo decode for JNI which means call open, decode and then close in one JNI call -UINT16 ir_decode_combo(const UINT8 category, const UINT8 sub_category, - UINT8* binary, UINT16 bin_length, - UINT8 key_code, UINT16* user_data, - t_remote_ac_status* ac_status, BOOL change_wind_direction) -{ - UINT16 decoded_length = 0; - - if (category < REMOTE_CATEGORY_AC || - category >= REMOTE_CATEGORY_NEXT) - { - ir_printf("wrong remote category\n"); - return IR_DECODE_FAILED; - } - - remote_category = (t_remote_category) category; - - if (key_code < 0 || key_code >= KEY_CODE_MAX[remote_category]) - { - ir_printf("key_code exceeded!\n"); - return 0; - } - - if (IR_DECODE_SUCCEEDED == - ir_binary_open(category, sub_category, binary, bin_length)) - { - decoded_length = ir_decode(key_code, user_data, ac_status, change_wind_direction); - ir_close(); - return decoded_length; - } - else - { - return 0; - } -} - -#if (defined BOARD_PC || defined BOARD_PC_DLL) -void ir_lib_free_inner_buffer() -{ - if (NULL != binary_content) - { - ir_free(binary_content); - binary_content = NULL; - } -} +/************************************************************************************** +Filename: ir_decode.c +Revised: Date: 2016-10-01 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode (status type) + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + +#include +#include + +#include + +#include "include/ir_decode.h" +#include "include/ir_utils.h" +#include "include/ir_ac_build_frame.h" +#include "include/ir_ac_apply.h" + +struct ir_bin_buffer binary_file; +struct ir_bin_buffer *p_ir_buffer = &binary_file; + +static const char* version = "0.2.5"; + +#if defined USE_DYNAMIC_TAG +struct tag_head *tags; +#else +struct tag_head tags[TAG_COUNT_FOR_PROTOCOL]; +#endif + +static UINT8 byte_array[PROTOCOL_SIZE] = { 0 }; +#if !defined NO_FS +static size_t binary_length = 0; +static UINT8 *binary_content = NULL; +#endif + +static t_remote_category remote_category = REMOTE_CATEGORY_NONE; +static UINT8 ir_binary_type = IR_TYPE_STATUS; +static UINT8 ir_hexadecimal = SUB_CATEGORY_QUATERNARY; + +static int KEY_CODE_MAX[] = +{ + 0, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, + STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, +}; + +UINT8 *ir_hex_code = NULL; +UINT8 ir_hex_len = 0; +t_ac_protocol *context = (t_ac_protocol *) byte_array; + +static lp_apply_ac_parameter apply_table[AC_APPLY_MAX] = +{ + apply_power, + apply_mode, + apply_temperature, + apply_temperature, + apply_wind_speed, + apply_swing, + apply_swing +}; + +// static functions declarations +#if !defined NO_FS +static INT8 ir_ac_file_open(const char *file_name); +#endif + +static INT8 ir_ac_binary_open(UINT8 *binary, UINT16 bin_length); +static UINT16 ir_ac_control(t_remote_ac_status ac_status, UINT16* user_data, UINT8 key_code, + BOOL change_wind_direction); +static INT8 ir_ac_binary_close(); + +#if !defined NO_FS +static INT8 ir_tv_file_open(const char *file_name); +#endif + +static INT8 ir_tv_binary_open(UINT8 *binary, UINT16 bin_length); +static INT8 ir_tv_binary_parse(UINT8 ir_hex_encode); +static UINT16 ir_tv_control(UINT8 key, UINT16 *l_user_data); +static INT8 ir_tv_binary_close(); + + +void noprint(const char *fmt, ...) +{ + (void) fmt; +} + +// pubic function definitions +const char* get_lib_version() +{ + return version; +} + +#if (!defined BOARD_51 && !defined BOARD_CC26XX) +INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name) +{ + INT8 ret = 0; + if (category < REMOTE_CATEGORY_AC || + category >= REMOTE_CATEGORY_NEXT) + { + ir_printf("wrong remote category : %d\n", category); + return IR_DECODE_FAILED; + } + remote_category = category; + + if (sub_category < SUB_CATEGORY_QUATERNARY || + sub_category >= SUB_CATEGORY_NEXT) + { + ir_printf("wrong remote sub category : %d\n", sub_category); + return IR_DECODE_FAILED; + } + + if (category == REMOTE_CATEGORY_AC) + { + ir_binary_type = IR_TYPE_STATUS; + ret = ir_ac_file_open(file_name); + if (IR_DECODE_SUCCEEDED == ret) + { + return ir_ac_lib_parse(); + } + else + { + return ret; + } + } + else + { + ir_binary_type = IR_TYPE_COMMANDS; + if (SUB_CATEGORY_QUATERNARY == sub_category) + { + ir_hexadecimal = 0; + } + else if (SUB_CATEGORY_HEXADECIMAL == sub_category) + { + ir_hexadecimal = 1; + } + else + { + return IR_DECODE_FAILED; + } + + ret = ir_tv_file_open(file_name); + if (IR_DECODE_SUCCEEDED == ret) + { + return ir_tv_binary_parse(ir_hexadecimal); + } + else + { + return ret; + } + } +} +#else +INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name) +{ + return IR_DECODE_SUCCEEDED; +} +#endif + +INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binary, UINT16 bin_length) +{ + INT8 ret = 0; + + if (category < REMOTE_CATEGORY_AC || + category >= REMOTE_CATEGORY_NEXT) + { + ir_printf("wrong remote category\n"); + return IR_DECODE_FAILED; + } + remote_category = (t_remote_category) category; + + if (sub_category < SUB_CATEGORY_QUATERNARY || + sub_category >= SUB_CATEGORY_NEXT) + { + ir_printf("wrong remote sub category : %d\n", sub_category); + return IR_DECODE_FAILED; + } + + if (category == REMOTE_CATEGORY_AC) + { + ir_binary_type = IR_TYPE_STATUS; + ret = ir_ac_binary_open(binary, bin_length); + if (IR_DECODE_SUCCEEDED == ret) + { + return ir_ac_lib_parse(); + } + else + { + return ret; + } + } + else + { + ir_binary_type = IR_TYPE_COMMANDS; + if (SUB_CATEGORY_QUATERNARY == sub_category) + { + ir_hexadecimal = 0; + } + else if (SUB_CATEGORY_HEXADECIMAL == sub_category) + { + ir_hexadecimal = 1; + } + else + { + return IR_DECODE_FAILED; + } + + ret = ir_tv_binary_open(binary, bin_length); + if (IR_DECODE_SUCCEEDED == ret) + { + return ir_tv_binary_parse(ir_hexadecimal); + } + else + { + return ret; + } + } +} + +/** the main entry of decode algorithm **/ +UINT16 ir_decode(UINT8 key_code, UINT16* user_data, + t_remote_ac_status* ac_status, BOOL change_wind_direction) +{ + ir_printf("remote_category = %d, KEY_CODE_MAX = %d\n", remote_category, KEY_CODE_MAX[remote_category]); + + if (key_code < 0 || key_code >= KEY_CODE_MAX[remote_category]) + { + ir_printf("key_code exceeded!\n"); + return 0; + } + + if (IR_TYPE_COMMANDS == ir_binary_type) + { + return ir_tv_control(key_code, user_data); + } + else + { + if (NULL == ac_status) + { + return 0; + } + ir_printf("ac status is not null in decode core : power = %d, mode = %d, " + "temp = %d, wind_dir = %d, wind_speed = %d, " + "key_code = %d, change_wind_direction = %d\n", + ac_status->ac_power, ac_status->ac_mode, + ac_status->ac_temp, ac_status->ac_wind_dir, + ac_status->ac_wind_speed, + key_code, change_wind_direction); + return ir_ac_control(*ac_status, user_data, key_code, change_wind_direction); + } +} + + +INT8 ir_close() +{ + if (IR_TYPE_COMMANDS == ir_binary_type) + { + ir_printf("tv binary close\n"); + return ir_tv_binary_close(); + } + else + { + ir_printf("ac binary close\n"); + return ir_ac_binary_close(); + } +} + + +// static function definitions + +//////// AC Begin //////// +#if !defined NO_FS +static INT8 ir_ac_file_open(const char *file_name) +{ + size_t ret = 0; +#if !defined WIN32 + FILE *stream = fopen(file_name, "rb"); +#else + FILE *stream; + fopen_s(&stream, file_name, "rb"); +#endif + if (NULL == stream) + { + ir_printf("\nfile open failed\n"); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_END); + binary_length = (size_t) ftell(stream); + binary_content = (UINT8 *) ir_malloc(binary_length); + + if (NULL == binary_content) + { + ir_printf("\nfailed to alloc memory for binary\n"); + fclose(stream); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_SET); + ret = fread(binary_content, binary_length, 1, stream); + + if (ret <= 0) + { + fclose(stream); + ir_free(binary_content); + binary_length = 0; + return IR_DECODE_FAILED; + } + + fclose(stream); + + if (IR_DECODE_FAILED == ir_ac_binary_open(binary_content, (UINT16) binary_length)) + { + ir_free(binary_content); + binary_length = 0; + return IR_DECODE_FAILED; + } + return IR_DECODE_SUCCEEDED; +} +#endif + +static INT8 ir_ac_binary_open(UINT8 *binary, UINT16 bin_length) +{ + // it is recommended that the parameter binary pointing to + // a global memory block in embedded platform environment + p_ir_buffer->data = binary; + p_ir_buffer->len = bin_length; + p_ir_buffer->offset = 0; + return IR_DECODE_SUCCEEDED; +} + +static UINT16 ir_ac_control(t_remote_ac_status ac_status, UINT16* user_data, UINT8 key_code, + BOOL change_wind_direction) +{ + UINT16 time_length = 0; + UINT8 function_code = 0; + + switch(key_code) + { + case 0: + function_code = AC_FUNCTION_POWER; + break; + case 1: + function_code = AC_FUNCTION_MODE; + break; + case 2: + case 7: + function_code = AC_FUNCTION_TEMPERATURE_UP; + break; + case 3: + case 8: + function_code = AC_FUNCTION_TEMPERATURE_DOWN; + break; + case 9: + function_code = AC_FUNCTION_WIND_SPEED; + break; + case 10: + function_code = AC_FUNCTION_WIND_SWING; + break; + case 11: + function_code = AC_FUNCTION_WIND_FIX; + break; + default: + ir_printf("unsupported key_code\n"); + return 0; + } + + 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 + ir_memcpy(ir_hex_code, context->default_code.data, context->default_code.len); + +#if defined USE_APPLY_TABLE + if(ac_status.ac_power != AC_POWER_OFF) + { + for (i = AC_APPLY_POWER; i < AC_APPLY_MAX; i++) + { + apply_table[i](context, parameter_array[i]); + } + } +#else + if (ac_status.ac_power == 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.ac_mode].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_function(context, function_code); + // checksum should always be applied + apply_checksum(context); + + time_length = create_ir_frame(); + + return time_length; +} + +static INT8 ir_ac_binary_close() +{ +#if defined USE_DYNAMIC_TAG + // free context + if (NULL != tags) + { + ir_free(tags); + tags = NULL; + } +#endif + + free_ac_context(); + + return IR_DECODE_SUCCEEDED; +} + +// 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].all_temp) + { + *temp_min = *temp_max = -1; + return IR_DECODE_SUCCEEDED; + } + + *temp_min = -1; + *temp_max = -1; + for (i = 0; i < (UINT8) AC_TEMP_MAX; i++) + { + if (is_in(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 < (UINT8) 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 &= (UINT8)(~(UINT8)((UINT8)1 << (UINT8)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].all_speed) + { + *supported_wind_speed = 0; + return IR_DECODE_SUCCEEDED; + } + + *supported_wind_speed = 0x0F; + + for (i = 0; i < (UINT8) AC_WS_MAX; i++) + { + if (is_in(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 &= (UINT8)(~(UINT8)((UINT8)1 << (UINT8)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 = (UINT8) (context->si.mode_count - 1); + if (*supported_wind_direction < 0) + { + *supported_wind_direction = 0; + } + return IR_DECODE_SUCCEEDED; + } + else + { + return IR_DECODE_FAILED; + } +} + +//////// AC End //////// + +//////// TV Begin //////// +#if !defined NO_FS +static INT8 ir_tv_file_open(const char *file_name) +{ + size_t ret = 0; + +#if !defined WIN32 + FILE *stream = fopen(file_name, "rb"); +#else + FILE *stream; + fopen_s(&stream, file_name, "rb"); +#endif + + if (stream == NULL) + { + ir_printf("\nfile open failed\n"); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_END); + binary_length = (size_t) ftell(stream); + + binary_content = (UINT8 *) ir_malloc(binary_length); + if (NULL == binary_content) + { + ir_printf("\nfailed to alloc memory for binary\n"); + fclose(stream); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_SET); + ret = fread(binary_content, binary_length, 1, stream); + if (ret <= 0) + { + fclose(stream); + ir_free(binary_content); + binary_length = 0; + return IR_DECODE_FAILED; + } + + fclose(stream); + + if (IR_DECODE_FAILED == ir_tv_binary_open(binary_content, (UINT16) binary_length)) + { + ir_free(binary_content); + binary_length = 0; + return IR_DECODE_FAILED; + } + return IR_DECODE_SUCCEEDED; +} +#endif + +static INT8 ir_tv_binary_open(UINT8 *binary, UINT16 bin_length) +{ + return tv_binary_open(binary, bin_length); +} + +static INT8 ir_tv_binary_parse(UINT8 ir_hex_encode) +{ + if (FALSE == tv_binary_parse(ir_hex_encode)) + { + ir_printf("parse irda binary failed\n"); + return IR_DECODE_FAILED; + } + return IR_DECODE_SUCCEEDED; +} + +static UINT16 ir_tv_control(UINT8 key, UINT16 *l_user_data) +{ +#if defined BOARD_PC + UINT16 print_index = 0; +#endif + UINT16 ir_code_length = 0; + memset(l_user_data, 0x00, USER_DATA_SIZE); + ir_code_length = tv_binary_decode(key, l_user_data); + + return ir_code_length; +} + +static INT8 ir_tv_binary_close() +{ +#if (defined BOARD_PC || defined BOARD_PC_DLL) + ir_lib_free_inner_buffer(); +#endif + return IR_DECODE_SUCCEEDED; +} +//////// TV End //////// + +// combo decode for JNI which means call open, decode and then close in one JNI call +UINT16 ir_decode_combo(const UINT8 category, const UINT8 sub_category, + UINT8* binary, UINT16 bin_length, + UINT8 key_code, UINT16* user_data, + t_remote_ac_status* ac_status, BOOL change_wind_direction) +{ + UINT16 decoded_length = 0; + + if (category < REMOTE_CATEGORY_AC || + category >= REMOTE_CATEGORY_NEXT) + { + ir_printf("wrong remote category\n"); + return IR_DECODE_FAILED; + } + + remote_category = (t_remote_category) category; + + if (key_code < 0 || key_code >= KEY_CODE_MAX[remote_category]) + { + ir_printf("key_code exceeded!\n"); + return 0; + } + + if (IR_DECODE_SUCCEEDED == + ir_binary_open(category, sub_category, binary, bin_length)) + { + decoded_length = ir_decode(key_code, user_data, ac_status, change_wind_direction); + ir_close(); + return decoded_length; + } + else + { + return 0; + } +} + +#if (defined BOARD_PC || defined BOARD_PC_DLL) +void ir_lib_free_inner_buffer() +{ + if (NULL != binary_content) + { + ir_free(binary_content); + binary_content = NULL; + } +} #endif \ No newline at end of file diff --git a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_tv_control.c b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_tv_control.c index 88796f5..53a3e80 100644 --- a/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_tv_control.c +++ b/cc25xx-8051-example/ti/BLE-CC254x/Projects/ble/SimpleBLEPeripheral-IREXT/Source/ir_decoder/src/ir_tv_control.c @@ -1,453 +1,453 @@ -/************************************************************************************** -Filename: ir_tv_control.c -Revised: Date: 2016-10-21 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode (compressed command type) - -Revision log: -* 2016-10-21: created by strawmanbobi -**************************************************************************************/ - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "hicpp-signed-bitwise" -#endif - -#include - -#include "include/ir_defs.h" -#include "include/ir_decode.h" -#include "include/ir_tv_control.h" - - -struct buffer -{ - UINT8 *data; - UINT16 len; - UINT16 offset; -} ir_file; - - -static struct buffer *pbuffer = &ir_file; - -static UINT8 *prot_cycles_num = NULL; -static t_ir_cycles *prot_cycles_data[IRDA_MAX]; -static UINT8 prot_items_cnt = 0; -static t_ir_data *prot_items_data = NULL; -static t_ir_data_tv *remote_p; -static UINT8 *remote_pdata = NULL; - -static UINT16 time_index = 0; -static UINT8 ir_level = IRDA_LEVEL_LOW; -static UINT8 ir_toggle_bit = FALSE; -static UINT8 ir_decode_flag = IRDA_DECODE_1_BIT; -static UINT8 cycles_num_size = 0; - - -static BOOL get_ir_protocol(UINT8 encode_type); - -static BOOL get_ir_keymap(void); - -static void print_ir_time(t_ir_data *data, UINT8 key_index, UINT16 *ir_time); - -static void process_decode_number(UINT8 keycode, t_ir_data *data, UINT8 valid_bits, UINT16 *ir_time); - -static void convert_to_ir_time(UINT8 value, UINT16 *ir_time); - -static void replace_with(t_ir_cycles *pcycles_num, UINT16 *ir_time); - - -INT8 tv_binary_open(UINT8 *binary, UINT16 binary_length) -{ - // load binary to buffer - pbuffer->data = binary; - pbuffer->len = binary_length; - pbuffer->offset = 0; - return IR_DECODE_SUCCEEDED; -} - -BOOL tv_binary_parse(UINT8 encode_type) -{ - if (FALSE == get_ir_protocol(encode_type)) - { - return FALSE; - } - - return get_ir_keymap(); -} - -UINT16 tv_binary_decode(UINT8 key, UINT16 *user_data) -{ - UINT16 i = 0; - - time_index = 0; - ir_level = IRDA_LEVEL_LOW; - - for (i = 0; i < prot_items_cnt; i++) - { - print_ir_time(&prot_items_data[i], key, user_data); - } - - // next flip - if (2 == prot_cycles_num[IRDA_FLIP]) - { - ir_toggle_bit = (ir_toggle_bit == FALSE) ? TRUE : FALSE; - } - - return time_index; -} - - -static BOOL get_ir_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; - - /* t_ac_protocol name */ - 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) - { - ir_decode_flag = IRDA_DECODE_1_BIT; - } - else - { - ir_decode_flag = IRDA_DECODE_2_BITS; - } - } - else if (encode_type == 1) - { - cycles_num_size = IRDA_MAX; - ir_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] = (t_ir_cycles *) (&prot_cycles[sizeof(t_ir_cycles) * cycles_sum]); - } - else - { - prot_cycles_data[i] = NULL; - } - cycles_sum += prot_cycles_num[i]; - } - pbuffer->offset += sizeof(t_ir_cycles) * cycles_sum; - - /* items count */ - prot_items_cnt = pbuffer->data[pbuffer->offset]; - pbuffer->offset += sizeof(UINT8); - - /* items data */ - prot_items_data = (t_ir_data *) (pbuffer->data + pbuffer->offset); - pbuffer->offset += prot_items_cnt * sizeof(t_ir_data); - - ir_toggle_bit = FALSE; - - return TRUE; -} - -static BOOL get_ir_keymap(void) -{ - remote_p = (t_ir_data_tv *) (pbuffer->data + pbuffer->offset); - pbuffer->offset += sizeof(t_ir_data_tv); - - if (strncmp(remote_p->magic, "irda", 4) == 0) - { - remote_pdata = pbuffer->data + pbuffer->offset; - return TRUE; - } - - return FALSE; -} - -static void print_ir_time(t_ir_data *data, UINT8 key_index, UINT16 *ir_time) -{ - UINT8 i = 0; - UINT8 cycles_num = 0; - t_ir_cycles *pcycles = NULL; - UINT8 key_code = 0; - - if (NULL == data || NULL == ir_time) - { - ir_printf("data or ir_time is null\n"); - return; - } - - pcycles = prot_cycles_data[data->index]; - key_code = remote_pdata[remote_p->per_keycode_bytes * key_index + data->index - 1]; - - if (prot_cycles_num[IRDA_ONE] != 1 || prot_cycles_num[IRDA_ZERO] != 1) - { - ir_printf("logical 1 or 0 is invalid\n"); - return; - } - - if (time_index >= USER_DATA_SIZE) - { - ir_printf("time index exceeded\n"); - return; - } - - if (data->bits == 1) - { - if (pcycles == NULL) - { - ir_printf("pcycles is null\n"); - return; - } - - cycles_num = prot_cycles_num[data->index]; - if (cycles_num > 5) - { - ir_printf("cycles number exceeded\n"); - return; - } - - for (i = cycles_num; i > 0; i--) - { - if (cycles_num == 2 && data->index == IRDA_FLIP) - { - if (ir_toggle_bit == TRUE) - { - pcycles += 1; - } - } - - if (pcycles->mask && pcycles->space) - { - if (pcycles->flag == IRDA_FLAG_NORMAL) - { - if (ir_level == IRDA_LEVEL_HIGH && time_index != 0) - { - time_index--; - ir_time[time_index++] += pcycles->mask; - } - else if (ir_level == IRDA_LEVEL_LOW) - { - ir_time[time_index++] = pcycles->mask; - } - ir_time[time_index++] = pcycles->space; - ir_level = IRDA_LEVEL_LOW; - } - else if (pcycles->flag == IRDA_FLAG_INVERSE) - { - if (ir_level == IRDA_LEVEL_LOW && time_index != 0) - { - time_index--; - ir_time[time_index++] += pcycles->space; - } - else if (ir_level == IRDA_LEVEL_HIGH) - { - ir_time[time_index++] = pcycles->space; - } - ir_time[time_index++] = pcycles->mask; - ir_level = IRDA_LEVEL_HIGH; - } - } - else if (0 == pcycles->mask && 0 != pcycles->space) - { - if (ir_level == IRDA_LEVEL_LOW && time_index != 0) - { - time_index--; - ir_time[time_index++] += pcycles->space; - } - else if (ir_level == IRDA_LEVEL_HIGH) - { - ir_time[time_index++] = pcycles->space; - } - ir_level = IRDA_LEVEL_LOW; - } - else if (0 == pcycles->space && 0 != pcycles->mask) - { - if (ir_level == IRDA_LEVEL_HIGH && time_index != 0) - { - time_index--; - ir_time[time_index++] += pcycles->mask; - } - else if (ir_level == IRDA_LEVEL_LOW) - { - ir_time[time_index++] = pcycles->mask; - } - ir_level = IRDA_LEVEL_HIGH; - } - else - { - // do nothing - } - - if (cycles_num == 2 && data->index == IRDA_FLIP) - { - break; - } - pcycles++; - } - } - else - { - // mode: inverse - if (data->mode == 1) - key_code = ~key_code; - - if (ir_decode_flag == IRDA_DECODE_1_BIT) - { - // for binary formatted code - process_decode_number(key_code, data, 1, ir_time); - } - else if (ir_decode_flag == IRDA_DECODE_2_BITS) - { - // for quaternary formatted code - process_decode_number(key_code, data, 2, ir_time); - } - else if (ir_decode_flag == IRDA_DECODE_4_BITS) - { - // for hexadecimal formatted code - process_decode_number(key_code, data, 4, ir_time); - } - } -} - -static void process_decode_number(UINT8 keycode, t_ir_data *data, UINT8 valid_bits, UINT16 *ir_time) -{ - UINT8 i = 0; - UINT8 value = 0; - UINT8 bit_num = data->bits / valid_bits; - UINT8 valid_value = 0; - - valid_value = (UINT8) ((valid_bits == 1) ? 1 : (valid_bits * valid_bits - 1)); - - if (data->lsb == IRDA_LSB) - { - for (i = 0; i < bit_num; i++) - { - value = (keycode >> (valid_bits * i)) & valid_value; - convert_to_ir_time(value, ir_time); - } - } - else if (data->lsb == IRDA_MSB) - { - for (i = 0; i < bit_num; i++) - { - value = (keycode >> (data->bits - valid_bits * (i + 1))) & valid_value; - convert_to_ir_time(value, ir_time); - } - } -} - -static void convert_to_ir_time(UINT8 value, UINT16 *ir_time) -{ - switch (value) - { - case 0: - replace_with(prot_cycles_data[IRDA_ZERO], ir_time); - break; - case 1: - replace_with(prot_cycles_data[IRDA_ONE], ir_time); - break; - case 2: - replace_with(prot_cycles_data[IRDA_TWO], ir_time); - break; - case 3: - replace_with(prot_cycles_data[IRDA_THREE], ir_time); - break; - case 4: - replace_with(prot_cycles_data[IRDA_FOUR], ir_time); - break; - case 5: - replace_with(prot_cycles_data[IRDA_FIVE], ir_time); - break; - case 6: - replace_with(prot_cycles_data[IRDA_SIX], ir_time); - break; - case 7: - replace_with(prot_cycles_data[IRDA_SEVEN], ir_time); - break; - case 8: - replace_with(prot_cycles_data[IRDA_EIGHT], ir_time); - break; - case 9: - replace_with(prot_cycles_data[IRDA_NINE], ir_time); - break; - case 0x0A: - replace_with(prot_cycles_data[IRDA_A], ir_time); - break; - case 0x0B: - replace_with(prot_cycles_data[IRDA_B], ir_time); - break; - case 0x0C: - replace_with(prot_cycles_data[IRDA_C], ir_time); - break; - case 0x0D: - replace_with(prot_cycles_data[IRDA_D], ir_time); - break; - case 0x0E: - replace_with(prot_cycles_data[IRDA_E], ir_time); - break; - case 0x0F: - replace_with(prot_cycles_data[IRDA_F], ir_time); - break; - default: - break; - } -} - -static void replace_with(t_ir_cycles *pcycles_num, UINT16 *ir_time) -{ - if (NULL == pcycles_num || NULL == ir_time) - { - return; - } - - if (pcycles_num->flag == IRDA_FLAG_NORMAL) - { - if (ir_level == IRDA_LEVEL_HIGH && time_index != 0) - { - time_index--; - ir_time[time_index++] += pcycles_num->mask; - } - else if (ir_level == IRDA_LEVEL_LOW) - { - ir_time[time_index++] = pcycles_num->mask; - } - ir_time[time_index++] = pcycles_num->space; - ir_level = IRDA_LEVEL_LOW; - } - else if (pcycles_num->flag == IRDA_FLAG_INVERSE) - { - if (ir_level == IRDA_LEVEL_LOW && time_index != 0) - { - time_index--; - ir_time[time_index++] += pcycles_num->space; - } - else if (ir_level == IRDA_LEVEL_HIGH) - { - ir_time[time_index++] = pcycles_num->space; - } - ir_time[time_index++] = pcycles_num->mask; - ir_level = IRDA_LEVEL_HIGH; - } +/************************************************************************************** +Filename: ir_tv_control.c +Revised: Date: 2016-10-21 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode (compressed command type) + +Revision log: +* 2016-10-21: created by strawmanbobi +**************************************************************************************/ + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "hicpp-signed-bitwise" +#endif + +#include + +#include "include/ir_defs.h" +#include "include/ir_decode.h" +#include "include/ir_tv_control.h" + + +struct buffer +{ + UINT8 *data; + UINT16 len; + UINT16 offset; +} ir_file; + + +static struct buffer *pbuffer = &ir_file; + +static UINT8 *prot_cycles_num = NULL; +static t_ir_cycles *prot_cycles_data[IRDA_MAX]; +static UINT8 prot_items_cnt = 0; +static t_ir_data *prot_items_data = NULL; +static t_ir_data_tv *remote_p; +static UINT8 *remote_pdata = NULL; + +static UINT16 time_index = 0; +static UINT8 ir_level = IRDA_LEVEL_LOW; +static UINT8 ir_toggle_bit = FALSE; +static UINT8 ir_decode_flag = IRDA_DECODE_1_BIT; +static UINT8 cycles_num_size = 0; + + +static BOOL get_ir_protocol(UINT8 encode_type); + +static BOOL get_ir_keymap(void); + +static void print_ir_time(t_ir_data *data, UINT8 key_index, UINT16 *ir_time); + +static void process_decode_number(UINT8 keycode, t_ir_data *data, UINT8 valid_bits, UINT16 *ir_time); + +static void convert_to_ir_time(UINT8 value, UINT16 *ir_time); + +static void replace_with(t_ir_cycles *pcycles_num, UINT16 *ir_time); + + +INT8 tv_binary_open(UINT8 *binary, UINT16 binary_length) +{ + // load binary to buffer + pbuffer->data = binary; + pbuffer->len = binary_length; + pbuffer->offset = 0; + return IR_DECODE_SUCCEEDED; +} + +BOOL tv_binary_parse(UINT8 encode_type) +{ + if (FALSE == get_ir_protocol(encode_type)) + { + return FALSE; + } + + return get_ir_keymap(); +} + +UINT16 tv_binary_decode(UINT8 key, UINT16 *user_data) +{ + UINT16 i = 0; + + time_index = 0; + ir_level = IRDA_LEVEL_LOW; + + for (i = 0; i < prot_items_cnt; i++) + { + print_ir_time(&prot_items_data[i], key, user_data); + } + + // next flip + if (2 == prot_cycles_num[IRDA_FLIP]) + { + ir_toggle_bit = (ir_toggle_bit == FALSE) ? TRUE : FALSE; + } + + return time_index; +} + + +static BOOL get_ir_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; + + /* t_ac_protocol name */ + 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) + { + ir_decode_flag = IRDA_DECODE_1_BIT; + } + else + { + ir_decode_flag = IRDA_DECODE_2_BITS; + } + } + else if (encode_type == 1) + { + cycles_num_size = IRDA_MAX; + ir_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] = (t_ir_cycles *) (&prot_cycles[sizeof(t_ir_cycles) * cycles_sum]); + } + else + { + prot_cycles_data[i] = NULL; + } + cycles_sum += prot_cycles_num[i]; + } + pbuffer->offset += sizeof(t_ir_cycles) * cycles_sum; + + /* items count */ + prot_items_cnt = pbuffer->data[pbuffer->offset]; + pbuffer->offset += sizeof(UINT8); + + /* items data */ + prot_items_data = (t_ir_data *) (pbuffer->data + pbuffer->offset); + pbuffer->offset += prot_items_cnt * sizeof(t_ir_data); + + ir_toggle_bit = FALSE; + + return TRUE; +} + +static BOOL get_ir_keymap(void) +{ + remote_p = (t_ir_data_tv *) (pbuffer->data + pbuffer->offset); + pbuffer->offset += sizeof(t_ir_data_tv); + + if (strncmp(remote_p->magic, "irda", 4) == 0) + { + remote_pdata = pbuffer->data + pbuffer->offset; + return TRUE; + } + + return FALSE; +} + +static void print_ir_time(t_ir_data *data, UINT8 key_index, UINT16 *ir_time) +{ + UINT8 i = 0; + UINT8 cycles_num = 0; + t_ir_cycles *pcycles = NULL; + UINT8 key_code = 0; + + if (NULL == data || NULL == ir_time) + { + ir_printf("data or ir_time is null\n"); + return; + } + + pcycles = prot_cycles_data[data->index]; + key_code = remote_pdata[remote_p->per_keycode_bytes * key_index + data->index - 1]; + + if (prot_cycles_num[IRDA_ONE] != 1 || prot_cycles_num[IRDA_ZERO] != 1) + { + ir_printf("logical 1 or 0 is invalid\n"); + return; + } + + if (time_index >= USER_DATA_SIZE) + { + ir_printf("time index exceeded\n"); + return; + } + + if (data->bits == 1) + { + if (pcycles == NULL) + { + ir_printf("pcycles is null\n"); + return; + } + + cycles_num = prot_cycles_num[data->index]; + if (cycles_num > 5) + { + ir_printf("cycles number exceeded\n"); + return; + } + + for (i = cycles_num; i > 0; i--) + { + if (cycles_num == 2 && data->index == IRDA_FLIP) + { + if (ir_toggle_bit == TRUE) + { + pcycles += 1; + } + } + + if (pcycles->mask && pcycles->space) + { + if (pcycles->flag == IRDA_FLAG_NORMAL) + { + if (ir_level == IRDA_LEVEL_HIGH && time_index != 0) + { + time_index--; + ir_time[time_index++] += pcycles->mask; + } + else if (ir_level == IRDA_LEVEL_LOW) + { + ir_time[time_index++] = pcycles->mask; + } + ir_time[time_index++] = pcycles->space; + ir_level = IRDA_LEVEL_LOW; + } + else if (pcycles->flag == IRDA_FLAG_INVERSE) + { + if (ir_level == IRDA_LEVEL_LOW && time_index != 0) + { + time_index--; + ir_time[time_index++] += pcycles->space; + } + else if (ir_level == IRDA_LEVEL_HIGH) + { + ir_time[time_index++] = pcycles->space; + } + ir_time[time_index++] = pcycles->mask; + ir_level = IRDA_LEVEL_HIGH; + } + } + else if (0 == pcycles->mask && 0 != pcycles->space) + { + if (ir_level == IRDA_LEVEL_LOW && time_index != 0) + { + time_index--; + ir_time[time_index++] += pcycles->space; + } + else if (ir_level == IRDA_LEVEL_HIGH) + { + ir_time[time_index++] = pcycles->space; + } + ir_level = IRDA_LEVEL_LOW; + } + else if (0 == pcycles->space && 0 != pcycles->mask) + { + if (ir_level == IRDA_LEVEL_HIGH && time_index != 0) + { + time_index--; + ir_time[time_index++] += pcycles->mask; + } + else if (ir_level == IRDA_LEVEL_LOW) + { + ir_time[time_index++] = pcycles->mask; + } + ir_level = IRDA_LEVEL_HIGH; + } + else + { + // do nothing + } + + if (cycles_num == 2 && data->index == IRDA_FLIP) + { + break; + } + pcycles++; + } + } + else + { + // mode: inverse + if (data->mode == 1) + key_code = ~key_code; + + if (ir_decode_flag == IRDA_DECODE_1_BIT) + { + // for binary formatted code + process_decode_number(key_code, data, 1, ir_time); + } + else if (ir_decode_flag == IRDA_DECODE_2_BITS) + { + // for quaternary formatted code + process_decode_number(key_code, data, 2, ir_time); + } + else if (ir_decode_flag == IRDA_DECODE_4_BITS) + { + // for hexadecimal formatted code + process_decode_number(key_code, data, 4, ir_time); + } + } +} + +static void process_decode_number(UINT8 keycode, t_ir_data *data, UINT8 valid_bits, UINT16 *ir_time) +{ + UINT8 i = 0; + UINT8 value = 0; + UINT8 bit_num = data->bits / valid_bits; + UINT8 valid_value = 0; + + valid_value = (UINT8) ((valid_bits == 1) ? 1 : (valid_bits * valid_bits - 1)); + + if (data->lsb == IRDA_LSB) + { + for (i = 0; i < bit_num; i++) + { + value = (keycode >> (valid_bits * i)) & valid_value; + convert_to_ir_time(value, ir_time); + } + } + else if (data->lsb == IRDA_MSB) + { + for (i = 0; i < bit_num; i++) + { + value = (keycode >> (data->bits - valid_bits * (i + 1))) & valid_value; + convert_to_ir_time(value, ir_time); + } + } +} + +static void convert_to_ir_time(UINT8 value, UINT16 *ir_time) +{ + switch (value) + { + case 0: + replace_with(prot_cycles_data[IRDA_ZERO], ir_time); + break; + case 1: + replace_with(prot_cycles_data[IRDA_ONE], ir_time); + break; + case 2: + replace_with(prot_cycles_data[IRDA_TWO], ir_time); + break; + case 3: + replace_with(prot_cycles_data[IRDA_THREE], ir_time); + break; + case 4: + replace_with(prot_cycles_data[IRDA_FOUR], ir_time); + break; + case 5: + replace_with(prot_cycles_data[IRDA_FIVE], ir_time); + break; + case 6: + replace_with(prot_cycles_data[IRDA_SIX], ir_time); + break; + case 7: + replace_with(prot_cycles_data[IRDA_SEVEN], ir_time); + break; + case 8: + replace_with(prot_cycles_data[IRDA_EIGHT], ir_time); + break; + case 9: + replace_with(prot_cycles_data[IRDA_NINE], ir_time); + break; + case 0x0A: + replace_with(prot_cycles_data[IRDA_A], ir_time); + break; + case 0x0B: + replace_with(prot_cycles_data[IRDA_B], ir_time); + break; + case 0x0C: + replace_with(prot_cycles_data[IRDA_C], ir_time); + break; + case 0x0D: + replace_with(prot_cycles_data[IRDA_D], ir_time); + break; + case 0x0E: + replace_with(prot_cycles_data[IRDA_E], ir_time); + break; + case 0x0F: + replace_with(prot_cycles_data[IRDA_F], ir_time); + break; + default: + break; + } +} + +static void replace_with(t_ir_cycles *pcycles_num, UINT16 *ir_time) +{ + if (NULL == pcycles_num || NULL == ir_time) + { + return; + } + + if (pcycles_num->flag == IRDA_FLAG_NORMAL) + { + if (ir_level == IRDA_LEVEL_HIGH && time_index != 0) + { + time_index--; + ir_time[time_index++] += pcycles_num->mask; + } + else if (ir_level == IRDA_LEVEL_LOW) + { + ir_time[time_index++] = pcycles_num->mask; + } + ir_time[time_index++] = pcycles_num->space; + ir_level = IRDA_LEVEL_LOW; + } + else if (pcycles_num->flag == IRDA_FLAG_INVERSE) + { + if (ir_level == IRDA_LEVEL_LOW && time_index != 0) + { + time_index--; + ir_time[time_index++] += pcycles_num->space; + } + else if (ir_level == IRDA_LEVEL_HIGH) + { + ir_time[time_index++] = pcycles_num->space; + } + ir_time[time_index++] = pcycles_num->mask; + ir_level = IRDA_LEVEL_HIGH; + } } \ No newline at end of file diff --git a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/ir_decoder/src/include/ir_decode.h b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/ir_decoder/src/include/ir_decode.h index 750d416..6d7ebeb 100644 --- a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/ir_decoder/src/include/ir_decode.h +++ b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/ir_decoder/src/include/ir_decode.h @@ -1,371 +1,371 @@ -/************************************************************************************** -Filename: ir_decode.h -Revised: Date: 2016-10-01 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - -#ifndef _IR_DECODE_H_ -#define _IR_DECODE_H_ - -#if defined (BOARD_PC) -#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" -#pragma ide diagnostic ignored "OCUnusedMacroInspection" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include "ir_defs.h" -#include "ir_ac_control.h" -#include "ir_tv_control.h" - -#define IR_DECODE_FAILED (-1) -#define IR_DECODE_SUCCEEDED (0) - -#define IR_TYPE_STATUS 0 -#define IR_TYPE_COMMANDS 1 - -// remote control key definition -#define KEY_TV_POWER 0 -#define KEY_TV_MUTE 1 -#define KEY_TV_UP 2 -#define KEY_TV_DOWN 3 -#define KEY_TV_LEFT 4 -#define KEY_TV_RIGHT 5 -#define KEY_TV_OK 6 -#define KEY_TV_VOL_PLUS 7 -#define KEY_TV_VOL_MINUS 8 -#define KEY_TV_BACK 9 -#define KEY_TV_INPUT 10 -#define KEY_TV_MENU 11 -#define KEY_TV_HOME 12 -#define KEY_TV_SETTINGS 13 - -#define KEY_AC_POWER 0 -#define KEY_AC_MODE_SWITCH 1 -#define KEY_AC_TEMP_PLUS 2 -#define KEY_AC_TEMP_MINUS 3 -#define KEY_AC_WIND_SPEED 9 -#define KEY_AC_WIND_SWING 10 -#define KEY_AC_WIND_FIX 11 - -#define KEY_STB_POWER 0 -#define KEY_STB_MUTE 1 -#define KEY_STB_UP 2 -#define KEY_STB_DOWN 3 -#define KEY_STB_LEFT 4 -#define KEY_STB_RIGHT 5 -#define KEY_STB_OK 6 -#define KEY_STB_VOL_PLUS 7 -#define KEY_STB_VOL_MINUS 8 -#define KEY_STB_BACK 9 -#define KEY_STB_INPUT 10 -#define KEY_STB_MENU 11 -#define KEY_STB_PAGE_UP 12 -#define KEY_STB_PAGE_DOWN 13 - -#define KEY_NETBOX_POWER 0 -#define KEY_NETBOX_UP 1 -#define KEY_NETBOX_DOWN 2 -#define KEY_NETBOX_LEFT 3 -#define KEY_NETBOX_RIGHT 4 -#define KEY_NETBOX_OK 5 -#define KEY_NETBOX_VOL_PLUS 6 -#define KEY_NETBOX_VOL_MINUS 7 -#define KEY_NETBOX_BACK 8 -#define KEY_NETBOX_MENU 9 -#define KEY_NETBOX_HOME 10 - -#define KEY_IPTV_POWER 0 -#define KEY_IPTV_MUTE 1 -#define KEY_IPTV_UP 2 -#define KEY_IPTV_DOWN 3 -#define KEY_IPTV_LEFT 4 -#define KEY_IPTV_RIGHT 5 -#define KEY_IPTV_OK 6 -#define KEY_IPTV_VOL_PLUS 7 -#define KEY_IPTV_VOL_MINUS 8 -#define KEY_IPTV_BACK 9 -#define KEY_IPTV_INPUT 10 -#define KEY_IPTV_MENU 11 -#define KEY_IPTV_PAGE_UP 12 -#define KEY_IPTV_PAGE_DOWN 13 - -#define KEY_DVD_POWER 0 -#define KEY_DVD_UP 1 -#define KEY_DVD_DOWN 2 -#define KEY_DVD_LEFT 3 -#define KEY_DVD_RIGHT 4 -#define KEY_DVD_OK 5 -#define KEY_DVD_VOL_PLUS 6 -#define KEY_DVD_VOL_MINUS 7 -#define KEY_DVD_PLAY 8 -#define KEY_DVD_PAUSE 9 -#define KEY_DVD_EJECT 10 -#define KEY_DVD_REWIND 11 -#define KEY_DVD_FASTFORWARD 12 -#define KEY_DVD_MENU 13 - -#define KEY_FAN_POWER 0 -#define KEY_FAN_WIND_PLUS 6 -#define KEY_FAN_WIND_MUNIS 7 -#define KEY_FAN_SWING 8 -#define KEY_FAN_WIND_SPEED 9 -#define KEY_FAN_WIND_TYPE 10 - -#define KEY_PROJECTOR_POWER 0 -#define KEY_PROJECTOR_UP 1 -#define KEY_PROJECTOR_DOWN 2 -#define KEY_PROJECTOR_LEFT 3 -#define KEY_PROJECTOR_RIGHT 4 -#define KEY_PROJECTOR_OK 5 -#define KEY_PROJECTOR_VOL_PLUS 6 -#define KEY_PROJECTOR_VOL_MINUS 7 -#define KEY_PROJECTOR_ZOOM_OUT 8 -#define KEY_PROJECTOR_MENU 9 -#define KEY_PROJECTOR_ZOOM_IN 10 -#define KEY_PROJECTOR_BACK 11 - -#define KEY_STEREO_POWER 0 -#define KEY_STEREO_UP 1 -#define KEY_STEREO_DOWN 2 -#define KEY_STEREO_LEFT 3 -#define KEY_STEREO_RIGHT 4 -#define KEY_STEREO_OK 5 -#define KEY_STEREO_VOL_PLUS 6 -#define KEY_STEREO_VOL_MINUS 7 -#define KEY_STEREO_MUTE 8 -#define KEY_STEREO_MENU 9 - -#define KEY_BULB_POWER 0 -#define KEY_BULB_COLOR_1 1 -#define KEY_BULB_COLOR_2 2 -#define KEY_BULB_COLOR_3 3 -#define KEY_BULB_COLOR_4 4 -#define KEY_BULB_COLOR_0 5 -#define KEY_BULB_BRIGHT_PLUS 6 -#define KEY_BULB_BRIGHT_MINUS 7 -#define KEY_BULB_BRIGHT_POWER_ON 8 -#define KEY_BULB_BRIGHT_RAINBOW 9 -#define KEY_BULB_BRIGHT_POWER_OFF 10 - -#define KEY_CLEANROBOT_POWER 0 -#define KEY_CLEANROBOT_FOWWARD 1 -#define KEY_CLEANROBOT_BACKWARD 2 -#define KEY_CLEANROBOT_LEFT 3 -#define KEY_CLEANROBOT_RIGHT 4 -#define KEY_CLEANROBOT_START 5 -#define KEY_CLEANROBOT_STOP 6 -#define KEY_CLEANROBOT_AUTO 8 -#define KEY_CLEANROBOT_SPOT 9 -#define KEY_CLEANROBOT_SPEED 10 -#define KEY_CLEANROBOT_TIMER 11 -#define KEY_CLEANROBOT_CHARGE 12 -#define KEY_CLEANROBOT_PRESERVE 13 - -#define KEY_AIRCLEANER_POWER 0 -#define KEY_AIRCLEANER_ION 5 -#define KEY_AIRCLEANER_AUTO 8 -#define KEY_AIRCLEANER_WIND_SPEED 9 -#define KEY_AIRCLEANER_MODE_SWITCH 10 -#define KEY_AIRCLEANER_TIMER 11 -#define KEY_AIRCLEANER_LIGHT 12 -#define KEY_AIRCLEANER_FORCE 13 - -#define KEY_DYSON_POWER 0 -#define KEY_DYSON_WIND_SPEED_PLUS 1 -#define KEY_DYSON_WIND_SPEED_MINUS 2 -#define KEY_DYSON_TIMER_MINUS 3 -#define KEY_DYSON_TIMER_PLUS 4 -#define KEY_DYSON_AUTO 5 -#define KEY_DYSON_TEMP_PLUS 6 -#define KEY_DYSON_TEMP_MINUS 7 -#define KEY_DYSON_SWING 8 -#define KEY_DYSON_DIFFUSION 9 -#define KEY_DYSON_FAV 10 -#define KEY_DYSON_TIMER 11 -#define KEY_DYSON_SLEEP 12 -#define KEY_DYSON_COOL 13 - -#define STANDARD_KEY_COUNT 14 -#define CHANNEL_KEY_COUNT 10 - -typedef enum -{ - REMOTE_CATEGORY_NONE = 0, - REMOTE_CATEGORY_AC = 1, - REMOTE_CATEGORY_TV = 2, - REMOTE_CATEGORY_STB = 3, - REMOTE_CATEGORY_NETBOX = 4, - REMOTE_CATEGORY_IPTV = 5, - REMOTE_CATEGORY_DVD = 6, - REMOTE_CATEGORY_FAN = 7, - REMOTE_CATEGORY_PROJECTOR = 8, - REMOTE_CATEGORY_STEREO = 9, - REMOTE_CATEGORY_LIGHT = 10, - REMOTE_CATEGORY_BSTB = 11, - REMOTE_CATEGORY_CLEANING_ROBOT = 12, - REMOTE_CATEGORY_AREMOTE_CLEANER = 13, - REMOTE_CATEGORY_DYSON = 14, - REMOTE_CATEGORY_NEXT, - REMOTE_CATEGORY_MAX = 64, -} t_remote_category; - -typedef enum -{ - SUB_CATEGORY_BINARY = 0, // deprecated - SUB_CATEGORY_QUATERNARY = 1, - SUB_CATEGORY_HEXADECIMAL = 2, - SUB_CATEGORY_NEXT = 3, - SUB_CATEGORY_MAX = 4, -} t_remote_sub_category; - -/** - * function get_lib_version - * - * description: get version of library - * - * parameters: N/A - * - * returns: the string contains library version - * - */ -extern const char* get_lib_version(); - -/** - * function ir_file_open - * - * description: open IR binary code from file - * - * parameters: category (in) - category ID get from indexing API - * sub_category (in) - subcategory ID get from indexing API - * file_name (in) - file name of IR binary - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - * - */ -extern INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name); - -/** - * function ir_binary_open - * - * description: open IR binary code from buffer - * - * parameters: category (in) - category ID get from indexing API - * sub_category (in) - subcategory ID get from indexing API - * binary (in) - pointer to binary buffer - * bin_length (in) - binary buffer size - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binary, UINT16 bin_length); - -/** - * function ir_decode - * - * description: decode IR binary into INT16 array which indicates the IR levels - * - * parameters: key_code (in) - the code of pressed key - * user_data (out) - output decoded data in INT16 array format - * ac_status(in) - pointer to AC status (optional) - * change_wind_direction (in) - if control changes wind direction for AC (for AC only) - * - * returns: length of decoded data (0 indicates decode failure) - */ -extern UINT16 ir_decode(UINT8 key_code, UINT16* user_data, t_remote_ac_status* ac_status, BOOL change_wind_direction); - -/** - * function ir_close - * - * description: close IR binary code - * - * parameters: N/A - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 ir_close(); - -/** - * function get_temperature_range - * - * description: get the supported temperature range [min, max] for the opened AC IR binary - * - * 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 - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_temperature_range(UINT8 ac_mode, INT8 *temp_min, INT8 *temp_max); - -/** - * function get_supported_mode - * - * description: get supported mode for the opened AC IR binary - * - * parameters: supported_mode (out) mode supported by the remote in lower 5 bits - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_supported_mode(UINT8 *supported_mode); - -/** - * function get_supported_wind_speed - * - * description: get supported wind speed levels for the opened AC IR binary in certain mode - * - * 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 - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_supported_wind_speed(UINT8 ac_mode, UINT8 *supported_wind_speed); - -/** - * function get_supported_swing - * - * description: get supported swing functions for the opened AC IR binary in certain mode - * - * 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 - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_supported_swing(UINT8 ac_mode, UINT8 *supported_swing); - -/** - * function get_supported_wind_direction - * - * description: get supported wind directions for the opened AC IR binary in certain mode - * - * parameters: supported_wind_direction (out) swing supported by the remote in lower 2 bits - * - * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED - */ -extern INT8 get_supported_wind_direction(UINT8 *supported_wind_direction); - - -// private extern function -#if (defined BOARD_PC || defined BOARD_PC_DLL) -extern void ir_lib_free_inner_buffer(); -#endif - -// this function is preferred being called by JNI only -UINT16 ir_decode_combo(const UINT8 category, const UINT8 sub_category, - UINT8* binary, UINT16 bin_length, - UINT8 key_code, UINT16* user_data, - t_remote_ac_status* ac_status, BOOL change_wind_direction); - -#ifdef __cplusplus -} -#endif - +/************************************************************************************** +Filename: ir_decode.h +Revised: Date: 2016-10-01 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + +#ifndef _IR_DECODE_H_ +#define _IR_DECODE_H_ + +#if defined (BOARD_PC) +#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" +#pragma ide diagnostic ignored "OCUnusedMacroInspection" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "ir_defs.h" +#include "ir_ac_control.h" +#include "ir_tv_control.h" + +#define IR_DECODE_FAILED (-1) +#define IR_DECODE_SUCCEEDED (0) + +#define IR_TYPE_STATUS 0 +#define IR_TYPE_COMMANDS 1 + +// remote control key definition +#define KEY_TV_POWER 0 +#define KEY_TV_MUTE 1 +#define KEY_TV_UP 2 +#define KEY_TV_DOWN 3 +#define KEY_TV_LEFT 4 +#define KEY_TV_RIGHT 5 +#define KEY_TV_OK 6 +#define KEY_TV_VOL_PLUS 7 +#define KEY_TV_VOL_MINUS 8 +#define KEY_TV_BACK 9 +#define KEY_TV_INPUT 10 +#define KEY_TV_MENU 11 +#define KEY_TV_HOME 12 +#define KEY_TV_SETTINGS 13 + +#define KEY_AC_POWER 0 +#define KEY_AC_MODE_SWITCH 1 +#define KEY_AC_TEMP_PLUS 2 +#define KEY_AC_TEMP_MINUS 3 +#define KEY_AC_WIND_SPEED 9 +#define KEY_AC_WIND_SWING 10 +#define KEY_AC_WIND_FIX 11 + +#define KEY_STB_POWER 0 +#define KEY_STB_MUTE 1 +#define KEY_STB_UP 2 +#define KEY_STB_DOWN 3 +#define KEY_STB_LEFT 4 +#define KEY_STB_RIGHT 5 +#define KEY_STB_OK 6 +#define KEY_STB_VOL_PLUS 7 +#define KEY_STB_VOL_MINUS 8 +#define KEY_STB_BACK 9 +#define KEY_STB_INPUT 10 +#define KEY_STB_MENU 11 +#define KEY_STB_PAGE_UP 12 +#define KEY_STB_PAGE_DOWN 13 + +#define KEY_NETBOX_POWER 0 +#define KEY_NETBOX_UP 1 +#define KEY_NETBOX_DOWN 2 +#define KEY_NETBOX_LEFT 3 +#define KEY_NETBOX_RIGHT 4 +#define KEY_NETBOX_OK 5 +#define KEY_NETBOX_VOL_PLUS 6 +#define KEY_NETBOX_VOL_MINUS 7 +#define KEY_NETBOX_BACK 8 +#define KEY_NETBOX_MENU 9 +#define KEY_NETBOX_HOME 10 + +#define KEY_IPTV_POWER 0 +#define KEY_IPTV_MUTE 1 +#define KEY_IPTV_UP 2 +#define KEY_IPTV_DOWN 3 +#define KEY_IPTV_LEFT 4 +#define KEY_IPTV_RIGHT 5 +#define KEY_IPTV_OK 6 +#define KEY_IPTV_VOL_PLUS 7 +#define KEY_IPTV_VOL_MINUS 8 +#define KEY_IPTV_BACK 9 +#define KEY_IPTV_INPUT 10 +#define KEY_IPTV_MENU 11 +#define KEY_IPTV_PAGE_UP 12 +#define KEY_IPTV_PAGE_DOWN 13 + +#define KEY_DVD_POWER 0 +#define KEY_DVD_UP 1 +#define KEY_DVD_DOWN 2 +#define KEY_DVD_LEFT 3 +#define KEY_DVD_RIGHT 4 +#define KEY_DVD_OK 5 +#define KEY_DVD_VOL_PLUS 6 +#define KEY_DVD_VOL_MINUS 7 +#define KEY_DVD_PLAY 8 +#define KEY_DVD_PAUSE 9 +#define KEY_DVD_EJECT 10 +#define KEY_DVD_REWIND 11 +#define KEY_DVD_FASTFORWARD 12 +#define KEY_DVD_MENU 13 + +#define KEY_FAN_POWER 0 +#define KEY_FAN_WIND_PLUS 6 +#define KEY_FAN_WIND_MUNIS 7 +#define KEY_FAN_SWING 8 +#define KEY_FAN_WIND_SPEED 9 +#define KEY_FAN_WIND_TYPE 10 + +#define KEY_PROJECTOR_POWER 0 +#define KEY_PROJECTOR_UP 1 +#define KEY_PROJECTOR_DOWN 2 +#define KEY_PROJECTOR_LEFT 3 +#define KEY_PROJECTOR_RIGHT 4 +#define KEY_PROJECTOR_OK 5 +#define KEY_PROJECTOR_VOL_PLUS 6 +#define KEY_PROJECTOR_VOL_MINUS 7 +#define KEY_PROJECTOR_ZOOM_OUT 8 +#define KEY_PROJECTOR_MENU 9 +#define KEY_PROJECTOR_ZOOM_IN 10 +#define KEY_PROJECTOR_BACK 11 + +#define KEY_STEREO_POWER 0 +#define KEY_STEREO_UP 1 +#define KEY_STEREO_DOWN 2 +#define KEY_STEREO_LEFT 3 +#define KEY_STEREO_RIGHT 4 +#define KEY_STEREO_OK 5 +#define KEY_STEREO_VOL_PLUS 6 +#define KEY_STEREO_VOL_MINUS 7 +#define KEY_STEREO_MUTE 8 +#define KEY_STEREO_MENU 9 + +#define KEY_BULB_POWER 0 +#define KEY_BULB_COLOR_1 1 +#define KEY_BULB_COLOR_2 2 +#define KEY_BULB_COLOR_3 3 +#define KEY_BULB_COLOR_4 4 +#define KEY_BULB_COLOR_0 5 +#define KEY_BULB_BRIGHT_PLUS 6 +#define KEY_BULB_BRIGHT_MINUS 7 +#define KEY_BULB_BRIGHT_POWER_ON 8 +#define KEY_BULB_BRIGHT_RAINBOW 9 +#define KEY_BULB_BRIGHT_POWER_OFF 10 + +#define KEY_CLEANROBOT_POWER 0 +#define KEY_CLEANROBOT_FOWWARD 1 +#define KEY_CLEANROBOT_BACKWARD 2 +#define KEY_CLEANROBOT_LEFT 3 +#define KEY_CLEANROBOT_RIGHT 4 +#define KEY_CLEANROBOT_START 5 +#define KEY_CLEANROBOT_STOP 6 +#define KEY_CLEANROBOT_AUTO 8 +#define KEY_CLEANROBOT_SPOT 9 +#define KEY_CLEANROBOT_SPEED 10 +#define KEY_CLEANROBOT_TIMER 11 +#define KEY_CLEANROBOT_CHARGE 12 +#define KEY_CLEANROBOT_PRESERVE 13 + +#define KEY_AIRCLEANER_POWER 0 +#define KEY_AIRCLEANER_ION 5 +#define KEY_AIRCLEANER_AUTO 8 +#define KEY_AIRCLEANER_WIND_SPEED 9 +#define KEY_AIRCLEANER_MODE_SWITCH 10 +#define KEY_AIRCLEANER_TIMER 11 +#define KEY_AIRCLEANER_LIGHT 12 +#define KEY_AIRCLEANER_FORCE 13 + +#define KEY_DYSON_POWER 0 +#define KEY_DYSON_WIND_SPEED_PLUS 1 +#define KEY_DYSON_WIND_SPEED_MINUS 2 +#define KEY_DYSON_TIMER_MINUS 3 +#define KEY_DYSON_TIMER_PLUS 4 +#define KEY_DYSON_AUTO 5 +#define KEY_DYSON_TEMP_PLUS 6 +#define KEY_DYSON_TEMP_MINUS 7 +#define KEY_DYSON_SWING 8 +#define KEY_DYSON_DIFFUSION 9 +#define KEY_DYSON_FAV 10 +#define KEY_DYSON_TIMER 11 +#define KEY_DYSON_SLEEP 12 +#define KEY_DYSON_COOL 13 + +#define STANDARD_KEY_COUNT 14 +#define CHANNEL_KEY_COUNT 10 + +typedef enum +{ + REMOTE_CATEGORY_NONE = 0, + REMOTE_CATEGORY_AC = 1, + REMOTE_CATEGORY_TV = 2, + REMOTE_CATEGORY_STB = 3, + REMOTE_CATEGORY_NETBOX = 4, + REMOTE_CATEGORY_IPTV = 5, + REMOTE_CATEGORY_DVD = 6, + REMOTE_CATEGORY_FAN = 7, + REMOTE_CATEGORY_PROJECTOR = 8, + REMOTE_CATEGORY_STEREO = 9, + REMOTE_CATEGORY_LIGHT = 10, + REMOTE_CATEGORY_BSTB = 11, + REMOTE_CATEGORY_CLEANING_ROBOT = 12, + REMOTE_CATEGORY_AREMOTE_CLEANER = 13, + REMOTE_CATEGORY_DYSON = 14, + REMOTE_CATEGORY_NEXT, + REMOTE_CATEGORY_MAX = 64, +} t_remote_category; + +typedef enum +{ + SUB_CATEGORY_BINARY = 0, // deprecated + SUB_CATEGORY_QUATERNARY = 1, + SUB_CATEGORY_HEXADECIMAL = 2, + SUB_CATEGORY_NEXT = 3, + SUB_CATEGORY_MAX = 4, +} t_remote_sub_category; + +/** + * function get_lib_version + * + * description: get version of library + * + * parameters: N/A + * + * returns: the string contains library version + * + */ +extern const char* get_lib_version(); + +/** + * function ir_file_open + * + * description: open IR binary code from file + * + * parameters: category (in) - category ID get from indexing API + * sub_category (in) - subcategory ID get from indexing API + * file_name (in) - file name of IR binary + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + * + */ +extern INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name); + +/** + * function ir_binary_open + * + * description: open IR binary code from buffer + * + * parameters: category (in) - category ID get from indexing API + * sub_category (in) - subcategory ID get from indexing API + * binary (in) - pointer to binary buffer + * bin_length (in) - binary buffer size + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binary, UINT16 bin_length); + +/** + * function ir_decode + * + * description: decode IR binary into INT16 array which indicates the IR levels + * + * parameters: key_code (in) - the code of pressed key + * user_data (out) - output decoded data in INT16 array format + * ac_status(in) - pointer to AC status (optional) + * change_wind_direction (in) - if control changes wind direction for AC (for AC only) + * + * returns: length of decoded data (0 indicates decode failure) + */ +extern UINT16 ir_decode(UINT8 key_code, UINT16* user_data, t_remote_ac_status* ac_status, BOOL change_wind_direction); + +/** + * function ir_close + * + * description: close IR binary code + * + * parameters: N/A + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 ir_close(); + +/** + * function get_temperature_range + * + * description: get the supported temperature range [min, max] for the opened AC IR binary + * + * 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 + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_temperature_range(UINT8 ac_mode, INT8 *temp_min, INT8 *temp_max); + +/** + * function get_supported_mode + * + * description: get supported mode for the opened AC IR binary + * + * parameters: supported_mode (out) mode supported by the remote in lower 5 bits + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_mode(UINT8 *supported_mode); + +/** + * function get_supported_wind_speed + * + * description: get supported wind speed levels for the opened AC IR binary in certain mode + * + * 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 + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_wind_speed(UINT8 ac_mode, UINT8 *supported_wind_speed); + +/** + * function get_supported_swing + * + * description: get supported swing functions for the opened AC IR binary in certain mode + * + * 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 + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_swing(UINT8 ac_mode, UINT8 *supported_swing); + +/** + * function get_supported_wind_direction + * + * description: get supported wind directions for the opened AC IR binary in certain mode + * + * parameters: supported_wind_direction (out) swing supported by the remote in lower 2 bits + * + * returns: IR_DECODE_SUCCEEDED / IR_DECODE_FAILED + */ +extern INT8 get_supported_wind_direction(UINT8 *supported_wind_direction); + + +// private extern function +#if (defined BOARD_PC || defined BOARD_PC_DLL) +extern void ir_lib_free_inner_buffer(); +#endif + +// this function is preferred being called by JNI only +UINT16 ir_decode_combo(const UINT8 category, const UINT8 sub_category, + UINT8* binary, UINT16 bin_length, + UINT8 key_code, UINT16* user_data, + t_remote_ac_status* ac_status, BOOL change_wind_direction); + +#ifdef __cplusplus +} +#endif + #endif // _IR_DECODE_H_ \ No newline at end of file diff --git a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/ir_decoder/src/ir_decode.c b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/ir_decoder/src/ir_decode.c index 86e9359..1994d5f 100644 --- a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/ir_decoder/src/ir_decode.c +++ b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/ir_decoder/src/ir_decode.c @@ -1,773 +1,773 @@ -/************************************************************************************** -Filename: ir_decode.c -Revised: Date: 2016-10-01 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode (status type) - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - -#include -#include - -#include - -#include "include/ir_decode.h" -#include "include/ir_utils.h" -#include "include/ir_ac_build_frame.h" -#include "include/ir_ac_apply.h" - -struct ir_bin_buffer binary_file; -struct ir_bin_buffer *p_ir_buffer = &binary_file; - -static const char* version = "0.2.5"; - -#if defined USE_DYNAMIC_TAG -struct tag_head *tags; -#else -struct tag_head tags[TAG_COUNT_FOR_PROTOCOL]; -#endif - -static UINT8 byte_array[PROTOCOL_SIZE] = { 0 }; -#if !defined NO_FS -static size_t binary_length = 0; -static UINT8 *binary_content = NULL; -#endif - -static t_remote_category remote_category = REMOTE_CATEGORY_NONE; -static UINT8 ir_binary_type = IR_TYPE_STATUS; -static UINT8 ir_hexadecimal = SUB_CATEGORY_QUATERNARY; - -static int KEY_CODE_MAX[] = -{ - 0, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, - STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, - STANDARD_KEY_COUNT, - STANDARD_KEY_COUNT, -}; - -UINT8 *ir_hex_code = NULL; -UINT8 ir_hex_len = 0; -t_ac_protocol *context = (t_ac_protocol *) byte_array; - -static lp_apply_ac_parameter apply_table[AC_APPLY_MAX] = -{ - apply_power, - apply_mode, - apply_temperature, - apply_temperature, - apply_wind_speed, - apply_swing, - apply_swing -}; - -// static functions declarations -#if !defined NO_FS -static INT8 ir_ac_file_open(const char *file_name); -#endif - -static INT8 ir_ac_binary_open(UINT8 *binary, UINT16 bin_length); -static UINT16 ir_ac_control(t_remote_ac_status ac_status, UINT16* user_data, UINT8 key_code, - BOOL change_wind_direction); -static INT8 ir_ac_binary_close(); - -#if !defined NO_FS -static INT8 ir_tv_file_open(const char *file_name); -#endif - -static INT8 ir_tv_binary_open(UINT8 *binary, UINT16 bin_length); -static INT8 ir_tv_binary_parse(UINT8 ir_hex_encode); -static UINT16 ir_tv_control(UINT8 key, UINT16 *l_user_data); -static INT8 ir_tv_binary_close(); - - -void noprint(const char *fmt, ...) -{ - (void) fmt; -} - -// pubic function definitions -const char* get_lib_version() -{ - return version; -} - -#if (!defined BOARD_51 && !defined BOARD_CC26XX) -INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name) -{ - INT8 ret = 0; - if (category < REMOTE_CATEGORY_AC || - category >= REMOTE_CATEGORY_NEXT) - { - ir_printf("wrong remote category : %d\n", category); - return IR_DECODE_FAILED; - } - remote_category = category; - - if (sub_category < SUB_CATEGORY_QUATERNARY || - sub_category >= SUB_CATEGORY_NEXT) - { - ir_printf("wrong remote sub category : %d\n", sub_category); - return IR_DECODE_FAILED; - } - - if (category == REMOTE_CATEGORY_AC) - { - ir_binary_type = IR_TYPE_STATUS; - ret = ir_ac_file_open(file_name); - if (IR_DECODE_SUCCEEDED == ret) - { - return ir_ac_lib_parse(); - } - else - { - return ret; - } - } - else - { - ir_binary_type = IR_TYPE_COMMANDS; - if (SUB_CATEGORY_QUATERNARY == sub_category) - { - ir_hexadecimal = 0; - } - else if (SUB_CATEGORY_HEXADECIMAL == sub_category) - { - ir_hexadecimal = 1; - } - else - { - return IR_DECODE_FAILED; - } - - ret = ir_tv_file_open(file_name); - if (IR_DECODE_SUCCEEDED == ret) - { - return ir_tv_binary_parse(ir_hexadecimal); - } - else - { - return ret; - } - } -} -#else -INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name) -{ - return IR_DECODE_SUCCEEDED; -} -#endif - -INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binary, UINT16 bin_length) -{ - INT8 ret = 0; - - if (category < REMOTE_CATEGORY_AC || - category >= REMOTE_CATEGORY_NEXT) - { - ir_printf("wrong remote category\n"); - return IR_DECODE_FAILED; - } - remote_category = (t_remote_category) category; - - if (sub_category < SUB_CATEGORY_QUATERNARY || - sub_category >= SUB_CATEGORY_NEXT) - { - ir_printf("wrong remote sub category : %d\n", sub_category); - return IR_DECODE_FAILED; - } - - if (category == REMOTE_CATEGORY_AC) - { - ir_binary_type = IR_TYPE_STATUS; - ret = ir_ac_binary_open(binary, bin_length); - if (IR_DECODE_SUCCEEDED == ret) - { - return ir_ac_lib_parse(); - } - else - { - return ret; - } - } - else - { - ir_binary_type = IR_TYPE_COMMANDS; - if (SUB_CATEGORY_QUATERNARY == sub_category) - { - ir_hexadecimal = 0; - } - else if (SUB_CATEGORY_HEXADECIMAL == sub_category) - { - ir_hexadecimal = 1; - } - else - { - return IR_DECODE_FAILED; - } - - ret = ir_tv_binary_open(binary, bin_length); - if (IR_DECODE_SUCCEEDED == ret) - { - return ir_tv_binary_parse(ir_hexadecimal); - } - else - { - return ret; - } - } -} - -/** the main entry of decode algorithm **/ -UINT16 ir_decode(UINT8 key_code, UINT16* user_data, - t_remote_ac_status* ac_status, BOOL change_wind_direction) -{ - ir_printf("remote_category = %d, KEY_CODE_MAX = %d\n", remote_category, KEY_CODE_MAX[remote_category]); - - if (key_code < 0 || key_code >= KEY_CODE_MAX[remote_category]) - { - ir_printf("key_code exceeded!\n"); - return 0; - } - - if (IR_TYPE_COMMANDS == ir_binary_type) - { - return ir_tv_control(key_code, user_data); - } - else - { - if (NULL == ac_status) - { - return 0; - } - ir_printf("ac status is not null in decode core : power = %d, mode = %d, " - "temp = %d, wind_dir = %d, wind_speed = %d, " - "key_code = %d, change_wind_direction = %d\n", - ac_status->ac_power, ac_status->ac_mode, - ac_status->ac_temp, ac_status->ac_wind_dir, - ac_status->ac_wind_speed, - key_code, change_wind_direction); - return ir_ac_control(*ac_status, user_data, key_code, change_wind_direction); - } -} - - -INT8 ir_close() -{ - if (IR_TYPE_COMMANDS == ir_binary_type) - { - ir_printf("tv binary close\n"); - return ir_tv_binary_close(); - } - else - { - ir_printf("ac binary close\n"); - return ir_ac_binary_close(); - } -} - - -// static function definitions - -//////// AC Begin //////// -#if !defined NO_FS -static INT8 ir_ac_file_open(const char *file_name) -{ - size_t ret = 0; -#if !defined WIN32 - FILE *stream = fopen(file_name, "rb"); -#else - FILE *stream; - fopen_s(&stream, file_name, "rb"); -#endif - if (NULL == stream) - { - ir_printf("\nfile open failed\n"); - return IR_DECODE_FAILED; - } - - fseek(stream, 0, SEEK_END); - binary_length = (size_t) ftell(stream); - binary_content = (UINT8 *) ir_malloc(binary_length); - - if (NULL == binary_content) - { - ir_printf("\nfailed to alloc memory for binary\n"); - fclose(stream); - return IR_DECODE_FAILED; - } - - fseek(stream, 0, SEEK_SET); - ret = fread(binary_content, binary_length, 1, stream); - - if (ret <= 0) - { - fclose(stream); - ir_free(binary_content); - binary_length = 0; - return IR_DECODE_FAILED; - } - - fclose(stream); - - if (IR_DECODE_FAILED == ir_ac_binary_open(binary_content, (UINT16) binary_length)) - { - ir_free(binary_content); - binary_length = 0; - return IR_DECODE_FAILED; - } - return IR_DECODE_SUCCEEDED; -} -#endif - -static INT8 ir_ac_binary_open(UINT8 *binary, UINT16 bin_length) -{ - // it is recommended that the parameter binary pointing to - // a global memory block in embedded platform environment - p_ir_buffer->data = binary; - p_ir_buffer->len = bin_length; - p_ir_buffer->offset = 0; - return IR_DECODE_SUCCEEDED; -} - -static UINT16 ir_ac_control(t_remote_ac_status ac_status, UINT16* user_data, UINT8 key_code, - BOOL change_wind_direction) -{ - UINT16 time_length = 0; - UINT8 function_code = 0; - - switch(key_code) - { - case 0: - function_code = AC_FUNCTION_POWER; - break; - case 1: - function_code = AC_FUNCTION_MODE; - break; - case 2: - case 7: - function_code = AC_FUNCTION_TEMPERATURE_UP; - break; - case 3: - case 8: - function_code = AC_FUNCTION_TEMPERATURE_DOWN; - break; - case 9: - function_code = AC_FUNCTION_WIND_SPEED; - break; - case 10: - function_code = AC_FUNCTION_WIND_SWING; - break; - case 11: - function_code = AC_FUNCTION_WIND_FIX; - break; - default: - ir_printf("unsupported key_code\n"); - return 0; - } - - 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 - ir_memcpy(ir_hex_code, context->default_code.data, context->default_code.len); - -#if defined USE_APPLY_TABLE - if(ac_status.ac_power != AC_POWER_OFF) - { - for (i = AC_APPLY_POWER; i < AC_APPLY_MAX; i++) - { - apply_table[i](context, parameter_array[i]); - } - } -#else - if (ac_status.ac_power == 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.ac_mode].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_function(context, function_code); - // checksum should always be applied - apply_checksum(context); - - time_length = create_ir_frame(); - - return time_length; -} - -static INT8 ir_ac_binary_close() -{ -#if defined USE_DYNAMIC_TAG - // free context - if (NULL != tags) - { - ir_free(tags); - tags = NULL; - } -#endif - - free_ac_context(); - - return IR_DECODE_SUCCEEDED; -} - -// 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].all_temp) - { - *temp_min = *temp_max = -1; - return IR_DECODE_SUCCEEDED; - } - - *temp_min = -1; - *temp_max = -1; - for (i = 0; i < (UINT8) AC_TEMP_MAX; i++) - { - if (is_in(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 < (UINT8) 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 &= (UINT8)(~(UINT8)((UINT8)1 << (UINT8)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].all_speed) - { - *supported_wind_speed = 0; - return IR_DECODE_SUCCEEDED; - } - - *supported_wind_speed = 0x0F; - - for (i = 0; i < (UINT8) AC_WS_MAX; i++) - { - if (is_in(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 &= (UINT8)(~(UINT8)((UINT8)1 << (UINT8)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 = (UINT8) (context->si.mode_count - 1); - if (*supported_wind_direction < 0) - { - *supported_wind_direction = 0; - } - return IR_DECODE_SUCCEEDED; - } - else - { - return IR_DECODE_FAILED; - } -} - -//////// AC End //////// - -//////// TV Begin //////// -#if !defined NO_FS -static INT8 ir_tv_file_open(const char *file_name) -{ - size_t ret = 0; - -#if !defined WIN32 - FILE *stream = fopen(file_name, "rb"); -#else - FILE *stream; - fopen_s(&stream, file_name, "rb"); -#endif - - if (stream == NULL) - { - ir_printf("\nfile open failed\n"); - return IR_DECODE_FAILED; - } - - fseek(stream, 0, SEEK_END); - binary_length = (size_t) ftell(stream); - - binary_content = (UINT8 *) ir_malloc(binary_length); - if (NULL == binary_content) - { - ir_printf("\nfailed to alloc memory for binary\n"); - fclose(stream); - return IR_DECODE_FAILED; - } - - fseek(stream, 0, SEEK_SET); - ret = fread(binary_content, binary_length, 1, stream); - if (ret <= 0) - { - fclose(stream); - ir_free(binary_content); - binary_length = 0; - return IR_DECODE_FAILED; - } - - fclose(stream); - - if (IR_DECODE_FAILED == ir_tv_binary_open(binary_content, (UINT16) binary_length)) - { - ir_free(binary_content); - binary_length = 0; - return IR_DECODE_FAILED; - } - return IR_DECODE_SUCCEEDED; -} -#endif - -static INT8 ir_tv_binary_open(UINT8 *binary, UINT16 bin_length) -{ - return tv_binary_open(binary, bin_length); -} - -static INT8 ir_tv_binary_parse(UINT8 ir_hex_encode) -{ - if (FALSE == tv_binary_parse(ir_hex_encode)) - { - ir_printf("parse irda binary failed\n"); - return IR_DECODE_FAILED; - } - return IR_DECODE_SUCCEEDED; -} - -static UINT16 ir_tv_control(UINT8 key, UINT16 *l_user_data) -{ -#if defined BOARD_PC - UINT16 print_index = 0; -#endif - UINT16 ir_code_length = 0; - memset(l_user_data, 0x00, USER_DATA_SIZE); - ir_code_length = tv_binary_decode(key, l_user_data); - - return ir_code_length; -} - -static INT8 ir_tv_binary_close() -{ -#if (defined BOARD_PC || defined BOARD_PC_DLL) - ir_lib_free_inner_buffer(); -#endif - return IR_DECODE_SUCCEEDED; -} -//////// TV End //////// - -// combo decode for JNI which means call open, decode and then close in one JNI call -UINT16 ir_decode_combo(const UINT8 category, const UINT8 sub_category, - UINT8* binary, UINT16 bin_length, - UINT8 key_code, UINT16* user_data, - t_remote_ac_status* ac_status, BOOL change_wind_direction) -{ - UINT16 decoded_length = 0; - - if (category < REMOTE_CATEGORY_AC || - category >= REMOTE_CATEGORY_NEXT) - { - ir_printf("wrong remote category\n"); - return IR_DECODE_FAILED; - } - - remote_category = (t_remote_category) category; - - if (key_code < 0 || key_code >= KEY_CODE_MAX[remote_category]) - { - ir_printf("key_code exceeded!\n"); - return 0; - } - - if (IR_DECODE_SUCCEEDED == - ir_binary_open(category, sub_category, binary, bin_length)) - { - decoded_length = ir_decode(key_code, user_data, ac_status, change_wind_direction); - ir_close(); - return decoded_length; - } - else - { - return 0; - } -} - -#if (defined BOARD_PC || defined BOARD_PC_DLL) -void ir_lib_free_inner_buffer() -{ - if (NULL != binary_content) - { - ir_free(binary_content); - binary_content = NULL; - } -} +/************************************************************************************** +Filename: ir_decode.c +Revised: Date: 2016-10-01 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode (status type) + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + +#include +#include + +#include + +#include "include/ir_decode.h" +#include "include/ir_utils.h" +#include "include/ir_ac_build_frame.h" +#include "include/ir_ac_apply.h" + +struct ir_bin_buffer binary_file; +struct ir_bin_buffer *p_ir_buffer = &binary_file; + +static const char* version = "0.2.5"; + +#if defined USE_DYNAMIC_TAG +struct tag_head *tags; +#else +struct tag_head tags[TAG_COUNT_FOR_PROTOCOL]; +#endif + +static UINT8 byte_array[PROTOCOL_SIZE] = { 0 }; +#if !defined NO_FS +static size_t binary_length = 0; +static UINT8 *binary_content = NULL; +#endif + +static t_remote_category remote_category = REMOTE_CATEGORY_NONE; +static UINT8 ir_binary_type = IR_TYPE_STATUS; +static UINT8 ir_hexadecimal = SUB_CATEGORY_QUATERNARY; + +static int KEY_CODE_MAX[] = +{ + 0, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, + STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT + CHANNEL_KEY_COUNT, + STANDARD_KEY_COUNT, + STANDARD_KEY_COUNT, +}; + +UINT8 *ir_hex_code = NULL; +UINT8 ir_hex_len = 0; +t_ac_protocol *context = (t_ac_protocol *) byte_array; + +static lp_apply_ac_parameter apply_table[AC_APPLY_MAX] = +{ + apply_power, + apply_mode, + apply_temperature, + apply_temperature, + apply_wind_speed, + apply_swing, + apply_swing +}; + +// static functions declarations +#if !defined NO_FS +static INT8 ir_ac_file_open(const char *file_name); +#endif + +static INT8 ir_ac_binary_open(UINT8 *binary, UINT16 bin_length); +static UINT16 ir_ac_control(t_remote_ac_status ac_status, UINT16* user_data, UINT8 key_code, + BOOL change_wind_direction); +static INT8 ir_ac_binary_close(); + +#if !defined NO_FS +static INT8 ir_tv_file_open(const char *file_name); +#endif + +static INT8 ir_tv_binary_open(UINT8 *binary, UINT16 bin_length); +static INT8 ir_tv_binary_parse(UINT8 ir_hex_encode); +static UINT16 ir_tv_control(UINT8 key, UINT16 *l_user_data); +static INT8 ir_tv_binary_close(); + + +void noprint(const char *fmt, ...) +{ + (void) fmt; +} + +// pubic function definitions +const char* get_lib_version() +{ + return version; +} + +#if (!defined BOARD_51 && !defined BOARD_CC26XX) +INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name) +{ + INT8 ret = 0; + if (category < REMOTE_CATEGORY_AC || + category >= REMOTE_CATEGORY_NEXT) + { + ir_printf("wrong remote category : %d\n", category); + return IR_DECODE_FAILED; + } + remote_category = category; + + if (sub_category < SUB_CATEGORY_QUATERNARY || + sub_category >= SUB_CATEGORY_NEXT) + { + ir_printf("wrong remote sub category : %d\n", sub_category); + return IR_DECODE_FAILED; + } + + if (category == REMOTE_CATEGORY_AC) + { + ir_binary_type = IR_TYPE_STATUS; + ret = ir_ac_file_open(file_name); + if (IR_DECODE_SUCCEEDED == ret) + { + return ir_ac_lib_parse(); + } + else + { + return ret; + } + } + else + { + ir_binary_type = IR_TYPE_COMMANDS; + if (SUB_CATEGORY_QUATERNARY == sub_category) + { + ir_hexadecimal = 0; + } + else if (SUB_CATEGORY_HEXADECIMAL == sub_category) + { + ir_hexadecimal = 1; + } + else + { + return IR_DECODE_FAILED; + } + + ret = ir_tv_file_open(file_name); + if (IR_DECODE_SUCCEEDED == ret) + { + return ir_tv_binary_parse(ir_hexadecimal); + } + else + { + return ret; + } + } +} +#else +INT8 ir_file_open(const UINT8 category, const UINT8 sub_category, const char* file_name) +{ + return IR_DECODE_SUCCEEDED; +} +#endif + +INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binary, UINT16 bin_length) +{ + INT8 ret = 0; + + if (category < REMOTE_CATEGORY_AC || + category >= REMOTE_CATEGORY_NEXT) + { + ir_printf("wrong remote category\n"); + return IR_DECODE_FAILED; + } + remote_category = (t_remote_category) category; + + if (sub_category < SUB_CATEGORY_QUATERNARY || + sub_category >= SUB_CATEGORY_NEXT) + { + ir_printf("wrong remote sub category : %d\n", sub_category); + return IR_DECODE_FAILED; + } + + if (category == REMOTE_CATEGORY_AC) + { + ir_binary_type = IR_TYPE_STATUS; + ret = ir_ac_binary_open(binary, bin_length); + if (IR_DECODE_SUCCEEDED == ret) + { + return ir_ac_lib_parse(); + } + else + { + return ret; + } + } + else + { + ir_binary_type = IR_TYPE_COMMANDS; + if (SUB_CATEGORY_QUATERNARY == sub_category) + { + ir_hexadecimal = 0; + } + else if (SUB_CATEGORY_HEXADECIMAL == sub_category) + { + ir_hexadecimal = 1; + } + else + { + return IR_DECODE_FAILED; + } + + ret = ir_tv_binary_open(binary, bin_length); + if (IR_DECODE_SUCCEEDED == ret) + { + return ir_tv_binary_parse(ir_hexadecimal); + } + else + { + return ret; + } + } +} + +/** the main entry of decode algorithm **/ +UINT16 ir_decode(UINT8 key_code, UINT16* user_data, + t_remote_ac_status* ac_status, BOOL change_wind_direction) +{ + ir_printf("remote_category = %d, KEY_CODE_MAX = %d\n", remote_category, KEY_CODE_MAX[remote_category]); + + if (key_code < 0 || key_code >= KEY_CODE_MAX[remote_category]) + { + ir_printf("key_code exceeded!\n"); + return 0; + } + + if (IR_TYPE_COMMANDS == ir_binary_type) + { + return ir_tv_control(key_code, user_data); + } + else + { + if (NULL == ac_status) + { + return 0; + } + ir_printf("ac status is not null in decode core : power = %d, mode = %d, " + "temp = %d, wind_dir = %d, wind_speed = %d, " + "key_code = %d, change_wind_direction = %d\n", + ac_status->ac_power, ac_status->ac_mode, + ac_status->ac_temp, ac_status->ac_wind_dir, + ac_status->ac_wind_speed, + key_code, change_wind_direction); + return ir_ac_control(*ac_status, user_data, key_code, change_wind_direction); + } +} + + +INT8 ir_close() +{ + if (IR_TYPE_COMMANDS == ir_binary_type) + { + ir_printf("tv binary close\n"); + return ir_tv_binary_close(); + } + else + { + ir_printf("ac binary close\n"); + return ir_ac_binary_close(); + } +} + + +// static function definitions + +//////// AC Begin //////// +#if !defined NO_FS +static INT8 ir_ac_file_open(const char *file_name) +{ + size_t ret = 0; +#if !defined WIN32 + FILE *stream = fopen(file_name, "rb"); +#else + FILE *stream; + fopen_s(&stream, file_name, "rb"); +#endif + if (NULL == stream) + { + ir_printf("\nfile open failed\n"); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_END); + binary_length = (size_t) ftell(stream); + binary_content = (UINT8 *) ir_malloc(binary_length); + + if (NULL == binary_content) + { + ir_printf("\nfailed to alloc memory for binary\n"); + fclose(stream); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_SET); + ret = fread(binary_content, binary_length, 1, stream); + + if (ret <= 0) + { + fclose(stream); + ir_free(binary_content); + binary_length = 0; + return IR_DECODE_FAILED; + } + + fclose(stream); + + if (IR_DECODE_FAILED == ir_ac_binary_open(binary_content, (UINT16) binary_length)) + { + ir_free(binary_content); + binary_length = 0; + return IR_DECODE_FAILED; + } + return IR_DECODE_SUCCEEDED; +} +#endif + +static INT8 ir_ac_binary_open(UINT8 *binary, UINT16 bin_length) +{ + // it is recommended that the parameter binary pointing to + // a global memory block in embedded platform environment + p_ir_buffer->data = binary; + p_ir_buffer->len = bin_length; + p_ir_buffer->offset = 0; + return IR_DECODE_SUCCEEDED; +} + +static UINT16 ir_ac_control(t_remote_ac_status ac_status, UINT16* user_data, UINT8 key_code, + BOOL change_wind_direction) +{ + UINT16 time_length = 0; + UINT8 function_code = 0; + + switch(key_code) + { + case 0: + function_code = AC_FUNCTION_POWER; + break; + case 1: + function_code = AC_FUNCTION_MODE; + break; + case 2: + case 7: + function_code = AC_FUNCTION_TEMPERATURE_UP; + break; + case 3: + case 8: + function_code = AC_FUNCTION_TEMPERATURE_DOWN; + break; + case 9: + function_code = AC_FUNCTION_WIND_SPEED; + break; + case 10: + function_code = AC_FUNCTION_WIND_SWING; + break; + case 11: + function_code = AC_FUNCTION_WIND_FIX; + break; + default: + ir_printf("unsupported key_code\n"); + return 0; + } + + 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 + ir_memcpy(ir_hex_code, context->default_code.data, context->default_code.len); + +#if defined USE_APPLY_TABLE + if(ac_status.ac_power != AC_POWER_OFF) + { + for (i = AC_APPLY_POWER; i < AC_APPLY_MAX; i++) + { + apply_table[i](context, parameter_array[i]); + } + } +#else + if (ac_status.ac_power == 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.ac_mode].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_function(context, function_code); + // checksum should always be applied + apply_checksum(context); + + time_length = create_ir_frame(); + + return time_length; +} + +static INT8 ir_ac_binary_close() +{ +#if defined USE_DYNAMIC_TAG + // free context + if (NULL != tags) + { + ir_free(tags); + tags = NULL; + } +#endif + + free_ac_context(); + + return IR_DECODE_SUCCEEDED; +} + +// 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].all_temp) + { + *temp_min = *temp_max = -1; + return IR_DECODE_SUCCEEDED; + } + + *temp_min = -1; + *temp_max = -1; + for (i = 0; i < (UINT8) AC_TEMP_MAX; i++) + { + if (is_in(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 < (UINT8) 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 &= (UINT8)(~(UINT8)((UINT8)1 << (UINT8)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].all_speed) + { + *supported_wind_speed = 0; + return IR_DECODE_SUCCEEDED; + } + + *supported_wind_speed = 0x0F; + + for (i = 0; i < (UINT8) AC_WS_MAX; i++) + { + if (is_in(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 &= (UINT8)(~(UINT8)((UINT8)1 << (UINT8)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 = (UINT8) (context->si.mode_count - 1); + if (*supported_wind_direction < 0) + { + *supported_wind_direction = 0; + } + return IR_DECODE_SUCCEEDED; + } + else + { + return IR_DECODE_FAILED; + } +} + +//////// AC End //////// + +//////// TV Begin //////// +#if !defined NO_FS +static INT8 ir_tv_file_open(const char *file_name) +{ + size_t ret = 0; + +#if !defined WIN32 + FILE *stream = fopen(file_name, "rb"); +#else + FILE *stream; + fopen_s(&stream, file_name, "rb"); +#endif + + if (stream == NULL) + { + ir_printf("\nfile open failed\n"); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_END); + binary_length = (size_t) ftell(stream); + + binary_content = (UINT8 *) ir_malloc(binary_length); + if (NULL == binary_content) + { + ir_printf("\nfailed to alloc memory for binary\n"); + fclose(stream); + return IR_DECODE_FAILED; + } + + fseek(stream, 0, SEEK_SET); + ret = fread(binary_content, binary_length, 1, stream); + if (ret <= 0) + { + fclose(stream); + ir_free(binary_content); + binary_length = 0; + return IR_DECODE_FAILED; + } + + fclose(stream); + + if (IR_DECODE_FAILED == ir_tv_binary_open(binary_content, (UINT16) binary_length)) + { + ir_free(binary_content); + binary_length = 0; + return IR_DECODE_FAILED; + } + return IR_DECODE_SUCCEEDED; +} +#endif + +static INT8 ir_tv_binary_open(UINT8 *binary, UINT16 bin_length) +{ + return tv_binary_open(binary, bin_length); +} + +static INT8 ir_tv_binary_parse(UINT8 ir_hex_encode) +{ + if (FALSE == tv_binary_parse(ir_hex_encode)) + { + ir_printf("parse irda binary failed\n"); + return IR_DECODE_FAILED; + } + return IR_DECODE_SUCCEEDED; +} + +static UINT16 ir_tv_control(UINT8 key, UINT16 *l_user_data) +{ +#if defined BOARD_PC + UINT16 print_index = 0; +#endif + UINT16 ir_code_length = 0; + memset(l_user_data, 0x00, USER_DATA_SIZE); + ir_code_length = tv_binary_decode(key, l_user_data); + + return ir_code_length; +} + +static INT8 ir_tv_binary_close() +{ +#if (defined BOARD_PC || defined BOARD_PC_DLL) + ir_lib_free_inner_buffer(); +#endif + return IR_DECODE_SUCCEEDED; +} +//////// TV End //////// + +// combo decode for JNI which means call open, decode and then close in one JNI call +UINT16 ir_decode_combo(const UINT8 category, const UINT8 sub_category, + UINT8* binary, UINT16 bin_length, + UINT8 key_code, UINT16* user_data, + t_remote_ac_status* ac_status, BOOL change_wind_direction) +{ + UINT16 decoded_length = 0; + + if (category < REMOTE_CATEGORY_AC || + category >= REMOTE_CATEGORY_NEXT) + { + ir_printf("wrong remote category\n"); + return IR_DECODE_FAILED; + } + + remote_category = (t_remote_category) category; + + if (key_code < 0 || key_code >= KEY_CODE_MAX[remote_category]) + { + ir_printf("key_code exceeded!\n"); + return 0; + } + + if (IR_DECODE_SUCCEEDED == + ir_binary_open(category, sub_category, binary, bin_length)) + { + decoded_length = ir_decode(key_code, user_data, ac_status, change_wind_direction); + ir_close(); + return decoded_length; + } + else + { + return 0; + } +} + +#if (defined BOARD_PC || defined BOARD_PC_DLL) +void ir_lib_free_inner_buffer() +{ + if (NULL != binary_content) + { + ir_free(binary_content); + binary_content = NULL; + } +} #endif \ No newline at end of file diff --git a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.c b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.c index 5b74562..76dcb81 100644 --- a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.c +++ b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.c @@ -1,1592 +1,1592 @@ -/************************************************************************************** -Filename: simpleBLEPeripheral.c -Revised: Date: 2017-01-10 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode (status type) - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - - -/********************************************************************* - * INCLUDES - */ -#include -#include - -#include -#include -#include -#include - -#include "hci_tl.h" -#include "gatt.h" -#include "gapgattserver.h" -#include "gattservapp.h" -#include "devinfoservice.h" -#include "Profile/simpleGATTprofile.h" - -#if defined(SENSORTAG_HW) -#include "bsp_spi.h" -#endif // SENSORTAG_HW - -#if defined(FEATURE_OAD) || defined(IMAGE_INVALIDATE) -#include "oad_target.h" -#include "oad.h" -#endif //FEATURE_OAD || IMAGE_INVALIDATE - -#include "peripheral.h" -#include "gapbondmgr.h" - -#include "osal_snv.h" -#include "ICallBleAPIMSG.h" - -#include "util.h" -#include "Board/board_lcd.h" -#include "Board/board_key.h" -#include "Board/board_led.h" -#include "Board/Board_uart.h" - -#include "Board.h" - -#include "simpleBLEPeripheral.h" - -#include - -#include "buffer.h" - -/********************************************************************* - * CONSTANTS - */ -// Advertising interval when device is discoverable (units of 625us, 160=100ms) -#define DEFAULT_ADVERTISING_INTERVAL 160 - -// Limited discoverable mode advertises for 30.72s, and then stops -// General discoverable mode advertises indefinitely -#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL - -#ifndef FEATURE_OAD -// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic -// parameter update request is enabled -#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 80 - -// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic -// parameter update request is enabled -#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 800 -#else -// Minimum connection interval (units of 1.25ms, 8=10ms) if automatic -// parameter update request is enabled -#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 8 - -// Maximum connection interval (units of 1.25ms, 8=10ms) if automatic -// parameter update request is enabled -#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 8 -#endif // FEATURE_OAD - -// Slave latency to use if automatic parameter update request is enabled -#define DEFAULT_DESIRED_SLAVE_LATENCY 0 - -// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter -// update request is enabled -#define DEFAULT_DESIRED_CONN_TIMEOUT 1000 - -// Whether to enable automatic parameter update request when a connection is -// formed -#define DEFAULT_ENABLE_UPDATE_REQUEST TRUE - -// Connection Pause Peripheral time value (in seconds) -#define DEFAULT_CONN_PAUSE_PERIPHERAL 6 - -// How often to perform periodic event (in msec) -#define SBP_PERIODIC_EVT_PERIOD 5000 - -#ifdef FEATURE_OAD -// The size of an OAD packet. -#define OAD_PACKET_SIZE ((OAD_BLOCK_SIZE) + 2) -#endif // FEATURE_OAD - -// Task configuration -#define SBP_TASK_PRIORITY 1 - -#ifndef SBP_TASK_STACK_SIZE -#define SBP_TASK_STACK_SIZE 644 -#endif - -// Internal Events for RTOS application -#define SBP_STATE_CHANGE_EVT 0x0001 -#define SBP_CHAR_CHANGE_EVT 0x0002 -#define SBP_PERIODIC_EVT 0x0004 -#define SBP_CONN_EVT_END_EVT 0x0008 -#define SBC_KEY_CHANGE_EVT 0x0010 -#define SBP_BUZZER_EVT 0x0020 -#define SBP_UART_CHANGE_EVT 0x0040 -#define SBP_IREXT_DECODE_EVT 0x0080 - -/* IREXT - begin */ -static transfer_control_block btcb = -{ - .binary_recv_length = 0, - .binary_recv_expected_length = 0, - .transfer_on_going = 0, -}; - -static decode_control_block dccb = -{ - .ir_type = IR_TYPE_NONE, - .ir_state = IR_STATE_STANDBY, - .source_code_length = 0, - .decoded_length = 0, -}; - -static t_remote_ac_status ac_status = -{ - .ac_power = AC_POWER_OFF, - .ac_temp = AC_TEMP_24, - .ac_mode = AC_MODE_COOL, - .ac_wind_dir = AC_SWING_ON, - .ac_wind_speed = AC_WS_AUTO, - .ac_display = 0, - .ac_sleep = 0, - .ac_timer = 0, -}; - - -// local function prototypes -static void IRext_uartFeedback(); - -static void ParseSummary(uint8_t* data, uint16_t len); - -static void ParseBinary(uint8_t* data, uint16_t len); - -static void ParseCommand(uint8_t* data, uint16_t len); - - -// IR operation -static void IRext_processState() -{ - if (IR_STATE_STANDBY == dccb.ir_state) - { - dccb.ir_state = IR_STATE_NONE; - LCD_WRITE_STRING("IR NONE", LCD_PAGE7); - } - else if (IR_STATE_READY == dccb.ir_state) - { - if (IR_TYPE_TV == dccb.ir_type) - { - if (IR_DECODE_SUCCEEDED == - ir_binary_open(REMOTE_CATEGORY_TV, 1, dccb.source_code, dccb.source_code_length)) - { - LCD_WRITE_STRING("IR OPENED", LCD_PAGE7); - HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); - dccb.ir_state = IR_STATE_OPENED; - } - else - { - LCD_WRITE_STRING("OPEN TV ERROR", LCD_PAGE7); - } - } - else if (IR_TYPE_AC == dccb.ir_type) - { - if (IR_DECODE_SUCCEEDED == - ir_binary_open(REMOTE_CATEGORY_AC, 1, dccb.source_code, dccb.source_code_length)) - { - LCD_WRITE_STRING("IR OPENED", LCD_PAGE7); - HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); - dccb.ir_state = IR_STATE_OPENED; - } - else - { - LCD_WRITE_STRING("OPEN AC ERROR", LCD_PAGE7); - } - } - else - { - LCD_WRITE_STRING("TYPE ERROR", LCD_PAGE7); - } - } - else if (IR_STATE_OPENED == dccb.ir_state) - { - if (IR_DECODE_SUCCEEDED == ir_close()) - { - LCD_WRITE_STRING("IR READY", LCD_PAGE7); - HalLedSet(HAL_LED_1 | HAL_LED_2, HAL_LED_MODE_OFF); - dccb.ir_state = IR_STATE_READY; - } - } -} - -// KEY operation -static void IRext_processKey(uint8_t ir_type, uint8_t ir_key, char* key_display) -{ - if (IR_STATE_OPENED == dccb.ir_state) - { - if (IR_TYPE_TV == dccb.ir_type) - { - dccb.decoded_length = ir_decode(ir_key, dccb.ir_decoded, NULL, 0); - } - else if (IR_TYPE_AC == dccb.ir_type) - { - dccb.decoded_length = ir_decode(ir_key, dccb.ir_decoded, &ac_status, 0); - } - else - { - LCD_WRITE_STRING("DECODE ERROR", LCD_PAGE6); - } - - if (dccb.decoded_length > 0) - { - LCD_WRITE_STRING(key_display, LCD_PAGE6); - IRext_uartFeedback(); - } - else - { - LCD_WRITE_STRING("ERROR", LCD_PAGE6); - } - } - else - { - LCD_WRITE_STRING("ERROR", LCD_PAGE6); - } -} - -// UART operation -static void IRext_uartFeedback() -{ - - if (dccb.decoded_length > 0) - { - for (uint16_t index = 0; index < dccb.decoded_length; index++) - { - WriteBytes((uint8_t*)&dccb.ir_decoded[index], 2); - UART_DLY_ms(10); - } - } -} - -static void IRext_processUartMsg(uint8_t* data, uint16_t len) -{ - if (NULL == data) - { - return; - } - - // 1 byte UART packet type (header) - uint8_t header = data[0]; - - if (HEADER_SR == header) - { - LCD_WRITE_STRING("PARSE SUMMARY", LCD_PAGE6); - ParseSummary(&data[1], len - 2); - } - else if (HEADER_BT == header) - { - LCD_WRITE_STRING("PARSE BINARY", LCD_PAGE6); - ParseBinary(&data[1], len - 1); - } - else if (HEADER_CMD == header) - { - LCD_WRITE_STRING("PARSE COMMAND", LCD_PAGE6); - ParseCommand(&data[1], len - 1); - } - else - { - LCD_WRITE_STRING("ERROR MESSAGE", LCD_PAGE6); - // invalid header - } -} - -static void ParseSummary(uint8_t* data, uint16_t len) -{ - char cat_char[2] = { 0 }; - char len_char[5] = { 0 }; - - if (len == BINARY_LENGTH_SIZE) - { - memset(&btcb, 0x00, sizeof(transfer_control_block)); - // to compatible with irext web console (transfer binary) - // |cate|length| - // 1 byte category - // 4 bytes length in ASCII format value = n - memcpy(cat_char, &data[0], CATEGORY_LENGTH_SIZE); - dccb.ir_type = (ir_type_t)atoi(cat_char); - dccb.source_code_length = 0; - memset(dccb.source_code, 0x00, BINARY_SOURCE_SIZE_MAX); - - memcpy(len_char, &data[1], BINARY_LENGTH_SIZE); - btcb.binary_recv_expected_length = atoi(len_char); - btcb.binary_recv_length = 0; - - btcb.transfer_on_going = 1; - WriteValue("0", btcb.binary_recv_length, FORMAT_DECIMAL); - } - else - { - // invalid summary - - } -} - -static void ParseBinary(uint8_t* data, uint16_t len) -{ - // n bytes payload fragment - memcpy(&dccb.source_code[btcb.binary_recv_length], - data, - len); - btcb.binary_recv_length += len; - if (btcb.binary_recv_length >= btcb.binary_recv_expected_length) - { - // finish binary transfer - dccb.source_code_length = btcb.binary_recv_length; - LCD_WRITE_STRING("IR READY", LCD_PAGE7); - HalLedSet(HAL_LED_1 | HAL_LED_2, HAL_LED_MODE_OFF); - dccb.ir_state = IR_STATE_READY; - - btcb.transfer_on_going = 0; - } - // feed back next expected offset in any cases - WriteValue("0", btcb.binary_recv_length, FORMAT_DECIMAL); -} - -static void ParseCommand(uint8_t* data, uint16_t len) -{ - uint8 ir_type = 0; - uint8 key_code = 0; - uint8 ac_function = 0; - - if (IR_STATE_OPENED != dccb.ir_state) - { - // feek back error state - WriteBytes("11", 2); - return; - } - - ir_type = data[0]; - - if (IR_TYPE_TV == dccb.ir_type && 0x31 == ir_type) - { - // decode as TV - key_code = data[1] - 0x30; - dccb.decoded_length = ir_decode(key_code, dccb.ir_decoded, NULL, 0); - } - else if (IR_TYPE_AC == dccb.ir_type && 0x32 == ir_type) - { - ac_function = data[1] - 0x30; - dccb.decoded_length = ir_decode(ac_function, dccb.ir_decoded, &ac_status, 0); - } - - if (dccb.decoded_length > 0) - { - LCD_WRITE_STRING("decoded", LCD_PAGE6); - IRext_uartFeedback(); - } - else - { - LCD_WRITE_STRING("ERROR", LCD_PAGE6); - } -} - -void TransportDataToUart(uint8_t* data, uint16_t len) -{ - UART_WriteTransport(data, len); -} - - -/* IREXT - end */ - - -/********************************************************************* - * TYPEDEFS - */ - -// App event passed from profiles. -typedef struct -{ - appEvtHdr_t hdr; // event header. -} sbpEvt_t; - -/********************************************************************* - * LOCAL VARIABLES - */ - -// Entity ID globally used to check for source and/or destination of messages -static ICall_EntityID selfEntity; - -// Semaphore globally used to post events to the application thread -static ICall_Semaphore sem; - -// Clock instances for internal periodic events. -static Clock_Struct periodicClock; - -// Queue object used for app messages -static Queue_Struct appMsg; -static Queue_Handle appMsgQueue; - -#if defined(FEATURE_OAD) -// Event data from OAD profile. -static Queue_Struct oadQ; -static Queue_Handle hOadQ; -#endif //FEATURE_OAD - -// events flag for internal application events. -static uint16_t events; - -// Task configuration -Task_Struct sbpTask; -Char sbpTaskStack[SBP_TASK_STACK_SIZE]; - -#define TEST_LED_MODE_ALL_BLINK 0 -#define TEST_LED_MODE_ALL_FLOW 1 -#define TEST_LED_MODE_KEY_CTRL 2 -#define TEST_LED_MODE_HOST_CTRL 3 -static uint8 my_led_mode = TEST_LED_MODE_ALL_BLINK; - -// Profile state and parameters -//static gaprole_States_t gapProfileState = GAPROLE_INIT; - -// GAP - SCAN RSP data (max size = 31 bytes) -static uint8_t scanRspData[] = -{ - // complete name - 0x14, // length of this data - GAP_ADTYPE_LOCAL_NAME_COMPLETE, - 'I', - 'R', - 'E', - 'X', - 'T', - '_', - 'C', - 'C', - '2', - '6', - 'X', - 'X', - '_', - 'S', - 'a', - 'm', - 'p', - 'l', - 'e', - - // connection interval range - 0x05, // length of this data - GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE, - LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms - HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), - LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s - HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), - - // Tx power level - 0x02, // length of this data - GAP_ADTYPE_POWER_LEVEL, - 0 // 0dBm -}; - -// GAP - Advertisement data (max size = 31 bytes, though this is -// best kept short to conserve power while advertisting) -static uint8_t advertData[] = -{ - // Flags; this sets the device to use limited discoverable - // mode (advertises for 30 seconds at a time) instead of general - // discoverable mode (advertises indefinitely) - 0x02, // length of this data - GAP_ADTYPE_FLAGS, - DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, - - // service UUID, to notify central devices what services are included - // in this peripheral - 0x03, // length of this data - GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all -#ifdef FEATURE_OAD - LO_UINT16(OAD_SERVICE_UUID), - HI_UINT16(OAD_SERVICE_UUID) -#else - LO_UINT16(SIMPLEPROFILE_SERV_UUID), - HI_UINT16(SIMPLEPROFILE_SERV_UUID) -#endif //!FEATURE_OAD -}; - -// GAP GATT Attributes -static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "IREXT_CC26XX"; - -// Globals used for ATT Response retransmission -static gattMsgEvent_t *pAttRsp = NULL; -static uint8_t rspTxRetry = 0; - -/********************************************************************* - * LOCAL FUNCTIONS - */ - -static void SimpleBLEPeripheral_init( void ); -static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1); - -static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg); -static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg); -static void SimpleBLEPeripheral_handleKeys(uint8_t shift, uint8_t keys); -static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg); -static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState); -static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID); -static void SimpleBLEPeripheral_performPeriodicTask(void); - -static void SimpleBLEPeripheral_sendAttRsp(void); -static void SimpleBLEPeripheral_freeAttRsp(uint8_t status); - -static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState); -#ifndef FEATURE_OAD -static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID); -#endif //!FEATURE_OAD -static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state); - -#ifdef FEATURE_OAD -void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle, - uint8_t *pData); -#endif //FEATURE_OAD - -static void SimpleBLEPeripheral_clockHandler(UArg arg); -void SimpleBLEPeripheral_keyChangeHandler(uint8 keys); - -/********************************************************************* - * PROFILE CALLBACKS - */ - -// GAP Role Callbacks -static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs = -{ - SimpleBLEPeripheral_stateChangeCB // Profile State Change Callbacks -}; - -// GAP Bond Manager Callbacks -static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs = -{ - NULL, // Passcode callback (not used by application) - NULL // Pairing / Bonding state Callback (not used by application) -}; - -// Simple GATT Profile Callbacks -#ifndef FEATURE_OAD -static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs = -{ - SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback -}; -#endif //!FEATURE_OAD - -#ifdef FEATURE_OAD -static oadTargetCBs_t simpleBLEPeripheral_oadCBs = -{ - SimpleBLEPeripheral_processOadWriteCB // Write Callback. -}; -#endif //FEATURE_OAD - -/********************************************************************* - * PUBLIC FUNCTIONS - */ - -/********************************************************************* - * @fn SimpleBLEPeripheral_createTask - * - * @brief Task creation function for the Simple BLE Peripheral. - * - * @param None. - * - * @return None. - */ -void SimpleBLEPeripheral_createTask(void) -{ - Task_Params taskParams; - - // Configure task - Task_Params_init(&taskParams); - taskParams.stack = sbpTaskStack; - taskParams.stackSize = SBP_TASK_STACK_SIZE; - taskParams.priority = SBP_TASK_PRIORITY; - - Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL); -} - -void UartCallBack(uint16_t rxLen, uint16_t txLen) -{ - if(rxLen > 0) - { - queue_write(UART_GetRxBufferAddress(), rxLen); - SimpleBLEPeripheral_enqueueMsg(SBP_UART_CHANGE_EVT, NULL); - } -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_init - * - * @brief Called during initialization and contains application - * specific initialization (ie. hardware initialization/setup, - * table initialization, power up notification, etc), and - * profile initialization/setup. - * - * @param None. - * - * @return None. - */ -static void SimpleBLEPeripheral_init(void) -{ - // ****************************************************************** - // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp - // ****************************************************************** - // Register the current thread as an ICall dispatcher application - // so that the application can send and receive messages. - ICall_registerApp(&selfEntity, &sem); - - // Hard code the BD Address till CC2650 board gets its own IEEE address - // uint8 bdAddress[B_ADDR_LEN] = { 0xAD, 0xD0, 0x0A, 0xAD, 0xD0, 0x0A }; - // HCI_EXT_SetBDADDRCmd(bdAddress); - - // Set device's Sleep Clock Accuracy - // HCI_EXT_SetSCACmd(40); - - // Create an RTOS queue for message from profile to be sent to app. - appMsgQueue = Util_constructQueue(&appMsg); - - // Create one-shot clocks for internal periodic events. - Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler, - SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT); - - Board_initKeys(SimpleBLEPeripheral_keyChangeHandler); - - HalLedInit(); - - Uart_Init(UartCallBack); - -#ifndef SENSORTAG_HW - Board_openLCD(); -#endif //SENSORTAG_HW - -#if SENSORTAG_HW - // Setup SPI bus for serial flash and Devpack interface - bspSpiOpen(); -#endif //SENSORTAG_HW - - // Setup the GAP - GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL); - - // Setup the GAP Peripheral Role Profile - { - // For all hardware platforms, device starts advertising upon initialization - uint8_t initialAdvertEnable = TRUE; - - // By setting this to zero, the device will go into the waiting state after - // being discoverable for 30.72 second, and will not being advertising again - // until the enabler is set back to TRUE - uint16_t advertOffTime = 0; - - uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST; - uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; - uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; - uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY; - uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT; - - // Set the GAP Role Parameters - GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), - &initialAdvertEnable); - GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t), - &advertOffTime); - -#if defined UARD_DEBUG - // print adv data - PrintString("\r\n--- response data ---\r\n"); - for (pIndex = 0; pIndex < sizeof(scanRspData); pIndex++) - { - WriteValue("0x", scanRspData[pIndex], FORMAT_HEX); - UART_DLY_ms(10); - PrintString(" "); - UART_DLY_ms(10); - } - PrintString("\r\n-----\r\n"); -#endif - - GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), - scanRspData); - -#if defined UARD_DEBUG - // print adv data - PrintString("\r\n--- adv data ---\r\n"); - for (pIndex = 0; pIndex < sizeof(advertData); pIndex++) - { - WriteValue("0x", advertData[pIndex], FORMAT_HEX); - UART_DLY_ms(10); - PrintString(" "); - UART_DLY_ms(10); - } - PrintString("\r\n-----\r\n"); -#endif - - GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData); - - GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t), - &enableUpdateRequest); - GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), - &desiredMinInterval); - GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), - &desiredMaxInterval); - GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t), - &desiredSlaveLatency); - GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t), - &desiredConnTimeout); - } - - // Set the GAP Characteristics - GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName); - - // Set advertising interval - { - uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL; - - GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt); - GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt); - GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt); - GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt); - } - - // Setup the GAP Bond Manager - { - // passkey "000000" - uint32_t passkey = 0; - uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; - uint8_t mitm = TRUE; - uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY; - uint8_t bonding = TRUE; - - GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t), - &passkey); - GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode); - GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm); - GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap); - GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding); - } - - { - uint8_t AdvMap = GAP_ADVCHAN_37; - GAPRole_SetParameter(GAPROLE_ADV_CHANNEL_MAP, sizeof(uint8_t), &AdvMap); - } - - // Initialize GATT attributes - GGS_AddService(GATT_ALL_SERVICES); // GAP - GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes - DevInfo_AddService(); // Device Information Service - -#ifndef FEATURE_OAD - SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile -#endif //!FEATURE_OAD - -#ifdef FEATURE_OAD - VOID OAD_addService(); // OAD Profile - OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs); - hOadQ = Util_constructQueue(&oadQ); -#endif - -#ifdef IMAGE_INVALIDATE - Reset_addService(); -#endif //IMAGE_INVALIDATE - - -#ifndef FEATURE_OAD - // Setup the SimpleProfile Characteristic Values - { - uint8_t charValue1 = 1; - uint8_t charValue2 = 2; - uint8_t charValue3 = 3; - uint8_t charValue4 = 4; - uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 }; - - SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t), - &charValue1); - SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t), - &charValue2); - SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t), - &charValue3); - SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t), - &charValue4); - SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, - charValue5); - } - - // Register callback with SimpleGATTprofile - SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs); -#endif //!FEATURE_OAD - - // Start the Device - VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs); - - // Start Bond Manager - VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs); - - // Register with GAP for HCI/Host messages - GAP_RegisterForMsgs(selfEntity); - - // Register for GATT local events and ATT Responses pending for transmission - GATT_RegisterForMsgs(selfEntity); - -#if defined FEATURE_OAD -#if defined (HAL_IMAGE_A) - LCD_WRITE_STRING("BLE Peripheral A", LCD_PAGE0); -#else - LCD_WRITE_STRING("BLE Peripheral B", LCD_PAGE0); -#endif // HAL_IMAGE_A -#else - LCD_WRITE_STRING("IRext sample", LCD_PAGE0); - LCD_WRITE_STRING("STANDBY", LCD_PAGE7); - HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); -#endif -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_taskFxn - * - * @brief Application task entry point for the Simple BLE Peripheral. - * - * @param a0, a1 - not used. - * - * @return None. - */ -static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1) -{ - // Initialize application - SimpleBLEPeripheral_init(); - - // Application main loop - for (;;) - { - // Waits for a signal to the semaphore associated with the calling thread. - // Note that the semaphore associated with a thread is signaled when a - // message is queued to the message receive queue of the thread or when - // ICall_signal() function is called onto the semaphore. - ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); - - if (errno == ICALL_ERRNO_SUCCESS) - { - ICall_EntityID dest; - ICall_ServiceEnum src; - ICall_HciExtEvt *pMsg = NULL; - - if (ICall_fetchServiceMsg(&src, &dest, - (void **)&pMsg) == ICALL_ERRNO_SUCCESS) - { - uint8 safeToDealloc = TRUE; - - if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) - { - ICall_Event *pEvt = (ICall_Event *)pMsg; - - // Check for BLE stack events first - if (pEvt->signature == 0xffff) - { - if (pEvt->event_flag & SBP_CONN_EVT_END_EVT) - { - // Try to retransmit pending ATT Response (if any) - SimpleBLEPeripheral_sendAttRsp(); - } - } - else - { - // Process inter-task message - safeToDealloc = SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg); - } - } - - if (pMsg && safeToDealloc) - { - ICall_freeMsg(pMsg); - } - } - - // If RTOS queue is not empty, process app message. - while (!Queue_empty(appMsgQueue)) - { - sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue); - if (pMsg) - { - // Process message. - SimpleBLEPeripheral_processAppMsg(pMsg); - - // Free the space from the message. - ICall_free(pMsg); - } - } - } - - if (events & SBP_PERIODIC_EVT) - { - events &= ~SBP_PERIODIC_EVT; - - Util_startClock(&periodicClock); - - // Perform periodic application task - SimpleBLEPeripheral_performPeriodicTask(); - - if(TEST_LED_MODE_ALL_BLINK == my_led_mode) - { - static int count = 0; - - HalLedSet(HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4, HAL_LED_MODE_TOGGLE); - - if(++count > 20) - { - HalLedSet(HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4, HAL_LED_MODE_OFF); - my_led_mode = TEST_LED_MODE_ALL_FLOW; - } - } - else if(TEST_LED_MODE_ALL_FLOW == my_led_mode) - { - static uint8 i = 0; - static int count = 0; - uint8 ledshow[] = {HAL_LED_1, HAL_LED_1, HAL_LED_2, HAL_LED_2, - HAL_LED_3, HAL_LED_3, HAL_LED_4, HAL_LED_4, - HAL_LED_3, HAL_LED_3, HAL_LED_2, HAL_LED_2 - }; - - HalLedSet(ledshow[i], HAL_LED_MODE_TOGGLE); - i++; - i %= (sizeof(ledshow)); - if(++count > ((sizeof(ledshow))*5)) - { - HalLedSet(HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4, HAL_LED_MODE_OFF); - my_led_mode = TEST_LED_MODE_KEY_CTRL; - } - - } - } -#ifdef FEATURE_OAD - while (!Queue_empty(hOadQ)) - { - oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ); - - // Identify new image. - if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ) - { - OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData); - } - // Write a next block request. - else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ) - { - OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData); - } - - // Free buffer. - ICall_free(oadWriteEvt); - } -#endif //FEATURE_OAD - } -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_processStackMsg - * - * @brief Process an incoming stack message. - * - * @param pMsg - message to process - * - * @return TRUE if safe to deallocate incoming message, FALSE otherwise. - */ -static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg) -{ - uint8_t safeToDealloc = TRUE; - - switch (pMsg->event) - { - case GATT_MSG_EVENT: - // Process GATT message - safeToDealloc = SimpleBLEPeripheral_processGATTMsg((gattMsgEvent_t *)pMsg); - break; - - case HCI_GAP_EVENT_EVENT: - { - // Process HCI message - switch(pMsg->status) - { - case HCI_COMMAND_COMPLETE_EVENT_CODE: - // Process HCI Command Complete Event - break; - - default: - break; - } - } - break; - - default: - // do nothing - break; - } - - return (safeToDealloc); -} - -static void SimpleBLEPeripheral_handleKeys(uint8_t shift, uint8_t keys) -{ - (void)shift; - - if((my_led_mode == TEST_LED_MODE_ALL_BLINK) || (my_led_mode == TEST_LED_MODE_ALL_FLOW) ) - { - my_led_mode = TEST_LED_MODE_KEY_CTRL; - HalLedSet(HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4, HAL_LED_MODE_OFF); - } - - if (keys & KEY_LEFT) - { - IRext_processKey(IR_TYPE_TV, IR_KEY_POWER, "POWER"); - return; - } - - if (keys & KEY_UP) - { - IRext_processKey(IR_TYPE_TV, IR_KEY_VOL_UP, "VOL+"); - return; - } - - if (keys & KEY_RIGHT) - { - IRext_processKey(IR_TYPE_TV, IR_KEY_MUTE, "MUTE"); - return; - } - - if (keys & KEY_DOWN) - { - IRext_processKey(IR_TYPE_TV, IR_KEY_VOL_DOWN, "VOL-"); - return; - } - - if (keys & KEY_SELECT) - { - IRext_processState(); - return; - } -} -/********************************************************************* - * @fn SimpleBLEPeripheral_processGATTMsg - * - * @brief Process GATT messages and events. - * - * @return TRUE if safe to deallocate incoming message, FALSE otherwise. - */ -static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg) -{ - // See if GATT server was unable to transmit an ATT response - if (pMsg->hdr.status == blePending) - { - // No HCI buffer was available. Let's try to retransmit the response - // on the next connection event. - if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity, - SBP_CONN_EVT_END_EVT) == SUCCESS) - { - // First free any pending response - SimpleBLEPeripheral_freeAttRsp(FAILURE); - - // Hold on to the response message for retransmission - pAttRsp = pMsg; - - // Don't free the response message yet - return (FALSE); - } - } - else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT) - { - // ATT request-response or indication-confirmation flow control is - // violated. All subsequent ATT requests or indications will be dropped. - // The app is informed in case it wants to drop the connection. - - // Display the opcode of the message that caused the violation. - LCD_WRITE_STRING_VALUE("FC Violated:", pMsg->msg.flowCtrlEvt.opcode, - 10, LCD_PAGE5); - } - else if (pMsg->method == ATT_MTU_UPDATED_EVENT) - { - // MTU size updated - LCD_WRITE_STRING_VALUE("MTU Size:", pMsg->msg.mtuEvt.MTU, 10, LCD_PAGE5); - } - - // Free message payload. Needed only for ATT Protocol messages - GATT_bm_free(&pMsg->msg, pMsg->method); - - // It's safe to free the incoming message - return (TRUE); -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_sendAttRsp - * - * @brief Send a pending ATT response message. - * - * @param none - * - * @return none - */ -static void SimpleBLEPeripheral_sendAttRsp(void) -{ - // See if there's a pending ATT Response to be transmitted - if (pAttRsp != NULL) - { - uint8_t status; - - // Increment retransmission count - rspTxRetry++; - - // Try to retransmit ATT response till either we're successful or - // the ATT Client times out (after 30s) and drops the connection. - status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, &(pAttRsp->msg)); - if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL)) - { - // Disable connection event end notice - HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0); - - // We're done with the response message - SimpleBLEPeripheral_freeAttRsp(status); - } - else - { - // Continue retrying - LCD_WRITE_STRING_VALUE("Rsp send retry:", rspTxRetry, 10, LCD_PAGE5); - } - } -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_freeAttRsp - * - * @brief Free ATT response message. - * - * @param status - response transmit status - * - * @return none - */ -static void SimpleBLEPeripheral_freeAttRsp(uint8_t status) -{ - // See if there's a pending ATT response message - if (pAttRsp != NULL) - { - // See if the response was sent out successfully - if (status == SUCCESS) - { - LCD_WRITE_STRING_VALUE("Rsp sent, retry:", rspTxRetry, 10, LCD_PAGE5); - } - else - { - // Free response payload - GATT_bm_free(&pAttRsp->msg, pAttRsp->method); - - LCD_WRITE_STRING_VALUE("Rsp retry failed:", rspTxRetry, 10, LCD_PAGE5); - } - - // Free response message - ICall_freeMsg(pAttRsp); - - // Reset our globals - pAttRsp = NULL; - rspTxRetry = 0; - } -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_processAppMsg - * - * @brief Process an incoming callback from a profile. - * - * @param pMsg - message to process - * - * @return None. - */ -static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg) -{ - switch (pMsg->hdr.event) - { - case SBP_STATE_CHANGE_EVT: - SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg-> - hdr.state); - break; - - case SBC_KEY_CHANGE_EVT: - SimpleBLEPeripheral_handleKeys(0, pMsg->hdr.state); - break; - - case SBP_CHAR_CHANGE_EVT: - SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state); - break; - - case SBP_UART_CHANGE_EVT: - { - uint8_t valueToCopy[UART_BUFFER_SIZE] = {0}; - uint8 len = queue_read(valueToCopy, UART_BUFFER_SIZE); - if(len > 0) - { - if (IR_STATE_STANDBY == dccb.ir_state) - { - SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR6, len, valueToCopy); - } - else - { - IRext_processUartMsg(valueToCopy, len); - } - } - if(queue_total() > 0) - { - // receive next frame - SimpleBLEPeripheral_enqueueMsg(SBP_UART_CHANGE_EVT, NULL); - } - } - - default: - // Do nothing - break; - } -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_stateChangeCB - * - * @brief Callback from GAP Role indicating a role state change. - * - * @param newState - new state - * - * @return None. - */ -static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState) -{ - SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState); -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_processStateChangeEvt - * - * @brief Process a pending GAP Role state change event. - * - * @param newState - new state - * - * @return None. - */ -static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState) -{ -#ifdef PLUS_BROADCASTER - static bool firstConnFlag = false; -#endif // PLUS_BROADCASTER - - switch ( newState ) - { - case GAPROLE_STARTED: - { - uint8_t ownAddress[B_ADDR_LEN]; - uint8_t systemId[DEVINFO_SYSTEM_ID_LEN]; - - GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress); - - // use 6 bytes of device address for 8 bytes of system ID value - systemId[0] = ownAddress[0]; - systemId[1] = ownAddress[1]; - systemId[2] = ownAddress[2]; - - // set middle bytes to zero - systemId[4] = 0x00; - systemId[3] = 0x00; - - // shift three bytes up - systemId[7] = ownAddress[5]; - systemId[6] = ownAddress[4]; - systemId[5] = ownAddress[3]; - - DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId); - - // Display device address - LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1); - LCD_WRITE_STRING("Initialized", LCD_PAGE2); - } - break; - - case GAPROLE_ADVERTISING: - LCD_WRITE_STRING("Advertising", LCD_PAGE2); - break; - -#ifdef PLUS_BROADCASTER - /* After a connection is dropped a device in PLUS_BROADCASTER will continue - * sending non-connectable advertisements and shall sending this change of - * state to the application. These are then disabled here so that sending - * connectable advertisements can resume. - */ - case GAPROLE_ADVERTISING_NONCONN: - { - uint8_t advertEnabled = FALSE; - - // Disable non-connectable advertising. - GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t), - &advertEnabled); - - advertEnabled = TRUE; - - // Enabled connectable advertising. - GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), - &advertEnabled); - - // Reset flag for next connection. - firstConnFlag = false; - - SimpleBLEPeripheral_freeAttRsp(bleNotConnected); - } - break; -#endif //PLUS_BROADCASTER - - case GAPROLE_CONNECTED: - { - uint8_t peerAddress[B_ADDR_LEN]; - - GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress); - - Util_startClock(&periodicClock); - - LCD_WRITE_STRING("Connected", LCD_PAGE2); - LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddress), LCD_PAGE3); - -#ifdef PLUS_BROADCASTER - // Only turn advertising on for this state when we first connect - // otherwise, when we go from connected_advertising back to this state - // we will be turning advertising back on. - if (firstConnFlag == false) - { - uint8_t advertEnabled = FALSE; // Turn on Advertising - - // Disable connectable advertising. - GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), - &advertEnabled); - - // Set to true for non-connectabel advertising. - advertEnabled = TRUE; - - // Enable non-connectable advertising. - GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t), - &advertEnabled); - firstConnFlag = true; - } -#endif // PLUS_BROADCASTER - } - break; - - case GAPROLE_CONNECTED_ADV: - LCD_WRITE_STRING("Connected Advertising", LCD_PAGE2); - break; - - case GAPROLE_WAITING: - Util_stopClock(&periodicClock); - SimpleBLEPeripheral_freeAttRsp(bleNotConnected); - - LCD_WRITE_STRING("Disconnected", LCD_PAGE2); - - // Clear remaining lines - LCD_WRITE_STRING("", LCD_PAGE3); - LCD_WRITE_STRING("", LCD_PAGE4); - LCD_WRITE_STRING("", LCD_PAGE5); - break; - - case GAPROLE_WAITING_AFTER_TIMEOUT: - SimpleBLEPeripheral_freeAttRsp(bleNotConnected); - - LCD_WRITE_STRING("Timed Out", LCD_PAGE2); - - // Clear remaining lines - LCD_WRITE_STRING("", LCD_PAGE3); - LCD_WRITE_STRING("", LCD_PAGE4); - LCD_WRITE_STRING("", LCD_PAGE5); - -#ifdef PLUS_BROADCASTER - // Reset flag for next connection. - firstConnFlag = false; -#endif //#ifdef (PLUS_BROADCASTER) - break; - - case GAPROLE_ERROR: - LCD_WRITE_STRING("Error", LCD_PAGE2); - break; - - default: - LCD_WRITE_STRING("", LCD_PAGE2); - break; - } -} - -#ifndef FEATURE_OAD -/********************************************************************* - * @fn SimpleBLEPeripheral_charValueChangeCB - * - * @brief Callback from Simple Profile indicating a characteristic - * value change. - * - * @param paramID - parameter ID of the value that was changed. - * - * @return None. - */ -static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID) -{ - SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID); -} -#endif //!FEATURE_OAD - -/********************************************************************* - * @fn SimpleBLEPeripheral_processCharValueChangeEvt - * - * @brief Process a pending Simple Profile characteristic value change - * event. - * - * @param paramID - parameter ID of the value that was changed. - * - * @return None. - */ -static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID) -{ -#ifndef FEATURE_OAD - uint8_t newValue[20]; - uint8 returnBytes; - - switch(paramID) - { - case SIMPLEPROFILE_CHAR1: - SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, newValue, &returnBytes); - - // LCD_WRITE_STRING_VALUE("Char 1:", (uint32_t)newValue, 10, LCD_PAGE4); - break; - - case SIMPLEPROFILE_CHAR3: - SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, newValue, &returnBytes); - - // LCD_WRITE_STRING_VALUE("Char 3:", (uint32_t)newValue, 10, LCD_PAGE4); - break; - - case SIMPLEPROFILE_CHAR6: - SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR6, newValue, &returnBytes); - - if(returnBytes > 0) - { - UART_WriteTransport(newValue, returnBytes); - } - break; - - default: - // should not reach here! - break; - } -#endif //!FEATURE_OAD -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_performPeriodicTask - * - * @brief Perform a periodic application task. This function gets called - * every five seconds (SBP_PERIODIC_EVT_PERIOD). In this example, - * the value of the third characteristic in the SimpleGATTProfile - * service is retrieved from the profile, and then copied into the - * value of the the fourth characteristic. - * - * @param None. - * - * @return None. - */ -static void SimpleBLEPeripheral_performPeriodicTask(void) -{ - // Do nothing -} - - -#if defined(FEATURE_OAD) -/********************************************************************* - * @fn SimpleBLEPeripheral_processOadWriteCB - * - * @brief Process a write request to the OAD profile. - * - * @param event - event type: - * OAD_WRITE_IDENTIFY_REQ - * OAD_WRITE_BLOCK_REQ - * @param connHandle - the connection Handle this request is from. - * @param pData - pointer to data for processing and/or storing. - * - * @return None. - */ -void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle, - uint8_t *pData) -{ - oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \ - sizeof(uint8_t) * OAD_PACKET_SIZE); - - if ( oadWriteEvt != NULL ) - { - oadWriteEvt->event = event; - oadWriteEvt->connHandle = connHandle; - - oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1); - memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE); - - Queue_enqueue(hOadQ, (Queue_Elem *)oadWriteEvt); - - // Post the application's semaphore. - Semaphore_post(sem); - } - else - { - // Fail silently. - } -} -#endif //FEATURE_OAD - -/********************************************************************* - * @fn SimpleBLEPeripheral_clockHandler - * - * @brief Handler function for clock timeouts. - * - * @param arg - event type - * - * @return None. - */ -static void SimpleBLEPeripheral_clockHandler(UArg arg) -{ - // Store the event. - events |= arg; - - // Wake up the application. - Semaphore_post(sem); -} - - -/********************************************************************* - * @fn SimpleBLEPeripheral_keyChangeHandler - * - * @brief Key event handler function - * - * @param a0 - ignored - * - * @return none - */ -void SimpleBLEPeripheral_keyChangeHandler(uint8 keys) -{ - SimpleBLEPeripheral_enqueueMsg(SBC_KEY_CHANGE_EVT, keys); -} - -/********************************************************************* - * @fn SimpleBLEPeripheral_enqueueMsg - * - * @brief Creates a message and puts the message in RTOS queue. - * - * @param event - message event. - * @param state - message state. - * - * @return None. - */ -static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state) -{ - sbpEvt_t *pMsg; - - // Create dynamic pointer to message. - if ((pMsg = ICall_malloc(sizeof(sbpEvt_t)))) - { - pMsg->hdr.event = event; - pMsg->hdr.state = state; - - // Enqueue the message. - Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg); - } -} - - -/********************************************************************* -*********************************************************************/ +/************************************************************************************** +Filename: simpleBLEPeripheral.c +Revised: Date: 2017-01-10 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode (status type) + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + + +/********************************************************************* + * INCLUDES + */ +#include +#include + +#include +#include +#include +#include + +#include "hci_tl.h" +#include "gatt.h" +#include "gapgattserver.h" +#include "gattservapp.h" +#include "devinfoservice.h" +#include "Profile/simpleGATTprofile.h" + +#if defined(SENSORTAG_HW) +#include "bsp_spi.h" +#endif // SENSORTAG_HW + +#if defined(FEATURE_OAD) || defined(IMAGE_INVALIDATE) +#include "oad_target.h" +#include "oad.h" +#endif //FEATURE_OAD || IMAGE_INVALIDATE + +#include "peripheral.h" +#include "gapbondmgr.h" + +#include "osal_snv.h" +#include "ICallBleAPIMSG.h" + +#include "util.h" +#include "Board/board_lcd.h" +#include "Board/board_key.h" +#include "Board/board_led.h" +#include "Board/Board_uart.h" + +#include "Board.h" + +#include "simpleBLEPeripheral.h" + +#include + +#include "buffer.h" + +/********************************************************************* + * CONSTANTS + */ +// Advertising interval when device is discoverable (units of 625us, 160=100ms) +#define DEFAULT_ADVERTISING_INTERVAL 160 + +// Limited discoverable mode advertises for 30.72s, and then stops +// General discoverable mode advertises indefinitely +#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL + +#ifndef FEATURE_OAD +// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic +// parameter update request is enabled +#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 80 + +// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic +// parameter update request is enabled +#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 800 +#else +// Minimum connection interval (units of 1.25ms, 8=10ms) if automatic +// parameter update request is enabled +#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 8 + +// Maximum connection interval (units of 1.25ms, 8=10ms) if automatic +// parameter update request is enabled +#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 8 +#endif // FEATURE_OAD + +// Slave latency to use if automatic parameter update request is enabled +#define DEFAULT_DESIRED_SLAVE_LATENCY 0 + +// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter +// update request is enabled +#define DEFAULT_DESIRED_CONN_TIMEOUT 1000 + +// Whether to enable automatic parameter update request when a connection is +// formed +#define DEFAULT_ENABLE_UPDATE_REQUEST TRUE + +// Connection Pause Peripheral time value (in seconds) +#define DEFAULT_CONN_PAUSE_PERIPHERAL 6 + +// How often to perform periodic event (in msec) +#define SBP_PERIODIC_EVT_PERIOD 5000 + +#ifdef FEATURE_OAD +// The size of an OAD packet. +#define OAD_PACKET_SIZE ((OAD_BLOCK_SIZE) + 2) +#endif // FEATURE_OAD + +// Task configuration +#define SBP_TASK_PRIORITY 1 + +#ifndef SBP_TASK_STACK_SIZE +#define SBP_TASK_STACK_SIZE 644 +#endif + +// Internal Events for RTOS application +#define SBP_STATE_CHANGE_EVT 0x0001 +#define SBP_CHAR_CHANGE_EVT 0x0002 +#define SBP_PERIODIC_EVT 0x0004 +#define SBP_CONN_EVT_END_EVT 0x0008 +#define SBC_KEY_CHANGE_EVT 0x0010 +#define SBP_BUZZER_EVT 0x0020 +#define SBP_UART_CHANGE_EVT 0x0040 +#define SBP_IREXT_DECODE_EVT 0x0080 + +/* IREXT - begin */ +static transfer_control_block btcb = +{ + .binary_recv_length = 0, + .binary_recv_expected_length = 0, + .transfer_on_going = 0, +}; + +static decode_control_block dccb = +{ + .ir_type = IR_TYPE_NONE, + .ir_state = IR_STATE_STANDBY, + .source_code_length = 0, + .decoded_length = 0, +}; + +static t_remote_ac_status ac_status = +{ + .ac_power = AC_POWER_OFF, + .ac_temp = AC_TEMP_24, + .ac_mode = AC_MODE_COOL, + .ac_wind_dir = AC_SWING_ON, + .ac_wind_speed = AC_WS_AUTO, + .ac_display = 0, + .ac_sleep = 0, + .ac_timer = 0, +}; + + +// local function prototypes +static void IRext_uartFeedback(); + +static void ParseSummary(uint8_t* data, uint16_t len); + +static void ParseBinary(uint8_t* data, uint16_t len); + +static void ParseCommand(uint8_t* data, uint16_t len); + + +// IR operation +static void IRext_processState() +{ + if (IR_STATE_STANDBY == dccb.ir_state) + { + dccb.ir_state = IR_STATE_NONE; + LCD_WRITE_STRING("IR NONE", LCD_PAGE7); + } + else if (IR_STATE_READY == dccb.ir_state) + { + if (IR_TYPE_TV == dccb.ir_type) + { + if (IR_DECODE_SUCCEEDED == + ir_binary_open(REMOTE_CATEGORY_TV, 1, dccb.source_code, dccb.source_code_length)) + { + LCD_WRITE_STRING("IR OPENED", LCD_PAGE7); + HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); + dccb.ir_state = IR_STATE_OPENED; + } + else + { + LCD_WRITE_STRING("OPEN TV ERROR", LCD_PAGE7); + } + } + else if (IR_TYPE_AC == dccb.ir_type) + { + if (IR_DECODE_SUCCEEDED == + ir_binary_open(REMOTE_CATEGORY_AC, 1, dccb.source_code, dccb.source_code_length)) + { + LCD_WRITE_STRING("IR OPENED", LCD_PAGE7); + HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); + dccb.ir_state = IR_STATE_OPENED; + } + else + { + LCD_WRITE_STRING("OPEN AC ERROR", LCD_PAGE7); + } + } + else + { + LCD_WRITE_STRING("TYPE ERROR", LCD_PAGE7); + } + } + else if (IR_STATE_OPENED == dccb.ir_state) + { + if (IR_DECODE_SUCCEEDED == ir_close()) + { + LCD_WRITE_STRING("IR READY", LCD_PAGE7); + HalLedSet(HAL_LED_1 | HAL_LED_2, HAL_LED_MODE_OFF); + dccb.ir_state = IR_STATE_READY; + } + } +} + +// KEY operation +static void IRext_processKey(uint8_t ir_type, uint8_t ir_key, char* key_display) +{ + if (IR_STATE_OPENED == dccb.ir_state) + { + if (IR_TYPE_TV == dccb.ir_type) + { + dccb.decoded_length = ir_decode(ir_key, dccb.ir_decoded, NULL, 0); + } + else if (IR_TYPE_AC == dccb.ir_type) + { + dccb.decoded_length = ir_decode(ir_key, dccb.ir_decoded, &ac_status, 0); + } + else + { + LCD_WRITE_STRING("DECODE ERROR", LCD_PAGE6); + } + + if (dccb.decoded_length > 0) + { + LCD_WRITE_STRING(key_display, LCD_PAGE6); + IRext_uartFeedback(); + } + else + { + LCD_WRITE_STRING("ERROR", LCD_PAGE6); + } + } + else + { + LCD_WRITE_STRING("ERROR", LCD_PAGE6); + } +} + +// UART operation +static void IRext_uartFeedback() +{ + + if (dccb.decoded_length > 0) + { + for (uint16_t index = 0; index < dccb.decoded_length; index++) + { + WriteBytes((uint8_t*)&dccb.ir_decoded[index], 2); + UART_DLY_ms(10); + } + } +} + +static void IRext_processUartMsg(uint8_t* data, uint16_t len) +{ + if (NULL == data) + { + return; + } + + // 1 byte UART packet type (header) + uint8_t header = data[0]; + + if (HEADER_SR == header) + { + LCD_WRITE_STRING("PARSE SUMMARY", LCD_PAGE6); + ParseSummary(&data[1], len - 2); + } + else if (HEADER_BT == header) + { + LCD_WRITE_STRING("PARSE BINARY", LCD_PAGE6); + ParseBinary(&data[1], len - 1); + } + else if (HEADER_CMD == header) + { + LCD_WRITE_STRING("PARSE COMMAND", LCD_PAGE6); + ParseCommand(&data[1], len - 1); + } + else + { + LCD_WRITE_STRING("ERROR MESSAGE", LCD_PAGE6); + // invalid header + } +} + +static void ParseSummary(uint8_t* data, uint16_t len) +{ + char cat_char[2] = { 0 }; + char len_char[5] = { 0 }; + + if (len == BINARY_LENGTH_SIZE) + { + memset(&btcb, 0x00, sizeof(transfer_control_block)); + // to compatible with irext web console (transfer binary) + // |cate|length| + // 1 byte category + // 4 bytes length in ASCII format value = n + memcpy(cat_char, &data[0], CATEGORY_LENGTH_SIZE); + dccb.ir_type = (ir_type_t)atoi(cat_char); + dccb.source_code_length = 0; + memset(dccb.source_code, 0x00, BINARY_SOURCE_SIZE_MAX); + + memcpy(len_char, &data[1], BINARY_LENGTH_SIZE); + btcb.binary_recv_expected_length = atoi(len_char); + btcb.binary_recv_length = 0; + + btcb.transfer_on_going = 1; + WriteValue("0", btcb.binary_recv_length, FORMAT_DECIMAL); + } + else + { + // invalid summary + + } +} + +static void ParseBinary(uint8_t* data, uint16_t len) +{ + // n bytes payload fragment + memcpy(&dccb.source_code[btcb.binary_recv_length], + data, + len); + btcb.binary_recv_length += len; + if (btcb.binary_recv_length >= btcb.binary_recv_expected_length) + { + // finish binary transfer + dccb.source_code_length = btcb.binary_recv_length; + LCD_WRITE_STRING("IR READY", LCD_PAGE7); + HalLedSet(HAL_LED_1 | HAL_LED_2, HAL_LED_MODE_OFF); + dccb.ir_state = IR_STATE_READY; + + btcb.transfer_on_going = 0; + } + // feed back next expected offset in any cases + WriteValue("0", btcb.binary_recv_length, FORMAT_DECIMAL); +} + +static void ParseCommand(uint8_t* data, uint16_t len) +{ + uint8 ir_type = 0; + uint8 key_code = 0; + uint8 ac_function = 0; + + if (IR_STATE_OPENED != dccb.ir_state) + { + // feek back error state + WriteBytes("11", 2); + return; + } + + ir_type = data[0]; + + if (IR_TYPE_TV == dccb.ir_type && 0x31 == ir_type) + { + // decode as TV + key_code = data[1] - 0x30; + dccb.decoded_length = ir_decode(key_code, dccb.ir_decoded, NULL, 0); + } + else if (IR_TYPE_AC == dccb.ir_type && 0x32 == ir_type) + { + ac_function = data[1] - 0x30; + dccb.decoded_length = ir_decode(ac_function, dccb.ir_decoded, &ac_status, 0); + } + + if (dccb.decoded_length > 0) + { + LCD_WRITE_STRING("decoded", LCD_PAGE6); + IRext_uartFeedback(); + } + else + { + LCD_WRITE_STRING("ERROR", LCD_PAGE6); + } +} + +void TransportDataToUart(uint8_t* data, uint16_t len) +{ + UART_WriteTransport(data, len); +} + + +/* IREXT - end */ + + +/********************************************************************* + * TYPEDEFS + */ + +// App event passed from profiles. +typedef struct +{ + appEvtHdr_t hdr; // event header. +} sbpEvt_t; + +/********************************************************************* + * LOCAL VARIABLES + */ + +// Entity ID globally used to check for source and/or destination of messages +static ICall_EntityID selfEntity; + +// Semaphore globally used to post events to the application thread +static ICall_Semaphore sem; + +// Clock instances for internal periodic events. +static Clock_Struct periodicClock; + +// Queue object used for app messages +static Queue_Struct appMsg; +static Queue_Handle appMsgQueue; + +#if defined(FEATURE_OAD) +// Event data from OAD profile. +static Queue_Struct oadQ; +static Queue_Handle hOadQ; +#endif //FEATURE_OAD + +// events flag for internal application events. +static uint16_t events; + +// Task configuration +Task_Struct sbpTask; +Char sbpTaskStack[SBP_TASK_STACK_SIZE]; + +#define TEST_LED_MODE_ALL_BLINK 0 +#define TEST_LED_MODE_ALL_FLOW 1 +#define TEST_LED_MODE_KEY_CTRL 2 +#define TEST_LED_MODE_HOST_CTRL 3 +static uint8 my_led_mode = TEST_LED_MODE_ALL_BLINK; + +// Profile state and parameters +//static gaprole_States_t gapProfileState = GAPROLE_INIT; + +// GAP - SCAN RSP data (max size = 31 bytes) +static uint8_t scanRspData[] = +{ + // complete name + 0x14, // length of this data + GAP_ADTYPE_LOCAL_NAME_COMPLETE, + 'I', + 'R', + 'E', + 'X', + 'T', + '_', + 'C', + 'C', + '2', + '6', + 'X', + 'X', + '_', + 'S', + 'a', + 'm', + 'p', + 'l', + 'e', + + // connection interval range + 0x05, // length of this data + GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE, + LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms + HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), + LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s + HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), + + // Tx power level + 0x02, // length of this data + GAP_ADTYPE_POWER_LEVEL, + 0 // 0dBm +}; + +// GAP - Advertisement data (max size = 31 bytes, though this is +// best kept short to conserve power while advertisting) +static uint8_t advertData[] = +{ + // Flags; this sets the device to use limited discoverable + // mode (advertises for 30 seconds at a time) instead of general + // discoverable mode (advertises indefinitely) + 0x02, // length of this data + GAP_ADTYPE_FLAGS, + DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, + + // service UUID, to notify central devices what services are included + // in this peripheral + 0x03, // length of this data + GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all +#ifdef FEATURE_OAD + LO_UINT16(OAD_SERVICE_UUID), + HI_UINT16(OAD_SERVICE_UUID) +#else + LO_UINT16(SIMPLEPROFILE_SERV_UUID), + HI_UINT16(SIMPLEPROFILE_SERV_UUID) +#endif //!FEATURE_OAD +}; + +// GAP GATT Attributes +static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "IREXT_CC26XX"; + +// Globals used for ATT Response retransmission +static gattMsgEvent_t *pAttRsp = NULL; +static uint8_t rspTxRetry = 0; + +/********************************************************************* + * LOCAL FUNCTIONS + */ + +static void SimpleBLEPeripheral_init( void ); +static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1); + +static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg); +static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg); +static void SimpleBLEPeripheral_handleKeys(uint8_t shift, uint8_t keys); +static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg); +static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState); +static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID); +static void SimpleBLEPeripheral_performPeriodicTask(void); + +static void SimpleBLEPeripheral_sendAttRsp(void); +static void SimpleBLEPeripheral_freeAttRsp(uint8_t status); + +static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState); +#ifndef FEATURE_OAD +static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID); +#endif //!FEATURE_OAD +static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state); + +#ifdef FEATURE_OAD +void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle, + uint8_t *pData); +#endif //FEATURE_OAD + +static void SimpleBLEPeripheral_clockHandler(UArg arg); +void SimpleBLEPeripheral_keyChangeHandler(uint8 keys); + +/********************************************************************* + * PROFILE CALLBACKS + */ + +// GAP Role Callbacks +static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs = +{ + SimpleBLEPeripheral_stateChangeCB // Profile State Change Callbacks +}; + +// GAP Bond Manager Callbacks +static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs = +{ + NULL, // Passcode callback (not used by application) + NULL // Pairing / Bonding state Callback (not used by application) +}; + +// Simple GATT Profile Callbacks +#ifndef FEATURE_OAD +static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs = +{ + SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback +}; +#endif //!FEATURE_OAD + +#ifdef FEATURE_OAD +static oadTargetCBs_t simpleBLEPeripheral_oadCBs = +{ + SimpleBLEPeripheral_processOadWriteCB // Write Callback. +}; +#endif //FEATURE_OAD + +/********************************************************************* + * PUBLIC FUNCTIONS + */ + +/********************************************************************* + * @fn SimpleBLEPeripheral_createTask + * + * @brief Task creation function for the Simple BLE Peripheral. + * + * @param None. + * + * @return None. + */ +void SimpleBLEPeripheral_createTask(void) +{ + Task_Params taskParams; + + // Configure task + Task_Params_init(&taskParams); + taskParams.stack = sbpTaskStack; + taskParams.stackSize = SBP_TASK_STACK_SIZE; + taskParams.priority = SBP_TASK_PRIORITY; + + Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL); +} + +void UartCallBack(uint16_t rxLen, uint16_t txLen) +{ + if(rxLen > 0) + { + queue_write(UART_GetRxBufferAddress(), rxLen); + SimpleBLEPeripheral_enqueueMsg(SBP_UART_CHANGE_EVT, NULL); + } +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_init + * + * @brief Called during initialization and contains application + * specific initialization (ie. hardware initialization/setup, + * table initialization, power up notification, etc), and + * profile initialization/setup. + * + * @param None. + * + * @return None. + */ +static void SimpleBLEPeripheral_init(void) +{ + // ****************************************************************** + // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp + // ****************************************************************** + // Register the current thread as an ICall dispatcher application + // so that the application can send and receive messages. + ICall_registerApp(&selfEntity, &sem); + + // Hard code the BD Address till CC2650 board gets its own IEEE address + // uint8 bdAddress[B_ADDR_LEN] = { 0xAD, 0xD0, 0x0A, 0xAD, 0xD0, 0x0A }; + // HCI_EXT_SetBDADDRCmd(bdAddress); + + // Set device's Sleep Clock Accuracy + // HCI_EXT_SetSCACmd(40); + + // Create an RTOS queue for message from profile to be sent to app. + appMsgQueue = Util_constructQueue(&appMsg); + + // Create one-shot clocks for internal periodic events. + Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler, + SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT); + + Board_initKeys(SimpleBLEPeripheral_keyChangeHandler); + + HalLedInit(); + + Uart_Init(UartCallBack); + +#ifndef SENSORTAG_HW + Board_openLCD(); +#endif //SENSORTAG_HW + +#if SENSORTAG_HW + // Setup SPI bus for serial flash and Devpack interface + bspSpiOpen(); +#endif //SENSORTAG_HW + + // Setup the GAP + GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL); + + // Setup the GAP Peripheral Role Profile + { + // For all hardware platforms, device starts advertising upon initialization + uint8_t initialAdvertEnable = TRUE; + + // By setting this to zero, the device will go into the waiting state after + // being discoverable for 30.72 second, and will not being advertising again + // until the enabler is set back to TRUE + uint16_t advertOffTime = 0; + + uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST; + uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; + uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; + uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY; + uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT; + + // Set the GAP Role Parameters + GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), + &initialAdvertEnable); + GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t), + &advertOffTime); + +#if defined UARD_DEBUG + // print adv data + PrintString("\r\n--- response data ---\r\n"); + for (pIndex = 0; pIndex < sizeof(scanRspData); pIndex++) + { + WriteValue("0x", scanRspData[pIndex], FORMAT_HEX); + UART_DLY_ms(10); + PrintString(" "); + UART_DLY_ms(10); + } + PrintString("\r\n-----\r\n"); +#endif + + GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), + scanRspData); + +#if defined UARD_DEBUG + // print adv data + PrintString("\r\n--- adv data ---\r\n"); + for (pIndex = 0; pIndex < sizeof(advertData); pIndex++) + { + WriteValue("0x", advertData[pIndex], FORMAT_HEX); + UART_DLY_ms(10); + PrintString(" "); + UART_DLY_ms(10); + } + PrintString("\r\n-----\r\n"); +#endif + + GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData); + + GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t), + &enableUpdateRequest); + GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), + &desiredMinInterval); + GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), + &desiredMaxInterval); + GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t), + &desiredSlaveLatency); + GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t), + &desiredConnTimeout); + } + + // Set the GAP Characteristics + GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName); + + // Set advertising interval + { + uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL; + + GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt); + GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt); + GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt); + GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt); + } + + // Setup the GAP Bond Manager + { + // passkey "000000" + uint32_t passkey = 0; + uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; + uint8_t mitm = TRUE; + uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY; + uint8_t bonding = TRUE; + + GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t), + &passkey); + GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode); + GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm); + GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap); + GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding); + } + + { + uint8_t AdvMap = GAP_ADVCHAN_37; + GAPRole_SetParameter(GAPROLE_ADV_CHANNEL_MAP, sizeof(uint8_t), &AdvMap); + } + + // Initialize GATT attributes + GGS_AddService(GATT_ALL_SERVICES); // GAP + GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes + DevInfo_AddService(); // Device Information Service + +#ifndef FEATURE_OAD + SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile +#endif //!FEATURE_OAD + +#ifdef FEATURE_OAD + VOID OAD_addService(); // OAD Profile + OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs); + hOadQ = Util_constructQueue(&oadQ); +#endif + +#ifdef IMAGE_INVALIDATE + Reset_addService(); +#endif //IMAGE_INVALIDATE + + +#ifndef FEATURE_OAD + // Setup the SimpleProfile Characteristic Values + { + uint8_t charValue1 = 1; + uint8_t charValue2 = 2; + uint8_t charValue3 = 3; + uint8_t charValue4 = 4; + uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 }; + + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t), + &charValue1); + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t), + &charValue2); + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t), + &charValue3); + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t), + &charValue4); + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, + charValue5); + } + + // Register callback with SimpleGATTprofile + SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs); +#endif //!FEATURE_OAD + + // Start the Device + VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs); + + // Start Bond Manager + VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs); + + // Register with GAP for HCI/Host messages + GAP_RegisterForMsgs(selfEntity); + + // Register for GATT local events and ATT Responses pending for transmission + GATT_RegisterForMsgs(selfEntity); + +#if defined FEATURE_OAD +#if defined (HAL_IMAGE_A) + LCD_WRITE_STRING("BLE Peripheral A", LCD_PAGE0); +#else + LCD_WRITE_STRING("BLE Peripheral B", LCD_PAGE0); +#endif // HAL_IMAGE_A +#else + LCD_WRITE_STRING("IRext sample", LCD_PAGE0); + LCD_WRITE_STRING("STANDBY", LCD_PAGE7); + HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); +#endif +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_taskFxn + * + * @brief Application task entry point for the Simple BLE Peripheral. + * + * @param a0, a1 - not used. + * + * @return None. + */ +static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1) +{ + // Initialize application + SimpleBLEPeripheral_init(); + + // Application main loop + for (;;) + { + // Waits for a signal to the semaphore associated with the calling thread. + // Note that the semaphore associated with a thread is signaled when a + // message is queued to the message receive queue of the thread or when + // ICall_signal() function is called onto the semaphore. + ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); + + if (errno == ICALL_ERRNO_SUCCESS) + { + ICall_EntityID dest; + ICall_ServiceEnum src; + ICall_HciExtEvt *pMsg = NULL; + + if (ICall_fetchServiceMsg(&src, &dest, + (void **)&pMsg) == ICALL_ERRNO_SUCCESS) + { + uint8 safeToDealloc = TRUE; + + if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) + { + ICall_Event *pEvt = (ICall_Event *)pMsg; + + // Check for BLE stack events first + if (pEvt->signature == 0xffff) + { + if (pEvt->event_flag & SBP_CONN_EVT_END_EVT) + { + // Try to retransmit pending ATT Response (if any) + SimpleBLEPeripheral_sendAttRsp(); + } + } + else + { + // Process inter-task message + safeToDealloc = SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg); + } + } + + if (pMsg && safeToDealloc) + { + ICall_freeMsg(pMsg); + } + } + + // If RTOS queue is not empty, process app message. + while (!Queue_empty(appMsgQueue)) + { + sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue); + if (pMsg) + { + // Process message. + SimpleBLEPeripheral_processAppMsg(pMsg); + + // Free the space from the message. + ICall_free(pMsg); + } + } + } + + if (events & SBP_PERIODIC_EVT) + { + events &= ~SBP_PERIODIC_EVT; + + Util_startClock(&periodicClock); + + // Perform periodic application task + SimpleBLEPeripheral_performPeriodicTask(); + + if(TEST_LED_MODE_ALL_BLINK == my_led_mode) + { + static int count = 0; + + HalLedSet(HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4, HAL_LED_MODE_TOGGLE); + + if(++count > 20) + { + HalLedSet(HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4, HAL_LED_MODE_OFF); + my_led_mode = TEST_LED_MODE_ALL_FLOW; + } + } + else if(TEST_LED_MODE_ALL_FLOW == my_led_mode) + { + static uint8 i = 0; + static int count = 0; + uint8 ledshow[] = {HAL_LED_1, HAL_LED_1, HAL_LED_2, HAL_LED_2, + HAL_LED_3, HAL_LED_3, HAL_LED_4, HAL_LED_4, + HAL_LED_3, HAL_LED_3, HAL_LED_2, HAL_LED_2 + }; + + HalLedSet(ledshow[i], HAL_LED_MODE_TOGGLE); + i++; + i %= (sizeof(ledshow)); + if(++count > ((sizeof(ledshow))*5)) + { + HalLedSet(HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4, HAL_LED_MODE_OFF); + my_led_mode = TEST_LED_MODE_KEY_CTRL; + } + + } + } +#ifdef FEATURE_OAD + while (!Queue_empty(hOadQ)) + { + oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ); + + // Identify new image. + if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ) + { + OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData); + } + // Write a next block request. + else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ) + { + OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData); + } + + // Free buffer. + ICall_free(oadWriteEvt); + } +#endif //FEATURE_OAD + } +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_processStackMsg + * + * @brief Process an incoming stack message. + * + * @param pMsg - message to process + * + * @return TRUE if safe to deallocate incoming message, FALSE otherwise. + */ +static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg) +{ + uint8_t safeToDealloc = TRUE; + + switch (pMsg->event) + { + case GATT_MSG_EVENT: + // Process GATT message + safeToDealloc = SimpleBLEPeripheral_processGATTMsg((gattMsgEvent_t *)pMsg); + break; + + case HCI_GAP_EVENT_EVENT: + { + // Process HCI message + switch(pMsg->status) + { + case HCI_COMMAND_COMPLETE_EVENT_CODE: + // Process HCI Command Complete Event + break; + + default: + break; + } + } + break; + + default: + // do nothing + break; + } + + return (safeToDealloc); +} + +static void SimpleBLEPeripheral_handleKeys(uint8_t shift, uint8_t keys) +{ + (void)shift; + + if((my_led_mode == TEST_LED_MODE_ALL_BLINK) || (my_led_mode == TEST_LED_MODE_ALL_FLOW) ) + { + my_led_mode = TEST_LED_MODE_KEY_CTRL; + HalLedSet(HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4, HAL_LED_MODE_OFF); + } + + if (keys & KEY_LEFT) + { + IRext_processKey(IR_TYPE_TV, IR_KEY_POWER, "POWER"); + return; + } + + if (keys & KEY_UP) + { + IRext_processKey(IR_TYPE_TV, IR_KEY_VOL_UP, "VOL+"); + return; + } + + if (keys & KEY_RIGHT) + { + IRext_processKey(IR_TYPE_TV, IR_KEY_MUTE, "MUTE"); + return; + } + + if (keys & KEY_DOWN) + { + IRext_processKey(IR_TYPE_TV, IR_KEY_VOL_DOWN, "VOL-"); + return; + } + + if (keys & KEY_SELECT) + { + IRext_processState(); + return; + } +} +/********************************************************************* + * @fn SimpleBLEPeripheral_processGATTMsg + * + * @brief Process GATT messages and events. + * + * @return TRUE if safe to deallocate incoming message, FALSE otherwise. + */ +static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg) +{ + // See if GATT server was unable to transmit an ATT response + if (pMsg->hdr.status == blePending) + { + // No HCI buffer was available. Let's try to retransmit the response + // on the next connection event. + if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity, + SBP_CONN_EVT_END_EVT) == SUCCESS) + { + // First free any pending response + SimpleBLEPeripheral_freeAttRsp(FAILURE); + + // Hold on to the response message for retransmission + pAttRsp = pMsg; + + // Don't free the response message yet + return (FALSE); + } + } + else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT) + { + // ATT request-response or indication-confirmation flow control is + // violated. All subsequent ATT requests or indications will be dropped. + // The app is informed in case it wants to drop the connection. + + // Display the opcode of the message that caused the violation. + LCD_WRITE_STRING_VALUE("FC Violated:", pMsg->msg.flowCtrlEvt.opcode, + 10, LCD_PAGE5); + } + else if (pMsg->method == ATT_MTU_UPDATED_EVENT) + { + // MTU size updated + LCD_WRITE_STRING_VALUE("MTU Size:", pMsg->msg.mtuEvt.MTU, 10, LCD_PAGE5); + } + + // Free message payload. Needed only for ATT Protocol messages + GATT_bm_free(&pMsg->msg, pMsg->method); + + // It's safe to free the incoming message + return (TRUE); +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_sendAttRsp + * + * @brief Send a pending ATT response message. + * + * @param none + * + * @return none + */ +static void SimpleBLEPeripheral_sendAttRsp(void) +{ + // See if there's a pending ATT Response to be transmitted + if (pAttRsp != NULL) + { + uint8_t status; + + // Increment retransmission count + rspTxRetry++; + + // Try to retransmit ATT response till either we're successful or + // the ATT Client times out (after 30s) and drops the connection. + status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, &(pAttRsp->msg)); + if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL)) + { + // Disable connection event end notice + HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0); + + // We're done with the response message + SimpleBLEPeripheral_freeAttRsp(status); + } + else + { + // Continue retrying + LCD_WRITE_STRING_VALUE("Rsp send retry:", rspTxRetry, 10, LCD_PAGE5); + } + } +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_freeAttRsp + * + * @brief Free ATT response message. + * + * @param status - response transmit status + * + * @return none + */ +static void SimpleBLEPeripheral_freeAttRsp(uint8_t status) +{ + // See if there's a pending ATT response message + if (pAttRsp != NULL) + { + // See if the response was sent out successfully + if (status == SUCCESS) + { + LCD_WRITE_STRING_VALUE("Rsp sent, retry:", rspTxRetry, 10, LCD_PAGE5); + } + else + { + // Free response payload + GATT_bm_free(&pAttRsp->msg, pAttRsp->method); + + LCD_WRITE_STRING_VALUE("Rsp retry failed:", rspTxRetry, 10, LCD_PAGE5); + } + + // Free response message + ICall_freeMsg(pAttRsp); + + // Reset our globals + pAttRsp = NULL; + rspTxRetry = 0; + } +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_processAppMsg + * + * @brief Process an incoming callback from a profile. + * + * @param pMsg - message to process + * + * @return None. + */ +static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg) +{ + switch (pMsg->hdr.event) + { + case SBP_STATE_CHANGE_EVT: + SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg-> + hdr.state); + break; + + case SBC_KEY_CHANGE_EVT: + SimpleBLEPeripheral_handleKeys(0, pMsg->hdr.state); + break; + + case SBP_CHAR_CHANGE_EVT: + SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state); + break; + + case SBP_UART_CHANGE_EVT: + { + uint8_t valueToCopy[UART_BUFFER_SIZE] = {0}; + uint8 len = queue_read(valueToCopy, UART_BUFFER_SIZE); + if(len > 0) + { + if (IR_STATE_STANDBY == dccb.ir_state) + { + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR6, len, valueToCopy); + } + else + { + IRext_processUartMsg(valueToCopy, len); + } + } + if(queue_total() > 0) + { + // receive next frame + SimpleBLEPeripheral_enqueueMsg(SBP_UART_CHANGE_EVT, NULL); + } + } + + default: + // Do nothing + break; + } +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_stateChangeCB + * + * @brief Callback from GAP Role indicating a role state change. + * + * @param newState - new state + * + * @return None. + */ +static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState) +{ + SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState); +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_processStateChangeEvt + * + * @brief Process a pending GAP Role state change event. + * + * @param newState - new state + * + * @return None. + */ +static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState) +{ +#ifdef PLUS_BROADCASTER + static bool firstConnFlag = false; +#endif // PLUS_BROADCASTER + + switch ( newState ) + { + case GAPROLE_STARTED: + { + uint8_t ownAddress[B_ADDR_LEN]; + uint8_t systemId[DEVINFO_SYSTEM_ID_LEN]; + + GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress); + + // use 6 bytes of device address for 8 bytes of system ID value + systemId[0] = ownAddress[0]; + systemId[1] = ownAddress[1]; + systemId[2] = ownAddress[2]; + + // set middle bytes to zero + systemId[4] = 0x00; + systemId[3] = 0x00; + + // shift three bytes up + systemId[7] = ownAddress[5]; + systemId[6] = ownAddress[4]; + systemId[5] = ownAddress[3]; + + DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId); + + // Display device address + LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1); + LCD_WRITE_STRING("Initialized", LCD_PAGE2); + } + break; + + case GAPROLE_ADVERTISING: + LCD_WRITE_STRING("Advertising", LCD_PAGE2); + break; + +#ifdef PLUS_BROADCASTER + /* After a connection is dropped a device in PLUS_BROADCASTER will continue + * sending non-connectable advertisements and shall sending this change of + * state to the application. These are then disabled here so that sending + * connectable advertisements can resume. + */ + case GAPROLE_ADVERTISING_NONCONN: + { + uint8_t advertEnabled = FALSE; + + // Disable non-connectable advertising. + GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t), + &advertEnabled); + + advertEnabled = TRUE; + + // Enabled connectable advertising. + GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), + &advertEnabled); + + // Reset flag for next connection. + firstConnFlag = false; + + SimpleBLEPeripheral_freeAttRsp(bleNotConnected); + } + break; +#endif //PLUS_BROADCASTER + + case GAPROLE_CONNECTED: + { + uint8_t peerAddress[B_ADDR_LEN]; + + GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress); + + Util_startClock(&periodicClock); + + LCD_WRITE_STRING("Connected", LCD_PAGE2); + LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddress), LCD_PAGE3); + +#ifdef PLUS_BROADCASTER + // Only turn advertising on for this state when we first connect + // otherwise, when we go from connected_advertising back to this state + // we will be turning advertising back on. + if (firstConnFlag == false) + { + uint8_t advertEnabled = FALSE; // Turn on Advertising + + // Disable connectable advertising. + GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), + &advertEnabled); + + // Set to true for non-connectabel advertising. + advertEnabled = TRUE; + + // Enable non-connectable advertising. + GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t), + &advertEnabled); + firstConnFlag = true; + } +#endif // PLUS_BROADCASTER + } + break; + + case GAPROLE_CONNECTED_ADV: + LCD_WRITE_STRING("Connected Advertising", LCD_PAGE2); + break; + + case GAPROLE_WAITING: + Util_stopClock(&periodicClock); + SimpleBLEPeripheral_freeAttRsp(bleNotConnected); + + LCD_WRITE_STRING("Disconnected", LCD_PAGE2); + + // Clear remaining lines + LCD_WRITE_STRING("", LCD_PAGE3); + LCD_WRITE_STRING("", LCD_PAGE4); + LCD_WRITE_STRING("", LCD_PAGE5); + break; + + case GAPROLE_WAITING_AFTER_TIMEOUT: + SimpleBLEPeripheral_freeAttRsp(bleNotConnected); + + LCD_WRITE_STRING("Timed Out", LCD_PAGE2); + + // Clear remaining lines + LCD_WRITE_STRING("", LCD_PAGE3); + LCD_WRITE_STRING("", LCD_PAGE4); + LCD_WRITE_STRING("", LCD_PAGE5); + +#ifdef PLUS_BROADCASTER + // Reset flag for next connection. + firstConnFlag = false; +#endif //#ifdef (PLUS_BROADCASTER) + break; + + case GAPROLE_ERROR: + LCD_WRITE_STRING("Error", LCD_PAGE2); + break; + + default: + LCD_WRITE_STRING("", LCD_PAGE2); + break; + } +} + +#ifndef FEATURE_OAD +/********************************************************************* + * @fn SimpleBLEPeripheral_charValueChangeCB + * + * @brief Callback from Simple Profile indicating a characteristic + * value change. + * + * @param paramID - parameter ID of the value that was changed. + * + * @return None. + */ +static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID) +{ + SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID); +} +#endif //!FEATURE_OAD + +/********************************************************************* + * @fn SimpleBLEPeripheral_processCharValueChangeEvt + * + * @brief Process a pending Simple Profile characteristic value change + * event. + * + * @param paramID - parameter ID of the value that was changed. + * + * @return None. + */ +static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID) +{ +#ifndef FEATURE_OAD + uint8_t newValue[20]; + uint8 returnBytes; + + switch(paramID) + { + case SIMPLEPROFILE_CHAR1: + SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, newValue, &returnBytes); + + // LCD_WRITE_STRING_VALUE("Char 1:", (uint32_t)newValue, 10, LCD_PAGE4); + break; + + case SIMPLEPROFILE_CHAR3: + SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, newValue, &returnBytes); + + // LCD_WRITE_STRING_VALUE("Char 3:", (uint32_t)newValue, 10, LCD_PAGE4); + break; + + case SIMPLEPROFILE_CHAR6: + SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR6, newValue, &returnBytes); + + if(returnBytes > 0) + { + UART_WriteTransport(newValue, returnBytes); + } + break; + + default: + // should not reach here! + break; + } +#endif //!FEATURE_OAD +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_performPeriodicTask + * + * @brief Perform a periodic application task. This function gets called + * every five seconds (SBP_PERIODIC_EVT_PERIOD). In this example, + * the value of the third characteristic in the SimpleGATTProfile + * service is retrieved from the profile, and then copied into the + * value of the the fourth characteristic. + * + * @param None. + * + * @return None. + */ +static void SimpleBLEPeripheral_performPeriodicTask(void) +{ + // Do nothing +} + + +#if defined(FEATURE_OAD) +/********************************************************************* + * @fn SimpleBLEPeripheral_processOadWriteCB + * + * @brief Process a write request to the OAD profile. + * + * @param event - event type: + * OAD_WRITE_IDENTIFY_REQ + * OAD_WRITE_BLOCK_REQ + * @param connHandle - the connection Handle this request is from. + * @param pData - pointer to data for processing and/or storing. + * + * @return None. + */ +void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle, + uint8_t *pData) +{ + oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \ + sizeof(uint8_t) * OAD_PACKET_SIZE); + + if ( oadWriteEvt != NULL ) + { + oadWriteEvt->event = event; + oadWriteEvt->connHandle = connHandle; + + oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1); + memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE); + + Queue_enqueue(hOadQ, (Queue_Elem *)oadWriteEvt); + + // Post the application's semaphore. + Semaphore_post(sem); + } + else + { + // Fail silently. + } +} +#endif //FEATURE_OAD + +/********************************************************************* + * @fn SimpleBLEPeripheral_clockHandler + * + * @brief Handler function for clock timeouts. + * + * @param arg - event type + * + * @return None. + */ +static void SimpleBLEPeripheral_clockHandler(UArg arg) +{ + // Store the event. + events |= arg; + + // Wake up the application. + Semaphore_post(sem); +} + + +/********************************************************************* + * @fn SimpleBLEPeripheral_keyChangeHandler + * + * @brief Key event handler function + * + * @param a0 - ignored + * + * @return none + */ +void SimpleBLEPeripheral_keyChangeHandler(uint8 keys) +{ + SimpleBLEPeripheral_enqueueMsg(SBC_KEY_CHANGE_EVT, keys); +} + +/********************************************************************* + * @fn SimpleBLEPeripheral_enqueueMsg + * + * @brief Creates a message and puts the message in RTOS queue. + * + * @param event - message event. + * @param state - message state. + * + * @return None. + */ +static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state) +{ + sbpEvt_t *pMsg; + + // Create dynamic pointer to message. + if ((pMsg = ICall_malloc(sizeof(sbpEvt_t)))) + { + pMsg->hdr.event = event; + pMsg->hdr.state = state; + + // Enqueue the message. + Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg); + } +} + + +/********************************************************************* +*********************************************************************/ diff --git a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.h b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.h index 7fede24..cc50317 100644 --- a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.h +++ b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.h @@ -1,112 +1,112 @@ -/************************************************************************************** -Filename: simpleBLEPeripheral.h -Revised: Date: 2017-01-10 -Revision: Revision: 1.0 - -Description: This file provides algorithms for IR decode (status type) - -Revision log: -* 2016-10-01: created by strawmanbobi -**************************************************************************************/ - -#ifndef SIMPLEBLEPERIPHERAL_H -#define SIMPLEBLEPERIPHERAL_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -/********************************************************************* - * INCLUDES - */ - -/********************************************************************* -* EXTERNAL VARIABLES -*/ - -/********************************************************************* - * CONSTANTS - */ - -/********************************************************************* - * MACROS - */ - -/* IREXT - begin */ - -#include "./ir_decoder/src/include/ir_decode.h" - -// UART associated definitions -#define HEADER_SR 0x30 -#define HEADER_BT 0x31 -#define HEADER_CMD 0x32 - -#define CATEGORY_LENGTH_SIZE 1 -#define BINARY_LENGTH_SIZE 4 - -// IR associated definitions -#define BINARY_SOURCE_SIZE_MAX 1024 - -#define IR_KEY_POWER 0 -#define IR_KEY_MUTE 1 -#define IR_KEY_VOL_UP 7 -#define IR_KEY_VOL_DOWN 8 - -typedef enum -{ - IR_TYPE_NONE = 0, - IR_TYPE_TV, - IR_TYPE_AC, - IR_TYPE_MAX -} ir_type_t; - -typedef enum -{ - IR_STATE_STANDBY = 0, - IR_STATE_NONE, - IR_STATE_READY, - IR_STATE_OPENED, - IR_STATE_MAX -} ir_state_t; - -typedef struct -{ - int32_t binary_recv_length; - int32_t binary_recv_expected_length; - uint8_t transfer_on_going; -} transfer_control_block; - -typedef struct -{ - ir_type_t ir_type; - ir_state_t ir_state; - uint8_t source_code[BINARY_SOURCE_SIZE_MAX]; - uint16_t source_code_length; - uint16_t ir_decoded[USER_DATA_SIZE]; - uint16_t decoded_length; -} decode_control_block; - -/* IREXT - end */ - - -/********************************************************************* - * FUNCTIONS - */ - -extern void TransportDataToUart(uint8_t* data, uint16_t len); - -/* - * Task creation function for the Simple BLE Peripheral. - */ -extern void SimpleBLEPeripheral_createTask(void); - - -/********************************************************************* -*********************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif /* SIMPLEBLEPERIPHERAL_H */ +/************************************************************************************** +Filename: simpleBLEPeripheral.h +Revised: Date: 2017-01-10 +Revision: Revision: 1.0 + +Description: This file provides algorithms for IR decode (status type) + +Revision log: +* 2016-10-01: created by strawmanbobi +**************************************************************************************/ + +#ifndef SIMPLEBLEPERIPHERAL_H +#define SIMPLEBLEPERIPHERAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + * INCLUDES + */ + +/********************************************************************* +* EXTERNAL VARIABLES +*/ + +/********************************************************************* + * CONSTANTS + */ + +/********************************************************************* + * MACROS + */ + +/* IREXT - begin */ + +#include "./ir_decoder/src/include/ir_decode.h" + +// UART associated definitions +#define HEADER_SR 0x30 +#define HEADER_BT 0x31 +#define HEADER_CMD 0x32 + +#define CATEGORY_LENGTH_SIZE 1 +#define BINARY_LENGTH_SIZE 4 + +// IR associated definitions +#define BINARY_SOURCE_SIZE_MAX 1024 + +#define IR_KEY_POWER 0 +#define IR_KEY_MUTE 1 +#define IR_KEY_VOL_UP 7 +#define IR_KEY_VOL_DOWN 8 + +typedef enum +{ + IR_TYPE_NONE = 0, + IR_TYPE_TV, + IR_TYPE_AC, + IR_TYPE_MAX +} ir_type_t; + +typedef enum +{ + IR_STATE_STANDBY = 0, + IR_STATE_NONE, + IR_STATE_READY, + IR_STATE_OPENED, + IR_STATE_MAX +} ir_state_t; + +typedef struct +{ + int32_t binary_recv_length; + int32_t binary_recv_expected_length; + uint8_t transfer_on_going; +} transfer_control_block; + +typedef struct +{ + ir_type_t ir_type; + ir_state_t ir_state; + uint8_t source_code[BINARY_SOURCE_SIZE_MAX]; + uint16_t source_code_length; + uint16_t ir_decoded[USER_DATA_SIZE]; + uint16_t decoded_length; +} decode_control_block; + +/* IREXT - end */ + + +/********************************************************************* + * FUNCTIONS + */ + +extern void TransportDataToUart(uint8_t* data, uint16_t len); + +/* + * Task creation function for the Simple BLE Peripheral. + */ +extern void SimpleBLEPeripheral_createTask(void); + + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* SIMPLEBLEPERIPHERAL_H */ diff --git a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/common/cc26xx/Boundary/BoundaryConfig.xml b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/common/cc26xx/Boundary/BoundaryConfig.xml index fb3dfae..f8277fa 100644 --- a/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/common/cc26xx/Boundary/BoundaryConfig.xml +++ b/cc26xx-ARM-Cortex-M3-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/common/cc26xx/Boundary/BoundaryConfig.xml @@ -1,4 +1,4 @@ - +