From 258e2ea19f59ac033c70ac84948916ed3ee3eb49 Mon Sep 17 00:00:00 2001 From: strawmanbobi Date: Thu, 1 Jan 2026 20:34:23 +0800 Subject: [PATCH] made progress in arduino example --- .../ui/fragment/ControlFragment.java | 10 +- arduino-example/platformio.ini | 6 +- arduino-example/src/main.cpp | 12 +- arduino-example/src/remote.cpp | 103 ++++++++++++++++++ arduino-example/src/remote.h | 31 ++++++ arduino-example/src/utils.cpp | 79 ++++++++++++++ arduino-example/src/utils.h | 30 +++++ 7 files changed, 262 insertions(+), 9 deletions(-) create mode 100644 arduino-example/src/remote.cpp create mode 100644 arduino-example/src/remote.h create mode 100644 arduino-example/src/utils.cpp create mode 100644 arduino-example/src/utils.h 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 1596006..e706e17 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 @@ -297,7 +297,7 @@ public class ControlFragment extends Fragment implements View.OnClickListener { byte []binContent = FileUtils.getByteArrayFromFile(binFileName); sendBinToEmitter(binContent); } else { - emitterConnected = EMITTER_CONNECTED; + emitterConnected = EMITTER_BIN_RECEIVED; } } @@ -342,8 +342,14 @@ public class ControlFragment extends Fragment implements View.OnClickListener { } private void sendBinToEmitter(byte[] binContent) { + if (null == binContent) { + Log.e(TAG, "binary bytes is null"); + return; + } + int categoryId = mCurrentRemoteControl.getCategoryId(); + int subCate = mCurrentRemoteControl.getSubCategory(); String binBase64 = Base64.getEncoder().encodeToString(binContent); - String binStr = A_REQUEST_BIN + "," + binBase64.length() + "," + binBase64; + String binStr = A_REQUEST_BIN + "," + categoryId + "," + subCate + "," + binBase64.length() + "," + binBase64; Log.d(TAG, "sending bin in base64: " + binStr); new Thread(() -> { try { diff --git a/arduino-example/platformio.ini b/arduino-example/platformio.ini index 423f0d7..eaa9f3a 100644 --- a/arduino-example/platformio.ini +++ b/arduino-example/platformio.ini @@ -18,4 +18,8 @@ monitor_speed = 115200 lib_deps = WiFiS3 ArduinoGraphics - Arduino_LED_Matrix \ No newline at end of file + Arduino_LED_Matrix + adamvr/base64@^1.0.0 + +build_flags = + -I ./src/ir_decode/include \ No newline at end of file diff --git a/arduino-example/src/main.cpp b/arduino-example/src/main.cpp index 599e1ef..4ec3daa 100644 --- a/arduino-example/src/main.cpp +++ b/arduino-example/src/main.cpp @@ -23,14 +23,14 @@ #include #include - -#include "ArduinoGraphics.h" -#include "Arduino_LED_Matrix.h" +#include +#include #include "configure.h" +#include "remote.h" -#define WIFI_SERVER_PORT (8000) +#define WIFI_SERVER_PORT (8000) // global variable definitions constexpr char ssid[] = SECRET_SSID; @@ -44,7 +44,6 @@ auto *eBin = "e_bin"; auto *aControl = "a_control"; auto *eControl = "e_control"; - int status = WL_IDLE_STATUS; unsigned long lastStatusCheck = 0; boolean wifiStatusPrinted = false; @@ -81,7 +80,7 @@ void printWiFiStatus() { Serial.print("IP Address: "); Serial.println(ip); - long rssi = WiFi.RSSI(); + const long rssi = WiFi.RSSI(); Serial.print("Signal Strength (RSSI): "); Serial.print(rssi); Serial.println(" dBm"); @@ -135,6 +134,7 @@ void onCommand(const String *command, WiFiClient *client) { } else if (command->startsWith(aBin)) { Serial.println("Received bin command"); Serial.println(*command); + onRemoteBin(command->c_str()); } } diff --git a/arduino-example/src/remote.cpp b/arduino-example/src/remote.cpp new file mode 100644 index 0000000..cd917ef --- /dev/null +++ b/arduino-example/src/remote.cpp @@ -0,0 +1,103 @@ +/** + * + * Copyright (c) 2020-2025 IRext Opensource Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "utils.h" +#include "ir_decode.h" + + +#define REMOTE_BIN_MAX (1024) + +#define ABIN_COMMAND_SEG (5) +#define SEG_ABIN_HEADER (0) +#define SEG_ABIN_CATE (1) +#define SEG_ABIN_SUBCATE (2) +#define SEG_ABIN_LENGTH (3) +#define SEG_ABIN_BIN (4) + +// global variable definitions +unsigned char *remoteBin = nullptr; +int remoteBinLen = 0; + + +// public function definitions +int onRemoteBin(const char *binStr) { + char *aBinCommand[ABIN_COMMAND_SEG]; + char *remoteBinStr = nullptr; + int categoryId = 0; + int subCateId = 0; + int aBinCommandSeg = 0; + int remoteBinBase64Len = 0; + + aBinCommandSeg = splitString(binStr, aBinCommand, ABIN_COMMAND_SEG, ","); + if (ABIN_COMMAND_SEG != aBinCommandSeg) { + Serial.println("Invalid aBinCommand"); + return -1; + } + categoryId = strtol(aBinCommand[SEG_ABIN_CATE], nullptr, 10); + subCateId = strtol(aBinCommand[SEG_ABIN_SUBCATE], nullptr, 10); + remoteBinBase64Len = strtol(aBinCommand[SEG_ABIN_LENGTH], nullptr, 10); + remoteBinStr = aBinCommand[SEG_ABIN_BIN]; + if (remoteBinBase64Len != strlen(remoteBinStr)) { + Serial.println("remoteBin length not correct"); + return -1; + } + + remoteBinLen = base64_dec_len(remoteBinStr, remoteBinBase64Len); + remoteBin = static_cast(malloc(remoteBinLen)); + char debugStr[129]; + if (nullptr == remoteBin) { + Serial.println("Not enough memory for remoteBin"); + return -1; + } + Serial.print("Remote bin length = "); + Serial.println(remoteBinLen); + memset(remoteBin, 0, remoteBinLen); + + if (remoteBinLen != base64_decode(reinterpret_cast(remoteBin), remoteBinStr, remoteBinBase64Len)) { + Serial.println("Base64 decode failed"); + return -1; + } + +#if defined REMOTE_BIN_DEBUG + snprintf(debugStr, 128, "%02x %02x %02x %02x %02x %02x %02x %02x", + remoteBin[0], remoteBin[1], remoteBin[2], remoteBin[3], + remoteBin[4], remoteBin[5], remoteBin[6], remoteBin[7]); + Serial.println(debugStr); + snprintf(debugStr, 128, "%02x %02x %02x %02x %02x %02x %02x %02x", + remoteBin[remoteBinLen - 8], remoteBin[remoteBinLen - 7], remoteBin[remoteBinLen - 6], remoteBin[remoteBinLen - 5], + remoteBin[remoteBinLen - 4], remoteBin[remoteBinLen - 3], remoteBin[remoteBinLen - 2], remoteBin[remoteBinLen - 1]); + Serial.println(debugStr); +#endif + + if (IR_DECODE_FAILED == ir_binary_open(categoryId, subCateId, remoteBin, remoteBinLen)) { + Serial.println("ir_binary_open failed"); + return -1; + } + Serial.println("ir_binary_open success"); + ir_close(); + + return remoteBinLen; +} \ No newline at end of file diff --git a/arduino-example/src/remote.h b/arduino-example/src/remote.h new file mode 100644 index 0000000..d43444d --- /dev/null +++ b/arduino-example/src/remote.h @@ -0,0 +1,31 @@ +/** + * + * Copyright (c) 2020-2025 IRext Opensource Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef ARDUINO_EXAMPLE_REMOTE_H +#define ARDUINO_EXAMPLE_REMOTE_H + +// #define REMOTE_BIN_DEBUG (1) + +int onRemoteBin(const char *binStr); + +#endif //ARDUINO_EXAMPLE_REMOTE_H \ No newline at end of file diff --git a/arduino-example/src/utils.cpp b/arduino-example/src/utils.cpp new file mode 100644 index 0000000..1bff719 --- /dev/null +++ b/arduino-example/src/utils.cpp @@ -0,0 +1,79 @@ +/** + * + * Copyright (c) 2020-2025 IRext Opensource Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include + + +// public function definitions +int splitString(const char *str, char *parts[], + const int parts_max, const char *delimiter) { + char *pch = nullptr; + char *copy = nullptr; + char *tmp = nullptr; + int i = 0; + + copy = strdup(str); + if (nullptr == copy) { + goto _exit; + } + + pch = strtok(copy, delimiter); + + tmp = strdup(pch); + if (nullptr == tmp) { + goto _exit; + } + + if (i >= parts_max) { + goto _exit; + } + parts[i++] = tmp; + + while (pch) { + pch = strtok(nullptr, delimiter); + if (nullptr == pch) + break; + + tmp = strdup(pch); + if (nullptr == tmp) { + goto _exit; + } + + if (i >= parts_max) { + goto _exit; + } + parts[i++] = tmp; + } + + free(copy); + return i; + + _exit: + free(copy); + for (int j = 0; j < i; j++) { + free(parts[j]); + } + return -1; +} \ No newline at end of file diff --git a/arduino-example/src/utils.h b/arduino-example/src/utils.h new file mode 100644 index 0000000..b28dbc4 --- /dev/null +++ b/arduino-example/src/utils.h @@ -0,0 +1,30 @@ +/** + * + * Copyright (c) 2020-2025 IRext Opensource Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef ARDUINO_EXAMPLE_UTILS_H +#define ARDUINO_EXAMPLE_UTILS_H + +int splitString(const char *str, char *parts[], + const int parts_max, const char *delimiter); + +#endif //ARDUINO_EXAMPLE_UTILS_H \ No newline at end of file